Merge "Optimize libc for generic armv7/armv8 neon cores"
diff --git a/PREUPLOAD.cfg b/PREUPLOAD.cfg
index 7b533a4..f7c8fd7 100644
--- a/PREUPLOAD.cfg
+++ b/PREUPLOAD.cfg
@@ -1,2 +1,5 @@
 [Hook Scripts]
 notice = tools/update_notice.sh
+seccomp = tools/update_seccomp.sh
+syscalls = tools/update_syscalls.sh
+version_scripts = tools/update_version_scripts.sh
diff --git a/README.md b/README.md
index 7114015..f0be759 100644
--- a/README.md
+++ b/README.md
@@ -211,13 +211,13 @@
 
     $ mma # In $ANDROID_ROOT/bionic.
     $ adb root && adb remount && adb sync
-    $ adb shell /data/nativetest/bionic-unit-tests/bionic-unit-tests32
+    $ adb shell /data/nativetest/bionic-unit-tests/bionic-unit-tests
     $ adb shell \
-        /data/nativetest/bionic-unit-tests-static/bionic-unit-tests-static32
+        /data/nativetest/bionic-unit-tests-static/bionic-unit-tests-static
     # Only for 64-bit targets
-    $ adb shell /data/nativetest64/bionic-unit-tests/bionic-unit-tests64
+    $ adb shell /data/nativetest64/bionic-unit-tests/bionic-unit-tests
     $ adb shell \
-        /data/nativetest64/bionic-unit-tests-static/bionic-unit-tests-static64
+        /data/nativetest64/bionic-unit-tests-static/bionic-unit-tests-static
 
 Note that we use our own custom gtest runner that offers a superset of the
 options documented at
@@ -286,7 +286,7 @@
     $ adb shell \
         GCOV_PREFIX=/data/local/tmp/gcov \
         GCOV_PREFIX_STRIP=`echo $ANDROID_BUILD_TOP | grep -o / | wc -l` \
-        /data/nativetest/bionic-unit-tests/bionic-unit-tests32
+        /data/nativetest/bionic-unit-tests/bionic-unit-tests
     $ acov
 
 `acov` will pull all coverage information from the device, push it to the right
diff --git a/android-changes-for-ndk-developers.md b/android-changes-for-ndk-developers.md
index c301857..0620d9e 100644
--- a/android-changes-for-ndk-developers.md
+++ b/android-changes-for-ndk-developers.md
@@ -376,3 +376,22 @@
 ```
 
 enables logging of all errors and dlopen calls
+
+## dlclose interacts badly with thread local variables with non-trivial destructors
+
+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]).
+
+[issue 360]: https://github.com/android-ndk/ndk/issues/360
+
+Not calling `dlclose` or ensuring that your library has `RTLD_NODELETE`
+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   |
diff --git a/benchmarks/Android.bp b/benchmarks/Android.bp
index e8745a2..00c9560 100644
--- a/benchmarks/Android.bp
+++ b/benchmarks/Android.bp
@@ -73,7 +73,6 @@
 cc_benchmark_host {
     name: "bionic-benchmarks-glibc",
     defaults: ["bionic-benchmarks-defaults"],
-    host_ldlibs: ["-lrt"],
     target: {
         darwin: {
             // Only supported on linux systems.
diff --git a/benchmarks/math_benchmark.cpp b/benchmarks/math_benchmark.cpp
index 7b9a283..4d9d3cb 100644
--- a/benchmarks/math_benchmark.cpp
+++ b/benchmarks/math_benchmark.cpp
@@ -69,16 +69,11 @@
 }
 BIONIC_BENCHMARK(BM_math_isfinite_macro);
 
-#if defined(__BIONIC__)
-#define test_isfinite __isfinite
-#else
-#define test_isfinite __finite
-#endif
 static void BM_math_isfinite(benchmark::State& state) {
   d = 0.0;
   v = values[state.range(0)];
   while (state.KeepRunning()) {
-    d += test_isfinite(v);
+    d += isfinite(v);
   }
   SetLabel(state);
 }
@@ -134,17 +129,15 @@
 }
 BIONIC_BENCHMARK(BM_math_isnormal_macro);
 
-#if defined(__BIONIC__)
 static void BM_math_isnormal(benchmark::State& state) {
   d = 0.0;
   v = values[state.range(0)];
   while (state.KeepRunning()) {
-    d += (__isnormal)(v);
+    d += isnormal(v);
   }
   SetLabel(state);
 }
 BIONIC_BENCHMARK(BM_math_isnormal);
-#endif
 
 static void BM_math_sin_fast(benchmark::State& state) {
   d = 1.0;
@@ -202,7 +195,7 @@
   d = 0.0;
   v = values[state.range(0)];
   while (state.KeepRunning()) {
-    d += (__signbit)(v);
+    d += signbit(v);
   }
   SetLabel(state);
 }
diff --git a/benchmarks/pthread_benchmark.cpp b/benchmarks/pthread_benchmark.cpp
index 7a967ef..1ad6345 100644
--- a/benchmarks/pthread_benchmark.cpp
+++ b/benchmarks/pthread_benchmark.cpp
@@ -137,9 +137,7 @@
 }
 BIONIC_BENCHMARK(BM_pthread_create);
 
-static void* RunThread(void* arg) {
-  benchmark::State& state = *reinterpret_cast<benchmark::State*>(arg);
-  state.PauseTiming();
+static void* RunThread(void*) {
   return NULL;
 }
 
@@ -148,22 +146,18 @@
     pthread_t thread;
     pthread_create(&thread, NULL, RunThread, &state);
     pthread_join(thread, NULL);
-    state.ResumeTiming();
   }
 }
 BIONIC_BENCHMARK(BM_pthread_create_and_run);
 
-static void* ExitThread(void* arg) {
-  benchmark::State& state = *reinterpret_cast<benchmark::State*>(arg);
-  state.ResumeTiming();
+static void* ExitThread(void*) {
   pthread_exit(NULL);
 }
 
 static void BM_pthread_exit_and_join(benchmark::State& state) {
   while (state.KeepRunning()) {
-    state.PauseTiming();
     pthread_t thread;
-    pthread_create(&thread, NULL, ExitThread, &state);
+    pthread_create(&thread, NULL, ExitThread, nullptr);
     pthread_join(thread, NULL);
   }
 }
diff --git a/benchmarks/stdio_benchmark.cpp b/benchmarks/stdio_benchmark.cpp
index 0e7f668..76e9ddb 100644
--- a/benchmarks/stdio_benchmark.cpp
+++ b/benchmarks/stdio_benchmark.cpp
@@ -171,3 +171,37 @@
   FopenFgetcFclose(state, true);
 }
 BIONIC_BENCHMARK(BM_stdio_fopen_fgetc_fclose_no_locking);
+
+static void BM_stdio_printf_literal(benchmark::State& state) {
+  while (state.KeepRunning()) {
+    char buf[BUFSIZ];
+    snprintf(buf, sizeof(buf), "this is just a literal string with no format specifiers");
+  }
+}
+BIONIC_BENCHMARK(BM_stdio_printf_literal);
+
+static void BM_stdio_printf_s(benchmark::State& state) {
+  while (state.KeepRunning()) {
+    char buf[BUFSIZ];
+    snprintf(buf, sizeof(buf), "this is a more typical error message with detail: %s",
+             "No such file or directory");
+  }
+}
+BIONIC_BENCHMARK(BM_stdio_printf_s);
+
+static void BM_stdio_printf_d(benchmark::State& state) {
+  while (state.KeepRunning()) {
+    char buf[BUFSIZ];
+    snprintf(buf, sizeof(buf), "this is a more typical error message with detail: %d", 123456);
+  }
+}
+BIONIC_BENCHMARK(BM_stdio_printf_d);
+
+static void BM_stdio_printf_1$s(benchmark::State& state) {
+  while (state.KeepRunning()) {
+    char buf[BUFSIZ];
+    snprintf(buf, sizeof(buf), "this is a more typical error message with detail: %1$s",
+             "No such file or directory");
+  }
+}
+BIONIC_BENCHMARK(BM_stdio_printf_1$s);
diff --git a/benchmarks/suites/full.xml b/benchmarks/suites/full.xml
index a7bd9d4..9bfd6ff 100644
--- a/benchmarks/suites/full.xml
+++ b/benchmarks/suites/full.xml
@@ -189,6 +189,18 @@
   <name>BM_stdio_fopen_getline_fclose_no_locking</name>
 </fn>
 <fn>
+  <name>BM_stdio_printf_literal</name>
+</fn>
+<fn>
+  <name>BM_stdio_printf_s</name>
+</fn>
+<fn>
+  <name>BM_stdio_printf_d</name>
+</fn>
+<fn>
+  <name>BM_stdio_printf_1$s</name>
+</fn>
+<fn>
   <name>BM_string_memcmp</name>
   <args>AT_ALIGNED_TWOBUF</args>
 </fn>
diff --git a/benchmarks/tests/interface_test.cpp b/benchmarks/tests/interface_test.cpp
index b8279b6..6987320 100644
--- a/benchmarks/tests/interface_test.cpp
+++ b/benchmarks/tests/interface_test.cpp
@@ -71,7 +71,8 @@
   char path[PATH_MAX];
   ssize_t path_len = readlink("/proc/self/exe", path, sizeof(path));
   ASSERT_TRUE(path_len >= 0);
-  *exe_name = std::string(std::regex_replace(path, std::regex("-tests"), ""));
+  *exe_name = std::string(std::regex_replace(path, std::regex("nativetest"), "benchmarktest"));
+  *exe_name = std::regex_replace(*exe_name, std::regex("-tests"), "");
 }
 
 void SystemTests::Exec(std::vector<const char*> args) {
@@ -289,6 +290,10 @@
     "BM_stdio_fopen_fgetc_fclose_no_locking/1024/iterations:1\n"
     "BM_stdio_fopen_getline_fclose_locking/iterations:1\n"
     "BM_stdio_fopen_getline_fclose_no_locking/iterations:1\n"
+    "BM_stdio_printf_literal/iterations:1\n"
+    "BM_stdio_printf_s/iterations:1\n"
+    "BM_stdio_printf_d/iterations:1\n"
+    "BM_stdio_printf_1$s/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"
diff --git a/docs/32-bit-abi.md b/docs/32-bit-abi.md
index eecbe6d..5e3ae45 100644
--- a/docs/32-bit-abi.md
+++ b/docs/32-bit-abi.md
@@ -57,3 +57,14 @@
 Android all use the 32-bit `time_t`.
 
 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,
+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
+a hang in `pthread_mutex_lock` if the libc startup code doesn't detect
+this condition and abort.
diff --git a/docs/status.md b/docs/status.md
index 25f5663..6467143 100644
--- a/docs/status.md
+++ b/docs/status.md
@@ -8,8 +8,17 @@
 
 New libc functions in P:
   * `__freading`/`__fwriting` (completing <stdio_ext.h>)
+  * `endhostent`/endnetent`/`endprotoent`/`getnetent`/`getprotoent`/`sethostent`/`setnetent`/`setprotoent` (completing <netdb.h>)
+  * `fexecve`
+  * `fflush_unlocked`/`fgetc_unlocked`/`fgets_unlocked`/`fputc_unlocked`/`fputs_unlocked`/`fread_unlocked`/`fwrite_unlocked`
+  * `getentropy`/`getrandom` (adding <sys/random.h>)
   * `getlogin_r`
+  * `glob`/`globfree` (adding <glob.h>)
+  * `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`
+  * <spawn.h>
+  * `swab`
   * `syncfs`
 
 New libc functions in O:
@@ -56,7 +65,7 @@
 
 Run `./libc/tools/check-symbols-glibc.py` in bionic/ for the current
 list of POSIX functions implemented by glibc but not by bionic. Currently
-(2017-09):
+(2017-10):
 ```
 aio_cancel
 aio_error
@@ -65,47 +74,8 @@
 aio_return
 aio_suspend
 aio_write
-endhostent
-endnetent
-endprotoent
-endutxent
-fexecve
-fmtmsg
-getdate
-getdate_err
-getnetent
-getprotoent
-glob
-globfree
-hcreate
-hdestroy
-hsearch
 lio_listio
-posix_spawn
-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_spawnattr_destroy
-posix_spawnattr_getflags
-posix_spawnattr_getpgroup
-posix_spawnattr_getschedparam
-posix_spawnattr_getschedpolicy
-posix_spawnattr_getsigdefault
-posix_spawnattr_getsigmask
-posix_spawnattr_init
-posix_spawnattr_setflags
-posix_spawnattr_setpgroup
-posix_spawnattr_setschedparam
-posix_spawnattr_setschedpolicy
-posix_spawnattr_setsigdefault
-posix_spawnattr_setsigmask
-posix_spawnp
-pthread_attr_getinheritsched
-pthread_attr_setinheritsched
 pthread_cancel
-pthread_getconcurrency
 pthread_mutex_consistent
 pthread_mutex_getprioceiling
 pthread_mutex_setprioceiling
@@ -117,14 +87,7 @@
 pthread_mutexattr_setrobust
 pthread_setcancelstate
 pthread_setcanceltype
-pthread_setconcurrency
-pthread_setschedprio
 pthread_testcancel
-sethostent
-setnetent
-setprotoent
-sockatmark
-swab
 wordexp
 wordfree
 ```
diff --git a/libc/Android.bp b/libc/Android.bp
index dd4f33f..b88c987 100644
--- a/libc/Android.bp
+++ b/libc/Android.bp
@@ -14,14 +14,12 @@
     "bionic/siginterrupt.c",
     "bionic/sigsetmask.c",
     "stdio/fmemopen.cpp",
-    "stdio/fread.c",
     "stdio/parsefloat.c",
     "stdio/refill.c",
     "stdio/stdio.cpp",
     "stdio/stdio_ext.cpp",
     "stdio/vfscanf.c",
     "stdio/vfwscanf.c",
-    "stdlib/atexit.c",
     "stdlib/exit.c",
 ]
 
@@ -299,13 +297,14 @@
 cc_library_static {
     defaults: ["libc_defaults"],
     srcs: [
+        "upstream-freebsd/lib/libc/gen/glob.c",
         "upstream-freebsd/lib/libc/stdlib/realpath.c",
     ],
 
     cflags: [
         "-Wno-sign-compare",
         "-include freebsd-compat.h",
-        "-Wframe-larger-than=15000",
+        "-Wframe-larger-than=66000",
     ],
 
     local_include_dirs: [
@@ -439,28 +438,22 @@
         "upstream-openbsd/lib/libc/net/ntohl.c",
         "upstream-openbsd/lib/libc/net/ntohs.c",
         "upstream-openbsd/lib/libc/net/res_random.c",
-        "upstream-openbsd/lib/libc/stdio/fflush.c",
         "upstream-openbsd/lib/libc/stdio/fgetln.c",
-        "upstream-openbsd/lib/libc/stdio/fgets.c",
         "upstream-openbsd/lib/libc/stdio/fgetwc.c",
         "upstream-openbsd/lib/libc/stdio/fgetws.c",
         "upstream-openbsd/lib/libc/stdio/flags.c",
         "upstream-openbsd/lib/libc/stdio/fpurge.c",
-        "upstream-openbsd/lib/libc/stdio/fputs.c",
         "upstream-openbsd/lib/libc/stdio/fputwc.c",
         "upstream-openbsd/lib/libc/stdio/fputws.c",
         "upstream-openbsd/lib/libc/stdio/fvwrite.c",
         "upstream-openbsd/lib/libc/stdio/fwalk.c",
         "upstream-openbsd/lib/libc/stdio/fwide.c",
-        "upstream-openbsd/lib/libc/stdio/fwrite.c",
         "upstream-openbsd/lib/libc/stdio/getdelim.c",
         "upstream-openbsd/lib/libc/stdio/gets.c",
         "upstream-openbsd/lib/libc/stdio/makebuf.c",
         "upstream-openbsd/lib/libc/stdio/mktemp.c",
         "upstream-openbsd/lib/libc/stdio/open_memstream.c",
         "upstream-openbsd/lib/libc/stdio/open_wmemstream.c",
-        "upstream-openbsd/lib/libc/stdio/perror.c",
-        "upstream-openbsd/lib/libc/stdio/puts.c",
         "upstream-openbsd/lib/libc/stdio/rget.c",
         "upstream-openbsd/lib/libc/stdio/setvbuf.c",
         "upstream-openbsd/lib/libc/stdio/tempnam.c",
@@ -531,8 +524,8 @@
     name: "libc_openbsd_large_stack",
     defaults: ["libc_defaults"],
     srcs: [
-        "upstream-openbsd/lib/libc/stdio/vfprintf.c",
-        "upstream-openbsd/lib/libc/stdio/vfwprintf.c",
+        "stdio/vfprintf.cpp",
+        "stdio/vfwprintf.cpp",
     ],
     cflags: [
         "-include openbsd-compat.h",
@@ -541,10 +534,10 @@
     ],
 
     local_include_dirs: [
-        "stdio",
-        "upstream-openbsd/android/include",
-        "upstream-openbsd/lib/libc/include",
+        "upstream-openbsd/android/include/",
+        "upstream-openbsd/lib/libc/include/",
         "upstream-openbsd/lib/libc/gdtoa/",
+        "upstream-openbsd/lib/libc/stdio/",
     ],
 }
 
@@ -830,11 +823,6 @@
 cc_library_static {
     defaults: ["libc_defaults"],
     srcs: [
-        // The following implementations depend on pthread data, so we can't
-        // include them in libc_ndk.a.
-        "bionic/__cxa_thread_atexit_impl.cpp",
-        "bionic/fork.cpp",
-
         // The data that backs getauxval is initialized in the libc init
         // functions which are invoked by the linker. If this file is included
         // in libc_ndk.a, only one of the copies of the global data will be
@@ -1244,7 +1232,6 @@
         "bionic/__gnu_basename.cpp",
         "bionic/__libc_current_sigrtmax.cpp",
         "bionic/__libc_current_sigrtmin.cpp",
-        "bionic/__set_errno.cpp",
         "bionic/abort.cpp",
         "bionic/accept.cpp",
         "bionic/accept4.cpp",
@@ -1378,6 +1365,7 @@
         "bionic/sigwait.cpp",
         "bionic/sigwaitinfo.cpp",
         "bionic/socket.cpp",
+        "bionic/spawn.cpp",
         "bionic/stat.cpp",
         "bionic/statvfs.cpp",
         "bionic/stdlib_l.cpp",
@@ -1388,6 +1376,7 @@
         "bionic/strings_l.cpp",
         "bionic/strsignal.cpp",
         "bionic/strtold.cpp",
+        "bionic/swab.cpp",
         "bionic/symlink.cpp",
         "bionic/sync_file_range.cpp",
         "bionic/sys_msg.cpp",
@@ -1398,7 +1387,6 @@
         "bionic/sys_time.cpp",
         "bionic/sysinfo.cpp",
         "bionic/syslog.cpp",
-        "bionic/system_properties.cpp",
         "bionic/tdestroy.cpp",
         "bionic/termios.cpp",
         "bionic/thread_private.cpp",
@@ -1412,6 +1400,16 @@
         "bionic/wctype.cpp",
         "bionic/wcwidth.cpp",
         "bionic/wmempcpy.cpp",
+        "system_properties/context_node.cpp",
+        "system_properties/contexts_split.cpp",
+        "system_properties/prop_area.cpp",
+        "system_properties/prop_info.cpp",
+        "system_properties/system_properties.cpp",
+
+
+        // This contains a weak stub implementation of __find_icu_symbol for wctype.cpp,
+        // which will be overridden by the actual one in libc.so.
+        "bionic/icu_static.cpp",
     ],
 
     multilib: {
@@ -1466,6 +1464,12 @@
         "bionic/pthread_setschedparam.cpp",
         "bionic/pthread_sigmask.cpp",
         "bionic/pthread_spinlock.cpp",
+
+        // The following implementations depend on pthread data or implementation,
+        // so we can't include them in libc_ndk.a.
+        "bionic/__cxa_thread_atexit_impl.cpp",
+        "stdlib/atexit.c",
+        "bionic/fork.cpp",
     ],
 
     cppflags: ["-Wold-style-cast"],
@@ -1479,6 +1483,7 @@
 
 cc_library_static {
     defaults: ["libc_defaults"],
+    srcs: ["bionic/__set_errno.cpp"],
     arch: {
         arm: {
             srcs: ["arch-arm/syscalls/**/*.S"],
@@ -1578,9 +1583,8 @@
 }
 
 // ========================================================
-// libc_common.a
+// libc_nopthread.a
 // ========================================================
-
 cc_library_static {
     defaults: ["libc_defaults"],
     srcs: libc_common_src_files,
@@ -1589,7 +1593,7 @@
             srcs: libc_common_src_files_32,
         },
     },
-    name: "libc_common",
+    name: "libc_nopthread",
 
     whole_static_libs: [
         "libc_bionic",
@@ -1604,7 +1608,6 @@
         "libc_openbsd",
         "libc_openbsd_large_stack",
         "libc_openbsd_ndk",
-        "libc_pthread",
         "libc_stack_protector",
         "libc_syscalls",
         "libc_tzcode",
@@ -1619,6 +1622,20 @@
 }
 
 // ========================================================
+// libc_common.a
+// ========================================================
+
+cc_library_static {
+    defaults: ["libc_defaults"],
+    name: "libc_common",
+
+    whole_static_libs: [
+        "libc_nopthread",
+        "libc_pthread",
+    ],
+}
+
+// ========================================================
 // libc_nomalloc.a
 // ========================================================
 //
@@ -1672,9 +1689,7 @@
     static: {
         srcs: [
             "bionic/dl_iterate_phdr_static.cpp",
-            "bionic/icu_static.cpp",
             "bionic/malloc_common.cpp",
-            "bionic/libc_init_static.cpp",
         ],
         cflags: ["-DLIBC_STATIC"],
         whole_static_libs: ["libc_init_static"],
@@ -1808,38 +1823,13 @@
     defaults: ["linux_bionic_supported"],
     vendor_available: true,
 
-    no_default_compiler_flags: true,
-
-    cflags: ["-Wno-gcc-compat", "-Werror"],
-
-    arch: {
-        arm: {
-            local_include_dirs: ["arch-arm/include"],
-        },
-        arm64: {
-            local_include_dirs: ["arch-arm64/include"],
-        },
-        mips: {
-            local_include_dirs: ["arch-mips/include"],
-        },
-        mips64: {
-            local_include_dirs: ["arch-mips64/include"],
-        },
-        x86: {
-            local_include_dirs: ["arch-x86/include"],
-        },
-        x86_64: {
-            local_include_dirs: ["arch-x86_64/include"],
-        },
-    },
+    cflags: ["-Wno-gcc-compat", "-Wall", "-Werror"],
 }
 
 cc_defaults {
     name: "crt_so_defaults",
+    defaults: ["crt_defaults"],
 
-    cflags: ["-Wno-gcc-compat", "-Werror"],
-
-    vendor_available: true,
     arch: {
         mips: {
             cflags: ["-fPIC"],
@@ -1868,10 +1858,7 @@
     },
     srcs: ["arch-common/bionic/crtbrand.S"],
 
-    defaults: [
-        "crt_defaults",
-        "crt_so_defaults",
-    ],
+    defaults: ["crt_so_defaults"],
 }
 
 cc_object {
@@ -1879,19 +1866,13 @@
     local_include_dirs: ["include"],
     srcs: ["arch-common/bionic/crtbegin_so.c"],
 
-    defaults: [
-        "crt_defaults",
-        "crt_so_defaults",
-    ],
+    defaults: ["crt_so_defaults"],
 }
 
 cc_object {
     name: "crtbegin_so",
 
-    defaults: [
-        "crt_defaults",
-        "crt_so_defaults",
-    ],
+    defaults: ["crt_so_defaults"],
     objs: [
         "crtbegin_so1",
         "crtbrand",
@@ -1903,10 +1884,7 @@
     local_include_dirs: ["include"],
     srcs: ["arch-common/bionic/crtend_so.S"],
 
-    defaults: [
-        "crt_defaults",
-        "crt_so_defaults",
-    ],
+    defaults: ["crt_so_defaults"],
 }
 
 cc_object {
@@ -2059,22 +2037,6 @@
 }
 
 ndk_headers {
-    name: "libc_asm_mips",
-    from: "kernel/uapi/asm-mips",
-    to: "mipsel-linux-android",
-    srcs: ["kernel/uapi/asm-mips/**/*.h"],
-    license: "NOTICE",
-}
-
-ndk_headers {
-    name: "libc_asm_mips64",
-    from: "kernel/uapi/asm-mips",
-    to: "mips64el-linux-android",
-    srcs: ["kernel/uapi/asm-mips/**/*.h"],
-    license: "NOTICE",
-}
-
-ndk_headers {
     name: "libc_asm_x86",
     from: "kernel/uapi/asm-x86",
     to: "i686-linux-android",
@@ -2090,54 +2052,6 @@
     license: "NOTICE",
 }
 
-ndk_headers {
-    name: "libc_machine_arm",
-    from: "arch-arm/include",
-    to: "arm-linux-androideabi",
-    srcs: ["arch-arm/include/**/*.h"],
-    license: "NOTICE",
-}
-
-ndk_headers {
-    name: "libc_machine_arm64",
-    from: "arch-arm64/include",
-    to: "aarch64-linux-android",
-    srcs: ["arch-arm64/include/**/*.h"],
-    license: "NOTICE",
-}
-
-ndk_headers {
-    name: "libc_machine_mips",
-    from: "arch-mips/include",
-    to: "mipsel-linux-android",
-    srcs: ["arch-mips/include/**/*.h"],
-    license: "NOTICE",
-}
-
-ndk_headers {
-    name: "libc_machine_mips64",
-    from: "arch-mips/include",
-    to: "mips64el-linux-android",
-    srcs: ["arch-mips/include/**/*.h"],
-    license: "NOTICE",
-}
-
-ndk_headers {
-    name: "libc_machine_x86",
-    from: "arch-x86/include",
-    to: "i686-linux-android",
-    srcs: ["arch-x86/include/**/*.h"],
-    license: "NOTICE",
-}
-
-ndk_headers {
-    name: "libc_machine_x86_64",
-    from: "arch-x86_64/include",
-    to: "x86_64-linux-android",
-    srcs: ["arch-x86_64/include/**/*.h"],
-    license: "NOTICE",
-}
-
 ndk_library {
     name: "libc",
     symbol_file: "libc.map.txt",
@@ -2152,7 +2066,6 @@
     arch: {
         arm: {
             export_include_dirs: [
-                "arch-arm/include",
                 "kernel/uapi",
                 "kernel/uapi/asm-arm",
                 "kernel/android/uapi",
@@ -2160,7 +2073,6 @@
         },
         arm64: {
             export_include_dirs: [
-                "arch-arm64/include",
                 "kernel/uapi",
                 "kernel/uapi/asm-arm64",
                 "kernel/android/uapi",
@@ -2168,7 +2080,6 @@
         },
         mips: {
             export_include_dirs: [
-                "arch-mips/include",
                 "kernel/uapi",
                 "kernel/uapi/asm-mips",
                 "kernel/android/uapi",
@@ -2176,7 +2087,6 @@
         },
         mips64: {
             export_include_dirs: [
-                "arch-mips64/include",
                 "kernel/uapi",
                 "kernel/uapi/asm-mips",
                 "kernel/android/uapi",
@@ -2184,7 +2094,6 @@
         },
         x86: {
             export_include_dirs: [
-                "arch-x86/include",
                 "kernel/uapi",
                 "kernel/uapi/asm-x86",
                 "kernel/android/uapi",
@@ -2192,7 +2101,6 @@
         },
         x86_64: {
             export_include_dirs: [
-                "arch-x86_64/include",
                 "kernel/uapi",
                 "kernel/uapi/asm-x86",
                 "kernel/android/uapi",
diff --git a/libc/NOTICE b/libc/NOTICE
index feea29d..db4b5a5 100644
--- a/libc/NOTICE
+++ b/libc/NOTICE
@@ -1914,6 +1914,75 @@
    The Regents of the University of California.  All rights reserved.
 
 This code is derived from software contributed to Berkeley by
+Guido van Rossum.
+
+Copyright (c) 2011 The FreeBSD Foundation
+All rights reserved.
+Portions of this software were developed by David Chisnall
+under sponsorship from the FreeBSD Foundation.
+
+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.
+
+-------------------------------------------------------------------
+
+Copyright (c) 1989, 1993
+   The Regents of the University of California.  All rights reserved.
+
+This code is derived from software contributed to Berkeley by
+Guido van Rossum.
+
+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.
+
+-------------------------------------------------------------------
+
+Copyright (c) 1989, 1993
+   The Regents of the University of California.  All rights reserved.
+
+This code is derived from software contributed to Berkeley by
 Roger L. Snyder.
 
 Redistribution and use in source and binary forms, with or without
@@ -2639,39 +2708,6 @@
 Copyright (c) 1992, 1993
    The Regents of the University of California.  All rights reserved.
 
-This code is derived from software contributed to Berkeley by
-Ralph Campbell. This file is derived from the MIPS RISC
-Architecture book by Gerry Kane.
-
-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.
-
--------------------------------------------------------------------
-
-Copyright (c) 1992, 1993
-   The Regents of the University of California.  All rights reserved.
-
 This software was developed by the Computer Systems Engineering group
 at Lawrence Berkeley Laboratory under DARPA contract BG 91-66 and
 contributed to Berkeley.
@@ -3776,32 +3812,6 @@
 -------------------------------------------------------------------
 
 Copyright (c) 2003 Mike Barcroft <mike@FreeBSD.org>
-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.
-
-THIS SOFTWARE IS PROVIDED BY THE AUTHOR 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 AUTHOR 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) 2003 Mike Barcroft <mike@FreeBSD.org>
 Copyright (c) 2002 David Schultz <das@FreeBSD.ORG>
 All rights reserved.
 
@@ -3978,42 +3988,6 @@
 
 -------------------------------------------------------------------
 
-Copyright (c) 2004 The NetBSD Foundation, Inc.
-All rights reserved.
-
-This code is derived from software contributed to The NetBSD Foundation
-by Christos Zoulas.
-
-Redistribution and use in source and binary forms, with or without
-modification, are permitted provided that the following conditions
-are met:
-1. Redistributions of source code must retain the above copyright
-   notice, this list of conditions and the following disclaimer.
-2. Redistributions in binary form must reproduce the above copyright
-   notice, this list of conditions and the following disclaimer in the
-   documentation and/or other materials provided with the distribution.
-3. All advertising materials mentioning features or use of this software
-   must display the following acknowledgement:
-       This product includes software developed by the NetBSD
-       Foundation, Inc. and its contributors.
-4. Neither the name of The NetBSD Foundation 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 NETBSD FOUNDATION, INC. AND CONTRIBUTORS
-``AS IS'' AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED
-TO, THE IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR
-PURPOSE ARE DISCLAIMED.  IN NO EVENT SHALL THE FOUNDATION OR CONTRIBUTORS
-BE LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR
-CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF
-SUBSTITUTE GOODS OR SERVICES; LOSS OF USE, DATA, OR PROFITS; OR BUSINESS
-INTERRUPTION) HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY, WHETHER IN
-CONTRACT, STRICT LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE)
-ARISING IN ANY WAY OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF THE
-POSSIBILITY OF SUCH DAMAGE.
-
--------------------------------------------------------------------
-
 Copyright (c) 2004 by Internet Systems Consortium, Inc. ("ISC")
 Copyright (c) 1995,1999 by Internet Software Consortium.
 
@@ -5669,6 +5643,34 @@
 
 -------------------------------------------------------------------
 
+Copyright (c) 2017 ARM Ltd
+All rights reserved.
+
+Redistribution and use in source and binary forms, with or without
+modification, are permitted provided that the following conditions
+are met:
+1. Redistributions of source code must retain the above copyright
+   notice, this list of conditions and the following disclaimer.
+2. Redistributions in binary form must reproduce the above copyright
+   notice, this list of conditions and the following disclaimer in the
+   documentation and/or other materials provided with the distribution.
+3. The name of the company may not be used to endorse or promote
+   products derived from this software without specific prior written
+   permission.
+
+THIS SOFTWARE IS PROVIDED BY ARM LTD ``AS IS'' AND ANY EXPRESS OR IMPLIED
+WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE IMPLIED WARRANTIES OF
+MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE ARE DISCLAIMED.
+IN NO EVENT SHALL ARM LTD BE LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL,
+SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT LIMITED
+TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; LOSS OF USE, DATA, OR
+PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND ON ANY THEORY OF
+LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT (INCLUDING
+NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE OF THIS
+SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE.
+
+-------------------------------------------------------------------
+
 Copyright (c) 2017 Imagination Technologies.
 
 All rights reserved.
diff --git a/libc/SECCOMP_WHITELIST.TXT b/libc/SECCOMP_WHITELIST.TXT
index 2c4767b..36a579b 100644
--- a/libc/SECCOMP_WHITELIST.TXT
+++ b/libc/SECCOMP_WHITELIST.TXT
@@ -35,7 +35,6 @@
 int	rt_sigreturn:rt_sigreturn(unsigned long __unused)	all
 int	rt_tgsigqueueinfo:int rt_tgsigqueueinfo(pid_t tgid, pid_t tid, int sig, siginfo_t *uinfo)	all
 int	restart_syscall:int restart_syscall()	all
-int	getrandom:int getrandom(void *buf, size_t buflen, unsigned int flags) all
 int	fstatat64|fstatat:newfstatat(int, const char*, struct stat*, int)	mips64
 int	fstat64|fstat:fstat(int, struct stat*)	mips64
 int	_flush_cache:cacheflush(char* addr, const int nbytes, const int op)	mips64
diff --git a/libc/SYSCALLS.TXT b/libc/SYSCALLS.TXT
index a1d1af0..f8be0b0 100644
--- a/libc/SYSCALLS.TXT
+++ b/libc/SYSCALLS.TXT
@@ -353,3 +353,6 @@
 # vdso stuff.
 int __clock_gettime:clock_gettime(clockid_t, timespec*) all
 int __gettimeofday:gettimeofday(timeval*, timezone*) all
+
+# <sys/random.h>
+ssize_t getrandom(void*, size_t, unsigned) all
diff --git a/libc/arch-arm/bionic/setjmp.S b/libc/arch-arm/bionic/setjmp.S
index 6ee162e..b814124 100644
--- a/libc/arch-arm/bionic/setjmp.S
+++ b/libc/arch-arm/bionic/setjmp.S
@@ -76,11 +76,13 @@
 #define _JB_CHECKSUM    (_JB_CORE_BASE+10)
 
 ENTRY(setjmp)
+__BIONIC_WEAK_ASM_FOR_NATIVE_BRIDGE(setjmp)
   mov r1, #1
   b sigsetjmp
 END(setjmp)
 
 ENTRY(_setjmp)
+__BIONIC_WEAK_ASM_FOR_NATIVE_BRIDGE(_setjmp)
   mov r1, #0
   b sigsetjmp
 END(_setjmp)
@@ -117,6 +119,7 @@
 
 // int sigsetjmp(sigjmp_buf env, int save_signal_mask);
 ENTRY(sigsetjmp)
+__BIONIC_WEAK_ASM_FOR_NATIVE_BRIDGE(sigsetjmp)
   stmfd sp!, {r0, lr}
   .cfi_def_cfa_offset 8
   .cfi_rel_offset r0, 0
@@ -191,6 +194,7 @@
 
 // void siglongjmp(sigjmp_buf env, int value);
 ENTRY(siglongjmp)
+__BIONIC_WEAK_ASM_FOR_NATIVE_BRIDGE(siglongjmp)
   stmfd sp!, {r0, r1, lr}
   .cfi_def_cfa_offset 12
   .cfi_rel_offset r0, 0
@@ -262,4 +266,6 @@
 END(siglongjmp)
 
 ALIAS_SYMBOL(longjmp, siglongjmp)
+__BIONIC_WEAK_ASM_FOR_NATIVE_BRIDGE(longjmp)
 ALIAS_SYMBOL(_longjmp, siglongjmp)
+__BIONIC_WEAK_ASM_FOR_NATIVE_BRIDGE(_longjmp)
diff --git a/libc/arch-arm/bionic/vfork.S b/libc/arch-arm/bionic/vfork.S
index 1b7cbad..8329111 100644
--- a/libc/arch-arm/bionic/vfork.S
+++ b/libc/arch-arm/bionic/vfork.S
@@ -29,6 +29,7 @@
 #include <private/bionic_asm.h>
 
 ENTRY(vfork)
+__BIONIC_WEAK_ASM_FOR_NATIVE_BRIDGE(vfork)
     // __get_tls()[TLS_SLOT_THREAD_ID]->cached_pid_ = 0
     mrc     p15, 0, r3, c13, c0, 3
     ldr     r3, [r3, #4]
diff --git a/libc/arch-arm/include/machine/setjmp.h b/libc/arch-arm/include/machine/setjmp.h
deleted file mode 100644
index cc9c347..0000000
--- a/libc/arch-arm/include/machine/setjmp.h
+++ /dev/null
@@ -1,35 +0,0 @@
-/*
- * Copyright (C) 2010 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.
- */
-
-/* _JBLEN is the size of a jmp_buf in longs.
- * Do not modify this value or you will break the ABI !
- *
- * This value comes from the original OpenBSD ARM-specific header
- * that was replaced by this one.
- */
-#define _JBLEN  64
diff --git a/libc/arch-arm/krait/bionic/memcpy_base.S b/libc/arch-arm/krait/bionic/memcpy_base.S
index 7368e63..dc8ad2c 100644
--- a/libc/arch-arm/krait/bionic/memcpy_base.S
+++ b/libc/arch-arm/krait/bionic/memcpy_base.S
@@ -27,8 +27,6 @@
 
 /* Assumes neon instructions and a cache line size of 64 bytes. */
 
-#include <machine/asm.h>
-
 #define PLDOFFS	(10)
 #define PLDTHRESH (PLDOFFS)
 #define BBTHRESH (4096/64)
diff --git a/libc/arch-arm/syscalls/getrandom.S b/libc/arch-arm/syscalls/getrandom.S
new file mode 100644
index 0000000..3f28af6
--- /dev/null
+++ b/libc/arch-arm/syscalls/getrandom.S
@@ -0,0 +1,16 @@
+/* Generated by gensyscalls.py. Do not edit. */
+
+#include <private/bionic_asm.h>
+
+ENTRY(getrandom)
+    mov     ip, r7
+    .cfi_register r7, ip
+    ldr     r7, =__NR_getrandom
+    swi     #0
+    mov     r7, ip
+    .cfi_restore r7
+    cmn     r0, #(MAX_ERRNO + 1)
+    bxls    lr
+    neg     r0, r0
+    b       __set_errno_internal
+END(getrandom)
diff --git a/libc/arch-arm64/bionic/setjmp.S b/libc/arch-arm64/bionic/setjmp.S
index 2550134..ee618b1 100644
--- a/libc/arch-arm64/bionic/setjmp.S
+++ b/libc/arch-arm64/bionic/setjmp.S
@@ -99,17 +99,20 @@
 .endm
 
 ENTRY(setjmp)
+__BIONIC_WEAK_ASM_FOR_NATIVE_BRIDGE(setjmp)
   mov w1, #1
   b sigsetjmp
 END(setjmp)
 
 ENTRY(_setjmp)
+__BIONIC_WEAK_ASM_FOR_NATIVE_BRIDGE(_setjmp)
   mov w1, #0
   b sigsetjmp
 END(_setjmp)
 
 // int sigsetjmp(sigjmp_buf env, int save_signal_mask);
 ENTRY(sigsetjmp)
+__BIONIC_WEAK_ASM_FOR_NATIVE_BRIDGE(sigsetjmp)
   stp x0, x30, [sp, #-16]!
   .cfi_def_cfa_offset 16
   .cfi_rel_offset x0, 0
@@ -178,6 +181,7 @@
 
 // void siglongjmp(sigjmp_buf env, int value);
 ENTRY(siglongjmp)
+__BIONIC_WEAK_ASM_FOR_NATIVE_BRIDGE(siglongjmp)
 #if USE_CHECKSUM
   // Check the checksum before doing anything.
   m_calculate_checksum x12, x0, x2
@@ -256,4 +260,6 @@
 END(siglongjmp)
 
 ALIAS_SYMBOL(longjmp, siglongjmp)
+__BIONIC_WEAK_ASM_FOR_NATIVE_BRIDGE(longjmp)
 ALIAS_SYMBOL(_longjmp, siglongjmp)
+__BIONIC_WEAK_ASM_FOR_NATIVE_BRIDGE(_longjmp)
diff --git a/libc/arch-arm64/bionic/vfork.S b/libc/arch-arm64/bionic/vfork.S
index 92fa333..0a83cc7 100644
--- a/libc/arch-arm64/bionic/vfork.S
+++ b/libc/arch-arm64/bionic/vfork.S
@@ -31,6 +31,7 @@
 #include <linux/sched.h>
 
 ENTRY(vfork)
+__BIONIC_WEAK_ASM_FOR_NATIVE_BRIDGE(vfork)
     // __get_tls()[TLS_SLOT_THREAD_ID]->cached_pid_ = 0
     mrs     x0, tpidr_el0
     ldr     x0, [x0, #8]
diff --git a/libc/arch-arm64/generic/bionic/memcmp.S b/libc/arch-arm64/generic/bionic/memcmp.S
index 3d08ecd..3a138bf 100644
--- a/libc/arch-arm64/generic/bionic/memcmp.S
+++ b/libc/arch-arm64/generic/bionic/memcmp.S
@@ -1,33 +1,34 @@
-/* Copyright (c) 2014, Linaro Limited
-   All rights reserved.
-
-   Redistribution and use in source and binary forms, with or without
-   modification, are permitted provided that the following conditions are met:
-       * Redistributions of source code must retain the above copyright
-         notice, this list of conditions and the following disclaimer.
-       * Redistributions in binary form must reproduce the above copyright
-         notice, this list of conditions and the following disclaimer in the
-         documentation and/or other materials provided with the distribution.
-       * Neither the name of the Linaro nor the
-         names of its contributors may be used to endorse or promote products
-         derived from this software without specific prior written permission.
-
-   THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS
-   "AS IS" AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT
-   LIMITED TO, THE IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR
-   A PARTICULAR PURPOSE ARE DISCLAIMED. IN NO EVENT SHALL THE COPYRIGHT
-   HOLDER OR CONTRIBUTORS BE LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL,
-   SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT
-   LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; LOSS OF USE,
-   DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND ON ANY
-   THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT
-   (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE
-   OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE.
-*/
+/*
+ * Copyright (c) 2017 ARM Ltd
+ * All rights reserved.
+ *
+ * Redistribution and use in source and binary forms, with or without
+ * modification, are permitted provided that the following conditions
+ * are met:
+ * 1. Redistributions of source code must retain the above copyright
+ *    notice, this list of conditions and the following disclaimer.
+ * 2. Redistributions in binary form must reproduce the above copyright
+ *    notice, this list of conditions and the following disclaimer in the
+ *    documentation and/or other materials provided with the distribution.
+ * 3. The name of the company may not be used to endorse or promote
+ *    products derived from this software without specific prior written
+ *    permission.
+ *
+ * THIS SOFTWARE IS PROVIDED BY ARM LTD ``AS IS'' AND ANY EXPRESS OR IMPLIED
+ * WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE IMPLIED WARRANTIES OF
+ * MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE ARE DISCLAIMED.
+ * IN NO EVENT SHALL ARM LTD BE LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL,
+ * SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT LIMITED
+ * TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; LOSS OF USE, DATA, OR
+ * PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND ON ANY THEORY OF
+ * LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT (INCLUDING
+ * NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE OF THIS
+ * SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE.
+ */
 
 /* Assumptions:
  *
- * ARMv8-a, AArch64
+ * ARMv8-a, AArch64, unaligned accesses.
  */
 
 #include <private/bionic_asm.h>
@@ -36,120 +37,93 @@
 #define src1		x0
 #define src2		x1
 #define limit		x2
-#define result		x0
+#define result		w0
 
 /* Internal variables.  */
 #define data1		x3
 #define data1w		w3
 #define data2		x4
 #define data2w		w4
-#define has_nul		x5
-#define diff		x6
-#define endloop		x7
-#define tmp1		x8
-#define tmp2		x9
-#define tmp3		x10
-#define pos		x11
-#define limit_wd	x12
-#define mask		x13
+#define tmp1		x5
 
+/* Small inputs of less than 8 bytes are handled separately.  This allows the
+   main code to be sped up using unaligned loads since there are now at least
+   8 bytes to be compared.  If the first 8 bytes are equal, align src1.
+   This ensures each iteration does at most one unaligned access even if both
+   src1 and src2 are unaligned, and mutually aligned inputs behave as if
+   aligned.  After the main loop, process the last 8 bytes using unaligned
+   accesses.  */
+
+.p2align 6
 ENTRY(memcmp)
-	cbz	limit, .Lret0
-	eor	tmp1, src1, src2
-	tst	tmp1, #7
-	b.ne	.Lmisaligned8
-	ands	tmp1, src1, #7
-	b.ne	.Lmutual_align
-	add	limit_wd, limit, #7
-	lsr	limit_wd, limit_wd, #3
-	/* Start of performance-critical section  -- one 64B cache line.  */
-.Lloop_aligned:
-	ldr	data1, [src1], #8
-	ldr	data2, [src2], #8
-.Lstart_realigned:
-	subs	limit_wd, limit_wd, #1
-	eor	diff, data1, data2	/* Non-zero if differences found.  */
-	csinv	endloop, diff, xzr, ne	/* Last Dword or differences.  */
-	cbz	endloop, .Lloop_aligned
-	/* End of performance-critical section  -- one 64B cache line.  */
+	subs	limit, limit, 8
+	b.lo	.Lless8
 
-	/* Not reached the limit, must have found a diff.  */
-	cbnz	limit_wd, .Lnot_limit
+	/* Limit >= 8, so check first 8 bytes using unaligned loads.  */
+	ldr	data1, [src1], 8
+	ldr	data2, [src2], 8
+	and	tmp1, src1, 7
+	add	limit, limit, tmp1
+	cmp	data1, data2
+	bne	.Lreturn
 
-	/* Limit % 8 == 0 => all bytes significant.  */
-	ands	limit, limit, #7
-	b.eq	.Lnot_limit
+	/* Align src1 and adjust src2 with bytes not yet done.  */
+	sub	src1, src1, tmp1
+	sub	src2, src2, tmp1
 
-	lsl	limit, limit, #3	/* Bits -> bytes.  */
-	mov	mask, #~0
-#ifdef __AARCH64EB__
-	lsr	mask, mask, limit
-#else
-	lsl	mask, mask, limit
-#endif
-	bic	data1, data1, mask
-	bic	data2, data2, mask
+	subs	limit, limit, 8
+	b.ls	.Llast_bytes
 
-	orr	diff, diff, mask
-.Lnot_limit:
+	/* Loop performing 8 bytes per iteration using aligned src1.
+	   Limit is pre-decremented by 8 and must be larger than zero.
+	   Exit if <= 8 bytes left to do or if the data is not equal.  */
+	.p2align 4
+.Lloop8:
+	ldr	data1, [src1], 8
+	ldr	data2, [src2], 8
+	subs	limit, limit, 8
+	ccmp	data1, data2, 0, hi  /* NZCV = 0b0000.  */
+	b.eq	.Lloop8
 
-#ifndef	__AARCH64EB__
-	rev	diff, diff
+	cmp	data1, data2
+	bne	.Lreturn
+
+	/* Compare last 1-8 bytes using unaligned access.  */
+.Llast_bytes:
+	ldr	data1, [src1, limit]
+	ldr	data2, [src2, limit]
+
+	/* Compare data bytes and set return value to 0, -1 or 1.  */
+.Lreturn:
+#ifndef __AARCH64EB__
 	rev	data1, data1
 	rev	data2, data2
 #endif
-	/* The MS-non-zero bit of DIFF marks either the first bit
-	   that is different, or the end of the significant data.
-	   Shifting left now will bring the critical information into the
-	   top bits.  */
-	clz	pos, diff
-	lsl	data1, data1, pos
-	lsl	data2, data2, pos
-	/* But we need to zero-extend (char is unsigned) the value and then
-	   perform a signed 32-bit subtraction.  */
-	lsr	data1, data1, #56
-	sub	result, data1, data2, lsr #56
-	ret
+	cmp     data1, data2
+.Lret_eq:
+	cset	result, ne
+	cneg	result, result, lo
+        ret
 
-.Lmutual_align:
-	/* Sources are mutually aligned, but are not currently at an
-	   alignment boundary.  Round down the addresses and then mask off
-	   the bytes that precede the start point.  */
-	bic	src1, src1, #7
-	bic	src2, src2, #7
-	add	limit, limit, tmp1	/* Adjust the limit for the extra.  */
-	lsl	tmp1, tmp1, #3		/* Bytes beyond alignment -> bits.  */
-	ldr	data1, [src1], #8
-	neg	tmp1, tmp1		/* Bits to alignment -64.  */
-	ldr	data2, [src2], #8
-	mov	tmp2, #~0
-#ifdef __AARCH64EB__
-	/* Big-endian.  Early bytes are at MSB.  */
-	lsl	tmp2, tmp2, tmp1	/* Shift (tmp1 & 63).  */
-#else
-	/* Little-endian.  Early bytes are at LSB.  */
-	lsr	tmp2, tmp2, tmp1	/* Shift (tmp1 & 63).  */
-#endif
-	add	limit_wd, limit, #7
-	orr	data1, data1, tmp2
-	orr	data2, data2, tmp2
-	lsr	limit_wd, limit_wd, #3
-	b	.Lstart_realigned
-
-.Lret0:
-	mov	result, #0
-	ret
-
-	.p2align 6
-.Lmisaligned8:
-	sub	limit, limit, #1
-1:
-	/* Perhaps we can do better than this.  */
-	ldrb	data1w, [src1], #1
-	ldrb	data2w, [src2], #1
-	subs	limit, limit, #1
-	ccmp	data1w, data2w, #0, cs	/* NZCV = 0b0000.  */
-	b.eq	1b
-	sub	result, data1, data2
+	.p2align 4
+	/* Compare up to 8 bytes.  Limit is [-8..-1].  */
+.Lless8:
+	adds	limit, limit, 4
+	b.lo	.Lless4
+	ldr	data1w, [src1], 4
+	ldr	data2w, [src2], 4
+	cmp	data1w, data2w
+	b.ne	.Lreturn
+	sub	limit, limit, 4
+.Lless4:
+	adds	limit, limit, 4
+	beq	.Lret_eq
+.Lbyte_loop:
+	ldrb	data1w, [src1], 1
+	ldrb	data2w, [src2], 1
+	subs	limit, limit, 1
+	ccmp	data1w, data2w, 0, ne	/* NZCV = 0b0000.  */
+	b.eq	.Lbyte_loop
+	sub	result, data1w, data2w
 	ret
 END(memcmp)
diff --git a/libc/arch-arm64/include/machine/fenv.h b/libc/arch-arm64/include/machine/fenv.h
deleted file mode 100644
index a8568b8..0000000
--- a/libc/arch-arm64/include/machine/fenv.h
+++ /dev/null
@@ -1,102 +0,0 @@
-/*-
- * Copyright (c) 2004-2005 David Schultz <das@FreeBSD.ORG>
- * 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.
- *
- * THIS SOFTWARE IS PROVIDED BY THE AUTHOR 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 AUTHOR 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.
- *
- * $FreeBSD: src/lib/msun/arm/fenv.h,v 1.5 2005/03/16 19:03:45 das Exp $
- */
-
-/*
- * In ARMv8, AArch64 state, floating-point operation is controlled by:
- *
- *  * FPCR - 32Bit Floating-Point Control Register:
- *      * [31:27] - Reserved, Res0;
- *      * [26]    - AHP, Alternative half-precision control bit;
- *      * [25]    - DN, Default NaN mode control bit;
- *      * [24]    - FZ, Flush-to-zero mode control bit;
- *      * [23:22] - RMode, Rounding Mode control field:
- *            * 00  - Round to Nearest (RN) mode;
- *            * 01  - Round towards Plus Infinity (RP) mode;
- *            * 10  - Round towards Minus Infinity (RM) mode;
- *            * 11  - Round towards Zero (RZ) mode.
- *      * [21:20] - Stride, ignored during AArch64 execution;
- *      * [19]    - Reserved, Res0;
- *      * [18:16] - Len, ignored during AArch64 execution;
- *      * [15]    - IDE, Input Denormal exception trap;
- *      * [14:13] - Reserved, Res0;
- *      * [12]    - IXE, Inexact exception trap;
- *      * [11]    - UFE, Underflow exception trap;
- *      * [10]    - OFE, Overflow exception trap;
- *      * [9]     - DZE, Division by Zero exception;
- *      * [8]     - IOE, Invalid Operation exception;
- *      * [7:0]   - Reserved, Res0.
- *
- *  * FPSR - 32Bit Floating-Point Status Register:
- *      * [31]    - N, Negative condition flag for AArch32 (AArch64 sets PSTATE.N);
- *      * [30]    - Z, Zero condition flag for AArch32 (AArch64 sets PSTATE.Z);
- *      * [29]    - C, Carry conditon flag for AArch32 (AArch64 sets PSTATE.C);
- *      * [28]    - V, Overflow conditon flag for AArch32 (AArch64 sets PSTATE.V);
- *      * [27]    - QC, Cumulative saturation bit, Advanced SIMD only;
- *      * [26:8]  - Reserved, Res0;
- *      * [7]     - IDC, Input Denormal cumulative exception;
- *      * [6:5]   - Reserved, Res0;
- *      * [4]     - IXC, Inexact cumulative exception;
- *      * [3]     - UFC, Underflow cumulative exception;
- *      * [2]     - OFC, Overflow cumulative exception;
- *      * [1]     - DZC, Division by Zero cumulative exception;
- *      * [0]     - IOC, Invalid Operation cumulative exception.
- */
-
-#ifndef _ARM64_FENV_H_
-#define _ARM64_FENV_H_
-
-#include <sys/types.h>
-
-__BEGIN_DECLS
-
-typedef struct {
-  __uint32_t __control;     /* FPCR, Floating-point Control Register */
-  __uint32_t __status;      /* FPSR, Floating-point Status Register */
-} fenv_t;
-
-typedef __uint32_t fexcept_t;
-
-/* Exception flags. */
-#define FE_INVALID    0x01
-#define FE_DIVBYZERO  0x02
-#define FE_OVERFLOW   0x04
-#define FE_UNDERFLOW  0x08
-#define FE_INEXACT    0x10
-#define FE_DENORMAL   0x80
-#define FE_ALL_EXCEPT (FE_DIVBYZERO | FE_INEXACT | FE_INVALID | \
-                       FE_OVERFLOW | FE_UNDERFLOW | FE_DENORMAL)
-
-/* Rounding modes. */
-#define FE_TONEAREST  0x0
-#define FE_UPWARD     0x1
-#define FE_DOWNWARD   0x2
-#define FE_TOWARDZERO 0x3
-
-__END_DECLS
-
-#endif /* !_ARM64_FENV_H_ */
diff --git a/libc/arch-arm64/syscalls/getrandom.S b/libc/arch-arm64/syscalls/getrandom.S
new file mode 100644
index 0000000..c8fe41f
--- /dev/null
+++ b/libc/arch-arm64/syscalls/getrandom.S
@@ -0,0 +1,14 @@
+/* Generated by gensyscalls.py. Do not edit. */
+
+#include <private/bionic_asm.h>
+
+ENTRY(getrandom)
+    mov     x8, __NR_getrandom
+    svc     #0
+
+    cmn     x0, #(MAX_ERRNO + 1)
+    cneg    x0, x0, hi
+    b.hi    __set_errno_internal
+
+    ret
+END(getrandom)
diff --git a/libc/arch-common/bionic/__dso_handle.h b/libc/arch-common/bionic/__dso_handle.h
index d4bff77..fa40060 100644
--- a/libc/arch-common/bionic/__dso_handle.h
+++ b/libc/arch-common/bionic/__dso_handle.h
@@ -28,11 +28,6 @@
 
 
 #ifndef CRT_LEGACY_WORKAROUND
-__attribute__ ((visibility ("hidden")))
+__attribute__((__visibility__("hidden")))
 #endif
-#ifdef __aarch64__
-__attribute__ ((section (".data")))
-#else
-__attribute__ ((section (".bss")))
-#endif
-void *__dso_handle = (void *) 0;
+void* __dso_handle = (void*) 0;
diff --git a/libc/arch-common/bionic/__dso_handle_so.h b/libc/arch-common/bionic/__dso_handle_so.h
index fab328a..e2c26b6 100644
--- a/libc/arch-common/bionic/__dso_handle_so.h
+++ b/libc/arch-common/bionic/__dso_handle_so.h
@@ -26,11 +26,4 @@
  * SUCH DAMAGE.
  */
 
-
-__attribute__ ((visibility ("hidden")))
-__attribute__ ((section (".data")))
-#ifdef __aarch64__
-void *__dso_handle = (void *) 0;
-#else
-void *__dso_handle = &__dso_handle;
-#endif
+__attribute__((__visibility__("hidden"))) void* __dso_handle = &__dso_handle;
diff --git a/libc/arch-mips/bionic/__bionic_clone.S b/libc/arch-mips/bionic/__bionic_clone.S
index a3cacd1..b6056f2 100644
--- a/libc/arch-mips/bionic/__bionic_clone.S
+++ b/libc/arch-mips/bionic/__bionic_clone.S
@@ -33,39 +33,39 @@
 // pid_t __bionic_clone(int flags, void* child_stack, pid_t* parent_tid, void* tls, pid_t* child_tid, int (*fn)(void*), void* arg);
 ENTRY_PRIVATE(__bionic_clone)
         .set	noreorder
-        .cpload t9
+        .cpload $t9
         .set	reorder
 
 	# set up child stack
-	subu	a1,16
-	lw	t0,20(sp)     # fn
-	lw	t1,24(sp)     # arg
-	sw	t0,0(a1)	# fn
-	sw	t1,4(a1)	# arg
+	subu	$a1,16
+	lw	$t0,20($sp)     # fn
+	lw	$t1,24($sp)     # arg
+	sw	$t0,0($a1)	# fn
+	sw	$t1,4($a1)	# arg
 
 	# remainder of arguments are correct for clone system call
-        li	v0,__NR_clone
+        li	$v0,__NR_clone
         syscall
 
-        bnez	a3,.L__error_bc
+        bnez	$a3,.L__error_bc
 
-        beqz	v0,.L__thread_start_bc
+        beqz	$v0,.L__thread_start_bc
 
-        j ra
+        j $ra
 
 .L__thread_start_bc:
         # Clear return address in child so we don't unwind further.
-        li      ra,0
+        li      $ra,0
 
-        lw	a0,0(sp)	#  fn
-        lw	a1,4(sp)	#  arg
+        lw	$a0,0($sp)	#  fn
+        lw	$a1,4($sp)	#  arg
 
 	# void __start_thread(int (*func)(void*), void *arg)
-        la	t9,__start_thread
-        j	t9
+        la	$t9,__start_thread
+        j	$t9
 
 .L__error_bc:
-	move	a0,v0
-	la	t9,__set_errno_internal
-	j	t9
+	move	$a0,$v0
+	la	$t9,__set_errno_internal
+	j	$t9
 END(__bionic_clone)
diff --git a/libc/arch-mips/bionic/_exit_with_stack_teardown.S b/libc/arch-mips/bionic/_exit_with_stack_teardown.S
index 7d47160..566b1c8 100644
--- a/libc/arch-mips/bionic/_exit_with_stack_teardown.S
+++ b/libc/arch-mips/bionic/_exit_with_stack_teardown.S
@@ -30,12 +30,12 @@
 
 // void _exit_with_stack_teardown(void* stackBase, size_t stackSize)
 ENTRY_PRIVATE(_exit_with_stack_teardown)
-	li	v0, __NR_munmap
+	li	$v0, __NR_munmap
 	syscall
 	// If munmap failed, we ignore the failure and exit anyway.
 
-	li	a0, 0
-	li	v0, __NR_exit
+	li	$a0, 0
+	li	$v0, __NR_exit
 	syscall
         // The exit syscall does not return.
 END(_exit_with_stack_teardown)
diff --git a/libc/arch-mips/bionic/setjmp.S b/libc/arch-mips/bionic/setjmp.S
index 3b4ff55..ffe3665 100644
--- a/libc/arch-mips/bionic/setjmp.S
+++ b/libc/arch-mips/bionic/setjmp.S
@@ -119,7 +119,6 @@
  */
 
 #include <private/bionic_asm.h>
-#include <machine/setjmp.h>
 
 /* jmpbuf is declared to users as an array of longs, which is only
  * 4-byte aligned in 32-bit builds.  The Mips jmpbuf begins with a
@@ -161,10 +160,6 @@
 #define	SC_TOTAL_BYTES	(SC_FPREGS_OFFSET + SC_FPREGS_BYTES)
 #define	SC_TOTAL_LONGS	(SC_TOTAL_BYTES/REGSZ)
 
-#if SC_TOTAL_LONGS > _JBLEN
-#error _JBLEN is too small
-#endif
-
 #define USE_CHECKSUM 1
 
 .macro m_mangle_reg_and_store reg, cookie, temp, offset
@@ -203,138 +198,142 @@
 GPOFF= FRAMESZ-2*REGSZ
 RAOFF= FRAMESZ-1*REGSZ
 
-NON_LEAF(sigsetjmp, FRAMESZ, ra)
+NON_LEAF(sigsetjmp, FRAMESZ, $ra)
+__BIONIC_WEAK_ASM_FOR_NATIVE_BRIDGE(sigsetjmp)
 	.mask	0x80000000, RAOFF
-	PTR_SUBU sp, FRAMESZ			# allocate stack frame
+	PTR_SUBU $sp, FRAMESZ			# allocate stack frame
 	SETUP_GP64(GPOFF, sigsetjmp)
 	SAVE_GP(GPOFF)
 	.set	reorder
 
 setjmp_common:
 #ifndef __LP64__
-	li	t0, ~7
-	and	a0, t0				# round jmpbuf addr DOWN to 8-byte boundary
+	li	$t0, ~7
+	and	$a0, $t0				# round jmpbuf addr DOWN to 8-byte boundary
 #endif
-	REG_S	ra, RAOFF(sp)			# spill state
-	REG_S	a0, A0OFF(sp)
+	REG_S	$ra, RAOFF($sp)			# spill state
+	REG_S	$a0, A0OFF($sp)
 
 	# get the cookie and store it along with the signal flag.
-	move	a0, a1
+	move	$a0, $a1
 	jal	__bionic_setjmp_cookie_get
-	REG_L	a0, A0OFF(sp)
+	REG_L	$a0, A0OFF($sp)
 
-	REG_S	v0, SC_FLAG_OFFSET(a0)		# save cookie and savesigs flag
-	andi	t0, v0, 1			# extract savesigs flag
+	REG_S	$v0, SC_FLAG_OFFSET($a0)		# save cookie and savesigs flag
+	andi	$t0, $v0, 1			# extract savesigs flag
 
-	beqz	t0, 1f				# do saving of signal mask?
+	beqz	$t0, 1f				# do saving of signal mask?
 
 	# call sigprocmask(int how ignored, sigset_t* null, sigset_t* SC_MASK(a0)):
-	LA	a2, SC_MASK_OFFSET(a0)		# gets current signal mask
-	li	a0, 0				# how; ignored when new mask is null
-	li	a1, 0				# null new mask
+	LA	$a2, SC_MASK_OFFSET($a0)		# gets current signal mask
+	li	$a0, 0				# how; ignored when new mask is null
+	li	$a1, 0				# null new mask
 	jal	sigprocmask			# get current signal mask
-	REG_L	a0, A0OFF(sp)
+	REG_L	$a0, A0OFF($sp)
 1:
-	REG_L	gp, GPOFF(sp)			# restore spills
-	REG_L	ra, RAOFF(sp)
-	REG_L	t0, SC_FLAG_OFFSET(a0)		# move cookie to temp reg
+	REG_L	$gp, GPOFF($sp)			# restore spills
+	REG_L	$ra, RAOFF($sp)
+	REG_L	$t0, SC_FLAG_OFFSET($a0)		# move cookie to temp reg
 
 	# callee-saved long-sized regs:
-	PTR_ADDU v1, sp, FRAMESZ		# save orig sp
+	PTR_ADDU $v1, $sp, FRAMESZ		# save orig sp
 
 	# m_mangle_reg_and_store reg, cookie, temp, offset
-	m_mangle_reg_and_store	ra, t0, t1, SC_REGS+0*REGSZ(a0)
-	m_mangle_reg_and_store	s0, t0, t2, SC_REGS+1*REGSZ(a0)
-	m_mangle_reg_and_store	s1, t0, t3, SC_REGS+2*REGSZ(a0)
-	m_mangle_reg_and_store	s2, t0, t1, SC_REGS+3*REGSZ(a0)
-	m_mangle_reg_and_store	s3, t0, t2, SC_REGS+4*REGSZ(a0)
-	m_mangle_reg_and_store	s4, t0, t3, SC_REGS+5*REGSZ(a0)
-	m_mangle_reg_and_store	s5, t0, t1, SC_REGS+6*REGSZ(a0)
-	m_mangle_reg_and_store	s6, t0, t2, SC_REGS+7*REGSZ(a0)
-	m_mangle_reg_and_store	s7, t0, t3, SC_REGS+8*REGSZ(a0)
-	m_mangle_reg_and_store	s8, t0, t1, SC_REGS+9*REGSZ(a0)
-	m_mangle_reg_and_store	gp, t0, t2, SC_REGS+10*REGSZ(a0)
-	m_mangle_reg_and_store	v1, t0, t3, SC_REGS+11*REGSZ(a0)
+	m_mangle_reg_and_store	$ra, $t0, $t1, SC_REGS+0*REGSZ($a0)
+	m_mangle_reg_and_store	$s0, $t0, $t2, SC_REGS+1*REGSZ($a0)
+	m_mangle_reg_and_store	$s1, $t0, $t3, SC_REGS+2*REGSZ($a0)
+	m_mangle_reg_and_store	$s2, $t0, $t1, SC_REGS+3*REGSZ($a0)
+	m_mangle_reg_and_store	$s3, $t0, $t2, SC_REGS+4*REGSZ($a0)
+	m_mangle_reg_and_store	$s4, $t0, $t3, SC_REGS+5*REGSZ($a0)
+	m_mangle_reg_and_store	$s5, $t0, $t1, SC_REGS+6*REGSZ($a0)
+	m_mangle_reg_and_store	$s6, $t0, $t2, SC_REGS+7*REGSZ($a0)
+	m_mangle_reg_and_store	$s7, $t0, $t3, SC_REGS+8*REGSZ($a0)
+	m_mangle_reg_and_store	$s8, $t0, $t1, SC_REGS+9*REGSZ($a0)
+	m_mangle_reg_and_store	$gp, $t0, $t2, SC_REGS+10*REGSZ($a0)
+	m_mangle_reg_and_store	$v1, $t0, $t3, SC_REGS+11*REGSZ($a0)
 
-	cfc1	v0, $31
+	cfc1	$v0, $31
 
 #ifdef __LP64__
 	# callee-saved fp regs on mips n64 ABI are $f24..$f31
-	s.d	$f24, SC_FPREGS+0*REGSZ_FP(a0)
-	s.d	$f25, SC_FPREGS+1*REGSZ_FP(a0)
-	s.d	$f26, SC_FPREGS+2*REGSZ_FP(a0)
-	s.d	$f27, SC_FPREGS+3*REGSZ_FP(a0)
-	s.d	$f28, SC_FPREGS+4*REGSZ_FP(a0)
-	s.d	$f29, SC_FPREGS+5*REGSZ_FP(a0)
-	s.d	$f30, SC_FPREGS+6*REGSZ_FP(a0)
-	s.d	$f31, SC_FPREGS+7*REGSZ_FP(a0)
+	s.d	$f24, SC_FPREGS+0*REGSZ_FP($a0)
+	s.d	$f25, SC_FPREGS+1*REGSZ_FP($a0)
+	s.d	$f26, SC_FPREGS+2*REGSZ_FP($a0)
+	s.d	$f27, SC_FPREGS+3*REGSZ_FP($a0)
+	s.d	$f28, SC_FPREGS+4*REGSZ_FP($a0)
+	s.d	$f29, SC_FPREGS+5*REGSZ_FP($a0)
+	s.d	$f30, SC_FPREGS+6*REGSZ_FP($a0)
+	s.d	$f31, SC_FPREGS+7*REGSZ_FP($a0)
 #else
 	# callee-saved fp regs on mips o32 ABI are
 	#   the even-numbered double fp regs $f20,$f22,...$f30
-	s.d	$f20, SC_FPREGS+0*REGSZ_FP(a0)
-	s.d	$f22, SC_FPREGS+1*REGSZ_FP(a0)
-	s.d	$f24, SC_FPREGS+2*REGSZ_FP(a0)
-	s.d	$f26, SC_FPREGS+3*REGSZ_FP(a0)
-	s.d	$f28, SC_FPREGS+4*REGSZ_FP(a0)
-	s.d	$f30, SC_FPREGS+5*REGSZ_FP(a0)
+	s.d	$f20, SC_FPREGS+0*REGSZ_FP($a0)
+	s.d	$f22, SC_FPREGS+1*REGSZ_FP($a0)
+	s.d	$f24, SC_FPREGS+2*REGSZ_FP($a0)
+	s.d	$f26, SC_FPREGS+3*REGSZ_FP($a0)
+	s.d	$f28, SC_FPREGS+4*REGSZ_FP($a0)
+	s.d	$f30, SC_FPREGS+5*REGSZ_FP($a0)
 #endif
-	sw	v0, SC_FPSR_OFFSET(a0)
+	sw	$v0, SC_FPSR_OFFSET($a0)
 #if USE_CHECKSUM
-	m_calculate_checksum t0, a0, t1
-	REG_S t0, SC_CKSUM_OFFSET(a0)
+	m_calculate_checksum $t0, $a0, $t1
+	REG_S $t0, SC_CKSUM_OFFSET($a0)
 #endif
-	move	v0, zero
+	move	$v0, $zero
 	RESTORE_GP64
-	PTR_ADDU sp, FRAMESZ
-	j	ra
+	PTR_ADDU $sp, FRAMESZ
+	j	$ra
 END(sigsetjmp)
 
 
 # Alternate entry points:
 
-NON_LEAF(setjmp, FRAMESZ, ra)
+NON_LEAF(setjmp, FRAMESZ, $ra)
+__BIONIC_WEAK_ASM_FOR_NATIVE_BRIDGE(setjmp)
 	.mask	0x80000000, RAOFF
-	PTR_SUBU sp, FRAMESZ
+	PTR_SUBU $sp, FRAMESZ
 	SETUP_GP64(GPOFF, setjmp)		# can't share sigsetjmp's gp code
 	SAVE_GP(GPOFF)
 	.set	reorder
 
-	li	a1, 1				# save/restore signals state
+	li	$a1, 1				# save/restore signals state
 	b	setjmp_common			# tail call
 END(setjmp)
 
 
-NON_LEAF(_setjmp, FRAMESZ, ra)
+NON_LEAF(_setjmp, FRAMESZ, $ra)
+__BIONIC_WEAK_ASM_FOR_NATIVE_BRIDGE(_setjmp)
 	.mask	0x80000000, RAOFF
-	PTR_SUBU sp, FRAMESZ
+	PTR_SUBU $sp, FRAMESZ
 	SETUP_GP64(GPOFF, _setjmp)		# can't share sigsetjmp's gp code
 	SAVE_GP(GPOFF)
 	.set	reorder
 
-	li	a1, 0				# don't save/restore signals
+	li	$a1, 0				# don't save/restore signals
 	b	setjmp_common			# tail call
 END(_setjmp)
 
 
-NON_LEAF(siglongjmp, FRAMESZ, ra)
+NON_LEAF(siglongjmp, FRAMESZ, $ra)
+__BIONIC_WEAK_ASM_FOR_NATIVE_BRIDGE(siglongjmp)
 	.mask	0x80000000, RAOFF
-	PTR_SUBU sp, FRAMESZ
+	PTR_SUBU $sp, FRAMESZ
 	SETUP_GP64(GPOFF, siglongjmp)
 	SAVE_GP(GPOFF)
 	.set	reorder
 
 #ifndef __LP64__
-	li	t0, ~7
-	and	a0, t0				# round jmpbuf addr DOWN to 8-byte boundary
+	li	$t0, ~7
+	and	$a0, $t0				# round jmpbuf addr DOWN to 8-byte boundary
 #endif
 
-	move	s1, a1				# temp spill
-	move	s0, a0
+	move	$s1, $a1				# temp spill
+	move	$s0, $a0
 
 #if USE_CHECKSUM
-	m_calculate_checksum t0, s0, s2
-	REG_L	s2, SC_CKSUM_OFFSET(s0)
-	beq	t0, s2, 0f
+	m_calculate_checksum $t0, $s0, $s2
+	REG_L	$s2, SC_CKSUM_OFFSET($s0)
+	beq	$t0, $s2, 0f
 	nop
 	jal	__bionic_setjmp_checksum_mismatch
 	nop
@@ -342,76 +341,78 @@
 #endif
 
 	# extract savesigs flag
-	REG_L	s2, SC_FLAG_OFFSET(s0)
-	andi	t0, s2, 1
-	beqz	t0, 1f				# restore signal mask?
+	REG_L	$s2, SC_FLAG_OFFSET($s0)
+	andi	$t0, $s2, 1
+	beqz	$t0, 1f				# restore signal mask?
 
 	# call sigprocmask(int how SIG_SETMASK, sigset_t* SC_MASK(a0), sigset_t* null):
-	LA	a1, SC_MASK_OFFSET(s0)		# signals being restored
-	li	a0, 3				# mips SIG_SETMASK
-	li	a2, 0				# null
+	LA	$a1, SC_MASK_OFFSET($s0)		# signals being restored
+	li	$a0, 3				# mips SIG_SETMASK
+	li	$a2, 0				# null
 	jal	sigprocmask			# restore signal mask
 1:
-	move	t0, s2				# get cookie to temp reg
-	move	a1, s1
-	move	a0, s0
+	move	$t0, $s2				# get cookie to temp reg
+	move	$a1, $s1
+	move	$a0, $s0
 
 	# callee-saved long-sized regs:
 
 	# m_unmangle_reg_and_load reg, cookie, temp, offset
 	# don't restore gp yet, old value is needed for cookie_check call
-	m_unmangle_reg_and_load ra, t0, t1, SC_REGS+0*REGSZ(a0)
-	m_unmangle_reg_and_load s0, t0, t2, SC_REGS+1*REGSZ(a0)
-	m_unmangle_reg_and_load s1, t0, t3, SC_REGS+2*REGSZ(a0)
-	m_unmangle_reg_and_load s2, t0, t1, SC_REGS+3*REGSZ(a0)
-	m_unmangle_reg_and_load s3, t0, t2, SC_REGS+4*REGSZ(a0)
-	m_unmangle_reg_and_load s4, t0, t3, SC_REGS+5*REGSZ(a0)
-	m_unmangle_reg_and_load s5, t0, t1, SC_REGS+6*REGSZ(a0)
-	m_unmangle_reg_and_load s6, t0, t2, SC_REGS+7*REGSZ(a0)
-	m_unmangle_reg_and_load s7, t0, t3, SC_REGS+8*REGSZ(a0)
-	m_unmangle_reg_and_load s8, t0, t1, SC_REGS+9*REGSZ(a0)
-	m_unmangle_reg_and_load v1, t0, t2, SC_REGS+10*REGSZ(a0)
-	m_unmangle_reg_and_load sp, t0, t3, SC_REGS+11*REGSZ(a0)
+	m_unmangle_reg_and_load $ra, $t0, $t1, SC_REGS+0*REGSZ($a0)
+	m_unmangle_reg_and_load $s0, $t0, $t2, SC_REGS+1*REGSZ($a0)
+	m_unmangle_reg_and_load $s1, $t0, $t3, SC_REGS+2*REGSZ($a0)
+	m_unmangle_reg_and_load $s2, $t0, $t1, SC_REGS+3*REGSZ($a0)
+	m_unmangle_reg_and_load $s3, $t0, $t2, SC_REGS+4*REGSZ($a0)
+	m_unmangle_reg_and_load $s4, $t0, $t3, SC_REGS+5*REGSZ($a0)
+	m_unmangle_reg_and_load $s5, $t0, $t1, SC_REGS+6*REGSZ($a0)
+	m_unmangle_reg_and_load $s6, $t0, $t2, SC_REGS+7*REGSZ($a0)
+	m_unmangle_reg_and_load $s7, $t0, $t3, SC_REGS+8*REGSZ($a0)
+	m_unmangle_reg_and_load $s8, $t0, $t1, SC_REGS+9*REGSZ($a0)
+	m_unmangle_reg_and_load $v1, $t0, $t2, SC_REGS+10*REGSZ($a0)
+	m_unmangle_reg_and_load $sp, $t0, $t3, SC_REGS+11*REGSZ($a0)
 
-	lw	v0, SC_FPSR_OFFSET(a0)
-	ctc1	v0, $31			# restore old fr mode before fp values
+	lw	$v0, SC_FPSR_OFFSET($a0)
+	ctc1	$v0, $31			# restore old fr mode before fp values
 #ifdef __LP64__
 	# callee-saved fp regs on mips n64 ABI are $f24..$f31
-	l.d	$f24, SC_FPREGS+0*REGSZ_FP(a0)
-	l.d	$f25, SC_FPREGS+1*REGSZ_FP(a0)
-	l.d	$f26, SC_FPREGS+2*REGSZ_FP(a0)
-	l.d	$f27, SC_FPREGS+3*REGSZ_FP(a0)
-	l.d	$f28, SC_FPREGS+4*REGSZ_FP(a0)
-	l.d	$f29, SC_FPREGS+5*REGSZ_FP(a0)
-	l.d	$f30, SC_FPREGS+6*REGSZ_FP(a0)
-	l.d	$f31, SC_FPREGS+7*REGSZ_FP(a0)
+	l.d	$f24, SC_FPREGS+0*REGSZ_FP($a0)
+	l.d	$f25, SC_FPREGS+1*REGSZ_FP($a0)
+	l.d	$f26, SC_FPREGS+2*REGSZ_FP($a0)
+	l.d	$f27, SC_FPREGS+3*REGSZ_FP($a0)
+	l.d	$f28, SC_FPREGS+4*REGSZ_FP($a0)
+	l.d	$f29, SC_FPREGS+5*REGSZ_FP($a0)
+	l.d	$f30, SC_FPREGS+6*REGSZ_FP($a0)
+	l.d	$f31, SC_FPREGS+7*REGSZ_FP($a0)
 #else
 	# callee-saved fp regs on mips o32 ABI are
 	#   the even-numbered double fp regs $f20,$f22,...$f30
-	l.d	$f20, SC_FPREGS+0*REGSZ_FP(a0)
-	l.d	$f22, SC_FPREGS+1*REGSZ_FP(a0)
-	l.d	$f24, SC_FPREGS+2*REGSZ_FP(a0)
-	l.d	$f26, SC_FPREGS+3*REGSZ_FP(a0)
-	l.d	$f28, SC_FPREGS+4*REGSZ_FP(a0)
-	l.d	$f30, SC_FPREGS+5*REGSZ_FP(a0)
+	l.d	$f20, SC_FPREGS+0*REGSZ_FP($a0)
+	l.d	$f22, SC_FPREGS+1*REGSZ_FP($a0)
+	l.d	$f24, SC_FPREGS+2*REGSZ_FP($a0)
+	l.d	$f26, SC_FPREGS+3*REGSZ_FP($a0)
+	l.d	$f28, SC_FPREGS+4*REGSZ_FP($a0)
+	l.d	$f30, SC_FPREGS+5*REGSZ_FP($a0)
 #endif
 
 	# check cookie
-	PTR_SUBU sp, FRAMESZ
-	REG_S	v1, GPOFF(sp)
-	REG_S	ra, RAOFF(sp)
-	REG_S	a1, A1OFF(sp)
-	move	a0, t0
+	PTR_SUBU $sp, FRAMESZ
+	REG_S	$v1, GPOFF($sp)
+	REG_S	$ra, RAOFF($sp)
+	REG_S	$a1, A1OFF($sp)
+	move	$a0, $t0
 	jal	__bionic_setjmp_cookie_check
-	REG_L	gp, GPOFF(sp)
-	REG_L	ra, RAOFF(sp)
-	REG_L	a1, A1OFF(sp)
-	PTR_ADDU sp, FRAMESZ
+	REG_L	$gp, GPOFF($sp)
+	REG_L	$ra, RAOFF($sp)
+	REG_L	$a1, A1OFF($sp)
+	PTR_ADDU $sp, FRAMESZ
 
-	sltiu	t0, a1, 1		# never return 0!
-	xor	v0, a1, t0
-	j	ra			# return to setjmp call site
+	sltiu	$t0, $a1, 1		# never return 0!
+	xor	$v0, $a1, $t0
+	j	$ra			# return to setjmp call site
 END(siglongjmp)
 
 ALIAS_SYMBOL(longjmp, siglongjmp)
+__BIONIC_WEAK_ASM_FOR_NATIVE_BRIDGE(longjmp)
 ALIAS_SYMBOL(_longjmp, siglongjmp)
+__BIONIC_WEAK_ASM_FOR_NATIVE_BRIDGE(_longjmp)
diff --git a/libc/arch-mips/bionic/syscall.S b/libc/arch-mips/bionic/syscall.S
index 5fed0ac..857bbab 100644
--- a/libc/arch-mips/bionic/syscall.S
+++ b/libc/arch-mips/bionic/syscall.S
@@ -36,26 +36,26 @@
 
 ENTRY(syscall)
     .set noreorder
-    .cpload t9
-    move    v0, a0
-    move    a0, a1
-    move    a1, a2
-    move    a2, a3
-    lw      a3, 16(sp)
-    lw      t0, 20(sp)
-    lw      t1, 24(sp)
-    subu    sp, STACKSIZE
-    sw      t0, 16(sp)
-    sw      t1, 20(sp)
+    .cpload $t9
+    move    $v0, $a0
+    move    $a0, $a1
+    move    $a1, $a2
+    move    $a2, $a3
+    lw      $a3, 16($sp)
+    lw      $t0, 20($sp)
+    lw      $t1, 24($sp)
+    subu    $sp, STACKSIZE
+    sw      $t0, 16($sp)
+    sw      $t1, 20($sp)
     syscall
-    addu    sp, STACKSIZE
-    bnez    a3, 1f
-    move    a0, v0
-    j       ra
+    addu    $sp, STACKSIZE
+    bnez    $a3, 1f
+    move    $a0, $v0
+    j       $ra
     nop
 1:
-    la      t9,__set_errno_internal
-    j       t9
+    la      $t9, __set_errno_internal
+    j       $t9
     nop
     .set reorder
 END(syscall)
diff --git a/libc/arch-mips/bionic/vfork.S b/libc/arch-mips/bionic/vfork.S
index 7ccf70b..c4f67c6 100644
--- a/libc/arch-mips/bionic/vfork.S
+++ b/libc/arch-mips/bionic/vfork.S
@@ -34,33 +34,34 @@
 #define SIGCHLD 18
 
 ENTRY(vfork)
+__BIONIC_WEAK_ASM_FOR_NATIVE_BRIDGE(vfork)
 	.set	noreorder
-	.cpload	t9
+	.cpload	$t9
 
 	// __get_tls()[TLS_SLOT_THREAD_ID]->cached_pid_ = 0
 	.set	push
 	.set	mips32r2
-	rdhwr	v0, $29			// v0 = tls; kernel trap on mips32r1
+	rdhwr	$v0, $29			// v0 = tls; kernel trap on mips32r1
 	.set	pop
-	lw	v0, REGSZ*1(v0)		// v0 = v0[TLS_SLOT_THREAD_ID ie 1]
-	sw	$0, REGSZ*2+4(v0)	// v0->cached_pid_ = 0
+	lw	$v0, REGSZ*1($v0)		// v0 = v0[TLS_SLOT_THREAD_ID ie 1]
+	sw	$0, REGSZ*2+4($v0)	// v0->cached_pid_ = 0
 
-	li	a0, (CLONE_VM | CLONE_VFORK | SIGCHLD)
-	li	a1, 0
-	li	a2, 0
-	li	a3, 0
-	subu	sp, 8
-	sw	$0, 16(sp)
-	li	v0, __NR_clone
+	li	$a0, (CLONE_VM | CLONE_VFORK | SIGCHLD)
+	li	$a1, 0
+	li	$a2, 0
+	li	$a3, 0
+	subu	$sp, 8
+	sw	$0, 16($sp)
+	li	$v0, __NR_clone
 	syscall
-	addu	sp, 8
-	bnez	a3, 1f
-	 move	a0, v0
+	addu	$sp, 8
+	bnez	$a3, 1f
+	 move	$a0, $v0
 
-	j	ra
+	j	$ra
 	 nop
 1:
-	la	t9, __set_errno_internal
-	j	t9
+	la	$t9, __set_errno_internal
+	j	$t9
 	 nop
 END(vfork)
diff --git a/libc/arch-mips/include/machine/regdef.h b/libc/arch-mips/include/machine/regdef.h
deleted file mode 100644
index 3a7cd68..0000000
--- a/libc/arch-mips/include/machine/regdef.h
+++ /dev/null
@@ -1,99 +0,0 @@
-/*	$OpenBSD: regdef.h,v 1.3 2005/08/07 07:29:44 miod Exp $	*/
-
-/*
- * Copyright (c) 1992, 1993
- *	The Regents of the University of California.  All rights reserved.
- *
- * This code is derived from software contributed to Berkeley by
- * Ralph Campbell. This file is derived from the MIPS RISC
- * Architecture book by Gerry Kane.
- *
- * 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.
- *
- *	@(#)regdef.h	8.1 (Berkeley) 6/10/93
- */
-#ifndef _MIPS_REGDEF_H_
-#define _MIPS_REGDEF_H_
-
-#if (_MIPS_SIM == _ABI64) && !defined(__mips_n64)
-#define __mips_n64 1
-#endif
-#if (_MIPS_SIM == _ABIN32) &&  !defined(__mips_n32)
-#define __mips_n32 1
-#endif
-
-#define zero	$0	/* always zero */
-#define AT	$at	/* assembler temp */
-#define v0	$2	/* return value */
-#define v1	$3
-#define a0	$4	/* argument registers */
-#define a1	$5
-#define a2	$6
-#define a3	$7
-#if defined(__mips_n32) || defined(__mips_n64)
-#define a4	$8	/* expanded register arguments */
-#define a5	$9
-#define a6	$10
-#define a7	$11
-#define ta0	$8	/* alias */
-#define ta1	$9
-#define ta2	$10
-#define ta3	$11
-#define t0	$12	/* temp registers (not saved across subroutine calls) */
-#define t1	$13
-#define t2	$14
-#define t3	$15
-#else
-#define t0	$8	/* temp registers (not saved across subroutine calls) */
-#define t1	$9
-#define t2	$10
-#define t3	$11
-#define t4	$12
-#define t5	$13
-#define t6	$14
-#define t7	$15
-#define ta0	$12	/* alias */
-#define ta1	$13
-#define ta2	$14
-#define ta3	$15
-#endif
-#define s0	$16	/* saved across subroutine calls (callee saved) */
-#define s1	$17
-#define s2	$18
-#define s3	$19
-#define s4	$20
-#define s5	$21
-#define s6	$22
-#define s7	$23
-#define t8	$24	/* two more temp registers */
-#define t9	$25
-#define k0	$26	/* kernel temporary */
-#define k1	$27
-#define gp	$28	/* global pointer */
-#define sp	$29	/* stack pointer */
-#define s8	$30	/* one more callee saved */
-#define ra	$31	/* return address */
-
-#endif /* !_MIPS_REGDEF_H_ */
diff --git a/libc/arch-mips/include/machine/setjmp.h b/libc/arch-mips/include/machine/setjmp.h
deleted file mode 100644
index 4067d51..0000000
--- a/libc/arch-mips/include/machine/setjmp.h
+++ /dev/null
@@ -1,15 +0,0 @@
-/*	$OpenBSD: setjmp.h,v 1.2 2004/08/10 21:10:56 pefo Exp $	*/
-
-/* Public domain */
-
-#ifndef _MIPS_SETJMP_H_
-#define _MIPS_SETJMP_H_
-
-#ifdef __LP64__
-#define	_JBLEN	25	/* size, in 8-byte longs, of a mips64 jmp_buf/sigjmp_buf */
-#else
-#define	_JBLEN	157	/* historical size, in 4-byte longs, of a mips32 jmp_buf */
-			/* actual used size is 34 */
-#endif
-
-#endif /* !_MIPS_SETJMP_H_ */
diff --git a/libc/arch-mips/string/memset.S b/libc/arch-mips/string/memset.S
index 7ea6753..85ba2e9 100644
--- a/libc/arch-mips/string/memset.S
+++ b/libc/arch-mips/string/memset.S
@@ -209,12 +209,12 @@
 LEAF(__memset_chk)
 #endif
 	.set	noreorder
-        sltu    t2, a3, a2
-        beq     t2, zero, memset
+        sltu    $t2, $a3, $a2
+        beq     $t2, $zero, memset
         nop
-        .cpsetup t9, t8, __memset_chk
-        LA      t9, __memset_chk_fail
-        jr      t9
+        .cpsetup $t9, $t8, __memset_chk
+        LA      $t9, __memset_chk_fail
+        jr      $t9
         nop
         .set	reorder
 END(__memset_chk)
@@ -229,41 +229,41 @@
 	.set	noreorder
 /* If the size is less than 2*NSIZE (8 or 16), go to L(lastb).  Regardless of
    size, copy dst pointer to v0 for the return value.  */
-	slti	t2,a2,(2 * NSIZE)
-	bne	t2,zero,L(lastb)
-	move	v0,a0
+	slti	$t2,$a2,(2 * NSIZE)
+	bne	$t2,$zero,L(lastb)
+	move	$v0,$a0
 
 /* If memset value is not zero, we copy it to all the bytes in a 32 or 64
    bit word.  */
-	beq	a1,zero,L(set0)		/* If memset value is zero no smear  */
-	PTR_SUBU a3,zero,a0
+	beq	$a1,$zero,L(set0)		/* If memset value is zero no smear  */
+	PTR_SUBU $a3,$zero,$a0
 	nop
 
 	/* smear byte into 32 or 64 bit word */
 #if ((__mips == 64) || (__mips == 32)) && (__mips_isa_rev >= 2)
 # ifdef USE_DOUBLE
-	dins	a1, a1, 8, 8        /* Replicate fill byte into half-word.  */
-	dins	a1, a1, 16, 16      /* Replicate fill byte into word.       */
-	dins	a1, a1, 32, 32      /* Replicate fill byte into dbl word.   */
+	dins	$a1, $a1, 8, 8        /* Replicate fill byte into half-word.  */
+	dins	$a1, $a1, 16, 16      /* Replicate fill byte into word.       */
+	dins	$a1, $a1, 32, 32      /* Replicate fill byte into dbl word.   */
 # else
-	ins	a1, a1, 8, 8        /* Replicate fill byte into half-word.  */
-	ins	a1, a1, 16, 16      /* Replicate fill byte into word.       */
+	ins	$a1, $a1, 8, 8        /* Replicate fill byte into half-word.  */
+	ins	$a1, $a1, 16, 16      /* Replicate fill byte into word.       */
 # endif
 #else
 # ifdef USE_DOUBLE
-        and     a1,0xff
-	dsll	t2,a1,8
-	or	a1,t2
-	dsll	t2,a1,16
-	or	a1,t2
-	dsll	t2,a1,32
-	or	a1,t2
+        and     $a1,0xff
+	dsll	$t2,$a1,8
+	or	$a1,$t2
+	dsll	$t2,$a1,16
+	or	$a1,$t2
+	dsll	$t2,$a1,32
+	or	$a1,$t2
 # else
-        and     a1,0xff
-	sll	t2,a1,8
-	or	a1,t2
-	sll	t2,a1,16
-	or	a1,t2
+        and     $a1,0xff
+	sll	$t2,$a1,8
+	or	$a1,$t2
+	sll	$t2,$a1,16
+	or	$a1,$t2
 # endif
 #endif
 
@@ -271,16 +271,16 @@
    aligned.  If it is already aligned just jump to L(aligned).  */
 L(set0):
 #ifndef R6_CODE
-	andi	t2,a3,(NSIZE-1)		/* word-unaligned address?          */
-	beq	t2,zero,L(aligned)	/* t2 is the unalignment count      */
-	PTR_SUBU a2,a2,t2
-	C_STHI	a1,0(a0)
-	PTR_ADDU a0,a0,t2
+	andi	$t2,$a3,(NSIZE-1)		/* word-unaligned address?          */
+	beq	$t2,$zero,L(aligned)	/* t2 is the unalignment count      */
+	PTR_SUBU $a2,$a2,$t2
+	C_STHI	$a1,0($a0)
+	PTR_ADDU $a0,$a0,$t2
 #else /* R6_CODE */
-	andi	t2,a0,(NSIZE-1)
-	lapc	t9,L(atable)
-	PTR_LSA	t9,t2,t9,2
-	jrc	t9
+	andi	$t2,$a0,(NSIZE-1)
+	lapc	$t9,L(atable)
+	PTR_LSA	$t9,$t2,$t9,2
+	jrc	$t9
 L(atable):
 	bc	L(aligned)
 # ifdef USE_DOUBLE
@@ -293,24 +293,24 @@
 	bc	L(lb2)
 	bc	L(lb1)
 L(lb7):
-	sb	a1,6(a0)
+	sb	$a1,6($a0)
 L(lb6):
-	sb	a1,5(a0)
+	sb	$a1,5($a0)
 L(lb5):
-	sb	a1,4(a0)
+	sb	$a1,4($a0)
 L(lb4):
-	sb	a1,3(a0)
+	sb	$a1,3($a0)
 L(lb3):
-	sb	a1,2(a0)
+	sb	$a1,2($a0)
 L(lb2):
-	sb	a1,1(a0)
+	sb	$a1,1($a0)
 L(lb1):
-	sb	a1,0(a0)
+	sb	$a1,0($a0)
 
-	li	t9,NSIZE
-	subu	t2,t9,t2
-	PTR_SUBU a2,a2,t2
-	PTR_ADDU a0,a0,t2
+	li	$t9,NSIZE
+	subu	$t2,$t9,$t2
+	PTR_SUBU $a2,$a2,$t2
+	PTR_ADDU $a0,$a0,$t2
 #endif /* R6_CODE */
 
 L(aligned):
@@ -320,11 +320,11 @@
    byte stores into one 8 byte store).  We know there are at least 4 bytes
    left to store or we would have jumped to L(lastb) earlier in the code.  */
 #ifdef DOUBLE_ALIGN
-	andi	t2,a3,4
-	beq	t2,zero,L(double_aligned)
-	PTR_SUBU a2,a2,t2
-	sw	a1,0(a0)
-	PTR_ADDU a0,a0,t2
+	andi	$t2,$a3,4
+	beq	$t2,$zero,L(double_aligned)
+	PTR_SUBU $a2,$a2,$t2
+	sw	$a1,0($a0)
+	PTR_ADDU $a0,$a0,$t2
 L(double_aligned):
 #endif
 
@@ -333,10 +333,10 @@
    chunks are copied and a3 to the dest pointer after all the 64/128 byte
    chunks have been copied.  We will loop, incrementing a0 until it equals
    a3.  */
-	andi	t8,a2,NSIZEDMASK /* any whole 64-byte/128-byte chunks? */
-	beq	a2,t8,L(chkw)	 /* if a2==t8, no 64-byte/128-byte chunks */
-	PTR_SUBU a3,a2,t8	 /* subtract from a2 the reminder */
-	PTR_ADDU a3,a0,a3	 /* Now a3 is the final dst after loop */
+	andi	$t8,$a2,NSIZEDMASK /* any whole 64-byte/128-byte chunks? */
+	beq	$a2,$t8,L(chkw)	 /* if a2==t8, no 64-byte/128-byte chunks */
+	PTR_SUBU $a3,$a2,$t8	 /* subtract from a2 the reminder */
+	PTR_ADDU $a3,$a0,$a3	 /* Now a3 is the final dst after loop */
 
 /* When in the loop we may prefetch with the 'prepare to store' hint,
    in this case the a0+x should not be past the "t0-32" address.  This
@@ -345,68 +345,68 @@
    will use "prefetch hint,128(a0)", so "t0-160" is the limit.  */
 #if defined(USE_PREFETCH) \
     && (PREFETCH_STORE_HINT == PREFETCH_HINT_PREPAREFORSTORE)
-	PTR_ADDU t0,a0,a2		/* t0 is the "past the end" address */
-	PTR_SUBU t9,t0,PREFETCH_LIMIT	/* t9 is the "last safe pref" address */
+	PTR_ADDU $t0,$a0,$a2		/* t0 is the "past the end" address */
+	PTR_SUBU $t9,$t0,PREFETCH_LIMIT	/* t9 is the "last safe pref" address */
 #endif
 #if defined(USE_PREFETCH) \
     && (PREFETCH_STORE_HINT != PREFETCH_HINT_PREPAREFORSTORE)
-	PREFETCH_FOR_STORE (1, a0)
-	PREFETCH_FOR_STORE (2, a0)
-	PREFETCH_FOR_STORE (3, a0)
+	PREFETCH_FOR_STORE (1, $a0)
+	PREFETCH_FOR_STORE (2, $a0)
+	PREFETCH_FOR_STORE (3, $a0)
 #endif
 
 L(loop16w):
 #if defined(USE_PREFETCH) \
     && (PREFETCH_STORE_HINT == PREFETCH_HINT_PREPAREFORSTORE)
-	sltu	v1,t9,a0		/* If a0 > t9 don't use next prefetch */
-	bgtz	v1,L(skip_pref)
+	sltu	$v1,$t9,$a0		/* If a0 > t9 don't use next prefetch */
+	bgtz	$v1,L(skip_pref)
 	nop
 #endif
 #ifndef R6_CODE
-	PREFETCH_FOR_STORE (4, a0)
-	PREFETCH_FOR_STORE (5, a0)
+	PREFETCH_FOR_STORE (4, $a0)
+	PREFETCH_FOR_STORE (5, $a0)
 #else
-	PREFETCH_FOR_STORE (2, a0)
+	PREFETCH_FOR_STORE (2, $a0)
 #endif
 L(skip_pref):
-	C_ST	a1,UNIT(0)(a0)
-	C_ST	a1,UNIT(1)(a0)
-	C_ST	a1,UNIT(2)(a0)
-	C_ST	a1,UNIT(3)(a0)
-	C_ST	a1,UNIT(4)(a0)
-	C_ST	a1,UNIT(5)(a0)
-	C_ST	a1,UNIT(6)(a0)
-	C_ST	a1,UNIT(7)(a0)
-	C_ST	a1,UNIT(8)(a0)
-	C_ST	a1,UNIT(9)(a0)
-	C_ST	a1,UNIT(10)(a0)
-	C_ST	a1,UNIT(11)(a0)
-	C_ST	a1,UNIT(12)(a0)
-	C_ST	a1,UNIT(13)(a0)
-	C_ST	a1,UNIT(14)(a0)
-	C_ST	a1,UNIT(15)(a0)
-	PTR_ADDIU a0,a0,UNIT(16)	/* adding 64/128 to dest */
-	bne	a0,a3,L(loop16w)
+	C_ST	$a1,UNIT(0)($a0)
+	C_ST	$a1,UNIT(1)($a0)
+	C_ST	$a1,UNIT(2)($a0)
+	C_ST	$a1,UNIT(3)($a0)
+	C_ST	$a1,UNIT(4)($a0)
+	C_ST	$a1,UNIT(5)($a0)
+	C_ST	$a1,UNIT(6)($a0)
+	C_ST	$a1,UNIT(7)($a0)
+	C_ST	$a1,UNIT(8)($a0)
+	C_ST	$a1,UNIT(9)($a0)
+	C_ST	$a1,UNIT(10)($a0)
+	C_ST	$a1,UNIT(11)($a0)
+	C_ST	$a1,UNIT(12)($a0)
+	C_ST	$a1,UNIT(13)($a0)
+	C_ST	$a1,UNIT(14)($a0)
+	C_ST	$a1,UNIT(15)($a0)
+	PTR_ADDIU $a0,$a0,UNIT(16)	/* adding 64/128 to dest */
+	bne	$a0,$a3,L(loop16w)
 	nop
-	move	a2,t8
+	move	$a2,$t8
 
 /* Here we have dest word-aligned but less than 64-bytes or 128 bytes to go.
    Check for a 32(64) byte chunk and copy if if there is one.  Otherwise
    jump down to L(chk1w) to handle the tail end of the copy.  */
 L(chkw):
-	andi	t8,a2,NSIZEMASK	/* is there a 32-byte/64-byte chunk.  */
+	andi	$t8,$a2,NSIZEMASK	/* is there a 32-byte/64-byte chunk.  */
 				/* the t8 is the reminder count past 32-bytes */
-	beq	a2,t8,L(chk1w)/* when a2==t8, no 32-byte chunk */
+	beq	$a2,$t8,L(chk1w)/* when a2==t8, no 32-byte chunk */
 	nop
-	C_ST	a1,UNIT(0)(a0)
-	C_ST	a1,UNIT(1)(a0)
-	C_ST	a1,UNIT(2)(a0)
-	C_ST	a1,UNIT(3)(a0)
-	C_ST	a1,UNIT(4)(a0)
-	C_ST	a1,UNIT(5)(a0)
-	C_ST	a1,UNIT(6)(a0)
-	C_ST	a1,UNIT(7)(a0)
-	PTR_ADDIU a0,a0,UNIT(8)
+	C_ST	$a1,UNIT(0)($a0)
+	C_ST	$a1,UNIT(1)($a0)
+	C_ST	$a1,UNIT(2)($a0)
+	C_ST	$a1,UNIT(3)($a0)
+	C_ST	$a1,UNIT(4)($a0)
+	C_ST	$a1,UNIT(5)($a0)
+	C_ST	$a1,UNIT(6)($a0)
+	C_ST	$a1,UNIT(7)($a0)
+	PTR_ADDIU $a0,$a0,UNIT(8)
 
 /* Here we have less than 32(64) bytes to set.  Set up for a loop to
    copy one word (or double word) at a time.  Set a2 to count how many
@@ -414,27 +414,27 @@
    copied and a3 to the dest pointer after all the (d)word chunks have
    been copied.  We will loop, incrementing a0 until a0 equals a3.  */
 L(chk1w):
-	andi	a2,t8,(NSIZE-1)	/* a2 is the reminder past one (d)word chunks */
-	beq	a2,t8,L(lastb)
-	PTR_SUBU a3,t8,a2	/* a3 is count of bytes in one (d)word chunks */
-	PTR_ADDU a3,a0,a3	/* a3 is the dst address after loop */
+	andi	$a2,$t8,(NSIZE-1)	/* a2 is the reminder past one (d)word chunks */
+	beq	$a2,$t8,L(lastb)
+	PTR_SUBU $a3,$t8,$a2	/* a3 is count of bytes in one (d)word chunks */
+	PTR_ADDU $a3,$a0,$a3	/* a3 is the dst address after loop */
 
 /* copying in words (4-byte or 8 byte chunks) */
 L(wordCopy_loop):
-	PTR_ADDIU a0,a0,UNIT(1)
-	bne	a0,a3,L(wordCopy_loop)
-	C_ST	a1,UNIT(-1)(a0)
+	PTR_ADDIU $a0,$a0,UNIT(1)
+	bne	$a0,$a3,L(wordCopy_loop)
+	C_ST	$a1,UNIT(-1)($a0)
 
 /* Copy the last 8 (or 16) bytes */
 L(lastb):
-	blez	a2,L(leave)
-	PTR_ADDU a3,a0,a2       /* a3 is the last dst address */
+	blez	$a2,L(leave)
+	PTR_ADDU $a3,$a0,$a2       /* a3 is the last dst address */
 L(lastbloop):
-	PTR_ADDIU a0,a0,1
-	bne	a0,a3,L(lastbloop)
-	sb	a1,-1(a0)
+	PTR_ADDIU $a0,$a0,1
+	bne	$a0,$a3,L(lastbloop)
+	sb	$a1,-1($a0)
 L(leave):
-	j	ra
+	j	$ra
 	nop
 
 	.set	at
diff --git a/libc/arch-mips/string/strcmp.S b/libc/arch-mips/string/strcmp.S
index e1faf2d..4791a0d 100644
--- a/libc/arch-mips/string/strcmp.S
+++ b/libc/arch-mips/string/strcmp.S
@@ -100,18 +100,18 @@
    instructions so that the nop is not needed but testing showed that this
    code is actually faster (based on glibc strcmp test).  */
 #define BYTECMP01(OFFSET) \
-    lbu v0, OFFSET(a0); \
-    lbu v1, OFFSET(a1); \
-    beq v0, zero, L(bexit01); \
+    lbu $v0, OFFSET($a0); \
+    lbu $v1, OFFSET($a1); \
+    beq $v0, $zero, L(bexit01); \
     nop; \
-    bne v0, v1, L(bexit01)
+    bne $v0, $v1, L(bexit01)
 
 #define BYTECMP89(OFFSET) \
-    lbu t8, OFFSET(a0); \
-    lbu t9, OFFSET(a1); \
-    beq t8, zero, L(bexit89); \
+    lbu $t8, OFFSET($a0); \
+    lbu $t9, OFFSET($a1); \
+    beq $t8, $zero, L(bexit89); \
     nop;    \
-    bne t8, t9, L(bexit89)
+    bne $t8, $t9, L(bexit89)
 
 /* Allow the routine to be named something else if desired.  */
 #ifndef STRCMP_NAME
@@ -126,46 +126,46 @@
     .set    nomips16
     .set    noreorder
 
-    andi t1, a1, (NSIZE - 1)
-    beqz t1, L(exitalign)
-    or   t0, zero, NSIZE
-    SUBU t1, t0, t1 #process (NSIZE - 1) bytes at max
+    andi $t1, $a1, (NSIZE - 1)
+    beqz $t1, L(exitalign)
+    or   $t0, $zero, NSIZE
+    SUBU $t1, $t0, $t1 #process (NSIZE - 1) bytes at max
 
 L(alignloop): #do by bytes until a1 aligned
     BYTECMP01(0)
-    SUBU t1, t1, 0x1
-    PTR_ADDIU a0, a0, 0x1
-    bnez  t1, L(alignloop)
-    PTR_ADDIU a1, a1, 0x1
+    SUBU $t1, $t1, 0x1
+    PTR_ADDIU $a0, $a0, 0x1
+    bnez  $t1, L(alignloop)
+    PTR_ADDIU $a1, $a1, 0x1
 
 L(exitalign):
 
 /* string a1 is NSIZE byte aligned at this point. */
 
-    lui t8, 0x0101
-    ori t8, 0x0101
-    lui t9, 0x7f7f
-    ori t9, 0x7f7f
+    lui $t8, 0x0101
+    ori $t8, 0x0101
+    lui $t9, 0x7f7f
+    ori $t9, 0x7f7f
 #if __mips64
-    dsll t1, t8, 32
-    or  t8, t1
-    dsll t1, t9, 32
-    or  t9, t1
+    dsll $t1, $t8, 32
+    or  $t8, $t1
+    dsll $t1, $t9, 32
+    or  $t9, $t1
 #endif
 
-    andi t2, a0, (NSIZE - 1) #check if a0 aligned
-    SUBU t3, t0, t2 #t3 will be used as shifter
-    bnez t2, L(uloopenter)
-    SUBU a2, a0, t2 #bring back a0 to aligned position
+    andi $t2, $a0, (NSIZE - 1) #check if a0 aligned
+    SUBU $t3, $t0, $t2 #t3 will be used as shifter
+    bnez $t2, L(uloopenter)
+    SUBU $a2, $a0, $t2 #bring back a0 to aligned position
 
 #define STRCMPW(OFFSET) \
-    LW   v0, OFFSET(a0); \
-    LW   v1, OFFSET(a1); \
-    SUBU t0, v0, t8; \
-    bne  v0, v1, L(worddiff); \
-    nor  t1, v0, t9; \
-    and  t0, t0, t1; \
-    bne  t0, zero, L(returnzero);\
+    LW   $v0, OFFSET($a0); \
+    LW   $v1, OFFSET($a1); \
+    SUBU $t0, $v0, $t8; \
+    bne  $v0, $v1, L(worddiff); \
+    nor  $t1, $v0, $t9; \
+    and  $t0, $t0, $t1; \
+    bne  $t0, $zero, L(returnzero);\
 
 L(wordloop):
     STRCMPW(0 * NSIZE)
@@ -183,34 +183,34 @@
     STRCMPW(6 * NSIZE)
     DELAY_READ
     STRCMPW(7 * NSIZE)
-    PTR_ADDIU a0, a0, (8 * NSIZE)
+    PTR_ADDIU $a0, $a0, (8 * NSIZE)
     b   L(wordloop)
-    PTR_ADDIU a1, a1, (8 * NSIZE)
+    PTR_ADDIU $a1, $a1, (8 * NSIZE)
 
 #define USTRCMPW(OFFSET) \
-    LW  v1, OFFSET(a1); \
-    SUBU    t0, v0, t8; \
-    nor t1, v0, t9; \
-    and t0, t0, t1; \
-    bne t0, zero, L(worddiff); \
-    SRL v0, t2; \
-    LW  a3, (OFFSET + NSIZE)(a2); \
-    SUBU    t0, v1, t8; \
-    SLL t1, a3, t3; \
-    or v0, v0, t1; \
-    bne v0, v1, L(worddiff); \
-    nor t1, v1, t9; \
-    and t0, t0, t1; \
-    bne t0, zero, L(returnzero); \
-    move v0, a3;\
+    LW  $v1, OFFSET($a1); \
+    SUBU    $t0, $v0, $t8; \
+    nor $t1, $v0, $t9; \
+    and $t0, $t0, $t1; \
+    bne $t0, $zero, L(worddiff); \
+    SRL $v0, $t2; \
+    LW  $a3, (OFFSET + NSIZE)($a2); \
+    SUBU    $t0, $v1, $t8; \
+    SLL $t1, $a3, $t3; \
+    or $v0, $v0, $t1; \
+    bne $v0, $v1, L(worddiff); \
+    nor $t1, $v1, $t9; \
+    and $t0, $t0, $t1; \
+    bne $t0, $zero, L(returnzero); \
+    move $v0, $a3;\
 
 L(uloopenter):
-    LW  v0, 0(a2)
-    SLL t2, 3  #multiply by 8
-    SLL t3, 3  #multiply by 8
-    li  a3, -1 #all 1s
-    SRL a3, t3
-    or v0, a3 #replace with all 1s if zeros in unintented read
+    LW  $v0, 0($a2)
+    SLL $t2, 3  #multiply by 8
+    SLL $t3, 3  #multiply by 8
+    li  $a3, -1 #all 1s
+    SRL $a3, $t3
+    or $v0, $a3 #replace with all 1s if zeros in unintented read
 
 L(uwordloop):
     USTRCMPW(0 * NSIZE)
@@ -221,114 +221,114 @@
     USTRCMPW(5 * NSIZE)
     USTRCMPW(6 * NSIZE)
     USTRCMPW(7 * NSIZE)
-    PTR_ADDIU a2, a2, (8 * NSIZE)
+    PTR_ADDIU $a2, $a2, (8 * NSIZE)
     b   L(uwordloop)
-    PTR_ADDIU a1, a1, (8 * NSIZE)
+    PTR_ADDIU $a1, $a1, (8 * NSIZE)
 
 L(returnzero):
-    j   ra
-    move    v0, zero
+    j   $ra
+    move    $v0, $zero
 
 #if __mips_isa_rev > 1
 #define EXT_COMPARE01(POS) \
-    EXT t0, v0, POS, 8; \
-    beq t0, zero, L(wexit01); \
-    EXT t1, v1, POS, 8; \
-    bne t0, t1, L(wexit01)
+    EXT $t0, $v0, POS, 8; \
+    beq $t0, $zero, L(wexit01); \
+    EXT $t1, $v1, POS, 8; \
+    bne $t0, $t1, L(wexit01)
 #define EXT_COMPARE89(POS) \
-    EXT t8, v0, POS, 8; \
-    beq t8, zero, L(wexit89); \
-    EXT t9, v1, POS, 8; \
-    bne t8, t9, L(wexit89)
+    EXT $t8, $v0, POS, 8; \
+    beq $t8, $zero, L(wexit89); \
+    EXT $t9, $v1, POS, 8; \
+    bne $t8, $t9, L(wexit89)
 #else
 #define EXT_COMPARE01(POS) \
-    SRL  t0, v0, POS; \
-    SRL  t1, v1, POS; \
-    andi t0, t0, 0xff; \
-    beq  t0, zero, L(wexit01); \
-    andi t1, t1, 0xff; \
-    bne  t0, t1, L(wexit01)
+    SRL  $t0, $v0, POS; \
+    SRL  $t1, $v1, POS; \
+    andi $t0, $t0, 0xff; \
+    beq  $t0, $zero, L(wexit01); \
+    andi $t1, $t1, 0xff; \
+    bne  $t0, $t1, L(wexit01)
 #define EXT_COMPARE89(POS) \
-    SRL  t8, v0, POS; \
-    SRL  t9, v1, POS; \
-    andi t8, t8, 0xff; \
-    beq  t8, zero, L(wexit89); \
-    andi t9, t9, 0xff; \
-    bne  t8, t9, L(wexit89)
+    SRL  $t8, $v0, POS; \
+    SRL  $t9, $v1, POS; \
+    andi $t8, $t8, 0xff; \
+    beq  $t8, $zero, L(wexit89); \
+    andi $t9, $t9, 0xff; \
+    bne  $t8, $t9, L(wexit89)
 #endif
 
 L(worddiff):
 #ifdef USE_CLZ
-    SUBU    t0, v0, t8
-    nor t1, v0, t9
-    and t1, t0, t1
-    xor t0, v0, v1
-    or  t0, t0, t1
+    SUBU    $t0, $v0, $t8
+    nor $t1, $v0, $t9
+    and $t1, $t0, $t1
+    xor $t0, $v0, $v1
+    or  $t0, $t0, $t1
 # if __BYTE_ORDER__ == __ORDER_LITTLE_ENDIAN__
-    wsbh    t0, t0
-    rotr    t0, t0, 16
+    wsbh    $t0, $t0
+    rotr    $t0, $t0, 16
 # endif
-    clz t1, t0
-    and t1, 0xf8
+    clz $t1, $t0
+    and $t1, 0xf8
 # if __BYTE_ORDER__ == __ORDER_BIG_ENDIAN__
-    neg t1
-    addu    t1, 24
+    neg $t1
+    addu    $t1, 24
 # endif
-    rotrv   v0, v0, t1
-    rotrv   v1, v1, t1
-    and v0, v0, 0xff
-    and v1, v1, 0xff
-    j   ra
-    SUBU    v0, v0, v1
+    rotrv   $v0, $v0, $t1
+    rotrv   $v1, $v1, $t1
+    and $v0, $v0, 0xff
+    and $v1, $v1, 0xff
+    j   $ra
+    SUBU    $v0, $v0, $v1
 #else /* USE_CLZ */
 # if __BYTE_ORDER__ == __ORDER_LITTLE_ENDIAN__
-    andi    t0, v0, 0xff
-    beq t0, zero, L(wexit01)
-    andi    t1, v1, 0xff
-    bne t0, t1, L(wexit01)
+    andi    $t0, $v0, 0xff
+    beq $t0, $zero, L(wexit01)
+    andi    $t1, $v1, 0xff
+    bne $t0, $t1, L(wexit01)
     EXT_COMPARE89(8)
     EXT_COMPARE01(16)
 #ifndef __mips64
-    SRL t8, v0, 24
-    SRL t9, v1, 24
+    SRL $t8, $v0, 24
+    SRL $t9, $v1, 24
 #else
     EXT_COMPARE89(24)
     EXT_COMPARE01(32)
     EXT_COMPARE89(40)
     EXT_COMPARE01(48)
-    SRL t8, v0, 56
-    SRL t9, v1, 56
+    SRL $t8, $v0, 56
+    SRL $t9, $v1, 56
 #endif
 
 # else /* __BYTE_ORDER__ == __ORDER_LITTLE_ENDIAN__ */
 #ifdef __mips64
-    SRL t0, v0, 56
-    beq t0, zero, L(wexit01)
-    SRL t1, v1, 56
-    bne t0, t1, L(wexit01)
+    SRL $t0, $v0, 56
+    beq $t0, $zero, L(wexit01)
+    SRL $t1, $v1, 56
+    bne $t0, $t1, L(wexit01)
     EXT_COMPARE89(48)
     EXT_COMPARE01(40)
     EXT_COMPARE89(32)
     EXT_COMPARE01(24)
 #else
-    SRL t0, v0, 24
-    beq t0, zero, L(wexit01)
-    SRL t1, v1, 24
-    bne t0, t1, L(wexit01)
+    SRL $t0, $v0, 24
+    beq $t0, $zero, L(wexit01)
+    SRL $t1, $v1, 24
+    bne $t0, $t1, L(wexit01)
 #endif
     EXT_COMPARE89(16)
     EXT_COMPARE01(8)
 
-    andi    t8, v0, 0xff
-    andi    t9, v1, 0xff
+    andi    $t8, $v0, 0xff
+    andi    $t9, $v1, 0xff
 # endif /* __BYTE_ORDER__ == __ORDER_LITTLE_ENDIAN__ */
 
 L(wexit89):
-    j   ra
-    SUBU    v0, t8, t9
+    j   $ra
+    SUBU    $v0, $t8, $t9
 L(wexit01):
-    j   ra
-    SUBU    v0, t0, t1
+    j   $ra
+    SUBU    $v0, $t0, $t1
 #endif /* USE_CLZ */
 
 L(byteloop):
@@ -340,16 +340,16 @@
     BYTECMP89(5)
     BYTECMP01(6)
     BYTECMP89(7)
-    PTR_ADDIU a0, a0, 8
+    PTR_ADDIU $a0, $a0, 8
     b   L(byteloop)
-    PTR_ADDIU a1, a1, 8
+    PTR_ADDIU $a1, $a1, 8
 
 L(bexit01):
-    j   ra
-    SUBU    v0, v0, v1
+    j   $ra
+    SUBU    $v0, $v0, $v1
 L(bexit89):
-    j   ra
-    SUBU    v0, t8, t9
+    j   $ra
+    SUBU    $v0, $t8, $t9
 
     .set    at
     .set    reorder
diff --git a/libc/arch-mips/string/strncmp.S b/libc/arch-mips/string/strncmp.S
index 4867c44..49250a0 100644
--- a/libc/arch-mips/string/strncmp.S
+++ b/libc/arch-mips/string/strncmp.S
@@ -102,18 +102,18 @@
    instructions so that the nop is not needed but testing showed that this
    code is actually faster (based on glibc strcmp test).  */
 #define BYTECMP01(OFFSET) \
-    lbu v0, OFFSET(a0); \
-    lbu v1, OFFSET(a1); \
-    beq v0, zero, L(bexit01); \
+    lbu $v0, OFFSET($a0); \
+    lbu $v1, OFFSET($a1); \
+    beq $v0, $zero, L(bexit01); \
     nop; \
-    bne v0, v1, L(bexit01)
+    bne $v0, $v1, L(bexit01)
 
 #define BYTECMP89(OFFSET) \
-    lbu t8, OFFSET(a0); \
-    lbu t9, OFFSET(a1); \
-    beq t8, zero, L(bexit89); \
+    lbu $t8, OFFSET($a0); \
+    lbu $t9, OFFSET($a1); \
+    beq $t8, $zero, L(bexit89); \
     nop;    \
-    bne t8, t9, L(bexit89)
+    bne $t8, $t9, L(bexit89)
 
 /* Allow the routine to be named something else if desired.  */
 #ifndef STRNCMP_NAME
@@ -128,34 +128,34 @@
     .set    nomips16
     .set    noreorder
 
-    srl t0, a2, (2 + NSIZE / 4)
-    beqz  t0, L(byteloop) #process by bytes if less than (2 * NSIZE)
-    andi t1, a1, (NSIZE - 1)
-    beqz  t1, L(exitalign)
-    or   t0, zero, NSIZE
-    SUBU t1, t0, t1 #process (NSIZE - 1) bytes at max
-    SUBU a2, a2, t1 #dec count by t1
+    srl $t0, $a2, (2 + NSIZE / 4)
+    beqz  $t0, L(byteloop) #process by bytes if less than (2 * NSIZE)
+    andi $t1, $a1, (NSIZE - 1)
+    beqz  $t1, L(exitalign)
+    or   $t0, $zero, NSIZE
+    SUBU $t1, $t0, $t1 #process (NSIZE - 1) bytes at max
+    SUBU $a2, $a2, $t1 #dec count by t1
 
 L(alignloop): #do by bytes until a1 aligned
     BYTECMP01(0)
-    SUBU t1, t1, 0x1
-    PTR_ADDIU a0, a0, 0x1
-    bne  t1, zero, L(alignloop)
-    PTR_ADDIU a1, a1, 0x1
+    SUBU $t1, $t1, 0x1
+    PTR_ADDIU $a0, $a0, 0x1
+    bne  $t1, $zero, L(alignloop)
+    PTR_ADDIU $a1, $a1, 0x1
 
 L(exitalign):
 
 /* string a1 is NSIZE byte aligned at this point. */
 #ifndef __mips1
-    lui t8, 0x0101
-    ori t8, 0x0101
-    lui t9, 0x7f7f
-    ori t9, 0x7f7f
+    lui $t8, 0x0101
+    ori $t8, 0x0101
+    lui $t9, 0x7f7f
+    ori $t9, 0x7f7f
 #if __mips64
-    dsll t0, t8, 32
-    or  t8, t0
-    dsll t1, t9, 32
-    or  t9, t1
+    dsll $t0, $t8, 32
+    or  $t8, $t0
+    dsll $t1, $t9, 32
+    or  $t9, $t1
 #endif
 #endif
 
@@ -164,25 +164,25 @@
    remainings archs need to implemented with unaligned instructions */
 
 #if __mips1
-    andi t0, a0, (NSIZE - 1)
-    bne  t0, zero, L(byteloop)
+    andi $t0, $a0, (NSIZE - 1)
+    bne  $t0, $zero, L(byteloop)
 #elif __mips_isa_rev < 6
-    andi t0, a0, (NSIZE - 1)
-    bne  t0, zero, L(uwordloop)
+    andi $t0, $a0, (NSIZE - 1)
+    bne  $t0, $zero, L(uwordloop)
 #endif
 
 #define STRCMPW(OFFSET) \
-    LW   v0, (OFFSET)(a0); \
-    LW   v1, (OFFSET)(a1); \
-    SUBU t0, v0, t8; \
-    bne  v0, v1, L(worddiff); \
-    nor  t1, v0, t9; \
-    and  t0, t0, t1; \
-    bne  t0, zero, L(returnzero);\
+    LW   $v0, (OFFSET)($a0); \
+    LW   $v1, (OFFSET)($a1); \
+    SUBU $t0, $v0, $t8; \
+    bne  $v0, $v1, L(worddiff); \
+    nor  $t1, $v0, $t9; \
+    and  $t0, $t0, $t1; \
+    bne  $t0, $zero, L(returnzero);\
 
 L(wordloop):
-    SUBU t1, a2, (8 * NSIZE)
-    bltz t1, L(onewords)
+    SUBU $t1, $a2, (8 * NSIZE)
+    bltz $t1, L(onewords)
     STRCMPW(0 * NSIZE)
     DELAY_READ
     STRCMPW(1 * NSIZE)
@@ -198,34 +198,34 @@
     STRCMPW(6 * NSIZE)
     DELAY_READ
     STRCMPW(7 * NSIZE)
-    SUBU a2, a2, (8 * NSIZE)
-    PTR_ADDIU a0, a0, (8 * NSIZE)
+    SUBU $a2, $a2, (8 * NSIZE)
+    PTR_ADDIU $a0, $a0, (8 * NSIZE)
     b   L(wordloop)
-    PTR_ADDIU a1, a1, (8 * NSIZE)
+    PTR_ADDIU $a1, $a1, (8 * NSIZE)
 
 L(onewords):
-    SUBU t1, a2, NSIZE
-    bltz t1, L(byteloop)
+    SUBU $t1, $a2, NSIZE
+    bltz $t1, L(byteloop)
     STRCMPW(0)
-    SUBU a2, a2, NSIZE
-    PTR_ADDIU a0, a0, NSIZE
+    SUBU $a2, $a2, NSIZE
+    PTR_ADDIU $a0, $a0, NSIZE
     b   L(onewords)
-    PTR_ADDIU a1, a1, NSIZE
+    PTR_ADDIU $a1, $a1, NSIZE
 
 #if __mips_isa_rev < 6 && !__mips1
 #define USTRCMPW(OFFSET) \
-    LWR v0, (OFFSET)(a0); \
-    LWL v0, (OFFSET + NSIZE - 1)(a0); \
-    LW  v1, (OFFSET)(a1); \
-    SUBU    t0, v0, t8; \
-    bne v0, v1, L(worddiff); \
-    nor t1, v0, t9; \
-    and t0, t0, t1; \
-    bne t0, zero, L(returnzero);\
+    LWR $v0, (OFFSET)($a0); \
+    LWL $v0, (OFFSET + NSIZE - 1)($a0); \
+    LW  $v1, (OFFSET)($a1); \
+    SUBU    $t0, $v0, $t8; \
+    bne $v0, $v1, L(worddiff); \
+    nor $t1, $v0, $t9; \
+    and $t0, $t0, $t1; \
+    bne $t0, $zero, L(returnzero);\
 
 L(uwordloop):
-    SUBU t1, a2, (8 * NSIZE)
-    bltz t1, L(uonewords)
+    SUBU $t1, $a2, (8 * NSIZE)
+    bltz $t1, L(uonewords)
     USTRCMPW(0 * NSIZE)
     DELAY_READ
     USTRCMPW(1 * NSIZE)
@@ -241,154 +241,154 @@
     USTRCMPW(6 * NSIZE)
     DELAY_READ
     USTRCMPW(7 * NSIZE)
-    SUBU a2, a2, (8 * NSIZE)
-    PTR_ADDIU a0, a0, (8 * NSIZE)
+    SUBU $a2, $a2, (8 * NSIZE)
+    PTR_ADDIU $a0, $a0, (8 * NSIZE)
     b   L(uwordloop)
-    PTR_ADDIU a1, a1, (8 * NSIZE)
+    PTR_ADDIU $a1, $a1, (8 * NSIZE)
 
 L(uonewords):
-    SUBU t1, a2, NSIZE
-    bltz t1, L(byteloop)
+    SUBU $t1, $a2, NSIZE
+    bltz $t1, L(byteloop)
     USTRCMPW(0)
-    SUBU a2, a2, NSIZE
-    PTR_ADDIU a0, a0, NSIZE
+    SUBU $a2, $a2, NSIZE
+    PTR_ADDIU $a0, $a0, NSIZE
     b   L(uonewords)
-    PTR_ADDIU a1, a1, NSIZE
+    PTR_ADDIU $a1, $a1, NSIZE
 
 #endif
 
 L(returnzero):
-    j   ra
-    move    v0, zero
+    j   $ra
+    move    $v0, $zero
 
 #if __mips_isa_rev > 1
 #define EXT_COMPARE01(POS) \
-    EXT t0, v0, POS, 8; \
-    beq t0, zero, L(wexit01); \
-    EXT t1, v1, POS, 8; \
-    bne t0, t1, L(wexit01)
+    EXT $t0, $v0, POS, 8; \
+    beq $t0, $zero, L(wexit01); \
+    EXT $t1, $v1, POS, 8; \
+    bne $t0, $t1, L(wexit01)
 #define EXT_COMPARE89(POS) \
-    EXT t8, v0, POS, 8; \
-    beq t8, zero, L(wexit89); \
-    EXT t9, v1, POS, 8; \
-    bne t8, t9, L(wexit89)
+    EXT $t8, $v0, POS, 8; \
+    beq $t8, $zero, L(wexit89); \
+    EXT $t9, $v1, POS, 8; \
+    bne $t8, $t9, L(wexit89)
 #else
 #define EXT_COMPARE01(POS) \
-    SRL  t0, v0, POS; \
-    SRL  t1, v1, POS; \
-    andi t0, t0, 0xff; \
-    beq  t0, zero, L(wexit01); \
-    andi t1, t1, 0xff; \
-    bne  t0, t1, L(wexit01)
+    SRL  $t0, $v0, POS; \
+    SRL  $t1, $v1, POS; \
+    andi $t0, $t0, 0xff; \
+    beq  $t0, $zero, L(wexit01); \
+    andi $t1, $t1, 0xff; \
+    bne  $t0, $t1, L(wexit01)
 #define EXT_COMPARE89(POS) \
-    SRL  t8, v0, POS; \
-    SRL  t9, v1, POS; \
-    andi t8, t8, 0xff; \
-    beq  t8, zero, L(wexit89); \
-    andi t9, t9, 0xff; \
-    bne  t8, t9, L(wexit89)
+    SRL  $t8, $v0, POS; \
+    SRL  $t9, $v1, POS; \
+    andi $t8, $t8, 0xff; \
+    beq  $t8, $zero, L(wexit89); \
+    andi $t9, $t9, 0xff; \
+    bne  $t8, $t9, L(wexit89)
 #endif
 
 L(worddiff):
 #ifdef USE_CLZ
-    SUBU    t0, v0, t8
-    nor t1, v0, t9
-    and t1, t0, t1
-    xor t0, v0, v1
-    or  t0, t0, t1
+    SUBU    $t0, $v0, $t8
+    nor $t1, $v0, $t9
+    and $t1, $t0, $t1
+    xor $t0, $v0, $v1
+    or  $t0, $t0, $t1
 # if __BYTE_ORDER__ == __ORDER_LITTLE_ENDIAN__
-    wsbh    t0, t0
-    rotr    t0, t0, 16
+    wsbh    $t0, $t0
+    rotr    $t0, $t0, 16
 # endif
-    clz t1, t0
-    and t1, 0xf8
+    clz $t1, $t0
+    and $t1, 0xf8
 # if __BYTE_ORDER__ == __ORDER_BIG_ENDIAN__
-    neg t1
-    addu    t1, 24
+    neg $t1
+    addu    $t1, 24
 # endif
-    rotrv   v0, v0, t1
-    rotrv   v1, v1, t1
-    and v0, v0, 0xff
-    and v1, v1, 0xff
-    j   ra
-    SUBU    v0, v0, v1
+    rotrv   $v0, $v0, $t1
+    rotrv   $v1, $v1, $t1
+    and $v0, $v0, 0xff
+    and $v1, $v1, 0xff
+    j   $ra
+    SUBU    $v0, $v0, $v1
 #else /* USE_CLZ */
 # if __BYTE_ORDER__ == __ORDER_LITTLE_ENDIAN__
-    andi    t0, v0, 0xff
-    beq t0, zero, L(wexit01)
-    andi    t1, v1, 0xff
-    bne t0, t1, L(wexit01)
+    andi    $t0, $v0, 0xff
+    beq $t0, $zero, L(wexit01)
+    andi    $t1, $v1, 0xff
+    bne $t0, $t1, L(wexit01)
     EXT_COMPARE89(8)
     EXT_COMPARE01(16)
 #ifndef __mips64
-    SRL t8, v0, 24
-    SRL t9, v1, 24
+    SRL $t8, $v0, 24
+    SRL $t9, $v1, 24
 #else
     EXT_COMPARE89(24)
     EXT_COMPARE01(32)
     EXT_COMPARE89(40)
     EXT_COMPARE01(48)
-    SRL t8, v0, 56
-    SRL t9, v1, 56
+    SRL $t8, $v0, 56
+    SRL $t9, $v1, 56
 #endif
 
 # else /* __BYTE_ORDER__ == __ORDER_LITTLE_ENDIAN__ */
 #ifdef __mips64
-    SRL t0, v0, 56
-    beq t0, zero, L(wexit01)
-    SRL t1, v1, 56
-    bne t0, t1, L(wexit01)
+    SRL $t0, $v0, 56
+    beq $t0, $zero, L(wexit01)
+    SRL $t1, $v1, 56
+    bne $t0, $t1, L(wexit01)
     EXT_COMPARE89(48)
     EXT_COMPARE01(40)
     EXT_COMPARE89(32)
     EXT_COMPARE01(24)
 #else
-    SRL t0, v0, 24
-    beq t0, zero, L(wexit01)
-    SRL t1, v1, 24
-    bne t0, t1, L(wexit01)
+    SRL $t0, $v0, 24
+    beq $t0, $zero, L(wexit01)
+    SRL $t1, $v1, 24
+    bne $t0, $t1, L(wexit01)
 #endif
     EXT_COMPARE89(16)
     EXT_COMPARE01(8)
 
-    andi    t8, v0, 0xff
-    andi    t9, v1, 0xff
+    andi    $t8, $v0, 0xff
+    andi    $t9, $v1, 0xff
 # endif /* __BYTE_ORDER__ == __ORDER_LITTLE_ENDIAN__ */
 
 L(wexit89):
-    j   ra
-    SUBU    v0, t8, t9
+    j   $ra
+    SUBU    $v0, $t8, $t9
 L(wexit01):
-    j   ra
-    SUBU    v0, t0, t1
+    j   $ra
+    SUBU    $v0, $t0, $t1
 #endif /* USE_CLZ */
 
 L(byteloop):
-    beq a2, zero, L(returnzero)
-    SUBU a2, a2, 1
+    beq $a2, $zero, L(returnzero)
+    SUBU $a2, $a2, 1
     BYTECMP01(0)
     nop
-    beq a2, zero, L(returnzero)
-    SUBU a2, a2, 1
+    beq $a2, $zero, L(returnzero)
+    SUBU $a2, $a2, 1
     BYTECMP89(1)
     nop
-    beq a2, zero, L(returnzero)
-    SUBU a2, a2, 1
+    beq $a2, $zero, L(returnzero)
+    SUBU $a2, $a2, 1
     BYTECMP01(2)
     nop
-    beq a2, zero, L(returnzero)
-    SUBU a2, a2, 1
+    beq $a2, $zero, L(returnzero)
+    SUBU $a2, $a2, 1
     BYTECMP89(3)
-    PTR_ADDIU a0, a0, 4
+    PTR_ADDIU $a0, $a0, 4
     b   L(byteloop)
-    PTR_ADDIU a1, a1, 4
+    PTR_ADDIU $a1, $a1, 4
 
 L(bexit01):
-    j   ra
-    SUBU    v0, v0, v1
+    j   $ra
+    SUBU    $v0, $v0, $v1
 L(bexit89):
-    j   ra
-    SUBU    v0, t8, t9
+    j   $ra
+    SUBU    $v0, $t8, $t9
 
     .set    at
     .set    reorder
diff --git a/libc/arch-mips/syscalls/___clock_nanosleep.S b/libc/arch-mips/syscalls/___clock_nanosleep.S
index 4879489..55a77d4 100644
--- a/libc/arch-mips/syscalls/___clock_nanosleep.S
+++ b/libc/arch-mips/syscalls/___clock_nanosleep.S
@@ -4,16 +4,16 @@
 
 ENTRY(___clock_nanosleep)
     .set noreorder
-    .cpload t9
-    li v0, __NR_clock_nanosleep
+    .cpload $t9
+    li $v0, __NR_clock_nanosleep
     syscall
-    bnez a3, 1f
-    move a0, v0
-    j ra
+    bnez $a3, 1f
+    move $a0, $v0
+    j $ra
     nop
 1:
-    la t9,__set_errno_internal
-    j t9
+    la $t9,__set_errno_internal
+    j $t9
     nop
     .set reorder
 END(___clock_nanosleep)
diff --git a/libc/arch-mips/syscalls/___close.S b/libc/arch-mips/syscalls/___close.S
index 356cfd6..592766a 100644
--- a/libc/arch-mips/syscalls/___close.S
+++ b/libc/arch-mips/syscalls/___close.S
@@ -4,16 +4,16 @@
 
 ENTRY(___close)
     .set noreorder
-    .cpload t9
-    li v0, __NR_close
+    .cpload $t9
+    li $v0, __NR_close
     syscall
-    bnez a3, 1f
-    move a0, v0
-    j ra
+    bnez $a3, 1f
+    move $a0, $v0
+    j $ra
     nop
 1:
-    la t9,__set_errno_internal
-    j t9
+    la $t9,__set_errno_internal
+    j $t9
     nop
     .set reorder
 END(___close)
diff --git a/libc/arch-mips/syscalls/___faccessat.S b/libc/arch-mips/syscalls/___faccessat.S
index 4e11bae..9222c6f 100644
--- a/libc/arch-mips/syscalls/___faccessat.S
+++ b/libc/arch-mips/syscalls/___faccessat.S
@@ -4,16 +4,16 @@
 
 ENTRY(___faccessat)
     .set noreorder
-    .cpload t9
-    li v0, __NR_faccessat
+    .cpload $t9
+    li $v0, __NR_faccessat
     syscall
-    bnez a3, 1f
-    move a0, v0
-    j ra
+    bnez $a3, 1f
+    move $a0, $v0
+    j $ra
     nop
 1:
-    la t9,__set_errno_internal
-    j t9
+    la $t9,__set_errno_internal
+    j $t9
     nop
     .set reorder
 END(___faccessat)
diff --git a/libc/arch-mips/syscalls/___fchmod.S b/libc/arch-mips/syscalls/___fchmod.S
index ac102ec..680c368 100644
--- a/libc/arch-mips/syscalls/___fchmod.S
+++ b/libc/arch-mips/syscalls/___fchmod.S
@@ -4,16 +4,16 @@
 
 ENTRY(___fchmod)
     .set noreorder
-    .cpload t9
-    li v0, __NR_fchmod
+    .cpload $t9
+    li $v0, __NR_fchmod
     syscall
-    bnez a3, 1f
-    move a0, v0
-    j ra
+    bnez $a3, 1f
+    move $a0, $v0
+    j $ra
     nop
 1:
-    la t9,__set_errno_internal
-    j t9
+    la $t9,__set_errno_internal
+    j $t9
     nop
     .set reorder
 END(___fchmod)
diff --git a/libc/arch-mips/syscalls/___fchmodat.S b/libc/arch-mips/syscalls/___fchmodat.S
index d581efa..0c8a6bb 100644
--- a/libc/arch-mips/syscalls/___fchmodat.S
+++ b/libc/arch-mips/syscalls/___fchmodat.S
@@ -4,16 +4,16 @@
 
 ENTRY(___fchmodat)
     .set noreorder
-    .cpload t9
-    li v0, __NR_fchmodat
+    .cpload $t9
+    li $v0, __NR_fchmodat
     syscall
-    bnez a3, 1f
-    move a0, v0
-    j ra
+    bnez $a3, 1f
+    move $a0, $v0
+    j $ra
     nop
 1:
-    la t9,__set_errno_internal
-    j t9
+    la $t9,__set_errno_internal
+    j $t9
     nop
     .set reorder
 END(___fchmodat)
diff --git a/libc/arch-mips/syscalls/___fgetxattr.S b/libc/arch-mips/syscalls/___fgetxattr.S
index 50ab69c..a1cc13b 100644
--- a/libc/arch-mips/syscalls/___fgetxattr.S
+++ b/libc/arch-mips/syscalls/___fgetxattr.S
@@ -4,16 +4,16 @@
 
 ENTRY(___fgetxattr)
     .set noreorder
-    .cpload t9
-    li v0, __NR_fgetxattr
+    .cpload $t9
+    li $v0, __NR_fgetxattr
     syscall
-    bnez a3, 1f
-    move a0, v0
-    j ra
+    bnez $a3, 1f
+    move $a0, $v0
+    j $ra
     nop
 1:
-    la t9,__set_errno_internal
-    j t9
+    la $t9,__set_errno_internal
+    j $t9
     nop
     .set reorder
 END(___fgetxattr)
diff --git a/libc/arch-mips/syscalls/___flistxattr.S b/libc/arch-mips/syscalls/___flistxattr.S
index 5a4a53d..77856fd 100644
--- a/libc/arch-mips/syscalls/___flistxattr.S
+++ b/libc/arch-mips/syscalls/___flistxattr.S
@@ -4,16 +4,16 @@
 
 ENTRY(___flistxattr)
     .set noreorder
-    .cpload t9
-    li v0, __NR_flistxattr
+    .cpload $t9
+    li $v0, __NR_flistxattr
     syscall
-    bnez a3, 1f
-    move a0, v0
-    j ra
+    bnez $a3, 1f
+    move $a0, $v0
+    j $ra
     nop
 1:
-    la t9,__set_errno_internal
-    j t9
+    la $t9,__set_errno_internal
+    j $t9
     nop
     .set reorder
 END(___flistxattr)
diff --git a/libc/arch-mips/syscalls/___fsetxattr.S b/libc/arch-mips/syscalls/___fsetxattr.S
index 0312921..9c6a419 100644
--- a/libc/arch-mips/syscalls/___fsetxattr.S
+++ b/libc/arch-mips/syscalls/___fsetxattr.S
@@ -4,16 +4,16 @@
 
 ENTRY(___fsetxattr)
     .set noreorder
-    .cpload t9
-    li v0, __NR_fsetxattr
+    .cpload $t9
+    li $v0, __NR_fsetxattr
     syscall
-    bnez a3, 1f
-    move a0, v0
-    j ra
+    bnez $a3, 1f
+    move $a0, $v0
+    j $ra
     nop
 1:
-    la t9,__set_errno_internal
-    j t9
+    la $t9,__set_errno_internal
+    j $t9
     nop
     .set reorder
 END(___fsetxattr)
diff --git a/libc/arch-mips/syscalls/___mremap.S b/libc/arch-mips/syscalls/___mremap.S
index 82e2eb3..768b958 100644
--- a/libc/arch-mips/syscalls/___mremap.S
+++ b/libc/arch-mips/syscalls/___mremap.S
@@ -4,16 +4,16 @@
 
 ENTRY(___mremap)
     .set noreorder
-    .cpload t9
-    li v0, __NR_mremap
+    .cpload $t9
+    li $v0, __NR_mremap
     syscall
-    bnez a3, 1f
-    move a0, v0
-    j ra
+    bnez $a3, 1f
+    move $a0, $v0
+    j $ra
     nop
 1:
-    la t9,__set_errno_internal
-    j t9
+    la $t9,__set_errno_internal
+    j $t9
     nop
     .set reorder
 END(___mremap)
diff --git a/libc/arch-mips/syscalls/___rt_sigqueueinfo.S b/libc/arch-mips/syscalls/___rt_sigqueueinfo.S
index 95af36f..dde3782 100644
--- a/libc/arch-mips/syscalls/___rt_sigqueueinfo.S
+++ b/libc/arch-mips/syscalls/___rt_sigqueueinfo.S
@@ -4,16 +4,16 @@
 
 ENTRY(___rt_sigqueueinfo)
     .set noreorder
-    .cpload t9
-    li v0, __NR_rt_sigqueueinfo
+    .cpload $t9
+    li $v0, __NR_rt_sigqueueinfo
     syscall
-    bnez a3, 1f
-    move a0, v0
-    j ra
+    bnez $a3, 1f
+    move $a0, $v0
+    j $ra
     nop
 1:
-    la t9,__set_errno_internal
-    j t9
+    la $t9,__set_errno_internal
+    j $t9
     nop
     .set reorder
 END(___rt_sigqueueinfo)
diff --git a/libc/arch-mips/syscalls/__accept4.S b/libc/arch-mips/syscalls/__accept4.S
index 72df04f..596660c 100644
--- a/libc/arch-mips/syscalls/__accept4.S
+++ b/libc/arch-mips/syscalls/__accept4.S
@@ -4,16 +4,16 @@
 
 ENTRY(__accept4)
     .set noreorder
-    .cpload t9
-    li v0, __NR_accept4
+    .cpload $t9
+    li $v0, __NR_accept4
     syscall
-    bnez a3, 1f
-    move a0, v0
-    j ra
+    bnez $a3, 1f
+    move $a0, $v0
+    j $ra
     nop
 1:
-    la t9,__set_errno_internal
-    j t9
+    la $t9,__set_errno_internal
+    j $t9
     nop
     .set reorder
 END(__accept4)
diff --git a/libc/arch-mips/syscalls/__brk.S b/libc/arch-mips/syscalls/__brk.S
index 8472663..ea0f2c3 100644
--- a/libc/arch-mips/syscalls/__brk.S
+++ b/libc/arch-mips/syscalls/__brk.S
@@ -4,16 +4,16 @@
 
 ENTRY(__brk)
     .set noreorder
-    .cpload t9
-    li v0, __NR_brk
+    .cpload $t9
+    li $v0, __NR_brk
     syscall
-    bnez a3, 1f
-    move a0, v0
-    j ra
+    bnez $a3, 1f
+    move $a0, $v0
+    j $ra
     nop
 1:
-    la t9,__set_errno_internal
-    j t9
+    la $t9,__set_errno_internal
+    j $t9
     nop
     .set reorder
 END(__brk)
diff --git a/libc/arch-mips/syscalls/__clock_gettime.S b/libc/arch-mips/syscalls/__clock_gettime.S
index 6fad7e9..a68990b 100644
--- a/libc/arch-mips/syscalls/__clock_gettime.S
+++ b/libc/arch-mips/syscalls/__clock_gettime.S
@@ -4,16 +4,16 @@
 
 ENTRY(__clock_gettime)
     .set noreorder
-    .cpload t9
-    li v0, __NR_clock_gettime
+    .cpload $t9
+    li $v0, __NR_clock_gettime
     syscall
-    bnez a3, 1f
-    move a0, v0
-    j ra
+    bnez $a3, 1f
+    move $a0, $v0
+    j $ra
     nop
 1:
-    la t9,__set_errno_internal
-    j t9
+    la $t9,__set_errno_internal
+    j $t9
     nop
     .set reorder
 END(__clock_gettime)
diff --git a/libc/arch-mips/syscalls/__connect.S b/libc/arch-mips/syscalls/__connect.S
index 38c1b9b..9a87105 100644
--- a/libc/arch-mips/syscalls/__connect.S
+++ b/libc/arch-mips/syscalls/__connect.S
@@ -4,16 +4,16 @@
 
 ENTRY(__connect)
     .set noreorder
-    .cpload t9
-    li v0, __NR_connect
+    .cpload $t9
+    li $v0, __NR_connect
     syscall
-    bnez a3, 1f
-    move a0, v0
-    j ra
+    bnez $a3, 1f
+    move $a0, $v0
+    j $ra
     nop
 1:
-    la t9,__set_errno_internal
-    j t9
+    la $t9,__set_errno_internal
+    j $t9
     nop
     .set reorder
 END(__connect)
diff --git a/libc/arch-mips/syscalls/__epoll_pwait.S b/libc/arch-mips/syscalls/__epoll_pwait.S
index 3aed9bc..68f9d1f 100644
--- a/libc/arch-mips/syscalls/__epoll_pwait.S
+++ b/libc/arch-mips/syscalls/__epoll_pwait.S
@@ -4,16 +4,16 @@
 
 ENTRY(__epoll_pwait)
     .set noreorder
-    .cpload t9
-    li v0, __NR_epoll_pwait
+    .cpload $t9
+    li $v0, __NR_epoll_pwait
     syscall
-    bnez a3, 1f
-    move a0, v0
-    j ra
+    bnez $a3, 1f
+    move $a0, $v0
+    j $ra
     nop
 1:
-    la t9,__set_errno_internal
-    j t9
+    la $t9,__set_errno_internal
+    j $t9
     nop
     .set reorder
 END(__epoll_pwait)
diff --git a/libc/arch-mips/syscalls/__exit.S b/libc/arch-mips/syscalls/__exit.S
index 7349804..d4d1ab8 100644
--- a/libc/arch-mips/syscalls/__exit.S
+++ b/libc/arch-mips/syscalls/__exit.S
@@ -4,16 +4,16 @@
 
 ENTRY(__exit)
     .set noreorder
-    .cpload t9
-    li v0, __NR_exit
+    .cpload $t9
+    li $v0, __NR_exit
     syscall
-    bnez a3, 1f
-    move a0, v0
-    j ra
+    bnez $a3, 1f
+    move $a0, $v0
+    j $ra
     nop
 1:
-    la t9,__set_errno_internal
-    j t9
+    la $t9,__set_errno_internal
+    j $t9
     nop
     .set reorder
 END(__exit)
diff --git a/libc/arch-mips/syscalls/__fadvise64.S b/libc/arch-mips/syscalls/__fadvise64.S
index abacbb2..be0694e 100644
--- a/libc/arch-mips/syscalls/__fadvise64.S
+++ b/libc/arch-mips/syscalls/__fadvise64.S
@@ -4,16 +4,16 @@
 
 ENTRY(__fadvise64)
     .set noreorder
-    .cpload t9
-    li v0, __NR_fadvise64
+    .cpload $t9
+    li $v0, __NR_fadvise64
     syscall
-    bnez a3, 1f
-    move a0, v0
-    j ra
+    bnez $a3, 1f
+    move $a0, $v0
+    j $ra
     nop
 1:
-    la t9,__set_errno_internal
-    j t9
+    la $t9,__set_errno_internal
+    j $t9
     nop
     .set reorder
 END(__fadvise64)
diff --git a/libc/arch-mips/syscalls/__fcntl64.S b/libc/arch-mips/syscalls/__fcntl64.S
index 2734be2..d6e54e4 100644
--- a/libc/arch-mips/syscalls/__fcntl64.S
+++ b/libc/arch-mips/syscalls/__fcntl64.S
@@ -4,16 +4,16 @@
 
 ENTRY(__fcntl64)
     .set noreorder
-    .cpload t9
-    li v0, __NR_fcntl64
+    .cpload $t9
+    li $v0, __NR_fcntl64
     syscall
-    bnez a3, 1f
-    move a0, v0
-    j ra
+    bnez $a3, 1f
+    move $a0, $v0
+    j $ra
     nop
 1:
-    la t9,__set_errno_internal
-    j t9
+    la $t9,__set_errno_internal
+    j $t9
     nop
     .set reorder
 END(__fcntl64)
diff --git a/libc/arch-mips/syscalls/__fstatfs64.S b/libc/arch-mips/syscalls/__fstatfs64.S
index e08cf7e..8dc2ed3 100644
--- a/libc/arch-mips/syscalls/__fstatfs64.S
+++ b/libc/arch-mips/syscalls/__fstatfs64.S
@@ -4,16 +4,16 @@
 
 ENTRY(__fstatfs64)
     .set noreorder
-    .cpload t9
-    li v0, __NR_fstatfs64
+    .cpload $t9
+    li $v0, __NR_fstatfs64
     syscall
-    bnez a3, 1f
-    move a0, v0
-    j ra
+    bnez $a3, 1f
+    move $a0, $v0
+    j $ra
     nop
 1:
-    la t9,__set_errno_internal
-    j t9
+    la $t9,__set_errno_internal
+    j $t9
     nop
     .set reorder
 END(__fstatfs64)
diff --git a/libc/arch-mips/syscalls/__getcpu.S b/libc/arch-mips/syscalls/__getcpu.S
index 262f440..b159f2c 100644
--- a/libc/arch-mips/syscalls/__getcpu.S
+++ b/libc/arch-mips/syscalls/__getcpu.S
@@ -4,16 +4,16 @@
 
 ENTRY(__getcpu)
     .set noreorder
-    .cpload t9
-    li v0, __NR_getcpu
+    .cpload $t9
+    li $v0, __NR_getcpu
     syscall
-    bnez a3, 1f
-    move a0, v0
-    j ra
+    bnez $a3, 1f
+    move $a0, $v0
+    j $ra
     nop
 1:
-    la t9,__set_errno_internal
-    j t9
+    la $t9,__set_errno_internal
+    j $t9
     nop
     .set reorder
 END(__getcpu)
diff --git a/libc/arch-mips/syscalls/__getcwd.S b/libc/arch-mips/syscalls/__getcwd.S
index ca6ec7c..6482244 100644
--- a/libc/arch-mips/syscalls/__getcwd.S
+++ b/libc/arch-mips/syscalls/__getcwd.S
@@ -4,16 +4,16 @@
 
 ENTRY(__getcwd)
     .set noreorder
-    .cpload t9
-    li v0, __NR_getcwd
+    .cpload $t9
+    li $v0, __NR_getcwd
     syscall
-    bnez a3, 1f
-    move a0, v0
-    j ra
+    bnez $a3, 1f
+    move $a0, $v0
+    j $ra
     nop
 1:
-    la t9,__set_errno_internal
-    j t9
+    la $t9,__set_errno_internal
+    j $t9
     nop
     .set reorder
 END(__getcwd)
diff --git a/libc/arch-mips/syscalls/__getdents64.S b/libc/arch-mips/syscalls/__getdents64.S
index fe7ef86..8324a80 100644
--- a/libc/arch-mips/syscalls/__getdents64.S
+++ b/libc/arch-mips/syscalls/__getdents64.S
@@ -4,16 +4,16 @@
 
 ENTRY(__getdents64)
     .set noreorder
-    .cpload t9
-    li v0, __NR_getdents64
+    .cpload $t9
+    li $v0, __NR_getdents64
     syscall
-    bnez a3, 1f
-    move a0, v0
-    j ra
+    bnez $a3, 1f
+    move $a0, $v0
+    j $ra
     nop
 1:
-    la t9,__set_errno_internal
-    j t9
+    la $t9,__set_errno_internal
+    j $t9
     nop
     .set reorder
 END(__getdents64)
diff --git a/libc/arch-mips/syscalls/__getpid.S b/libc/arch-mips/syscalls/__getpid.S
index f5ab049..9f122e0 100644
--- a/libc/arch-mips/syscalls/__getpid.S
+++ b/libc/arch-mips/syscalls/__getpid.S
@@ -4,16 +4,16 @@
 
 ENTRY(__getpid)
     .set noreorder
-    .cpload t9
-    li v0, __NR_getpid
+    .cpload $t9
+    li $v0, __NR_getpid
     syscall
-    bnez a3, 1f
-    move a0, v0
-    j ra
+    bnez $a3, 1f
+    move $a0, $v0
+    j $ra
     nop
 1:
-    la t9,__set_errno_internal
-    j t9
+    la $t9,__set_errno_internal
+    j $t9
     nop
     .set reorder
 END(__getpid)
diff --git a/libc/arch-mips/syscalls/__getpriority.S b/libc/arch-mips/syscalls/__getpriority.S
index ef6235d..22aa7c1 100644
--- a/libc/arch-mips/syscalls/__getpriority.S
+++ b/libc/arch-mips/syscalls/__getpriority.S
@@ -4,16 +4,16 @@
 
 ENTRY(__getpriority)
     .set noreorder
-    .cpload t9
-    li v0, __NR_getpriority
+    .cpload $t9
+    li $v0, __NR_getpriority
     syscall
-    bnez a3, 1f
-    move a0, v0
-    j ra
+    bnez $a3, 1f
+    move $a0, $v0
+    j $ra
     nop
 1:
-    la t9,__set_errno_internal
-    j t9
+    la $t9,__set_errno_internal
+    j $t9
     nop
     .set reorder
 END(__getpriority)
diff --git a/libc/arch-mips/syscalls/__gettimeofday.S b/libc/arch-mips/syscalls/__gettimeofday.S
index e8b9d6a..021ca7f 100644
--- a/libc/arch-mips/syscalls/__gettimeofday.S
+++ b/libc/arch-mips/syscalls/__gettimeofday.S
@@ -4,16 +4,16 @@
 
 ENTRY(__gettimeofday)
     .set noreorder
-    .cpload t9
-    li v0, __NR_gettimeofday
+    .cpload $t9
+    li $v0, __NR_gettimeofday
     syscall
-    bnez a3, 1f
-    move a0, v0
-    j ra
+    bnez $a3, 1f
+    move $a0, $v0
+    j $ra
     nop
 1:
-    la t9,__set_errno_internal
-    j t9
+    la $t9,__set_errno_internal
+    j $t9
     nop
     .set reorder
 END(__gettimeofday)
diff --git a/libc/arch-mips/syscalls/__ioctl.S b/libc/arch-mips/syscalls/__ioctl.S
index 27716e8..fb45f5d 100644
--- a/libc/arch-mips/syscalls/__ioctl.S
+++ b/libc/arch-mips/syscalls/__ioctl.S
@@ -4,16 +4,16 @@
 
 ENTRY(__ioctl)
     .set noreorder
-    .cpload t9
-    li v0, __NR_ioctl
+    .cpload $t9
+    li $v0, __NR_ioctl
     syscall
-    bnez a3, 1f
-    move a0, v0
-    j ra
+    bnez $a3, 1f
+    move $a0, $v0
+    j $ra
     nop
 1:
-    la t9,__set_errno_internal
-    j t9
+    la $t9,__set_errno_internal
+    j $t9
     nop
     .set reorder
 END(__ioctl)
diff --git a/libc/arch-mips/syscalls/__llseek.S b/libc/arch-mips/syscalls/__llseek.S
index e0cb321..d622d92 100644
--- a/libc/arch-mips/syscalls/__llseek.S
+++ b/libc/arch-mips/syscalls/__llseek.S
@@ -4,16 +4,16 @@
 
 ENTRY(__llseek)
     .set noreorder
-    .cpload t9
-    li v0, __NR__llseek
+    .cpload $t9
+    li $v0, __NR__llseek
     syscall
-    bnez a3, 1f
-    move a0, v0
-    j ra
+    bnez $a3, 1f
+    move $a0, $v0
+    j $ra
     nop
 1:
-    la t9,__set_errno_internal
-    j t9
+    la $t9,__set_errno_internal
+    j $t9
     nop
     .set reorder
 END(__llseek)
diff --git a/libc/arch-mips/syscalls/__mmap2.S b/libc/arch-mips/syscalls/__mmap2.S
index 8175b31..435fc77 100644
--- a/libc/arch-mips/syscalls/__mmap2.S
+++ b/libc/arch-mips/syscalls/__mmap2.S
@@ -4,16 +4,16 @@
 
 ENTRY(__mmap2)
     .set noreorder
-    .cpload t9
-    li v0, __NR_mmap2
+    .cpload $t9
+    li $v0, __NR_mmap2
     syscall
-    bnez a3, 1f
-    move a0, v0
-    j ra
+    bnez $a3, 1f
+    move $a0, $v0
+    j $ra
     nop
 1:
-    la t9,__set_errno_internal
-    j t9
+    la $t9,__set_errno_internal
+    j $t9
     nop
     .set reorder
 END(__mmap2)
diff --git a/libc/arch-mips/syscalls/__openat.S b/libc/arch-mips/syscalls/__openat.S
index c0c3cdf..a30c4a8 100644
--- a/libc/arch-mips/syscalls/__openat.S
+++ b/libc/arch-mips/syscalls/__openat.S
@@ -4,16 +4,16 @@
 
 ENTRY(__openat)
     .set noreorder
-    .cpload t9
-    li v0, __NR_openat
+    .cpload $t9
+    li $v0, __NR_openat
     syscall
-    bnez a3, 1f
-    move a0, v0
-    j ra
+    bnez $a3, 1f
+    move $a0, $v0
+    j $ra
     nop
 1:
-    la t9,__set_errno_internal
-    j t9
+    la $t9,__set_errno_internal
+    j $t9
     nop
     .set reorder
 END(__openat)
diff --git a/libc/arch-mips/syscalls/__ppoll.S b/libc/arch-mips/syscalls/__ppoll.S
index 75dbbc8..e2f4363 100644
--- a/libc/arch-mips/syscalls/__ppoll.S
+++ b/libc/arch-mips/syscalls/__ppoll.S
@@ -4,16 +4,16 @@
 
 ENTRY(__ppoll)
     .set noreorder
-    .cpload t9
-    li v0, __NR_ppoll
+    .cpload $t9
+    li $v0, __NR_ppoll
     syscall
-    bnez a3, 1f
-    move a0, v0
-    j ra
+    bnez $a3, 1f
+    move $a0, $v0
+    j $ra
     nop
 1:
-    la t9,__set_errno_internal
-    j t9
+    la $t9,__set_errno_internal
+    j $t9
     nop
     .set reorder
 END(__ppoll)
diff --git a/libc/arch-mips/syscalls/__preadv64.S b/libc/arch-mips/syscalls/__preadv64.S
index a46b869..3bc732a 100644
--- a/libc/arch-mips/syscalls/__preadv64.S
+++ b/libc/arch-mips/syscalls/__preadv64.S
@@ -4,16 +4,16 @@
 
 ENTRY(__preadv64)
     .set noreorder
-    .cpload t9
-    li v0, __NR_preadv
+    .cpload $t9
+    li $v0, __NR_preadv
     syscall
-    bnez a3, 1f
-    move a0, v0
-    j ra
+    bnez $a3, 1f
+    move $a0, $v0
+    j $ra
     nop
 1:
-    la t9,__set_errno_internal
-    j t9
+    la $t9,__set_errno_internal
+    j $t9
     nop
     .set reorder
 END(__preadv64)
diff --git a/libc/arch-mips/syscalls/__pselect6.S b/libc/arch-mips/syscalls/__pselect6.S
index d028156..34c7df1 100644
--- a/libc/arch-mips/syscalls/__pselect6.S
+++ b/libc/arch-mips/syscalls/__pselect6.S
@@ -4,16 +4,16 @@
 
 ENTRY(__pselect6)
     .set noreorder
-    .cpload t9
-    li v0, __NR_pselect6
+    .cpload $t9
+    li $v0, __NR_pselect6
     syscall
-    bnez a3, 1f
-    move a0, v0
-    j ra
+    bnez $a3, 1f
+    move $a0, $v0
+    j $ra
     nop
 1:
-    la t9,__set_errno_internal
-    j t9
+    la $t9,__set_errno_internal
+    j $t9
     nop
     .set reorder
 END(__pselect6)
diff --git a/libc/arch-mips/syscalls/__ptrace.S b/libc/arch-mips/syscalls/__ptrace.S
index c5d91fb..f3879ea 100644
--- a/libc/arch-mips/syscalls/__ptrace.S
+++ b/libc/arch-mips/syscalls/__ptrace.S
@@ -4,16 +4,16 @@
 
 ENTRY(__ptrace)
     .set noreorder
-    .cpload t9
-    li v0, __NR_ptrace
+    .cpload $t9
+    li $v0, __NR_ptrace
     syscall
-    bnez a3, 1f
-    move a0, v0
-    j ra
+    bnez $a3, 1f
+    move $a0, $v0
+    j $ra
     nop
 1:
-    la t9,__set_errno_internal
-    j t9
+    la $t9,__set_errno_internal
+    j $t9
     nop
     .set reorder
 END(__ptrace)
diff --git a/libc/arch-mips/syscalls/__pwritev64.S b/libc/arch-mips/syscalls/__pwritev64.S
index 1222942..569a0d4 100644
--- a/libc/arch-mips/syscalls/__pwritev64.S
+++ b/libc/arch-mips/syscalls/__pwritev64.S
@@ -4,16 +4,16 @@
 
 ENTRY(__pwritev64)
     .set noreorder
-    .cpload t9
-    li v0, __NR_pwritev
+    .cpload $t9
+    li $v0, __NR_pwritev
     syscall
-    bnez a3, 1f
-    move a0, v0
-    j ra
+    bnez $a3, 1f
+    move $a0, $v0
+    j $ra
     nop
 1:
-    la t9,__set_errno_internal
-    j t9
+    la $t9,__set_errno_internal
+    j $t9
     nop
     .set reorder
 END(__pwritev64)
diff --git a/libc/arch-mips/syscalls/__reboot.S b/libc/arch-mips/syscalls/__reboot.S
index c01f7fb..c77d09b 100644
--- a/libc/arch-mips/syscalls/__reboot.S
+++ b/libc/arch-mips/syscalls/__reboot.S
@@ -4,16 +4,16 @@
 
 ENTRY(__reboot)
     .set noreorder
-    .cpload t9
-    li v0, __NR_reboot
+    .cpload $t9
+    li $v0, __NR_reboot
     syscall
-    bnez a3, 1f
-    move a0, v0
-    j ra
+    bnez $a3, 1f
+    move $a0, $v0
+    j $ra
     nop
 1:
-    la t9,__set_errno_internal
-    j t9
+    la $t9,__set_errno_internal
+    j $t9
     nop
     .set reorder
 END(__reboot)
diff --git a/libc/arch-mips/syscalls/__rt_sigaction.S b/libc/arch-mips/syscalls/__rt_sigaction.S
index 7fa37fd..ae18296 100644
--- a/libc/arch-mips/syscalls/__rt_sigaction.S
+++ b/libc/arch-mips/syscalls/__rt_sigaction.S
@@ -4,16 +4,16 @@
 
 ENTRY(__rt_sigaction)
     .set noreorder
-    .cpload t9
-    li v0, __NR_rt_sigaction
+    .cpload $t9
+    li $v0, __NR_rt_sigaction
     syscall
-    bnez a3, 1f
-    move a0, v0
-    j ra
+    bnez $a3, 1f
+    move $a0, $v0
+    j $ra
     nop
 1:
-    la t9,__set_errno_internal
-    j t9
+    la $t9,__set_errno_internal
+    j $t9
     nop
     .set reorder
 END(__rt_sigaction)
diff --git a/libc/arch-mips/syscalls/__rt_sigpending.S b/libc/arch-mips/syscalls/__rt_sigpending.S
index b80b311..b3597c8 100644
--- a/libc/arch-mips/syscalls/__rt_sigpending.S
+++ b/libc/arch-mips/syscalls/__rt_sigpending.S
@@ -4,16 +4,16 @@
 
 ENTRY(__rt_sigpending)
     .set noreorder
-    .cpload t9
-    li v0, __NR_rt_sigpending
+    .cpload $t9
+    li $v0, __NR_rt_sigpending
     syscall
-    bnez a3, 1f
-    move a0, v0
-    j ra
+    bnez $a3, 1f
+    move $a0, $v0
+    j $ra
     nop
 1:
-    la t9,__set_errno_internal
-    j t9
+    la $t9,__set_errno_internal
+    j $t9
     nop
     .set reorder
 END(__rt_sigpending)
diff --git a/libc/arch-mips/syscalls/__rt_sigprocmask.S b/libc/arch-mips/syscalls/__rt_sigprocmask.S
index e2a39eb..ca165c3 100644
--- a/libc/arch-mips/syscalls/__rt_sigprocmask.S
+++ b/libc/arch-mips/syscalls/__rt_sigprocmask.S
@@ -4,16 +4,16 @@
 
 ENTRY(__rt_sigprocmask)
     .set noreorder
-    .cpload t9
-    li v0, __NR_rt_sigprocmask
+    .cpload $t9
+    li $v0, __NR_rt_sigprocmask
     syscall
-    bnez a3, 1f
-    move a0, v0
-    j ra
+    bnez $a3, 1f
+    move $a0, $v0
+    j $ra
     nop
 1:
-    la t9,__set_errno_internal
-    j t9
+    la $t9,__set_errno_internal
+    j $t9
     nop
     .set reorder
 END(__rt_sigprocmask)
diff --git a/libc/arch-mips/syscalls/__rt_sigsuspend.S b/libc/arch-mips/syscalls/__rt_sigsuspend.S
index e91c53f..afd6837 100644
--- a/libc/arch-mips/syscalls/__rt_sigsuspend.S
+++ b/libc/arch-mips/syscalls/__rt_sigsuspend.S
@@ -4,16 +4,16 @@
 
 ENTRY(__rt_sigsuspend)
     .set noreorder
-    .cpload t9
-    li v0, __NR_rt_sigsuspend
+    .cpload $t9
+    li $v0, __NR_rt_sigsuspend
     syscall
-    bnez a3, 1f
-    move a0, v0
-    j ra
+    bnez $a3, 1f
+    move $a0, $v0
+    j $ra
     nop
 1:
-    la t9,__set_errno_internal
-    j t9
+    la $t9,__set_errno_internal
+    j $t9
     nop
     .set reorder
 END(__rt_sigsuspend)
diff --git a/libc/arch-mips/syscalls/__rt_sigtimedwait.S b/libc/arch-mips/syscalls/__rt_sigtimedwait.S
index 0b4195f..c9d6d3c 100644
--- a/libc/arch-mips/syscalls/__rt_sigtimedwait.S
+++ b/libc/arch-mips/syscalls/__rt_sigtimedwait.S
@@ -4,16 +4,16 @@
 
 ENTRY(__rt_sigtimedwait)
     .set noreorder
-    .cpload t9
-    li v0, __NR_rt_sigtimedwait
+    .cpload $t9
+    li $v0, __NR_rt_sigtimedwait
     syscall
-    bnez a3, 1f
-    move a0, v0
-    j ra
+    bnez $a3, 1f
+    move $a0, $v0
+    j $ra
     nop
 1:
-    la t9,__set_errno_internal
-    j t9
+    la $t9,__set_errno_internal
+    j $t9
     nop
     .set reorder
 END(__rt_sigtimedwait)
diff --git a/libc/arch-mips/syscalls/__sched_getaffinity.S b/libc/arch-mips/syscalls/__sched_getaffinity.S
index b09f404..94ea2a4 100644
--- a/libc/arch-mips/syscalls/__sched_getaffinity.S
+++ b/libc/arch-mips/syscalls/__sched_getaffinity.S
@@ -4,16 +4,16 @@
 
 ENTRY(__sched_getaffinity)
     .set noreorder
-    .cpload t9
-    li v0, __NR_sched_getaffinity
+    .cpload $t9
+    li $v0, __NR_sched_getaffinity
     syscall
-    bnez a3, 1f
-    move a0, v0
-    j ra
+    bnez $a3, 1f
+    move $a0, $v0
+    j $ra
     nop
 1:
-    la t9,__set_errno_internal
-    j t9
+    la $t9,__set_errno_internal
+    j $t9
     nop
     .set reorder
 END(__sched_getaffinity)
diff --git a/libc/arch-mips/syscalls/__set_tid_address.S b/libc/arch-mips/syscalls/__set_tid_address.S
index 8ca0716..4a28783 100644
--- a/libc/arch-mips/syscalls/__set_tid_address.S
+++ b/libc/arch-mips/syscalls/__set_tid_address.S
@@ -4,16 +4,16 @@
 
 ENTRY(__set_tid_address)
     .set noreorder
-    .cpload t9
-    li v0, __NR_set_tid_address
+    .cpload $t9
+    li $v0, __NR_set_tid_address
     syscall
-    bnez a3, 1f
-    move a0, v0
-    j ra
+    bnez $a3, 1f
+    move $a0, $v0
+    j $ra
     nop
 1:
-    la t9,__set_errno_internal
-    j t9
+    la $t9,__set_errno_internal
+    j $t9
     nop
     .set reorder
 END(__set_tid_address)
diff --git a/libc/arch-mips/syscalls/__set_tls.S b/libc/arch-mips/syscalls/__set_tls.S
index 1f9eba5..00825b3 100644
--- a/libc/arch-mips/syscalls/__set_tls.S
+++ b/libc/arch-mips/syscalls/__set_tls.S
@@ -4,16 +4,16 @@
 
 ENTRY(__set_tls)
     .set noreorder
-    .cpload t9
-    li v0, __NR_set_thread_area
+    .cpload $t9
+    li $v0, __NR_set_thread_area
     syscall
-    bnez a3, 1f
-    move a0, v0
-    j ra
+    bnez $a3, 1f
+    move $a0, $v0
+    j $ra
     nop
 1:
-    la t9,__set_errno_internal
-    j t9
+    la $t9,__set_errno_internal
+    j $t9
     nop
     .set reorder
 END(__set_tls)
diff --git a/libc/arch-mips/syscalls/__sigaction.S b/libc/arch-mips/syscalls/__sigaction.S
index 0886e95..ef91e1d 100644
--- a/libc/arch-mips/syscalls/__sigaction.S
+++ b/libc/arch-mips/syscalls/__sigaction.S
@@ -4,16 +4,16 @@
 
 ENTRY(__sigaction)
     .set noreorder
-    .cpload t9
-    li v0, __NR_sigaction
+    .cpload $t9
+    li $v0, __NR_sigaction
     syscall
-    bnez a3, 1f
-    move a0, v0
-    j ra
+    bnez $a3, 1f
+    move $a0, $v0
+    j $ra
     nop
 1:
-    la t9,__set_errno_internal
-    j t9
+    la $t9,__set_errno_internal
+    j $t9
     nop
     .set reorder
 END(__sigaction)
diff --git a/libc/arch-mips/syscalls/__signalfd4.S b/libc/arch-mips/syscalls/__signalfd4.S
index 8e5717e..754ad37 100644
--- a/libc/arch-mips/syscalls/__signalfd4.S
+++ b/libc/arch-mips/syscalls/__signalfd4.S
@@ -4,16 +4,16 @@
 
 ENTRY(__signalfd4)
     .set noreorder
-    .cpload t9
-    li v0, __NR_signalfd4
+    .cpload $t9
+    li $v0, __NR_signalfd4
     syscall
-    bnez a3, 1f
-    move a0, v0
-    j ra
+    bnez $a3, 1f
+    move $a0, $v0
+    j $ra
     nop
 1:
-    la t9,__set_errno_internal
-    j t9
+    la $t9,__set_errno_internal
+    j $t9
     nop
     .set reorder
 END(__signalfd4)
diff --git a/libc/arch-mips/syscalls/__socket.S b/libc/arch-mips/syscalls/__socket.S
index c933355..5d59e03 100644
--- a/libc/arch-mips/syscalls/__socket.S
+++ b/libc/arch-mips/syscalls/__socket.S
@@ -4,16 +4,16 @@
 
 ENTRY(__socket)
     .set noreorder
-    .cpload t9
-    li v0, __NR_socket
+    .cpload $t9
+    li $v0, __NR_socket
     syscall
-    bnez a3, 1f
-    move a0, v0
-    j ra
+    bnez $a3, 1f
+    move $a0, $v0
+    j $ra
     nop
 1:
-    la t9,__set_errno_internal
-    j t9
+    la $t9,__set_errno_internal
+    j $t9
     nop
     .set reorder
 END(__socket)
diff --git a/libc/arch-mips/syscalls/__statfs64.S b/libc/arch-mips/syscalls/__statfs64.S
index ed4dcdb..8ebe9f3 100644
--- a/libc/arch-mips/syscalls/__statfs64.S
+++ b/libc/arch-mips/syscalls/__statfs64.S
@@ -4,16 +4,16 @@
 
 ENTRY(__statfs64)
     .set noreorder
-    .cpload t9
-    li v0, __NR_statfs64
+    .cpload $t9
+    li $v0, __NR_statfs64
     syscall
-    bnez a3, 1f
-    move a0, v0
-    j ra
+    bnez $a3, 1f
+    move $a0, $v0
+    j $ra
     nop
 1:
-    la t9,__set_errno_internal
-    j t9
+    la $t9,__set_errno_internal
+    j $t9
     nop
     .set reorder
 END(__statfs64)
diff --git a/libc/arch-mips/syscalls/__sync_file_range.S b/libc/arch-mips/syscalls/__sync_file_range.S
index 79d41e0..ffd9c09 100644
--- a/libc/arch-mips/syscalls/__sync_file_range.S
+++ b/libc/arch-mips/syscalls/__sync_file_range.S
@@ -4,16 +4,16 @@
 
 ENTRY(__sync_file_range)
     .set noreorder
-    .cpload t9
-    li v0, __NR_sync_file_range
+    .cpload $t9
+    li $v0, __NR_sync_file_range
     syscall
-    bnez a3, 1f
-    move a0, v0
-    j ra
+    bnez $a3, 1f
+    move $a0, $v0
+    j $ra
     nop
 1:
-    la t9,__set_errno_internal
-    j t9
+    la $t9,__set_errno_internal
+    j $t9
     nop
     .set reorder
 END(__sync_file_range)
diff --git a/libc/arch-mips/syscalls/__timer_create.S b/libc/arch-mips/syscalls/__timer_create.S
index ef50749..fc1b9a5 100644
--- a/libc/arch-mips/syscalls/__timer_create.S
+++ b/libc/arch-mips/syscalls/__timer_create.S
@@ -4,16 +4,16 @@
 
 ENTRY(__timer_create)
     .set noreorder
-    .cpload t9
-    li v0, __NR_timer_create
+    .cpload $t9
+    li $v0, __NR_timer_create
     syscall
-    bnez a3, 1f
-    move a0, v0
-    j ra
+    bnez $a3, 1f
+    move $a0, $v0
+    j $ra
     nop
 1:
-    la t9,__set_errno_internal
-    j t9
+    la $t9,__set_errno_internal
+    j $t9
     nop
     .set reorder
 END(__timer_create)
diff --git a/libc/arch-mips/syscalls/__timer_delete.S b/libc/arch-mips/syscalls/__timer_delete.S
index 5993ace..b1ca8b7 100644
--- a/libc/arch-mips/syscalls/__timer_delete.S
+++ b/libc/arch-mips/syscalls/__timer_delete.S
@@ -4,16 +4,16 @@
 
 ENTRY(__timer_delete)
     .set noreorder
-    .cpload t9
-    li v0, __NR_timer_delete
+    .cpload $t9
+    li $v0, __NR_timer_delete
     syscall
-    bnez a3, 1f
-    move a0, v0
-    j ra
+    bnez $a3, 1f
+    move $a0, $v0
+    j $ra
     nop
 1:
-    la t9,__set_errno_internal
-    j t9
+    la $t9,__set_errno_internal
+    j $t9
     nop
     .set reorder
 END(__timer_delete)
diff --git a/libc/arch-mips/syscalls/__timer_getoverrun.S b/libc/arch-mips/syscalls/__timer_getoverrun.S
index 31234e5..07e75e5 100644
--- a/libc/arch-mips/syscalls/__timer_getoverrun.S
+++ b/libc/arch-mips/syscalls/__timer_getoverrun.S
@@ -4,16 +4,16 @@
 
 ENTRY(__timer_getoverrun)
     .set noreorder
-    .cpload t9
-    li v0, __NR_timer_getoverrun
+    .cpload $t9
+    li $v0, __NR_timer_getoverrun
     syscall
-    bnez a3, 1f
-    move a0, v0
-    j ra
+    bnez $a3, 1f
+    move $a0, $v0
+    j $ra
     nop
 1:
-    la t9,__set_errno_internal
-    j t9
+    la $t9,__set_errno_internal
+    j $t9
     nop
     .set reorder
 END(__timer_getoverrun)
diff --git a/libc/arch-mips/syscalls/__timer_gettime.S b/libc/arch-mips/syscalls/__timer_gettime.S
index 38800d3..7ee9cad 100644
--- a/libc/arch-mips/syscalls/__timer_gettime.S
+++ b/libc/arch-mips/syscalls/__timer_gettime.S
@@ -4,16 +4,16 @@
 
 ENTRY(__timer_gettime)
     .set noreorder
-    .cpload t9
-    li v0, __NR_timer_gettime
+    .cpload $t9
+    li $v0, __NR_timer_gettime
     syscall
-    bnez a3, 1f
-    move a0, v0
-    j ra
+    bnez $a3, 1f
+    move $a0, $v0
+    j $ra
     nop
 1:
-    la t9,__set_errno_internal
-    j t9
+    la $t9,__set_errno_internal
+    j $t9
     nop
     .set reorder
 END(__timer_gettime)
diff --git a/libc/arch-mips/syscalls/__timer_settime.S b/libc/arch-mips/syscalls/__timer_settime.S
index 73cea73..4f7d95a 100644
--- a/libc/arch-mips/syscalls/__timer_settime.S
+++ b/libc/arch-mips/syscalls/__timer_settime.S
@@ -4,16 +4,16 @@
 
 ENTRY(__timer_settime)
     .set noreorder
-    .cpload t9
-    li v0, __NR_timer_settime
+    .cpload $t9
+    li $v0, __NR_timer_settime
     syscall
-    bnez a3, 1f
-    move a0, v0
-    j ra
+    bnez $a3, 1f
+    move $a0, $v0
+    j $ra
     nop
 1:
-    la t9,__set_errno_internal
-    j t9
+    la $t9,__set_errno_internal
+    j $t9
     nop
     .set reorder
 END(__timer_settime)
diff --git a/libc/arch-mips/syscalls/__waitid.S b/libc/arch-mips/syscalls/__waitid.S
index 9d17f8f..274d7b6 100644
--- a/libc/arch-mips/syscalls/__waitid.S
+++ b/libc/arch-mips/syscalls/__waitid.S
@@ -4,16 +4,16 @@
 
 ENTRY(__waitid)
     .set noreorder
-    .cpload t9
-    li v0, __NR_waitid
+    .cpload $t9
+    li $v0, __NR_waitid
     syscall
-    bnez a3, 1f
-    move a0, v0
-    j ra
+    bnez $a3, 1f
+    move $a0, $v0
+    j $ra
     nop
 1:
-    la t9,__set_errno_internal
-    j t9
+    la $t9,__set_errno_internal
+    j $t9
     nop
     .set reorder
 END(__waitid)
diff --git a/libc/arch-mips/syscalls/_exit.S b/libc/arch-mips/syscalls/_exit.S
index 6e97aac..f41912c 100644
--- a/libc/arch-mips/syscalls/_exit.S
+++ b/libc/arch-mips/syscalls/_exit.S
@@ -4,16 +4,16 @@
 
 ENTRY(_exit)
     .set noreorder
-    .cpload t9
-    li v0, __NR_exit_group
+    .cpload $t9
+    li $v0, __NR_exit_group
     syscall
-    bnez a3, 1f
-    move a0, v0
-    j ra
+    bnez $a3, 1f
+    move $a0, $v0
+    j $ra
     nop
 1:
-    la t9,__set_errno_internal
-    j t9
+    la $t9,__set_errno_internal
+    j $t9
     nop
     .set reorder
 END(_exit)
diff --git a/libc/arch-mips/syscalls/_flush_cache.S b/libc/arch-mips/syscalls/_flush_cache.S
index a4030e9..fa737e8 100644
--- a/libc/arch-mips/syscalls/_flush_cache.S
+++ b/libc/arch-mips/syscalls/_flush_cache.S
@@ -4,16 +4,16 @@
 
 ENTRY(_flush_cache)
     .set noreorder
-    .cpload t9
-    li v0, __NR_cacheflush
+    .cpload $t9
+    li $v0, __NR_cacheflush
     syscall
-    bnez a3, 1f
-    move a0, v0
-    j ra
+    bnez $a3, 1f
+    move $a0, $v0
+    j $ra
     nop
 1:
-    la t9,__set_errno_internal
-    j t9
+    la $t9,__set_errno_internal
+    j $t9
     nop
     .set reorder
 END(_flush_cache)
diff --git a/libc/arch-mips/syscalls/acct.S b/libc/arch-mips/syscalls/acct.S
index e3a5ccd..9908c3f 100644
--- a/libc/arch-mips/syscalls/acct.S
+++ b/libc/arch-mips/syscalls/acct.S
@@ -4,16 +4,16 @@
 
 ENTRY(acct)
     .set noreorder
-    .cpload t9
-    li v0, __NR_acct
+    .cpload $t9
+    li $v0, __NR_acct
     syscall
-    bnez a3, 1f
-    move a0, v0
-    j ra
+    bnez $a3, 1f
+    move $a0, $v0
+    j $ra
     nop
 1:
-    la t9,__set_errno_internal
-    j t9
+    la $t9,__set_errno_internal
+    j $t9
     nop
     .set reorder
 END(acct)
diff --git a/libc/arch-mips/syscalls/adjtimex.S b/libc/arch-mips/syscalls/adjtimex.S
index fef215f..bc525d0 100644
--- a/libc/arch-mips/syscalls/adjtimex.S
+++ b/libc/arch-mips/syscalls/adjtimex.S
@@ -4,16 +4,16 @@
 
 ENTRY(adjtimex)
     .set noreorder
-    .cpload t9
-    li v0, __NR_adjtimex
+    .cpload $t9
+    li $v0, __NR_adjtimex
     syscall
-    bnez a3, 1f
-    move a0, v0
-    j ra
+    bnez $a3, 1f
+    move $a0, $v0
+    j $ra
     nop
 1:
-    la t9,__set_errno_internal
-    j t9
+    la $t9,__set_errno_internal
+    j $t9
     nop
     .set reorder
 END(adjtimex)
diff --git a/libc/arch-mips/syscalls/bind.S b/libc/arch-mips/syscalls/bind.S
index 78fe2bb..cda6e24 100644
--- a/libc/arch-mips/syscalls/bind.S
+++ b/libc/arch-mips/syscalls/bind.S
@@ -4,16 +4,16 @@
 
 ENTRY(bind)
     .set noreorder
-    .cpload t9
-    li v0, __NR_bind
+    .cpload $t9
+    li $v0, __NR_bind
     syscall
-    bnez a3, 1f
-    move a0, v0
-    j ra
+    bnez $a3, 1f
+    move $a0, $v0
+    j $ra
     nop
 1:
-    la t9,__set_errno_internal
-    j t9
+    la $t9,__set_errno_internal
+    j $t9
     nop
     .set reorder
 END(bind)
diff --git a/libc/arch-mips/syscalls/capget.S b/libc/arch-mips/syscalls/capget.S
index 0cbb626..9c8d430 100644
--- a/libc/arch-mips/syscalls/capget.S
+++ b/libc/arch-mips/syscalls/capget.S
@@ -4,16 +4,16 @@
 
 ENTRY(capget)
     .set noreorder
-    .cpload t9
-    li v0, __NR_capget
+    .cpload $t9
+    li $v0, __NR_capget
     syscall
-    bnez a3, 1f
-    move a0, v0
-    j ra
+    bnez $a3, 1f
+    move $a0, $v0
+    j $ra
     nop
 1:
-    la t9,__set_errno_internal
-    j t9
+    la $t9,__set_errno_internal
+    j $t9
     nop
     .set reorder
 END(capget)
diff --git a/libc/arch-mips/syscalls/capset.S b/libc/arch-mips/syscalls/capset.S
index e811080..f30beba 100644
--- a/libc/arch-mips/syscalls/capset.S
+++ b/libc/arch-mips/syscalls/capset.S
@@ -4,16 +4,16 @@
 
 ENTRY(capset)
     .set noreorder
-    .cpload t9
-    li v0, __NR_capset
+    .cpload $t9
+    li $v0, __NR_capset
     syscall
-    bnez a3, 1f
-    move a0, v0
-    j ra
+    bnez $a3, 1f
+    move $a0, $v0
+    j $ra
     nop
 1:
-    la t9,__set_errno_internal
-    j t9
+    la $t9,__set_errno_internal
+    j $t9
     nop
     .set reorder
 END(capset)
diff --git a/libc/arch-mips/syscalls/chdir.S b/libc/arch-mips/syscalls/chdir.S
index 82b7a2b..17de18d 100644
--- a/libc/arch-mips/syscalls/chdir.S
+++ b/libc/arch-mips/syscalls/chdir.S
@@ -4,16 +4,16 @@
 
 ENTRY(chdir)
     .set noreorder
-    .cpload t9
-    li v0, __NR_chdir
+    .cpload $t9
+    li $v0, __NR_chdir
     syscall
-    bnez a3, 1f
-    move a0, v0
-    j ra
+    bnez $a3, 1f
+    move $a0, $v0
+    j $ra
     nop
 1:
-    la t9,__set_errno_internal
-    j t9
+    la $t9,__set_errno_internal
+    j $t9
     nop
     .set reorder
 END(chdir)
diff --git a/libc/arch-mips/syscalls/chroot.S b/libc/arch-mips/syscalls/chroot.S
index e6a29fc..c1998af 100644
--- a/libc/arch-mips/syscalls/chroot.S
+++ b/libc/arch-mips/syscalls/chroot.S
@@ -4,16 +4,16 @@
 
 ENTRY(chroot)
     .set noreorder
-    .cpload t9
-    li v0, __NR_chroot
+    .cpload $t9
+    li $v0, __NR_chroot
     syscall
-    bnez a3, 1f
-    move a0, v0
-    j ra
+    bnez $a3, 1f
+    move $a0, $v0
+    j $ra
     nop
 1:
-    la t9,__set_errno_internal
-    j t9
+    la $t9,__set_errno_internal
+    j $t9
     nop
     .set reorder
 END(chroot)
diff --git a/libc/arch-mips/syscalls/clock_adjtime.S b/libc/arch-mips/syscalls/clock_adjtime.S
index f8a4ce2..10f0d39 100644
--- a/libc/arch-mips/syscalls/clock_adjtime.S
+++ b/libc/arch-mips/syscalls/clock_adjtime.S
@@ -4,16 +4,16 @@
 
 ENTRY(clock_adjtime)
     .set noreorder
-    .cpload t9
-    li v0, __NR_clock_adjtime
+    .cpload $t9
+    li $v0, __NR_clock_adjtime
     syscall
-    bnez a3, 1f
-    move a0, v0
-    j ra
+    bnez $a3, 1f
+    move $a0, $v0
+    j $ra
     nop
 1:
-    la t9,__set_errno_internal
-    j t9
+    la $t9,__set_errno_internal
+    j $t9
     nop
     .set reorder
 END(clock_adjtime)
diff --git a/libc/arch-mips/syscalls/clock_getres.S b/libc/arch-mips/syscalls/clock_getres.S
index ac7c5c6..153f629 100644
--- a/libc/arch-mips/syscalls/clock_getres.S
+++ b/libc/arch-mips/syscalls/clock_getres.S
@@ -4,16 +4,16 @@
 
 ENTRY(clock_getres)
     .set noreorder
-    .cpload t9
-    li v0, __NR_clock_getres
+    .cpload $t9
+    li $v0, __NR_clock_getres
     syscall
-    bnez a3, 1f
-    move a0, v0
-    j ra
+    bnez $a3, 1f
+    move $a0, $v0
+    j $ra
     nop
 1:
-    la t9,__set_errno_internal
-    j t9
+    la $t9,__set_errno_internal
+    j $t9
     nop
     .set reorder
 END(clock_getres)
diff --git a/libc/arch-mips/syscalls/clock_settime.S b/libc/arch-mips/syscalls/clock_settime.S
index 193bdc2..651729d 100644
--- a/libc/arch-mips/syscalls/clock_settime.S
+++ b/libc/arch-mips/syscalls/clock_settime.S
@@ -4,16 +4,16 @@
 
 ENTRY(clock_settime)
     .set noreorder
-    .cpload t9
-    li v0, __NR_clock_settime
+    .cpload $t9
+    li $v0, __NR_clock_settime
     syscall
-    bnez a3, 1f
-    move a0, v0
-    j ra
+    bnez $a3, 1f
+    move $a0, $v0
+    j $ra
     nop
 1:
-    la t9,__set_errno_internal
-    j t9
+    la $t9,__set_errno_internal
+    j $t9
     nop
     .set reorder
 END(clock_settime)
diff --git a/libc/arch-mips/syscalls/delete_module.S b/libc/arch-mips/syscalls/delete_module.S
index 8c01c06..def5a16 100644
--- a/libc/arch-mips/syscalls/delete_module.S
+++ b/libc/arch-mips/syscalls/delete_module.S
@@ -4,16 +4,16 @@
 
 ENTRY(delete_module)
     .set noreorder
-    .cpload t9
-    li v0, __NR_delete_module
+    .cpload $t9
+    li $v0, __NR_delete_module
     syscall
-    bnez a3, 1f
-    move a0, v0
-    j ra
+    bnez $a3, 1f
+    move $a0, $v0
+    j $ra
     nop
 1:
-    la t9,__set_errno_internal
-    j t9
+    la $t9,__set_errno_internal
+    j $t9
     nop
     .set reorder
 END(delete_module)
diff --git a/libc/arch-mips/syscalls/dup.S b/libc/arch-mips/syscalls/dup.S
index b4dcd70..0c0ee8d 100644
--- a/libc/arch-mips/syscalls/dup.S
+++ b/libc/arch-mips/syscalls/dup.S
@@ -4,16 +4,16 @@
 
 ENTRY(dup)
     .set noreorder
-    .cpload t9
-    li v0, __NR_dup
+    .cpload $t9
+    li $v0, __NR_dup
     syscall
-    bnez a3, 1f
-    move a0, v0
-    j ra
+    bnez $a3, 1f
+    move $a0, $v0
+    j $ra
     nop
 1:
-    la t9,__set_errno_internal
-    j t9
+    la $t9,__set_errno_internal
+    j $t9
     nop
     .set reorder
 END(dup)
diff --git a/libc/arch-mips/syscalls/dup3.S b/libc/arch-mips/syscalls/dup3.S
index 1d9c236..cbec960 100644
--- a/libc/arch-mips/syscalls/dup3.S
+++ b/libc/arch-mips/syscalls/dup3.S
@@ -4,16 +4,16 @@
 
 ENTRY(dup3)
     .set noreorder
-    .cpload t9
-    li v0, __NR_dup3
+    .cpload $t9
+    li $v0, __NR_dup3
     syscall
-    bnez a3, 1f
-    move a0, v0
-    j ra
+    bnez $a3, 1f
+    move $a0, $v0
+    j $ra
     nop
 1:
-    la t9,__set_errno_internal
-    j t9
+    la $t9,__set_errno_internal
+    j $t9
     nop
     .set reorder
 END(dup3)
diff --git a/libc/arch-mips/syscalls/epoll_create1.S b/libc/arch-mips/syscalls/epoll_create1.S
index 8754879..fc268fe 100644
--- a/libc/arch-mips/syscalls/epoll_create1.S
+++ b/libc/arch-mips/syscalls/epoll_create1.S
@@ -4,16 +4,16 @@
 
 ENTRY(epoll_create1)
     .set noreorder
-    .cpload t9
-    li v0, __NR_epoll_create1
+    .cpload $t9
+    li $v0, __NR_epoll_create1
     syscall
-    bnez a3, 1f
-    move a0, v0
-    j ra
+    bnez $a3, 1f
+    move $a0, $v0
+    j $ra
     nop
 1:
-    la t9,__set_errno_internal
-    j t9
+    la $t9,__set_errno_internal
+    j $t9
     nop
     .set reorder
 END(epoll_create1)
diff --git a/libc/arch-mips/syscalls/epoll_ctl.S b/libc/arch-mips/syscalls/epoll_ctl.S
index 14c9202..222c97a 100644
--- a/libc/arch-mips/syscalls/epoll_ctl.S
+++ b/libc/arch-mips/syscalls/epoll_ctl.S
@@ -4,16 +4,16 @@
 
 ENTRY(epoll_ctl)
     .set noreorder
-    .cpload t9
-    li v0, __NR_epoll_ctl
+    .cpload $t9
+    li $v0, __NR_epoll_ctl
     syscall
-    bnez a3, 1f
-    move a0, v0
-    j ra
+    bnez $a3, 1f
+    move $a0, $v0
+    j $ra
     nop
 1:
-    la t9,__set_errno_internal
-    j t9
+    la $t9,__set_errno_internal
+    j $t9
     nop
     .set reorder
 END(epoll_ctl)
diff --git a/libc/arch-mips/syscalls/eventfd.S b/libc/arch-mips/syscalls/eventfd.S
index 6494dbc..2bca718 100644
--- a/libc/arch-mips/syscalls/eventfd.S
+++ b/libc/arch-mips/syscalls/eventfd.S
@@ -4,16 +4,16 @@
 
 ENTRY(eventfd)
     .set noreorder
-    .cpload t9
-    li v0, __NR_eventfd2
+    .cpload $t9
+    li $v0, __NR_eventfd2
     syscall
-    bnez a3, 1f
-    move a0, v0
-    j ra
+    bnez $a3, 1f
+    move $a0, $v0
+    j $ra
     nop
 1:
-    la t9,__set_errno_internal
-    j t9
+    la $t9,__set_errno_internal
+    j $t9
     nop
     .set reorder
 END(eventfd)
diff --git a/libc/arch-mips/syscalls/execve.S b/libc/arch-mips/syscalls/execve.S
index 2d20b51..3dd36a1 100644
--- a/libc/arch-mips/syscalls/execve.S
+++ b/libc/arch-mips/syscalls/execve.S
@@ -4,16 +4,16 @@
 
 ENTRY(execve)
     .set noreorder
-    .cpload t9
-    li v0, __NR_execve
+    .cpload $t9
+    li $v0, __NR_execve
     syscall
-    bnez a3, 1f
-    move a0, v0
-    j ra
+    bnez $a3, 1f
+    move $a0, $v0
+    j $ra
     nop
 1:
-    la t9,__set_errno_internal
-    j t9
+    la $t9,__set_errno_internal
+    j $t9
     nop
     .set reorder
 END(execve)
diff --git a/libc/arch-mips/syscalls/fallocate64.S b/libc/arch-mips/syscalls/fallocate64.S
index 5f05513..ed50bb5 100644
--- a/libc/arch-mips/syscalls/fallocate64.S
+++ b/libc/arch-mips/syscalls/fallocate64.S
@@ -4,16 +4,16 @@
 
 ENTRY(fallocate64)
     .set noreorder
-    .cpload t9
-    li v0, __NR_fallocate
+    .cpload $t9
+    li $v0, __NR_fallocate
     syscall
-    bnez a3, 1f
-    move a0, v0
-    j ra
+    bnez $a3, 1f
+    move $a0, $v0
+    j $ra
     nop
 1:
-    la t9,__set_errno_internal
-    j t9
+    la $t9,__set_errno_internal
+    j $t9
     nop
     .set reorder
 END(fallocate64)
diff --git a/libc/arch-mips/syscalls/fchdir.S b/libc/arch-mips/syscalls/fchdir.S
index d683baa..5b92e85 100644
--- a/libc/arch-mips/syscalls/fchdir.S
+++ b/libc/arch-mips/syscalls/fchdir.S
@@ -4,16 +4,16 @@
 
 ENTRY(fchdir)
     .set noreorder
-    .cpload t9
-    li v0, __NR_fchdir
+    .cpload $t9
+    li $v0, __NR_fchdir
     syscall
-    bnez a3, 1f
-    move a0, v0
-    j ra
+    bnez $a3, 1f
+    move $a0, $v0
+    j $ra
     nop
 1:
-    la t9,__set_errno_internal
-    j t9
+    la $t9,__set_errno_internal
+    j $t9
     nop
     .set reorder
 END(fchdir)
diff --git a/libc/arch-mips/syscalls/fchown.S b/libc/arch-mips/syscalls/fchown.S
index 1ac9451..afd96e8 100644
--- a/libc/arch-mips/syscalls/fchown.S
+++ b/libc/arch-mips/syscalls/fchown.S
@@ -4,16 +4,16 @@
 
 ENTRY(fchown)
     .set noreorder
-    .cpload t9
-    li v0, __NR_fchown
+    .cpload $t9
+    li $v0, __NR_fchown
     syscall
-    bnez a3, 1f
-    move a0, v0
-    j ra
+    bnez $a3, 1f
+    move $a0, $v0
+    j $ra
     nop
 1:
-    la t9,__set_errno_internal
-    j t9
+    la $t9,__set_errno_internal
+    j $t9
     nop
     .set reorder
 END(fchown)
diff --git a/libc/arch-mips/syscalls/fchownat.S b/libc/arch-mips/syscalls/fchownat.S
index be1a021..be2021b 100644
--- a/libc/arch-mips/syscalls/fchownat.S
+++ b/libc/arch-mips/syscalls/fchownat.S
@@ -4,16 +4,16 @@
 
 ENTRY(fchownat)
     .set noreorder
-    .cpload t9
-    li v0, __NR_fchownat
+    .cpload $t9
+    li $v0, __NR_fchownat
     syscall
-    bnez a3, 1f
-    move a0, v0
-    j ra
+    bnez $a3, 1f
+    move $a0, $v0
+    j $ra
     nop
 1:
-    la t9,__set_errno_internal
-    j t9
+    la $t9,__set_errno_internal
+    j $t9
     nop
     .set reorder
 END(fchownat)
diff --git a/libc/arch-mips/syscalls/fdatasync.S b/libc/arch-mips/syscalls/fdatasync.S
index 24d6541..0b37d8f 100644
--- a/libc/arch-mips/syscalls/fdatasync.S
+++ b/libc/arch-mips/syscalls/fdatasync.S
@@ -4,16 +4,16 @@
 
 ENTRY(fdatasync)
     .set noreorder
-    .cpload t9
-    li v0, __NR_fdatasync
+    .cpload $t9
+    li $v0, __NR_fdatasync
     syscall
-    bnez a3, 1f
-    move a0, v0
-    j ra
+    bnez $a3, 1f
+    move $a0, $v0
+    j $ra
     nop
 1:
-    la t9,__set_errno_internal
-    j t9
+    la $t9,__set_errno_internal
+    j $t9
     nop
     .set reorder
 END(fdatasync)
diff --git a/libc/arch-mips/syscalls/flock.S b/libc/arch-mips/syscalls/flock.S
index 8d70c9e..badb41d 100644
--- a/libc/arch-mips/syscalls/flock.S
+++ b/libc/arch-mips/syscalls/flock.S
@@ -4,16 +4,16 @@
 
 ENTRY(flock)
     .set noreorder
-    .cpload t9
-    li v0, __NR_flock
+    .cpload $t9
+    li $v0, __NR_flock
     syscall
-    bnez a3, 1f
-    move a0, v0
-    j ra
+    bnez $a3, 1f
+    move $a0, $v0
+    j $ra
     nop
 1:
-    la t9,__set_errno_internal
-    j t9
+    la $t9,__set_errno_internal
+    j $t9
     nop
     .set reorder
 END(flock)
diff --git a/libc/arch-mips/syscalls/fremovexattr.S b/libc/arch-mips/syscalls/fremovexattr.S
index fba2d6d..290ecc8 100644
--- a/libc/arch-mips/syscalls/fremovexattr.S
+++ b/libc/arch-mips/syscalls/fremovexattr.S
@@ -4,16 +4,16 @@
 
 ENTRY(fremovexattr)
     .set noreorder
-    .cpload t9
-    li v0, __NR_fremovexattr
+    .cpload $t9
+    li $v0, __NR_fremovexattr
     syscall
-    bnez a3, 1f
-    move a0, v0
-    j ra
+    bnez $a3, 1f
+    move $a0, $v0
+    j $ra
     nop
 1:
-    la t9,__set_errno_internal
-    j t9
+    la $t9,__set_errno_internal
+    j $t9
     nop
     .set reorder
 END(fremovexattr)
diff --git a/libc/arch-mips/syscalls/fstat64.S b/libc/arch-mips/syscalls/fstat64.S
index 16e2791..3ecc2ba 100644
--- a/libc/arch-mips/syscalls/fstat64.S
+++ b/libc/arch-mips/syscalls/fstat64.S
@@ -4,16 +4,16 @@
 
 ENTRY(fstat64)
     .set noreorder
-    .cpload t9
-    li v0, __NR_fstat64
+    .cpload $t9
+    li $v0, __NR_fstat64
     syscall
-    bnez a3, 1f
-    move a0, v0
-    j ra
+    bnez $a3, 1f
+    move $a0, $v0
+    j $ra
     nop
 1:
-    la t9,__set_errno_internal
-    j t9
+    la $t9,__set_errno_internal
+    j $t9
     nop
     .set reorder
 END(fstat64)
diff --git a/libc/arch-mips/syscalls/fstatat64.S b/libc/arch-mips/syscalls/fstatat64.S
index ebcf6b0..5b7550c 100644
--- a/libc/arch-mips/syscalls/fstatat64.S
+++ b/libc/arch-mips/syscalls/fstatat64.S
@@ -4,16 +4,16 @@
 
 ENTRY(fstatat64)
     .set noreorder
-    .cpload t9
-    li v0, __NR_fstatat64
+    .cpload $t9
+    li $v0, __NR_fstatat64
     syscall
-    bnez a3, 1f
-    move a0, v0
-    j ra
+    bnez $a3, 1f
+    move $a0, $v0
+    j $ra
     nop
 1:
-    la t9,__set_errno_internal
-    j t9
+    la $t9,__set_errno_internal
+    j $t9
     nop
     .set reorder
 END(fstatat64)
diff --git a/libc/arch-mips/syscalls/fsync.S b/libc/arch-mips/syscalls/fsync.S
index 819f0f2..24e86a2 100644
--- a/libc/arch-mips/syscalls/fsync.S
+++ b/libc/arch-mips/syscalls/fsync.S
@@ -4,16 +4,16 @@
 
 ENTRY(fsync)
     .set noreorder
-    .cpload t9
-    li v0, __NR_fsync
+    .cpload $t9
+    li $v0, __NR_fsync
     syscall
-    bnez a3, 1f
-    move a0, v0
-    j ra
+    bnez $a3, 1f
+    move $a0, $v0
+    j $ra
     nop
 1:
-    la t9,__set_errno_internal
-    j t9
+    la $t9,__set_errno_internal
+    j $t9
     nop
     .set reorder
 END(fsync)
diff --git a/libc/arch-mips/syscalls/ftruncate64.S b/libc/arch-mips/syscalls/ftruncate64.S
index 059ff77..858141c 100644
--- a/libc/arch-mips/syscalls/ftruncate64.S
+++ b/libc/arch-mips/syscalls/ftruncate64.S
@@ -4,16 +4,16 @@
 
 ENTRY(ftruncate64)
     .set noreorder
-    .cpload t9
-    li v0, __NR_ftruncate64
+    .cpload $t9
+    li $v0, __NR_ftruncate64
     syscall
-    bnez a3, 1f
-    move a0, v0
-    j ra
+    bnez $a3, 1f
+    move $a0, $v0
+    j $ra
     nop
 1:
-    la t9,__set_errno_internal
-    j t9
+    la $t9,__set_errno_internal
+    j $t9
     nop
     .set reorder
 END(ftruncate64)
diff --git a/libc/arch-mips/syscalls/getegid.S b/libc/arch-mips/syscalls/getegid.S
index 8ae2d1e..6bdf47f 100644
--- a/libc/arch-mips/syscalls/getegid.S
+++ b/libc/arch-mips/syscalls/getegid.S
@@ -4,16 +4,16 @@
 
 ENTRY(getegid)
     .set noreorder
-    .cpload t9
-    li v0, __NR_getegid
+    .cpload $t9
+    li $v0, __NR_getegid
     syscall
-    bnez a3, 1f
-    move a0, v0
-    j ra
+    bnez $a3, 1f
+    move $a0, $v0
+    j $ra
     nop
 1:
-    la t9,__set_errno_internal
-    j t9
+    la $t9,__set_errno_internal
+    j $t9
     nop
     .set reorder
 END(getegid)
diff --git a/libc/arch-mips/syscalls/geteuid.S b/libc/arch-mips/syscalls/geteuid.S
index cf5cf6c..07b571e 100644
--- a/libc/arch-mips/syscalls/geteuid.S
+++ b/libc/arch-mips/syscalls/geteuid.S
@@ -4,16 +4,16 @@
 
 ENTRY(geteuid)
     .set noreorder
-    .cpload t9
-    li v0, __NR_geteuid
+    .cpload $t9
+    li $v0, __NR_geteuid
     syscall
-    bnez a3, 1f
-    move a0, v0
-    j ra
+    bnez $a3, 1f
+    move $a0, $v0
+    j $ra
     nop
 1:
-    la t9,__set_errno_internal
-    j t9
+    la $t9,__set_errno_internal
+    j $t9
     nop
     .set reorder
 END(geteuid)
diff --git a/libc/arch-mips/syscalls/getgid.S b/libc/arch-mips/syscalls/getgid.S
index 9bd1fc3..a2020fa 100644
--- a/libc/arch-mips/syscalls/getgid.S
+++ b/libc/arch-mips/syscalls/getgid.S
@@ -4,16 +4,16 @@
 
 ENTRY(getgid)
     .set noreorder
-    .cpload t9
-    li v0, __NR_getgid
+    .cpload $t9
+    li $v0, __NR_getgid
     syscall
-    bnez a3, 1f
-    move a0, v0
-    j ra
+    bnez $a3, 1f
+    move $a0, $v0
+    j $ra
     nop
 1:
-    la t9,__set_errno_internal
-    j t9
+    la $t9,__set_errno_internal
+    j $t9
     nop
     .set reorder
 END(getgid)
diff --git a/libc/arch-mips/syscalls/getgroups.S b/libc/arch-mips/syscalls/getgroups.S
index 2eda185..86510dc 100644
--- a/libc/arch-mips/syscalls/getgroups.S
+++ b/libc/arch-mips/syscalls/getgroups.S
@@ -4,16 +4,16 @@
 
 ENTRY(getgroups)
     .set noreorder
-    .cpload t9
-    li v0, __NR_getgroups
+    .cpload $t9
+    li $v0, __NR_getgroups
     syscall
-    bnez a3, 1f
-    move a0, v0
-    j ra
+    bnez $a3, 1f
+    move $a0, $v0
+    j $ra
     nop
 1:
-    la t9,__set_errno_internal
-    j t9
+    la $t9,__set_errno_internal
+    j $t9
     nop
     .set reorder
 END(getgroups)
diff --git a/libc/arch-mips/syscalls/getitimer.S b/libc/arch-mips/syscalls/getitimer.S
index 2e382c7..6d671f5 100644
--- a/libc/arch-mips/syscalls/getitimer.S
+++ b/libc/arch-mips/syscalls/getitimer.S
@@ -4,16 +4,16 @@
 
 ENTRY(getitimer)
     .set noreorder
-    .cpload t9
-    li v0, __NR_getitimer
+    .cpload $t9
+    li $v0, __NR_getitimer
     syscall
-    bnez a3, 1f
-    move a0, v0
-    j ra
+    bnez $a3, 1f
+    move $a0, $v0
+    j $ra
     nop
 1:
-    la t9,__set_errno_internal
-    j t9
+    la $t9,__set_errno_internal
+    j $t9
     nop
     .set reorder
 END(getitimer)
diff --git a/libc/arch-mips/syscalls/getpeername.S b/libc/arch-mips/syscalls/getpeername.S
index 8642798..b372574 100644
--- a/libc/arch-mips/syscalls/getpeername.S
+++ b/libc/arch-mips/syscalls/getpeername.S
@@ -4,16 +4,16 @@
 
 ENTRY(getpeername)
     .set noreorder
-    .cpload t9
-    li v0, __NR_getpeername
+    .cpload $t9
+    li $v0, __NR_getpeername
     syscall
-    bnez a3, 1f
-    move a0, v0
-    j ra
+    bnez $a3, 1f
+    move $a0, $v0
+    j $ra
     nop
 1:
-    la t9,__set_errno_internal
-    j t9
+    la $t9,__set_errno_internal
+    j $t9
     nop
     .set reorder
 END(getpeername)
diff --git a/libc/arch-mips/syscalls/getpgid.S b/libc/arch-mips/syscalls/getpgid.S
index 562b9ce..25a1fdf 100644
--- a/libc/arch-mips/syscalls/getpgid.S
+++ b/libc/arch-mips/syscalls/getpgid.S
@@ -4,16 +4,16 @@
 
 ENTRY(getpgid)
     .set noreorder
-    .cpload t9
-    li v0, __NR_getpgid
+    .cpload $t9
+    li $v0, __NR_getpgid
     syscall
-    bnez a3, 1f
-    move a0, v0
-    j ra
+    bnez $a3, 1f
+    move $a0, $v0
+    j $ra
     nop
 1:
-    la t9,__set_errno_internal
-    j t9
+    la $t9,__set_errno_internal
+    j $t9
     nop
     .set reorder
 END(getpgid)
diff --git a/libc/arch-mips/syscalls/getppid.S b/libc/arch-mips/syscalls/getppid.S
index afff0b9..54f1252 100644
--- a/libc/arch-mips/syscalls/getppid.S
+++ b/libc/arch-mips/syscalls/getppid.S
@@ -4,16 +4,16 @@
 
 ENTRY(getppid)
     .set noreorder
-    .cpload t9
-    li v0, __NR_getppid
+    .cpload $t9
+    li $v0, __NR_getppid
     syscall
-    bnez a3, 1f
-    move a0, v0
-    j ra
+    bnez $a3, 1f
+    move $a0, $v0
+    j $ra
     nop
 1:
-    la t9,__set_errno_internal
-    j t9
+    la $t9,__set_errno_internal
+    j $t9
     nop
     .set reorder
 END(getppid)
diff --git a/libc/arch-mips/syscalls/getrandom.S b/libc/arch-mips/syscalls/getrandom.S
new file mode 100644
index 0000000..9a32c78
--- /dev/null
+++ b/libc/arch-mips/syscalls/getrandom.S
@@ -0,0 +1,19 @@
+/* Generated by gensyscalls.py. Do not edit. */
+
+#include <private/bionic_asm.h>
+
+ENTRY(getrandom)
+    .set noreorder
+    .cpload $t9
+    li $v0, __NR_getrandom
+    syscall
+    bnez $a3, 1f
+    move $a0, $v0
+    j $ra
+    nop
+1:
+    la $t9,__set_errno_internal
+    j $t9
+    nop
+    .set reorder
+END(getrandom)
diff --git a/libc/arch-mips/syscalls/getresgid.S b/libc/arch-mips/syscalls/getresgid.S
index 248d3f9..8336f66 100644
--- a/libc/arch-mips/syscalls/getresgid.S
+++ b/libc/arch-mips/syscalls/getresgid.S
@@ -4,16 +4,16 @@
 
 ENTRY(getresgid)
     .set noreorder
-    .cpload t9
-    li v0, __NR_getresgid
+    .cpload $t9
+    li $v0, __NR_getresgid
     syscall
-    bnez a3, 1f
-    move a0, v0
-    j ra
+    bnez $a3, 1f
+    move $a0, $v0
+    j $ra
     nop
 1:
-    la t9,__set_errno_internal
-    j t9
+    la $t9,__set_errno_internal
+    j $t9
     nop
     .set reorder
 END(getresgid)
diff --git a/libc/arch-mips/syscalls/getresuid.S b/libc/arch-mips/syscalls/getresuid.S
index 924b6cd..9e4cb36 100644
--- a/libc/arch-mips/syscalls/getresuid.S
+++ b/libc/arch-mips/syscalls/getresuid.S
@@ -4,16 +4,16 @@
 
 ENTRY(getresuid)
     .set noreorder
-    .cpload t9
-    li v0, __NR_getresuid
+    .cpload $t9
+    li $v0, __NR_getresuid
     syscall
-    bnez a3, 1f
-    move a0, v0
-    j ra
+    bnez $a3, 1f
+    move $a0, $v0
+    j $ra
     nop
 1:
-    la t9,__set_errno_internal
-    j t9
+    la $t9,__set_errno_internal
+    j $t9
     nop
     .set reorder
 END(getresuid)
diff --git a/libc/arch-mips/syscalls/getrlimit.S b/libc/arch-mips/syscalls/getrlimit.S
index 19570d6..2ae1c04 100644
--- a/libc/arch-mips/syscalls/getrlimit.S
+++ b/libc/arch-mips/syscalls/getrlimit.S
@@ -4,16 +4,16 @@
 
 ENTRY(getrlimit)
     .set noreorder
-    .cpload t9
-    li v0, __NR_getrlimit
+    .cpload $t9
+    li $v0, __NR_getrlimit
     syscall
-    bnez a3, 1f
-    move a0, v0
-    j ra
+    bnez $a3, 1f
+    move $a0, $v0
+    j $ra
     nop
 1:
-    la t9,__set_errno_internal
-    j t9
+    la $t9,__set_errno_internal
+    j $t9
     nop
     .set reorder
 END(getrlimit)
diff --git a/libc/arch-mips/syscalls/getrusage.S b/libc/arch-mips/syscalls/getrusage.S
index 75bc8bc..c4a5aec 100644
--- a/libc/arch-mips/syscalls/getrusage.S
+++ b/libc/arch-mips/syscalls/getrusage.S
@@ -4,16 +4,16 @@
 
 ENTRY(getrusage)
     .set noreorder
-    .cpload t9
-    li v0, __NR_getrusage
+    .cpload $t9
+    li $v0, __NR_getrusage
     syscall
-    bnez a3, 1f
-    move a0, v0
-    j ra
+    bnez $a3, 1f
+    move $a0, $v0
+    j $ra
     nop
 1:
-    la t9,__set_errno_internal
-    j t9
+    la $t9,__set_errno_internal
+    j $t9
     nop
     .set reorder
 END(getrusage)
diff --git a/libc/arch-mips/syscalls/getsid.S b/libc/arch-mips/syscalls/getsid.S
index 6436ecd..26f84c3 100644
--- a/libc/arch-mips/syscalls/getsid.S
+++ b/libc/arch-mips/syscalls/getsid.S
@@ -4,16 +4,16 @@
 
 ENTRY(getsid)
     .set noreorder
-    .cpload t9
-    li v0, __NR_getsid
+    .cpload $t9
+    li $v0, __NR_getsid
     syscall
-    bnez a3, 1f
-    move a0, v0
-    j ra
+    bnez $a3, 1f
+    move $a0, $v0
+    j $ra
     nop
 1:
-    la t9,__set_errno_internal
-    j t9
+    la $t9,__set_errno_internal
+    j $t9
     nop
     .set reorder
 END(getsid)
diff --git a/libc/arch-mips/syscalls/getsockname.S b/libc/arch-mips/syscalls/getsockname.S
index ffadd92..f54df87 100644
--- a/libc/arch-mips/syscalls/getsockname.S
+++ b/libc/arch-mips/syscalls/getsockname.S
@@ -4,16 +4,16 @@
 
 ENTRY(getsockname)
     .set noreorder
-    .cpload t9
-    li v0, __NR_getsockname
+    .cpload $t9
+    li $v0, __NR_getsockname
     syscall
-    bnez a3, 1f
-    move a0, v0
-    j ra
+    bnez $a3, 1f
+    move $a0, $v0
+    j $ra
     nop
 1:
-    la t9,__set_errno_internal
-    j t9
+    la $t9,__set_errno_internal
+    j $t9
     nop
     .set reorder
 END(getsockname)
diff --git a/libc/arch-mips/syscalls/getsockopt.S b/libc/arch-mips/syscalls/getsockopt.S
index 6ebe15e..32cd721 100644
--- a/libc/arch-mips/syscalls/getsockopt.S
+++ b/libc/arch-mips/syscalls/getsockopt.S
@@ -4,16 +4,16 @@
 
 ENTRY(getsockopt)
     .set noreorder
-    .cpload t9
-    li v0, __NR_getsockopt
+    .cpload $t9
+    li $v0, __NR_getsockopt
     syscall
-    bnez a3, 1f
-    move a0, v0
-    j ra
+    bnez $a3, 1f
+    move $a0, $v0
+    j $ra
     nop
 1:
-    la t9,__set_errno_internal
-    j t9
+    la $t9,__set_errno_internal
+    j $t9
     nop
     .set reorder
 END(getsockopt)
diff --git a/libc/arch-mips/syscalls/getuid.S b/libc/arch-mips/syscalls/getuid.S
index 5858632..d2fe78f 100644
--- a/libc/arch-mips/syscalls/getuid.S
+++ b/libc/arch-mips/syscalls/getuid.S
@@ -4,16 +4,16 @@
 
 ENTRY(getuid)
     .set noreorder
-    .cpload t9
-    li v0, __NR_getuid
+    .cpload $t9
+    li $v0, __NR_getuid
     syscall
-    bnez a3, 1f
-    move a0, v0
-    j ra
+    bnez $a3, 1f
+    move $a0, $v0
+    j $ra
     nop
 1:
-    la t9,__set_errno_internal
-    j t9
+    la $t9,__set_errno_internal
+    j $t9
     nop
     .set reorder
 END(getuid)
diff --git a/libc/arch-mips/syscalls/getxattr.S b/libc/arch-mips/syscalls/getxattr.S
index 28c7fe6..0e5a33f 100644
--- a/libc/arch-mips/syscalls/getxattr.S
+++ b/libc/arch-mips/syscalls/getxattr.S
@@ -4,16 +4,16 @@
 
 ENTRY(getxattr)
     .set noreorder
-    .cpload t9
-    li v0, __NR_getxattr
+    .cpload $t9
+    li $v0, __NR_getxattr
     syscall
-    bnez a3, 1f
-    move a0, v0
-    j ra
+    bnez $a3, 1f
+    move $a0, $v0
+    j $ra
     nop
 1:
-    la t9,__set_errno_internal
-    j t9
+    la $t9,__set_errno_internal
+    j $t9
     nop
     .set reorder
 END(getxattr)
diff --git a/libc/arch-mips/syscalls/init_module.S b/libc/arch-mips/syscalls/init_module.S
index 989614a..e4434c3 100644
--- a/libc/arch-mips/syscalls/init_module.S
+++ b/libc/arch-mips/syscalls/init_module.S
@@ -4,16 +4,16 @@
 
 ENTRY(init_module)
     .set noreorder
-    .cpload t9
-    li v0, __NR_init_module
+    .cpload $t9
+    li $v0, __NR_init_module
     syscall
-    bnez a3, 1f
-    move a0, v0
-    j ra
+    bnez $a3, 1f
+    move $a0, $v0
+    j $ra
     nop
 1:
-    la t9,__set_errno_internal
-    j t9
+    la $t9,__set_errno_internal
+    j $t9
     nop
     .set reorder
 END(init_module)
diff --git a/libc/arch-mips/syscalls/inotify_add_watch.S b/libc/arch-mips/syscalls/inotify_add_watch.S
index 7d3315f..3710cb7 100644
--- a/libc/arch-mips/syscalls/inotify_add_watch.S
+++ b/libc/arch-mips/syscalls/inotify_add_watch.S
@@ -4,16 +4,16 @@
 
 ENTRY(inotify_add_watch)
     .set noreorder
-    .cpload t9
-    li v0, __NR_inotify_add_watch
+    .cpload $t9
+    li $v0, __NR_inotify_add_watch
     syscall
-    bnez a3, 1f
-    move a0, v0
-    j ra
+    bnez $a3, 1f
+    move $a0, $v0
+    j $ra
     nop
 1:
-    la t9,__set_errno_internal
-    j t9
+    la $t9,__set_errno_internal
+    j $t9
     nop
     .set reorder
 END(inotify_add_watch)
diff --git a/libc/arch-mips/syscalls/inotify_init1.S b/libc/arch-mips/syscalls/inotify_init1.S
index e4ec266..b38f018 100644
--- a/libc/arch-mips/syscalls/inotify_init1.S
+++ b/libc/arch-mips/syscalls/inotify_init1.S
@@ -4,16 +4,16 @@
 
 ENTRY(inotify_init1)
     .set noreorder
-    .cpload t9
-    li v0, __NR_inotify_init1
+    .cpload $t9
+    li $v0, __NR_inotify_init1
     syscall
-    bnez a3, 1f
-    move a0, v0
-    j ra
+    bnez $a3, 1f
+    move $a0, $v0
+    j $ra
     nop
 1:
-    la t9,__set_errno_internal
-    j t9
+    la $t9,__set_errno_internal
+    j $t9
     nop
     .set reorder
 END(inotify_init1)
diff --git a/libc/arch-mips/syscalls/inotify_rm_watch.S b/libc/arch-mips/syscalls/inotify_rm_watch.S
index eec9856..a7b6fbe 100644
--- a/libc/arch-mips/syscalls/inotify_rm_watch.S
+++ b/libc/arch-mips/syscalls/inotify_rm_watch.S
@@ -4,16 +4,16 @@
 
 ENTRY(inotify_rm_watch)
     .set noreorder
-    .cpload t9
-    li v0, __NR_inotify_rm_watch
+    .cpload $t9
+    li $v0, __NR_inotify_rm_watch
     syscall
-    bnez a3, 1f
-    move a0, v0
-    j ra
+    bnez $a3, 1f
+    move $a0, $v0
+    j $ra
     nop
 1:
-    la t9,__set_errno_internal
-    j t9
+    la $t9,__set_errno_internal
+    j $t9
     nop
     .set reorder
 END(inotify_rm_watch)
diff --git a/libc/arch-mips/syscalls/kill.S b/libc/arch-mips/syscalls/kill.S
index 415da73..1075da1 100644
--- a/libc/arch-mips/syscalls/kill.S
+++ b/libc/arch-mips/syscalls/kill.S
@@ -4,16 +4,16 @@
 
 ENTRY(kill)
     .set noreorder
-    .cpload t9
-    li v0, __NR_kill
+    .cpload $t9
+    li $v0, __NR_kill
     syscall
-    bnez a3, 1f
-    move a0, v0
-    j ra
+    bnez $a3, 1f
+    move $a0, $v0
+    j $ra
     nop
 1:
-    la t9,__set_errno_internal
-    j t9
+    la $t9,__set_errno_internal
+    j $t9
     nop
     .set reorder
 END(kill)
diff --git a/libc/arch-mips/syscalls/klogctl.S b/libc/arch-mips/syscalls/klogctl.S
index 123d8a0..c3fa53c 100644
--- a/libc/arch-mips/syscalls/klogctl.S
+++ b/libc/arch-mips/syscalls/klogctl.S
@@ -4,16 +4,16 @@
 
 ENTRY(klogctl)
     .set noreorder
-    .cpload t9
-    li v0, __NR_syslog
+    .cpload $t9
+    li $v0, __NR_syslog
     syscall
-    bnez a3, 1f
-    move a0, v0
-    j ra
+    bnez $a3, 1f
+    move $a0, $v0
+    j $ra
     nop
 1:
-    la t9,__set_errno_internal
-    j t9
+    la $t9,__set_errno_internal
+    j $t9
     nop
     .set reorder
 END(klogctl)
diff --git a/libc/arch-mips/syscalls/lgetxattr.S b/libc/arch-mips/syscalls/lgetxattr.S
index a9916d9..b05850d 100644
--- a/libc/arch-mips/syscalls/lgetxattr.S
+++ b/libc/arch-mips/syscalls/lgetxattr.S
@@ -4,16 +4,16 @@
 
 ENTRY(lgetxattr)
     .set noreorder
-    .cpload t9
-    li v0, __NR_lgetxattr
+    .cpload $t9
+    li $v0, __NR_lgetxattr
     syscall
-    bnez a3, 1f
-    move a0, v0
-    j ra
+    bnez $a3, 1f
+    move $a0, $v0
+    j $ra
     nop
 1:
-    la t9,__set_errno_internal
-    j t9
+    la $t9,__set_errno_internal
+    j $t9
     nop
     .set reorder
 END(lgetxattr)
diff --git a/libc/arch-mips/syscalls/linkat.S b/libc/arch-mips/syscalls/linkat.S
index a05a995..eacc488 100644
--- a/libc/arch-mips/syscalls/linkat.S
+++ b/libc/arch-mips/syscalls/linkat.S
@@ -4,16 +4,16 @@
 
 ENTRY(linkat)
     .set noreorder
-    .cpload t9
-    li v0, __NR_linkat
+    .cpload $t9
+    li $v0, __NR_linkat
     syscall
-    bnez a3, 1f
-    move a0, v0
-    j ra
+    bnez $a3, 1f
+    move $a0, $v0
+    j $ra
     nop
 1:
-    la t9,__set_errno_internal
-    j t9
+    la $t9,__set_errno_internal
+    j $t9
     nop
     .set reorder
 END(linkat)
diff --git a/libc/arch-mips/syscalls/listen.S b/libc/arch-mips/syscalls/listen.S
index 7bb2ec8..cbda026 100644
--- a/libc/arch-mips/syscalls/listen.S
+++ b/libc/arch-mips/syscalls/listen.S
@@ -4,16 +4,16 @@
 
 ENTRY(listen)
     .set noreorder
-    .cpload t9
-    li v0, __NR_listen
+    .cpload $t9
+    li $v0, __NR_listen
     syscall
-    bnez a3, 1f
-    move a0, v0
-    j ra
+    bnez $a3, 1f
+    move $a0, $v0
+    j $ra
     nop
 1:
-    la t9,__set_errno_internal
-    j t9
+    la $t9,__set_errno_internal
+    j $t9
     nop
     .set reorder
 END(listen)
diff --git a/libc/arch-mips/syscalls/listxattr.S b/libc/arch-mips/syscalls/listxattr.S
index c160178..0ee14a0 100644
--- a/libc/arch-mips/syscalls/listxattr.S
+++ b/libc/arch-mips/syscalls/listxattr.S
@@ -4,16 +4,16 @@
 
 ENTRY(listxattr)
     .set noreorder
-    .cpload t9
-    li v0, __NR_listxattr
+    .cpload $t9
+    li $v0, __NR_listxattr
     syscall
-    bnez a3, 1f
-    move a0, v0
-    j ra
+    bnez $a3, 1f
+    move $a0, $v0
+    j $ra
     nop
 1:
-    la t9,__set_errno_internal
-    j t9
+    la $t9,__set_errno_internal
+    j $t9
     nop
     .set reorder
 END(listxattr)
diff --git a/libc/arch-mips/syscalls/llistxattr.S b/libc/arch-mips/syscalls/llistxattr.S
index 9bf05b0..46f79df 100644
--- a/libc/arch-mips/syscalls/llistxattr.S
+++ b/libc/arch-mips/syscalls/llistxattr.S
@@ -4,16 +4,16 @@
 
 ENTRY(llistxattr)
     .set noreorder
-    .cpload t9
-    li v0, __NR_llistxattr
+    .cpload $t9
+    li $v0, __NR_llistxattr
     syscall
-    bnez a3, 1f
-    move a0, v0
-    j ra
+    bnez $a3, 1f
+    move $a0, $v0
+    j $ra
     nop
 1:
-    la t9,__set_errno_internal
-    j t9
+    la $t9,__set_errno_internal
+    j $t9
     nop
     .set reorder
 END(llistxattr)
diff --git a/libc/arch-mips/syscalls/lremovexattr.S b/libc/arch-mips/syscalls/lremovexattr.S
index fe73ddb..74aa7c9 100644
--- a/libc/arch-mips/syscalls/lremovexattr.S
+++ b/libc/arch-mips/syscalls/lremovexattr.S
@@ -4,16 +4,16 @@
 
 ENTRY(lremovexattr)
     .set noreorder
-    .cpload t9
-    li v0, __NR_lremovexattr
+    .cpload $t9
+    li $v0, __NR_lremovexattr
     syscall
-    bnez a3, 1f
-    move a0, v0
-    j ra
+    bnez $a3, 1f
+    move $a0, $v0
+    j $ra
     nop
 1:
-    la t9,__set_errno_internal
-    j t9
+    la $t9,__set_errno_internal
+    j $t9
     nop
     .set reorder
 END(lremovexattr)
diff --git a/libc/arch-mips/syscalls/lseek.S b/libc/arch-mips/syscalls/lseek.S
index 6d6b4e5..9f93986 100644
--- a/libc/arch-mips/syscalls/lseek.S
+++ b/libc/arch-mips/syscalls/lseek.S
@@ -4,16 +4,16 @@
 
 ENTRY(lseek)
     .set noreorder
-    .cpload t9
-    li v0, __NR_lseek
+    .cpload $t9
+    li $v0, __NR_lseek
     syscall
-    bnez a3, 1f
-    move a0, v0
-    j ra
+    bnez $a3, 1f
+    move $a0, $v0
+    j $ra
     nop
 1:
-    la t9,__set_errno_internal
-    j t9
+    la $t9,__set_errno_internal
+    j $t9
     nop
     .set reorder
 END(lseek)
diff --git a/libc/arch-mips/syscalls/lsetxattr.S b/libc/arch-mips/syscalls/lsetxattr.S
index 69ea0a2..a87121f 100644
--- a/libc/arch-mips/syscalls/lsetxattr.S
+++ b/libc/arch-mips/syscalls/lsetxattr.S
@@ -4,16 +4,16 @@
 
 ENTRY(lsetxattr)
     .set noreorder
-    .cpload t9
-    li v0, __NR_lsetxattr
+    .cpload $t9
+    li $v0, __NR_lsetxattr
     syscall
-    bnez a3, 1f
-    move a0, v0
-    j ra
+    bnez $a3, 1f
+    move $a0, $v0
+    j $ra
     nop
 1:
-    la t9,__set_errno_internal
-    j t9
+    la $t9,__set_errno_internal
+    j $t9
     nop
     .set reorder
 END(lsetxattr)
diff --git a/libc/arch-mips/syscalls/madvise.S b/libc/arch-mips/syscalls/madvise.S
index 7d67b80..5fd4856 100644
--- a/libc/arch-mips/syscalls/madvise.S
+++ b/libc/arch-mips/syscalls/madvise.S
@@ -4,16 +4,16 @@
 
 ENTRY(madvise)
     .set noreorder
-    .cpload t9
-    li v0, __NR_madvise
+    .cpload $t9
+    li $v0, __NR_madvise
     syscall
-    bnez a3, 1f
-    move a0, v0
-    j ra
+    bnez $a3, 1f
+    move $a0, $v0
+    j $ra
     nop
 1:
-    la t9,__set_errno_internal
-    j t9
+    la $t9,__set_errno_internal
+    j $t9
     nop
     .set reorder
 END(madvise)
diff --git a/libc/arch-mips/syscalls/mincore.S b/libc/arch-mips/syscalls/mincore.S
index 96f5e29..db74719 100644
--- a/libc/arch-mips/syscalls/mincore.S
+++ b/libc/arch-mips/syscalls/mincore.S
@@ -4,16 +4,16 @@
 
 ENTRY(mincore)
     .set noreorder
-    .cpload t9
-    li v0, __NR_mincore
+    .cpload $t9
+    li $v0, __NR_mincore
     syscall
-    bnez a3, 1f
-    move a0, v0
-    j ra
+    bnez $a3, 1f
+    move $a0, $v0
+    j $ra
     nop
 1:
-    la t9,__set_errno_internal
-    j t9
+    la $t9,__set_errno_internal
+    j $t9
     nop
     .set reorder
 END(mincore)
diff --git a/libc/arch-mips/syscalls/mkdirat.S b/libc/arch-mips/syscalls/mkdirat.S
index 55dd976..3ff69c3 100644
--- a/libc/arch-mips/syscalls/mkdirat.S
+++ b/libc/arch-mips/syscalls/mkdirat.S
@@ -4,16 +4,16 @@
 
 ENTRY(mkdirat)
     .set noreorder
-    .cpload t9
-    li v0, __NR_mkdirat
+    .cpload $t9
+    li $v0, __NR_mkdirat
     syscall
-    bnez a3, 1f
-    move a0, v0
-    j ra
+    bnez $a3, 1f
+    move $a0, $v0
+    j $ra
     nop
 1:
-    la t9,__set_errno_internal
-    j t9
+    la $t9,__set_errno_internal
+    j $t9
     nop
     .set reorder
 END(mkdirat)
diff --git a/libc/arch-mips/syscalls/mknodat.S b/libc/arch-mips/syscalls/mknodat.S
index 1a03a8e..651a619 100644
--- a/libc/arch-mips/syscalls/mknodat.S
+++ b/libc/arch-mips/syscalls/mknodat.S
@@ -4,16 +4,16 @@
 
 ENTRY(mknodat)
     .set noreorder
-    .cpload t9
-    li v0, __NR_mknodat
+    .cpload $t9
+    li $v0, __NR_mknodat
     syscall
-    bnez a3, 1f
-    move a0, v0
-    j ra
+    bnez $a3, 1f
+    move $a0, $v0
+    j $ra
     nop
 1:
-    la t9,__set_errno_internal
-    j t9
+    la $t9,__set_errno_internal
+    j $t9
     nop
     .set reorder
 END(mknodat)
diff --git a/libc/arch-mips/syscalls/mlock.S b/libc/arch-mips/syscalls/mlock.S
index 3cf7c1b..d1bb3a4 100644
--- a/libc/arch-mips/syscalls/mlock.S
+++ b/libc/arch-mips/syscalls/mlock.S
@@ -4,16 +4,16 @@
 
 ENTRY(mlock)
     .set noreorder
-    .cpload t9
-    li v0, __NR_mlock
+    .cpload $t9
+    li $v0, __NR_mlock
     syscall
-    bnez a3, 1f
-    move a0, v0
-    j ra
+    bnez $a3, 1f
+    move $a0, $v0
+    j $ra
     nop
 1:
-    la t9,__set_errno_internal
-    j t9
+    la $t9,__set_errno_internal
+    j $t9
     nop
     .set reorder
 END(mlock)
diff --git a/libc/arch-mips/syscalls/mlockall.S b/libc/arch-mips/syscalls/mlockall.S
index 3b90f41..495be12 100644
--- a/libc/arch-mips/syscalls/mlockall.S
+++ b/libc/arch-mips/syscalls/mlockall.S
@@ -4,16 +4,16 @@
 
 ENTRY(mlockall)
     .set noreorder
-    .cpload t9
-    li v0, __NR_mlockall
+    .cpload $t9
+    li $v0, __NR_mlockall
     syscall
-    bnez a3, 1f
-    move a0, v0
-    j ra
+    bnez $a3, 1f
+    move $a0, $v0
+    j $ra
     nop
 1:
-    la t9,__set_errno_internal
-    j t9
+    la $t9,__set_errno_internal
+    j $t9
     nop
     .set reorder
 END(mlockall)
diff --git a/libc/arch-mips/syscalls/mount.S b/libc/arch-mips/syscalls/mount.S
index fdf299f..6eccf01 100644
--- a/libc/arch-mips/syscalls/mount.S
+++ b/libc/arch-mips/syscalls/mount.S
@@ -4,16 +4,16 @@
 
 ENTRY(mount)
     .set noreorder
-    .cpload t9
-    li v0, __NR_mount
+    .cpload $t9
+    li $v0, __NR_mount
     syscall
-    bnez a3, 1f
-    move a0, v0
-    j ra
+    bnez $a3, 1f
+    move $a0, $v0
+    j $ra
     nop
 1:
-    la t9,__set_errno_internal
-    j t9
+    la $t9,__set_errno_internal
+    j $t9
     nop
     .set reorder
 END(mount)
diff --git a/libc/arch-mips/syscalls/mprotect.S b/libc/arch-mips/syscalls/mprotect.S
index 5618310..486fd5d 100644
--- a/libc/arch-mips/syscalls/mprotect.S
+++ b/libc/arch-mips/syscalls/mprotect.S
@@ -4,16 +4,16 @@
 
 ENTRY(mprotect)
     .set noreorder
-    .cpload t9
-    li v0, __NR_mprotect
+    .cpload $t9
+    li $v0, __NR_mprotect
     syscall
-    bnez a3, 1f
-    move a0, v0
-    j ra
+    bnez $a3, 1f
+    move $a0, $v0
+    j $ra
     nop
 1:
-    la t9,__set_errno_internal
-    j t9
+    la $t9,__set_errno_internal
+    j $t9
     nop
     .set reorder
 END(mprotect)
diff --git a/libc/arch-mips/syscalls/msync.S b/libc/arch-mips/syscalls/msync.S
index fb7462d..6554fd0 100644
--- a/libc/arch-mips/syscalls/msync.S
+++ b/libc/arch-mips/syscalls/msync.S
@@ -4,16 +4,16 @@
 
 ENTRY(msync)
     .set noreorder
-    .cpload t9
-    li v0, __NR_msync
+    .cpload $t9
+    li $v0, __NR_msync
     syscall
-    bnez a3, 1f
-    move a0, v0
-    j ra
+    bnez $a3, 1f
+    move $a0, $v0
+    j $ra
     nop
 1:
-    la t9,__set_errno_internal
-    j t9
+    la $t9,__set_errno_internal
+    j $t9
     nop
     .set reorder
 END(msync)
diff --git a/libc/arch-mips/syscalls/munlock.S b/libc/arch-mips/syscalls/munlock.S
index 6c65c02..3a3f50c 100644
--- a/libc/arch-mips/syscalls/munlock.S
+++ b/libc/arch-mips/syscalls/munlock.S
@@ -4,16 +4,16 @@
 
 ENTRY(munlock)
     .set noreorder
-    .cpload t9
-    li v0, __NR_munlock
+    .cpload $t9
+    li $v0, __NR_munlock
     syscall
-    bnez a3, 1f
-    move a0, v0
-    j ra
+    bnez $a3, 1f
+    move $a0, $v0
+    j $ra
     nop
 1:
-    la t9,__set_errno_internal
-    j t9
+    la $t9,__set_errno_internal
+    j $t9
     nop
     .set reorder
 END(munlock)
diff --git a/libc/arch-mips/syscalls/munlockall.S b/libc/arch-mips/syscalls/munlockall.S
index e30dddc..4efb260 100644
--- a/libc/arch-mips/syscalls/munlockall.S
+++ b/libc/arch-mips/syscalls/munlockall.S
@@ -4,16 +4,16 @@
 
 ENTRY(munlockall)
     .set noreorder
-    .cpload t9
-    li v0, __NR_munlockall
+    .cpload $t9
+    li $v0, __NR_munlockall
     syscall
-    bnez a3, 1f
-    move a0, v0
-    j ra
+    bnez $a3, 1f
+    move $a0, $v0
+    j $ra
     nop
 1:
-    la t9,__set_errno_internal
-    j t9
+    la $t9,__set_errno_internal
+    j $t9
     nop
     .set reorder
 END(munlockall)
diff --git a/libc/arch-mips/syscalls/munmap.S b/libc/arch-mips/syscalls/munmap.S
index 903edde..364f0c1 100644
--- a/libc/arch-mips/syscalls/munmap.S
+++ b/libc/arch-mips/syscalls/munmap.S
@@ -4,16 +4,16 @@
 
 ENTRY(munmap)
     .set noreorder
-    .cpload t9
-    li v0, __NR_munmap
+    .cpload $t9
+    li $v0, __NR_munmap
     syscall
-    bnez a3, 1f
-    move a0, v0
-    j ra
+    bnez $a3, 1f
+    move $a0, $v0
+    j $ra
     nop
 1:
-    la t9,__set_errno_internal
-    j t9
+    la $t9,__set_errno_internal
+    j $t9
     nop
     .set reorder
 END(munmap)
diff --git a/libc/arch-mips/syscalls/nanosleep.S b/libc/arch-mips/syscalls/nanosleep.S
index 8dae88b..7e88d00 100644
--- a/libc/arch-mips/syscalls/nanosleep.S
+++ b/libc/arch-mips/syscalls/nanosleep.S
@@ -4,16 +4,16 @@
 
 ENTRY(nanosleep)
     .set noreorder
-    .cpload t9
-    li v0, __NR_nanosleep
+    .cpload $t9
+    li $v0, __NR_nanosleep
     syscall
-    bnez a3, 1f
-    move a0, v0
-    j ra
+    bnez $a3, 1f
+    move $a0, $v0
+    j $ra
     nop
 1:
-    la t9,__set_errno_internal
-    j t9
+    la $t9,__set_errno_internal
+    j $t9
     nop
     .set reorder
 END(nanosleep)
diff --git a/libc/arch-mips/syscalls/personality.S b/libc/arch-mips/syscalls/personality.S
index 2f51d39..67f9ec1 100644
--- a/libc/arch-mips/syscalls/personality.S
+++ b/libc/arch-mips/syscalls/personality.S
@@ -4,16 +4,16 @@
 
 ENTRY(personality)
     .set noreorder
-    .cpload t9
-    li v0, __NR_personality
+    .cpload $t9
+    li $v0, __NR_personality
     syscall
-    bnez a3, 1f
-    move a0, v0
-    j ra
+    bnez $a3, 1f
+    move $a0, $v0
+    j $ra
     nop
 1:
-    la t9,__set_errno_internal
-    j t9
+    la $t9,__set_errno_internal
+    j $t9
     nop
     .set reorder
 END(personality)
diff --git a/libc/arch-mips/syscalls/pipe2.S b/libc/arch-mips/syscalls/pipe2.S
index b06309c..4040d1f 100644
--- a/libc/arch-mips/syscalls/pipe2.S
+++ b/libc/arch-mips/syscalls/pipe2.S
@@ -4,16 +4,16 @@
 
 ENTRY(pipe2)
     .set noreorder
-    .cpload t9
-    li v0, __NR_pipe2
+    .cpload $t9
+    li $v0, __NR_pipe2
     syscall
-    bnez a3, 1f
-    move a0, v0
-    j ra
+    bnez $a3, 1f
+    move $a0, $v0
+    j $ra
     nop
 1:
-    la t9,__set_errno_internal
-    j t9
+    la $t9,__set_errno_internal
+    j $t9
     nop
     .set reorder
 END(pipe2)
diff --git a/libc/arch-mips/syscalls/prctl.S b/libc/arch-mips/syscalls/prctl.S
index 71544ee..e6b0024 100644
--- a/libc/arch-mips/syscalls/prctl.S
+++ b/libc/arch-mips/syscalls/prctl.S
@@ -4,16 +4,16 @@
 
 ENTRY(prctl)
     .set noreorder
-    .cpload t9
-    li v0, __NR_prctl
+    .cpload $t9
+    li $v0, __NR_prctl
     syscall
-    bnez a3, 1f
-    move a0, v0
-    j ra
+    bnez $a3, 1f
+    move $a0, $v0
+    j $ra
     nop
 1:
-    la t9,__set_errno_internal
-    j t9
+    la $t9,__set_errno_internal
+    j $t9
     nop
     .set reorder
 END(prctl)
diff --git a/libc/arch-mips/syscalls/pread64.S b/libc/arch-mips/syscalls/pread64.S
index 9e7248b..0181595 100644
--- a/libc/arch-mips/syscalls/pread64.S
+++ b/libc/arch-mips/syscalls/pread64.S
@@ -4,16 +4,16 @@
 
 ENTRY(pread64)
     .set noreorder
-    .cpload t9
-    li v0, __NR_pread64
+    .cpload $t9
+    li $v0, __NR_pread64
     syscall
-    bnez a3, 1f
-    move a0, v0
-    j ra
+    bnez $a3, 1f
+    move $a0, $v0
+    j $ra
     nop
 1:
-    la t9,__set_errno_internal
-    j t9
+    la $t9,__set_errno_internal
+    j $t9
     nop
     .set reorder
 END(pread64)
diff --git a/libc/arch-mips/syscalls/prlimit64.S b/libc/arch-mips/syscalls/prlimit64.S
index ca913df..c93af64 100644
--- a/libc/arch-mips/syscalls/prlimit64.S
+++ b/libc/arch-mips/syscalls/prlimit64.S
@@ -4,16 +4,16 @@
 
 ENTRY(prlimit64)
     .set noreorder
-    .cpload t9
-    li v0, __NR_prlimit64
+    .cpload $t9
+    li $v0, __NR_prlimit64
     syscall
-    bnez a3, 1f
-    move a0, v0
-    j ra
+    bnez $a3, 1f
+    move $a0, $v0
+    j $ra
     nop
 1:
-    la t9,__set_errno_internal
-    j t9
+    la $t9,__set_errno_internal
+    j $t9
     nop
     .set reorder
 END(prlimit64)
diff --git a/libc/arch-mips/syscalls/process_vm_readv.S b/libc/arch-mips/syscalls/process_vm_readv.S
index 22b74f0..e571db0 100644
--- a/libc/arch-mips/syscalls/process_vm_readv.S
+++ b/libc/arch-mips/syscalls/process_vm_readv.S
@@ -4,16 +4,16 @@
 
 ENTRY(process_vm_readv)
     .set noreorder
-    .cpload t9
-    li v0, __NR_process_vm_readv
+    .cpload $t9
+    li $v0, __NR_process_vm_readv
     syscall
-    bnez a3, 1f
-    move a0, v0
-    j ra
+    bnez $a3, 1f
+    move $a0, $v0
+    j $ra
     nop
 1:
-    la t9,__set_errno_internal
-    j t9
+    la $t9,__set_errno_internal
+    j $t9
     nop
     .set reorder
 END(process_vm_readv)
diff --git a/libc/arch-mips/syscalls/process_vm_writev.S b/libc/arch-mips/syscalls/process_vm_writev.S
index dd1dc4b..cab3b6d 100644
--- a/libc/arch-mips/syscalls/process_vm_writev.S
+++ b/libc/arch-mips/syscalls/process_vm_writev.S
@@ -4,16 +4,16 @@
 
 ENTRY(process_vm_writev)
     .set noreorder
-    .cpload t9
-    li v0, __NR_process_vm_writev
+    .cpload $t9
+    li $v0, __NR_process_vm_writev
     syscall
-    bnez a3, 1f
-    move a0, v0
-    j ra
+    bnez $a3, 1f
+    move $a0, $v0
+    j $ra
     nop
 1:
-    la t9,__set_errno_internal
-    j t9
+    la $t9,__set_errno_internal
+    j $t9
     nop
     .set reorder
 END(process_vm_writev)
diff --git a/libc/arch-mips/syscalls/pwrite64.S b/libc/arch-mips/syscalls/pwrite64.S
index ac206aa..4f46f75 100644
--- a/libc/arch-mips/syscalls/pwrite64.S
+++ b/libc/arch-mips/syscalls/pwrite64.S
@@ -4,16 +4,16 @@
 
 ENTRY(pwrite64)
     .set noreorder
-    .cpload t9
-    li v0, __NR_pwrite64
+    .cpload $t9
+    li $v0, __NR_pwrite64
     syscall
-    bnez a3, 1f
-    move a0, v0
-    j ra
+    bnez $a3, 1f
+    move $a0, $v0
+    j $ra
     nop
 1:
-    la t9,__set_errno_internal
-    j t9
+    la $t9,__set_errno_internal
+    j $t9
     nop
     .set reorder
 END(pwrite64)
diff --git a/libc/arch-mips/syscalls/quotactl.S b/libc/arch-mips/syscalls/quotactl.S
index fef336a..2c8044a 100644
--- a/libc/arch-mips/syscalls/quotactl.S
+++ b/libc/arch-mips/syscalls/quotactl.S
@@ -4,16 +4,16 @@
 
 ENTRY(quotactl)
     .set noreorder
-    .cpload t9
-    li v0, __NR_quotactl
+    .cpload $t9
+    li $v0, __NR_quotactl
     syscall
-    bnez a3, 1f
-    move a0, v0
-    j ra
+    bnez $a3, 1f
+    move $a0, $v0
+    j $ra
     nop
 1:
-    la t9,__set_errno_internal
-    j t9
+    la $t9,__set_errno_internal
+    j $t9
     nop
     .set reorder
 END(quotactl)
diff --git a/libc/arch-mips/syscalls/read.S b/libc/arch-mips/syscalls/read.S
index 1355b66..afc6199 100644
--- a/libc/arch-mips/syscalls/read.S
+++ b/libc/arch-mips/syscalls/read.S
@@ -4,16 +4,16 @@
 
 ENTRY(read)
     .set noreorder
-    .cpload t9
-    li v0, __NR_read
+    .cpload $t9
+    li $v0, __NR_read
     syscall
-    bnez a3, 1f
-    move a0, v0
-    j ra
+    bnez $a3, 1f
+    move $a0, $v0
+    j $ra
     nop
 1:
-    la t9,__set_errno_internal
-    j t9
+    la $t9,__set_errno_internal
+    j $t9
     nop
     .set reorder
 END(read)
diff --git a/libc/arch-mips/syscalls/readahead.S b/libc/arch-mips/syscalls/readahead.S
index b28df08..1fe93d8 100644
--- a/libc/arch-mips/syscalls/readahead.S
+++ b/libc/arch-mips/syscalls/readahead.S
@@ -4,16 +4,16 @@
 
 ENTRY(readahead)
     .set noreorder
-    .cpload t9
-    li v0, __NR_readahead
+    .cpload $t9
+    li $v0, __NR_readahead
     syscall
-    bnez a3, 1f
-    move a0, v0
-    j ra
+    bnez $a3, 1f
+    move $a0, $v0
+    j $ra
     nop
 1:
-    la t9,__set_errno_internal
-    j t9
+    la $t9,__set_errno_internal
+    j $t9
     nop
     .set reorder
 END(readahead)
diff --git a/libc/arch-mips/syscalls/readlinkat.S b/libc/arch-mips/syscalls/readlinkat.S
index 5cf84a2..927f86f 100644
--- a/libc/arch-mips/syscalls/readlinkat.S
+++ b/libc/arch-mips/syscalls/readlinkat.S
@@ -4,16 +4,16 @@
 
 ENTRY(readlinkat)
     .set noreorder
-    .cpload t9
-    li v0, __NR_readlinkat
+    .cpload $t9
+    li $v0, __NR_readlinkat
     syscall
-    bnez a3, 1f
-    move a0, v0
-    j ra
+    bnez $a3, 1f
+    move $a0, $v0
+    j $ra
     nop
 1:
-    la t9,__set_errno_internal
-    j t9
+    la $t9,__set_errno_internal
+    j $t9
     nop
     .set reorder
 END(readlinkat)
diff --git a/libc/arch-mips/syscalls/readv.S b/libc/arch-mips/syscalls/readv.S
index 57952a0..6af3ac4 100644
--- a/libc/arch-mips/syscalls/readv.S
+++ b/libc/arch-mips/syscalls/readv.S
@@ -4,16 +4,16 @@
 
 ENTRY(readv)
     .set noreorder
-    .cpload t9
-    li v0, __NR_readv
+    .cpload $t9
+    li $v0, __NR_readv
     syscall
-    bnez a3, 1f
-    move a0, v0
-    j ra
+    bnez $a3, 1f
+    move $a0, $v0
+    j $ra
     nop
 1:
-    la t9,__set_errno_internal
-    j t9
+    la $t9,__set_errno_internal
+    j $t9
     nop
     .set reorder
 END(readv)
diff --git a/libc/arch-mips/syscalls/recvfrom.S b/libc/arch-mips/syscalls/recvfrom.S
index 707ba4b..448d892 100644
--- a/libc/arch-mips/syscalls/recvfrom.S
+++ b/libc/arch-mips/syscalls/recvfrom.S
@@ -4,16 +4,16 @@
 
 ENTRY(recvfrom)
     .set noreorder
-    .cpload t9
-    li v0, __NR_recvfrom
+    .cpload $t9
+    li $v0, __NR_recvfrom
     syscall
-    bnez a3, 1f
-    move a0, v0
-    j ra
+    bnez $a3, 1f
+    move $a0, $v0
+    j $ra
     nop
 1:
-    la t9,__set_errno_internal
-    j t9
+    la $t9,__set_errno_internal
+    j $t9
     nop
     .set reorder
 END(recvfrom)
diff --git a/libc/arch-mips/syscalls/recvmmsg.S b/libc/arch-mips/syscalls/recvmmsg.S
index 796d0d8..42660e2 100644
--- a/libc/arch-mips/syscalls/recvmmsg.S
+++ b/libc/arch-mips/syscalls/recvmmsg.S
@@ -4,16 +4,16 @@
 
 ENTRY(recvmmsg)
     .set noreorder
-    .cpload t9
-    li v0, __NR_recvmmsg
+    .cpload $t9
+    li $v0, __NR_recvmmsg
     syscall
-    bnez a3, 1f
-    move a0, v0
-    j ra
+    bnez $a3, 1f
+    move $a0, $v0
+    j $ra
     nop
 1:
-    la t9,__set_errno_internal
-    j t9
+    la $t9,__set_errno_internal
+    j $t9
     nop
     .set reorder
 END(recvmmsg)
diff --git a/libc/arch-mips/syscalls/recvmsg.S b/libc/arch-mips/syscalls/recvmsg.S
index fdcac32..71c7990 100644
--- a/libc/arch-mips/syscalls/recvmsg.S
+++ b/libc/arch-mips/syscalls/recvmsg.S
@@ -4,16 +4,16 @@
 
 ENTRY(recvmsg)
     .set noreorder
-    .cpload t9
-    li v0, __NR_recvmsg
+    .cpload $t9
+    li $v0, __NR_recvmsg
     syscall
-    bnez a3, 1f
-    move a0, v0
-    j ra
+    bnez $a3, 1f
+    move $a0, $v0
+    j $ra
     nop
 1:
-    la t9,__set_errno_internal
-    j t9
+    la $t9,__set_errno_internal
+    j $t9
     nop
     .set reorder
 END(recvmsg)
diff --git a/libc/arch-mips/syscalls/removexattr.S b/libc/arch-mips/syscalls/removexattr.S
index d99e1ae..4830373 100644
--- a/libc/arch-mips/syscalls/removexattr.S
+++ b/libc/arch-mips/syscalls/removexattr.S
@@ -4,16 +4,16 @@
 
 ENTRY(removexattr)
     .set noreorder
-    .cpload t9
-    li v0, __NR_removexattr
+    .cpload $t9
+    li $v0, __NR_removexattr
     syscall
-    bnez a3, 1f
-    move a0, v0
-    j ra
+    bnez $a3, 1f
+    move $a0, $v0
+    j $ra
     nop
 1:
-    la t9,__set_errno_internal
-    j t9
+    la $t9,__set_errno_internal
+    j $t9
     nop
     .set reorder
 END(removexattr)
diff --git a/libc/arch-mips/syscalls/renameat.S b/libc/arch-mips/syscalls/renameat.S
index c865d74..1486f95 100644
--- a/libc/arch-mips/syscalls/renameat.S
+++ b/libc/arch-mips/syscalls/renameat.S
@@ -4,16 +4,16 @@
 
 ENTRY(renameat)
     .set noreorder
-    .cpload t9
-    li v0, __NR_renameat
+    .cpload $t9
+    li $v0, __NR_renameat
     syscall
-    bnez a3, 1f
-    move a0, v0
-    j ra
+    bnez $a3, 1f
+    move $a0, $v0
+    j $ra
     nop
 1:
-    la t9,__set_errno_internal
-    j t9
+    la $t9,__set_errno_internal
+    j $t9
     nop
     .set reorder
 END(renameat)
diff --git a/libc/arch-mips/syscalls/sched_get_priority_max.S b/libc/arch-mips/syscalls/sched_get_priority_max.S
index 1c73af6..f1d35c6 100644
--- a/libc/arch-mips/syscalls/sched_get_priority_max.S
+++ b/libc/arch-mips/syscalls/sched_get_priority_max.S
@@ -4,16 +4,16 @@
 
 ENTRY(sched_get_priority_max)
     .set noreorder
-    .cpload t9
-    li v0, __NR_sched_get_priority_max
+    .cpload $t9
+    li $v0, __NR_sched_get_priority_max
     syscall
-    bnez a3, 1f
-    move a0, v0
-    j ra
+    bnez $a3, 1f
+    move $a0, $v0
+    j $ra
     nop
 1:
-    la t9,__set_errno_internal
-    j t9
+    la $t9,__set_errno_internal
+    j $t9
     nop
     .set reorder
 END(sched_get_priority_max)
diff --git a/libc/arch-mips/syscalls/sched_get_priority_min.S b/libc/arch-mips/syscalls/sched_get_priority_min.S
index b69b72b..cdb5539 100644
--- a/libc/arch-mips/syscalls/sched_get_priority_min.S
+++ b/libc/arch-mips/syscalls/sched_get_priority_min.S
@@ -4,16 +4,16 @@
 
 ENTRY(sched_get_priority_min)
     .set noreorder
-    .cpload t9
-    li v0, __NR_sched_get_priority_min
+    .cpload $t9
+    li $v0, __NR_sched_get_priority_min
     syscall
-    bnez a3, 1f
-    move a0, v0
-    j ra
+    bnez $a3, 1f
+    move $a0, $v0
+    j $ra
     nop
 1:
-    la t9,__set_errno_internal
-    j t9
+    la $t9,__set_errno_internal
+    j $t9
     nop
     .set reorder
 END(sched_get_priority_min)
diff --git a/libc/arch-mips/syscalls/sched_getparam.S b/libc/arch-mips/syscalls/sched_getparam.S
index 387257a..71724bd 100644
--- a/libc/arch-mips/syscalls/sched_getparam.S
+++ b/libc/arch-mips/syscalls/sched_getparam.S
@@ -4,16 +4,16 @@
 
 ENTRY(sched_getparam)
     .set noreorder
-    .cpload t9
-    li v0, __NR_sched_getparam
+    .cpload $t9
+    li $v0, __NR_sched_getparam
     syscall
-    bnez a3, 1f
-    move a0, v0
-    j ra
+    bnez $a3, 1f
+    move $a0, $v0
+    j $ra
     nop
 1:
-    la t9,__set_errno_internal
-    j t9
+    la $t9,__set_errno_internal
+    j $t9
     nop
     .set reorder
 END(sched_getparam)
diff --git a/libc/arch-mips/syscalls/sched_getscheduler.S b/libc/arch-mips/syscalls/sched_getscheduler.S
index 9b293db..8fae1c2 100644
--- a/libc/arch-mips/syscalls/sched_getscheduler.S
+++ b/libc/arch-mips/syscalls/sched_getscheduler.S
@@ -4,16 +4,16 @@
 
 ENTRY(sched_getscheduler)
     .set noreorder
-    .cpload t9
-    li v0, __NR_sched_getscheduler
+    .cpload $t9
+    li $v0, __NR_sched_getscheduler
     syscall
-    bnez a3, 1f
-    move a0, v0
-    j ra
+    bnez $a3, 1f
+    move $a0, $v0
+    j $ra
     nop
 1:
-    la t9,__set_errno_internal
-    j t9
+    la $t9,__set_errno_internal
+    j $t9
     nop
     .set reorder
 END(sched_getscheduler)
diff --git a/libc/arch-mips/syscalls/sched_rr_get_interval.S b/libc/arch-mips/syscalls/sched_rr_get_interval.S
index 3d7b8a8..eb53d77 100644
--- a/libc/arch-mips/syscalls/sched_rr_get_interval.S
+++ b/libc/arch-mips/syscalls/sched_rr_get_interval.S
@@ -4,16 +4,16 @@
 
 ENTRY(sched_rr_get_interval)
     .set noreorder
-    .cpload t9
-    li v0, __NR_sched_rr_get_interval
+    .cpload $t9
+    li $v0, __NR_sched_rr_get_interval
     syscall
-    bnez a3, 1f
-    move a0, v0
-    j ra
+    bnez $a3, 1f
+    move $a0, $v0
+    j $ra
     nop
 1:
-    la t9,__set_errno_internal
-    j t9
+    la $t9,__set_errno_internal
+    j $t9
     nop
     .set reorder
 END(sched_rr_get_interval)
diff --git a/libc/arch-mips/syscalls/sched_setaffinity.S b/libc/arch-mips/syscalls/sched_setaffinity.S
index a0e9f6c..a4837fa 100644
--- a/libc/arch-mips/syscalls/sched_setaffinity.S
+++ b/libc/arch-mips/syscalls/sched_setaffinity.S
@@ -4,16 +4,16 @@
 
 ENTRY(sched_setaffinity)
     .set noreorder
-    .cpload t9
-    li v0, __NR_sched_setaffinity
+    .cpload $t9
+    li $v0, __NR_sched_setaffinity
     syscall
-    bnez a3, 1f
-    move a0, v0
-    j ra
+    bnez $a3, 1f
+    move $a0, $v0
+    j $ra
     nop
 1:
-    la t9,__set_errno_internal
-    j t9
+    la $t9,__set_errno_internal
+    j $t9
     nop
     .set reorder
 END(sched_setaffinity)
diff --git a/libc/arch-mips/syscalls/sched_setparam.S b/libc/arch-mips/syscalls/sched_setparam.S
index a8a8982..4b6d0a2 100644
--- a/libc/arch-mips/syscalls/sched_setparam.S
+++ b/libc/arch-mips/syscalls/sched_setparam.S
@@ -4,16 +4,16 @@
 
 ENTRY(sched_setparam)
     .set noreorder
-    .cpload t9
-    li v0, __NR_sched_setparam
+    .cpload $t9
+    li $v0, __NR_sched_setparam
     syscall
-    bnez a3, 1f
-    move a0, v0
-    j ra
+    bnez $a3, 1f
+    move $a0, $v0
+    j $ra
     nop
 1:
-    la t9,__set_errno_internal
-    j t9
+    la $t9,__set_errno_internal
+    j $t9
     nop
     .set reorder
 END(sched_setparam)
diff --git a/libc/arch-mips/syscalls/sched_setscheduler.S b/libc/arch-mips/syscalls/sched_setscheduler.S
index a2cd7fa..69d7259 100644
--- a/libc/arch-mips/syscalls/sched_setscheduler.S
+++ b/libc/arch-mips/syscalls/sched_setscheduler.S
@@ -4,16 +4,16 @@
 
 ENTRY(sched_setscheduler)
     .set noreorder
-    .cpload t9
-    li v0, __NR_sched_setscheduler
+    .cpload $t9
+    li $v0, __NR_sched_setscheduler
     syscall
-    bnez a3, 1f
-    move a0, v0
-    j ra
+    bnez $a3, 1f
+    move $a0, $v0
+    j $ra
     nop
 1:
-    la t9,__set_errno_internal
-    j t9
+    la $t9,__set_errno_internal
+    j $t9
     nop
     .set reorder
 END(sched_setscheduler)
diff --git a/libc/arch-mips/syscalls/sched_yield.S b/libc/arch-mips/syscalls/sched_yield.S
index 295266f..da6b531 100644
--- a/libc/arch-mips/syscalls/sched_yield.S
+++ b/libc/arch-mips/syscalls/sched_yield.S
@@ -4,16 +4,16 @@
 
 ENTRY(sched_yield)
     .set noreorder
-    .cpload t9
-    li v0, __NR_sched_yield
+    .cpload $t9
+    li $v0, __NR_sched_yield
     syscall
-    bnez a3, 1f
-    move a0, v0
-    j ra
+    bnez $a3, 1f
+    move $a0, $v0
+    j $ra
     nop
 1:
-    la t9,__set_errno_internal
-    j t9
+    la $t9,__set_errno_internal
+    j $t9
     nop
     .set reorder
 END(sched_yield)
diff --git a/libc/arch-mips/syscalls/sendfile.S b/libc/arch-mips/syscalls/sendfile.S
index 5e5e887..9145cea 100644
--- a/libc/arch-mips/syscalls/sendfile.S
+++ b/libc/arch-mips/syscalls/sendfile.S
@@ -4,16 +4,16 @@
 
 ENTRY(sendfile)
     .set noreorder
-    .cpload t9
-    li v0, __NR_sendfile
+    .cpload $t9
+    li $v0, __NR_sendfile
     syscall
-    bnez a3, 1f
-    move a0, v0
-    j ra
+    bnez $a3, 1f
+    move $a0, $v0
+    j $ra
     nop
 1:
-    la t9,__set_errno_internal
-    j t9
+    la $t9,__set_errno_internal
+    j $t9
     nop
     .set reorder
 END(sendfile)
diff --git a/libc/arch-mips/syscalls/sendfile64.S b/libc/arch-mips/syscalls/sendfile64.S
index 78f1908..0093917 100644
--- a/libc/arch-mips/syscalls/sendfile64.S
+++ b/libc/arch-mips/syscalls/sendfile64.S
@@ -4,16 +4,16 @@
 
 ENTRY(sendfile64)
     .set noreorder
-    .cpload t9
-    li v0, __NR_sendfile64
+    .cpload $t9
+    li $v0, __NR_sendfile64
     syscall
-    bnez a3, 1f
-    move a0, v0
-    j ra
+    bnez $a3, 1f
+    move $a0, $v0
+    j $ra
     nop
 1:
-    la t9,__set_errno_internal
-    j t9
+    la $t9,__set_errno_internal
+    j $t9
     nop
     .set reorder
 END(sendfile64)
diff --git a/libc/arch-mips/syscalls/sendmmsg.S b/libc/arch-mips/syscalls/sendmmsg.S
index 1dc7576..d4e9806 100644
--- a/libc/arch-mips/syscalls/sendmmsg.S
+++ b/libc/arch-mips/syscalls/sendmmsg.S
@@ -4,16 +4,16 @@
 
 ENTRY(sendmmsg)
     .set noreorder
-    .cpload t9
-    li v0, __NR_sendmmsg
+    .cpload $t9
+    li $v0, __NR_sendmmsg
     syscall
-    bnez a3, 1f
-    move a0, v0
-    j ra
+    bnez $a3, 1f
+    move $a0, $v0
+    j $ra
     nop
 1:
-    la t9,__set_errno_internal
-    j t9
+    la $t9,__set_errno_internal
+    j $t9
     nop
     .set reorder
 END(sendmmsg)
diff --git a/libc/arch-mips/syscalls/sendmsg.S b/libc/arch-mips/syscalls/sendmsg.S
index 88c653e..ec019d6 100644
--- a/libc/arch-mips/syscalls/sendmsg.S
+++ b/libc/arch-mips/syscalls/sendmsg.S
@@ -4,16 +4,16 @@
 
 ENTRY(sendmsg)
     .set noreorder
-    .cpload t9
-    li v0, __NR_sendmsg
+    .cpload $t9
+    li $v0, __NR_sendmsg
     syscall
-    bnez a3, 1f
-    move a0, v0
-    j ra
+    bnez $a3, 1f
+    move $a0, $v0
+    j $ra
     nop
 1:
-    la t9,__set_errno_internal
-    j t9
+    la $t9,__set_errno_internal
+    j $t9
     nop
     .set reorder
 END(sendmsg)
diff --git a/libc/arch-mips/syscalls/sendto.S b/libc/arch-mips/syscalls/sendto.S
index ef3fa9f..884fd06 100644
--- a/libc/arch-mips/syscalls/sendto.S
+++ b/libc/arch-mips/syscalls/sendto.S
@@ -4,16 +4,16 @@
 
 ENTRY(sendto)
     .set noreorder
-    .cpload t9
-    li v0, __NR_sendto
+    .cpload $t9
+    li $v0, __NR_sendto
     syscall
-    bnez a3, 1f
-    move a0, v0
-    j ra
+    bnez $a3, 1f
+    move $a0, $v0
+    j $ra
     nop
 1:
-    la t9,__set_errno_internal
-    j t9
+    la $t9,__set_errno_internal
+    j $t9
     nop
     .set reorder
 END(sendto)
diff --git a/libc/arch-mips/syscalls/setdomainname.S b/libc/arch-mips/syscalls/setdomainname.S
index ec0504c..9144a81 100644
--- a/libc/arch-mips/syscalls/setdomainname.S
+++ b/libc/arch-mips/syscalls/setdomainname.S
@@ -4,16 +4,16 @@
 
 ENTRY(setdomainname)
     .set noreorder
-    .cpload t9
-    li v0, __NR_setdomainname
+    .cpload $t9
+    li $v0, __NR_setdomainname
     syscall
-    bnez a3, 1f
-    move a0, v0
-    j ra
+    bnez $a3, 1f
+    move $a0, $v0
+    j $ra
     nop
 1:
-    la t9,__set_errno_internal
-    j t9
+    la $t9,__set_errno_internal
+    j $t9
     nop
     .set reorder
 END(setdomainname)
diff --git a/libc/arch-mips/syscalls/setfsgid.S b/libc/arch-mips/syscalls/setfsgid.S
index 158d2c0..b927d23 100644
--- a/libc/arch-mips/syscalls/setfsgid.S
+++ b/libc/arch-mips/syscalls/setfsgid.S
@@ -4,16 +4,16 @@
 
 ENTRY(setfsgid)
     .set noreorder
-    .cpload t9
-    li v0, __NR_setfsgid
+    .cpload $t9
+    li $v0, __NR_setfsgid
     syscall
-    bnez a3, 1f
-    move a0, v0
-    j ra
+    bnez $a3, 1f
+    move $a0, $v0
+    j $ra
     nop
 1:
-    la t9,__set_errno_internal
-    j t9
+    la $t9,__set_errno_internal
+    j $t9
     nop
     .set reorder
 END(setfsgid)
diff --git a/libc/arch-mips/syscalls/setfsuid.S b/libc/arch-mips/syscalls/setfsuid.S
index f76fd17..c95f30f 100644
--- a/libc/arch-mips/syscalls/setfsuid.S
+++ b/libc/arch-mips/syscalls/setfsuid.S
@@ -4,16 +4,16 @@
 
 ENTRY(setfsuid)
     .set noreorder
-    .cpload t9
-    li v0, __NR_setfsuid
+    .cpload $t9
+    li $v0, __NR_setfsuid
     syscall
-    bnez a3, 1f
-    move a0, v0
-    j ra
+    bnez $a3, 1f
+    move $a0, $v0
+    j $ra
     nop
 1:
-    la t9,__set_errno_internal
-    j t9
+    la $t9,__set_errno_internal
+    j $t9
     nop
     .set reorder
 END(setfsuid)
diff --git a/libc/arch-mips/syscalls/setgid.S b/libc/arch-mips/syscalls/setgid.S
index 44127cd..a1665cc 100644
--- a/libc/arch-mips/syscalls/setgid.S
+++ b/libc/arch-mips/syscalls/setgid.S
@@ -4,16 +4,16 @@
 
 ENTRY(setgid)
     .set noreorder
-    .cpload t9
-    li v0, __NR_setgid
+    .cpload $t9
+    li $v0, __NR_setgid
     syscall
-    bnez a3, 1f
-    move a0, v0
-    j ra
+    bnez $a3, 1f
+    move $a0, $v0
+    j $ra
     nop
 1:
-    la t9,__set_errno_internal
-    j t9
+    la $t9,__set_errno_internal
+    j $t9
     nop
     .set reorder
 END(setgid)
diff --git a/libc/arch-mips/syscalls/setgroups.S b/libc/arch-mips/syscalls/setgroups.S
index be4dc13..f8f4c52 100644
--- a/libc/arch-mips/syscalls/setgroups.S
+++ b/libc/arch-mips/syscalls/setgroups.S
@@ -4,16 +4,16 @@
 
 ENTRY(setgroups)
     .set noreorder
-    .cpload t9
-    li v0, __NR_setgroups
+    .cpload $t9
+    li $v0, __NR_setgroups
     syscall
-    bnez a3, 1f
-    move a0, v0
-    j ra
+    bnez $a3, 1f
+    move $a0, $v0
+    j $ra
     nop
 1:
-    la t9,__set_errno_internal
-    j t9
+    la $t9,__set_errno_internal
+    j $t9
     nop
     .set reorder
 END(setgroups)
diff --git a/libc/arch-mips/syscalls/sethostname.S b/libc/arch-mips/syscalls/sethostname.S
index 2987b52..1a3e37b 100644
--- a/libc/arch-mips/syscalls/sethostname.S
+++ b/libc/arch-mips/syscalls/sethostname.S
@@ -4,16 +4,16 @@
 
 ENTRY(sethostname)
     .set noreorder
-    .cpload t9
-    li v0, __NR_sethostname
+    .cpload $t9
+    li $v0, __NR_sethostname
     syscall
-    bnez a3, 1f
-    move a0, v0
-    j ra
+    bnez $a3, 1f
+    move $a0, $v0
+    j $ra
     nop
 1:
-    la t9,__set_errno_internal
-    j t9
+    la $t9,__set_errno_internal
+    j $t9
     nop
     .set reorder
 END(sethostname)
diff --git a/libc/arch-mips/syscalls/setitimer.S b/libc/arch-mips/syscalls/setitimer.S
index 968b453..1a32e97 100644
--- a/libc/arch-mips/syscalls/setitimer.S
+++ b/libc/arch-mips/syscalls/setitimer.S
@@ -4,16 +4,16 @@
 
 ENTRY(setitimer)
     .set noreorder
-    .cpload t9
-    li v0, __NR_setitimer
+    .cpload $t9
+    li $v0, __NR_setitimer
     syscall
-    bnez a3, 1f
-    move a0, v0
-    j ra
+    bnez $a3, 1f
+    move $a0, $v0
+    j $ra
     nop
 1:
-    la t9,__set_errno_internal
-    j t9
+    la $t9,__set_errno_internal
+    j $t9
     nop
     .set reorder
 END(setitimer)
diff --git a/libc/arch-mips/syscalls/setns.S b/libc/arch-mips/syscalls/setns.S
index a9270ec..6021aa6 100644
--- a/libc/arch-mips/syscalls/setns.S
+++ b/libc/arch-mips/syscalls/setns.S
@@ -4,16 +4,16 @@
 
 ENTRY(setns)
     .set noreorder
-    .cpload t9
-    li v0, __NR_setns
+    .cpload $t9
+    li $v0, __NR_setns
     syscall
-    bnez a3, 1f
-    move a0, v0
-    j ra
+    bnez $a3, 1f
+    move $a0, $v0
+    j $ra
     nop
 1:
-    la t9,__set_errno_internal
-    j t9
+    la $t9,__set_errno_internal
+    j $t9
     nop
     .set reorder
 END(setns)
diff --git a/libc/arch-mips/syscalls/setpgid.S b/libc/arch-mips/syscalls/setpgid.S
index d2db62f..449eabd 100644
--- a/libc/arch-mips/syscalls/setpgid.S
+++ b/libc/arch-mips/syscalls/setpgid.S
@@ -4,16 +4,16 @@
 
 ENTRY(setpgid)
     .set noreorder
-    .cpload t9
-    li v0, __NR_setpgid
+    .cpload $t9
+    li $v0, __NR_setpgid
     syscall
-    bnez a3, 1f
-    move a0, v0
-    j ra
+    bnez $a3, 1f
+    move $a0, $v0
+    j $ra
     nop
 1:
-    la t9,__set_errno_internal
-    j t9
+    la $t9,__set_errno_internal
+    j $t9
     nop
     .set reorder
 END(setpgid)
diff --git a/libc/arch-mips/syscalls/setpriority.S b/libc/arch-mips/syscalls/setpriority.S
index 9b68335..53f500b 100644
--- a/libc/arch-mips/syscalls/setpriority.S
+++ b/libc/arch-mips/syscalls/setpriority.S
@@ -4,16 +4,16 @@
 
 ENTRY(setpriority)
     .set noreorder
-    .cpload t9
-    li v0, __NR_setpriority
+    .cpload $t9
+    li $v0, __NR_setpriority
     syscall
-    bnez a3, 1f
-    move a0, v0
-    j ra
+    bnez $a3, 1f
+    move $a0, $v0
+    j $ra
     nop
 1:
-    la t9,__set_errno_internal
-    j t9
+    la $t9,__set_errno_internal
+    j $t9
     nop
     .set reorder
 END(setpriority)
diff --git a/libc/arch-mips/syscalls/setregid.S b/libc/arch-mips/syscalls/setregid.S
index 6b7474c..f251969 100644
--- a/libc/arch-mips/syscalls/setregid.S
+++ b/libc/arch-mips/syscalls/setregid.S
@@ -4,16 +4,16 @@
 
 ENTRY(setregid)
     .set noreorder
-    .cpload t9
-    li v0, __NR_setregid
+    .cpload $t9
+    li $v0, __NR_setregid
     syscall
-    bnez a3, 1f
-    move a0, v0
-    j ra
+    bnez $a3, 1f
+    move $a0, $v0
+    j $ra
     nop
 1:
-    la t9,__set_errno_internal
-    j t9
+    la $t9,__set_errno_internal
+    j $t9
     nop
     .set reorder
 END(setregid)
diff --git a/libc/arch-mips/syscalls/setresgid.S b/libc/arch-mips/syscalls/setresgid.S
index 223a0d0..78eb897 100644
--- a/libc/arch-mips/syscalls/setresgid.S
+++ b/libc/arch-mips/syscalls/setresgid.S
@@ -4,16 +4,16 @@
 
 ENTRY(setresgid)
     .set noreorder
-    .cpload t9
-    li v0, __NR_setresgid
+    .cpload $t9
+    li $v0, __NR_setresgid
     syscall
-    bnez a3, 1f
-    move a0, v0
-    j ra
+    bnez $a3, 1f
+    move $a0, $v0
+    j $ra
     nop
 1:
-    la t9,__set_errno_internal
-    j t9
+    la $t9,__set_errno_internal
+    j $t9
     nop
     .set reorder
 END(setresgid)
diff --git a/libc/arch-mips/syscalls/setresuid.S b/libc/arch-mips/syscalls/setresuid.S
index 1f99682..c78a4db 100644
--- a/libc/arch-mips/syscalls/setresuid.S
+++ b/libc/arch-mips/syscalls/setresuid.S
@@ -4,16 +4,16 @@
 
 ENTRY(setresuid)
     .set noreorder
-    .cpload t9
-    li v0, __NR_setresuid
+    .cpload $t9
+    li $v0, __NR_setresuid
     syscall
-    bnez a3, 1f
-    move a0, v0
-    j ra
+    bnez $a3, 1f
+    move $a0, $v0
+    j $ra
     nop
 1:
-    la t9,__set_errno_internal
-    j t9
+    la $t9,__set_errno_internal
+    j $t9
     nop
     .set reorder
 END(setresuid)
diff --git a/libc/arch-mips/syscalls/setreuid.S b/libc/arch-mips/syscalls/setreuid.S
index fa9c3d2..81e8551 100644
--- a/libc/arch-mips/syscalls/setreuid.S
+++ b/libc/arch-mips/syscalls/setreuid.S
@@ -4,16 +4,16 @@
 
 ENTRY(setreuid)
     .set noreorder
-    .cpload t9
-    li v0, __NR_setreuid
+    .cpload $t9
+    li $v0, __NR_setreuid
     syscall
-    bnez a3, 1f
-    move a0, v0
-    j ra
+    bnez $a3, 1f
+    move $a0, $v0
+    j $ra
     nop
 1:
-    la t9,__set_errno_internal
-    j t9
+    la $t9,__set_errno_internal
+    j $t9
     nop
     .set reorder
 END(setreuid)
diff --git a/libc/arch-mips/syscalls/setrlimit.S b/libc/arch-mips/syscalls/setrlimit.S
index 016e24c..ad11caf 100644
--- a/libc/arch-mips/syscalls/setrlimit.S
+++ b/libc/arch-mips/syscalls/setrlimit.S
@@ -4,16 +4,16 @@
 
 ENTRY(setrlimit)
     .set noreorder
-    .cpload t9
-    li v0, __NR_setrlimit
+    .cpload $t9
+    li $v0, __NR_setrlimit
     syscall
-    bnez a3, 1f
-    move a0, v0
-    j ra
+    bnez $a3, 1f
+    move $a0, $v0
+    j $ra
     nop
 1:
-    la t9,__set_errno_internal
-    j t9
+    la $t9,__set_errno_internal
+    j $t9
     nop
     .set reorder
 END(setrlimit)
diff --git a/libc/arch-mips/syscalls/setsid.S b/libc/arch-mips/syscalls/setsid.S
index 9f3cb48..c83d39f 100644
--- a/libc/arch-mips/syscalls/setsid.S
+++ b/libc/arch-mips/syscalls/setsid.S
@@ -4,16 +4,16 @@
 
 ENTRY(setsid)
     .set noreorder
-    .cpload t9
-    li v0, __NR_setsid
+    .cpload $t9
+    li $v0, __NR_setsid
     syscall
-    bnez a3, 1f
-    move a0, v0
-    j ra
+    bnez $a3, 1f
+    move $a0, $v0
+    j $ra
     nop
 1:
-    la t9,__set_errno_internal
-    j t9
+    la $t9,__set_errno_internal
+    j $t9
     nop
     .set reorder
 END(setsid)
diff --git a/libc/arch-mips/syscalls/setsockopt.S b/libc/arch-mips/syscalls/setsockopt.S
index b2368a1..2d398ef 100644
--- a/libc/arch-mips/syscalls/setsockopt.S
+++ b/libc/arch-mips/syscalls/setsockopt.S
@@ -4,16 +4,16 @@
 
 ENTRY(setsockopt)
     .set noreorder
-    .cpload t9
-    li v0, __NR_setsockopt
+    .cpload $t9
+    li $v0, __NR_setsockopt
     syscall
-    bnez a3, 1f
-    move a0, v0
-    j ra
+    bnez $a3, 1f
+    move $a0, $v0
+    j $ra
     nop
 1:
-    la t9,__set_errno_internal
-    j t9
+    la $t9,__set_errno_internal
+    j $t9
     nop
     .set reorder
 END(setsockopt)
diff --git a/libc/arch-mips/syscalls/settimeofday.S b/libc/arch-mips/syscalls/settimeofday.S
index e3a5a06..4ae8057 100644
--- a/libc/arch-mips/syscalls/settimeofday.S
+++ b/libc/arch-mips/syscalls/settimeofday.S
@@ -4,16 +4,16 @@
 
 ENTRY(settimeofday)
     .set noreorder
-    .cpload t9
-    li v0, __NR_settimeofday
+    .cpload $t9
+    li $v0, __NR_settimeofday
     syscall
-    bnez a3, 1f
-    move a0, v0
-    j ra
+    bnez $a3, 1f
+    move $a0, $v0
+    j $ra
     nop
 1:
-    la t9,__set_errno_internal
-    j t9
+    la $t9,__set_errno_internal
+    j $t9
     nop
     .set reorder
 END(settimeofday)
diff --git a/libc/arch-mips/syscalls/setuid.S b/libc/arch-mips/syscalls/setuid.S
index ff3da0a..732fb8a 100644
--- a/libc/arch-mips/syscalls/setuid.S
+++ b/libc/arch-mips/syscalls/setuid.S
@@ -4,16 +4,16 @@
 
 ENTRY(setuid)
     .set noreorder
-    .cpload t9
-    li v0, __NR_setuid
+    .cpload $t9
+    li $v0, __NR_setuid
     syscall
-    bnez a3, 1f
-    move a0, v0
-    j ra
+    bnez $a3, 1f
+    move $a0, $v0
+    j $ra
     nop
 1:
-    la t9,__set_errno_internal
-    j t9
+    la $t9,__set_errno_internal
+    j $t9
     nop
     .set reorder
 END(setuid)
diff --git a/libc/arch-mips/syscalls/setxattr.S b/libc/arch-mips/syscalls/setxattr.S
index 5b3a241..36a5d47 100644
--- a/libc/arch-mips/syscalls/setxattr.S
+++ b/libc/arch-mips/syscalls/setxattr.S
@@ -4,16 +4,16 @@
 
 ENTRY(setxattr)
     .set noreorder
-    .cpload t9
-    li v0, __NR_setxattr
+    .cpload $t9
+    li $v0, __NR_setxattr
     syscall
-    bnez a3, 1f
-    move a0, v0
-    j ra
+    bnez $a3, 1f
+    move $a0, $v0
+    j $ra
     nop
 1:
-    la t9,__set_errno_internal
-    j t9
+    la $t9,__set_errno_internal
+    j $t9
     nop
     .set reorder
 END(setxattr)
diff --git a/libc/arch-mips/syscalls/shutdown.S b/libc/arch-mips/syscalls/shutdown.S
index 5db046f..885a501 100644
--- a/libc/arch-mips/syscalls/shutdown.S
+++ b/libc/arch-mips/syscalls/shutdown.S
@@ -4,16 +4,16 @@
 
 ENTRY(shutdown)
     .set noreorder
-    .cpload t9
-    li v0, __NR_shutdown
+    .cpload $t9
+    li $v0, __NR_shutdown
     syscall
-    bnez a3, 1f
-    move a0, v0
-    j ra
+    bnez $a3, 1f
+    move $a0, $v0
+    j $ra
     nop
 1:
-    la t9,__set_errno_internal
-    j t9
+    la $t9,__set_errno_internal
+    j $t9
     nop
     .set reorder
 END(shutdown)
diff --git a/libc/arch-mips/syscalls/sigaltstack.S b/libc/arch-mips/syscalls/sigaltstack.S
index f543759..4276d71 100644
--- a/libc/arch-mips/syscalls/sigaltstack.S
+++ b/libc/arch-mips/syscalls/sigaltstack.S
@@ -4,16 +4,16 @@
 
 ENTRY(sigaltstack)
     .set noreorder
-    .cpload t9
-    li v0, __NR_sigaltstack
+    .cpload $t9
+    li $v0, __NR_sigaltstack
     syscall
-    bnez a3, 1f
-    move a0, v0
-    j ra
+    bnez $a3, 1f
+    move $a0, $v0
+    j $ra
     nop
 1:
-    la t9,__set_errno_internal
-    j t9
+    la $t9,__set_errno_internal
+    j $t9
     nop
     .set reorder
 END(sigaltstack)
diff --git a/libc/arch-mips/syscalls/socketpair.S b/libc/arch-mips/syscalls/socketpair.S
index 7f85da3..ac66b34 100644
--- a/libc/arch-mips/syscalls/socketpair.S
+++ b/libc/arch-mips/syscalls/socketpair.S
@@ -4,16 +4,16 @@
 
 ENTRY(socketpair)
     .set noreorder
-    .cpload t9
-    li v0, __NR_socketpair
+    .cpload $t9
+    li $v0, __NR_socketpair
     syscall
-    bnez a3, 1f
-    move a0, v0
-    j ra
+    bnez $a3, 1f
+    move $a0, $v0
+    j $ra
     nop
 1:
-    la t9,__set_errno_internal
-    j t9
+    la $t9,__set_errno_internal
+    j $t9
     nop
     .set reorder
 END(socketpair)
diff --git a/libc/arch-mips/syscalls/splice.S b/libc/arch-mips/syscalls/splice.S
index a55b7e8..afecd83 100644
--- a/libc/arch-mips/syscalls/splice.S
+++ b/libc/arch-mips/syscalls/splice.S
@@ -4,16 +4,16 @@
 
 ENTRY(splice)
     .set noreorder
-    .cpload t9
-    li v0, __NR_splice
+    .cpload $t9
+    li $v0, __NR_splice
     syscall
-    bnez a3, 1f
-    move a0, v0
-    j ra
+    bnez $a3, 1f
+    move $a0, $v0
+    j $ra
     nop
 1:
-    la t9,__set_errno_internal
-    j t9
+    la $t9,__set_errno_internal
+    j $t9
     nop
     .set reorder
 END(splice)
diff --git a/libc/arch-mips/syscalls/swapoff.S b/libc/arch-mips/syscalls/swapoff.S
index ce782d0..dfe3a5c 100644
--- a/libc/arch-mips/syscalls/swapoff.S
+++ b/libc/arch-mips/syscalls/swapoff.S
@@ -4,16 +4,16 @@
 
 ENTRY(swapoff)
     .set noreorder
-    .cpload t9
-    li v0, __NR_swapoff
+    .cpload $t9
+    li $v0, __NR_swapoff
     syscall
-    bnez a3, 1f
-    move a0, v0
-    j ra
+    bnez $a3, 1f
+    move $a0, $v0
+    j $ra
     nop
 1:
-    la t9,__set_errno_internal
-    j t9
+    la $t9,__set_errno_internal
+    j $t9
     nop
     .set reorder
 END(swapoff)
diff --git a/libc/arch-mips/syscalls/swapon.S b/libc/arch-mips/syscalls/swapon.S
index 127c3a8..12cfca1 100644
--- a/libc/arch-mips/syscalls/swapon.S
+++ b/libc/arch-mips/syscalls/swapon.S
@@ -4,16 +4,16 @@
 
 ENTRY(swapon)
     .set noreorder
-    .cpload t9
-    li v0, __NR_swapon
+    .cpload $t9
+    li $v0, __NR_swapon
     syscall
-    bnez a3, 1f
-    move a0, v0
-    j ra
+    bnez $a3, 1f
+    move $a0, $v0
+    j $ra
     nop
 1:
-    la t9,__set_errno_internal
-    j t9
+    la $t9,__set_errno_internal
+    j $t9
     nop
     .set reorder
 END(swapon)
diff --git a/libc/arch-mips/syscalls/symlinkat.S b/libc/arch-mips/syscalls/symlinkat.S
index b0690a4..a349ede 100644
--- a/libc/arch-mips/syscalls/symlinkat.S
+++ b/libc/arch-mips/syscalls/symlinkat.S
@@ -4,16 +4,16 @@
 
 ENTRY(symlinkat)
     .set noreorder
-    .cpload t9
-    li v0, __NR_symlinkat
+    .cpload $t9
+    li $v0, __NR_symlinkat
     syscall
-    bnez a3, 1f
-    move a0, v0
-    j ra
+    bnez $a3, 1f
+    move $a0, $v0
+    j $ra
     nop
 1:
-    la t9,__set_errno_internal
-    j t9
+    la $t9,__set_errno_internal
+    j $t9
     nop
     .set reorder
 END(symlinkat)
diff --git a/libc/arch-mips/syscalls/sync.S b/libc/arch-mips/syscalls/sync.S
index 8858e74..80667b3 100644
--- a/libc/arch-mips/syscalls/sync.S
+++ b/libc/arch-mips/syscalls/sync.S
@@ -4,16 +4,16 @@
 
 ENTRY(sync)
     .set noreorder
-    .cpload t9
-    li v0, __NR_sync
+    .cpload $t9
+    li $v0, __NR_sync
     syscall
-    bnez a3, 1f
-    move a0, v0
-    j ra
+    bnez $a3, 1f
+    move $a0, $v0
+    j $ra
     nop
 1:
-    la t9,__set_errno_internal
-    j t9
+    la $t9,__set_errno_internal
+    j $t9
     nop
     .set reorder
 END(sync)
diff --git a/libc/arch-mips/syscalls/syncfs.S b/libc/arch-mips/syscalls/syncfs.S
index cd87a61..78ee0e7 100644
--- a/libc/arch-mips/syscalls/syncfs.S
+++ b/libc/arch-mips/syscalls/syncfs.S
@@ -4,16 +4,16 @@
 
 ENTRY(syncfs)
     .set noreorder
-    .cpload t9
-    li v0, __NR_syncfs
+    .cpload $t9
+    li $v0, __NR_syncfs
     syscall
-    bnez a3, 1f
-    move a0, v0
-    j ra
+    bnez $a3, 1f
+    move $a0, $v0
+    j $ra
     nop
 1:
-    la t9,__set_errno_internal
-    j t9
+    la $t9,__set_errno_internal
+    j $t9
     nop
     .set reorder
 END(syncfs)
diff --git a/libc/arch-mips/syscalls/sysinfo.S b/libc/arch-mips/syscalls/sysinfo.S
index beefc0e..42fa57d 100644
--- a/libc/arch-mips/syscalls/sysinfo.S
+++ b/libc/arch-mips/syscalls/sysinfo.S
@@ -4,16 +4,16 @@
 
 ENTRY(sysinfo)
     .set noreorder
-    .cpload t9
-    li v0, __NR_sysinfo
+    .cpload $t9
+    li $v0, __NR_sysinfo
     syscall
-    bnez a3, 1f
-    move a0, v0
-    j ra
+    bnez $a3, 1f
+    move $a0, $v0
+    j $ra
     nop
 1:
-    la t9,__set_errno_internal
-    j t9
+    la $t9,__set_errno_internal
+    j $t9
     nop
     .set reorder
 END(sysinfo)
diff --git a/libc/arch-mips/syscalls/tee.S b/libc/arch-mips/syscalls/tee.S
index 1115907..97867e3 100644
--- a/libc/arch-mips/syscalls/tee.S
+++ b/libc/arch-mips/syscalls/tee.S
@@ -4,16 +4,16 @@
 
 ENTRY(tee)
     .set noreorder
-    .cpload t9
-    li v0, __NR_tee
+    .cpload $t9
+    li $v0, __NR_tee
     syscall
-    bnez a3, 1f
-    move a0, v0
-    j ra
+    bnez $a3, 1f
+    move $a0, $v0
+    j $ra
     nop
 1:
-    la t9,__set_errno_internal
-    j t9
+    la $t9,__set_errno_internal
+    j $t9
     nop
     .set reorder
 END(tee)
diff --git a/libc/arch-mips/syscalls/tgkill.S b/libc/arch-mips/syscalls/tgkill.S
index bea211d..cded9e5 100644
--- a/libc/arch-mips/syscalls/tgkill.S
+++ b/libc/arch-mips/syscalls/tgkill.S
@@ -4,16 +4,16 @@
 
 ENTRY(tgkill)
     .set noreorder
-    .cpload t9
-    li v0, __NR_tgkill
+    .cpload $t9
+    li $v0, __NR_tgkill
     syscall
-    bnez a3, 1f
-    move a0, v0
-    j ra
+    bnez $a3, 1f
+    move $a0, $v0
+    j $ra
     nop
 1:
-    la t9,__set_errno_internal
-    j t9
+    la $t9,__set_errno_internal
+    j $t9
     nop
     .set reorder
 END(tgkill)
diff --git a/libc/arch-mips/syscalls/timerfd_create.S b/libc/arch-mips/syscalls/timerfd_create.S
index 116c628..840f7e2 100644
--- a/libc/arch-mips/syscalls/timerfd_create.S
+++ b/libc/arch-mips/syscalls/timerfd_create.S
@@ -4,16 +4,16 @@
 
 ENTRY(timerfd_create)
     .set noreorder
-    .cpload t9
-    li v0, __NR_timerfd_create
+    .cpload $t9
+    li $v0, __NR_timerfd_create
     syscall
-    bnez a3, 1f
-    move a0, v0
-    j ra
+    bnez $a3, 1f
+    move $a0, $v0
+    j $ra
     nop
 1:
-    la t9,__set_errno_internal
-    j t9
+    la $t9,__set_errno_internal
+    j $t9
     nop
     .set reorder
 END(timerfd_create)
diff --git a/libc/arch-mips/syscalls/timerfd_gettime.S b/libc/arch-mips/syscalls/timerfd_gettime.S
index df7138c..7ddc25f 100644
--- a/libc/arch-mips/syscalls/timerfd_gettime.S
+++ b/libc/arch-mips/syscalls/timerfd_gettime.S
@@ -4,16 +4,16 @@
 
 ENTRY(timerfd_gettime)
     .set noreorder
-    .cpload t9
-    li v0, __NR_timerfd_gettime
+    .cpload $t9
+    li $v0, __NR_timerfd_gettime
     syscall
-    bnez a3, 1f
-    move a0, v0
-    j ra
+    bnez $a3, 1f
+    move $a0, $v0
+    j $ra
     nop
 1:
-    la t9,__set_errno_internal
-    j t9
+    la $t9,__set_errno_internal
+    j $t9
     nop
     .set reorder
 END(timerfd_gettime)
diff --git a/libc/arch-mips/syscalls/timerfd_settime.S b/libc/arch-mips/syscalls/timerfd_settime.S
index 2bfadb9..b4e7926 100644
--- a/libc/arch-mips/syscalls/timerfd_settime.S
+++ b/libc/arch-mips/syscalls/timerfd_settime.S
@@ -4,16 +4,16 @@
 
 ENTRY(timerfd_settime)
     .set noreorder
-    .cpload t9
-    li v0, __NR_timerfd_settime
+    .cpload $t9
+    li $v0, __NR_timerfd_settime
     syscall
-    bnez a3, 1f
-    move a0, v0
-    j ra
+    bnez $a3, 1f
+    move $a0, $v0
+    j $ra
     nop
 1:
-    la t9,__set_errno_internal
-    j t9
+    la $t9,__set_errno_internal
+    j $t9
     nop
     .set reorder
 END(timerfd_settime)
diff --git a/libc/arch-mips/syscalls/times.S b/libc/arch-mips/syscalls/times.S
index 90ce97f..ad4003b 100644
--- a/libc/arch-mips/syscalls/times.S
+++ b/libc/arch-mips/syscalls/times.S
@@ -4,16 +4,16 @@
 
 ENTRY(times)
     .set noreorder
-    .cpload t9
-    li v0, __NR_times
+    .cpload $t9
+    li $v0, __NR_times
     syscall
-    bnez a3, 1f
-    move a0, v0
-    j ra
+    bnez $a3, 1f
+    move $a0, $v0
+    j $ra
     nop
 1:
-    la t9,__set_errno_internal
-    j t9
+    la $t9,__set_errno_internal
+    j $t9
     nop
     .set reorder
 END(times)
diff --git a/libc/arch-mips/syscalls/truncate.S b/libc/arch-mips/syscalls/truncate.S
index 6800705..cb077e9 100644
--- a/libc/arch-mips/syscalls/truncate.S
+++ b/libc/arch-mips/syscalls/truncate.S
@@ -4,16 +4,16 @@
 
 ENTRY(truncate)
     .set noreorder
-    .cpload t9
-    li v0, __NR_truncate
+    .cpload $t9
+    li $v0, __NR_truncate
     syscall
-    bnez a3, 1f
-    move a0, v0
-    j ra
+    bnez $a3, 1f
+    move $a0, $v0
+    j $ra
     nop
 1:
-    la t9,__set_errno_internal
-    j t9
+    la $t9,__set_errno_internal
+    j $t9
     nop
     .set reorder
 END(truncate)
diff --git a/libc/arch-mips/syscalls/truncate64.S b/libc/arch-mips/syscalls/truncate64.S
index 870e735..4ccd2ad 100644
--- a/libc/arch-mips/syscalls/truncate64.S
+++ b/libc/arch-mips/syscalls/truncate64.S
@@ -4,16 +4,16 @@
 
 ENTRY(truncate64)
     .set noreorder
-    .cpload t9
-    li v0, __NR_truncate64
+    .cpload $t9
+    li $v0, __NR_truncate64
     syscall
-    bnez a3, 1f
-    move a0, v0
-    j ra
+    bnez $a3, 1f
+    move $a0, $v0
+    j $ra
     nop
 1:
-    la t9,__set_errno_internal
-    j t9
+    la $t9,__set_errno_internal
+    j $t9
     nop
     .set reorder
 END(truncate64)
diff --git a/libc/arch-mips/syscalls/umask.S b/libc/arch-mips/syscalls/umask.S
index ccf4292..196dc07 100644
--- a/libc/arch-mips/syscalls/umask.S
+++ b/libc/arch-mips/syscalls/umask.S
@@ -4,16 +4,16 @@
 
 ENTRY(umask)
     .set noreorder
-    .cpload t9
-    li v0, __NR_umask
+    .cpload $t9
+    li $v0, __NR_umask
     syscall
-    bnez a3, 1f
-    move a0, v0
-    j ra
+    bnez $a3, 1f
+    move $a0, $v0
+    j $ra
     nop
 1:
-    la t9,__set_errno_internal
-    j t9
+    la $t9,__set_errno_internal
+    j $t9
     nop
     .set reorder
 END(umask)
diff --git a/libc/arch-mips/syscalls/umount2.S b/libc/arch-mips/syscalls/umount2.S
index 65a7129..f61e3e9 100644
--- a/libc/arch-mips/syscalls/umount2.S
+++ b/libc/arch-mips/syscalls/umount2.S
@@ -4,16 +4,16 @@
 
 ENTRY(umount2)
     .set noreorder
-    .cpload t9
-    li v0, __NR_umount2
+    .cpload $t9
+    li $v0, __NR_umount2
     syscall
-    bnez a3, 1f
-    move a0, v0
-    j ra
+    bnez $a3, 1f
+    move $a0, $v0
+    j $ra
     nop
 1:
-    la t9,__set_errno_internal
-    j t9
+    la $t9,__set_errno_internal
+    j $t9
     nop
     .set reorder
 END(umount2)
diff --git a/libc/arch-mips/syscalls/uname.S b/libc/arch-mips/syscalls/uname.S
index f540b3a..c3408e0 100644
--- a/libc/arch-mips/syscalls/uname.S
+++ b/libc/arch-mips/syscalls/uname.S
@@ -4,16 +4,16 @@
 
 ENTRY(uname)
     .set noreorder
-    .cpload t9
-    li v0, __NR_uname
+    .cpload $t9
+    li $v0, __NR_uname
     syscall
-    bnez a3, 1f
-    move a0, v0
-    j ra
+    bnez $a3, 1f
+    move $a0, $v0
+    j $ra
     nop
 1:
-    la t9,__set_errno_internal
-    j t9
+    la $t9,__set_errno_internal
+    j $t9
     nop
     .set reorder
 END(uname)
diff --git a/libc/arch-mips/syscalls/unlinkat.S b/libc/arch-mips/syscalls/unlinkat.S
index 001f9cf..400a0b6 100644
--- a/libc/arch-mips/syscalls/unlinkat.S
+++ b/libc/arch-mips/syscalls/unlinkat.S
@@ -4,16 +4,16 @@
 
 ENTRY(unlinkat)
     .set noreorder
-    .cpload t9
-    li v0, __NR_unlinkat
+    .cpload $t9
+    li $v0, __NR_unlinkat
     syscall
-    bnez a3, 1f
-    move a0, v0
-    j ra
+    bnez $a3, 1f
+    move $a0, $v0
+    j $ra
     nop
 1:
-    la t9,__set_errno_internal
-    j t9
+    la $t9,__set_errno_internal
+    j $t9
     nop
     .set reorder
 END(unlinkat)
diff --git a/libc/arch-mips/syscalls/unshare.S b/libc/arch-mips/syscalls/unshare.S
index 13ca452..2e81abb 100644
--- a/libc/arch-mips/syscalls/unshare.S
+++ b/libc/arch-mips/syscalls/unshare.S
@@ -4,16 +4,16 @@
 
 ENTRY(unshare)
     .set noreorder
-    .cpload t9
-    li v0, __NR_unshare
+    .cpload $t9
+    li $v0, __NR_unshare
     syscall
-    bnez a3, 1f
-    move a0, v0
-    j ra
+    bnez $a3, 1f
+    move $a0, $v0
+    j $ra
     nop
 1:
-    la t9,__set_errno_internal
-    j t9
+    la $t9,__set_errno_internal
+    j $t9
     nop
     .set reorder
 END(unshare)
diff --git a/libc/arch-mips/syscalls/utimensat.S b/libc/arch-mips/syscalls/utimensat.S
index 14e5a10..70d0bdd 100644
--- a/libc/arch-mips/syscalls/utimensat.S
+++ b/libc/arch-mips/syscalls/utimensat.S
@@ -4,16 +4,16 @@
 
 ENTRY(utimensat)
     .set noreorder
-    .cpload t9
-    li v0, __NR_utimensat
+    .cpload $t9
+    li $v0, __NR_utimensat
     syscall
-    bnez a3, 1f
-    move a0, v0
-    j ra
+    bnez $a3, 1f
+    move $a0, $v0
+    j $ra
     nop
 1:
-    la t9,__set_errno_internal
-    j t9
+    la $t9,__set_errno_internal
+    j $t9
     nop
     .set reorder
 END(utimensat)
diff --git a/libc/arch-mips/syscalls/vmsplice.S b/libc/arch-mips/syscalls/vmsplice.S
index 0191f53..e575962 100644
--- a/libc/arch-mips/syscalls/vmsplice.S
+++ b/libc/arch-mips/syscalls/vmsplice.S
@@ -4,16 +4,16 @@
 
 ENTRY(vmsplice)
     .set noreorder
-    .cpload t9
-    li v0, __NR_vmsplice
+    .cpload $t9
+    li $v0, __NR_vmsplice
     syscall
-    bnez a3, 1f
-    move a0, v0
-    j ra
+    bnez $a3, 1f
+    move $a0, $v0
+    j $ra
     nop
 1:
-    la t9,__set_errno_internal
-    j t9
+    la $t9,__set_errno_internal
+    j $t9
     nop
     .set reorder
 END(vmsplice)
diff --git a/libc/arch-mips/syscalls/wait4.S b/libc/arch-mips/syscalls/wait4.S
index 8a12533..c9572da 100644
--- a/libc/arch-mips/syscalls/wait4.S
+++ b/libc/arch-mips/syscalls/wait4.S
@@ -4,16 +4,16 @@
 
 ENTRY(wait4)
     .set noreorder
-    .cpload t9
-    li v0, __NR_wait4
+    .cpload $t9
+    li $v0, __NR_wait4
     syscall
-    bnez a3, 1f
-    move a0, v0
-    j ra
+    bnez $a3, 1f
+    move $a0, $v0
+    j $ra
     nop
 1:
-    la t9,__set_errno_internal
-    j t9
+    la $t9,__set_errno_internal
+    j $t9
     nop
     .set reorder
 END(wait4)
diff --git a/libc/arch-mips/syscalls/write.S b/libc/arch-mips/syscalls/write.S
index 62dc36f..501c211 100644
--- a/libc/arch-mips/syscalls/write.S
+++ b/libc/arch-mips/syscalls/write.S
@@ -4,16 +4,16 @@
 
 ENTRY(write)
     .set noreorder
-    .cpload t9
-    li v0, __NR_write
+    .cpload $t9
+    li $v0, __NR_write
     syscall
-    bnez a3, 1f
-    move a0, v0
-    j ra
+    bnez $a3, 1f
+    move $a0, $v0
+    j $ra
     nop
 1:
-    la t9,__set_errno_internal
-    j t9
+    la $t9,__set_errno_internal
+    j $t9
     nop
     .set reorder
 END(write)
diff --git a/libc/arch-mips/syscalls/writev.S b/libc/arch-mips/syscalls/writev.S
index d8d6616..597d7fa 100644
--- a/libc/arch-mips/syscalls/writev.S
+++ b/libc/arch-mips/syscalls/writev.S
@@ -4,16 +4,16 @@
 
 ENTRY(writev)
     .set noreorder
-    .cpload t9
-    li v0, __NR_writev
+    .cpload $t9
+    li $v0, __NR_writev
     syscall
-    bnez a3, 1f
-    move a0, v0
-    j ra
+    bnez $a3, 1f
+    move $a0, $v0
+    j $ra
     nop
 1:
-    la t9,__set_errno_internal
-    j t9
+    la $t9,__set_errno_internal
+    j $t9
     nop
     .set reorder
 END(writev)
diff --git a/libc/arch-mips64/bionic/__bionic_clone.S b/libc/arch-mips64/bionic/__bionic_clone.S
index 0d266ee..d725efc 100644
--- a/libc/arch-mips64/bionic/__bionic_clone.S
+++ b/libc/arch-mips64/bionic/__bionic_clone.S
@@ -43,59 +43,59 @@
 
 // pid_t __bionic_clone(int flags, void* child_stack, pid_t* parent_tid, void* tls, pid_t* child_tid, int (*fn)(void*), void* arg);
 LEAF(__bionic_clone, FRAMESZ)
-	PTR_SUBU sp, FRAMESZ			# allocate stack frame
+	PTR_SUBU $sp, FRAMESZ			# allocate stack frame
 	SETUP_GP64(FRAME_GP,__bionic_clone)
 	SAVE_GP(FRAME_GP)
 
 	# set up child stack
-	PTR_SUBU a1,FRAMESZ
+	PTR_SUBU $a1,FRAMESZ
 #if (_MIPS_SIM == _ABIO32) || (_MIPS_SIM == _ABI32)
-	PTR_L	t0,FRAMESZ+5*REGSZ(sp)	# fn
-	PRL_L	t1,FRAMESZ+6*REGSZ(sp)	# arg
-	PTR_S	t0,FRAME_FN(a1)		# fn
-	PTR_S	t1,FRAME_ARG(a1)	# arg
+	PTR_L	$t0,FRAMESZ+5*REGSZ($sp)	# fn
+	PRL_L	$t1,FRAMESZ+6*REGSZ($sp)	# arg
+	PTR_S	$t0,FRAME_FN($a1)		# fn
+	PTR_S	$t1,FRAME_ARG($a1)	# arg
 #else
-	PTR_L	t0,FRAME_GP(sp)		# copy gp to child stack
-	PTR_S	t0,FRAME_GP(a1)
-	PTR_S	a5,FRAME_FN(a1)		# fn
-	PTR_S	a6,FRAME_ARG(a1)	# arg
+	PTR_L	$t0,FRAME_GP($sp)		# copy gp to child stack
+	PTR_S	$t0,FRAME_GP($a1)
+	PTR_S	$a5,FRAME_FN($a1)		# fn
+	PTR_S	$a6,FRAME_ARG($a1)	# arg
 # endif
 
 	# remainder of arguments are correct for clone system call
-	LI	v0,__NR_clone
+	LI	$v0,__NR_clone
 	syscall
 
-	move    a0,v0
-	bnez	a3,.L__error_bc
+	move    $a0,$v0
+	bnez	$a3,.L__error_bc
 
-	beqz	v0,.L__thread_start_bc
+	beqz	$v0,.L__thread_start_bc
 
 	RESTORE_GP64
-	PTR_ADDU sp,FRAMESZ
-	j	ra
+	PTR_ADDU $sp,FRAMESZ
+	j	$ra
 
 .L__thread_start_bc:
 	# Clear return address in child so we don't unwind further.
-	li	ra,0
+	li	$ra,0
 
 	# void __start_thread(int (*func)(void*), void *arg)
-	PTR_L	a0,FRAME_FN(sp)		#  fn
-	PTR_L	a1,FRAME_ARG(sp)	#  arg
-	LA	t9,__start_thread
+	PTR_L	$a0,FRAME_FN($sp)		#  fn
+	PTR_L	$a1,FRAME_ARG($sp)	#  arg
+	LA	$t9,__start_thread
 	RESTORE_GP64
 	/*
 	 * For O32 etc the child stack must have space for a0..a3 to be stored
 	 * For N64 etc, the child stack can be restored to the original value
 	 */
 #if !((_MIPS_SIM == _ABIO32) || (_MIPS_SIM == _ABI32))
-	PTR_ADDU sp,FRAMESZ
+	PTR_ADDU $sp,FRAMESZ
 #endif
-	j	t9
+	j	$t9
 
 .L__error_bc:
-	LA	t9,__set_errno_internal
+	LA	$t9,__set_errno_internal
 	RESTORE_GP64
-	PTR_ADDU sp,FRAMESZ
-	j	t9
+	PTR_ADDU $sp,FRAMESZ
+	j	$t9
 	END(__bionic_clone)
 .hidden __bionic_clone
diff --git a/libc/arch-mips64/bionic/_exit_with_stack_teardown.S b/libc/arch-mips64/bionic/_exit_with_stack_teardown.S
index fcf8cc1..4f80801 100644
--- a/libc/arch-mips64/bionic/_exit_with_stack_teardown.S
+++ b/libc/arch-mips64/bionic/_exit_with_stack_teardown.S
@@ -30,12 +30,12 @@
 
 // void _exit_with_stack_teardown(void* stackBase, size_t stackSize)
 ENTRY_PRIVATE(_exit_with_stack_teardown)
-  li	v0, __NR_munmap
+  li	$v0, __NR_munmap
   syscall
   // If munmap failed, we ignore the failure and exit anyway.
 
-  li	a0, 0
-  li	v0, __NR_exit
+  li	$a0, 0
+  li	$v0, __NR_exit
   syscall
   // The exit syscall does not return.
 END(_exit_with_stack_teardown)
diff --git a/libc/arch-mips64/bionic/syscall.S b/libc/arch-mips64/bionic/syscall.S
index 4c739fd..ce5dfd3 100644
--- a/libc/arch-mips64/bionic/syscall.S
+++ b/libc/arch-mips64/bionic/syscall.S
@@ -36,33 +36,33 @@
 #endif
 
 LEAF(syscall,FRAMESZ)
-	PTR_SUBU sp, FRAMESZ	# allocate stack frame
+	PTR_SUBU $sp, FRAMESZ	# allocate stack frame
 	SETUP_GP64(FRAME_GP,syscall)
 	SAVE_GP(FRAME_GP)
-	move	v0, a0		# syscall number to v0
-	move	a0, a1		# shift args down
-	move	a1, a2
-	move	a2, a3
+	move	$v0, $a0		# syscall number to v0
+	move	$a0, $a1		# shift args down
+	move	$a1, $a2
+	move	$a2, $a3
 #if (_MIPS_SIM == _ABIO32) || (_MIPS_SIM == _ABI32)
-	REG_L	a3, FRAMESZ+4*REGSZ(sp)
-	REG_L	t0, FRAMESZ+5*REGSZ(sp)
-	REG_L	t1, FRAMESZ+6*REGSZ(sp)
-	REG_S	t0, 4*REGSZ(sp)
-	REG_S	t1, 5*REGSZ(sp)
+	REG_L	$a3, FRAMESZ+4*REGSZ($sp)
+	REG_L	$t0, FRAMESZ+5*REGSZ($sp)
+	REG_L	$t1, FRAMESZ+6*REGSZ($sp)
+	REG_S	$t0, 4*REGSZ($sp)
+	REG_S	$t1, 5*REGSZ($sp)
 #else
-	move	a3, a4
-	move	a4, a5
-	move	a5, a6
+	move	$a3, $a4
+	move	$a4, $a5
+	move	$a5, $a6
 #endif
 	syscall
-	move	a0, v0
-	bnez	a3, 1f
+	move	$a0, $v0
+	bnez	$a3, 1f
 	RESTORE_GP64
-	PTR_ADDU sp, FRAMESZ
-	j	ra
+	PTR_ADDU $sp, FRAMESZ
+	j	$ra
 1:
-	LA	t9,__set_errno_internal
+	LA	$t9,__set_errno_internal
 	RESTORE_GP64
-	PTR_ADDU sp, FRAMESZ
-	j	t9
+	PTR_ADDU $sp, FRAMESZ
+	j	$t9
 	END(syscall)
diff --git a/libc/arch-mips64/bionic/vfork.S b/libc/arch-mips64/bionic/vfork.S
index e0a39ed..b5ff5d4 100644
--- a/libc/arch-mips64/bionic/vfork.S
+++ b/libc/arch-mips64/bionic/vfork.S
@@ -42,36 +42,37 @@
 #endif
 
 LEAF(vfork,FRAMESZ)
+__BIONIC_WEAK_ASM_FOR_NATIVE_BRIDGE(vfork)
 #if FRAMESZ!=0
-	PTR_SUBU sp, FRAMESZ
+	PTR_SUBU $sp, FRAMESZ
 #endif
-	SETUP_GP64(a5, vfork)
+	SETUP_GP64($a5, vfork)
 
 	// __get_tls()[TLS_SLOT_THREAD_ID]->cached_pid_ = 0
-	rdhwr	v0, $29			// v0 = tls
-	REG_L	v0, REGSZ*1(v0)		// v0 = v0[TLS_SLOT_THREAD_ID ie 1]
-	sw	$0, REGSZ*2+4(v0)	// v0->cached_pid_ = 0
+	rdhwr	$v0, $29			// v0 = tls
+	REG_L	$v0, REGSZ*1($v0)		// v0 = v0[TLS_SLOT_THREAD_ID ie 1]
+	sw	$0, REGSZ*2+4($v0)	// v0->cached_pid_ = 0
 
-	LI	a0, (CLONE_VM | CLONE_VFORK | SIGCHLD)
-	move	a1, $0
-	move	a2, $0
-	move	a3, $0
+	LI	$a0, (CLONE_VM | CLONE_VFORK | SIGCHLD)
+	move	$a1, $0
+	move	$a2, $0
+	move	$a3, $0
 #if (_MIPS_SIM == _ABIO32) || (_MIPS_SIM == _ABI32)
 	REG_S	$0, 4*REGSZ(sp)
 #else
-	move	a4, $0
+	move	$a4, $0
 #endif
-	LI	v0, __NR_clone
+	LI	$v0, __NR_clone
 	syscall
 #if FRAMESZ!=0
-	PTR_ADDU sp,FRAMESZ
+	PTR_ADDU $sp,FRAMESZ
 #endif
-	move	a0, v0
-	bnez	a3, 1f
+	move	$a0, $v0
+	bnez	$a3, 1f
 	RESTORE_GP64
-	j	ra
+	j	$ra
 1:
-	LA	t9,__set_errno_internal
+	LA	$t9,__set_errno_internal
 	RESTORE_GP64
-	j	t9
+	j	$t9
 	END(vfork)
diff --git a/libc/arch-mips64/include b/libc/arch-mips64/include
deleted file mode 120000
index fabbe8a..0000000
--- a/libc/arch-mips64/include
+++ /dev/null
@@ -1 +0,0 @@
-../arch-mips/include
\ No newline at end of file
diff --git a/libc/arch-mips64/syscalls/___clock_nanosleep.S b/libc/arch-mips64/syscalls/___clock_nanosleep.S
index e9fb316..1633136 100644
--- a/libc/arch-mips64/syscalls/___clock_nanosleep.S
+++ b/libc/arch-mips64/syscalls/___clock_nanosleep.S
@@ -5,22 +5,22 @@
 ENTRY(___clock_nanosleep)
     .set push
     .set noreorder
-    li v0, __NR_clock_nanosleep
+    li $v0, __NR_clock_nanosleep
     syscall
-    bnez a3, 1f
-    move a0, v0
-    j ra
+    bnez $a3, 1f
+    move $a0, $v0
+    j $ra
     nop
 1:
-    move t0, ra
-    bal     2f
+    move $t0, $ra
+    bal 2f
     nop
 2:
-    .cpsetup ra, t1, 2b
-    LA t9,__set_errno_internal
+    .cpsetup $ra, $t1, 2b
+    LA $t9, __set_errno_internal
     .cpreturn
-    j t9
-    move ra, t0
+    j $t9
+    move $ra, $t0
     .set pop
 END(___clock_nanosleep)
 .hidden ___clock_nanosleep
diff --git a/libc/arch-mips64/syscalls/___close.S b/libc/arch-mips64/syscalls/___close.S
index f1ce708..a8ab9a3 100644
--- a/libc/arch-mips64/syscalls/___close.S
+++ b/libc/arch-mips64/syscalls/___close.S
@@ -5,22 +5,22 @@
 ENTRY(___close)
     .set push
     .set noreorder
-    li v0, __NR_close
+    li $v0, __NR_close
     syscall
-    bnez a3, 1f
-    move a0, v0
-    j ra
+    bnez $a3, 1f
+    move $a0, $v0
+    j $ra
     nop
 1:
-    move t0, ra
-    bal     2f
+    move $t0, $ra
+    bal 2f
     nop
 2:
-    .cpsetup ra, t1, 2b
-    LA t9,__set_errno_internal
+    .cpsetup $ra, $t1, 2b
+    LA $t9, __set_errno_internal
     .cpreturn
-    j t9
-    move ra, t0
+    j $t9
+    move $ra, $t0
     .set pop
 END(___close)
 .hidden ___close
diff --git a/libc/arch-mips64/syscalls/___faccessat.S b/libc/arch-mips64/syscalls/___faccessat.S
index 240625f..6e15b92 100644
--- a/libc/arch-mips64/syscalls/___faccessat.S
+++ b/libc/arch-mips64/syscalls/___faccessat.S
@@ -5,22 +5,22 @@
 ENTRY(___faccessat)
     .set push
     .set noreorder
-    li v0, __NR_faccessat
+    li $v0, __NR_faccessat
     syscall
-    bnez a3, 1f
-    move a0, v0
-    j ra
+    bnez $a3, 1f
+    move $a0, $v0
+    j $ra
     nop
 1:
-    move t0, ra
-    bal     2f
+    move $t0, $ra
+    bal 2f
     nop
 2:
-    .cpsetup ra, t1, 2b
-    LA t9,__set_errno_internal
+    .cpsetup $ra, $t1, 2b
+    LA $t9, __set_errno_internal
     .cpreturn
-    j t9
-    move ra, t0
+    j $t9
+    move $ra, $t0
     .set pop
 END(___faccessat)
 .hidden ___faccessat
diff --git a/libc/arch-mips64/syscalls/___fchmod.S b/libc/arch-mips64/syscalls/___fchmod.S
index 7c16c54..610c7f7 100644
--- a/libc/arch-mips64/syscalls/___fchmod.S
+++ b/libc/arch-mips64/syscalls/___fchmod.S
@@ -5,22 +5,22 @@
 ENTRY(___fchmod)
     .set push
     .set noreorder
-    li v0, __NR_fchmod
+    li $v0, __NR_fchmod
     syscall
-    bnez a3, 1f
-    move a0, v0
-    j ra
+    bnez $a3, 1f
+    move $a0, $v0
+    j $ra
     nop
 1:
-    move t0, ra
-    bal     2f
+    move $t0, $ra
+    bal 2f
     nop
 2:
-    .cpsetup ra, t1, 2b
-    LA t9,__set_errno_internal
+    .cpsetup $ra, $t1, 2b
+    LA $t9, __set_errno_internal
     .cpreturn
-    j t9
-    move ra, t0
+    j $t9
+    move $ra, $t0
     .set pop
 END(___fchmod)
 .hidden ___fchmod
diff --git a/libc/arch-mips64/syscalls/___fchmodat.S b/libc/arch-mips64/syscalls/___fchmodat.S
index 50f108e..70ad465 100644
--- a/libc/arch-mips64/syscalls/___fchmodat.S
+++ b/libc/arch-mips64/syscalls/___fchmodat.S
@@ -5,22 +5,22 @@
 ENTRY(___fchmodat)
     .set push
     .set noreorder
-    li v0, __NR_fchmodat
+    li $v0, __NR_fchmodat
     syscall
-    bnez a3, 1f
-    move a0, v0
-    j ra
+    bnez $a3, 1f
+    move $a0, $v0
+    j $ra
     nop
 1:
-    move t0, ra
-    bal     2f
+    move $t0, $ra
+    bal 2f
     nop
 2:
-    .cpsetup ra, t1, 2b
-    LA t9,__set_errno_internal
+    .cpsetup $ra, $t1, 2b
+    LA $t9, __set_errno_internal
     .cpreturn
-    j t9
-    move ra, t0
+    j $t9
+    move $ra, $t0
     .set pop
 END(___fchmodat)
 .hidden ___fchmodat
diff --git a/libc/arch-mips64/syscalls/___fgetxattr.S b/libc/arch-mips64/syscalls/___fgetxattr.S
index 935b080..fefb416 100644
--- a/libc/arch-mips64/syscalls/___fgetxattr.S
+++ b/libc/arch-mips64/syscalls/___fgetxattr.S
@@ -5,22 +5,22 @@
 ENTRY(___fgetxattr)
     .set push
     .set noreorder
-    li v0, __NR_fgetxattr
+    li $v0, __NR_fgetxattr
     syscall
-    bnez a3, 1f
-    move a0, v0
-    j ra
+    bnez $a3, 1f
+    move $a0, $v0
+    j $ra
     nop
 1:
-    move t0, ra
-    bal     2f
+    move $t0, $ra
+    bal 2f
     nop
 2:
-    .cpsetup ra, t1, 2b
-    LA t9,__set_errno_internal
+    .cpsetup $ra, $t1, 2b
+    LA $t9, __set_errno_internal
     .cpreturn
-    j t9
-    move ra, t0
+    j $t9
+    move $ra, $t0
     .set pop
 END(___fgetxattr)
 .hidden ___fgetxattr
diff --git a/libc/arch-mips64/syscalls/___flistxattr.S b/libc/arch-mips64/syscalls/___flistxattr.S
index 586bcf7..ff1991d 100644
--- a/libc/arch-mips64/syscalls/___flistxattr.S
+++ b/libc/arch-mips64/syscalls/___flistxattr.S
@@ -5,22 +5,22 @@
 ENTRY(___flistxattr)
     .set push
     .set noreorder
-    li v0, __NR_flistxattr
+    li $v0, __NR_flistxattr
     syscall
-    bnez a3, 1f
-    move a0, v0
-    j ra
+    bnez $a3, 1f
+    move $a0, $v0
+    j $ra
     nop
 1:
-    move t0, ra
-    bal     2f
+    move $t0, $ra
+    bal 2f
     nop
 2:
-    .cpsetup ra, t1, 2b
-    LA t9,__set_errno_internal
+    .cpsetup $ra, $t1, 2b
+    LA $t9, __set_errno_internal
     .cpreturn
-    j t9
-    move ra, t0
+    j $t9
+    move $ra, $t0
     .set pop
 END(___flistxattr)
 .hidden ___flistxattr
diff --git a/libc/arch-mips64/syscalls/___fsetxattr.S b/libc/arch-mips64/syscalls/___fsetxattr.S
index c02f406..454be4b 100644
--- a/libc/arch-mips64/syscalls/___fsetxattr.S
+++ b/libc/arch-mips64/syscalls/___fsetxattr.S
@@ -5,22 +5,22 @@
 ENTRY(___fsetxattr)
     .set push
     .set noreorder
-    li v0, __NR_fsetxattr
+    li $v0, __NR_fsetxattr
     syscall
-    bnez a3, 1f
-    move a0, v0
-    j ra
+    bnez $a3, 1f
+    move $a0, $v0
+    j $ra
     nop
 1:
-    move t0, ra
-    bal     2f
+    move $t0, $ra
+    bal 2f
     nop
 2:
-    .cpsetup ra, t1, 2b
-    LA t9,__set_errno_internal
+    .cpsetup $ra, $t1, 2b
+    LA $t9, __set_errno_internal
     .cpreturn
-    j t9
-    move ra, t0
+    j $t9
+    move $ra, $t0
     .set pop
 END(___fsetxattr)
 .hidden ___fsetxattr
diff --git a/libc/arch-mips64/syscalls/___mremap.S b/libc/arch-mips64/syscalls/___mremap.S
index 5004d50..4c996a6 100644
--- a/libc/arch-mips64/syscalls/___mremap.S
+++ b/libc/arch-mips64/syscalls/___mremap.S
@@ -5,22 +5,22 @@
 ENTRY(___mremap)
     .set push
     .set noreorder
-    li v0, __NR_mremap
+    li $v0, __NR_mremap
     syscall
-    bnez a3, 1f
-    move a0, v0
-    j ra
+    bnez $a3, 1f
+    move $a0, $v0
+    j $ra
     nop
 1:
-    move t0, ra
-    bal     2f
+    move $t0, $ra
+    bal 2f
     nop
 2:
-    .cpsetup ra, t1, 2b
-    LA t9,__set_errno_internal
+    .cpsetup $ra, $t1, 2b
+    LA $t9, __set_errno_internal
     .cpreturn
-    j t9
-    move ra, t0
+    j $t9
+    move $ra, $t0
     .set pop
 END(___mremap)
 .hidden ___mremap
diff --git a/libc/arch-mips64/syscalls/___rt_sigqueueinfo.S b/libc/arch-mips64/syscalls/___rt_sigqueueinfo.S
index 1503f51..5cb239a 100644
--- a/libc/arch-mips64/syscalls/___rt_sigqueueinfo.S
+++ b/libc/arch-mips64/syscalls/___rt_sigqueueinfo.S
@@ -5,22 +5,22 @@
 ENTRY(___rt_sigqueueinfo)
     .set push
     .set noreorder
-    li v0, __NR_rt_sigqueueinfo
+    li $v0, __NR_rt_sigqueueinfo
     syscall
-    bnez a3, 1f
-    move a0, v0
-    j ra
+    bnez $a3, 1f
+    move $a0, $v0
+    j $ra
     nop
 1:
-    move t0, ra
-    bal     2f
+    move $t0, $ra
+    bal 2f
     nop
 2:
-    .cpsetup ra, t1, 2b
-    LA t9,__set_errno_internal
+    .cpsetup $ra, $t1, 2b
+    LA $t9, __set_errno_internal
     .cpreturn
-    j t9
-    move ra, t0
+    j $t9
+    move $ra, $t0
     .set pop
 END(___rt_sigqueueinfo)
 .hidden ___rt_sigqueueinfo
diff --git a/libc/arch-mips64/syscalls/__accept4.S b/libc/arch-mips64/syscalls/__accept4.S
index ed9b6c7..d13222e 100644
--- a/libc/arch-mips64/syscalls/__accept4.S
+++ b/libc/arch-mips64/syscalls/__accept4.S
@@ -5,22 +5,22 @@
 ENTRY(__accept4)
     .set push
     .set noreorder
-    li v0, __NR_accept4
+    li $v0, __NR_accept4
     syscall
-    bnez a3, 1f
-    move a0, v0
-    j ra
+    bnez $a3, 1f
+    move $a0, $v0
+    j $ra
     nop
 1:
-    move t0, ra
-    bal     2f
+    move $t0, $ra
+    bal 2f
     nop
 2:
-    .cpsetup ra, t1, 2b
-    LA t9,__set_errno_internal
+    .cpsetup $ra, $t1, 2b
+    LA $t9, __set_errno_internal
     .cpreturn
-    j t9
-    move ra, t0
+    j $t9
+    move $ra, $t0
     .set pop
 END(__accept4)
 .hidden __accept4
diff --git a/libc/arch-mips64/syscalls/__brk.S b/libc/arch-mips64/syscalls/__brk.S
index e1f89c7..a643a66 100644
--- a/libc/arch-mips64/syscalls/__brk.S
+++ b/libc/arch-mips64/syscalls/__brk.S
@@ -5,22 +5,22 @@
 ENTRY(__brk)
     .set push
     .set noreorder
-    li v0, __NR_brk
+    li $v0, __NR_brk
     syscall
-    bnez a3, 1f
-    move a0, v0
-    j ra
+    bnez $a3, 1f
+    move $a0, $v0
+    j $ra
     nop
 1:
-    move t0, ra
-    bal     2f
+    move $t0, $ra
+    bal 2f
     nop
 2:
-    .cpsetup ra, t1, 2b
-    LA t9,__set_errno_internal
+    .cpsetup $ra, $t1, 2b
+    LA $t9, __set_errno_internal
     .cpreturn
-    j t9
-    move ra, t0
+    j $t9
+    move $ra, $t0
     .set pop
 END(__brk)
 .hidden __brk
diff --git a/libc/arch-mips64/syscalls/__clock_gettime.S b/libc/arch-mips64/syscalls/__clock_gettime.S
index 3407122..fb3486b 100644
--- a/libc/arch-mips64/syscalls/__clock_gettime.S
+++ b/libc/arch-mips64/syscalls/__clock_gettime.S
@@ -5,22 +5,22 @@
 ENTRY(__clock_gettime)
     .set push
     .set noreorder
-    li v0, __NR_clock_gettime
+    li $v0, __NR_clock_gettime
     syscall
-    bnez a3, 1f
-    move a0, v0
-    j ra
+    bnez $a3, 1f
+    move $a0, $v0
+    j $ra
     nop
 1:
-    move t0, ra
-    bal     2f
+    move $t0, $ra
+    bal 2f
     nop
 2:
-    .cpsetup ra, t1, 2b
-    LA t9,__set_errno_internal
+    .cpsetup $ra, $t1, 2b
+    LA $t9, __set_errno_internal
     .cpreturn
-    j t9
-    move ra, t0
+    j $t9
+    move $ra, $t0
     .set pop
 END(__clock_gettime)
 .hidden __clock_gettime
diff --git a/libc/arch-mips64/syscalls/__connect.S b/libc/arch-mips64/syscalls/__connect.S
index 8c44464..01f465f 100644
--- a/libc/arch-mips64/syscalls/__connect.S
+++ b/libc/arch-mips64/syscalls/__connect.S
@@ -5,22 +5,22 @@
 ENTRY(__connect)
     .set push
     .set noreorder
-    li v0, __NR_connect
+    li $v0, __NR_connect
     syscall
-    bnez a3, 1f
-    move a0, v0
-    j ra
+    bnez $a3, 1f
+    move $a0, $v0
+    j $ra
     nop
 1:
-    move t0, ra
-    bal     2f
+    move $t0, $ra
+    bal 2f
     nop
 2:
-    .cpsetup ra, t1, 2b
-    LA t9,__set_errno_internal
+    .cpsetup $ra, $t1, 2b
+    LA $t9, __set_errno_internal
     .cpreturn
-    j t9
-    move ra, t0
+    j $t9
+    move $ra, $t0
     .set pop
 END(__connect)
 .hidden __connect
diff --git a/libc/arch-mips64/syscalls/__epoll_pwait.S b/libc/arch-mips64/syscalls/__epoll_pwait.S
index 5dfb380..7362583 100644
--- a/libc/arch-mips64/syscalls/__epoll_pwait.S
+++ b/libc/arch-mips64/syscalls/__epoll_pwait.S
@@ -5,22 +5,22 @@
 ENTRY(__epoll_pwait)
     .set push
     .set noreorder
-    li v0, __NR_epoll_pwait
+    li $v0, __NR_epoll_pwait
     syscall
-    bnez a3, 1f
-    move a0, v0
-    j ra
+    bnez $a3, 1f
+    move $a0, $v0
+    j $ra
     nop
 1:
-    move t0, ra
-    bal     2f
+    move $t0, $ra
+    bal 2f
     nop
 2:
-    .cpsetup ra, t1, 2b
-    LA t9,__set_errno_internal
+    .cpsetup $ra, $t1, 2b
+    LA $t9, __set_errno_internal
     .cpreturn
-    j t9
-    move ra, t0
+    j $t9
+    move $ra, $t0
     .set pop
 END(__epoll_pwait)
 .hidden __epoll_pwait
diff --git a/libc/arch-mips64/syscalls/__exit.S b/libc/arch-mips64/syscalls/__exit.S
index 2d5e03d..d32746a 100644
--- a/libc/arch-mips64/syscalls/__exit.S
+++ b/libc/arch-mips64/syscalls/__exit.S
@@ -5,22 +5,22 @@
 ENTRY(__exit)
     .set push
     .set noreorder
-    li v0, __NR_exit
+    li $v0, __NR_exit
     syscall
-    bnez a3, 1f
-    move a0, v0
-    j ra
+    bnez $a3, 1f
+    move $a0, $v0
+    j $ra
     nop
 1:
-    move t0, ra
-    bal     2f
+    move $t0, $ra
+    bal 2f
     nop
 2:
-    .cpsetup ra, t1, 2b
-    LA t9,__set_errno_internal
+    .cpsetup $ra, $t1, 2b
+    LA $t9, __set_errno_internal
     .cpreturn
-    j t9
-    move ra, t0
+    j $t9
+    move $ra, $t0
     .set pop
 END(__exit)
 .hidden __exit
diff --git a/libc/arch-mips64/syscalls/__fadvise64.S b/libc/arch-mips64/syscalls/__fadvise64.S
index 90aceb0..6170142 100644
--- a/libc/arch-mips64/syscalls/__fadvise64.S
+++ b/libc/arch-mips64/syscalls/__fadvise64.S
@@ -5,22 +5,22 @@
 ENTRY(__fadvise64)
     .set push
     .set noreorder
-    li v0, __NR_fadvise64
+    li $v0, __NR_fadvise64
     syscall
-    bnez a3, 1f
-    move a0, v0
-    j ra
+    bnez $a3, 1f
+    move $a0, $v0
+    j $ra
     nop
 1:
-    move t0, ra
-    bal     2f
+    move $t0, $ra
+    bal 2f
     nop
 2:
-    .cpsetup ra, t1, 2b
-    LA t9,__set_errno_internal
+    .cpsetup $ra, $t1, 2b
+    LA $t9, __set_errno_internal
     .cpreturn
-    j t9
-    move ra, t0
+    j $t9
+    move $ra, $t0
     .set pop
 END(__fadvise64)
 .hidden __fadvise64
diff --git a/libc/arch-mips64/syscalls/__fstatfs.S b/libc/arch-mips64/syscalls/__fstatfs.S
index 8766e22..bc57bb1 100644
--- a/libc/arch-mips64/syscalls/__fstatfs.S
+++ b/libc/arch-mips64/syscalls/__fstatfs.S
@@ -5,22 +5,22 @@
 ENTRY(__fstatfs)
     .set push
     .set noreorder
-    li v0, __NR_fstatfs
+    li $v0, __NR_fstatfs
     syscall
-    bnez a3, 1f
-    move a0, v0
-    j ra
+    bnez $a3, 1f
+    move $a0, $v0
+    j $ra
     nop
 1:
-    move t0, ra
-    bal     2f
+    move $t0, $ra
+    bal 2f
     nop
 2:
-    .cpsetup ra, t1, 2b
-    LA t9,__set_errno_internal
+    .cpsetup $ra, $t1, 2b
+    LA $t9, __set_errno_internal
     .cpreturn
-    j t9
-    move ra, t0
+    j $t9
+    move $ra, $t0
     .set pop
 END(__fstatfs)
 .hidden __fstatfs
diff --git a/libc/arch-mips64/syscalls/__getcpu.S b/libc/arch-mips64/syscalls/__getcpu.S
index a16c21e..05acc44 100644
--- a/libc/arch-mips64/syscalls/__getcpu.S
+++ b/libc/arch-mips64/syscalls/__getcpu.S
@@ -5,22 +5,22 @@
 ENTRY(__getcpu)
     .set push
     .set noreorder
-    li v0, __NR_getcpu
+    li $v0, __NR_getcpu
     syscall
-    bnez a3, 1f
-    move a0, v0
-    j ra
+    bnez $a3, 1f
+    move $a0, $v0
+    j $ra
     nop
 1:
-    move t0, ra
-    bal     2f
+    move $t0, $ra
+    bal 2f
     nop
 2:
-    .cpsetup ra, t1, 2b
-    LA t9,__set_errno_internal
+    .cpsetup $ra, $t1, 2b
+    LA $t9, __set_errno_internal
     .cpreturn
-    j t9
-    move ra, t0
+    j $t9
+    move $ra, $t0
     .set pop
 END(__getcpu)
 .hidden __getcpu
diff --git a/libc/arch-mips64/syscalls/__getcwd.S b/libc/arch-mips64/syscalls/__getcwd.S
index 53eeb68..572d52d 100644
--- a/libc/arch-mips64/syscalls/__getcwd.S
+++ b/libc/arch-mips64/syscalls/__getcwd.S
@@ -5,22 +5,22 @@
 ENTRY(__getcwd)
     .set push
     .set noreorder
-    li v0, __NR_getcwd
+    li $v0, __NR_getcwd
     syscall
-    bnez a3, 1f
-    move a0, v0
-    j ra
+    bnez $a3, 1f
+    move $a0, $v0
+    j $ra
     nop
 1:
-    move t0, ra
-    bal     2f
+    move $t0, $ra
+    bal 2f
     nop
 2:
-    .cpsetup ra, t1, 2b
-    LA t9,__set_errno_internal
+    .cpsetup $ra, $t1, 2b
+    LA $t9, __set_errno_internal
     .cpreturn
-    j t9
-    move ra, t0
+    j $t9
+    move $ra, $t0
     .set pop
 END(__getcwd)
 .hidden __getcwd
diff --git a/libc/arch-mips64/syscalls/__getdents64.S b/libc/arch-mips64/syscalls/__getdents64.S
index 3720b8e..9166c5f 100644
--- a/libc/arch-mips64/syscalls/__getdents64.S
+++ b/libc/arch-mips64/syscalls/__getdents64.S
@@ -5,22 +5,22 @@
 ENTRY(__getdents64)
     .set push
     .set noreorder
-    li v0, __NR_getdents64
+    li $v0, __NR_getdents64
     syscall
-    bnez a3, 1f
-    move a0, v0
-    j ra
+    bnez $a3, 1f
+    move $a0, $v0
+    j $ra
     nop
 1:
-    move t0, ra
-    bal     2f
+    move $t0, $ra
+    bal 2f
     nop
 2:
-    .cpsetup ra, t1, 2b
-    LA t9,__set_errno_internal
+    .cpsetup $ra, $t1, 2b
+    LA $t9, __set_errno_internal
     .cpreturn
-    j t9
-    move ra, t0
+    j $t9
+    move $ra, $t0
     .set pop
 END(__getdents64)
 .hidden __getdents64
diff --git a/libc/arch-mips64/syscalls/__getpid.S b/libc/arch-mips64/syscalls/__getpid.S
index 6d5d926..7344062 100644
--- a/libc/arch-mips64/syscalls/__getpid.S
+++ b/libc/arch-mips64/syscalls/__getpid.S
@@ -5,22 +5,22 @@
 ENTRY(__getpid)
     .set push
     .set noreorder
-    li v0, __NR_getpid
+    li $v0, __NR_getpid
     syscall
-    bnez a3, 1f
-    move a0, v0
-    j ra
+    bnez $a3, 1f
+    move $a0, $v0
+    j $ra
     nop
 1:
-    move t0, ra
-    bal     2f
+    move $t0, $ra
+    bal 2f
     nop
 2:
-    .cpsetup ra, t1, 2b
-    LA t9,__set_errno_internal
+    .cpsetup $ra, $t1, 2b
+    LA $t9, __set_errno_internal
     .cpreturn
-    j t9
-    move ra, t0
+    j $t9
+    move $ra, $t0
     .set pop
 END(__getpid)
 .hidden __getpid
diff --git a/libc/arch-mips64/syscalls/__getpriority.S b/libc/arch-mips64/syscalls/__getpriority.S
index 19327ab..faa386a 100644
--- a/libc/arch-mips64/syscalls/__getpriority.S
+++ b/libc/arch-mips64/syscalls/__getpriority.S
@@ -5,22 +5,22 @@
 ENTRY(__getpriority)
     .set push
     .set noreorder
-    li v0, __NR_getpriority
+    li $v0, __NR_getpriority
     syscall
-    bnez a3, 1f
-    move a0, v0
-    j ra
+    bnez $a3, 1f
+    move $a0, $v0
+    j $ra
     nop
 1:
-    move t0, ra
-    bal     2f
+    move $t0, $ra
+    bal 2f
     nop
 2:
-    .cpsetup ra, t1, 2b
-    LA t9,__set_errno_internal
+    .cpsetup $ra, $t1, 2b
+    LA $t9, __set_errno_internal
     .cpreturn
-    j t9
-    move ra, t0
+    j $t9
+    move $ra, $t0
     .set pop
 END(__getpriority)
 .hidden __getpriority
diff --git a/libc/arch-mips64/syscalls/__gettimeofday.S b/libc/arch-mips64/syscalls/__gettimeofday.S
index 2ac5e9b..2316491 100644
--- a/libc/arch-mips64/syscalls/__gettimeofday.S
+++ b/libc/arch-mips64/syscalls/__gettimeofday.S
@@ -5,22 +5,22 @@
 ENTRY(__gettimeofday)
     .set push
     .set noreorder
-    li v0, __NR_gettimeofday
+    li $v0, __NR_gettimeofday
     syscall
-    bnez a3, 1f
-    move a0, v0
-    j ra
+    bnez $a3, 1f
+    move $a0, $v0
+    j $ra
     nop
 1:
-    move t0, ra
-    bal     2f
+    move $t0, $ra
+    bal 2f
     nop
 2:
-    .cpsetup ra, t1, 2b
-    LA t9,__set_errno_internal
+    .cpsetup $ra, $t1, 2b
+    LA $t9, __set_errno_internal
     .cpreturn
-    j t9
-    move ra, t0
+    j $t9
+    move $ra, $t0
     .set pop
 END(__gettimeofday)
 .hidden __gettimeofday
diff --git a/libc/arch-mips64/syscalls/__ioctl.S b/libc/arch-mips64/syscalls/__ioctl.S
index 7fad0d1..7193cc1 100644
--- a/libc/arch-mips64/syscalls/__ioctl.S
+++ b/libc/arch-mips64/syscalls/__ioctl.S
@@ -5,22 +5,22 @@
 ENTRY(__ioctl)
     .set push
     .set noreorder
-    li v0, __NR_ioctl
+    li $v0, __NR_ioctl
     syscall
-    bnez a3, 1f
-    move a0, v0
-    j ra
+    bnez $a3, 1f
+    move $a0, $v0
+    j $ra
     nop
 1:
-    move t0, ra
-    bal     2f
+    move $t0, $ra
+    bal 2f
     nop
 2:
-    .cpsetup ra, t1, 2b
-    LA t9,__set_errno_internal
+    .cpsetup $ra, $t1, 2b
+    LA $t9, __set_errno_internal
     .cpreturn
-    j t9
-    move ra, t0
+    j $t9
+    move $ra, $t0
     .set pop
 END(__ioctl)
 .hidden __ioctl
diff --git a/libc/arch-mips64/syscalls/__openat.S b/libc/arch-mips64/syscalls/__openat.S
index d3ac13a..a1d6d2f 100644
--- a/libc/arch-mips64/syscalls/__openat.S
+++ b/libc/arch-mips64/syscalls/__openat.S
@@ -5,22 +5,22 @@
 ENTRY(__openat)
     .set push
     .set noreorder
-    li v0, __NR_openat
+    li $v0, __NR_openat
     syscall
-    bnez a3, 1f
-    move a0, v0
-    j ra
+    bnez $a3, 1f
+    move $a0, $v0
+    j $ra
     nop
 1:
-    move t0, ra
-    bal     2f
+    move $t0, $ra
+    bal 2f
     nop
 2:
-    .cpsetup ra, t1, 2b
-    LA t9,__set_errno_internal
+    .cpsetup $ra, $t1, 2b
+    LA $t9, __set_errno_internal
     .cpreturn
-    j t9
-    move ra, t0
+    j $t9
+    move $ra, $t0
     .set pop
 END(__openat)
 .hidden __openat
diff --git a/libc/arch-mips64/syscalls/__ppoll.S b/libc/arch-mips64/syscalls/__ppoll.S
index 4e6fb8a..5992310 100644
--- a/libc/arch-mips64/syscalls/__ppoll.S
+++ b/libc/arch-mips64/syscalls/__ppoll.S
@@ -5,22 +5,22 @@
 ENTRY(__ppoll)
     .set push
     .set noreorder
-    li v0, __NR_ppoll
+    li $v0, __NR_ppoll
     syscall
-    bnez a3, 1f
-    move a0, v0
-    j ra
+    bnez $a3, 1f
+    move $a0, $v0
+    j $ra
     nop
 1:
-    move t0, ra
-    bal     2f
+    move $t0, $ra
+    bal 2f
     nop
 2:
-    .cpsetup ra, t1, 2b
-    LA t9,__set_errno_internal
+    .cpsetup $ra, $t1, 2b
+    LA $t9, __set_errno_internal
     .cpreturn
-    j t9
-    move ra, t0
+    j $t9
+    move $ra, $t0
     .set pop
 END(__ppoll)
 .hidden __ppoll
diff --git a/libc/arch-mips64/syscalls/__pselect6.S b/libc/arch-mips64/syscalls/__pselect6.S
index 6d49d1c..e55eee7 100644
--- a/libc/arch-mips64/syscalls/__pselect6.S
+++ b/libc/arch-mips64/syscalls/__pselect6.S
@@ -5,22 +5,22 @@
 ENTRY(__pselect6)
     .set push
     .set noreorder
-    li v0, __NR_pselect6
+    li $v0, __NR_pselect6
     syscall
-    bnez a3, 1f
-    move a0, v0
-    j ra
+    bnez $a3, 1f
+    move $a0, $v0
+    j $ra
     nop
 1:
-    move t0, ra
-    bal     2f
+    move $t0, $ra
+    bal 2f
     nop
 2:
-    .cpsetup ra, t1, 2b
-    LA t9,__set_errno_internal
+    .cpsetup $ra, $t1, 2b
+    LA $t9, __set_errno_internal
     .cpreturn
-    j t9
-    move ra, t0
+    j $t9
+    move $ra, $t0
     .set pop
 END(__pselect6)
 .hidden __pselect6
diff --git a/libc/arch-mips64/syscalls/__ptrace.S b/libc/arch-mips64/syscalls/__ptrace.S
index 5a3ce16..842d778 100644
--- a/libc/arch-mips64/syscalls/__ptrace.S
+++ b/libc/arch-mips64/syscalls/__ptrace.S
@@ -5,22 +5,22 @@
 ENTRY(__ptrace)
     .set push
     .set noreorder
-    li v0, __NR_ptrace
+    li $v0, __NR_ptrace
     syscall
-    bnez a3, 1f
-    move a0, v0
-    j ra
+    bnez $a3, 1f
+    move $a0, $v0
+    j $ra
     nop
 1:
-    move t0, ra
-    bal     2f
+    move $t0, $ra
+    bal 2f
     nop
 2:
-    .cpsetup ra, t1, 2b
-    LA t9,__set_errno_internal
+    .cpsetup $ra, $t1, 2b
+    LA $t9, __set_errno_internal
     .cpreturn
-    j t9
-    move ra, t0
+    j $t9
+    move $ra, $t0
     .set pop
 END(__ptrace)
 .hidden __ptrace
diff --git a/libc/arch-mips64/syscalls/__reboot.S b/libc/arch-mips64/syscalls/__reboot.S
index 587310d..6b1ae9f 100644
--- a/libc/arch-mips64/syscalls/__reboot.S
+++ b/libc/arch-mips64/syscalls/__reboot.S
@@ -5,22 +5,22 @@
 ENTRY(__reboot)
     .set push
     .set noreorder
-    li v0, __NR_reboot
+    li $v0, __NR_reboot
     syscall
-    bnez a3, 1f
-    move a0, v0
-    j ra
+    bnez $a3, 1f
+    move $a0, $v0
+    j $ra
     nop
 1:
-    move t0, ra
-    bal     2f
+    move $t0, $ra
+    bal 2f
     nop
 2:
-    .cpsetup ra, t1, 2b
-    LA t9,__set_errno_internal
+    .cpsetup $ra, $t1, 2b
+    LA $t9, __set_errno_internal
     .cpreturn
-    j t9
-    move ra, t0
+    j $t9
+    move $ra, $t0
     .set pop
 END(__reboot)
 .hidden __reboot
diff --git a/libc/arch-mips64/syscalls/__rt_sigaction.S b/libc/arch-mips64/syscalls/__rt_sigaction.S
index 7dd3cae..484b482 100644
--- a/libc/arch-mips64/syscalls/__rt_sigaction.S
+++ b/libc/arch-mips64/syscalls/__rt_sigaction.S
@@ -5,22 +5,22 @@
 ENTRY(__rt_sigaction)
     .set push
     .set noreorder
-    li v0, __NR_rt_sigaction
+    li $v0, __NR_rt_sigaction
     syscall
-    bnez a3, 1f
-    move a0, v0
-    j ra
+    bnez $a3, 1f
+    move $a0, $v0
+    j $ra
     nop
 1:
-    move t0, ra
-    bal     2f
+    move $t0, $ra
+    bal 2f
     nop
 2:
-    .cpsetup ra, t1, 2b
-    LA t9,__set_errno_internal
+    .cpsetup $ra, $t1, 2b
+    LA $t9, __set_errno_internal
     .cpreturn
-    j t9
-    move ra, t0
+    j $t9
+    move $ra, $t0
     .set pop
 END(__rt_sigaction)
 .hidden __rt_sigaction
diff --git a/libc/arch-mips64/syscalls/__rt_sigpending.S b/libc/arch-mips64/syscalls/__rt_sigpending.S
index 68ae39a..5961578 100644
--- a/libc/arch-mips64/syscalls/__rt_sigpending.S
+++ b/libc/arch-mips64/syscalls/__rt_sigpending.S
@@ -5,22 +5,22 @@
 ENTRY(__rt_sigpending)
     .set push
     .set noreorder
-    li v0, __NR_rt_sigpending
+    li $v0, __NR_rt_sigpending
     syscall
-    bnez a3, 1f
-    move a0, v0
-    j ra
+    bnez $a3, 1f
+    move $a0, $v0
+    j $ra
     nop
 1:
-    move t0, ra
-    bal     2f
+    move $t0, $ra
+    bal 2f
     nop
 2:
-    .cpsetup ra, t1, 2b
-    LA t9,__set_errno_internal
+    .cpsetup $ra, $t1, 2b
+    LA $t9, __set_errno_internal
     .cpreturn
-    j t9
-    move ra, t0
+    j $t9
+    move $ra, $t0
     .set pop
 END(__rt_sigpending)
 .hidden __rt_sigpending
diff --git a/libc/arch-mips64/syscalls/__rt_sigprocmask.S b/libc/arch-mips64/syscalls/__rt_sigprocmask.S
index 54620e9..c962f66 100644
--- a/libc/arch-mips64/syscalls/__rt_sigprocmask.S
+++ b/libc/arch-mips64/syscalls/__rt_sigprocmask.S
@@ -5,22 +5,22 @@
 ENTRY(__rt_sigprocmask)
     .set push
     .set noreorder
-    li v0, __NR_rt_sigprocmask
+    li $v0, __NR_rt_sigprocmask
     syscall
-    bnez a3, 1f
-    move a0, v0
-    j ra
+    bnez $a3, 1f
+    move $a0, $v0
+    j $ra
     nop
 1:
-    move t0, ra
-    bal     2f
+    move $t0, $ra
+    bal 2f
     nop
 2:
-    .cpsetup ra, t1, 2b
-    LA t9,__set_errno_internal
+    .cpsetup $ra, $t1, 2b
+    LA $t9, __set_errno_internal
     .cpreturn
-    j t9
-    move ra, t0
+    j $t9
+    move $ra, $t0
     .set pop
 END(__rt_sigprocmask)
 .hidden __rt_sigprocmask
diff --git a/libc/arch-mips64/syscalls/__rt_sigsuspend.S b/libc/arch-mips64/syscalls/__rt_sigsuspend.S
index ea15def..7613af2 100644
--- a/libc/arch-mips64/syscalls/__rt_sigsuspend.S
+++ b/libc/arch-mips64/syscalls/__rt_sigsuspend.S
@@ -5,22 +5,22 @@
 ENTRY(__rt_sigsuspend)
     .set push
     .set noreorder
-    li v0, __NR_rt_sigsuspend
+    li $v0, __NR_rt_sigsuspend
     syscall
-    bnez a3, 1f
-    move a0, v0
-    j ra
+    bnez $a3, 1f
+    move $a0, $v0
+    j $ra
     nop
 1:
-    move t0, ra
-    bal     2f
+    move $t0, $ra
+    bal 2f
     nop
 2:
-    .cpsetup ra, t1, 2b
-    LA t9,__set_errno_internal
+    .cpsetup $ra, $t1, 2b
+    LA $t9, __set_errno_internal
     .cpreturn
-    j t9
-    move ra, t0
+    j $t9
+    move $ra, $t0
     .set pop
 END(__rt_sigsuspend)
 .hidden __rt_sigsuspend
diff --git a/libc/arch-mips64/syscalls/__rt_sigtimedwait.S b/libc/arch-mips64/syscalls/__rt_sigtimedwait.S
index 177f17c..0c80a2e 100644
--- a/libc/arch-mips64/syscalls/__rt_sigtimedwait.S
+++ b/libc/arch-mips64/syscalls/__rt_sigtimedwait.S
@@ -5,22 +5,22 @@
 ENTRY(__rt_sigtimedwait)
     .set push
     .set noreorder
-    li v0, __NR_rt_sigtimedwait
+    li $v0, __NR_rt_sigtimedwait
     syscall
-    bnez a3, 1f
-    move a0, v0
-    j ra
+    bnez $a3, 1f
+    move $a0, $v0
+    j $ra
     nop
 1:
-    move t0, ra
-    bal     2f
+    move $t0, $ra
+    bal 2f
     nop
 2:
-    .cpsetup ra, t1, 2b
-    LA t9,__set_errno_internal
+    .cpsetup $ra, $t1, 2b
+    LA $t9, __set_errno_internal
     .cpreturn
-    j t9
-    move ra, t0
+    j $t9
+    move $ra, $t0
     .set pop
 END(__rt_sigtimedwait)
 .hidden __rt_sigtimedwait
diff --git a/libc/arch-mips64/syscalls/__sched_getaffinity.S b/libc/arch-mips64/syscalls/__sched_getaffinity.S
index 2081706..5f5dae2 100644
--- a/libc/arch-mips64/syscalls/__sched_getaffinity.S
+++ b/libc/arch-mips64/syscalls/__sched_getaffinity.S
@@ -5,22 +5,22 @@
 ENTRY(__sched_getaffinity)
     .set push
     .set noreorder
-    li v0, __NR_sched_getaffinity
+    li $v0, __NR_sched_getaffinity
     syscall
-    bnez a3, 1f
-    move a0, v0
-    j ra
+    bnez $a3, 1f
+    move $a0, $v0
+    j $ra
     nop
 1:
-    move t0, ra
-    bal     2f
+    move $t0, $ra
+    bal 2f
     nop
 2:
-    .cpsetup ra, t1, 2b
-    LA t9,__set_errno_internal
+    .cpsetup $ra, $t1, 2b
+    LA $t9, __set_errno_internal
     .cpreturn
-    j t9
-    move ra, t0
+    j $t9
+    move $ra, $t0
     .set pop
 END(__sched_getaffinity)
 .hidden __sched_getaffinity
diff --git a/libc/arch-mips64/syscalls/__set_tid_address.S b/libc/arch-mips64/syscalls/__set_tid_address.S
index cd966dd..a411701 100644
--- a/libc/arch-mips64/syscalls/__set_tid_address.S
+++ b/libc/arch-mips64/syscalls/__set_tid_address.S
@@ -5,22 +5,22 @@
 ENTRY(__set_tid_address)
     .set push
     .set noreorder
-    li v0, __NR_set_tid_address
+    li $v0, __NR_set_tid_address
     syscall
-    bnez a3, 1f
-    move a0, v0
-    j ra
+    bnez $a3, 1f
+    move $a0, $v0
+    j $ra
     nop
 1:
-    move t0, ra
-    bal     2f
+    move $t0, $ra
+    bal 2f
     nop
 2:
-    .cpsetup ra, t1, 2b
-    LA t9,__set_errno_internal
+    .cpsetup $ra, $t1, 2b
+    LA $t9, __set_errno_internal
     .cpreturn
-    j t9
-    move ra, t0
+    j $t9
+    move $ra, $t0
     .set pop
 END(__set_tid_address)
 .hidden __set_tid_address
diff --git a/libc/arch-mips64/syscalls/__set_tls.S b/libc/arch-mips64/syscalls/__set_tls.S
index cc98150..a72c8e3 100644
--- a/libc/arch-mips64/syscalls/__set_tls.S
+++ b/libc/arch-mips64/syscalls/__set_tls.S
@@ -5,22 +5,22 @@
 ENTRY(__set_tls)
     .set push
     .set noreorder
-    li v0, __NR_set_thread_area
+    li $v0, __NR_set_thread_area
     syscall
-    bnez a3, 1f
-    move a0, v0
-    j ra
+    bnez $a3, 1f
+    move $a0, $v0
+    j $ra
     nop
 1:
-    move t0, ra
-    bal     2f
+    move $t0, $ra
+    bal 2f
     nop
 2:
-    .cpsetup ra, t1, 2b
-    LA t9,__set_errno_internal
+    .cpsetup $ra, $t1, 2b
+    LA $t9, __set_errno_internal
     .cpreturn
-    j t9
-    move ra, t0
+    j $t9
+    move $ra, $t0
     .set pop
 END(__set_tls)
 .hidden __set_tls
diff --git a/libc/arch-mips64/syscalls/__signalfd4.S b/libc/arch-mips64/syscalls/__signalfd4.S
index ea6eef1..35e2a0a 100644
--- a/libc/arch-mips64/syscalls/__signalfd4.S
+++ b/libc/arch-mips64/syscalls/__signalfd4.S
@@ -5,22 +5,22 @@
 ENTRY(__signalfd4)
     .set push
     .set noreorder
-    li v0, __NR_signalfd4
+    li $v0, __NR_signalfd4
     syscall
-    bnez a3, 1f
-    move a0, v0
-    j ra
+    bnez $a3, 1f
+    move $a0, $v0
+    j $ra
     nop
 1:
-    move t0, ra
-    bal     2f
+    move $t0, $ra
+    bal 2f
     nop
 2:
-    .cpsetup ra, t1, 2b
-    LA t9,__set_errno_internal
+    .cpsetup $ra, $t1, 2b
+    LA $t9, __set_errno_internal
     .cpreturn
-    j t9
-    move ra, t0
+    j $t9
+    move $ra, $t0
     .set pop
 END(__signalfd4)
 .hidden __signalfd4
diff --git a/libc/arch-mips64/syscalls/__socket.S b/libc/arch-mips64/syscalls/__socket.S
index a499359..dce2031 100644
--- a/libc/arch-mips64/syscalls/__socket.S
+++ b/libc/arch-mips64/syscalls/__socket.S
@@ -5,22 +5,22 @@
 ENTRY(__socket)
     .set push
     .set noreorder
-    li v0, __NR_socket
+    li $v0, __NR_socket
     syscall
-    bnez a3, 1f
-    move a0, v0
-    j ra
+    bnez $a3, 1f
+    move $a0, $v0
+    j $ra
     nop
 1:
-    move t0, ra
-    bal     2f
+    move $t0, $ra
+    bal 2f
     nop
 2:
-    .cpsetup ra, t1, 2b
-    LA t9,__set_errno_internal
+    .cpsetup $ra, $t1, 2b
+    LA $t9, __set_errno_internal
     .cpreturn
-    j t9
-    move ra, t0
+    j $t9
+    move $ra, $t0
     .set pop
 END(__socket)
 .hidden __socket
diff --git a/libc/arch-mips64/syscalls/__statfs.S b/libc/arch-mips64/syscalls/__statfs.S
index 52db4e2..9960fc7 100644
--- a/libc/arch-mips64/syscalls/__statfs.S
+++ b/libc/arch-mips64/syscalls/__statfs.S
@@ -5,22 +5,22 @@
 ENTRY(__statfs)
     .set push
     .set noreorder
-    li v0, __NR_statfs
+    li $v0, __NR_statfs
     syscall
-    bnez a3, 1f
-    move a0, v0
-    j ra
+    bnez $a3, 1f
+    move $a0, $v0
+    j $ra
     nop
 1:
-    move t0, ra
-    bal     2f
+    move $t0, $ra
+    bal 2f
     nop
 2:
-    .cpsetup ra, t1, 2b
-    LA t9,__set_errno_internal
+    .cpsetup $ra, $t1, 2b
+    LA $t9, __set_errno_internal
     .cpreturn
-    j t9
-    move ra, t0
+    j $t9
+    move $ra, $t0
     .set pop
 END(__statfs)
 .hidden __statfs
diff --git a/libc/arch-mips64/syscalls/__sync_file_range.S b/libc/arch-mips64/syscalls/__sync_file_range.S
index e22c36e..eeb470d 100644
--- a/libc/arch-mips64/syscalls/__sync_file_range.S
+++ b/libc/arch-mips64/syscalls/__sync_file_range.S
@@ -5,22 +5,22 @@
 ENTRY(__sync_file_range)
     .set push
     .set noreorder
-    li v0, __NR_sync_file_range
+    li $v0, __NR_sync_file_range
     syscall
-    bnez a3, 1f
-    move a0, v0
-    j ra
+    bnez $a3, 1f
+    move $a0, $v0
+    j $ra
     nop
 1:
-    move t0, ra
-    bal     2f
+    move $t0, $ra
+    bal 2f
     nop
 2:
-    .cpsetup ra, t1, 2b
-    LA t9,__set_errno_internal
+    .cpsetup $ra, $t1, 2b
+    LA $t9, __set_errno_internal
     .cpreturn
-    j t9
-    move ra, t0
+    j $t9
+    move $ra, $t0
     .set pop
 END(__sync_file_range)
 .hidden __sync_file_range
diff --git a/libc/arch-mips64/syscalls/__timer_create.S b/libc/arch-mips64/syscalls/__timer_create.S
index c66d8f9..2fecc4d 100644
--- a/libc/arch-mips64/syscalls/__timer_create.S
+++ b/libc/arch-mips64/syscalls/__timer_create.S
@@ -5,22 +5,22 @@
 ENTRY(__timer_create)
     .set push
     .set noreorder
-    li v0, __NR_timer_create
+    li $v0, __NR_timer_create
     syscall
-    bnez a3, 1f
-    move a0, v0
-    j ra
+    bnez $a3, 1f
+    move $a0, $v0
+    j $ra
     nop
 1:
-    move t0, ra
-    bal     2f
+    move $t0, $ra
+    bal 2f
     nop
 2:
-    .cpsetup ra, t1, 2b
-    LA t9,__set_errno_internal
+    .cpsetup $ra, $t1, 2b
+    LA $t9, __set_errno_internal
     .cpreturn
-    j t9
-    move ra, t0
+    j $t9
+    move $ra, $t0
     .set pop
 END(__timer_create)
 .hidden __timer_create
diff --git a/libc/arch-mips64/syscalls/__timer_delete.S b/libc/arch-mips64/syscalls/__timer_delete.S
index 45cf5e8..be6ac60 100644
--- a/libc/arch-mips64/syscalls/__timer_delete.S
+++ b/libc/arch-mips64/syscalls/__timer_delete.S
@@ -5,22 +5,22 @@
 ENTRY(__timer_delete)
     .set push
     .set noreorder
-    li v0, __NR_timer_delete
+    li $v0, __NR_timer_delete
     syscall
-    bnez a3, 1f
-    move a0, v0
-    j ra
+    bnez $a3, 1f
+    move $a0, $v0
+    j $ra
     nop
 1:
-    move t0, ra
-    bal     2f
+    move $t0, $ra
+    bal 2f
     nop
 2:
-    .cpsetup ra, t1, 2b
-    LA t9,__set_errno_internal
+    .cpsetup $ra, $t1, 2b
+    LA $t9, __set_errno_internal
     .cpreturn
-    j t9
-    move ra, t0
+    j $t9
+    move $ra, $t0
     .set pop
 END(__timer_delete)
 .hidden __timer_delete
diff --git a/libc/arch-mips64/syscalls/__timer_getoverrun.S b/libc/arch-mips64/syscalls/__timer_getoverrun.S
index 8a73160..dfabba6 100644
--- a/libc/arch-mips64/syscalls/__timer_getoverrun.S
+++ b/libc/arch-mips64/syscalls/__timer_getoverrun.S
@@ -5,22 +5,22 @@
 ENTRY(__timer_getoverrun)
     .set push
     .set noreorder
-    li v0, __NR_timer_getoverrun
+    li $v0, __NR_timer_getoverrun
     syscall
-    bnez a3, 1f
-    move a0, v0
-    j ra
+    bnez $a3, 1f
+    move $a0, $v0
+    j $ra
     nop
 1:
-    move t0, ra
-    bal     2f
+    move $t0, $ra
+    bal 2f
     nop
 2:
-    .cpsetup ra, t1, 2b
-    LA t9,__set_errno_internal
+    .cpsetup $ra, $t1, 2b
+    LA $t9, __set_errno_internal
     .cpreturn
-    j t9
-    move ra, t0
+    j $t9
+    move $ra, $t0
     .set pop
 END(__timer_getoverrun)
 .hidden __timer_getoverrun
diff --git a/libc/arch-mips64/syscalls/__timer_gettime.S b/libc/arch-mips64/syscalls/__timer_gettime.S
index 32ee5bf..49606c2 100644
--- a/libc/arch-mips64/syscalls/__timer_gettime.S
+++ b/libc/arch-mips64/syscalls/__timer_gettime.S
@@ -5,22 +5,22 @@
 ENTRY(__timer_gettime)
     .set push
     .set noreorder
-    li v0, __NR_timer_gettime
+    li $v0, __NR_timer_gettime
     syscall
-    bnez a3, 1f
-    move a0, v0
-    j ra
+    bnez $a3, 1f
+    move $a0, $v0
+    j $ra
     nop
 1:
-    move t0, ra
-    bal     2f
+    move $t0, $ra
+    bal 2f
     nop
 2:
-    .cpsetup ra, t1, 2b
-    LA t9,__set_errno_internal
+    .cpsetup $ra, $t1, 2b
+    LA $t9, __set_errno_internal
     .cpreturn
-    j t9
-    move ra, t0
+    j $t9
+    move $ra, $t0
     .set pop
 END(__timer_gettime)
 .hidden __timer_gettime
diff --git a/libc/arch-mips64/syscalls/__timer_settime.S b/libc/arch-mips64/syscalls/__timer_settime.S
index 59764d8..a61d92c 100644
--- a/libc/arch-mips64/syscalls/__timer_settime.S
+++ b/libc/arch-mips64/syscalls/__timer_settime.S
@@ -5,22 +5,22 @@
 ENTRY(__timer_settime)
     .set push
     .set noreorder
-    li v0, __NR_timer_settime
+    li $v0, __NR_timer_settime
     syscall
-    bnez a3, 1f
-    move a0, v0
-    j ra
+    bnez $a3, 1f
+    move $a0, $v0
+    j $ra
     nop
 1:
-    move t0, ra
-    bal     2f
+    move $t0, $ra
+    bal 2f
     nop
 2:
-    .cpsetup ra, t1, 2b
-    LA t9,__set_errno_internal
+    .cpsetup $ra, $t1, 2b
+    LA $t9, __set_errno_internal
     .cpreturn
-    j t9
-    move ra, t0
+    j $t9
+    move $ra, $t0
     .set pop
 END(__timer_settime)
 .hidden __timer_settime
diff --git a/libc/arch-mips64/syscalls/__waitid.S b/libc/arch-mips64/syscalls/__waitid.S
index 5ee090d..bc4810c 100644
--- a/libc/arch-mips64/syscalls/__waitid.S
+++ b/libc/arch-mips64/syscalls/__waitid.S
@@ -5,22 +5,22 @@
 ENTRY(__waitid)
     .set push
     .set noreorder
-    li v0, __NR_waitid
+    li $v0, __NR_waitid
     syscall
-    bnez a3, 1f
-    move a0, v0
-    j ra
+    bnez $a3, 1f
+    move $a0, $v0
+    j $ra
     nop
 1:
-    move t0, ra
-    bal     2f
+    move $t0, $ra
+    bal 2f
     nop
 2:
-    .cpsetup ra, t1, 2b
-    LA t9,__set_errno_internal
+    .cpsetup $ra, $t1, 2b
+    LA $t9, __set_errno_internal
     .cpreturn
-    j t9
-    move ra, t0
+    j $t9
+    move $ra, $t0
     .set pop
 END(__waitid)
 .hidden __waitid
diff --git a/libc/arch-mips64/syscalls/_exit.S b/libc/arch-mips64/syscalls/_exit.S
index 37f8119..638fdb1 100644
--- a/libc/arch-mips64/syscalls/_exit.S
+++ b/libc/arch-mips64/syscalls/_exit.S
@@ -5,22 +5,22 @@
 ENTRY(_exit)
     .set push
     .set noreorder
-    li v0, __NR_exit_group
+    li $v0, __NR_exit_group
     syscall
-    bnez a3, 1f
-    move a0, v0
-    j ra
+    bnez $a3, 1f
+    move $a0, $v0
+    j $ra
     nop
 1:
-    move t0, ra
-    bal     2f
+    move $t0, $ra
+    bal 2f
     nop
 2:
-    .cpsetup ra, t1, 2b
-    LA t9,__set_errno_internal
+    .cpsetup $ra, $t1, 2b
+    LA $t9, __set_errno_internal
     .cpreturn
-    j t9
-    move ra, t0
+    j $t9
+    move $ra, $t0
     .set pop
 END(_exit)
 
diff --git a/libc/arch-mips64/syscalls/acct.S b/libc/arch-mips64/syscalls/acct.S
index ff728dc..abf4c26 100644
--- a/libc/arch-mips64/syscalls/acct.S
+++ b/libc/arch-mips64/syscalls/acct.S
@@ -5,21 +5,21 @@
 ENTRY(acct)
     .set push
     .set noreorder
-    li v0, __NR_acct
+    li $v0, __NR_acct
     syscall
-    bnez a3, 1f
-    move a0, v0
-    j ra
+    bnez $a3, 1f
+    move $a0, $v0
+    j $ra
     nop
 1:
-    move t0, ra
-    bal     2f
+    move $t0, $ra
+    bal 2f
     nop
 2:
-    .cpsetup ra, t1, 2b
-    LA t9,__set_errno_internal
+    .cpsetup $ra, $t1, 2b
+    LA $t9, __set_errno_internal
     .cpreturn
-    j t9
-    move ra, t0
+    j $t9
+    move $ra, $t0
     .set pop
 END(acct)
diff --git a/libc/arch-mips64/syscalls/adjtimex.S b/libc/arch-mips64/syscalls/adjtimex.S
index 57b012c..716f46f 100644
--- a/libc/arch-mips64/syscalls/adjtimex.S
+++ b/libc/arch-mips64/syscalls/adjtimex.S
@@ -5,21 +5,21 @@
 ENTRY(adjtimex)
     .set push
     .set noreorder
-    li v0, __NR_adjtimex
+    li $v0, __NR_adjtimex
     syscall
-    bnez a3, 1f
-    move a0, v0
-    j ra
+    bnez $a3, 1f
+    move $a0, $v0
+    j $ra
     nop
 1:
-    move t0, ra
-    bal     2f
+    move $t0, $ra
+    bal 2f
     nop
 2:
-    .cpsetup ra, t1, 2b
-    LA t9,__set_errno_internal
+    .cpsetup $ra, $t1, 2b
+    LA $t9, __set_errno_internal
     .cpreturn
-    j t9
-    move ra, t0
+    j $t9
+    move $ra, $t0
     .set pop
 END(adjtimex)
diff --git a/libc/arch-mips64/syscalls/bind.S b/libc/arch-mips64/syscalls/bind.S
index 9c2b5b8..a0b43ab 100644
--- a/libc/arch-mips64/syscalls/bind.S
+++ b/libc/arch-mips64/syscalls/bind.S
@@ -5,21 +5,21 @@
 ENTRY(bind)
     .set push
     .set noreorder
-    li v0, __NR_bind
+    li $v0, __NR_bind
     syscall
-    bnez a3, 1f
-    move a0, v0
-    j ra
+    bnez $a3, 1f
+    move $a0, $v0
+    j $ra
     nop
 1:
-    move t0, ra
-    bal     2f
+    move $t0, $ra
+    bal 2f
     nop
 2:
-    .cpsetup ra, t1, 2b
-    LA t9,__set_errno_internal
+    .cpsetup $ra, $t1, 2b
+    LA $t9, __set_errno_internal
     .cpreturn
-    j t9
-    move ra, t0
+    j $t9
+    move $ra, $t0
     .set pop
 END(bind)
diff --git a/libc/arch-mips64/syscalls/capget.S b/libc/arch-mips64/syscalls/capget.S
index 9d05438..1fd3b43 100644
--- a/libc/arch-mips64/syscalls/capget.S
+++ b/libc/arch-mips64/syscalls/capget.S
@@ -5,21 +5,21 @@
 ENTRY(capget)
     .set push
     .set noreorder
-    li v0, __NR_capget
+    li $v0, __NR_capget
     syscall
-    bnez a3, 1f
-    move a0, v0
-    j ra
+    bnez $a3, 1f
+    move $a0, $v0
+    j $ra
     nop
 1:
-    move t0, ra
-    bal     2f
+    move $t0, $ra
+    bal 2f
     nop
 2:
-    .cpsetup ra, t1, 2b
-    LA t9,__set_errno_internal
+    .cpsetup $ra, $t1, 2b
+    LA $t9, __set_errno_internal
     .cpreturn
-    j t9
-    move ra, t0
+    j $t9
+    move $ra, $t0
     .set pop
 END(capget)
diff --git a/libc/arch-mips64/syscalls/capset.S b/libc/arch-mips64/syscalls/capset.S
index e947028..e183202 100644
--- a/libc/arch-mips64/syscalls/capset.S
+++ b/libc/arch-mips64/syscalls/capset.S
@@ -5,21 +5,21 @@
 ENTRY(capset)
     .set push
     .set noreorder
-    li v0, __NR_capset
+    li $v0, __NR_capset
     syscall
-    bnez a3, 1f
-    move a0, v0
-    j ra
+    bnez $a3, 1f
+    move $a0, $v0
+    j $ra
     nop
 1:
-    move t0, ra
-    bal     2f
+    move $t0, $ra
+    bal 2f
     nop
 2:
-    .cpsetup ra, t1, 2b
-    LA t9,__set_errno_internal
+    .cpsetup $ra, $t1, 2b
+    LA $t9, __set_errno_internal
     .cpreturn
-    j t9
-    move ra, t0
+    j $t9
+    move $ra, $t0
     .set pop
 END(capset)
diff --git a/libc/arch-mips64/syscalls/chdir.S b/libc/arch-mips64/syscalls/chdir.S
index 14b22c9..c4dc3b7 100644
--- a/libc/arch-mips64/syscalls/chdir.S
+++ b/libc/arch-mips64/syscalls/chdir.S
@@ -5,21 +5,21 @@
 ENTRY(chdir)
     .set push
     .set noreorder
-    li v0, __NR_chdir
+    li $v0, __NR_chdir
     syscall
-    bnez a3, 1f
-    move a0, v0
-    j ra
+    bnez $a3, 1f
+    move $a0, $v0
+    j $ra
     nop
 1:
-    move t0, ra
-    bal     2f
+    move $t0, $ra
+    bal 2f
     nop
 2:
-    .cpsetup ra, t1, 2b
-    LA t9,__set_errno_internal
+    .cpsetup $ra, $t1, 2b
+    LA $t9, __set_errno_internal
     .cpreturn
-    j t9
-    move ra, t0
+    j $t9
+    move $ra, $t0
     .set pop
 END(chdir)
diff --git a/libc/arch-mips64/syscalls/chroot.S b/libc/arch-mips64/syscalls/chroot.S
index e805f51..7880087 100644
--- a/libc/arch-mips64/syscalls/chroot.S
+++ b/libc/arch-mips64/syscalls/chroot.S
@@ -5,21 +5,21 @@
 ENTRY(chroot)
     .set push
     .set noreorder
-    li v0, __NR_chroot
+    li $v0, __NR_chroot
     syscall
-    bnez a3, 1f
-    move a0, v0
-    j ra
+    bnez $a3, 1f
+    move $a0, $v0
+    j $ra
     nop
 1:
-    move t0, ra
-    bal     2f
+    move $t0, $ra
+    bal 2f
     nop
 2:
-    .cpsetup ra, t1, 2b
-    LA t9,__set_errno_internal
+    .cpsetup $ra, $t1, 2b
+    LA $t9, __set_errno_internal
     .cpreturn
-    j t9
-    move ra, t0
+    j $t9
+    move $ra, $t0
     .set pop
 END(chroot)
diff --git a/libc/arch-mips64/syscalls/clock_adjtime.S b/libc/arch-mips64/syscalls/clock_adjtime.S
index 206e9fd..3650647 100644
--- a/libc/arch-mips64/syscalls/clock_adjtime.S
+++ b/libc/arch-mips64/syscalls/clock_adjtime.S
@@ -5,21 +5,21 @@
 ENTRY(clock_adjtime)
     .set push
     .set noreorder
-    li v0, __NR_clock_adjtime
+    li $v0, __NR_clock_adjtime
     syscall
-    bnez a3, 1f
-    move a0, v0
-    j ra
+    bnez $a3, 1f
+    move $a0, $v0
+    j $ra
     nop
 1:
-    move t0, ra
-    bal     2f
+    move $t0, $ra
+    bal 2f
     nop
 2:
-    .cpsetup ra, t1, 2b
-    LA t9,__set_errno_internal
+    .cpsetup $ra, $t1, 2b
+    LA $t9, __set_errno_internal
     .cpreturn
-    j t9
-    move ra, t0
+    j $t9
+    move $ra, $t0
     .set pop
 END(clock_adjtime)
diff --git a/libc/arch-mips64/syscalls/clock_getres.S b/libc/arch-mips64/syscalls/clock_getres.S
index 41003a0..32fac1a 100644
--- a/libc/arch-mips64/syscalls/clock_getres.S
+++ b/libc/arch-mips64/syscalls/clock_getres.S
@@ -5,21 +5,21 @@
 ENTRY(clock_getres)
     .set push
     .set noreorder
-    li v0, __NR_clock_getres
+    li $v0, __NR_clock_getres
     syscall
-    bnez a3, 1f
-    move a0, v0
-    j ra
+    bnez $a3, 1f
+    move $a0, $v0
+    j $ra
     nop
 1:
-    move t0, ra
-    bal     2f
+    move $t0, $ra
+    bal 2f
     nop
 2:
-    .cpsetup ra, t1, 2b
-    LA t9,__set_errno_internal
+    .cpsetup $ra, $t1, 2b
+    LA $t9, __set_errno_internal
     .cpreturn
-    j t9
-    move ra, t0
+    j $t9
+    move $ra, $t0
     .set pop
 END(clock_getres)
diff --git a/libc/arch-mips64/syscalls/clock_settime.S b/libc/arch-mips64/syscalls/clock_settime.S
index 77b6ae4..fa63bad 100644
--- a/libc/arch-mips64/syscalls/clock_settime.S
+++ b/libc/arch-mips64/syscalls/clock_settime.S
@@ -5,21 +5,21 @@
 ENTRY(clock_settime)
     .set push
     .set noreorder
-    li v0, __NR_clock_settime
+    li $v0, __NR_clock_settime
     syscall
-    bnez a3, 1f
-    move a0, v0
-    j ra
+    bnez $a3, 1f
+    move $a0, $v0
+    j $ra
     nop
 1:
-    move t0, ra
-    bal     2f
+    move $t0, $ra
+    bal 2f
     nop
 2:
-    .cpsetup ra, t1, 2b
-    LA t9,__set_errno_internal
+    .cpsetup $ra, $t1, 2b
+    LA $t9, __set_errno_internal
     .cpreturn
-    j t9
-    move ra, t0
+    j $t9
+    move $ra, $t0
     .set pop
 END(clock_settime)
diff --git a/libc/arch-mips64/syscalls/delete_module.S b/libc/arch-mips64/syscalls/delete_module.S
index 8396537..41f0333 100644
--- a/libc/arch-mips64/syscalls/delete_module.S
+++ b/libc/arch-mips64/syscalls/delete_module.S
@@ -5,21 +5,21 @@
 ENTRY(delete_module)
     .set push
     .set noreorder
-    li v0, __NR_delete_module
+    li $v0, __NR_delete_module
     syscall
-    bnez a3, 1f
-    move a0, v0
-    j ra
+    bnez $a3, 1f
+    move $a0, $v0
+    j $ra
     nop
 1:
-    move t0, ra
-    bal     2f
+    move $t0, $ra
+    bal 2f
     nop
 2:
-    .cpsetup ra, t1, 2b
-    LA t9,__set_errno_internal
+    .cpsetup $ra, $t1, 2b
+    LA $t9, __set_errno_internal
     .cpreturn
-    j t9
-    move ra, t0
+    j $t9
+    move $ra, $t0
     .set pop
 END(delete_module)
diff --git a/libc/arch-mips64/syscalls/dup.S b/libc/arch-mips64/syscalls/dup.S
index d1ca5e7..b916cd5 100644
--- a/libc/arch-mips64/syscalls/dup.S
+++ b/libc/arch-mips64/syscalls/dup.S
@@ -5,21 +5,21 @@
 ENTRY(dup)
     .set push
     .set noreorder
-    li v0, __NR_dup
+    li $v0, __NR_dup
     syscall
-    bnez a3, 1f
-    move a0, v0
-    j ra
+    bnez $a3, 1f
+    move $a0, $v0
+    j $ra
     nop
 1:
-    move t0, ra
-    bal     2f
+    move $t0, $ra
+    bal 2f
     nop
 2:
-    .cpsetup ra, t1, 2b
-    LA t9,__set_errno_internal
+    .cpsetup $ra, $t1, 2b
+    LA $t9, __set_errno_internal
     .cpreturn
-    j t9
-    move ra, t0
+    j $t9
+    move $ra, $t0
     .set pop
 END(dup)
diff --git a/libc/arch-mips64/syscalls/dup3.S b/libc/arch-mips64/syscalls/dup3.S
index 5601f31..975e768 100644
--- a/libc/arch-mips64/syscalls/dup3.S
+++ b/libc/arch-mips64/syscalls/dup3.S
@@ -5,21 +5,21 @@
 ENTRY(dup3)
     .set push
     .set noreorder
-    li v0, __NR_dup3
+    li $v0, __NR_dup3
     syscall
-    bnez a3, 1f
-    move a0, v0
-    j ra
+    bnez $a3, 1f
+    move $a0, $v0
+    j $ra
     nop
 1:
-    move t0, ra
-    bal     2f
+    move $t0, $ra
+    bal 2f
     nop
 2:
-    .cpsetup ra, t1, 2b
-    LA t9,__set_errno_internal
+    .cpsetup $ra, $t1, 2b
+    LA $t9, __set_errno_internal
     .cpreturn
-    j t9
-    move ra, t0
+    j $t9
+    move $ra, $t0
     .set pop
 END(dup3)
diff --git a/libc/arch-mips64/syscalls/epoll_create1.S b/libc/arch-mips64/syscalls/epoll_create1.S
index 11f1ceb..2cb913a 100644
--- a/libc/arch-mips64/syscalls/epoll_create1.S
+++ b/libc/arch-mips64/syscalls/epoll_create1.S
@@ -5,21 +5,21 @@
 ENTRY(epoll_create1)
     .set push
     .set noreorder
-    li v0, __NR_epoll_create1
+    li $v0, __NR_epoll_create1
     syscall
-    bnez a3, 1f
-    move a0, v0
-    j ra
+    bnez $a3, 1f
+    move $a0, $v0
+    j $ra
     nop
 1:
-    move t0, ra
-    bal     2f
+    move $t0, $ra
+    bal 2f
     nop
 2:
-    .cpsetup ra, t1, 2b
-    LA t9,__set_errno_internal
+    .cpsetup $ra, $t1, 2b
+    LA $t9, __set_errno_internal
     .cpreturn
-    j t9
-    move ra, t0
+    j $t9
+    move $ra, $t0
     .set pop
 END(epoll_create1)
diff --git a/libc/arch-mips64/syscalls/epoll_ctl.S b/libc/arch-mips64/syscalls/epoll_ctl.S
index 9eba605..2a8f731 100644
--- a/libc/arch-mips64/syscalls/epoll_ctl.S
+++ b/libc/arch-mips64/syscalls/epoll_ctl.S
@@ -5,21 +5,21 @@
 ENTRY(epoll_ctl)
     .set push
     .set noreorder
-    li v0, __NR_epoll_ctl
+    li $v0, __NR_epoll_ctl
     syscall
-    bnez a3, 1f
-    move a0, v0
-    j ra
+    bnez $a3, 1f
+    move $a0, $v0
+    j $ra
     nop
 1:
-    move t0, ra
-    bal     2f
+    move $t0, $ra
+    bal 2f
     nop
 2:
-    .cpsetup ra, t1, 2b
-    LA t9,__set_errno_internal
+    .cpsetup $ra, $t1, 2b
+    LA $t9, __set_errno_internal
     .cpreturn
-    j t9
-    move ra, t0
+    j $t9
+    move $ra, $t0
     .set pop
 END(epoll_ctl)
diff --git a/libc/arch-mips64/syscalls/eventfd.S b/libc/arch-mips64/syscalls/eventfd.S
index 5cd63e4..f8eaee7 100644
--- a/libc/arch-mips64/syscalls/eventfd.S
+++ b/libc/arch-mips64/syscalls/eventfd.S
@@ -5,21 +5,21 @@
 ENTRY(eventfd)
     .set push
     .set noreorder
-    li v0, __NR_eventfd2
+    li $v0, __NR_eventfd2
     syscall
-    bnez a3, 1f
-    move a0, v0
-    j ra
+    bnez $a3, 1f
+    move $a0, $v0
+    j $ra
     nop
 1:
-    move t0, ra
-    bal     2f
+    move $t0, $ra
+    bal 2f
     nop
 2:
-    .cpsetup ra, t1, 2b
-    LA t9,__set_errno_internal
+    .cpsetup $ra, $t1, 2b
+    LA $t9, __set_errno_internal
     .cpreturn
-    j t9
-    move ra, t0
+    j $t9
+    move $ra, $t0
     .set pop
 END(eventfd)
diff --git a/libc/arch-mips64/syscalls/execve.S b/libc/arch-mips64/syscalls/execve.S
index bcd5d60..6f7d1d7 100644
--- a/libc/arch-mips64/syscalls/execve.S
+++ b/libc/arch-mips64/syscalls/execve.S
@@ -5,21 +5,21 @@
 ENTRY(execve)
     .set push
     .set noreorder
-    li v0, __NR_execve
+    li $v0, __NR_execve
     syscall
-    bnez a3, 1f
-    move a0, v0
-    j ra
+    bnez $a3, 1f
+    move $a0, $v0
+    j $ra
     nop
 1:
-    move t0, ra
-    bal     2f
+    move $t0, $ra
+    bal 2f
     nop
 2:
-    .cpsetup ra, t1, 2b
-    LA t9,__set_errno_internal
+    .cpsetup $ra, $t1, 2b
+    LA $t9, __set_errno_internal
     .cpreturn
-    j t9
-    move ra, t0
+    j $t9
+    move $ra, $t0
     .set pop
 END(execve)
diff --git a/libc/arch-mips64/syscalls/fallocate.S b/libc/arch-mips64/syscalls/fallocate.S
index 14e25a0..6685475 100644
--- a/libc/arch-mips64/syscalls/fallocate.S
+++ b/libc/arch-mips64/syscalls/fallocate.S
@@ -5,22 +5,22 @@
 ENTRY(fallocate)
     .set push
     .set noreorder
-    li v0, __NR_fallocate
+    li $v0, __NR_fallocate
     syscall
-    bnez a3, 1f
-    move a0, v0
-    j ra
+    bnez $a3, 1f
+    move $a0, $v0
+    j $ra
     nop
 1:
-    move t0, ra
-    bal     2f
+    move $t0, $ra
+    bal 2f
     nop
 2:
-    .cpsetup ra, t1, 2b
-    LA t9,__set_errno_internal
+    .cpsetup $ra, $t1, 2b
+    LA $t9, __set_errno_internal
     .cpreturn
-    j t9
-    move ra, t0
+    j $t9
+    move $ra, $t0
     .set pop
 END(fallocate)
 
diff --git a/libc/arch-mips64/syscalls/fchdir.S b/libc/arch-mips64/syscalls/fchdir.S
index e05625c..ba76746 100644
--- a/libc/arch-mips64/syscalls/fchdir.S
+++ b/libc/arch-mips64/syscalls/fchdir.S
@@ -5,21 +5,21 @@
 ENTRY(fchdir)
     .set push
     .set noreorder
-    li v0, __NR_fchdir
+    li $v0, __NR_fchdir
     syscall
-    bnez a3, 1f
-    move a0, v0
-    j ra
+    bnez $a3, 1f
+    move $a0, $v0
+    j $ra
     nop
 1:
-    move t0, ra
-    bal     2f
+    move $t0, $ra
+    bal 2f
     nop
 2:
-    .cpsetup ra, t1, 2b
-    LA t9,__set_errno_internal
+    .cpsetup $ra, $t1, 2b
+    LA $t9, __set_errno_internal
     .cpreturn
-    j t9
-    move ra, t0
+    j $t9
+    move $ra, $t0
     .set pop
 END(fchdir)
diff --git a/libc/arch-mips64/syscalls/fchown.S b/libc/arch-mips64/syscalls/fchown.S
index 5dc33c0..edbc1f1 100644
--- a/libc/arch-mips64/syscalls/fchown.S
+++ b/libc/arch-mips64/syscalls/fchown.S
@@ -5,21 +5,21 @@
 ENTRY(fchown)
     .set push
     .set noreorder
-    li v0, __NR_fchown
+    li $v0, __NR_fchown
     syscall
-    bnez a3, 1f
-    move a0, v0
-    j ra
+    bnez $a3, 1f
+    move $a0, $v0
+    j $ra
     nop
 1:
-    move t0, ra
-    bal     2f
+    move $t0, $ra
+    bal 2f
     nop
 2:
-    .cpsetup ra, t1, 2b
-    LA t9,__set_errno_internal
+    .cpsetup $ra, $t1, 2b
+    LA $t9, __set_errno_internal
     .cpreturn
-    j t9
-    move ra, t0
+    j $t9
+    move $ra, $t0
     .set pop
 END(fchown)
diff --git a/libc/arch-mips64/syscalls/fchownat.S b/libc/arch-mips64/syscalls/fchownat.S
index f4cefe0..219a32e 100644
--- a/libc/arch-mips64/syscalls/fchownat.S
+++ b/libc/arch-mips64/syscalls/fchownat.S
@@ -5,21 +5,21 @@
 ENTRY(fchownat)
     .set push
     .set noreorder
-    li v0, __NR_fchownat
+    li $v0, __NR_fchownat
     syscall
-    bnez a3, 1f
-    move a0, v0
-    j ra
+    bnez $a3, 1f
+    move $a0, $v0
+    j $ra
     nop
 1:
-    move t0, ra
-    bal     2f
+    move $t0, $ra
+    bal 2f
     nop
 2:
-    .cpsetup ra, t1, 2b
-    LA t9,__set_errno_internal
+    .cpsetup $ra, $t1, 2b
+    LA $t9, __set_errno_internal
     .cpreturn
-    j t9
-    move ra, t0
+    j $t9
+    move $ra, $t0
     .set pop
 END(fchownat)
diff --git a/libc/arch-mips64/syscalls/fcntl.S b/libc/arch-mips64/syscalls/fcntl.S
index dabc65b..25571f9 100644
--- a/libc/arch-mips64/syscalls/fcntl.S
+++ b/libc/arch-mips64/syscalls/fcntl.S
@@ -5,21 +5,21 @@
 ENTRY(fcntl)
     .set push
     .set noreorder
-    li v0, __NR_fcntl
+    li $v0, __NR_fcntl
     syscall
-    bnez a3, 1f
-    move a0, v0
-    j ra
+    bnez $a3, 1f
+    move $a0, $v0
+    j $ra
     nop
 1:
-    move t0, ra
-    bal     2f
+    move $t0, $ra
+    bal 2f
     nop
 2:
-    .cpsetup ra, t1, 2b
-    LA t9,__set_errno_internal
+    .cpsetup $ra, $t1, 2b
+    LA $t9, __set_errno_internal
     .cpreturn
-    j t9
-    move ra, t0
+    j $t9
+    move $ra, $t0
     .set pop
 END(fcntl)
diff --git a/libc/arch-mips64/syscalls/fdatasync.S b/libc/arch-mips64/syscalls/fdatasync.S
index 52be110..b8f21c7 100644
--- a/libc/arch-mips64/syscalls/fdatasync.S
+++ b/libc/arch-mips64/syscalls/fdatasync.S
@@ -5,21 +5,21 @@
 ENTRY(fdatasync)
     .set push
     .set noreorder
-    li v0, __NR_fdatasync
+    li $v0, __NR_fdatasync
     syscall
-    bnez a3, 1f
-    move a0, v0
-    j ra
+    bnez $a3, 1f
+    move $a0, $v0
+    j $ra
     nop
 1:
-    move t0, ra
-    bal     2f
+    move $t0, $ra
+    bal 2f
     nop
 2:
-    .cpsetup ra, t1, 2b
-    LA t9,__set_errno_internal
+    .cpsetup $ra, $t1, 2b
+    LA $t9, __set_errno_internal
     .cpreturn
-    j t9
-    move ra, t0
+    j $t9
+    move $ra, $t0
     .set pop
 END(fdatasync)
diff --git a/libc/arch-mips64/syscalls/flock.S b/libc/arch-mips64/syscalls/flock.S
index d74a5db..0242f98 100644
--- a/libc/arch-mips64/syscalls/flock.S
+++ b/libc/arch-mips64/syscalls/flock.S
@@ -5,21 +5,21 @@
 ENTRY(flock)
     .set push
     .set noreorder
-    li v0, __NR_flock
+    li $v0, __NR_flock
     syscall
-    bnez a3, 1f
-    move a0, v0
-    j ra
+    bnez $a3, 1f
+    move $a0, $v0
+    j $ra
     nop
 1:
-    move t0, ra
-    bal     2f
+    move $t0, $ra
+    bal 2f
     nop
 2:
-    .cpsetup ra, t1, 2b
-    LA t9,__set_errno_internal
+    .cpsetup $ra, $t1, 2b
+    LA $t9, __set_errno_internal
     .cpreturn
-    j t9
-    move ra, t0
+    j $t9
+    move $ra, $t0
     .set pop
 END(flock)
diff --git a/libc/arch-mips64/syscalls/fremovexattr.S b/libc/arch-mips64/syscalls/fremovexattr.S
index 417be4a..b328c67 100644
--- a/libc/arch-mips64/syscalls/fremovexattr.S
+++ b/libc/arch-mips64/syscalls/fremovexattr.S
@@ -5,21 +5,21 @@
 ENTRY(fremovexattr)
     .set push
     .set noreorder
-    li v0, __NR_fremovexattr
+    li $v0, __NR_fremovexattr
     syscall
-    bnez a3, 1f
-    move a0, v0
-    j ra
+    bnez $a3, 1f
+    move $a0, $v0
+    j $ra
     nop
 1:
-    move t0, ra
-    bal     2f
+    move $t0, $ra
+    bal 2f
     nop
 2:
-    .cpsetup ra, t1, 2b
-    LA t9,__set_errno_internal
+    .cpsetup $ra, $t1, 2b
+    LA $t9, __set_errno_internal
     .cpreturn
-    j t9
-    move ra, t0
+    j $t9
+    move $ra, $t0
     .set pop
 END(fremovexattr)
diff --git a/libc/arch-mips64/syscalls/fsync.S b/libc/arch-mips64/syscalls/fsync.S
index 7056e36..197159f 100644
--- a/libc/arch-mips64/syscalls/fsync.S
+++ b/libc/arch-mips64/syscalls/fsync.S
@@ -5,21 +5,21 @@
 ENTRY(fsync)
     .set push
     .set noreorder
-    li v0, __NR_fsync
+    li $v0, __NR_fsync
     syscall
-    bnez a3, 1f
-    move a0, v0
-    j ra
+    bnez $a3, 1f
+    move $a0, $v0
+    j $ra
     nop
 1:
-    move t0, ra
-    bal     2f
+    move $t0, $ra
+    bal 2f
     nop
 2:
-    .cpsetup ra, t1, 2b
-    LA t9,__set_errno_internal
+    .cpsetup $ra, $t1, 2b
+    LA $t9, __set_errno_internal
     .cpreturn
-    j t9
-    move ra, t0
+    j $t9
+    move $ra, $t0
     .set pop
 END(fsync)
diff --git a/libc/arch-mips64/syscalls/ftruncate.S b/libc/arch-mips64/syscalls/ftruncate.S
index 063e8f3..09b06fa 100644
--- a/libc/arch-mips64/syscalls/ftruncate.S
+++ b/libc/arch-mips64/syscalls/ftruncate.S
@@ -5,22 +5,22 @@
 ENTRY(ftruncate)
     .set push
     .set noreorder
-    li v0, __NR_ftruncate
+    li $v0, __NR_ftruncate
     syscall
-    bnez a3, 1f
-    move a0, v0
-    j ra
+    bnez $a3, 1f
+    move $a0, $v0
+    j $ra
     nop
 1:
-    move t0, ra
-    bal     2f
+    move $t0, $ra
+    bal 2f
     nop
 2:
-    .cpsetup ra, t1, 2b
-    LA t9,__set_errno_internal
+    .cpsetup $ra, $t1, 2b
+    LA $t9, __set_errno_internal
     .cpreturn
-    j t9
-    move ra, t0
+    j $t9
+    move $ra, $t0
     .set pop
 END(ftruncate)
 
diff --git a/libc/arch-mips64/syscalls/getegid.S b/libc/arch-mips64/syscalls/getegid.S
index 439c6f0..9192835 100644
--- a/libc/arch-mips64/syscalls/getegid.S
+++ b/libc/arch-mips64/syscalls/getegid.S
@@ -5,21 +5,21 @@
 ENTRY(getegid)
     .set push
     .set noreorder
-    li v0, __NR_getegid
+    li $v0, __NR_getegid
     syscall
-    bnez a3, 1f
-    move a0, v0
-    j ra
+    bnez $a3, 1f
+    move $a0, $v0
+    j $ra
     nop
 1:
-    move t0, ra
-    bal     2f
+    move $t0, $ra
+    bal 2f
     nop
 2:
-    .cpsetup ra, t1, 2b
-    LA t9,__set_errno_internal
+    .cpsetup $ra, $t1, 2b
+    LA $t9, __set_errno_internal
     .cpreturn
-    j t9
-    move ra, t0
+    j $t9
+    move $ra, $t0
     .set pop
 END(getegid)
diff --git a/libc/arch-mips64/syscalls/geteuid.S b/libc/arch-mips64/syscalls/geteuid.S
index 5619dc6..5a5cbf9 100644
--- a/libc/arch-mips64/syscalls/geteuid.S
+++ b/libc/arch-mips64/syscalls/geteuid.S
@@ -5,21 +5,21 @@
 ENTRY(geteuid)
     .set push
     .set noreorder
-    li v0, __NR_geteuid
+    li $v0, __NR_geteuid
     syscall
-    bnez a3, 1f
-    move a0, v0
-    j ra
+    bnez $a3, 1f
+    move $a0, $v0
+    j $ra
     nop
 1:
-    move t0, ra
-    bal     2f
+    move $t0, $ra
+    bal 2f
     nop
 2:
-    .cpsetup ra, t1, 2b
-    LA t9,__set_errno_internal
+    .cpsetup $ra, $t1, 2b
+    LA $t9, __set_errno_internal
     .cpreturn
-    j t9
-    move ra, t0
+    j $t9
+    move $ra, $t0
     .set pop
 END(geteuid)
diff --git a/libc/arch-mips64/syscalls/getgid.S b/libc/arch-mips64/syscalls/getgid.S
index 777be1a..c434419 100644
--- a/libc/arch-mips64/syscalls/getgid.S
+++ b/libc/arch-mips64/syscalls/getgid.S
@@ -5,21 +5,21 @@
 ENTRY(getgid)
     .set push
     .set noreorder
-    li v0, __NR_getgid
+    li $v0, __NR_getgid
     syscall
-    bnez a3, 1f
-    move a0, v0
-    j ra
+    bnez $a3, 1f
+    move $a0, $v0
+    j $ra
     nop
 1:
-    move t0, ra
-    bal     2f
+    move $t0, $ra
+    bal 2f
     nop
 2:
-    .cpsetup ra, t1, 2b
-    LA t9,__set_errno_internal
+    .cpsetup $ra, $t1, 2b
+    LA $t9, __set_errno_internal
     .cpreturn
-    j t9
-    move ra, t0
+    j $t9
+    move $ra, $t0
     .set pop
 END(getgid)
diff --git a/libc/arch-mips64/syscalls/getgroups.S b/libc/arch-mips64/syscalls/getgroups.S
index 93c4fa1..29ac854 100644
--- a/libc/arch-mips64/syscalls/getgroups.S
+++ b/libc/arch-mips64/syscalls/getgroups.S
@@ -5,21 +5,21 @@
 ENTRY(getgroups)
     .set push
     .set noreorder
-    li v0, __NR_getgroups
+    li $v0, __NR_getgroups
     syscall
-    bnez a3, 1f
-    move a0, v0
-    j ra
+    bnez $a3, 1f
+    move $a0, $v0
+    j $ra
     nop
 1:
-    move t0, ra
-    bal     2f
+    move $t0, $ra
+    bal 2f
     nop
 2:
-    .cpsetup ra, t1, 2b
-    LA t9,__set_errno_internal
+    .cpsetup $ra, $t1, 2b
+    LA $t9, __set_errno_internal
     .cpreturn
-    j t9
-    move ra, t0
+    j $t9
+    move $ra, $t0
     .set pop
 END(getgroups)
diff --git a/libc/arch-mips64/syscalls/getitimer.S b/libc/arch-mips64/syscalls/getitimer.S
index fe78a97..445fb1d 100644
--- a/libc/arch-mips64/syscalls/getitimer.S
+++ b/libc/arch-mips64/syscalls/getitimer.S
@@ -5,21 +5,21 @@
 ENTRY(getitimer)
     .set push
     .set noreorder
-    li v0, __NR_getitimer
+    li $v0, __NR_getitimer
     syscall
-    bnez a3, 1f
-    move a0, v0
-    j ra
+    bnez $a3, 1f
+    move $a0, $v0
+    j $ra
     nop
 1:
-    move t0, ra
-    bal     2f
+    move $t0, $ra
+    bal 2f
     nop
 2:
-    .cpsetup ra, t1, 2b
-    LA t9,__set_errno_internal
+    .cpsetup $ra, $t1, 2b
+    LA $t9, __set_errno_internal
     .cpreturn
-    j t9
-    move ra, t0
+    j $t9
+    move $ra, $t0
     .set pop
 END(getitimer)
diff --git a/libc/arch-mips64/syscalls/getpeername.S b/libc/arch-mips64/syscalls/getpeername.S
index 121f1a6..0f081c8 100644
--- a/libc/arch-mips64/syscalls/getpeername.S
+++ b/libc/arch-mips64/syscalls/getpeername.S
@@ -5,21 +5,21 @@
 ENTRY(getpeername)
     .set push
     .set noreorder
-    li v0, __NR_getpeername
+    li $v0, __NR_getpeername
     syscall
-    bnez a3, 1f
-    move a0, v0
-    j ra
+    bnez $a3, 1f
+    move $a0, $v0
+    j $ra
     nop
 1:
-    move t0, ra
-    bal     2f
+    move $t0, $ra
+    bal 2f
     nop
 2:
-    .cpsetup ra, t1, 2b
-    LA t9,__set_errno_internal
+    .cpsetup $ra, $t1, 2b
+    LA $t9, __set_errno_internal
     .cpreturn
-    j t9
-    move ra, t0
+    j $t9
+    move $ra, $t0
     .set pop
 END(getpeername)
diff --git a/libc/arch-mips64/syscalls/getpgid.S b/libc/arch-mips64/syscalls/getpgid.S
index 19dc77f..7859ad4 100644
--- a/libc/arch-mips64/syscalls/getpgid.S
+++ b/libc/arch-mips64/syscalls/getpgid.S
@@ -5,21 +5,21 @@
 ENTRY(getpgid)
     .set push
     .set noreorder
-    li v0, __NR_getpgid
+    li $v0, __NR_getpgid
     syscall
-    bnez a3, 1f
-    move a0, v0
-    j ra
+    bnez $a3, 1f
+    move $a0, $v0
+    j $ra
     nop
 1:
-    move t0, ra
-    bal     2f
+    move $t0, $ra
+    bal 2f
     nop
 2:
-    .cpsetup ra, t1, 2b
-    LA t9,__set_errno_internal
+    .cpsetup $ra, $t1, 2b
+    LA $t9, __set_errno_internal
     .cpreturn
-    j t9
-    move ra, t0
+    j $t9
+    move $ra, $t0
     .set pop
 END(getpgid)
diff --git a/libc/arch-mips64/syscalls/getppid.S b/libc/arch-mips64/syscalls/getppid.S
index d00f309..c67ed1f 100644
--- a/libc/arch-mips64/syscalls/getppid.S
+++ b/libc/arch-mips64/syscalls/getppid.S
@@ -5,21 +5,21 @@
 ENTRY(getppid)
     .set push
     .set noreorder
-    li v0, __NR_getppid
+    li $v0, __NR_getppid
     syscall
-    bnez a3, 1f
-    move a0, v0
-    j ra
+    bnez $a3, 1f
+    move $a0, $v0
+    j $ra
     nop
 1:
-    move t0, ra
-    bal     2f
+    move $t0, $ra
+    bal 2f
     nop
 2:
-    .cpsetup ra, t1, 2b
-    LA t9,__set_errno_internal
+    .cpsetup $ra, $t1, 2b
+    LA $t9, __set_errno_internal
     .cpreturn
-    j t9
-    move ra, t0
+    j $t9
+    move $ra, $t0
     .set pop
 END(getppid)
diff --git a/libc/arch-mips64/syscalls/getrandom.S b/libc/arch-mips64/syscalls/getrandom.S
new file mode 100644
index 0000000..b4f5ea8
--- /dev/null
+++ b/libc/arch-mips64/syscalls/getrandom.S
@@ -0,0 +1,25 @@
+/* Generated by gensyscalls.py. Do not edit. */
+
+#include <private/bionic_asm.h>
+
+ENTRY(getrandom)
+    .set push
+    .set noreorder
+    li $v0, __NR_getrandom
+    syscall
+    bnez $a3, 1f
+    move $a0, $v0
+    j $ra
+    nop
+1:
+    move $t0, $ra
+    bal 2f
+    nop
+2:
+    .cpsetup $ra, $t1, 2b
+    LA $t9, __set_errno_internal
+    .cpreturn
+    j $t9
+    move $ra, $t0
+    .set pop
+END(getrandom)
diff --git a/libc/arch-mips64/syscalls/getresgid.S b/libc/arch-mips64/syscalls/getresgid.S
index 18cb5a1..ba1aafe 100644
--- a/libc/arch-mips64/syscalls/getresgid.S
+++ b/libc/arch-mips64/syscalls/getresgid.S
@@ -5,21 +5,21 @@
 ENTRY(getresgid)
     .set push
     .set noreorder
-    li v0, __NR_getresgid
+    li $v0, __NR_getresgid
     syscall
-    bnez a3, 1f
-    move a0, v0
-    j ra
+    bnez $a3, 1f
+    move $a0, $v0
+    j $ra
     nop
 1:
-    move t0, ra
-    bal     2f
+    move $t0, $ra
+    bal 2f
     nop
 2:
-    .cpsetup ra, t1, 2b
-    LA t9,__set_errno_internal
+    .cpsetup $ra, $t1, 2b
+    LA $t9, __set_errno_internal
     .cpreturn
-    j t9
-    move ra, t0
+    j $t9
+    move $ra, $t0
     .set pop
 END(getresgid)
diff --git a/libc/arch-mips64/syscalls/getresuid.S b/libc/arch-mips64/syscalls/getresuid.S
index c217bf7..d9c40f9 100644
--- a/libc/arch-mips64/syscalls/getresuid.S
+++ b/libc/arch-mips64/syscalls/getresuid.S
@@ -5,21 +5,21 @@
 ENTRY(getresuid)
     .set push
     .set noreorder
-    li v0, __NR_getresuid
+    li $v0, __NR_getresuid
     syscall
-    bnez a3, 1f
-    move a0, v0
-    j ra
+    bnez $a3, 1f
+    move $a0, $v0
+    j $ra
     nop
 1:
-    move t0, ra
-    bal     2f
+    move $t0, $ra
+    bal 2f
     nop
 2:
-    .cpsetup ra, t1, 2b
-    LA t9,__set_errno_internal
+    .cpsetup $ra, $t1, 2b
+    LA $t9, __set_errno_internal
     .cpreturn
-    j t9
-    move ra, t0
+    j $t9
+    move $ra, $t0
     .set pop
 END(getresuid)
diff --git a/libc/arch-mips64/syscalls/getrlimit.S b/libc/arch-mips64/syscalls/getrlimit.S
index 5e2a82a..ae1cc86 100644
--- a/libc/arch-mips64/syscalls/getrlimit.S
+++ b/libc/arch-mips64/syscalls/getrlimit.S
@@ -5,22 +5,22 @@
 ENTRY(getrlimit)
     .set push
     .set noreorder
-    li v0, __NR_getrlimit
+    li $v0, __NR_getrlimit
     syscall
-    bnez a3, 1f
-    move a0, v0
-    j ra
+    bnez $a3, 1f
+    move $a0, $v0
+    j $ra
     nop
 1:
-    move t0, ra
-    bal     2f
+    move $t0, $ra
+    bal 2f
     nop
 2:
-    .cpsetup ra, t1, 2b
-    LA t9,__set_errno_internal
+    .cpsetup $ra, $t1, 2b
+    LA $t9, __set_errno_internal
     .cpreturn
-    j t9
-    move ra, t0
+    j $t9
+    move $ra, $t0
     .set pop
 END(getrlimit)
 
diff --git a/libc/arch-mips64/syscalls/getrusage.S b/libc/arch-mips64/syscalls/getrusage.S
index 4bf557e..4c6d3f1 100644
--- a/libc/arch-mips64/syscalls/getrusage.S
+++ b/libc/arch-mips64/syscalls/getrusage.S
@@ -5,21 +5,21 @@
 ENTRY(getrusage)
     .set push
     .set noreorder
-    li v0, __NR_getrusage
+    li $v0, __NR_getrusage
     syscall
-    bnez a3, 1f
-    move a0, v0
-    j ra
+    bnez $a3, 1f
+    move $a0, $v0
+    j $ra
     nop
 1:
-    move t0, ra
-    bal     2f
+    move $t0, $ra
+    bal 2f
     nop
 2:
-    .cpsetup ra, t1, 2b
-    LA t9,__set_errno_internal
+    .cpsetup $ra, $t1, 2b
+    LA $t9, __set_errno_internal
     .cpreturn
-    j t9
-    move ra, t0
+    j $t9
+    move $ra, $t0
     .set pop
 END(getrusage)
diff --git a/libc/arch-mips64/syscalls/getsid.S b/libc/arch-mips64/syscalls/getsid.S
index 030c91d..6a7b844 100644
--- a/libc/arch-mips64/syscalls/getsid.S
+++ b/libc/arch-mips64/syscalls/getsid.S
@@ -5,21 +5,21 @@
 ENTRY(getsid)
     .set push
     .set noreorder
-    li v0, __NR_getsid
+    li $v0, __NR_getsid
     syscall
-    bnez a3, 1f
-    move a0, v0
-    j ra
+    bnez $a3, 1f
+    move $a0, $v0
+    j $ra
     nop
 1:
-    move t0, ra
-    bal     2f
+    move $t0, $ra
+    bal 2f
     nop
 2:
-    .cpsetup ra, t1, 2b
-    LA t9,__set_errno_internal
+    .cpsetup $ra, $t1, 2b
+    LA $t9, __set_errno_internal
     .cpreturn
-    j t9
-    move ra, t0
+    j $t9
+    move $ra, $t0
     .set pop
 END(getsid)
diff --git a/libc/arch-mips64/syscalls/getsockname.S b/libc/arch-mips64/syscalls/getsockname.S
index 88a9426..742c496 100644
--- a/libc/arch-mips64/syscalls/getsockname.S
+++ b/libc/arch-mips64/syscalls/getsockname.S
@@ -5,21 +5,21 @@
 ENTRY(getsockname)
     .set push
     .set noreorder
-    li v0, __NR_getsockname
+    li $v0, __NR_getsockname
     syscall
-    bnez a3, 1f
-    move a0, v0
-    j ra
+    bnez $a3, 1f
+    move $a0, $v0
+    j $ra
     nop
 1:
-    move t0, ra
-    bal     2f
+    move $t0, $ra
+    bal 2f
     nop
 2:
-    .cpsetup ra, t1, 2b
-    LA t9,__set_errno_internal
+    .cpsetup $ra, $t1, 2b
+    LA $t9, __set_errno_internal
     .cpreturn
-    j t9
-    move ra, t0
+    j $t9
+    move $ra, $t0
     .set pop
 END(getsockname)
diff --git a/libc/arch-mips64/syscalls/getsockopt.S b/libc/arch-mips64/syscalls/getsockopt.S
index 08ee634..451006e 100644
--- a/libc/arch-mips64/syscalls/getsockopt.S
+++ b/libc/arch-mips64/syscalls/getsockopt.S
@@ -5,21 +5,21 @@
 ENTRY(getsockopt)
     .set push
     .set noreorder
-    li v0, __NR_getsockopt
+    li $v0, __NR_getsockopt
     syscall
-    bnez a3, 1f
-    move a0, v0
-    j ra
+    bnez $a3, 1f
+    move $a0, $v0
+    j $ra
     nop
 1:
-    move t0, ra
-    bal     2f
+    move $t0, $ra
+    bal 2f
     nop
 2:
-    .cpsetup ra, t1, 2b
-    LA t9,__set_errno_internal
+    .cpsetup $ra, $t1, 2b
+    LA $t9, __set_errno_internal
     .cpreturn
-    j t9
-    move ra, t0
+    j $t9
+    move $ra, $t0
     .set pop
 END(getsockopt)
diff --git a/libc/arch-mips64/syscalls/getuid.S b/libc/arch-mips64/syscalls/getuid.S
index 3d5f940..964d5a6 100644
--- a/libc/arch-mips64/syscalls/getuid.S
+++ b/libc/arch-mips64/syscalls/getuid.S
@@ -5,21 +5,21 @@
 ENTRY(getuid)
     .set push
     .set noreorder
-    li v0, __NR_getuid
+    li $v0, __NR_getuid
     syscall
-    bnez a3, 1f
-    move a0, v0
-    j ra
+    bnez $a3, 1f
+    move $a0, $v0
+    j $ra
     nop
 1:
-    move t0, ra
-    bal     2f
+    move $t0, $ra
+    bal 2f
     nop
 2:
-    .cpsetup ra, t1, 2b
-    LA t9,__set_errno_internal
+    .cpsetup $ra, $t1, 2b
+    LA $t9, __set_errno_internal
     .cpreturn
-    j t9
-    move ra, t0
+    j $t9
+    move $ra, $t0
     .set pop
 END(getuid)
diff --git a/libc/arch-mips64/syscalls/getxattr.S b/libc/arch-mips64/syscalls/getxattr.S
index 1c443f2..23fc3d1 100644
--- a/libc/arch-mips64/syscalls/getxattr.S
+++ b/libc/arch-mips64/syscalls/getxattr.S
@@ -5,21 +5,21 @@
 ENTRY(getxattr)
     .set push
     .set noreorder
-    li v0, __NR_getxattr
+    li $v0, __NR_getxattr
     syscall
-    bnez a3, 1f
-    move a0, v0
-    j ra
+    bnez $a3, 1f
+    move $a0, $v0
+    j $ra
     nop
 1:
-    move t0, ra
-    bal     2f
+    move $t0, $ra
+    bal 2f
     nop
 2:
-    .cpsetup ra, t1, 2b
-    LA t9,__set_errno_internal
+    .cpsetup $ra, $t1, 2b
+    LA $t9, __set_errno_internal
     .cpreturn
-    j t9
-    move ra, t0
+    j $t9
+    move $ra, $t0
     .set pop
 END(getxattr)
diff --git a/libc/arch-mips64/syscalls/init_module.S b/libc/arch-mips64/syscalls/init_module.S
index 3e2f074..3b02055 100644
--- a/libc/arch-mips64/syscalls/init_module.S
+++ b/libc/arch-mips64/syscalls/init_module.S
@@ -5,21 +5,21 @@
 ENTRY(init_module)
     .set push
     .set noreorder
-    li v0, __NR_init_module
+    li $v0, __NR_init_module
     syscall
-    bnez a3, 1f
-    move a0, v0
-    j ra
+    bnez $a3, 1f
+    move $a0, $v0
+    j $ra
     nop
 1:
-    move t0, ra
-    bal     2f
+    move $t0, $ra
+    bal 2f
     nop
 2:
-    .cpsetup ra, t1, 2b
-    LA t9,__set_errno_internal
+    .cpsetup $ra, $t1, 2b
+    LA $t9, __set_errno_internal
     .cpreturn
-    j t9
-    move ra, t0
+    j $t9
+    move $ra, $t0
     .set pop
 END(init_module)
diff --git a/libc/arch-mips64/syscalls/inotify_add_watch.S b/libc/arch-mips64/syscalls/inotify_add_watch.S
index bffdad8..583b8bb 100644
--- a/libc/arch-mips64/syscalls/inotify_add_watch.S
+++ b/libc/arch-mips64/syscalls/inotify_add_watch.S
@@ -5,21 +5,21 @@
 ENTRY(inotify_add_watch)
     .set push
     .set noreorder
-    li v0, __NR_inotify_add_watch
+    li $v0, __NR_inotify_add_watch
     syscall
-    bnez a3, 1f
-    move a0, v0
-    j ra
+    bnez $a3, 1f
+    move $a0, $v0
+    j $ra
     nop
 1:
-    move t0, ra
-    bal     2f
+    move $t0, $ra
+    bal 2f
     nop
 2:
-    .cpsetup ra, t1, 2b
-    LA t9,__set_errno_internal
+    .cpsetup $ra, $t1, 2b
+    LA $t9, __set_errno_internal
     .cpreturn
-    j t9
-    move ra, t0
+    j $t9
+    move $ra, $t0
     .set pop
 END(inotify_add_watch)
diff --git a/libc/arch-mips64/syscalls/inotify_init1.S b/libc/arch-mips64/syscalls/inotify_init1.S
index c70d101..5ccb9af 100644
--- a/libc/arch-mips64/syscalls/inotify_init1.S
+++ b/libc/arch-mips64/syscalls/inotify_init1.S
@@ -5,21 +5,21 @@
 ENTRY(inotify_init1)
     .set push
     .set noreorder
-    li v0, __NR_inotify_init1
+    li $v0, __NR_inotify_init1
     syscall
-    bnez a3, 1f
-    move a0, v0
-    j ra
+    bnez $a3, 1f
+    move $a0, $v0
+    j $ra
     nop
 1:
-    move t0, ra
-    bal     2f
+    move $t0, $ra
+    bal 2f
     nop
 2:
-    .cpsetup ra, t1, 2b
-    LA t9,__set_errno_internal
+    .cpsetup $ra, $t1, 2b
+    LA $t9, __set_errno_internal
     .cpreturn
-    j t9
-    move ra, t0
+    j $t9
+    move $ra, $t0
     .set pop
 END(inotify_init1)
diff --git a/libc/arch-mips64/syscalls/inotify_rm_watch.S b/libc/arch-mips64/syscalls/inotify_rm_watch.S
index d893787..7f18c0f 100644
--- a/libc/arch-mips64/syscalls/inotify_rm_watch.S
+++ b/libc/arch-mips64/syscalls/inotify_rm_watch.S
@@ -5,21 +5,21 @@
 ENTRY(inotify_rm_watch)
     .set push
     .set noreorder
-    li v0, __NR_inotify_rm_watch
+    li $v0, __NR_inotify_rm_watch
     syscall
-    bnez a3, 1f
-    move a0, v0
-    j ra
+    bnez $a3, 1f
+    move $a0, $v0
+    j $ra
     nop
 1:
-    move t0, ra
-    bal     2f
+    move $t0, $ra
+    bal 2f
     nop
 2:
-    .cpsetup ra, t1, 2b
-    LA t9,__set_errno_internal
+    .cpsetup $ra, $t1, 2b
+    LA $t9, __set_errno_internal
     .cpreturn
-    j t9
-    move ra, t0
+    j $t9
+    move $ra, $t0
     .set pop
 END(inotify_rm_watch)
diff --git a/libc/arch-mips64/syscalls/kill.S b/libc/arch-mips64/syscalls/kill.S
index 475b615..dcc440b 100644
--- a/libc/arch-mips64/syscalls/kill.S
+++ b/libc/arch-mips64/syscalls/kill.S
@@ -5,21 +5,21 @@
 ENTRY(kill)
     .set push
     .set noreorder
-    li v0, __NR_kill
+    li $v0, __NR_kill
     syscall
-    bnez a3, 1f
-    move a0, v0
-    j ra
+    bnez $a3, 1f
+    move $a0, $v0
+    j $ra
     nop
 1:
-    move t0, ra
-    bal     2f
+    move $t0, $ra
+    bal 2f
     nop
 2:
-    .cpsetup ra, t1, 2b
-    LA t9,__set_errno_internal
+    .cpsetup $ra, $t1, 2b
+    LA $t9, __set_errno_internal
     .cpreturn
-    j t9
-    move ra, t0
+    j $t9
+    move $ra, $t0
     .set pop
 END(kill)
diff --git a/libc/arch-mips64/syscalls/klogctl.S b/libc/arch-mips64/syscalls/klogctl.S
index 98b9f0b..62af663 100644
--- a/libc/arch-mips64/syscalls/klogctl.S
+++ b/libc/arch-mips64/syscalls/klogctl.S
@@ -5,21 +5,21 @@
 ENTRY(klogctl)
     .set push
     .set noreorder
-    li v0, __NR_syslog
+    li $v0, __NR_syslog
     syscall
-    bnez a3, 1f
-    move a0, v0
-    j ra
+    bnez $a3, 1f
+    move $a0, $v0
+    j $ra
     nop
 1:
-    move t0, ra
-    bal     2f
+    move $t0, $ra
+    bal 2f
     nop
 2:
-    .cpsetup ra, t1, 2b
-    LA t9,__set_errno_internal
+    .cpsetup $ra, $t1, 2b
+    LA $t9, __set_errno_internal
     .cpreturn
-    j t9
-    move ra, t0
+    j $t9
+    move $ra, $t0
     .set pop
 END(klogctl)
diff --git a/libc/arch-mips64/syscalls/lgetxattr.S b/libc/arch-mips64/syscalls/lgetxattr.S
index 55d7c42..20e3134 100644
--- a/libc/arch-mips64/syscalls/lgetxattr.S
+++ b/libc/arch-mips64/syscalls/lgetxattr.S
@@ -5,21 +5,21 @@
 ENTRY(lgetxattr)
     .set push
     .set noreorder
-    li v0, __NR_lgetxattr
+    li $v0, __NR_lgetxattr
     syscall
-    bnez a3, 1f
-    move a0, v0
-    j ra
+    bnez $a3, 1f
+    move $a0, $v0
+    j $ra
     nop
 1:
-    move t0, ra
-    bal     2f
+    move $t0, $ra
+    bal 2f
     nop
 2:
-    .cpsetup ra, t1, 2b
-    LA t9,__set_errno_internal
+    .cpsetup $ra, $t1, 2b
+    LA $t9, __set_errno_internal
     .cpreturn
-    j t9
-    move ra, t0
+    j $t9
+    move $ra, $t0
     .set pop
 END(lgetxattr)
diff --git a/libc/arch-mips64/syscalls/linkat.S b/libc/arch-mips64/syscalls/linkat.S
index df749eb..425c417 100644
--- a/libc/arch-mips64/syscalls/linkat.S
+++ b/libc/arch-mips64/syscalls/linkat.S
@@ -5,21 +5,21 @@
 ENTRY(linkat)
     .set push
     .set noreorder
-    li v0, __NR_linkat
+    li $v0, __NR_linkat
     syscall
-    bnez a3, 1f
-    move a0, v0
-    j ra
+    bnez $a3, 1f
+    move $a0, $v0
+    j $ra
     nop
 1:
-    move t0, ra
-    bal     2f
+    move $t0, $ra
+    bal 2f
     nop
 2:
-    .cpsetup ra, t1, 2b
-    LA t9,__set_errno_internal
+    .cpsetup $ra, $t1, 2b
+    LA $t9, __set_errno_internal
     .cpreturn
-    j t9
-    move ra, t0
+    j $t9
+    move $ra, $t0
     .set pop
 END(linkat)
diff --git a/libc/arch-mips64/syscalls/listen.S b/libc/arch-mips64/syscalls/listen.S
index 195cade..8263ec3 100644
--- a/libc/arch-mips64/syscalls/listen.S
+++ b/libc/arch-mips64/syscalls/listen.S
@@ -5,21 +5,21 @@
 ENTRY(listen)
     .set push
     .set noreorder
-    li v0, __NR_listen
+    li $v0, __NR_listen
     syscall
-    bnez a3, 1f
-    move a0, v0
-    j ra
+    bnez $a3, 1f
+    move $a0, $v0
+    j $ra
     nop
 1:
-    move t0, ra
-    bal     2f
+    move $t0, $ra
+    bal 2f
     nop
 2:
-    .cpsetup ra, t1, 2b
-    LA t9,__set_errno_internal
+    .cpsetup $ra, $t1, 2b
+    LA $t9, __set_errno_internal
     .cpreturn
-    j t9
-    move ra, t0
+    j $t9
+    move $ra, $t0
     .set pop
 END(listen)
diff --git a/libc/arch-mips64/syscalls/listxattr.S b/libc/arch-mips64/syscalls/listxattr.S
index 30b0f2b..5f04ffc 100644
--- a/libc/arch-mips64/syscalls/listxattr.S
+++ b/libc/arch-mips64/syscalls/listxattr.S
@@ -5,21 +5,21 @@
 ENTRY(listxattr)
     .set push
     .set noreorder
-    li v0, __NR_listxattr
+    li $v0, __NR_listxattr
     syscall
-    bnez a3, 1f
-    move a0, v0
-    j ra
+    bnez $a3, 1f
+    move $a0, $v0
+    j $ra
     nop
 1:
-    move t0, ra
-    bal     2f
+    move $t0, $ra
+    bal 2f
     nop
 2:
-    .cpsetup ra, t1, 2b
-    LA t9,__set_errno_internal
+    .cpsetup $ra, $t1, 2b
+    LA $t9, __set_errno_internal
     .cpreturn
-    j t9
-    move ra, t0
+    j $t9
+    move $ra, $t0
     .set pop
 END(listxattr)
diff --git a/libc/arch-mips64/syscalls/llistxattr.S b/libc/arch-mips64/syscalls/llistxattr.S
index d349116..9663fd9 100644
--- a/libc/arch-mips64/syscalls/llistxattr.S
+++ b/libc/arch-mips64/syscalls/llistxattr.S
@@ -5,21 +5,21 @@
 ENTRY(llistxattr)
     .set push
     .set noreorder
-    li v0, __NR_llistxattr
+    li $v0, __NR_llistxattr
     syscall
-    bnez a3, 1f
-    move a0, v0
-    j ra
+    bnez $a3, 1f
+    move $a0, $v0
+    j $ra
     nop
 1:
-    move t0, ra
-    bal     2f
+    move $t0, $ra
+    bal 2f
     nop
 2:
-    .cpsetup ra, t1, 2b
-    LA t9,__set_errno_internal
+    .cpsetup $ra, $t1, 2b
+    LA $t9, __set_errno_internal
     .cpreturn
-    j t9
-    move ra, t0
+    j $t9
+    move $ra, $t0
     .set pop
 END(llistxattr)
diff --git a/libc/arch-mips64/syscalls/lremovexattr.S b/libc/arch-mips64/syscalls/lremovexattr.S
index db4e4d3..905548a 100644
--- a/libc/arch-mips64/syscalls/lremovexattr.S
+++ b/libc/arch-mips64/syscalls/lremovexattr.S
@@ -5,21 +5,21 @@
 ENTRY(lremovexattr)
     .set push
     .set noreorder
-    li v0, __NR_lremovexattr
+    li $v0, __NR_lremovexattr
     syscall
-    bnez a3, 1f
-    move a0, v0
-    j ra
+    bnez $a3, 1f
+    move $a0, $v0
+    j $ra
     nop
 1:
-    move t0, ra
-    bal     2f
+    move $t0, $ra
+    bal 2f
     nop
 2:
-    .cpsetup ra, t1, 2b
-    LA t9,__set_errno_internal
+    .cpsetup $ra, $t1, 2b
+    LA $t9, __set_errno_internal
     .cpreturn
-    j t9
-    move ra, t0
+    j $t9
+    move $ra, $t0
     .set pop
 END(lremovexattr)
diff --git a/libc/arch-mips64/syscalls/lseek.S b/libc/arch-mips64/syscalls/lseek.S
index 3bfc29d..1eee1fa 100644
--- a/libc/arch-mips64/syscalls/lseek.S
+++ b/libc/arch-mips64/syscalls/lseek.S
@@ -5,22 +5,22 @@
 ENTRY(lseek)
     .set push
     .set noreorder
-    li v0, __NR_lseek
+    li $v0, __NR_lseek
     syscall
-    bnez a3, 1f
-    move a0, v0
-    j ra
+    bnez $a3, 1f
+    move $a0, $v0
+    j $ra
     nop
 1:
-    move t0, ra
-    bal     2f
+    move $t0, $ra
+    bal 2f
     nop
 2:
-    .cpsetup ra, t1, 2b
-    LA t9,__set_errno_internal
+    .cpsetup $ra, $t1, 2b
+    LA $t9, __set_errno_internal
     .cpreturn
-    j t9
-    move ra, t0
+    j $t9
+    move $ra, $t0
     .set pop
 END(lseek)
 
diff --git a/libc/arch-mips64/syscalls/lsetxattr.S b/libc/arch-mips64/syscalls/lsetxattr.S
index c161eb3..38e3523 100644
--- a/libc/arch-mips64/syscalls/lsetxattr.S
+++ b/libc/arch-mips64/syscalls/lsetxattr.S
@@ -5,21 +5,21 @@
 ENTRY(lsetxattr)
     .set push
     .set noreorder
-    li v0, __NR_lsetxattr
+    li $v0, __NR_lsetxattr
     syscall
-    bnez a3, 1f
-    move a0, v0
-    j ra
+    bnez $a3, 1f
+    move $a0, $v0
+    j $ra
     nop
 1:
-    move t0, ra
-    bal     2f
+    move $t0, $ra
+    bal 2f
     nop
 2:
-    .cpsetup ra, t1, 2b
-    LA t9,__set_errno_internal
+    .cpsetup $ra, $t1, 2b
+    LA $t9, __set_errno_internal
     .cpreturn
-    j t9
-    move ra, t0
+    j $t9
+    move $ra, $t0
     .set pop
 END(lsetxattr)
diff --git a/libc/arch-mips64/syscalls/madvise.S b/libc/arch-mips64/syscalls/madvise.S
index 88f3830..5283700 100644
--- a/libc/arch-mips64/syscalls/madvise.S
+++ b/libc/arch-mips64/syscalls/madvise.S
@@ -5,21 +5,21 @@
 ENTRY(madvise)
     .set push
     .set noreorder
-    li v0, __NR_madvise
+    li $v0, __NR_madvise
     syscall
-    bnez a3, 1f
-    move a0, v0
-    j ra
+    bnez $a3, 1f
+    move $a0, $v0
+    j $ra
     nop
 1:
-    move t0, ra
-    bal     2f
+    move $t0, $ra
+    bal 2f
     nop
 2:
-    .cpsetup ra, t1, 2b
-    LA t9,__set_errno_internal
+    .cpsetup $ra, $t1, 2b
+    LA $t9, __set_errno_internal
     .cpreturn
-    j t9
-    move ra, t0
+    j $t9
+    move $ra, $t0
     .set pop
 END(madvise)
diff --git a/libc/arch-mips64/syscalls/mincore.S b/libc/arch-mips64/syscalls/mincore.S
index 695c9b2..c7f419a 100644
--- a/libc/arch-mips64/syscalls/mincore.S
+++ b/libc/arch-mips64/syscalls/mincore.S
@@ -5,21 +5,21 @@
 ENTRY(mincore)
     .set push
     .set noreorder
-    li v0, __NR_mincore
+    li $v0, __NR_mincore
     syscall
-    bnez a3, 1f
-    move a0, v0
-    j ra
+    bnez $a3, 1f
+    move $a0, $v0
+    j $ra
     nop
 1:
-    move t0, ra
-    bal     2f
+    move $t0, $ra
+    bal 2f
     nop
 2:
-    .cpsetup ra, t1, 2b
-    LA t9,__set_errno_internal
+    .cpsetup $ra, $t1, 2b
+    LA $t9, __set_errno_internal
     .cpreturn
-    j t9
-    move ra, t0
+    j $t9
+    move $ra, $t0
     .set pop
 END(mincore)
diff --git a/libc/arch-mips64/syscalls/mkdirat.S b/libc/arch-mips64/syscalls/mkdirat.S
index 71cdfd1..2e1a45b 100644
--- a/libc/arch-mips64/syscalls/mkdirat.S
+++ b/libc/arch-mips64/syscalls/mkdirat.S
@@ -5,21 +5,21 @@
 ENTRY(mkdirat)
     .set push
     .set noreorder
-    li v0, __NR_mkdirat
+    li $v0, __NR_mkdirat
     syscall
-    bnez a3, 1f
-    move a0, v0
-    j ra
+    bnez $a3, 1f
+    move $a0, $v0
+    j $ra
     nop
 1:
-    move t0, ra
-    bal     2f
+    move $t0, $ra
+    bal 2f
     nop
 2:
-    .cpsetup ra, t1, 2b
-    LA t9,__set_errno_internal
+    .cpsetup $ra, $t1, 2b
+    LA $t9, __set_errno_internal
     .cpreturn
-    j t9
-    move ra, t0
+    j $t9
+    move $ra, $t0
     .set pop
 END(mkdirat)
diff --git a/libc/arch-mips64/syscalls/mknodat.S b/libc/arch-mips64/syscalls/mknodat.S
index 9943e49..42d73c4 100644
--- a/libc/arch-mips64/syscalls/mknodat.S
+++ b/libc/arch-mips64/syscalls/mknodat.S
@@ -5,21 +5,21 @@
 ENTRY(mknodat)
     .set push
     .set noreorder
-    li v0, __NR_mknodat
+    li $v0, __NR_mknodat
     syscall
-    bnez a3, 1f
-    move a0, v0
-    j ra
+    bnez $a3, 1f
+    move $a0, $v0
+    j $ra
     nop
 1:
-    move t0, ra
-    bal     2f
+    move $t0, $ra
+    bal 2f
     nop
 2:
-    .cpsetup ra, t1, 2b
-    LA t9,__set_errno_internal
+    .cpsetup $ra, $t1, 2b
+    LA $t9, __set_errno_internal
     .cpreturn
-    j t9
-    move ra, t0
+    j $t9
+    move $ra, $t0
     .set pop
 END(mknodat)
diff --git a/libc/arch-mips64/syscalls/mlock.S b/libc/arch-mips64/syscalls/mlock.S
index 081f12b..dd6b784 100644
--- a/libc/arch-mips64/syscalls/mlock.S
+++ b/libc/arch-mips64/syscalls/mlock.S
@@ -5,21 +5,21 @@
 ENTRY(mlock)
     .set push
     .set noreorder
-    li v0, __NR_mlock
+    li $v0, __NR_mlock
     syscall
-    bnez a3, 1f
-    move a0, v0
-    j ra
+    bnez $a3, 1f
+    move $a0, $v0
+    j $ra
     nop
 1:
-    move t0, ra
-    bal     2f
+    move $t0, $ra
+    bal 2f
     nop
 2:
-    .cpsetup ra, t1, 2b
-    LA t9,__set_errno_internal
+    .cpsetup $ra, $t1, 2b
+    LA $t9, __set_errno_internal
     .cpreturn
-    j t9
-    move ra, t0
+    j $t9
+    move $ra, $t0
     .set pop
 END(mlock)
diff --git a/libc/arch-mips64/syscalls/mlockall.S b/libc/arch-mips64/syscalls/mlockall.S
index 0e158f4..a4debce 100644
--- a/libc/arch-mips64/syscalls/mlockall.S
+++ b/libc/arch-mips64/syscalls/mlockall.S
@@ -5,21 +5,21 @@
 ENTRY(mlockall)
     .set push
     .set noreorder
-    li v0, __NR_mlockall
+    li $v0, __NR_mlockall
     syscall
-    bnez a3, 1f
-    move a0, v0
-    j ra
+    bnez $a3, 1f
+    move $a0, $v0
+    j $ra
     nop
 1:
-    move t0, ra
-    bal     2f
+    move $t0, $ra
+    bal 2f
     nop
 2:
-    .cpsetup ra, t1, 2b
-    LA t9,__set_errno_internal
+    .cpsetup $ra, $t1, 2b
+    LA $t9, __set_errno_internal
     .cpreturn
-    j t9
-    move ra, t0
+    j $t9
+    move $ra, $t0
     .set pop
 END(mlockall)
diff --git a/libc/arch-mips64/syscalls/mmap.S b/libc/arch-mips64/syscalls/mmap.S
index cc53eb2..e380c72 100644
--- a/libc/arch-mips64/syscalls/mmap.S
+++ b/libc/arch-mips64/syscalls/mmap.S
@@ -5,22 +5,22 @@
 ENTRY(mmap)
     .set push
     .set noreorder
-    li v0, __NR_mmap
+    li $v0, __NR_mmap
     syscall
-    bnez a3, 1f
-    move a0, v0
-    j ra
+    bnez $a3, 1f
+    move $a0, $v0
+    j $ra
     nop
 1:
-    move t0, ra
-    bal     2f
+    move $t0, $ra
+    bal 2f
     nop
 2:
-    .cpsetup ra, t1, 2b
-    LA t9,__set_errno_internal
+    .cpsetup $ra, $t1, 2b
+    LA $t9, __set_errno_internal
     .cpreturn
-    j t9
-    move ra, t0
+    j $t9
+    move $ra, $t0
     .set pop
 END(mmap)
 
diff --git a/libc/arch-mips64/syscalls/mount.S b/libc/arch-mips64/syscalls/mount.S
index 50c7541..4d2bca1 100644
--- a/libc/arch-mips64/syscalls/mount.S
+++ b/libc/arch-mips64/syscalls/mount.S
@@ -5,21 +5,21 @@
 ENTRY(mount)
     .set push
     .set noreorder
-    li v0, __NR_mount
+    li $v0, __NR_mount
     syscall
-    bnez a3, 1f
-    move a0, v0
-    j ra
+    bnez $a3, 1f
+    move $a0, $v0
+    j $ra
     nop
 1:
-    move t0, ra
-    bal     2f
+    move $t0, $ra
+    bal 2f
     nop
 2:
-    .cpsetup ra, t1, 2b
-    LA t9,__set_errno_internal
+    .cpsetup $ra, $t1, 2b
+    LA $t9, __set_errno_internal
     .cpreturn
-    j t9
-    move ra, t0
+    j $t9
+    move $ra, $t0
     .set pop
 END(mount)
diff --git a/libc/arch-mips64/syscalls/mprotect.S b/libc/arch-mips64/syscalls/mprotect.S
index d755489..e1f3ab0 100644
--- a/libc/arch-mips64/syscalls/mprotect.S
+++ b/libc/arch-mips64/syscalls/mprotect.S
@@ -5,21 +5,21 @@
 ENTRY(mprotect)
     .set push
     .set noreorder
-    li v0, __NR_mprotect
+    li $v0, __NR_mprotect
     syscall
-    bnez a3, 1f
-    move a0, v0
-    j ra
+    bnez $a3, 1f
+    move $a0, $v0
+    j $ra
     nop
 1:
-    move t0, ra
-    bal     2f
+    move $t0, $ra
+    bal 2f
     nop
 2:
-    .cpsetup ra, t1, 2b
-    LA t9,__set_errno_internal
+    .cpsetup $ra, $t1, 2b
+    LA $t9, __set_errno_internal
     .cpreturn
-    j t9
-    move ra, t0
+    j $t9
+    move $ra, $t0
     .set pop
 END(mprotect)
diff --git a/libc/arch-mips64/syscalls/msync.S b/libc/arch-mips64/syscalls/msync.S
index efe31c1..ec2d175 100644
--- a/libc/arch-mips64/syscalls/msync.S
+++ b/libc/arch-mips64/syscalls/msync.S
@@ -5,21 +5,21 @@
 ENTRY(msync)
     .set push
     .set noreorder
-    li v0, __NR_msync
+    li $v0, __NR_msync
     syscall
-    bnez a3, 1f
-    move a0, v0
-    j ra
+    bnez $a3, 1f
+    move $a0, $v0
+    j $ra
     nop
 1:
-    move t0, ra
-    bal     2f
+    move $t0, $ra
+    bal 2f
     nop
 2:
-    .cpsetup ra, t1, 2b
-    LA t9,__set_errno_internal
+    .cpsetup $ra, $t1, 2b
+    LA $t9, __set_errno_internal
     .cpreturn
-    j t9
-    move ra, t0
+    j $t9
+    move $ra, $t0
     .set pop
 END(msync)
diff --git a/libc/arch-mips64/syscalls/munlock.S b/libc/arch-mips64/syscalls/munlock.S
index 44b930a..95c4df1 100644
--- a/libc/arch-mips64/syscalls/munlock.S
+++ b/libc/arch-mips64/syscalls/munlock.S
@@ -5,21 +5,21 @@
 ENTRY(munlock)
     .set push
     .set noreorder
-    li v0, __NR_munlock
+    li $v0, __NR_munlock
     syscall
-    bnez a3, 1f
-    move a0, v0
-    j ra
+    bnez $a3, 1f
+    move $a0, $v0
+    j $ra
     nop
 1:
-    move t0, ra
-    bal     2f
+    move $t0, $ra
+    bal 2f
     nop
 2:
-    .cpsetup ra, t1, 2b
-    LA t9,__set_errno_internal
+    .cpsetup $ra, $t1, 2b
+    LA $t9, __set_errno_internal
     .cpreturn
-    j t9
-    move ra, t0
+    j $t9
+    move $ra, $t0
     .set pop
 END(munlock)
diff --git a/libc/arch-mips64/syscalls/munlockall.S b/libc/arch-mips64/syscalls/munlockall.S
index ffeb5e1..9862461 100644
--- a/libc/arch-mips64/syscalls/munlockall.S
+++ b/libc/arch-mips64/syscalls/munlockall.S
@@ -5,21 +5,21 @@
 ENTRY(munlockall)
     .set push
     .set noreorder
-    li v0, __NR_munlockall
+    li $v0, __NR_munlockall
     syscall
-    bnez a3, 1f
-    move a0, v0
-    j ra
+    bnez $a3, 1f
+    move $a0, $v0
+    j $ra
     nop
 1:
-    move t0, ra
-    bal     2f
+    move $t0, $ra
+    bal 2f
     nop
 2:
-    .cpsetup ra, t1, 2b
-    LA t9,__set_errno_internal
+    .cpsetup $ra, $t1, 2b
+    LA $t9, __set_errno_internal
     .cpreturn
-    j t9
-    move ra, t0
+    j $t9
+    move $ra, $t0
     .set pop
 END(munlockall)
diff --git a/libc/arch-mips64/syscalls/munmap.S b/libc/arch-mips64/syscalls/munmap.S
index cd0c05c..2ca802d 100644
--- a/libc/arch-mips64/syscalls/munmap.S
+++ b/libc/arch-mips64/syscalls/munmap.S
@@ -5,21 +5,21 @@
 ENTRY(munmap)
     .set push
     .set noreorder
-    li v0, __NR_munmap
+    li $v0, __NR_munmap
     syscall
-    bnez a3, 1f
-    move a0, v0
-    j ra
+    bnez $a3, 1f
+    move $a0, $v0
+    j $ra
     nop
 1:
-    move t0, ra
-    bal     2f
+    move $t0, $ra
+    bal 2f
     nop
 2:
-    .cpsetup ra, t1, 2b
-    LA t9,__set_errno_internal
+    .cpsetup $ra, $t1, 2b
+    LA $t9, __set_errno_internal
     .cpreturn
-    j t9
-    move ra, t0
+    j $t9
+    move $ra, $t0
     .set pop
 END(munmap)
diff --git a/libc/arch-mips64/syscalls/nanosleep.S b/libc/arch-mips64/syscalls/nanosleep.S
index bdaf256..291bb00 100644
--- a/libc/arch-mips64/syscalls/nanosleep.S
+++ b/libc/arch-mips64/syscalls/nanosleep.S
@@ -5,21 +5,21 @@
 ENTRY(nanosleep)
     .set push
     .set noreorder
-    li v0, __NR_nanosleep
+    li $v0, __NR_nanosleep
     syscall
-    bnez a3, 1f
-    move a0, v0
-    j ra
+    bnez $a3, 1f
+    move $a0, $v0
+    j $ra
     nop
 1:
-    move t0, ra
-    bal     2f
+    move $t0, $ra
+    bal 2f
     nop
 2:
-    .cpsetup ra, t1, 2b
-    LA t9,__set_errno_internal
+    .cpsetup $ra, $t1, 2b
+    LA $t9, __set_errno_internal
     .cpreturn
-    j t9
-    move ra, t0
+    j $t9
+    move $ra, $t0
     .set pop
 END(nanosleep)
diff --git a/libc/arch-mips64/syscalls/personality.S b/libc/arch-mips64/syscalls/personality.S
index 6a12c95..a85cd76 100644
--- a/libc/arch-mips64/syscalls/personality.S
+++ b/libc/arch-mips64/syscalls/personality.S
@@ -5,21 +5,21 @@
 ENTRY(personality)
     .set push
     .set noreorder
-    li v0, __NR_personality
+    li $v0, __NR_personality
     syscall
-    bnez a3, 1f
-    move a0, v0
-    j ra
+    bnez $a3, 1f
+    move $a0, $v0
+    j $ra
     nop
 1:
-    move t0, ra
-    bal     2f
+    move $t0, $ra
+    bal 2f
     nop
 2:
-    .cpsetup ra, t1, 2b
-    LA t9,__set_errno_internal
+    .cpsetup $ra, $t1, 2b
+    LA $t9, __set_errno_internal
     .cpreturn
-    j t9
-    move ra, t0
+    j $t9
+    move $ra, $t0
     .set pop
 END(personality)
diff --git a/libc/arch-mips64/syscalls/pipe2.S b/libc/arch-mips64/syscalls/pipe2.S
index 1b08a45..96e25e2 100644
--- a/libc/arch-mips64/syscalls/pipe2.S
+++ b/libc/arch-mips64/syscalls/pipe2.S
@@ -5,21 +5,21 @@
 ENTRY(pipe2)
     .set push
     .set noreorder
-    li v0, __NR_pipe2
+    li $v0, __NR_pipe2
     syscall
-    bnez a3, 1f
-    move a0, v0
-    j ra
+    bnez $a3, 1f
+    move $a0, $v0
+    j $ra
     nop
 1:
-    move t0, ra
-    bal     2f
+    move $t0, $ra
+    bal 2f
     nop
 2:
-    .cpsetup ra, t1, 2b
-    LA t9,__set_errno_internal
+    .cpsetup $ra, $t1, 2b
+    LA $t9, __set_errno_internal
     .cpreturn
-    j t9
-    move ra, t0
+    j $t9
+    move $ra, $t0
     .set pop
 END(pipe2)
diff --git a/libc/arch-mips64/syscalls/prctl.S b/libc/arch-mips64/syscalls/prctl.S
index 61bb7c2..14b7155 100644
--- a/libc/arch-mips64/syscalls/prctl.S
+++ b/libc/arch-mips64/syscalls/prctl.S
@@ -5,21 +5,21 @@
 ENTRY(prctl)
     .set push
     .set noreorder
-    li v0, __NR_prctl
+    li $v0, __NR_prctl
     syscall
-    bnez a3, 1f
-    move a0, v0
-    j ra
+    bnez $a3, 1f
+    move $a0, $v0
+    j $ra
     nop
 1:
-    move t0, ra
-    bal     2f
+    move $t0, $ra
+    bal 2f
     nop
 2:
-    .cpsetup ra, t1, 2b
-    LA t9,__set_errno_internal
+    .cpsetup $ra, $t1, 2b
+    LA $t9, __set_errno_internal
     .cpreturn
-    j t9
-    move ra, t0
+    j $t9
+    move $ra, $t0
     .set pop
 END(prctl)
diff --git a/libc/arch-mips64/syscalls/pread64.S b/libc/arch-mips64/syscalls/pread64.S
index 7965ba9..74dada3 100644
--- a/libc/arch-mips64/syscalls/pread64.S
+++ b/libc/arch-mips64/syscalls/pread64.S
@@ -5,22 +5,22 @@
 ENTRY(pread64)
     .set push
     .set noreorder
-    li v0, __NR_pread64
+    li $v0, __NR_pread64
     syscall
-    bnez a3, 1f
-    move a0, v0
-    j ra
+    bnez $a3, 1f
+    move $a0, $v0
+    j $ra
     nop
 1:
-    move t0, ra
-    bal     2f
+    move $t0, $ra
+    bal 2f
     nop
 2:
-    .cpsetup ra, t1, 2b
-    LA t9,__set_errno_internal
+    .cpsetup $ra, $t1, 2b
+    LA $t9, __set_errno_internal
     .cpreturn
-    j t9
-    move ra, t0
+    j $t9
+    move $ra, $t0
     .set pop
 END(pread64)
 
diff --git a/libc/arch-mips64/syscalls/preadv.S b/libc/arch-mips64/syscalls/preadv.S
index df43a8d..744b06c 100644
--- a/libc/arch-mips64/syscalls/preadv.S
+++ b/libc/arch-mips64/syscalls/preadv.S
@@ -5,22 +5,22 @@
 ENTRY(preadv)
     .set push
     .set noreorder
-    li v0, __NR_preadv
+    li $v0, __NR_preadv
     syscall
-    bnez a3, 1f
-    move a0, v0
-    j ra
+    bnez $a3, 1f
+    move $a0, $v0
+    j $ra
     nop
 1:
-    move t0, ra
-    bal     2f
+    move $t0, $ra
+    bal 2f
     nop
 2:
-    .cpsetup ra, t1, 2b
-    LA t9,__set_errno_internal
+    .cpsetup $ra, $t1, 2b
+    LA $t9, __set_errno_internal
     .cpreturn
-    j t9
-    move ra, t0
+    j $t9
+    move $ra, $t0
     .set pop
 END(preadv)
 
diff --git a/libc/arch-mips64/syscalls/prlimit64.S b/libc/arch-mips64/syscalls/prlimit64.S
index e04a5b6..c60cf8e 100644
--- a/libc/arch-mips64/syscalls/prlimit64.S
+++ b/libc/arch-mips64/syscalls/prlimit64.S
@@ -5,22 +5,22 @@
 ENTRY(prlimit64)
     .set push
     .set noreorder
-    li v0, __NR_prlimit64
+    li $v0, __NR_prlimit64
     syscall
-    bnez a3, 1f
-    move a0, v0
-    j ra
+    bnez $a3, 1f
+    move $a0, $v0
+    j $ra
     nop
 1:
-    move t0, ra
-    bal     2f
+    move $t0, $ra
+    bal 2f
     nop
 2:
-    .cpsetup ra, t1, 2b
-    LA t9,__set_errno_internal
+    .cpsetup $ra, $t1, 2b
+    LA $t9, __set_errno_internal
     .cpreturn
-    j t9
-    move ra, t0
+    j $t9
+    move $ra, $t0
     .set pop
 END(prlimit64)
 
diff --git a/libc/arch-mips64/syscalls/process_vm_readv.S b/libc/arch-mips64/syscalls/process_vm_readv.S
index f3c7372..38ff7eb 100644
--- a/libc/arch-mips64/syscalls/process_vm_readv.S
+++ b/libc/arch-mips64/syscalls/process_vm_readv.S
@@ -5,21 +5,21 @@
 ENTRY(process_vm_readv)
     .set push
     .set noreorder
-    li v0, __NR_process_vm_readv
+    li $v0, __NR_process_vm_readv
     syscall
-    bnez a3, 1f
-    move a0, v0
-    j ra
+    bnez $a3, 1f
+    move $a0, $v0
+    j $ra
     nop
 1:
-    move t0, ra
-    bal     2f
+    move $t0, $ra
+    bal 2f
     nop
 2:
-    .cpsetup ra, t1, 2b
-    LA t9,__set_errno_internal
+    .cpsetup $ra, $t1, 2b
+    LA $t9, __set_errno_internal
     .cpreturn
-    j t9
-    move ra, t0
+    j $t9
+    move $ra, $t0
     .set pop
 END(process_vm_readv)
diff --git a/libc/arch-mips64/syscalls/process_vm_writev.S b/libc/arch-mips64/syscalls/process_vm_writev.S
index 0e8140b..c317cae 100644
--- a/libc/arch-mips64/syscalls/process_vm_writev.S
+++ b/libc/arch-mips64/syscalls/process_vm_writev.S
@@ -5,21 +5,21 @@
 ENTRY(process_vm_writev)
     .set push
     .set noreorder
-    li v0, __NR_process_vm_writev
+    li $v0, __NR_process_vm_writev
     syscall
-    bnez a3, 1f
-    move a0, v0
-    j ra
+    bnez $a3, 1f
+    move $a0, $v0
+    j $ra
     nop
 1:
-    move t0, ra
-    bal     2f
+    move $t0, $ra
+    bal 2f
     nop
 2:
-    .cpsetup ra, t1, 2b
-    LA t9,__set_errno_internal
+    .cpsetup $ra, $t1, 2b
+    LA $t9, __set_errno_internal
     .cpreturn
-    j t9
-    move ra, t0
+    j $t9
+    move $ra, $t0
     .set pop
 END(process_vm_writev)
diff --git a/libc/arch-mips64/syscalls/pwrite64.S b/libc/arch-mips64/syscalls/pwrite64.S
index 97e0183..1d6ac69 100644
--- a/libc/arch-mips64/syscalls/pwrite64.S
+++ b/libc/arch-mips64/syscalls/pwrite64.S
@@ -5,22 +5,22 @@
 ENTRY(pwrite64)
     .set push
     .set noreorder
-    li v0, __NR_pwrite64
+    li $v0, __NR_pwrite64
     syscall
-    bnez a3, 1f
-    move a0, v0
-    j ra
+    bnez $a3, 1f
+    move $a0, $v0
+    j $ra
     nop
 1:
-    move t0, ra
-    bal     2f
+    move $t0, $ra
+    bal 2f
     nop
 2:
-    .cpsetup ra, t1, 2b
-    LA t9,__set_errno_internal
+    .cpsetup $ra, $t1, 2b
+    LA $t9, __set_errno_internal
     .cpreturn
-    j t9
-    move ra, t0
+    j $t9
+    move $ra, $t0
     .set pop
 END(pwrite64)
 
diff --git a/libc/arch-mips64/syscalls/pwritev.S b/libc/arch-mips64/syscalls/pwritev.S
index f55cec0..f3044f9 100644
--- a/libc/arch-mips64/syscalls/pwritev.S
+++ b/libc/arch-mips64/syscalls/pwritev.S
@@ -5,22 +5,22 @@
 ENTRY(pwritev)
     .set push
     .set noreorder
-    li v0, __NR_pwritev
+    li $v0, __NR_pwritev
     syscall
-    bnez a3, 1f
-    move a0, v0
-    j ra
+    bnez $a3, 1f
+    move $a0, $v0
+    j $ra
     nop
 1:
-    move t0, ra
-    bal     2f
+    move $t0, $ra
+    bal 2f
     nop
 2:
-    .cpsetup ra, t1, 2b
-    LA t9,__set_errno_internal
+    .cpsetup $ra, $t1, 2b
+    LA $t9, __set_errno_internal
     .cpreturn
-    j t9
-    move ra, t0
+    j $t9
+    move $ra, $t0
     .set pop
 END(pwritev)
 
diff --git a/libc/arch-mips64/syscalls/quotactl.S b/libc/arch-mips64/syscalls/quotactl.S
index 861947c..83735ac 100644
--- a/libc/arch-mips64/syscalls/quotactl.S
+++ b/libc/arch-mips64/syscalls/quotactl.S
@@ -5,21 +5,21 @@
 ENTRY(quotactl)
     .set push
     .set noreorder
-    li v0, __NR_quotactl
+    li $v0, __NR_quotactl
     syscall
-    bnez a3, 1f
-    move a0, v0
-    j ra
+    bnez $a3, 1f
+    move $a0, $v0
+    j $ra
     nop
 1:
-    move t0, ra
-    bal     2f
+    move $t0, $ra
+    bal 2f
     nop
 2:
-    .cpsetup ra, t1, 2b
-    LA t9,__set_errno_internal
+    .cpsetup $ra, $t1, 2b
+    LA $t9, __set_errno_internal
     .cpreturn
-    j t9
-    move ra, t0
+    j $t9
+    move $ra, $t0
     .set pop
 END(quotactl)
diff --git a/libc/arch-mips64/syscalls/read.S b/libc/arch-mips64/syscalls/read.S
index 74d39df..b44e6af 100644
--- a/libc/arch-mips64/syscalls/read.S
+++ b/libc/arch-mips64/syscalls/read.S
@@ -5,21 +5,21 @@
 ENTRY(read)
     .set push
     .set noreorder
-    li v0, __NR_read
+    li $v0, __NR_read
     syscall
-    bnez a3, 1f
-    move a0, v0
-    j ra
+    bnez $a3, 1f
+    move $a0, $v0
+    j $ra
     nop
 1:
-    move t0, ra
-    bal     2f
+    move $t0, $ra
+    bal 2f
     nop
 2:
-    .cpsetup ra, t1, 2b
-    LA t9,__set_errno_internal
+    .cpsetup $ra, $t1, 2b
+    LA $t9, __set_errno_internal
     .cpreturn
-    j t9
-    move ra, t0
+    j $t9
+    move $ra, $t0
     .set pop
 END(read)
diff --git a/libc/arch-mips64/syscalls/readahead.S b/libc/arch-mips64/syscalls/readahead.S
index ae511d9..f111ac4 100644
--- a/libc/arch-mips64/syscalls/readahead.S
+++ b/libc/arch-mips64/syscalls/readahead.S
@@ -5,21 +5,21 @@
 ENTRY(readahead)
     .set push
     .set noreorder
-    li v0, __NR_readahead
+    li $v0, __NR_readahead
     syscall
-    bnez a3, 1f
-    move a0, v0
-    j ra
+    bnez $a3, 1f
+    move $a0, $v0
+    j $ra
     nop
 1:
-    move t0, ra
-    bal     2f
+    move $t0, $ra
+    bal 2f
     nop
 2:
-    .cpsetup ra, t1, 2b
-    LA t9,__set_errno_internal
+    .cpsetup $ra, $t1, 2b
+    LA $t9, __set_errno_internal
     .cpreturn
-    j t9
-    move ra, t0
+    j $t9
+    move $ra, $t0
     .set pop
 END(readahead)
diff --git a/libc/arch-mips64/syscalls/readlinkat.S b/libc/arch-mips64/syscalls/readlinkat.S
index 473a946..987943b 100644
--- a/libc/arch-mips64/syscalls/readlinkat.S
+++ b/libc/arch-mips64/syscalls/readlinkat.S
@@ -5,21 +5,21 @@
 ENTRY(readlinkat)
     .set push
     .set noreorder
-    li v0, __NR_readlinkat
+    li $v0, __NR_readlinkat
     syscall
-    bnez a3, 1f
-    move a0, v0
-    j ra
+    bnez $a3, 1f
+    move $a0, $v0
+    j $ra
     nop
 1:
-    move t0, ra
-    bal     2f
+    move $t0, $ra
+    bal 2f
     nop
 2:
-    .cpsetup ra, t1, 2b
-    LA t9,__set_errno_internal
+    .cpsetup $ra, $t1, 2b
+    LA $t9, __set_errno_internal
     .cpreturn
-    j t9
-    move ra, t0
+    j $t9
+    move $ra, $t0
     .set pop
 END(readlinkat)
diff --git a/libc/arch-mips64/syscalls/readv.S b/libc/arch-mips64/syscalls/readv.S
index daa800c..04bf55c 100644
--- a/libc/arch-mips64/syscalls/readv.S
+++ b/libc/arch-mips64/syscalls/readv.S
@@ -5,21 +5,21 @@
 ENTRY(readv)
     .set push
     .set noreorder
-    li v0, __NR_readv
+    li $v0, __NR_readv
     syscall
-    bnez a3, 1f
-    move a0, v0
-    j ra
+    bnez $a3, 1f
+    move $a0, $v0
+    j $ra
     nop
 1:
-    move t0, ra
-    bal     2f
+    move $t0, $ra
+    bal 2f
     nop
 2:
-    .cpsetup ra, t1, 2b
-    LA t9,__set_errno_internal
+    .cpsetup $ra, $t1, 2b
+    LA $t9, __set_errno_internal
     .cpreturn
-    j t9
-    move ra, t0
+    j $t9
+    move $ra, $t0
     .set pop
 END(readv)
diff --git a/libc/arch-mips64/syscalls/recvfrom.S b/libc/arch-mips64/syscalls/recvfrom.S
index 4c9b5fa..7c906ac 100644
--- a/libc/arch-mips64/syscalls/recvfrom.S
+++ b/libc/arch-mips64/syscalls/recvfrom.S
@@ -5,21 +5,21 @@
 ENTRY(recvfrom)
     .set push
     .set noreorder
-    li v0, __NR_recvfrom
+    li $v0, __NR_recvfrom
     syscall
-    bnez a3, 1f
-    move a0, v0
-    j ra
+    bnez $a3, 1f
+    move $a0, $v0
+    j $ra
     nop
 1:
-    move t0, ra
-    bal     2f
+    move $t0, $ra
+    bal 2f
     nop
 2:
-    .cpsetup ra, t1, 2b
-    LA t9,__set_errno_internal
+    .cpsetup $ra, $t1, 2b
+    LA $t9, __set_errno_internal
     .cpreturn
-    j t9
-    move ra, t0
+    j $t9
+    move $ra, $t0
     .set pop
 END(recvfrom)
diff --git a/libc/arch-mips64/syscalls/recvmmsg.S b/libc/arch-mips64/syscalls/recvmmsg.S
index 817250c..0c022cb 100644
--- a/libc/arch-mips64/syscalls/recvmmsg.S
+++ b/libc/arch-mips64/syscalls/recvmmsg.S
@@ -5,21 +5,21 @@
 ENTRY(recvmmsg)
     .set push
     .set noreorder
-    li v0, __NR_recvmmsg
+    li $v0, __NR_recvmmsg
     syscall
-    bnez a3, 1f
-    move a0, v0
-    j ra
+    bnez $a3, 1f
+    move $a0, $v0
+    j $ra
     nop
 1:
-    move t0, ra
-    bal     2f
+    move $t0, $ra
+    bal 2f
     nop
 2:
-    .cpsetup ra, t1, 2b
-    LA t9,__set_errno_internal
+    .cpsetup $ra, $t1, 2b
+    LA $t9, __set_errno_internal
     .cpreturn
-    j t9
-    move ra, t0
+    j $t9
+    move $ra, $t0
     .set pop
 END(recvmmsg)
diff --git a/libc/arch-mips64/syscalls/recvmsg.S b/libc/arch-mips64/syscalls/recvmsg.S
index 877899d..a06bcdd 100644
--- a/libc/arch-mips64/syscalls/recvmsg.S
+++ b/libc/arch-mips64/syscalls/recvmsg.S
@@ -5,21 +5,21 @@
 ENTRY(recvmsg)
     .set push
     .set noreorder
-    li v0, __NR_recvmsg
+    li $v0, __NR_recvmsg
     syscall
-    bnez a3, 1f
-    move a0, v0
-    j ra
+    bnez $a3, 1f
+    move $a0, $v0
+    j $ra
     nop
 1:
-    move t0, ra
-    bal     2f
+    move $t0, $ra
+    bal 2f
     nop
 2:
-    .cpsetup ra, t1, 2b
-    LA t9,__set_errno_internal
+    .cpsetup $ra, $t1, 2b
+    LA $t9, __set_errno_internal
     .cpreturn
-    j t9
-    move ra, t0
+    j $t9
+    move $ra, $t0
     .set pop
 END(recvmsg)
diff --git a/libc/arch-mips64/syscalls/removexattr.S b/libc/arch-mips64/syscalls/removexattr.S
index c9d8a0e..fb5d8de 100644
--- a/libc/arch-mips64/syscalls/removexattr.S
+++ b/libc/arch-mips64/syscalls/removexattr.S
@@ -5,21 +5,21 @@
 ENTRY(removexattr)
     .set push
     .set noreorder
-    li v0, __NR_removexattr
+    li $v0, __NR_removexattr
     syscall
-    bnez a3, 1f
-    move a0, v0
-    j ra
+    bnez $a3, 1f
+    move $a0, $v0
+    j $ra
     nop
 1:
-    move t0, ra
-    bal     2f
+    move $t0, $ra
+    bal 2f
     nop
 2:
-    .cpsetup ra, t1, 2b
-    LA t9,__set_errno_internal
+    .cpsetup $ra, $t1, 2b
+    LA $t9, __set_errno_internal
     .cpreturn
-    j t9
-    move ra, t0
+    j $t9
+    move $ra, $t0
     .set pop
 END(removexattr)
diff --git a/libc/arch-mips64/syscalls/renameat.S b/libc/arch-mips64/syscalls/renameat.S
index 16b9333..9a8ab45 100644
--- a/libc/arch-mips64/syscalls/renameat.S
+++ b/libc/arch-mips64/syscalls/renameat.S
@@ -5,21 +5,21 @@
 ENTRY(renameat)
     .set push
     .set noreorder
-    li v0, __NR_renameat
+    li $v0, __NR_renameat
     syscall
-    bnez a3, 1f
-    move a0, v0
-    j ra
+    bnez $a3, 1f
+    move $a0, $v0
+    j $ra
     nop
 1:
-    move t0, ra
-    bal     2f
+    move $t0, $ra
+    bal 2f
     nop
 2:
-    .cpsetup ra, t1, 2b
-    LA t9,__set_errno_internal
+    .cpsetup $ra, $t1, 2b
+    LA $t9, __set_errno_internal
     .cpreturn
-    j t9
-    move ra, t0
+    j $t9
+    move $ra, $t0
     .set pop
 END(renameat)
diff --git a/libc/arch-mips64/syscalls/sched_get_priority_max.S b/libc/arch-mips64/syscalls/sched_get_priority_max.S
index 67e2675..89b3649 100644
--- a/libc/arch-mips64/syscalls/sched_get_priority_max.S
+++ b/libc/arch-mips64/syscalls/sched_get_priority_max.S
@@ -5,21 +5,21 @@
 ENTRY(sched_get_priority_max)
     .set push
     .set noreorder
-    li v0, __NR_sched_get_priority_max
+    li $v0, __NR_sched_get_priority_max
     syscall
-    bnez a3, 1f
-    move a0, v0
-    j ra
+    bnez $a3, 1f
+    move $a0, $v0
+    j $ra
     nop
 1:
-    move t0, ra
-    bal     2f
+    move $t0, $ra
+    bal 2f
     nop
 2:
-    .cpsetup ra, t1, 2b
-    LA t9,__set_errno_internal
+    .cpsetup $ra, $t1, 2b
+    LA $t9, __set_errno_internal
     .cpreturn
-    j t9
-    move ra, t0
+    j $t9
+    move $ra, $t0
     .set pop
 END(sched_get_priority_max)
diff --git a/libc/arch-mips64/syscalls/sched_get_priority_min.S b/libc/arch-mips64/syscalls/sched_get_priority_min.S
index 957f523..31c162d 100644
--- a/libc/arch-mips64/syscalls/sched_get_priority_min.S
+++ b/libc/arch-mips64/syscalls/sched_get_priority_min.S
@@ -5,21 +5,21 @@
 ENTRY(sched_get_priority_min)
     .set push
     .set noreorder
-    li v0, __NR_sched_get_priority_min
+    li $v0, __NR_sched_get_priority_min
     syscall
-    bnez a3, 1f
-    move a0, v0
-    j ra
+    bnez $a3, 1f
+    move $a0, $v0
+    j $ra
     nop
 1:
-    move t0, ra
-    bal     2f
+    move $t0, $ra
+    bal 2f
     nop
 2:
-    .cpsetup ra, t1, 2b
-    LA t9,__set_errno_internal
+    .cpsetup $ra, $t1, 2b
+    LA $t9, __set_errno_internal
     .cpreturn
-    j t9
-    move ra, t0
+    j $t9
+    move $ra, $t0
     .set pop
 END(sched_get_priority_min)
diff --git a/libc/arch-mips64/syscalls/sched_getparam.S b/libc/arch-mips64/syscalls/sched_getparam.S
index 77bb4eb..a15aaf5 100644
--- a/libc/arch-mips64/syscalls/sched_getparam.S
+++ b/libc/arch-mips64/syscalls/sched_getparam.S
@@ -5,21 +5,21 @@
 ENTRY(sched_getparam)
     .set push
     .set noreorder
-    li v0, __NR_sched_getparam
+    li $v0, __NR_sched_getparam
     syscall
-    bnez a3, 1f
-    move a0, v0
-    j ra
+    bnez $a3, 1f
+    move $a0, $v0
+    j $ra
     nop
 1:
-    move t0, ra
-    bal     2f
+    move $t0, $ra
+    bal 2f
     nop
 2:
-    .cpsetup ra, t1, 2b
-    LA t9,__set_errno_internal
+    .cpsetup $ra, $t1, 2b
+    LA $t9, __set_errno_internal
     .cpreturn
-    j t9
-    move ra, t0
+    j $t9
+    move $ra, $t0
     .set pop
 END(sched_getparam)
diff --git a/libc/arch-mips64/syscalls/sched_getscheduler.S b/libc/arch-mips64/syscalls/sched_getscheduler.S
index 324fa21..0e48a16 100644
--- a/libc/arch-mips64/syscalls/sched_getscheduler.S
+++ b/libc/arch-mips64/syscalls/sched_getscheduler.S
@@ -5,21 +5,21 @@
 ENTRY(sched_getscheduler)
     .set push
     .set noreorder
-    li v0, __NR_sched_getscheduler
+    li $v0, __NR_sched_getscheduler
     syscall
-    bnez a3, 1f
-    move a0, v0
-    j ra
+    bnez $a3, 1f
+    move $a0, $v0
+    j $ra
     nop
 1:
-    move t0, ra
-    bal     2f
+    move $t0, $ra
+    bal 2f
     nop
 2:
-    .cpsetup ra, t1, 2b
-    LA t9,__set_errno_internal
+    .cpsetup $ra, $t1, 2b
+    LA $t9, __set_errno_internal
     .cpreturn
-    j t9
-    move ra, t0
+    j $t9
+    move $ra, $t0
     .set pop
 END(sched_getscheduler)
diff --git a/libc/arch-mips64/syscalls/sched_rr_get_interval.S b/libc/arch-mips64/syscalls/sched_rr_get_interval.S
index 3019554..8ee4fe7 100644
--- a/libc/arch-mips64/syscalls/sched_rr_get_interval.S
+++ b/libc/arch-mips64/syscalls/sched_rr_get_interval.S
@@ -5,21 +5,21 @@
 ENTRY(sched_rr_get_interval)
     .set push
     .set noreorder
-    li v0, __NR_sched_rr_get_interval
+    li $v0, __NR_sched_rr_get_interval
     syscall
-    bnez a3, 1f
-    move a0, v0
-    j ra
+    bnez $a3, 1f
+    move $a0, $v0
+    j $ra
     nop
 1:
-    move t0, ra
-    bal     2f
+    move $t0, $ra
+    bal 2f
     nop
 2:
-    .cpsetup ra, t1, 2b
-    LA t9,__set_errno_internal
+    .cpsetup $ra, $t1, 2b
+    LA $t9, __set_errno_internal
     .cpreturn
-    j t9
-    move ra, t0
+    j $t9
+    move $ra, $t0
     .set pop
 END(sched_rr_get_interval)
diff --git a/libc/arch-mips64/syscalls/sched_setaffinity.S b/libc/arch-mips64/syscalls/sched_setaffinity.S
index 1520902..a5056b4 100644
--- a/libc/arch-mips64/syscalls/sched_setaffinity.S
+++ b/libc/arch-mips64/syscalls/sched_setaffinity.S
@@ -5,21 +5,21 @@
 ENTRY(sched_setaffinity)
     .set push
     .set noreorder
-    li v0, __NR_sched_setaffinity
+    li $v0, __NR_sched_setaffinity
     syscall
-    bnez a3, 1f
-    move a0, v0
-    j ra
+    bnez $a3, 1f
+    move $a0, $v0
+    j $ra
     nop
 1:
-    move t0, ra
-    bal     2f
+    move $t0, $ra
+    bal 2f
     nop
 2:
-    .cpsetup ra, t1, 2b
-    LA t9,__set_errno_internal
+    .cpsetup $ra, $t1, 2b
+    LA $t9, __set_errno_internal
     .cpreturn
-    j t9
-    move ra, t0
+    j $t9
+    move $ra, $t0
     .set pop
 END(sched_setaffinity)
diff --git a/libc/arch-mips64/syscalls/sched_setparam.S b/libc/arch-mips64/syscalls/sched_setparam.S
index a37b15c..def1e4e 100644
--- a/libc/arch-mips64/syscalls/sched_setparam.S
+++ b/libc/arch-mips64/syscalls/sched_setparam.S
@@ -5,21 +5,21 @@
 ENTRY(sched_setparam)
     .set push
     .set noreorder
-    li v0, __NR_sched_setparam
+    li $v0, __NR_sched_setparam
     syscall
-    bnez a3, 1f
-    move a0, v0
-    j ra
+    bnez $a3, 1f
+    move $a0, $v0
+    j $ra
     nop
 1:
-    move t0, ra
-    bal     2f
+    move $t0, $ra
+    bal 2f
     nop
 2:
-    .cpsetup ra, t1, 2b
-    LA t9,__set_errno_internal
+    .cpsetup $ra, $t1, 2b
+    LA $t9, __set_errno_internal
     .cpreturn
-    j t9
-    move ra, t0
+    j $t9
+    move $ra, $t0
     .set pop
 END(sched_setparam)
diff --git a/libc/arch-mips64/syscalls/sched_setscheduler.S b/libc/arch-mips64/syscalls/sched_setscheduler.S
index ea4c6c4..0178541 100644
--- a/libc/arch-mips64/syscalls/sched_setscheduler.S
+++ b/libc/arch-mips64/syscalls/sched_setscheduler.S
@@ -5,21 +5,21 @@
 ENTRY(sched_setscheduler)
     .set push
     .set noreorder
-    li v0, __NR_sched_setscheduler
+    li $v0, __NR_sched_setscheduler
     syscall
-    bnez a3, 1f
-    move a0, v0
-    j ra
+    bnez $a3, 1f
+    move $a0, $v0
+    j $ra
     nop
 1:
-    move t0, ra
-    bal     2f
+    move $t0, $ra
+    bal 2f
     nop
 2:
-    .cpsetup ra, t1, 2b
-    LA t9,__set_errno_internal
+    .cpsetup $ra, $t1, 2b
+    LA $t9, __set_errno_internal
     .cpreturn
-    j t9
-    move ra, t0
+    j $t9
+    move $ra, $t0
     .set pop
 END(sched_setscheduler)
diff --git a/libc/arch-mips64/syscalls/sched_yield.S b/libc/arch-mips64/syscalls/sched_yield.S
index 5d86ea5..f69ac3c 100644
--- a/libc/arch-mips64/syscalls/sched_yield.S
+++ b/libc/arch-mips64/syscalls/sched_yield.S
@@ -5,21 +5,21 @@
 ENTRY(sched_yield)
     .set push
     .set noreorder
-    li v0, __NR_sched_yield
+    li $v0, __NR_sched_yield
     syscall
-    bnez a3, 1f
-    move a0, v0
-    j ra
+    bnez $a3, 1f
+    move $a0, $v0
+    j $ra
     nop
 1:
-    move t0, ra
-    bal     2f
+    move $t0, $ra
+    bal 2f
     nop
 2:
-    .cpsetup ra, t1, 2b
-    LA t9,__set_errno_internal
+    .cpsetup $ra, $t1, 2b
+    LA $t9, __set_errno_internal
     .cpreturn
-    j t9
-    move ra, t0
+    j $t9
+    move $ra, $t0
     .set pop
 END(sched_yield)
diff --git a/libc/arch-mips64/syscalls/sendfile.S b/libc/arch-mips64/syscalls/sendfile.S
index a50459e..b4d3994 100644
--- a/libc/arch-mips64/syscalls/sendfile.S
+++ b/libc/arch-mips64/syscalls/sendfile.S
@@ -5,22 +5,22 @@
 ENTRY(sendfile)
     .set push
     .set noreorder
-    li v0, __NR_sendfile
+    li $v0, __NR_sendfile
     syscall
-    bnez a3, 1f
-    move a0, v0
-    j ra
+    bnez $a3, 1f
+    move $a0, $v0
+    j $ra
     nop
 1:
-    move t0, ra
-    bal     2f
+    move $t0, $ra
+    bal 2f
     nop
 2:
-    .cpsetup ra, t1, 2b
-    LA t9,__set_errno_internal
+    .cpsetup $ra, $t1, 2b
+    LA $t9, __set_errno_internal
     .cpreturn
-    j t9
-    move ra, t0
+    j $t9
+    move $ra, $t0
     .set pop
 END(sendfile)
 
diff --git a/libc/arch-mips64/syscalls/sendmmsg.S b/libc/arch-mips64/syscalls/sendmmsg.S
index 4a8d855..2ecd7ef 100644
--- a/libc/arch-mips64/syscalls/sendmmsg.S
+++ b/libc/arch-mips64/syscalls/sendmmsg.S
@@ -5,21 +5,21 @@
 ENTRY(sendmmsg)
     .set push
     .set noreorder
-    li v0, __NR_sendmmsg
+    li $v0, __NR_sendmmsg
     syscall
-    bnez a3, 1f
-    move a0, v0
-    j ra
+    bnez $a3, 1f
+    move $a0, $v0
+    j $ra
     nop
 1:
-    move t0, ra
-    bal     2f
+    move $t0, $ra
+    bal 2f
     nop
 2:
-    .cpsetup ra, t1, 2b
-    LA t9,__set_errno_internal
+    .cpsetup $ra, $t1, 2b
+    LA $t9, __set_errno_internal
     .cpreturn
-    j t9
-    move ra, t0
+    j $t9
+    move $ra, $t0
     .set pop
 END(sendmmsg)
diff --git a/libc/arch-mips64/syscalls/sendmsg.S b/libc/arch-mips64/syscalls/sendmsg.S
index 519dce4..d4f9735 100644
--- a/libc/arch-mips64/syscalls/sendmsg.S
+++ b/libc/arch-mips64/syscalls/sendmsg.S
@@ -5,21 +5,21 @@
 ENTRY(sendmsg)
     .set push
     .set noreorder
-    li v0, __NR_sendmsg
+    li $v0, __NR_sendmsg
     syscall
-    bnez a3, 1f
-    move a0, v0
-    j ra
+    bnez $a3, 1f
+    move $a0, $v0
+    j $ra
     nop
 1:
-    move t0, ra
-    bal     2f
+    move $t0, $ra
+    bal 2f
     nop
 2:
-    .cpsetup ra, t1, 2b
-    LA t9,__set_errno_internal
+    .cpsetup $ra, $t1, 2b
+    LA $t9, __set_errno_internal
     .cpreturn
-    j t9
-    move ra, t0
+    j $t9
+    move $ra, $t0
     .set pop
 END(sendmsg)
diff --git a/libc/arch-mips64/syscalls/sendto.S b/libc/arch-mips64/syscalls/sendto.S
index 84efc09..e10abd5 100644
--- a/libc/arch-mips64/syscalls/sendto.S
+++ b/libc/arch-mips64/syscalls/sendto.S
@@ -5,21 +5,21 @@
 ENTRY(sendto)
     .set push
     .set noreorder
-    li v0, __NR_sendto
+    li $v0, __NR_sendto
     syscall
-    bnez a3, 1f
-    move a0, v0
-    j ra
+    bnez $a3, 1f
+    move $a0, $v0
+    j $ra
     nop
 1:
-    move t0, ra
-    bal     2f
+    move $t0, $ra
+    bal 2f
     nop
 2:
-    .cpsetup ra, t1, 2b
-    LA t9,__set_errno_internal
+    .cpsetup $ra, $t1, 2b
+    LA $t9, __set_errno_internal
     .cpreturn
-    j t9
-    move ra, t0
+    j $t9
+    move $ra, $t0
     .set pop
 END(sendto)
diff --git a/libc/arch-mips64/syscalls/setdomainname.S b/libc/arch-mips64/syscalls/setdomainname.S
index 6cee88e..5e6b7c0 100644
--- a/libc/arch-mips64/syscalls/setdomainname.S
+++ b/libc/arch-mips64/syscalls/setdomainname.S
@@ -5,21 +5,21 @@
 ENTRY(setdomainname)
     .set push
     .set noreorder
-    li v0, __NR_setdomainname
+    li $v0, __NR_setdomainname
     syscall
-    bnez a3, 1f
-    move a0, v0
-    j ra
+    bnez $a3, 1f
+    move $a0, $v0
+    j $ra
     nop
 1:
-    move t0, ra
-    bal     2f
+    move $t0, $ra
+    bal 2f
     nop
 2:
-    .cpsetup ra, t1, 2b
-    LA t9,__set_errno_internal
+    .cpsetup $ra, $t1, 2b
+    LA $t9, __set_errno_internal
     .cpreturn
-    j t9
-    move ra, t0
+    j $t9
+    move $ra, $t0
     .set pop
 END(setdomainname)
diff --git a/libc/arch-mips64/syscalls/setfsgid.S b/libc/arch-mips64/syscalls/setfsgid.S
index db1bd7f..05d9681 100644
--- a/libc/arch-mips64/syscalls/setfsgid.S
+++ b/libc/arch-mips64/syscalls/setfsgid.S
@@ -5,21 +5,21 @@
 ENTRY(setfsgid)
     .set push
     .set noreorder
-    li v0, __NR_setfsgid
+    li $v0, __NR_setfsgid
     syscall
-    bnez a3, 1f
-    move a0, v0
-    j ra
+    bnez $a3, 1f
+    move $a0, $v0
+    j $ra
     nop
 1:
-    move t0, ra
-    bal     2f
+    move $t0, $ra
+    bal 2f
     nop
 2:
-    .cpsetup ra, t1, 2b
-    LA t9,__set_errno_internal
+    .cpsetup $ra, $t1, 2b
+    LA $t9, __set_errno_internal
     .cpreturn
-    j t9
-    move ra, t0
+    j $t9
+    move $ra, $t0
     .set pop
 END(setfsgid)
diff --git a/libc/arch-mips64/syscalls/setfsuid.S b/libc/arch-mips64/syscalls/setfsuid.S
index 4254b18..8097b77 100644
--- a/libc/arch-mips64/syscalls/setfsuid.S
+++ b/libc/arch-mips64/syscalls/setfsuid.S
@@ -5,21 +5,21 @@
 ENTRY(setfsuid)
     .set push
     .set noreorder
-    li v0, __NR_setfsuid
+    li $v0, __NR_setfsuid
     syscall
-    bnez a3, 1f
-    move a0, v0
-    j ra
+    bnez $a3, 1f
+    move $a0, $v0
+    j $ra
     nop
 1:
-    move t0, ra
-    bal     2f
+    move $t0, $ra
+    bal 2f
     nop
 2:
-    .cpsetup ra, t1, 2b
-    LA t9,__set_errno_internal
+    .cpsetup $ra, $t1, 2b
+    LA $t9, __set_errno_internal
     .cpreturn
-    j t9
-    move ra, t0
+    j $t9
+    move $ra, $t0
     .set pop
 END(setfsuid)
diff --git a/libc/arch-mips64/syscalls/setgid.S b/libc/arch-mips64/syscalls/setgid.S
index 166a6d6..7ba4874 100644
--- a/libc/arch-mips64/syscalls/setgid.S
+++ b/libc/arch-mips64/syscalls/setgid.S
@@ -5,21 +5,21 @@
 ENTRY(setgid)
     .set push
     .set noreorder
-    li v0, __NR_setgid
+    li $v0, __NR_setgid
     syscall
-    bnez a3, 1f
-    move a0, v0
-    j ra
+    bnez $a3, 1f
+    move $a0, $v0
+    j $ra
     nop
 1:
-    move t0, ra
-    bal     2f
+    move $t0, $ra
+    bal 2f
     nop
 2:
-    .cpsetup ra, t1, 2b
-    LA t9,__set_errno_internal
+    .cpsetup $ra, $t1, 2b
+    LA $t9, __set_errno_internal
     .cpreturn
-    j t9
-    move ra, t0
+    j $t9
+    move $ra, $t0
     .set pop
 END(setgid)
diff --git a/libc/arch-mips64/syscalls/setgroups.S b/libc/arch-mips64/syscalls/setgroups.S
index 24649f7..f482d0d 100644
--- a/libc/arch-mips64/syscalls/setgroups.S
+++ b/libc/arch-mips64/syscalls/setgroups.S
@@ -5,21 +5,21 @@
 ENTRY(setgroups)
     .set push
     .set noreorder
-    li v0, __NR_setgroups
+    li $v0, __NR_setgroups
     syscall
-    bnez a3, 1f
-    move a0, v0
-    j ra
+    bnez $a3, 1f
+    move $a0, $v0
+    j $ra
     nop
 1:
-    move t0, ra
-    bal     2f
+    move $t0, $ra
+    bal 2f
     nop
 2:
-    .cpsetup ra, t1, 2b
-    LA t9,__set_errno_internal
+    .cpsetup $ra, $t1, 2b
+    LA $t9, __set_errno_internal
     .cpreturn
-    j t9
-    move ra, t0
+    j $t9
+    move $ra, $t0
     .set pop
 END(setgroups)
diff --git a/libc/arch-mips64/syscalls/sethostname.S b/libc/arch-mips64/syscalls/sethostname.S
index 2f132a2..651df0e 100644
--- a/libc/arch-mips64/syscalls/sethostname.S
+++ b/libc/arch-mips64/syscalls/sethostname.S
@@ -5,21 +5,21 @@
 ENTRY(sethostname)
     .set push
     .set noreorder
-    li v0, __NR_sethostname
+    li $v0, __NR_sethostname
     syscall
-    bnez a3, 1f
-    move a0, v0
-    j ra
+    bnez $a3, 1f
+    move $a0, $v0
+    j $ra
     nop
 1:
-    move t0, ra
-    bal     2f
+    move $t0, $ra
+    bal 2f
     nop
 2:
-    .cpsetup ra, t1, 2b
-    LA t9,__set_errno_internal
+    .cpsetup $ra, $t1, 2b
+    LA $t9, __set_errno_internal
     .cpreturn
-    j t9
-    move ra, t0
+    j $t9
+    move $ra, $t0
     .set pop
 END(sethostname)
diff --git a/libc/arch-mips64/syscalls/setitimer.S b/libc/arch-mips64/syscalls/setitimer.S
index 5764573..35c2bda 100644
--- a/libc/arch-mips64/syscalls/setitimer.S
+++ b/libc/arch-mips64/syscalls/setitimer.S
@@ -5,21 +5,21 @@
 ENTRY(setitimer)
     .set push
     .set noreorder
-    li v0, __NR_setitimer
+    li $v0, __NR_setitimer
     syscall
-    bnez a3, 1f
-    move a0, v0
-    j ra
+    bnez $a3, 1f
+    move $a0, $v0
+    j $ra
     nop
 1:
-    move t0, ra
-    bal     2f
+    move $t0, $ra
+    bal 2f
     nop
 2:
-    .cpsetup ra, t1, 2b
-    LA t9,__set_errno_internal
+    .cpsetup $ra, $t1, 2b
+    LA $t9, __set_errno_internal
     .cpreturn
-    j t9
-    move ra, t0
+    j $t9
+    move $ra, $t0
     .set pop
 END(setitimer)
diff --git a/libc/arch-mips64/syscalls/setns.S b/libc/arch-mips64/syscalls/setns.S
index 6b6178f..d640545 100644
--- a/libc/arch-mips64/syscalls/setns.S
+++ b/libc/arch-mips64/syscalls/setns.S
@@ -5,21 +5,21 @@
 ENTRY(setns)
     .set push
     .set noreorder
-    li v0, __NR_setns
+    li $v0, __NR_setns
     syscall
-    bnez a3, 1f
-    move a0, v0
-    j ra
+    bnez $a3, 1f
+    move $a0, $v0
+    j $ra
     nop
 1:
-    move t0, ra
-    bal     2f
+    move $t0, $ra
+    bal 2f
     nop
 2:
-    .cpsetup ra, t1, 2b
-    LA t9,__set_errno_internal
+    .cpsetup $ra, $t1, 2b
+    LA $t9, __set_errno_internal
     .cpreturn
-    j t9
-    move ra, t0
+    j $t9
+    move $ra, $t0
     .set pop
 END(setns)
diff --git a/libc/arch-mips64/syscalls/setpgid.S b/libc/arch-mips64/syscalls/setpgid.S
index 233f784..8c5f71e 100644
--- a/libc/arch-mips64/syscalls/setpgid.S
+++ b/libc/arch-mips64/syscalls/setpgid.S
@@ -5,21 +5,21 @@
 ENTRY(setpgid)
     .set push
     .set noreorder
-    li v0, __NR_setpgid
+    li $v0, __NR_setpgid
     syscall
-    bnez a3, 1f
-    move a0, v0
-    j ra
+    bnez $a3, 1f
+    move $a0, $v0
+    j $ra
     nop
 1:
-    move t0, ra
-    bal     2f
+    move $t0, $ra
+    bal 2f
     nop
 2:
-    .cpsetup ra, t1, 2b
-    LA t9,__set_errno_internal
+    .cpsetup $ra, $t1, 2b
+    LA $t9, __set_errno_internal
     .cpreturn
-    j t9
-    move ra, t0
+    j $t9
+    move $ra, $t0
     .set pop
 END(setpgid)
diff --git a/libc/arch-mips64/syscalls/setpriority.S b/libc/arch-mips64/syscalls/setpriority.S
index d88a2ff..5777a0c 100644
--- a/libc/arch-mips64/syscalls/setpriority.S
+++ b/libc/arch-mips64/syscalls/setpriority.S
@@ -5,21 +5,21 @@
 ENTRY(setpriority)
     .set push
     .set noreorder
-    li v0, __NR_setpriority
+    li $v0, __NR_setpriority
     syscall
-    bnez a3, 1f
-    move a0, v0
-    j ra
+    bnez $a3, 1f
+    move $a0, $v0
+    j $ra
     nop
 1:
-    move t0, ra
-    bal     2f
+    move $t0, $ra
+    bal 2f
     nop
 2:
-    .cpsetup ra, t1, 2b
-    LA t9,__set_errno_internal
+    .cpsetup $ra, $t1, 2b
+    LA $t9, __set_errno_internal
     .cpreturn
-    j t9
-    move ra, t0
+    j $t9
+    move $ra, $t0
     .set pop
 END(setpriority)
diff --git a/libc/arch-mips64/syscalls/setregid.S b/libc/arch-mips64/syscalls/setregid.S
index c82b4fd..03be155 100644
--- a/libc/arch-mips64/syscalls/setregid.S
+++ b/libc/arch-mips64/syscalls/setregid.S
@@ -5,21 +5,21 @@
 ENTRY(setregid)
     .set push
     .set noreorder
-    li v0, __NR_setregid
+    li $v0, __NR_setregid
     syscall
-    bnez a3, 1f
-    move a0, v0
-    j ra
+    bnez $a3, 1f
+    move $a0, $v0
+    j $ra
     nop
 1:
-    move t0, ra
-    bal     2f
+    move $t0, $ra
+    bal 2f
     nop
 2:
-    .cpsetup ra, t1, 2b
-    LA t9,__set_errno_internal
+    .cpsetup $ra, $t1, 2b
+    LA $t9, __set_errno_internal
     .cpreturn
-    j t9
-    move ra, t0
+    j $t9
+    move $ra, $t0
     .set pop
 END(setregid)
diff --git a/libc/arch-mips64/syscalls/setresgid.S b/libc/arch-mips64/syscalls/setresgid.S
index 90b2939..555e925 100644
--- a/libc/arch-mips64/syscalls/setresgid.S
+++ b/libc/arch-mips64/syscalls/setresgid.S
@@ -5,21 +5,21 @@
 ENTRY(setresgid)
     .set push
     .set noreorder
-    li v0, __NR_setresgid
+    li $v0, __NR_setresgid
     syscall
-    bnez a3, 1f
-    move a0, v0
-    j ra
+    bnez $a3, 1f
+    move $a0, $v0
+    j $ra
     nop
 1:
-    move t0, ra
-    bal     2f
+    move $t0, $ra
+    bal 2f
     nop
 2:
-    .cpsetup ra, t1, 2b
-    LA t9,__set_errno_internal
+    .cpsetup $ra, $t1, 2b
+    LA $t9, __set_errno_internal
     .cpreturn
-    j t9
-    move ra, t0
+    j $t9
+    move $ra, $t0
     .set pop
 END(setresgid)
diff --git a/libc/arch-mips64/syscalls/setresuid.S b/libc/arch-mips64/syscalls/setresuid.S
index 501ac5d..6884f38 100644
--- a/libc/arch-mips64/syscalls/setresuid.S
+++ b/libc/arch-mips64/syscalls/setresuid.S
@@ -5,21 +5,21 @@
 ENTRY(setresuid)
     .set push
     .set noreorder
-    li v0, __NR_setresuid
+    li $v0, __NR_setresuid
     syscall
-    bnez a3, 1f
-    move a0, v0
-    j ra
+    bnez $a3, 1f
+    move $a0, $v0
+    j $ra
     nop
 1:
-    move t0, ra
-    bal     2f
+    move $t0, $ra
+    bal 2f
     nop
 2:
-    .cpsetup ra, t1, 2b
-    LA t9,__set_errno_internal
+    .cpsetup $ra, $t1, 2b
+    LA $t9, __set_errno_internal
     .cpreturn
-    j t9
-    move ra, t0
+    j $t9
+    move $ra, $t0
     .set pop
 END(setresuid)
diff --git a/libc/arch-mips64/syscalls/setreuid.S b/libc/arch-mips64/syscalls/setreuid.S
index 1b3203c..4163765 100644
--- a/libc/arch-mips64/syscalls/setreuid.S
+++ b/libc/arch-mips64/syscalls/setreuid.S
@@ -5,21 +5,21 @@
 ENTRY(setreuid)
     .set push
     .set noreorder
-    li v0, __NR_setreuid
+    li $v0, __NR_setreuid
     syscall
-    bnez a3, 1f
-    move a0, v0
-    j ra
+    bnez $a3, 1f
+    move $a0, $v0
+    j $ra
     nop
 1:
-    move t0, ra
-    bal     2f
+    move $t0, $ra
+    bal 2f
     nop
 2:
-    .cpsetup ra, t1, 2b
-    LA t9,__set_errno_internal
+    .cpsetup $ra, $t1, 2b
+    LA $t9, __set_errno_internal
     .cpreturn
-    j t9
-    move ra, t0
+    j $t9
+    move $ra, $t0
     .set pop
 END(setreuid)
diff --git a/libc/arch-mips64/syscalls/setrlimit.S b/libc/arch-mips64/syscalls/setrlimit.S
index be6fdc3..5cc8a52 100644
--- a/libc/arch-mips64/syscalls/setrlimit.S
+++ b/libc/arch-mips64/syscalls/setrlimit.S
@@ -5,22 +5,22 @@
 ENTRY(setrlimit)
     .set push
     .set noreorder
-    li v0, __NR_setrlimit
+    li $v0, __NR_setrlimit
     syscall
-    bnez a3, 1f
-    move a0, v0
-    j ra
+    bnez $a3, 1f
+    move $a0, $v0
+    j $ra
     nop
 1:
-    move t0, ra
-    bal     2f
+    move $t0, $ra
+    bal 2f
     nop
 2:
-    .cpsetup ra, t1, 2b
-    LA t9,__set_errno_internal
+    .cpsetup $ra, $t1, 2b
+    LA $t9, __set_errno_internal
     .cpreturn
-    j t9
-    move ra, t0
+    j $t9
+    move $ra, $t0
     .set pop
 END(setrlimit)
 
diff --git a/libc/arch-mips64/syscalls/setsid.S b/libc/arch-mips64/syscalls/setsid.S
index 6d872d3..5422096 100644
--- a/libc/arch-mips64/syscalls/setsid.S
+++ b/libc/arch-mips64/syscalls/setsid.S
@@ -5,21 +5,21 @@
 ENTRY(setsid)
     .set push
     .set noreorder
-    li v0, __NR_setsid
+    li $v0, __NR_setsid
     syscall
-    bnez a3, 1f
-    move a0, v0
-    j ra
+    bnez $a3, 1f
+    move $a0, $v0
+    j $ra
     nop
 1:
-    move t0, ra
-    bal     2f
+    move $t0, $ra
+    bal 2f
     nop
 2:
-    .cpsetup ra, t1, 2b
-    LA t9,__set_errno_internal
+    .cpsetup $ra, $t1, 2b
+    LA $t9, __set_errno_internal
     .cpreturn
-    j t9
-    move ra, t0
+    j $t9
+    move $ra, $t0
     .set pop
 END(setsid)
diff --git a/libc/arch-mips64/syscalls/setsockopt.S b/libc/arch-mips64/syscalls/setsockopt.S
index b2fc736..8c3ce62 100644
--- a/libc/arch-mips64/syscalls/setsockopt.S
+++ b/libc/arch-mips64/syscalls/setsockopt.S
@@ -5,21 +5,21 @@
 ENTRY(setsockopt)
     .set push
     .set noreorder
-    li v0, __NR_setsockopt
+    li $v0, __NR_setsockopt
     syscall
-    bnez a3, 1f
-    move a0, v0
-    j ra
+    bnez $a3, 1f
+    move $a0, $v0
+    j $ra
     nop
 1:
-    move t0, ra
-    bal     2f
+    move $t0, $ra
+    bal 2f
     nop
 2:
-    .cpsetup ra, t1, 2b
-    LA t9,__set_errno_internal
+    .cpsetup $ra, $t1, 2b
+    LA $t9, __set_errno_internal
     .cpreturn
-    j t9
-    move ra, t0
+    j $t9
+    move $ra, $t0
     .set pop
 END(setsockopt)
diff --git a/libc/arch-mips64/syscalls/settimeofday.S b/libc/arch-mips64/syscalls/settimeofday.S
index 9f1acfe..9723dee 100644
--- a/libc/arch-mips64/syscalls/settimeofday.S
+++ b/libc/arch-mips64/syscalls/settimeofday.S
@@ -5,21 +5,21 @@
 ENTRY(settimeofday)
     .set push
     .set noreorder
-    li v0, __NR_settimeofday
+    li $v0, __NR_settimeofday
     syscall
-    bnez a3, 1f
-    move a0, v0
-    j ra
+    bnez $a3, 1f
+    move $a0, $v0
+    j $ra
     nop
 1:
-    move t0, ra
-    bal     2f
+    move $t0, $ra
+    bal 2f
     nop
 2:
-    .cpsetup ra, t1, 2b
-    LA t9,__set_errno_internal
+    .cpsetup $ra, $t1, 2b
+    LA $t9, __set_errno_internal
     .cpreturn
-    j t9
-    move ra, t0
+    j $t9
+    move $ra, $t0
     .set pop
 END(settimeofday)
diff --git a/libc/arch-mips64/syscalls/setuid.S b/libc/arch-mips64/syscalls/setuid.S
index dcd39ff..4ed7a7c 100644
--- a/libc/arch-mips64/syscalls/setuid.S
+++ b/libc/arch-mips64/syscalls/setuid.S
@@ -5,21 +5,21 @@
 ENTRY(setuid)
     .set push
     .set noreorder
-    li v0, __NR_setuid
+    li $v0, __NR_setuid
     syscall
-    bnez a3, 1f
-    move a0, v0
-    j ra
+    bnez $a3, 1f
+    move $a0, $v0
+    j $ra
     nop
 1:
-    move t0, ra
-    bal     2f
+    move $t0, $ra
+    bal 2f
     nop
 2:
-    .cpsetup ra, t1, 2b
-    LA t9,__set_errno_internal
+    .cpsetup $ra, $t1, 2b
+    LA $t9, __set_errno_internal
     .cpreturn
-    j t9
-    move ra, t0
+    j $t9
+    move $ra, $t0
     .set pop
 END(setuid)
diff --git a/libc/arch-mips64/syscalls/setxattr.S b/libc/arch-mips64/syscalls/setxattr.S
index 4a1b87a..d837b5e 100644
--- a/libc/arch-mips64/syscalls/setxattr.S
+++ b/libc/arch-mips64/syscalls/setxattr.S
@@ -5,21 +5,21 @@
 ENTRY(setxattr)
     .set push
     .set noreorder
-    li v0, __NR_setxattr
+    li $v0, __NR_setxattr
     syscall
-    bnez a3, 1f
-    move a0, v0
-    j ra
+    bnez $a3, 1f
+    move $a0, $v0
+    j $ra
     nop
 1:
-    move t0, ra
-    bal     2f
+    move $t0, $ra
+    bal 2f
     nop
 2:
-    .cpsetup ra, t1, 2b
-    LA t9,__set_errno_internal
+    .cpsetup $ra, $t1, 2b
+    LA $t9, __set_errno_internal
     .cpreturn
-    j t9
-    move ra, t0
+    j $t9
+    move $ra, $t0
     .set pop
 END(setxattr)
diff --git a/libc/arch-mips64/syscalls/shutdown.S b/libc/arch-mips64/syscalls/shutdown.S
index d654288..3a616bd 100644
--- a/libc/arch-mips64/syscalls/shutdown.S
+++ b/libc/arch-mips64/syscalls/shutdown.S
@@ -5,21 +5,21 @@
 ENTRY(shutdown)
     .set push
     .set noreorder
-    li v0, __NR_shutdown
+    li $v0, __NR_shutdown
     syscall
-    bnez a3, 1f
-    move a0, v0
-    j ra
+    bnez $a3, 1f
+    move $a0, $v0
+    j $ra
     nop
 1:
-    move t0, ra
-    bal     2f
+    move $t0, $ra
+    bal 2f
     nop
 2:
-    .cpsetup ra, t1, 2b
-    LA t9,__set_errno_internal
+    .cpsetup $ra, $t1, 2b
+    LA $t9, __set_errno_internal
     .cpreturn
-    j t9
-    move ra, t0
+    j $t9
+    move $ra, $t0
     .set pop
 END(shutdown)
diff --git a/libc/arch-mips64/syscalls/sigaltstack.S b/libc/arch-mips64/syscalls/sigaltstack.S
index 92778c1..13b539b 100644
--- a/libc/arch-mips64/syscalls/sigaltstack.S
+++ b/libc/arch-mips64/syscalls/sigaltstack.S
@@ -5,21 +5,21 @@
 ENTRY(sigaltstack)
     .set push
     .set noreorder
-    li v0, __NR_sigaltstack
+    li $v0, __NR_sigaltstack
     syscall
-    bnez a3, 1f
-    move a0, v0
-    j ra
+    bnez $a3, 1f
+    move $a0, $v0
+    j $ra
     nop
 1:
-    move t0, ra
-    bal     2f
+    move $t0, $ra
+    bal 2f
     nop
 2:
-    .cpsetup ra, t1, 2b
-    LA t9,__set_errno_internal
+    .cpsetup $ra, $t1, 2b
+    LA $t9, __set_errno_internal
     .cpreturn
-    j t9
-    move ra, t0
+    j $t9
+    move $ra, $t0
     .set pop
 END(sigaltstack)
diff --git a/libc/arch-mips64/syscalls/socketpair.S b/libc/arch-mips64/syscalls/socketpair.S
index 8fbf7a8..b95dabd 100644
--- a/libc/arch-mips64/syscalls/socketpair.S
+++ b/libc/arch-mips64/syscalls/socketpair.S
@@ -5,21 +5,21 @@
 ENTRY(socketpair)
     .set push
     .set noreorder
-    li v0, __NR_socketpair
+    li $v0, __NR_socketpair
     syscall
-    bnez a3, 1f
-    move a0, v0
-    j ra
+    bnez $a3, 1f
+    move $a0, $v0
+    j $ra
     nop
 1:
-    move t0, ra
-    bal     2f
+    move $t0, $ra
+    bal 2f
     nop
 2:
-    .cpsetup ra, t1, 2b
-    LA t9,__set_errno_internal
+    .cpsetup $ra, $t1, 2b
+    LA $t9, __set_errno_internal
     .cpreturn
-    j t9
-    move ra, t0
+    j $t9
+    move $ra, $t0
     .set pop
 END(socketpair)
diff --git a/libc/arch-mips64/syscalls/splice.S b/libc/arch-mips64/syscalls/splice.S
index ea745cf..9eae4d0 100644
--- a/libc/arch-mips64/syscalls/splice.S
+++ b/libc/arch-mips64/syscalls/splice.S
@@ -5,21 +5,21 @@
 ENTRY(splice)
     .set push
     .set noreorder
-    li v0, __NR_splice
+    li $v0, __NR_splice
     syscall
-    bnez a3, 1f
-    move a0, v0
-    j ra
+    bnez $a3, 1f
+    move $a0, $v0
+    j $ra
     nop
 1:
-    move t0, ra
-    bal     2f
+    move $t0, $ra
+    bal 2f
     nop
 2:
-    .cpsetup ra, t1, 2b
-    LA t9,__set_errno_internal
+    .cpsetup $ra, $t1, 2b
+    LA $t9, __set_errno_internal
     .cpreturn
-    j t9
-    move ra, t0
+    j $t9
+    move $ra, $t0
     .set pop
 END(splice)
diff --git a/libc/arch-mips64/syscalls/swapoff.S b/libc/arch-mips64/syscalls/swapoff.S
index 8c0048d..c70d1bc 100644
--- a/libc/arch-mips64/syscalls/swapoff.S
+++ b/libc/arch-mips64/syscalls/swapoff.S
@@ -5,21 +5,21 @@
 ENTRY(swapoff)
     .set push
     .set noreorder
-    li v0, __NR_swapoff
+    li $v0, __NR_swapoff
     syscall
-    bnez a3, 1f
-    move a0, v0
-    j ra
+    bnez $a3, 1f
+    move $a0, $v0
+    j $ra
     nop
 1:
-    move t0, ra
-    bal     2f
+    move $t0, $ra
+    bal 2f
     nop
 2:
-    .cpsetup ra, t1, 2b
-    LA t9,__set_errno_internal
+    .cpsetup $ra, $t1, 2b
+    LA $t9, __set_errno_internal
     .cpreturn
-    j t9
-    move ra, t0
+    j $t9
+    move $ra, $t0
     .set pop
 END(swapoff)
diff --git a/libc/arch-mips64/syscalls/swapon.S b/libc/arch-mips64/syscalls/swapon.S
index e8f6ff2..879c68e 100644
--- a/libc/arch-mips64/syscalls/swapon.S
+++ b/libc/arch-mips64/syscalls/swapon.S
@@ -5,21 +5,21 @@
 ENTRY(swapon)
     .set push
     .set noreorder
-    li v0, __NR_swapon
+    li $v0, __NR_swapon
     syscall
-    bnez a3, 1f
-    move a0, v0
-    j ra
+    bnez $a3, 1f
+    move $a0, $v0
+    j $ra
     nop
 1:
-    move t0, ra
-    bal     2f
+    move $t0, $ra
+    bal 2f
     nop
 2:
-    .cpsetup ra, t1, 2b
-    LA t9,__set_errno_internal
+    .cpsetup $ra, $t1, 2b
+    LA $t9, __set_errno_internal
     .cpreturn
-    j t9
-    move ra, t0
+    j $t9
+    move $ra, $t0
     .set pop
 END(swapon)
diff --git a/libc/arch-mips64/syscalls/symlinkat.S b/libc/arch-mips64/syscalls/symlinkat.S
index 592b8e2..2483993 100644
--- a/libc/arch-mips64/syscalls/symlinkat.S
+++ b/libc/arch-mips64/syscalls/symlinkat.S
@@ -5,21 +5,21 @@
 ENTRY(symlinkat)
     .set push
     .set noreorder
-    li v0, __NR_symlinkat
+    li $v0, __NR_symlinkat
     syscall
-    bnez a3, 1f
-    move a0, v0
-    j ra
+    bnez $a3, 1f
+    move $a0, $v0
+    j $ra
     nop
 1:
-    move t0, ra
-    bal     2f
+    move $t0, $ra
+    bal 2f
     nop
 2:
-    .cpsetup ra, t1, 2b
-    LA t9,__set_errno_internal
+    .cpsetup $ra, $t1, 2b
+    LA $t9, __set_errno_internal
     .cpreturn
-    j t9
-    move ra, t0
+    j $t9
+    move $ra, $t0
     .set pop
 END(symlinkat)
diff --git a/libc/arch-mips64/syscalls/sync.S b/libc/arch-mips64/syscalls/sync.S
index 8997c1b..61cc1a3 100644
--- a/libc/arch-mips64/syscalls/sync.S
+++ b/libc/arch-mips64/syscalls/sync.S
@@ -5,21 +5,21 @@
 ENTRY(sync)
     .set push
     .set noreorder
-    li v0, __NR_sync
+    li $v0, __NR_sync
     syscall
-    bnez a3, 1f
-    move a0, v0
-    j ra
+    bnez $a3, 1f
+    move $a0, $v0
+    j $ra
     nop
 1:
-    move t0, ra
-    bal     2f
+    move $t0, $ra
+    bal 2f
     nop
 2:
-    .cpsetup ra, t1, 2b
-    LA t9,__set_errno_internal
+    .cpsetup $ra, $t1, 2b
+    LA $t9, __set_errno_internal
     .cpreturn
-    j t9
-    move ra, t0
+    j $t9
+    move $ra, $t0
     .set pop
 END(sync)
diff --git a/libc/arch-mips64/syscalls/syncfs.S b/libc/arch-mips64/syscalls/syncfs.S
index 504ca4a..8eb2501 100644
--- a/libc/arch-mips64/syscalls/syncfs.S
+++ b/libc/arch-mips64/syscalls/syncfs.S
@@ -5,21 +5,21 @@
 ENTRY(syncfs)
     .set push
     .set noreorder
-    li v0, __NR_syncfs
+    li $v0, __NR_syncfs
     syscall
-    bnez a3, 1f
-    move a0, v0
-    j ra
+    bnez $a3, 1f
+    move $a0, $v0
+    j $ra
     nop
 1:
-    move t0, ra
-    bal     2f
+    move $t0, $ra
+    bal 2f
     nop
 2:
-    .cpsetup ra, t1, 2b
-    LA t9,__set_errno_internal
+    .cpsetup $ra, $t1, 2b
+    LA $t9, __set_errno_internal
     .cpreturn
-    j t9
-    move ra, t0
+    j $t9
+    move $ra, $t0
     .set pop
 END(syncfs)
diff --git a/libc/arch-mips64/syscalls/sysinfo.S b/libc/arch-mips64/syscalls/sysinfo.S
index a54e158..2c7acc7 100644
--- a/libc/arch-mips64/syscalls/sysinfo.S
+++ b/libc/arch-mips64/syscalls/sysinfo.S
@@ -5,21 +5,21 @@
 ENTRY(sysinfo)
     .set push
     .set noreorder
-    li v0, __NR_sysinfo
+    li $v0, __NR_sysinfo
     syscall
-    bnez a3, 1f
-    move a0, v0
-    j ra
+    bnez $a3, 1f
+    move $a0, $v0
+    j $ra
     nop
 1:
-    move t0, ra
-    bal     2f
+    move $t0, $ra
+    bal 2f
     nop
 2:
-    .cpsetup ra, t1, 2b
-    LA t9,__set_errno_internal
+    .cpsetup $ra, $t1, 2b
+    LA $t9, __set_errno_internal
     .cpreturn
-    j t9
-    move ra, t0
+    j $t9
+    move $ra, $t0
     .set pop
 END(sysinfo)
diff --git a/libc/arch-mips64/syscalls/tee.S b/libc/arch-mips64/syscalls/tee.S
index 99cf84b..cd60f0b 100644
--- a/libc/arch-mips64/syscalls/tee.S
+++ b/libc/arch-mips64/syscalls/tee.S
@@ -5,21 +5,21 @@
 ENTRY(tee)
     .set push
     .set noreorder
-    li v0, __NR_tee
+    li $v0, __NR_tee
     syscall
-    bnez a3, 1f
-    move a0, v0
-    j ra
+    bnez $a3, 1f
+    move $a0, $v0
+    j $ra
     nop
 1:
-    move t0, ra
-    bal     2f
+    move $t0, $ra
+    bal 2f
     nop
 2:
-    .cpsetup ra, t1, 2b
-    LA t9,__set_errno_internal
+    .cpsetup $ra, $t1, 2b
+    LA $t9, __set_errno_internal
     .cpreturn
-    j t9
-    move ra, t0
+    j $t9
+    move $ra, $t0
     .set pop
 END(tee)
diff --git a/libc/arch-mips64/syscalls/tgkill.S b/libc/arch-mips64/syscalls/tgkill.S
index f37f792..86d7d4b 100644
--- a/libc/arch-mips64/syscalls/tgkill.S
+++ b/libc/arch-mips64/syscalls/tgkill.S
@@ -5,21 +5,21 @@
 ENTRY(tgkill)
     .set push
     .set noreorder
-    li v0, __NR_tgkill
+    li $v0, __NR_tgkill
     syscall
-    bnez a3, 1f
-    move a0, v0
-    j ra
+    bnez $a3, 1f
+    move $a0, $v0
+    j $ra
     nop
 1:
-    move t0, ra
-    bal     2f
+    move $t0, $ra
+    bal 2f
     nop
 2:
-    .cpsetup ra, t1, 2b
-    LA t9,__set_errno_internal
+    .cpsetup $ra, $t1, 2b
+    LA $t9, __set_errno_internal
     .cpreturn
-    j t9
-    move ra, t0
+    j $t9
+    move $ra, $t0
     .set pop
 END(tgkill)
diff --git a/libc/arch-mips64/syscalls/timerfd_create.S b/libc/arch-mips64/syscalls/timerfd_create.S
index 0e53a15..8086217 100644
--- a/libc/arch-mips64/syscalls/timerfd_create.S
+++ b/libc/arch-mips64/syscalls/timerfd_create.S
@@ -5,21 +5,21 @@
 ENTRY(timerfd_create)
     .set push
     .set noreorder
-    li v0, __NR_timerfd_create
+    li $v0, __NR_timerfd_create
     syscall
-    bnez a3, 1f
-    move a0, v0
-    j ra
+    bnez $a3, 1f
+    move $a0, $v0
+    j $ra
     nop
 1:
-    move t0, ra
-    bal     2f
+    move $t0, $ra
+    bal 2f
     nop
 2:
-    .cpsetup ra, t1, 2b
-    LA t9,__set_errno_internal
+    .cpsetup $ra, $t1, 2b
+    LA $t9, __set_errno_internal
     .cpreturn
-    j t9
-    move ra, t0
+    j $t9
+    move $ra, $t0
     .set pop
 END(timerfd_create)
diff --git a/libc/arch-mips64/syscalls/timerfd_gettime.S b/libc/arch-mips64/syscalls/timerfd_gettime.S
index 26d6832..4b17e12 100644
--- a/libc/arch-mips64/syscalls/timerfd_gettime.S
+++ b/libc/arch-mips64/syscalls/timerfd_gettime.S
@@ -5,21 +5,21 @@
 ENTRY(timerfd_gettime)
     .set push
     .set noreorder
-    li v0, __NR_timerfd_gettime
+    li $v0, __NR_timerfd_gettime
     syscall
-    bnez a3, 1f
-    move a0, v0
-    j ra
+    bnez $a3, 1f
+    move $a0, $v0
+    j $ra
     nop
 1:
-    move t0, ra
-    bal     2f
+    move $t0, $ra
+    bal 2f
     nop
 2:
-    .cpsetup ra, t1, 2b
-    LA t9,__set_errno_internal
+    .cpsetup $ra, $t1, 2b
+    LA $t9, __set_errno_internal
     .cpreturn
-    j t9
-    move ra, t0
+    j $t9
+    move $ra, $t0
     .set pop
 END(timerfd_gettime)
diff --git a/libc/arch-mips64/syscalls/timerfd_settime.S b/libc/arch-mips64/syscalls/timerfd_settime.S
index b06290e..51c8cd7 100644
--- a/libc/arch-mips64/syscalls/timerfd_settime.S
+++ b/libc/arch-mips64/syscalls/timerfd_settime.S
@@ -5,21 +5,21 @@
 ENTRY(timerfd_settime)
     .set push
     .set noreorder
-    li v0, __NR_timerfd_settime
+    li $v0, __NR_timerfd_settime
     syscall
-    bnez a3, 1f
-    move a0, v0
-    j ra
+    bnez $a3, 1f
+    move $a0, $v0
+    j $ra
     nop
 1:
-    move t0, ra
-    bal     2f
+    move $t0, $ra
+    bal 2f
     nop
 2:
-    .cpsetup ra, t1, 2b
-    LA t9,__set_errno_internal
+    .cpsetup $ra, $t1, 2b
+    LA $t9, __set_errno_internal
     .cpreturn
-    j t9
-    move ra, t0
+    j $t9
+    move $ra, $t0
     .set pop
 END(timerfd_settime)
diff --git a/libc/arch-mips64/syscalls/times.S b/libc/arch-mips64/syscalls/times.S
index fa7f64f..5922b67 100644
--- a/libc/arch-mips64/syscalls/times.S
+++ b/libc/arch-mips64/syscalls/times.S
@@ -5,21 +5,21 @@
 ENTRY(times)
     .set push
     .set noreorder
-    li v0, __NR_times
+    li $v0, __NR_times
     syscall
-    bnez a3, 1f
-    move a0, v0
-    j ra
+    bnez $a3, 1f
+    move $a0, $v0
+    j $ra
     nop
 1:
-    move t0, ra
-    bal     2f
+    move $t0, $ra
+    bal 2f
     nop
 2:
-    .cpsetup ra, t1, 2b
-    LA t9,__set_errno_internal
+    .cpsetup $ra, $t1, 2b
+    LA $t9, __set_errno_internal
     .cpreturn
-    j t9
-    move ra, t0
+    j $t9
+    move $ra, $t0
     .set pop
 END(times)
diff --git a/libc/arch-mips64/syscalls/truncate.S b/libc/arch-mips64/syscalls/truncate.S
index b832796..a23223b 100644
--- a/libc/arch-mips64/syscalls/truncate.S
+++ b/libc/arch-mips64/syscalls/truncate.S
@@ -5,22 +5,22 @@
 ENTRY(truncate)
     .set push
     .set noreorder
-    li v0, __NR_truncate
+    li $v0, __NR_truncate
     syscall
-    bnez a3, 1f
-    move a0, v0
-    j ra
+    bnez $a3, 1f
+    move $a0, $v0
+    j $ra
     nop
 1:
-    move t0, ra
-    bal     2f
+    move $t0, $ra
+    bal 2f
     nop
 2:
-    .cpsetup ra, t1, 2b
-    LA t9,__set_errno_internal
+    .cpsetup $ra, $t1, 2b
+    LA $t9, __set_errno_internal
     .cpreturn
-    j t9
-    move ra, t0
+    j $t9
+    move $ra, $t0
     .set pop
 END(truncate)
 
diff --git a/libc/arch-mips64/syscalls/umask.S b/libc/arch-mips64/syscalls/umask.S
index 9349030..ca0ab49 100644
--- a/libc/arch-mips64/syscalls/umask.S
+++ b/libc/arch-mips64/syscalls/umask.S
@@ -5,21 +5,21 @@
 ENTRY(umask)
     .set push
     .set noreorder
-    li v0, __NR_umask
+    li $v0, __NR_umask
     syscall
-    bnez a3, 1f
-    move a0, v0
-    j ra
+    bnez $a3, 1f
+    move $a0, $v0
+    j $ra
     nop
 1:
-    move t0, ra
-    bal     2f
+    move $t0, $ra
+    bal 2f
     nop
 2:
-    .cpsetup ra, t1, 2b
-    LA t9,__set_errno_internal
+    .cpsetup $ra, $t1, 2b
+    LA $t9, __set_errno_internal
     .cpreturn
-    j t9
-    move ra, t0
+    j $t9
+    move $ra, $t0
     .set pop
 END(umask)
diff --git a/libc/arch-mips64/syscalls/umount2.S b/libc/arch-mips64/syscalls/umount2.S
index cc9ad16..45d5c2e 100644
--- a/libc/arch-mips64/syscalls/umount2.S
+++ b/libc/arch-mips64/syscalls/umount2.S
@@ -5,21 +5,21 @@
 ENTRY(umount2)
     .set push
     .set noreorder
-    li v0, __NR_umount2
+    li $v0, __NR_umount2
     syscall
-    bnez a3, 1f
-    move a0, v0
-    j ra
+    bnez $a3, 1f
+    move $a0, $v0
+    j $ra
     nop
 1:
-    move t0, ra
-    bal     2f
+    move $t0, $ra
+    bal 2f
     nop
 2:
-    .cpsetup ra, t1, 2b
-    LA t9,__set_errno_internal
+    .cpsetup $ra, $t1, 2b
+    LA $t9, __set_errno_internal
     .cpreturn
-    j t9
-    move ra, t0
+    j $t9
+    move $ra, $t0
     .set pop
 END(umount2)
diff --git a/libc/arch-mips64/syscalls/uname.S b/libc/arch-mips64/syscalls/uname.S
index 16157da..3385cfa 100644
--- a/libc/arch-mips64/syscalls/uname.S
+++ b/libc/arch-mips64/syscalls/uname.S
@@ -5,21 +5,21 @@
 ENTRY(uname)
     .set push
     .set noreorder
-    li v0, __NR_uname
+    li $v0, __NR_uname
     syscall
-    bnez a3, 1f
-    move a0, v0
-    j ra
+    bnez $a3, 1f
+    move $a0, $v0
+    j $ra
     nop
 1:
-    move t0, ra
-    bal     2f
+    move $t0, $ra
+    bal 2f
     nop
 2:
-    .cpsetup ra, t1, 2b
-    LA t9,__set_errno_internal
+    .cpsetup $ra, $t1, 2b
+    LA $t9, __set_errno_internal
     .cpreturn
-    j t9
-    move ra, t0
+    j $t9
+    move $ra, $t0
     .set pop
 END(uname)
diff --git a/libc/arch-mips64/syscalls/unlinkat.S b/libc/arch-mips64/syscalls/unlinkat.S
index 4b11679..030f643 100644
--- a/libc/arch-mips64/syscalls/unlinkat.S
+++ b/libc/arch-mips64/syscalls/unlinkat.S
@@ -5,21 +5,21 @@
 ENTRY(unlinkat)
     .set push
     .set noreorder
-    li v0, __NR_unlinkat
+    li $v0, __NR_unlinkat
     syscall
-    bnez a3, 1f
-    move a0, v0
-    j ra
+    bnez $a3, 1f
+    move $a0, $v0
+    j $ra
     nop
 1:
-    move t0, ra
-    bal     2f
+    move $t0, $ra
+    bal 2f
     nop
 2:
-    .cpsetup ra, t1, 2b
-    LA t9,__set_errno_internal
+    .cpsetup $ra, $t1, 2b
+    LA $t9, __set_errno_internal
     .cpreturn
-    j t9
-    move ra, t0
+    j $t9
+    move $ra, $t0
     .set pop
 END(unlinkat)
diff --git a/libc/arch-mips64/syscalls/unshare.S b/libc/arch-mips64/syscalls/unshare.S
index 2c82fea..e58a7fc 100644
--- a/libc/arch-mips64/syscalls/unshare.S
+++ b/libc/arch-mips64/syscalls/unshare.S
@@ -5,21 +5,21 @@
 ENTRY(unshare)
     .set push
     .set noreorder
-    li v0, __NR_unshare
+    li $v0, __NR_unshare
     syscall
-    bnez a3, 1f
-    move a0, v0
-    j ra
+    bnez $a3, 1f
+    move $a0, $v0
+    j $ra
     nop
 1:
-    move t0, ra
-    bal     2f
+    move $t0, $ra
+    bal 2f
     nop
 2:
-    .cpsetup ra, t1, 2b
-    LA t9,__set_errno_internal
+    .cpsetup $ra, $t1, 2b
+    LA $t9, __set_errno_internal
     .cpreturn
-    j t9
-    move ra, t0
+    j $t9
+    move $ra, $t0
     .set pop
 END(unshare)
diff --git a/libc/arch-mips64/syscalls/utimensat.S b/libc/arch-mips64/syscalls/utimensat.S
index 48da938..a524baa 100644
--- a/libc/arch-mips64/syscalls/utimensat.S
+++ b/libc/arch-mips64/syscalls/utimensat.S
@@ -5,21 +5,21 @@
 ENTRY(utimensat)
     .set push
     .set noreorder
-    li v0, __NR_utimensat
+    li $v0, __NR_utimensat
     syscall
-    bnez a3, 1f
-    move a0, v0
-    j ra
+    bnez $a3, 1f
+    move $a0, $v0
+    j $ra
     nop
 1:
-    move t0, ra
-    bal     2f
+    move $t0, $ra
+    bal 2f
     nop
 2:
-    .cpsetup ra, t1, 2b
-    LA t9,__set_errno_internal
+    .cpsetup $ra, $t1, 2b
+    LA $t9, __set_errno_internal
     .cpreturn
-    j t9
-    move ra, t0
+    j $t9
+    move $ra, $t0
     .set pop
 END(utimensat)
diff --git a/libc/arch-mips64/syscalls/vmsplice.S b/libc/arch-mips64/syscalls/vmsplice.S
index 3bcae74..5e97d86 100644
--- a/libc/arch-mips64/syscalls/vmsplice.S
+++ b/libc/arch-mips64/syscalls/vmsplice.S
@@ -5,21 +5,21 @@
 ENTRY(vmsplice)
     .set push
     .set noreorder
-    li v0, __NR_vmsplice
+    li $v0, __NR_vmsplice
     syscall
-    bnez a3, 1f
-    move a0, v0
-    j ra
+    bnez $a3, 1f
+    move $a0, $v0
+    j $ra
     nop
 1:
-    move t0, ra
-    bal     2f
+    move $t0, $ra
+    bal 2f
     nop
 2:
-    .cpsetup ra, t1, 2b
-    LA t9,__set_errno_internal
+    .cpsetup $ra, $t1, 2b
+    LA $t9, __set_errno_internal
     .cpreturn
-    j t9
-    move ra, t0
+    j $t9
+    move $ra, $t0
     .set pop
 END(vmsplice)
diff --git a/libc/arch-mips64/syscalls/wait4.S b/libc/arch-mips64/syscalls/wait4.S
index f9c3974..33b0e61 100644
--- a/libc/arch-mips64/syscalls/wait4.S
+++ b/libc/arch-mips64/syscalls/wait4.S
@@ -5,21 +5,21 @@
 ENTRY(wait4)
     .set push
     .set noreorder
-    li v0, __NR_wait4
+    li $v0, __NR_wait4
     syscall
-    bnez a3, 1f
-    move a0, v0
-    j ra
+    bnez $a3, 1f
+    move $a0, $v0
+    j $ra
     nop
 1:
-    move t0, ra
-    bal     2f
+    move $t0, $ra
+    bal 2f
     nop
 2:
-    .cpsetup ra, t1, 2b
-    LA t9,__set_errno_internal
+    .cpsetup $ra, $t1, 2b
+    LA $t9, __set_errno_internal
     .cpreturn
-    j t9
-    move ra, t0
+    j $t9
+    move $ra, $t0
     .set pop
 END(wait4)
diff --git a/libc/arch-mips64/syscalls/write.S b/libc/arch-mips64/syscalls/write.S
index ef9b19e..0499094 100644
--- a/libc/arch-mips64/syscalls/write.S
+++ b/libc/arch-mips64/syscalls/write.S
@@ -5,21 +5,21 @@
 ENTRY(write)
     .set push
     .set noreorder
-    li v0, __NR_write
+    li $v0, __NR_write
     syscall
-    bnez a3, 1f
-    move a0, v0
-    j ra
+    bnez $a3, 1f
+    move $a0, $v0
+    j $ra
     nop
 1:
-    move t0, ra
-    bal     2f
+    move $t0, $ra
+    bal 2f
     nop
 2:
-    .cpsetup ra, t1, 2b
-    LA t9,__set_errno_internal
+    .cpsetup $ra, $t1, 2b
+    LA $t9, __set_errno_internal
     .cpreturn
-    j t9
-    move ra, t0
+    j $t9
+    move $ra, $t0
     .set pop
 END(write)
diff --git a/libc/arch-mips64/syscalls/writev.S b/libc/arch-mips64/syscalls/writev.S
index d103d71..5054af3 100644
--- a/libc/arch-mips64/syscalls/writev.S
+++ b/libc/arch-mips64/syscalls/writev.S
@@ -5,21 +5,21 @@
 ENTRY(writev)
     .set push
     .set noreorder
-    li v0, __NR_writev
+    li $v0, __NR_writev
     syscall
-    bnez a3, 1f
-    move a0, v0
-    j ra
+    bnez $a3, 1f
+    move $a0, $v0
+    j $ra
     nop
 1:
-    move t0, ra
-    bal     2f
+    move $t0, $ra
+    bal 2f
     nop
 2:
-    .cpsetup ra, t1, 2b
-    LA t9,__set_errno_internal
+    .cpsetup $ra, $t1, 2b
+    LA $t9, __set_errno_internal
     .cpreturn
-    j t9
-    move ra, t0
+    j $t9
+    move $ra, $t0
     .set pop
 END(writev)
diff --git a/libc/arch-x86/bionic/setjmp.S b/libc/arch-x86/bionic/setjmp.S
index efb6459..6e6c365 100644
--- a/libc/arch-x86/bionic/setjmp.S
+++ b/libc/arch-x86/bionic/setjmp.S
@@ -78,18 +78,21 @@
 .endm
 
 ENTRY(setjmp)
+__BIONIC_WEAK_ASM_FOR_NATIVE_BRIDGE(setjmp)
   movl 4(%esp),%ecx
   mov $1,%eax
   jmp .L_sigsetjmp
 END(setjmp)
 
 ENTRY(_setjmp)
+__BIONIC_WEAK_ASM_FOR_NATIVE_BRIDGE(_setjmp)
   movl 4(%esp),%ecx
   movl $0,%eax
   jmp .L_sigsetjmp
 END(_setjmp)
 
 ENTRY(sigsetjmp)
+__BIONIC_WEAK_ASM_FOR_NATIVE_BRIDGE(sigsetjmp)
   movl 4(%esp),%ecx
   movl 8(%esp),%eax
 
@@ -142,6 +145,7 @@
 END(sigsetjmp)
 
 ENTRY(siglongjmp)
+__BIONIC_WEAK_ASM_FOR_NATIVE_BRIDGE(siglongjmp)
   movl 4(%esp),%edx
 
   // Check the checksum before doing anything.
@@ -205,4 +209,6 @@
 END(siglongjmp)
 
 ALIAS_SYMBOL(longjmp, siglongjmp)
+__BIONIC_WEAK_ASM_FOR_NATIVE_BRIDGE(longjmp)
 ALIAS_SYMBOL(_longjmp, siglongjmp)
+__BIONIC_WEAK_ASM_FOR_NATIVE_BRIDGE(_longjmp)
diff --git a/libc/arch-x86/bionic/vfork.S b/libc/arch-x86/bionic/vfork.S
index 5c71b8d..79d7899 100644
--- a/libc/arch-x86/bionic/vfork.S
+++ b/libc/arch-x86/bionic/vfork.S
@@ -31,6 +31,7 @@
 // This custom code preserves the return address across the system call.
 
 ENTRY(vfork)
+__BIONIC_WEAK_ASM_FOR_NATIVE_BRIDGE(vfork)
   popl    %ecx  // Grab the return address.
   .cfi_adjust_cfa_offset 4
   .cfi_rel_offset ecx, 0
diff --git a/libc/arch-x86/include/machine/setjmp.h b/libc/arch-x86/include/machine/setjmp.h
deleted file mode 100644
index ded095d..0000000
--- a/libc/arch-x86/include/machine/setjmp.h
+++ /dev/null
@@ -1,8 +0,0 @@
-/*	$OpenBSD: setjmp.h,v 1.2 2000/08/05 22:07:32 niklas Exp $	*/
-/*	$NetBSD: setjmp.h,v 1.1 1994/12/20 10:36:43 cgd Exp $	*/
-
-/*
- * machine/setjmp.h: machine dependent setjmp-related information.
- */
-
-#define	_JBLEN	10		/* size, in longs, of a jmp_buf */
diff --git a/libc/arch-x86/syscalls/getrandom.S b/libc/arch-x86/syscalls/getrandom.S
new file mode 100644
index 0000000..2e8ebc9
--- /dev/null
+++ b/libc/arch-x86/syscalls/getrandom.S
@@ -0,0 +1,39 @@
+/* Generated by gensyscalls.py. Do not edit. */
+
+#include <private/bionic_asm.h>
+
+ENTRY(getrandom)
+    pushl   %ebx
+    .cfi_def_cfa_offset 8
+    .cfi_rel_offset ebx, 0
+    pushl   %ecx
+    .cfi_adjust_cfa_offset 4
+    .cfi_rel_offset ecx, 0
+    pushl   %edx
+    .cfi_adjust_cfa_offset 4
+    .cfi_rel_offset edx, 0
+
+    call    __kernel_syscall
+    pushl   %eax
+    .cfi_adjust_cfa_offset 4
+    .cfi_rel_offset eax, 0
+
+    mov     20(%esp), %ebx
+    mov     24(%esp), %ecx
+    mov     28(%esp), %edx
+    movl    $__NR_getrandom, %eax
+    call    *(%esp)
+    addl    $4, %esp
+
+    cmpl    $-MAX_ERRNO, %eax
+    jb      1f
+    negl    %eax
+    pushl   %eax
+    call    __set_errno_internal
+    addl    $4, %esp
+1:
+    popl    %edx
+    popl    %ecx
+    popl    %ebx
+    ret
+END(getrandom)
diff --git a/libc/arch-x86_64/bionic/setjmp.S b/libc/arch-x86_64/bionic/setjmp.S
index 34b4365..1d34561 100644
--- a/libc/arch-x86_64/bionic/setjmp.S
+++ b/libc/arch-x86_64/bionic/setjmp.S
@@ -91,17 +91,20 @@
 .endm
 
 ENTRY(setjmp)
+__BIONIC_WEAK_ASM_FOR_NATIVE_BRIDGE(setjmp)
   movl $1,%esi
   jmp PIC_PLT(sigsetjmp)
 END(setjmp)
 
 ENTRY(_setjmp)
+__BIONIC_WEAK_ASM_FOR_NATIVE_BRIDGE(_setjmp)
   movl $0,%esi
   jmp PIC_PLT(sigsetjmp)
 END(_setjmp)
 
 // int sigsetjmp(sigjmp_buf env, int save_signal_mask);
 ENTRY(sigsetjmp)
+__BIONIC_WEAK_ASM_FOR_NATIVE_BRIDGE(sigsetjmp)
   pushq %rdi
   movq %rsi,%rdi
   call PIC_PLT(__bionic_setjmp_cookie_get)
@@ -148,6 +151,7 @@
 
 // void siglongjmp(sigjmp_buf env, int value);
 ENTRY(siglongjmp)
+__BIONIC_WEAK_ASM_FOR_NATIVE_BRIDGE(siglongjmp)
   movq %rdi,%r12
   pushq %rsi // Push 'value'.
 
@@ -206,4 +210,6 @@
 END(siglongjmp)
 
 ALIAS_SYMBOL(longjmp, siglongjmp)
+__BIONIC_WEAK_ASM_FOR_NATIVE_BRIDGE(longjmp)
 ALIAS_SYMBOL(_longjmp, siglongjmp)
+__BIONIC_WEAK_ASM_FOR_NATIVE_BRIDGE(_longjmp)
diff --git a/libc/arch-x86_64/bionic/vfork.S b/libc/arch-x86_64/bionic/vfork.S
index 3b32c66..ce96a8c 100644
--- a/libc/arch-x86_64/bionic/vfork.S
+++ b/libc/arch-x86_64/bionic/vfork.S
@@ -31,6 +31,7 @@
 // This custom code preserves the return address across the system call.
 
 ENTRY(vfork)
+__BIONIC_WEAK_ASM_FOR_NATIVE_BRIDGE(vfork)
   popq    %rdi  // Grab the return address.
 
   // __get_tls()[TLS_SLOT_THREAD_ID]->cached_pid_ = 0
diff --git a/libc/arch-x86_64/include/machine/setjmp.h b/libc/arch-x86_64/include/machine/setjmp.h
deleted file mode 100644
index 46ddd4b..0000000
--- a/libc/arch-x86_64/include/machine/setjmp.h
+++ /dev/null
@@ -1,4 +0,0 @@
-/*	$OpenBSD: setjmp.h,v 1.1 2004/01/28 01:39:39 mickey Exp $	*/
-/*	$NetBSD: setjmp.h,v 1.1 2003/04/26 18:39:47 fvdl Exp $	*/
-
-#define	_JBLEN	11		/* size, in longs, of a jmp_buf */
diff --git a/libc/arch-x86_64/syscalls/getrandom.S b/libc/arch-x86_64/syscalls/getrandom.S
new file mode 100644
index 0000000..c5e44a9
--- /dev/null
+++ b/libc/arch-x86_64/syscalls/getrandom.S
@@ -0,0 +1,15 @@
+/* Generated by gensyscalls.py. Do not edit. */
+
+#include <private/bionic_asm.h>
+
+ENTRY(getrandom)
+    movl    $__NR_getrandom, %eax
+    syscall
+    cmpq    $-MAX_ERRNO, %rax
+    jb      1f
+    negl    %eax
+    movl    %eax, %edi
+    call    __set_errno_internal
+1:
+    ret
+END(getrandom)
diff --git a/libc/async_safe/async_safe_log.cpp b/libc/async_safe/async_safe_log.cpp
index 78f62bd..d5aad16 100644
--- a/libc/async_safe/async_safe_log.cpp
+++ b/libc/async_safe/async_safe_log.cpp
@@ -47,6 +47,7 @@
 #include <async_safe/log.h>
 
 #include "private/CachedProperty.h"
+#include "private/ErrnoRestorer.h"
 #include "private/ScopedPthreadMutexLocker.h"
 
 // Must be kept in sync with frameworks/base/core/java/android/util/EventLog.java.
@@ -508,6 +509,7 @@
 }
 
 int async_safe_format_log_va_list(int priority, const char* tag, const char* format, va_list args) {
+  ErrnoRestorer errno_restorer;
   char buffer[1024];
   BufferOutputStream os(buffer, sizeof(buffer));
   out_vformat(os, format, args);
diff --git a/libc/async_safe/include/async_safe/log.h b/libc/async_safe/include/async_safe/log.h
index 2f54742..10833e4 100644
--- a/libc/async_safe/include/async_safe/log.h
+++ b/libc/async_safe/include/async_safe/log.h
@@ -92,7 +92,7 @@
 
 int async_safe_format_fd(int fd, const char* format , ...) __printflike(2, 3);
 int async_safe_format_log(int pri, const char* tag, const char* fmt, ...) __printflike(3, 4);
-int async_safe_format_log_va_list( int pri, const char* tag, const char* fmt, va_list ap);
+int async_safe_format_log_va_list(int pri, const char* tag, const char* fmt, va_list ap);
 int async_safe_write_log(int pri, const char* tag, const char* msg);
 
 #define CHECK(predicate) \
diff --git a/libc/bionic/__cxa_thread_atexit_impl.cpp b/libc/bionic/__cxa_thread_atexit_impl.cpp
index 6284b12..f687fd1 100644
--- a/libc/bionic/__cxa_thread_atexit_impl.cpp
+++ b/libc/bionic/__cxa_thread_atexit_impl.cpp
@@ -15,6 +15,8 @@
  */
 #include <sys/cdefs.h>
 
+#include <private/bionic_defs.h>
+
 #include "pthread_internal.h"
 
 class thread_local_dtor {
@@ -25,7 +27,10 @@
   thread_local_dtor* next;
 };
 
-extern "C" int __cxa_thread_atexit_impl(void (*func) (void *), void *arg, void *dso_handle) {
+extern "C" int __cxa_thread_atexit_impl(void (*func) (void *), void *arg, void *dso_handle);
+
+__BIONIC_WEAK_FOR_NATIVE_BRIDGE
+int __cxa_thread_atexit_impl(void (*func) (void *), void *arg, void *dso_handle) {
   thread_local_dtor* dtor = new thread_local_dtor();
 
   dtor->func = func;
diff --git a/libc/bionic/__libc_init_main_thread.cpp b/libc/bionic/__libc_init_main_thread.cpp
index 9cbff11..efa7dee 100644
--- a/libc/bionic/__libc_init_main_thread.cpp
+++ b/libc/bionic/__libc_init_main_thread.cpp
@@ -31,6 +31,7 @@
 #include "private/KernelArgumentBlock.h"
 #include "private/bionic_arc4random.h"
 #include "private/bionic_auxv.h"
+#include "private/bionic_defs.h"
 #include "private/bionic_globals.h"
 #include "private/bionic_ssp.h"
 #include "pthread_internal.h"
@@ -58,6 +59,7 @@
 // -fno-stack-protector because it's responsible for setting up the main
 // thread's TLS (which stack protector relies on).
 
+__BIONIC_WEAK_FOR_NATIVE_BRIDGE
 void __libc_init_main_thread(KernelArgumentBlock& args) {
   __libc_auxv = args.auxv;
 #if defined(__i386__)
@@ -83,10 +85,14 @@
   // thread's stack rather than on the heap.
   // The main thread has no mmap allocated space for stack or pthread_internal_t.
   main_thread.mmap_size = 0;
+
   pthread_attr_init(&main_thread.attr);
-  main_thread.attr.guard_size = 0; // The main thread has no guard page.
-  main_thread.attr.stack_size = 0; // User code should never see this; we'll compute it when asked.
-  // TODO: the main thread's sched_policy and sched_priority need to be queried.
+  // We don't want to explicitly set the main thread's scheduler attributes (http://b/68328561).
+  pthread_attr_setinheritsched(&main_thread.attr, PTHREAD_INHERIT_SCHED);
+  // The main thread has no guard page.
+  pthread_attr_setguardsize(&main_thread.attr, 0);
+  // User code should never see this; we'll compute it when asked.
+  pthread_attr_setstacksize(&main_thread.attr, 0);
 
   // The TLS stack guard is set from the global, so ensure that we've initialized the global
   // before we initialize the TLS. Dynamic executables will initialize their copy of the global
diff --git a/libc/bionic/android_set_abort_message.cpp b/libc/bionic/android_set_abort_message.cpp
index 2a11613..268c4f3 100644
--- a/libc/bionic/android_set_abort_message.cpp
+++ b/libc/bionic/android_set_abort_message.cpp
@@ -29,8 +29,10 @@
 #include <android/set_abort_message.h>
 
 #include <pthread.h>
+#include <string.h>
 #include <sys/mman.h>
 
+#include "private/bionic_defs.h"
 #include "private/ScopedPthreadMutexLocker.h"
 
 static pthread_mutex_t g_abort_msg_lock = PTHREAD_MUTEX_INITIALIZER;
@@ -42,6 +44,7 @@
 
 abort_msg_t** __abort_message_ptr; // Accessible to __libc_init_common.
 
+__BIONIC_WEAK_FOR_NATIVE_BRIDGE
 void android_set_abort_message(const char* msg) {
   ScopedPthreadMutexLocker locker(&g_abort_msg_lock);
 
diff --git a/libc/bionic/bionic_arc4random.cpp b/libc/bionic/bionic_arc4random.cpp
index a339900..391eb0c 100644
--- a/libc/bionic/bionic_arc4random.cpp
+++ b/libc/bionic/bionic_arc4random.cpp
@@ -31,6 +31,7 @@
 #include <errno.h>
 #include <stdatomic.h>
 #include <stdlib.h>
+#include <string.h>
 #include <sys/auxv.h>
 #include <unistd.h>
 
diff --git a/libc/bionic/clone.cpp b/libc/bionic/clone.cpp
index d7ce37f..b895305 100644
--- a/libc/bionic/clone.cpp
+++ b/libc/bionic/clone.cpp
@@ -34,11 +34,16 @@
 
 #include "pthread_internal.h"
 
+#include "private/bionic_defs.h"
+#include "private/bionic_macros.h"
+
 extern "C" pid_t __bionic_clone(uint32_t flags, void* child_stack, int* parent_tid, void* tls, int* child_tid, int (*fn)(void*), void* arg);
 extern "C" __noreturn void __exit(int status);
 
 // Called from the __bionic_clone assembler to call the thread function then exit.
 extern "C" __LIBC_HIDDEN__ void __start_thread(int (*fn)(void*), void* arg) {
+  BIONIC_STOP_UNWIND;
+
   pthread_internal_t* self = __get_thread();
   if (self && self->tid == -1) {
     self->tid = syscall(__NR_gettid);
@@ -48,10 +53,11 @@
   __exit(status);
 }
 
+__BIONIC_WEAK_FOR_NATIVE_BRIDGE
 int clone(int (*fn)(void*), void* child_stack, int flags, void* arg, ...) {
-  int* parent_tid = NULL;
-  void* new_tls = NULL;
-  int* child_tid = NULL;
+  int* parent_tid = nullptr;
+  void* new_tls = nullptr;
+  int* child_tid = nullptr;
 
   if (fn != nullptr && child_stack == nullptr) {
     errno = EINVAL;
diff --git a/libc/bionic/dirent.cpp b/libc/bionic/dirent.cpp
index 6fd3842..37a2fa7 100644
--- a/libc/bionic/dirent.cpp
+++ b/libc/bionic/dirent.cpp
@@ -36,6 +36,7 @@
 #include <sys/types.h>
 #include <unistd.h>
 
+#include "private/bionic_fortify.h"
 #include "private/ErrnoRestorer.h"
 #include "private/ScopedPthreadMutexLocker.h"
 
@@ -56,6 +57,8 @@
   long current_pos_;
 };
 
+#define CHECK_DIR(d) if (d == nullptr) __fortify_fatal("%s: null DIR*", __FUNCTION__)
+
 static DIR* __allocate_DIR(int fd) {
   DIR* d = reinterpret_cast<DIR*>(malloc(sizeof(DIR)));
   if (d == NULL) {
@@ -69,8 +72,9 @@
   return d;
 }
 
-int dirfd(DIR* dirp) {
-  return dirp->fd_;
+int dirfd(DIR* d) {
+  CHECK_DIR(d);
+  return d->fd_;
 }
 
 DIR* fdopendir(int fd) {
@@ -93,6 +97,7 @@
 }
 
 static bool __fill_DIR(DIR* d) {
+  CHECK_DIR(d);
   int rc = TEMP_FAILURE_RETRY(__getdents64(d->fd_, d->buff_, sizeof(d->buff_)));
   if (rc <= 0) {
     return false;
@@ -117,12 +122,15 @@
 }
 
 dirent* readdir(DIR* d) {
+  CHECK_DIR(d);
   ScopedPthreadMutexLocker locker(&d->mutex_);
   return __readdir_locked(d);
 }
 __strong_alias(readdir64, readdir);
 
 int readdir_r(DIR* d, dirent* entry, dirent** result) {
+  CHECK_DIR(d);
+
   ErrnoRestorer errno_restorer;
 
   *result = NULL;
@@ -156,6 +164,8 @@
 }
 
 void rewinddir(DIR* d) {
+  CHECK_DIR(d);
+
   ScopedPthreadMutexLocker locker(&d->mutex_);
   lseek(d->fd_, 0, SEEK_SET);
   d->available_bytes_ = 0;
@@ -163,6 +173,8 @@
 }
 
 void seekdir(DIR* d, long offset) {
+  CHECK_DIR(d);
+
   ScopedPthreadMutexLocker locker(&d->mutex_);
   off_t ret = lseek(d->fd_, offset, SEEK_SET);
   if (ret != -1L) {
@@ -172,6 +184,8 @@
 }
 
 long telldir(DIR* d) {
+  CHECK_DIR(d);
+
   return d->current_pos_;
 }
 
diff --git a/libc/bionic/dl_iterate_phdr_static.cpp b/libc/bionic/dl_iterate_phdr_static.cpp
index 2196ac8..bbce1fc 100644
--- a/libc/bionic/dl_iterate_phdr_static.cpp
+++ b/libc/bionic/dl_iterate_phdr_static.cpp
@@ -53,7 +53,6 @@
   exe_info.dlpi_phdr = reinterpret_cast<ElfW(Phdr)*>(reinterpret_cast<uintptr_t>(ehdr) + ehdr->e_phoff);
   exe_info.dlpi_phnum = ehdr->e_phnum;
 
-#if defined(AT_SYSINFO_EHDR)
   // Try the executable first.
   int rc = cb(&exe_info, sizeof(exe_info), data);
   if (rc != 0) {
@@ -79,8 +78,4 @@
     }
   }
   return cb(&vdso_info, sizeof(vdso_info), data);
-#else
-  // There's only the executable to try.
-  return cb(&exe_info, sizeof(exe_info), data);
-#endif
 }
diff --git a/libc/bionic/environ.cpp b/libc/bionic/environ.cpp
index 363c1fd..243af62 100644
--- a/libc/bionic/environ.cpp
+++ b/libc/bionic/environ.cpp
@@ -28,6 +28,8 @@
 
 #include <unistd.h>
 
+#include "private/bionic_defs.h"
 // Keep that variable in separate .o file to make sure programs which define
 // their own "environ" are compileable.
+__BIONIC_WEAK_VARIABLE_FOR_NATIVE_BRIDGE
 char** environ;
diff --git a/libc/bionic/exec.cpp b/libc/bionic/exec.cpp
index 2001106..1cf3a58 100644
--- a/libc/bionic/exec.cpp
+++ b/libc/bionic/exec.cpp
@@ -39,6 +39,8 @@
 #include <string.h>
 #include <unistd.h>
 
+#include "private/FdPath.h"
+
 extern "C" char** environ;
 
 enum ExecVariant { kIsExecL, kIsExecLE, kIsExecLP };
@@ -170,3 +172,10 @@
   if (saw_EACCES) errno = EACCES;
   return -1;
 }
+
+int fexecve(int fd, char* const* argv, char* const* envp) {
+  // execveat with AT_EMPTY_PATH (>= 3.19) seems to offer no advantages.
+  execve(FdPath(fd).c_str(), argv, envp);
+  if (errno == ENOENT) errno = EBADF;
+  return -1;
+}
diff --git a/libc/bionic/fchmod.cpp b/libc/bionic/fchmod.cpp
index ace8c6b..a486aae 100644
--- a/libc/bionic/fchmod.cpp
+++ b/libc/bionic/fchmod.cpp
@@ -33,13 +33,14 @@
 #include <unistd.h>
 #include <stdio.h>
 
+#include "private/FdPath.h"
+
 extern "C" int ___fchmod(int, mode_t);
 
 int fchmod(int fd, mode_t mode) {
   int saved_errno = errno;
   int result = ___fchmod(fd, mode);
-
-  if ((result == 0) || (errno != EBADF)) {
+  if (result == 0 || errno != EBADF) {
     return result;
   }
 
@@ -52,16 +53,14 @@
   // on an O_PATH file descriptor, and "man open" documents fchmod
   // on O_PATH file descriptors as returning EBADF.
   int fd_flag = fcntl(fd, F_GETFL);
-  if ((fd_flag == -1) || ((fd_flag & O_PATH) == 0)) {
+  if (fd_flag == -1 || (fd_flag & O_PATH) == 0) {
     errno = EBADF;
     return -1;
   }
 
-  char buf[40];
-  snprintf(buf, sizeof(buf), "/proc/self/fd/%d", fd);
   errno = saved_errno;
-  result = chmod(buf, mode);
-  if ((result == -1) && (errno == ELOOP)) {
+  result = chmod(FdPath(fd).c_str(), mode);
+  if (result == -1 && errno == ELOOP) {
     // Linux does not support changing the mode of a symlink.
     // For fchmodat(AT_SYMLINK_NOFOLLOW), POSIX requires a return
     // value of ENOTSUP. Assume that's true here too.
diff --git a/libc/bionic/fgetxattr.cpp b/libc/bionic/fgetxattr.cpp
index 6d999bf..38b7ac3 100644
--- a/libc/bionic/fgetxattr.cpp
+++ b/libc/bionic/fgetxattr.cpp
@@ -33,13 +33,15 @@
 #include <fcntl.h>
 #include <stdio.h>
 
+#include "private/FdPath.h"
+
 extern "C" ssize_t ___fgetxattr(int, const char*, void*, size_t);
 
 ssize_t fgetxattr(int fd, const char *name, void *value, size_t size) {
   int saved_errno = errno;
   ssize_t result = ___fgetxattr(fd, name, value, size);
 
-  if ((result != -1) || (errno != EBADF)) {
+  if (result != -1 || errno != EBADF) {
     return result;
   }
 
@@ -47,13 +49,11 @@
   // may not directly support fgetxattr() on such a file descriptor.
   // Use /proc/self/fd instead to emulate this support.
   int fd_flag = fcntl(fd, F_GETFL);
-  if ((fd_flag == -1) || ((fd_flag & O_PATH) == 0)) {
+  if (fd_flag == -1 || (fd_flag & O_PATH) == 0) {
     errno = EBADF;
     return -1;
   }
 
-  char buf[40];
-  snprintf(buf, sizeof(buf), "/proc/self/fd/%d", fd);
   errno = saved_errno;
-  return getxattr(buf, name, value, size);
+  return getxattr(FdPath(fd).c_str(), name, value, size);
 }
diff --git a/libc/bionic/flistxattr.cpp b/libc/bionic/flistxattr.cpp
index 05a96d2..8ad9b85 100644
--- a/libc/bionic/flistxattr.cpp
+++ b/libc/bionic/flistxattr.cpp
@@ -33,13 +33,14 @@
 #include <fcntl.h>
 #include <stdio.h>
 
+#include "private/FdPath.h"
+
 extern "C" ssize_t ___flistxattr(int, char*, size_t);
 
 ssize_t flistxattr(int fd, char *list, size_t size) {
   int saved_errno = errno;
   ssize_t result = ___flistxattr(fd, list, size);
-
-  if ((result != -1) || (errno != EBADF)) {
+  if (result != -1 || errno != EBADF) {
     return result;
   }
 
@@ -47,13 +48,11 @@
   // may not directly support fgetxattr() on such a file descriptor.
   // Use /proc/self/fd instead to emulate this support.
   int fd_flag = fcntl(fd, F_GETFL);
-  if ((fd_flag == -1) || ((fd_flag & O_PATH) == 0)) {
+  if (fd_flag == -1 || (fd_flag & O_PATH) == 0) {
     errno = EBADF;
     return -1;
   }
 
-  char buf[40];
-  snprintf(buf, sizeof(buf), "/proc/self/fd/%d", fd);
   errno = saved_errno;
-  return listxattr(buf, list, size);
+  return listxattr(FdPath(fd).c_str(), list, size);
 }
diff --git a/libc/bionic/fork.cpp b/libc/bionic/fork.cpp
index efcbb8c..33b7343 100644
--- a/libc/bionic/fork.cpp
+++ b/libc/bionic/fork.cpp
@@ -28,8 +28,10 @@
 
 #include <unistd.h>
 
+#include "private/bionic_defs.h"
 #include "pthread_internal.h"
 
+__BIONIC_WEAK_FOR_NATIVE_BRIDGE
 int fork() {
   __bionic_atfork_run_prepare();
 
diff --git a/libc/bionic/fpclassify.cpp b/libc/bionic/fpclassify.cpp
index 42ed3ef..7aa53f3 100644
--- a/libc/bionic/fpclassify.cpp
+++ b/libc/bionic/fpclassify.cpp
@@ -26,145 +26,80 @@
  * SUCH DAMAGE.
  */
 
-#include <sys/types.h>
-
 #include <math.h>
 
-#include "private/bionic_ieee.h"
+// Legacy cruft from before we had builtin implementations of the standard macros.
+// No longer declared in our <math.h>.
 
-// These aren't declared in our <math.h>.
-extern "C" int __isinf(double);
-extern "C" int __isnan(double);
-
-union float_u {
-  float f;
-  ieee_single bits;
-};
-
-union double_u {
-  double d;
-  ieee_double bits;
-};
-
-int __fpclassifyd(double d) {
-  double_u u;
-  u.d = d;
-  if (u.bits.dbl_exp == 0) {
-    return ((u.bits.dbl_fracl | u.bits.dbl_frach) == 0) ? FP_ZERO : FP_SUBNORMAL;
-  }
-  if (u.bits.dbl_exp == DBL_EXP_INFNAN) {
-    return ((u.bits.dbl_fracl | u.bits.dbl_frach) == 0) ? FP_INFINITE : FP_NAN;
-  }
-  return FP_NORMAL;
+extern "C" int __fpclassifyd(double d) {
+  return fpclassify(d);
 }
 __strong_alias(__fpclassify, __fpclassifyd); // glibc uses __fpclassify, BSD __fpclassifyd.
 
-int __fpclassifyf(float f) {
-  float_u u;
-  u.f = f;
-  if (u.bits.sng_exp == 0) {
-    return (u.bits.sng_frac == 0) ? FP_ZERO : FP_SUBNORMAL;
-  }
-  if (u.bits.sng_exp == SNG_EXP_INFNAN) {
-    return (u.bits.sng_frac == 0) ? FP_INFINITE : FP_NAN;
-  }
-  return FP_NORMAL;
+extern "C" int __fpclassifyf(float f) {
+  return fpclassify(f);
 }
 
-int __isinf(double d) {
-  return (__fpclassifyd(d) == FP_INFINITE);
+extern "C" int __isinf(double d) {
+  return isinf(d);
 }
 __strong_alias(isinf, __isinf);
 
-int __isinff(float f) {
-  return (__fpclassifyf(f) == FP_INFINITE);
+extern "C" int __isinff(float f) {
+  return isinf(f);
 }
 __strong_alias(isinff, __isinff);
 
-int __isnan(double d) {
-  return (__fpclassifyd(d) == FP_NAN);
+extern "C" int __isnan(double d) {
+  return isnan(d);
 }
 __strong_alias(isnan, __isnan);
 
-int __isnanf(float f) {
-  return (__fpclassifyf(f) == FP_NAN);
+extern "C" int __isnanf(float f) {
+  return isnan(f);
 }
 __strong_alias(isnanf, __isnanf);
 
-int __isfinite(double d) {
-  int type = __fpclassifyd(d);
-  return ((type != FP_NAN) && (type != FP_INFINITE));
+extern "C" int __isfinite(double d) {
+  return isfinite(d);
 }
 __strong_alias(isfinite, __isfinite);
 
-int __isfinitef(float f) {
-  int type = __fpclassifyf(f);
-  return ((type != FP_NAN) && (type != FP_INFINITE));
+extern "C" int __isfinitef(float f) {
+  return isfinite(f);
 }
 __strong_alias(isfinitef, __isfinitef);
 
-int __isnormal(double d) {
-  return (__fpclassifyd(d) == FP_NORMAL);
+extern "C" int __isnormal(double d) {
+  return isnormal(d);
 }
 __strong_alias(isnormal, __isnormal);
 
-int __isnormalf(float f) {
-  return (__fpclassifyf(f) == FP_NORMAL);
+extern "C" int __isnormalf(float f) {
+  return isnormal(f);
 }
 __strong_alias(isnormalf, __isnormalf);
 
-#if defined(__LP64__)
-
-// LP64 uses 128-bit long doubles.
-
-union long_double_u {
-  long double ld;
-  ieee_ext bits;
-};
-
-#define zero_frac(b) ((b.ext_fracl | b.ext_fraclm | b.ext_frachm | b.ext_frach) == 0)
-
-int __fpclassifyl(long double ld) {
-  long_double_u u;
-  u.ld = ld;
-  if (u.bits.ext_exp == 0) {
-    return zero_frac(u.bits) ? FP_ZERO : FP_SUBNORMAL;
-  }
-  if (u.bits.ext_exp == EXT_EXP_INFNAN) {
-    return zero_frac(u.bits) ? FP_INFINITE : FP_NAN;
-  }
-  return FP_NORMAL;
+extern "C" int __fpclassifyl(long double ld) {
+  return fpclassify(ld);
 }
 
-int __isinfl(long double ld) {
-  return (__fpclassifyl(ld) == FP_INFINITE);
+extern "C" int __isinfl(long double ld) {
+  return isinf(ld);
 }
 
-int __isnanl(long double ld) {
-  return (__fpclassifyl(ld) == FP_NAN);
+extern "C" int __isnanl(long double ld) {
+  return isnan(ld);
 }
 
-int __isfinitel(long double ld) {
-  int type = __fpclassifyl(ld);
-  return ((type != FP_NAN) && (type != FP_INFINITE));
+extern "C" int __isfinitel(long double ld) {
+  return isfinite(ld);
 }
 
-int __isnormall(long double ld) {
-  return (__fpclassifyl(ld) == FP_NORMAL);
+extern "C" int __isnormall(long double ld) {
+  return isnormal(ld);
 }
 
-#else
-
-// LP32 uses double as long double.
-
-__strong_alias(__fpclassifyl, __fpclassify);
-__strong_alias(__isinfl, __isinf);
-__strong_alias(__isnanl, __isnan);
-__strong_alias(__isfinitel, __isfinite);
-__strong_alias(__isnormall, __isnormal);
-
-#endif
-
 __strong_alias(isinfl, __isinfl);
 __strong_alias(isnanl, __isnanl);
 __strong_alias(isfinitel, __isfinitel);
diff --git a/libc/bionic/fsetxattr.cpp b/libc/bionic/fsetxattr.cpp
index 6d2e868..9ad0c76 100644
--- a/libc/bionic/fsetxattr.cpp
+++ b/libc/bionic/fsetxattr.cpp
@@ -33,13 +33,14 @@
 #include <fcntl.h>
 #include <stdio.h>
 
+#include "private/FdPath.h"
+
 extern "C" int ___fsetxattr(int, const char*, const void*, size_t, int);
 
 int fsetxattr(int fd, const char* name, const void* value, size_t size, int flags) {
   int saved_errno = errno;
   int result = ___fsetxattr(fd, name, value, size, flags);
-
-  if ((result == 0) || (errno != EBADF)) {
+  if (result == 0 || errno != EBADF) {
     return result;
   }
 
@@ -47,13 +48,11 @@
   // may not directly support fsetxattr() on such a file descriptor.
   // Use /proc/self/fd instead to emulate this support.
   int fd_flag = fcntl(fd, F_GETFL);
-  if ((fd_flag == -1) || ((fd_flag & O_PATH) == 0)) {
+  if (fd_flag == -1 || (fd_flag & O_PATH) == 0) {
     errno = EBADF;
     return -1;
   }
 
-  char buf[40];
-  snprintf(buf, sizeof(buf), "/proc/self/fd/%d", fd);
   errno = saved_errno;
-  return setxattr(buf, name, value, size, flags);
+  return setxattr(FdPath(fd).c_str(), name, value, size, flags);
 }
diff --git a/libc/bionic/grp_pwd.cpp b/libc/bionic/grp_pwd.cpp
index 2823662..43a5032 100644
--- a/libc/bionic/grp_pwd.cpp
+++ b/libc/bionic/grp_pwd.cpp
@@ -195,6 +195,89 @@
   return NULL;
 }
 
+// These are a list of the reserved app ranges, and should never contain anything below
+// AID_APP_START.  They exist per user, so a given uid/gid modulo AID_USER_OFFSET will map
+// to these ranges.
+static constexpr struct {
+  uid_t start;
+  uid_t end;
+} user_ranges[] = {
+  { AID_APP_START, AID_APP_END },
+  { AID_CACHE_GID_START, AID_CACHE_GID_END },
+  { AID_EXT_GID_START, AID_EXT_GID_END },
+  { AID_EXT_CACHE_GID_START, AID_EXT_CACHE_GID_END },
+  { AID_SHARED_GID_START, AID_SHARED_GID_END },
+  { AID_ISOLATED_START, AID_ISOLATED_END },
+};
+
+static constexpr bool verify_user_ranges_ascending() {
+  auto array_size = arraysize(user_ranges);
+  if (array_size < 2) return false;
+
+  if (user_ranges[0].start > user_ranges[0].end) return false;
+
+  for (size_t i = 1; i < array_size; ++i) {
+    if (user_ranges[i].start > user_ranges[i].end) return false;
+    if (user_ranges[i - 1].end > user_ranges[i].start) return false;
+  }
+  return true;
+}
+
+static_assert(verify_user_ranges_ascending(), "user_ranges must have ascending ranges");
+
+static bool is_valid_app_id(id_t id) {
+  id_t appid = id % AID_USER_OFFSET;
+
+  // AID_OVERFLOWUID is never a valid app id, so we explicitly return false to ensure this.
+  // This is true across all users, as there is no reason to ever map this id into any user range.
+  if (appid == AID_OVERFLOWUID) {
+    return false;
+  }
+
+  // If we've resolved to something before app_start, we have already checked against
+  // android_ids, so no need to check again.
+  if (appid < user_ranges[0].start) {
+    return true;
+  }
+
+  // Otherwise check that the appid is in one of the reserved ranges.
+  for (size_t i = 0; i < arraysize(user_ranges); ++i) {
+    if (appid >= user_ranges[i].start && appid <= user_ranges[i].end) {
+      return true;
+    }
+  }
+
+  return false;
+}
+
+// This provides an iterater for app_ids within the first user's app id's.
+static uid_t get_next_app_id(uid_t current_id) {
+  // If current_id is below the first of the user_ranges, then we're uninitialized, and return the
+  // first valid id.
+  if (current_id < user_ranges[0].start) {
+    return user_ranges[0].start;
+  }
+
+  uid_t incremented_id = current_id + 1;
+
+  // Check to see if our incremented_id is between two ranges, and if so, return the beginning of
+  // the next valid range.
+  for (size_t i = 1; i < arraysize(user_ranges); ++i) {
+    if (incremented_id > user_ranges[i - 1].end && incremented_id < user_ranges[i].start) {
+      return user_ranges[i].start;
+    }
+  }
+
+  // Check to see if our incremented_id is above final range, and return -1 to indicate that we've
+  // completed if so.
+  if (incremented_id > user_ranges[arraysize(user_ranges) - 1].end) {
+    return -1;
+  }
+
+  // Otherwise the incremented_id is valid, so return it.
+  return incremented_id;
+}
+
 // Translate a user/group name to the corresponding user/group id.
 // all_a1234 -> 0 * AID_USER_OFFSET + AID_SHARED_GID_START + 1234 (group name only)
 // u0_a1234_cache -> 0 * AID_USER_OFFSET + AID_CACHE_GID_START + 1234 (group name only)
@@ -377,7 +460,7 @@
 // AID_USER_OFFSET+                        -> u1_radio, u1_a1234, u2_i1234, etc.
 // returns a passwd structure (sets errno to ENOENT on failure).
 static passwd* app_id_to_passwd(uid_t uid, passwd_state_t* state) {
-  if (uid < AID_APP_START) {
+  if (uid < AID_APP_START || !is_valid_app_id(uid)) {
     errno = ENOENT;
     return NULL;
   }
@@ -405,7 +488,7 @@
 // Translate a gid into the corresponding app_<gid>
 // group structure (sets errno to ENOENT on failure).
 static group* app_id_to_group(gid_t gid, group_state_t* state) {
-  if (gid < AID_APP_START) {
+  if (gid < AID_APP_START || !is_valid_app_id(gid)) {
     errno = ENOENT;
     return NULL;
   }
@@ -521,15 +604,13 @@
         state->getpwent_idx++ - start + AID_OEM_RESERVED_2_START, state);
   }
 
-  start = end;
-  end += AID_USER_OFFSET - AID_APP_START; // Do not expose higher users
+  state->getpwent_idx = get_next_app_id(state->getpwent_idx);
 
-  if (state->getpwent_idx < end) {
-    return app_id_to_passwd(state->getpwent_idx++ - start + AID_APP_START, state);
+  if (state->getpwent_idx != -1) {
+    return app_id_to_passwd(state->getpwent_idx, state);
   }
 
   // We are not reporting u1_a* and higher or we will be here forever
-  state->getpwent_idx = -1;
   return NULL;
 }
 
@@ -580,7 +661,7 @@
   ErrnoRestorer errno_restorer;
   *result = NULL;
   char* p = reinterpret_cast<char*>(
-      BIONIC_ALIGN(reinterpret_cast<uintptr_t>(buf), sizeof(uintptr_t)));
+      __BIONIC_ALIGN(reinterpret_cast<uintptr_t>(buf), sizeof(uintptr_t)));
   if (p + sizeof(group_state_t) > buf + buflen) {
     return ERANGE;
   }
@@ -652,12 +733,12 @@
   start = end;
   end += AID_USER_OFFSET - AID_APP_START; // Do not expose higher groups
 
-  if (state->getgrent_idx < end) {
-    init_group_state(state);
-    return app_id_to_group(state->getgrent_idx++ - start + AID_APP_START, state);
+  state->getgrent_idx = get_next_app_id(state->getgrent_idx);
+
+  if (state->getgrent_idx != -1) {
+    return app_id_to_group(state->getgrent_idx, state);
   }
 
   // We are not reporting u1_a* and higher or we will be here forever
-  state->getgrent_idx = -1;
   return NULL;
 }
diff --git a/libc/bionic/iconv.cpp b/libc/bionic/iconv.cpp
index b0372a1..015d70f 100644
--- a/libc/bionic/iconv.cpp
+++ b/libc/bionic/iconv.cpp
@@ -32,6 +32,7 @@
 #include <endian.h>
 #include <errno.h>
 #include <stdlib.h>
+#include <string.h>
 #include <uchar.h>
 
 #include "private/bionic_mbstate.h"
diff --git a/libc/bionic/icu.cpp b/libc/bionic/icu.cpp
index 944a3f8..78e551b 100644
--- a/libc/bionic/icu.cpp
+++ b/libc/bionic/icu.cpp
@@ -32,6 +32,7 @@
 #include <dlfcn.h>
 #include <pthread.h>
 #include <stdlib.h>
+#include <string.h>
 
 #include <async_safe/log.h>
 
diff --git a/libc/bionic/icu_static.cpp b/libc/bionic/icu_static.cpp
index cf24a38..e81e291 100644
--- a/libc/bionic/icu_static.cpp
+++ b/libc/bionic/icu_static.cpp
@@ -29,6 +29,6 @@
 #include "private/icu.h"
 
 // We don't have dlopen/dlsym for static binaries yet.
-void* __find_icu_symbol(const char*) {
+__attribute__((weak)) void* __find_icu_symbol(const char*) {
   return nullptr;
 }
diff --git a/libc/bionic/jemalloc_wrapper.cpp b/libc/bionic/jemalloc_wrapper.cpp
index 266b966..19081a4 100644
--- a/libc/bionic/jemalloc_wrapper.cpp
+++ b/libc/bionic/jemalloc_wrapper.cpp
@@ -23,7 +23,7 @@
 
 void* je_pvalloc(size_t bytes) {
   size_t pagesize = getpagesize();
-  size_t size = BIONIC_ALIGN(bytes, pagesize);
+  size_t size = __BIONIC_ALIGN(bytes, pagesize);
   if (size < bytes) {
     return NULL;
   }
diff --git a/libc/bionic/libc_init_common.cpp b/libc/bionic/libc_init_common.cpp
index 48fd670..c22f571 100644
--- a/libc/bionic/libc_init_common.cpp
+++ b/libc/bionic/libc_init_common.cpp
@@ -261,6 +261,7 @@
     "LD_PROFILE",
     "LD_SHOW_AUXV",
     "LD_USE_LOAD_BIAS",
+    "LIBC_DEBUG_MALLOC_OPTIONS",
     "LOCALDOMAIN",
     "LOCPATH",
     "MALLOC_CHECK_",
diff --git a/libc/bionic/libc_init_dynamic.cpp b/libc/bionic/libc_init_dynamic.cpp
index 7c73950..0b68280 100644
--- a/libc/bionic/libc_init_dynamic.cpp
+++ b/libc/bionic/libc_init_dynamic.cpp
@@ -52,6 +52,7 @@
 #include "libc_init_common.h"
 
 #include "private/bionic_globals.h"
+#include "private/bionic_macros.h"
 #include "private/bionic_ssp.h"
 #include "private/bionic_tls.h"
 #include "private/KernelArgumentBlock.h"
@@ -76,11 +77,14 @@
   netdClientInit();
 }
 
-// We flag the __libc_preinit function as a constructor to ensure
-// that its address is listed in libc.so's .init_array section.
-// This ensures that the function is called by the dynamic linker
-// as soon as the shared library is loaded.
-__attribute__((constructor)) static void __libc_preinit() {
+// We flag the __libc_preinit function as a constructor to ensure that
+// its address is listed in libc.so's .init_array section.
+// This ensures that the function is called by the dynamic linker as
+// soon as the shared library is loaded.
+// We give this constructor priority 1 because we want libc's constructor
+// to run before any others (such as the jemalloc constructor), and lower
+// is better (http://b/68046352).
+__attribute__((constructor(1))) static void __libc_preinit() {
   // Read the kernel argument block pointer from TLS.
   void** tls = __get_tls();
   KernelArgumentBlock** args_slot = &reinterpret_cast<KernelArgumentBlock**>(tls)[TLS_SLOT_BIONIC_PREINIT];
@@ -108,6 +112,7 @@
                             void (*onexit)(void) __unused,
                             int (*slingshot)(int, char**, char**),
                             structors_array_t const * const structors) {
+  BIONIC_STOP_UNWIND;
 
   KernelArgumentBlock args(raw_args);
 
diff --git a/libc/bionic/libc_init_static.cpp b/libc/bionic/libc_init_static.cpp
index 5e06d39..93a63b5 100644
--- a/libc/bionic/libc_init_static.cpp
+++ b/libc/bionic/libc_init_static.cpp
@@ -40,6 +40,7 @@
 #include "pthread_internal.h"
 
 #include "private/bionic_globals.h"
+#include "private/bionic_macros.h"
 #include "private/bionic_page.h"
 #include "private/bionic_tls.h"
 #include "private/KernelArgumentBlock.h"
@@ -82,6 +83,8 @@
                             void (*onexit)(void) __unused,
                             int (*slingshot)(int, char**, char**),
                             structors_array_t const * const structors) {
+  BIONIC_STOP_UNWIND;
+
   KernelArgumentBlock args(raw_args);
   __libc_init_main_thread(args);
 
diff --git a/libc/bionic/mmap.cpp b/libc/bionic/mmap.cpp
index 57a8cdf..3503319 100644
--- a/libc/bionic/mmap.cpp
+++ b/libc/bionic/mmap.cpp
@@ -48,7 +48,7 @@
   }
 
   // prevent allocations large enough for `end - start` to overflow
-  size_t rounded = BIONIC_ALIGN(size, PAGE_SIZE);
+  size_t rounded = __BIONIC_ALIGN(size, PAGE_SIZE);
   if (rounded < size || rounded > PTRDIFF_MAX) {
     errno = ENOMEM;
     return MAP_FAILED;
diff --git a/libc/bionic/mremap.cpp b/libc/bionic/mremap.cpp
index 6653d43..896ccef 100644
--- a/libc/bionic/mremap.cpp
+++ b/libc/bionic/mremap.cpp
@@ -38,7 +38,7 @@
 
 void* mremap(void* old_address, size_t old_size, size_t new_size, int flags, ...) {
   // prevent allocations large enough for `end - start` to overflow
-  size_t rounded = BIONIC_ALIGN(new_size, PAGE_SIZE);
+  size_t rounded = __BIONIC_ALIGN(new_size, PAGE_SIZE);
   if (rounded < new_size || rounded > PTRDIFF_MAX) {
     errno = ENOMEM;
     return MAP_FAILED;
diff --git a/libc/bionic/netdb.cpp b/libc/bionic/netdb.cpp
index da61f98..dc2a037 100644
--- a/libc/bionic/netdb.cpp
+++ b/libc/bionic/netdb.cpp
@@ -28,22 +28,40 @@
 
 #include <netdb.h>
 
-// We don't have an /etc/networks, so all inputs return NULL.
-netent* getnetbyname(const char* /*name*/) {
-  return NULL;
+// We don't have an /etc/networks or /etc/protocols, so these are just dummies.
+
+void endnetent() {
 }
 
-// We don't have an /etc/networks, so all inputs return NULL.
+void endprotoent() {
+}
+
 netent* getnetbyaddr(uint32_t /*net*/, int /*type*/) {
-  return NULL;
+  return nullptr;
 }
 
-// We don't have an /etc/protocols, so all inputs return NULL.
+netent* getnetbyname(const char* /*name*/) {
+  return nullptr;
+}
+
+netent* getnetent() {
+  return nullptr;
+}
+
 protoent* getprotobyname(const char* /*name*/) {
-  return NULL;
+  return nullptr;
 }
 
-// We don't have an /etc/protocols, so all inputs return NULL.
 protoent* getprotobynumber(int /*proto*/) {
-  return NULL;
+  return nullptr;
+}
+
+protoent* getprotoent() {
+  return nullptr;
+}
+
+void setnetent(int /*stayopen*/) {
+}
+
+void setprotoent(int /*stayopen*/) {
 }
diff --git a/libc/bionic/pthread_attr.cpp b/libc/bionic/pthread_attr.cpp
index fc9e74a..93177f1 100644
--- a/libc/bionic/pthread_attr.cpp
+++ b/libc/bionic/pthread_attr.cpp
@@ -35,10 +35,12 @@
 
 #include <async_safe/log.h>
 
+#include "private/bionic_defs.h"
 #include "private/bionic_string_utils.h"
 #include "private/ErrnoRestorer.h"
 #include "pthread_internal.h"
 
+__BIONIC_WEAK_FOR_NATIVE_BRIDGE
 int pthread_attr_init(pthread_attr_t* attr) {
   attr->flags = 0;
   attr->stack_base = NULL;
@@ -49,11 +51,40 @@
   return 0;
 }
 
+__BIONIC_WEAK_FOR_NATIVE_BRIDGE
 int pthread_attr_destroy(pthread_attr_t* attr) {
   memset(attr, 0x42, sizeof(pthread_attr_t));
   return 0;
 }
 
+__BIONIC_WEAK_FOR_NATIVE_BRIDGE
+int pthread_attr_setinheritsched(pthread_attr_t* attr, int flag) {
+  if (flag == PTHREAD_EXPLICIT_SCHED) {
+    attr->flags &= ~PTHREAD_ATTR_FLAG_INHERIT;
+    attr->flags |= PTHREAD_ATTR_FLAG_EXPLICIT;
+  } else if (flag == PTHREAD_INHERIT_SCHED) {
+    attr->flags |= PTHREAD_ATTR_FLAG_INHERIT;
+    attr->flags &= ~PTHREAD_ATTR_FLAG_EXPLICIT;
+  } else {
+    return EINVAL;
+  }
+  return 0;
+}
+
+__BIONIC_WEAK_FOR_NATIVE_BRIDGE
+int pthread_attr_getinheritsched(const pthread_attr_t* attr, int* flag) {
+  if ((attr->flags & PTHREAD_ATTR_FLAG_INHERIT) != 0) {
+    *flag = PTHREAD_INHERIT_SCHED;
+  } else if ((attr->flags & PTHREAD_ATTR_FLAG_EXPLICIT) != 0) {
+    *flag = PTHREAD_EXPLICIT_SCHED;
+  } else {
+    // Historical behavior before P, when pthread_attr_setinheritsched was added.
+    *flag = (attr->sched_policy != SCHED_NORMAL) ? PTHREAD_EXPLICIT_SCHED : PTHREAD_INHERIT_SCHED;
+  }
+  return 0;
+}
+
+__BIONIC_WEAK_FOR_NATIVE_BRIDGE
 int pthread_attr_setdetachstate(pthread_attr_t* attr, int state) {
   if (state == PTHREAD_CREATE_DETACHED) {
     attr->flags |= PTHREAD_ATTR_FLAG_DETACHED;
@@ -65,31 +96,37 @@
   return 0;
 }
 
+__BIONIC_WEAK_FOR_NATIVE_BRIDGE
 int pthread_attr_getdetachstate(const pthread_attr_t* attr, int* state) {
   *state = (attr->flags & PTHREAD_ATTR_FLAG_DETACHED) ? PTHREAD_CREATE_DETACHED : PTHREAD_CREATE_JOINABLE;
   return 0;
 }
 
+__BIONIC_WEAK_FOR_NATIVE_BRIDGE
 int pthread_attr_setschedpolicy(pthread_attr_t* attr, int policy) {
   attr->sched_policy = policy;
   return 0;
 }
 
+__BIONIC_WEAK_FOR_NATIVE_BRIDGE
 int pthread_attr_getschedpolicy(const pthread_attr_t* attr, int* policy) {
   *policy = attr->sched_policy;
   return 0;
 }
 
+__BIONIC_WEAK_FOR_NATIVE_BRIDGE
 int pthread_attr_setschedparam(pthread_attr_t* attr, const sched_param* param) {
   attr->sched_priority = param->sched_priority;
   return 0;
 }
 
+__BIONIC_WEAK_FOR_NATIVE_BRIDGE
 int pthread_attr_getschedparam(const pthread_attr_t* attr, sched_param* param) {
   param->sched_priority = attr->sched_priority;
   return 0;
 }
 
+__BIONIC_WEAK_FOR_NATIVE_BRIDGE
 int pthread_attr_setstacksize(pthread_attr_t* attr, size_t stack_size) {
   if (stack_size < PTHREAD_STACK_MIN) {
     return EINVAL;
@@ -98,11 +135,13 @@
   return 0;
 }
 
+__BIONIC_WEAK_FOR_NATIVE_BRIDGE
 int pthread_attr_getstacksize(const pthread_attr_t* attr, size_t* stack_size) {
   void* unused;
   return pthread_attr_getstack(attr, &unused, stack_size);
 }
 
+__BIONIC_WEAK_FOR_NATIVE_BRIDGE
 int pthread_attr_setstack(pthread_attr_t* attr, void* stack_base, size_t stack_size) {
   if ((stack_size & (PAGE_SIZE - 1) || stack_size < PTHREAD_STACK_MIN)) {
     return EINVAL;
@@ -181,22 +220,26 @@
   async_safe_fatal("Stack not found in /proc/self/maps");
 }
 
+__BIONIC_WEAK_FOR_NATIVE_BRIDGE
 int pthread_attr_getstack(const pthread_attr_t* attr, void** stack_base, size_t* stack_size) {
   *stack_base = attr->stack_base;
   *stack_size = attr->stack_size;
   return 0;
 }
 
+__BIONIC_WEAK_FOR_NATIVE_BRIDGE
 int pthread_attr_setguardsize(pthread_attr_t* attr, size_t guard_size) {
   attr->guard_size = guard_size;
   return 0;
 }
 
+__BIONIC_WEAK_FOR_NATIVE_BRIDGE
 int pthread_attr_getguardsize(const pthread_attr_t* attr, size_t* guard_size) {
   *guard_size = attr->guard_size;
   return 0;
 }
 
+__BIONIC_WEAK_FOR_NATIVE_BRIDGE
 int pthread_getattr_np(pthread_t t, pthread_attr_t* attr) {
   pthread_internal_t* thread = reinterpret_cast<pthread_internal_t*>(t);
   *attr = thread->attr;
@@ -213,6 +256,7 @@
   return 0;
 }
 
+__BIONIC_WEAK_FOR_NATIVE_BRIDGE
 int pthread_attr_setscope(pthread_attr_t*, int scope) {
   if (scope == PTHREAD_SCOPE_SYSTEM) {
     return 0;
@@ -223,6 +267,7 @@
   return EINVAL;
 }
 
+__BIONIC_WEAK_FOR_NATIVE_BRIDGE
 int pthread_attr_getscope(const pthread_attr_t*, int* scope) {
   *scope = PTHREAD_SCOPE_SYSTEM;
   return 0;
diff --git a/libc/bionic/pthread_create.cpp b/libc/bionic/pthread_create.cpp
index 65ab92c..21a707b 100644
--- a/libc/bionic/pthread_create.cpp
+++ b/libc/bionic/pthread_create.cpp
@@ -37,6 +37,7 @@
 
 #include <async_safe/log.h>
 
+#include "private/bionic_defs.h"
 #include "private/bionic_macros.h"
 #include "private/bionic_prctl.h"
 #include "private/bionic_ssp.h"
@@ -109,7 +110,7 @@
 }
 
 int __init_thread(pthread_internal_t* thread) {
-  int error = 0;
+  thread->cleanup_stack = nullptr;
 
   if (__predict_true((thread->attr.flags & PTHREAD_ATTR_FLAG_DETACHED) == 0)) {
     atomic_init(&thread->join_state, THREAD_NOT_JOINED);
@@ -117,23 +118,48 @@
     atomic_init(&thread->join_state, THREAD_DETACHED);
   }
 
-  // Set the scheduling policy/priority of the thread.
-  if (thread->attr.sched_policy != SCHED_NORMAL) {
-    sched_param param;
+  // Set the scheduling policy/priority of the thread if necessary.
+  bool need_set = true;
+  int policy;
+  sched_param param;
+  if ((thread->attr.flags & PTHREAD_ATTR_FLAG_INHERIT) != 0) {
+    // Unless the parent has SCHED_RESET_ON_FORK set, we've already inherited from the parent.
+    policy = sched_getscheduler(0);
+    need_set = ((policy & SCHED_RESET_ON_FORK) != 0);
+    if (need_set) {
+      if (policy == -1) {
+        async_safe_format_log(ANDROID_LOG_WARN, "libc",
+                              "pthread_create sched_getscheduler failed: %s", strerror(errno));
+        return errno;
+      }
+      if (sched_getparam(0, &param) == -1) {
+        async_safe_format_log(ANDROID_LOG_WARN, "libc",
+                              "pthread_create sched_getparam failed: %s", strerror(errno));
+        return errno;
+      }
+    }
+  } else {
+    policy = thread->attr.sched_policy;
     param.sched_priority = thread->attr.sched_priority;
-    if (sched_setscheduler(thread->tid, thread->attr.sched_policy, &param) == -1) {
+  }
+  // Backwards compatibility: before P, Android didn't have pthread_attr_setinheritsched,
+  // and our behavior was neither of the POSIX behaviors.
+  if ((thread->attr.flags & (PTHREAD_ATTR_FLAG_INHERIT|PTHREAD_ATTR_FLAG_EXPLICIT)) == 0) {
+    need_set = (thread->attr.sched_policy != SCHED_NORMAL);
+  }
+  if (need_set) {
+    if (sched_setscheduler(thread->tid, policy, &param) == -1) {
+      async_safe_format_log(ANDROID_LOG_WARN, "libc",
+                            "pthread_create sched_setscheduler(%d, {%d}) call failed: %s", policy,
+                            param.sched_priority, strerror(errno));
 #if defined(__LP64__)
       // For backwards compatibility reasons, we only report failures on 64-bit devices.
-      error = errno;
+      return errno;
 #endif
-      async_safe_format_log(ANDROID_LOG_WARN, "libc",
-                            "pthread_create sched_setscheduler call failed: %s", strerror(errno));
     }
   }
 
-  thread->cleanup_stack = NULL;
-
-  return error;
+  return 0;
 }
 
 static void* __create_thread_mapped_space(size_t mmap_size, size_t stack_guard_size) {
@@ -172,8 +198,8 @@
     // Make sure the stack size and guard size are multiples of PAGE_SIZE.
     if (__builtin_add_overflow(attr->stack_size, attr->guard_size, &mmap_size)) return EAGAIN;
     if (__builtin_add_overflow(mmap_size, sizeof(pthread_internal_t), &mmap_size)) return EAGAIN;
-    mmap_size = BIONIC_ALIGN(mmap_size, PAGE_SIZE);
-    attr->guard_size = BIONIC_ALIGN(attr->guard_size, PAGE_SIZE);
+    mmap_size = __BIONIC_ALIGN(mmap_size, PAGE_SIZE);
+    attr->guard_size = __BIONIC_ALIGN(attr->guard_size, PAGE_SIZE);
     attr->stack_base = __create_thread_mapped_space(mmap_size, attr->guard_size);
     if (attr->stack_base == NULL) {
       return EAGAIN;
@@ -238,6 +264,8 @@
   return NULL;
 }
 
+
+__BIONIC_WEAK_FOR_NATIVE_BRIDGE
 int pthread_create(pthread_t* thread_out, pthread_attr_t const* attr,
                    void* (*start_routine)(void*), void* arg) {
   ErrnoRestorer errno_restorer;
diff --git a/libc/bionic/pthread_detach.cpp b/libc/bionic/pthread_detach.cpp
index fb8e0dd..011e6c6 100644
--- a/libc/bionic/pthread_detach.cpp
+++ b/libc/bionic/pthread_detach.cpp
@@ -29,8 +29,10 @@
 #include <errno.h>
 #include <pthread.h>
 
+#include "private/bionic_defs.h"
 #include "pthread_internal.h"
 
+__BIONIC_WEAK_FOR_NATIVE_BRIDGE
 int pthread_detach(pthread_t t) {
   pthread_internal_t* thread = __pthread_internal_find(t);
   if (thread == NULL) {
diff --git a/libc/bionic/pthread_exit.cpp b/libc/bionic/pthread_exit.cpp
index ac29c1d..8b4c44e 100644
--- a/libc/bionic/pthread_exit.cpp
+++ b/libc/bionic/pthread_exit.cpp
@@ -33,6 +33,7 @@
 #include <string.h>
 #include <sys/mman.h>
 
+#include "private/bionic_defs.h"
 #include "pthread_internal.h"
 
 extern "C" __noreturn void _exit_with_stack_teardown(void*, size_t);
@@ -44,6 +45,7 @@
  *         and thread cancelation
  */
 
+__BIONIC_WEAK_FOR_NATIVE_BRIDGE
 void __pthread_cleanup_push(__pthread_cleanup_t* c, __pthread_cleanup_func_t routine, void* arg) {
   pthread_internal_t* thread = __get_thread();
   c->__cleanup_routine = routine;
@@ -52,6 +54,7 @@
   thread->cleanup_stack = c;
 }
 
+__BIONIC_WEAK_FOR_NATIVE_BRIDGE
 void __pthread_cleanup_pop(__pthread_cleanup_t* c, int execute) {
   pthread_internal_t* thread = __get_thread();
   thread->cleanup_stack = c->__cleanup_prev;
@@ -60,6 +63,7 @@
   }
 }
 
+__BIONIC_WEAK_FOR_NATIVE_BRIDGE
 void pthread_exit(void* return_value) {
   // Call dtors for thread_local objects first.
   __cxa_thread_finalize();
diff --git a/libc/bionic/pthread_gettid_np.cpp b/libc/bionic/pthread_gettid_np.cpp
index fe85442..1beddc9 100644
--- a/libc/bionic/pthread_gettid_np.cpp
+++ b/libc/bionic/pthread_gettid_np.cpp
@@ -26,8 +26,10 @@
  * SUCH DAMAGE.
  */
 
+#include "private/bionic_defs.h"
 #include "pthread_internal.h"
 
+__BIONIC_WEAK_FOR_NATIVE_BRIDGE
 pid_t pthread_gettid_np(pthread_t t) {
   pthread_internal_t* thread = __pthread_internal_find(t);
   return thread ? thread->tid : -1;
diff --git a/libc/bionic/pthread_internal.h b/libc/bionic/pthread_internal.h
index ad8be66..a4cba87 100644
--- a/libc/bionic/pthread_internal.h
+++ b/libc/bionic/pthread_internal.h
@@ -34,12 +34,17 @@
 #include "private/bionic_lock.h"
 #include "private/bionic_tls.h"
 
-/* Has the thread been detached by a pthread_join or pthread_detach call? */
+// Has the thread been detached by a pthread_join or pthread_detach call?
 #define PTHREAD_ATTR_FLAG_DETACHED 0x00000001
 
-/* Has the thread been joined by another thread? */
+// Has the thread been joined by another thread?
 #define PTHREAD_ATTR_FLAG_JOINED 0x00000002
 
+// Used for pthread_attr_setinheritsched. We need two flags for this apparent
+// boolean because our historical behavior matches neither of the POSIX choices.
+#define PTHREAD_ATTR_FLAG_INHERIT 0x00000004
+#define PTHREAD_ATTR_FLAG_EXPLICIT 0x00000008
+
 class pthread_key_data_t {
  public:
   uintptr_t seq; // Use uintptr_t just for alignment, as we use pointer below.
diff --git a/libc/bionic/pthread_join.cpp b/libc/bionic/pthread_join.cpp
index 4d852cb..be76c20 100644
--- a/libc/bionic/pthread_join.cpp
+++ b/libc/bionic/pthread_join.cpp
@@ -28,9 +28,11 @@
 
 #include <errno.h>
 
+#include "private/bionic_defs.h"
 #include "private/bionic_futex.h"
 #include "pthread_internal.h"
 
+__BIONIC_WEAK_FOR_NATIVE_BRIDGE
 int pthread_join(pthread_t t, void** return_value) {
   if (t == pthread_self()) {
     return EDEADLK;
diff --git a/libc/bionic/pthread_key.cpp b/libc/bionic/pthread_key.cpp
index 6d77afa..baff9cc 100644
--- a/libc/bionic/pthread_key.cpp
+++ b/libc/bionic/pthread_key.cpp
@@ -30,6 +30,7 @@
 #include <pthread.h>
 #include <stdatomic.h>
 
+#include "private/bionic_defs.h"
 #include "private/bionic_tls.h"
 #include "pthread_internal.h"
 
@@ -115,6 +116,7 @@
   }
 }
 
+__BIONIC_WEAK_FOR_NATIVE_BRIDGE
 int pthread_key_create(pthread_key_t* key, void (*key_destructor)(void*)) {
   for (size_t i = 0; i < BIONIC_PTHREAD_KEY_COUNT; ++i) {
     uintptr_t seq = atomic_load_explicit(&key_map[i].seq, memory_order_relaxed);
@@ -133,6 +135,7 @@
 // not call the destructors for non-NULL key values. Instead, it is the
 // responsibility of the caller to properly dispose of the corresponding data
 // and resources, using any means it finds suitable.
+__BIONIC_WEAK_FOR_NATIVE_BRIDGE
 int pthread_key_delete(pthread_key_t key) {
   if (__predict_false(!KeyInValidRange(key))) {
     return EINVAL;
@@ -148,6 +151,7 @@
   return EINVAL;
 }
 
+__BIONIC_WEAK_FOR_NATIVE_BRIDGE
 void* pthread_getspecific(pthread_key_t key) {
   if (__predict_false(!KeyInValidRange(key))) {
     return NULL;
@@ -166,6 +170,7 @@
   return NULL;
 }
 
+__BIONIC_WEAK_FOR_NATIVE_BRIDGE
 int pthread_setspecific(pthread_key_t key, const void* ptr) {
   if (__predict_false(!KeyInValidRange(key))) {
     return EINVAL;
diff --git a/libc/bionic/pthread_setschedparam.cpp b/libc/bionic/pthread_setschedparam.cpp
index 3e80959..10826d1 100644
--- a/libc/bionic/pthread_setschedparam.cpp
+++ b/libc/bionic/pthread_setschedparam.cpp
@@ -27,9 +27,10 @@
  */
 
 #include <errno.h>
+#include <pthread.h>
+#include <sched.h>
 
 #include "private/ErrnoRestorer.h"
-#include "pthread_internal.h"
 
 int pthread_setschedparam(pthread_t t, int policy, const sched_param* param) {
   ErrnoRestorer errno_restorer;
@@ -39,3 +40,13 @@
 
   return (sched_setscheduler(tid, policy, param) == -1) ? errno : 0;
 }
+
+int pthread_setschedprio(pthread_t t, int priority) {
+  ErrnoRestorer errno_restorer;
+
+  pid_t tid = pthread_gettid_np(t);
+  if (tid == -1) return ESRCH;
+
+  sched_param param = { .sched_priority = priority };
+  return (sched_setparam(tid, &param) == -1) ? errno : 0;
+}
diff --git a/libc/bionic/pty.cpp b/libc/bionic/pty.cpp
index bdabf36..599cbd2 100644
--- a/libc/bionic/pty.cpp
+++ b/libc/bionic/pty.cpp
@@ -37,6 +37,7 @@
 #include <utmp.h>
 
 #include "bionic/pthread_internal.h"
+#include "private/FdPath.h"
 
 int getpt() {
   return posix_openpt(O_RDWR|O_NOCTTY);
@@ -94,10 +95,7 @@
     return errno;
   }
 
-  char path[64];
-  snprintf(path, sizeof(path), "/proc/self/fd/%d", fd);
-
-  ssize_t count = readlink(path, buf, len);
+  ssize_t count = readlink(FdPath(fd).c_str(), buf, len);
   if (count == -1) {
     return errno;
   }
diff --git a/libc/bionic/spawn.cpp b/libc/bionic/spawn.cpp
new file mode 100644
index 0000000..061d68c
--- /dev/null
+++ b/libc/bionic/spawn.cpp
@@ -0,0 +1,312 @@
+/*
+ * Copyright (C) 2017 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 <spawn.h>
+
+#include <errno.h>
+#include <fcntl.h>
+#include <signal.h>
+#include <stdlib.h>
+#include <string.h>
+#include <unistd.h>
+
+#include "private/ScopedSignalBlocker.h"
+
+enum Action {
+  kOpen,
+  kClose,
+  kDup2
+};
+
+struct __posix_spawn_file_action {
+  __posix_spawn_file_action* next;
+
+  Action what;
+  int fd;
+  int new_fd;
+  char* path;
+  int flags;
+  mode_t mode;
+
+  void Do() {
+    if (what == kOpen) {
+      fd = open(path, flags, mode);
+      if (fd == -1) _exit(127);
+      // If it didn't land where we wanted it, move it.
+      if (fd != new_fd) {
+        if (dup2(fd, new_fd) == -1) _exit(127);
+        close(fd);
+      }
+    } else if (what == kClose) {
+      // Failure to close is ignored.
+      close(fd);
+    } else {
+      if (dup2(fd, new_fd) == -1) _exit(127);
+    }
+  }
+};
+
+struct __posix_spawn_file_actions {
+  __posix_spawn_file_action* head;
+  __posix_spawn_file_action* last;
+
+  void Do() {
+    for (__posix_spawn_file_action* action = head; action != nullptr; action = action->next) {
+      action->Do();
+    }
+  }
+};
+
+struct __posix_spawnattr {
+  short flags;
+  pid_t pgroup;
+  sched_param schedparam;
+  int schedpolicy;
+  sigset_t sigmask;
+  sigset_t sigdefault;
+
+  void Do() {
+    if ((flags & POSIX_SPAWN_SETSIGDEF) != 0) {
+      // POSIX: "If POSIX_SPAWN_SETSIGDEF is set ... signals in sigdefault ... shall be set to
+      // their default actions in the child process."
+      struct sigaction sa = {};
+      sa.sa_handler = SIG_DFL;
+      for (int s = 1; s < _NSIG; ++s) {
+        if (sigismember(&sigdefault, s) && sigaction(s, &sa, nullptr) == -1) _exit(127);
+      }
+    }
+
+    if ((flags & POSIX_SPAWN_SETPGROUP) != 0 && setpgid(0, pgroup) == -1) _exit(127);
+    if ((flags & POSIX_SPAWN_SETSID) != 0 && setsid() == -1) _exit(127);
+
+    // POSIX_SPAWN_SETSCHEDULER overrides POSIX_SPAWN_SETSCHEDPARAM, but it is not an error
+    // to set both.
+    if ((flags & POSIX_SPAWN_SETSCHEDULER) != 0) {
+      if (sched_setscheduler(0, schedpolicy, &schedparam) == -1) _exit(127);
+    } else if ((flags & POSIX_SPAWN_SETSCHEDPARAM) != 0) {
+      if (sched_setparam(0, &schedparam) == -1) _exit(127);
+    }
+
+    if ((flags & POSIX_SPAWN_RESETIDS) != 0) {
+      if (seteuid(getuid()) == -1 || setegid(getgid()) == -1) _exit(127);
+    }
+
+    if ((flags & POSIX_SPAWN_SETSIGMASK) != 0) {
+      if (sigprocmask(SIG_SETMASK, &sigmask, nullptr)) _exit(127);
+    }
+  }
+};
+
+static int posix_spawn(pid_t* pid_ptr,
+                       const char* path,
+                       const posix_spawn_file_actions_t* actions,
+                       const posix_spawnattr_t* attr,
+                       char* const argv[],
+                       char* const env[],
+                       int exec_fn(const char* path, char* const argv[], char* const env[])) {
+  // See http://man7.org/linux/man-pages/man3/posix_spawn.3.html
+  // and http://pubs.opengroup.org/onlinepubs/9699919799/functions/posix_spawn.html
+
+  ScopedSignalBlocker ssb;
+
+  short flags = attr ? (*attr)->flags : 0;
+  bool use_vfork = ((flags & POSIX_SPAWN_USEVFORK) != 0) || (actions == nullptr && flags == 0);
+
+  pid_t pid = use_vfork ? vfork() : fork();
+  if (pid == -1) return errno;
+
+  if (pid == 0) {
+    // Child.
+    if (attr) (*attr)->Do();
+    if (actions) (*actions)->Do();
+    if ((flags & POSIX_SPAWN_SETSIGMASK) == 0) ssb.reset();
+    exec_fn(path, argv, env ? env : environ);
+    _exit(127);
+  }
+
+  // Parent.
+  if (pid_ptr) *pid_ptr = pid;
+  return 0;
+}
+
+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[]) {
+  return posix_spawn(pid, path, actions, attr, argv, env, execve);
+}
+
+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[]) {
+  return posix_spawn(pid, file, actions, attr, argv, env, execvpe);
+}
+
+int posix_spawnattr_init(posix_spawnattr_t* attr) {
+  *attr = reinterpret_cast<__posix_spawnattr*>(calloc(1, sizeof(__posix_spawnattr)));
+  return (*attr == nullptr) ? errno : 0;
+}
+
+int posix_spawnattr_destroy(posix_spawnattr_t* attr) {
+  free(*attr);
+  *attr = nullptr;
+  return 0;
+}
+
+int posix_spawnattr_setflags(posix_spawnattr_t* attr, short flags) {
+  if ((flags & ~(POSIX_SPAWN_RESETIDS | POSIX_SPAWN_SETPGROUP | POSIX_SPAWN_SETSIGDEF |
+                 POSIX_SPAWN_SETSIGMASK | POSIX_SPAWN_SETSCHEDPARAM | POSIX_SPAWN_SETSCHEDULER |
+                 POSIX_SPAWN_USEVFORK | POSIX_SPAWN_SETSID)) != 0) {
+    return EINVAL;
+  }
+  (*attr)->flags = flags;
+  return 0;
+}
+
+int posix_spawnattr_getflags(const posix_spawnattr_t* attr, short* flags) {
+  *flags = (*attr)->flags;
+  return 0;
+}
+
+int posix_spawnattr_setpgroup(posix_spawnattr_t* attr, pid_t pgroup) {
+  (*attr)->pgroup = pgroup;
+  return 0;
+}
+
+int posix_spawnattr_getpgroup(const posix_spawnattr_t* attr, pid_t* pgroup) {
+  *pgroup = (*attr)->pgroup;
+  return 0;
+}
+
+int posix_spawnattr_setsigmask(posix_spawnattr_t* attr, const sigset_t* mask) {
+  (*attr)->sigmask = *mask;
+  return 0;
+}
+
+int posix_spawnattr_getsigmask(const posix_spawnattr_t* attr, sigset_t* mask) {
+  *mask = (*attr)->sigmask;
+  return 0;
+}
+
+int posix_spawnattr_setsigdefault(posix_spawnattr_t* attr, const sigset_t* mask) {
+  (*attr)->sigdefault = *mask;
+  return 0;
+}
+
+int posix_spawnattr_getsigdefault(const posix_spawnattr_t* attr, sigset_t* mask) {
+  *mask = (*attr)->sigdefault;
+  return 0;
+}
+
+int posix_spawnattr_setschedparam(posix_spawnattr_t* attr, const struct sched_param* param) {
+  (*attr)->schedparam = *param;
+  return 0;
+}
+
+int posix_spawnattr_getschedparam(const posix_spawnattr_t* attr, struct sched_param* param) {
+  *param = (*attr)->schedparam;
+  return 0;
+}
+
+int posix_spawnattr_setschedpolicy(posix_spawnattr_t* attr, int policy) {
+  (*attr)->schedpolicy = policy;
+  return 0;
+}
+
+int posix_spawnattr_getschedpolicy(const posix_spawnattr_t* attr, int* policy) {
+  *policy = (*attr)->schedpolicy;
+  return 0;
+}
+
+int posix_spawn_file_actions_init(posix_spawn_file_actions_t* actions) {
+  *actions = reinterpret_cast<__posix_spawn_file_actions*>(calloc(1, sizeof(**actions)));
+  return (*actions == nullptr) ? errno : 0;
+}
+
+int posix_spawn_file_actions_destroy(posix_spawn_file_actions_t* actions) {
+  __posix_spawn_file_action* a = (*actions)->head;
+  while (a) {
+    __posix_spawn_file_action* last = a;
+    a = a->next;
+    free(last->path);
+    free(last);
+  }
+  free(*actions);
+  *actions = nullptr;
+  return 0;
+}
+
+static int posix_spawn_add_file_action(posix_spawn_file_actions_t* actions,
+                                       Action what,
+                                       int fd,
+                                       int new_fd,
+                                       const char* path,
+                                       int flags,
+                                       mode_t mode) {
+  __posix_spawn_file_action* action =
+      reinterpret_cast<__posix_spawn_file_action*>(malloc(sizeof(*action)));
+  if (action == nullptr) return errno;
+
+  action->next = nullptr;
+  if (path != nullptr) {
+    action->path = strdup(path);
+    if (action->path == nullptr) {
+      free(action);
+      return errno;
+    }
+  } else {
+    action->path = nullptr;
+  }
+  action->what = what;
+  action->fd = fd;
+  action->new_fd = new_fd;
+  action->flags = flags;
+  action->mode = mode;
+
+  if ((*actions)->head == nullptr) {
+    (*actions)->head = (*actions)->last = action;
+  } else {
+    (*actions)->last->next = action;
+    (*actions)->last = action;
+  }
+
+  return 0;
+}
+
+int posix_spawn_file_actions_addopen(posix_spawn_file_actions_t* actions,
+                                     int fd, const char* path, int flags, mode_t mode) {
+  if (fd < 0) return EBADF;
+  return posix_spawn_add_file_action(actions, kOpen, -1, fd, path, flags, mode);
+}
+
+int posix_spawn_file_actions_addclose(posix_spawn_file_actions_t* actions, int fd) {
+  if (fd < 0) return EBADF;
+  return posix_spawn_add_file_action(actions, kClose, fd, -1, nullptr, 0, 0);
+}
+
+int posix_spawn_file_actions_adddup2(posix_spawn_file_actions_t* actions, int fd, int new_fd) {
+  if (fd < 0 || new_fd < 0) return EBADF;
+  return posix_spawn_add_file_action(actions, kDup2, fd, new_fd, nullptr, 0, 0);
+}
diff --git a/libc/arch-arm64/include/machine/setjmp.h b/libc/bionic/swab.cpp
similarity index 76%
rename from libc/arch-arm64/include/machine/setjmp.h
rename to libc/bionic/swab.cpp
index 27c2fe5..bc53ba4 100644
--- a/libc/arch-arm64/include/machine/setjmp.h
+++ b/libc/bionic/swab.cpp
@@ -1,5 +1,5 @@
 /*
- * Copyright (C) 2013 The Android Open Source Project
+ * Copyright (C) 2017 The Android Open Source Project
  * All rights reserved.
  *
  * Redistribution and use in source and binary forms, with or without
@@ -26,5 +26,16 @@
  * SUCH DAMAGE.
  */
 
-/* _JBLEN is the size of a jmp_buf in longs (64bit on AArch64) */
-#define _JBLEN 32
+#include <unistd.h>
+
+void swab(const void* void_src, void* void_dst, ssize_t byte_count) {
+  const uint8_t* src = static_cast<const uint8_t*>(void_src);
+  uint8_t* dst = static_cast<uint8_t*>(void_dst);
+  while (byte_count > 1) {
+    uint8_t x = *src++;
+    uint8_t y = *src++;
+    *dst++ = y;
+    *dst++ = x;
+    byte_count -= 2;
+  }
+}
diff --git a/libc/bionic/sysconf.cpp b/libc/bionic/sysconf.cpp
index 7325dbd..2442fd9 100644
--- a/libc/bionic/sysconf.cpp
+++ b/libc/bionic/sysconf.cpp
@@ -52,9 +52,16 @@
     // Things we actually have to calculate...
     //
     case _SC_ARG_MAX:
-      // Not a constant since Linux 2.6.23; see fs/exec.c for details.
-      // At least 32 pages, otherwise a quarter of the stack limit.
-      return MAX(__sysconf_rlimit(RLIMIT_STACK) / 4, _KERNEL_ARG_MAX);
+      // https://lkml.org/lkml/2017/11/15/813...
+      //
+      // I suspect a 128kB sysconf(_SC_ARG_MAX) is the sanest bet, simply
+      // because of that "conservative is better than aggressive".
+      //
+      // Especially since _technically_ we're still limiting things to that
+      // 128kB due to the single-string limit.
+      //
+      //               Linus
+      return ARG_MAX;
 
     case _SC_AVPHYS_PAGES:      return get_avphys_pages();
     case _SC_CHILD_MAX:         return __sysconf_rlimit(RLIMIT_NPROC);
@@ -148,7 +155,7 @@
     case _SC_THREAD_PRIO_INHERIT: return _POSIX_THREAD_PRIO_INHERIT;
     case _SC_THREAD_PRIO_PROTECT: return _POSIX_THREAD_PRIO_PROTECT;
     case _SC_THREAD_SAFE_FUNCTIONS:  return _POSIX_THREAD_SAFE_FUNCTIONS;
-    case _SC_MONOTONIC_CLOCK:   return _POSIX_VERSION;
+    case _SC_MONOTONIC_CLOCK:   return _POSIX_MONOTONIC_CLOCK;
 
     case _SC_2_PBS:             return -1;     // Obsolescent in POSIX.1-2008.
     case _SC_2_PBS_ACCOUNTING:  return -1;     // Obsolescent in POSIX.1-2008.
@@ -159,7 +166,7 @@
     case _SC_ADVISORY_INFO:     return _POSIX_ADVISORY_INFO;
     case _SC_BARRIERS:          return _POSIX_BARRIERS;
     case _SC_CLOCK_SELECTION:   return _POSIX_CLOCK_SELECTION;
-    case _SC_CPUTIME:           return _POSIX_VERSION;
+    case _SC_CPUTIME:           return _POSIX_CPUTIME;
 
     case _SC_HOST_NAME_MAX:     return _POSIX_HOST_NAME_MAX;    // Minimum requirement.
     case _SC_IPV6:              return _POSIX_IPV6;
@@ -172,7 +179,7 @@
     case _SC_SPORADIC_SERVER:   return _POSIX_SPORADIC_SERVER;
     case _SC_SS_REPL_MAX:       return -1;
     case _SC_SYMLOOP_MAX:       return _POSIX_SYMLOOP_MAX;      // Minimum requirement.
-    case _SC_THREAD_CPUTIME:    return _POSIX_VERSION;
+    case _SC_THREAD_CPUTIME:    return _POSIX_THREAD_CPUTIME;
 
     case _SC_THREAD_PROCESS_SHARED: return _POSIX_THREAD_PROCESS_SHARED;
     case _SC_THREAD_ROBUST_PRIO_INHERIT:  return _POSIX_THREAD_ROBUST_PRIO_INHERIT;
diff --git a/libc/bionic/system_properties.cpp b/libc/bionic/system_properties.cpp
deleted file mode 100644
index c57cd9c..0000000
--- a/libc/bionic/system_properties.cpp
+++ /dev/null
@@ -1,1470 +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 <ctype.h>
-#include <errno.h>
-#include <fcntl.h>
-#include <poll.h>
-#include <stdatomic.h>
-#include <stddef.h>
-#include <stdint.h>
-#include <stdlib.h>
-#include <string.h>
-#include <unistd.h>
-#include <new>
-
-#include <linux/xattr.h>
-#include <netinet/in.h>
-#include <sys/mman.h>
-#include <sys/select.h>
-#include <sys/socket.h>
-#include <sys/stat.h>
-#include <sys/types.h>
-#include <sys/uio.h>
-#include <sys/un.h>
-#include <sys/xattr.h>
-
-#define _REALLY_INCLUDE_SYS__SYSTEM_PROPERTIES_H_
-#include <sys/_system_properties.h>
-#include <sys/system_properties.h>
-
-#include <async_safe/log.h>
-
-#include "private/ErrnoRestorer.h"
-#include "private/bionic_futex.h"
-#include "private/bionic_lock.h"
-#include "private/bionic_macros.h"
-#include "private/bionic_sdk_version.h"
-
-static constexpr int PROP_FILENAME_MAX = 1024;
-
-static constexpr uint32_t PROP_AREA_MAGIC = 0x504f5250;
-static constexpr uint32_t PROP_AREA_VERSION = 0xfc6ed0ab;
-
-static constexpr size_t PA_SIZE = 128 * 1024;
-
-#define SERIAL_DIRTY(serial) ((serial)&1)
-#define SERIAL_VALUE_LEN(serial) ((serial) >> 24)
-
-static const char property_service_socket[] = "/dev/socket/" PROP_SERVICE_NAME;
-static const char* kServiceVersionPropertyName = "ro.property_service.version";
-
-/*
- * Properties are stored in a hybrid trie/binary tree structure.
- * Each property's name is delimited at '.' characters, and the tokens are put
- * into a trie structure.  Siblings at each level of the trie are stored in a
- * binary tree.  For instance, "ro.secure"="1" could be stored as follows:
- *
- * +-----+   children    +----+   children    +--------+
- * |     |-------------->| ro |-------------->| secure |
- * +-----+               +----+               +--------+
- *                       /    \                /   |
- *                 left /      \ right   left /    |  prop   +===========+
- *                     v        v            v     +-------->| ro.secure |
- *                  +-----+   +-----+     +-----+            +-----------+
- *                  | net |   | sys |     | com |            |     1     |
- *                  +-----+   +-----+     +-----+            +===========+
- */
-
-// Represents a node in the trie.
-struct prop_bt {
-  uint32_t namelen;
-
-  // The property trie is updated only by the init process (single threaded) which provides
-  // property service. And it can be read by multiple threads at the same time.
-  // As the property trie is not protected by locks, we use atomic_uint_least32_t types for the
-  // left, right, children "pointers" in the trie node. To make sure readers who see the
-  // change of "pointers" can also notice the change of prop_bt structure contents pointed by
-  // the "pointers", we always use release-consume ordering pair when accessing these "pointers".
-
-  // prop "points" to prop_info structure if there is a propery associated with the trie node.
-  // Its situation is similar to the left, right, children "pointers". So we use
-  // atomic_uint_least32_t and release-consume ordering to protect it as well.
-
-  // We should also avoid rereading these fields redundantly, since not
-  // all processor implementations ensure that multiple loads from the
-  // same field are carried out in the right order.
-  atomic_uint_least32_t prop;
-
-  atomic_uint_least32_t left;
-  atomic_uint_least32_t right;
-
-  atomic_uint_least32_t children;
-
-  char name[0];
-
-  prop_bt(const char* name, const uint32_t name_length) {
-    this->namelen = name_length;
-    memcpy(this->name, name, name_length);
-    this->name[name_length] = '\0';
-  }
-
- private:
-  DISALLOW_COPY_AND_ASSIGN(prop_bt);
-};
-
-class prop_area {
- public:
-  prop_area(const uint32_t magic, const uint32_t version) : magic_(magic), version_(version) {
-    atomic_init(&serial_, 0);
-    memset(reserved_, 0, sizeof(reserved_));
-    // Allocate enough space for the root node.
-    bytes_used_ = sizeof(prop_bt);
-  }
-
-  const prop_info* find(const char* name);
-  bool add(const char* name, unsigned int namelen, const char* value, unsigned int valuelen);
-
-  bool foreach (void (*propfn)(const prop_info* pi, void* cookie), void* cookie);
-
-  atomic_uint_least32_t* serial() {
-    return &serial_;
-  }
-  uint32_t magic() const {
-    return magic_;
-  }
-  uint32_t version() const {
-    return version_;
-  }
-
- private:
-  void* allocate_obj(const size_t size, uint_least32_t* const off);
-  prop_bt* new_prop_bt(const char* name, uint32_t namelen, uint_least32_t* const off);
-  prop_info* new_prop_info(const char* name, uint32_t namelen, const char* value, uint32_t valuelen,
-                           uint_least32_t* const off);
-  void* to_prop_obj(uint_least32_t off);
-  prop_bt* to_prop_bt(atomic_uint_least32_t* off_p);
-  prop_info* to_prop_info(atomic_uint_least32_t* off_p);
-
-  prop_bt* root_node();
-
-  prop_bt* find_prop_bt(prop_bt* const bt, const char* name, uint32_t namelen, bool alloc_if_needed);
-
-  const prop_info* find_property(prop_bt* const trie, const char* name, uint32_t namelen,
-                                 const char* value, uint32_t valuelen, bool alloc_if_needed);
-
-  bool foreach_property(prop_bt* const trie, void (*propfn)(const prop_info* pi, void* cookie),
-                        void* cookie);
-
-  uint32_t bytes_used_;
-  atomic_uint_least32_t serial_;
-  uint32_t magic_;
-  uint32_t version_;
-  uint32_t reserved_[28];
-  char data_[0];
-
-  DISALLOW_COPY_AND_ASSIGN(prop_area);
-};
-
-struct prop_info {
-  atomic_uint_least32_t serial;
-  // we need to keep this buffer around because the property
-  // value can be modified whereas name is constant.
-  char value[PROP_VALUE_MAX];
-  char name[0];
-
-  prop_info(const char* name, uint32_t namelen, const char* value, uint32_t valuelen) {
-    memcpy(this->name, name, namelen);
-    this->name[namelen] = '\0';
-    atomic_init(&this->serial, valuelen << 24);
-    memcpy(this->value, value, valuelen);
-    this->value[valuelen] = '\0';
-  }
-
- private:
-  DISALLOW_IMPLICIT_CONSTRUCTORS(prop_info);
-};
-
-// This is public because it was exposed in the NDK. As of 2017-01, ~60 apps reference this symbol.
-prop_area* __system_property_area__ = nullptr;
-
-static char property_filename[PROP_FILENAME_MAX] = PROP_FILENAME;
-static size_t pa_data_size;
-static size_t pa_size;
-static bool initialized = false;
-
-static prop_area* map_prop_area_rw(const char* filename, const char* context,
-                                   bool* fsetxattr_failed) {
-  /* dev is a tmpfs that we can use to carve a shared workspace
-   * out of, so let's do that...
-   */
-  const int fd = open(filename, O_RDWR | O_CREAT | O_NOFOLLOW | O_CLOEXEC | O_EXCL, 0444);
-
-  if (fd < 0) {
-    if (errno == EACCES) {
-      /* for consistency with the case where the process has already
-       * mapped the page in and segfaults when trying to write to it
-       */
-      abort();
-    }
-    return nullptr;
-  }
-
-  if (context) {
-    if (fsetxattr(fd, XATTR_NAME_SELINUX, context, strlen(context) + 1, 0) != 0) {
-      async_safe_format_log(ANDROID_LOG_ERROR, "libc",
-                            "fsetxattr failed to set context (%s) for \"%s\"", context, filename);
-      /*
-       * fsetxattr() will fail during system properties tests due to selinux policy.
-       * We do not want to create a custom policy for the tester, so we will continue in
-       * this function but set a flag that an error has occurred.
-       * Init, which is the only daemon that should ever call this function will abort
-       * when this error occurs.
-       * Otherwise, the tester will ignore it and continue, albeit without any selinux
-       * property separation.
-       */
-      if (fsetxattr_failed) {
-        *fsetxattr_failed = true;
-      }
-    }
-  }
-
-  if (ftruncate(fd, PA_SIZE) < 0) {
-    close(fd);
-    return nullptr;
-  }
-
-  pa_size = PA_SIZE;
-  pa_data_size = pa_size - sizeof(prop_area);
-
-  void* const memory_area = mmap(nullptr, pa_size, PROT_READ | PROT_WRITE, MAP_SHARED, fd, 0);
-  if (memory_area == MAP_FAILED) {
-    close(fd);
-    return nullptr;
-  }
-
-  prop_area* pa = new (memory_area) prop_area(PROP_AREA_MAGIC, PROP_AREA_VERSION);
-
-  close(fd);
-  return pa;
-}
-
-static prop_area* map_fd_ro(const int fd) {
-  struct stat fd_stat;
-  if (fstat(fd, &fd_stat) < 0) {
-    return nullptr;
-  }
-
-  if ((fd_stat.st_uid != 0) || (fd_stat.st_gid != 0) ||
-      ((fd_stat.st_mode & (S_IWGRP | S_IWOTH)) != 0) ||
-      (fd_stat.st_size < static_cast<off_t>(sizeof(prop_area)))) {
-    return nullptr;
-  }
-
-  pa_size = fd_stat.st_size;
-  pa_data_size = pa_size - sizeof(prop_area);
-
-  void* const map_result = mmap(nullptr, pa_size, PROT_READ, MAP_SHARED, fd, 0);
-  if (map_result == MAP_FAILED) {
-    return nullptr;
-  }
-
-  prop_area* pa = reinterpret_cast<prop_area*>(map_result);
-  if ((pa->magic() != PROP_AREA_MAGIC) || (pa->version() != PROP_AREA_VERSION)) {
-    munmap(pa, pa_size);
-    return nullptr;
-  }
-
-  return pa;
-}
-
-static prop_area* map_prop_area(const char* filename) {
-  int fd = open(filename, O_CLOEXEC | O_NOFOLLOW | O_RDONLY);
-  if (fd == -1) return nullptr;
-
-  prop_area* map_result = map_fd_ro(fd);
-  close(fd);
-
-  return map_result;
-}
-
-void* prop_area::allocate_obj(const size_t size, uint_least32_t* const off) {
-  const size_t aligned = BIONIC_ALIGN(size, sizeof(uint_least32_t));
-  if (bytes_used_ + aligned > pa_data_size) {
-    return nullptr;
-  }
-
-  *off = bytes_used_;
-  bytes_used_ += aligned;
-  return data_ + *off;
-}
-
-prop_bt* prop_area::new_prop_bt(const char* name, uint32_t namelen, uint_least32_t* const off) {
-  uint_least32_t new_offset;
-  void* const p = allocate_obj(sizeof(prop_bt) + namelen + 1, &new_offset);
-  if (p != nullptr) {
-    prop_bt* bt = new (p) prop_bt(name, namelen);
-    *off = new_offset;
-    return bt;
-  }
-
-  return nullptr;
-}
-
-prop_info* prop_area::new_prop_info(const char* name, uint32_t namelen, const char* value,
-                                    uint32_t valuelen, uint_least32_t* const off) {
-  uint_least32_t new_offset;
-  void* const p = allocate_obj(sizeof(prop_info) + namelen + 1, &new_offset);
-  if (p != nullptr) {
-    prop_info* info = new (p) prop_info(name, namelen, value, valuelen);
-    *off = new_offset;
-    return info;
-  }
-
-  return nullptr;
-}
-
-void* prop_area::to_prop_obj(uint_least32_t off) {
-  if (off > pa_data_size) return nullptr;
-
-  return (data_ + off);
-}
-
-inline prop_bt* prop_area::to_prop_bt(atomic_uint_least32_t* off_p) {
-  uint_least32_t off = atomic_load_explicit(off_p, memory_order_consume);
-  return reinterpret_cast<prop_bt*>(to_prop_obj(off));
-}
-
-inline prop_info* prop_area::to_prop_info(atomic_uint_least32_t* off_p) {
-  uint_least32_t off = atomic_load_explicit(off_p, memory_order_consume);
-  return reinterpret_cast<prop_info*>(to_prop_obj(off));
-}
-
-inline prop_bt* prop_area::root_node() {
-  return reinterpret_cast<prop_bt*>(to_prop_obj(0));
-}
-
-static int cmp_prop_name(const char* one, uint32_t one_len, const char* two, uint32_t two_len) {
-  if (one_len < two_len)
-    return -1;
-  else if (one_len > two_len)
-    return 1;
-  else
-    return strncmp(one, two, one_len);
-}
-
-prop_bt* prop_area::find_prop_bt(prop_bt* const bt, const char* name, uint32_t namelen,
-                                 bool alloc_if_needed) {
-  prop_bt* current = bt;
-  while (true) {
-    if (!current) {
-      return nullptr;
-    }
-
-    const int ret = cmp_prop_name(name, namelen, current->name, current->namelen);
-    if (ret == 0) {
-      return current;
-    }
-
-    if (ret < 0) {
-      uint_least32_t left_offset = atomic_load_explicit(&current->left, memory_order_relaxed);
-      if (left_offset != 0) {
-        current = to_prop_bt(&current->left);
-      } else {
-        if (!alloc_if_needed) {
-          return nullptr;
-        }
-
-        uint_least32_t new_offset;
-        prop_bt* new_bt = new_prop_bt(name, namelen, &new_offset);
-        if (new_bt) {
-          atomic_store_explicit(&current->left, new_offset, memory_order_release);
-        }
-        return new_bt;
-      }
-    } else {
-      uint_least32_t right_offset = atomic_load_explicit(&current->right, memory_order_relaxed);
-      if (right_offset != 0) {
-        current = to_prop_bt(&current->right);
-      } else {
-        if (!alloc_if_needed) {
-          return nullptr;
-        }
-
-        uint_least32_t new_offset;
-        prop_bt* new_bt = new_prop_bt(name, namelen, &new_offset);
-        if (new_bt) {
-          atomic_store_explicit(&current->right, new_offset, memory_order_release);
-        }
-        return new_bt;
-      }
-    }
-  }
-}
-
-const prop_info* prop_area::find_property(prop_bt* const trie, const char* name, uint32_t namelen,
-                                          const char* value, uint32_t valuelen,
-                                          bool alloc_if_needed) {
-  if (!trie) return nullptr;
-
-  const char* remaining_name = name;
-  prop_bt* current = trie;
-  while (true) {
-    const char* sep = strchr(remaining_name, '.');
-    const bool want_subtree = (sep != nullptr);
-    const uint32_t substr_size = (want_subtree) ? sep - remaining_name : strlen(remaining_name);
-
-    if (!substr_size) {
-      return nullptr;
-    }
-
-    prop_bt* root = nullptr;
-    uint_least32_t children_offset = atomic_load_explicit(&current->children, memory_order_relaxed);
-    if (children_offset != 0) {
-      root = to_prop_bt(&current->children);
-    } else if (alloc_if_needed) {
-      uint_least32_t new_offset;
-      root = new_prop_bt(remaining_name, substr_size, &new_offset);
-      if (root) {
-        atomic_store_explicit(&current->children, new_offset, memory_order_release);
-      }
-    }
-
-    if (!root) {
-      return nullptr;
-    }
-
-    current = find_prop_bt(root, remaining_name, substr_size, alloc_if_needed);
-    if (!current) {
-      return nullptr;
-    }
-
-    if (!want_subtree) break;
-
-    remaining_name = sep + 1;
-  }
-
-  uint_least32_t prop_offset = atomic_load_explicit(&current->prop, memory_order_relaxed);
-  if (prop_offset != 0) {
-    return to_prop_info(&current->prop);
-  } else if (alloc_if_needed) {
-    uint_least32_t new_offset;
-    prop_info* new_info = new_prop_info(name, namelen, value, valuelen, &new_offset);
-    if (new_info) {
-      atomic_store_explicit(&current->prop, new_offset, memory_order_release);
-    }
-
-    return new_info;
-  } else {
-    return nullptr;
-  }
-}
-
-class PropertyServiceConnection {
- public:
-  PropertyServiceConnection() : last_error_(0) {
-    socket_ = ::socket(AF_LOCAL, SOCK_STREAM | SOCK_CLOEXEC, 0);
-    if (socket_ == -1) {
-      last_error_ = errno;
-      return;
-    }
-
-    const size_t namelen = strlen(property_service_socket);
-    sockaddr_un addr;
-    memset(&addr, 0, sizeof(addr));
-    strlcpy(addr.sun_path, property_service_socket, sizeof(addr.sun_path));
-    addr.sun_family = AF_LOCAL;
-    socklen_t alen = namelen + offsetof(sockaddr_un, sun_path) + 1;
-
-    if (TEMP_FAILURE_RETRY(connect(socket_, reinterpret_cast<sockaddr*>(&addr), alen)) == -1) {
-      last_error_ = errno;
-      close(socket_);
-      socket_ = -1;
-    }
-  }
-
-  bool IsValid() {
-    return socket_ != -1;
-  }
-
-  int GetLastError() {
-    return last_error_;
-  }
-
-  bool RecvInt32(int32_t* value) {
-    int result = TEMP_FAILURE_RETRY(recv(socket_, value, sizeof(*value), MSG_WAITALL));
-    return CheckSendRecvResult(result, sizeof(*value));
-  }
-
-  int socket() {
-    return socket_;
-  }
-
-  ~PropertyServiceConnection() {
-    if (socket_ != -1) {
-      close(socket_);
-    }
-  }
-
- private:
-  bool CheckSendRecvResult(int result, int expected_len) {
-    if (result == -1) {
-      last_error_ = errno;
-    } else if (result != expected_len) {
-      last_error_ = -1;
-    } else {
-      last_error_ = 0;
-    }
-
-    return last_error_ == 0;
-  }
-
-  int socket_;
-  int last_error_;
-
-  friend class SocketWriter;
-};
-
-class SocketWriter {
- public:
-  explicit SocketWriter(PropertyServiceConnection* connection)
-      : connection_(connection), iov_index_(0), uint_buf_index_(0)
-  {}
-
-  SocketWriter& WriteUint32(uint32_t value) {
-    CHECK(uint_buf_index_ < kUintBufSize);
-    CHECK(iov_index_ < kIovSize);
-    uint32_t* ptr = uint_buf_ + uint_buf_index_;
-    uint_buf_[uint_buf_index_++] = value;
-    iov_[iov_index_].iov_base = ptr;
-    iov_[iov_index_].iov_len = sizeof(*ptr);
-    ++iov_index_;
-    return *this;
-  }
-
-  SocketWriter& WriteString(const char* value) {
-    uint32_t valuelen = strlen(value);
-    WriteUint32(valuelen);
-    if (valuelen == 0) {
-      return *this;
-    }
-
-    CHECK(iov_index_ < kIovSize);
-    iov_[iov_index_].iov_base = const_cast<char*>(value);
-    iov_[iov_index_].iov_len = valuelen;
-    ++iov_index_;
-
-    return *this;
-  }
-
-  bool Send() {
-    if (!connection_->IsValid()) {
-      return false;
-    }
-
-    if (writev(connection_->socket(), iov_, iov_index_) == -1) {
-      connection_->last_error_ = errno;
-      return false;
-    }
-
-    iov_index_ = uint_buf_index_ = 0;
-    return true;
-  }
-
- private:
-  static constexpr size_t kUintBufSize = 8;
-  static constexpr size_t kIovSize = 8;
-
-  PropertyServiceConnection* connection_;
-  iovec iov_[kIovSize];
-  size_t iov_index_;
-  uint32_t uint_buf_[kUintBufSize];
-  size_t uint_buf_index_;
-
-  DISALLOW_IMPLICIT_CONSTRUCTORS(SocketWriter);
-};
-
-struct prop_msg {
-  unsigned cmd;
-  char name[PROP_NAME_MAX];
-  char value[PROP_VALUE_MAX];
-};
-
-static int send_prop_msg(const prop_msg* msg) {
-  PropertyServiceConnection connection;
-  if (!connection.IsValid()) {
-    return connection.GetLastError();
-  }
-
-  int result = -1;
-  int s = connection.socket();
-
-  const int num_bytes = TEMP_FAILURE_RETRY(send(s, msg, sizeof(prop_msg), 0));
-  if (num_bytes == sizeof(prop_msg)) {
-    // We successfully wrote to the property server but now we
-    // wait for the property server to finish its work.  It
-    // acknowledges its completion by closing the socket so we
-    // poll here (on nothing), waiting for the socket to close.
-    // If you 'adb shell setprop foo bar' you'll see the POLLHUP
-    // once the socket closes.  Out of paranoia we cap our poll
-    // at 250 ms.
-    pollfd pollfds[1];
-    pollfds[0].fd = s;
-    pollfds[0].events = 0;
-    const int poll_result = TEMP_FAILURE_RETRY(poll(pollfds, 1, 250 /* ms */));
-    if (poll_result == 1 && (pollfds[0].revents & POLLHUP) != 0) {
-      result = 0;
-    } else {
-      // Ignore the timeout and treat it like a success anyway.
-      // The init process is single-threaded and its property
-      // service is sometimes slow to respond (perhaps it's off
-      // starting a child process or something) and thus this
-      // times out and the caller thinks it failed, even though
-      // it's still getting around to it.  So we fake it here,
-      // mostly for ctl.* properties, but we do try and wait 250
-      // ms so callers who do read-after-write can reliably see
-      // what they've written.  Most of the time.
-      // TODO: fix the system properties design.
-      async_safe_format_log(ANDROID_LOG_WARN, "libc",
-                            "Property service has timed out while trying to set \"%s\" to \"%s\"",
-                            msg->name, msg->value);
-      result = 0;
-    }
-  }
-
-  return result;
-}
-
-bool prop_area::foreach_property(prop_bt* const trie,
-                                 void (*propfn)(const prop_info* pi, void* cookie), void* cookie) {
-  if (!trie) return false;
-
-  uint_least32_t left_offset = atomic_load_explicit(&trie->left, memory_order_relaxed);
-  if (left_offset != 0) {
-    const int err = foreach_property(to_prop_bt(&trie->left), propfn, cookie);
-    if (err < 0) return false;
-  }
-  uint_least32_t prop_offset = atomic_load_explicit(&trie->prop, memory_order_relaxed);
-  if (prop_offset != 0) {
-    prop_info* info = to_prop_info(&trie->prop);
-    if (!info) return false;
-    propfn(info, cookie);
-  }
-  uint_least32_t children_offset = atomic_load_explicit(&trie->children, memory_order_relaxed);
-  if (children_offset != 0) {
-    const int err = foreach_property(to_prop_bt(&trie->children), propfn, cookie);
-    if (err < 0) return false;
-  }
-  uint_least32_t right_offset = atomic_load_explicit(&trie->right, memory_order_relaxed);
-  if (right_offset != 0) {
-    const int err = foreach_property(to_prop_bt(&trie->right), propfn, cookie);
-    if (err < 0) return false;
-  }
-
-  return true;
-}
-
-const prop_info* prop_area::find(const char* name) {
-  return find_property(root_node(), name, strlen(name), nullptr, 0, false);
-}
-
-bool prop_area::add(const char* name, unsigned int namelen, const char* value,
-                    unsigned int valuelen) {
-  return find_property(root_node(), name, namelen, value, valuelen, true);
-}
-
-bool prop_area::foreach (void (*propfn)(const prop_info* pi, void* cookie), void* cookie) {
-  return foreach_property(root_node(), propfn, cookie);
-}
-
-class context_node {
- public:
-  context_node(context_node* next, const char* context, prop_area* pa)
-      : next(next), context_(strdup(context)), pa_(pa), no_access_(false) {
-    lock_.init(false);
-  }
-  ~context_node() {
-    unmap();
-    free(context_);
-  }
-  bool open(bool access_rw, bool* fsetxattr_failed);
-  bool check_access_and_open();
-  void reset_access();
-
-  const char* context() const {
-    return context_;
-  }
-  prop_area* pa() {
-    return pa_;
-  }
-
-  context_node* next;
-
- private:
-  bool check_access();
-  void unmap();
-
-  Lock lock_;
-  char* context_;
-  prop_area* pa_;
-  bool no_access_;
-};
-
-struct prefix_node {
-  prefix_node(struct prefix_node* next, const char* prefix, context_node* context)
-      : prefix(strdup(prefix)), prefix_len(strlen(prefix)), context(context), next(next) {
-  }
-  ~prefix_node() {
-    free(prefix);
-  }
-  char* prefix;
-  const size_t prefix_len;
-  context_node* context;
-  struct prefix_node* next;
-};
-
-template <typename List, typename... Args>
-static inline void list_add(List** list, Args... args) {
-  *list = new List(*list, args...);
-}
-
-static void list_add_after_len(prefix_node** list, const char* prefix, context_node* context) {
-  size_t prefix_len = strlen(prefix);
-
-  auto next_list = list;
-
-  while (*next_list) {
-    if ((*next_list)->prefix_len < prefix_len || (*next_list)->prefix[0] == '*') {
-      list_add(next_list, prefix, context);
-      return;
-    }
-    next_list = &(*next_list)->next;
-  }
-  list_add(next_list, prefix, context);
-}
-
-template <typename List, typename Func>
-static void list_foreach(List* list, Func func) {
-  while (list) {
-    func(list);
-    list = list->next;
-  }
-}
-
-template <typename List, typename Func>
-static List* list_find(List* list, Func func) {
-  while (list) {
-    if (func(list)) {
-      return list;
-    }
-    list = list->next;
-  }
-  return nullptr;
-}
-
-template <typename List>
-static void list_free(List** list) {
-  while (*list) {
-    auto old_list = *list;
-    *list = old_list->next;
-    delete old_list;
-  }
-}
-
-static prefix_node* prefixes = nullptr;
-static context_node* contexts = nullptr;
-
-/*
- * pthread_mutex_lock() calls into system_properties in the case of contention.
- * This creates a risk of dead lock if any system_properties functions
- * use pthread locks after system_property initialization.
- *
- * For this reason, the below three functions use a bionic Lock and static
- * allocation of memory for each filename.
- */
-
-bool context_node::open(bool access_rw, bool* fsetxattr_failed) {
-  lock_.lock();
-  if (pa_) {
-    lock_.unlock();
-    return true;
-  }
-
-  char filename[PROP_FILENAME_MAX];
-  int len = async_safe_format_buffer(filename, sizeof(filename), "%s/%s", property_filename,
-                                     context_);
-  if (len < 0 || len > PROP_FILENAME_MAX) {
-    lock_.unlock();
-    return false;
-  }
-
-  if (access_rw) {
-    pa_ = map_prop_area_rw(filename, context_, fsetxattr_failed);
-  } else {
-    pa_ = map_prop_area(filename);
-  }
-  lock_.unlock();
-  return pa_;
-}
-
-bool context_node::check_access_and_open() {
-  if (!pa_ && !no_access_) {
-    if (!check_access() || !open(false, nullptr)) {
-      no_access_ = true;
-    }
-  }
-  return pa_;
-}
-
-void context_node::reset_access() {
-  if (!check_access()) {
-    unmap();
-    no_access_ = true;
-  } else {
-    no_access_ = false;
-  }
-}
-
-bool context_node::check_access() {
-  char filename[PROP_FILENAME_MAX];
-  int len = async_safe_format_buffer(filename, sizeof(filename), "%s/%s", property_filename,
-                                     context_);
-  if (len < 0 || len > PROP_FILENAME_MAX) {
-    return false;
-  }
-
-  return access(filename, R_OK) == 0;
-}
-
-void context_node::unmap() {
-  if (!pa_) {
-    return;
-  }
-
-  munmap(pa_, pa_size);
-  if (pa_ == __system_property_area__) {
-    __system_property_area__ = nullptr;
-  }
-  pa_ = nullptr;
-}
-
-static bool map_system_property_area(bool access_rw, bool* fsetxattr_failed) {
-  char filename[PROP_FILENAME_MAX];
-  int len =
-      async_safe_format_buffer(filename, sizeof(filename), "%s/properties_serial",
-                               property_filename);
-  if (len < 0 || len > PROP_FILENAME_MAX) {
-    __system_property_area__ = nullptr;
-    return false;
-  }
-
-  if (access_rw) {
-    __system_property_area__ =
-        map_prop_area_rw(filename, "u:object_r:properties_serial:s0", fsetxattr_failed);
-  } else {
-    __system_property_area__ = map_prop_area(filename);
-  }
-  return __system_property_area__;
-}
-
-static prop_area* get_prop_area_for_name(const char* name) {
-  auto entry = list_find(prefixes, [name](prefix_node* l) {
-    return l->prefix[0] == '*' || !strncmp(l->prefix, name, l->prefix_len);
-  });
-  if (!entry) {
-    return nullptr;
-  }
-
-  auto cnode = entry->context;
-  if (!cnode->pa()) {
-    /*
-     * We explicitly do not check no_access_ in this case because unlike the
-     * case of foreach(), we want to generate an selinux audit for each
-     * non-permitted property access in this function.
-     */
-    cnode->open(false, nullptr);
-  }
-  return cnode->pa();
-}
-
-/*
- * The below two functions are duplicated from label_support.c in libselinux.
- * TODO: Find a location suitable for these functions such that both libc and
- * libselinux can share a common source file.
- */
-
-/*
- * The read_spec_entries and read_spec_entry functions may be used to
- * replace sscanf to read entries from spec files. The file and
- * property services now use these.
- */
-
-/* Read an entry from a spec file (e.g. file_contexts) */
-static inline int read_spec_entry(char** entry, char** ptr, int* len) {
-  *entry = nullptr;
-  char* tmp_buf = nullptr;
-
-  while (isspace(**ptr) && **ptr != '\0') (*ptr)++;
-
-  tmp_buf = *ptr;
-  *len = 0;
-
-  while (!isspace(**ptr) && **ptr != '\0') {
-    (*ptr)++;
-    (*len)++;
-  }
-
-  if (*len) {
-    *entry = strndup(tmp_buf, *len);
-    if (!*entry) return -1;
-  }
-
-  return 0;
-}
-
-/*
- * line_buf - Buffer containing the spec entries .
- * num_args - The number of spec parameter entries to process.
- * ...      - A 'char **spec_entry' for each parameter.
- * returns  - The number of items processed.
- *
- * This function calls read_spec_entry() to do the actual string processing.
- */
-static int read_spec_entries(char* line_buf, int num_args, ...) {
-  char **spec_entry, *buf_p;
-  int len, rc, items, entry_len = 0;
-  va_list ap;
-
-  len = strlen(line_buf);
-  if (line_buf[len - 1] == '\n')
-    line_buf[len - 1] = '\0';
-  else
-    /* Handle case if line not \n terminated by bumping
-     * the len for the check below (as the line is NUL
-     * terminated by getline(3)) */
-    len++;
-
-  buf_p = line_buf;
-  while (isspace(*buf_p)) buf_p++;
-
-  /* Skip comment lines and empty lines. */
-  if (*buf_p == '#' || *buf_p == '\0') return 0;
-
-  /* Process the spec file entries */
-  va_start(ap, num_args);
-
-  items = 0;
-  while (items < num_args) {
-    spec_entry = va_arg(ap, char**);
-
-    if (len - 1 == buf_p - line_buf) {
-      va_end(ap);
-      return items;
-    }
-
-    rc = read_spec_entry(spec_entry, &buf_p, &entry_len);
-    if (rc < 0) {
-      va_end(ap);
-      return rc;
-    }
-    if (entry_len) items++;
-  }
-  va_end(ap);
-  return items;
-}
-
-static bool initialize_properties_from_file(const char* filename) {
-  FILE* file = fopen(filename, "re");
-  if (!file) {
-    return false;
-  }
-
-  char* buffer = nullptr;
-  size_t line_len;
-  char* prop_prefix = nullptr;
-  char* context = nullptr;
-
-  while (getline(&buffer, &line_len, file) > 0) {
-    int items = read_spec_entries(buffer, 2, &prop_prefix, &context);
-    if (items <= 0) {
-      continue;
-    }
-    if (items == 1) {
-      free(prop_prefix);
-      continue;
-    }
-    /*
-     * init uses ctl.* properties as an IPC mechanism and does not write them
-     * to a property file, therefore we do not need to create property files
-     * to store them.
-     */
-    if (!strncmp(prop_prefix, "ctl.", 4)) {
-      free(prop_prefix);
-      free(context);
-      continue;
-    }
-
-    auto old_context =
-        list_find(contexts, [context](context_node* l) { return !strcmp(l->context(), context); });
-    if (old_context) {
-      list_add_after_len(&prefixes, prop_prefix, old_context);
-    } else {
-      list_add(&contexts, context, nullptr);
-      list_add_after_len(&prefixes, prop_prefix, contexts);
-    }
-    free(prop_prefix);
-    free(context);
-  }
-
-  free(buffer);
-  fclose(file);
-
-  return true;
-}
-
-static bool initialize_properties() {
-  // If we do find /property_contexts, then this is being
-  // run as part of the OTA updater on older release that had
-  // /property_contexts - b/34370523
-  if (initialize_properties_from_file("/property_contexts")) {
-    return true;
-  }
-
-  // Use property_contexts from /system & /vendor, fall back to those from /
-  if (access("/system/etc/selinux/plat_property_contexts", R_OK) != -1) {
-    if (!initialize_properties_from_file("/system/etc/selinux/plat_property_contexts")) {
-      return false;
-    }
-    // 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.
-    initialize_properties_from_file("/vendor/etc/selinux/nonplat_property_contexts");
-  } else {
-    if (!initialize_properties_from_file("/plat_property_contexts")) {
-      return false;
-    }
-    initialize_properties_from_file("/nonplat_property_contexts");
-  }
-
-  return true;
-}
-
-static bool is_dir(const char* pathname) {
-  struct stat info;
-  if (stat(pathname, &info) == -1) {
-    return false;
-  }
-  return S_ISDIR(info.st_mode);
-}
-
-static void free_and_unmap_contexts() {
-  list_free(&prefixes);
-  list_free(&contexts);
-  if (__system_property_area__) {
-    munmap(__system_property_area__, pa_size);
-    __system_property_area__ = nullptr;
-  }
-}
-
-int __system_properties_init() {
-  // This is called from __libc_init_common, and should leave errno at 0 (http://b/37248982).
-  ErrnoRestorer errno_restorer;
-
-  if (initialized) {
-    list_foreach(contexts, [](context_node* l) { l->reset_access(); });
-    return 0;
-  }
-  if (is_dir(property_filename)) {
-    if (!initialize_properties()) {
-      return -1;
-    }
-    if (!map_system_property_area(false, nullptr)) {
-      free_and_unmap_contexts();
-      return -1;
-    }
-  } else {
-    __system_property_area__ = map_prop_area(property_filename);
-    if (!__system_property_area__) {
-      return -1;
-    }
-    list_add(&contexts, "legacy_system_prop_area", __system_property_area__);
-    list_add_after_len(&prefixes, "*", contexts);
-  }
-  initialized = true;
-  return 0;
-}
-
-int __system_property_set_filename(const char* filename) {
-  size_t len = strlen(filename);
-  if (len >= sizeof(property_filename)) return -1;
-
-  strcpy(property_filename, filename);
-  return 0;
-}
-
-int __system_property_area_init() {
-  free_and_unmap_contexts();
-  mkdir(property_filename, S_IRWXU | S_IXGRP | S_IXOTH);
-  if (!initialize_properties()) {
-    return -1;
-  }
-  bool open_failed = false;
-  bool fsetxattr_failed = false;
-  list_foreach(contexts, [&fsetxattr_failed, &open_failed](context_node* l) {
-    if (!l->open(true, &fsetxattr_failed)) {
-      open_failed = true;
-    }
-  });
-  if (open_failed || !map_system_property_area(true, &fsetxattr_failed)) {
-    free_and_unmap_contexts();
-    return -1;
-  }
-  initialized = true;
-  return fsetxattr_failed ? -2 : 0;
-}
-
-uint32_t __system_property_area_serial() {
-  prop_area* pa = __system_property_area__;
-  if (!pa) {
-    return -1;
-  }
-  // Make sure this read fulfilled before __system_property_serial
-  return atomic_load_explicit(pa->serial(), memory_order_acquire);
-}
-
-const prop_info* __system_property_find(const char* name) {
-  if (!__system_property_area__) {
-    return nullptr;
-  }
-
-  prop_area* pa = get_prop_area_for_name(name);
-  if (!pa) {
-    async_safe_format_log(ANDROID_LOG_ERROR, "libc", "Access denied finding property \"%s\"", name);
-    return nullptr;
-  }
-
-  return pa->find(name);
-}
-
-// The C11 standard doesn't allow atomic loads from const fields,
-// though C++11 does.  Fudge it until standards get straightened out.
-static inline uint_least32_t load_const_atomic(const atomic_uint_least32_t* s, memory_order mo) {
-  atomic_uint_least32_t* non_const_s = const_cast<atomic_uint_least32_t*>(s);
-  return atomic_load_explicit(non_const_s, mo);
-}
-
-int __system_property_read(const prop_info* pi, char* name, char* value) {
-  while (true) {
-    uint32_t serial = __system_property_serial(pi);  // acquire semantics
-    size_t len = SERIAL_VALUE_LEN(serial);
-    memcpy(value, pi->value, len + 1);
-    // TODO: Fix the synchronization scheme here.
-    // There is no fully supported way to implement this kind
-    // of synchronization in C++11, since the memcpy races with
-    // updates to pi, and the data being accessed is not atomic.
-    // The following fence is unintuitive, but would be the
-    // correct one if memcpy used memory_order_relaxed atomic accesses.
-    // In practice it seems unlikely that the generated code would
-    // would be any different, so this should be OK.
-    atomic_thread_fence(memory_order_acquire);
-    if (serial == load_const_atomic(&(pi->serial), memory_order_relaxed)) {
-      if (name != nullptr) {
-        size_t namelen = strlcpy(name, pi->name, PROP_NAME_MAX);
-        if (namelen >= PROP_NAME_MAX) {
-          async_safe_format_log(ANDROID_LOG_ERROR, "libc",
-                                "The property name length for \"%s\" is >= %d;"
-                                " please use __system_property_read_callback"
-                                " to read this property. (the name is truncated to \"%s\")",
-                                pi->name, PROP_NAME_MAX - 1, name);
-        }
-      }
-      return len;
-    }
-  }
-}
-
-void __system_property_read_callback(const prop_info* pi,
-                                     void (*callback)(void* cookie,
-                                                      const char* name,
-                                                      const char* value,
-                                                      uint32_t serial),
-                                     void* cookie) {
-  while (true) {
-    uint32_t serial = __system_property_serial(pi);  // acquire semantics
-    size_t len = SERIAL_VALUE_LEN(serial);
-    char value_buf[len + 1];
-
-    memcpy(value_buf, pi->value, len);
-    value_buf[len] = '\0';
-
-    // TODO: see todo in __system_property_read function
-    atomic_thread_fence(memory_order_acquire);
-    if (serial == load_const_atomic(&(pi->serial), memory_order_relaxed)) {
-      callback(cookie, pi->name, value_buf, serial);
-      return;
-    }
-  }
-}
-
-int __system_property_get(const char* name, char* value) {
-  const prop_info* pi = __system_property_find(name);
-
-  if (pi != 0) {
-    return __system_property_read(pi, nullptr, value);
-  } else {
-    value[0] = 0;
-    return 0;
-  }
-}
-
-static constexpr uint32_t kProtocolVersion1 = 1;
-static constexpr uint32_t kProtocolVersion2 = 2;  // current
-
-static atomic_uint_least32_t g_propservice_protocol_version = 0;
-
-static void detect_protocol_version() {
-  char value[PROP_VALUE_MAX];
-  if (__system_property_get(kServiceVersionPropertyName, value) == 0) {
-    g_propservice_protocol_version = kProtocolVersion1;
-    async_safe_format_log(ANDROID_LOG_WARN, "libc",
-                          "Using old property service protocol (\"%s\" is not set)",
-                          kServiceVersionPropertyName);
-  } else {
-    uint32_t version = static_cast<uint32_t>(atoll(value));
-    if (version >= kProtocolVersion2) {
-      g_propservice_protocol_version = kProtocolVersion2;
-    } else {
-      async_safe_format_log(ANDROID_LOG_WARN, "libc",
-                            "Using old property service protocol (\"%s\"=\"%s\")",
-                            kServiceVersionPropertyName, value);
-      g_propservice_protocol_version = kProtocolVersion1;
-    }
-  }
-}
-
-int __system_property_set(const char* key, const char* value) {
-  if (key == nullptr) return -1;
-  if (value == nullptr) value = "";
-  if (strlen(value) >= PROP_VALUE_MAX) return -1;
-
-  if (g_propservice_protocol_version == 0) {
-    detect_protocol_version();
-  }
-
-  if (g_propservice_protocol_version == kProtocolVersion1) {
-    // Old protocol does not support long names
-    if (strlen(key) >= PROP_NAME_MAX) return -1;
-
-    prop_msg msg;
-    memset(&msg, 0, sizeof msg);
-    msg.cmd = PROP_MSG_SETPROP;
-    strlcpy(msg.name, key, sizeof msg.name);
-    strlcpy(msg.value, value, sizeof msg.value);
-
-    return send_prop_msg(&msg);
-  } else {
-    // Use proper protocol
-    PropertyServiceConnection connection;
-    if (!connection.IsValid()) {
-      errno = connection.GetLastError();
-      async_safe_format_log(ANDROID_LOG_WARN,
-                            "libc",
-                            "Unable to set property \"%s\" to \"%s\": connection failed; errno=%d (%s)",
-                            key,
-                            value,
-                            errno,
-                            strerror(errno));
-      return -1;
-    }
-
-    SocketWriter writer(&connection);
-    if (!writer.WriteUint32(PROP_MSG_SETPROP2).WriteString(key).WriteString(value).Send()) {
-      errno = connection.GetLastError();
-      async_safe_format_log(ANDROID_LOG_WARN,
-                            "libc",
-                            "Unable to set property \"%s\" to \"%s\": write failed; errno=%d (%s)",
-                            key,
-                            value,
-                            errno,
-                            strerror(errno));
-      return -1;
-    }
-
-    int result = -1;
-    if (!connection.RecvInt32(&result)) {
-      errno = connection.GetLastError();
-      async_safe_format_log(ANDROID_LOG_WARN,
-                            "libc",
-                            "Unable to set property \"%s\" to \"%s\": recv failed; errno=%d (%s)",
-                            key,
-                            value,
-                            errno,
-                            strerror(errno));
-      return -1;
-    }
-
-    if (result != PROP_SUCCESS) {
-      async_safe_format_log(ANDROID_LOG_WARN,
-                            "libc",
-                            "Unable to set property \"%s\" to \"%s\": error code: 0x%x",
-                            key,
-                            value,
-                            result);
-      return -1;
-    }
-
-    return 0;
-  }
-}
-
-int __system_property_update(prop_info* pi, const char* value, unsigned int len) {
-  if (len >= PROP_VALUE_MAX) {
-    return -1;
-  }
-
-  prop_area* pa = __system_property_area__;
-
-  if (!pa) {
-    return -1;
-  }
-
-  uint32_t serial = atomic_load_explicit(&pi->serial, memory_order_relaxed);
-  serial |= 1;
-  atomic_store_explicit(&pi->serial, serial, memory_order_relaxed);
-  // The memcpy call here also races.  Again pretend it
-  // used memory_order_relaxed atomics, and use the analogous
-  // counterintuitive fence.
-  atomic_thread_fence(memory_order_release);
-  strlcpy(pi->value, value, len + 1);
-
-  atomic_store_explicit(&pi->serial, (len << 24) | ((serial + 1) & 0xffffff), memory_order_release);
-  __futex_wake(&pi->serial, INT32_MAX);
-
-  atomic_store_explicit(pa->serial(), atomic_load_explicit(pa->serial(), memory_order_relaxed) + 1,
-                        memory_order_release);
-  __futex_wake(pa->serial(), INT32_MAX);
-
-  return 0;
-}
-
-int __system_property_add(const char* name, unsigned int namelen, const char* value,
-                          unsigned int valuelen) {
-  if (valuelen >= PROP_VALUE_MAX) {
-    return -1;
-  }
-
-  if (namelen < 1) {
-    return -1;
-  }
-
-  if (!__system_property_area__) {
-    return -1;
-  }
-
-  prop_area* pa = get_prop_area_for_name(name);
-
-  if (!pa) {
-    async_safe_format_log(ANDROID_LOG_ERROR, "libc", "Access denied adding property \"%s\"", name);
-    return -1;
-  }
-
-  bool ret = pa->add(name, namelen, value, valuelen);
-  if (!ret) {
-    return -1;
-  }
-
-  // There is only a single mutator, but we want to make sure that
-  // updates are visible to a reader waiting for the update.
-  atomic_store_explicit(
-      __system_property_area__->serial(),
-      atomic_load_explicit(__system_property_area__->serial(), memory_order_relaxed) + 1,
-      memory_order_release);
-  __futex_wake(__system_property_area__->serial(), INT32_MAX);
-  return 0;
-}
-
-// Wait for non-locked serial, and retrieve it with acquire semantics.
-uint32_t __system_property_serial(const prop_info* pi) {
-  uint32_t serial = load_const_atomic(&pi->serial, memory_order_acquire);
-  while (SERIAL_DIRTY(serial)) {
-    __futex_wait(const_cast<_Atomic(uint_least32_t)*>(&pi->serial), serial, nullptr);
-    serial = load_const_atomic(&pi->serial, memory_order_acquire);
-  }
-  return serial;
-}
-
-uint32_t __system_property_wait_any(uint32_t old_serial) {
-  uint32_t new_serial;
-  __system_property_wait(nullptr, old_serial, &new_serial, nullptr);
-  return new_serial;
-}
-
-bool __system_property_wait(const prop_info* pi,
-                            uint32_t old_serial,
-                            uint32_t* new_serial_ptr,
-                            const timespec* relative_timeout) {
-  // Are we waiting on the global serial or a specific serial?
-  atomic_uint_least32_t* serial_ptr;
-  if (pi == nullptr) {
-    if (__system_property_area__ == nullptr) return -1;
-    serial_ptr = __system_property_area__->serial();
-  } else {
-    serial_ptr = const_cast<atomic_uint_least32_t*>(&pi->serial);
-  }
-
-  uint32_t new_serial;
-  do {
-    int rc;
-    if ((rc = __futex_wait(serial_ptr, old_serial, relative_timeout)) != 0 && rc == -ETIMEDOUT) {
-      return false;
-    }
-    new_serial = load_const_atomic(serial_ptr, memory_order_acquire);
-  } while (new_serial == old_serial);
-
-  *new_serial_ptr = new_serial;
-  return true;
-}
-
-const prop_info* __system_property_find_nth(unsigned n) {
-  struct find_nth {
-    const uint32_t sought;
-    uint32_t current;
-    const prop_info* result;
-
-    explicit find_nth(uint32_t n) : sought(n), current(0), result(nullptr) {}
-    static void fn(const prop_info* pi, void* ptr) {
-      find_nth* self = reinterpret_cast<find_nth*>(ptr);
-      if (self->current++ == self->sought) self->result = pi;
-    }
-  } state(n);
-  __system_property_foreach(find_nth::fn, &state);
-  return state.result;
-}
-
-int __system_property_foreach(void (*propfn)(const prop_info* pi, void* cookie), void* cookie) {
-  if (!__system_property_area__) {
-    return -1;
-  }
-
-  list_foreach(contexts, [propfn, cookie](context_node* l) {
-    if (l->check_access_and_open()) {
-      l->pa()->foreach(propfn, cookie);
-    }
-  });
-  return 0;
-}
diff --git a/libc/bionic/tmpfile.cpp b/libc/bionic/tmpfile.cpp
index dc142a9..bda3566 100644
--- a/libc/bionic/tmpfile.cpp
+++ b/libc/bionic/tmpfile.cpp
@@ -39,22 +39,7 @@
 #include <unistd.h>
 
 #include "private/ErrnoRestorer.h"
-
-class ScopedSignalBlocker {
- public:
-  ScopedSignalBlocker() {
-    sigset_t set;
-    sigfillset(&set);
-    sigprocmask(SIG_BLOCK, &set, &old_set_);
-  }
-
-  ~ScopedSignalBlocker() {
-    sigprocmask(SIG_SETMASK, &old_set_, NULL);
-  }
-
- private:
-  sigset_t old_set_;
-};
+#include "private/ScopedSignalBlocker.h"
 
 static FILE* __tmpfile_dir(const char* tmp_dir) {
   char* path = NULL;
diff --git a/libc/bionic/vdso.cpp b/libc/bionic/vdso.cpp
index dd4c070..8cdb504 100644
--- a/libc/bionic/vdso.cpp
+++ b/libc/bionic/vdso.cpp
@@ -26,8 +26,6 @@
 #include <unistd.h>
 #include "private/KernelArgumentBlock.h"
 
-#define AT_SYSINFO_EHDR 33 /* until we have new enough uapi headers... */
-
 int clock_gettime(int clock_id, timespec* tp) {
   auto vdso_clock_gettime = reinterpret_cast<decltype(&clock_gettime)>(
     __libc_globals->vdso[VDSO_CLOCK_GETTIME].fn);
diff --git a/libc/bionic/wcstod.cpp b/libc/bionic/wcstod.cpp
index 41df854..41a94fb 100644
--- a/libc/bionic/wcstod.cpp
+++ b/libc/bionic/wcstod.cpp
@@ -31,6 +31,7 @@
 #include <wchar.h>
 
 #include <stdlib.h>
+#include <string.h>
 
 #include "local.h"
 
diff --git a/libc/dns/net/gethnamaddr.c b/libc/dns/net/gethnamaddr.c
index 4e416fd..7118a29 100644
--- a/libc/dns/net/gethnamaddr.c
+++ b/libc/dns/net/gethnamaddr.c
@@ -170,6 +170,15 @@
 	{ 0, 0 }
 };
 
+static int h_errno_to_result(int* herrno_p) {
+  // glibc considers ERANGE a special case (and BSD uses ENOSPC instead).
+  if (*herrno_p == NETDB_INTERNAL && errno == ENOSPC) {
+    errno = ERANGE;
+    return errno;
+  }
+  // glibc considers HOST_NOT_FOUND not an error for the _r functions' return value.
+  return (*herrno_p != HOST_NOT_FOUND) ? *herrno_p : 0;
+}
 
 #ifdef DEBUG
 static void
@@ -519,9 +528,8 @@
     struct hostent **result, int *errorp)
 {
 	res_state res = __res_get_state();
-
 	if (res == NULL) {
-	  *result = NULL;
+		*result = NULL;
 		*errorp = NETDB_INTERNAL;
 		return -1;
 	}
@@ -538,12 +546,7 @@
 	}
 	*result = gethostbyname_internal(name, AF_INET, res, hp, buf, buflen, errorp,
 	                                 &NETCONTEXT_UNSET);
-	__res_put_state(res);
-	if (!*result && errno == ENOSPC) {
-	  errno = ERANGE;
-	  return ERANGE; /* Return error as in linux manual page. */
-	}
-	return (*result) ? 0 : -1;
+	return h_errno_to_result(errorp);
 }
 
 /* The prototype of gethostbyname2_r is from glibc, not that in netbsd. */
@@ -552,7 +555,6 @@
     size_t buflen, struct hostent **result, int *errorp)
 {
 	res_state res = __res_get_state();
-
 	if (res == NULL) {
 		*result = NULL;
 		*errorp = NETDB_INTERNAL;
@@ -560,12 +562,7 @@
 	}
 	*result = gethostbyname_internal(name, af, res, hp, buf, buflen, errorp,
 	                                 &NETCONTEXT_UNSET);
-	__res_put_state(res);
-	if (!*result && errno == ENOSPC) {
-		errno = ERANGE;
-		return ERANGE;
-	}
-	return (*result) ? 0 : -1;
+	return h_errno_to_result(errorp);
 }
 
 __LIBC_HIDDEN__ FILE* android_open_proxy() {
@@ -859,11 +856,7 @@
 {
 	*result = android_gethostbyaddrfornetcontext_proxy_internal(
 		addr, len, af, hp, buf, buflen, h_errnop, &NETCONTEXT_UNSET);
-	if (!*result && errno == ENOSPC) {
-		errno = ERANGE;
-		return ERANGE;
-	}
-	return (*result) ? 0 : -1;
+	return h_errno_to_result(h_errnop);
 }
 
 static struct hostent *
diff --git a/libc/dns/net/getservbyport.c b/libc/dns/net/getservbyport.c
deleted file mode 100644
index 7dcaafb..0000000
--- a/libc/dns/net/getservbyport.c
+++ /dev/null
@@ -1,52 +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 <sys/cdefs.h>
-#include <netdb.h>
-#include "servent.h"
-
-struct servent *
-getservbyport(int port, const char *proto)
-{
-    res_static       rs = __res_get_static();
-
-    if (rs == NULL || proto == NULL) {
-        errno = EINVAL;
-        return NULL;
-    }
-
-    rs->servent_ptr = NULL;
-    while (1) {
-        struct servent*  s = getservent_r(rs);
-        if (s == NULL)
-            break;
-        if ( s->s_port == port && !strcmp( s->s_proto, proto ) )
-            return s;
-    }
-
-    return NULL;
-}
diff --git a/libc/dns/net/getservent.c b/libc/dns/net/getservent.c
index 0a727c7..03add59 100644
--- a/libc/dns/net/getservent.c
+++ b/libc/dns/net/getservent.c
@@ -25,32 +25,17 @@
  * OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF
  * SUCH DAMAGE.
  */
-#include <sys/cdefs.h>
-#include <sys/types.h>
-#include <endian.h>
-#include <malloc.h>
+
 #include <netdb.h>
-#include "servent.h"
+
+#include <endian.h>
+#include <stdlib.h>
+#include <string.h>
+
+#include "resolv_static.h"
 #include "services.h"
 
-void
-setservent(int f)
-{
-    res_static  rs = __res_get_static();
-    if (rs) {
-        rs->servent_ptr = NULL;
-    }
-}
-
-void
-endservent(void)
-{
-    /* nothing to do */
-}
-
-struct servent *
-getservent_r( res_static  rs )
-{
+struct servent* getservent_r(res_static rs) {
     const char*  p;
     const char*  q;
     int          namelen;
@@ -119,12 +104,48 @@
     return &rs->servent;
 }
 
-struct servent *
-getservent(void)
-{
-    res_static   rs = __res_get_static();
+void setservent(int stayopen) {
+  endservent();
+}
 
-    if (rs == NULL) return NULL;
+void endservent(void) {
+  res_static rs = __res_get_static();
+  if (rs) rs->servent_ptr = NULL;
+}
 
-    return getservent_r(rs);
+struct servent* getservent(void) {
+  res_static rs = __res_get_static();
+  return rs ? getservent_r(rs) : NULL;
+}
+
+struct servent* getservbyname(const char* name, const char* proto) {
+  res_static rs = __res_get_static();
+  if (rs == NULL) return NULL;
+
+  const char* old_servent_ptr = rs->servent_ptr;
+  rs->servent_ptr = NULL;
+  struct servent* s;
+  while ((s = getservent_r(rs)) != NULL) {
+    if (strcmp(s->s_name, name) == 0 && (proto == NULL || strcmp(s->s_proto, proto) == 0)) {
+      break;
+    }
+  }
+  rs->servent_ptr = old_servent_ptr;
+  return s;
+}
+
+struct servent* getservbyport(int port, const char* proto) {
+  res_static rs = __res_get_static();
+  if (rs == NULL) return NULL;
+
+  const char* old_servent_ptr = rs->servent_ptr;
+  rs->servent_ptr = NULL;
+  struct servent* s;
+  while ((s = getservent_r(rs)) != NULL) {
+    if (s->s_port == port && (proto == NULL || strcmp(s->s_proto, proto) == 0)) {
+      break;
+    }
+  }
+  rs->servent_ptr = old_servent_ptr;
+  return s;
 }
diff --git a/libc/dns/net/servent.h b/libc/dns/net/servent.h
deleted file mode 100644
index 822b375..0000000
--- a/libc/dns/net/servent.h
+++ /dev/null
@@ -1,44 +0,0 @@
-/*	$NetBSD: servent.h,v 1.1 2005/04/18 19:39:45 kleink Exp $	*/
-
-/*-
- * Copyright (c) 2004 The NetBSD Foundation, Inc.
- * All rights reserved.
- *
- * This code is derived from software contributed to The NetBSD Foundation
- * by Christos Zoulas.
- *
- * Redistribution and use in source and binary forms, with or without
- * modification, are permitted provided that the following conditions
- * are met:
- * 1. Redistributions of source code must retain the above copyright
- *    notice, this list of conditions and the following disclaimer.
- * 2. Redistributions in binary form must reproduce the above copyright
- *    notice, this list of conditions and the following disclaimer in the
- *    documentation and/or other materials provided with the distribution.
- * 3. All advertising materials mentioning features or use of this software
- *    must display the following acknowledgement:
- *        This product includes software developed by the NetBSD
- *        Foundation, Inc. and its contributors.
- * 4. Neither the name of The NetBSD Foundation 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 NETBSD FOUNDATION, INC. AND CONTRIBUTORS
- * ``AS IS'' AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED
- * TO, THE IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR
- * PURPOSE ARE DISCLAIMED.  IN NO EVENT SHALL THE FOUNDATION OR CONTRIBUTORS
- * BE LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR
- * CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF
- * SUBSTITUTE GOODS OR SERVICES; LOSS OF USE, DATA, OR PROFITS; OR BUSINESS
- * INTERRUPTION) HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY, WHETHER IN
- * CONTRACT, STRICT LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE)
- * ARISING IN ANY WAY OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF THE
- * POSSIBILITY OF SUCH DAMAGE.
- */
-
-#include <stdio.h>
-#include <errno.h>
-#include <string.h>
-#include "resolv_static.h"
-
-struct servent*  getservent_r(res_static rs);
diff --git a/libc/dns/net/sethostent.c b/libc/dns/net/sethostent.c
index 916421e..a743a54 100644
--- a/libc/dns/net/sethostent.c
+++ b/libc/dns/net/sethostent.c
@@ -64,13 +64,26 @@
 
 static struct hostent *_hf_gethtbyname2(const char *, int, struct getnamaddr *);
 
-static const char *_h_hosts = _PATH_HOSTS;
+void
+/*ARGSUSED*/
+sethostent(int stayopen)
+{
+	res_static rs = __res_get_static();
+	if (rs) sethostent_r(&rs->hostf);
+}
+
+void
+endhostent(void)
+{
+	res_static rs = __res_get_static();
+	if (rs) endhostent_r(&rs->hostf);
+}
 
 void
 sethostent_r(FILE **hf)
 {
 	if (!*hf)
-		*hf = fopen(_h_hosts, "re");
+		*hf = fopen(_PATH_HOSTS, "re");
 	else
 		rewind(*hf);
 }
@@ -117,14 +130,15 @@
 #endif
 	if (hp == NULL) {
 		if (*info->he == NETDB_INTERNAL && errno == ENOSPC) {
-			return NS_UNAVAIL;
+			return NS_UNAVAIL; // glibc compatibility.
 		}
+		*info->he = HOST_NOT_FOUND;
 		return NS_NOTFOUND;
 	}
 	return NS_SUCCESS;
 }
 
-static struct hostent *
+struct hostent *
 _hf_gethtbyname2(const char *name, int af, struct getnamaddr *info)
 {
 	struct hostent *hp, hent;
@@ -145,7 +159,6 @@
 	}
 
 	if ((ptr = buf = malloc(len = info->buflen)) == NULL) {
-		endhostent_r(&hf);
 		*info->he = NETDB_INTERNAL;
 		return NULL;
 	}
@@ -163,7 +176,7 @@
 		    info->he);
 		if (hp == NULL) {
 			if (*info->he == NETDB_INTERNAL && errno == ENOSPC) {
-				goto nospc;
+				goto nospc; // glibc compatibility.
 			}
 			break;
 		}
@@ -230,7 +243,6 @@
 	free(buf);
 	return hp;
 nospc:
-	endhostent_r(&hf);
 	*info->he = NETDB_INTERNAL;
 	free(buf);
 	errno = ENOSPC;
@@ -265,9 +277,7 @@
 	endhostent_r(&hf);
 
 	if (hp == NULL) {
-		if (errno == ENOSPC) {
-			return NS_UNAVAIL;
-		}
+		if (errno == ENOSPC) return NS_UNAVAIL; // glibc compatibility.
 		*info->he = HOST_NOT_FOUND;
 		return NS_NOTFOUND;
 	}
diff --git a/libc/include/android/api-level.h b/libc/include/android/api-level.h
index 7e3aa99..18825e7 100644
--- a/libc/include/android/api-level.h
+++ b/libc/include/android/api-level.h
@@ -57,5 +57,6 @@
 #define __ANDROID_API_N__ 24
 #define __ANDROID_API_N_MR1__ 25
 #define __ANDROID_API_O__ 26
+#define __ANDROID_API_O_MR1__ 27
 
 #endif /* ANDROID_API_LEVEL_H */
diff --git a/libc/include/android/legacy_fenv_inlines_arm.h b/libc/include/android/legacy_fenv_inlines_arm.h
index 58c49c2..de024cf 100644
--- a/libc/include/android/legacy_fenv_inlines_arm.h
+++ b/libc/include/android/legacy_fenv_inlines_arm.h
@@ -35,9 +35,6 @@
 
 __BEGIN_DECLS
 
-#define FPSCR_ENABLE_SHIFT 8
-#define FPSCR_ENABLE_MASK  (FE_ALL_EXCEPT << FPSCR_ENABLE_SHIFT)
-
 #define FPSCR_RMODE_SHIFT 22
 
 static __inline int fegetenv(fenv_t* __envp) {
@@ -108,7 +105,7 @@
   fenv_t __env;
   fegetenv(&__env);
   *__envp = __env;
-  __env &= ~(FE_ALL_EXCEPT | FPSCR_ENABLE_MASK);
+  __env &= ~FE_ALL_EXCEPT;
   fesetenv(&__env);
   return 0;
 }
@@ -121,30 +118,18 @@
   return 0;
 }
 
-static __inline int feenableexcept(int __mask) {
-  fenv_t __old_fpscr, __new_fpscr;
-  fegetenv(&__old_fpscr);
-  __new_fpscr = __old_fpscr | (__mask & FE_ALL_EXCEPT) << FPSCR_ENABLE_SHIFT;
-  fesetenv(&__new_fpscr);
-  return ((__old_fpscr >> FPSCR_ENABLE_SHIFT) & FE_ALL_EXCEPT);
+static __inline int feenableexcept(int __mask __unused) {
+  return -1;
 }
 
-static __inline int fedisableexcept(int __mask) {
-  fenv_t __old_fpscr, __new_fpscr;
-  fegetenv(&__old_fpscr);
-  __new_fpscr = __old_fpscr & ~((__mask & FE_ALL_EXCEPT) << FPSCR_ENABLE_SHIFT);
-  fesetenv(&__new_fpscr);
-  return ((__old_fpscr >> FPSCR_ENABLE_SHIFT) & FE_ALL_EXCEPT);
+static __inline int fedisableexcept(int __mask __unused) {
+  return 0;
 }
 
 static __inline int fegetexcept(void) {
-  fenv_t __fpscr;
-  fegetenv(&__fpscr);
-  return ((__fpscr & FPSCR_ENABLE_MASK) >> FPSCR_ENABLE_SHIFT);
+  return 0;
 }
 
-#undef FPSCR_ENABLE_SHIFT
-#undef FPSCR_ENABLE_MASK
 #undef FPSCR_RMODE_SHIFT
 
 __END_DECLS
diff --git a/libc/include/android/legacy_sys_mman_inlines.h b/libc/include/android/legacy_sys_mman_inlines.h
new file mode 100644
index 0000000..7eb537e
--- /dev/null
+++ b/libc/include/android/legacy_sys_mman_inlines.h
@@ -0,0 +1,70 @@
+/*
+ * Copyright (C) 2017 The Android Open Source Project
+ * All rights reserved.
+ *
+ * Redistribution and use in source and binary forms, with or without
+ * modification, are permitted provided that the following conditions
+ * are met:
+ *  * Redistributions of source code must retain the above copyright
+ *    notice, this list of conditions and the following disclaimer.
+ *  * Redistributions in binary form must reproduce the above copyright
+ *    notice, this list of conditions and the following disclaimer in
+ *    the documentation and/or other materials provided with the
+ *    distribution.
+ *
+ * THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS
+ * "AS IS" AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT
+ * LIMITED TO, THE IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS
+ * FOR A PARTICULAR PURPOSE ARE DISCLAIMED. IN NO EVENT SHALL THE
+ * COPYRIGHT OWNER OR CONTRIBUTORS BE LIABLE FOR ANY DIRECT, INDIRECT,
+ * INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING,
+ * BUT NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; LOSS
+ * OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED
+ * AND ON ANY THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY,
+ * OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT
+ * OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF
+ * SUCH DAMAGE.
+ */
+
+#pragma once
+
+#include <sys/cdefs.h>
+#include <sys/mman.h>
+#include <sys/syscall.h>
+#include <unistd.h>
+
+#if __ANDROID_API__ < __ANDROID_API_L__
+
+__BEGIN_DECLS
+
+/*
+ * While this was never an inline, this function alone has caused most of the
+ * bug reports related to _FILE_OFFSET_BITS=64. Providing an inline for it
+ * should allow a lot more code to build with _FILE_OFFSET_BITS=64 when
+ * targeting pre-L.
+ */
+static __inline void* mmap64(void* __addr, size_t __size, int __prot, int __flags, int __fd,
+                             off64_t __offset) __RENAME(mmap64);
+static __inline void* mmap64(void* __addr, size_t __size, int __prot, int __flags, int __fd,
+                             off64_t __offset) {
+  const int __mmap2_shift = 12; // 2**12 == 4096
+  if (__offset < 0 || (__offset & ((1UL << __mmap2_shift) - 1)) != 0) {
+    errno = EINVAL;
+    return MAP_FAILED;
+  }
+
+  // prevent allocations large enough for `end - start` to overflow
+  size_t __rounded = __BIONIC_ALIGN(__size, PAGE_SIZE);
+  if (__rounded < __size || __rounded > PTRDIFF_MAX) {
+    errno = ENOMEM;
+    return MAP_FAILED;
+  }
+
+  extern void* __mmap2(void* __addr, size_t __size, int __prot, int __flags, int __fd,
+                       size_t __offset);
+  return __mmap2(__addr, __size, __prot, __flags, __fd, __offset >> __mmap2_shift);
+}
+
+__END_DECLS
+
+#endif  /* __ANDROID_API__ < __ANDROID_API_L__ */
diff --git a/libc/arch-arm/include/machine/fenv.h b/libc/include/bits/fenv_arm.h
similarity index 72%
rename from libc/arch-arm/include/machine/fenv.h
rename to libc/include/bits/fenv_arm.h
index 0e483e3..042fec3 100644
--- a/libc/arch-arm/include/machine/fenv.h
+++ b/libc/include/bits/fenv_arm.h
@@ -26,21 +26,35 @@
  * $FreeBSD: src/lib/msun/arm/fenv.h,v 1.5 2005/03/16 19:03:45 das Exp $
  */
 
-/*
- * Rewritten for Android.
- *
- * The ARM FPSCR is described here:
- * http://infocenter.arm.com/help/index.jsp?topic=/com.arm.doc.ddi0344b/Chdfafia.html
- */
-
-#ifndef _ARM_FENV_H_
-#define _ARM_FENV_H_
+#ifndef _BITS_FENV_ARM_H_
+#define _BITS_FENV_ARM_H_
 
 #include <sys/types.h>
 
 __BEGIN_DECLS
 
+/*
+ * The ARM Cortex-A75 registers are described here:
+ *
+ * AArch64:
+ *  FPCR: http://infocenter.arm.com/help/topic/com.arm.doc.100403_0200_00_en/lau1442502503726.html
+ *  FPSR: http://infocenter.arm.com/help/topic/com.arm.doc.100403_0200_00_en/lau1442502526288.html
+ * AArch32:
+ *  FPSCR: http://infocenter.arm.com/help/topic/com.arm.doc.100403_0200_00_en/lau1442504290459.html
+ */
+
+#if defined(__LP64__)
+typedef struct {
+  /* FPCR, Floating-point Control Register. */
+  __uint32_t __control;
+  /* FPSR, Floating-point Status Register. */
+  __uint32_t __status;
+} fenv_t;
+
+#else
 typedef __uint32_t fenv_t;
+#endif
+
 typedef __uint32_t fexcept_t;
 
 /* Exception flags. */
@@ -49,8 +63,8 @@
 #define FE_OVERFLOW   0x04
 #define FE_UNDERFLOW  0x08
 #define FE_INEXACT    0x10
-#define FE_ALL_EXCEPT (FE_DIVBYZERO | FE_INEXACT | FE_INVALID | \
-                       FE_OVERFLOW | FE_UNDERFLOW)
+#define FE_DENORMAL   0x80
+#define FE_ALL_EXCEPT (FE_DIVBYZERO | FE_INEXACT | FE_INVALID | FE_OVERFLOW | FE_UNDERFLOW | FE_DENORMAL)
 
 /* Rounding modes. */
 #define FE_TONEAREST  0x0
@@ -60,4 +74,4 @@
 
 __END_DECLS
 
-#endif /* !_ARM_FENV_H_ */
+#endif
diff --git a/libc/arch-mips/include/machine/fenv.h b/libc/include/bits/fenv_mips.h
similarity index 97%
rename from libc/arch-mips/include/machine/fenv.h
rename to libc/include/bits/fenv_mips.h
index 689e1cb..9298e86 100644
--- a/libc/arch-mips/include/machine/fenv.h
+++ b/libc/include/bits/fenv_mips.h
@@ -68,8 +68,8 @@
  * 11 - rounding (down)toward minus infinity (RM)
  */
 
-#ifndef _MIPS_FENV_H_
-#define _MIPS_FENV_H_
+#ifndef _BITS_FENV_MIPS_H_
+#define _BITS_FENV_MIPS_H_
 
 #include <sys/types.h>
 
@@ -95,4 +95,4 @@
 
 __END_DECLS
 
-#endif /* !_MIPS_FENV_H_ */
+#endif
diff --git a/libc/arch-x86/include/machine/fenv.h b/libc/include/bits/fenv_x86.h
similarity index 96%
rename from libc/arch-x86/include/machine/fenv.h
rename to libc/include/bits/fenv_x86.h
index de45add..75b109b 100644
--- a/libc/arch-x86/include/machine/fenv.h
+++ b/libc/include/bits/fenv_x86.h
@@ -26,8 +26,8 @@
  * $FreeBSD: src/lib/msun/i387/fenv.h,v 1.4 2005/03/17 22:21:46 das Exp $
  */
 
-#ifndef _I387_FENV_H_
-#define _I387_FENV_H_
+#ifndef _BITS_FENV_X86_H_
+#define _BITS_FENV_X86_H_
 
 #include <sys/types.h>
 
@@ -66,4 +66,4 @@
 
 __END_DECLS
 
-#endif /* !I387_FENV_H_ */
+#endif
diff --git a/libc/arch-x86_64/include/machine/fenv.h b/libc/include/bits/fenv_x86_64.h
similarity index 97%
rename from libc/arch-x86_64/include/machine/fenv.h
rename to libc/include/bits/fenv_x86_64.h
index c2b25ed..006d19e 100644
--- a/libc/arch-x86_64/include/machine/fenv.h
+++ b/libc/include/bits/fenv_x86_64.h
@@ -24,8 +24,8 @@
  * SUCH DAMAGE.
  */
 
-#ifndef _AMD64_FENV_H_
-#define _AMD64_FENV_H_
+#ifndef _BITS_FENV_X86_64_H_
+#define _BITS_FENV_X86_64_H_
 
 #include <sys/types.h>
 
@@ -92,4 +92,4 @@
 
 __END_DECLS
 
-#endif /* !_AMD64_FENV_H_ */
+#endif
diff --git a/libc/include/bits/posix_limits.h b/libc/include/bits/posix_limits.h
index cfc46f5..8dfea52 100644
--- a/libc/include/bits/posix_limits.h
+++ b/libc/include/bits/posix_limits.h
@@ -31,95 +31,78 @@
 
 #include <sys/cdefs.h>
 
-#define __BIONIC_POSIX_FEATURE_SINCE(level) (((__ANDROID_API__) >= level) ? 200809L : -1)
+#define _POSIX_VERSION 200809L
+#define _POSIX2_VERSION _POSIX_VERSION
+#define _XOPEN_VERSION 700
 
-/* Any constant values here other than -1 or 200809L are explicitly specified by POSIX.1-2008. */
+#define __BIONIC_POSIX_FEATURE_MISSING (-1)
+#define __BIONIC_POSIX_FEATURE_SINCE(level) \
+    (((__ANDROID_API__) >= level) ? _POSIX_VERSION : __BIONIC_POSIX_FEATURE_MISSING)
+
+/* Availability macros. */
+/* See http://man7.org/linux/man-pages/man7/posixoptions.7.html for documentation. */
 /* Keep this list sorted by name. */
 #define _POSIX_ADVISORY_INFO __BIONIC_POSIX_FEATURE_SINCE(23) /* posix_memadvise arrived late. */
-#define _POSIX_AIO_LISTIO_MAX       2
-#define _POSIX_AIO_MAX              1
-#define _POSIX_ARG_MAX              4096
-#define _POSIX_ASYNCHRONOUS_IO      -1  /* not implemented */
+#define _POSIX_ASYNCHRONOUS_IO __BIONIC_POSIX_FEATURE_MISSING
 #define _POSIX_BARRIERS __BIONIC_POSIX_FEATURE_SINCE(24)
-#define _POSIX_CHILD_MAX            25
-#define _POSIX_CHOWN_RESTRICTED     1  /* yes, chown requires appropriate privileges */
-#define _POSIX_CLOCK_SELECTION      200809L
-#define _POSIX_CPUTIME              0  /* Use sysconf to detect support at runtime. */
-#define _POSIX_DELAYTIMER_MAX       32
-#define _POSIX_FSYNC 200809L
-#define _POSIX_HOST_NAME_MAX        255
-#define _POSIX_IPV6                 200809L
-#define _POSIX_JOB_CONTROL          1  /* job control is a Linux feature */
-#define _POSIX_LINK_MAX             8
-#define _POSIX_LOGIN_NAME_MAX       9  /* includes trailing NUL */
-#define _POSIX_MAPPED_FILES         200809L  /* mmap-ed files supported */
-#define _POSIX_MAX_CANON            255
-#define _POSIX_MAX_INPUT            255
-#define _POSIX_MEMLOCK __BIONIC_POSIX_FEATURE_SINCE(17) /* mlockall. */
-#define _POSIX_MEMLOCK_RANGE        200809L /* mlock. */
-#define _POSIX_MEMORY_PROTECTION    200809L
-#define _POSIX_MESSAGE_PASSING      -1  /* not implemented */
-#define _POSIX_MONOTONIC_CLOCK      0  /* the monotonic clock may be available; ask sysconf */
-#define _POSIX_MQ_OPEN_MAX          8
-#define _POSIX_MQ_PRIO_MAX          32
-#define _POSIX_NAME_MAX             14
-#define _POSIX_NGROUPS_MAX          8
-#define _POSIX_NO_TRUNC             1  /* very long pathnames generate an error */
-#define _POSIX_OPEN_MAX             20
-#define _POSIX_PATH_MAX             256
-#define _POSIX_PIPE_BUF             512
-#define _POSIX_PRIORITY_SCHEDULING  200809L  /* priority scheduling is a Linux feature */
-#define _POSIX_PRIORITIZED_IO       -1  /* not implemented */
-#define _POSIX_RAW_SOCKETS          200809L
-#define _POSIX_READER_WRITER_LOCKS  200809L
-#define _POSIX_REALTIME_SIGNALS     200809L
-#define _POSIX_REGEXP               1
-#define _POSIX_RE_DUP_MAX           255
-#define _POSIX_SAVED_IDS            1  /* saved user ids is a Linux feature */
-#define _POSIX_SEMAPHORES           200809L
-#define _POSIX_SEM_NSEMS_MAX        256
-#define _POSIX_SEM_VALUE_MAX        32767
-#define _POSIX_SHARED_MEMORY_OBJECTS  -1  /* shm_open()/shm_unlink() not implemented */
-#define _POSIX_SHELL                1   /* system() supported */
-#define _POSIX_SIGQUEUE_MAX         32
-#define _POSIX_SPAWN                -1  /* not implemented */
-#define _POSIX_SPIN_LOCKS __BIONIC_POSIX_FEATURE_SINCE(24)
-#define _POSIX_SPORADIC_SERVER      -1  /* not implemented */
-#define _POSIX_SSIZE_MAX            32767
-#define _POSIX_STREAM_MAX           8
-#define _POSIX_SYMLINK_MAX          255
-#define _POSIX_SYMLOOP_MAX          8
-#define _POSIX_SYNCHRONIZED_IO      200809L  /* synchronized i/o supported */
-#define _POSIX_THREADS              200809L  /* we support threads */
-#define _POSIX_THREAD_ATTR_STACKADDR  200809L
-#define _POSIX_THREAD_ATTR_STACKSIZE  200809L
-#define _POSIX_THREAD_CPUTIME       0  /* Use sysconf to detect support at runtime. */
-#define _POSIX_THREAD_DESTRUCTOR_ITERATIONS 4
-#define _POSIX_THREAD_KEYS_MAX      128
-#define _POSIX_THREAD_PRIORITY_SCHEDULING 200809L
-#define _POSIX_THREAD_PRIO_INHERIT -1  /* not implemented */
-#define _POSIX_THREAD_PRIO_PROTECT -1  /* not implemented */
-#define _POSIX_THREAD_PROCESS_SHARED  200809L  /* PTHREAD_PROCESS_SHARED supported. */
-#define _POSIX_THREAD_ROBUST_PRIO_INHERIT -1  /* not implemented */
-#define _POSIX_THREAD_ROBUST_PRIO_PROTECT -1  /* not implemented */
-#define _POSIX_THREAD_SAFE_FUNCTIONS 200809L
-#define _POSIX_THREAD_SPORADIC_SERVER -1  /* not implemented */
-#define _POSIX_THREAD_THREADS_MAX   64
+#define _POSIX_CHOWN_RESTRICTED 1 /* chown/fchown require appropriate privileges. */
+#define _POSIX_CLOCK_SELECTION __BIONIC_POSIX_FEATURE_SINCE(21) /* clock_nanosleep/pthread_condattr_getclock/pthread_condattr_setclock. */
+#define _POSIX_CPUTIME _POSIX_VERSION /* CLOCK_PROCESS_CPUTIME_ID. */
+#define _POSIX_FSYNC _POSIX_VERSION /* fsync. */
+#define _POSIX_IPV6 _POSIX_VERSION
+#define _POSIX_JOB_CONTROL __BIONIC_POSIX_FEATURE_SINCE(21) /* setpgid/tcdrain/tcflush/tcgetpgrp/tcsendbreak/tcsetattr/tcsetpgrp. */
+#define _POSIX_MAPPED_FILES _POSIX_VERSION /* mmap/msync/munmap. */
+#define _POSIX_MEMLOCK __BIONIC_POSIX_FEATURE_SINCE(17) /* mlockall/munlockall. */
+#define _POSIX_MEMLOCK_RANGE _POSIX_VERSION /* mlock/munlock. */
+#define _POSIX_MEMORY_PROTECTION _POSIX_VERSION /* mprotect. */
+#define _POSIX_MESSAGE_PASSING __BIONIC_POSIX_FEATURE_MISSING
+#define _POSIX_MONOTONIC_CLOCK _POSIX_VERSION /* CLOCK_MONOTONIC. */
+#define _POSIX_NO_TRUNC 1 /* Over-long pathnames return errors. */
+#define _POSIX_PRIORITIZED_IO __BIONIC_POSIX_FEATURE_MISSING
+#define _POSIX_PRIORITY_SCHEDULING _POSIX_VERSION /* sched_*. */
+#define _POSIX_RAW_SOCKETS _POSIX_VERSION
+#define _POSIX_READER_WRITER_LOCKS _POSIX_VERSION /* pthread_rwlock*. */
+#define _POSIX_REALTIME_SIGNALS __BIONIC_POSIX_FEATURE_SINCE(23) /* sigqueue/sigtimedwait/sigwaitinfo. */
+#define _POSIX_REGEXP 1
+#define _POSIX_SAVED_IDS 1
+#define _POSIX_SEMAPHORES _POSIX_VERSION /* sem_*. */
+#define _POSIX_SHARED_MEMORY_OBJECTS __BIONIC_POSIX_FEATURE_MISSING /* mmap/munmap are implemented, but shm_open/shm_unlink are not. */
+#define _POSIX_SHELL 1 /* system. */
+#define _POSIX_SPAWN __BIONIC_POSIX_FEATURE_SINCE(28) /* <spawn.h> */
+#define _POSIX_SPIN_LOCKS __BIONIC_POSIX_FEATURE_SINCE(24) /* pthread_spin_*. */
+#define _POSIX_SPORADIC_SERVER __BIONIC_POSIX_FEATURE_MISSING /* No SCHED_SPORADIC. */
+#define _POSIX_SYNCHRONIZED_IO _POSIX_VERSION
+#define _POSIX_THREAD_ATTR_STACKADDR _POSIX_VERSION /* Strictly, we're missing the deprecated pthread_attr_getstackaddr/pthread_attr_setstackaddr, but we do have pthread_attr_getstack/pthread_attr_setstack. */
+#define _POSIX_THREAD_ATTR_STACKSIZE _POSIX_VERSION /* pthread_attr_getstack/pthread_attr_getstacksize/pthread_attr_setstack/pthread_attr_setstacksize. */
+#define _POSIX_THREAD_CPUTIME _POSIX_VERSION /* CLOCK_THREAD_CPUTIME_ID. */
+#define _POSIX_THREAD_PRIO_INHERIT __BIONIC_POSIX_FEATURE_MISSING
+#define _POSIX_THREAD_PRIO_PROTECT __BIONIC_POSIX_FEATURE_MISSING
+#define _POSIX_THREAD_PRIORITY_SCHEDULING _POSIX_VERSION /* Strictly, pthread_attr_getinheritsched/pthread_attr_setinheritsched arrived in 28. */
+#define _POSIX_THREAD_PROCESS_SHARED _POSIX_VERSION
+#define _POSIX_THREAD_ROBUST_PRIO_INHERIT __BIONIC_POSIX_FEATURE_MISSING
+#define _POSIX_THREAD_ROBUST_PRIO_PROTECT __BIONIC_POSIX_FEATURE_MISSING
+#define _POSIX_THREAD_SAFE_FUNCTIONS _POSIX_VERSION
+#define _POSIX_THREAD_SPORADIC_SERVER __BIONIC_POSIX_FEATURE_MISSING /* No SCHED_SPORADIC. */
+#define _POSIX_THREADS _POSIX_VERSION /* Strictly, pthread_cancel/pthread_testcancel are missing. */
 #define _POSIX_TIMEOUTS __BIONIC_POSIX_FEATURE_SINCE(21) /* pthread_mutex_timedlock arrived late. */
-#define _POSIX_TIMERS               200809L  /* Posix timers are supported */
-#define _POSIX_TIMER_MAX            32
-#define _POSIX_TRACE                -1  /* not implemented */
-#define _POSIX_TRACE_EVENT_FILTER   -1  /* not implemented */
-#define _POSIX_TRACE_INHERIT        -1  /* not implemented */
-#define _POSIX_TRACE_LOG            -1  /* not implemented */
-#define _POSIX_TRACE_NAME_MAX       8
-#define _POSIX_TRACE_SYS_MAX        8
-#define _POSIX_TRACE_USER_EVENT_MAX 32
-#define _POSIX_TTY_NAME_MAX         9  /* includes trailing NUL */
-#define _POSIX_TYPED_MEMORY_OBJECTS -1  /* not implemented */
-#define _POSIX_TZNAME_MAX           6
+#define _POSIX_TIMERS _POSIX_VERSION /* clock_getres/clock_gettime/clock_settime/nanosleep/timer_create/timer_delete/timer_gettime/timer_getoverrun/timer_settime. */
+#define _POSIX_TRACE __BIONIC_POSIX_FEATURE_MISSING
+#define _POSIX_TRACE_EVENT_FILTER __BIONIC_POSIX_FEATURE_MISSING
+#define _POSIX_TRACE_INHERIT __BIONIC_POSIX_FEATURE_MISSING
+#define _POSIX_TRACE_LOG __BIONIC_POSIX_FEATURE_MISSING
+#define _POSIX_TYPED_MEMORY_OBJECTS __BIONIC_POSIX_FEATURE_MISSING
+
 #define _POSIX_VDISABLE             '\0'
 
+#define _POSIX2_C_BIND              _POSIX_VERSION
+#define _POSIX2_C_DEV               __BIONIC_POSIX_FEATURE_MISSING
+#define _POSIX2_CHAR_TERM           _POSIX_VERSION
+#define _POSIX2_FORT_DEV            __BIONIC_POSIX_FEATURE_MISSING
+#define _POSIX2_FORT_RUN            __BIONIC_POSIX_FEATURE_MISSING
+#define _POSIX2_LOCALEDEF           __BIONIC_POSIX_FEATURE_MISSING
+#define _POSIX2_SW_DEV              __BIONIC_POSIX_FEATURE_MISSING
+#define _POSIX2_UPE                 __BIONIC_POSIX_FEATURE_MISSING
+
 #if defined(__LP64__)
 #define _POSIX_V7_ILP32_OFF32       -1
 #define _POSIX_V7_ILP32_OFFBIG      -1
@@ -132,29 +115,66 @@
 #define _POSIX_V7_LPBIG_OFFBIG      -1
 #endif
 
+#define _XOPEN_CRYPT                __BIONIC_POSIX_FEATURE_MISSING
+#define _XOPEN_ENH_I18N             1
+#define _XOPEN_LEGACY               __BIONIC_POSIX_FEATURE_MISSING
+#define _XOPEN_REALTIME             1
+#define _XOPEN_REALTIME_THREADS     1
+#define _XOPEN_SHM                  1
+#define _XOPEN_STREAMS              __BIONIC_POSIX_FEATURE_MISSING
+#define _XOPEN_UNIX                 1
+
+/* Minimum values for other maxima. These numbers are simply lower bounds mandated by POSIX. */
+/* The constant values here are explicitly specified by POSIX, not implementation dependent. */
+#define _POSIX_AIO_LISTIO_MAX       2
+#define _POSIX_AIO_MAX              1
+#define _POSIX_ARG_MAX              4096
+#define _POSIX_CHILD_MAX            25
+#define _POSIX_CLOCKRES_MIN         20000000
+#define _POSIX_DELAYTIMER_MAX       32
+#define _POSIX_HOST_NAME_MAX        255
+#define _POSIX_LINK_MAX             8
+#define _POSIX_LOGIN_NAME_MAX       9
+#define _POSIX_MAX_CANON            255
+#define _POSIX_MAX_INPUT            255
+#define _POSIX_MQ_OPEN_MAX          8
+#define _POSIX_MQ_PRIO_MAX          32
+#define _POSIX_NAME_MAX             14
+#define _POSIX_NGROUPS_MAX          8
+#define _POSIX_OPEN_MAX             20
+#define _POSIX_PATH_MAX             256
+#define _POSIX_PIPE_BUF             512
+#define _POSIX_RE_DUP_MAX           255
+#define _POSIX_RTSIG_MAX            8
+#define _POSIX_SEM_NSEMS_MAX        256
+#define _POSIX_SEM_VALUE_MAX        32767
+#define _POSIX_SIGQUEUE_MAX         32
+#define _POSIX_SSIZE_MAX            32767
+#define _POSIX_STREAM_MAX           8
+#define _POSIX_SS_REPL_MAX          4
+#define _POSIX_SYMLINK_MAX          255
+#define _POSIX_SYMLOOP_MAX          8
+#define _POSIX_THREAD_DESTRUCTOR_ITERATIONS 4
+#define _POSIX_THREAD_KEYS_MAX      128
+#define _POSIX_THREAD_THREADS_MAX   64
+#define _POSIX_TIMER_MAX            32
+#define _POSIX_TRACE_EVENT_NAME_MAX 30
+#define _POSIX_TRACE_NAME_MAX       8
+#define _POSIX_TRACE_SYS_MAX        8
+#define _POSIX_TRACE_USER_EVENT_MAX 32
+#define _POSIX_TTY_NAME_MAX         9
+#define _POSIX_TZNAME_MAX           6
 #define _POSIX2_BC_BASE_MAX         99
 #define _POSIX2_BC_DIM_MAX          2048
 #define _POSIX2_BC_SCALE_MAX        99
 #define _POSIX2_BC_STRING_MAX       1000
 #define _POSIX2_CHARCLASS_NAME_MAX  14
-#define _POSIX2_CHAR_TERM           -1  /* not implemented */
 #define _POSIX2_COLL_WEIGHTS_MAX    2
-#define _POSIX2_C_BIND              _POSIX_VERSION
-#define _POSIX2_C_DEV               -1  /* c dev utilities not implemented */
 #define _POSIX2_EXPR_NEST_MAX       32
 #define _POSIX2_LINE_MAX            2048
-#define _POSIX2_LOCALEDEF           -1  /* localedef utilitiy not implemented */
-#define _POSIX2_RE_DUP_MAX          _POSIX_RE_DUP_MAX
-#define _POSIX2_SW_DEV              -1  /* software dev utilities not implemented */
-#define _POSIX2_UPE                 -1  /* user portability utilities not implemented */
-
-#define _XOPEN_ENH_I18N             -1  /* we don't support internationalization in the C library */
-#define _XOPEN_CRYPT                -1  /* don't support X/Open Encryption */
+#define _POSIX2_RE_DUP_MAX          255
 #define _XOPEN_IOV_MAX              16
-#define _XOPEN_LEGACY               -1  /* not support all */
-#define _XOPEN_REALTIME             -1 /* we don't support all these functions */
-#define _XOPEN_REALTIME_THREADS     -1  /* same here */
-#define _XOPEN_SHM                  -1
-#define _XOPEN_UNIX                 1
+#define _XOPEN_NAME_MAX             255
+#define _XOPEN_PATH_MAX             1024
 
 #endif
diff --git a/libc/include/elf.h b/libc/include/elf.h
index 4181006..5c2503a 100644
--- a/libc/include/elf.h
+++ b/libc/include/elf.h
@@ -40,9 +40,7 @@
 #include <linux/elf.h>
 #include <linux/elf-em.h>
 
-#define ELF32_R_INFO(sym, type) ((((Elf32_Word)sym) << 8) | ((type) & 0xff))
-#define ELF64_R_INFO(sym, type) ((((Elf64_Xword)sym) << 32) | ((type) & 0xffffffff))
-
+/* http://www.sco.com/developers/gabi/latest/ch4.intro.html */
 typedef __s64 Elf32_Sxword;
 
 typedef struct {
@@ -59,6 +57,22 @@
   } a_un;
 } Elf64_auxv_t;
 
+/* http://www.sco.com/developers/gabi/latest/ch4.sheader.html */
+typedef struct {
+  Elf32_Word ch_type;
+  Elf32_Word ch_size;
+  Elf32_Word ch_addralign;
+} Elf32_Chdr;
+typedef struct {
+  Elf64_Word ch_type;
+  Elf64_Word ch_reserved;
+  Elf64_Xword ch_size;
+  Elf64_Xword ch_addralign;
+} Elf64_Chdr;
+
+typedef __u16 Elf32_Section;
+typedef __u16 Elf64_Section;
+
 typedef Elf32_Half Elf32_Versym;
 typedef Elf64_Half Elf64_Versym;
 
@@ -124,6 +138,7 @@
   Elf64_Word vna_next;
 } Elf64_Vernaux;
 
+/* http://www.sco.com/developers/gabi/latest/ch5.dynamic.html */
 #define DF_ORIGIN     0x00000001
 #define DF_SYMBOLIC   0x00000002
 #define DF_TEXTREL    0x00000004
@@ -159,6 +174,7 @@
 #define DF_1_STUB       0x04000000
 #define DF_1_PIE        0x08000000
 
+/* http://www.sco.com/developers/gabi/latest/ch5.dynamic.html */
 #define DT_BIND_NOW 24
 #define DT_INIT_ARRAY 25
 #define DT_FINI_ARRAY 26
@@ -173,40 +189,269 @@
 /* Android compressed rel/rela sections */
 #define DT_ANDROID_REL (DT_LOOS + 2)
 #define DT_ANDROID_RELSZ (DT_LOOS + 3)
-
 #define DT_ANDROID_RELA (DT_LOOS + 4)
 #define DT_ANDROID_RELASZ (DT_LOOS + 5)
 
-/* gnu hash entry */
 #define DT_GNU_HASH 0x6ffffef5
 
+/* http://www.sco.com/developers/gabi/latest/ch4.eheader.html */
+#define EI_ABIVERSION 8
+#undef EI_PAD
+#define EI_PAD 9
+
+/* http://www.sco.com/developers/gabi/latest/ch4.sheader.html */
+#define ELFCOMPRESS_ZLIB 1
+#define ELFCOMPRESS_LOOS 0x60000000
+#define ELFCOMPRESS_HIOS 0x6fffffff
+#define ELFCOMPRESS_LOPROC 0x70000000
+#define ELFCOMPRESS_HIPROC 0x7fffffff
+
+/* http://www.sco.com/developers/gabi/latest/ch4.eheader.html */
 #define ELFOSABI_SYSV 0 /* Synonym for ELFOSABI_NONE used by valgrind. */
+#define ELFOSABI_HPUX 1
+#define ELFOSABI_NETBSD 2
+#define ELFOSABI_GNU 3 /* Synonym for ELFOSABI_LINUX. */
+#define ELFOSABI_SOLARIS 6
+#define ELFOSABI_AIX 7
+#define ELFOSABI_IRIX 8
+#define ELFOSABI_FREEBSD 9
+#define ELFOSABI_TRU64 10
+#define ELFOSABI_MODESTO 11
+#define ELFOSABI_OPENBSD 12
+#define ELFOSABI_OPENVMS 13
+#define ELFOSABI_NSK 14
+#define ELFOSABI_AROS 15
+#define ELFOSABI_FENIXOS 16
+#define ELFOSABI_CLOUDABI 17
+#define ELFOSABI_OPENVOS 18
+#define ELFOSABI_ARM_AEABI 64
 
-#define PT_GNU_RELRO 0x6474e552
+/* http://www.sco.com/developers/gabi/latest/ch4.reloc.html */
+#define ELF32_R_INFO(sym, type) ((((Elf32_Word)sym) << 8) | ((type) & 0xff))
+#define ELF64_R_INFO(sym, type) ((((Elf64_Xword)sym) << 32) | ((type) & 0xffffffff))
 
+/* http://www.sco.com/developers/gabi/latest/ch4.symtab.html */
 #undef ELF_ST_TYPE
 #define ELF_ST_TYPE(x) ((x) & 0xf)
 #define ELF_ST_INFO(b,t) (((b) << 4) + ((t) & 0xf))
 #define ELF32_ST_INFO(b,t) ELF_ST_INFO(b,t)
 #define ELF64_ST_INFO(b,t) ELF_ST_INFO(b,t)
 
-#define STB_LOOS      10
-#define STB_HIOS      12
-#define STB_LOPROC    13
-#define STB_HIPROC    15
+/* http://www.sco.com/developers/gabi/latest/ch4.eheader.html */
+#define EM_S370 9
+#define EM_VPP500 17
+#define EM_960 19
+#define EM_V800 36
+#define EM_FR20 37
+#define EM_RH32 38
+#define EM_RCE 39
+#define EM_FAKE_ALPHA 41
+#define EM_TRICORE 44
+#define EM_ARC 45
+#define EM_H8_300H 47
+#define EM_H8S 48
+#define EM_H8_500 49
+#define EM_MIPS_X 51
+#define EM_COLDFIRE 52
+#define EM_68HC12 53
+#define EM_MMA 54
+#define EM_PCP 55
+#define EM_NCPU 56
+#define EM_NDR1 57
+#define EM_STARCORE 58
+#define EM_ME16 59
+#define EM_ST100 60
+#define EM_TINYJ 61
+#define EM_PDSP 63
+#define EM_PDP10 64
+#define EM_PDP11 65
+#define EM_FX66 66
+#define EM_ST9PLUS 67
+#define EM_ST7 68
+#define EM_68HC16 69
+#define EM_68HC11 70
+#define EM_68HC08 71
+#define EM_68HC05 72
+#define EM_SVX 73
+#define EM_ST19 74
+#define EM_VAX 75
+#define EM_JAVELIN 77
+#define EM_FIREPATH 78
+#define EM_ZSP 79
+#define EM_MMIX 80
+#define EM_HUANY 81
+#define EM_PRISM 82
+#define EM_AVR 83
+#define EM_FR30 84
+#define EM_D10V 85
+#define EM_D30V 86
+#define EM_V850 87
+#define EM_MN10200 90
+#define EM_PJ 91
+#define EM_ARC_COMPACT 93
+#define EM_XTENSA 94
+#define EM_VIDEOCORE 95
+#define EM_TMM_GPP 96
+#define EM_NS32K 97
+#define EM_TPC 98
+#define EM_SNP1K 99
+#define EM_ST200 100
+#define EM_IP2K 101
+#define EM_MAX 102
+#define EM_CR 103
+#define EM_F2MC16 104
+#define EM_MSP430 105
+#define EM_SE_C33 107
+#define EM_SEP 108
+#define EM_ARCA 109
+#define EM_UNICORE 110
+#define EM_EXCESS 111
+#define EM_DXP 112
+#define EM_CRX 114
+#define EM_XGATE 115
+#define EM_C166 116
+#define EM_M16C 117
+#define EM_DSPIC30F 118
+#define EM_CE 119
+#define EM_M32C 120
+#define EM_TSK3000 131
+#define EM_RS08 132
+#define EM_SHARC 133
+#define EM_ECOG2 134
+#define EM_SCORE7 135
+#define EM_DSP24 136
+#define EM_VIDEOCORE3 137
+#define EM_LATTICEMICO32 138
+#define EM_SE_C17 139
+#define EM_TI_C2000 141
+#define EM_TI_C5500 142
+#define EM_MMDSP_PLUS 160
+#define EM_CYPRESS_M8C 161
+#define EM_R32C 162
+#define EM_TRIMEDIA 163
+#define EM_QDSP6 164
+#define EM_8051 165
+#define EM_STXP7X 166
+#define EM_NDS32 167
+#define EM_ECOG1 168
+#define EM_ECOG1X 168
+#define EM_MAXQ30 169
+#define EM_XIMO16 170
+#define EM_MANIK 171
+#define EM_CRAYNV2 172
+#define EM_RX 173
+#define EM_METAG 174
+#define EM_MCST_ELBRUS 175
+#define EM_ECOG16 176
+#define EM_CR16 177
+#define EM_ETPU 178
+#define EM_SLE9X 179
+#define EM_L10M 180
+#define EM_K10M 181
+#define EM_AVR32 185
+#define EM_STM8 186
+#define EM_TILE64 187
+#define EM_CUDA 190
+#define EM_CLOUDSHIELD 192
+#define EM_COREA_1ST 193
+#define EM_COREA_2ND 194
+#define EM_ARC_COMPACT2 195
+#define EM_OPEN8 196
+#define EM_RL78 197
+#define EM_VIDEOCORE5 198
+#define EM_78KOR 199
+#define EM_56800EX 200
+#define EM_BA1 201
+#define EM_BA2 202
+#define EM_XCORE 203
+#define EM_MCHP_PIC 204
+#define EM_INTEL205 205
+#define EM_INTEL206 206
+#define EM_INTEL207 207
+#define EM_INTEL208 208
+#define EM_INTEL209 209
+#define EM_KM32 210
+#define EM_KMX32 211
+#define EM_KMX16 212
+#define EM_KMX8 213
+#define EM_KVARC 214
+#define EM_CDP 215
+#define EM_COGE 216
+#define EM_COOL 217
+#define EM_NORC 218
+#define EM_CSR_KALIMBA 219
+#define EM_Z80 220
+#define EM_VISIUM 221
+#define EM_FT32 222
+#define EM_MOXIE 223
+#define EM_AMDGPU 224
+#define EM_RISCV 243
 
-#define SHT_LOOS    0x60000000
-#define SHT_HIOS    0x6fffffff
+/* http://www.sco.com/developers/gabi/latest/ch4.eheader.html */
+#define ET_LOOS 0xfe00
+#define ET_HIOS 0xfeff
 
+/* http://www.sco.com/developers/gabi/latest/ch4.sheader.html */
+#define GRP_COMDAT 0x1
+#define GRP_MASKOS   0x0ff00000
+#define GRP_MASKPROC 0xf0000000
+
+/* http://www.sco.com/developers/gabi/latest/ch5.pheader.html */
+#define PF_X 0x1
+#define PF_W 0x2
+#define PF_R 0x4
+#define PF_MASKOS   0x0ff00000
+#define PF_MASKPROC 0xf0000000
+
+#define PT_GNU_RELRO 0x6474e552
+
+#define STB_LOOS 10
+#define STB_HIOS 12
+#define STB_LOPROC 13
+#define STB_HIPROC 15
+
+/* http://www.sco.com/developers/gabi/latest/ch4.sheader.html */
+#define SHF_MERGE 0x10
+#define SHF_STRINGS 0x20
+#define SHF_INFO_LINK 0x40
+#define SHF_LINK_ORDER 0x80
+#define SHF_OS_NONCONFORMING 0x100
+#define SHF_GROUP 0x200
+#define SHF_TLS 0x400
+#define SHF_COMPRESSED 0x800
+#define SHF_MASKOS 0x0ff00000
+#define SHF_MASKPROC 0xf0000000
+
+/* http://www.sco.com/developers/gabi/latest/ch4.sheader.html */
+#define SHN_LOOS 0xff20
+#define SHN_HIOS 0xff3f
+#define SHN_XINDEX 0xffff
+
+/* http://www.sco.com/developers/gabi/latest/ch4.sheader.html */
+#define SHT_INIT_ARRAY 14
+#define SHT_FINI_ARRAY 15
+#define SHT_PREINIT_ARRAY 16
+#define SHT_GROUP 17
+#define SHT_SYMTAB_SHNDX 18
+#undef SHT_NUM
+#define SHT_NUM 19
+#define SHT_LOOS 0x60000000
+#define SHT_HIOS 0x6fffffff
+
+/* http://www.sco.com/developers/gabi/latest/ch4.symtab.html */
+#define STN_UNDEF 0
+
+/* http://www.sco.com/developers/gabi/latest/ch4.symtab.html */
 #define STT_GNU_IFUNC 10
-#define STT_LOOS      10
-#define STT_HIOS      12
-#define STT_LOPROC    13
-#define STT_HIPROC    15
+#define STT_LOOS 10
+#define STT_HIOS 12
+#define STT_LOPROC 13
+#define STT_HIPROC 15
 
-#define STV_DEFAULT   0
-#define STV_INTERNAL  1
-#define STV_HIDDEN    2
+/* http://www.sco.com/developers/gabi/latest/ch4.symtab.html */
+#define STV_DEFAULT 0
+#define STV_INTERNAL 1
+#define STV_HIDDEN 2
 #define STV_PROTECTED 3
 
 /* The kernel uses NT_PRFPREG but glibc also offers NT_FPREGSET */
@@ -219,7 +464,7 @@
 #define VER_FLG_BASE 0x1
 #define VER_FLG_WEAK 0x2
 
-#define VER_NDX_LOCAL  0
+#define VER_NDX_LOCAL 0
 #define VER_NDX_GLOBAL 1
 
 #endif /* _ELF_H */
diff --git a/libc/include/fenv.h b/libc/include/fenv.h
index ae35ae3..2b607f5 100644
--- a/libc/include/fenv.h
+++ b/libc/include/fenv.h
@@ -31,7 +31,16 @@
 #define _FENV_H_
 
 #include <sys/cdefs.h>
-#include <machine/fenv.h>
+
+#if defined(__aarch64__) || defined(__arm__)
+#include <bits/fenv_arm.h>
+#elif defined(__i386__)
+#include <bits/fenv_x86.h>
+#elif defined(__mips__)
+#include <bits/fenv_mips.h>
+#elif defined(__x86_64__)
+#include <bits/fenv_x86_64.h>
+#endif
 
 __BEGIN_DECLS
 
diff --git a/libc/include/glob.h b/libc/include/glob.h
new file mode 100644
index 0000000..6ae8573
--- /dev/null
+++ b/libc/include/glob.h
@@ -0,0 +1,98 @@
+/*
+ * Copyright (c) 1989, 1993
+ *	The Regents of the University of California.  All rights reserved.
+ *
+ * This code is derived from software contributed to Berkeley by
+ * Guido van Rossum.
+ *
+ * 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.
+ *
+ *	@(#)glob.h	8.1 (Berkeley) 6/2/93
+ * $FreeBSD$
+ */
+
+#ifndef _GLOB_H_
+#define _GLOB_H_
+
+#include <sys/cdefs.h>
+#include <sys/types.h>
+
+struct dirent;
+struct stat;
+
+typedef struct {
+  size_t gl_pathc;	/* Count of total paths so far. */
+  size_t gl_matchc;	/* Count of paths matching pattern. */
+  size_t gl_offs;		/* Reserved at beginning of gl_pathv. */
+  int gl_flags;		/* Copy of flags parameter to glob. */
+  char** gl_pathv;	/* List of paths matching pattern. */
+
+  /* Copy of `__error_callback` parameter to glob. */
+  int (*gl_errfunc)(const char* __failure_path, int __failure_errno);
+
+  /*
+   * Alternate filesystem access methods for glob; replacement
+   * versions of closedir(3), readdir(3), opendir(3), stat(2)
+   * and lstat(2).
+   */
+  void (*gl_closedir)(void*);
+  struct dirent* (*gl_readdir)(void*);
+  void* (*gl_opendir)(const char*);
+  int (*gl_lstat)(const char*, struct stat*);
+  int (*gl_stat)(const char*, struct stat*);
+} glob_t;
+
+/* Believed to have been introduced in 1003.2-1992 */
+#define GLOB_APPEND	0x0001	/* Append to output from previous call. */
+#define GLOB_DOOFFS	0x0002	/* Prepend `gl_offs` null pointers (leaving space for exec, say). */
+#define GLOB_ERR	0x0004	/* Return on error. */
+#define GLOB_MARK	0x0008	/* Append "/" to the names of returned directories. */
+#define GLOB_NOCHECK	0x0010	/* Return pattern itself if nothing matches. */
+#define GLOB_NOSORT	0x0020	/* Don't sort. */
+#define GLOB_NOESCAPE	0x2000	/* Disable backslash escaping. */
+
+/* Error values returned by glob(3) */
+#define GLOB_NOSPACE	(-1)	/* Malloc call failed. */
+#define GLOB_ABORTED	(-2)	/* Unignored error. */
+#define GLOB_NOMATCH	(-3)	/* No match and GLOB_NOCHECK was not set. */
+
+#if __USE_BSD
+#define GLOB_ALTDIRFUNC	0x0040	/* Use alternately specified directory funcs. */
+#define GLOB_BRACE	0x0080	/* Expand braces like csh. */
+#define GLOB_MAGCHAR	0x0100	/* Set in `gl_flags` if the pattern had globbing characters. */
+#define GLOB_NOMAGIC	0x0200	/* GLOB_NOCHECK without magic chars (csh). */
+#define GLOB_QUOTE	0x0400	/* Quote special chars with \. */
+#define GLOB_TILDE	0x0800	/* Expand tilde names from the passwd file. */
+#define GLOB_LIMIT	0x1000	/* limit number of returned paths */
+#endif
+
+__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;
+
+__END_DECLS
+
+#endif
diff --git a/libc/include/limits.h b/libc/include/limits.h
index 51f4fad..48e7ea9 100644
--- a/libc/include/limits.h
+++ b/libc/include/limits.h
@@ -61,6 +61,7 @@
 #else
 # define LONG_BIT 32
 #endif
+#define WORD_BIT 32
 
 #define	SCHAR_MAX	0x7f		/* max value for a signed char */
 #define SCHAR_MIN	(-0x7f-1)	/* min value for a signed char */
@@ -130,6 +131,8 @@
 
 #define MB_LEN_MAX 4
 
+#define NZERO 20
+
 #define IOV_MAX 1024
 #define SEM_VALUE_MAX 0x3fffffff
 
@@ -140,10 +143,6 @@
 #define LOGIN_NAME_MAX 256
 #define TTY_NAME_MAX 32
 
-#define _POSIX_VERSION 200809L
-#define _POSIX2_VERSION _POSIX_VERSION
-#define _XOPEN_VERSION 700       /* by Posix definition */
-
 /* >= _POSIX_THREAD_DESTRUCTOR_ITERATIONS */
 #define PTHREAD_DESTRUCTOR_ITERATIONS 4
 /* >= _POSIX_THREAD_KEYS_MAX */
diff --git a/libc/include/math.h b/libc/include/math.h
index 6f8b863..57ca260 100644
--- a/libc/include/math.h
+++ b/libc/include/math.h
@@ -352,30 +352,6 @@
 
 #define MAXFLOAT	((float)3.40282346638528860e+38)
 
-/* Legacy cruft from before we had builtin implementations of the standard macros. */
-
-int __fpclassifyd(double __x) __attribute_const__;
-int __fpclassifyf(float __x) __attribute_const__;
-int __fpclassifyl(long double __x) __attribute_const__;
-
-int __isfinitef(float __x) __attribute_const__;
-int __isfinite(double __x) __attribute_const__;
-int __isfinitel(long double __x) __attribute_const__;
-
-int __isinff(float __x) __attribute_const__;
-int __isinfl(long double __x) __attribute_const__;
-
-int __isnanf(float __x) __attribute_const__ __INTRODUCED_IN(21);
-int __isnanl(long double __x) __attribute_const__;
-
-int __isnormal(double __x) __attribute_const__;
-int __isnormalf(float __x) __attribute_const__;
-int __isnormall(long double __x) __attribute_const__;
-
-int __signbit(double __x) __attribute_const__;
-int __signbitf(float __x) __attribute_const__;
-int __signbitl(long double __x) __attribute_const__;
-
 /* BSD extensions. */
 
 #if defined(__USE_BSD)
diff --git a/libc/include/netdb.h b/libc/include/netdb.h
index 66ec8e3..4ee0ce2 100644
--- a/libc/include/netdb.h
+++ b/libc/include/netdb.h
@@ -196,31 +196,47 @@
 
 __BEGIN_DECLS
 
+int getaddrinfo(const char* __node, const char* __service, const struct addrinfo* __hints, struct addrinfo** __result);
+void freeaddrinfo(struct addrinfo* __ptr);
+
+/* Android ABI error: POSIX getnameinfo(3) uses socklen_t rather than size_t. */
+int getnameinfo(const struct sockaddr* __sa, socklen_t __sa_length, char* __host, size_t __host_length, char* __service, size_t __service_length, int __flags);
+const char* gai_strerror(int __error);
+
+/* These functions are obsolete. Use getaddrinfo/getnameinfo instead. */
 #define h_errno (*__get_h_errno())
 int* __get_h_errno(void);
-void endservent(void);
+void herror(const char* __s);
+const char* hstrerror(int __error);
 struct hostent* gethostbyaddr(const void* __addr, socklen_t __length, int __type);
 int gethostbyaddr_r(const void* __addr, socklen_t __length, int __type, struct hostent* __ret, char* __buf, size_t __buf_size, struct hostent** __result, int* __h_errno_ptr) __INTRODUCED_IN(23);
 struct hostent* gethostbyname(const char* __name);
 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;
 struct hostent* gethostent(void);
+void sethostent(int __stay_open) __INTRODUCED_IN_FUTURE;
+
+/* These functions are obsolete. None of these functions return anything but nullptr. */
+void endnetent(void) __INTRODUCED_IN_FUTURE;
 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;
+
+/* None of these functions return anything but nullptr. */
+void endprotoent(void) __INTRODUCED_IN_FUTURE;
 struct protoent* getprotobyname(const char* __name);
 struct protoent* getprotobynumber(int __proto);
-struct servent* getservbyname(const char* __name, const char* __proto);
-struct servent* getservbyport(int __port, const char* __proto);
-struct servent* getservent(void);
-void herror(const char* __s);
-const char* hstrerror(int __error);
+struct protoent* getprotoent(void) __INTRODUCED_IN_FUTURE;
+void setprotoent(int __stay_open) __INTRODUCED_IN_FUTURE;
 
-int getaddrinfo(const char* __node, const char* __service, const struct addrinfo* __hints, struct addrinfo** __result);
-/* POSIX getnameinfo uses socklen_t, not size_t, but LP64 sizeof(socklen_t) != sizeof(size_t). */
-int getnameinfo(const struct sockaddr* __sa, socklen_t __sa_length, char* __host, size_t __host_length, char* __service, size_t __service_length, int __flags);
-void freeaddrinfo(struct addrinfo* __ptr);
-const char* gai_strerror(int __error);
+/* These functions return entries from a built-in database. */
+void endservent(void);
+struct servent* getservbyname(const char* __name, const char* __proto);
+struct servent* getservbyport(int __port_in_network_order, const char* __proto);
+struct servent* getservent(void);
 void setservent(int __stay_open);
 
 __END_DECLS
diff --git a/libc/include/pthread.h b/libc/include/pthread.h
index 32315fe..99515da 100644
--- a/libc/include/pthread.h
+++ b/libc/include/pthread.h
@@ -74,20 +74,24 @@
 #define PTHREAD_STACK_MIN (2 * PAGE_SIZE)
 #endif
 
-#define PTHREAD_CREATE_DETACHED  0x00000001
-#define PTHREAD_CREATE_JOINABLE  0x00000000
+#define PTHREAD_CREATE_DETACHED 1
+#define PTHREAD_CREATE_JOINABLE 0
 
-#define PTHREAD_PROCESS_PRIVATE  0
-#define PTHREAD_PROCESS_SHARED   1
+#define PTHREAD_EXPLICIT_SCHED 0
+#define PTHREAD_INHERIT_SCHED 1
 
-#define PTHREAD_SCOPE_SYSTEM     0
-#define PTHREAD_SCOPE_PROCESS    1
+#define PTHREAD_PROCESS_PRIVATE 0
+#define PTHREAD_PROCESS_SHARED 1
+
+#define PTHREAD_SCOPE_SYSTEM 0
+#define PTHREAD_SCOPE_PROCESS 1
 
 int pthread_atfork(void (*__prepare)(void), void (*__parent)(void), void (*__child)(void)) __INTRODUCED_IN(12);
 
 int pthread_attr_destroy(pthread_attr_t* __attr);
 int pthread_attr_getdetachstate(const pthread_attr_t* __attr, int* __state);
 int pthread_attr_getguardsize(const pthread_attr_t* __attr, size_t* __size);
+int pthread_attr_getinheritsched(const pthread_attr_t* __attr, int* __flag);
 int pthread_attr_getschedparam(const pthread_attr_t* __attr, struct sched_param* __param);
 int pthread_attr_getschedpolicy(const pthread_attr_t* __attr, int* __policy);
 int pthread_attr_getscope(const pthread_attr_t* __attr, int* __scope);
@@ -96,6 +100,7 @@
 int pthread_attr_init(pthread_attr_t* __attr);
 int pthread_attr_setdetachstate(pthread_attr_t* __attr, int __state);
 int pthread_attr_setguardsize(pthread_attr_t* __attr, size_t __size);
+int pthread_attr_setinheritsched(pthread_attr_t* __attr, int __flag);
 int pthread_attr_setschedparam(pthread_attr_t* __attr, const struct sched_param* __param);
 int pthread_attr_setschedpolicy(pthread_attr_t* __attr, int __policy);
 int pthread_attr_setscope(pthread_attr_t* __attr, int __scope);
@@ -220,6 +225,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_setspecific(pthread_key_t __key, const void* __value);
 
diff --git a/libc/include/setjmp.h b/libc/include/setjmp.h
index 12a3083..d44946f 100644
--- a/libc/include/setjmp.h
+++ b/libc/include/setjmp.h
@@ -41,11 +41,28 @@
 #define _SETJMP_H_
 
 #include <sys/cdefs.h>
-#include <machine/setjmp.h>
+
+#if defined(__aarch64__)
+#define _JBLEN 32
+#elif defined(__arm__)
+#define _JBLEN 64
+#elif defined(__i386__)
+#define _JBLEN 10
+#elif defined(__mips__)
+  #if defined(__LP64__)
+  #define _JBLEN 25
+  #else
+  #define _JBLEN 157
+  #endif
+#elif defined(__x86_64__)
+#define _JBLEN 11
+#endif
 
 typedef long sigjmp_buf[_JBLEN + 1];
 typedef long jmp_buf[_JBLEN];
 
+#undef _JBLEN
+
 __BEGIN_DECLS
 
 int _setjmp(jmp_buf __env);
diff --git a/libc/include/spawn.h b/libc/include/spawn.h
new file mode 100644
index 0000000..ea4bb19
--- /dev/null
+++ b/libc/include/spawn.h
@@ -0,0 +1,86 @@
+/*
+ * Copyright (C) 2017 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.
+ */
+
+#ifndef _SPAWN_H_
+#define _SPAWN_H_
+
+#include <sys/cdefs.h>
+#include <sys/types.h>
+#include <sched.h>
+#include <signal.h>
+
+__BEGIN_DECLS
+
+#define POSIX_SPAWN_RESETIDS 1
+#define POSIX_SPAWN_SETPGROUP 2
+#define POSIX_SPAWN_SETSIGDEF 4
+#define POSIX_SPAWN_SETSIGMASK 8
+#define POSIX_SPAWN_SETSCHEDPARAM 16
+#define POSIX_SPAWN_SETSCHEDULER 32
+#if defined(__USE_GNU)
+#define POSIX_SPAWN_USEVFORK 64
+#define POSIX_SPAWN_SETSID 128
+#endif
+
+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_spawnattr_init(posix_spawnattr_t* __attr) __INTRODUCED_IN_FUTURE;
+int posix_spawnattr_destroy(posix_spawnattr_t* __attr) __INTRODUCED_IN_FUTURE;
+
+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_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_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_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_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_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_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_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;
+
+__END_DECLS
+
+#endif
diff --git a/libc/include/stdio.h b/libc/include/stdio.h
index 559e52a..2d45fc5 100644
--- a/libc/include/stdio.h
+++ b/libc/include/stdio.h
@@ -256,7 +256,20 @@
 int fileno_unlocked(FILE* __fp) __INTRODUCED_IN(24);
 #define fropen(cookie, fn) funopen(cookie, fn, 0, 0, 0)
 #define fwopen(cookie, fn) funopen(cookie, 0, fn, 0, 0)
-#endif /* __USE_BSD */
+#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;
+#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;
+#endif
 
 #if defined(__BIONIC_INCLUDE_FORTIFY_HEADERS)
 #include <bits/fortify/stdio.h>
diff --git a/libc/include/string.h b/libc/include/string.h
index d409ba8..226566c 100644
--- a/libc/include/string.h
+++ b/libc/include/string.h
@@ -63,11 +63,8 @@
 char* __strchr_chk(const char* __s, int __ch, size_t __n) __INTRODUCED_IN(18);
 #if defined(__USE_GNU)
 #if defined(__cplusplus)
-/* The versioner doesn't handle C++ blocks yet, so manually guarded. */
-#if __ANDROID_API__ >= 24
 extern "C++" char* strchrnul(char* __s, int __ch) __RENAME(strchrnul) __attribute_pure__ __INTRODUCED_IN(24);
 extern "C++" const char* strchrnul(const char* __s, int __ch) __RENAME(strchrnul) __attribute_pure__ __INTRODUCED_IN(24);
-#endif  /* __ANDROID_API__ >= 24 */
 #else
 char* strchrnul(const char* __s, int __ch) __attribute_pure__ __INTRODUCED_IN(24);
 #endif
@@ -136,11 +133,8 @@
  * It doesn't modify its argument, and in C++ it's const-correct.
  */
 #if defined(__cplusplus)
-/* The versioner doesn't handle C++ blocks yet, so manually guarded. */
-#if __ANDROID_API__ >= 23
 extern "C++" char* basename(char* __path) __RENAME(__gnu_basename) __INTRODUCED_IN(23);
 extern "C++" const char* basename(const char* __path) __RENAME(__gnu_basename) __INTRODUCED_IN(23);
-#endif  /* __ANDROID_API__ >= 23 */
 #else
 char* basename(const char* __path) __RENAME(__gnu_basename) __INTRODUCED_IN(23);
 #endif
diff --git a/libc/include/sys/cdefs.h b/libc/include/sys/cdefs.h
index 063b51d..833ced0 100644
--- a/libc/include/sys/cdefs.h
+++ b/libc/include/sys/cdefs.h
@@ -79,6 +79,8 @@
 #define __BIONIC_CAST(_k,_t,_v) ((_t) (_v))
 #endif
 
+#define __BIONIC_ALIGN(__value, __alignment) (((__value) + (__alignment)-1) & ~((__alignment)-1))
+
 /*
  * The __CONCAT macro is used to concatenate parts of symbol names, e.g.
  * with "#define OLD(foo) __CONCAT(old,foo)", OLD(foo) produces oldfoo.
@@ -259,8 +261,13 @@
 
 #if defined(_FORTIFY_SOURCE) && _FORTIFY_SOURCE > 0
 #  if defined(__clang__)
-/* FORTIFY's _chk functions effectively disable ASAN's stdlib interceptors. */
-#    if !__has_feature(address_sanitizer)
+/*
+ * FORTIFY's _chk functions effectively disable ASAN's stdlib interceptors.
+ * Additionally, the static analyzer/clang-tidy try to pattern match some
+ * standard library functions, and FORTIFY sometimes interferes with this. So,
+ * we turn FORTIFY off in both cases.
+ */
+#    if !__has_feature(address_sanitizer) && !defined(__clang_analyzer__)
 #      define __BIONIC_FORTIFY 1
 #    endif
 #  elif defined(__OPTIMIZE__) && __OPTIMIZE__ > 0
diff --git a/libc/include/sys/mman.h b/libc/include/sys/mman.h
index 1e752c4..028b024 100644
--- a/libc/include/sys/mman.h
+++ b/libc/include/sys/mman.h
@@ -45,12 +45,30 @@
 #define MREMAP_FIXED    2
 
 #if defined(__USE_FILE_OFFSET64)
-void* mmap(void* __addr, size_t __size, int __prot, int __flags, int __fd, off_t __offset) __RENAME(mmap64) __INTRODUCED_IN(21);
+/*
+ * mmap64 wasn't really around until L, but we added an inline for it since it
+ * allows a lot more code to compile with _FILE_OFFSET_BITS=64.
+ *
+ * GCC removes the static inline unless it is explicitly used. We can get around
+ * this with __attribute__((used)), but that needlessly adds a definition of
+ * mmap64 to every translation unit that includes this header. Instead, just
+ * preserve the old behavior for GCC and emit a useful diagnostic.
+ */
+void* mmap(void* __addr, size_t __size, int __prot, int __flags, int __fd, off_t __offset)
+#if !defined(__clang__) && __ANDROID_API__ < __ANDROID_API_L__
+    __attribute__((error("mmap is not available with _FILE_OFFSET_BITS=64 when using GCC until "
+                         "android-21. Either raise your minSdkVersion, disable "
+                         "_FILE_OFFSET_BITS=64, or switch to Clang.")));
+#else
+    __RENAME(mmap64);
+#endif  /* defined(__clang__) */
 #else
 void* mmap(void* __addr, size_t __size, int __prot, int __flags, int __fd, off_t __offset);
-#endif
+#endif  /* defined(__USE_FILE_OFFSET64) */
 
+#if __ANDROID_API__ >= __ANDROID_API_L__
 void* mmap64(void* __addr, size_t __size, int __prot, int __flags, int __fd, off64_t __offset) __INTRODUCED_IN(21);
+#endif
 
 int munmap(void* __addr, size_t __size);
 int msync(void* __addr, size_t __size, int __flags);
@@ -86,4 +104,6 @@
 
 __END_DECLS
 
+#include <android/legacy_sys_mman_inlines.h>
+
 #endif
diff --git a/libc/arch-arm64/include/machine/setjmp.h b/libc/include/sys/random.h
similarity index 72%
copy from libc/arch-arm64/include/machine/setjmp.h
copy to libc/include/sys/random.h
index 27c2fe5..3475652 100644
--- a/libc/arch-arm64/include/machine/setjmp.h
+++ b/libc/include/sys/random.h
@@ -1,5 +1,5 @@
 /*
- * Copyright (C) 2013 The Android Open Source Project
+ * Copyright (C) 2017 The Android Open Source Project
  * All rights reserved.
  *
  * Redistribution and use in source and binary forms, with or without
@@ -26,5 +26,22 @@
  * SUCH DAMAGE.
  */
 
-/* _JBLEN is the size of a jmp_buf in longs (64bit on AArch64) */
-#define _JBLEN 32
+#ifndef _SYS_RANDOM_H_
+#define _SYS_RANDOM_H_
+
+#include <sys/cdefs.h>
+#include <sys/types.h>
+
+#include <linux/random.h>
+
+__BEGIN_DECLS
+
+/* 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;
+
+ssize_t getrandom(void* __buffer, size_t __buffer_size, unsigned int __flags) __wur __INTRODUCED_IN_FUTURE;
+
+__END_DECLS
+
+#endif
diff --git a/libc/include/unistd.h b/libc/include/unistd.h
index 9cfb918..c60cf80 100644
--- a/libc/include/unistd.h
+++ b/libc/include/unistd.h
@@ -98,6 +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 nice(int __incr);
 
@@ -246,6 +247,8 @@
 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;
+
 #if defined(__BIONIC_INCLUDE_FORTIFY_HEADERS)
 #include <bits/fortify/unistd.h>
 #endif
diff --git a/libc/kernel/tools/cpp.py b/libc/kernel/tools/cpp.py
index fff80f6..68144cd 100644
--- a/libc/kernel/tools/cpp.py
+++ b/libc/kernel/tools/cpp.py
@@ -27,7 +27,7 @@
 
 # Set up LD_LIBRARY_PATH to include libclang.so, libLLVM.so, and etc.
 # Note that setting LD_LIBRARY_PATH with os.putenv() sometimes doesn't help.
-clang.cindex.Config.set_library_path(os.path.join(top, 'prebuilts/sdk/tools/linux/lib64'))
+clang.cindex.Config.set_library_file(os.path.join(top, 'prebuilts/sdk/tools/linux/lib64/libclang_android.so'))
 
 from defaults import kCppUndefinedMacro
 from defaults import kernel_remove_config_macros
diff --git a/libc/kernel/tools/defaults.py b/libc/kernel/tools/defaults.py
index b0fb95f..1afdc77 100644
--- a/libc/kernel/tools/defaults.py
+++ b/libc/kernel/tools/defaults.py
@@ -58,8 +58,6 @@
 
 # Replace tokens in the output according to this mapping.
 kernel_token_replacements = {
-    # The kernel's ARG_MAX is actually the "minimum" maximum (see fs/exec.c).
-    "ARG_MAX": "_KERNEL_ARG_MAX",
     # The kernel usage of __unused for unused struct fields conflicts with the macro defined in <sys/cdefs.h>.
     "__unused": "__linux_unused",
     # The kernel usage of C++ keywords causes problems for C++ code so rename.
@@ -84,8 +82,6 @@
     "epoll_event": "__kernel_uapi_epoll_event",
     # This causes problems when trying to export the headers for the ndk.
     "__attribute_const__": "__attribute__((__const__))",
-    # There is a mismatch between upstream and our kernels for this structure.
-    "binder_fd_array_object": "__kernel_binder_fd_array_object",
     }
 
 # This is the set of known static inline functions that we want to keep
diff --git a/libc/kernel/uapi/asm-arm/asm/kvm.h b/libc/kernel/uapi/asm-arm/asm/kvm.h
index c814a09..2332ae2 100644
--- a/libc/kernel/uapi/asm-arm/asm/kvm.h
+++ b/libc/kernel/uapi/asm-arm/asm/kvm.h
@@ -147,6 +147,12 @@
 #define KVM_DEV_ARM_VGIC_LINE_LEVEL_INFO_MASK (0x3fffffULL << KVM_DEV_ARM_VGIC_LINE_LEVEL_INFO_SHIFT)
 #define KVM_DEV_ARM_VGIC_LINE_LEVEL_INTID_MASK 0x3ff
 #define VGIC_LEVEL_INFO_LINE_LEVEL 0
+#define KVM_ARM_VCPU_PMU_V3_CTRL 0
+#define KVM_ARM_VCPU_PMU_V3_IRQ 0
+#define KVM_ARM_VCPU_PMU_V3_INIT 1
+#define KVM_ARM_VCPU_TIMER_CTRL 1
+#define KVM_ARM_VCPU_TIMER_IRQ_VTIMER 0
+#define KVM_ARM_VCPU_TIMER_IRQ_PTIMER 1
 #define KVM_DEV_ARM_VGIC_CTRL_INIT 0
 #define KVM_DEV_ARM_ITS_SAVE_TABLES 1
 #define KVM_DEV_ARM_ITS_RESTORE_TABLES 2
diff --git a/libc/kernel/uapi/asm-arm64/asm/hwcap.h b/libc/kernel/uapi/asm-arm64/asm/hwcap.h
index 4ab16ad..60b8305 100644
--- a/libc/kernel/uapi/asm-arm64/asm/hwcap.h
+++ b/libc/kernel/uapi/asm-arm64/asm/hwcap.h
@@ -34,4 +34,5 @@
 #define HWCAP_JSCVT (1 << 13)
 #define HWCAP_FCMA (1 << 14)
 #define HWCAP_LRCPC (1 << 15)
+#define HWCAP_DCPOP (1 << 16)
 #endif
diff --git a/libc/kernel/uapi/asm-arm64/asm/kvm.h b/libc/kernel/uapi/asm-arm64/asm/kvm.h
index dade888..a68a8a2 100644
--- a/libc/kernel/uapi/asm-arm64/asm/kvm.h
+++ b/libc/kernel/uapi/asm-arm64/asm/kvm.h
@@ -147,6 +147,9 @@
 #define KVM_ARM_VCPU_PMU_V3_CTRL 0
 #define KVM_ARM_VCPU_PMU_V3_IRQ 0
 #define KVM_ARM_VCPU_PMU_V3_INIT 1
+#define KVM_ARM_VCPU_TIMER_CTRL 1
+#define KVM_ARM_VCPU_TIMER_IRQ_VTIMER 0
+#define KVM_ARM_VCPU_TIMER_IRQ_PTIMER 1
 #define KVM_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-arm64/asm/sigcontext.h b/libc/kernel/uapi/asm-arm64/asm/sigcontext.h
index 80d61b0..be2464e 100644
--- a/libc/kernel/uapi/asm-arm64/asm/sigcontext.h
+++ b/libc/kernel/uapi/asm-arm64/asm/sigcontext.h
@@ -43,4 +43,11 @@
   struct _aarch64_ctx head;
   __u64 esr;
 };
+#define EXTRA_MAGIC 0x45585401
+struct extra_context {
+  struct _aarch64_ctx head;
+  __u64 datap;
+  __u32 size;
+  __u32 __reserved[3];
+};
 #endif
diff --git a/libc/kernel/uapi/asm-generic/hugetlb_encode.h b/libc/kernel/uapi/asm-generic/hugetlb_encode.h
new file mode 100644
index 0000000..68849b3
--- /dev/null
+++ b/libc/kernel/uapi/asm-generic/hugetlb_encode.h
@@ -0,0 +1,33 @@
+/****************************************************************************
+ ****************************************************************************
+ ***
+ ***   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 _ASM_GENERIC_HUGETLB_ENCODE_H_
+#define _ASM_GENERIC_HUGETLB_ENCODE_H_
+#define HUGETLB_FLAG_ENCODE_SHIFT 26
+#define HUGETLB_FLAG_ENCODE_MASK 0x3f
+#define HUGETLB_FLAG_ENCODE_64KB (16 << HUGETLB_FLAG_ENCODE_SHIFT)
+#define HUGETLB_FLAG_ENCODE_512KB (19 << HUGETLB_FLAG_ENCODE_SHIFT)
+#define HUGETLB_FLAG_ENCODE_1MB (20 << HUGETLB_FLAG_ENCODE_SHIFT)
+#define HUGETLB_FLAG_ENCODE_2MB (21 << HUGETLB_FLAG_ENCODE_SHIFT)
+#define HUGETLB_FLAG_ENCODE_8MB (23 << HUGETLB_FLAG_ENCODE_SHIFT)
+#define HUGETLB_FLAG_ENCODE_16MB (24 << HUGETLB_FLAG_ENCODE_SHIFT)
+#define HUGETLB_FLAG_ENCODE_256MB (28 << HUGETLB_FLAG_ENCODE_SHIFT)
+#define HUGETLB_FLAG_ENCODE_1GB (30 << HUGETLB_FLAG_ENCODE_SHIFT)
+#define HUGETLB_FLAG_ENCODE_2GB (31 << HUGETLB_FLAG_ENCODE_SHIFT)
+#define HUGETLB_FLAG_ENCODE_16GB (34 << HUGETLB_FLAG_ENCODE_SHIFT)
+#endif
diff --git a/libc/kernel/uapi/asm-generic/ioctls.h b/libc/kernel/uapi/asm-generic/ioctls.h
index 792bf0f..41dbce2 100644
--- a/libc/kernel/uapi/asm-generic/ioctls.h
+++ b/libc/kernel/uapi/asm-generic/ioctls.h
@@ -80,6 +80,7 @@
 #define TIOCGPKT _IOR('T', 0x38, int)
 #define TIOCGPTLCK _IOR('T', 0x39, int)
 #define TIOCGEXCL _IOR('T', 0x40, int)
+#define TIOCGPTPEER _IO('T', 0x41)
 #define FIONCLEX 0x5450
 #define FIOCLEX 0x5451
 #define FIOASYNC 0x5452
diff --git a/libc/kernel/uapi/asm-generic/mman-common.h b/libc/kernel/uapi/asm-generic/mman-common.h
index 047743d..a15624a 100644
--- a/libc/kernel/uapi/asm-generic/mman-common.h
+++ b/libc/kernel/uapi/asm-generic/mman-common.h
@@ -52,9 +52,9 @@
 #define MADV_NOHUGEPAGE 15
 #define MADV_DONTDUMP 16
 #define MADV_DODUMP 17
+#define MADV_WIPEONFORK 18
+#define MADV_KEEPONFORK 19
 #define MAP_FILE 0
-#define MAP_HUGE_SHIFT 26
-#define MAP_HUGE_MASK 0x3f
 #define PKEY_DISABLE_ACCESS 0x1
 #define PKEY_DISABLE_WRITE 0x2
 #define PKEY_ACCESS_MASK (PKEY_DISABLE_ACCESS | PKEY_DISABLE_WRITE)
diff --git a/libc/kernel/uapi/asm-generic/siginfo.h b/libc/kernel/uapi/asm-generic/siginfo.h
index f98fd73..669c9d4 100644
--- a/libc/kernel/uapi/asm-generic/siginfo.h
+++ b/libc/kernel/uapi/asm-generic/siginfo.h
@@ -126,75 +126,66 @@
 #define si_syscall _sifields._sigsys._syscall
 #define si_arch _sifields._sigsys._arch
 #endif
-#define __SI_KILL 0
-#define __SI_TIMER 0
-#define __SI_POLL 0
-#define __SI_FAULT 0
-#define __SI_CHLD 0
-#define __SI_RT 0
-#define __SI_MESGQ 0
-#define __SI_SYS 0
-#define __SI_CODE(T,N) (N)
 #define SI_USER 0
 #define SI_KERNEL 0x80
 #define SI_QUEUE - 1
-#define SI_TIMER __SI_CODE(__SI_TIMER, - 2)
-#define SI_MESGQ __SI_CODE(__SI_MESGQ, - 3)
+#define SI_TIMER - 2
+#define SI_MESGQ - 3
 #define SI_ASYNCIO - 4
 #define SI_SIGIO - 5
 #define SI_TKILL - 6
 #define SI_DETHREAD - 7
 #define SI_FROMUSER(siptr) ((siptr)->si_code <= 0)
 #define SI_FROMKERNEL(siptr) ((siptr)->si_code > 0)
-#define ILL_ILLOPC (__SI_FAULT | 1)
-#define ILL_ILLOPN (__SI_FAULT | 2)
-#define ILL_ILLADR (__SI_FAULT | 3)
-#define ILL_ILLTRP (__SI_FAULT | 4)
-#define ILL_PRVOPC (__SI_FAULT | 5)
-#define ILL_PRVREG (__SI_FAULT | 6)
-#define ILL_COPROC (__SI_FAULT | 7)
-#define ILL_BADSTK (__SI_FAULT | 8)
+#define ILL_ILLOPC 1
+#define ILL_ILLOPN 2
+#define ILL_ILLADR 3
+#define ILL_ILLTRP 4
+#define ILL_PRVOPC 5
+#define ILL_PRVREG 6
+#define ILL_COPROC 7
+#define ILL_BADSTK 8
 #define NSIGILL 8
-#define FPE_INTDIV (__SI_FAULT | 1)
-#define FPE_INTOVF (__SI_FAULT | 2)
-#define FPE_FLTDIV (__SI_FAULT | 3)
-#define FPE_FLTOVF (__SI_FAULT | 4)
-#define FPE_FLTUND (__SI_FAULT | 5)
-#define FPE_FLTRES (__SI_FAULT | 6)
-#define FPE_FLTINV (__SI_FAULT | 7)
-#define FPE_FLTSUB (__SI_FAULT | 8)
+#define FPE_INTDIV 1
+#define FPE_INTOVF 2
+#define FPE_FLTDIV 3
+#define FPE_FLTOVF 4
+#define FPE_FLTUND 5
+#define FPE_FLTRES 6
+#define FPE_FLTINV 7
+#define FPE_FLTSUB 8
 #define NSIGFPE 8
-#define SEGV_MAPERR (__SI_FAULT | 1)
-#define SEGV_ACCERR (__SI_FAULT | 2)
-#define SEGV_BNDERR (__SI_FAULT | 3)
-#define SEGV_PKUERR (__SI_FAULT | 4)
+#define SEGV_MAPERR 1
+#define SEGV_ACCERR 2
+#define SEGV_BNDERR 3
+#define SEGV_PKUERR 4
 #define NSIGSEGV 4
-#define BUS_ADRALN (__SI_FAULT | 1)
-#define BUS_ADRERR (__SI_FAULT | 2)
-#define BUS_OBJERR (__SI_FAULT | 3)
-#define BUS_MCEERR_AR (__SI_FAULT | 4)
-#define BUS_MCEERR_AO (__SI_FAULT | 5)
+#define BUS_ADRALN 1
+#define BUS_ADRERR 2
+#define BUS_OBJERR 3
+#define BUS_MCEERR_AR 4
+#define BUS_MCEERR_AO 5
 #define NSIGBUS 5
-#define TRAP_BRKPT (__SI_FAULT | 1)
-#define TRAP_TRACE (__SI_FAULT | 2)
-#define TRAP_BRANCH (__SI_FAULT | 3)
-#define TRAP_HWBKPT (__SI_FAULT | 4)
+#define TRAP_BRKPT 1
+#define TRAP_TRACE 2
+#define TRAP_BRANCH 3
+#define TRAP_HWBKPT 4
 #define NSIGTRAP 4
-#define CLD_EXITED (__SI_CHLD | 1)
-#define CLD_KILLED (__SI_CHLD | 2)
-#define CLD_DUMPED (__SI_CHLD | 3)
-#define CLD_TRAPPED (__SI_CHLD | 4)
-#define CLD_STOPPED (__SI_CHLD | 5)
-#define CLD_CONTINUED (__SI_CHLD | 6)
+#define CLD_EXITED 1
+#define CLD_KILLED 2
+#define CLD_DUMPED 3
+#define CLD_TRAPPED 4
+#define CLD_STOPPED 5
+#define CLD_CONTINUED 6
 #define NSIGCHLD 6
-#define POLL_IN (__SI_POLL | 1)
-#define POLL_OUT (__SI_POLL | 2)
-#define POLL_MSG (__SI_POLL | 3)
-#define POLL_ERR (__SI_POLL | 4)
-#define POLL_PRI (__SI_POLL | 5)
-#define POLL_HUP (__SI_POLL | 6)
+#define POLL_IN 1
+#define POLL_OUT 2
+#define POLL_MSG 3
+#define POLL_ERR 4
+#define POLL_PRI 5
+#define POLL_HUP 6
 #define NSIGPOLL 6
-#define SYS_SECCOMP (__SI_SYS | 1)
+#define SYS_SECCOMP 1
 #define NSIGSYS 1
 #define SIGEV_SIGNAL 0
 #define SIGEV_NONE 1
diff --git a/libc/kernel/uapi/asm-generic/socket.h b/libc/kernel/uapi/asm-generic/socket.h
index d1dc0099..b821554 100644
--- a/libc/kernel/uapi/asm-generic/socket.h
+++ b/libc/kernel/uapi/asm-generic/socket.h
@@ -85,4 +85,7 @@
 #define SO_MEMINFO 55
 #define SO_INCOMING_NAPI_ID 56
 #define SO_COOKIE 57
+#define SCM_TIMESTAMPING_PKTINFO 58
+#define SO_PEERGROUPS 59
+#define SO_ZEROCOPY 60
 #endif
diff --git a/libc/kernel/uapi/asm-mips/asm/inst.h b/libc/kernel/uapi/asm-mips/asm/inst.h
index 46a65e6..61fa3d6 100644
--- a/libc/kernel/uapi/asm-mips/asm/inst.h
+++ b/libc/kernel/uapi/asm-mips/asm/inst.h
@@ -414,10 +414,13 @@
 };
 enum bshfl_func {
   wsbh_op = 0x2,
-  dshd_op = 0x5,
   seb_op = 0x10,
   seh_op = 0x18,
 };
+enum dbshfl_func {
+  dsbh_op = 0x2,
+  dshd_op = 0x5,
+};
 enum msa_func {
   msa_elm_op = 0x19,
 };
@@ -798,6 +801,10 @@
   __BITFIELD_FIELD(unsigned int opcode : 6, __BITFIELD_FIELD(signed int s10 : 10, __BITFIELD_FIELD(unsigned int rs : 5, __BITFIELD_FIELD(unsigned int wd : 5, __BITFIELD_FIELD(unsigned int func : 4, __BITFIELD_FIELD(unsigned int df : 2,;
  ))))))
 };
+struct dsp_format {
+  __BITFIELD_FIELD(unsigned int opcode : 6, __BITFIELD_FIELD(unsigned int base : 5, __BITFIELD_FIELD(unsigned int index : 5, __BITFIELD_FIELD(unsigned int rd : 5, __BITFIELD_FIELD(unsigned int op : 5, __BITFIELD_FIELD(unsigned int func : 6,;
+ ))))))
+};
 struct spec3_format {
   __BITFIELD_FIELD(unsigned int opcode : 6, __BITFIELD_FIELD(unsigned int rs : 5, __BITFIELD_FIELD(unsigned int rt : 5, __BITFIELD_FIELD(signed int simmediate : 9, __BITFIELD_FIELD(unsigned int func : 7,;
  )))))
@@ -883,7 +890,7 @@
  ))))
 };
 struct mm16_r5_format {
-  __BITFIELD_FIELD(unsigned int opcode : 6, __BITFIELD_FIELD(unsigned int rt : 5, __BITFIELD_FIELD(signed int simmediate : 5, __BITFIELD_FIELD(unsigned int : 16,;
+  __BITFIELD_FIELD(unsigned int opcode : 6, __BITFIELD_FIELD(unsigned int rt : 5, __BITFIELD_FIELD(unsigned int imm : 5, __BITFIELD_FIELD(unsigned int : 16,;
  ))))
 };
 struct m16e_rr {
@@ -933,6 +940,7 @@
   struct b_format b_format;
   struct ps_format ps_format;
   struct v_format v_format;
+  struct dsp_format dsp_format;
   struct spec3_format spec3_format;
   struct fb_format fb_format;
   struct fp0_format fp0_format;
diff --git a/libc/kernel/uapi/asm-mips/asm/ioctls.h b/libc/kernel/uapi/asm-mips/asm/ioctls.h
index 1845c65..a4a40b0 100644
--- a/libc/kernel/uapi/asm-mips/asm/ioctls.h
+++ b/libc/kernel/uapi/asm-mips/asm/ioctls.h
@@ -84,6 +84,7 @@
 #define TIOCGPKT _IOR('T', 0x38, int)
 #define TIOCGPTLCK _IOR('T', 0x39, int)
 #define TIOCGEXCL _IOR('T', 0x40, int)
+#define TIOCGPTPEER _IO('T', 0x41)
 #define TIOCSCTTY 0x5480
 #define TIOCGSOFTCAR 0x5481
 #define TIOCSSOFTCAR 0x5482
diff --git a/libc/kernel/uapi/asm-mips/asm/mman.h b/libc/kernel/uapi/asm-mips/asm/mman.h
index ad08f7a..b976885 100644
--- a/libc/kernel/uapi/asm-mips/asm/mman.h
+++ b/libc/kernel/uapi/asm-mips/asm/mman.h
@@ -66,9 +66,9 @@
 #define MADV_NOHUGEPAGE 15
 #define MADV_DONTDUMP 16
 #define MADV_DODUMP 17
+#define MADV_WIPEONFORK 18
+#define MADV_KEEPONFORK 19
 #define MAP_FILE 0
-#define MAP_HUGE_SHIFT 26
-#define MAP_HUGE_MASK 0x3f
 #define PKEY_DISABLE_ACCESS 0x1
 #define PKEY_DISABLE_WRITE 0x2
 #define PKEY_ACCESS_MASK (PKEY_DISABLE_ACCESS | PKEY_DISABLE_WRITE)
diff --git a/libc/kernel/uapi/asm-mips/asm/siginfo.h b/libc/kernel/uapi/asm-mips/asm/siginfo.h
index b652925..413abd9 100644
--- a/libc/kernel/uapi/asm-mips/asm/siginfo.h
+++ b/libc/kernel/uapi/asm-mips/asm/siginfo.h
@@ -95,6 +95,6 @@
 #undef SI_TIMER
 #undef SI_MESGQ
 #define SI_ASYNCIO - 2
-#define SI_TIMER __SI_CODE(__SI_TIMER, - 3)
-#define SI_MESGQ __SI_CODE(__SI_MESGQ, - 4)
+#define SI_TIMER - 3
+#define SI_MESGQ - 4
 #endif
diff --git a/libc/kernel/uapi/asm-mips/asm/socket.h b/libc/kernel/uapi/asm-mips/asm/socket.h
index e97ae58..b8de15c 100644
--- a/libc/kernel/uapi/asm-mips/asm/socket.h
+++ b/libc/kernel/uapi/asm-mips/asm/socket.h
@@ -84,4 +84,7 @@
 #define SO_MEMINFO 55
 #define SO_INCOMING_NAPI_ID 56
 #define SO_COOKIE 57
+#define SCM_TIMESTAMPING_PKTINFO 58
+#define SO_PEERGROUPS 59
+#define SO_ZEROCOPY 60
 #endif
diff --git a/libc/kernel/uapi/asm-x86/asm/hyperv.h b/libc/kernel/uapi/asm-x86/asm/hyperv.h
index 2d4b97a..d5c9b19 100644
--- a/libc/kernel/uapi/asm-x86/asm/hyperv.h
+++ b/libc/kernel/uapi/asm-x86/asm/hyperv.h
@@ -32,8 +32,7 @@
 #define HV_X64_MSR_TIME_REF_COUNT_AVAILABLE (1 << 1)
 #define HV_X64_MSR_REFERENCE_TSC_AVAILABLE (1 << 9)
 #define HV_X64_MSR_REFERENCE_TSC 0x40000021
-#define HV_X64_MSR_APIC_FREQUENCY_AVAILABLE (1 << 11)
-#define HV_X64_MSR_TSC_FREQUENCY_AVAILABLE (1 << 11)
+#define HV_X64_ACCESS_FREQUENCY_MSRS (1 << 11)
 #define HV_X64_MSR_SYNIC_AVAILABLE (1 << 2)
 #define HV_X64_MSR_SYNTIMER_AVAILABLE (1 << 3)
 #define HV_X64_MSR_APIC_ACCESS_AVAILABLE (1 << 4)
@@ -41,6 +40,7 @@
 #define HV_X64_MSR_VP_INDEX_AVAILABLE (1 << 6)
 #define HV_X64_MSR_RESET_AVAILABLE (1 << 7)
 #define HV_X64_MSR_STAT_PAGES_AVAILABLE (1 << 8)
+#define HV_FEATURE_FREQUENCY_MSRS_AVAILABLE (1 << 8)
 #define HV_FEATURE_GUEST_CRASH_MSR_AVAILABLE (1 << 10)
 #define HV_X64_CREATE_PARTITIONS (1 << 0)
 #define HV_X64_ACCESS_PARTITION_ID (1 << 1)
@@ -68,6 +68,7 @@
 #define HV_X64_SYSTEM_RESET_RECOMMENDED (1 << 4)
 #define HV_X64_RELAXED_TIMING_RECOMMENDED (1 << 5)
 #define HV_X64_DEPRECATING_AEOI_RECOMMENDED (1 << 9)
+#define HV_X64_EX_PROCESSOR_MASKS_RECOMMENDED (1 << 11)
 #define HV_CRASH_CTL_CRASH_NOTIFY (1ULL << 63)
 #define HV_X64_MSR_GUEST_OS_ID 0x40000000
 #define HV_X64_MSR_HYPERCALL 0x40000001
@@ -121,7 +122,11 @@
 #define HV_X64_MSR_HYPERCALL_ENABLE 0x00000001
 #define HV_X64_MSR_HYPERCALL_PAGE_ADDRESS_SHIFT 12
 #define HV_X64_MSR_HYPERCALL_PAGE_ADDRESS_MASK (~((1ull << HV_X64_MSR_HYPERCALL_PAGE_ADDRESS_SHIFT) - 1))
+#define HVCALL_FLUSH_VIRTUAL_ADDRESS_SPACE 0x0002
+#define HVCALL_FLUSH_VIRTUAL_ADDRESS_LIST 0x0003
 #define HVCALL_NOTIFY_LONG_SPIN_WAIT 0x0008
+#define HVCALL_FLUSH_VIRTUAL_ADDRESS_SPACE_EX 0x0013
+#define HVCALL_FLUSH_VIRTUAL_ADDRESS_LIST_EX 0x0014
 #define HVCALL_POST_MESSAGE 0x005c
 #define HVCALL_SIGNAL_EVENT 0x005d
 #define HV_X64_MSR_APIC_ASSIST_PAGE_ENABLE 0x00000001
@@ -133,6 +138,14 @@
 #define HV_PROCESSOR_POWER_STATE_C1 1
 #define HV_PROCESSOR_POWER_STATE_C2 2
 #define HV_PROCESSOR_POWER_STATE_C3 3
+#define HV_FLUSH_ALL_PROCESSORS BIT(0)
+#define HV_FLUSH_ALL_VIRTUAL_ADDRESS_SPACES BIT(1)
+#define HV_FLUSH_NON_GLOBAL_MAPPINGS_ONLY BIT(2)
+#define HV_FLUSH_USE_EXTENDED_RANGE_FORMAT BIT(3)
+enum HV_GENERIC_SET_FORMAT {
+  HV_GENERIC_SET_SPARCE_4K,
+  HV_GENERIC_SET_ALL,
+};
 #define HV_STATUS_SUCCESS 0
 #define HV_STATUS_INVALID_HYPERCALL_CODE 2
 #define HV_STATUS_INVALID_HYPERCALL_INPUT 3
diff --git a/libc/kernel/uapi/asm-x86/asm/kvm_para.h b/libc/kernel/uapi/asm-x86/asm/kvm_para.h
index 78008df..b7635cb 100644
--- a/libc/kernel/uapi/asm-x86/asm/kvm_para.h
+++ b/libc/kernel/uapi/asm-x86/asm/kvm_para.h
@@ -61,6 +61,7 @@
 #define KVM_MAX_MMU_OP_BATCH 32
 #define KVM_ASYNC_PF_ENABLED (1 << 0)
 #define KVM_ASYNC_PF_SEND_ALWAYS (1 << 1)
+#define KVM_ASYNC_PF_DELIVERY_AS_PF_VMEXIT (1 << 2)
 #define KVM_MMU_OP_WRITE_PTE 1
 #define KVM_MMU_OP_FLUSH_TLB 2
 #define KVM_MMU_OP_RELEASE_PT 3
diff --git a/libc/kernel/uapi/asm-x86/asm/mman.h b/libc/kernel/uapi/asm-x86/asm/mman.h
index b958829..1061a6f 100644
--- a/libc/kernel/uapi/asm-x86/asm/mman.h
+++ b/libc/kernel/uapi/asm-x86/asm/mman.h
@@ -19,7 +19,5 @@
 #ifndef _ASM_X86_MMAN_H
 #define _ASM_X86_MMAN_H
 #define MAP_32BIT 0x40
-#define MAP_HUGE_2MB (21 << MAP_HUGE_SHIFT)
-#define MAP_HUGE_1GB (30 << MAP_HUGE_SHIFT)
 #include <asm-generic/mman.h>
 #endif
diff --git a/libc/kernel/uapi/asm-x86/asm/processor-flags.h b/libc/kernel/uapi/asm-x86/asm/processor-flags.h
index 9f61c0a..f0f8dd2 100644
--- a/libc/kernel/uapi/asm-x86/asm/processor-flags.h
+++ b/libc/kernel/uapi/asm-x86/asm/processor-flags.h
@@ -104,6 +104,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_LA57_BIT 12
+#define X86_CR4_LA57 _BITUL(X86_CR4_LA57_BIT)
 #define X86_CR4_VMXE_BIT 13
 #define X86_CR4_VMXE _BITUL(X86_CR4_VMXE_BIT)
 #define X86_CR4_SMXE_BIT 14
diff --git a/libc/kernel/uapi/drm/amdgpu_drm.h b/libc/kernel/uapi/drm/amdgpu_drm.h
index f5e8b16..6ae9c9c 100644
--- a/libc/kernel/uapi/drm/amdgpu_drm.h
+++ b/libc/kernel/uapi/drm/amdgpu_drm.h
@@ -34,6 +34,7 @@
 #define DRM_AMDGPU_GEM_OP 0x10
 #define DRM_AMDGPU_GEM_USERPTR 0x11
 #define DRM_AMDGPU_WAIT_FENCES 0x12
+#define DRM_AMDGPU_VM 0x13
 #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)
@@ -47,6 +48,7 @@
 #define DRM_IOCTL_AMDGPU_GEM_OP DRM_IOWR(DRM_COMMAND_BASE + DRM_AMDGPU_GEM_OP, struct drm_amdgpu_gem_op)
 #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 AMDGPU_GEM_DOMAIN_CPU 0x1
 #define AMDGPU_GEM_DOMAIN_GTT 0x2
 #define AMDGPU_GEM_DOMAIN_VRAM 0x4
@@ -123,6 +125,19 @@
   struct drm_amdgpu_ctx_in in;
   union drm_amdgpu_ctx_out out;
 };
+#define AMDGPU_VM_OP_RESERVE_VMID 1
+#define AMDGPU_VM_OP_UNRESERVE_VMID 2
+struct drm_amdgpu_vm_in {
+  __u32 op;
+  __u32 flags;
+};
+struct drm_amdgpu_vm_out {
+  __u64 flags;
+};
+union drm_amdgpu_vm {
+  struct drm_amdgpu_vm_in in;
+  struct drm_amdgpu_vm_out out;
+};
 #define AMDGPU_GEM_USERPTR_READONLY (1 << 0)
 #define AMDGPU_GEM_USERPTR_ANONONLY (1 << 1)
 #define AMDGPU_GEM_USERPTR_VALIDATE (1 << 2)
@@ -262,11 +277,15 @@
 #define AMDGPU_HW_IP_UVD 3
 #define AMDGPU_HW_IP_VCE 4
 #define AMDGPU_HW_IP_UVD_ENC 5
-#define AMDGPU_HW_IP_NUM 6
+#define AMDGPU_HW_IP_VCN_DEC 6
+#define AMDGPU_HW_IP_VCN_ENC 7
+#define AMDGPU_HW_IP_NUM 8
 #define AMDGPU_HW_IP_INSTANCE_MAX_COUNT 1
 #define AMDGPU_CHUNK_ID_IB 0x01
 #define AMDGPU_CHUNK_ID_FENCE 0x02
 #define AMDGPU_CHUNK_ID_DEPENDENCIES 0x03
+#define AMDGPU_CHUNK_ID_SYNCOBJ_IN 0x04
+#define AMDGPU_CHUNK_ID_SYNCOBJ_OUT 0x05
 struct drm_amdgpu_cs_chunk {
   __u32 chunk_id;
   __u32 length_dw;
@@ -309,6 +328,9 @@
   __u32 handle;
   __u32 offset;
 };
+struct drm_amdgpu_cs_chunk_sem {
+  __u32 handle;
+};
 struct drm_amdgpu_cs_chunk_data {
   union {
     struct drm_amdgpu_cs_chunk_ib ib_data;
@@ -358,6 +380,7 @@
 #define AMDGPU_INFO_SENSOR_GPU_AVG_POWER 0x5
 #define AMDGPU_INFO_SENSOR_VDDNB 0x6
 #define AMDGPU_INFO_SENSOR_VDDGFX 0x7
+#define AMDGPU_INFO_NUM_VRAM_CPU_PAGE_FAULTS 0x1E
 #define AMDGPU_INFO_MMR_SE_INDEX_SHIFT 0
 #define AMDGPU_INFO_MMR_SE_INDEX_MASK 0xff
 #define AMDGPU_INFO_MMR_SH_INDEX_SHIFT 8
@@ -480,6 +503,7 @@
   __u32 gs_prim_buffer_depth;
   __u32 max_gs_waves_per_vgt;
   __u32 _pad1;
+  __u32 cu_ao_bitmap[4][4];
 };
 struct drm_amdgpu_info_hw_ip {
   __u32 hw_ip_version_major;
@@ -513,6 +537,7 @@
 #define AMDGPU_FAMILY_VI 130
 #define AMDGPU_FAMILY_CZ 135
 #define AMDGPU_FAMILY_AI 141
+#define AMDGPU_FAMILY_RV 142
 #ifdef __cplusplus
 #endif
 #endif
diff --git a/libc/kernel/uapi/drm/armada_drm.h b/libc/kernel/uapi/drm/armada_drm.h
index 331a558..ea1f37d 100644
--- a/libc/kernel/uapi/drm/armada_drm.h
+++ b/libc/kernel/uapi/drm/armada_drm.h
@@ -26,23 +26,23 @@
 #define DRM_ARMADA_GEM_PWRITE 0x03
 #define ARMADA_IOCTL(dir,name,str) DRM_ ##dir(DRM_COMMAND_BASE + DRM_ARMADA_ ##name, struct drm_armada_ ##str)
 struct drm_armada_gem_create {
-  uint32_t handle;
-  uint32_t size;
+  __u32 handle;
+  __u32 size;
 };
 #define DRM_IOCTL_ARMADA_GEM_CREATE ARMADA_IOCTL(IOWR, GEM_CREATE, gem_create)
 struct drm_armada_gem_mmap {
-  uint32_t handle;
-  uint32_t pad;
-  uint64_t offset;
-  uint64_t size;
-  uint64_t addr;
+  __u32 handle;
+  __u32 pad;
+  __u64 offset;
+  __u64 size;
+  __u64 addr;
 };
 #define DRM_IOCTL_ARMADA_GEM_MMAP ARMADA_IOCTL(IOWR, GEM_MMAP, gem_mmap)
 struct drm_armada_gem_pwrite {
-  uint64_t ptr;
-  uint32_t handle;
-  uint32_t offset;
-  uint32_t size;
+  __u64 ptr;
+  __u32 handle;
+  __u32 offset;
+  __u32 size;
 };
 #define DRM_IOCTL_ARMADA_GEM_PWRITE ARMADA_IOCTL(IOW, GEM_PWRITE, gem_pwrite)
 #ifdef __cplusplus
diff --git a/libc/kernel/uapi/drm/drm.h b/libc/kernel/uapi/drm/drm.h
index 251deeb..6863dc1 100644
--- a/libc/kernel/uapi/drm/drm.h
+++ b/libc/kernel/uapi/drm/drm.h
@@ -361,6 +361,7 @@
 #define DRM_CAP_ADDFB2_MODIFIERS 0x10
 #define DRM_CAP_PAGE_FLIP_TARGET 0x11
 #define DRM_CAP_CRTC_IN_VBLANK_EVENT 0x12
+#define DRM_CAP_SYNCOBJ 0x13
 struct drm_get_cap {
   __u64 capability;
   __u64 value;
@@ -379,6 +380,38 @@
   __u32 flags;
   __s32 fd;
 };
+struct drm_syncobj_create {
+  __u32 handle;
+#define DRM_SYNCOBJ_CREATE_SIGNALED (1 << 0)
+  __u32 flags;
+};
+struct drm_syncobj_destroy {
+  __u32 handle;
+  __u32 pad;
+};
+#define DRM_SYNCOBJ_FD_TO_HANDLE_FLAGS_IMPORT_SYNC_FILE (1 << 0)
+#define DRM_SYNCOBJ_HANDLE_TO_FD_FLAGS_EXPORT_SYNC_FILE (1 << 0)
+struct drm_syncobj_handle {
+  __u32 handle;
+  __u32 flags;
+  __s32 fd;
+  __u32 pad;
+};
+#define DRM_SYNCOBJ_WAIT_FLAGS_WAIT_ALL (1 << 0)
+#define DRM_SYNCOBJ_WAIT_FLAGS_WAIT_FOR_SUBMIT (1 << 1)
+struct drm_syncobj_wait {
+  __u64 handles;
+  __s64 timeout_nsec;
+  __u32 count_handles;
+  __u32 flags;
+  __u32 first_signaled;
+  __u32 pad;
+};
+struct drm_syncobj_array {
+  __u64 handles;
+  __u32 count_handles;
+  __u32 pad;
+};
 #ifdef __cplusplus
 #endif
 #include "drm_mode.h"
@@ -477,6 +510,13 @@
 #define DRM_IOCTL_MODE_ATOMIC DRM_IOWR(0xBC, struct drm_mode_atomic)
 #define DRM_IOCTL_MODE_CREATEPROPBLOB DRM_IOWR(0xBD, struct drm_mode_create_blob)
 #define DRM_IOCTL_MODE_DESTROYPROPBLOB DRM_IOWR(0xBE, struct drm_mode_destroy_blob)
+#define DRM_IOCTL_SYNCOBJ_CREATE DRM_IOWR(0xBF, struct drm_syncobj_create)
+#define DRM_IOCTL_SYNCOBJ_DESTROY DRM_IOWR(0xC0, struct drm_syncobj_destroy)
+#define DRM_IOCTL_SYNCOBJ_HANDLE_TO_FD DRM_IOWR(0xC1, struct drm_syncobj_handle)
+#define DRM_IOCTL_SYNCOBJ_FD_TO_HANDLE DRM_IOWR(0xC2, struct drm_syncobj_handle)
+#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_COMMAND_BASE 0x40
 #define DRM_COMMAND_END 0xA0
 struct drm_event {
diff --git a/libc/kernel/uapi/drm/drm_fourcc.h b/libc/kernel/uapi/drm/drm_fourcc.h
index 630ad30..da416cf 100644
--- a/libc/kernel/uapi/drm/drm_fourcc.h
+++ b/libc/kernel/uapi/drm/drm_fourcc.h
@@ -105,11 +105,16 @@
 #define DRM_FORMAT_MOD_VENDOR_SAMSUNG 0x04
 #define DRM_FORMAT_MOD_VENDOR_QCOM 0x05
 #define DRM_FORMAT_MOD_VENDOR_VIVANTE 0x06
+#define DRM_FORMAT_MOD_VENDOR_BROADCOM 0x07
+#define DRM_FORMAT_RESERVED ((1ULL << 56) - 1)
 #define fourcc_mod_code(vendor,val) ((((__u64) DRM_FORMAT_MOD_VENDOR_ ##vendor) << 56) | (val & 0x00ffffffffffffffULL))
+#define DRM_FORMAT_MOD_INVALID fourcc_mod_code(NONE, DRM_FORMAT_RESERVED)
 #define DRM_FORMAT_MOD_LINEAR fourcc_mod_code(NONE, 0)
 #define I915_FORMAT_MOD_X_TILED fourcc_mod_code(INTEL, 1)
 #define I915_FORMAT_MOD_Y_TILED fourcc_mod_code(INTEL, 2)
 #define I915_FORMAT_MOD_Yf_TILED fourcc_mod_code(INTEL, 3)
+#define I915_FORMAT_MOD_Y_TILED_CCS fourcc_mod_code(INTEL, 4)
+#define I915_FORMAT_MOD_Yf_TILED_CCS fourcc_mod_code(INTEL, 5)
 #define DRM_FORMAT_MOD_SAMSUNG_64_32_TILE fourcc_mod_code(SAMSUNG, 1)
 #define DRM_FORMAT_MOD_VIVANTE_TILED fourcc_mod_code(VIVANTE, 1)
 #define DRM_FORMAT_MOD_VIVANTE_SUPER_TILED fourcc_mod_code(VIVANTE, 2)
@@ -121,6 +126,7 @@
 #define fourcc_mod_tegra_param(m) (m & ((1ULL << __fourcc_mod_tegra_mode_shift) - 1))
 #define NV_FORMAT_MOD_TEGRA_TILED fourcc_mod_tegra_code(1, 0)
 #define NV_FORMAT_MOD_TEGRA_16BX2_BLOCK(v) fourcc_mod_tegra_code(2, v)
+#define DRM_FORMAT_MOD_BROADCOM_VC4_T_TILED fourcc_mod_code(BROADCOM, 1)
 #ifdef __cplusplus
 #endif
 #endif
diff --git a/libc/kernel/uapi/drm/drm_mode.h b/libc/kernel/uapi/drm/drm_mode.h
index 9e7ee92..5e97a72 100644
--- a/libc/kernel/uapi/drm/drm_mode.h
+++ b/libc/kernel/uapi/drm/drm_mode.h
@@ -79,6 +79,14 @@
 #define DRM_MODE_DIRTY_ANNOTATE 2
 #define DRM_MODE_LINK_STATUS_GOOD 0
 #define DRM_MODE_LINK_STATUS_BAD 1
+#define DRM_MODE_ROTATE_0 (1 << 0)
+#define DRM_MODE_ROTATE_90 (1 << 1)
+#define DRM_MODE_ROTATE_180 (1 << 2)
+#define DRM_MODE_ROTATE_270 (1 << 3)
+#define DRM_MODE_ROTATE_MASK (DRM_MODE_ROTATE_0 | DRM_MODE_ROTATE_90 | DRM_MODE_ROTATE_180 | DRM_MODE_ROTATE_270)
+#define DRM_MODE_REFLECT_X (1 << 4)
+#define DRM_MODE_REFLECT_Y (1 << 5)
+#define DRM_MODE_REFLECT_MASK (DRM_MODE_REFLECT_X | DRM_MODE_REFLECT_Y)
 struct drm_mode_modeinfo {
   __u32 clock;
   __u16 hdisplay;
@@ -396,6 +404,21 @@
   __u64 reserved;
   __u64 user_data;
 };
+struct drm_format_modifier_blob {
+#define FORMAT_BLOB_CURRENT 1
+  __u32 version;
+  __u32 flags;
+  __u32 count_formats;
+  __u32 formats_offset;
+  __u32 count_modifiers;
+  __u32 modifiers_offset;
+};
+struct drm_format_modifier {
+  __u64 formats;
+  __u32 offset;
+  __u32 pad;
+  __u64 modifier;
+};
 struct drm_mode_create_blob {
   __u64 data;
   __u32 length;
diff --git a/libc/kernel/uapi/drm/i915_drm.h b/libc/kernel/uapi/drm/i915_drm.h
index af6f064..50ea43a 100644
--- a/libc/kernel/uapi/drm/i915_drm.h
+++ b/libc/kernel/uapi/drm/i915_drm.h
@@ -172,6 +172,8 @@
 #define DRM_I915_GEM_CONTEXT_GETPARAM 0x34
 #define DRM_I915_GEM_CONTEXT_SETPARAM 0x35
 #define DRM_I915_PERF_OPEN 0x36
+#define DRM_I915_PERF_ADD_CONFIG 0x37
+#define DRM_I915_PERF_REMOVE_CONFIG 0x38
 #define DRM_IOCTL_I915_INIT DRM_IOW(DRM_COMMAND_BASE + DRM_I915_INIT, drm_i915_init_t)
 #define DRM_IOCTL_I915_FLUSH DRM_IO(DRM_COMMAND_BASE + DRM_I915_FLUSH)
 #define DRM_IOCTL_I915_FLIP DRM_IO(DRM_COMMAND_BASE + DRM_I915_FLIP)
@@ -226,6 +228,8 @@
 #define DRM_IOCTL_I915_GEM_CONTEXT_GETPARAM DRM_IOWR(DRM_COMMAND_BASE + DRM_I915_GEM_CONTEXT_GETPARAM, struct drm_i915_gem_context_param)
 #define DRM_IOCTL_I915_GEM_CONTEXT_SETPARAM DRM_IOWR(DRM_COMMAND_BASE + DRM_I915_GEM_CONTEXT_SETPARAM, struct drm_i915_gem_context_param)
 #define DRM_IOCTL_I915_PERF_OPEN DRM_IOW(DRM_COMMAND_BASE + DRM_I915_PERF_OPEN, struct drm_i915_perf_open_param)
+#define DRM_IOCTL_I915_PERF_ADD_CONFIG DRM_IOW(DRM_COMMAND_BASE + DRM_I915_PERF_ADD_CONFIG, struct drm_i915_perf_oa_config)
+#define DRM_IOCTL_I915_PERF_REMOVE_CONFIG DRM_IOW(DRM_COMMAND_BASE + DRM_I915_PERF_REMOVE_CONFIG, __u64)
 typedef struct drm_i915_batchbuffer {
   int start;
   int used;
@@ -292,6 +296,11 @@
 #define I915_PARAM_HUC_STATUS 42
 #define I915_PARAM_HAS_EXEC_ASYNC 43
 #define I915_PARAM_HAS_EXEC_FENCE 44
+#define I915_PARAM_HAS_EXEC_CAPTURE 45
+#define I915_PARAM_SLICE_MASK 46
+#define I915_PARAM_SUBSLICE_MASK 47
+#define I915_PARAM_HAS_EXEC_BATCH_FIRST 48
+#define I915_PARAM_HAS_EXEC_FENCE_ARRAY 49
 typedef struct drm_i915_getparam {
   __s32 param;
   int __user * value;
@@ -396,6 +405,7 @@
 #define I915_GEM_DOMAIN_INSTRUCTION 0x00000010
 #define I915_GEM_DOMAIN_VERTEX 0x00000020
 #define I915_GEM_DOMAIN_GTT 0x00000040
+#define I915_GEM_DOMAIN_WC 0x00000080
 struct drm_i915_gem_exec_object {
   __u32 handle;
   __u32 relocation_count;
@@ -426,7 +436,8 @@
 #define EXEC_OBJECT_PINNED (1 << 4)
 #define EXEC_OBJECT_PAD_TO_SIZE (1 << 5)
 #define EXEC_OBJECT_ASYNC (1 << 6)
-#define __EXEC_OBJECT_UNKNOWN_FLAGS - (EXEC_OBJECT_ASYNC << 1)
+#define EXEC_OBJECT_CAPTURE (1 << 7)
+#define __EXEC_OBJECT_UNKNOWN_FLAGS - (EXEC_OBJECT_CAPTURE << 1)
   __u64 flags;
   union {
     __u64 rsvd1;
@@ -434,6 +445,13 @@
   };
   __u64 rsvd2;
 };
+struct drm_i915_gem_exec_fence {
+  __u32 handle;
+#define I915_EXEC_FENCE_WAIT (1 << 0)
+#define I915_EXEC_FENCE_SIGNAL (1 << 1)
+#define __I915_EXEC_FENCE_UNKNOWN_FLAGS (- (I915_EXEC_FENCE_SIGNAL << 1))
+  __u32 flags;
+};
 struct drm_i915_gem_execbuffer2 {
   __u64 buffers_ptr;
   __u32 buffer_count;
@@ -470,7 +488,9 @@
 #define I915_EXEC_RESOURCE_STREAMER (1 << 15)
 #define I915_EXEC_FENCE_IN (1 << 16)
 #define I915_EXEC_FENCE_OUT (1 << 17)
-#define __I915_EXEC_UNKNOWN_FLAGS (- (I915_EXEC_FENCE_OUT << 1))
+#define I915_EXEC_BATCH_FIRST (1 << 18)
+#define I915_EXEC_FENCE_ARRAY (1 << 19)
+#define __I915_EXEC_UNKNOWN_FLAGS (- (I915_EXEC_FENCE_ARRAY << 1))
 #define I915_EXEC_CONTEXT_ID_MASK (0xffffffff)
 #define i915_execbuffer2_set_context_id(eb2,context) (eb2).rsvd1 = context & I915_EXEC_CONTEXT_ID_MASK
 #define i915_execbuffer2_get_context_id(eb2) ((eb2).rsvd1 & I915_EXEC_CONTEXT_ID_MASK)
@@ -650,6 +670,9 @@
   I915_OA_FORMAT_A45_B8_C8,
   I915_OA_FORMAT_B4_C8_A16,
   I915_OA_FORMAT_C4_B8,
+  I915_OA_FORMAT_A12,
+  I915_OA_FORMAT_A12_B8_C8,
+  I915_OA_FORMAT_A32u40_A4u32_B8_C8,
   I915_OA_FORMAT_MAX
 };
 enum drm_i915_perf_property_id {
@@ -681,6 +704,15 @@
   DRM_I915_PERF_RECORD_OA_BUFFER_LOST = 3,
   DRM_I915_PERF_RECORD_MAX
 };
+struct drm_i915_perf_oa_config {
+  char uuid[36];
+  __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;
+};
 #ifdef __cplusplus
 #endif
 #endif
diff --git a/libc/kernel/uapi/drm/msm_drm.h b/libc/kernel/uapi/drm/msm_drm.h
index 83ad769..4f1a423 100644
--- a/libc/kernel/uapi/drm/msm_drm.h
+++ b/libc/kernel/uapi/drm/msm_drm.h
@@ -55,9 +55,11 @@
   __u32 flags;
   __u32 handle;
 };
+#define MSM_INFO_IOVA 0x01
+#define MSM_INFO_FLAGS (MSM_INFO_IOVA)
 struct drm_msm_gem_info {
   __u32 handle;
-  __u32 pad;
+  __u32 flags;
   __u64 offset;
 };
 #define MSM_PREP_READ 0x01
@@ -89,7 +91,7 @@
   __u32 size;
   __u32 pad;
   __u32 nr_relocs;
-  __u64 __user relocs;
+  __u64 relocs;
 };
 #define MSM_SUBMIT_BO_READ 0x0001
 #define MSM_SUBMIT_BO_WRITE 0x0002
@@ -108,8 +110,8 @@
   __u32 fence;
   __u32 nr_bos;
   __u32 nr_cmds;
-  __u64 __user bos;
-  __u64 __user cmds;
+  __u64 bos;
+  __u64 cmds;
   __s32 fence_fd;
 };
 struct drm_msm_wait_fence {
@@ -133,7 +135,6 @@
 #define DRM_MSM_GEM_SUBMIT 0x06
 #define DRM_MSM_WAIT_FENCE 0x07
 #define DRM_MSM_GEM_MADVISE 0x08
-#define DRM_MSM_NUM_IOCTLS 0x09
 #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)
diff --git a/libc/kernel/uapi/drm/qxl_drm.h b/libc/kernel/uapi/drm/qxl_drm.h
index c1966ae..5942635 100644
--- a/libc/kernel/uapi/drm/qxl_drm.h
+++ b/libc/kernel/uapi/drm/qxl_drm.h
@@ -51,8 +51,8 @@
   __u32 pad;
 };
 struct drm_qxl_command {
-  __u64 __user command;
-  __u64 __user relocs;
+  __u64 command;
+  __u64 relocs;
   __u32 type;
   __u32 command_size;
   __u32 relocs_num;
@@ -61,7 +61,7 @@
 struct drm_qxl_execbuffer {
   __u32 flags;
   __u32 commands_num;
-  __u64 __user commands;
+  __u64 commands;
 };
 struct drm_qxl_update_area {
   __u32 handle;
diff --git a/libc/kernel/uapi/drm/vc4_drm.h b/libc/kernel/uapi/drm/vc4_drm.h
index 8c59253..d96c49d 100644
--- a/libc/kernel/uapi/drm/vc4_drm.h
+++ b/libc/kernel/uapi/drm/vc4_drm.h
@@ -29,6 +29,9 @@
 #define DRM_VC4_CREATE_SHADER_BO 0x05
 #define DRM_VC4_GET_HANG_STATE 0x06
 #define DRM_VC4_GET_PARAM 0x07
+#define DRM_VC4_SET_TILING 0x08
+#define DRM_VC4_GET_TILING 0x09
+#define DRM_VC4_LABEL_BO 0x0a
 #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)
@@ -37,6 +40,9 @@
 #define DRM_IOCTL_VC4_CREATE_SHADER_BO DRM_IOWR(DRM_COMMAND_BASE + DRM_VC4_CREATE_SHADER_BO, struct drm_vc4_create_shader_bo)
 #define DRM_IOCTL_VC4_GET_HANG_STATE DRM_IOWR(DRM_COMMAND_BASE + DRM_VC4_GET_HANG_STATE, struct drm_vc4_get_hang_state)
 #define DRM_IOCTL_VC4_GET_PARAM DRM_IOWR(DRM_COMMAND_BASE + DRM_VC4_GET_PARAM, struct drm_vc4_get_param)
+#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)
 struct drm_vc4_submit_rcl_surface {
   __u32 hindex;
   __u32 offset;
@@ -71,6 +77,9 @@
   __u8 clear_s;
   __u32 pad : 24;
 #define VC4_SUBMIT_CL_USE_CLEAR_COLOR (1 << 0)
+#define VC4_SUBMIT_CL_FIXED_RCL_ORDER (1 << 1)
+#define VC4_SUBMIT_CL_RCL_ORDER_INCREASING_X (1 << 2)
+#define VC4_SUBMIT_CL_RCL_ORDER_INCREASING_Y (1 << 3)
   __u32 flags;
   __u64 seqno;
 };
@@ -132,11 +141,27 @@
 #define DRM_VC4_PARAM_SUPPORTS_BRANCHES 3
 #define DRM_VC4_PARAM_SUPPORTS_ETC1 4
 #define DRM_VC4_PARAM_SUPPORTS_THREADED_FS 5
+#define DRM_VC4_PARAM_SUPPORTS_FIXED_RCL_ORDER 6
 struct drm_vc4_get_param {
   __u32 param;
   __u32 pad;
   __u64 value;
 };
+struct drm_vc4_get_tiling {
+  __u32 handle;
+  __u32 flags;
+  __u64 modifier;
+};
+struct drm_vc4_set_tiling {
+  __u32 handle;
+  __u32 flags;
+  __u64 modifier;
+};
+struct drm_vc4_label_bo {
+  __u32 handle;
+  __u32 len;
+  __u64 name;
+};
 #ifdef __cplusplus
 #endif
 #endif
diff --git a/libc/kernel/uapi/drm/vmwgfx_drm.h b/libc/kernel/uapi/drm/vmwgfx_drm.h
index 2b7e0fe..f6a7b14 100644
--- a/libc/kernel/uapi/drm/vmwgfx_drm.h
+++ b/libc/kernel/uapi/drm/vmwgfx_drm.h
@@ -104,6 +104,8 @@
   struct drm_vmw_surface_arg req;
 };
 #define DRM_VMW_EXECBUF_VERSION 2
+#define DRM_VMW_EXECBUF_FLAG_IMPORT_FENCE_FD (1 << 0)
+#define DRM_VMW_EXECBUF_FLAG_EXPORT_FENCE_FD (1 << 1)
 struct drm_vmw_execbuf_arg {
   __u64 commands;
   __u32 command_size;
@@ -112,14 +114,14 @@
   __u32 version;
   __u32 flags;
   __u32 context_handle;
-  __u32 pad64;
+  __s32 imported_fence_fd;
 };
 struct drm_vmw_fence_rep {
   __u32 handle;
   __u32 mask;
   __u32 seqno;
   __u32 passed_seqno;
-  __u32 pad64;
+  __s32 fd;
   __s32 error;
 };
 struct drm_vmw_alloc_dmabuf_req {
diff --git a/libc/kernel/uapi/linux/aio_abi.h b/libc/kernel/uapi/linux/aio_abi.h
index 2a7a6e7..e71936d 100644
--- a/libc/kernel/uapi/linux/aio_abi.h
+++ b/libc/kernel/uapi/linux/aio_abi.h
@@ -19,6 +19,7 @@
 #ifndef __LINUX__AIO_ABI_H
 #define __LINUX__AIO_ABI_H
 #include <linux/types.h>
+#include <linux/fs.h>
 #include <asm/byteorder.h>
 typedef __kernel_ulong_t aio_context_t;
 enum {
@@ -37,16 +38,17 @@
   __s64 res;
   __s64 res2;
 };
+struct iocb {
+  __u64 aio_data;
 #if defined(__BYTE_ORDER) ? __BYTE_ORDER == __LITTLE_ENDIAN : defined(__LITTLE_ENDIAN)
-#define PADDED(x,y) x, y
+  __u32 aio_key;
+  __kernel_rwf_t aio_rw_flags;
 #elif defined(__BYTE_ORDER)?__BYTE_ORDER==__BIG_ENDIAN:defined(__BIG_ENDIAN)
-#define PADDED(x,y) y, x
+  __kernel_rwf_t aio_rw_flags;
+  __u32 aio_key;
 #else
 #error edit for your odd byteorder .
 #endif
-struct iocb {
-  __u64 aio_data;
-  __u32 PADDED(aio_key, aio_reserved1);
   __u16 aio_lio_opcode;
   __s16 aio_reqprio;
   __u32 aio_fildes;
diff --git a/libc/kernel/uapi/linux/android/binder.h b/libc/kernel/uapi/linux/android/binder.h
index 717826d..538a441 100644
--- a/libc/kernel/uapi/linux/android/binder.h
+++ b/libc/kernel/uapi/linux/android/binder.h
@@ -74,8 +74,9 @@
 enum {
   BINDER_BUFFER_FLAG_HAS_PARENT = 0x01,
 };
-struct __kernel_binder_fd_array_object {
+struct binder_fd_array_object {
   struct binder_object_header hdr;
+  __u32 pad;
   binder_size_t num_fds;
   binder_size_t parent;
   binder_size_t parent_offset;
@@ -96,6 +97,12 @@
 #else
 #define BINDER_CURRENT_PROTOCOL_VERSION 8
 #endif
+struct binder_node_debug_info {
+  binder_uintptr_t ptr;
+  binder_uintptr_t cookie;
+  __u32 has_strong_ref;
+  __u32 has_weak_ref;
+};
 #define BINDER_WRITE_READ _IOWR('b', 1, struct binder_write_read)
 #define BINDER_SET_IDLE_TIMEOUT _IOW('b', 3, __s64)
 #define BINDER_SET_MAX_THREADS _IOW('b', 5, __u32)
@@ -103,6 +110,7 @@
 #define BINDER_SET_CONTEXT_MGR _IOW('b', 7, __s32)
 #define BINDER_THREAD_EXIT _IOW('b', 8, __s32)
 #define BINDER_VERSION _IOWR('b', 9, struct binder_version)
+#define BINDER_GET_NODE_DEBUG_INFO _IOWR('b', 11, struct binder_node_debug_info)
 enum transaction_flags {
   TF_ONE_WAY = 0x01,
   TF_ROOT_OBJECT = 0x04,
diff --git a/libc/kernel/uapi/linux/auto_dev-ioctl.h b/libc/kernel/uapi/linux/auto_dev-ioctl.h
index be00b9e..23c8096 100644
--- a/libc/kernel/uapi/linux/auto_dev-ioctl.h
+++ b/libc/kernel/uapi/linux/auto_dev-ioctl.h
@@ -22,7 +22,7 @@
 #include <linux/string.h>
 #define AUTOFS_DEVICE_NAME "autofs"
 #define AUTOFS_DEV_IOCTL_VERSION_MAJOR 1
-#define AUTOFS_DEV_IOCTL_VERSION_MINOR 0
+#define AUTOFS_DEV_IOCTL_VERSION_MINOR 1
 #define AUTOFS_DEV_IOCTL_SIZE sizeof(struct autofs_dev_ioctl)
 struct args_protover {
   __u32 version;
diff --git a/libc/kernel/uapi/linux/auto_fs4.h b/libc/kernel/uapi/linux/auto_fs4.h
index d09b39b..be6766b 100644
--- a/libc/kernel/uapi/linux/auto_fs4.h
+++ b/libc/kernel/uapi/linux/auto_fs4.h
@@ -85,8 +85,6 @@
   AUTOFS_IOC_ASKUMOUNT_CMD = 0x70,
 };
 #define AUTOFS_IOC_EXPIRE_MULTI _IOW(AUTOFS_IOCTL, AUTOFS_IOC_EXPIRE_MULTI_CMD, int)
-#define AUTOFS_IOC_EXPIRE_INDIRECT AUTOFS_IOC_EXPIRE_MULTI
-#define AUTOFS_IOC_EXPIRE_DIRECT AUTOFS_IOC_EXPIRE_MULTI
 #define AUTOFS_IOC_PROTOSUBVER _IOR(AUTOFS_IOCTL, AUTOFS_IOC_PROTOSUBVER_CMD, int)
 #define AUTOFS_IOC_ASKUMOUNT _IOR(AUTOFS_IOCTL, AUTOFS_IOC_ASKUMOUNT_CMD, int)
 #endif
diff --git a/libc/kernel/uapi/linux/blktrace_api.h b/libc/kernel/uapi/linux/blktrace_api.h
index a6129f8..64c0b77 100644
--- a/libc/kernel/uapi/linux/blktrace_api.h
+++ b/libc/kernel/uapi/linux/blktrace_api.h
@@ -59,11 +59,13 @@
   __BLK_TA_REMAP,
   __BLK_TA_ABORT,
   __BLK_TA_DRV_DATA,
+  __BLK_TA_CGROUP = 1 << 8,
 };
 enum blktrace_notify {
   __BLK_TN_PROCESS = 0,
   __BLK_TN_TIMESTAMP,
   __BLK_TN_MESSAGE,
+  __BLK_TN_CGROUP = __BLK_TA_CGROUP,
 };
 #define BLK_TA_QUEUE (__BLK_TA_QUEUE | BLK_TC_ACT(BLK_TC_QUEUE))
 #define BLK_TA_BACKMERGE (__BLK_TA_BACKMERGE | BLK_TC_ACT(BLK_TC_QUEUE))
diff --git a/libc/kernel/uapi/linux/bpf.h b/libc/kernel/uapi/linux/bpf.h
index 08c1aba..1dfb99f 100644
--- a/libc/kernel/uapi/linux/bpf.h
+++ b/libc/kernel/uapi/linux/bpf.h
@@ -31,8 +31,12 @@
 #define BPF_FROM_LE BPF_TO_LE
 #define BPF_FROM_BE BPF_TO_BE
 #define BPF_JNE 0x50
+#define BPF_JLT 0xa0
+#define BPF_JLE 0xb0
 #define BPF_JSGT 0x60
 #define BPF_JSGE 0x70
+#define BPF_JSLT 0xc0
+#define BPF_JSLE 0xd0
 #define BPF_CALL 0x80
 #define BPF_EXIT 0x90
 enum {
@@ -73,6 +77,11 @@
   BPF_PROG_ATTACH,
   BPF_PROG_DETACH,
   BPF_PROG_TEST_RUN,
+  BPF_PROG_GET_NEXT_ID,
+  BPF_MAP_GET_NEXT_ID,
+  BPF_PROG_GET_FD_BY_ID,
+  BPF_MAP_GET_FD_BY_ID,
+  BPF_OBJ_GET_INFO_BY_FD,
 };
 enum bpf_map_type {
   BPF_MAP_TYPE_UNSPEC,
@@ -89,6 +98,8 @@
   BPF_MAP_TYPE_LPM_TRIE,
   BPF_MAP_TYPE_ARRAY_OF_MAPS,
   BPF_MAP_TYPE_HASH_OF_MAPS,
+  BPF_MAP_TYPE_DEVMAP,
+  BPF_MAP_TYPE_SOCKMAP,
 };
 enum bpf_prog_type {
   BPF_PROG_TYPE_UNSPEC,
@@ -104,11 +115,16 @@
   BPF_PROG_TYPE_LWT_IN,
   BPF_PROG_TYPE_LWT_OUT,
   BPF_PROG_TYPE_LWT_XMIT,
+  BPF_PROG_TYPE_SOCK_OPS,
+  BPF_PROG_TYPE_SK_SKB,
 };
 enum bpf_attach_type {
   BPF_CGROUP_INET_INGRESS,
   BPF_CGROUP_INET_EGRESS,
   BPF_CGROUP_INET_SOCK_CREATE,
+  BPF_CGROUP_SOCK_OPS,
+  BPF_SK_SKB_STREAM_PARSER,
+  BPF_SK_SKB_STREAM_VERDICT,
   __MAX_BPF_ATTACH_TYPE
 };
 #define MAX_BPF_ATTACH_TYPE __MAX_BPF_ATTACH_TYPE
@@ -120,6 +136,7 @@
 #define BPF_EXIST 2
 #define BPF_F_NO_PREALLOC (1U << 0)
 #define BPF_F_NO_COMMON_LRU (1U << 1)
+#define BPF_F_NUMA_NODE (1U << 2)
 union bpf_attr {
   struct {
     __u32 map_type;
@@ -128,6 +145,7 @@
     __u32 max_entries;
     __u32 map_flags;
     __u32 inner_map_fd;
+    __u32 numa_node;
   };
   struct {
     __u32 map_fd;
@@ -169,8 +187,21 @@
     __u32 repeat;
     __u32 duration;
   } test;
+  struct {
+    union {
+      __u32 start_id;
+      __u32 prog_id;
+      __u32 map_id;
+    };
+    __u32 next_id;
+  };
+  struct {
+    __u32 bpf_fd;
+    __u32 info_len;
+    __aligned_u64 info;
+  } info;
 } __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),
+#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_ENUM_FN(x) BPF_FUNC_ ##x
 enum bpf_func_id {
   __BPF_FUNC_MAPPER(__BPF_ENUM_FN) __BPF_FUNC_MAX_ID,
@@ -193,6 +224,9 @@
 #define BPF_F_INDEX_MASK 0xffffffffULL
 #define BPF_F_CURRENT_CPU BPF_F_INDEX_MASK
 #define BPF_F_CTXLEN_MASK (0xfffffULL << 32)
+enum bpf_adj_room_mode {
+  BPF_ADJ_ROOM_NET,
+};
 struct __sk_buff {
   __u32 len;
   __u32 pkt_type;
@@ -212,6 +246,13 @@
   __u32 data;
   __u32 data_end;
   __u32 napi_id;
+  __u32 family;
+  __u32 remote_ip4;
+  __u32 local_ip4;
+  __u32 remote_ip6[4];
+  __u32 local_ip6[4];
+  __u32 remote_port;
+  __u32 local_port;
 };
 struct bpf_tunnel_key {
   __u32 tunnel_id;
@@ -234,6 +275,8 @@
   __u32 family;
   __u32 type;
   __u32 protocol;
+  __u32 mark;
+  __u32 priority;
 };
 #define XDP_PACKET_HEADROOM 256
 enum xdp_action {
@@ -241,9 +284,57 @@
   XDP_DROP,
   XDP_PASS,
   XDP_TX,
+  XDP_REDIRECT,
 };
 struct xdp_md {
   __u32 data;
   __u32 data_end;
 };
+enum sk_action {
+  SK_DROP = 0,
+  SK_PASS,
+};
+#define BPF_TAG_SIZE 8
+struct bpf_prog_info {
+  __u32 type;
+  __u32 id;
+  __u8 tag[BPF_TAG_SIZE];
+  __u32 jited_prog_len;
+  __u32 xlated_prog_len;
+  __aligned_u64 jited_prog_insns;
+  __aligned_u64 xlated_prog_insns;
+} __attribute__((aligned(8)));
+struct bpf_map_info {
+  __u32 type;
+  __u32 id;
+  __u32 key_size;
+  __u32 value_size;
+  __u32 max_entries;
+  __u32 map_flags;
+} __attribute__((aligned(8)));
+struct bpf_sock_ops {
+  __u32 op;
+  union {
+    __u32 reply;
+    __u32 replylong[4];
+  };
+  __u32 family;
+  __u32 remote_ip4;
+  __u32 local_ip4;
+  __u32 remote_ip6[4];
+  __u32 local_ip6[4];
+  __u32 remote_port;
+  __u32 local_port;
+};
+enum {
+  BPF_SOCK_OPS_VOID,
+  BPF_SOCK_OPS_TIMEOUT_INIT,
+  BPF_SOCK_OPS_RWND_INIT,
+  BPF_SOCK_OPS_TCP_CONNECT_CB,
+  BPF_SOCK_OPS_ACTIVE_ESTABLISHED_CB,
+  BPF_SOCK_OPS_PASSIVE_ESTABLISHED_CB,
+  BPF_SOCK_OPS_NEEDS_ECN,
+};
+#define TCP_BPF_IW 1001
+#define TCP_BPF_SNDCWND_CLAMP 1002
 #endif
diff --git a/libc/kernel/uapi/linux/btrfs.h b/libc/kernel/uapi/linux/btrfs.h
index 56e33ae..a23ab58 100644
--- a/libc/kernel/uapi/linux/btrfs.h
+++ b/libc/kernel/uapi/linux/btrfs.h
@@ -167,7 +167,7 @@
 #define BTRFS_FEATURE_INCOMPAT_DEFAULT_SUBVOL (1ULL << 1)
 #define BTRFS_FEATURE_INCOMPAT_MIXED_GROUPS (1ULL << 2)
 #define BTRFS_FEATURE_INCOMPAT_COMPRESS_LZO (1ULL << 3)
-#define BTRFS_FEATURE_INCOMPAT_COMPRESS_LZOv2 (1ULL << 4)
+#define BTRFS_FEATURE_INCOMPAT_COMPRESS_ZSTD (1ULL << 4)
 #define BTRFS_FEATURE_INCOMPAT_BIG_METADATA (1ULL << 5)
 #define BTRFS_FEATURE_INCOMPAT_EXTENDED_IREF (1ULL << 6)
 #define BTRFS_FEATURE_INCOMPAT_RAID56 (1ULL << 7)
diff --git a/libc/kernel/uapi/linux/capability.h b/libc/kernel/uapi/linux/capability.h
index f414848..8ba448e 100644
--- a/libc/kernel/uapi/linux/capability.h
+++ b/libc/kernel/uapi/linux/capability.h
@@ -44,9 +44,12 @@
 #define VFS_CAP_REVISION_2 0x02000000
 #define VFS_CAP_U32_2 2
 #define XATTR_CAPS_SZ_2 (sizeof(__le32) * (1 + 2 * VFS_CAP_U32_2))
-#define XATTR_CAPS_SZ XATTR_CAPS_SZ_2
-#define VFS_CAP_U32 VFS_CAP_U32_2
-#define VFS_CAP_REVISION VFS_CAP_REVISION_2
+#define VFS_CAP_REVISION_3 0x03000000
+#define VFS_CAP_U32_3 2
+#define XATTR_CAPS_SZ_3 (sizeof(__le32) * (2 + 2 * VFS_CAP_U32_3))
+#define XATTR_CAPS_SZ XATTR_CAPS_SZ_3
+#define VFS_CAP_U32 VFS_CAP_U32_3
+#define VFS_CAP_REVISION VFS_CAP_REVISION_3
 struct vfs_cap_data {
   __le32 magic_etc;
   struct {
@@ -54,6 +57,14 @@
     __le32 inheritable;
   } data[VFS_CAP_U32];
 };
+struct vfs_ns_cap_data {
+  __le32 magic_etc;
+  struct {
+    __le32 permitted;
+    __le32 inheritable;
+  } data[VFS_CAP_U32];
+  __le32 rootid;
+};
 #define _LINUX_CAPABILITY_VERSION _LINUX_CAPABILITY_VERSION_1
 #define _LINUX_CAPABILITY_U32S _LINUX_CAPABILITY_U32S_1
 #define CAP_CHOWN 0
diff --git a/libc/kernel/uapi/linux/cec.h b/libc/kernel/uapi/linux/cec.h
index 8125ac4..3fcee96 100644
--- a/libc/kernel/uapi/linux/cec.h
+++ b/libc/kernel/uapi/linux/cec.h
@@ -91,6 +91,7 @@
 #define CEC_MODE_FOLLOWER (0x1 << 4)
 #define CEC_MODE_EXCL_FOLLOWER (0x2 << 4)
 #define CEC_MODE_EXCL_FOLLOWER_PASSTHRU (0x3 << 4)
+#define CEC_MODE_MONITOR_PIN (0xd << 4)
 #define CEC_MODE_MONITOR (0xe << 4)
 #define CEC_MODE_MONITOR_ALL (0xf << 4)
 #define CEC_MODE_FOLLOWER_MSK 0xf0
@@ -100,6 +101,8 @@
 #define CEC_CAP_PASSTHROUGH (1 << 3)
 #define CEC_CAP_RC (1 << 4)
 #define CEC_CAP_MONITOR_ALL (1 << 5)
+#define CEC_CAP_NEEDS_HPD (1 << 6)
+#define CEC_CAP_MONITOR_PIN (1 << 7)
 struct cec_caps {
   char driver[32];
   char name[32];
@@ -125,7 +128,10 @@
 #define CEC_LOG_ADDRS_FL_CDC_ONLY (1 << 2)
 #define CEC_EVENT_STATE_CHANGE 1
 #define CEC_EVENT_LOST_MSGS 2
+#define CEC_EVENT_PIN_CEC_LOW 3
+#define CEC_EVENT_PIN_CEC_HIGH 4
 #define CEC_EVENT_FL_INITIAL_STATE (1 << 0)
+#define CEC_EVENT_FL_DROPPED_EVENTS (1 << 1)
 struct cec_event_state_change {
   __u16 phys_addr;
   __u16 log_addr_mask;
diff --git a/libc/kernel/uapi/linux/devlink.h b/libc/kernel/uapi/linux/devlink.h
index 01f6e74..1d5c43c 100644
--- a/libc/kernel/uapi/linux/devlink.h
+++ b/libc/kernel/uapi/linux/devlink.h
@@ -168,4 +168,18 @@
 enum devlink_dpipe_action_type {
   DEVLINK_DPIPE_ACTION_TYPE_FIELD_MODIFY,
 };
+enum devlink_dpipe_field_ethernet_id {
+  DEVLINK_DPIPE_FIELD_ETHERNET_DST_MAC,
+};
+enum devlink_dpipe_field_ipv4_id {
+  DEVLINK_DPIPE_FIELD_IPV4_DST_IP,
+};
+enum devlink_dpipe_field_ipv6_id {
+  DEVLINK_DPIPE_FIELD_IPV6_DST_IP,
+};
+enum devlink_dpipe_header_id {
+  DEVLINK_DPIPE_HEADER_ETHERNET,
+  DEVLINK_DPIPE_HEADER_IPV4,
+  DEVLINK_DPIPE_HEADER_IPV6,
+};
 #endif
diff --git a/libc/kernel/uapi/linux/dlm_netlink.h b/libc/kernel/uapi/linux/dlm_netlink.h
index 64e5d1e..0c655fa 100644
--- a/libc/kernel/uapi/linux/dlm_netlink.h
+++ b/libc/kernel/uapi/linux/dlm_netlink.h
@@ -19,6 +19,7 @@
 #ifndef _DLM_NETLINK_H
 #define _DLM_NETLINK_H
 #include <linux/types.h>
+#include <linux/dlmconstants.h>
 enum {
   DLM_STATUS_WAITING = 1,
   DLM_STATUS_GRANTED = 2,
diff --git a/libc/kernel/uapi/linux/dm-ioctl.h b/libc/kernel/uapi/linux/dm-ioctl.h
index a418ea0..cc340b5 100644
--- a/libc/kernel/uapi/linux/dm-ioctl.h
+++ b/libc/kernel/uapi/linux/dm-ioctl.h
@@ -80,7 +80,8 @@
   DM_TABLE_STATUS_CMD,
   DM_LIST_VERSIONS_CMD,
   DM_TARGET_MSG_CMD,
-  DM_DEV_SET_GEOMETRY_CMD
+  DM_DEV_SET_GEOMETRY_CMD,
+  DM_DEV_ARM_POLL_CMD,
 };
 #define DM_IOCTL 0xfd
 #define DM_VERSION _IOWR(DM_IOCTL, DM_VERSION_CMD, struct dm_ioctl)
@@ -92,6 +93,7 @@
 #define DM_DEV_SUSPEND _IOWR(DM_IOCTL, DM_DEV_SUSPEND_CMD, struct dm_ioctl)
 #define DM_DEV_STATUS _IOWR(DM_IOCTL, DM_DEV_STATUS_CMD, struct dm_ioctl)
 #define DM_DEV_WAIT _IOWR(DM_IOCTL, DM_DEV_WAIT_CMD, struct dm_ioctl)
+#define DM_DEV_ARM_POLL _IOWR(DM_IOCTL, DM_DEV_ARM_POLL_CMD, struct dm_ioctl)
 #define DM_TABLE_LOAD _IOWR(DM_IOCTL, DM_TABLE_LOAD_CMD, struct dm_ioctl)
 #define DM_TABLE_CLEAR _IOWR(DM_IOCTL, DM_TABLE_CLEAR_CMD, struct dm_ioctl)
 #define DM_TABLE_DEPS _IOWR(DM_IOCTL, DM_TABLE_DEPS_CMD, struct dm_ioctl)
@@ -100,9 +102,9 @@
 #define DM_TARGET_MSG _IOWR(DM_IOCTL, DM_TARGET_MSG_CMD, struct dm_ioctl)
 #define DM_DEV_SET_GEOMETRY _IOWR(DM_IOCTL, DM_DEV_SET_GEOMETRY_CMD, struct dm_ioctl)
 #define DM_VERSION_MAJOR 4
-#define DM_VERSION_MINOR 35
+#define DM_VERSION_MINOR 37
 #define DM_VERSION_PATCHLEVEL 0
-#define DM_VERSION_EXTRA "-ioctl(2016-06-23)"
+#define DM_VERSION_EXTRA "-ioctl(2017-09-20)"
 #define DM_READONLY_FLAG (1 << 0)
 #define DM_SUSPEND_FLAG (1 << 1)
 #define DM_PERSISTENT_DEV_FLAG (1 << 3)
diff --git a/libc/kernel/uapi/linux/dvb/ca.h b/libc/kernel/uapi/linux/dvb/ca.h
index c494ad5..fa977c7 100644
--- a/libc/kernel/uapi/linux/dvb/ca.h
+++ b/libc/kernel/uapi/linux/dvb/ca.h
@@ -18,7 +18,7 @@
  ****************************************************************************/
 #ifndef _DVBCA_H_
 #define _DVBCA_H_
-typedef struct ca_slot_info {
+struct ca_slot_info {
   int num;
   int type;
 #define CA_CI 1
@@ -29,41 +29,41 @@
   unsigned int flags;
 #define CA_CI_MODULE_PRESENT 1
 #define CA_CI_MODULE_READY 2
-} ca_slot_info_t;
-typedef struct ca_descr_info {
+};
+struct ca_descr_info {
   unsigned int num;
   unsigned int type;
 #define CA_ECD 1
 #define CA_NDS 2
 #define CA_DSS 4
-} ca_descr_info_t;
-typedef struct ca_caps {
+};
+struct ca_caps {
   unsigned int slot_num;
   unsigned int slot_type;
   unsigned int descr_num;
   unsigned int descr_type;
-} ca_caps_t;
-typedef struct ca_msg {
+};
+struct ca_msg {
   unsigned int index;
   unsigned int type;
   unsigned int length;
   unsigned char msg[256];
-} ca_msg_t;
-typedef struct ca_descr {
+};
+struct ca_descr {
   unsigned int index;
   unsigned int parity;
   unsigned char cw[8];
-} ca_descr_t;
-typedef struct ca_pid {
-  unsigned int pid;
-  int index;
-} ca_pid_t;
+};
 #define CA_RESET _IO('o', 128)
-#define CA_GET_CAP _IOR('o', 129, ca_caps_t)
-#define CA_GET_SLOT_INFO _IOR('o', 130, ca_slot_info_t)
-#define CA_GET_DESCR_INFO _IOR('o', 131, ca_descr_info_t)
-#define CA_GET_MSG _IOR('o', 132, ca_msg_t)
-#define CA_SEND_MSG _IOW('o', 133, ca_msg_t)
-#define CA_SET_DESCR _IOW('o', 134, ca_descr_t)
-#define CA_SET_PID _IOW('o', 135, ca_pid_t)
+#define CA_GET_CAP _IOR('o', 129, struct ca_caps)
+#define CA_GET_SLOT_INFO _IOR('o', 130, struct ca_slot_info)
+#define CA_GET_DESCR_INFO _IOR('o', 131, struct ca_descr_info)
+#define CA_GET_MSG _IOR('o', 132, struct ca_msg)
+#define CA_SEND_MSG _IOW('o', 133, struct ca_msg)
+#define CA_SET_DESCR _IOW('o', 134, struct ca_descr)
+typedef struct ca_slot_info ca_slot_info_t;
+typedef struct ca_descr_info ca_descr_info_t;
+typedef struct ca_caps ca_caps_t;
+typedef struct ca_msg ca_msg_t;
+typedef struct ca_descr ca_descr_t;
 #endif
diff --git a/libc/kernel/uapi/linux/dvb/dmx.h b/libc/kernel/uapi/linux/dvb/dmx.h
index 438c832..d4ea26e 100644
--- a/libc/kernel/uapi/linux/dvb/dmx.h
+++ b/libc/kernel/uapi/linux/dvb/dmx.h
@@ -27,12 +27,11 @@
   DMX_OUT_TS_TAP,
   DMX_OUT_TSDEMUX_TAP
 };
-typedef enum dmx_output dmx_output_t;
-typedef enum dmx_input {
+enum dmx_input {
   DMX_IN_FRONTEND,
   DMX_IN_DVR
-} dmx_input_t;
-typedef enum dmx_ts_pes {
+};
+enum dmx_ts_pes {
   DMX_PES_AUDIO0,
   DMX_PES_VIDEO0,
   DMX_PES_TELETEXT0,
@@ -54,48 +53,33 @@
   DMX_PES_SUBTITLE3,
   DMX_PES_PCR3,
   DMX_PES_OTHER
-} dmx_pes_type_t;
+};
 #define DMX_PES_AUDIO DMX_PES_AUDIO0
 #define DMX_PES_VIDEO DMX_PES_VIDEO0
 #define DMX_PES_TELETEXT DMX_PES_TELETEXT0
 #define DMX_PES_SUBTITLE DMX_PES_SUBTITLE0
 #define DMX_PES_PCR DMX_PES_PCR0
-typedef struct dmx_filter {
+struct dmx_filter {
   __u8 filter[DMX_FILTER_SIZE];
   __u8 mask[DMX_FILTER_SIZE];
   __u8 mode[DMX_FILTER_SIZE];
-} dmx_filter_t;
+};
 struct dmx_sct_filter_params {
   __u16 pid;
-  dmx_filter_t filter;
+  struct dmx_filter filter;
   __u32 timeout;
   __u32 flags;
 #define DMX_CHECK_CRC 1
 #define DMX_ONESHOT 2
 #define DMX_IMMEDIATE_START 4
-#define DMX_KERNEL_CLIENT 0x8000
 };
 struct dmx_pes_filter_params {
   __u16 pid;
-  dmx_input_t input;
-  dmx_output_t output;
-  dmx_pes_type_t pes_type;
+  enum dmx_input input;
+  enum dmx_output output;
+  enum dmx_ts_pes pes_type;
   __u32 flags;
 };
-typedef struct dmx_caps {
-  __u32 caps;
-  int num_decoders;
-} dmx_caps_t;
-typedef enum dmx_source {
-  DMX_SOURCE_FRONT0 = 0,
-  DMX_SOURCE_FRONT1,
-  DMX_SOURCE_FRONT2,
-  DMX_SOURCE_FRONT3,
-  DMX_SOURCE_DVR0 = 16,
-  DMX_SOURCE_DVR1,
-  DMX_SOURCE_DVR2,
-  DMX_SOURCE_DVR3
-} dmx_source_t;
 struct dmx_stc {
   unsigned int num;
   unsigned int base;
@@ -107,9 +91,11 @@
 #define DMX_SET_PES_FILTER _IOW('o', 44, struct dmx_pes_filter_params)
 #define DMX_SET_BUFFER_SIZE _IO('o', 45)
 #define DMX_GET_PES_PIDS _IOR('o', 47, __u16[5])
-#define DMX_GET_CAPS _IOR('o', 48, dmx_caps_t)
-#define DMX_SET_SOURCE _IOW('o', 49, dmx_source_t)
 #define DMX_GET_STC _IOWR('o', 50, struct dmx_stc)
 #define DMX_ADD_PID _IOW('o', 51, __u16)
 #define DMX_REMOVE_PID _IOW('o', 52, __u16)
+typedef enum dmx_output dmx_output_t;
+typedef enum dmx_input dmx_input_t;
+typedef enum dmx_ts_pes dmx_pes_type_t;
+typedef struct dmx_filter dmx_filter_t;
 #endif
diff --git a/libc/kernel/uapi/linux/dvb/frontend.h b/libc/kernel/uapi/linux/dvb/frontend.h
index 387e3f1..c8a48c1 100644
--- a/libc/kernel/uapi/linux/dvb/frontend.h
+++ b/libc/kernel/uapi/linux/dvb/frontend.h
@@ -19,12 +19,6 @@
 #ifndef _DVBFRONTEND_H_
 #define _DVBFRONTEND_H_
 #include <linux/types.h>
-enum fe_type {
-  FE_QPSK,
-  FE_QAM,
-  FE_OFDM,
-  FE_ATSC
-};
 enum fe_caps {
   FE_IS_STUPID = 0,
   FE_CAN_INVERSION_AUTO = 0x1,
@@ -58,6 +52,12 @@
   FE_CAN_RECOVER = 0x40000000,
   FE_CAN_MUTE_TS = 0x80000000
 };
+enum fe_type {
+  FE_QPSK,
+  FE_QAM,
+  FE_OFDM,
+  FE_ATSC
+};
 struct dvb_frontend_info {
   char name[128];
   enum fe_type type;
@@ -94,6 +94,7 @@
   SEC_MINI_B
 };
 enum fe_status {
+  FE_NONE = 0x00,
   FE_HAS_SIGNAL = 0x01,
   FE_HAS_CARRIER = 0x02,
   FE_HAS_VITERBI = 0x04,
@@ -308,13 +309,6 @@
 };
 #define NO_STREAM_ID_FILTER (~0U)
 #define LNA_AUTO (~0U)
-struct dtv_cmds_h {
-  char * name;
-  __u32 cmd;
-  __u32 set : 1;
-  __u32 buffer : 1;
-  __u32 reserved : 30;
-};
 enum fecap_scale_params {
   FE_SCALE_NOT_AVAILABLE = 0,
   FE_SCALE_DECIBEL,
@@ -353,6 +347,25 @@
   __u32 num;
   struct dtv_property * props;
 };
+#define FE_TUNE_MODE_ONESHOT 0x01
+#define FE_GET_INFO _IOR('o', 61, struct dvb_frontend_info)
+#define FE_DISEQC_RESET_OVERLOAD _IO('o', 62)
+#define FE_DISEQC_SEND_MASTER_CMD _IOW('o', 63, struct dvb_diseqc_master_cmd)
+#define FE_DISEQC_RECV_SLAVE_REPLY _IOR('o', 64, struct dvb_diseqc_slave_reply)
+#define FE_DISEQC_SEND_BURST _IO('o', 65)
+#define FE_SET_TONE _IO('o', 66)
+#define FE_SET_VOLTAGE _IO('o', 67)
+#define FE_ENABLE_HIGH_LNB_VOLTAGE _IO('o', 68)
+#define FE_READ_STATUS _IOR('o', 69, fe_status_t)
+#define FE_READ_BER _IOR('o', 70, __u32)
+#define FE_READ_SIGNAL_STRENGTH _IOR('o', 71, __u16)
+#define FE_READ_SNR _IOR('o', 72, __u16)
+#define FE_READ_UNCORRECTED_BLOCKS _IOR('o', 73, __u32)
+#define FE_SET_FRONTEND_TUNE_MODE _IO('o', 81)
+#define FE_GET_EVENT _IOR('o', 78, struct dvb_frontend_event)
+#define FE_DISHNETWORK_SEND_LEGACY_CMD _IO('o', 80)
+#define FE_SET_PROPERTY _IOW('o', 82, struct dtv_properties)
+#define FE_GET_PROPERTY _IOR('o', 83, struct dtv_properties)
 enum fe_bandwidth {
   BANDWIDTH_8_MHZ,
   BANDWIDTH_7_MHZ,
@@ -413,25 +426,6 @@
   fe_status_t status;
   struct dvb_frontend_parameters parameters;
 };
-#define FE_SET_PROPERTY _IOW('o', 82, struct dtv_properties)
-#define FE_GET_PROPERTY _IOR('o', 83, struct dtv_properties)
-#define FE_TUNE_MODE_ONESHOT 0x01
-#define FE_GET_INFO _IOR('o', 61, struct dvb_frontend_info)
-#define FE_DISEQC_RESET_OVERLOAD _IO('o', 62)
-#define FE_DISEQC_SEND_MASTER_CMD _IOW('o', 63, struct dvb_diseqc_master_cmd)
-#define FE_DISEQC_RECV_SLAVE_REPLY _IOR('o', 64, struct dvb_diseqc_slave_reply)
-#define FE_DISEQC_SEND_BURST _IO('o', 65)
-#define FE_SET_TONE _IO('o', 66)
-#define FE_SET_VOLTAGE _IO('o', 67)
-#define FE_ENABLE_HIGH_LNB_VOLTAGE _IO('o', 68)
-#define FE_READ_STATUS _IOR('o', 69, fe_status_t)
-#define FE_READ_BER _IOR('o', 70, __u32)
-#define FE_READ_SIGNAL_STRENGTH _IOR('o', 71, __u16)
-#define FE_READ_SNR _IOR('o', 72, __u16)
-#define FE_READ_UNCORRECTED_BLOCKS _IOR('o', 73, __u32)
 #define FE_SET_FRONTEND _IOW('o', 76, struct dvb_frontend_parameters)
 #define FE_GET_FRONTEND _IOR('o', 77, struct dvb_frontend_parameters)
-#define FE_SET_FRONTEND_TUNE_MODE _IO('o', 81)
-#define FE_GET_EVENT _IOR('o', 78, struct dvb_frontend_event)
-#define FE_DISHNETWORK_SEND_LEGACY_CMD _IO('o', 80)
 #endif
diff --git a/libc/kernel/uapi/linux/dvb/video.h b/libc/kernel/uapi/linux/dvb/video.h
index e235114..7ada1a0 100644
--- a/libc/kernel/uapi/linux/dvb/video.h
+++ b/libc/kernel/uapi/linux/dvb/video.h
@@ -89,7 +89,7 @@
 #define VIDEO_EVENT_FRAME_RATE_CHANGED 2
 #define VIDEO_EVENT_DECODER_STOPPED 3
 #define VIDEO_EVENT_VSYNC 4
-  __kernel_time_t timestamp;
+  long timestamp;
   union {
     video_size_t size;
     unsigned int frame_rate;
diff --git a/libc/kernel/uapi/linux/errqueue.h b/libc/kernel/uapi/linux/errqueue.h
index 5daeb10..196189b 100644
--- a/libc/kernel/uapi/linux/errqueue.h
+++ b/libc/kernel/uapi/linux/errqueue.h
@@ -33,8 +33,10 @@
 #define SO_EE_ORIGIN_ICMP 2
 #define SO_EE_ORIGIN_ICMP6 3
 #define SO_EE_ORIGIN_TXSTATUS 4
+#define SO_EE_ORIGIN_ZEROCOPY 5
 #define SO_EE_ORIGIN_TIMESTAMPING SO_EE_ORIGIN_TXSTATUS
 #define SO_EE_OFFENDER(ee) ((struct sockaddr *) ((ee) + 1))
+#define SO_EE_CODE_ZEROCOPY_COPIED 1
 struct scm_timestamping {
   struct timespec ts[3];
 };
diff --git a/libc/kernel/uapi/linux/ethtool.h b/libc/kernel/uapi/linux/ethtool.h
index 56df94b..6f1c0f3 100644
--- a/libc/kernel/uapi/linux/ethtool.h
+++ b/libc/kernel/uapi/linux/ethtool.h
@@ -418,6 +418,24 @@
   __u32 queue_mask[__KERNEL_DIV_ROUND_UP(MAX_NUM_QUEUE, 32)];
   char data[];
 };
+struct ethtool_fecparam {
+  __u32 cmd;
+  __u32 active_fec;
+  __u32 fec;
+  __u32 reserved;
+};
+enum ethtool_fec_config_bits {
+  ETHTOOL_FEC_NONE_BIT,
+  ETHTOOL_FEC_AUTO_BIT,
+  ETHTOOL_FEC_OFF_BIT,
+  ETHTOOL_FEC_RS_BIT,
+  ETHTOOL_FEC_BASER_BIT,
+};
+#define ETHTOOL_FEC_NONE (1 << ETHTOOL_FEC_NONE_BIT)
+#define ETHTOOL_FEC_AUTO (1 << ETHTOOL_FEC_AUTO_BIT)
+#define ETHTOOL_FEC_OFF (1 << ETHTOOL_FEC_OFF_BIT)
+#define ETHTOOL_FEC_RS (1 << ETHTOOL_FEC_RS_BIT)
+#define ETHTOOL_FEC_BASER (1 << ETHTOOL_FEC_BASER_BIT)
 #define ETHTOOL_GSET 0x00000001
 #define ETHTOOL_SSET 0x00000002
 #define ETHTOOL_GDRVINFO 0x00000003
@@ -496,6 +514,8 @@
 #define ETHTOOL_SLINKSETTINGS 0x0000004d
 #define ETHTOOL_PHY_GTUNABLE 0x0000004e
 #define ETHTOOL_PHY_STUNABLE 0x0000004f
+#define ETHTOOL_GFECPARAM 0x00000050
+#define ETHTOOL_SFECPARAM 0x00000051
 #define SPARC_ETH_GSET ETHTOOL_GSET
 #define SPARC_ETH_SSET ETHTOOL_SSET
 enum ethtool_link_mode_bit_indices {
@@ -548,7 +568,10 @@
   ETHTOOL_LINK_MODE_10000baseER_Full_BIT = 46,
   ETHTOOL_LINK_MODE_2500baseT_Full_BIT = 47,
   ETHTOOL_LINK_MODE_5000baseT_Full_BIT = 48,
-  __ETHTOOL_LINK_MODE_LAST = ETHTOOL_LINK_MODE_5000baseT_Full_BIT,
+  ETHTOOL_LINK_MODE_FEC_NONE_BIT = 49,
+  ETHTOOL_LINK_MODE_FEC_RS_BIT = 50,
+  ETHTOOL_LINK_MODE_FEC_BASER_BIT = 51,
+  __ETHTOOL_LINK_MODE_LAST = ETHTOOL_LINK_MODE_FEC_BASER_BIT,
 };
 #define __ETHTOOL_LINK_MODE_LEGACY_MASK(base_name) (1UL << (ETHTOOL_LINK_MODE_ ##base_name ##_BIT))
 #define SUPPORTED_10baseT_Half __ETHTOOL_LINK_MODE_LEGACY_MASK(10baseT_Half)
@@ -721,7 +744,9 @@
   __u8 eth_tp_mdix;
   __u8 eth_tp_mdix_ctrl;
   __s8 link_mode_masks_nwords;
-  __u32 reserved[8];
+  __u8 transceiver;
+  __u8 reserved1[3];
+  __u32 reserved[7];
   __u32 link_mode_masks[0];
 };
 #endif
diff --git a/libc/kernel/uapi/linux/fcntl.h b/libc/kernel/uapi/linux/fcntl.h
index c4a8314..e98a67b 100644
--- a/libc/kernel/uapi/linux/fcntl.h
+++ b/libc/kernel/uapi/linux/fcntl.h
@@ -32,6 +32,16 @@
 #define F_SEAL_SHRINK 0x0002
 #define F_SEAL_GROW 0x0004
 #define F_SEAL_WRITE 0x0008
+#define F_GET_RW_HINT (F_LINUX_SPECIFIC_BASE + 11)
+#define F_SET_RW_HINT (F_LINUX_SPECIFIC_BASE + 12)
+#define F_GET_FILE_RW_HINT (F_LINUX_SPECIFIC_BASE + 13)
+#define F_SET_FILE_RW_HINT (F_LINUX_SPECIFIC_BASE + 14)
+#define RWF_WRITE_LIFE_NOT_SET 0
+#define RWH_WRITE_LIFE_NONE 1
+#define RWH_WRITE_LIFE_SHORT 2
+#define RWH_WRITE_LIFE_MEDIUM 3
+#define RWH_WRITE_LIFE_LONG 4
+#define RWH_WRITE_LIFE_EXTREME 5
 #define DN_ACCESS 0x00000001
 #define DN_MODIFY 0x00000002
 #define DN_CREATE 0x00000004
diff --git a/libc/kernel/uapi/linux/fs.h b/libc/kernel/uapi/linux/fs.h
index 75c17a4..f4e74cd 100644
--- a/libc/kernel/uapi/linux/fs.h
+++ b/libc/kernel/uapi/linux/fs.h
@@ -193,6 +193,8 @@
 #define FS_ENCRYPTION_MODE_AES_256_GCM 2
 #define FS_ENCRYPTION_MODE_AES_256_CBC 3
 #define FS_ENCRYPTION_MODE_AES_256_CTS 4
+#define FS_ENCRYPTION_MODE_AES_128_CBC 5
+#define FS_ENCRYPTION_MODE_AES_128_CTS 6
 struct fscrypt_policy {
   __u8 version;
   __u8 contents_encryption_mode;
@@ -243,7 +245,10 @@
 #define SYNC_FILE_RANGE_WAIT_BEFORE 1
 #define SYNC_FILE_RANGE_WRITE 2
 #define SYNC_FILE_RANGE_WAIT_AFTER 4
-#define RWF_HIPRI 0x00000001
-#define RWF_DSYNC 0x00000002
-#define RWF_SYNC 0x00000004
+typedef int __bitwise __kernel_rwf_t;
+#define RWF_HIPRI ((__force __kernel_rwf_t) 0x00000001)
+#define RWF_DSYNC ((__force __kernel_rwf_t) 0x00000002)
+#define RWF_SYNC ((__force __kernel_rwf_t) 0x00000004)
+#define RWF_NOWAIT ((__force __kernel_rwf_t) 0x00000008)
+#define RWF_SUPPORTED (RWF_HIPRI | RWF_DSYNC | RWF_SYNC | RWF_NOWAIT)
 #endif
diff --git a/libc/kernel/uapi/linux/if_arp.h b/libc/kernel/uapi/linux/if_arp.h
index 9f056fb..0b1959d 100644
--- a/libc/kernel/uapi/linux/if_arp.h
+++ b/libc/kernel/uapi/linux/if_arp.h
@@ -50,6 +50,7 @@
 #define ARPHRD_LAPB 516
 #define ARPHRD_DDCMP 517
 #define ARPHRD_RAWHDLC 518
+#define ARPHRD_RAWIP 519
 #define ARPHRD_TUNNEL 768
 #define ARPHRD_TUNNEL6 769
 #define ARPHRD_FRAD 770
diff --git a/libc/kernel/uapi/linux/if_ether.h b/libc/kernel/uapi/linux/if_ether.h
index 846d238..f40321e 100644
--- a/libc/kernel/uapi/linux/if_ether.h
+++ b/libc/kernel/uapi/linux/if_ether.h
@@ -51,6 +51,7 @@
 #define ETH_P_ATALK 0x809B
 #define ETH_P_AARP 0x80F3
 #define ETH_P_8021Q 0x8100
+#define ETH_P_ERSPAN 0x88BE
 #define ETH_P_IPX 0x8137
 #define ETH_P_IPV6 0x86DD
 #define ETH_P_PAUSE 0x8808
@@ -80,11 +81,13 @@
 #define ETH_P_FIP 0x8914
 #define ETH_P_80221 0x8917
 #define ETH_P_HSR 0x892F
+#define ETH_P_NSH 0x894F
 #define ETH_P_LOOPBACK 0x9000
 #define ETH_P_QINQ1 0x9100
 #define ETH_P_QINQ2 0x9200
 #define ETH_P_QINQ3 0x9300
 #define ETH_P_EDSA 0xDADA
+#define ETH_P_IFE 0xED3E
 #define ETH_P_AF_IUCV 0xFBFB
 #define ETH_P_802_3_MIN 0x0600
 #define ETH_P_802_3 0x0001
@@ -112,6 +115,7 @@
 #define ETH_P_IEEE802154 0x00F6
 #define ETH_P_CAIF 0x00F7
 #define ETH_P_XDSA 0x00F8
+#define ETH_P_MAP 0x00F9
 struct ethhdr {
   unsigned char h_dest[ETH_ALEN];
   unsigned char h_source[ETH_ALEN];
diff --git a/libc/kernel/uapi/linux/if_link.h b/libc/kernel/uapi/linux/if_link.h
index 8ea790b..c041c82 100644
--- a/libc/kernel/uapi/linux/if_link.h
+++ b/libc/kernel/uapi/linux/if_link.h
@@ -135,6 +135,7 @@
   IFLA_GSO_MAX_SIZE,
   IFLA_PAD,
   IFLA_XDP,
+  IFLA_EVENT,
   __IFLA_MAX
 };
 #define IFLA_MAX (__IFLA_MAX - 1)
@@ -693,18 +694,31 @@
 #define XDP_FLAGS_UPDATE_IF_NOEXIST (1U << 0)
 #define XDP_FLAGS_SKB_MODE (1U << 1)
 #define XDP_FLAGS_DRV_MODE (1U << 2)
-#define XDP_FLAGS_MASK (XDP_FLAGS_UPDATE_IF_NOEXIST | XDP_FLAGS_SKB_MODE | XDP_FLAGS_DRV_MODE)
+#define XDP_FLAGS_HW_MODE (1U << 3)
+#define XDP_FLAGS_MODES (XDP_FLAGS_SKB_MODE | XDP_FLAGS_DRV_MODE | XDP_FLAGS_HW_MODE)
+#define XDP_FLAGS_MASK (XDP_FLAGS_UPDATE_IF_NOEXIST | XDP_FLAGS_MODES)
 enum {
   XDP_ATTACHED_NONE = 0,
   XDP_ATTACHED_DRV,
   XDP_ATTACHED_SKB,
+  XDP_ATTACHED_HW,
 };
 enum {
   IFLA_XDP_UNSPEC,
   IFLA_XDP_FD,
   IFLA_XDP_ATTACHED,
   IFLA_XDP_FLAGS,
+  IFLA_XDP_PROG_ID,
   __IFLA_XDP_MAX,
 };
 #define IFLA_XDP_MAX (__IFLA_XDP_MAX - 1)
+enum {
+  IFLA_EVENT_NONE,
+  IFLA_EVENT_REBOOT,
+  IFLA_EVENT_FEATURES,
+  IFLA_EVENT_BONDING_FAILOVER,
+  IFLA_EVENT_NOTIFY_PEERS,
+  IFLA_EVENT_IGMP_RESEND,
+  IFLA_EVENT_BONDING_OPTIONS,
+};
 #endif
diff --git a/libc/kernel/uapi/linux/if_tunnel.h b/libc/kernel/uapi/linux/if_tunnel.h
index aaad4cb..bfc6479 100644
--- a/libc/kernel/uapi/linux/if_tunnel.h
+++ b/libc/kernel/uapi/linux/if_tunnel.h
@@ -134,6 +134,7 @@
   IFLA_GRE_COLLECT_METADATA,
   IFLA_GRE_IGNORE_DF,
   IFLA_GRE_FWMARK,
+  IFLA_GRE_ERSPAN_INDEX,
   __IFLA_GRE_MAX,
 };
 #define IFLA_GRE_MAX (__IFLA_GRE_MAX - 1)
diff --git a/libc/kernel/uapi/linux/inet_diag.h b/libc/kernel/uapi/linux/inet_diag.h
index 9753de0..47a3b34 100644
--- a/libc/kernel/uapi/linux/inet_diag.h
+++ b/libc/kernel/uapi/linux/inet_diag.h
@@ -119,6 +119,8 @@
   INET_DIAG_PAD,
   INET_DIAG_MARK,
   INET_DIAG_BBRINFO,
+  INET_DIAG_CLASS_ID,
+  INET_DIAG_MD5SIG,
   __INET_DIAG_MAX,
 };
 #define INET_DIAG_MAX (__INET_DIAG_MAX - 1)
diff --git a/libc/kernel/uapi/linux/input-event-codes.h b/libc/kernel/uapi/linux/input-event-codes.h
index aea69f3..346ec91 100644
--- a/libc/kernel/uapi/linux/input-event-codes.h
+++ b/libc/kernel/uapi/linux/input-event-codes.h
@@ -538,6 +538,7 @@
 #define KEY_APPSELECT 0x244
 #define KEY_SCREENSAVER 0x245
 #define KEY_VOICECOMMAND 0x246
+#define KEY_ASSISTANT 0x247
 #define KEY_BRIGHTNESS_MIN 0x250
 #define KEY_BRIGHTNESS_MAX 0x251
 #define KEY_KBDINPUTASSIST_PREV 0x260
diff --git a/libc/kernel/uapi/linux/kcmp.h b/libc/kernel/uapi/linux/kcmp.h
index 53064b1..d185c0a 100644
--- a/libc/kernel/uapi/linux/kcmp.h
+++ b/libc/kernel/uapi/linux/kcmp.h
@@ -18,6 +18,7 @@
  ****************************************************************************/
 #ifndef _UAPI_LINUX_KCMP_H
 #define _UAPI_LINUX_KCMP_H
+#include <linux/types.h>
 enum kcmp_type {
   KCMP_FILE,
   KCMP_VM,
@@ -26,6 +27,12 @@
   KCMP_SIGHAND,
   KCMP_IO,
   KCMP_SYSVSEM,
+  KCMP_EPOLL_TFD,
   KCMP_TYPES,
 };
+struct kcmp_epoll_slot {
+  __u32 efd;
+  __u32 tfd;
+  __u32 toff;
+};
 #endif
diff --git a/libc/kernel/uapi/linux/kfd_ioctl.h b/libc/kernel/uapi/linux/kfd_ioctl.h
index 79e5c01..f870cd6 100644
--- a/libc/kernel/uapi/linux/kfd_ioctl.h
+++ b/libc/kernel/uapi/linux/kfd_ioctl.h
@@ -18,13 +18,13 @@
  ****************************************************************************/
 #ifndef KFD_IOCTL_H_INCLUDED
 #define KFD_IOCTL_H_INCLUDED
-#include <linux/types.h>
+#include <drm/drm.h>
 #include <linux/ioctl.h>
 #define KFD_IOCTL_MAJOR_VERSION 1
 #define KFD_IOCTL_MINOR_VERSION 1
 struct kfd_ioctl_get_version_args {
-  uint32_t major_version;
-  uint32_t minor_version;
+  __u32 major_version;
+  __u32 minor_version;
 };
 #define KFD_IOC_QUEUE_TYPE_COMPUTE 0
 #define KFD_IOC_QUEUE_TYPE_SDMA 1
@@ -32,86 +32,86 @@
 #define KFD_MAX_QUEUE_PERCENTAGE 100
 #define KFD_MAX_QUEUE_PRIORITY 15
 struct kfd_ioctl_create_queue_args {
-  uint64_t ring_base_address;
-  uint64_t write_pointer_address;
-  uint64_t read_pointer_address;
-  uint64_t doorbell_offset;
-  uint32_t ring_size;
-  uint32_t gpu_id;
-  uint32_t queue_type;
-  uint32_t queue_percentage;
-  uint32_t queue_priority;
-  uint32_t queue_id;
-  uint64_t eop_buffer_address;
-  uint64_t eop_buffer_size;
-  uint64_t ctx_save_restore_address;
-  uint64_t ctx_save_restore_size;
+  __u64 ring_base_address;
+  __u64 write_pointer_address;
+  __u64 read_pointer_address;
+  __u64 doorbell_offset;
+  __u32 ring_size;
+  __u32 gpu_id;
+  __u32 queue_type;
+  __u32 queue_percentage;
+  __u32 queue_priority;
+  __u32 queue_id;
+  __u64 eop_buffer_address;
+  __u64 eop_buffer_size;
+  __u64 ctx_save_restore_address;
+  __u64 ctx_save_restore_size;
 };
 struct kfd_ioctl_destroy_queue_args {
-  uint32_t queue_id;
-  uint32_t pad;
+  __u32 queue_id;
+  __u32 pad;
 };
 struct kfd_ioctl_update_queue_args {
-  uint64_t ring_base_address;
-  uint32_t queue_id;
-  uint32_t ring_size;
-  uint32_t queue_percentage;
-  uint32_t queue_priority;
+  __u64 ring_base_address;
+  __u32 queue_id;
+  __u32 ring_size;
+  __u32 queue_percentage;
+  __u32 queue_priority;
 };
 #define KFD_IOC_CACHE_POLICY_COHERENT 0
 #define KFD_IOC_CACHE_POLICY_NONCOHERENT 1
 struct kfd_ioctl_set_memory_policy_args {
-  uint64_t alternate_aperture_base;
-  uint64_t alternate_aperture_size;
-  uint32_t gpu_id;
-  uint32_t default_policy;
-  uint32_t alternate_policy;
-  uint32_t pad;
+  __u64 alternate_aperture_base;
+  __u64 alternate_aperture_size;
+  __u32 gpu_id;
+  __u32 default_policy;
+  __u32 alternate_policy;
+  __u32 pad;
 };
 struct kfd_ioctl_get_clock_counters_args {
-  uint64_t gpu_clock_counter;
-  uint64_t cpu_clock_counter;
-  uint64_t system_clock_counter;
-  uint64_t system_clock_freq;
-  uint32_t gpu_id;
-  uint32_t pad;
+  __u64 gpu_clock_counter;
+  __u64 cpu_clock_counter;
+  __u64 system_clock_counter;
+  __u64 system_clock_freq;
+  __u32 gpu_id;
+  __u32 pad;
 };
 #define NUM_OF_SUPPORTED_GPUS 7
 struct kfd_process_device_apertures {
-  uint64_t lds_base;
-  uint64_t lds_limit;
-  uint64_t scratch_base;
-  uint64_t scratch_limit;
-  uint64_t gpuvm_base;
-  uint64_t gpuvm_limit;
-  uint32_t gpu_id;
-  uint32_t pad;
+  __u64 lds_base;
+  __u64 lds_limit;
+  __u64 scratch_base;
+  __u64 scratch_limit;
+  __u64 gpuvm_base;
+  __u64 gpuvm_limit;
+  __u32 gpu_id;
+  __u32 pad;
 };
 struct kfd_ioctl_get_process_apertures_args {
   struct kfd_process_device_apertures process_apertures[NUM_OF_SUPPORTED_GPUS];
-  uint32_t num_of_nodes;
-  uint32_t pad;
+  __u32 num_of_nodes;
+  __u32 pad;
 };
 #define MAX_ALLOWED_NUM_POINTS 100
 #define MAX_ALLOWED_AW_BUFF_SIZE 4096
 #define MAX_ALLOWED_WAC_BUFF_SIZE 128
 struct kfd_ioctl_dbg_register_args {
-  uint32_t gpu_id;
-  uint32_t pad;
+  __u32 gpu_id;
+  __u32 pad;
 };
 struct kfd_ioctl_dbg_unregister_args {
-  uint32_t gpu_id;
-  uint32_t pad;
+  __u32 gpu_id;
+  __u32 pad;
 };
 struct kfd_ioctl_dbg_address_watch_args {
-  uint64_t content_ptr;
-  uint32_t gpu_id;
-  uint32_t buf_size_in_bytes;
+  __u64 content_ptr;
+  __u32 gpu_id;
+  __u32 buf_size_in_bytes;
 };
 struct kfd_ioctl_dbg_wave_control_args {
-  uint64_t content_ptr;
-  uint32_t gpu_id;
-  uint32_t buf_size_in_bytes;
+  __u64 content_ptr;
+  __u32 gpu_id;
+  __u32 buf_size_in_bytes;
 };
 #define KFD_IOC_EVENT_SIGNAL 0
 #define KFD_IOC_EVENT_NODECHANGE 1
@@ -127,52 +127,67 @@
 #define KFD_IOC_WAIT_RESULT_FAIL 2
 #define KFD_SIGNAL_EVENT_LIMIT 256
 struct kfd_ioctl_create_event_args {
-  uint64_t event_page_offset;
-  uint32_t event_trigger_data;
-  uint32_t event_type;
-  uint32_t auto_reset;
-  uint32_t node_id;
-  uint32_t event_id;
-  uint32_t event_slot_index;
+  __u64 event_page_offset;
+  __u32 event_trigger_data;
+  __u32 event_type;
+  __u32 auto_reset;
+  __u32 node_id;
+  __u32 event_id;
+  __u32 event_slot_index;
 };
 struct kfd_ioctl_destroy_event_args {
-  uint32_t event_id;
-  uint32_t pad;
+  __u32 event_id;
+  __u32 pad;
 };
 struct kfd_ioctl_set_event_args {
-  uint32_t event_id;
-  uint32_t pad;
+  __u32 event_id;
+  __u32 pad;
 };
 struct kfd_ioctl_reset_event_args {
-  uint32_t event_id;
-  uint32_t pad;
+  __u32 event_id;
+  __u32 pad;
 };
 struct kfd_memory_exception_failure {
-  uint32_t NotPresent;
-  uint32_t ReadOnly;
-  uint32_t NoExecute;
-  uint32_t pad;
+  __u32 NotPresent;
+  __u32 ReadOnly;
+  __u32 NoExecute;
+  __u32 pad;
 };
 struct kfd_hsa_memory_exception_data {
   struct kfd_memory_exception_failure failure;
-  uint64_t va;
-  uint32_t gpu_id;
-  uint32_t pad;
+  __u64 va;
+  __u32 gpu_id;
+  __u32 pad;
 };
 struct kfd_event_data {
   union {
     struct kfd_hsa_memory_exception_data memory_exception_data;
   };
-  uint64_t kfd_event_data_ext;
-  uint32_t event_id;
-  uint32_t pad;
+  __u64 kfd_event_data_ext;
+  __u32 event_id;
+  __u32 pad;
 };
 struct kfd_ioctl_wait_events_args {
-  uint64_t events_ptr;
-  uint32_t num_events;
-  uint32_t wait_for_all;
-  uint32_t timeout;
-  uint32_t wait_result;
+  __u64 events_ptr;
+  __u32 num_events;
+  __u32 wait_for_all;
+  __u32 timeout;
+  __u32 wait_result;
+};
+struct kfd_ioctl_set_scratch_backing_va_args {
+  uint64_t va_addr;
+  uint32_t gpu_id;
+  uint32_t 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;
 };
 #define AMDKFD_IOCTL_BASE 'K'
 #define AMDKFD_IO(nr) _IO(AMDKFD_IOCTL_BASE, nr)
@@ -195,6 +210,8 @@
 #define AMDKFD_IOC_DBG_UNREGISTER AMDKFD_IOW(0x0E, struct kfd_ioctl_dbg_unregister_args)
 #define AMDKFD_IOC_DBG_ADDRESS_WATCH AMDKFD_IOW(0x0F, struct kfd_ioctl_dbg_address_watch_args)
 #define AMDKFD_IOC_DBG_WAVE_CONTROL AMDKFD_IOW(0x10, struct kfd_ioctl_dbg_wave_control_args)
+#define AMDKFD_IOC_SET_SCRATCH_BACKING_VA AMDKFD_IOWR(0x11, struct kfd_ioctl_set_scratch_backing_va_args)
+#define AMDKFD_IOC_GET_TILE_CONFIG AMDKFD_IOWR(0x12, struct kfd_ioctl_get_tile_config_args)
 #define AMDKFD_COMMAND_START 0x01
-#define AMDKFD_COMMAND_END 0x11
+#define AMDKFD_COMMAND_END 0x13
 #endif
diff --git a/libc/kernel/uapi/linux/kvm.h b/libc/kernel/uapi/linux/kvm.h
index f61a08b..6bd4701 100644
--- a/libc/kernel/uapi/linux/kvm.h
+++ b/libc/kernel/uapi/linux/kvm.h
@@ -123,6 +123,17 @@
   __u32 flags;
   __u32 reserved[9];
 };
+#define KVM_S390_CMMA_PEEK (1 << 0)
+struct kvm_s390_cmma_log {
+  __u64 start_gfn;
+  __u32 count;
+  __u32 flags;
+  union {
+    __u64 remaining;
+    __u64 mask;
+  };
+  __u64 values;
+};
 struct kvm_hyperv_exit {
 #define KVM_EXIT_HYPERV_SYNIC 1
 #define KVM_EXIT_HYPERV_HCALL 2
@@ -526,7 +537,8 @@
 struct kvm_ppc_smmu_info {
   __u64 flags;
   __u32 slb_size;
-  __u32 pad;
+  __u16 data_keys;
+  __u16 instr_keys;
   struct kvm_ppc_one_seg_page_size sps[KVM_PPC_PAGE_SIZES_MAX_SZ];
 };
 struct kvm_ppc_resize_hpt {
@@ -711,6 +723,11 @@
 #define KVM_CAP_SPAPR_TCE_VFIO 142
 #define KVM_CAP_X86_GUEST_MWAIT 143
 #define KVM_CAP_ARM_USER_IRQ 144
+#define KVM_CAP_S390_CMMA_MIGRATION 145
+#define KVM_CAP_PPC_FWNMI 146
+#define KVM_CAP_PPC_SMT_POSSIBLE 147
+#define KVM_CAP_HYPERV_SYNIC2 148
+#define KVM_CAP_HYPERV_VP_INDEX 149
 #ifdef KVM_CAP_IRQ_ROUTING
 struct kvm_irq_routing_irqchip {
   __u32 irqchip;
@@ -1009,6 +1026,8 @@
 #define KVM_S390_SET_IRQ_STATE _IOW(KVMIO, 0xb5, struct kvm_s390_irq_state)
 #define KVM_S390_GET_IRQ_STATE _IOW(KVMIO, 0xb6, struct kvm_s390_irq_state)
 #define KVM_SMI _IO(KVMIO, 0xb7)
+#define KVM_S390_GET_CMMA_BITS _IOWR(KVMIO, 0xb8, struct kvm_s390_cmma_log)
+#define KVM_S390_SET_CMMA_BITS _IOW(KVMIO, 0xb9, struct kvm_s390_cmma_log)
 #define KVM_DEV_ASSIGN_ENABLE_IOMMU (1 << 0)
 #define KVM_DEV_ASSIGN_PCI_2_3 (1 << 1)
 #define KVM_DEV_ASSIGN_MASK_INTX (1 << 2)
diff --git a/libc/kernel/uapi/linux/limits.h b/libc/kernel/uapi/linux/limits.h
index 41108f9..ad0e33e 100644
--- a/libc/kernel/uapi/linux/limits.h
+++ b/libc/kernel/uapi/linux/limits.h
@@ -20,7 +20,7 @@
 #define _LINUX_LIMITS_H
 #define NR_OPEN 1024
 #define NGROUPS_MAX 65536
-#define _KERNEL_ARG_MAX 131072
+#define ARG_MAX 131072
 #define LINK_MAX 127
 #define MAX_CANON 255
 #define MAX_INPUT 255
diff --git a/libc/kernel/uapi/linux/loop.h b/libc/kernel/uapi/linux/loop.h
index ff3482f..d5a23b5 100644
--- a/libc/kernel/uapi/linux/loop.h
+++ b/libc/kernel/uapi/linux/loop.h
@@ -77,6 +77,7 @@
 #define LOOP_CHANGE_FD 0x4C06
 #define LOOP_SET_CAPACITY 0x4C07
 #define LOOP_SET_DIRECT_IO 0x4C08
+#define LOOP_SET_BLOCK_SIZE 0x4C09
 #define LOOP_CTL_ADD 0x4C80
 #define LOOP_CTL_REMOVE 0x4C81
 #define LOOP_CTL_GET_FREE 0x4C82
diff --git a/libc/kernel/uapi/linux/lwtunnel.h b/libc/kernel/uapi/linux/lwtunnel.h
index c88d866..05cc4fd 100644
--- a/libc/kernel/uapi/linux/lwtunnel.h
+++ b/libc/kernel/uapi/linux/lwtunnel.h
@@ -27,6 +27,7 @@
   LWTUNNEL_ENCAP_IP6,
   LWTUNNEL_ENCAP_SEG6,
   LWTUNNEL_ENCAP_BPF,
+  LWTUNNEL_ENCAP_SEG6_LOCAL,
   __LWTUNNEL_ENCAP_MAX,
 };
 #define LWTUNNEL_ENCAP_MAX (__LWTUNNEL_ENCAP_MAX - 1)
diff --git a/libc/kernel/uapi/linux/magic.h b/libc/kernel/uapi/linux/magic.h
index a9dac5d..6e0ddf7 100644
--- a/libc/kernel/uapi/linux/magic.h
+++ b/libc/kernel/uapi/linux/magic.h
@@ -57,6 +57,7 @@
 #define MSDOS_SUPER_MAGIC 0x4d44
 #define NCP_SUPER_MAGIC 0x564c
 #define NFS_SUPER_MAGIC 0x6969
+#define OCFS2_SUPER_MAGIC 0x7461636f
 #define OPENPROM_SUPER_MAGIC 0x9fa1
 #define QNX4_SUPER_MAGIC 0x002f
 #define QNX6_SUPER_MAGIC 0x68191122
@@ -86,6 +87,7 @@
 #define BTRFS_TEST_MAGIC 0x73727279
 #define NSFS_MAGIC 0x6e736673
 #define BPF_FS_MAGIC 0xcafe4a11
+#define AAFS_MAGIC 0x5a3c69f0
 #define UDF_SUPER_MAGIC 0x15013346
 #define BALLOON_KVM_MAGIC 0x13661366
 #define ZSMALLOC_MAGIC 0x58295829
diff --git a/libc/kernel/uapi/linux/wil6210_uapi.h b/libc/kernel/uapi/linux/max2175.h
similarity index 62%
rename from libc/kernel/uapi/linux/wil6210_uapi.h
rename to libc/kernel/uapi/linux/max2175.h
index e68b6c8..e6998e1 100644
--- a/libc/kernel/uapi/linux/wil6210_uapi.h
+++ b/libc/kernel/uapi/linux/max2175.h
@@ -16,30 +16,10 @@
  ***
  ****************************************************************************
  ****************************************************************************/
-#ifndef __WIL6210_UAPI_H__
-#define __WIL6210_UAPI_H__
-#define __user
-#include <linux/sockios.h>
-#define WIL_IOCTL_MEMIO (SIOCDEVPRIVATE + 2)
-#define WIL_IOCTL_MEMIO_BLOCK (SIOCDEVPRIVATE + 3)
-enum wil_memio_op {
-  wil_mmio_read = 0,
-  wil_mmio_write = 1,
-  wil_mmio_op_mask = 0xff,
-  wil_mmio_addr_linker = 0 << 8,
-  wil_mmio_addr_ahb = 1 << 8,
-  wil_mmio_addr_bar = 2 << 8,
-  wil_mmio_addr_mask = 0xff00,
-};
-struct wil_memio {
-  uint32_t op;
-  uint32_t addr;
-  uint32_t val;
-};
-struct wil_memio_block {
-  uint32_t op;
-  uint32_t addr;
-  uint32_t size;
-  void __user * block;
-};
+#ifndef __UAPI_MAX2175_H_
+#define __UAPI_MAX2175_H_
+#include <linux/v4l2-controls.h>
+#define V4L2_CID_MAX2175_I2S_ENABLE (V4L2_CID_USER_MAX217X_BASE + 0x01)
+#define V4L2_CID_MAX2175_HSLS (V4L2_CID_USER_MAX217X_BASE + 0x02)
+#define V4L2_CID_MAX2175_RX_MODE (V4L2_CID_USER_MAX217X_BASE + 0x03)
 #endif
diff --git a/libc/kernel/uapi/linux/media.h b/libc/kernel/uapi/linux/media.h
index 690d9b2a..b24d616 100644
--- a/libc/kernel/uapi/linux/media.h
+++ b/libc/kernel/uapi/linux/media.h
@@ -22,7 +22,6 @@
 #include <linux/ioctl.h>
 #include <linux/types.h>
 #include <linux/version.h>
-#define MEDIA_API_VERSION KERNEL_VERSION(0, 1, 0)
 struct media_device_info {
   char driver[16];
   char model[32];
@@ -56,6 +55,8 @@
 #define MEDIA_ENT_F_PROC_VIDEO_LUT (MEDIA_ENT_F_BASE + 0x4004)
 #define MEDIA_ENT_F_PROC_VIDEO_SCALER (MEDIA_ENT_F_BASE + 0x4005)
 #define MEDIA_ENT_F_PROC_VIDEO_STATISTICS (MEDIA_ENT_F_BASE + 0x4006)
+#define MEDIA_ENT_F_VID_MUX (MEDIA_ENT_F_BASE + 0x5001)
+#define MEDIA_ENT_F_VID_IF_BRIDGE (MEDIA_ENT_F_BASE + 0x5002)
 #define MEDIA_ENT_F_IO_V4L (MEDIA_ENT_F_OLD_BASE + 1)
 #define MEDIA_ENT_F_CAM_SENSOR (MEDIA_ENT_F_OLD_SUBDEV_BASE + 1)
 #define MEDIA_ENT_F_FLASH (MEDIA_ENT_F_OLD_SUBDEV_BASE + 2)
@@ -80,6 +81,7 @@
 #define MEDIA_ENT_T_V4L2_SUBDEV_LENS MEDIA_ENT_F_LENS
 #define MEDIA_ENT_T_V4L2_SUBDEV_DECODER MEDIA_ENT_F_ATV_DECODER
 #define MEDIA_ENT_T_V4L2_SUBDEV_TUNER MEDIA_ENT_F_TUNER
+#define MEDIA_API_VERSION KERNEL_VERSION(0, 1, 0)
 #define MEDIA_ENT_FL_DEFAULT (1 << 0)
 #define MEDIA_ENT_FL_CONNECTOR (1 << 1)
 struct media_entity_desc {
diff --git a/libc/kernel/uapi/linux/membarrier.h b/libc/kernel/uapi/linux/membarrier.h
index e9edbaa..2f5ea7d 100644
--- a/libc/kernel/uapi/linux/membarrier.h
+++ b/libc/kernel/uapi/linux/membarrier.h
@@ -21,5 +21,7 @@
 enum membarrier_cmd {
   MEMBARRIER_CMD_QUERY = 0,
   MEMBARRIER_CMD_SHARED = (1 << 0),
+  MEMBARRIER_CMD_PRIVATE_EXPEDITED = (1 << 3),
+  MEMBARRIER_CMD_REGISTER_PRIVATE_EXPEDITED = (1 << 4),
 };
 #endif
diff --git a/libc/kernel/uapi/linux/memfd.h b/libc/kernel/uapi/linux/memfd.h
index d3d08a1..e3e5cd5 100644
--- a/libc/kernel/uapi/linux/memfd.h
+++ b/libc/kernel/uapi/linux/memfd.h
@@ -18,6 +18,20 @@
  ****************************************************************************/
 #ifndef _UAPI_LINUX_MEMFD_H
 #define _UAPI_LINUX_MEMFD_H
+#include <asm-generic/hugetlb_encode.h>
 #define MFD_CLOEXEC 0x0001U
 #define MFD_ALLOW_SEALING 0x0002U
+#define MFD_HUGETLB 0x0004U
+#define MFD_HUGE_SHIFT HUGETLB_FLAG_ENCODE_SHIFT
+#define MFD_HUGE_MASK HUGETLB_FLAG_ENCODE_MASK
+#define MFD_HUGE_64KB HUGETLB_FLAG_ENCODE_64KB
+#define MFD_HUGE_512KB HUGETLB_FLAG_ENCODE_512KB
+#define MFD_HUGE_1MB HUGETLB_FLAG_ENCODE_1MB
+#define MFD_HUGE_2MB HUGETLB_FLAG_ENCODE_2MB
+#define MFD_HUGE_8MB HUGETLB_FLAG_ENCODE_8MB
+#define MFD_HUGE_16MB HUGETLB_FLAG_ENCODE_16MB
+#define MFD_HUGE_256MB HUGETLB_FLAG_ENCODE_256MB
+#define MFD_HUGE_1GB HUGETLB_FLAG_ENCODE_1GB
+#define MFD_HUGE_2GB HUGETLB_FLAG_ENCODE_2GB
+#define MFD_HUGE_16GB HUGETLB_FLAG_ENCODE_16GB
 #endif
diff --git a/libc/kernel/uapi/linux/mempolicy.h b/libc/kernel/uapi/linux/mempolicy.h
index 081f9d6..6f721f6 100644
--- a/libc/kernel/uapi/linux/mempolicy.h
+++ b/libc/kernel/uapi/linux/mempolicy.h
@@ -27,12 +27,6 @@
   MPOL_LOCAL,
   MPOL_MAX,
 };
-enum mpol_rebind_step {
-  MPOL_REBIND_ONCE,
-  MPOL_REBIND_STEP1,
-  MPOL_REBIND_STEP2,
-  MPOL_REBIND_NSTEP,
-};
 #define MPOL_F_STATIC_NODES (1 << 15)
 #define MPOL_F_RELATIVE_NODES (1 << 14)
 #define MPOL_MODE_FLAGS (MPOL_F_STATIC_NODES | MPOL_F_RELATIVE_NODES)
@@ -47,7 +41,6 @@
 #define MPOL_MF_VALID (MPOL_MF_STRICT | MPOL_MF_MOVE | MPOL_MF_MOVE_ALL)
 #define MPOL_F_SHARED (1 << 0)
 #define MPOL_F_LOCAL (1 << 1)
-#define MPOL_F_REBINDING (1 << 2)
 #define MPOL_F_MOF (1 << 3)
 #define MPOL_F_MORON (1 << 4)
 #endif
diff --git a/libc/kernel/uapi/linux/mman.h b/libc/kernel/uapi/linux/mman.h
index c5b3130..b0ce77e 100644
--- a/libc/kernel/uapi/linux/mman.h
+++ b/libc/kernel/uapi/linux/mman.h
@@ -19,9 +19,22 @@
 #ifndef _UAPI_LINUX_MMAN_H
 #define _UAPI_LINUX_MMAN_H
 #include <asm/mman.h>
+#include <asm-generic/hugetlb_encode.h>
 #define MREMAP_MAYMOVE 1
 #define MREMAP_FIXED 2
 #define OVERCOMMIT_GUESS 0
 #define OVERCOMMIT_ALWAYS 1
 #define OVERCOMMIT_NEVER 2
+#define MAP_HUGE_SHIFT HUGETLB_FLAG_ENCODE_SHIFT
+#define MAP_HUGE_MASK HUGETLB_FLAG_ENCODE_MASK
+#define MAP_HUGE_64KB HUGETLB_FLAG_ENCODE_64KB
+#define MAP_HUGE_512KB HUGETLB_FLAG_ENCODE_512KB
+#define MAP_HUGE_1MB HUGETLB_FLAG_ENCODE_1MB
+#define MAP_HUGE_2MB HUGETLB_FLAG_ENCODE_2MB
+#define MAP_HUGE_8MB HUGETLB_FLAG_ENCODE_8MB
+#define MAP_HUGE_16MB HUGETLB_FLAG_ENCODE_16MB
+#define MAP_HUGE_256MB HUGETLB_FLAG_ENCODE_256MB
+#define MAP_HUGE_1GB HUGETLB_FLAG_ENCODE_1GB
+#define MAP_HUGE_2GB HUGETLB_FLAG_ENCODE_2GB
+#define MAP_HUGE_16GB HUGETLB_FLAG_ENCODE_16GB
 #endif
diff --git a/libc/kernel/uapi/linux/mroute.h b/libc/kernel/uapi/linux/mroute.h
index 9f4c937..d962f8b 100644
--- a/libc/kernel/uapi/linux/mroute.h
+++ b/libc/kernel/uapi/linux/mroute.h
@@ -95,6 +95,48 @@
   unsigned char unused3;
   struct in_addr im_src, im_dst;
 };
+enum {
+  IPMRA_TABLE_UNSPEC,
+  IPMRA_TABLE_ID,
+  IPMRA_TABLE_CACHE_RES_QUEUE_LEN,
+  IPMRA_TABLE_MROUTE_REG_VIF_NUM,
+  IPMRA_TABLE_MROUTE_DO_ASSERT,
+  IPMRA_TABLE_MROUTE_DO_PIM,
+  IPMRA_TABLE_VIFS,
+  __IPMRA_TABLE_MAX
+};
+#define IPMRA_TABLE_MAX (__IPMRA_TABLE_MAX - 1)
+enum {
+  IPMRA_VIF_UNSPEC,
+  IPMRA_VIF,
+  __IPMRA_VIF_MAX
+};
+#define IPMRA_VIF_MAX (__IPMRA_VIF_MAX - 1)
+enum {
+  IPMRA_VIFA_UNSPEC,
+  IPMRA_VIFA_IFINDEX,
+  IPMRA_VIFA_VIF_ID,
+  IPMRA_VIFA_FLAGS,
+  IPMRA_VIFA_BYTES_IN,
+  IPMRA_VIFA_BYTES_OUT,
+  IPMRA_VIFA_PACKETS_IN,
+  IPMRA_VIFA_PACKETS_OUT,
+  IPMRA_VIFA_LOCAL_ADDR,
+  IPMRA_VIFA_REMOTE_ADDR,
+  IPMRA_VIFA_PAD,
+  __IPMRA_VIFA_MAX
+};
+#define IPMRA_VIFA_MAX (__IPMRA_VIFA_MAX - 1)
+enum {
+  IPMRA_CREPORT_UNSPEC,
+  IPMRA_CREPORT_MSGTYPE,
+  IPMRA_CREPORT_VIF_ID,
+  IPMRA_CREPORT_SRC_ADDR,
+  IPMRA_CREPORT_DST_ADDR,
+  IPMRA_CREPORT_PKT,
+  __IPMRA_CREPORT_MAX
+};
+#define IPMRA_CREPORT_MAX (__IPMRA_CREPORT_MAX - 1)
 #define MFC_ASSERT_THRESH (3 * HZ)
 #define IGMPMSG_NOCACHE 1
 #define IGMPMSG_WRONGVIF 2
diff --git a/libc/kernel/uapi/linux/mroute6.h b/libc/kernel/uapi/linux/mroute6.h
index d9c86bf..ccb38d9 100644
--- a/libc/kernel/uapi/linux/mroute6.h
+++ b/libc/kernel/uapi/linux/mroute6.h
@@ -94,4 +94,14 @@
   __u32 im6_pad;
   struct in6_addr im6_src, im6_dst;
 };
+enum {
+  IP6MRA_CREPORT_UNSPEC,
+  IP6MRA_CREPORT_MSGTYPE,
+  IP6MRA_CREPORT_MIF_ID,
+  IP6MRA_CREPORT_SRC_ADDR,
+  IP6MRA_CREPORT_DST_ADDR,
+  IP6MRA_CREPORT_PKT,
+  __IP6MRA_CREPORT_MAX
+};
+#define IP6MRA_CREPORT_MAX (__IP6MRA_CREPORT_MAX - 1)
 #endif
diff --git a/libc/kernel/uapi/linux/nbd.h b/libc/kernel/uapi/linux/nbd.h
index 50079fa..749c38a 100644
--- a/libc/kernel/uapi/linux/nbd.h
+++ b/libc/kernel/uapi/linux/nbd.h
@@ -40,8 +40,10 @@
 #define NBD_FLAG_HAS_FLAGS (1 << 0)
 #define NBD_FLAG_READ_ONLY (1 << 1)
 #define NBD_FLAG_SEND_FLUSH (1 << 2)
+#define NBD_FLAG_SEND_FUA (1 << 3)
 #define NBD_FLAG_SEND_TRIM (1 << 5)
 #define NBD_FLAG_CAN_MULTI_CONN (1 << 8)
+#define NBD_CMD_FLAG_FUA (1 << 16)
 #define NBD_CFLAG_DESTROY_ON_DISCONNECT (1 << 0)
 #define NBD_REQUEST_MAGIC 0x25609513
 #define NBD_REPLY_MAGIC 0x67446698
diff --git a/libc/kernel/uapi/linux/ndctl.h b/libc/kernel/uapi/linux/ndctl.h
index cfe5c9c..44c9ee0 100644
--- a/libc/kernel/uapi/linux/ndctl.h
+++ b/libc/kernel/uapi/linux/ndctl.h
@@ -98,7 +98,8 @@
   __u32 status;
   __u32 max_ars_out;
   __u32 clear_err_unit;
-  __u32 reserved;
+  __u16 flags;
+  __u16 reserved;
 } __packed;
 struct nd_cmd_ars_start {
   __u64 address;
@@ -153,6 +154,7 @@
 enum {
   ND_ARS_VOLATILE = 1,
   ND_ARS_PERSISTENT = 2,
+  ND_ARS_RETURN_PREV_DATA = 1 << 1,
   ND_CONFIG_LOCKED = 1,
 };
 #define ND_IOCTL 'N'
diff --git a/libc/kernel/uapi/linux/neighbour.h b/libc/kernel/uapi/linux/neighbour.h
index 1a322de..cf32a12 100644
--- a/libc/kernel/uapi/linux/neighbour.h
+++ b/libc/kernel/uapi/linux/neighbour.h
@@ -50,6 +50,7 @@
 #define NTF_MASTER 0x04
 #define NTF_PROXY 0x08
 #define NTF_EXT_LEARNED 0x10
+#define NTF_OFFLOADED 0x20
 #define NTF_ROUTER 0x80
 #define NUD_INCOMPLETE 0x01
 #define NUD_REACHABLE 0x02
diff --git a/libc/kernel/uapi/linux/net_tstamp.h b/libc/kernel/uapi/linux/net_tstamp.h
index 9a2373e..49d4c2c 100644
--- a/libc/kernel/uapi/linux/net_tstamp.h
+++ b/libc/kernel/uapi/linux/net_tstamp.h
@@ -18,6 +18,7 @@
  ****************************************************************************/
 #ifndef _NET_TIMESTAMPING_H
 #define _NET_TIMESTAMPING_H
+#include <linux/types.h>
 #include <linux/socket.h>
 enum {
   SOF_TIMESTAMPING_TX_HARDWARE = (1 << 0),
@@ -33,7 +34,9 @@
   SOF_TIMESTAMPING_OPT_CMSG = (1 << 10),
   SOF_TIMESTAMPING_OPT_TSONLY = (1 << 11),
   SOF_TIMESTAMPING_OPT_STATS = (1 << 12),
-  SOF_TIMESTAMPING_LAST = SOF_TIMESTAMPING_OPT_STATS,
+  SOF_TIMESTAMPING_OPT_PKTINFO = (1 << 13),
+  SOF_TIMESTAMPING_OPT_TX_SWHW = (1 << 14),
+  SOF_TIMESTAMPING_LAST = SOF_TIMESTAMPING_OPT_TX_SWHW,
   SOF_TIMESTAMPING_MASK = (SOF_TIMESTAMPING_LAST - 1) | SOF_TIMESTAMPING_LAST
 };
 #define SOF_TIMESTAMPING_TX_RECORD_MASK (SOF_TIMESTAMPING_TX_HARDWARE | SOF_TIMESTAMPING_TX_SOFTWARE | SOF_TIMESTAMPING_TX_SCHED | SOF_TIMESTAMPING_TX_ACK)
@@ -63,5 +66,11 @@
   HWTSTAMP_FILTER_PTP_V2_EVENT,
   HWTSTAMP_FILTER_PTP_V2_SYNC,
   HWTSTAMP_FILTER_PTP_V2_DELAY_REQ,
+  HWTSTAMP_FILTER_NTP_ALL,
+};
+struct scm_ts_pktinfo {
+  __u32 if_index;
+  __u32 pkt_length;
+  __u32 reserved[2];
 };
 #endif
diff --git a/libc/kernel/uapi/linux/netfilter/nf_tables.h b/libc/kernel/uapi/linux/netfilter/nf_tables.h
index c090f94..169fb33 100644
--- a/libc/kernel/uapi/linux/netfilter/nf_tables.h
+++ b/libc/kernel/uapi/linux/netfilter/nf_tables.h
@@ -18,10 +18,11 @@
  ****************************************************************************/
 #ifndef _LINUX_NF_TABLES_H
 #define _LINUX_NF_TABLES_H
-#define NFT_TABLE_MAXNAMELEN 32
-#define NFT_CHAIN_MAXNAMELEN 32
-#define NFT_SET_MAXNAMELEN 32
-#define NFT_OBJ_MAXNAMELEN 32
+#define NFT_NAME_MAXLEN 256
+#define NFT_TABLE_MAXNAMELEN NFT_NAME_MAXLEN
+#define NFT_CHAIN_MAXNAMELEN NFT_NAME_MAXLEN
+#define NFT_SET_MAXNAMELEN NFT_NAME_MAXLEN
+#define NFT_OBJ_MAXNAMELEN NFT_NAME_MAXLEN
 #define NFT_USERDATA_MAXLEN 256
 enum nft_registers {
   NFT_REG_VERDICT,
@@ -374,6 +375,7 @@
   NFTA_EXTHDR_LEN,
   NFTA_EXTHDR_FLAGS,
   NFTA_EXTHDR_OP,
+  NFTA_EXTHDR_SREG,
   __NFTA_EXTHDR_MAX
 };
 #define NFTA_EXTHDR_MAX (__NFTA_EXTHDR_MAX - 1)
@@ -408,6 +410,7 @@
   NFT_RT_CLASSID,
   NFT_RT_NEXTHOP4,
   NFT_RT_NEXTHOP6,
+  NFT_RT_TCPMSS,
 };
 enum nft_hash_types {
   NFT_HASH_JENKINS,
@@ -610,6 +613,8 @@
 enum nft_gen_attributes {
   NFTA_GEN_UNSPEC,
   NFTA_GEN_ID,
+  NFTA_GEN_PROC_PID,
+  NFTA_GEN_PROC_NAME,
   __NFTA_GEN_MAX
 };
 #define NFTA_GEN_MAX (__NFTA_GEN_MAX - 1)
@@ -649,7 +654,8 @@
 #define NFT_OBJECT_COUNTER 1
 #define NFT_OBJECT_QUOTA 2
 #define NFT_OBJECT_CT_HELPER 3
-#define __NFT_OBJECT_MAX 4
+#define NFT_OBJECT_LIMIT 4
+#define __NFT_OBJECT_MAX 5
 #define NFT_OBJECT_MAX (__NFT_OBJECT_MAX - 1)
 enum nft_object_attributes {
   NFTA_OBJ_UNSPEC,
diff --git a/libc/kernel/uapi/linux/netfilter/xt_bpf.h b/libc/kernel/uapi/linux/netfilter/xt_bpf.h
index d9a54f9..043af45 100644
--- a/libc/kernel/uapi/linux/netfilter/xt_bpf.h
+++ b/libc/kernel/uapi/linux/netfilter/xt_bpf.h
@@ -34,6 +34,7 @@
   XT_BPF_MODE_FD_PINNED,
   XT_BPF_MODE_FD_ELF,
 };
+#define XT_BPF_MODE_PATH_PINNED XT_BPF_MODE_FD_PINNED
 struct xt_bpf_info_v1 {
   __u16 mode;
   __u16 bpf_program_num_elem;
diff --git a/libc/kernel/uapi/linux/netfilter/xt_hashlimit.h b/libc/kernel/uapi/linux/netfilter/xt_hashlimit.h
index c9d62f3..572c85d 100644
--- a/libc/kernel/uapi/linux/netfilter/xt_hashlimit.h
+++ b/libc/kernel/uapi/linux/netfilter/xt_hashlimit.h
@@ -32,6 +32,7 @@
   XT_HASHLIMIT_HASH_SPT = 1 << 3,
   XT_HASHLIMIT_INVERT = 1 << 4,
   XT_HASHLIMIT_BYTES = 1 << 5,
+  XT_HASHLIMIT_RATE_MATCH = 1 << 6,
 };
 struct hashlimit_cfg {
   __u32 mode;
@@ -71,6 +72,17 @@
   __u32 expire;
   __u8 srcmask, dstmask;
 };
+struct hashlimit_cfg3 {
+  __u64 avg;
+  __u64 burst;
+  __u32 mode;
+  __u32 size;
+  __u32 max;
+  __u32 gc_interval;
+  __u32 expire;
+  __u32 interval;
+  __u8 srcmask, dstmask;
+};
 struct xt_hashlimit_mtinfo1 {
   char name[IFNAMSIZ];
   struct hashlimit_cfg1 cfg;
@@ -81,4 +93,9 @@
   struct hashlimit_cfg2 cfg;
   struct xt_hashlimit_htable * hinfo __attribute__((aligned(8)));
 };
+struct xt_hashlimit_mtinfo3 {
+  char name[NAME_MAX];
+  struct hashlimit_cfg3 cfg;
+  struct xt_hashlimit_htable * hinfo __attribute__((aligned(8)));
+};
 #endif
diff --git a/libc/kernel/uapi/linux/netlink.h b/libc/kernel/uapi/linux/netlink.h
index 4eb428a..4f35c02 100644
--- a/libc/kernel/uapi/linux/netlink.h
+++ b/libc/kernel/uapi/linux/netlink.h
@@ -72,6 +72,7 @@
 #define NLM_F_EXCL 0x200
 #define NLM_F_CREATE 0x400
 #define NLM_F_APPEND 0x800
+#define NLM_F_NONREC 0x100
 #define NLM_F_CAPPED 0x100
 #define NLM_F_ACK_TLVS 0x200
 #define NLMSG_ALIGNTO 4U
@@ -153,4 +154,8 @@
 #define NLA_ALIGNTO 4
 #define NLA_ALIGN(len) (((len) + NLA_ALIGNTO - 1) & ~(NLA_ALIGNTO - 1))
 #define NLA_HDRLEN ((int) NLA_ALIGN(sizeof(struct nlattr)))
+struct nla_bitfield32 {
+  __u32 value;
+  __u32 selector;
+};
 #endif
diff --git a/libc/kernel/uapi/linux/nl80211.h b/libc/kernel/uapi/linux/nl80211.h
index 103b9da..bb9a835 100644
--- a/libc/kernel/uapi/linux/nl80211.h
+++ b/libc/kernel/uapi/linux/nl80211.h
@@ -156,6 +156,8 @@
   NL80211_CMD_NAN_MATCH,
   NL80211_CMD_SET_MULTICAST_TO_UNICAST,
   NL80211_CMD_UPDATE_CONNECT_PARAMS,
+  NL80211_CMD_SET_PMK,
+  NL80211_CMD_DEL_PMK,
   __NL80211_CMD_AFTER_LAST,
   NL80211_CMD_MAX = __NL80211_CMD_AFTER_LAST - 1
 };
@@ -429,6 +431,9 @@
   NL80211_ATTR_PMK,
   NL80211_ATTR_SCHED_SCAN_MULTI,
   NL80211_ATTR_SCHED_SCAN_MAX_REQS,
+  NL80211_ATTR_WANT_1X_4WAY_HS,
+  NL80211_ATTR_PMKR0_NAME,
+  NL80211_ATTR_PORT_AUTHORIZED,
   __NL80211_ATTR_AFTER_LAST,
   NUM_NL80211_ATTR = __NL80211_ATTR_AFTER_LAST,
   NL80211_ATTR_MAX = __NL80211_ATTR_AFTER_LAST - 1
@@ -1187,6 +1192,8 @@
   NL80211_EXT_FEATURE_SCHED_SCAN_RELATIVE_RSSI,
   NL80211_EXT_FEATURE_CQM_RSSI_LIST,
   NL80211_EXT_FEATURE_FILS_SK_OFFLOAD,
+  NL80211_EXT_FEATURE_4WAY_HANDSHAKE_STA_PSK,
+  NL80211_EXT_FEATURE_4WAY_HANDSHAKE_STA_1X,
   NUM_NL80211_EXT_FEATURES,
   MAX_NL80211_EXT_FEATURES = NUM_NL80211_EXT_FEATURES - 1
 };
diff --git a/libc/kernel/uapi/linux/pci_regs.h b/libc/kernel/uapi/linux/pci_regs.h
index baa9421..c7f8381 100644
--- a/libc/kernel/uapi/linux/pci_regs.h
+++ b/libc/kernel/uapi/linux/pci_regs.h
@@ -424,10 +424,12 @@
 #define PCI_EXP_DEVSTA_URD 0x0008
 #define PCI_EXP_DEVSTA_AUXPD 0x0010
 #define PCI_EXP_DEVSTA_TRPND 0x0020
+#define PCI_CAP_EXP_RC_ENDPOINT_SIZEOF_V1 12
 #define PCI_EXP_LNKCAP 12
 #define PCI_EXP_LNKCAP_SLS 0x0000000f
 #define PCI_EXP_LNKCAP_SLS_2_5GB 0x00000001
 #define PCI_EXP_LNKCAP_SLS_5_0GB 0x00000002
+#define PCI_EXP_LNKCAP_SLS_8_0GB 0x00000003
 #define PCI_EXP_LNKCAP_MLW 0x000003f0
 #define PCI_EXP_LNKCAP_ASPMS 0x00000c00
 #define PCI_EXP_LNKCAP_L0SEL 0x00007000
@@ -541,7 +543,7 @@
 #define PCI_EXP_DEVCTL2_OBFF_MSGB_EN 0x4000
 #define PCI_EXP_DEVCTL2_OBFF_WAKE_EN 0x6000
 #define PCI_EXP_DEVSTA2 42
-#define PCI_CAP_EXP_ENDPOINT_SIZEOF_V2 44
+#define PCI_CAP_EXP_RC_ENDPOINT_SIZEOF_V2 44
 #define PCI_EXP_LNKCAP2 44
 #define PCI_EXP_LNKCAP2_SLS_2_5GB 0x00000002
 #define PCI_EXP_LNKCAP2_SLS_5_0GB 0x00000004
@@ -549,6 +551,7 @@
 #define PCI_EXP_LNKCAP2_CROSSLINK 0x00000100
 #define PCI_EXP_LNKCTL2 48
 #define PCI_EXP_LNKSTA2 50
+#define PCI_CAP_EXP_ENDPOINT_SIZEOF_V2 52
 #define PCI_EXP_SLTCAP2 52
 #define PCI_EXP_SLTCTL2 56
 #define PCI_EXP_SLTSTA2 58
@@ -814,6 +817,7 @@
 #define PCI_EXP_DPC_CAP_RP_EXT 0x20
 #define PCI_EXP_DPC_CAP_POISONED_TLP 0x40
 #define PCI_EXP_DPC_CAP_SW_TRIGGER 0x80
+#define PCI_EXP_DPC_RP_PIO_LOG_SIZE 0xF00
 #define PCI_EXP_DPC_CAP_DL_ACTIVE 0x1000
 #define PCI_EXP_DPC_CTL 6
 #define PCI_EXP_DPC_CTL_EN_NONFATAL 0x02
@@ -823,6 +827,14 @@
 #define PCI_EXP_DPC_STATUS_INTERRUPT 0x08
 #define PCI_EXP_DPC_RP_BUSY 0x10
 #define PCI_EXP_DPC_SOURCE_ID 10
+#define PCI_EXP_DPC_RP_PIO_STATUS 0x0C
+#define PCI_EXP_DPC_RP_PIO_MASK 0x10
+#define PCI_EXP_DPC_RP_PIO_SEVERITY 0x14
+#define PCI_EXP_DPC_RP_PIO_SYSERROR 0x18
+#define PCI_EXP_DPC_RP_PIO_EXCEPTION 0x1C
+#define PCI_EXP_DPC_RP_PIO_HEADER_LOG 0x20
+#define PCI_EXP_DPC_RP_PIO_IMPSPEC_LOG 0x30
+#define PCI_EXP_DPC_RP_PIO_TLPPREFIX_LOG 0x34
 #define PCI_PTM_CAP 0x04
 #define PCI_PTM_CAP_REQ 0x00000001
 #define PCI_PTM_CAP_ROOT 0x00000004
diff --git a/libc/kernel/uapi/linux/perf_event.h b/libc/kernel/uapi/linux/perf_event.h
index 8adad9c..326827e 100644
--- a/libc/kernel/uapi/linux/perf_event.h
+++ b/libc/kernel/uapi/linux/perf_event.h
@@ -98,7 +98,8 @@
   PERF_SAMPLE_IDENTIFIER = 1U << 16,
   PERF_SAMPLE_TRANSACTION = 1U << 17,
   PERF_SAMPLE_REGS_INTR = 1U << 18,
-  PERF_SAMPLE_MAX = 1U << 19,
+  PERF_SAMPLE_PHYS_ADDR = 1U << 19,
+  PERF_SAMPLE_MAX = 1U << 20,
 };
 enum perf_branch_sample_type_shift {
   PERF_SAMPLE_BRANCH_USER_SHIFT = 0,
@@ -117,6 +118,7 @@
   PERF_SAMPLE_BRANCH_CALL_SHIFT = 13,
   PERF_SAMPLE_BRANCH_NO_FLAGS_SHIFT = 14,
   PERF_SAMPLE_BRANCH_NO_CYCLES_SHIFT = 15,
+  PERF_SAMPLE_BRANCH_TYPE_SAVE_SHIFT = 16,
   PERF_SAMPLE_BRANCH_MAX_SHIFT
 };
 enum perf_branch_sample_type {
@@ -136,8 +138,23 @@
   PERF_SAMPLE_BRANCH_CALL = 1U << PERF_SAMPLE_BRANCH_CALL_SHIFT,
   PERF_SAMPLE_BRANCH_NO_FLAGS = 1U << PERF_SAMPLE_BRANCH_NO_FLAGS_SHIFT,
   PERF_SAMPLE_BRANCH_NO_CYCLES = 1U << PERF_SAMPLE_BRANCH_NO_CYCLES_SHIFT,
+  PERF_SAMPLE_BRANCH_TYPE_SAVE = 1U << PERF_SAMPLE_BRANCH_TYPE_SAVE_SHIFT,
   PERF_SAMPLE_BRANCH_MAX = 1U << PERF_SAMPLE_BRANCH_MAX_SHIFT,
 };
+enum {
+  PERF_BR_UNKNOWN = 0,
+  PERF_BR_COND = 1,
+  PERF_BR_UNCOND = 2,
+  PERF_BR_IND = 3,
+  PERF_BR_CALL = 4,
+  PERF_BR_IND_CALL = 5,
+  PERF_BR_RET = 6,
+  PERF_BR_SYSCALL = 7,
+  PERF_BR_SYSRET = 8,
+  PERF_BR_COND_CALL = 9,
+  PERF_BR_COND_RET = 10,
+  PERF_BR_MAX,
+};
 #define PERF_SAMPLE_BRANCH_PLM_ALL (PERF_SAMPLE_BRANCH_USER | PERF_SAMPLE_BRANCH_KERNEL | PERF_SAMPLE_BRANCH_HV)
 enum perf_sample_regs_abi {
   PERF_SAMPLE_REGS_ABI_NONE = 0,
@@ -320,14 +337,14 @@
 union perf_mem_data_src {
   __u64 val;
   struct {
-    __u64 mem_op : 5, mem_lvl : 14, mem_snoop : 5, mem_lock : 2, mem_dtlb : 7, mem_rsvd : 31;
+    __u64 mem_op : 5, mem_lvl : 14, mem_snoop : 5, mem_lock : 2, mem_dtlb : 7, mem_lvl_num : 4, mem_remote : 1, mem_snoopx : 2, mem_rsvd : 24;
   };
 };
 #elif defined(__BIG_ENDIAN_BITFIELD)
 union perf_mem_data_src {
   __u64 val;
   struct {
-    __u64 mem_rsvd : 31, mem_dtlb : 7, mem_lock : 2, mem_snoop : 5, mem_lvl : 14, mem_op : 5;
+    __u64 mem_rsvd : 24, mem_snoopx : 2, mem_remote : 1, mem_lvl_num : 4, mem_dtlb : 7, mem_lock : 2, mem_snoop : 5, mem_lvl : 14, mem_op : 5;
   };
 };
 #else
@@ -354,12 +371,26 @@
 #define PERF_MEM_LVL_IO 0x1000
 #define PERF_MEM_LVL_UNC 0x2000
 #define PERF_MEM_LVL_SHIFT 5
+#define PERF_MEM_REMOTE_REMOTE 0x01
+#define PERF_MEM_REMOTE_SHIFT 37
+#define PERF_MEM_LVLNUM_L1 0x01
+#define PERF_MEM_LVLNUM_L2 0x02
+#define PERF_MEM_LVLNUM_L3 0x03
+#define PERF_MEM_LVLNUM_L4 0x04
+#define PERF_MEM_LVLNUM_ANY_CACHE 0x0b
+#define PERF_MEM_LVLNUM_LFB 0x0c
+#define PERF_MEM_LVLNUM_RAM 0x0d
+#define PERF_MEM_LVLNUM_PMEM 0x0e
+#define PERF_MEM_LVLNUM_NA 0x0f
+#define PERF_MEM_LVLNUM_SHIFT 33
 #define PERF_MEM_SNOOP_NA 0x01
 #define PERF_MEM_SNOOP_NONE 0x02
 #define PERF_MEM_SNOOP_HIT 0x04
 #define PERF_MEM_SNOOP_MISS 0x08
 #define PERF_MEM_SNOOP_HITM 0x10
 #define PERF_MEM_SNOOP_SHIFT 19
+#define PERF_MEM_SNOOPX_FWD 0x01
+#define PERF_MEM_SNOOPX_SHIFT 37
 #define PERF_MEM_LOCK_NA 0x01
 #define PERF_MEM_LOCK_LOCKED 0x02
 #define PERF_MEM_LOCK_SHIFT 24
@@ -375,6 +406,6 @@
 struct perf_branch_entry {
   __u64 from;
   __u64 to;
-  __u64 mispred : 1, predicted : 1, in_tx : 1, abort : 1, cycles : 16, reserved : 44;
+  __u64 mispred : 1, predicted : 1, in_tx : 1, abort : 1, cycles : 16, type : 4, reserved : 40;
 };
 #endif
diff --git a/libc/kernel/uapi/linux/pkt_cls.h b/libc/kernel/uapi/linux/pkt_cls.h
index af251c0..4bac8f9 100644
--- a/libc/kernel/uapi/linux/pkt_cls.h
+++ b/libc/kernel/uapi/linux/pkt_cls.h
@@ -49,11 +49,13 @@
 #define TC_ACT_QUEUED 5
 #define TC_ACT_REPEAT 6
 #define TC_ACT_REDIRECT 7
+#define TC_ACT_TRAP 8
 #define __TC_ACT_EXT_SHIFT 28
 #define __TC_ACT_EXT(local) ((local) << __TC_ACT_EXT_SHIFT)
 #define TC_ACT_EXT_VAL_MASK ((1 << __TC_ACT_EXT_SHIFT) - 1)
 #define TC_ACT_EXT_CMP(combined,opcode) (((combined) & (~TC_ACT_EXT_VAL_MASK)) == opcode)
 #define TC_ACT_JUMP __TC_ACT_EXT(1)
+#define TC_ACT_GOTO_CHAIN __TC_ACT_EXT(2)
 enum {
   TCA_ID_UNSPEC = 0,
   TCA_ID_POLICE = 1,
@@ -291,6 +293,7 @@
   TCA_BPF_FLAGS,
   TCA_BPF_FLAGS_GEN,
   TCA_BPF_TAG,
+  TCA_BPF_ID,
   __TCA_BPF_MAX,
 };
 #define TCA_BPF_MAX (__TCA_BPF_MAX - 1)
@@ -366,6 +369,12 @@
   TCA_FLOWER_KEY_MPLS_BOS,
   TCA_FLOWER_KEY_MPLS_TC,
   TCA_FLOWER_KEY_MPLS_LABEL,
+  TCA_FLOWER_KEY_TCP_FLAGS,
+  TCA_FLOWER_KEY_TCP_FLAGS_MASK,
+  TCA_FLOWER_KEY_IP_TOS,
+  TCA_FLOWER_KEY_IP_TOS_MASK,
+  TCA_FLOWER_KEY_IP_TTL,
+  TCA_FLOWER_KEY_IP_TTL_MASK,
   __TCA_FLOWER_MAX,
 };
 #define TCA_FLOWER_MAX (__TCA_FLOWER_MAX - 1)
diff --git a/libc/kernel/uapi/linux/quota.h b/libc/kernel/uapi/linux/quota.h
index cc5ccbb..280b396 100644
--- a/libc/kernel/uapi/linux/quota.h
+++ b/libc/kernel/uapi/linux/quota.h
@@ -18,7 +18,6 @@
  ****************************************************************************/
 #ifndef _UAPI_LINUX_QUOTA_
 #define _UAPI_LINUX_QUOTA_
-#include <linux/errno.h>
 #include <linux/types.h>
 #define __DQUOT_VERSION__ "dquot_6.6.0"
 #define MAXQUOTAS 3
diff --git a/libc/kernel/uapi/linux/raid/md_p.h b/libc/kernel/uapi/linux/raid/md_p.h
index ea54bdb..0bc6756 100644
--- a/libc/kernel/uapi/linux/raid/md_p.h
+++ b/libc/kernel/uapi/linux/raid/md_p.h
@@ -181,7 +181,8 @@
 #define MD_FEATURE_CLUSTERED 256
 #define MD_FEATURE_JOURNAL 512
 #define MD_FEATURE_PPL 1024
-#define MD_FEATURE_ALL (MD_FEATURE_BITMAP_OFFSET | MD_FEATURE_RECOVERY_OFFSET | MD_FEATURE_RESHAPE_ACTIVE | MD_FEATURE_BAD_BLOCKS | MD_FEATURE_REPLACEMENT | MD_FEATURE_RESHAPE_BACKWARDS | MD_FEATURE_NEW_OFFSET | MD_FEATURE_RECOVERY_BITMAP | MD_FEATURE_CLUSTERED | MD_FEATURE_JOURNAL | MD_FEATURE_PPL)
+#define MD_FEATURE_MULTIPLE_PPLS 2048
+#define MD_FEATURE_ALL (MD_FEATURE_BITMAP_OFFSET | MD_FEATURE_RECOVERY_OFFSET | MD_FEATURE_RESHAPE_ACTIVE | MD_FEATURE_BAD_BLOCKS | MD_FEATURE_REPLACEMENT | MD_FEATURE_RESHAPE_BACKWARDS | MD_FEATURE_NEW_OFFSET | MD_FEATURE_RECOVERY_BITMAP | MD_FEATURE_CLUSTERED | MD_FEATURE_JOURNAL | MD_FEATURE_PPL | MD_FEATURE_MULTIPLE_PPLS)
 struct r5l_payload_header {
   __le16 type;
   __le16 flags;
diff --git a/libc/kernel/uapi/linux/rtnetlink.h b/libc/kernel/uapi/linux/rtnetlink.h
index d094068..c363e34 100644
--- a/libc/kernel/uapi/linux/rtnetlink.h
+++ b/libc/kernel/uapi/linux/rtnetlink.h
@@ -131,6 +131,8 @@
 #define RTM_NEWSTATS RTM_NEWSTATS
   RTM_GETSTATS = 94,
 #define RTM_GETSTATS RTM_GETSTATS
+  RTM_NEWCACHEREPORT = 96,
+#define RTM_NEWCACHEREPORT RTM_NEWCACHEREPORT
   __RTM_MAX,
 #define RTM_MAX (((__RTM_MAX + 3) & ~3) - 1)
 };
@@ -204,6 +206,7 @@
 #define RTM_F_EQUALIZE 0x400
 #define RTM_F_PREFIX 0x800
 #define RTM_F_LOOKUP_TABLE 0x1000
+#define RTM_F_FIB_MATCH 0x2000
 enum rt_class_t {
   RT_TABLE_UNSPEC = 0,
   RT_TABLE_COMPAT = 252,
@@ -398,6 +401,7 @@
   TCA_STAB,
   TCA_PAD,
   TCA_DUMP_INVISIBLE,
+  TCA_CHAIN,
   __TCA_MAX
 };
 #define TCA_MAX (__TCA_MAX - 1)
@@ -493,6 +497,10 @@
 #define RTNLGRP_NSID RTNLGRP_NSID
   RTNLGRP_MPLS_NETCONF,
 #define RTNLGRP_MPLS_NETCONF RTNLGRP_MPLS_NETCONF
+  RTNLGRP_IPV4_MROUTE_R,
+#define RTNLGRP_IPV4_MROUTE_R RTNLGRP_IPV4_MROUTE_R
+  RTNLGRP_IPV6_MROUTE_R,
+#define RTNLGRP_IPV6_MROUTE_R RTNLGRP_IPV6_MROUTE_R
   __RTNLGRP_MAX
 };
 #define RTNLGRP_MAX (__RTNLGRP_MAX - 1)
@@ -501,10 +509,20 @@
   unsigned char tca__pad1;
   unsigned short tca__pad2;
 };
+enum {
+  TCA_ROOT_UNSPEC,
+  TCA_ROOT_TAB,
+#define TCA_ACT_TAB TCA_ROOT_TAB
+#define TCAA_MAX TCA_ROOT_TAB
+  TCA_ROOT_FLAGS,
+  TCA_ROOT_COUNT,
+  TCA_ROOT_TIME_DELTA,
+  __TCA_ROOT_MAX,
+#define TCA_ROOT_MAX (__TCA_ROOT_MAX - 1)
+};
 #define TA_RTA(r) ((struct rtattr *) (((char *) (r)) + NLMSG_ALIGN(sizeof(struct tcamsg))))
 #define TA_PAYLOAD(n) NLMSG_PAYLOAD(n, sizeof(struct tcamsg))
-#define TCA_ACT_TAB 1
-#define TCAA_MAX 1
+#define TCA_FLAG_LARGE_DUMP_ON (1 << 0)
 #define RTEXT_FILTER_VF (1 << 0)
 #define RTEXT_FILTER_BRVLAN (1 << 1)
 #define RTEXT_FILTER_BRVLAN_COMPRESSED (1 << 2)
diff --git a/libc/kernel/uapi/linux/rxrpc.h b/libc/kernel/uapi/linux/rxrpc.h
new file mode 100644
index 0000000..b8b7b04
--- /dev/null
+++ b/libc/kernel/uapi/linux/rxrpc.h
@@ -0,0 +1,91 @@
+/****************************************************************************
+ ****************************************************************************
+ ***
+ ***   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_RXRPC_H
+#define _UAPI_LINUX_RXRPC_H
+#include <linux/types.h>
+#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;
+  union {
+    sa_family_t family;
+    struct sockaddr_in sin;
+    struct sockaddr_in6 sin6;
+  } transport;
+};
+#define RXRPC_SECURITY_KEY 1
+#define RXRPC_SECURITY_KEYRING 2
+#define RXRPC_EXCLUSIVE_CONNECTION 3
+#define RXRPC_MIN_SECURITY_LEVEL 4
+#define RXRPC_UPGRADEABLE_SERVICE 5
+#define RXRPC_SUPPORTED_CMSG 6
+enum rxrpc_cmsg_type {
+  RXRPC_USER_CALL_ID = 1,
+  RXRPC_ABORT = 2,
+  RXRPC_ACK = 3,
+  RXRPC_NET_ERROR = 5,
+  RXRPC_BUSY = 6,
+  RXRPC_LOCAL_ERROR = 7,
+  RXRPC_NEW_CALL = 8,
+  RXRPC_ACCEPT = 9,
+  RXRPC_EXCLUSIVE_CALL = 10,
+  RXRPC_UPGRADE_SERVICE = 11,
+  RXRPC_TX_LENGTH = 12,
+  RXRPC__SUPPORTED
+};
+#define RXRPC_SECURITY_PLAIN 0
+#define RXRPC_SECURITY_AUTH 1
+#define RXRPC_SECURITY_ENCRYPT 2
+#define RXRPC_SECURITY_NONE 0
+#define RXRPC_SECURITY_RXKAD 2
+#define RXRPC_SECURITY_RXGK 4
+#define RXRPC_SECURITY_RXK5 5
+#define RX_CALL_DEAD - 1
+#define RX_INVALID_OPERATION - 2
+#define RX_CALL_TIMEOUT - 3
+#define RX_EOF - 4
+#define RX_PROTOCOL_ERROR - 5
+#define RX_USER_ABORT - 6
+#define RX_ADDRINUSE - 7
+#define RX_DEBUGI_BADTYPE - 8
+#define RXGEN_CC_MARSHAL - 450
+#define RXGEN_CC_UNMARSHAL - 451
+#define RXGEN_SS_MARSHAL - 452
+#define RXGEN_SS_UNMARSHAL - 453
+#define RXGEN_DECODE - 454
+#define RXGEN_OPCODE - 455
+#define RXGEN_SS_XDRFREE - 456
+#define RXGEN_CC_XDRFREE - 457
+#define RXKADINCONSISTENCY 19270400
+#define RXKADPACKETSHORT 19270401
+#define RXKADLEVELFAIL 19270402
+#define RXKADTICKETLEN 19270403
+#define RXKADOUTOFSEQUENCE 19270404
+#define RXKADNOAUTH 19270405
+#define RXKADBADKEY 19270406
+#define RXKADBADTICKET 19270407
+#define RXKADUNKNOWNKEY 19270408
+#define RXKADEXPIRED 19270409
+#define RXKADSEALEDINCON 19270410
+#define RXKADDATALEN 19270411
+#define RXKADILLEGALLEVEL 19270412
+#endif
diff --git a/libc/kernel/uapi/linux/sched.h b/libc/kernel/uapi/linux/sched.h
index 8d149b8..9958fba 100644
--- a/libc/kernel/uapi/linux/sched.h
+++ b/libc/kernel/uapi/linux/sched.h
@@ -50,4 +50,5 @@
 #define SCHED_DEADLINE 6
 #define SCHED_RESET_ON_FORK 0x40000000
 #define SCHED_FLAG_RESET_ON_FORK 0x01
+#define SCHED_FLAG_RECLAIM 0x02
 #endif
diff --git a/libc/kernel/uapi/linux/sctp.h b/libc/kernel/uapi/linux/sctp.h
index a5cef43..9a55459 100644
--- a/libc/kernel/uapi/linux/sctp.h
+++ b/libc/kernel/uapi/linux/sctp.h
@@ -76,6 +76,7 @@
 #define SCTP_RESET_STREAMS 119
 #define SCTP_RESET_ASSOC 120
 #define SCTP_ADD_STREAMS 121
+#define SCTP_SOCKOPT_PEELOFF_FLAGS 122
 #define SCTP_PR_SCTP_NONE 0x0000
 #define SCTP_PR_SCTP_TTL 0x0010
 #define SCTP_PR_SCTP_RTX 0x0020
@@ -204,7 +205,7 @@
   __u16 sre_type;
   __u16 sre_flags;
   __u32 sre_length;
-  __u16 sre_error;
+  __be16 sre_error;
   sctp_assoc_t sre_assoc_id;
   __u8 sre_data[0];
 };
@@ -525,6 +526,10 @@
   sctp_assoc_t associd;
   int sd;
 } sctp_peeloff_arg_t;
+typedef struct {
+  sctp_peeloff_arg_t p_arg;
+  unsigned flags;
+} sctp_peeloff_flags_arg_t;
 struct sctp_paddrthlds {
   sctp_assoc_t spt_assoc_id;
   struct sockaddr_storage spt_address;
diff --git a/libc/kernel/uapi/linux/seccomp.h b/libc/kernel/uapi/linux/seccomp.h
index db041a3..1fd53fc 100644
--- a/libc/kernel/uapi/linux/seccomp.h
+++ b/libc/kernel/uapi/linux/seccomp.h
@@ -25,12 +25,18 @@
 #define SECCOMP_MODE_FILTER 2
 #define SECCOMP_SET_MODE_STRICT 0
 #define SECCOMP_SET_MODE_FILTER 1
+#define SECCOMP_GET_ACTION_AVAIL 2
 #define SECCOMP_FILTER_FLAG_TSYNC 1
-#define SECCOMP_RET_KILL 0x00000000U
+#define SECCOMP_FILTER_FLAG_LOG 2
+#define SECCOMP_RET_KILL_PROCESS 0x80000000U
+#define SECCOMP_RET_KILL_THREAD 0x00000000U
+#define SECCOMP_RET_KILL SECCOMP_RET_KILL_THREAD
 #define SECCOMP_RET_TRAP 0x00030000U
 #define SECCOMP_RET_ERRNO 0x00050000U
 #define SECCOMP_RET_TRACE 0x7ff00000U
+#define SECCOMP_RET_LOG 0x7ffc0000U
 #define SECCOMP_RET_ALLOW 0x7fff0000U
+#define SECCOMP_RET_ACTION_FULL 0xffff0000U
 #define SECCOMP_RET_ACTION 0x7fff0000U
 #define SECCOMP_RET_DATA 0x0000ffffU
 struct seccomp_data {
diff --git a/libc/kernel/uapi/linux/seg6_iptunnel.h b/libc/kernel/uapi/linux/seg6_iptunnel.h
index 747fa09..1c1ad83 100644
--- a/libc/kernel/uapi/linux/seg6_iptunnel.h
+++ b/libc/kernel/uapi/linux/seg6_iptunnel.h
@@ -33,5 +33,6 @@
 enum {
   SEG6_IPTUN_MODE_INLINE,
   SEG6_IPTUN_MODE_ENCAP,
+  SEG6_IPTUN_MODE_L2ENCAP,
 };
 #endif
diff --git a/libc/kernel/uapi/linux/seg6_local.h b/libc/kernel/uapi/linux/seg6_local.h
new file mode 100644
index 0000000..7a10701
--- /dev/null
+++ b/libc/kernel/uapi/linux/seg6_local.h
@@ -0,0 +1,53 @@
+/****************************************************************************
+ ****************************************************************************
+ ***
+ ***   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_SEG6_LOCAL_H
+#define _UAPI_LINUX_SEG6_LOCAL_H
+#include <linux/seg6.h>
+enum {
+  SEG6_LOCAL_UNSPEC,
+  SEG6_LOCAL_ACTION,
+  SEG6_LOCAL_SRH,
+  SEG6_LOCAL_TABLE,
+  SEG6_LOCAL_NH4,
+  SEG6_LOCAL_NH6,
+  SEG6_LOCAL_IIF,
+  SEG6_LOCAL_OIF,
+  __SEG6_LOCAL_MAX,
+};
+#define SEG6_LOCAL_MAX (__SEG6_LOCAL_MAX - 1)
+enum {
+  SEG6_LOCAL_ACTION_UNSPEC = 0,
+  SEG6_LOCAL_ACTION_END = 1,
+  SEG6_LOCAL_ACTION_END_X = 2,
+  SEG6_LOCAL_ACTION_END_T = 3,
+  SEG6_LOCAL_ACTION_END_DX2 = 4,
+  SEG6_LOCAL_ACTION_END_DX6 = 5,
+  SEG6_LOCAL_ACTION_END_DX4 = 6,
+  SEG6_LOCAL_ACTION_END_DT6 = 7,
+  SEG6_LOCAL_ACTION_END_DT4 = 8,
+  SEG6_LOCAL_ACTION_END_B6 = 9,
+  SEG6_LOCAL_ACTION_END_B6_ENCAP = 10,
+  SEG6_LOCAL_ACTION_END_BM = 11,
+  SEG6_LOCAL_ACTION_END_S = 12,
+  SEG6_LOCAL_ACTION_END_AS = 13,
+  SEG6_LOCAL_ACTION_END_AM = 14,
+  __SEG6_LOCAL_ACTION_MAX,
+};
+#define SEG6_LOCAL_ACTION_MAX (__SEG6_LOCAL_ACTION_MAX - 1)
+#endif
diff --git a/libc/kernel/uapi/linux/serial.h b/libc/kernel/uapi/linux/serial.h
index 219a2ea..79f11e3 100644
--- a/libc/kernel/uapi/linux/serial.h
+++ b/libc/kernel/uapi/linux/serial.h
@@ -95,6 +95,7 @@
 #define SER_RS485_RTS_ON_SEND (1 << 1)
 #define SER_RS485_RTS_AFTER_SEND (1 << 2)
 #define SER_RS485_RX_DURING_TX (1 << 4)
+#define SER_RS485_TERMINATE_BUS (1 << 5)
   __u32 delay_rts_before_send;
   __u32 delay_rts_after_send;
   __u32 padding[5];
diff --git a/libc/kernel/uapi/linux/serial_core.h b/libc/kernel/uapi/linux/serial_core.h
index af349c2..68d2dcb 100644
--- a/libc/kernel/uapi/linux/serial_core.h
+++ b/libc/kernel/uapi/linux/serial_core.h
@@ -50,16 +50,17 @@
 #define PORT_ALTR_16550_F128 28
 #define PORT_RT2880 29
 #define PORT_16550A_FSL64 30
-#define PORT_DA830 31
-#define PORT_MAX_8250 31
 #define PORT_PXA 31
 #define PORT_AMBA 32
 #define PORT_CLPS711X 33
 #define PORT_SA1100 34
 #define PORT_UART00 35
+#define PORT_OWL 36
 #define PORT_21285 37
 #define PORT_SUNZILOG 38
 #define PORT_SUNSAB 39
+#define PORT_PCH_8LINE 44
+#define PORT_PCH_2LINE 45
 #define PORT_DZ 46
 #define PORT_ZS 47
 #define PORT_MUX 48
@@ -109,7 +110,7 @@
 #define PORT_ALTERA_UART 92
 #define PORT_SCIFB 93
 #define PORT_MAX310X 94
-#define PORT_MFD 95
+#define PORT_DA830 95
 #define PORT_OMAP 96
 #define PORT_VT8500 97
 #define PORT_XUARTPS 98
@@ -131,4 +132,5 @@
 #define PORT_MVEBU 114
 #define PORT_PIC32 115
 #define PORT_MPS2UART 116
+#define PORT_MTK_BTIF 117
 #endif
diff --git a/libc/kernel/uapi/linux/shm.h b/libc/kernel/uapi/linux/shm.h
index ab319f2..a3071e7 100644
--- a/libc/kernel/uapi/linux/shm.h
+++ b/libc/kernel/uapi/linux/shm.h
@@ -20,6 +20,7 @@
 #define _UAPI_LINUX_SHM_H_
 #include <linux/ipc.h>
 #include <linux/errno.h>
+#include <asm-generic/hugetlb_encode.h>
 #include <unistd.h>
 #define SHMMIN 1
 #define SHMMNI 4096
@@ -42,6 +43,20 @@
 #include <asm/shmbuf.h>
 #define SHM_R 0400
 #define SHM_W 0200
+#define SHM_HUGETLB 04000
+#define SHM_NORESERVE 010000
+#define SHM_HUGE_SHIFT HUGETLB_FLAG_ENCODE_SHIFT
+#define SHM_HUGE_MASK HUGETLB_FLAG_ENCODE_MASK
+#define SHM_HUGE_64KB HUGETLB_FLAG_ENCODE_64KB
+#define SHM_HUGE_512KB HUGETLB_FLAG_ENCODE_512KB
+#define SHM_HUGE_1MB HUGETLB_FLAG_ENCODE_1MB
+#define SHM_HUGE_2MB HUGETLB_FLAG_ENCODE_2MB
+#define SHM_HUGE_8MB HUGETLB_FLAG_ENCODE_8MB
+#define SHM_HUGE_16MB HUGETLB_FLAG_ENCODE_16MB
+#define SHM_HUGE_256MB HUGETLB_FLAG_ENCODE_256MB
+#define SHM_HUGE_1GB HUGETLB_FLAG_ENCODE_1GB
+#define SHM_HUGE_2GB HUGETLB_FLAG_ENCODE_2GB
+#define SHM_HUGE_16GB HUGETLB_FLAG_ENCODE_16GB
 #define SHM_RDONLY 010000
 #define SHM_RND 020000
 #define SHM_REMAP 040000
diff --git a/libc/kernel/uapi/linux/snmp.h b/libc/kernel/uapi/linux/snmp.h
index 91d693f..467a27a 100644
--- a/libc/kernel/uapi/linux/snmp.h
+++ b/libc/kernel/uapi/linux/snmp.h
@@ -152,12 +152,7 @@
   LINUX_MIB_DELAYEDACKLOST,
   LINUX_MIB_LISTENOVERFLOWS,
   LINUX_MIB_LISTENDROPS,
-  LINUX_MIB_TCPPREQUEUED,
-  LINUX_MIB_TCPDIRECTCOPYFROMBACKLOG,
-  LINUX_MIB_TCPDIRECTCOPYFROMPREQUEUE,
-  LINUX_MIB_TCPPREQUEUEDROPPED,
   LINUX_MIB_TCPHPHITS,
-  LINUX_MIB_TCPHPHITSTOUSER,
   LINUX_MIB_TCPPUREACKS,
   LINUX_MIB_TCPHPACKS,
   LINUX_MIB_TCPRENORECOVERY,
@@ -176,14 +171,12 @@
   LINUX_MIB_TCPSACKFAILURES,
   LINUX_MIB_TCPLOSSFAILURES,
   LINUX_MIB_TCPFASTRETRANS,
-  LINUX_MIB_TCPFORWARDRETRANS,
   LINUX_MIB_TCPSLOWSTARTRETRANS,
   LINUX_MIB_TCPTIMEOUTS,
   LINUX_MIB_TCPLOSSPROBES,
   LINUX_MIB_TCPLOSSPROBERECOVERY,
   LINUX_MIB_TCPRENORECOVERYFAIL,
   LINUX_MIB_TCPSACKRECOVERYFAIL,
-  LINUX_MIB_TCPSCHEDULERFAILED,
   LINUX_MIB_TCPRCVCOLLAPSED,
   LINUX_MIB_TCPDSACKOLDSENT,
   LINUX_MIB_TCPDSACKOFOSENT,
@@ -196,6 +189,7 @@
   LINUX_MIB_TCPABORTONLINGER,
   LINUX_MIB_TCPABORTFAILED,
   LINUX_MIB_TCPMEMORYPRESSURES,
+  LINUX_MIB_TCPMEMORYPRESSURESCHRONO,
   LINUX_MIB_TCPSACKDISCARD,
   LINUX_MIB_TCPDSACKIGNOREDOLD,
   LINUX_MIB_TCPDSACKIGNOREDNOUNDO,
diff --git a/libc/kernel/uapi/linux/spi/spidev.h b/libc/kernel/uapi/linux/spi/spidev.h
index 73efc6f..2fe8264 100644
--- a/libc/kernel/uapi/linux/spi/spidev.h
+++ b/libc/kernel/uapi/linux/spi/spidev.h
@@ -19,6 +19,7 @@
 #ifndef SPIDEV_H
 #define SPIDEV_H
 #include <linux/types.h>
+#include <linux/ioctl.h>
 #define SPI_CPHA 0x01
 #define SPI_CPOL 0x02
 #define SPI_MODE_0 (0 | 0)
diff --git a/libc/kernel/uapi/linux/switchtec_ioctl.h b/libc/kernel/uapi/linux/switchtec_ioctl.h
index a0341a8..9337be6 100644
--- a/libc/kernel/uapi/linux/switchtec_ioctl.h
+++ b/libc/kernel/uapi/linux/switchtec_ioctl.h
@@ -38,6 +38,8 @@
   __u32 num_partitions;
   __u32 padding;
 };
+#define SWITCHTEC_IOCTL_PART_ACTIVE 1
+#define SWITCHTEC_IOCTL_PART_RUNNING 2
 struct switchtec_ioctl_flash_part_info {
   __u32 flash_partition;
   __u32 address;
diff --git a/libc/kernel/uapi/linux/target_core_user.h b/libc/kernel/uapi/linux/target_core_user.h
index 640e9c7..264b46f 100644
--- a/libc/kernel/uapi/linux/target_core_user.h
+++ b/libc/kernel/uapi/linux/target_core_user.h
@@ -71,6 +71,11 @@
   TCMU_CMD_UNSPEC,
   TCMU_CMD_ADDED_DEVICE,
   TCMU_CMD_REMOVED_DEVICE,
+  TCMU_CMD_RECONFIG_DEVICE,
+  TCMU_CMD_ADDED_DEVICE_DONE,
+  TCMU_CMD_REMOVED_DEVICE_DONE,
+  TCMU_CMD_RECONFIG_DEVICE_DONE,
+  TCMU_CMD_SET_FEATURES,
   __TCMU_CMD_MAX,
 };
 #define TCMU_CMD_MAX (__TCMU_CMD_MAX - 1)
@@ -78,6 +83,13 @@
   TCMU_ATTR_UNSPEC,
   TCMU_ATTR_DEVICE,
   TCMU_ATTR_MINOR,
+  TCMU_ATTR_PAD,
+  TCMU_ATTR_DEV_CFG,
+  TCMU_ATTR_DEV_SIZE,
+  TCMU_ATTR_WRITECACHE,
+  TCMU_ATTR_CMD_STATUS,
+  TCMU_ATTR_DEVICE_ID,
+  TCMU_ATTR_SUPP_KERN_CMD_REPLY,
   __TCMU_ATTR_MAX,
 };
 #define TCMU_ATTR_MAX (__TCMU_ATTR_MAX - 1)
diff --git a/libc/kernel/uapi/linux/tc_act/tc_bpf.h b/libc/kernel/uapi/linux/tc_act/tc_bpf.h
index 2e6f6d1..c4963a5 100644
--- a/libc/kernel/uapi/linux/tc_act/tc_bpf.h
+++ b/libc/kernel/uapi/linux/tc_act/tc_bpf.h
@@ -33,6 +33,7 @@
   TCA_ACT_BPF_NAME,
   TCA_ACT_BPF_PAD,
   TCA_ACT_BPF_TAG,
+  TCA_ACT_BPF_ID,
   __TCA_ACT_BPF_MAX,
 };
 #define TCA_ACT_BPF_MAX (__TCA_ACT_BPF_MAX - 1)
diff --git a/libc/kernel/uapi/linux/tc_act/tc_tunnel_key.h b/libc/kernel/uapi/linux/tc_act/tc_tunnel_key.h
index 014a584..24e7403 100644
--- a/libc/kernel/uapi/linux/tc_act/tc_tunnel_key.h
+++ b/libc/kernel/uapi/linux/tc_act/tc_tunnel_key.h
@@ -37,6 +37,7 @@
   TCA_TUNNEL_KEY_ENC_KEY_ID,
   TCA_TUNNEL_KEY_PAD,
   TCA_TUNNEL_KEY_ENC_DST_PORT,
+  TCA_TUNNEL_KEY_NO_CSUM,
   __TCA_TUNNEL_KEY_MAX,
 };
 #define TCA_TUNNEL_KEY_MAX (__TCA_TUNNEL_KEY_MAX - 1)
diff --git a/libc/kernel/uapi/linux/tcp.h b/libc/kernel/uapi/linux/tcp.h
index 9c3a90d..f5134d6 100644
--- a/libc/kernel/uapi/linux/tcp.h
+++ b/libc/kernel/uapi/linux/tcp.h
@@ -85,6 +85,8 @@
 #define TCP_SAVED_SYN 28
 #define TCP_REPAIR_WINDOW 29
 #define TCP_FASTOPEN_CONNECT 30
+#define TCP_ULP 31
+#define TCP_MD5SIG_EXT 32
 struct tcp_repair_opt {
   __u32 opt_code;
   __u32 opt_val;
@@ -175,13 +177,29 @@
   TCP_NLA_SNDBUF_LIMITED,
   TCP_NLA_DATA_SEGS_OUT,
   TCP_NLA_TOTAL_RETRANS,
+  TCP_NLA_PACING_RATE,
+  TCP_NLA_DELIVERY_RATE,
+  TCP_NLA_SND_CWND,
+  TCP_NLA_REORDERING,
+  TCP_NLA_MIN_RTT,
+  TCP_NLA_RECUR_RETRANS,
+  TCP_NLA_DELIVERY_RATE_APP_LMT,
 };
 #define TCP_MD5SIG_MAXKEYLEN 80
+#define TCP_MD5SIG_FLAG_PREFIX 1
 struct tcp_md5sig {
   struct __kernel_sockaddr_storage tcpm_addr;
-  __u16 __tcpm_pad1;
+  __u8 tcpm_flags;
+  __u8 tcpm_prefixlen;
   __u16 tcpm_keylen;
-  __u32 __tcpm_pad2;
+  __u32 __tcpm_pad;
+  __u8 tcpm_key[TCP_MD5SIG_MAXKEYLEN];
+};
+struct tcp_diag_md5sig {
+  __u8 tcpm_family;
+  __u8 tcpm_prefixlen;
+  __u16 tcpm_keylen;
+  __be32 tcpm_addr[4];
   __u8 tcpm_key[TCP_MD5SIG_MAXKEYLEN];
 };
 #endif
diff --git a/libc/kernel/uapi/linux/tee.h b/libc/kernel/uapi/linux/tee.h
index 9a42337..20d0d80 100644
--- a/libc/kernel/uapi/linux/tee.h
+++ b/libc/kernel/uapi/linux/tee.h
@@ -26,6 +26,7 @@
 #define TEE_IOCTL_SHM_DMA_BUF 0x2
 #define TEE_MAX_ARG_SIZE 1024
 #define TEE_GEN_CAP_GP (1 << 0)
+#define TEE_GEN_CAP_PRIVILEGED (1 << 1)
 #define TEE_IMPL_ID_OPTEE 1
 #define TEE_OPTEE_CAP_TZ (1 << 0)
 struct tee_ioctl_version_data {
diff --git a/libc/kernel/uapi/linux/tls.h b/libc/kernel/uapi/linux/tls.h
new file mode 100644
index 0000000..73618e0
--- /dev/null
+++ b/libc/kernel/uapi/linux/tls.h
@@ -0,0 +1,51 @@
+/****************************************************************************
+ ****************************************************************************
+ ***
+ ***   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_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)
+#define TLS_VERSION_NUMBER(id) ((((id ##_VERSION_MAJOR) & 0xFF) << 8) | ((id ##_VERSION_MINOR) & 0xFF))
+#define TLS_1_2_VERSION_MAJOR 0x3
+#define TLS_1_2_VERSION_MINOR 0x3
+#define TLS_1_2_VERSION TLS_VERSION_NUMBER(TLS_1_2)
+#define TLS_CIPHER_AES_GCM_128 51
+#define TLS_CIPHER_AES_GCM_128_IV_SIZE 8
+#define TLS_CIPHER_AES_GCM_128_KEY_SIZE 16
+#define TLS_CIPHER_AES_GCM_128_SALT_SIZE 4
+#define TLS_CIPHER_AES_GCM_128_TAG_SIZE 16
+#define TLS_CIPHER_AES_GCM_128_REC_SEQ_SIZE 8
+#define TLS_SET_RECORD_TYPE 1
+struct tls_crypto_info {
+  __u16 version;
+  __u16 cipher_type;
+};
+struct tls12_crypto_info_aes_gcm_128 {
+  struct tls_crypto_info info;
+  unsigned char iv[TLS_CIPHER_AES_GCM_128_IV_SIZE];
+  unsigned char key[TLS_CIPHER_AES_GCM_128_KEY_SIZE];
+  unsigned char salt[TLS_CIPHER_AES_GCM_128_SALT_SIZE];
+  unsigned char rec_seq[TLS_CIPHER_AES_GCM_128_REC_SEQ_SIZE];
+};
+#endif
diff --git a/libc/kernel/uapi/linux/tty.h b/libc/kernel/uapi/linux/tty.h
index 9a09303..48fa908 100644
--- a/libc/kernel/uapi/linux/tty.h
+++ b/libc/kernel/uapi/linux/tty.h
@@ -45,4 +45,6 @@
 #define N_TRACESINK 23
 #define N_TRACEROUTER 24
 #define N_NCI 25
+#define N_SPEAKUP 26
+#define N_NULL 27
 #endif
diff --git a/libc/kernel/uapi/linux/usb/audio.h b/libc/kernel/uapi/linux/usb/audio.h
index 7f961fc..121c859 100644
--- a/libc/kernel/uapi/linux/usb/audio.h
+++ b/libc/kernel/uapi/linux/usb/audio.h
@@ -186,7 +186,7 @@
   __u8 bDescriptorType;
   __u8 bDescriptorSubtype;
   __u8 bUnitID;
-  __u16 wProcessType;
+  __le16 wProcessType;
   __u8 bNrInPins;
   __u8 baSourceID[];
 } __attribute__((packed));
@@ -260,8 +260,8 @@
   __u8 bDescriptorType;
   __u8 bDescriptorSubtype;
   __u8 bFormatType;
-  __u16 wMaxBitRate;
-  __u16 wSamplesPerFrame;
+  __le16 wMaxBitRate;
+  __le16 wSamplesPerFrame;
   __u8 bHeaderLength;
   __u8 bSideBandProtocol;
 } __attribute__((packed));
diff --git a/libc/kernel/uapi/linux/usb/ch9.h b/libc/kernel/uapi/linux/usb/ch9.h
index f06a970..38e7ae7 100644
--- a/libc/kernel/uapi/linux/usb/ch9.h
+++ b/libc/kernel/uapi/linux/usb/ch9.h
@@ -305,6 +305,7 @@
   __u8 bFunctionProtocol;
   __u8 iFunction;
 } __attribute__((packed));
+#define USB_DT_INTERFACE_ASSOCIATION_SIZE 8
 struct usb_security_descriptor {
   __u8 bLength;
   __u8 bDescriptorType;
diff --git a/libc/kernel/uapi/linux/wil6210_uapi.h b/libc/kernel/uapi/linux/usb/charger.h
similarity index 62%
copy from libc/kernel/uapi/linux/wil6210_uapi.h
copy to libc/kernel/uapi/linux/usb/charger.h
index e68b6c8..0810aab 100644
--- a/libc/kernel/uapi/linux/wil6210_uapi.h
+++ b/libc/kernel/uapi/linux/usb/charger.h
@@ -16,30 +16,18 @@
  ***
  ****************************************************************************
  ****************************************************************************/
-#ifndef __WIL6210_UAPI_H__
-#define __WIL6210_UAPI_H__
-#define __user
-#include <linux/sockios.h>
-#define WIL_IOCTL_MEMIO (SIOCDEVPRIVATE + 2)
-#define WIL_IOCTL_MEMIO_BLOCK (SIOCDEVPRIVATE + 3)
-enum wil_memio_op {
-  wil_mmio_read = 0,
-  wil_mmio_write = 1,
-  wil_mmio_op_mask = 0xff,
-  wil_mmio_addr_linker = 0 << 8,
-  wil_mmio_addr_ahb = 1 << 8,
-  wil_mmio_addr_bar = 2 << 8,
-  wil_mmio_addr_mask = 0xff00,
+#ifndef _UAPI__LINUX_USB_CHARGER_H
+#define _UAPI__LINUX_USB_CHARGER_H
+enum usb_charger_type {
+  UNKNOWN_TYPE,
+  SDP_TYPE,
+  DCP_TYPE,
+  CDP_TYPE,
+  ACA_TYPE,
 };
-struct wil_memio {
-  uint32_t op;
-  uint32_t addr;
-  uint32_t val;
-};
-struct wil_memio_block {
-  uint32_t op;
-  uint32_t addr;
-  uint32_t size;
-  void __user * block;
+enum usb_charger_state {
+  USB_CHARGER_DEFAULT,
+  USB_CHARGER_PRESENT,
+  USB_CHARGER_ABSENT,
 };
 #endif
diff --git a/libc/kernel/uapi/linux/usbdevice_fs.h b/libc/kernel/uapi/linux/usbdevice_fs.h
index 76b5f68..87afabe 100644
--- a/libc/kernel/uapi/linux/usbdevice_fs.h
+++ b/libc/kernel/uapi/linux/usbdevice_fs.h
@@ -147,4 +147,5 @@
 #define USBDEVFS_ALLOC_STREAMS _IOR('U', 28, struct usbdevfs_streams)
 #define USBDEVFS_FREE_STREAMS _IOR('U', 29, struct usbdevfs_streams)
 #define USBDEVFS_DROP_PRIVILEGES _IOW('U', 30, __u32)
+#define USBDEVFS_GET_SPEED _IO('U', 31)
 #endif
diff --git a/libc/kernel/uapi/linux/userfaultfd.h b/libc/kernel/uapi/linux/userfaultfd.h
index caa1eb4..ecc6302 100644
--- a/libc/kernel/uapi/linux/userfaultfd.h
+++ b/libc/kernel/uapi/linux/userfaultfd.h
@@ -20,7 +20,7 @@
 #define _LINUX_USERFAULTFD_H
 #include <linux/types.h>
 #define UFFD_API ((__u64) 0xAA)
-#define UFFD_API_FEATURES (UFFD_FEATURE_EVENT_FORK | UFFD_FEATURE_EVENT_REMAP | UFFD_FEATURE_EVENT_REMOVE | UFFD_FEATURE_EVENT_UNMAP | UFFD_FEATURE_MISSING_HUGETLBFS | UFFD_FEATURE_MISSING_SHMEM)
+#define UFFD_API_FEATURES (UFFD_FEATURE_EVENT_FORK | UFFD_FEATURE_EVENT_REMAP | UFFD_FEATURE_EVENT_REMOVE | UFFD_FEATURE_EVENT_UNMAP | UFFD_FEATURE_MISSING_HUGETLBFS | UFFD_FEATURE_MISSING_SHMEM | UFFD_FEATURE_SIGBUS | UFFD_FEATURE_THREAD_ID)
 #define UFFD_API_IOCTLS ((__u64) 1 << _UFFDIO_REGISTER | (__u64) 1 << _UFFDIO_UNREGISTER | (__u64) 1 << _UFFDIO_API)
 #define UFFD_API_RANGE_IOCTLS ((__u64) 1 << _UFFDIO_WAKE | (__u64) 1 << _UFFDIO_COPY | (__u64) 1 << _UFFDIO_ZEROPAGE)
 #define UFFD_API_RANGE_IOCTLS_BASIC ((__u64) 1 << _UFFDIO_WAKE | (__u64) 1 << _UFFDIO_COPY)
@@ -46,6 +46,9 @@
     struct {
       __u64 flags;
       __u64 address;
+      union {
+        __u32 ptid;
+      } feat;
     } pagefault;
     struct {
       __u32 ufd;
@@ -82,6 +85,8 @@
 #define UFFD_FEATURE_MISSING_HUGETLBFS (1 << 4)
 #define UFFD_FEATURE_MISSING_SHMEM (1 << 5)
 #define UFFD_FEATURE_EVENT_UNMAP (1 << 6)
+#define UFFD_FEATURE_SIGBUS (1 << 7)
+#define UFFD_FEATURE_THREAD_ID (1 << 8)
   __u64 features;
   __u64 ioctls;
 };
diff --git a/libc/kernel/uapi/linux/uuid.h b/libc/kernel/uapi/linux/uuid.h
index c48b6d3..808578f 100644
--- a/libc/kernel/uapi/linux/uuid.h
+++ b/libc/kernel/uapi/linux/uuid.h
@@ -22,16 +22,11 @@
 #include <linux/string.h>
 typedef struct {
   __u8 b[16];
-} uuid_le;
-typedef struct {
-  __u8 b[16];
-} uuid_be;
-#define UUID_LE(a,b,c,d0,d1,d2,d3,d4,d5,d6,d7) \
-((uuid_le) \
+} guid_t;
+#define GUID_INIT(a,b,c,d0,d1,d2,d3,d4,d5,d6,d7) \
+((guid_t) \
 { { (a) & 0xff, ((a) >> 8) & 0xff, ((a) >> 16) & 0xff, ((a) >> 24) & 0xff, (b) & 0xff, ((b) >> 8) & 0xff, (c) & 0xff, ((c) >> 8) & 0xff, (d0), (d1), (d2), (d3), (d4), (d5), (d6), (d7) } })
-#define UUID_BE(a,b,c,d0,d1,d2,d3,d4,d5,d6,d7) \
-((uuid_be) \
-{ { ((a) >> 24) & 0xff, ((a) >> 16) & 0xff, ((a) >> 8) & 0xff, (a) & 0xff, ((b) >> 8) & 0xff, (b) & 0xff, ((c) >> 8) & 0xff, (c) & 0xff, (d0), (d1), (d2), (d3), (d4), (d5), (d6), (d7) } })
+typedef guid_t uuid_le;
+#define UUID_LE(a,b,c,d0,d1,d2,d3,d4,d5,d6,d7) GUID_INIT(a, b, c, d0, d1, d2, d3, d4, d5, d6, d7)
 #define NULL_UUID_LE UUID_LE(0x00000000, 0x0000, 0x0000, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00)
-#define NULL_UUID_BE UUID_BE(0x00000000, 0x0000, 0x0000, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00)
 #endif
diff --git a/libc/kernel/uapi/linux/v4l2-controls.h b/libc/kernel/uapi/linux/v4l2-controls.h
index 8b69770..302da8f 100644
--- a/libc/kernel/uapi/linux/v4l2-controls.h
+++ b/libc/kernel/uapi/linux/v4l2-controls.h
@@ -107,6 +107,8 @@
 #define V4L2_CID_USER_SAA7134_BASE (V4L2_CID_USER_BASE + 0x1060)
 #define V4L2_CID_USER_ADV7180_BASE (V4L2_CID_USER_BASE + 0x1070)
 #define V4L2_CID_USER_TC358743_BASE (V4L2_CID_USER_BASE + 0x1080)
+#define V4L2_CID_USER_MAX217X_BASE (V4L2_CID_USER_BASE + 0x1090)
+#define V4L2_CID_USER_IMX_BASE (V4L2_CID_USER_BASE + 0x1090)
 #define V4L2_CID_MPEG_BASE (V4L2_CTRL_CLASS_MPEG | 0x900)
 #define V4L2_CID_MPEG_CLASS (V4L2_CTRL_CLASS_MPEG | 1)
 #define V4L2_CID_MPEG_STREAM_TYPE (V4L2_CID_MPEG_BASE + 0)
@@ -744,6 +746,7 @@
 #define V4L2_CID_PIXEL_RATE (V4L2_CID_IMAGE_PROC_CLASS_BASE + 2)
 #define V4L2_CID_TEST_PATTERN (V4L2_CID_IMAGE_PROC_CLASS_BASE + 3)
 #define V4L2_CID_DEINTERLACING_MODE (V4L2_CID_IMAGE_PROC_CLASS_BASE + 4)
+#define V4L2_CID_DIGITAL_GAIN (V4L2_CID_IMAGE_PROC_CLASS_BASE + 5)
 #define V4L2_CID_DV_CLASS_BASE (V4L2_CTRL_CLASS_DV | 0x900)
 #define V4L2_CID_DV_CLASS (V4L2_CTRL_CLASS_DV | 1)
 #define V4L2_CID_DV_TX_HOTPLUG (V4L2_CID_DV_CLASS_BASE + 1)
diff --git a/libc/kernel/uapi/linux/version.h b/libc/kernel/uapi/linux/version.h
index 73eb988..7714cb7 100644
--- a/libc/kernel/uapi/linux/version.h
+++ b/libc/kernel/uapi/linux/version.h
@@ -16,5 +16,5 @@
  ***
  ****************************************************************************
  ****************************************************************************/
-#define LINUX_VERSION_CODE 265219
+#define LINUX_VERSION_CODE 265728
 #define KERNEL_VERSION(a,b,c) (((a) << 16) + ((b) << 8) + (c))
diff --git a/libc/kernel/uapi/linux/videodev2.h b/libc/kernel/uapi/linux/videodev2.h
index 25e2fe8..c350108 100644
--- a/libc/kernel/uapi/linux/videodev2.h
+++ b/libc/kernel/uapi/linux/videodev2.h
@@ -288,6 +288,10 @@
 #define V4L2_PIX_FMT_SGBRG12 v4l2_fourcc('G', 'B', '1', '2')
 #define V4L2_PIX_FMT_SGRBG12 v4l2_fourcc('B', 'A', '1', '2')
 #define V4L2_PIX_FMT_SRGGB12 v4l2_fourcc('R', 'G', '1', '2')
+#define V4L2_PIX_FMT_SBGGR12P v4l2_fourcc('p', 'B', 'C', 'C')
+#define V4L2_PIX_FMT_SGBRG12P v4l2_fourcc('p', 'G', 'C', 'C')
+#define V4L2_PIX_FMT_SGRBG12P v4l2_fourcc('p', 'g', 'C', 'C')
+#define V4L2_PIX_FMT_SRGGB12P v4l2_fourcc('p', 'R', 'C', 'C')
 #define V4L2_PIX_FMT_SBGGR16 v4l2_fourcc('B', 'Y', 'R', '2')
 #define V4L2_PIX_FMT_SGBRG16 v4l2_fourcc('G', 'B', '1', '6')
 #define V4L2_PIX_FMT_SGRBG16 v4l2_fourcc('G', 'R', '1', '6')
@@ -346,6 +350,9 @@
 #define V4L2_SDR_FMT_CS8 v4l2_fourcc('C', 'S', '0', '8')
 #define V4L2_SDR_FMT_CS14LE v4l2_fourcc('C', 'S', '1', '4')
 #define V4L2_SDR_FMT_RU12LE v4l2_fourcc('R', 'U', '1', '2')
+#define V4L2_SDR_FMT_PCU16BE v4l2_fourcc('P', 'C', '1', '6')
+#define V4L2_SDR_FMT_PCU18BE v4l2_fourcc('P', 'C', '1', '8')
+#define V4L2_SDR_FMT_PCU20BE v4l2_fourcc('P', 'C', '2', '0')
 #define V4L2_TCH_FMT_DELTA_TD16 v4l2_fourcc('T', 'D', '1', '6')
 #define V4L2_TCH_FMT_DELTA_TD08 v4l2_fourcc('T', 'D', '0', '8')
 #define V4L2_TCH_FMT_TU16 v4l2_fourcc('T', 'U', '1', '6')
diff --git a/libc/kernel/uapi/linux/vtpm_proxy.h b/libc/kernel/uapi/linux/vtpm_proxy.h
index 15e39f2..0ab0536 100644
--- a/libc/kernel/uapi/linux/vtpm_proxy.h
+++ b/libc/kernel/uapi/linux/vtpm_proxy.h
@@ -31,4 +31,6 @@
   __u32 minor;
 };
 #define VTPM_PROXY_IOC_NEW_DEV _IOWR(0xa1, 0x00, struct vtpm_proxy_new_dev)
+#define TPM2_CC_SET_LOCALITY 0x20001000
+#define TPM_ORD_SET_LOCALITY 0x20001000
 #endif
diff --git a/libc/kernel/uapi/linux/xfrm.h b/libc/kernel/uapi/linux/xfrm.h
index 4ff9bea..5ec7193 100644
--- a/libc/kernel/uapi/linux/xfrm.h
+++ b/libc/kernel/uapi/linux/xfrm.h
@@ -258,6 +258,7 @@
   XFRMA_ADDRESS_FILTER,
   XFRMA_PAD,
   XFRMA_OFFLOAD_DEV,
+  XFRMA_OUTPUT_MARK,
   __XFRMA_MAX
 #define XFRMA_MAX (__XFRMA_MAX - 1)
 };
diff --git a/libc/kernel/uapi/rdma/ib_user_ioctl_verbs.h b/libc/kernel/uapi/rdma/ib_user_ioctl_verbs.h
new file mode 100644
index 0000000..766fe4c
--- /dev/null
+++ b/libc/kernel/uapi/rdma/ib_user_ioctl_verbs.h
@@ -0,0 +1,61 @@
+/****************************************************************************
+ ****************************************************************************
+ ***
+ ***   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 IB_USER_IOCTL_VERBS_H
+#define IB_USER_IOCTL_VERBS_H
+#include <rdma/rdma_user_ioctl.h>
+#define UVERBS_UDATA_DRIVER_DATA_NS 1
+#define UVERBS_UDATA_DRIVER_DATA_FLAG (1UL << UVERBS_ID_NS_SHIFT)
+enum uverbs_default_objects {
+  UVERBS_OBJECT_DEVICE,
+  UVERBS_OBJECT_PD,
+  UVERBS_OBJECT_COMP_CHANNEL,
+  UVERBS_OBJECT_CQ,
+  UVERBS_OBJECT_QP,
+  UVERBS_OBJECT_SRQ,
+  UVERBS_OBJECT_AH,
+  UVERBS_OBJECT_MR,
+  UVERBS_OBJECT_MW,
+  UVERBS_OBJECT_FLOW,
+  UVERBS_OBJECT_XRCD,
+  UVERBS_OBJECT_RWQ_IND_TBL,
+  UVERBS_OBJECT_WQ,
+  UVERBS_OBJECT_LAST,
+};
+enum {
+  UVERBS_UHW_IN = UVERBS_UDATA_DRIVER_DATA_FLAG,
+  UVERBS_UHW_OUT,
+};
+enum uverbs_create_cq_cmd_attr_ids {
+  CREATE_CQ_HANDLE,
+  CREATE_CQ_CQE,
+  CREATE_CQ_USER_HANDLE,
+  CREATE_CQ_COMP_CHANNEL,
+  CREATE_CQ_COMP_VECTOR,
+  CREATE_CQ_FLAGS,
+  CREATE_CQ_RESP_CQE,
+};
+enum uverbs_destroy_cq_cmd_attr_ids {
+  DESTROY_CQ_HANDLE,
+  DESTROY_CQ_RESP,
+};
+enum uverbs_actions_cq_ops {
+  UVERBS_CQ_CREATE,
+  UVERBS_CQ_DESTROY,
+};
+#endif
diff --git a/libc/kernel/uapi/rdma/ib_user_verbs.h b/libc/kernel/uapi/rdma/ib_user_verbs.h
index 4feb031..ff3ebcb 100644
--- a/libc/kernel/uapi/rdma/ib_user_verbs.h
+++ b/libc/kernel/uapi/rdma/ib_user_verbs.h
@@ -174,6 +174,14 @@
   __u32 max_rwq_indirection_table_size;
   __u32 reserved;
 };
+struct ib_uverbs_tm_caps {
+  __u32 max_rndv_hdr_size;
+  __u32 max_num_tags;
+  __u32 flags;
+  __u32 max_ops;
+  __u32 max_sge;
+  __u32 reserved;
+};
 struct ib_uverbs_ex_query_device_resp {
   struct ib_uverbs_query_device_resp base;
   __u32 comp_mask;
@@ -185,6 +193,7 @@
   struct ib_uverbs_rss_caps rss_caps;
   __u32 max_wq_type_rq;
   __u32 raw_packet_caps;
+  struct ib_uverbs_tm_caps tm_caps;
 };
 struct ib_uverbs_query_port {
   __u64 response;
@@ -467,7 +476,7 @@
   __u32 comp_mask;
   __u32 create_flags;
   __u32 rwq_ind_tbl_handle;
-  __u32 reserved1;
+  __u32 source_qpn;
 };
 struct ib_uverbs_open_qp {
   __u64 response;
@@ -852,7 +861,7 @@
   __u32 max_wr;
   __u32 max_sge;
   __u32 srq_limit;
-  __u32 reserved;
+  __u32 max_num_tags;
   __u32 xrcd_handle;
   __u32 cq_handle;
   __u64 driver_data[0];
diff --git a/libc/kernel/uapi/rdma/mlx4-abi.h b/libc/kernel/uapi/rdma/mlx4-abi.h
index 232d835..078b386 100644
--- a/libc/kernel/uapi/rdma/mlx4-abi.h
+++ b/libc/kernel/uapi/rdma/mlx4-abi.h
@@ -56,12 +56,49 @@
   __u32 srqn;
   __u32 reserved;
 };
+struct mlx4_ib_create_qp_rss {
+  __u64 rx_hash_fields_mask;
+  __u8 rx_hash_function;
+  __u8 reserved[7];
+  __u8 rx_hash_key[40];
+  __u32 comp_mask;
+  __u32 reserved1;
+};
 struct mlx4_ib_create_qp {
   __u64 buf_addr;
   __u64 db_addr;
   __u8 log_sq_bb_count;
   __u8 log_sq_stride;
   __u8 sq_no_prefetch;
-  __u8 reserved[5];
+  __u8 reserved;
+  __u32 inl_recv_sz;
+};
+struct mlx4_ib_create_wq {
+  __u64 buf_addr;
+  __u64 db_addr;
+  __u8 log_range_size;
+  __u8 reserved[3];
+  __u32 comp_mask;
+};
+struct mlx4_ib_modify_wq {
+  __u32 comp_mask;
+  __u32 reserved;
+};
+struct mlx4_ib_create_rwq_ind_tbl_resp {
+  __u32 response_length;
+  __u32 reserved;
+};
+enum mlx4_ib_rx_hash_function_flags {
+  MLX4_IB_RX_HASH_FUNC_TOEPLITZ = 1 << 0,
+};
+enum mlx4_ib_rx_hash_fields {
+  MLX4_IB_RX_HASH_SRC_IPV4 = 1 << 0,
+  MLX4_IB_RX_HASH_DST_IPV4 = 1 << 1,
+  MLX4_IB_RX_HASH_SRC_IPV6 = 1 << 2,
+  MLX4_IB_RX_HASH_DST_IPV6 = 1 << 3,
+  MLX4_IB_RX_HASH_SRC_PORT_TCP = 1 << 4,
+  MLX4_IB_RX_HASH_DST_PORT_TCP = 1 << 5,
+  MLX4_IB_RX_HASH_SRC_PORT_UDP = 1 << 6,
+  MLX4_IB_RX_HASH_DST_PORT_UDP = 1 << 7
 };
 #endif
diff --git a/libc/kernel/uapi/rdma/mlx5-abi.h b/libc/kernel/uapi/rdma/mlx5-abi.h
index 6e76a3d..b51ff4e 100644
--- a/libc/kernel/uapi/rdma/mlx5-abi.h
+++ b/libc/kernel/uapi/rdma/mlx5-abi.h
@@ -112,6 +112,20 @@
   __u32 supported_qpts;
   __u32 reserved;
 };
+enum mlx5_ib_mpw_caps {
+  MPW_RESERVED = 1 << 0,
+  MLX5_IB_ALLOW_MPW = 1 << 1,
+  MLX5_IB_SUPPORT_EMPW = 1 << 2,
+};
+enum mlx5_ib_sw_parsing_offloads {
+  MLX5_IB_SW_PARSING = 1 << 0,
+  MLX5_IB_SW_PARSING_CSUM = 1 << 1,
+  MLX5_IB_SW_PARSING_LSO = 1 << 2,
+};
+struct mlx5_ib_sw_parsing_caps {
+  __u32 sw_parsing_offloads;
+  __u32 supported_qpts;
+};
 struct mlx5_ib_query_device_resp {
   __u32 comp_mask;
   __u32 response_length;
@@ -121,6 +135,7 @@
   struct mlx5_packet_pacing_caps packet_pacing_caps;
   __u32 mlx5_ib_support_multi_pkt_send_wqes;
   __u32 reserved;
+  struct mlx5_ib_sw_parsing_caps sw_parsing_caps;
 };
 struct mlx5_ib_create_cq {
   __u64 buf_addr;
diff --git a/libc/kernel/uapi/rdma/qedr-abi.h b/libc/kernel/uapi/rdma/qedr-abi.h
index 597391f..55af44b 100644
--- a/libc/kernel/uapi/rdma/qedr-abi.h
+++ b/libc/kernel/uapi/rdma/qedr-abi.h
@@ -30,6 +30,9 @@
   __u32 sges_per_recv_wr;
   __u32 sges_per_srq_wr;
   __u32 max_cqes;
+  __u8 dpm_enabled;
+  __u8 wids_enabled;
+  __u16 wid_count;
 };
 struct qedr_alloc_pd_ureq {
   __u64 rsvd1;
diff --git a/libc/kernel/uapi/rdma/rdma_netlink.h b/libc/kernel/uapi/rdma/rdma_netlink.h
index ae261d7..c7bcb6d 100644
--- a/libc/kernel/uapi/rdma/rdma_netlink.h
+++ b/libc/kernel/uapi/rdma/rdma_netlink.h
@@ -24,7 +24,7 @@
   RDMA_NL_IWCM,
   RDMA_NL_RSVD,
   RDMA_NL_LS,
-  RDMA_NL_I40IW,
+  RDMA_NL_NLDEV,
   RDMA_NL_NUM_CLIENTS
 };
 enum {
@@ -170,4 +170,34 @@
 struct rdma_nla_ls_gid {
   __u8 gid[16];
 };
+enum rdma_nldev_command {
+  RDMA_NLDEV_CMD_UNSPEC,
+  RDMA_NLDEV_CMD_GET,
+  RDMA_NLDEV_CMD_SET,
+  RDMA_NLDEV_CMD_NEW,
+  RDMA_NLDEV_CMD_DEL,
+  RDMA_NLDEV_CMD_PORT_GET,
+  RDMA_NLDEV_CMD_PORT_SET,
+  RDMA_NLDEV_CMD_PORT_NEW,
+  RDMA_NLDEV_CMD_PORT_DEL,
+  RDMA_NLDEV_NUM_OPS
+};
+enum rdma_nldev_attr {
+  RDMA_NLDEV_ATTR_UNSPEC,
+  RDMA_NLDEV_ATTR_DEV_INDEX,
+  RDMA_NLDEV_ATTR_DEV_NAME,
+  RDMA_NLDEV_ATTR_PORT_INDEX,
+  RDMA_NLDEV_ATTR_CAP_FLAGS,
+  RDMA_NLDEV_ATTR_FW_VERSION,
+  RDMA_NLDEV_ATTR_NODE_GUID,
+  RDMA_NLDEV_ATTR_SYS_IMAGE_GUID,
+  RDMA_NLDEV_ATTR_SUBNET_PREFIX,
+  RDMA_NLDEV_ATTR_LID,
+  RDMA_NLDEV_ATTR_SM_LID,
+  RDMA_NLDEV_ATTR_LMC,
+  RDMA_NLDEV_ATTR_PORT_STATE,
+  RDMA_NLDEV_ATTR_PORT_PHYS_STATE,
+  RDMA_NLDEV_ATTR_DEV_NODE_TYPE,
+  RDMA_NLDEV_ATTR_MAX
+};
 #endif
diff --git a/libc/kernel/uapi/rdma/rdma_user_ioctl.h b/libc/kernel/uapi/rdma/rdma_user_ioctl.h
index bb65c5d..41c11bc 100644
--- a/libc/kernel/uapi/rdma/rdma_user_ioctl.h
+++ b/libc/kernel/uapi/rdma/rdma_user_ioctl.h
@@ -24,6 +24,28 @@
 #include <rdma/hfi/hfi1_ioctl.h>
 #define RDMA_IOCTL_MAGIC 0x1b
 #define IB_IOCTL_MAGIC RDMA_IOCTL_MAGIC
+#define RDMA_VERBS_IOCTL _IOWR(RDMA_IOCTL_MAGIC, 1, struct ib_uverbs_ioctl_hdr)
+#define UVERBS_ID_NS_MASK 0xF000
+#define UVERBS_ID_NS_SHIFT 12
+enum {
+  UVERBS_ATTR_F_MANDATORY = 1U << 0,
+  UVERBS_ATTR_F_VALID_OUTPUT = 1U << 1,
+};
+struct ib_uverbs_attr {
+  __u16 attr_id;
+  __u16 len;
+  __u16 flags;
+  __u16 reserved;
+  __u64 data;
+};
+struct ib_uverbs_ioctl_hdr {
+  __u16 length;
+  __u16 object_id;
+  __u16 method_id;
+  __u16 num_attrs;
+  __u64 reserved;
+  struct ib_uverbs_attr attrs[0];
+};
 #define IB_USER_MAD_REGISTER_AGENT _IOWR(RDMA_IOCTL_MAGIC, 0x01, struct ib_user_mad_reg_req)
 #define IB_USER_MAD_UNREGISTER_AGENT _IOW(RDMA_IOCTL_MAGIC, 0x02, __u32)
 #define IB_USER_MAD_ENABLE_PKEY _IO(RDMA_IOCTL_MAGIC, 0x03)
diff --git a/libc/kernel/uapi/rdma/vmw_pvrdma-abi.h b/libc/kernel/uapi/rdma/vmw_pvrdma-abi.h
index 3666815..2062366 100644
--- a/libc/kernel/uapi/rdma/vmw_pvrdma-abi.h
+++ b/libc/kernel/uapi/rdma/vmw_pvrdma-abi.h
@@ -92,7 +92,8 @@
   PVRDMA_WC_IP_CSUM_OK = 1 << 3,
   PVRDMA_WC_WITH_SMAC = 1 << 4,
   PVRDMA_WC_WITH_VLAN = 1 << 5,
-  PVRDMA_WC_FLAGS_MAX = PVRDMA_WC_WITH_VLAN,
+  PVRDMA_WC_WITH_NETWORK_HDR_TYPE = 1 << 6,
+  PVRDMA_WC_FLAGS_MAX = PVRDMA_WC_WITH_NETWORK_HDR_TYPE,
 };
 struct pvrdma_alloc_ucontext_resp {
   __u32 qp_tab_size;
@@ -226,6 +227,7 @@
   __u8 dlid_path_bits;
   __u8 port_num;
   __u8 smac[6];
-  __u8 reserved2[7];
+  __u8 network_hdr_type;
+  __u8 reserved2[6];
 };
 #endif
diff --git a/libc/kernel/uapi/scsi/cxlflash_ioctl.h b/libc/kernel/uapi/scsi/cxlflash_ioctl.h
index 91ffe62..9781905 100644
--- a/libc/kernel/uapi/scsi/cxlflash_ioctl.h
+++ b/libc/kernel/uapi/scsi/cxlflash_ioctl.h
@@ -19,6 +19,7 @@
 #ifndef _CXLFLASH_IOCTL_H
 #define _CXLFLASH_IOCTL_H
 #include <linux/types.h>
+#define CXLFLASH_WWID_LEN 16
 #define DK_CXLFLASH_VERSION_0 0
 struct dk_cxlflash_hdr {
   __u16 version;
@@ -104,7 +105,7 @@
   __u64 adap_fd;
   __u64 reserved[8];
 };
-#define DK_CXLFLASH_MANAGE_LUN_WWID_LEN 16
+#define DK_CXLFLASH_MANAGE_LUN_WWID_LEN CXLFLASH_WWID_LEN
 #define DK_CXLFLASH_MANAGE_LUN_ENABLE_SUPERPIPE 0x8000000000000000ULL
 #define DK_CXLFLASH_MANAGE_LUN_DISABLE_SUPERPIPE 0x4000000000000000ULL
 #define DK_CXLFLASH_MANAGE_LUN_ALL_PORTS_ACCESSIBLE 0x2000000000000000ULL
@@ -138,4 +139,48 @@
 #define DK_CXLFLASH_USER_VIRTUAL CXL_IOWR(0x87, dk_cxlflash_uvirtual)
 #define DK_CXLFLASH_VLUN_RESIZE CXL_IOWR(0x88, dk_cxlflash_resize)
 #define DK_CXLFLASH_VLUN_CLONE CXL_IOWR(0x89, dk_cxlflash_clone)
+#define HT_CXLFLASH_VERSION_0 0
+struct ht_cxlflash_hdr {
+  __u16 version;
+  __u16 subcmd;
+  __u16 rsvd[2];
+  __u64 flags;
+  __u64 return_flags;
+};
+#define HT_CXLFLASH_HOST_READ 0x0000000000000000ULL
+#define HT_CXLFLASH_HOST_WRITE 0x0000000000000001ULL
+#define HT_CXLFLASH_LUN_PROVISION_SUBCMD_CREATE_LUN 0x0001
+#define HT_CXLFLASH_LUN_PROVISION_SUBCMD_DELETE_LUN 0x0002
+#define HT_CXLFLASH_LUN_PROVISION_SUBCMD_QUERY_PORT 0x0003
+struct ht_cxlflash_lun_provision {
+  struct ht_cxlflash_hdr hdr;
+  __u16 port;
+  __u16 reserved16[3];
+  __u64 size;
+  __u64 lun_id;
+  __u8 wwid[CXLFLASH_WWID_LEN];
+  __u64 max_num_luns;
+  __u64 cur_num_luns;
+  __u64 max_cap_port;
+  __u64 cur_cap_port;
+  __u64 reserved[8];
+};
+#define HT_CXLFLASH_AFU_DEBUG_MAX_DATA_LEN 262144
+#define HT_CXLFLASH_AFU_DEBUG_SUBCMD_LEN 12
+struct ht_cxlflash_afu_debug {
+  struct ht_cxlflash_hdr hdr;
+  __u8 reserved8[4];
+  __u8 afu_subcmd[HT_CXLFLASH_AFU_DEBUG_SUBCMD_LEN];
+  __u64 data_ea;
+  __u32 data_len;
+  __u32 reserved32;
+  __u64 reserved[8];
+};
+union cxlflash_ht_ioctls {
+  struct ht_cxlflash_lun_provision lun_provision;
+  struct ht_cxlflash_afu_debug afu_debug;
+};
+#define MAX_HT_CXLFLASH_IOCTL_SZ (sizeof(union cxlflash_ht_ioctls))
+#define HT_CXLFLASH_LUN_PROVISION CXL_IOWR(0xBF, ht_cxlflash_lun_provision)
+#define HT_CXLFLASH_AFU_DEBUG CXL_IOWR(0xBE, ht_cxlflash_afu_debug)
 #endif
diff --git a/libc/kernel/uapi/sound/asoc.h b/libc/kernel/uapi/sound/asoc.h
index 35e1b15..d0bab8b 100644
--- a/libc/kernel/uapi/sound/asoc.h
+++ b/libc/kernel/uapi/sound/asoc.h
@@ -53,7 +53,15 @@
 #define SND_SOC_TPLG_DAPM_DAI_IN 13
 #define SND_SOC_TPLG_DAPM_DAI_OUT 14
 #define SND_SOC_TPLG_DAPM_DAI_LINK 15
-#define SND_SOC_TPLG_DAPM_LAST SND_SOC_TPLG_DAPM_DAI_LINK
+#define SND_SOC_TPLG_DAPM_BUFFER 16
+#define SND_SOC_TPLG_DAPM_SCHEDULER 17
+#define SND_SOC_TPLG_DAPM_EFFECT 18
+#define SND_SOC_TPLG_DAPM_SIGGEN 19
+#define SND_SOC_TPLG_DAPM_SRC 20
+#define SND_SOC_TPLG_DAPM_ASRC 21
+#define SND_SOC_TPLG_DAPM_ENCODER 22
+#define SND_SOC_TPLG_DAPM_DECODER 23
+#define SND_SOC_TPLG_DAPM_LAST SND_SOC_TPLG_DAPM_DECODER
 #define SND_SOC_TPLG_MAGIC 0x41536F43
 #define SND_SOC_TPLG_NUM_TEXTS 16
 #define SND_SOC_TPLG_ABI_VERSION 0x5
diff --git a/libc/kernel/uapi/sound/asound.h b/libc/kernel/uapi/sound/asound.h
index e3041ce..63f66b4 100644
--- a/libc/kernel/uapi/sound/asound.h
+++ b/libc/kernel/uapi/sound/asound.h
@@ -100,7 +100,7 @@
 #define SNDRV_HWDEP_IOCTL_INFO _IOR('H', 0x01, struct snd_hwdep_info)
 #define SNDRV_HWDEP_IOCTL_DSP_STATUS _IOR('H', 0x02, struct snd_hwdep_dsp_status)
 #define SNDRV_HWDEP_IOCTL_DSP_LOAD _IOW('H', 0x03, struct snd_hwdep_dsp_image)
-#define SNDRV_PCM_VERSION SNDRV_PROTOCOL_VERSION(2, 0, 13)
+#define SNDRV_PCM_VERSION SNDRV_PROTOCOL_VERSION(2, 0, 14)
 typedef unsigned long snd_pcm_uframes_t;
 typedef signed long snd_pcm_sframes_t;
 enum {
@@ -205,6 +205,7 @@
 #define SNDRV_PCM_INFO_MMAP_VALID 0x00000002
 #define SNDRV_PCM_INFO_DOUBLE 0x00000004
 #define SNDRV_PCM_INFO_BATCH 0x00000010
+#define SNDRV_PCM_INFO_SYNC_APPLPTR 0x00000020
 #define SNDRV_PCM_INFO_INTERLEAVED 0x00000100
 #define SNDRV_PCM_INFO_NONINTERLEAVED 0x00000200
 #define SNDRV_PCM_INFO_COMPLEX 0x00000400
@@ -446,6 +447,7 @@
 #define SNDRV_PCM_IOCTL_INFO _IOR('A', 0x01, struct snd_pcm_info)
 #define SNDRV_PCM_IOCTL_TSTAMP _IOW('A', 0x02, int)
 #define SNDRV_PCM_IOCTL_TTSTAMP _IOW('A', 0x03, int)
+#define SNDRV_PCM_IOCTL_USER_PVERSION _IOW('A', 0x04, int)
 #define SNDRV_PCM_IOCTL_HW_REFINE _IOWR('A', 0x10, struct snd_pcm_hw_params)
 #define SNDRV_PCM_IOCTL_HW_PARAMS _IOWR('A', 0x11, struct snd_pcm_hw_params)
 #define SNDRV_PCM_IOCTL_HW_FREE _IO('A', 0x12)
diff --git a/libc/kernel/uapi/sound/snd_sst_tokens.h b/libc/kernel/uapi/sound/snd_sst_tokens.h
index 13ae705..a4cfdd5 100644
--- a/libc/kernel/uapi/sound/snd_sst_tokens.h
+++ b/libc/kernel/uapi/sound/snd_sst_tokens.h
@@ -68,6 +68,31 @@
   SKL_TKN_STR_LIB_NAME,
   SKL_TKN_U32_PMODE,
   SKL_TKL_U32_D0I3_CAPS,
-  SKL_TKN_MAX = SKL_TKL_U32_D0I3_CAPS,
+  SKL_TKN_U32_D0I3_CAPS = SKL_TKL_U32_D0I3_CAPS,
+  SKL_TKN_U32_DMA_BUF_SIZE,
+  SKL_TKN_U32_PIPE_DIRECTION,
+  SKL_TKN_U32_PIPE_CONFIG_ID,
+  SKL_TKN_U32_NUM_CONFIGS,
+  SKL_TKN_U32_PATH_MEM_PGS,
+  SKL_TKN_U32_CFG_FREQ,
+  SKL_TKN_U8_CFG_CHAN,
+  SKL_TKN_U8_CFG_BPS,
+  SKL_TKN_CFG_MOD_RES_ID,
+  SKL_TKN_CFG_MOD_FMT_ID,
+  SKL_TKN_U8_NUM_MOD,
+  SKL_TKN_MM_U8_MOD_IDX,
+  SKL_TKN_MM_U8_NUM_RES,
+  SKL_TKN_MM_U8_NUM_INTF,
+  SKL_TKN_MM_U32_RES_ID,
+  SKL_TKN_MM_U32_CPS,
+  SKL_TKN_MM_U32_DMA_SIZE,
+  SKL_TKN_MM_U32_CPC,
+  SKL_TKN_MM_U32_RES_PIN_ID,
+  SKL_TKN_MM_U32_INTF_PIN_ID,
+  SKL_TKN_MM_U32_PIN_BUF,
+  SKL_TKN_MM_U32_FMT_ID,
+  SKL_TKN_MM_U32_NUM_IN_FMT,
+  SKL_TKN_MM_U32_NUM_OUT_FMT,
+  SKL_TKN_MAX = SKL_TKN_MM_U32_NUM_OUT_FMT,
 };
 #endif
diff --git a/libc/libc.arm.map b/libc/libc.arm.map
index 5018951..abab364 100644
--- a/libc/libc.arm.map
+++ b/libc/libc.arm.map
@@ -1318,21 +1318,66 @@
     wctrans_l; # introduced=26
 } LIBC_N;
 
-LIBC_P {
+LIBC_P { # introduced=P
   global:
-    __freading; # future
-    __fwriting; # future
-    getlogin_r; # future
-    hcreate; # future
-    hcreate_r; # future
-    hdestroy; # future
-    hdestroy_r; # future
-    hsearch; # future
-    hsearch_r; # future
-    iconv; # future
-    iconv_close; # future
-    iconv_open; # future
-    syncfs; # future
+    __freading;
+    __fwriting;
+    endhostent;
+    endnetent;
+    endprotoent;
+    fexecve;
+    fflush_unlocked;
+    fgetc_unlocked;
+    fgets_unlocked;
+    fputc_unlocked;
+    fputs_unlocked;
+    fread_unlocked;
+    fwrite_unlocked;
+    getentropy;
+    getnetent;
+    getprotoent;
+    getrandom;
+    getlogin_r;
+    glob;
+    globfree;
+    hcreate;
+    hcreate_r;
+    hdestroy;
+    hdestroy_r;
+    hsearch;
+    hsearch_r;
+    iconv;
+    iconv_close;
+    iconv_open;
+    posix_spawn;
+    posix_spawnattr_destroy;
+    posix_spawnattr_getflags;
+    posix_spawnattr_getpgroup;
+    posix_spawnattr_getschedparam;
+    posix_spawnattr_getschedpolicy;
+    posix_spawnattr_getsigdefault;
+    posix_spawnattr_getsigmask;
+    posix_spawnattr_init;
+    posix_spawnattr_setflags;
+    posix_spawnattr_setpgroup;
+    posix_spawnattr_setschedparam;
+    posix_spawnattr_setschedpolicy;
+    posix_spawnattr_setsigdefault;
+    posix_spawnattr_setsigmask;
+    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;
+    pthread_attr_getinheritsched;
+    pthread_attr_setinheritsched;
+    pthread_setschedprio;
+    sethostent;
+    setnetent;
+    setprotoent;
+    swab;
+    syncfs;
 } LIBC_O;
 
 LIBC_PRIVATE {
diff --git a/libc/libc.arm64.map b/libc/libc.arm64.map
index 4ea5896..d464a0c 100644
--- a/libc/libc.arm64.map
+++ b/libc/libc.arm64.map
@@ -1238,21 +1238,66 @@
     wctrans_l; # introduced=26
 } LIBC_N;
 
-LIBC_P {
+LIBC_P { # introduced=P
   global:
-    __freading; # future
-    __fwriting; # future
-    getlogin_r; # future
-    hcreate; # future
-    hcreate_r; # future
-    hdestroy; # future
-    hdestroy_r; # future
-    hsearch; # future
-    hsearch_r; # future
-    iconv; # future
-    iconv_close; # future
-    iconv_open; # future
-    syncfs; # future
+    __freading;
+    __fwriting;
+    endhostent;
+    endnetent;
+    endprotoent;
+    fexecve;
+    fflush_unlocked;
+    fgetc_unlocked;
+    fgets_unlocked;
+    fputc_unlocked;
+    fputs_unlocked;
+    fread_unlocked;
+    fwrite_unlocked;
+    getentropy;
+    getnetent;
+    getprotoent;
+    getrandom;
+    getlogin_r;
+    glob;
+    globfree;
+    hcreate;
+    hcreate_r;
+    hdestroy;
+    hdestroy_r;
+    hsearch;
+    hsearch_r;
+    iconv;
+    iconv_close;
+    iconv_open;
+    posix_spawn;
+    posix_spawnattr_destroy;
+    posix_spawnattr_getflags;
+    posix_spawnattr_getpgroup;
+    posix_spawnattr_getschedparam;
+    posix_spawnattr_getschedpolicy;
+    posix_spawnattr_getsigdefault;
+    posix_spawnattr_getsigmask;
+    posix_spawnattr_init;
+    posix_spawnattr_setflags;
+    posix_spawnattr_setpgroup;
+    posix_spawnattr_setschedparam;
+    posix_spawnattr_setschedpolicy;
+    posix_spawnattr_setsigdefault;
+    posix_spawnattr_setsigmask;
+    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;
+    pthread_attr_getinheritsched;
+    pthread_attr_setinheritsched;
+    pthread_setschedprio;
+    sethostent;
+    setnetent;
+    setprotoent;
+    swab;
+    syncfs;
 } LIBC_O;
 
 LIBC_PRIVATE {
diff --git a/libc/libc.map.txt b/libc/libc.map.txt
index a0ac50a..97965ac 100644
--- a/libc/libc.map.txt
+++ b/libc/libc.map.txt
@@ -1343,21 +1343,66 @@
     wctrans_l; # introduced=26
 } LIBC_N;
 
-LIBC_P {
+LIBC_P { # introduced=P
   global:
-    __freading; # future
-    __fwriting; # future
-    getlogin_r; # future
-    hcreate; # future
-    hcreate_r; # future
-    hdestroy; # future
-    hdestroy_r; # future
-    hsearch; # future
-    hsearch_r; # future
-    iconv; # future
-    iconv_close; # future
-    iconv_open; # future
-    syncfs; # future
+    __freading;
+    __fwriting;
+    endhostent;
+    endnetent;
+    endprotoent;
+    fexecve;
+    fflush_unlocked;
+    fgetc_unlocked;
+    fgets_unlocked;
+    fputc_unlocked;
+    fputs_unlocked;
+    fread_unlocked;
+    fwrite_unlocked;
+    getentropy;
+    getnetent;
+    getprotoent;
+    getrandom;
+    getlogin_r;
+    glob;
+    globfree;
+    hcreate;
+    hcreate_r;
+    hdestroy;
+    hdestroy_r;
+    hsearch;
+    hsearch_r;
+    iconv;
+    iconv_close;
+    iconv_open;
+    posix_spawn;
+    posix_spawnattr_destroy;
+    posix_spawnattr_getflags;
+    posix_spawnattr_getpgroup;
+    posix_spawnattr_getschedparam;
+    posix_spawnattr_getschedpolicy;
+    posix_spawnattr_getsigdefault;
+    posix_spawnattr_getsigmask;
+    posix_spawnattr_init;
+    posix_spawnattr_setflags;
+    posix_spawnattr_setpgroup;
+    posix_spawnattr_setschedparam;
+    posix_spawnattr_setschedpolicy;
+    posix_spawnattr_setsigdefault;
+    posix_spawnattr_setsigmask;
+    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;
+    pthread_attr_getinheritsched;
+    pthread_attr_setinheritsched;
+    pthread_setschedprio;
+    sethostent;
+    setnetent;
+    setprotoent;
+    swab;
+    syncfs;
 } LIBC_O;
 
 LIBC_PRIVATE {
diff --git a/libc/libc.mips.map b/libc/libc.mips.map
index 8970549..930a1ca 100644
--- a/libc/libc.mips.map
+++ b/libc/libc.mips.map
@@ -1302,21 +1302,66 @@
     wctrans_l; # introduced=26
 } LIBC_N;
 
-LIBC_P {
+LIBC_P { # introduced=P
   global:
-    __freading; # future
-    __fwriting; # future
-    getlogin_r; # future
-    hcreate; # future
-    hcreate_r; # future
-    hdestroy; # future
-    hdestroy_r; # future
-    hsearch; # future
-    hsearch_r; # future
-    iconv; # future
-    iconv_close; # future
-    iconv_open; # future
-    syncfs; # future
+    __freading;
+    __fwriting;
+    endhostent;
+    endnetent;
+    endprotoent;
+    fexecve;
+    fflush_unlocked;
+    fgetc_unlocked;
+    fgets_unlocked;
+    fputc_unlocked;
+    fputs_unlocked;
+    fread_unlocked;
+    fwrite_unlocked;
+    getentropy;
+    getnetent;
+    getprotoent;
+    getrandom;
+    getlogin_r;
+    glob;
+    globfree;
+    hcreate;
+    hcreate_r;
+    hdestroy;
+    hdestroy_r;
+    hsearch;
+    hsearch_r;
+    iconv;
+    iconv_close;
+    iconv_open;
+    posix_spawn;
+    posix_spawnattr_destroy;
+    posix_spawnattr_getflags;
+    posix_spawnattr_getpgroup;
+    posix_spawnattr_getschedparam;
+    posix_spawnattr_getschedpolicy;
+    posix_spawnattr_getsigdefault;
+    posix_spawnattr_getsigmask;
+    posix_spawnattr_init;
+    posix_spawnattr_setflags;
+    posix_spawnattr_setpgroup;
+    posix_spawnattr_setschedparam;
+    posix_spawnattr_setschedpolicy;
+    posix_spawnattr_setsigdefault;
+    posix_spawnattr_setsigmask;
+    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;
+    pthread_attr_getinheritsched;
+    pthread_attr_setinheritsched;
+    pthread_setschedprio;
+    sethostent;
+    setnetent;
+    setprotoent;
+    swab;
+    syncfs;
 } LIBC_O;
 
 LIBC_PRIVATE {
diff --git a/libc/libc.mips64.map b/libc/libc.mips64.map
index 4ea5896..d464a0c 100644
--- a/libc/libc.mips64.map
+++ b/libc/libc.mips64.map
@@ -1238,21 +1238,66 @@
     wctrans_l; # introduced=26
 } LIBC_N;
 
-LIBC_P {
+LIBC_P { # introduced=P
   global:
-    __freading; # future
-    __fwriting; # future
-    getlogin_r; # future
-    hcreate; # future
-    hcreate_r; # future
-    hdestroy; # future
-    hdestroy_r; # future
-    hsearch; # future
-    hsearch_r; # future
-    iconv; # future
-    iconv_close; # future
-    iconv_open; # future
-    syncfs; # future
+    __freading;
+    __fwriting;
+    endhostent;
+    endnetent;
+    endprotoent;
+    fexecve;
+    fflush_unlocked;
+    fgetc_unlocked;
+    fgets_unlocked;
+    fputc_unlocked;
+    fputs_unlocked;
+    fread_unlocked;
+    fwrite_unlocked;
+    getentropy;
+    getnetent;
+    getprotoent;
+    getrandom;
+    getlogin_r;
+    glob;
+    globfree;
+    hcreate;
+    hcreate_r;
+    hdestroy;
+    hdestroy_r;
+    hsearch;
+    hsearch_r;
+    iconv;
+    iconv_close;
+    iconv_open;
+    posix_spawn;
+    posix_spawnattr_destroy;
+    posix_spawnattr_getflags;
+    posix_spawnattr_getpgroup;
+    posix_spawnattr_getschedparam;
+    posix_spawnattr_getschedpolicy;
+    posix_spawnattr_getsigdefault;
+    posix_spawnattr_getsigmask;
+    posix_spawnattr_init;
+    posix_spawnattr_setflags;
+    posix_spawnattr_setpgroup;
+    posix_spawnattr_setschedparam;
+    posix_spawnattr_setschedpolicy;
+    posix_spawnattr_setsigdefault;
+    posix_spawnattr_setsigmask;
+    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;
+    pthread_attr_getinheritsched;
+    pthread_attr_setinheritsched;
+    pthread_setschedprio;
+    sethostent;
+    setnetent;
+    setprotoent;
+    swab;
+    syncfs;
 } LIBC_O;
 
 LIBC_PRIVATE {
diff --git a/libc/libc.x86.map b/libc/libc.x86.map
index 5439852..27b9743 100644
--- a/libc/libc.x86.map
+++ b/libc/libc.x86.map
@@ -1300,21 +1300,66 @@
     wctrans_l; # introduced=26
 } LIBC_N;
 
-LIBC_P {
+LIBC_P { # introduced=P
   global:
-    __freading; # future
-    __fwriting; # future
-    getlogin_r; # future
-    hcreate; # future
-    hcreate_r; # future
-    hdestroy; # future
-    hdestroy_r; # future
-    hsearch; # future
-    hsearch_r; # future
-    iconv; # future
-    iconv_close; # future
-    iconv_open; # future
-    syncfs; # future
+    __freading;
+    __fwriting;
+    endhostent;
+    endnetent;
+    endprotoent;
+    fexecve;
+    fflush_unlocked;
+    fgetc_unlocked;
+    fgets_unlocked;
+    fputc_unlocked;
+    fputs_unlocked;
+    fread_unlocked;
+    fwrite_unlocked;
+    getentropy;
+    getnetent;
+    getprotoent;
+    getrandom;
+    getlogin_r;
+    glob;
+    globfree;
+    hcreate;
+    hcreate_r;
+    hdestroy;
+    hdestroy_r;
+    hsearch;
+    hsearch_r;
+    iconv;
+    iconv_close;
+    iconv_open;
+    posix_spawn;
+    posix_spawnattr_destroy;
+    posix_spawnattr_getflags;
+    posix_spawnattr_getpgroup;
+    posix_spawnattr_getschedparam;
+    posix_spawnattr_getschedpolicy;
+    posix_spawnattr_getsigdefault;
+    posix_spawnattr_getsigmask;
+    posix_spawnattr_init;
+    posix_spawnattr_setflags;
+    posix_spawnattr_setpgroup;
+    posix_spawnattr_setschedparam;
+    posix_spawnattr_setschedpolicy;
+    posix_spawnattr_setsigdefault;
+    posix_spawnattr_setsigmask;
+    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;
+    pthread_attr_getinheritsched;
+    pthread_attr_setinheritsched;
+    pthread_setschedprio;
+    sethostent;
+    setnetent;
+    setprotoent;
+    swab;
+    syncfs;
 } LIBC_O;
 
 LIBC_PRIVATE {
diff --git a/libc/libc.x86_64.map b/libc/libc.x86_64.map
index 4ea5896..d464a0c 100644
--- a/libc/libc.x86_64.map
+++ b/libc/libc.x86_64.map
@@ -1238,21 +1238,66 @@
     wctrans_l; # introduced=26
 } LIBC_N;
 
-LIBC_P {
+LIBC_P { # introduced=P
   global:
-    __freading; # future
-    __fwriting; # future
-    getlogin_r; # future
-    hcreate; # future
-    hcreate_r; # future
-    hdestroy; # future
-    hdestroy_r; # future
-    hsearch; # future
-    hsearch_r; # future
-    iconv; # future
-    iconv_close; # future
-    iconv_open; # future
-    syncfs; # future
+    __freading;
+    __fwriting;
+    endhostent;
+    endnetent;
+    endprotoent;
+    fexecve;
+    fflush_unlocked;
+    fgetc_unlocked;
+    fgets_unlocked;
+    fputc_unlocked;
+    fputs_unlocked;
+    fread_unlocked;
+    fwrite_unlocked;
+    getentropy;
+    getnetent;
+    getprotoent;
+    getrandom;
+    getlogin_r;
+    glob;
+    globfree;
+    hcreate;
+    hcreate_r;
+    hdestroy;
+    hdestroy_r;
+    hsearch;
+    hsearch_r;
+    iconv;
+    iconv_close;
+    iconv_open;
+    posix_spawn;
+    posix_spawnattr_destroy;
+    posix_spawnattr_getflags;
+    posix_spawnattr_getpgroup;
+    posix_spawnattr_getschedparam;
+    posix_spawnattr_getschedpolicy;
+    posix_spawnattr_getsigdefault;
+    posix_spawnattr_getsigmask;
+    posix_spawnattr_init;
+    posix_spawnattr_setflags;
+    posix_spawnattr_setpgroup;
+    posix_spawnattr_setschedparam;
+    posix_spawnattr_setschedpolicy;
+    posix_spawnattr_setsigdefault;
+    posix_spawnattr_setsigmask;
+    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;
+    pthread_attr_getinheritsched;
+    pthread_attr_setinheritsched;
+    pthread_setschedprio;
+    sethostent;
+    setnetent;
+    setprotoent;
+    swab;
+    syncfs;
 } LIBC_O;
 
 LIBC_PRIVATE {
diff --git a/libc/malloc_debug/BacktraceData.cpp b/libc/malloc_debug/BacktraceData.cpp
index 65ae6fa..d597280 100644
--- a/libc/malloc_debug/BacktraceData.cpp
+++ b/libc/malloc_debug/BacktraceData.cpp
@@ -53,7 +53,7 @@
     : OptionData(debug_data) {
   size_t hdr_len = sizeof(BacktraceHeader) + sizeof(uintptr_t) * config.backtrace_frames();
   alloc_offset_ = *offset;
-  *offset += BIONIC_ALIGN(hdr_len, MINIMUM_ALIGNMENT_BYTES);
+  *offset += __BIONIC_ALIGN(hdr_len, MINIMUM_ALIGNMENT_BYTES);
 }
 
 bool BacktraceData::Initialize(const Config& config) {
diff --git a/libc/malloc_debug/Config.cpp b/libc/malloc_debug/Config.cpp
index e3798ab..3cecf9b 100644
--- a/libc/malloc_debug/Config.cpp
+++ b/libc/malloc_debug/Config.cpp
@@ -191,7 +191,7 @@
 
   // It's necessary to align the front guard to MINIMUM_ALIGNMENT_BYTES to
   // make sure that the header is aligned properly.
-  front_guard_bytes_ = BIONIC_ALIGN(rear_guard_bytes_, MINIMUM_ALIGNMENT_BYTES);
+  front_guard_bytes_ = __BIONIC_ALIGN(rear_guard_bytes_, MINIMUM_ALIGNMENT_BYTES);
   return true;
 }
 
@@ -201,7 +201,7 @@
   }
   // It's necessary to align the front guard to MINIMUM_ALIGNMENT_BYTES to
   // make sure that the header is aligned properly.
-  front_guard_bytes_ = BIONIC_ALIGN(front_guard_bytes_, MINIMUM_ALIGNMENT_BYTES);
+  front_guard_bytes_ = __BIONIC_ALIGN(front_guard_bytes_, MINIMUM_ALIGNMENT_BYTES);
   return true;
 }
 
diff --git a/libc/malloc_debug/DebugData.cpp b/libc/malloc_debug/DebugData.cpp
index e9974d7..d6ca998 100644
--- a/libc/malloc_debug/DebugData.cpp
+++ b/libc/malloc_debug/DebugData.cpp
@@ -47,7 +47,7 @@
     need_header_ = true;
 
     // Initialize all of the static header offsets.
-    pointer_offset_ = BIONIC_ALIGN(sizeof(Header), MINIMUM_ALIGNMENT_BYTES);
+    pointer_offset_ = __BIONIC_ALIGN(sizeof(Header), MINIMUM_ALIGNMENT_BYTES);
 
     if (config_.options() & BACKTRACE) {
       backtrace.reset(new BacktraceData(this, config_, &pointer_offset_));
diff --git a/libc/malloc_debug/malloc_debug.cpp b/libc/malloc_debug/malloc_debug.cpp
index d890a1c..a2ada2f 100644
--- a/libc/malloc_debug/malloc_debug.cpp
+++ b/libc/malloc_debug/malloc_debug.cpp
@@ -767,7 +767,7 @@
   }
 
   size_t pagesize = getpagesize();
-  size_t size = BIONIC_ALIGN(bytes, pagesize);
+  size_t size = __BIONIC_ALIGN(bytes, pagesize);
   if (size < bytes) {
     // Overflow
     errno = ENOMEM;
diff --git a/libc/malloc_debug/tests/malloc_debug_unit_tests.cpp b/libc/malloc_debug/tests/malloc_debug_unit_tests.cpp
index 37d8057..d7ba379 100644
--- a/libc/malloc_debug/tests/malloc_debug_unit_tests.cpp
+++ b/libc/malloc_debug/tests/malloc_debug_unit_tests.cpp
@@ -74,9 +74,10 @@
 constexpr uint32_t BACKTRACE_HEADER = 0x1;
 
 static size_t get_tag_offset(uint32_t flags = 0, size_t backtrace_frames = 0) {
-  size_t offset = BIONIC_ALIGN(sizeof(Header), MINIMUM_ALIGNMENT_BYTES);
+  size_t offset = __BIONIC_ALIGN(sizeof(Header), MINIMUM_ALIGNMENT_BYTES);
   if (flags & BACKTRACE_HEADER) {
-    offset += BIONIC_ALIGN(sizeof(BacktraceHeader) + sizeof(uintptr_t) * backtrace_frames, MINIMUM_ALIGNMENT_BYTES);
+    offset += __BIONIC_ALIGN(sizeof(BacktraceHeader) + sizeof(uintptr_t) * backtrace_frames,
+                             MINIMUM_ALIGNMENT_BYTES);
   }
   return offset;
 }
diff --git a/libc/private/CachedProperty.h b/libc/private/CachedProperty.h
index 417a855..84ead01 100644
--- a/libc/private/CachedProperty.h
+++ b/libc/private/CachedProperty.h
@@ -42,7 +42,9 @@
     : property_name_(property_name),
       prop_info_(nullptr),
       cached_area_serial_(0),
-      cached_property_serial_(0) {
+      cached_property_serial_(0),
+      is_read_only_(strncmp(property_name, "ro.", 3) == 0),
+      read_only_property_(nullptr) {
     cached_value_[0] = '\0';
   }
 
@@ -76,7 +78,9 @@
         __system_property_read_callback(prop_info_, &CachedProperty::Callback, this);
       }
     }
-
+    if (is_read_only_ && read_only_property_ != nullptr) {
+      return read_only_property_;
+    }
     return cached_value_;
   }
 
@@ -86,10 +90,18 @@
   uint32_t cached_area_serial_;
   uint32_t cached_property_serial_;
   char cached_value_[PROP_VALUE_MAX];
+  bool is_read_only_;
+  const char* read_only_property_;
 
   static void Callback(void* data, const char*, const char* value, uint32_t serial) {
     CachedProperty* instance = reinterpret_cast<CachedProperty*>(data);
     instance->cached_property_serial_ = serial;
-    strcpy(instance->cached_value_, value);
+    // Read only properties can be larger than PROP_VALUE_MAX, but also never change value or
+    // location, thus we return the pointer from the shared memory directly.
+    if (instance->is_read_only_) {
+      instance->read_only_property_ = value;
+    } else {
+      strlcpy(instance->cached_value_, value, PROP_VALUE_MAX);
+    }
   }
 };
diff --git a/libm/arm64/fma.S b/libc/private/FdPath.h
similarity index 68%
copy from libm/arm64/fma.S
copy to libc/private/FdPath.h
index 1a8a158..4a6a2d5 100644
--- a/libm/arm64/fma.S
+++ b/libc/private/FdPath.h
@@ -1,5 +1,5 @@
 /*
- * Copyright (C) 2015 The Android Open Source Project
+ * Copyright (C) 2017 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.
@@ -14,14 +14,18 @@
  * limitations under the License.
  */
 
-#include <private/bionic_asm.h>
+#pragma once
 
-ENTRY(fma)
-  fmadd d0, d0, d1, d2
-  ret
-END(fma)
+class FdPath {
+ public:
+  explicit FdPath(int fd) {
+    snprintf(buf, sizeof(buf), "/proc/self/fd/%d", fd);
+  }
 
-ENTRY(fmaf)
-  fmadd s0, s0, s1, s2
-  ret
-END(fmaf)
+  const char* c_str() {
+    return buf;
+  }
+
+ private:
+  char buf[40];
+};
diff --git a/libc/private/ScopedSignalBlocker.h b/libc/private/ScopedSignalBlocker.h
new file mode 100644
index 0000000..35d1c58
--- /dev/null
+++ b/libc/private/ScopedSignalBlocker.h
@@ -0,0 +1,46 @@
+/*
+ * Copyright (C) 2017 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 SCOPED_SIGNAL_BLOCKER_H
+#define SCOPED_SIGNAL_BLOCKER_H
+
+#include <signal.h>
+
+#include "bionic_macros.h"
+
+class ScopedSignalBlocker {
+ public:
+  explicit ScopedSignalBlocker() {
+    sigset_t set;
+    sigfillset(&set);
+    sigprocmask(SIG_BLOCK, &set, &old_set_);
+  }
+
+  ~ScopedSignalBlocker() {
+    reset();
+  }
+
+  void reset() {
+    sigprocmask(SIG_SETMASK, &old_set_, nullptr);
+  }
+
+ private:
+  sigset_t old_set_;
+
+  DISALLOW_COPY_AND_ASSIGN(ScopedSignalBlocker);
+};
+
+#endif
diff --git a/libc/private/bionic_asm.h b/libc/private/bionic_asm.h
index c1fab1f..30842f4 100644
--- a/libc/private/bionic_asm.h
+++ b/libc/private/bionic_asm.h
@@ -36,7 +36,17 @@
 #define __bionic_asm_custom_end(f)
 #define __bionic_asm_function_type @function
 
-#include <machine/asm.h>
+#if defined(__aarch64__)
+#include <private/bionic_asm_arm64.h>
+#elif defined(__arm__)
+#include <private/bionic_asm_arm.h>
+#elif defined(__i386__)
+#include <private/bionic_asm_x86.h>
+#elif defined(__mips__)
+#include <private/bionic_asm_mips.h>
+#elif defined(__x86_64__)
+#include <private/bionic_asm_x86_64.h>
+#endif
 
 #define ENTRY_NO_DWARF(f) \
     .text; \
@@ -68,8 +78,11 @@
     ENTRY_NO_DWARF(f); \
     .hidden f \
 
+#define __BIONIC_WEAK_ASM_FOR_NATIVE_BRIDGE(f) \
+    .weak f; \
+
 #define ALIAS_SYMBOL(alias, original) \
     .globl alias; \
     .equ alias, original
 
-#endif /* _PRIVATE_BIONIC_ASM_H_ */
+#endif
diff --git a/libc/arch-arm/include/machine/asm.h b/libc/private/bionic_asm_arm.h
similarity index 95%
rename from libc/arch-arm/include/machine/asm.h
rename to libc/private/bionic_asm_arm.h
index 70dbe67..d8381d3 100644
--- a/libc/arch-arm/include/machine/asm.h
+++ b/libc/private/bionic_asm_arm.h
@@ -35,8 +35,7 @@
  *	from: @(#)asm.h	5.5 (Berkeley) 5/7/91
  */
 
-#ifndef _ARM32_ASM_H_
-#define _ARM32_ASM_H_
+#pragma once
 
 #define __bionic_asm_align 0
 
@@ -47,5 +46,3 @@
 
 #undef __bionic_asm_function_type
 #define __bionic_asm_function_type #function
-
-#endif /* !_ARM_ASM_H_ */
diff --git a/libc/arch-arm64/include/machine/asm.h b/libc/private/bionic_asm_arm64.h
similarity index 95%
rename from libc/arch-arm64/include/machine/asm.h
rename to libc/private/bionic_asm_arm64.h
index 2bea043..43ecaf3 100644
--- a/libc/arch-arm64/include/machine/asm.h
+++ b/libc/private/bionic_asm_arm64.h
@@ -35,12 +35,9 @@
  *	from: @(#)asm.h	5.5 (Berkeley) 5/7/91
  */
 
-#ifndef _AARCH64_ASM_H_
-#define _AARCH64_ASM_H_
+#pragma once
 
 #define __bionic_asm_align 0
 
 #undef __bionic_asm_function_type
 #define __bionic_asm_function_type %function
-
-#endif /* _AARCH64_ASM_H_ */
diff --git a/libc/arch-mips/include/machine/asm.h b/libc/private/bionic_asm_mips.h
similarity index 95%
rename from libc/arch-mips/include/machine/asm.h
rename to libc/private/bionic_asm_mips.h
index dc83088..99dcfb1 100644
--- a/libc/arch-mips/include/machine/asm.h
+++ b/libc/private/bionic_asm_mips.h
@@ -25,8 +25,8 @@
  * SUCH DAMAGE.
  *
  */
-#ifndef _MIPS64_ASM_H
-#define _MIPS64_ASM_H
+
+#pragma once
 
 #define __bionic_asm_align 16
 
@@ -35,8 +35,6 @@
 #define __bionic_asm_custom_entry(f) .ent f
 #define __bionic_asm_custom_end(f) .end f
 
-#include <machine/regdef.h>
-
 #define	_MIPS_ISA_MIPS1	1	/* R2000/R3000 */
 #define	_MIPS_ISA_MIPS2	2	/* R4000/R6000 */
 #define	_MIPS_ISA_MIPS3	3	/* R4000 */
@@ -75,7 +73,7 @@
 
 #define	SETUP_GP		\
 	.set	noreorder;	\
-	.cpload	t9;		\
+	.cpload	$t9;		\
 	.set	reorder;
 
 #define	SAVE_GP(x)		\
@@ -91,7 +89,7 @@
 #define	SETUP_GP
 #define	SAVE_GP(x)
 #define	SETUP_GP64(gpoff, name)	\
-	.cpsetup t9, gpoff, name
+	.cpsetup $t9, gpoff, name
 #define	RESTORE_GP64		\
 	.cpreturn
 #endif
@@ -171,7 +169,7 @@
 	.ent x, 0;		\
 x: ;				\
 	.cfi_startproc; \
-	.frame sp, fsize, ra;	\
+	.frame $sp, fsize, $ra;	\
 	SETUP_GP		\
 
 /*
@@ -185,7 +183,5 @@
 	.ent x, 0;		\
 x: ;				\
 	.cfi_startproc; \
-	.frame sp, fsize, retpc; \
+	.frame $sp, fsize, retpc; \
 	SETUP_GP		\
-
-#endif /* !_MIPS_ASM_H */
diff --git a/libc/arch-x86/include/machine/asm.h b/libc/private/bionic_asm_x86.h
similarity index 95%
rename from libc/arch-x86/include/machine/asm.h
rename to libc/private/bionic_asm_x86.h
index 943f9dd..fcec40b 100644
--- a/libc/arch-x86/include/machine/asm.h
+++ b/libc/private/bionic_asm_x86.h
@@ -34,8 +34,7 @@
  *	@(#)asm.h	5.5 (Berkeley) 5/7/91
  */
 
-#ifndef _I386_ASM_H_
-#define _I386_ASM_H_
+#pragma once
 
 #define PIC_PROLOGUE	\
 	pushl	%ebx;	\
@@ -50,5 +49,3 @@
 #define PIC_GOTOFF(x)	x@GOTOFF(%ebx)
 
 #define __bionic_asm_align 16
-
-#endif /* !_I386_ASM_H_ */
diff --git a/libc/arch-x86_64/include/machine/asm.h b/libc/private/bionic_asm_x86_64.h
similarity index 95%
rename from libc/arch-x86_64/include/machine/asm.h
rename to libc/private/bionic_asm_x86_64.h
index 28cd08f..c553b0c 100644
--- a/libc/arch-x86_64/include/machine/asm.h
+++ b/libc/private/bionic_asm_x86_64.h
@@ -34,12 +34,9 @@
  *	@(#)asm.h	5.5 (Berkeley) 5/7/91
  */
 
-#ifndef _AMD64_ASM_H_
-#define _AMD64_ASM_H_
+#pragma once
 
 #define PIC_PLT(x)	x@PLT
 #define PIC_GOT(x)	x@GOTPCREL(%rip)
 
 #define __bionic_asm_align 16
-
-#endif /* !_AMD64_ASM_H_ */
diff --git a/libc/arch-arm64/include/machine/setjmp.h b/libc/private/bionic_defs.h
similarity index 74%
copy from libc/arch-arm64/include/machine/setjmp.h
copy to libc/private/bionic_defs.h
index 27c2fe5..1d4f86b 100644
--- a/libc/arch-arm64/include/machine/setjmp.h
+++ b/libc/private/bionic_defs.h
@@ -1,5 +1,5 @@
 /*
- * Copyright (C) 2013 The Android Open Source Project
+ * Copyright (C) 2017 The Android Open Source Project
  * All rights reserved.
  *
  * Redistribution and use in source and binary forms, with or without
@@ -26,5 +26,14 @@
  * SUCH DAMAGE.
  */
 
-/* _JBLEN is the size of a jmp_buf in longs (64bit on AArch64) */
-#define _JBLEN 32
+#ifndef __BIONIC_PRIVATE_BIONIC_DEFS_H_
+#define __BIONIC_PRIVATE_BIONIC_DEFS_H_
+
+/*
+ * This label is used to mark libc/libdl symbols that may need to be replaced
+ * by native bridge implementation.
+ */
+#define __BIONIC_WEAK_FOR_NATIVE_BRIDGE __attribute__((__weak__, __noinline__))
+#define __BIONIC_WEAK_VARIABLE_FOR_NATIVE_BRIDGE __attribute__((__weak__))
+
+#endif /* __BIONIC_PRIVATE_BIONIC_DEFS_H_ */
diff --git a/libc/private/bionic_fortify.h b/libc/private/bionic_fortify.h
index 8591117..7f22963 100644
--- a/libc/private/bionic_fortify.h
+++ b/libc/private/bionic_fortify.h
@@ -26,6 +26,8 @@
  * SUCH DAMAGE.
  */
 
+#pragma once
+
 #include <poll.h> // For struct pollfd.
 #include <stdarg.h>
 #include <stdlib.h>
diff --git a/libc/private/bionic_macros.h b/libc/private/bionic_macros.h
index 303218e..979a704 100644
--- a/libc/private/bionic_macros.h
+++ b/libc/private/bionic_macros.h
@@ -40,9 +40,6 @@
   TypeName() = delete;                           \
   DISALLOW_COPY_AND_ASSIGN(TypeName)
 
-#define BIONIC_ALIGN(value, alignment) \
-  (((value) + (alignment) - 1) & ~((alignment) - 1))
-
 #define BIONIC_ROUND_UP_POWER_OF_2(value) \
   ((sizeof(value) == 8) \
     ? (1UL << (64 - __builtin_clzl(static_cast<unsigned long>(value)))) \
@@ -66,4 +63,35 @@
   return reinterpret_cast<T*>(align_up(reinterpret_cast<uintptr_t>(p), align));
 }
 
+#if defined(__arm__)
+// Do not emit anything for arm, clang does not allow emiting an arm unwind
+// directive.
+// #define BIONIC_STOP_UNWIND asm volatile(".cantunwind")
+#define BIONIC_STOP_UNWIND
+#elif defined(__aarch64__)
+#define BIONIC_STOP_UNWIND asm volatile(".cfi_undefined x30")
+#elif defined(__i386__)
+#define BIONIC_STOP_UNWIND asm volatile(".cfi_undefined \%eip")
+#elif defined(__x86_64__)
+#define BIONIC_STOP_UNWIND asm volatile(".cfi_undefined \%rip")
+#elif defined (__mips__)
+#define BIONIC_STOP_UNWIND asm volatile(".cfi_undefined $ra")
+#endif
+
+// The arraysize(arr) macro returns the # of elements in an array arr.
+// The expression is a compile-time constant, and therefore can be
+// used in defining new arrays, for example.  If you use arraysize on
+// a pointer by mistake, you will get a compile-time error.
+//
+// One caveat is that arraysize() doesn't accept any array of an
+// anonymous type or a type defined inside a function.
+//
+// This template function declaration is used in defining arraysize.
+// Note that the function doesn't need an implementation, as we only
+// use its type.
+template <typename T, size_t N>
+char (&ArraySizeHelper(T (&array)[N]))[N];  // NOLINT(readability/casting)
+
+#define arraysize(array) (sizeof(ArraySizeHelper(array)))
+
 #endif // _BIONIC_MACROS_H_
diff --git a/libc/private/bionic_tls.h b/libc/private/bionic_tls.h
index 852b9ae..de086f2 100644
--- a/libc/private/bionic_tls.h
+++ b/libc/private/bionic_tls.h
@@ -102,7 +102,7 @@
   passwd_state_t passwd;
 };
 
-#define BIONIC_TLS_SIZE (BIONIC_ALIGN(sizeof(bionic_tls), PAGE_SIZE))
+#define BIONIC_TLS_SIZE (__BIONIC_ALIGN(sizeof(bionic_tls), PAGE_SIZE))
 
 /*
  * Bionic uses some pthread keys internally. All pthread keys used internally
diff --git a/libc/seccomp/Android.bp b/libc/seccomp/Android.bp
index a75aa65..b3707bc 100644
--- a/libc/seccomp/Android.bp
+++ b/libc/seccomp/Android.bp
@@ -16,6 +16,7 @@
         "mips64_global_policy.cpp",
     ],
     export_include_dirs: ["include"],
+    cflags: ["-Wall", "-Werror"],
     shared: {
         shared_libs: ["libbase"],
     },
diff --git a/libc/seccomp/arm64_global_policy.cpp b/libc/seccomp/arm64_global_policy.cpp
index 1a138b7..e2c594e 100644
--- a/libc/seccomp/arm64_global_policy.cpp
+++ b/libc/seccomp/arm64_global_policy.cpp
@@ -5,12 +5,12 @@
 
 #include "seccomp_bpfs.h"
 const sock_filter arm64_global_filter[] = {
-BPF_JUMP(BPF_JMP|BPF_JGE|BPF_K, 5, 0, 32),
+BPF_JUMP(BPF_JMP|BPF_JGE|BPF_K, 0, 0, 32),
 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), //setxattr|lsetxattr|fsetxattr|getxattr|lgetxattr|fgetxattr|listxattr|llistxattr|flistxattr|removexattr|lremovexattr|fremovexattr|getcwd
+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, 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
diff --git a/libc/seccomp/arm_global_policy.cpp b/libc/seccomp/arm_global_policy.cpp
index 2f9a122..d7b5d7e 100644
--- a/libc/seccomp/arm_global_policy.cpp
+++ b/libc/seccomp/arm_global_policy.cpp
@@ -5,7 +5,7 @@
 
 #include "seccomp_bpfs.h"
 const sock_filter arm_global_filter[] = {
-BPF_JUMP(BPF_JMP|BPF_JGE|BPF_K, 0, 0, 132),
+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),
@@ -13,88 +13,86 @@
 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, 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, 120, 119), //lseek|getpid|mount
-BPF_JUMP(BPF_JMP|BPF_JGE|BPF_K, 25, 119, 118), //getuid
+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, 116, 115), //ptrace
-BPF_JUMP(BPF_JMP|BPF_JGE|BPF_K, 34, 115, 114), //access
+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, 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, 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, 108, 107), //brk
-BPF_JUMP(BPF_JMP|BPF_JGE|BPF_K, 53, 107, 106), //acct|umount2
+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, 105, 104), //ioctl|fcntl
-BPF_JUMP(BPF_JMP|BPF_JGE|BPF_K, 58, 104, 103), //setpgid
+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, 101, 100), //umask|chroot
-BPF_JUMP(BPF_JMP|BPF_JGE|BPF_K, 65, 100, 99), //dup2|getppid
+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, 98, 97), //setsid|sigaction
-BPF_JUMP(BPF_JMP|BPF_JGE|BPF_K, 76, 97, 96), //sethostname|setrlimit
+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, 92, 91), //getrusage|gettimeofday|settimeofday
-BPF_JUMP(BPF_JMP|BPF_JGE|BPF_K, 86, 91, 90), //readlink
+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, 89, 88), //swapon|reboot
-BPF_JUMP(BPF_JMP|BPF_JGE|BPF_K, 93, 88, 87), //munmap|truncate
+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, 85, 84), //fchmod
-BPF_JUMP(BPF_JMP|BPF_JGE|BPF_K, 98, 84, 83), //getpriority|setpriority
+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, 82, 81), //syslog|setitimer|getitimer
-BPF_JUMP(BPF_JMP|BPF_JGE|BPF_K, 115, 81, 80), //wait4
+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, 77, 76), //sysinfo
-BPF_JUMP(BPF_JMP|BPF_JGE|BPF_K, 123, 76, 75), //fsync|sigreturn|clone|setdomainname|uname
+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, 74, 73), //adjtimex|mprotect
-BPF_JUMP(BPF_JMP|BPF_JGE|BPF_K, 130, 73, 72), //init_module|delete_module
+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, 70, 69), //quotactl|getpgid|fchdir
-BPF_JUMP(BPF_JMP|BPF_JGE|BPF_K, 137, 69, 68), //personality
+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, 67, 66), //setfsuid|setfsgid|_llseek|getdents|_newselect|flock|msync|readv|writev|getsid|fdatasync
-BPF_JUMP(BPF_JMP|BPF_JGE|BPF_K, 164, 66, 65), //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, 33, 0),
-BPF_JUMP(BPF_JMP|BPF_JGE|BPF_K, 248, 17, 0),
-BPF_JUMP(BPF_JMP|BPF_JGE|BPF_K, 213, 9, 0),
-BPF_JUMP(BPF_JMP|BPF_JGE|BPF_K, 190, 5, 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, 59, 58), //poll
-BPF_JUMP(BPF_JMP|BPF_JGE|BPF_K, 182, 58, 57), //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, 57, 56), //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, 55, 54), //vfork|ugetrlimit|mmap2|truncate64|ftruncate64|stat64|lstat64|fstat64
-BPF_JUMP(BPF_JMP|BPF_JGE|BPF_K, 212, 54, 53), //getuid32|getgid32|geteuid32|getegid32|setreuid32|setregid32|getgroups32|setgroups32|fchown32|setresuid32|getresuid32|setresgid32|getresgid32
-BPF_JUMP(BPF_JMP|BPF_JGE|BPF_K, 219, 3, 0),
-BPF_JUMP(BPF_JMP|BPF_JGE|BPF_K, 217, 1, 0),
-BPF_JUMP(BPF_JMP|BPF_JGE|BPF_K, 215, 51, 50), //setuid32|setgid32
-BPF_JUMP(BPF_JMP|BPF_JGE|BPF_K, 218, 50, 49), //getdents64
-BPF_JUMP(BPF_JMP|BPF_JGE|BPF_K, 224, 1, 0),
-BPF_JUMP(BPF_JMP|BPF_JGE|BPF_K, 222, 48, 47), //mincore|madvise|fcntl64
-BPF_JUMP(BPF_JMP|BPF_JGE|BPF_K, 243, 47, 46), //gettid|readahead|setxattr|lsetxattr|fsetxattr|getxattr|lgetxattr|fgetxattr|listxattr|llistxattr|flistxattr|removexattr|lremovexattr|fremovexattr|tkill|sendfile64|futex|sched_setaffinity|sched_getaffinity
+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), //exit_group
+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
diff --git a/libc/seccomp/mips64_global_policy.cpp b/libc/seccomp/mips64_global_policy.cpp
index 004eda2..04c13b3 100644
--- a/libc/seccomp/mips64_global_policy.cpp
+++ b/libc/seccomp/mips64_global_policy.cpp
@@ -59,9 +59,9 @@
 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, 5205, 1, 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), //exit_group
+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),
diff --git a/libc/seccomp/mips_global_policy.cpp b/libc/seccomp/mips_global_policy.cpp
index b4fa23d..103e544 100644
--- a/libc/seccomp/mips_global_policy.cpp
+++ b/libc/seccomp/mips_global_policy.cpp
@@ -5,93 +5,91 @@
 
 #include "seccomp_bpfs.h"
 const sock_filter mips_global_filter[] = {
-BPF_JUMP(BPF_JMP|BPF_JGE|BPF_K, 4001, 0, 114),
-BPF_JUMP(BPF_JMP|BPF_JGE|BPF_K, 4136, 57, 0),
-BPF_JUMP(BPF_JMP|BPF_JGE|BPF_K, 4066, 29, 0),
-BPF_JUMP(BPF_JMP|BPF_JGE|BPF_K, 4041, 15, 0),
+BPF_JUMP(BPF_JMP|BPF_JGE|BPF_K, 4001, 0, 112),
+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, 107, 106), //exit|fork|read|write|open|close
-BPF_JUMP(BPF_JMP|BPF_JGE|BPF_K, 4009, 106, 105), //creat
+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, 4019, 1, 0),
-BPF_JUMP(BPF_JMP|BPF_JGE|BPF_K, 4013, 104, 103), //unlink|execve|chdir
-BPF_JUMP(BPF_JMP|BPF_JGE|BPF_K, 4022, 103, 102), //lseek|getpid|mount
+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, 4033, 3, 0),
 BPF_JUMP(BPF_JMP|BPF_JGE|BPF_K, 4026, 1, 0),
-BPF_JUMP(BPF_JMP|BPF_JGE|BPF_K, 4025, 100, 99), //setuid|getuid
-BPF_JUMP(BPF_JMP|BPF_JGE|BPF_K, 4027, 99, 98), //ptrace
-BPF_JUMP(BPF_JMP|BPF_JGE|BPF_K, 4036, 1, 0),
-BPF_JUMP(BPF_JMP|BPF_JGE|BPF_K, 4034, 97, 96), //access
-BPF_JUMP(BPF_JMP|BPF_JGE|BPF_K, 4040, 96, 95), //sync|kill|rename|mkdir
-BPF_JUMP(BPF_JMP|BPF_JGE|BPF_K, 4057, 7, 0),
-BPF_JUMP(BPF_JMP|BPF_JGE|BPF_K, 4049, 3, 0),
-BPF_JUMP(BPF_JMP|BPF_JGE|BPF_K, 4045, 1, 0),
-BPF_JUMP(BPF_JMP|BPF_JGE|BPF_K, 4044, 92, 91), //dup|pipe|times
-BPF_JUMP(BPF_JMP|BPF_JGE|BPF_K, 4048, 91, 90), //brk|setgid|getgid
-BPF_JUMP(BPF_JMP|BPF_JGE|BPF_K, 4054, 1, 0),
-BPF_JUMP(BPF_JMP|BPF_JGE|BPF_K, 4053, 89, 88), //geteuid|getegid|acct|umount2
-BPF_JUMP(BPF_JMP|BPF_JGE|BPF_K, 4056, 88, 87), //ioctl|fcntl
-BPF_JUMP(BPF_JMP|BPF_JGE|BPF_K, 4063, 3, 0),
-BPF_JUMP(BPF_JMP|BPF_JGE|BPF_K, 4060, 1, 0),
-BPF_JUMP(BPF_JMP|BPF_JGE|BPF_K, 4058, 85, 84), //setpgid
-BPF_JUMP(BPF_JMP|BPF_JGE|BPF_K, 4062, 84, 83), //umask|chroot
-BPF_JUMP(BPF_JMP|BPF_JGE|BPF_K, 4065, 83, 82), //dup2|getppid
-BPF_JUMP(BPF_JMP|BPF_JGE|BPF_K, 4103, 13, 0),
-BPF_JUMP(BPF_JMP|BPF_JGE|BPF_K, 4087, 7, 0),
-BPF_JUMP(BPF_JMP|BPF_JGE|BPF_K, 4074, 3, 0),
-BPF_JUMP(BPF_JMP|BPF_JGE|BPF_K, 4070, 1, 0),
-BPF_JUMP(BPF_JMP|BPF_JGE|BPF_K, 4068, 78, 77), //setsid|sigaction
-BPF_JUMP(BPF_JMP|BPF_JGE|BPF_K, 4072, 77, 76), //setreuid|setregid
-BPF_JUMP(BPF_JMP|BPF_JGE|BPF_K, 4085, 1, 0),
-BPF_JUMP(BPF_JMP|BPF_JGE|BPF_K, 4082, 75, 74), //sethostname|setrlimit|getrlimit|getrusage|gettimeofday|settimeofday|getgroups|setgroups
-BPF_JUMP(BPF_JMP|BPF_JGE|BPF_K, 4086, 74, 73), //readlink
-BPF_JUMP(BPF_JMP|BPF_JGE|BPF_K, 4094, 3, 0),
-BPF_JUMP(BPF_JMP|BPF_JGE|BPF_K, 4090, 1, 0),
-BPF_JUMP(BPF_JMP|BPF_JGE|BPF_K, 4089, 71, 70), //swapon|reboot
-BPF_JUMP(BPF_JMP|BPF_JGE|BPF_K, 4093, 70, 69), //mmap|munmap|truncate
-BPF_JUMP(BPF_JMP|BPF_JGE|BPF_K, 4098, 69, 68), //fchmod|fchown|getpriority|setpriority
-BPF_JUMP(BPF_JMP|BPF_JGE|BPF_K, 4124, 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, 65, 64), //syslog|setitimer|getitimer
-BPF_JUMP(BPF_JMP|BPF_JGE|BPF_K, 4115, 64, 63), //wait4
-BPF_JUMP(BPF_JMP|BPF_JGE|BPF_K, 4118, 1, 0),
-BPF_JUMP(BPF_JMP|BPF_JGE|BPF_K, 4117, 62, 61), //sysinfo
-BPF_JUMP(BPF_JMP|BPF_JGE|BPF_K, 4123, 61, 60), //fsync|sigreturn|clone|setdomainname|uname
-BPF_JUMP(BPF_JMP|BPF_JGE|BPF_K, 4131, 3, 0),
-BPF_JUMP(BPF_JMP|BPF_JGE|BPF_K, 4128, 1, 0),
-BPF_JUMP(BPF_JMP|BPF_JGE|BPF_K, 4126, 58, 57), //adjtimex|mprotect
-BPF_JUMP(BPF_JMP|BPF_JGE|BPF_K, 4130, 57, 56), //init_module|delete_module
-BPF_JUMP(BPF_JMP|BPF_JGE|BPF_K, 4134, 56, 55), //quotactl|getpgid|fchdir
+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, 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, 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, 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, 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, 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, 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, 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, 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, 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, 4248, 27, 0),
-BPF_JUMP(BPF_JMP|BPF_JGE|BPF_K, 4188, 13, 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, 4138, 1, 0),
-BPF_JUMP(BPF_JMP|BPF_JGE|BPF_K, 4137, 50, 49), //personality
-BPF_JUMP(BPF_JMP|BPF_JGE|BPF_K, 4148, 49, 48), //setfsuid|setfsgid|_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, 47, 46), //getsid|fdatasync
-BPF_JUMP(BPF_JMP|BPF_JGE|BPF_K, 4168, 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, 4179, 3, 0),
-BPF_JUMP(BPF_JMP|BPF_JGE|BPF_K, 4176, 1, 0),
-BPF_JUMP(BPF_JMP|BPF_JGE|BPF_K, 4175, 43, 42), //bind|connect|getpeername|getsockname|getsockopt|listen
-BPF_JUMP(BPF_JMP|BPF_JGE|BPF_K, 4178, 42, 41), //recvfrom|recvmsg
-BPF_JUMP(BPF_JMP|BPF_JGE|BPF_K, 4187, 41, 40), //sendmsg|sendto|setsockopt|shutdown|socket|socketpair|setresuid|getresuid
-BPF_JUMP(BPF_JMP|BPF_JGE|BPF_K, 4217, 7, 0),
-BPF_JUMP(BPF_JMP|BPF_JGE|BPF_K, 4203, 3, 0),
-BPF_JUMP(BPF_JMP|BPF_JGE|BPF_K, 4190, 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), //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, 4210, 1, 0),
-BPF_JUMP(BPF_JMP|BPF_JGE|BPF_K, 4208, 34, 33), //getcwd|capget|capset|sigaltstack|sendfile
-BPF_JUMP(BPF_JMP|BPF_JGE|BPF_K, 4216, 33, 32), //mmap2|truncate64|ftruncate64|stat64|lstat64|fstat64
-BPF_JUMP(BPF_JMP|BPF_JGE|BPF_K, 4246, 3, 0),
-BPF_JUMP(BPF_JMP|BPF_JGE|BPF_K, 4222, 1, 0),
-BPF_JUMP(BPF_JMP|BPF_JGE|BPF_K, 4221, 30, 29), //mincore|madvise|getdents64|fcntl64
-BPF_JUMP(BPF_JMP|BPF_JGE|BPF_K, 4241, 29, 28), //gettid|readahead|setxattr|lsetxattr|fsetxattr|getxattr|lgetxattr|fgetxattr|listxattr|llistxattr|flistxattr|removexattr|lremovexattr|fremovexattr|tkill|sendfile64|futex|sched_setaffinity|sched_getaffinity
-BPF_JUMP(BPF_JMP|BPF_JGE|BPF_K, 4247, 28, 27), //exit_group
+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, 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, 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, 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, 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, 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, 4280, 3, 0),
diff --git a/libc/seccomp/x86_64_global_policy.cpp b/libc/seccomp/x86_64_global_policy.cpp
index 71be1c1..801d6c2 100644
--- a/libc/seccomp/x86_64_global_policy.cpp
+++ b/libc/seccomp/x86_64_global_policy.cpp
@@ -5,81 +5,83 @@
 
 #include "seccomp_bpfs.h"
 const sock_filter x86_64_global_filter[] = {
-BPF_JUMP(BPF_JMP|BPF_JGE|BPF_K, 0, 0, 86),
+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),
 BPF_JUMP(BPF_JMP|BPF_JGE|BPF_K, 35, 11, 0),
 BPF_JUMP(BPF_JMP|BPF_JGE|BPF_K, 8, 5, 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, 79, 78), //read|write
-BPF_JUMP(BPF_JMP|BPF_JGE|BPF_K, 4, 78, 77), //close
-BPF_JUMP(BPF_JMP|BPF_JGE|BPF_K, 6, 77, 76), //fstat
+BPF_JUMP(BPF_JMP|BPF_JGE|BPF_K, 2, 81, 80), //read|write
+BPF_JUMP(BPF_JMP|BPF_JGE|BPF_K, 4, 80, 79), //close
+BPF_JUMP(BPF_JMP|BPF_JGE|BPF_K, 6, 79, 78), //fstat
 BPF_JUMP(BPF_JMP|BPF_JGE|BPF_K, 32, 3, 0),
 BPF_JUMP(BPF_JMP|BPF_JGE|BPF_K, 24, 1, 0),
-BPF_JUMP(BPF_JMP|BPF_JGE|BPF_K, 21, 74, 73), //lseek|mmap|mprotect|munmap|brk|rt_sigaction|rt_sigprocmask|rt_sigreturn|ioctl|pread64|pwrite64|readv|writev
-BPF_JUMP(BPF_JMP|BPF_JGE|BPF_K, 29, 73, 72), //sched_yield|mremap|msync|mincore|madvise
-BPF_JUMP(BPF_JMP|BPF_JGE|BPF_K, 33, 72, 71), //dup
+BPF_JUMP(BPF_JMP|BPF_JGE|BPF_K, 21, 76, 75), //lseek|mmap|mprotect|munmap|brk|rt_sigaction|rt_sigprocmask|rt_sigreturn|ioctl|pread64|pwrite64|readv|writev
+BPF_JUMP(BPF_JMP|BPF_JGE|BPF_K, 29, 75, 74), //sched_yield|mremap|msync|mincore|madvise
+BPF_JUMP(BPF_JMP|BPF_JGE|BPF_K, 33, 74, 73), //dup
 BPF_JUMP(BPF_JMP|BPF_JGE|BPF_K, 58, 5, 0),
 BPF_JUMP(BPF_JMP|BPF_JGE|BPF_K, 44, 3, 0),
 BPF_JUMP(BPF_JMP|BPF_JGE|BPF_K, 38, 1, 0),
-BPF_JUMP(BPF_JMP|BPF_JGE|BPF_K, 37, 68, 67), //nanosleep|getitimer
-BPF_JUMP(BPF_JMP|BPF_JGE|BPF_K, 43, 67, 66), //setitimer|getpid|sendfile|socket|connect
-BPF_JUMP(BPF_JMP|BPF_JGE|BPF_K, 57, 66, 65), //sendto|recvfrom|sendmsg|recvmsg|shutdown|bind|listen|getsockname|getpeername|socketpair|setsockopt|getsockopt|clone
+BPF_JUMP(BPF_JMP|BPF_JGE|BPF_K, 37, 70, 69), //nanosleep|getitimer
+BPF_JUMP(BPF_JMP|BPF_JGE|BPF_K, 43, 69, 68), //setitimer|getpid|sendfile|socket|connect
+BPF_JUMP(BPF_JMP|BPF_JGE|BPF_K, 57, 68, 67), //sendto|recvfrom|sendmsg|recvmsg|shutdown|bind|listen|getsockname|getpeername|socketpair|setsockopt|getsockopt|clone
 BPF_JUMP(BPF_JMP|BPF_JGE|BPF_K, 72, 1, 0),
-BPF_JUMP(BPF_JMP|BPF_JGE|BPF_K, 64, 64, 63), //vfork|execve|exit|wait4|kill|uname
-BPF_JUMP(BPF_JMP|BPF_JGE|BPF_K, 78, 63, 62), //fcntl|flock|fsync|fdatasync|truncate|ftruncate
+BPF_JUMP(BPF_JMP|BPF_JGE|BPF_K, 64, 66, 65), //vfork|execve|exit|wait4|kill|uname
+BPF_JUMP(BPF_JMP|BPF_JGE|BPF_K, 78, 65, 64), //fcntl|flock|fsync|fdatasync|truncate|ftruncate
 BPF_JUMP(BPF_JMP|BPF_JGE|BPF_K, 137, 11, 0),
 BPF_JUMP(BPF_JMP|BPF_JGE|BPF_K, 95, 5, 0),
 BPF_JUMP(BPF_JMP|BPF_JGE|BPF_K, 93, 3, 0),
 BPF_JUMP(BPF_JMP|BPF_JGE|BPF_K, 91, 1, 0),
-BPF_JUMP(BPF_JMP|BPF_JGE|BPF_K, 82, 58, 57), //getcwd|chdir|fchdir
-BPF_JUMP(BPF_JMP|BPF_JGE|BPF_K, 92, 57, 56), //fchmod
-BPF_JUMP(BPF_JMP|BPF_JGE|BPF_K, 94, 56, 55), //fchown
+BPF_JUMP(BPF_JMP|BPF_JGE|BPF_K, 82, 60, 59), //getcwd|chdir|fchdir
+BPF_JUMP(BPF_JMP|BPF_JGE|BPF_K, 92, 59, 58), //fchmod
+BPF_JUMP(BPF_JMP|BPF_JGE|BPF_K, 94, 58, 57), //fchown
 BPF_JUMP(BPF_JMP|BPF_JGE|BPF_K, 135, 3, 0),
 BPF_JUMP(BPF_JMP|BPF_JGE|BPF_K, 112, 1, 0),
-BPF_JUMP(BPF_JMP|BPF_JGE|BPF_K, 111, 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, 132, 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, 136, 51, 50), //personality
+BPF_JUMP(BPF_JMP|BPF_JGE|BPF_K, 111, 55, 54), //umask|gettimeofday|getrlimit|getrusage|sysinfo|times|ptrace|getuid|syslog|getgid|setuid|setgid|geteuid|getegid|setpgid|getppid
+BPF_JUMP(BPF_JMP|BPF_JGE|BPF_K, 132, 54, 53), //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, 136, 53, 52), //personality
 BPF_JUMP(BPF_JMP|BPF_JGE|BPF_K, 157, 5, 0),
 BPF_JUMP(BPF_JMP|BPF_JGE|BPF_K, 155, 3, 0),
 BPF_JUMP(BPF_JMP|BPF_JGE|BPF_K, 140, 1, 0),
-BPF_JUMP(BPF_JMP|BPF_JGE|BPF_K, 139, 47, 46), //statfs|fstatfs
-BPF_JUMP(BPF_JMP|BPF_JGE|BPF_K, 153, 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, 156, 45, 44), //pivot_root
+BPF_JUMP(BPF_JMP|BPF_JGE|BPF_K, 139, 49, 48), //statfs|fstatfs
+BPF_JUMP(BPF_JMP|BPF_JGE|BPF_K, 153, 48, 47), //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, 156, 47, 46), //pivot_root
 BPF_JUMP(BPF_JMP|BPF_JGE|BPF_K, 169, 1, 0),
-BPF_JUMP(BPF_JMP|BPF_JGE|BPF_K, 168, 43, 42), //prctl|arch_prctl|adjtimex|setrlimit|chroot|sync|acct|settimeofday|mount|umount2|swapon
-BPF_JUMP(BPF_JMP|BPF_JGE|BPF_K, 172, 42, 41), //reboot|sethostname|setdomainname
-BPF_JUMP(BPF_JMP|BPF_JGE|BPF_K, 262, 21, 0),
-BPF_JUMP(BPF_JMP|BPF_JGE|BPF_K, 233, 11, 0),
+BPF_JUMP(BPF_JMP|BPF_JGE|BPF_K, 168, 45, 44), //prctl|arch_prctl|adjtimex|setrlimit|chroot|sync|acct|settimeofday|mount|umount2|swapon
+BPF_JUMP(BPF_JMP|BPF_JGE|BPF_K, 172, 44, 43), //reboot|sethostname|setdomainname
+BPF_JUMP(BPF_JMP|BPF_JGE|BPF_K, 257, 21, 0),
+BPF_JUMP(BPF_JMP|BPF_JGE|BPF_K, 221, 11, 0),
 BPF_JUMP(BPF_JMP|BPF_JGE|BPF_K, 202, 5, 0),
 BPF_JUMP(BPF_JMP|BPF_JGE|BPF_K, 186, 3, 0),
 BPF_JUMP(BPF_JMP|BPF_JGE|BPF_K, 179, 1, 0),
-BPF_JUMP(BPF_JMP|BPF_JGE|BPF_K, 177, 36, 35), //init_module|delete_module
-BPF_JUMP(BPF_JMP|BPF_JGE|BPF_K, 180, 35, 34), //quotactl
-BPF_JUMP(BPF_JMP|BPF_JGE|BPF_K, 201, 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, 221, 3, 0),
-BPF_JUMP(BPF_JMP|BPF_JGE|BPF_K, 217, 1, 0),
-BPF_JUMP(BPF_JMP|BPF_JGE|BPF_K, 205, 31, 30), //futex|sched_setaffinity|sched_getaffinity
-BPF_JUMP(BPF_JMP|BPF_JGE|BPF_K, 220, 30, 29), //getdents64|set_tid_address|restart_syscall
-BPF_JUMP(BPF_JMP|BPF_JGE|BPF_K, 232, 29, 28), //fadvise64|timer_create|timer_settime|timer_gettime|timer_getoverrun|timer_delete|clock_settime|clock_gettime|clock_getres|clock_nanosleep|exit_group
-BPF_JUMP(BPF_JMP|BPF_JGE|BPF_K, 254, 5, 0),
-BPF_JUMP(BPF_JMP|BPF_JGE|BPF_K, 250, 3, 0),
-BPF_JUMP(BPF_JMP|BPF_JGE|BPF_K, 247, 1, 0),
-BPF_JUMP(BPF_JMP|BPF_JGE|BPF_K, 235, 25, 24), //epoll_ctl|tgkill
-BPF_JUMP(BPF_JMP|BPF_JGE|BPF_K, 249, 24, 23), //waitid|add_key
+BPF_JUMP(BPF_JMP|BPF_JGE|BPF_K, 177, 38, 37), //init_module|delete_module
+BPF_JUMP(BPF_JMP|BPF_JGE|BPF_K, 180, 37, 36), //quotactl
+BPF_JUMP(BPF_JMP|BPF_JGE|BPF_K, 201, 36, 35), //gettid|readahead|setxattr|lsetxattr|fsetxattr|getxattr|lgetxattr|fgetxattr|listxattr|llistxattr|flistxattr|removexattr|lremovexattr|fremovexattr|tkill
+BPF_JUMP(BPF_JMP|BPF_JGE|BPF_K, 217, 3, 0),
+BPF_JUMP(BPF_JMP|BPF_JGE|BPF_K, 206, 1, 0),
+BPF_JUMP(BPF_JMP|BPF_JGE|BPF_K, 205, 33, 32), //futex|sched_setaffinity|sched_getaffinity
+BPF_JUMP(BPF_JMP|BPF_JGE|BPF_K, 211, 32, 31), //io_setup|io_destroy|io_getevents|io_submit|io_cancel
+BPF_JUMP(BPF_JMP|BPF_JGE|BPF_K, 220, 31, 30), //getdents64|set_tid_address|restart_syscall
+BPF_JUMP(BPF_JMP|BPF_JGE|BPF_K, 250, 5, 0),
+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, 27, 26), //fadvise64|timer_create|timer_settime|timer_gettime|timer_getoverrun|timer_delete|clock_settime|clock_gettime|clock_getres|clock_nanosleep|exit_group
+BPF_JUMP(BPF_JMP|BPF_JGE|BPF_K, 235, 26, 25), //epoll_ctl|tgkill
+BPF_JUMP(BPF_JMP|BPF_JGE|BPF_K, 249, 25, 24), //waitid|add_key
+BPF_JUMP(BPF_JMP|BPF_JGE|BPF_K, 254, 1, 0),
 BPF_JUMP(BPF_JMP|BPF_JGE|BPF_K, 253, 23, 22), //keyctl|ioprio_set|ioprio_get
-BPF_JUMP(BPF_JMP|BPF_JGE|BPF_K, 257, 1, 0),
-BPF_JUMP(BPF_JMP|BPF_JGE|BPF_K, 256, 21, 20), //inotify_add_watch|inotify_rm_watch
-BPF_JUMP(BPF_JMP|BPF_JGE|BPF_K, 261, 20, 19), //openat|mkdirat|mknodat|fchownat
-BPF_JUMP(BPF_JMP|BPF_JGE|BPF_K, 302, 9, 0),
-BPF_JUMP(BPF_JMP|BPF_JGE|BPF_K, 283, 5, 0),
-BPF_JUMP(BPF_JMP|BPF_JGE|BPF_K, 280, 3, 0),
-BPF_JUMP(BPF_JMP|BPF_JGE|BPF_K, 275, 1, 0),
-BPF_JUMP(BPF_JMP|BPF_JGE|BPF_K, 273, 15, 14), //newfstatat|unlinkat|renameat|linkat|symlinkat|readlinkat|fchmodat|faccessat|pselect6|ppoll|unshare
-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, 285, 1, 0),
+BPF_JUMP(BPF_JMP|BPF_JGE|BPF_K, 256, 22, 21), //inotify_add_watch|inotify_rm_watch
+BPF_JUMP(BPF_JMP|BPF_JGE|BPF_K, 302, 11, 0),
+BPF_JUMP(BPF_JMP|BPF_JGE|BPF_K, 280, 5, 0),
+BPF_JUMP(BPF_JMP|BPF_JGE|BPF_K, 275, 3, 0),
+BPF_JUMP(BPF_JMP|BPF_JGE|BPF_K, 262, 1, 0),
+BPF_JUMP(BPF_JMP|BPF_JGE|BPF_K, 261, 17, 16), //openat|mkdirat|mknodat|fchownat
+BPF_JUMP(BPF_JMP|BPF_JGE|BPF_K, 273, 16, 15), //newfstatat|unlinkat|renameat|linkat|symlinkat|readlinkat|fchmodat|faccessat|pselect6|ppoll|unshare
+BPF_JUMP(BPF_JMP|BPF_JGE|BPF_K, 279, 15, 14), //splice|tee|sync_file_range|vmsplice
+BPF_JUMP(BPF_JMP|BPF_JGE|BPF_K, 285, 3, 0),
+BPF_JUMP(BPF_JMP|BPF_JGE|BPF_K, 283, 1, 0),
+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),
diff --git a/libc/seccomp/x86_global_policy.cpp b/libc/seccomp/x86_global_policy.cpp
index 36f4884..9305729 100644
--- a/libc/seccomp/x86_global_policy.cpp
+++ b/libc/seccomp/x86_global_policy.cpp
@@ -5,109 +5,111 @@
 
 #include "seccomp_bpfs.h"
 const sock_filter x86_global_filter[] = {
-BPF_JUMP(BPF_JMP|BPF_JGE|BPF_K, 0, 0, 118),
+BPF_JUMP(BPF_JMP|BPF_JGE|BPF_K, 0, 0, 120),
 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, 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, 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, 19, 1, 0),
-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, 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, 33, 3, 0),
 BPF_JUMP(BPF_JMP|BPF_JGE|BPF_K, 26, 1, 0),
-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, 25, 106, 105), //getuid
+BPF_JUMP(BPF_JMP|BPF_JGE|BPF_K, 27, 105, 104), //ptrace
 BPF_JUMP(BPF_JMP|BPF_JGE|BPF_K, 36, 1, 0),
-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, 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, 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, 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, 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, 54, 1, 0),
-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, 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, 63, 3, 0),
 BPF_JUMP(BPF_JMP|BPF_JGE|BPF_K, 60, 1, 0),
-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, 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, 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, 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, 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, 85, 1, 0),
-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, 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, 94, 3, 0),
 BPF_JUMP(BPF_JMP|BPF_JGE|BPF_K, 90, 1, 0),
-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, 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, 96, 1, 0),
-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, 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, 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, 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, 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, 118, 1, 0),
-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, 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, 131, 3, 0),
 BPF_JUMP(BPF_JMP|BPF_JGE|BPF_K, 128, 1, 0),
-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, 286, 29, 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, 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, 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, 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, 168, 1, 0),
-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, 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, 190, 3, 0),
 BPF_JUMP(BPF_JMP|BPF_JGE|BPF_K, 183, 1, 0),
-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, 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, 199, 1, 0),
-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, 254, 7, 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, 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, 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, 252, 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, 253, 33, 32), //exit_group
-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, 30, 29), //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, 29, 28), //fadvise64_64
-BPF_JUMP(BPF_JMP|BPF_JGE|BPF_K, 285, 28, 27), //waitid
-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, 288, 1, 0),
-BPF_JUMP(BPF_JMP|BPF_JGE|BPF_K, 287, 23, 22), //add_key
+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, 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, 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, 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, 291, 1, 0),
 BPF_JUMP(BPF_JMP|BPF_JGE|BPF_K, 289, 22, 21), //keyctl
-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, 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, 350, 7, 0),
diff --git a/libc/stdio/floatio.h b/libc/stdio/floatio.h
deleted file mode 100644
index 9769030..0000000
--- a/libc/stdio/floatio.h
+++ /dev/null
@@ -1,58 +0,0 @@
-/*	$OpenBSD: floatio.h,v 1.4 2008/09/07 20:36:08 martynas Exp $	*/
-
-/*-
- * Copyright (c) 1990, 1993
- *	The Regents of the University of California.  All rights reserved.
- *
- * This code is derived from software contributed to Berkeley by
- * Chris Torek.
- *
- * Redistribution and use in source and binary forms, with or without
- * modification, are permitted provided that the following conditions
- * are met:
- * 1. Redistributions of source code must retain the above copyright
- *    notice, this list of conditions and the following disclaimer.
- * 2. Redistributions in binary form must reproduce the above copyright
- *    notice, this list of conditions and the following disclaimer in the
- *    documentation and/or other materials provided with the distribution.
- * 3. Neither the name of the University nor the names of its contributors
- *    may be used to endorse or promote products derived from this software
- *    without specific prior written permission.
- *
- * THIS SOFTWARE IS PROVIDED BY THE REGENTS AND CONTRIBUTORS ``AS IS'' AND
- * ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE
- * IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE
- * ARE DISCLAIMED.  IN NO EVENT SHALL THE REGENTS OR CONTRIBUTORS BE LIABLE
- * FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL
- * DAMAGES (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS
- * OR SERVICES; LOSS OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION)
- * HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT
- * LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY
- * OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF
- * SUCH DAMAGE.
- */
-
-/*
- * Floating point scanf/printf (input/output) definitions.
- */
-
-/* 11-bit exponent (VAX G floating point) is 308 decimal digits */
-#define	MAXEXP		308
-/* 128 bit fraction takes up 39 decimal digits; max reasonable precision */
-#define	MAXFRACT	39
-
-/*
- * MAXEXPDIG is the maximum number of decimal digits needed to store a
- * floating point exponent in the largest supported format.  It should
- * be ceil(log10(LDBL_MAX_10_EXP)) or, if hexadecimal floating point
- * conversions are supported, ceil(log10(LDBL_MAX_EXP)).  But since it
- * is presently never greater than 5 in practice, we fudge it.
- */
-#define	MAXEXPDIG	6
-#if LDBL_MAX_EXP > 999999
-#error "floating point buffers too small"
-#endif
-
-char *__hdtoa(double, const char *, int, int *, int *, char **);
-char *__hldtoa(long double, const char *, int, int *, int *, char **);
-char *__ldtoa(long double *, int, int, int *, int *, char **);
diff --git a/libc/stdio/fread.c b/libc/stdio/fread.c
deleted file mode 100644
index 7b858ae..0000000
--- a/libc/stdio/fread.c
+++ /dev/null
@@ -1,139 +0,0 @@
-/*	$OpenBSD: fread.c,v 1.12 2014/05/01 16:40:36 deraadt Exp $ */
-/*-
- * Copyright (c) 1990, 1993
- *	The Regents of the University of California.  All rights reserved.
- *
- * This code is derived from software contributed to Berkeley by
- * Chris Torek.
- *
- * Redistribution and use in source and binary forms, with or without
- * modification, are permitted provided that the following conditions
- * are met:
- * 1. Redistributions of source code must retain the above copyright
- *    notice, this list of conditions and the following disclaimer.
- * 2. Redistributions in binary form must reproduce the above copyright
- *    notice, this list of conditions and the following disclaimer in the
- *    documentation and/or other materials provided with the distribution.
- * 3. Neither the name of the University nor the names of its contributors
- *    may be used to endorse or promote products derived from this software
- *    without specific prior written permission.
- *
- * THIS SOFTWARE IS PROVIDED BY THE REGENTS AND CONTRIBUTORS ``AS IS'' AND
- * ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE
- * IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE
- * ARE DISCLAIMED.  IN NO EVENT SHALL THE REGENTS OR CONTRIBUTORS BE LIABLE
- * FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL
- * DAMAGES (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS
- * OR SERVICES; LOSS OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION)
- * HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT
- * LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY
- * OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF
- * SUCH DAMAGE.
- */
-
-#include <stdio.h>
-#include <string.h>
-#include <stdint.h>
-#include <errno.h>
-#include <sys/param.h>
-#include "local.h"
-
-#define MUL_NO_OVERFLOW	(1UL << (sizeof(size_t) * 4))
-
-size_t
-fread(void *buf, size_t size, size_t count, FILE *fp) __overloadable
-{
-	/*
-	 * Extension:  Catch integer overflow.
-	 */
-	if ((size >= MUL_NO_OVERFLOW || count >= MUL_NO_OVERFLOW) &&
-	    size > 0 && SIZE_MAX / size < count) {
-		errno = EOVERFLOW;
-		fp->_flags |= __SERR;
-		return (0);
-	}
-
-	const size_t desired_total = count * size;
-	size_t total = desired_total;
-
-	/*
-	 * ANSI and SUSv2 require a return value of 0 if size or count are 0.
-	 */
-	if (total == 0) {
-		return (0);
-	}
-
-	FLOCKFILE(fp);
-	_SET_ORIENTATION(fp, -1);
-
-	// TODO: how can this ever happen?!
-	if (fp->_r < 0)
-		fp->_r = 0;
-
-	/*
-	 * Ensure _bf._size is valid.
-	 */
-	if (fp->_bf._base == NULL) {
-		__smakebuf(fp);
-	}
-
-	char* dst = buf;
-
-	while (total > 0) {
-		/*
-		 * Copy data out of the buffer.
-		 */
-		size_t buffered_bytes = MIN((size_t) fp->_r, total);
-		memcpy(dst, fp->_p, buffered_bytes);
-		fp->_p += buffered_bytes;
-		fp->_r -= buffered_bytes;
-		dst += buffered_bytes;
-		total -= buffered_bytes;
-
-		/*
-		 * Are we done?
-		 */
-		if (total == 0) {
-			goto out;
-		}
-
-		/*
-		 * Do we have so much more to read that we should
-		 * avoid copying it through the buffer?
-		 */
-		if (total > (size_t) fp->_bf._size) {
-			/*
-			 * Make sure that fseek doesn't think it can
-			 * reuse the buffer since we are going to read
-			 * directly from the file descriptor.
-			 */
-			fp->_flags |= __SMOD;
-			break;
-		}
-
-		/*
-		 * Less than a buffer to go, so refill the buffer and
-		 * go around the loop again.
-		 */
-		if (__srefill(fp)) {
-			goto out;
-		}
-	}
-
-	/*
-	 * Read directly into the caller's buffer.
-	 */
-	while (total > 0) {
-		ssize_t bytes_read = (*fp->_read)(fp->_cookie, dst, total);
-		if (bytes_read <= 0) {
-			fp->_flags |= (bytes_read == 0) ? __SEOF : __SERR;
-			break;
-		}
-		dst += bytes_read;
-		total -= bytes_read;
-	}
-
-out:
-	FUNLOCKFILE(fp);
-	return ((desired_total - total) / size);
-}
diff --git a/libc/stdio/local.h b/libc/stdio/local.h
index bf6a8f8..0ff0785 100644
--- a/libc/stdio/local.h
+++ b/libc/stdio/local.h
@@ -38,6 +38,11 @@
 #include <pthread.h>
 #include <stdbool.h>
 #include <wchar.h>
+
+#if defined(__cplusplus) // Until we fork all of stdio...
+#include "private/bionic_fortify.h"
+#endif
+
 #include "wcio.h"
 
 /*
@@ -140,11 +145,12 @@
 // #define __SOPT 0x0400 --- historical (do fseek() optimization).
 // #define __SNPT 0x0800 --- historical (do not do fseek() optimization).
 // #define __SOFF 0x1000 --- historical (set iff _offset is in fact correct).
-#define __SMOD 0x2000  // true => fgetln modified _p text.
+// #define __SMOD 0x2000 --- historical (set iff fgetln modified _p text).
 #define __SALC 0x4000  // Allocate string space dynamically.
 #define __SIGN 0x8000  // Ignore this file in _fwalk.
 
 // TODO: remove remaining references to these obsolete flags (see above).
+#define __SMOD 0
 #define __SNPT 0
 #define __SOPT 0
 
@@ -228,9 +234,6 @@
 #define FLOCKFILE(fp)   if (!_EXT(fp)->_caller_handles_locking) flockfile(fp)
 #define FUNLOCKFILE(fp) if (!_EXT(fp)->_caller_handles_locking) funlockfile(fp)
 
-#define FLOATING_POINT
-#define PRINTF_WIDE_CHAR
-#define SCANF_WIDE_CHAR
 #define NO_PRINTF_PERCENT_N
 
 /* OpenBSD exposes these in <stdio.h>, but we only want them exposed to the implementation. */
@@ -238,10 +241,18 @@
 #define __sclearerr(p) ((void)((p)->_flags &= ~(__SERR|__SEOF)))
 #define __sgetc(p) (--(p)->_r < 0 ? __srget(p) : (int)(*(p)->_p++))
 
-/* OpenBSD declares these in fvwrite.h but we want to ensure they're hidden. */
-struct __suio;
-extern int __sfvwrite(FILE *, struct __suio *);
-wint_t __fputwc_unlock(wchar_t wc, FILE *fp);
+/* OpenBSD declares these in fvwrite.h, but we share them with C++ parts of the implementation. */
+struct __siov {
+  void* iov_base;
+  size_t iov_len;
+};
+struct __suio {
+  struct __siov* uio_iov;
+  int uio_iovcnt;
+  size_t uio_resid;
+};
+int __sfvwrite(FILE*, struct __suio*);
+wint_t __fputwc_unlock(wchar_t wc, FILE* fp);
 
 /* Remove the if (!__sdidinit) __sinit() idiom from untouched upstream stdio code. */
 extern void __sinit(void); // Not actually implemented.
@@ -250,6 +261,35 @@
 size_t parsefloat(FILE*, char*, char*);
 size_t wparsefloat(FILE*, wchar_t*, wchar_t*);
 
+// Sanity check a FILE* for nullptr, so we can emit a message while crashing
+// instead of doing a blind null-dereference.
+#define CHECK_FP(fp) if (fp == nullptr) __fortify_fatal("%s: null FILE*", __FUNCTION__)
+
+/*
+ * Floating point scanf/printf (input/output) definitions.
+ */
+
+/* 11-bit exponent (VAX G floating point) is 308 decimal digits */
+#define MAXEXP 308
+/* 128 bit fraction takes up 39 decimal digits; max reasonable precision */
+#define MAXFRACT 39
+
+/*
+ * MAXEXPDIG is the maximum number of decimal digits needed to store a
+ * floating point exponent in the largest supported format.  It should
+ * be ceil(log10(LDBL_MAX_10_EXP)) or, if hexadecimal floating point
+ * conversions are supported, ceil(log10(LDBL_MAX_EXP)).  But since it
+ * is presently never greater than 5 in practice, we fudge it.
+ */
+#define MAXEXPDIG 6
+#if LDBL_MAX_EXP > 999999
+#error "floating point buffers too small"
+#endif
+
+char* __hdtoa(double, const char*, int, int*, int*, char**);
+char* __hldtoa(long double, const char*, int, int*, int*, char**);
+char* __ldtoa(long double*, int, int, int*, int*, char**);
+
 __END_DECLS
 
 #endif
diff --git a/libc/stdio/parsefloat.c b/libc/stdio/parsefloat.c
index e911da4..d81e713 100644
--- a/libc/stdio/parsefloat.c
+++ b/libc/stdio/parsefloat.c
@@ -34,7 +34,6 @@
 #include <stdlib.h>
 
 #include "local.h"
-#include "floatio.h"
 
 #define	BUF		513	/* Maximum length of numeric string. */
 
diff --git a/libc/stdio/printf_common.h b/libc/stdio/printf_common.h
new file mode 100644
index 0000000..050120e
--- /dev/null
+++ b/libc/stdio/printf_common.h
@@ -0,0 +1,828 @@
+/*-
+ * Copyright (c) 1990 The Regents of the University of California.
+ * All rights reserved.
+ *
+ * This code is derived from software contributed to Berkeley by
+ * Chris Torek.
+ *
+ * Redistribution and use in source and binary forms, with or without
+ * modification, are permitted provided that the following conditions
+ * are met:
+ * 1. Redistributions of source code must retain the above copyright
+ *    notice, this list of conditions and the following disclaimer.
+ * 2. Redistributions in binary form must reproduce the above copyright
+ *    notice, this list of conditions and the following disclaimer in the
+ *    documentation and/or other materials provided with the distribution.
+ * 3. Neither the name of the University nor the names of its contributors
+ *    may be used to endorse or promote products derived from this software
+ *    without specific prior written permission.
+ *
+ * THIS SOFTWARE IS PROVIDED BY THE REGENTS AND CONTRIBUTORS ``AS IS'' AND
+ * ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE
+ * IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE
+ * ARE DISCLAIMED.  IN NO EVENT SHALL THE REGENTS OR CONTRIBUTORS BE LIABLE
+ * FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL
+ * DAMAGES (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS
+ * OR SERVICES; LOSS OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION)
+ * HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT
+ * LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY
+ * OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF
+ * SUCH DAMAGE.
+ */
+
+#include <sys/mman.h>
+#include <sys/types.h>
+
+#include <errno.h>
+#include <float.h>
+#include <langinfo.h>
+#include <limits.h>
+#include <locale.h>
+#include <math.h>
+#include <stdarg.h>
+#include <stddef.h>
+#include <stdint.h>
+#include <stdio.h>
+#include <stdlib.h>
+#include <string.h>
+#include <unistd.h>
+#include <wchar.h>
+
+#include "fvwrite.h"
+#include "gdtoa.h"
+#include "local.h"
+
+union arg {
+  int intarg;
+  unsigned int uintarg;
+  long longarg;
+  unsigned long ulongarg;
+  long long longlongarg;
+  unsigned long long ulonglongarg;
+  ptrdiff_t ptrdiffarg;
+  size_t sizearg;
+  ssize_t ssizearg;
+  intmax_t intmaxarg;
+  uintmax_t uintmaxarg;
+  void* pvoidarg;
+  char* pchararg;
+  signed char* pschararg;
+  short* pshortarg;
+  int* pintarg;
+  long* plongarg;
+  long long* plonglongarg;
+  ptrdiff_t* pptrdiffarg;
+  ssize_t* pssizearg;
+  intmax_t* pintmaxarg;
+  double doublearg;
+  long double longdoublearg;
+  wint_t wintarg;
+  wchar_t* pwchararg;
+};
+
+// Helper function for `fprintf to unbuffered unix file': creates a
+// temporary buffer.  We only work on write-only files; this avoids
+// worries about ungetc buffers and so forth.
+static int __sbprintf(FILE* fp, const CHAR_TYPE* fmt, va_list ap) {
+  FILE fake;
+  struct __sfileext fakeext;
+  unsigned char buf[BUFSIZ];
+
+  _FILEEXT_SETUP(&fake, &fakeext);
+  /* copy the important variables */
+  fake._flags = fp->_flags & ~__SNBF;
+  fake._file = fp->_file;
+  fake._cookie = fp->_cookie;
+  fake._write = fp->_write;
+
+  /* set up the buffer */
+  fake._bf._base = fake._p = buf;
+  fake._bf._size = fake._w = sizeof(buf);
+  fake._lbfsize = 0; /* not actually used, but Just In Case */
+
+  /* do the work, then copy any error status */
+  int ret = FUNCTION_NAME(&fake, fmt, ap);
+  if (ret >= 0 && __sflush(&fake)) ret = EOF;
+  if (fake._flags & __SERR) fp->_flags |= __SERR;
+  return ret;
+}
+
+static int __find_arguments(const CHAR_TYPE* fmt0, va_list ap, union arg** argtable, size_t* argtablesiz);
+static int __grow_type_table(unsigned char** typetable, int* tablesize);
+
+#define DEFPREC 6
+
+#define to_digit(c) ((c) - '0')
+#define is_digit(c) ((unsigned)to_digit(c) <= 9)
+#define to_char(n) ((CHAR_TYPE)((n) + '0'))
+
+template <typename CharT>
+static int exponent(CharT* p0, int exp, int fmtch) {
+  CharT* p = p0;
+  *p++ = fmtch;
+  if (exp < 0) {
+    exp = -exp;
+    *p++ = '-';
+  } else {
+    *p++ = '+';
+  }
+
+  CharT expbuf[MAXEXPDIG];
+  CharT* t = expbuf + MAXEXPDIG;
+  if (exp > 9) {
+    do {
+      *--t = to_char(exp % 10);
+    } while ((exp /= 10) > 9);
+    *--t = to_char(exp);
+    for (; t < expbuf + MAXEXPDIG; *p++ = *t++) /* nothing */;
+  } else {
+    /*
+     * Exponents for decimal floating point conversions
+     * (%[eEgG]) must be at least two characters long,
+     * whereas exponents for hexadecimal conversions can
+     * be only one character long.
+     */
+    if (fmtch == 'e' || fmtch == 'E') *p++ = '0';
+    *p++ = to_char(exp);
+  }
+  return (p - p0);
+}
+
+#define PAD(howmany, with)     \
+  do {                         \
+    if ((n = (howmany)) > 0) { \
+      while (n > PADSIZE) {    \
+        PRINT(with, PADSIZE);  \
+        n -= PADSIZE;          \
+      }                        \
+      PRINT(with, n);          \
+    }                          \
+  } while (0)
+
+#define PRINTANDPAD(p, ep, len, with)       \
+  do {                                      \
+    n2 = (ep) - (p);                        \
+    if (n2 > (len)) n2 = (len);             \
+    if (n2 > 0) PRINT((p), n2);             \
+    PAD((len) - (n2 > 0 ? n2 : 0), (with)); \
+  } while (0)
+
+/*
+ * The size of the buffer we use as scratch space for integer
+ * conversions, among other things.  Technically, we would need the
+ * most space for base 10 conversions with thousands' grouping
+ * characters between each pair of digits.  100 bytes is a
+ * conservative overestimate even for a 128-bit uintmax_t.
+ */
+#define BUF 100
+
+#define STATIC_ARG_TBL_SIZE 8 /* Size of static argument table. */
+
+/*
+ * Flags used during conversion.
+ */
+#define ALT 0x0001      /* alternate form */
+#define LADJUST 0x0004  /* left adjustment */
+#define LONGDBL 0x0008  /* long double */
+#define LONGINT 0x0010  /* long integer */
+#define LLONGINT 0x0020 /* long long integer */
+#define SHORTINT 0x0040 /* short integer */
+#define ZEROPAD 0x0080  /* zero (as opposed to blank) pad */
+#define FPT 0x0100      /* Floating point number */
+#define PTRINT 0x0200   /* (unsigned) ptrdiff_t */
+#define SIZEINT 0x0400  /* (signed) size_t */
+#define CHARINT 0x0800  /* 8 bit integer */
+#define MAXINT 0x1000   /* largest integer size (intmax_t) */
+
+/*
+ * Type ids for argument type table.
+ */
+#define T_UNUSED 0
+#define T_SHORT 1
+#define T_U_SHORT 2
+#define TP_SHORT 3
+#define T_INT 4
+#define T_U_INT 5
+#define TP_INT 6
+#define T_LONG 7
+#define T_U_LONG 8
+#define TP_LONG 9
+#define T_LLONG 10
+#define T_U_LLONG 11
+#define TP_LLONG 12
+#define T_DOUBLE 13
+#define T_LONG_DOUBLE 14
+#define TP_CHAR 15
+#define TP_VOID 16
+#define T_PTRINT 17
+#define TP_PTRINT 18
+#define T_SIZEINT 19
+#define T_SSIZEINT 20
+#define TP_SSIZEINT 21
+#define T_MAXINT 22
+#define T_MAXUINT 23
+#define TP_MAXINT 24
+#define T_CHAR 25
+#define T_U_CHAR 26
+#define T_WINT 27
+#define TP_WCHAR 28
+
+// To extend shorts properly, we need both signed and unsigned
+// argument extraction methods.
+#define SARG()                                                                               \
+  ((intmax_t)(flags & MAXINT                                                                 \
+                  ? GETARG(intmax_t)                                                         \
+                  : flags & LLONGINT                                                         \
+                        ? GETARG(long long)                                                  \
+                        : flags & LONGINT                                                    \
+                              ? GETARG(long)                                                 \
+                              : flags & PTRINT                                               \
+                                    ? GETARG(ptrdiff_t)                                      \
+                                    : flags & SIZEINT                                        \
+                                          ? GETARG(ssize_t)                                  \
+                                          : flags & SHORTINT                                 \
+                                                ? (short)GETARG(int)                         \
+                                                : flags & CHARINT ? (signed char)GETARG(int) \
+                                                                  : GETARG(int)))
+#define UARG()                                                                                \
+  ((uintmax_t)(flags & MAXINT                                                                 \
+                   ? GETARG(uintmax_t)                                                        \
+                   : flags & LLONGINT                                                         \
+                         ? GETARG(unsigned long long)                                         \
+                         : flags & LONGINT                                                    \
+                               ? GETARG(unsigned long)                                        \
+                               : flags & PTRINT ? (uintptr_t)GETARG(ptrdiff_t) : /* XXX */    \
+                                     flags & SIZEINT                                          \
+                                         ? GETARG(size_t)                                     \
+                                         : flags & SHORTINT                                   \
+                                               ? (unsigned short)GETARG(int)                  \
+                                               : flags & CHARINT ? (unsigned char)GETARG(int) \
+                                                                 : GETARG(unsigned int)))
+
+// Append a digit to a value and check for overflow.
+#define APPEND_DIGIT(val, dig)                            \
+  do {                                                    \
+    if ((val) > INT_MAX / 10) goto overflow;              \
+    (val) *= 10;                                          \
+    if ((val) > INT_MAX - to_digit((dig))) goto overflow; \
+    (val) += to_digit((dig));                             \
+  } while (0)
+
+// Get * arguments, including the form *nn$.  Preserve the nextarg
+// that the argument can be gotten once the type is determined.
+#define GETASTER(val)                                                     \
+  n2 = 0;                                                                 \
+  cp = fmt;                                                               \
+  while (is_digit(*cp)) {                                                 \
+    APPEND_DIGIT(n2, *cp);                                                \
+    cp++;                                                                 \
+  }                                                                       \
+  if (*cp == '$') {                                                       \
+    int hold = nextarg;                                                   \
+    if (argtable == NULL) {                                               \
+      argtable = statargtable;                                            \
+      if (__find_arguments(fmt0, orgap, &argtable, &argtablesiz) == -1) { \
+        ret = -1;                                                         \
+        goto error;                                                       \
+      }                                                                   \
+    }                                                                     \
+    nextarg = n2;                                                         \
+    val = GETARG(int);                                                    \
+    nextarg = hold;                                                       \
+    fmt = ++cp;                                                           \
+  } else {                                                                \
+    val = GETARG(int);                                                    \
+  }
+
+// Get the argument indexed by nextarg.   If the argument table is
+// built, use it to get the argument.  If its not, get the next
+// argument (and arguments must be gotten sequentially).
+#define GETARG(type) \
+  ((argtable != NULL) ? *((type*)(&argtable[nextarg++])) : (nextarg++, va_arg(ap, type)))
+
+/*
+ * Find all arguments when a positional parameter is encountered.  Returns a
+ * table, indexed by argument number, of pointers to each arguments.  The
+ * initial argument table should be an array of STATIC_ARG_TBL_SIZE entries.
+ * It will be replaced with a mmap-ed one if it overflows (malloc cannot be
+ * used since we are attempting to make snprintf thread safe, and alloca is
+ * problematic since we have nested functions..)
+ */
+static int __find_arguments(const CHAR_TYPE* fmt0, va_list ap, union arg** argtable,
+                            size_t* argtablesiz) {
+  int ch;                   /* character from fmt */
+  int n, n2;                /* handy integer (short term usage) */
+  int flags;                /* flags as above */
+  unsigned char* typetable; /* table of types */
+  unsigned char stattypetable[STATIC_ARG_TBL_SIZE];
+  int tablesize; /* current size of type table */
+  int tablemax;  /* largest used index in table */
+  int nextarg;   /* 1-based argument index */
+  int ret = 0;   /* return value */
+
+  /*
+   * Add an argument type to the table, expanding if necessary.
+   */
+#define ADDTYPE(type)                                                      \
+  ((nextarg >= tablesize) ? __grow_type_table(&typetable, &tablesize) : 0, \
+   (nextarg > tablemax) ? tablemax = nextarg : 0, typetable[nextarg++] = type)
+
+#define ADDSARG()                                                                             \
+  ((flags & MAXINT)                                                                           \
+       ? ADDTYPE(T_MAXINT)                                                                    \
+       : ((flags & PTRINT) ? ADDTYPE(T_PTRINT)                                                \
+                           : ((flags & SIZEINT)                                               \
+                                  ? ADDTYPE(T_SSIZEINT)                                       \
+                                  : ((flags & LLONGINT)                                       \
+                                         ? ADDTYPE(T_LLONG)                                   \
+                                         : ((flags & LONGINT)                                 \
+                                                ? ADDTYPE(T_LONG)                             \
+                                                : ((flags & SHORTINT)                         \
+                                                       ? ADDTYPE(T_SHORT)                     \
+                                                       : ((flags & CHARINT) ? ADDTYPE(T_CHAR) \
+                                                                            : ADDTYPE(T_INT))))))))
+
+#define ADDUARG()                                                                  \
+  ((flags & MAXINT)                                                                \
+       ? ADDTYPE(T_MAXUINT)                                                        \
+       : ((flags & PTRINT)                                                         \
+              ? ADDTYPE(T_PTRINT)                                                  \
+              : ((flags & SIZEINT)                                                 \
+                     ? ADDTYPE(T_SIZEINT)                                          \
+                     : ((flags & LLONGINT)                                         \
+                            ? ADDTYPE(T_U_LLONG)                                   \
+                            : ((flags & LONGINT)                                   \
+                                   ? ADDTYPE(T_U_LONG)                             \
+                                   : ((flags & SHORTINT)                           \
+                                          ? ADDTYPE(T_U_SHORT)                     \
+                                          : ((flags & CHARINT) ? ADDTYPE(T_U_CHAR) \
+                                                               : ADDTYPE(T_U_INT))))))))
+
+  /*
+   * Add * arguments to the type array.
+   */
+#define ADDASTER()         \
+  n2 = 0;                  \
+  cp = fmt;                \
+  while (is_digit(*cp)) {  \
+    APPEND_DIGIT(n2, *cp); \
+    cp++;                  \
+  }                        \
+  if (*cp == '$') {        \
+    int hold = nextarg;    \
+    nextarg = n2;          \
+    ADDTYPE(T_INT);        \
+    nextarg = hold;        \
+    fmt = ++cp;            \
+  } else {                 \
+    ADDTYPE(T_INT);        \
+  }
+  CHAR_TYPE* fmt = const_cast<CHAR_TYPE*>(fmt0);
+  CHAR_TYPE* cp;
+  typetable = stattypetable;
+  tablesize = STATIC_ARG_TBL_SIZE;
+  tablemax = 0;
+  nextarg = 1;
+  memset(typetable, T_UNUSED, STATIC_ARG_TBL_SIZE);
+
+  /*
+   * Scan the format for conversions (`%' character).
+   */
+  for (;;) {
+    for (cp = fmt; (ch = *fmt) != '\0' && ch != '%'; fmt++) continue;
+    if (ch == '\0') goto done;
+    fmt++; /* skip over '%' */
+
+    flags = 0;
+
+  rflag:
+    ch = *fmt++;
+  reswitch:
+    switch (ch) {
+      case ' ':
+      case '#':
+      case '\'':
+        goto rflag;
+      case '*':
+        ADDASTER();
+        goto rflag;
+      case '-':
+      case '+':
+        goto rflag;
+      case '.':
+        if ((ch = *fmt++) == '*') {
+          ADDASTER();
+          goto rflag;
+        }
+        while (is_digit(ch)) {
+          ch = *fmt++;
+        }
+        goto reswitch;
+      case '0':
+        goto rflag;
+      case '1':
+      case '2':
+      case '3':
+      case '4':
+      case '5':
+      case '6':
+      case '7':
+      case '8':
+      case '9':
+        n = 0;
+        do {
+          APPEND_DIGIT(n, ch);
+          ch = *fmt++;
+        } while (is_digit(ch));
+        if (ch == '$') {
+          nextarg = n;
+          goto rflag;
+        }
+        goto reswitch;
+      case 'L':
+        flags |= LONGDBL;
+        goto rflag;
+      case 'h':
+        if (*fmt == 'h') {
+          fmt++;
+          flags |= CHARINT;
+        } else {
+          flags |= SHORTINT;
+        }
+        goto rflag;
+      case 'j':
+        flags |= MAXINT;
+        goto rflag;
+      case 'l':
+        if (*fmt == 'l') {
+          fmt++;
+          flags |= LLONGINT;
+        } else {
+          flags |= LONGINT;
+        }
+        goto rflag;
+      case 'q':
+        flags |= LLONGINT;
+        goto rflag;
+      case 't':
+        flags |= PTRINT;
+        goto rflag;
+      case 'z':
+        flags |= SIZEINT;
+        goto rflag;
+      case 'C':
+        flags |= LONGINT;
+        /*FALLTHROUGH*/
+      case 'c':
+        if (flags & LONGINT)
+          ADDTYPE(T_WINT);
+        else
+          ADDTYPE(T_INT);
+        break;
+      case 'D':
+        flags |= LONGINT;
+        /*FALLTHROUGH*/
+      case 'd':
+      case 'i':
+        ADDSARG();
+        break;
+      case 'a':
+      case 'A':
+      case 'e':
+      case 'E':
+      case 'f':
+      case 'F':
+      case 'g':
+      case 'G':
+        if (flags & LONGDBL)
+          ADDTYPE(T_LONG_DOUBLE);
+        else
+          ADDTYPE(T_DOUBLE);
+        break;
+#ifndef NO_PRINTF_PERCENT_N
+      case 'n':
+        if (flags & LLONGINT)
+          ADDTYPE(TP_LLONG);
+        else if (flags & LONGINT)
+          ADDTYPE(TP_LONG);
+        else if (flags & SHORTINT)
+          ADDTYPE(TP_SHORT);
+        else if (flags & PTRINT)
+          ADDTYPE(TP_PTRINT);
+        else if (flags & SIZEINT)
+          ADDTYPE(TP_SSIZEINT);
+        else if (flags & MAXINT)
+          ADDTYPE(TP_MAXINT);
+        else
+          ADDTYPE(TP_INT);
+        continue; /* no output */
+#endif            /* NO_PRINTF_PERCENT_N */
+      case 'O':
+        flags |= LONGINT;
+        /*FALLTHROUGH*/
+      case 'o':
+        ADDUARG();
+        break;
+      case 'p':
+        ADDTYPE(TP_VOID);
+        break;
+      case 'S':
+        flags |= LONGINT;
+        /*FALLTHROUGH*/
+      case 's':
+        ADDTYPE((flags & LONGINT) ? TP_WCHAR : TP_CHAR);
+        break;
+      case 'U':
+        flags |= LONGINT;
+        /*FALLTHROUGH*/
+      case 'u':
+      case 'X':
+      case 'x':
+        ADDUARG();
+        break;
+      default: /* "%?" prints ?, unless ? is NUL */
+        if (ch == '\0') goto done;
+        break;
+    }
+  }
+done:
+  /*
+   * Build the argument table.
+   */
+  if (tablemax >= STATIC_ARG_TBL_SIZE) {
+    *argtablesiz = sizeof(union arg) * (tablemax + 1);
+    *argtable = static_cast<arg*>(mmap(NULL, *argtablesiz,
+                                       PROT_WRITE | PROT_READ,
+                                       MAP_ANON | MAP_PRIVATE, -1, 0));
+    if (*argtable == MAP_FAILED) return -1;
+  }
+
+  for (n = 1; n <= tablemax; n++) {
+    switch (typetable[n]) {
+      case T_UNUSED:
+      case T_CHAR:
+      case T_U_CHAR:
+      case T_SHORT:
+      case T_U_SHORT:
+      case T_INT:
+        (*argtable)[n].intarg = va_arg(ap, int);
+        break;
+      case TP_SHORT:
+        (*argtable)[n].pshortarg = va_arg(ap, short*);
+        break;
+      case T_U_INT:
+        (*argtable)[n].uintarg = va_arg(ap, unsigned int);
+        break;
+      case TP_INT:
+        (*argtable)[n].pintarg = va_arg(ap, int*);
+        break;
+      case T_LONG:
+        (*argtable)[n].longarg = va_arg(ap, long);
+        break;
+      case T_U_LONG:
+        (*argtable)[n].ulongarg = va_arg(ap, unsigned long);
+        break;
+      case TP_LONG:
+        (*argtable)[n].plongarg = va_arg(ap, long*);
+        break;
+      case T_LLONG:
+        (*argtable)[n].longlongarg = va_arg(ap, long long);
+        break;
+      case T_U_LLONG:
+        (*argtable)[n].ulonglongarg = va_arg(ap, unsigned long long);
+        break;
+      case TP_LLONG:
+        (*argtable)[n].plonglongarg = va_arg(ap, long long*);
+        break;
+      case T_DOUBLE:
+        (*argtable)[n].doublearg = va_arg(ap, double);
+        break;
+      case T_LONG_DOUBLE:
+        (*argtable)[n].longdoublearg = va_arg(ap, long double);
+        break;
+      case TP_CHAR:
+        (*argtable)[n].pchararg = va_arg(ap, char*);
+        break;
+      case TP_VOID:
+        (*argtable)[n].pvoidarg = va_arg(ap, void*);
+        break;
+      case T_PTRINT:
+        (*argtable)[n].ptrdiffarg = va_arg(ap, ptrdiff_t);
+        break;
+      case TP_PTRINT:
+        (*argtable)[n].pptrdiffarg = va_arg(ap, ptrdiff_t*);
+        break;
+      case T_SIZEINT:
+        (*argtable)[n].sizearg = va_arg(ap, size_t);
+        break;
+      case T_SSIZEINT:
+        (*argtable)[n].ssizearg = va_arg(ap, ssize_t);
+        break;
+      case TP_SSIZEINT:
+        (*argtable)[n].pssizearg = va_arg(ap, ssize_t*);
+        break;
+      case T_MAXINT:
+        (*argtable)[n].intmaxarg = va_arg(ap, intmax_t);
+        break;
+      case T_MAXUINT:
+        (*argtable)[n].uintmaxarg = va_arg(ap, uintmax_t);
+        break;
+      case TP_MAXINT:
+        (*argtable)[n].pintmaxarg = va_arg(ap, intmax_t*);
+        break;
+      case T_WINT:
+        (*argtable)[n].wintarg = va_arg(ap, wint_t);
+        break;
+      case TP_WCHAR:
+        (*argtable)[n].pwchararg = va_arg(ap, wchar_t*);
+        break;
+    }
+  }
+  goto finish;
+
+overflow:
+  errno = ENOMEM;
+  ret = -1;
+
+finish:
+  if (typetable != NULL && typetable != stattypetable) {
+    munmap(typetable, *argtablesiz);
+    typetable = NULL;
+  }
+  return (ret);
+}
+
+/*
+ * Increase the size of the type table.
+ */
+static int __grow_type_table(unsigned char** typetable, int* tablesize) {
+  unsigned char* old_table = *typetable;
+  int new_size = *tablesize * 2;
+
+  if (new_size < getpagesize()) new_size = getpagesize();
+
+  if (*tablesize == STATIC_ARG_TBL_SIZE) {
+    *typetable = static_cast<unsigned char*>(mmap(NULL, new_size,
+                                                  PROT_WRITE | PROT_READ,
+                                                  MAP_ANON | MAP_PRIVATE, -1, 0));
+    if (*typetable == MAP_FAILED) return -1;
+    bcopy(old_table, *typetable, *tablesize);
+  } else {
+    unsigned char* new_table = static_cast<unsigned char*>(mmap(NULL, new_size,
+                                                                PROT_WRITE | PROT_READ,
+                                                                MAP_ANON | MAP_PRIVATE, -1, 0));
+    if (new_table == MAP_FAILED) return -1;
+    memmove(new_table, *typetable, *tablesize);
+    munmap(*typetable, *tablesize);
+    *typetable = new_table;
+  }
+  memset(*typetable + *tablesize, T_UNUSED, (new_size - *tablesize));
+
+  *tablesize = new_size;
+  return 0;
+}
+
+struct helpers {
+  // Flush out all the vectors defined by the given uio,
+  // then reset it so that it can be reused.
+  static int sprint(FILE* fp, struct __suio* uio) {
+    if (uio->uio_resid == 0) {
+      uio->uio_iovcnt = 0;
+      return 0;
+    }
+    int result = __sfvwrite(fp, uio);
+    uio->uio_resid = 0;
+    uio->uio_iovcnt = 0;
+    return result;
+  }
+
+  // Convert a wide character string argument for the %ls format to a multibyte
+  // string representation. If not -1, prec specifies the maximum number of
+  // bytes to output, and also means that we can't assume that the wide char
+  // string is null-terminated.
+  static char* wcsconv(wchar_t* wcsarg, int prec) {
+    mbstate_t mbs;
+    char buf[MB_LEN_MAX];
+    wchar_t* p;
+    char* convbuf;
+    size_t clen, nbytes;
+
+    // Allocate space for the maximum number of bytes we could output.
+    if (prec < 0) {
+      memset(&mbs, 0, sizeof(mbs));
+      p = wcsarg;
+      nbytes = wcsrtombs(NULL, (const wchar_t**)&p, 0, &mbs);
+      if (nbytes == (size_t)-1) return NULL;
+    } else {
+      // Optimisation: if the output precision is small enough,
+      // just allocate enough memory for the maximum instead of
+      // scanning the string.
+      if (prec < 128) {
+        nbytes = prec;
+      } else {
+        nbytes = 0;
+        p = wcsarg;
+        memset(&mbs, 0, sizeof(mbs));
+        for (;;) {
+          clen = wcrtomb(buf, *p++, &mbs);
+          if (clen == 0 || clen == (size_t)-1 || nbytes + clen > (size_t)prec) break;
+          nbytes += clen;
+        }
+        if (clen == (size_t)-1) return NULL;
+      }
+    }
+    if ((convbuf = static_cast<char*>(malloc(nbytes + 1))) == NULL) return NULL;
+
+    // Fill the output buffer.
+    p = wcsarg;
+    memset(&mbs, 0, sizeof(mbs));
+    if ((nbytes = wcsrtombs(convbuf, (const wchar_t**)&p, nbytes, &mbs)) == (size_t)-1) {
+      free(convbuf);
+      return NULL;
+    }
+    convbuf[nbytes] = '\0';
+    return convbuf;
+  }
+
+  // Like __fputwc_unlock, but handles fake string (__SSTR) files properly.
+  // File must already be locked.
+  static wint_t xfputwc(wchar_t wc, FILE* fp) {
+    if ((fp->_flags & __SSTR) == 0) return __fputwc_unlock(wc, fp);
+
+    char buf[MB_LEN_MAX];
+    mbstate_t mbs = {};
+    size_t len = wcrtomb(buf, wc, &mbs);
+    if (len == (size_t)-1) {
+      fp->_flags |= __SERR;
+      errno = EILSEQ;
+      return WEOF;
+    }
+
+    struct __siov iov;
+    iov.iov_base = buf;
+    iov.iov_len = len;
+    struct __suio uio;
+    uio.uio_iov = &iov;
+    uio.uio_resid = len;
+    uio.uio_iovcnt = 1;
+    return (__sfvwrite(fp, &uio) != EOF ? (wint_t)wc : WEOF);
+  }
+
+  // Convert a multibyte character string argument for the %s format to a wide
+  // string representation. ``prec'' specifies the maximum number of bytes
+  // to output. If ``prec'' is greater than or equal to zero, we can't assume
+  // that the multibyte character string ends in a null character.
+  //
+  // Returns NULL on failure.
+  // To find out what happened check errno for ENOMEM, EILSEQ and EINVAL.
+  static wchar_t* mbsconv(char* mbsarg, int prec) {
+    mbstate_t mbs;
+    const char* p;
+    size_t insize, nchars, nconv;
+
+    if (mbsarg == NULL) return NULL;
+
+    // Supplied argument is a multibyte string; convert it to wide characters first.
+    if (prec >= 0) {
+      // String is not guaranteed to be NUL-terminated. Find the number of characters to print.
+      p = mbsarg;
+      insize = nchars = nconv = 0;
+      bzero(&mbs, sizeof(mbs));
+      while (nchars != (size_t)prec) {
+        nconv = mbrlen(p, MB_CUR_MAX, &mbs);
+        if (nconv == (size_t)0 || nconv == (size_t)-1 || nconv == (size_t)-2) break;
+        p += nconv;
+        nchars++;
+        insize += nconv;
+      }
+      if (nconv == (size_t)-1 || nconv == (size_t)-2) return (NULL);
+    } else {
+      insize = strlen(mbsarg);
+    }
+
+    // Allocate buffer for the result and perform the conversion,
+    // converting at most `size' bytes of the input multibyte string to
+    // wide characters for printing.
+    wchar_t* convbuf = static_cast<wchar_t*>(calloc(insize + 1, sizeof(*convbuf)));
+    if (convbuf == NULL) return NULL;
+    wchar_t* wcp = convbuf;
+    p = mbsarg;
+    bzero(&mbs, sizeof(mbs));
+    nconv = 0;
+    while (insize != 0) {
+      nconv = mbrtowc(wcp, p, insize, &mbs);
+      if (nconv == 0 || nconv == (size_t)-1 || nconv == (size_t)-2) break;
+      wcp++;
+      p += nconv;
+      insize -= nconv;
+    }
+    if (nconv == (size_t)-1 || nconv == (size_t)-2) {
+      free(convbuf);
+      return NULL;
+    }
+    *wcp = '\0';
+
+    return convbuf;
+  }
+
+};
diff --git a/libc/stdio/refill.c b/libc/stdio/refill.c
index a7c4bff..1df4191 100644
--- a/libc/stdio/refill.c
+++ b/libc/stdio/refill.c
@@ -111,7 +111,6 @@
 	}
 	fp->_p = fp->_bf._base;
 	fp->_r = (*fp->_read)(fp->_cookie, (char *)fp->_p, fp->_bf._size);
-	fp->_flags &= ~__SMOD;	/* buffer contents are again pristine */
 	if (fp->_r <= 0) {
 		if (fp->_r == 0)
 			fp->_flags |= __SEOF;
diff --git a/libc/stdio/stdio.cpp b/libc/stdio/stdio.cpp
index 4d6438b..d627556 100644
--- a/libc/stdio/stdio.cpp
+++ b/libc/stdio/stdio.cpp
@@ -44,6 +44,8 @@
 #include <sys/stat.h>
 #include <unistd.h>
 
+#include <async_safe/log.h>
+
 #include "local.h"
 #include "glue.h"
 #include "private/bionic_fortify.h"
@@ -89,7 +91,7 @@
 FILE* stdout = &__sF[1];
 FILE* stderr = &__sF[2];
 
-struct glue __sglue = { NULL, 3, __sF };
+struct glue __sglue = { nullptr, 3, __sF };
 static struct glue* lastglue = &__sglue;
 
 class ScopedFileLock {
@@ -114,7 +116,7 @@
   glue* g = reinterpret_cast<glue*>(data);
   FILE* p = reinterpret_cast<FILE*>(ALIGN(data + sizeof(*g)));
   __sfileext* pext = reinterpret_cast<__sfileext*>(ALIGN(data + sizeof(*g)) + n * sizeof(FILE));
-  g->next = NULL;
+  g->next = nullptr;
   g->niobs = n;
   g->iobs = p;
   while (--n >= 0) {
@@ -142,7 +144,7 @@
 	struct glue *g;
 
 	_THREAD_PRIVATE_MUTEX_LOCK(__sfp_mutex);
-	for (g = &__sglue; g != NULL; g = g->next) {
+	for (g = &__sglue; g != nullptr; g = g->next) {
 		for (fp = g->iobs, n = g->niobs; --n >= 0; fp++)
 			if (fp->_flags == 0)
 				goto found;
@@ -150,8 +152,7 @@
 
 	/* release lock while mallocing */
 	_THREAD_PRIVATE_MUTEX_UNLOCK(__sfp_mutex);
-	if ((g = moreglue(NDYNAMIC)) == NULL)
-		return (NULL);
+	if ((g = moreglue(NDYNAMIC)) == nullptr) return nullptr;
 	_THREAD_PRIVATE_MUTEX_LOCK(__sfp_mutex);
 	lastglue->next = g;
 	lastglue = g;
@@ -159,15 +160,15 @@
 found:
 	fp->_flags = 1;		/* reserve this slot; caller sets real flags */
 	_THREAD_PRIVATE_MUTEX_UNLOCK(__sfp_mutex);
-	fp->_p = NULL;		/* no current pointer */
+	fp->_p = nullptr;		/* no current pointer */
 	fp->_w = 0;		/* nothing to read or write */
 	fp->_r = 0;
-	fp->_bf._base = NULL;	/* no buffer */
+	fp->_bf._base = nullptr;	/* no buffer */
 	fp->_bf._size = 0;
 	fp->_lbfsize = 0;	/* not line buffered */
 	fp->_file = -1;		/* no file */
 
-	fp->_lb._base = NULL;	/* no line buffer */
+	fp->_lb._base = nullptr;	/* no line buffer */
 	fp->_lb._size = 0;
 	_FILEEXT_INIT(fp);
 
@@ -261,6 +262,7 @@
 // all possible, no matter what.
 // TODO: rewrite this mess completely.
 FILE* freopen(const char* file, const char* mode, FILE* fp) {
+  CHECK_FP(fp);
   int mode_flags;
   int flags = __sflags(mode, &mode_flags);
   if (flags == 0) {
@@ -285,8 +287,8 @@
     // Flush the stream; ANSI doesn't require this.
     if (fp->_flags & __SWR) __sflush(fp);
 
-    // If close is NULL, closing is a no-op, hence pointless.
-    isopen = fp->_close != NULL;
+    // If close is null, closing is a no-op, hence pointless.
+    isopen = (fp->_close != nullptr);
     if ((wantfd = fp->_file) < 0 && isopen) {
         (*fp->_close)(fp->_cookie);
         isopen = 0;
@@ -313,8 +315,8 @@
   if (fp->_flags & __SMBF) free(fp->_bf._base);
   fp->_w = 0;
   fp->_r = 0;
-  fp->_p = NULL;
-  fp->_bf._base = NULL;
+  fp->_p = nullptr;
+  fp->_bf._base = nullptr;
   fp->_bf._size = 0;
   fp->_lbfsize = 0;
   if (HASUB(fp)) FREEUB(fp);
@@ -361,6 +363,7 @@
 __strong_alias(freopen64, freopen);
 
 int fclose(FILE* fp) {
+  CHECK_FP(fp);
   if (fp->_flags == 0) {
     // Already freed!
     errno = EBADF;
@@ -370,7 +373,7 @@
   ScopedFileLock sfl(fp);
   WCIO_FREE(fp);
   int r = fp->_flags & __SWR ? __sflush(fp) : 0;
-  if (fp->_close != NULL && (*fp->_close)(fp->_cookie) < 0) {
+  if (fp->_close != nullptr && (*fp->_close)(fp->_cookie) < 0) {
     r = EOF;
   }
   if (fp->_flags & __SMBF) free(fp->_bf._base);
@@ -387,6 +390,7 @@
 }
 
 int fileno_unlocked(FILE* fp) {
+  CHECK_FP(fp);
   int fd = fp->_file;
   if (fd == -1) {
     errno = EBADF;
@@ -396,6 +400,7 @@
 }
 
 int fileno(FILE* fp) {
+  CHECK_FP(fp);
   ScopedFileLock sfl(fp);
   return fileno_unlocked(fp);
 }
@@ -405,28 +410,63 @@
 }
 
 void clearerr(FILE* fp) {
+  CHECK_FP(fp);
   ScopedFileLock sfl(fp);
   clearerr_unlocked(fp);
 }
 
 int feof_unlocked(FILE* fp) {
+  CHECK_FP(fp);
   return ((fp->_flags & __SEOF) != 0);
 }
 
 int feof(FILE* fp) {
+  CHECK_FP(fp);
   ScopedFileLock sfl(fp);
   return feof_unlocked(fp);
 }
 
 int ferror_unlocked(FILE* fp) {
+  CHECK_FP(fp);
   return __sferror(fp);
 }
 
 int ferror(FILE* fp) {
+  CHECK_FP(fp);
   ScopedFileLock sfl(fp);
   return ferror_unlocked(fp);
 }
 
+int __sflush(FILE* fp) {
+  // Flushing a read-only file is a no-op.
+  if ((fp->_flags & __SWR) == 0) return 0;
+
+  // Flushing a file without a buffer is a no-op.
+  unsigned char* p = fp->_bf._base;
+  if (p == nullptr) return 0;
+
+  // Set these immediately to avoid problems with longjmp and to allow
+  // exchange buffering (via setvbuf) in user write function.
+  int n = fp->_p - p;
+  fp->_p = p;
+  fp->_w = (fp->_flags & (__SLBF|__SNBF)) ? 0 : fp->_bf._size;
+
+  while (n > 0) {
+    int written = (*fp->_write)(fp->_cookie, reinterpret_cast<char*>(p), n);
+    if (written <= 0) {
+      fp->_flags |= __SERR;
+      return EOF;
+    }
+    n -= written, p += written;
+  }
+  return 0;
+}
+
+int __sflush_locked(FILE* fp) {
+  ScopedFileLock sfl(fp);
+  return __sflush(fp);
+}
+
 int __sread(void* cookie, char* buf, int n) {
   FILE* fp = reinterpret_cast<FILE*>(cookie);
   return TEMP_FAILURE_RETRY(read(fp->_file, buf, n));
@@ -484,7 +524,7 @@
     // smaller than that in the underlying object.
     result -= fp->_r;
     if (HASUB(fp)) result -= fp->_ur;
-  } else if (fp->_flags & __SWR && fp->_p != NULL) {
+  } else if (fp->_flags & __SWR && fp->_p != nullptr) {
     // Writing.  Any buffered characters cause the
     // position to be greater than that in the
     // underlying object.
@@ -516,7 +556,7 @@
     return -1;
   }
 
-  if (fp->_bf._base == NULL) __smakebuf(fp);
+  if (fp->_bf._base == nullptr) __smakebuf(fp);
 
   // Flush unwritten data and attempt the seek.
   if (__sflush(fp) || __seek_unlocked(fp, offset, whence) == -1) {
@@ -533,24 +573,29 @@
 }
 
 int fseeko(FILE* fp, off_t offset, int whence) {
+  CHECK_FP(fp);
   static_assert(sizeof(off_t) == sizeof(long), "sizeof(off_t) != sizeof(long)");
   return __fseeko64(fp, offset, whence, 8*sizeof(off_t));
 }
 __strong_alias(fseek, fseeko);
 
 int fseeko64(FILE* fp, off64_t offset, int whence) {
-  return __fseeko64(fp, offset, whence, 8*sizeof(off_t));
+  CHECK_FP(fp);
+  return __fseeko64(fp, offset, whence, 8*sizeof(off64_t));
 }
 
 int fsetpos(FILE* fp, const fpos_t* pos) {
+  CHECK_FP(fp);
   return fseeko(fp, *pos, SEEK_SET);
 }
 
 int fsetpos64(FILE* fp, const fpos64_t* pos) {
+  CHECK_FP(fp);
   return fseeko64(fp, *pos, SEEK_SET);
 }
 
 off_t ftello(FILE* fp) {
+  CHECK_FP(fp);
   static_assert(sizeof(off_t) == sizeof(long), "sizeof(off_t) != sizeof(long)");
   off64_t result = ftello64(fp);
   if (result > LONG_MAX) {
@@ -562,16 +607,19 @@
 __strong_alias(ftell, ftello);
 
 off64_t ftello64(FILE* fp) {
+  CHECK_FP(fp);
   ScopedFileLock sfl(fp);
   return __ftello64_unlocked(fp);
 }
 
 int fgetpos(FILE* fp, fpos_t* pos) {
+  CHECK_FP(fp);
   *pos = ftello(fp);
   return (*pos == -1) ? -1 : 0;
 }
 
 int fgetpos64(FILE* fp, fpos64_t* pos) {
+  CHECK_FP(fp);
   *pos = ftello64(fp);
   return (*pos == -1) ? -1 : 0;
 }
@@ -642,35 +690,122 @@
 }
 
 int fprintf(FILE* fp, const char* fmt, ...) {
+  CHECK_FP(fp);
   PRINTF_IMPL(vfprintf(fp, fmt, ap));
 }
 
 int fgetc(FILE* fp) {
+  CHECK_FP(fp);
   return getc(fp);
 }
 
+int fgetc_unlocked(FILE* fp) {
+  CHECK_FP(fp);
+  return getc_unlocked(fp);
+}
+
+/*
+ * Read at most n-1 characters from the given file.
+ * Stop when a newline has been read, or the count runs out.
+ * Return first argument, or NULL if no characters were read.
+ * Do not return NULL if n == 1.
+ */
+char* fgets(char* buf, int n, FILE* fp) __overloadable {
+  CHECK_FP(fp);
+  ScopedFileLock sfl(fp);
+  return fgets_unlocked(buf, n, fp);
+}
+
+char* fgets_unlocked(char* buf, int n, FILE* fp) {
+  if (n <= 0) {
+    errno = EINVAL;
+    return nullptr;
+  }
+
+  _SET_ORIENTATION(fp, -1);
+
+  char* s = buf;
+  n--; // Leave space for NUL.
+  while (n != 0) {
+    // If the buffer is empty, refill it.
+    if (fp->_r <= 0) {
+      if (__srefill(fp)) {
+        // EOF/error: stop with partial or no line.
+        if (s == buf) return nullptr;
+        break;
+      }
+    }
+    size_t len = fp->_r;
+    unsigned char* p = fp->_p;
+
+    // Scan through at most n bytes of the current buffer,
+    // looking for '\n'.  If found, copy up to and including
+    // newline, and stop.  Otherwise, copy entire chunk and loop.
+    if (len > static_cast<size_t>(n)) len = n;
+    unsigned char* t = static_cast<unsigned char*>(memchr(p, '\n', len));
+    if (t != nullptr) {
+      len = ++t - p;
+      fp->_r -= len;
+      fp->_p = t;
+      memcpy(s, p, len);
+      s[len] = '\0';
+      return buf;
+    }
+    fp->_r -= len;
+    fp->_p += len;
+    memcpy(s, p, len);
+    s += len;
+    n -= len;
+  }
+  *s = '\0';
+  return buf;
+}
+
 int fputc(int c, FILE* fp) {
+  CHECK_FP(fp);
   return putc(c, fp);
 }
 
+int fputc_unlocked(int c, FILE* fp) {
+  CHECK_FP(fp);
+  return putc_unlocked(c, fp);
+}
+
+int fputs(const char* s, FILE* fp) {
+  CHECK_FP(fp);
+  ScopedFileLock sfl(fp);
+  return fputs_unlocked(s, fp);
+}
+
+int fputs_unlocked(const char* s, FILE* fp) {
+  CHECK_FP(fp);
+  size_t length = strlen(s);
+  return (fwrite_unlocked(s, 1, length, fp) == length) ? 0 : EOF;
+}
+
 int fscanf(FILE* fp, const char* fmt, ...) {
+  CHECK_FP(fp);
   PRINTF_IMPL(vfscanf(fp, fmt, ap));
 }
 
 int fwprintf(FILE* fp, const wchar_t* fmt, ...) {
+  CHECK_FP(fp);
   PRINTF_IMPL(vfwprintf(fp, fmt, ap));
 }
 
 int fwscanf(FILE* fp, const wchar_t* fmt, ...) {
+  CHECK_FP(fp);
   PRINTF_IMPL(vfwscanf(fp, fmt, ap));
 }
 
 int getc(FILE* fp) {
+  CHECK_FP(fp);
   ScopedFileLock sfl(fp);
   return getc_unlocked(fp);
 }
 
 int getc_unlocked(FILE* fp) {
+  CHECK_FP(fp);
   return __sgetc(fp);
 }
 
@@ -683,10 +818,12 @@
 }
 
 ssize_t getline(char** buf, size_t* len, FILE* fp) {
+  CHECK_FP(fp);
   return getdelim(buf, len, '\n', fp);
 }
 
 wint_t getwc(FILE* fp) {
+  CHECK_FP(fp);
   return fgetwc(fp);
 }
 
@@ -694,16 +831,23 @@
   return fgetwc(stdin);
 }
 
+void perror(const char* msg) {
+  if (msg == nullptr) msg = "";
+  fprintf(stderr, "%s%s%s\n", msg, (*msg == '\0') ? "" : ": ", strerror(errno));
+}
+
 int printf(const char* fmt, ...) {
   PRINTF_IMPL(vfprintf(stdout, fmt, ap));
 }
 
 int putc(int c, FILE* fp) {
+  CHECK_FP(fp);
   ScopedFileLock sfl(fp);
   return putc_unlocked(c, fp);
 }
 
 int putc_unlocked(int c, FILE* fp) {
+  CHECK_FP(fp);
   if (cantwrite(fp)) {
     errno = EBADF;
     return EOF;
@@ -723,7 +867,15 @@
   return putc_unlocked(c, stdout);
 }
 
+int puts(const char* s) {
+  size_t length = strlen(s);
+  ScopedFileLock sfl(stdout);
+  return (fwrite_unlocked(s, 1, length, stdout) == length &&
+          putc_unlocked('\n', stdout) != EOF) ? 0 : EOF;
+}
+
 wint_t putwc(wchar_t wc, FILE* fp) {
+  CHECK_FP(fp);
   return fputwc(wc, fp);
 }
 
@@ -738,6 +890,7 @@
 }
 
 void rewind(FILE* fp) {
+  CHECK_FP(fp);
   ScopedFileLock sfl(fp);
   fseek(fp, 0, SEEK_SET);
   clearerr_unlocked(fp);
@@ -748,14 +901,17 @@
 }
 
 void setbuf(FILE* fp, char* buf) {
+  CHECK_FP(fp);
   setbuffer(fp, buf, BUFSIZ);
 }
 
 void setbuffer(FILE* fp, char* buf, int size) {
+  CHECK_FP(fp);
   setvbuf(fp, buf, buf ? _IOFBF : _IONBF, size);
 }
 
 int setlinebuf(FILE* fp) {
+  CHECK_FP(fp);
   return setvbuf(fp, nullptr, _IOLBF, 0);
 }
 
@@ -779,6 +935,26 @@
   PRINTF_IMPL(vswscanf(s, fmt, ap));
 }
 
+int vfprintf(FILE* fp, const char* fmt, va_list ap) {
+  ScopedFileLock sfl(fp);
+  return __vfprintf(fp, fmt, ap);
+}
+
+int vfscanf(FILE* fp, const char* fmt, va_list ap) {
+  ScopedFileLock sfl(fp);
+  return __svfscanf(fp, fmt, ap);
+}
+
+int vfwprintf(FILE* fp, const wchar_t* fmt, va_list ap) {
+  ScopedFileLock sfl(fp);
+  return __vfwprintf(fp, fmt, ap);
+}
+
+int vfwscanf(FILE* fp, const wchar_t* fmt, va_list ap) {
+  ScopedFileLock sfl(fp);
+  return __vfwscanf(fp, fmt, ap);
+}
+
 int vprintf(const char* fmt, va_list ap) {
   return vfprintf(stdout, fmt, ap);
 }
@@ -833,6 +1009,116 @@
   PRINTF_IMPL(vfwscanf(stdin, fmt, ap));
 }
 
+static int fflush_all() {
+  return _fwalk(__sflush_locked);
+}
+
+int fflush(FILE* fp) {
+  if (fp == nullptr) return fflush_all();
+  ScopedFileLock sfl(fp);
+  return fflush_unlocked(fp);
+}
+
+int fflush_unlocked(FILE* fp) {
+  if (fp == nullptr) return fflush_all();
+  if ((fp->_flags & (__SWR | __SRW)) == 0) {
+    errno = EBADF;
+    return EOF;
+  }
+  return __sflush(fp);
+}
+
+size_t fread(void* buf, size_t size, size_t count, FILE* fp) __overloadable {
+  CHECK_FP(fp);
+  ScopedFileLock sfl(fp);
+  return fread_unlocked(buf, size, count, fp);
+}
+
+size_t fread_unlocked(void* buf, size_t size, size_t count, FILE* fp) {
+  CHECK_FP(fp);
+
+  size_t desired_total;
+  if (__builtin_mul_overflow(size, count, &desired_total)) {
+    errno = EOVERFLOW;
+    fp->_flags |= __SERR;
+    return 0;
+  }
+
+  size_t total = desired_total;
+  if (total == 0) return 0;
+
+  _SET_ORIENTATION(fp, -1);
+
+  // TODO: how can this ever happen?!
+  if (fp->_r < 0) fp->_r = 0;
+
+  // Ensure _bf._size is valid.
+  if (fp->_bf._base == nullptr) __smakebuf(fp);
+
+  char* dst = static_cast<char*>(buf);
+
+  while (total > 0) {
+    // Copy data out of the buffer.
+    size_t buffered_bytes = MIN(static_cast<size_t>(fp->_r), total);
+    memcpy(dst, fp->_p, buffered_bytes);
+    fp->_p += buffered_bytes;
+    fp->_r -= buffered_bytes;
+    dst += buffered_bytes;
+    total -= buffered_bytes;
+
+    // Are we done?
+    if (total == 0) goto out;
+
+    // Do we have so much more to read that we should avoid copying it through the buffer?
+    if (total > static_cast<size_t>(fp->_bf._size)) break;
+
+    // Less than a buffer to go, so refill the buffer and go around the loop again.
+    if (__srefill(fp)) goto out;
+  }
+
+  // Read directly into the caller's buffer.
+  while (total > 0) {
+    ssize_t bytes_read = (*fp->_read)(fp->_cookie, dst, total);
+    if (bytes_read <= 0) {
+      fp->_flags |= (bytes_read == 0) ? __SEOF : __SERR;
+      break;
+    }
+    dst += bytes_read;
+    total -= bytes_read;
+  }
+
+out:
+  return ((desired_total - total) / size);
+}
+
+size_t fwrite(const void* buf, size_t size, size_t count, FILE* fp) {
+  CHECK_FP(fp);
+  ScopedFileLock sfl(fp);
+  return fwrite_unlocked(buf, size, count, fp);
+}
+
+size_t fwrite_unlocked(const void* buf, size_t size, size_t count, FILE* fp) {
+  CHECK_FP(fp);
+
+  size_t n;
+  if (__builtin_mul_overflow(size, count, &n)) {
+    errno = EOVERFLOW;
+    fp->_flags |= __SERR;
+    return 0;
+  }
+
+  if (n == 0) return 0;
+
+  __siov iov = { .iov_base = const_cast<void*>(buf), .iov_len = n };
+  __suio uio = { .uio_iov = &iov, .uio_iovcnt = 1, .uio_resid = n };
+
+  _SET_ORIENTATION(fp, -1);
+
+  // The usual case is success (__sfvwrite returns 0); skip the divide if this happens,
+  // since divides are generally slow.
+  return (__sfvwrite(fp, &uio) == 0) ? count : ((n - uio.uio_resid) / size);
+}
+
 namespace {
 
 namespace phony {
diff --git a/libc/stdio/vfprintf.cpp b/libc/stdio/vfprintf.cpp
new file mode 100644
index 0000000..9182880
--- /dev/null
+++ b/libc/stdio/vfprintf.cpp
@@ -0,0 +1,702 @@
+/*	$OpenBSD: vfprintf.c,v 1.71 2016/01/04 15:47:47 schwarze Exp $	*/
+/*-
+ * Copyright (c) 1990 The Regents of the University of California.
+ * All rights reserved.
+ *
+ * This code is derived from software contributed to Berkeley by
+ * Chris Torek.
+ *
+ * Redistribution and use in source and binary forms, with or without
+ * modification, are permitted provided that the following conditions
+ * are met:
+ * 1. Redistributions of source code must retain the above copyright
+ *    notice, this list of conditions and the following disclaimer.
+ * 2. Redistributions in binary form must reproduce the above copyright
+ *    notice, this list of conditions and the following disclaimer in the
+ *    documentation and/or other materials provided with the distribution.
+ * 3. Neither the name of the University nor the names of its contributors
+ *    may be used to endorse or promote products derived from this software
+ *    without specific prior written permission.
+ *
+ * THIS SOFTWARE IS PROVIDED BY THE REGENTS AND CONTRIBUTORS ``AS IS'' AND
+ * ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE
+ * IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE
+ * ARE DISCLAIMED.  IN NO EVENT SHALL THE REGENTS OR CONTRIBUTORS BE LIABLE
+ * FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL
+ * DAMAGES (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS
+ * OR SERVICES; LOSS OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION)
+ * HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT
+ * LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY
+ * OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF
+ * SUCH DAMAGE.
+ */
+
+#define CHAR_TYPE char
+#define FUNCTION_NAME __vfprintf
+#define CHAR_TYPE_STRLEN strlen
+#define CHAR_TYPE_STRNLEN strnlen
+#define CHAR_TYPE_INF "INF"
+#define CHAR_TYPE_inf "inf"
+#define CHAR_TYPE_NAN "NAN"
+#define CHAR_TYPE_nan "nan"
+#define CHAR_TYPE_ORIENTATION -1
+#include "printf_common.h"
+
+int FUNCTION_NAME(FILE* fp, const CHAR_TYPE* fmt0, va_list ap) {
+  int n, n2;
+  CHAR_TYPE* cp;            /* handy char pointer (short term usage) */
+  CHAR_TYPE sign;           /* sign prefix (' ', '+', '-', or \0) */
+  int flags;           /* flags as above */
+  int ret;             /* return value accumulator */
+  int width;           /* width from format (%8d), or 0 */
+  int prec;            /* precision from format; <0 for N/A */
+  /*
+   * We can decompose the printed representation of floating
+   * point numbers into several parts, some of which may be empty:
+   *
+   * [+|-| ] [0x|0X] MMM . NNN [e|E|p|P] [+|-] ZZ
+   *    A       B     ---C---      D       E   F
+   *
+   * A:	'sign' holds this value if present; '\0' otherwise
+   * B:	ox[1] holds the 'x' or 'X'; '\0' if not hexadecimal
+   * C:	cp points to the string MMMNNN.  Leading and trailing
+   *	zeros are not in the string and must be added.
+   * D:	expchar holds this character; '\0' if no exponent, e.g. %f
+   * F:	at least two digits for decimal, at least one digit for hex
+   */
+  char* decimal_point = NULL;
+  int signflag; /* true if float is negative */
+  union {       /* floating point arguments %[aAeEfFgG] */
+    double dbl;
+    long double ldbl;
+  } fparg;
+  int expt;                   /* integer value of exponent */
+  char expchar;               /* exponent character: [eEpP\0] */
+  char* dtoaend;              /* pointer to end of converted digits */
+  int expsize;                /* character count for expstr */
+  int lead;                   /* sig figs before decimal or group sep */
+  int ndig;                   /* actual number of digits returned by dtoa */
+  CHAR_TYPE expstr[MAXEXPDIG + 2]; /* buffer for exponent string: e+ZZZ */
+  char* dtoaresult = NULL;
+
+  uintmax_t _umax;             /* integer arguments %[diouxX] */
+  enum { OCT, DEC, HEX } base; /* base for %[diouxX] conversion */
+  int dprec;                   /* a copy of prec if %[diouxX], 0 otherwise */
+  int realsz;                  /* field size expanded by dprec */
+  int size;                    /* size of converted field or string */
+  const char* xdigs;           /* digits for %[xX] conversion */
+#define NIOV 8
+  struct __suio uio;       /* output information: summary */
+  struct __siov iov[NIOV]; /* ... and individual io vectors */
+  struct __siov* iovp; /* for PRINT macro */
+  CHAR_TYPE buf[BUF];           /* buffer with space for digits of uintmax_t */
+  CHAR_TYPE ox[2];              /* space for 0x; ox[1] is either x, X, or \0 */
+  union arg* argtable;     /* args, built due to positional arg */
+  union arg statargtable[STATIC_ARG_TBL_SIZE];
+  size_t argtablesiz;
+  int nextarg;   /* 1-based argument index */
+  va_list orgap; /* original argument pointer */
+  CHAR_TYPE* convbuf; /* buffer for wide/multibyte conversion */
+
+  /*
+   * Choose PADSIZE to trade efficiency vs. size.  If larger printf
+   * fields occur frequently, increase PADSIZE and make the initialisers
+   * below longer.
+   */
+#define PADSIZE 16 /* pad chunk size */
+  static CHAR_TYPE blanks[PADSIZE] = {
+    ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' '
+  };
+  static CHAR_TYPE zeroes[PADSIZE] = {
+    '0', '0', '0', '0', '0', '0', '0', '0', '0', '0', '0', '0', '0', '0', '0', '0'
+  };
+
+  static const char xdigs_lower[] = "0123456789abcdef";
+  static const char xdigs_upper[] = "0123456789ABCDEF";
+
+#define PRINT(ptr, len)                   \
+  do {                                    \
+    iovp->iov_base = (ptr);               \
+    iovp->iov_len = (len);                \
+    uio.uio_resid += (len);               \
+    iovp++;                               \
+    if (++uio.uio_iovcnt >= NIOV) {       \
+      if (helpers::sprint(fp, &uio)) goto error; \
+      iovp = iov;                         \
+    }                                     \
+  } while (0)
+#define FLUSH()                                          \
+  do {                                                   \
+    if (uio.uio_resid && helpers::sprint(fp, &uio)) goto error; \
+    uio.uio_iovcnt = 0;                                  \
+    iovp = iov;                                          \
+  } while (0)
+
+  _SET_ORIENTATION(fp, CHAR_TYPE_ORIENTATION);
+
+  // Writing "" to a read only file returns EOF, not 0.
+  if (cantwrite(fp)) {
+    errno = EBADF;
+    return EOF;
+  }
+
+  // Optimize writes to stderr and other unbuffered files).
+  if ((fp->_flags & (__SNBF | __SWR | __SRW)) == (__SNBF | __SWR) && fp->_file >= 0) {
+    return (__sbprintf(fp, fmt0, ap));
+  }
+
+  CHAR_TYPE* fmt = const_cast<CHAR_TYPE*>(fmt0);
+  argtable = NULL;
+  nextarg = 1;
+  va_copy(orgap, ap);
+  uio.uio_iov = iovp = iov;
+  uio.uio_resid = 0;
+  uio.uio_iovcnt = 0;
+  ret = 0;
+  convbuf = NULL;
+
+  /*
+   * Scan the format for conversions (`%' character).
+   */
+  for (;;) {
+    int ch;
+    for (cp = fmt; (ch = *fmt) != '\0' && ch != '%'; fmt++) continue;
+    if (fmt != cp) {
+      ptrdiff_t m = fmt - cp;
+      if (m < 0 || m > INT_MAX - ret) goto overflow;
+      PRINT(cp, m);
+      ret += m;
+    }
+    if (ch == '\0') goto done;
+    fmt++; /* skip over '%' */
+
+    flags = 0;
+    dprec = 0;
+    width = 0;
+    prec = -1;
+    sign = '\0';
+    ox[1] = '\0';
+
+  rflag:
+    ch = *fmt++;
+  reswitch:
+    switch (ch) {
+      case ' ':
+        /*
+         * ``If the space and + flags both appear, the space
+         * flag will be ignored.''
+         *	-- ANSI X3J11
+         */
+        if (!sign) sign = ' ';
+        goto rflag;
+      case '#':
+        flags |= ALT;
+        goto rflag;
+      case '\'':
+        /* grouping not implemented */
+        goto rflag;
+      case '*':
+        /*
+         * ``A negative field width argument is taken as a
+         * - flag followed by a positive field width.''
+         *	-- ANSI X3J11
+         * They don't exclude field widths read from args.
+         */
+        GETASTER(width);
+        if (width >= 0) goto rflag;
+        if (width == INT_MIN) goto overflow;
+        width = -width;
+        /* FALLTHROUGH */
+      case '-':
+        flags |= LADJUST;
+        goto rflag;
+      case '+':
+        sign = '+';
+        goto rflag;
+      case '.':
+        if ((ch = *fmt++) == '*') {
+          GETASTER(n);
+          prec = n < 0 ? -1 : n;
+          goto rflag;
+        }
+        n = 0;
+        while (is_digit(ch)) {
+          APPEND_DIGIT(n, ch);
+          ch = *fmt++;
+        }
+        if (ch == '$') {
+          nextarg = n;
+          if (argtable == NULL) {
+            argtable = statargtable;
+            if (__find_arguments(fmt0, orgap, &argtable, &argtablesiz) == -1) {
+              ret = -1;
+              goto error;
+            }
+          }
+          goto rflag;
+        }
+        prec = n;
+        goto reswitch;
+      case '0':
+        /*
+         * ``Note that 0 is taken as a flag, not as the
+         * beginning of a field width.''
+         *	-- ANSI X3J11
+         */
+        flags |= ZEROPAD;
+        goto rflag;
+      case '1':
+      case '2':
+      case '3':
+      case '4':
+      case '5':
+      case '6':
+      case '7':
+      case '8':
+      case '9':
+        n = 0;
+        do {
+          APPEND_DIGIT(n, ch);
+          ch = *fmt++;
+        } while (is_digit(ch));
+        if (ch == '$') {
+          nextarg = n;
+          if (argtable == NULL) {
+            argtable = statargtable;
+            if (__find_arguments(fmt0, orgap, &argtable, &argtablesiz) == -1) {
+              ret = -1;
+              goto error;
+            }
+          }
+          goto rflag;
+        }
+        width = n;
+        goto reswitch;
+      case 'L':
+        flags |= LONGDBL;
+        goto rflag;
+      case 'h':
+        if (*fmt == 'h') {
+          fmt++;
+          flags |= CHARINT;
+        } else {
+          flags |= SHORTINT;
+        }
+        goto rflag;
+      case 'j':
+        flags |= MAXINT;
+        goto rflag;
+      case 'l':
+        if (*fmt == 'l') {
+          fmt++;
+          flags |= LLONGINT;
+        } else {
+          flags |= LONGINT;
+        }
+        goto rflag;
+      case 'q':
+        flags |= LLONGINT;
+        goto rflag;
+      case 't':
+        flags |= PTRINT;
+        goto rflag;
+      case 'z':
+        flags |= SIZEINT;
+        goto rflag;
+      case 'C':
+        flags |= LONGINT;
+        /*FALLTHROUGH*/
+      case 'c':
+        if (flags & LONGINT) {
+          mbstate_t mbs;
+          size_t mbseqlen;
+
+          memset(&mbs, 0, sizeof(mbs));
+          mbseqlen = wcrtomb(buf, (wchar_t)GETARG(wint_t), &mbs);
+          if (mbseqlen == (size_t)-1) {
+            ret = -1;
+            goto error;
+          }
+          cp = buf;
+          size = (int)mbseqlen;
+        } else {
+          *(cp = buf) = GETARG(int);
+          size = 1;
+        }
+        sign = '\0';
+        break;
+      case 'D':
+        flags |= LONGINT;
+        /*FALLTHROUGH*/
+      case 'd':
+      case 'i':
+        _umax = SARG();
+        if ((intmax_t)_umax < 0) {
+          _umax = -_umax;
+          sign = '-';
+        }
+        base = DEC;
+        goto number;
+      case 'a':
+      case 'A':
+        if (ch == 'a') {
+          ox[1] = 'x';
+          xdigs = xdigs_lower;
+          expchar = 'p';
+        } else {
+          ox[1] = 'X';
+          xdigs = xdigs_upper;
+          expchar = 'P';
+        }
+        if (prec >= 0) prec++;
+        if (dtoaresult) __freedtoa(dtoaresult);
+        if (flags & LONGDBL) {
+          fparg.ldbl = GETARG(long double);
+          dtoaresult = cp = __hldtoa(fparg.ldbl, xdigs, prec, &expt, &signflag, &dtoaend);
+          if (dtoaresult == NULL) {
+            errno = ENOMEM;
+            goto error;
+          }
+        } else {
+          fparg.dbl = GETARG(double);
+          dtoaresult = cp = __hdtoa(fparg.dbl, xdigs, prec, &expt, &signflag, &dtoaend);
+          if (dtoaresult == NULL) {
+            errno = ENOMEM;
+            goto error;
+          }
+        }
+        if (prec < 0) prec = dtoaend - dtoaresult;
+        if (expt == INT_MAX) ox[1] = '\0';
+        goto fp_common;
+      case 'e':
+      case 'E':
+        expchar = ch;
+        if (prec < 0) /* account for digit before decpt */
+          prec = DEFPREC + 1;
+        else
+          prec++;
+        goto fp_begin;
+      case 'f':
+      case 'F':
+        expchar = '\0';
+        goto fp_begin;
+      case 'g':
+      case 'G':
+        expchar = ch - ('g' - 'e');
+        if (prec == 0) prec = 1;
+      fp_begin:
+        if (prec < 0) prec = DEFPREC;
+        if (dtoaresult) __freedtoa(dtoaresult);
+        if (flags & LONGDBL) {
+          fparg.ldbl = GETARG(long double);
+          dtoaresult = cp = __ldtoa(&fparg.ldbl, expchar ? 2 : 3, prec, &expt, &signflag, &dtoaend);
+          if (dtoaresult == NULL) {
+            errno = ENOMEM;
+            goto error;
+          }
+        } else {
+          fparg.dbl = GETARG(double);
+          dtoaresult = cp = __dtoa(fparg.dbl, expchar ? 2 : 3, prec, &expt, &signflag, &dtoaend);
+          if (dtoaresult == NULL) {
+            errno = ENOMEM;
+            goto error;
+          }
+          if (expt == 9999) expt = INT_MAX;
+        }
+      fp_common:
+        if (signflag) sign = '-';
+        if (expt == INT_MAX) { /* inf or nan */
+          if (*cp == 'N') {
+            cp = const_cast<CHAR_TYPE*>((ch >= 'a') ? CHAR_TYPE_nan : CHAR_TYPE_NAN);
+          } else {
+            cp = const_cast<CHAR_TYPE*>((ch >= 'a') ? CHAR_TYPE_inf : CHAR_TYPE_INF);
+          }
+          size = 3;
+          flags &= ~ZEROPAD;
+          break;
+        }
+        flags |= FPT;
+        ndig = dtoaend - cp;
+        if (ch == 'g' || ch == 'G') {
+          if (expt > -4 && expt <= prec) {
+            /* Make %[gG] smell like %[fF] */
+            expchar = '\0';
+            if (flags & ALT)
+              prec -= expt;
+            else
+              prec = ndig - expt;
+            if (prec < 0) prec = 0;
+          } else {
+            /*
+             * Make %[gG] smell like %[eE], but
+             * trim trailing zeroes if no # flag.
+             */
+            if (!(flags & ALT)) prec = ndig;
+          }
+        }
+        if (expchar) {
+          expsize = exponent(expstr, expt - 1, expchar);
+          size = expsize + prec;
+          if (prec > 1 || flags & ALT) ++size;
+        } else {
+          /* space for digits before decimal point */
+          if (expt > 0)
+            size = expt;
+          else /* "0" */
+            size = 1;
+          /* space for decimal pt and following digits */
+          if (prec || flags & ALT) size += prec + 1;
+          lead = expt;
+        }
+        break;
+#ifndef NO_PRINTF_PERCENT_N
+      case 'n':
+        if (flags & LLONGINT)
+          *GETARG(long long*) = ret;
+        else if (flags & LONGINT)
+          *GETARG(long*) = ret;
+        else if (flags & SHORTINT)
+          *GETARG(short*) = ret;
+        else if (flags & CHARINT)
+          *GETARG(signed char*) = ret;
+        else if (flags & PTRINT)
+          *GETARG(ptrdiff_t*) = ret;
+        else if (flags & SIZEINT)
+          *GETARG(ssize_t*) = ret;
+        else if (flags & MAXINT)
+          *GETARG(intmax_t*) = ret;
+        else
+          *GETARG(int*) = ret;
+        continue; /* no output */
+#endif            /* NO_PRINTF_PERCENT_N */
+      case 'O':
+        flags |= LONGINT;
+        /*FALLTHROUGH*/
+      case 'o':
+        _umax = UARG();
+        base = OCT;
+        goto nosign;
+      case 'p':
+        /*
+         * ``The argument shall be a pointer to void.  The
+         * value of the pointer is converted to a sequence
+         * of printable characters, in an implementation-
+         * defined manner.''
+         *	-- ANSI X3J11
+         */
+        _umax = (u_long)GETARG(void*);
+        base = HEX;
+        xdigs = xdigs_lower;
+        ox[1] = 'x';
+        goto nosign;
+      case 'S':
+        flags |= LONGINT;
+        /*FALLTHROUGH*/
+      case 's':
+        if (flags & LONGINT) {
+          wchar_t* wcp;
+
+          free(convbuf);
+          convbuf = NULL;
+          if ((wcp = GETARG(wchar_t*)) == NULL) {
+            cp = const_cast<char*>("(null)");
+          } else {
+            convbuf = helpers::wcsconv(wcp, prec);
+            if (convbuf == NULL) {
+              ret = -1;
+              goto error;
+            }
+            cp = convbuf;
+          }
+        } else if ((cp = GETARG(char*)) == NULL) {
+          cp = const_cast<char*>("(null)");
+        }
+        if (prec >= 0) {
+          size = CHAR_TYPE_STRNLEN(cp, prec);
+        } else {
+          size_t len;
+
+          if ((len = CHAR_TYPE_STRLEN(cp)) > INT_MAX) goto overflow;
+          size = (int)len;
+        }
+        sign = '\0';
+        break;
+      case 'U':
+        flags |= LONGINT;
+        /*FALLTHROUGH*/
+      case 'u':
+        _umax = UARG();
+        base = DEC;
+        goto nosign;
+      case 'X':
+        xdigs = xdigs_upper;
+        goto hex;
+      case 'x':
+        xdigs = xdigs_lower;
+      hex:
+        _umax = UARG();
+        base = HEX;
+        /* leading 0x/X only if non-zero */
+        if (flags & ALT && _umax != 0) ox[1] = ch;
+
+        /* unsigned conversions */
+      nosign:
+        sign = '\0';
+        /*
+         * ``... diouXx conversions ... if a precision is
+         * specified, the 0 flag will be ignored.''
+         *	-- ANSI X3J11
+         */
+      number:
+        if ((dprec = prec) >= 0) flags &= ~ZEROPAD;
+
+        /*
+         * ``The result of converting a zero value with an
+         * explicit precision of zero is no characters.''
+         *	-- ANSI X3J11
+         */
+        cp = buf + BUF;
+        if (_umax != 0 || prec != 0) {
+          /*
+           * Unsigned mod is hard, and unsigned mod
+           * by a constant is easier than that by
+           * a variable; hence this switch.
+           */
+          switch (base) {
+            case OCT:
+              do {
+                *--cp = to_char(_umax & 7);
+                _umax >>= 3;
+              } while (_umax);
+              /* handle octal leading 0 */
+              if (flags & ALT && *cp != '0') *--cp = '0';
+              break;
+
+            case DEC:
+              /* many numbers are 1 digit */
+              while (_umax >= 10) {
+                *--cp = to_char(_umax % 10);
+                _umax /= 10;
+              }
+              *--cp = to_char(_umax);
+              break;
+
+            case HEX:
+              do {
+                *--cp = xdigs[_umax & 15];
+                _umax >>= 4;
+              } while (_umax);
+              break;
+
+            default:
+              abort();
+          }
+        }
+        size = buf + BUF - cp;
+        if (size > BUF) abort(); /* should never happen */
+        break;
+      default: /* "%?" prints ?, unless ? is NUL */
+        if (ch == '\0') goto done;
+        /* pretend it was %c with argument ch */
+        cp = buf;
+        *cp = ch;
+        size = 1;
+        sign = '\0';
+        break;
+    }
+
+    /*
+     * All reasonable formats wind up here.  At this point, `cp'
+     * points to a string which (if not flags&LADJUST) should be
+     * padded out to `width' places.  If flags&ZEROPAD, it should
+     * first be prefixed by any sign or other prefix; otherwise,
+     * it should be blank padded before the prefix is emitted.
+     * After any left-hand padding and prefixing, emit zeroes
+     * required by a decimal %[diouxX] precision, then print the
+     * string proper, then emit zeroes required by any leftover
+     * floating precision; finally, if LADJUST, pad with blanks.
+     *
+     * Compute actual size, so we know how much to pad.
+     * size excludes decimal prec; realsz includes it.
+     */
+    realsz = dprec > size ? dprec : size;
+    if (sign) realsz++;
+    if (ox[1]) realsz += 2;
+
+    /* right-adjusting blank padding */
+    if ((flags & (LADJUST | ZEROPAD)) == 0) PAD(width - realsz, blanks);
+
+    /* prefix */
+    if (sign) PRINT(&sign, 1);
+    if (ox[1]) { /* ox[1] is either x, X, or \0 */
+      ox[0] = '0';
+      PRINT(ox, 2);
+    }
+
+    /* right-adjusting zero padding */
+    if ((flags & (LADJUST | ZEROPAD)) == ZEROPAD) PAD(width - realsz, zeroes);
+
+    /* leading zeroes from decimal precision */
+    PAD(dprec - size, zeroes);
+
+    /* the string or number proper */
+    if ((flags & FPT) == 0) {
+      PRINT(cp, size);
+    } else { /* glue together f_p fragments */
+      if (decimal_point == NULL) decimal_point = nl_langinfo(RADIXCHAR);
+      if (!expchar) { /* %[fF] or sufficiently short %[gG] */
+        if (expt <= 0) {
+          PRINT(zeroes, 1);
+          if (prec || flags & ALT) PRINT(decimal_point, 1);
+          PAD(-expt, zeroes);
+          /* already handled initial 0's */
+          prec += expt;
+        } else {
+          PRINTANDPAD(cp, dtoaend, lead, zeroes);
+          cp += lead;
+          if (prec || flags & ALT) PRINT(decimal_point, 1);
+        }
+        PRINTANDPAD(cp, dtoaend, prec, zeroes);
+      } else { /* %[eE] or sufficiently long %[gG] */
+        if (prec > 1 || flags & ALT) {
+          buf[0] = *cp++;
+          buf[1] = *decimal_point;
+          PRINT(buf, 2);
+          PRINT(cp, ndig - 1);
+          PAD(prec - ndig, zeroes);
+        } else { /* XeYYY */
+          PRINT(cp, 1);
+        }
+        PRINT(expstr, expsize);
+      }
+    }
+    /* left-adjusting padding (always blank) */
+    if (flags & LADJUST) PAD(width - realsz, blanks);
+
+    /* finally, adjust ret */
+    if (width < realsz) width = realsz;
+    if (width > INT_MAX - ret) goto overflow;
+    ret += width;
+
+    FLUSH(); /* copy out the I/O vectors */
+  }
+done:
+  FLUSH();
+error:
+  va_end(orgap);
+  if (__sferror(fp)) ret = -1;
+  goto finish;
+
+overflow:
+  errno = ENOMEM;
+  ret = -1;
+
+finish:
+  free(convbuf);
+  if (dtoaresult) __freedtoa(dtoaresult);
+  if (argtable != NULL && argtable != statargtable) {
+    munmap(argtable, argtablesiz);
+    argtable = NULL;
+  }
+  return (ret);
+}
diff --git a/libc/stdio/vfscanf.c b/libc/stdio/vfscanf.c
index e47d0df..853e0cf 100644
--- a/libc/stdio/vfscanf.c
+++ b/libc/stdio/vfscanf.c
@@ -32,762 +32,722 @@
  */
 
 #include <ctype.h>
-#include <wctype.h>
 #include <inttypes.h>
 #include <stdarg.h>
 #include <stddef.h>
 #include <stdio.h>
 #include <stdlib.h>
 #include <string.h>
+#include <wctype.h>
 #include "local.h"
 
-#ifdef FLOATING_POINT
-#include "floatio.h"
-#endif
-
-#define	BUF		513	/* Maximum length of numeric string. */
+#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 */
+#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 */
 
 /*
  * 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 */
+#define SIGNOK 0x01000   /* +/- is (still) legal */
+#define HAVESIGN 0x02000 /* sign detected */
+#define NDIGITS 0x04000  /* no digits detected */
 
-#define	DPTOK		0x08000	/* (float) decimal point is still legal */
-#define	EXPOK		0x10000	/* (float) exponent (e+3, etc) still legal */
+#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 */
+#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 */
+#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 */
 
 #define u_char unsigned char
 #define u_long unsigned long
 
-static u_char *__sccl(char *, u_char *);
+static u_char* __sccl(char*, u_char*);
 
 /*
  * Internal, unlocked version of vfscanf
  */
-int
-__svfscanf(FILE *fp, const char *fmt0, __va_list ap)
-{
-	u_char *fmt = (u_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 */
-	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 */
-#ifdef SCANF_WIDE_CHAR
-	wchar_t *wcp;		/* handy wide character pointer */
-	size_t nconv;		/* length of multibyte sequence converted */
-	mbstate_t mbs;
-#endif
+int __svfscanf(FILE* fp, const char* fmt0, __va_list ap) {
+  u_char* fmt = (u_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 */
+  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;
 
-	/* `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 };
+  /* `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 };
 
-	_SET_ORIENTATION(fp, -1);
+  _SET_ORIENTATION(fp, -1);
 
-	nassigned = 0;
-	nread = 0;
-	base = 0;		/* XXX just to keep gcc happy */
-	for (;;) {
-		c = *fmt++;
-		if (c == 0)
-			return (nassigned);
-		if (isspace(c)) {
-			while ((fp->_r > 0 || __srefill(fp) == 0) &&
-			    isspace(*fp->_p))
-				nread++, fp->_r--, fp->_p++;
-			continue;
-		}
-		if (c != '%')
-			goto literal;
-		width = 0;
-		flags = 0;
-		/*
-		 * switch on the format.  continue if done;
-		 * break once format type is derived.
-		 */
-again:		c = *fmt++;
-		switch (c) {
-		case '%':
-literal:
-			if (fp->_r <= 0 && __srefill(fp))
-				goto input_failure;
-			if (*fp->_p != c)
-				goto match_failure;
-			fp->_r--, fp->_p++;
-			nread++;
-			continue;
+  nassigned = 0;
+  nread = 0;
+  base = 0; /* XXX just to keep gcc happy */
+  for (;;) {
+    c = *fmt++;
+    if (c == 0) return (nassigned);
+    if (isspace(c)) {
+      while ((fp->_r > 0 || __srefill(fp) == 0) && isspace(*fp->_p)) nread++, fp->_r--, fp->_p++;
+      continue;
+    }
+    if (c != '%') goto literal;
+    width = 0;
+    flags = 0;
+    /*
+     * switch on the format.  continue if done;
+     * break once format type is derived.
+     */
+  again:
+    c = *fmt++;
+    switch (c) {
+      case '%':
+      literal:
+        if (fp->_r <= 0 && __srefill(fp)) goto input_failure;
+        if (*fp->_p != c) goto match_failure;
+        fp->_r--, fp->_p++;
+        nread++;
+        continue;
 
-		case '*':
-			flags |= SUPPRESS;
-			goto again;
-		case 'j':
-			flags |= MAXINT;
-			goto again;
-		case 'L':
-			flags |= LONGDBL;
-			goto again;
-		case 'h':
-			if (*fmt == 'h') {
-				fmt++;
-				flags |= SHORTSHORT;
-			} else {
-				flags |= SHORT;
-			}
-			goto again;
-		case 'l':
-			if (*fmt == 'l') {
-				fmt++;
-				flags |= LLONG;
-			} else {
-				flags |= LONG;
-			}
-			goto again;
-		case 'q':
-			flags |= LLONG;		/* deprecated */
-			goto again;
-		case 't':
-			flags |= PTRINT;
-			goto again;
-		case 'z':
-			flags |= SIZEINT;
-			goto again;
+      case '*':
+        flags |= SUPPRESS;
+        goto again;
+      case 'j':
+        flags |= MAXINT;
+        goto again;
+      case 'L':
+        flags |= LONGDBL;
+        goto again;
+      case 'h':
+        if (*fmt == 'h') {
+          fmt++;
+          flags |= SHORTSHORT;
+        } else {
+          flags |= SHORT;
+        }
+        goto again;
+      case 'l':
+        if (*fmt == 'l') {
+          fmt++;
+          flags |= LLONG;
+        } else {
+          flags |= LONG;
+        }
+        goto again;
+      case 'q':
+        flags |= LLONG; /* deprecated */
+        goto again;
+      case 't':
+        flags |= PTRINT;
+        goto again;
+      case 'z':
+        flags |= SIZEINT;
+        goto again;
 
-		case '0': case '1': case '2': case '3': case '4':
-		case '5': case '6': case '7': case '8': case '9':
-			width = width * 10 + c - '0';
-			goto again;
+      case '0':
+      case '1':
+      case '2':
+      case '3':
+      case '4':
+      case '5':
+      case '6':
+      case '7':
+      case '8':
+      case '9':
+        width = width * 10 + c - '0';
+        goto again;
 
-		/*
-		 * Conversions.
-		 * Those marked `compat' are for 4.[123]BSD compatibility.
-		 *
-		 * (According to ANSI, E and X formats are supposed
-		 * to the same as e and x.  Sorry about that.)
-		 */
-		case 'D':	/* compat */
-			flags |= LONG;
-			/* FALLTHROUGH */
-		case 'd':
-			c = CT_INT;
-			base = 10;
-			break;
+      /*
+       * Conversions.
+       * Those marked `compat' are for 4.[123]BSD compatibility.
+       *
+       * (According to ANSI, E and X formats are supposed
+       * to the same as e and x.  Sorry about that.)
+       */
+      case 'D': /* compat */
+        flags |= LONG;
+        /* FALLTHROUGH */
+      case 'd':
+        c = CT_INT;
+        base = 10;
+        break;
 
-		case 'i':
-			c = CT_INT;
-			base = 0;
-			break;
+      case 'i':
+        c = CT_INT;
+        base = 0;
+        break;
 
-		case 'O':	/* compat */
-			flags |= LONG;
-			/* FALLTHROUGH */
-		case 'o':
-			c = CT_INT;
-			flags |= UNSIGNED;
-			base = 8;
-			break;
+      case 'O': /* compat */
+        flags |= LONG;
+        /* FALLTHROUGH */
+      case 'o':
+        c = CT_INT;
+        flags |= UNSIGNED;
+        base = 8;
+        break;
 
-		case 'u':
-			c = CT_INT;
-			flags |= UNSIGNED;
-			base = 10;
-			break;
+      case 'u':
+        c = CT_INT;
+        flags |= UNSIGNED;
+        base = 10;
+        break;
 
-		case 'X':
-		case 'x':
-			flags |= PFXOK;	/* enable 0x prefixing */
-			c = CT_INT;
-			flags |= UNSIGNED;
-			base = 16;
-			break;
+      case 'X':
+      case 'x':
+        flags |= PFXOK; /* enable 0x prefixing */
+        c = CT_INT;
+        flags |= UNSIGNED;
+        base = 16;
+        break;
 
-#ifdef FLOATING_POINT
-		case 'e': case 'E':
-		case 'f': case 'F':
-		case 'g': case 'G':
-		case 'a': case 'A':
-			c = CT_FLOAT;
-			break;
-#endif
+      case 'e':
+      case 'E':
+      case 'f':
+      case 'F':
+      case 'g':
+      case 'G':
+      case 'a':
+      case 'A':
+        c = CT_FLOAT;
+        break;
 
-		case 's':
-			c = CT_STRING;
-			break;
+      case 's':
+        c = CT_STRING;
+        break;
 
-		case '[':
-			fmt = __sccl(ccltab, fmt);
-			flags |= NOSKIP;
-			c = CT_CCL;
-			break;
+      case '[':
+        fmt = __sccl(ccltab, fmt);
+        flags |= NOSKIP;
+        c = CT_CCL;
+        break;
 
-		case 'c':
-			flags |= NOSKIP;
-			c = CT_CHAR;
-			break;
+      case 'c':
+        flags |= NOSKIP;
+        c = CT_CHAR;
+        break;
 
-		case 'p':	/* pointer format is like hex */
-			flags |= POINTER | PFXOK;
-			c = CT_INT;
-			flags |= UNSIGNED;
-			base = 16;
-			break;
+      case 'p': /* pointer format is like hex */
+        flags |= POINTER | PFXOK;
+        c = CT_INT;
+        flags |= UNSIGNED;
+        base = 16;
+        break;
 
-		case 'n':
-			if (flags & SUPPRESS)
-				continue;
-			if (flags & SHORTSHORT)
-				*va_arg(ap, signed char *) = nread;
-			else if (flags & SHORT)
-				*va_arg(ap, short *) = nread;
-			else if (flags & LONG)
-				*va_arg(ap, long *) = nread;
-			else if (flags & SIZEINT)
-				*va_arg(ap, ssize_t *) = nread;
-			else if (flags & PTRINT)
-				*va_arg(ap, ptrdiff_t *) = nread;
-			else if (flags & LLONG)
-				*va_arg(ap, long long *) = nread;
-			else if (flags & MAXINT)
-				*va_arg(ap, intmax_t *) = nread;
-			else
-				*va_arg(ap, int *) = nread;
-			continue;
+      case 'n':
+        if (flags & SUPPRESS) continue;
+        if (flags & SHORTSHORT)
+          *va_arg(ap, signed char*) = nread;
+        else if (flags & SHORT)
+          *va_arg(ap, short*) = nread;
+        else if (flags & LONG)
+          *va_arg(ap, long*) = nread;
+        else if (flags & SIZEINT)
+          *va_arg(ap, ssize_t*) = nread;
+        else if (flags & PTRINT)
+          *va_arg(ap, ptrdiff_t*) = nread;
+        else if (flags & LLONG)
+          *va_arg(ap, long long*) = nread;
+        else if (flags & MAXINT)
+          *va_arg(ap, intmax_t*) = nread;
+        else
+          *va_arg(ap, int*) = nread;
+        continue;
 
-		/*
-		 * Disgusting backwards compatibility hacks.	XXX
-		 */
-		case '\0':	/* compat */
-			return (EOF);
+      /*
+       * Disgusting backwards compatibility hacks.	XXX
+       */
+      case '\0': /* compat */
+        return (EOF);
 
-		default:	/* compat */
-			if (isupper(c))
-				flags |= LONG;
-			c = CT_INT;
-			base = 10;
-			break;
-		}
+      default: /* compat */
+        if (isupper(c)) flags |= LONG;
+        c = CT_INT;
+        base = 10;
+        break;
+    }
 
-		/*
-		 * We have a conversion that requires input.
-		 */
-		if (fp->_r <= 0 && __srefill(fp))
-			goto input_failure;
+    /*
+     * We have a conversion that requires input.
+     */
+    if (fp->_r <= 0 && __srefill(fp)) goto input_failure;
 
-		/*
-		 * Consume leading white space, except for formats
-		 * that suppress this.
-		 */
-		if ((flags & NOSKIP) == 0) {
-			while (isspace(*fp->_p)) {
-				nread++;
-				if (--fp->_r > 0)
-					fp->_p++;
-				else if (__srefill(fp))
-					goto input_failure;
-			}
-			/*
-			 * Note that there is at least one character in
-			 * the buffer, so conversions that do not set NOSKIP
-			 * ca no longer result in an input failure.
-			 */
-		}
+    /*
+     * Consume leading white space, except for formats
+     * that suppress this.
+     */
+    if ((flags & NOSKIP) == 0) {
+      while (isspace(*fp->_p)) {
+        nread++;
+        if (--fp->_r > 0)
+          fp->_p++;
+        else if (__srefill(fp))
+          goto input_failure;
+      }
+      /*
+       * Note that there is at least one character in
+       * the buffer, so conversions that do not set NOSKIP
+       * ca no longer result in an input failure.
+       */
+    }
 
-		/*
-		 * Do the conversion.
-		 */
-		switch (c) {
+    /*
+     * Do the conversion.
+     */
+    switch (c) {
+      case CT_CHAR:
+        /* scan arbitrary characters (sets NOSKIP) */
+        if (width == 0) width = 1;
+        if (flags & LONG) {
+          if ((flags & SUPPRESS) == 0)
+            wcp = va_arg(ap, wchar_t*);
+          else
+            wcp = NULL;
+          n = 0;
+          while (width != 0) {
+            if (n == (int)MB_CUR_MAX) {
+              fp->_flags |= __SERR;
+              goto input_failure;
+            }
+            buf[n++] = *fp->_p;
+            fp->_p++;
+            fp->_r--;
+            memset(&mbs, 0, sizeof(mbs));
+            nconv = mbrtowc(wcp, buf, n, &mbs);
+            if (nconv == (size_t)-1) {
+              fp->_flags |= __SERR;
+              goto input_failure;
+            }
+            if (nconv == 0 && !(flags & SUPPRESS)) *wcp = L'\0';
+            if (nconv != (size_t)-2) {
+              nread += n;
+              width--;
+              if (!(flags & SUPPRESS)) wcp++;
+              n = 0;
+            }
+            if (fp->_r <= 0 && __srefill(fp)) {
+              if (n != 0) {
+                fp->_flags |= __SERR;
+                goto input_failure;
+              }
+              break;
+            }
+          }
+          if (!(flags & SUPPRESS)) nassigned++;
+        } else if (flags & SUPPRESS) {
+          size_t sum = 0;
+          for (;;) {
+            if ((n = fp->_r) < (int)width) {
+              sum += n;
+              width -= n;
+              fp->_p += n;
+              if (__srefill(fp)) {
+                if (sum == 0) goto input_failure;
+                break;
+              }
+            } else {
+              sum += width;
+              fp->_r -= width;
+              fp->_p += width;
+              break;
+            }
+          }
+          nread += sum;
+        } else {
+          size_t r = fread((void*)va_arg(ap, char*), 1, width, fp);
 
-		case CT_CHAR:
-			/* scan arbitrary characters (sets NOSKIP) */
-			if (width == 0)
-				width = 1;
-#ifdef SCANF_WIDE_CHAR
-			if (flags & LONG) {
-				if ((flags & SUPPRESS) == 0)
-					wcp = va_arg(ap, wchar_t *);
-				else
-					wcp = NULL;
-				n = 0;
-				while (width != 0) {
-					if (n == (int)MB_CUR_MAX) {
-						fp->_flags |= __SERR;
-						goto input_failure;
-					}
-					buf[n++] = *fp->_p;
-					fp->_p++;
-					fp->_r--;
-					memset(&mbs, 0, sizeof(mbs));
-					nconv = mbrtowc(wcp, buf, n, &mbs);
-					if (nconv == (size_t)-1) {
-						fp->_flags |= __SERR;
-						goto input_failure;
-					}
-					if (nconv == 0 && !(flags & SUPPRESS))
-						*wcp = L'\0';
-					if (nconv != (size_t)-2) {
-						nread += n;
-						width--;
-						if (!(flags & SUPPRESS))
-							wcp++;
-						n = 0;
-					}
-					if (fp->_r <= 0 && __srefill(fp)) {
-						if (n != 0) {
-							fp->_flags |= __SERR;
-							goto input_failure;
-						}
-						break;
-					}
-				}
-				if (!(flags & SUPPRESS))
-					nassigned++;
-			} else
-#endif /* SCANF_WIDE_CHAR */
-			if (flags & SUPPRESS) {
-				size_t sum = 0;
-				for (;;) {
-					if ((n = fp->_r) < (int)width) {
-						sum += n;
-						width -= n;
-						fp->_p += n;
-						if (__srefill(fp)) {
-							if (sum == 0)
-							    goto input_failure;
-							break;
-						}
-					} else {
-						sum += width;
-						fp->_r -= width;
-						fp->_p += width;
-						break;
-					}
-				}
-				nread += sum;
-			} else {
-				size_t r = fread((void *)va_arg(ap, char *), 1,
-				    width, fp);
+          if (r == 0) goto input_failure;
+          nread += r;
+          nassigned++;
+        }
+        break;
 
-				if (r == 0)
-					goto input_failure;
-				nread += r;
-				nassigned++;
-			}
-			break;
+      case CT_CCL:
+        /* scan a (nonempty) character class (sets NOSKIP) */
+        if (width == 0) width = (size_t)~0; /* `infinity' */
+        /* take only those things in the class */
+        if (flags & LONG) {
+          wchar_t twc;
+          int nchars;
 
-		case CT_CCL:
-			/* scan a (nonempty) character class (sets NOSKIP) */
-			if (width == 0)
-				width = (size_t)~0;	/* `infinity' */
-#ifdef SCANF_WIDE_CHAR
-			/* take only those things in the class */
-			if (flags & LONG) {
-				wchar_t twc;
-				int nchars;
+          if ((flags & SUPPRESS) == 0)
+            wcp = va_arg(ap, wchar_t*);
+          else
+            wcp = &twc;
+          n = 0;
+          nchars = 0;
+          while (width != 0) {
+            if (n == (int)MB_CUR_MAX) {
+              fp->_flags |= __SERR;
+              goto input_failure;
+            }
+            buf[n++] = *fp->_p;
+            fp->_p++;
+            fp->_r--;
+            memset(&mbs, 0, sizeof(mbs));
+            nconv = mbrtowc(wcp, buf, n, &mbs);
+            if (nconv == (size_t)-1) {
+              fp->_flags |= __SERR;
+              goto input_failure;
+            }
+            if (nconv == 0) *wcp = L'\0';
+            if (nconv != (size_t)-2) {
+              if (wctob(*wcp) != EOF && !ccltab[wctob(*wcp)]) {
+                while (n != 0) {
+                  n--;
+                  ungetc(buf[n], fp);
+                }
+                break;
+              }
+              nread += n;
+              width--;
+              if (!(flags & SUPPRESS)) wcp++;
+              nchars++;
+              n = 0;
+            }
+            if (fp->_r <= 0 && __srefill(fp)) {
+              if (n != 0) {
+                fp->_flags |= __SERR;
+                goto input_failure;
+              }
+              break;
+            }
+          }
+          if (n != 0) {
+            fp->_flags |= __SERR;
+            goto input_failure;
+          }
+          n = nchars;
+          if (n == 0) goto match_failure;
+          if (!(flags & SUPPRESS)) {
+            *wcp = L'\0';
+            nassigned++;
+          }
+        } else
+            /* take only those things in the class */
+            if (flags & SUPPRESS) {
+          n = 0;
+          while (ccltab[*fp->_p]) {
+            n++, fp->_r--, fp->_p++;
+            if (--width == 0) break;
+            if (fp->_r <= 0 && __srefill(fp)) {
+              if (n == 0) goto input_failure;
+              break;
+            }
+          }
+          if (n == 0) goto match_failure;
+        } else {
+          p0 = p = va_arg(ap, char*);
+          while (ccltab[*fp->_p]) {
+            fp->_r--;
+            *p++ = *fp->_p++;
+            if (--width == 0) break;
+            if (fp->_r <= 0 && __srefill(fp)) {
+              if (p == p0) goto input_failure;
+              break;
+            }
+          }
+          n = p - p0;
+          if (n == 0) goto match_failure;
+          *p = '\0';
+          nassigned++;
+        }
+        nread += n;
+        break;
 
-				if ((flags & SUPPRESS) == 0)
-					wcp = va_arg(ap, wchar_t *);
-				else
-					wcp = &twc;
-				n = 0;
-				nchars = 0;
-				while (width != 0) {
-					if (n == (int)MB_CUR_MAX) {
-						fp->_flags |= __SERR;
-						goto input_failure;
-					}
-					buf[n++] = *fp->_p;
-					fp->_p++;
-					fp->_r--;
-					memset(&mbs, 0, sizeof(mbs));
-					nconv = mbrtowc(wcp, buf, n, &mbs);
-					if (nconv == (size_t)-1) {
-						fp->_flags |= __SERR;
-						goto input_failure;
-					}
-					if (nconv == 0)
-						*wcp = L'\0';
-					if (nconv != (size_t)-2) {
-						if (wctob(*wcp) != EOF &&
-						    !ccltab[wctob(*wcp)]) {
-							while (n != 0) {
-								n--;
-								ungetc(buf[n],
-								    fp);
-							}
-							break;
-						}
-						nread += n;
-						width--;
-						if (!(flags & SUPPRESS))
-							wcp++;
-						nchars++;
-						n = 0;
-					}
-					if (fp->_r <= 0 && __srefill(fp)) {
-						if (n != 0) {
-							fp->_flags |= __SERR;
-							goto input_failure;
-						}
-						break;
-					}
-				}
-				if (n != 0) {
-					fp->_flags |= __SERR;
-					goto input_failure;
-				}
-				n = nchars;
-				if (n == 0)
-					goto match_failure;
-				if (!(flags & SUPPRESS)) {
-					*wcp = L'\0';
-					nassigned++;
-				}
-			} else
-#endif /* SCANF_WIDE_CHAR */
-			/* take only those things in the class */
-			if (flags & SUPPRESS) {
-				n = 0;
-				while (ccltab[*fp->_p]) {
-					n++, fp->_r--, fp->_p++;
-					if (--width == 0)
-						break;
-					if (fp->_r <= 0 && __srefill(fp)) {
-						if (n == 0)
-							goto input_failure;
-						break;
-					}
-				}
-				if (n == 0)
-					goto match_failure;
-			} else {
-				p0 = p = va_arg(ap, char *);
-				while (ccltab[*fp->_p]) {
-					fp->_r--;
-					*p++ = *fp->_p++;
-					if (--width == 0)
-						break;
-					if (fp->_r <= 0 && __srefill(fp)) {
-						if (p == p0)
-							goto input_failure;
-						break;
-					}
-				}
-				n = p - p0;
-				if (n == 0)
-					goto match_failure;
-				*p = '\0';
-				nassigned++;
-			}
-			nread += n;
-			break;
+      case CT_STRING:
+        /* like CCL, but zero-length string OK, & no NOSKIP */
+        if (width == 0) width = (size_t)~0;
+        if (flags & LONG) {
+          wchar_t twc;
 
-		case CT_STRING:
-			/* like CCL, but zero-length string OK, & no NOSKIP */
-			if (width == 0)
-				width = (size_t)~0;
-#ifdef SCANF_WIDE_CHAR
-			if (flags & LONG) {
-				wchar_t twc;
+          if ((flags & SUPPRESS) == 0)
+            wcp = va_arg(ap, wchar_t*);
+          else
+            wcp = &twc;
+          n = 0;
+          while (!isspace(*fp->_p) && width != 0) {
+            if (n == (int)MB_CUR_MAX) {
+              fp->_flags |= __SERR;
+              goto input_failure;
+            }
+            buf[n++] = *fp->_p;
+            fp->_p++;
+            fp->_r--;
+            memset(&mbs, 0, sizeof(mbs));
+            nconv = mbrtowc(wcp, buf, n, &mbs);
+            if (nconv == (size_t)-1) {
+              fp->_flags |= __SERR;
+              goto input_failure;
+            }
+            if (nconv == 0) *wcp = L'\0';
+            if (nconv != (size_t)-2) {
+              if (iswspace(*wcp)) {
+                while (n != 0) {
+                  n--;
+                  ungetc(buf[n], fp);
+                }
+                break;
+              }
+              nread += n;
+              width--;
+              if (!(flags & SUPPRESS)) wcp++;
+              n = 0;
+            }
+            if (fp->_r <= 0 && __srefill(fp)) {
+              if (n != 0) {
+                fp->_flags |= __SERR;
+                goto input_failure;
+              }
+              break;
+            }
+          }
+          if (!(flags & SUPPRESS)) {
+            *wcp = L'\0';
+            nassigned++;
+          }
+        } else if (flags & SUPPRESS) {
+          n = 0;
+          while (!isspace(*fp->_p)) {
+            n++, fp->_r--, fp->_p++;
+            if (--width == 0) break;
+            if (fp->_r <= 0 && __srefill(fp)) break;
+          }
+          nread += n;
+        } else {
+          p0 = p = va_arg(ap, char*);
+          while (!isspace(*fp->_p)) {
+            fp->_r--;
+            *p++ = *fp->_p++;
+            if (--width == 0) break;
+            if (fp->_r <= 0 && __srefill(fp)) break;
+          }
+          *p = '\0';
+          nread += p - p0;
+          nassigned++;
+        }
+        continue;
 
-				if ((flags & SUPPRESS) == 0)
-					wcp = va_arg(ap, wchar_t *);
-				else
-					wcp = &twc;
-				n = 0;
-				while (!isspace(*fp->_p) && width != 0) {
-					if (n == (int)MB_CUR_MAX) {
-						fp->_flags |= __SERR;
-						goto input_failure;
-					}
-					buf[n++] = *fp->_p;
-					fp->_p++;
-					fp->_r--;
-					memset(&mbs, 0, sizeof(mbs));
-					nconv = mbrtowc(wcp, buf, n, &mbs);
-					if (nconv == (size_t)-1) {
-						fp->_flags |= __SERR;
-						goto input_failure;
-					}
-					if (nconv == 0)
-						*wcp = L'\0';
-					if (nconv != (size_t)-2) {
-						if (iswspace(*wcp)) {
-							while (n != 0) {
-								n--;
-								ungetc(buf[n],
-								    fp);
-							}
-							break;
-						}
-						nread += n;
-						width--;
-						if (!(flags & SUPPRESS))
-							wcp++;
-						n = 0;
-					}
-					if (fp->_r <= 0 && __srefill(fp)) {
-						if (n != 0) {
-							fp->_flags |= __SERR;
-							goto input_failure;
-						}
-						break;
-					}
-				}
-				if (!(flags & SUPPRESS)) {
-					*wcp = L'\0';
-					nassigned++;
-				}
-			} else
-#endif /* SCANF_WIDE_CHAR */
-			if (flags & SUPPRESS) {
-				n = 0;
-				while (!isspace(*fp->_p)) {
-					n++, fp->_r--, fp->_p++;
-					if (--width == 0)
-						break;
-					if (fp->_r <= 0 && __srefill(fp))
-						break;
-				}
-				nread += n;
-			} else {
-				p0 = p = va_arg(ap, char *);
-				while (!isspace(*fp->_p)) {
-					fp->_r--;
-					*p++ = *fp->_p++;
-					if (--width == 0)
-						break;
-					if (fp->_r <= 0 && __srefill(fp))
-						break;
-				}
-				*p = '\0';
-				nread += p - p0;
-				nassigned++;
-			}
-			continue;
-
-		case CT_INT:
-			/* scan an integer as if by strtoimax/strtoumax */
+      case CT_INT:
+        /* scan an integer as if by strtoimax/strtoumax */
 #ifdef hardway
-			if (width == 0 || width > sizeof(buf) - 1)
-				width = sizeof(buf) - 1;
+        if (width == 0 || width > sizeof(buf) - 1) width = sizeof(buf) - 1;
 #else
-			/* size_t is unsigned, hence this optimisation */
-			if (--width > sizeof(buf) - 2)
-				width = sizeof(buf) - 2;
-			width++;
+        /* size_t is unsigned, hence this optimisation */
+        if (--width > sizeof(buf) - 2) width = sizeof(buf) - 2;
+        width++;
 #endif
-			flags |= SIGNOK | NDIGITS | NZDIGITS;
-			for (p = buf; width; width--) {
-				c = *fp->_p;
-				/*
-				 * Switch on the character; `goto ok'
-				 * if we accept it as a part of number.
-				 */
-				switch (c) {
+        flags |= SIGNOK | NDIGITS | NZDIGITS;
+        for (p = buf; width; width--) {
+          c = *fp->_p;
+          /*
+           * Switch on the character; `goto ok'
+           * if we accept it as a part of number.
+           */
+          switch (c) {
+            /*
+             * The digit 0 is always legal, but is
+             * special.  For %i conversions, if no
+             * digits (zero or nonzero) have been
+             * scanned (only signs), we will have
+             * base==0.  In that case, we should set
+             * it to 8 and enable 0x prefixing.
+             * Also, if we have not scanned zero digits
+             * before this, do not turn off prefixing
+             * (someone else will turn it off if we
+             * have scanned any nonzero digits).
+             */
+            case '0':
+              if (base == 0) {
+                base = 8;
+                flags |= PFXOK;
+              }
+              if (flags & NZDIGITS)
+                flags &= ~(SIGNOK | NZDIGITS | NDIGITS);
+              else
+                flags &= ~(SIGNOK | PFXOK | NDIGITS);
+              goto ok;
 
-				/*
-				 * The digit 0 is always legal, but is
-				 * special.  For %i conversions, if no
-				 * digits (zero or nonzero) have been
-				 * scanned (only signs), we will have
-				 * base==0.  In that case, we should set
-				 * it to 8 and enable 0x prefixing.
-				 * Also, if we have not scanned zero digits
-				 * before this, do not turn off prefixing
-				 * (someone else will turn it off if we
-				 * have scanned any nonzero digits).
-				 */
-				case '0':
-					if (base == 0) {
-						base = 8;
-						flags |= PFXOK;
-					}
-					if (flags & NZDIGITS)
-					    flags &= ~(SIGNOK|NZDIGITS|NDIGITS);
-					else
-					    flags &= ~(SIGNOK|PFXOK|NDIGITS);
-					goto ok;
+            /* 1 through 7 always legal */
+            case '1':
+            case '2':
+            case '3':
+            case '4':
+            case '5':
+            case '6':
+            case '7':
+              base = basefix[base];
+              flags &= ~(SIGNOK | PFXOK | NDIGITS);
+              goto ok;
 
-				/* 1 through 7 always legal */
-				case '1': case '2': case '3':
-				case '4': case '5': case '6': case '7':
-					base = basefix[base];
-					flags &= ~(SIGNOK | PFXOK | NDIGITS);
-					goto ok;
+            /* digits 8 and 9 ok iff decimal or hex */
+            case '8':
+            case '9':
+              base = basefix[base];
+              if (base <= 8) break; /* not legal here */
+              flags &= ~(SIGNOK | PFXOK | NDIGITS);
+              goto ok;
 
-				/* digits 8 and 9 ok iff decimal or hex */
-				case '8': case '9':
-					base = basefix[base];
-					if (base <= 8)
-						break;	/* not legal here */
-					flags &= ~(SIGNOK | PFXOK | NDIGITS);
-					goto ok;
+            /* letters ok iff hex */
+            case 'A':
+            case 'B':
+            case 'C':
+            case 'D':
+            case 'E':
+            case 'F':
+            case 'a':
+            case 'b':
+            case 'c':
+            case 'd':
+            case 'e':
+            case 'f':
+              /* no need to fix base here */
+              if (base <= 10) break; /* not legal here */
+              flags &= ~(SIGNOK | PFXOK | NDIGITS);
+              goto ok;
 
-				/* letters ok iff hex */
-				case 'A': case 'B': case 'C':
-				case 'D': case 'E': case 'F':
-				case 'a': case 'b': case 'c':
-				case 'd': case 'e': case 'f':
-					/* no need to fix base here */
-					if (base <= 10)
-						break;	/* not legal here */
-					flags &= ~(SIGNOK | PFXOK | NDIGITS);
-					goto ok;
+            /* sign ok only as first character */
+            case '+':
+            case '-':
+              if (flags & SIGNOK) {
+                flags &= ~SIGNOK;
+                flags |= HAVESIGN;
+                goto ok;
+              }
+              break;
 
-				/* sign ok only as first character */
-				case '+': case '-':
-					if (flags & SIGNOK) {
-						flags &= ~SIGNOK;
-						flags |= HAVESIGN;
-						goto ok;
-					}
-					break;
+            /*
+             * x ok iff flag still set and 2nd char (or
+             * 3rd char if we have a sign).
+             */
+            case 'x':
+            case 'X':
+              if ((flags & PFXOK) && p == buf + 1 + !!(flags & HAVESIGN)) {
+                base = 16; /* if %i */
+                flags &= ~PFXOK;
+                goto ok;
+              }
+              break;
+          }
 
-				/*
-				 * x ok iff flag still set and 2nd char (or
-				 * 3rd char if we have a sign).
-				 */
-				case 'x': case 'X':
-					if ((flags & PFXOK) && p ==
-					    buf + 1 + !!(flags & HAVESIGN)) {
-						base = 16;	/* if %i */
-						flags &= ~PFXOK;
-						goto ok;
-					}
-					break;
-				}
+          /*
+           * If we got here, c is not a legal character
+           * for a number.  Stop accumulating digits.
+           */
+          break;
+        ok:
+          /*
+           * c is legal: store it and look at the next.
+           */
+          *p++ = c;
+          if (--fp->_r > 0)
+            fp->_p++;
+          else if (__srefill(fp))
+            break; /* EOF */
+        }
+        /*
+         * If we had only a sign, it is no good; push
+         * back the sign.  If the number ends in `x',
+         * it was [sign] '0' 'x', so push back the x
+         * and treat it as [sign] '0'.
+         */
+        if (flags & NDIGITS) {
+          if (p > buf) (void)ungetc(*(u_char*)--p, fp);
+          goto match_failure;
+        }
+        c = ((u_char*)p)[-1];
+        if (c == 'x' || c == 'X') {
+          --p;
+          (void)ungetc(c, fp);
+        }
+        if ((flags & SUPPRESS) == 0) {
+          uintmax_t res;
 
-				/*
-				 * If we got here, c is not a legal character
-				 * for a number.  Stop accumulating digits.
-				 */
-				break;
-		ok:
-				/*
-				 * c is legal: store it and look at the next.
-				 */
-				*p++ = c;
-				if (--fp->_r > 0)
-					fp->_p++;
-				else if (__srefill(fp))
-					break;		/* EOF */
-			}
-			/*
-			 * If we had only a sign, it is no good; push
-			 * back the sign.  If the number ends in `x',
-			 * it was [sign] '0' 'x', so push back the x
-			 * and treat it as [sign] '0'.
-			 */
-			if (flags & NDIGITS) {
-				if (p > buf)
-					(void) ungetc(*(u_char *)--p, fp);
-				goto match_failure;
-			}
-			c = ((u_char *)p)[-1];
-			if (c == 'x' || c == 'X') {
-				--p;
-				(void) ungetc(c, fp);
-			}
-			if ((flags & SUPPRESS) == 0) {
-				uintmax_t res;
+          *p = '\0';
+          if (flags & UNSIGNED)
+            res = strtoumax(buf, NULL, base);
+          else
+            res = strtoimax(buf, NULL, base);
+          if (flags & POINTER)
+            *va_arg(ap, void**) = (void*)(uintptr_t)res;
+          else if (flags & MAXINT)
+            *va_arg(ap, intmax_t*) = res;
+          else if (flags & LLONG)
+            *va_arg(ap, long long*) = res;
+          else if (flags & SIZEINT)
+            *va_arg(ap, ssize_t*) = res;
+          else if (flags & PTRINT)
+            *va_arg(ap, ptrdiff_t*) = res;
+          else if (flags & LONG)
+            *va_arg(ap, long*) = res;
+          else if (flags & SHORT)
+            *va_arg(ap, short*) = res;
+          else if (flags & SHORTSHORT)
+            *va_arg(ap, signed char*) = res;
+          else
+            *va_arg(ap, int*) = res;
+          nassigned++;
+        }
+        nread += p - buf;
+        break;
 
-				*p = '\0';
-				if (flags & UNSIGNED)
-					res = strtoumax(buf, NULL, base);
-				else
-					res = strtoimax(buf, NULL, base);
-				if (flags & POINTER)
-					*va_arg(ap, void **) =
-					    (void *)(uintptr_t)res;
-				else if (flags & MAXINT)
-					*va_arg(ap, intmax_t *) = res;
-				else if (flags & LLONG)
-					*va_arg(ap, long long *) = res;
-				else if (flags & SIZEINT)
-					*va_arg(ap, ssize_t *) = res;
-				else if (flags & PTRINT)
-					*va_arg(ap, ptrdiff_t *) = res;
-				else if (flags & LONG)
-					*va_arg(ap, long *) = res;
-				else if (flags & SHORT)
-					*va_arg(ap, short *) = res;
-				else if (flags & SHORTSHORT)
-					*va_arg(ap, signed char *) = res;
-				else
-					*va_arg(ap, int *) = res;
-				nassigned++;
-			}
-			nread += p - buf;
-			break;
-
-#ifdef FLOATING_POINT
-		case CT_FLOAT:
-			/* scan a floating point number as if by strtod */
-			if (width == 0 || width > sizeof(buf) - 1)
-				width = sizeof(buf) - 1;
-			if ((width = parsefloat(fp, buf, buf + width)) == 0)
-				goto match_failure;
-			if ((flags & SUPPRESS) == 0) {
-				if (flags & LONGDBL) {
-					long double res = strtold(buf, &p);
-					*va_arg(ap, long double *) = res;
-				} else if (flags & LONG) {
-					double res = strtod(buf, &p);
-					*va_arg(ap, double *) = res;
-				} else {
-					float res = strtof(buf, &p);
-					*va_arg(ap, float *) = res;
-				}
-				if ((size_t)(p - buf) != width) abort();
-				nassigned++;
-			}
-			nread += width;
-			break;
-#endif /* FLOATING_POINT */
-		}
-	}
+      case CT_FLOAT:
+        /* scan a floating point number as if by strtod */
+        if (width == 0 || width > sizeof(buf) - 1) width = sizeof(buf) - 1;
+        if ((width = parsefloat(fp, buf, buf + width)) == 0) goto match_failure;
+        if ((flags & SUPPRESS) == 0) {
+          if (flags & LONGDBL) {
+            long double res = strtold(buf, &p);
+            *va_arg(ap, long double*) = res;
+          } else if (flags & LONG) {
+            double res = strtod(buf, &p);
+            *va_arg(ap, double*) = res;
+          } else {
+            float res = strtof(buf, &p);
+            *va_arg(ap, float*) = res;
+          }
+          if ((size_t)(p - buf) != width) abort();
+          nassigned++;
+        }
+        nread += width;
+        break;
+    }
+  }
 input_failure:
-	if (nassigned == 0)
-		nassigned = -1;
+  if (nassigned == 0) nassigned = -1;
 match_failure:
-	return (nassigned);
+  return (nassigned);
 }
 
 /*
@@ -796,103 +756,85 @@
  * closing `]'.  The table has a 1 wherever characters should be
  * considered part of the scanset.
  */
-static u_char *
-__sccl(char *tab, u_char *fmt)
-{
-	int c, n, v;
+static u_char* __sccl(char* tab, u_char* fmt) {
+  int c, n, v;
 
-	/* first `clear' the whole table */
-	c = *fmt++;		/* first char hat => negated scanset */
-	if (c == '^') {
-		v = 1;		/* default => accept */
-		c = *fmt++;	/* get new first char */
-	} else
-		v = 0;		/* default => reject */
-	/* should probably use memset here */
-	for (n = 0; n < 256; n++)
-		tab[n] = v;
-	if (c == 0)
-		return (fmt - 1);/* format ended before closing ] */
+  /* first `clear' the whole table */
+  c = *fmt++; /* first char hat => negated scanset */
+  if (c == '^') {
+    v = 1;      /* default => accept */
+    c = *fmt++; /* get new first char */
+  } else
+    v = 0; /* default => reject */
+  /* should probably use memset here */
+  for (n = 0; n < 256; n++) tab[n] = v;
+  if (c == 0) return (fmt - 1); /* format ended before closing ] */
 
-	/*
-	 * Now set the entries corresponding to the actual scanset
-	 * to the opposite of the above.
-	 *
-	 * The first character may be ']' (or '-') without being special;
-	 * the last character may be '-'.
-	 */
-	v = 1 - v;
-	for (;;) {
-		tab[c] = v;		/* take character c */
-doswitch:
-		n = *fmt++;		/* and examine the next */
-		switch (n) {
+  /*
+   * Now set the entries corresponding to the actual scanset
+   * to the opposite of the above.
+   *
+   * The first character may be ']' (or '-') without being special;
+   * the last character may be '-'.
+   */
+  v = 1 - v;
+  for (;;) {
+    tab[c] = v; /* take character c */
+  doswitch:
+    n = *fmt++; /* and examine the next */
+    switch (n) {
+      case 0: /* format ended too soon */
+        return (fmt - 1);
 
-		case 0:			/* format ended too soon */
-			return (fmt - 1);
-
-		case '-':
-			/*
-			 * A scanset of the form
-			 *	[01+-]
-			 * is defined as `the digit 0, the digit 1,
-			 * the character +, the character -', but
-			 * the effect of a scanset such as
-			 *	[a-zA-Z0-9]
-			 * is implementation defined.  The V7 Unix
-			 * scanf treats `a-z' as `the letters a through
-			 * z', but treats `a-a' as `the letter a, the
-			 * character -, and the letter a'.
-			 *
-			 * For compatibility, the `-' is not considerd
-			 * to define a range if the character following
-			 * it is either a close bracket (required by ANSI)
-			 * or is not numerically greater than the character
-			 * we just stored in the table (c).
-			 */
-			n = *fmt;
-			if (n == ']' || n < c) {
-				c = '-';
-				break;	/* resume the for(;;) */
-			}
-			fmt++;
-			do {		/* fill in the range */
-				tab[++c] = v;
-			} while (c < n);
-#if 1	/* XXX another disgusting compatibility hack */
-			/*
-			 * Alas, the V7 Unix scanf also treats formats
-			 * such as [a-c-e] as `the letters a through e'.
-			 * This too is permitted by the standard....
-			 */
-			goto doswitch;
+      case '-':
+        /*
+         * A scanset of the form
+         *	[01+-]
+         * is defined as `the digit 0, the digit 1,
+         * the character +, the character -', but
+         * the effect of a scanset such as
+         *	[a-zA-Z0-9]
+         * is implementation defined.  The V7 Unix
+         * scanf treats `a-z' as `the letters a through
+         * z', but treats `a-a' as `the letter a, the
+         * character -, and the letter a'.
+         *
+         * For compatibility, the `-' is not considerd
+         * to define a range if the character following
+         * it is either a close bracket (required by ANSI)
+         * or is not numerically greater than the character
+         * we just stored in the table (c).
+         */
+        n = *fmt;
+        if (n == ']' || n < c) {
+          c = '-';
+          break; /* resume the for(;;) */
+        }
+        fmt++;
+        do { /* fill in the range */
+          tab[++c] = v;
+        } while (c < n);
+#if 1 /* XXX another disgusting compatibility hack */
+        /*
+         * Alas, the V7 Unix scanf also treats formats
+         * such as [a-c-e] as `the letters a through e'.
+         * This too is permitted by the standard....
+         */
+        goto doswitch;
 #else
-			c = *fmt++;
-			if (c == 0)
-				return (fmt - 1);
-			if (c == ']')
-				return (fmt);
+        c = *fmt++;
+        if (c == 0) return (fmt - 1);
+        if (c == ']') return (fmt);
 #endif
-			break;
+        break;
 
-		case ']':		/* end of scanset */
-			return (fmt);
+      case ']': /* end of scanset */
+        return (fmt);
 
-		default:		/* just another character */
-			c = n;
-			break;
-		}
-	}
-	/* NOTREACHED */
-}
-
-int
-vfscanf(FILE *fp, const char *fmt0, __va_list ap)
-{
-	int r;
-
-	FLOCKFILE(fp);
-	r = __svfscanf(fp, fmt0, ap);
-	FUNLOCKFILE(fp);
-	return (r);
+      default: /* just another character */
+        c = n;
+        break;
+    }
+  }
+  /* NOTREACHED */
 }
diff --git a/libc/stdio/vfwprintf.cpp b/libc/stdio/vfwprintf.cpp
new file mode 100644
index 0000000..7a00202
--- /dev/null
+++ b/libc/stdio/vfwprintf.cpp
@@ -0,0 +1,680 @@
+/*	$OpenBSD: vfwprintf.c,v 1.15 2015/12/28 22:08:18 mmcc Exp $ */
+/*-
+ * Copyright (c) 1990 The Regents of the University of California.
+ * All rights reserved.
+ *
+ * This code is derived from software contributed to Berkeley by
+ * Chris Torek.
+ *
+ * Redistribution and use in source and binary forms, with or without
+ * modification, are permitted provided that the following conditions
+ * are met:
+ * 1. Redistributions of source code must retain the above copyright
+ *    notice, this list of conditions and the following disclaimer.
+ * 2. Redistributions in binary form must reproduce the above copyright
+ *    notice, this list of conditions and the following disclaimer in the
+ *    documentation and/or other materials provided with the distribution.
+ * 3. Neither the name of the University nor the names of its contributors
+ *    may be used to endorse or promote products derived from this software
+ *    without specific prior written permission.
+ *
+ * THIS SOFTWARE IS PROVIDED BY THE REGENTS AND CONTRIBUTORS ``AS IS'' AND
+ * ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE
+ * IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE
+ * ARE DISCLAIMED.  IN NO EVENT SHALL THE REGENTS OR CONTRIBUTORS BE LIABLE
+ * FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL
+ * DAMAGES (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS
+ * OR SERVICES; LOSS OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION)
+ * HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT
+ * LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY
+ * OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF
+ * SUCH DAMAGE.
+ */
+
+#define CHAR_TYPE wchar_t
+#define FUNCTION_NAME __vfwprintf
+#define CHAR_TYPE_STRLEN wcslen
+#define CHAR_TYPE_STRNLEN wcsnlen
+#define CHAR_TYPE_INF L"INF"
+#define CHAR_TYPE_inf L"inf"
+#define CHAR_TYPE_NAN L"NAN"
+#define CHAR_TYPE_nan L"nan"
+#define CHAR_TYPE_ORIENTATION 1
+#include "printf_common.h"
+
+int FUNCTION_NAME(FILE* fp, const CHAR_TYPE* fmt0, va_list ap) {
+  int n, n2;
+  CHAR_TYPE* cp;   /* handy char pointer (short term usage) */
+  CHAR_TYPE sign;  /* sign prefix (' ', '+', '-', or \0) */
+  int flags;     /* flags as above */
+  int ret;       /* return value accumulator */
+  int width;     /* width from format (%8d), or 0 */
+  int prec;      /* precision from format; <0 for N/A */
+  /*
+   * We can decompose the printed representation of floating
+   * point numbers into several parts, some of which may be empty:
+   *
+   * [+|-| ] [0x|0X] MMM . NNN [e|E|p|P] [+|-] ZZ
+   *    A       B     ---C---      D       E   F
+   *
+   * A:	'sign' holds this value if present; '\0' otherwise
+   * B:	ox[1] holds the 'x' or 'X'; '\0' if not hexadecimal
+   * C:	cp points to the string MMMNNN.  Leading and trailing
+   *	zeros are not in the string and must be added.
+   * D:	expchar holds this character; '\0' if no exponent, e.g. %f
+   * F:	at least two digits for decimal, at least one digit for hex
+   */
+  char* decimal_point = NULL;
+  int signflag; /* true if float is negative */
+  union {       /* floating point arguments %[aAeEfFgG] */
+    double dbl;
+    long double ldbl;
+  } fparg;
+  int expt;                      /* integer value of exponent */
+  char expchar;                  /* exponent character: [eEpP\0] */
+  char* dtoaend;                 /* pointer to end of converted digits */
+  int expsize;                   /* character count for expstr */
+  int lead;                      /* sig figs before decimal or group sep */
+  int ndig;                      /* actual number of digits returned by dtoa */
+  CHAR_TYPE expstr[MAXEXPDIG + 2]; /* buffer for exponent string: e+ZZZ */
+  char* dtoaresult = NULL;
+
+  uintmax_t _umax;             /* integer arguments %[diouxX] */
+  enum { OCT, DEC, HEX } base; /* base for %[diouxX] conversion */
+  int dprec;                   /* a copy of prec if %[diouxX], 0 otherwise */
+  int realsz;                  /* field size expanded by dprec */
+  int size;                    /* size of converted field or string */
+  const char* xdigs;           /* digits for %[xX] conversion */
+#define NIOV 8
+  struct __suio uio;       /* output information: summary */
+  struct __siov iov[NIOV]; /* ... and individual io vectors */
+  struct __siov* iovp; /* for PRINT macro */
+  CHAR_TYPE buf[BUF];            /* buffer with space for digits of uintmax_t */
+  CHAR_TYPE ox[2];               /* space for 0x; ox[1] is either x, X, or \0 */
+  union arg* argtable;         /* args, built due to positional arg */
+  union arg statargtable[STATIC_ARG_TBL_SIZE];
+  size_t argtablesiz;
+  int nextarg;      /* 1-based argument index */
+  va_list orgap;    /* original argument pointer */
+  CHAR_TYPE* convbuf; /* buffer for wide/multibyte conversion */
+
+  /*
+   * Choose PADSIZE to trade efficiency vs. size.  If larger printf
+   * fields occur frequently, increase PADSIZE and make the initialisers
+   * below longer.
+   */
+#define PADSIZE 16 /* pad chunk size */
+  static CHAR_TYPE blanks[PADSIZE] = {
+    ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' '
+  };
+  static CHAR_TYPE zeroes[PADSIZE] = {
+    '0', '0', '0', '0', '0', '0', '0', '0', '0', '0', '0', '0', '0', '0', '0', '0'
+  };
+
+  static const char xdigs_lower[] = "0123456789abcdef";
+  static const char xdigs_upper[] = "0123456789ABCDEF";
+
+#define PRINT(ptr, len)                                   \
+  do {                                                    \
+    for (int n3 = 0; n3 < (len); n3++) {                      \
+      if ((helpers::xfputwc((ptr)[n3], fp)) == WEOF) goto error; \
+    }                                                     \
+  } while (0)
+
+  _SET_ORIENTATION(fp, CHAR_TYPE_ORIENTATION);
+
+  // Writing "" to a read only file returns EOF, not 0.
+  if (cantwrite(fp)) {
+    errno = EBADF;
+    return EOF;
+  }
+
+  // Optimize writes to stderr and other unbuffered files).
+  if ((fp->_flags & (__SNBF | __SWR | __SRW)) == (__SNBF | __SWR) && fp->_file >= 0) {
+    return (__sbprintf(fp, fmt0, ap));
+  }
+
+  CHAR_TYPE* fmt = const_cast<CHAR_TYPE*>(fmt0);
+  argtable = NULL;
+  nextarg = 1;
+  va_copy(orgap, ap);
+  uio.uio_iov = iovp = iov;
+  uio.uio_resid = 0;
+  uio.uio_iovcnt = 0;
+  ret = 0;
+  convbuf = NULL;
+
+  /*
+   * Scan the format for conversions (`%' character).
+   */
+  for (;;) {
+    int ch;
+    for (cp = fmt; (ch = *fmt) != '\0' && ch != '%'; fmt++) continue;
+    if (fmt != cp) {
+      ptrdiff_t m = fmt - cp;
+      if (m < 0 || m > INT_MAX - ret) goto overflow;
+      PRINT(cp, m);
+      ret += m;
+    }
+    if (ch == '\0') goto done;
+    fmt++; /* skip over '%' */
+
+    flags = 0;
+    dprec = 0;
+    width = 0;
+    prec = -1;
+    sign = '\0';
+    ox[1] = '\0';
+
+  rflag:
+    ch = *fmt++;
+  reswitch:
+    switch (ch) {
+      case ' ':
+        /*
+         * ``If the space and + flags both appear, the space
+         * flag will be ignored.''
+         *	-- ANSI X3J11
+         */
+        if (!sign) sign = ' ';
+        goto rflag;
+      case '#':
+        flags |= ALT;
+        goto rflag;
+      case '\'':
+        /* grouping not implemented */
+        goto rflag;
+      case '*':
+        /*
+         * ``A negative field width argument is taken as a
+         * - flag followed by a positive field width.''
+         *	-- ANSI X3J11
+         * They don't exclude field widths read from args.
+         */
+        GETASTER(width);
+        if (width >= 0) goto rflag;
+        if (width == INT_MIN) goto overflow;
+        width = -width;
+        /* FALLTHROUGH */
+      case '-':
+        flags |= LADJUST;
+        goto rflag;
+      case '+':
+        sign = '+';
+        goto rflag;
+      case '.':
+        if ((ch = *fmt++) == '*') {
+          GETASTER(n);
+          prec = n < 0 ? -1 : n;
+          goto rflag;
+        }
+        n = 0;
+        while (is_digit(ch)) {
+          APPEND_DIGIT(n, ch);
+          ch = *fmt++;
+        }
+        if (ch == '$') {
+          nextarg = n;
+          if (argtable == NULL) {
+            argtable = statargtable;
+            if (__find_arguments(fmt0, orgap, &argtable, &argtablesiz) == -1) {
+              ret = -1;
+              goto error;
+            }
+          }
+          goto rflag;
+        }
+        prec = n;
+        goto reswitch;
+      case '0':
+        /*
+         * ``Note that 0 is taken as a flag, not as the
+         * beginning of a field width.''
+         *	-- ANSI X3J11
+         */
+        flags |= ZEROPAD;
+        goto rflag;
+      case '1':
+      case '2':
+      case '3':
+      case '4':
+      case '5':
+      case '6':
+      case '7':
+      case '8':
+      case '9':
+        n = 0;
+        do {
+          APPEND_DIGIT(n, ch);
+          ch = *fmt++;
+        } while (is_digit(ch));
+        if (ch == '$') {
+          nextarg = n;
+          if (argtable == NULL) {
+            argtable = statargtable;
+            if (__find_arguments(fmt0, orgap, &argtable, &argtablesiz) == -1) {
+              ret = -1;
+              goto error;
+            }
+          }
+          goto rflag;
+        }
+        width = n;
+        goto reswitch;
+      case 'L':
+        flags |= LONGDBL;
+        goto rflag;
+      case 'h':
+        if (*fmt == 'h') {
+          fmt++;
+          flags |= CHARINT;
+        } else {
+          flags |= SHORTINT;
+        }
+        goto rflag;
+      case 'j':
+        flags |= MAXINT;
+        goto rflag;
+      case 'l':
+        if (*fmt == 'l') {
+          fmt++;
+          flags |= LLONGINT;
+        } else {
+          flags |= LONGINT;
+        }
+        goto rflag;
+      case 'q':
+        flags |= LLONGINT;
+        goto rflag;
+      case 't':
+        flags |= PTRINT;
+        goto rflag;
+      case 'z':
+        flags |= SIZEINT;
+        goto rflag;
+      case 'C':
+        flags |= LONGINT;
+        /*FALLTHROUGH*/
+      case 'c':
+        if (flags & LONGINT)
+          *(cp = buf) = (wchar_t)GETARG(wint_t);
+        else
+          *(cp = buf) = (wchar_t)btowc(GETARG(int));
+        size = 1;
+        sign = '\0';
+        break;
+      case 'D':
+        flags |= LONGINT;
+        /*FALLTHROUGH*/
+      case 'd':
+      case 'i':
+        _umax = SARG();
+        if ((intmax_t)_umax < 0) {
+          _umax = -_umax;
+          sign = '-';
+        }
+        base = DEC;
+        goto number;
+      case 'a':
+      case 'A':
+        if (ch == 'a') {
+          ox[1] = 'x';
+          xdigs = xdigs_lower;
+          expchar = 'p';
+        } else {
+          ox[1] = 'X';
+          xdigs = xdigs_upper;
+          expchar = 'P';
+        }
+        if (prec >= 0) prec++;
+        if (dtoaresult) __freedtoa(dtoaresult);
+        if (flags & LONGDBL) {
+          fparg.ldbl = GETARG(long double);
+          dtoaresult = __hldtoa(fparg.ldbl, xdigs, prec, &expt, &signflag, &dtoaend);
+          if (dtoaresult == NULL) {
+            errno = ENOMEM;
+            goto error;
+          }
+        } else {
+          fparg.dbl = GETARG(double);
+          dtoaresult = __hdtoa(fparg.dbl, xdigs, prec, &expt, &signflag, &dtoaend);
+          if (dtoaresult == NULL) {
+            errno = ENOMEM;
+            goto error;
+          }
+        }
+        if (prec < 0) prec = dtoaend - dtoaresult;
+        if (expt == INT_MAX) ox[1] = '\0';
+        free(convbuf);
+        cp = convbuf = helpers::mbsconv(dtoaresult, -1);
+        if (cp == NULL) goto error;
+        ndig = dtoaend - dtoaresult;
+        goto fp_common;
+      case 'e':
+      case 'E':
+        expchar = ch;
+        if (prec < 0) /* account for digit before decpt */
+          prec = DEFPREC + 1;
+        else
+          prec++;
+        goto fp_begin;
+      case 'f':
+      case 'F':
+        expchar = '\0';
+        goto fp_begin;
+      case 'g':
+      case 'G':
+        expchar = ch - ('g' - 'e');
+        if (prec == 0) prec = 1;
+      fp_begin:
+        if (prec < 0) prec = DEFPREC;
+        if (dtoaresult) __freedtoa(dtoaresult);
+        if (flags & LONGDBL) {
+          fparg.ldbl = GETARG(long double);
+          dtoaresult = __ldtoa(&fparg.ldbl, expchar ? 2 : 3, prec, &expt, &signflag, &dtoaend);
+          if (dtoaresult == NULL) {
+            errno = ENOMEM;
+            goto error;
+          }
+        } else {
+          fparg.dbl = GETARG(double);
+          dtoaresult = __dtoa(fparg.dbl, expchar ? 2 : 3, prec, &expt, &signflag, &dtoaend);
+          if (dtoaresult == NULL) {
+            errno = ENOMEM;
+            goto error;
+          }
+          if (expt == 9999) expt = INT_MAX;
+        }
+        free(convbuf);
+        cp = convbuf = helpers::mbsconv(dtoaresult, -1);
+        if (cp == NULL) goto error;
+        ndig = dtoaend - dtoaresult;
+      fp_common:
+        if (signflag) sign = '-';
+        if (expt == INT_MAX) { /* inf or nan */
+          if (*cp == 'N') {
+            cp = const_cast<CHAR_TYPE*>((ch >= 'a') ? CHAR_TYPE_nan : CHAR_TYPE_NAN);
+          } else {
+            cp = const_cast<CHAR_TYPE*>((ch >= 'a') ? CHAR_TYPE_inf : CHAR_TYPE_INF);
+          }
+          size = 3;
+          flags &= ~ZEROPAD;
+          break;
+        }
+        flags |= FPT;
+        if (ch == 'g' || ch == 'G') {
+          if (expt > -4 && expt <= prec) {
+            /* Make %[gG] smell like %[fF] */
+            expchar = '\0';
+            if (flags & ALT)
+              prec -= expt;
+            else
+              prec = ndig - expt;
+            if (prec < 0) prec = 0;
+          } else {
+            /*
+             * Make %[gG] smell like %[eE], but
+             * trim trailing zeroes if no # flag.
+             */
+            if (!(flags & ALT)) prec = ndig;
+          }
+        }
+        if (expchar) {
+          expsize = exponent(expstr, expt - 1, expchar);
+          size = expsize + prec;
+          if (prec > 1 || flags & ALT) ++size;
+        } else {
+          /* space for digits before decimal point */
+          if (expt > 0)
+            size = expt;
+          else /* "0" */
+            size = 1;
+          /* space for decimal pt and following digits */
+          if (prec || flags & ALT) size += prec + 1;
+          lead = expt;
+        }
+        break;
+#ifndef NO_PRINTF_PERCENT_N
+      case 'n':
+        if (flags & LLONGINT)
+          *GETARG(long long*) = ret;
+        else if (flags & LONGINT)
+          *GETARG(long*) = ret;
+        else if (flags & SHORTINT)
+          *GETARG(short*) = ret;
+        else if (flags & CHARINT)
+          *GETARG(signed char*) = ret;
+        else if (flags & PTRINT)
+          *GETARG(ptrdiff_t*) = ret;
+        else if (flags & SIZEINT)
+          *GETARG(ssize_t*) = ret;
+        else if (flags & MAXINT)
+          *GETARG(intmax_t*) = ret;
+        else
+          *GETARG(int*) = ret;
+        continue; /* no output */
+#endif            /* NO_PRINTF_PERCENT_N */
+      case 'O':
+        flags |= LONGINT;
+        /*FALLTHROUGH*/
+      case 'o':
+        _umax = UARG();
+        base = OCT;
+        goto nosign;
+      case 'p':
+        /*
+         * ``The argument shall be a pointer to void.  The
+         * value of the pointer is converted to a sequence
+         * of printable characters, in an implementation-
+         * defined manner.''
+         *	-- ANSI X3J11
+         */
+        _umax = (u_long)GETARG(void*);
+        base = HEX;
+        xdigs = xdigs_lower;
+        ox[1] = 'x';
+        goto nosign;
+      case 'S':
+        flags |= LONGINT;
+        /*FALLTHROUGH*/
+      case 's':
+        if (flags & LONGINT) {
+          if ((cp = GETARG(wchar_t*)) == NULL) cp = const_cast<wchar_t*>(L"(null)");
+        } else {
+          char* mbsarg;
+          if ((mbsarg = GETARG(char*)) == NULL) mbsarg = const_cast<char*>("(null)");
+          free(convbuf);
+          convbuf = helpers::mbsconv(mbsarg, prec);
+          if (convbuf == NULL) {
+            fp->_flags |= __SERR;
+            goto error;
+          } else {
+            cp = convbuf;
+          }
+        }
+        if (prec >= 0) {
+          size = CHAR_TYPE_STRNLEN(cp, prec);
+        } else {
+          size_t len;
+
+          if ((len = CHAR_TYPE_STRLEN(cp)) > INT_MAX) goto overflow;
+          size = (int)len;
+        }
+        sign = '\0';
+        break;
+      case 'U':
+        flags |= LONGINT;
+        /*FALLTHROUGH*/
+      case 'u':
+        _umax = UARG();
+        base = DEC;
+        goto nosign;
+      case 'X':
+        xdigs = xdigs_upper;
+        goto hex;
+      case 'x':
+        xdigs = xdigs_lower;
+      hex:
+        _umax = UARG();
+        base = HEX;
+        /* leading 0x/X only if non-zero */
+        if (flags & ALT && _umax != 0) ox[1] = ch;
+
+        /* unsigned conversions */
+      nosign:
+        sign = '\0';
+        /*
+         * ``... diouXx conversions ... if a precision is
+         * specified, the 0 flag will be ignored.''
+         *	-- ANSI X3J11
+         */
+      number:
+        if ((dprec = prec) >= 0) flags &= ~ZEROPAD;
+
+        /*
+         * ``The result of converting a zero value with an
+         * explicit precision of zero is no characters.''
+         *	-- ANSI X3J11
+         */
+        cp = buf + BUF;
+        if (_umax != 0 || prec != 0) {
+          /*
+           * Unsigned mod is hard, and unsigned mod
+           * by a constant is easier than that by
+           * a variable; hence this switch.
+           */
+          switch (base) {
+            case OCT:
+              do {
+                *--cp = to_char(_umax & 7);
+                _umax >>= 3;
+              } while (_umax);
+              /* handle octal leading 0 */
+              if (flags & ALT && *cp != '0') *--cp = '0';
+              break;
+
+            case DEC:
+              /* many numbers are 1 digit */
+              while (_umax >= 10) {
+                *--cp = to_char(_umax % 10);
+                _umax /= 10;
+              }
+              *--cp = to_char(_umax);
+              break;
+
+            case HEX:
+              do {
+                *--cp = xdigs[_umax & 15];
+                _umax >>= 4;
+              } while (_umax);
+              break;
+
+            default:
+              abort();
+          }
+        }
+        size = buf + BUF - cp;
+        if (size > BUF) abort(); /* should never happen */
+        break;
+      default: /* "%?" prints ?, unless ? is NUL */
+        if (ch == '\0') goto done;
+        /* pretend it was %c with argument ch */
+        cp = buf;
+        *cp = ch;
+        size = 1;
+        sign = '\0';
+        break;
+    }
+
+    /*
+     * All reasonable formats wind up here.  At this point, `cp'
+     * points to a string which (if not flags&LADJUST) should be
+     * padded out to `width' places.  If flags&ZEROPAD, it should
+     * first be prefixed by any sign or other prefix; otherwise,
+     * it should be blank padded before the prefix is emitted.
+     * After any left-hand padding and prefixing, emit zeroes
+     * required by a decimal %[diouxX] precision, then print the
+     * string proper, then emit zeroes required by any leftover
+     * floating precision; finally, if LADJUST, pad with blanks.
+     *
+     * Compute actual size, so we know how much to pad.
+     * size excludes decimal prec; realsz includes it.
+     */
+    realsz = dprec > size ? dprec : size;
+    if (sign) realsz++;
+    if (ox[1]) realsz += 2;
+
+    /* right-adjusting blank padding */
+    if ((flags & (LADJUST | ZEROPAD)) == 0) PAD(width - realsz, blanks);
+
+    /* prefix */
+    if (sign) PRINT(&sign, 1);
+    if (ox[1]) { /* ox[1] is either x, X, or \0 */
+      ox[0] = '0';
+      PRINT(ox, 2);
+    }
+
+    /* right-adjusting zero padding */
+    if ((flags & (LADJUST | ZEROPAD)) == ZEROPAD) PAD(width - realsz, zeroes);
+
+    /* leading zeroes from decimal precision */
+    PAD(dprec - size, zeroes);
+
+    /* the string or number proper */
+    if ((flags & FPT) == 0) {
+      PRINT(cp, size);
+    } else { /* glue together f_p fragments */
+      if (decimal_point == NULL) decimal_point = nl_langinfo(RADIXCHAR);
+      if (!expchar) { /* %[fF] or sufficiently short %[gG] */
+        if (expt <= 0) {
+          PRINT(zeroes, 1);
+          if (prec || flags & ALT) PRINT(decimal_point, 1);
+          PAD(-expt, zeroes);
+          /* already handled initial 0's */
+          prec += expt;
+        } else {
+          PRINTANDPAD(cp, convbuf + ndig, lead, zeroes);
+          cp += lead;
+          if (prec || flags & ALT) PRINT(decimal_point, 1);
+        }
+        PRINTANDPAD(cp, convbuf + ndig, prec, zeroes);
+      } else { /* %[eE] or sufficiently long %[gG] */
+        if (prec > 1 || flags & ALT) {
+          buf[0] = *cp++;
+          buf[1] = *decimal_point;
+          PRINT(buf, 2);
+          PRINT(cp, ndig - 1);
+          PAD(prec - ndig, zeroes);
+        } else { /* XeYYY */
+          PRINT(cp, 1);
+        }
+        PRINT(expstr, expsize);
+      }
+    }
+    /* left-adjusting padding (always blank) */
+    if (flags & LADJUST) PAD(width - realsz, blanks);
+
+    /* finally, adjust ret */
+    if (width < realsz) width = realsz;
+    if (width > INT_MAX - ret) goto overflow;
+    ret += width;
+  }
+done:
+error:
+  va_end(orgap);
+  if (__sferror(fp)) ret = -1;
+  goto finish;
+
+overflow:
+  errno = ENOMEM;
+  ret = -1;
+
+finish:
+  free(convbuf);
+  if (dtoaresult) __freedtoa(dtoaresult);
+  if (argtable != NULL && argtable != statargtable) {
+    munmap(argtable, argtablesiz);
+    argtable = NULL;
+  }
+  return (ret);
+}
diff --git a/libc/stdio/vfwscanf.c b/libc/stdio/vfwscanf.c
index 0a7bfa9..206f4a2 100644
--- a/libc/stdio/vfwscanf.c
+++ b/libc/stdio/vfwscanf.c
@@ -42,58 +42,54 @@
 #include <wctype.h>
 #include "local.h"
 
-#ifdef FLOATING_POINT
-#include "floatio.h"
-#endif
-
-#define	BUF		513	/* Maximum length of numeric string. */
+#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 */
+#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 */
 
 /*
  * 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 */
+#define SIGNOK 0x01000   /* +/- is (still) legal */
+#define HAVESIGN 0x02000 /* sign detected */
+#define NDIGITS 0x04000  /* no digits detected */
 
-#define	DPTOK		0x08000	/* (float) decimal point is still legal */
-#define	EXPOK		0x10000	/* (float) exponent (e+3, etc) still legal */
+#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 */
+#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 */
+#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 */
 
 #define u_char unsigned char
 #define u_long unsigned long
 
-#define	INCCL(_c)	\
-	(cclcompl ? (wmemchr(ccls, (_c), ccle - ccls) == NULL) : \
-	(wmemchr(ccls, (_c), ccle - ccls) != NULL))
+#define INCCL(_c)                                        \
+  (cclcompl ? (wmemchr(ccls, (_c), ccle - ccls) == NULL) \
+            : (wmemchr(ccls, (_c), ccle - ccls) != NULL))
 
 #pragma GCC diagnostic push
 #pragma GCC diagnostic ignored "-Wframe-larger-than="
@@ -101,627 +97,560 @@
 /*
  * vfwscanf
  */
-int
-__vfwscanf(FILE * __restrict fp, const wchar_t * __restrict fmt, __va_list ap)
-{
-	wint_t c;	/* character from format, or conversion */
-	size_t width;	/* field width, or 0 */
-	wchar_t *p;	/* points into all kinds of strings */
-	int n;		/* handy integer */
-	int flags;	/* flags as defined above */
-	wchar_t *p0;	/* saves original value of p when necessary */
-	int nassigned;		/* number of fields assigned */
-	int nconversions;	/* number of conversions */
-	int nread;		/* number of characters consumed from fp */
-	int base;		/* base argument to strtoimax/strtouimax */
-	wchar_t buf[BUF];	/* buffer for numeric conversions */
-	const wchar_t *ccls;	/* character class start */
-	const wchar_t *ccle;	/* character class end */
-	int cclcompl;		/* ccl is complemented? */
-	wint_t wi;		/* handy wint_t */
-	char *mbp;		/* multibyte string pointer for %c %s %[ */
-	size_t nconv;		/* number of bytes in mb. conversion */
-	char mbbuf[MB_LEN_MAX];	/* temporary mb. character buffer */
- 	mbstate_t mbs;
+int __vfwscanf(FILE* __restrict fp, const wchar_t* __restrict fmt, __va_list ap) {
+  wint_t c;               /* character from format, or conversion */
+  size_t width;           /* field width, or 0 */
+  wchar_t* p;             /* points into all kinds of strings */
+  int n;                  /* handy integer */
+  int flags;              /* flags as defined above */
+  wchar_t* p0;            /* saves original value of p when necessary */
+  int nassigned;          /* number of fields assigned */
+  int nconversions;       /* number of conversions */
+  int nread;              /* number of characters consumed from fp */
+  int base;               /* base argument to strtoimax/strtouimax */
+  wchar_t buf[BUF];       /* buffer for numeric conversions */
+  const wchar_t* ccls;    /* character class start */
+  const wchar_t* ccle;    /* character class end */
+  int cclcompl;           /* ccl is complemented? */
+  wint_t wi;              /* handy wint_t */
+  char* mbp;              /* multibyte string pointer for %c %s %[ */
+  size_t nconv;           /* number of bytes in mb. conversion */
+  char mbbuf[MB_LEN_MAX]; /* temporary mb. character buffer */
+  mbstate_t mbs;
 
-	/* `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 };
+  /* `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 };
 
-	_SET_ORIENTATION(fp, 1);
+  _SET_ORIENTATION(fp, 1);
 
-	nassigned = 0;
-	nconversions = 0;
-	nread = 0;
-	base = 0;		/* XXX just to keep gcc happy */
-	ccls = ccle = NULL;
-	for (;;) {
-		c = *fmt++;
-		if (c == 0) {
-			return (nassigned);
-		}
-		if (iswspace(c)) {
-			while ((c = __fgetwc_unlock(fp)) != WEOF &&
-			    iswspace(c))
-				;
-			if (c != WEOF)
-				__ungetwc(c, fp);
-			continue;
-		}
-		if (c != '%')
-			goto literal;
-		width = 0;
-		flags = 0;
-		/*
-		 * switch on the format.  continue if done;
-		 * break once format type is derived.
-		 */
-again:		c = *fmt++;
-		switch (c) {
-		case '%':
-literal:
-			if ((wi = __fgetwc_unlock(fp)) == WEOF)
-				goto input_failure;
-			if (wi != c) {
-				__ungetwc(wi, fp);
-				goto input_failure;
-			}
-			nread++;
-			continue;
+  nassigned = 0;
+  nconversions = 0;
+  nread = 0;
+  base = 0; /* XXX just to keep gcc happy */
+  ccls = ccle = NULL;
+  for (;;) {
+    c = *fmt++;
+    if (c == 0) {
+      return (nassigned);
+    }
+    if (iswspace(c)) {
+      while ((c = __fgetwc_unlock(fp)) != WEOF && iswspace(c))
+        ;
+      if (c != WEOF) __ungetwc(c, fp);
+      continue;
+    }
+    if (c != '%') goto literal;
+    width = 0;
+    flags = 0;
+    /*
+     * switch on the format.  continue if done;
+     * break once format type is derived.
+     */
+  again:
+    c = *fmt++;
+    switch (c) {
+      case '%':
+      literal:
+        if ((wi = __fgetwc_unlock(fp)) == WEOF) goto input_failure;
+        if (wi != c) {
+          __ungetwc(wi, fp);
+          goto input_failure;
+        }
+        nread++;
+        continue;
 
-		case '*':
-			flags |= SUPPRESS;
-			goto again;
-		case 'j':
-			flags |= MAXINT;
-			goto again;
-		case 'L':
-			flags |= LONGDBL;
-			goto again;
-		case 'h':
-			if (*fmt == 'h') {
-				fmt++;
-				flags |= SHORTSHORT;
-			} else {
-				flags |= SHORT;
-			}
-			goto again;
-		case 'l':
-			if (*fmt == 'l') {
-				fmt++;
-				flags |= LLONG;
-			} else {
-				flags |= LONG;
-			}
-			goto again;
-		case 'q':
-			flags |= LLONG;		/* deprecated */
-			goto again;
-		case 't':
-			flags |= PTRINT;
-			goto again;
-		case 'z':
-			flags |= SIZEINT;
-			goto again;
+      case '*':
+        flags |= SUPPRESS;
+        goto again;
+      case 'j':
+        flags |= MAXINT;
+        goto again;
+      case 'L':
+        flags |= LONGDBL;
+        goto again;
+      case 'h':
+        if (*fmt == 'h') {
+          fmt++;
+          flags |= SHORTSHORT;
+        } else {
+          flags |= SHORT;
+        }
+        goto again;
+      case 'l':
+        if (*fmt == 'l') {
+          fmt++;
+          flags |= LLONG;
+        } else {
+          flags |= LONG;
+        }
+        goto again;
+      case 'q':
+        flags |= LLONG; /* deprecated */
+        goto again;
+      case 't':
+        flags |= PTRINT;
+        goto again;
+      case 'z':
+        flags |= SIZEINT;
+        goto again;
 
-		case '0': case '1': case '2': case '3': case '4':
-		case '5': case '6': case '7': case '8': case '9':
-			width = width * 10 + c - '0';
-			goto again;
+      case '0':
+      case '1':
+      case '2':
+      case '3':
+      case '4':
+      case '5':
+      case '6':
+      case '7':
+      case '8':
+      case '9':
+        width = width * 10 + c - '0';
+        goto again;
 
-		/*
-		 * Conversions.
-		 * Those marked `compat' are for 4.[123]BSD compatibility.
-		 *
-		 * (According to ANSI, E and X formats are supposed
-		 * to the same as e and x.  Sorry about that.)
-		 */
-		case 'D':	/* compat */
-			flags |= LONG;
-			/* FALLTHROUGH */
-		case 'd':
-			c = CT_INT;
-			base = 10;
-			break;
+      /*
+       * Conversions.
+       * Those marked `compat' are for 4.[123]BSD compatibility.
+       *
+       * (According to ANSI, E and X formats are supposed
+       * to the same as e and x.  Sorry about that.)
+       */
+      case 'D': /* compat */
+        flags |= LONG;
+        /* FALLTHROUGH */
+      case 'd':
+        c = CT_INT;
+        base = 10;
+        break;
 
-		case 'i':
-			c = CT_INT;
-			base = 0;
-			break;
+      case 'i':
+        c = CT_INT;
+        base = 0;
+        break;
 
-		case 'O':	/* compat */
-			flags |= LONG;
-			/* FALLTHROUGH */
-		case 'o':
-			c = CT_INT;
-			flags |= UNSIGNED;
-			base = 8;
-			break;
+      case 'O': /* compat */
+        flags |= LONG;
+        /* FALLTHROUGH */
+      case 'o':
+        c = CT_INT;
+        flags |= UNSIGNED;
+        base = 8;
+        break;
 
-		case 'u':
-			c = CT_INT;
-			flags |= UNSIGNED;
-			base = 10;
-			break;
+      case 'u':
+        c = CT_INT;
+        flags |= UNSIGNED;
+        base = 10;
+        break;
 
-		case 'X':
-		case 'x':
-			flags |= PFXOK;	/* enable 0x prefixing */
-			c = CT_INT;
-			flags |= UNSIGNED;
-			base = 16;
-			break;
+      case 'X':
+      case 'x':
+        flags |= PFXOK; /* enable 0x prefixing */
+        c = CT_INT;
+        flags |= UNSIGNED;
+        base = 16;
+        break;
 
-#ifdef FLOATING_POINT
-		case 'e': case 'E':
-		case 'f': case 'F':
-		case 'g': case 'G':
-		case 'a': case 'A':
-			c = CT_FLOAT;
-			break;
-#endif
+      case 'e':
+      case 'E':
+      case 'f':
+      case 'F':
+      case 'g':
+      case 'G':
+      case 'a':
+      case 'A':
+        c = CT_FLOAT;
+        break;
 
-		case 's':
-			c = CT_STRING;
-			break;
+      case 's':
+        c = CT_STRING;
+        break;
 
-		case '[':
-			ccls = fmt;
-			if (*fmt == '^') {
-				cclcompl = 1;
-				fmt++;
-			} else
-				cclcompl = 0;
-			if (*fmt == ']')
-				fmt++;
-			while (*fmt != '\0' && *fmt != ']')
-				fmt++;
-			ccle = fmt;
-			fmt++;
-			flags |= NOSKIP;
-			c = CT_CCL;
-			break;
+      case '[':
+        ccls = fmt;
+        if (*fmt == '^') {
+          cclcompl = 1;
+          fmt++;
+        } else
+          cclcompl = 0;
+        if (*fmt == ']') fmt++;
+        while (*fmt != '\0' && *fmt != ']') fmt++;
+        ccle = fmt;
+        fmt++;
+        flags |= NOSKIP;
+        c = CT_CCL;
+        break;
 
-		case 'c':
-			flags |= NOSKIP;
-			c = CT_CHAR;
-			break;
+      case 'c':
+        flags |= NOSKIP;
+        c = CT_CHAR;
+        break;
 
-		case 'p':	/* pointer format is like hex */
-			flags |= POINTER | PFXOK;
-			c = CT_INT;
-			flags |= UNSIGNED;
-			base = 16;
-			break;
+      case 'p': /* pointer format is like hex */
+        flags |= POINTER | PFXOK;
+        c = CT_INT;
+        flags |= UNSIGNED;
+        base = 16;
+        break;
 
-		case 'n':
-			nconversions++;
-			if (flags & SUPPRESS)
-				continue;
-			if (flags & SHORTSHORT)
-				*va_arg(ap, signed char *) = nread;
-			else if (flags & SHORT)
-				*va_arg(ap, short *) = nread;
-			else if (flags & LONG)
-				*va_arg(ap, long *) = nread;
-			else if (flags & SIZEINT)
-				*va_arg(ap, ssize_t *) = nread;
-			else if (flags & PTRINT)
-				*va_arg(ap, ptrdiff_t *) = nread;
-			else if (flags & LLONG)
-				*va_arg(ap, long long *) = nread;
-			else if (flags & MAXINT)
-				*va_arg(ap, intmax_t *) = nread;
-			else
-				*va_arg(ap, int *) = nread;
-			continue;
+      case 'n':
+        nconversions++;
+        if (flags & SUPPRESS) continue;
+        if (flags & SHORTSHORT)
+          *va_arg(ap, signed char*) = nread;
+        else if (flags & SHORT)
+          *va_arg(ap, short*) = nread;
+        else if (flags & LONG)
+          *va_arg(ap, long*) = nread;
+        else if (flags & SIZEINT)
+          *va_arg(ap, ssize_t*) = nread;
+        else if (flags & PTRINT)
+          *va_arg(ap, ptrdiff_t*) = nread;
+        else if (flags & LLONG)
+          *va_arg(ap, long long*) = nread;
+        else if (flags & MAXINT)
+          *va_arg(ap, intmax_t*) = nread;
+        else
+          *va_arg(ap, int*) = nread;
+        continue;
 
-		/*
-		 * Disgusting backwards compatibility hacks.	XXX
-		 */
-		case '\0':	/* compat */
-			return (EOF);
+      /*
+       * Disgusting backwards compatibility hacks.	XXX
+       */
+      case '\0': /* compat */
+        return (EOF);
 
-		default:	/* compat */
-			if (iswupper(c))
-				flags |= LONG;
-			c = CT_INT;
-			base = 10;
-			break;
-		}
+      default: /* compat */
+        if (iswupper(c)) flags |= LONG;
+        c = CT_INT;
+        base = 10;
+        break;
+    }
 
-		/*
-		 * Consume leading white space, except for formats
-		 * that suppress this.
-		 */
-		if ((flags & NOSKIP) == 0) {
-			while ((wi = __fgetwc_unlock(fp)) != WEOF &&
-			    iswspace(wi))
-				nread++;
-			if (wi == WEOF)
-				goto input_failure;
-			__ungetwc(wi, fp);
-		}
+    /*
+     * Consume leading white space, except for formats
+     * that suppress this.
+     */
+    if ((flags & NOSKIP) == 0) {
+      while ((wi = __fgetwc_unlock(fp)) != WEOF && iswspace(wi)) nread++;
+      if (wi == WEOF) goto input_failure;
+      __ungetwc(wi, fp);
+    }
 
-		/*
-		 * Do the conversion.
-		 */
-		switch (c) {
+    /*
+     * Do the conversion.
+     */
+    switch (c) {
+      case CT_CHAR:
+        /* scan arbitrary characters (sets NOSKIP) */
+        if (width == 0) width = 1;
+        if (flags & LONG) {
+          if (!(flags & SUPPRESS)) p = va_arg(ap, wchar_t*);
+          n = 0;
+          while (width-- != 0 && (wi = __fgetwc_unlock(fp)) != WEOF) {
+            if (!(flags & SUPPRESS)) *p++ = (wchar_t)wi;
+            n++;
+          }
+          if (n == 0) goto input_failure;
+          nread += n;
+          if (!(flags & SUPPRESS)) nassigned++;
+        } else {
+          if (!(flags & SUPPRESS)) mbp = va_arg(ap, char*);
+          n = 0;
+          memset(&mbs, 0, sizeof(mbs));
+          while (width != 0 && (wi = __fgetwc_unlock(fp)) != WEOF) {
+            if (width >= MB_CUR_MAX && !(flags & SUPPRESS)) {
+              nconv = wcrtomb(mbp, wi, &mbs);
+              if (nconv == (size_t)-1) goto input_failure;
+            } else {
+              nconv = wcrtomb(mbbuf, wi, &mbs);
+              if (nconv == (size_t)-1) goto input_failure;
+              if (nconv > width) {
+                __ungetwc(wi, fp);
+                break;
+              }
+              if (!(flags & SUPPRESS)) memcpy(mbp, mbbuf, nconv);
+            }
+            if (!(flags & SUPPRESS)) mbp += nconv;
+            width -= nconv;
+            n++;
+          }
+          if (n == 0) goto input_failure;
+          nread += n;
+          if (!(flags & SUPPRESS)) nassigned++;
+        }
+        nconversions++;
+        break;
 
-		case CT_CHAR:
-			/* scan arbitrary characters (sets NOSKIP) */
-			if (width == 0)
-				width = 1;
- 			if (flags & LONG) {
-				if (!(flags & SUPPRESS))
-					p = va_arg(ap, wchar_t *);
-				n = 0;
-				while (width-- != 0 &&
-				    (wi = __fgetwc_unlock(fp)) != WEOF) {
-					if (!(flags & SUPPRESS))
-						*p++ = (wchar_t)wi;
-					n++;
-				}
-				if (n == 0)
-					goto input_failure;
-				nread += n;
- 				if (!(flags & SUPPRESS))
- 					nassigned++;
-			} else {
-				if (!(flags & SUPPRESS))
-					mbp = va_arg(ap, char *);
-				n = 0;
-				memset(&mbs, 0, sizeof(mbs));
-				while (width != 0 &&
-				    (wi = __fgetwc_unlock(fp)) != WEOF) {
-					if (width >= MB_CUR_MAX &&
-					    !(flags & SUPPRESS)) {
-						nconv = wcrtomb(mbp, wi, &mbs);
-						if (nconv == (size_t)-1)
-							goto input_failure;
-					} else {
-						nconv = wcrtomb(mbbuf, wi,
-						    &mbs);
-						if (nconv == (size_t)-1)
-							goto input_failure;
-						if (nconv > width) {
-							__ungetwc(wi, fp);
- 							break;
- 						}
-						if (!(flags & SUPPRESS))
-							memcpy(mbp, mbbuf,
-							    nconv);
- 					}
-					if (!(flags & SUPPRESS))
-						mbp += nconv;
-					width -= nconv;
-					n++;
- 				}
-				if (n == 0)
- 					goto input_failure;
-				nread += n;
-				if (!(flags & SUPPRESS))
-					nassigned++;
-			}
-			nconversions++;
-			break;
+      case CT_CCL:
+        /* scan a (nonempty) character class (sets NOSKIP) */
+        if (width == 0) width = (size_t)~0; /* `infinity' */
+        /* take only those things in the class */
+        if ((flags & SUPPRESS) && (flags & LONG)) {
+          n = 0;
+          while ((wi = __fgetwc_unlock(fp)) != WEOF && width-- != 0 && INCCL(wi)) n++;
+          if (wi != WEOF) __ungetwc(wi, fp);
+          if (n == 0) goto match_failure;
+        } else if (flags & LONG) {
+          p0 = p = va_arg(ap, wchar_t*);
+          while ((wi = __fgetwc_unlock(fp)) != WEOF && width-- != 0 && INCCL(wi))
+            *p++ = (wchar_t)wi;
+          if (wi != WEOF) __ungetwc(wi, fp);
+          n = p - p0;
+          if (n == 0) goto match_failure;
+          *p = 0;
+          nassigned++;
+        } else {
+          if (!(flags & SUPPRESS)) mbp = va_arg(ap, char*);
+          n = 0;
+          memset(&mbs, 0, sizeof(mbs));
+          while ((wi = __fgetwc_unlock(fp)) != WEOF && width != 0 && INCCL(wi)) {
+            if (width >= MB_CUR_MAX && !(flags & SUPPRESS)) {
+              nconv = wcrtomb(mbp, wi, &mbs);
+              if (nconv == (size_t)-1) goto input_failure;
+            } else {
+              nconv = wcrtomb(mbbuf, wi, &mbs);
+              if (nconv == (size_t)-1) goto input_failure;
+              if (nconv > width) break;
+              if (!(flags & SUPPRESS)) memcpy(mbp, mbbuf, nconv);
+            }
+            if (!(flags & SUPPRESS)) mbp += nconv;
+            width -= nconv;
+            n++;
+          }
+          if (wi != WEOF) __ungetwc(wi, fp);
+          if (!(flags & SUPPRESS)) {
+            *mbp = 0;
+            nassigned++;
+          }
+        }
+        nread += n;
+        nconversions++;
+        break;
 
-		case CT_CCL:
-			/* scan a (nonempty) character class (sets NOSKIP) */
-			if (width == 0)
-				width = (size_t)~0;	/* `infinity' */
-			/* take only those things in the class */
-			if ((flags & SUPPRESS) && (flags & LONG)) {
-				n = 0;
-				while ((wi = __fgetwc_unlock(fp)) != WEOF &&
-				    width-- != 0 && INCCL(wi))
-					n++;
-				if (wi != WEOF)
-					__ungetwc(wi, fp);
-				if (n == 0)
-					goto match_failure;
-			} else if (flags & LONG) {
-				p0 = p = va_arg(ap, wchar_t *);
-				while ((wi = __fgetwc_unlock(fp)) != WEOF &&
-				    width-- != 0 && INCCL(wi))
-					*p++ = (wchar_t)wi;
-				if (wi != WEOF)
-					__ungetwc(wi, fp);
-				n = p - p0;
-				if (n == 0)
-					goto match_failure;
-				*p = 0;
-				nassigned++;
-			} else {
-				if (!(flags & SUPPRESS))
-					mbp = va_arg(ap, char *);
-				n = 0;
-				memset(&mbs, 0, sizeof(mbs));
-				while ((wi = __fgetwc_unlock(fp)) != WEOF &&
-				    width != 0 && INCCL(wi)) {
-					if (width >= MB_CUR_MAX &&
-					   !(flags & SUPPRESS)) {
-						nconv = wcrtomb(mbp, wi, &mbs);
-						if (nconv == (size_t)-1)
-							goto input_failure;
-					} else {
-						nconv = wcrtomb(mbbuf, wi,
-						    &mbs);
-						if (nconv == (size_t)-1)
-							goto input_failure;
-						if (nconv > width)
-							break;
-						if (!(flags & SUPPRESS))
-							memcpy(mbp, mbbuf,
-							    nconv);
-					}
-					if (!(flags & SUPPRESS))
-						mbp += nconv;
-					width -= nconv;
-					n++;
-				}
-				if (wi != WEOF)
-					__ungetwc(wi, fp);
-				if (!(flags & SUPPRESS)) {
-					*mbp = 0;
-					nassigned++;
-				}
- 			}
-			nread += n;
-			nconversions++;
-			break;
+      case CT_STRING:
+        /* like CCL, but zero-length string OK, & no NOSKIP */
+        if (width == 0) width = (size_t)~0;
+        if ((flags & SUPPRESS) && (flags & LONG)) {
+          while ((wi = __fgetwc_unlock(fp)) != WEOF && width-- != 0 && !iswspace(wi)) nread++;
+          if (wi != WEOF) __ungetwc(wi, fp);
+        } else if (flags & LONG) {
+          p0 = p = va_arg(ap, wchar_t*);
+          while ((wi = __fgetwc_unlock(fp)) != WEOF && width-- != 0 && !iswspace(wi)) {
+            *p++ = (wchar_t)wi;
+            nread++;
+          }
+          if (wi != WEOF) __ungetwc(wi, fp);
+          *p = 0;
+          nassigned++;
+        } else {
+          if (!(flags & SUPPRESS)) mbp = va_arg(ap, char*);
+          memset(&mbs, 0, sizeof(mbs));
+          while ((wi = __fgetwc_unlock(fp)) != WEOF && width != 0 && !iswspace(wi)) {
+            if (width >= MB_CUR_MAX && !(flags & SUPPRESS)) {
+              nconv = wcrtomb(mbp, wi, &mbs);
+              if (nconv == (size_t)-1) goto input_failure;
+            } else {
+              nconv = wcrtomb(mbbuf, wi, &mbs);
+              if (nconv == (size_t)-1) goto input_failure;
+              if (nconv > width) break;
+              if (!(flags & SUPPRESS)) memcpy(mbp, mbbuf, nconv);
+            }
+            if (!(flags & SUPPRESS)) mbp += nconv;
+            width -= nconv;
+            nread++;
+          }
+          if (wi != WEOF) __ungetwc(wi, fp);
+          if (!(flags & SUPPRESS)) {
+            *mbp = 0;
+            nassigned++;
+          }
+        }
+        nconversions++;
+        continue;
 
-		case CT_STRING:
-			/* like CCL, but zero-length string OK, & no NOSKIP */
-			if (width == 0)
-				width = (size_t)~0;
-			if ((flags & SUPPRESS) && (flags & LONG)) {
-				while ((wi = __fgetwc_unlock(fp)) != WEOF &&
-				    width-- != 0 &&
-				    !iswspace(wi))
-					nread++;
-				if (wi != WEOF)
-					__ungetwc(wi, fp);
-			} else if (flags & LONG) {
-				p0 = p = va_arg(ap, wchar_t *);
-				while ((wi = __fgetwc_unlock(fp)) != WEOF &&
-				    width-- != 0 &&
-				    !iswspace(wi)) {
-					*p++ = (wchar_t)wi;
-					nread++;
-				}
-				if (wi != WEOF)
-					__ungetwc(wi, fp);
-				*p = 0;
-				nassigned++;
-			} else {
-				if (!(flags & SUPPRESS))
-					mbp = va_arg(ap, char *);
-				memset(&mbs, 0, sizeof(mbs));
-				while ((wi = __fgetwc_unlock(fp)) != WEOF &&
-				    width != 0 &&
-				    !iswspace(wi)) {
-					if (width >= MB_CUR_MAX &&
-					    !(flags & SUPPRESS)) {
-						nconv = wcrtomb(mbp, wi, &mbs);
-						if (nconv == (size_t)-1)
-							goto input_failure;
-					} else {
-						nconv = wcrtomb(mbbuf, wi,
-						    &mbs);
-						if (nconv == (size_t)-1)
-							goto input_failure;
-						if (nconv > width)
-							break;
-						if (!(flags & SUPPRESS))
-							memcpy(mbp, mbbuf,
-							    nconv);
-					}
-					if (!(flags & SUPPRESS))
-						mbp += nconv;
-					width -= nconv;
-					nread++;
-				}
-				if (wi != WEOF)
-					__ungetwc(wi, fp);
-				if (!(flags & SUPPRESS)) {
-					*mbp = 0;
- 					nassigned++;
- 				}
-			}
-			nconversions++;
-			continue;
+      case CT_INT:
+        /* scan an integer as if by strtoimax/strtoumax */
+        if (width == 0 || width > sizeof(buf) / sizeof(*buf) - 1)
+          width = sizeof(buf) / sizeof(*buf) - 1;
+        flags |= SIGNOK | NDIGITS | NZDIGITS;
+        for (p = buf; width; width--) {
+          c = __fgetwc_unlock(fp);
+          /*
+           * Switch on the character; `goto ok'
+           * if we accept it as a part of number.
+           */
+          switch (c) {
+            /*
+             * The digit 0 is always legal, but is
+             * special.  For %i conversions, if no
+             * digits (zero or nonzero) have been
+             * scanned (only signs), we will have
+             * base==0.  In that case, we should set
+             * it to 8 and enable 0x prefixing.
+             * Also, if we have not scanned zero digits
+             * before this, do not turn off prefixing
+             * (someone else will turn it off if we
+             * have scanned any nonzero digits).
+             */
+            case '0':
+              if (base == 0) {
+                base = 8;
+                flags |= PFXOK;
+              }
+              if (flags & NZDIGITS)
+                flags &= ~(SIGNOK | NZDIGITS | NDIGITS);
+              else
+                flags &= ~(SIGNOK | PFXOK | NDIGITS);
+              goto ok;
 
-		case CT_INT:
-			/* scan an integer as if by strtoimax/strtoumax */
-			if (width == 0 || width > sizeof(buf) /
-			    sizeof(*buf) - 1)
-				width = sizeof(buf) / sizeof(*buf) - 1;
-			flags |= SIGNOK | NDIGITS | NZDIGITS;
-			for (p = buf; width; width--) {
-				c = __fgetwc_unlock(fp);
-				/*
-				 * Switch on the character; `goto ok'
-				 * if we accept it as a part of number.
-				 */
-				switch (c) {
+            /* 1 through 7 always legal */
+            case '1':
+            case '2':
+            case '3':
+            case '4':
+            case '5':
+            case '6':
+            case '7':
+              base = basefix[base];
+              flags &= ~(SIGNOK | PFXOK | NDIGITS);
+              goto ok;
 
-				/*
-				 * The digit 0 is always legal, but is
-				 * special.  For %i conversions, if no
-				 * digits (zero or nonzero) have been
-				 * scanned (only signs), we will have
-				 * base==0.  In that case, we should set
-				 * it to 8 and enable 0x prefixing.
-				 * Also, if we have not scanned zero digits
-				 * before this, do not turn off prefixing
-				 * (someone else will turn it off if we
-				 * have scanned any nonzero digits).
-				 */
-				case '0':
-					if (base == 0) {
-						base = 8;
-						flags |= PFXOK;
-					}
-					if (flags & NZDIGITS)
-					    flags &= ~(SIGNOK|NZDIGITS|NDIGITS);
-					else
-					    flags &= ~(SIGNOK|PFXOK|NDIGITS);
-					goto ok;
+            /* digits 8 and 9 ok iff decimal or hex */
+            case '8':
+            case '9':
+              base = basefix[base];
+              if (base <= 8) break; /* not legal here */
+              flags &= ~(SIGNOK | PFXOK | NDIGITS);
+              goto ok;
 
-				/* 1 through 7 always legal */
-				case '1': case '2': case '3':
-				case '4': case '5': case '6': case '7':
-					base = basefix[base];
-					flags &= ~(SIGNOK | PFXOK | NDIGITS);
-					goto ok;
+            /* letters ok iff hex */
+            case 'A':
+            case 'B':
+            case 'C':
+            case 'D':
+            case 'E':
+            case 'F':
+            case 'a':
+            case 'b':
+            case 'c':
+            case 'd':
+            case 'e':
+            case 'f':
+              /* no need to fix base here */
+              if (base <= 10) break; /* not legal here */
+              flags &= ~(SIGNOK | PFXOK | NDIGITS);
+              goto ok;
 
-				/* digits 8 and 9 ok iff decimal or hex */
-				case '8': case '9':
-					base = basefix[base];
-					if (base <= 8)
-						break;	/* not legal here */
-					flags &= ~(SIGNOK | PFXOK | NDIGITS);
-					goto ok;
+            /* sign ok only as first character */
+            case '+':
+            case '-':
+              if (flags & SIGNOK) {
+                flags &= ~SIGNOK;
+                flags |= HAVESIGN;
+                goto ok;
+              }
+              break;
 
-				/* letters ok iff hex */
-				case 'A': case 'B': case 'C':
-				case 'D': case 'E': case 'F':
-				case 'a': case 'b': case 'c':
-				case 'd': case 'e': case 'f':
-					/* no need to fix base here */
-					if (base <= 10)
-						break;	/* not legal here */
-					flags &= ~(SIGNOK | PFXOK | NDIGITS);
-					goto ok;
+            /*
+             * x ok iff flag still set and 2nd char (or
+             * 3rd char if we have a sign).
+             */
+            case 'x':
+            case 'X':
+              if ((flags & PFXOK) && p == buf + 1 + !!(flags & HAVESIGN)) {
+                base = 16; /* if %i */
+                flags &= ~PFXOK;
+                goto ok;
+              }
+              break;
+          }
 
-				/* sign ok only as first character */
-				case '+': case '-':
-					if (flags & SIGNOK) {
-						flags &= ~SIGNOK;
-						flags |= HAVESIGN;
-						goto ok;
-					}
-					break;
+          /*
+           * If we got here, c is not a legal character
+           * for a number.  Stop accumulating digits.
+           */
+          if (c != WEOF) __ungetwc(c, fp);
+          break;
+        ok:
+          /*
+           * c is legal: store it and look at the next.
+           */
+          *p++ = (wchar_t)c;
+        }
+        /*
+         * If we had only a sign, it is no good; push
+         * back the sign.  If the number ends in `x',
+         * it was [sign] '0' 'x', so push back the x
+         * and treat it as [sign] '0'.
+         */
+        if (flags & NDIGITS) {
+          if (p > buf) __ungetwc(*--p, fp);
+          goto match_failure;
+        }
+        c = p[-1];
+        if (c == 'x' || c == 'X') {
+          --p;
+          __ungetwc(c, fp);
+        }
+        if ((flags & SUPPRESS) == 0) {
+          uintmax_t res;
 
-				/*
-				 * x ok iff flag still set and 2nd char (or
-				 * 3rd char if we have a sign).
-				 */
-				case 'x': case 'X':
-					if ((flags & PFXOK) && p ==
-					    buf + 1 + !!(flags & HAVESIGN)) {
-						base = 16;	/* if %i */
-						flags &= ~PFXOK;
-						goto ok;
-					}
-					break;
-				}
+          *p = '\0';
+          if (flags & UNSIGNED)
+            res = wcstoimax(buf, NULL, base);
+          else
+            res = wcstoumax(buf, NULL, base);
+          if (flags & POINTER)
+            *va_arg(ap, void**) = (void*)(uintptr_t)res;
+          else if (flags & MAXINT)
+            *va_arg(ap, intmax_t*) = res;
+          else if (flags & LLONG)
+            *va_arg(ap, long long*) = res;
+          else if (flags & SIZEINT)
+            *va_arg(ap, ssize_t*) = res;
+          else if (flags & PTRINT)
+            *va_arg(ap, ptrdiff_t*) = res;
+          else if (flags & LONG)
+            *va_arg(ap, long*) = res;
+          else if (flags & SHORT)
+            *va_arg(ap, short*) = res;
+          else if (flags & SHORTSHORT)
+            *va_arg(ap, signed char*) = res;
+          else
+            *va_arg(ap, int*) = res;
+          nassigned++;
+        }
+        nread += p - buf;
+        nconversions++;
+        break;
 
-				/*
-				 * If we got here, c is not a legal character
-				 * for a number.  Stop accumulating digits.
-				 */
-				if (c != WEOF)
-					__ungetwc(c, fp);
-				break;
-		ok:
-				/*
-				 * c is legal: store it and look at the next.
-				 */
-				*p++ = (wchar_t)c;
-			}
-			/*
-			 * If we had only a sign, it is no good; push
-			 * back the sign.  If the number ends in `x',
-			 * it was [sign] '0' 'x', so push back the x
-			 * and treat it as [sign] '0'.
-			 */
-			if (flags & NDIGITS) {
-				if (p > buf)
-					__ungetwc(*--p, fp);
-				goto match_failure;
-			}
-			c = p[-1];
-			if (c == 'x' || c == 'X') {
-				--p;
-				__ungetwc(c, fp);
-			}
-			if ((flags & SUPPRESS) == 0) {
-				uintmax_t res;
-
-				*p = '\0';
-				if (flags & UNSIGNED)
-					res = wcstoimax(buf, NULL, base);
-				else
-					res = wcstoumax(buf, NULL, base);
-				if (flags & POINTER)
-					*va_arg(ap, void **) =
-					    (void *)(uintptr_t)res;
-				else if (flags & MAXINT)
-					*va_arg(ap, intmax_t *) = res;
-				else if (flags & LLONG)
-					*va_arg(ap, long long *) = res;
-				else if (flags & SIZEINT)
-					*va_arg(ap, ssize_t *) = res;
-				else if (flags & PTRINT)
-					*va_arg(ap, ptrdiff_t *) = res;
-				else if (flags & LONG)
-					*va_arg(ap, long *) = res;
-				else if (flags & SHORT)
-					*va_arg(ap, short *) = res;
-				else if (flags & SHORTSHORT)
-					*va_arg(ap, signed char *) = res;
-				else
-					*va_arg(ap, int *) = res;
-				nassigned++;
-			}
-			nread += p - buf;
-			nconversions++;
-			break;
-
-#ifdef FLOATING_POINT
-		case CT_FLOAT:
-			/* scan a floating point number as if by strtod */
-			if (width == 0 || width > sizeof(buf) /
-			    sizeof(*buf) - 1)
-				width = sizeof(buf) / sizeof(*buf) - 1;
-			if ((width = wparsefloat(fp, buf, buf + width)) == 0)
-				goto match_failure;
-			if ((flags & SUPPRESS) == 0) {
-				if (flags & LONGDBL) {
-					long double res = wcstold(buf, &p);
-					*va_arg(ap, long double *) = res;
-				} else if (flags & LONG) {
-					double res = wcstod(buf, &p);
-					*va_arg(ap, double *) = res;
-				} else {
-					float res = wcstof(buf, &p);
-					*va_arg(ap, float *) = res;
-				}
-				if (p - buf != (ptrdiff_t)width) abort();
-				nassigned++;
-			}
-			nread += width;
-			nconversions++;
-			break;
-#endif /* FLOATING_POINT */
-		}
-	}
+      case CT_FLOAT:
+        /* scan a floating point number as if by strtod */
+        if (width == 0 || width > sizeof(buf) / sizeof(*buf) - 1)
+          width = sizeof(buf) / sizeof(*buf) - 1;
+        if ((width = wparsefloat(fp, buf, buf + width)) == 0) goto match_failure;
+        if ((flags & SUPPRESS) == 0) {
+          if (flags & LONGDBL) {
+            long double res = wcstold(buf, &p);
+            *va_arg(ap, long double*) = res;
+          } else if (flags & LONG) {
+            double res = wcstod(buf, &p);
+            *va_arg(ap, double*) = res;
+          } else {
+            float res = wcstof(buf, &p);
+            *va_arg(ap, float*) = res;
+          }
+          if (p - buf != (ptrdiff_t)width) abort();
+          nassigned++;
+        }
+        nread += width;
+        nconversions++;
+        break;
+    }
+  }
 input_failure:
-	return (nconversions != 0 ? nassigned : EOF);
+  return (nconversions != 0 ? nassigned : EOF);
 match_failure:
-	return (nassigned);
+  return (nassigned);
 }
 #pragma GCC diagnostic pop
-
-int
-vfwscanf(FILE * __restrict fp, const wchar_t * __restrict fmt, __va_list ap)
-{
-	int r;
-
-	FLOCKFILE(fp);
-	r = __vfwscanf(fp, fmt, ap);
-	FUNLOCKFILE(fp);
-	return (r);
-}
diff --git a/libc/stdlib/exit.c b/libc/stdlib/exit.c
index 510cb83..e301a2a 100644
--- a/libc/stdlib/exit.c
+++ b/libc/stdlib/exit.c
@@ -29,9 +29,12 @@
 
 #include <unistd.h>
 
+#include "private/bionic_defs.h"
+
 extern void __cxa_finalize(void* dso_handle);
 extern void __cxa_thread_finalize();
 
+__BIONIC_WEAK_FOR_NATIVE_BRIDGE
 void exit(int status) {
   __cxa_thread_finalize();
   __cxa_finalize(NULL);
diff --git a/libc/system_properties/context_node.cpp b/libc/system_properties/context_node.cpp
new file mode 100644
index 0000000..13cef75
--- /dev/null
+++ b/libc/system_properties/context_node.cpp
@@ -0,0 +1,99 @@
+/*
+ * 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 "context_node.h"
+
+#include <unistd.h>
+
+#include <async_safe/log.h>
+
+#include "property_filename.h"
+
+// pthread_mutex_lock() calls into system_properties in the case of contention.
+// This creates a risk of dead lock if any system_properties functions
+// use pthread locks after system_property initialization.
+//
+// For this reason, the below three functions use a bionic Lock and static
+// allocation of memory for each filename.
+
+bool ContextNode::Open(bool access_rw, bool* fsetxattr_failed) {
+  lock_.lock();
+  if (pa_) {
+    lock_.unlock();
+    return true;
+  }
+
+  char filename[PROP_FILENAME_MAX];
+  int len =
+      async_safe_format_buffer(filename, sizeof(filename), "%s/%s", property_filename, context_);
+  if (len < 0 || len > PROP_FILENAME_MAX) {
+    lock_.unlock();
+    return false;
+  }
+
+  if (access_rw) {
+    pa_ = prop_area::map_prop_area_rw(filename, context_, fsetxattr_failed);
+  } else {
+    pa_ = prop_area::map_prop_area(filename);
+  }
+  lock_.unlock();
+  return pa_;
+}
+
+bool ContextNode::CheckAccessAndOpen() {
+  if (!pa_ && !no_access_) {
+    if (!CheckAccess() || !Open(false, nullptr)) {
+      no_access_ = true;
+    }
+  }
+  return pa_;
+}
+
+void ContextNode::ResetAccess() {
+  if (!CheckAccess()) {
+    Unmap();
+    no_access_ = true;
+  } else {
+    no_access_ = false;
+  }
+}
+
+bool ContextNode::CheckAccess() {
+  char filename[PROP_FILENAME_MAX];
+  int len =
+      async_safe_format_buffer(filename, sizeof(filename), "%s/%s", property_filename, context_);
+  if (len < 0 || len > PROP_FILENAME_MAX) {
+    return false;
+  }
+
+  return access(filename, R_OK) == 0;
+}
+
+void ContextNode::Unmap() {
+  prop_area::unmap_prop_area(&pa_);
+}
diff --git a/libc/dns/net/getservbyname.c b/libc/system_properties/context_node.h
similarity index 67%
copy from libc/dns/net/getservbyname.c
copy to libc/system_properties/context_node.h
index c32416c..1c6cbbb 100644
--- a/libc/dns/net/getservbyname.c
+++ b/libc/system_properties/context_node.h
@@ -26,18 +26,40 @@
  * SUCH DAMAGE.
  */
 
-#include <netdb.h>
+#ifndef SYSTEM_PROPERTIES_CONTEXT_NODE_H
+#define SYSTEM_PROPERTIES_CONTEXT_NODE_H
 
-#include "servent.h"
+#include "private/bionic_lock.h"
 
-struct servent* getservbyname(const char* name, const char* proto) {
-  res_static rs = __res_get_static();
-  rs->servent_ptr = NULL;
-  struct servent* s;
-  while ((s = getservent_r(rs)) != NULL) {
-    if (strcmp(s->s_name, name) == 0 && (proto == NULL || strcmp(s->s_proto, proto) == 0)) {
-      return s;
-    }
+#include "prop_area.h"
+
+class ContextNode {
+ public:
+  ContextNode(const char* context) : context_(context), pa_(nullptr), no_access_(false) {
+    lock_.init(false);
   }
-  return NULL;
-}
+  ~ContextNode() {
+    Unmap();
+  }
+  bool Open(bool access_rw, bool* fsetxattr_failed);
+  bool CheckAccessAndOpen();
+  void ResetAccess();
+
+  const char* context() const {
+    return context_;
+  }
+  prop_area* pa() {
+    return pa_;
+  }
+
+ private:
+  bool CheckAccess();
+  void Unmap();
+
+  Lock lock_;
+  const char* context_;
+  prop_area* pa_;
+  bool no_access_;
+};
+
+#endif
diff --git a/libc/dns/net/getservbyname.c b/libc/system_properties/contexts.h
similarity index 73%
copy from libc/dns/net/getservbyname.c
copy to libc/system_properties/contexts.h
index c32416c..5df9d96 100644
--- a/libc/dns/net/getservbyname.c
+++ b/libc/system_properties/contexts.h
@@ -26,18 +26,23 @@
  * SUCH DAMAGE.
  */
 
-#include <netdb.h>
+#ifndef SYSTEM_PROPERTIES_CONTEXTS_H
+#define SYSTEM_PROPERTIES_CONTEXTS_H
 
-#include "servent.h"
+#include "prop_area.h"
+#include "prop_info.h"
 
-struct servent* getservbyname(const char* name, const char* proto) {
-  res_static rs = __res_get_static();
-  rs->servent_ptr = NULL;
-  struct servent* s;
-  while ((s = getservent_r(rs)) != NULL) {
-    if (strcmp(s->s_name, name) == 0 && (proto == NULL || strcmp(s->s_proto, proto) == 0)) {
-      return s;
-    }
+class Contexts {
+ public:
+  virtual ~Contexts() {
   }
-  return NULL;
-}
+
+  virtual bool Initialize(bool writable) = 0;
+  virtual prop_area* GetPropAreaForName(const char* name) = 0;
+  virtual prop_area* GetSerialPropArea() = 0;
+  virtual void ForEach(void (*propfn)(const prop_info* pi, void* cookie), void* cookie) = 0;
+  virtual void ResetAccess() = 0;
+  virtual void FreeAndUnmap() = 0;
+};
+
+#endif
diff --git a/libc/system_properties/contexts_pre_split.h b/libc/system_properties/contexts_pre_split.h
new file mode 100644
index 0000000..bbc8529
--- /dev/null
+++ b/libc/system_properties/contexts_pre_split.h
@@ -0,0 +1,73 @@
+/*
+ * 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.
+ */
+
+#ifndef SYSTEM_PROPERTIES_CONTEXTS_PRE_SPLIT_H
+#define SYSTEM_PROPERTIES_CONTEXTS_PRE_SPLIT_H
+
+#include "contexts.h"
+#include "prop_area.h"
+#include "prop_info.h"
+#include "property_filename.h"
+
+class ContextsPreSplit : public Contexts {
+ public:
+  virtual ~ContextsPreSplit() override {
+  }
+
+  // We'll never initialize this legacy option as writable, so don't even check the arg.
+  virtual bool Initialize(bool) override {
+    pre_split_prop_area_ = prop_area::map_prop_area(property_filename);
+    return pre_split_prop_area_ != nullptr;
+  }
+
+  virtual prop_area* GetPropAreaForName(const char*) override {
+    return pre_split_prop_area_;
+  }
+
+  virtual prop_area* GetSerialPropArea() override {
+    return pre_split_prop_area_;
+  }
+
+  virtual void ForEach(void (*propfn)(const prop_info* pi, void* cookie), void* cookie) override {
+    pre_split_prop_area_->foreach (propfn, cookie);
+  }
+
+  // This is a no-op for pre-split properties as there is only one property file and it is
+  // accessible by all domains
+  virtual void ResetAccess() override {
+  }
+
+  virtual void FreeAndUnmap() override {
+    prop_area::unmap_prop_area(&pre_split_prop_area_);
+  }
+
+ private:
+  prop_area* pre_split_prop_area_ = nullptr;
+};
+
+#endif
diff --git a/libc/system_properties/contexts_split.cpp b/libc/system_properties/contexts_split.cpp
new file mode 100644
index 0000000..77f2069
--- /dev/null
+++ b/libc/system_properties/contexts_split.cpp
@@ -0,0 +1,351 @@
+/*
+ * 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 "contexts_split.h"
+
+#include <ctype.h>
+#include <stdlib.h>
+#include <string.h>
+#include <sys/stat.h>
+
+#include <async_safe/log.h>
+
+#include "context_node.h"
+#include "property_filename.h"
+
+class ContextListNode : public ContextNode {
+ public:
+  ContextListNode(ContextListNode* next, const char* context)
+      : ContextNode(strdup(context)), next(next) {
+  }
+
+  ~ContextListNode() {
+    free(const_cast<char*>(context()));
+  }
+
+  ContextListNode* next;
+};
+
+struct PrefixNode {
+  PrefixNode(struct PrefixNode* next, const char* prefix, ContextListNode* context)
+      : prefix(strdup(prefix)), prefix_len(strlen(prefix)), context(context), next(next) {
+  }
+  ~PrefixNode() {
+    free(prefix);
+  }
+  char* prefix;
+  const size_t prefix_len;
+  ContextListNode* context;
+  PrefixNode* next;
+};
+
+template <typename List, typename... Args>
+static inline void ListAdd(List** list, Args... args) {
+  *list = new List(*list, args...);
+}
+
+static void ListAddAfterLen(PrefixNode** list, const char* prefix, ContextListNode* context) {
+  size_t prefix_len = strlen(prefix);
+
+  auto next_list = list;
+
+  while (*next_list) {
+    if ((*next_list)->prefix_len < prefix_len || (*next_list)->prefix[0] == '*') {
+      ListAdd(next_list, prefix, context);
+      return;
+    }
+    next_list = &(*next_list)->next;
+  }
+  ListAdd(next_list, prefix, context);
+}
+
+template <typename List, typename Func>
+static void ListForEach(List* list, Func func) {
+  while (list) {
+    func(list);
+    list = list->next;
+  }
+}
+
+template <typename List, typename Func>
+static List* ListFind(List* list, Func func) {
+  while (list) {
+    if (func(list)) {
+      return list;
+    }
+    list = list->next;
+  }
+  return nullptr;
+}
+
+template <typename List>
+static void ListFree(List** list) {
+  while (*list) {
+    auto old_list = *list;
+    *list = old_list->next;
+    delete old_list;
+  }
+}
+
+// The below two functions are duplicated from label_support.c in libselinux.
+// TODO: Find a location suitable for these functions such that both libc and
+// libselinux can share a common source file.
+
+// The read_spec_entries and read_spec_entry functions may be used to
+// replace sscanf to read entries from spec files. The file and
+// property services now use these.
+
+// Read an entry from a spec file (e.g. file_contexts)
+static inline int read_spec_entry(char** entry, char** ptr, int* len) {
+  *entry = nullptr;
+  char* tmp_buf = nullptr;
+
+  while (isspace(**ptr) && **ptr != '\0') (*ptr)++;
+
+  tmp_buf = *ptr;
+  *len = 0;
+
+  while (!isspace(**ptr) && **ptr != '\0') {
+    (*ptr)++;
+    (*len)++;
+  }
+
+  if (*len) {
+    *entry = strndup(tmp_buf, *len);
+    if (!*entry) return -1;
+  }
+
+  return 0;
+}
+
+// line_buf - Buffer containing the spec entries .
+// num_args - The number of spec parameter entries to process.
+// ...      - A 'char **spec_entry' for each parameter.
+// returns  - The number of items processed.
+//
+// This function calls read_spec_entry() to do the actual string processing.
+static int read_spec_entries(char* line_buf, int num_args, ...) {
+  char **spec_entry, *buf_p;
+  int len, rc, items, entry_len = 0;
+  va_list ap;
+
+  len = strlen(line_buf);
+  if (line_buf[len - 1] == '\n')
+    line_buf[len - 1] = '\0';
+  else
+    // Handle case if line not \n terminated by bumping
+    // the len for the check below (as the line is NUL
+    // terminated by getline(3))
+    len++;
+
+  buf_p = line_buf;
+  while (isspace(*buf_p)) buf_p++;
+
+  // Skip comment lines and empty lines.
+  if (*buf_p == '#' || *buf_p == '\0') return 0;
+
+  // Process the spec file entries
+  va_start(ap, num_args);
+
+  items = 0;
+  while (items < num_args) {
+    spec_entry = va_arg(ap, char**);
+
+    if (len - 1 == buf_p - line_buf) {
+      va_end(ap);
+      return items;
+    }
+
+    rc = read_spec_entry(spec_entry, &buf_p, &entry_len);
+    if (rc < 0) {
+      va_end(ap);
+      return rc;
+    }
+    if (entry_len) items++;
+  }
+  va_end(ap);
+  return items;
+}
+
+bool ContextsSplit::MapSerialPropertyArea(bool access_rw, bool* fsetxattr_failed) {
+  char filename[PROP_FILENAME_MAX];
+  int len = async_safe_format_buffer(filename, sizeof(filename), "%s/properties_serial",
+                                     property_filename);
+  if (len < 0 || len > PROP_FILENAME_MAX) {
+    serial_prop_area_ = nullptr;
+    return false;
+  }
+
+  if (access_rw) {
+    serial_prop_area_ =
+        prop_area::map_prop_area_rw(filename, "u:object_r:properties_serial:s0", fsetxattr_failed);
+  } else {
+    serial_prop_area_ = prop_area::map_prop_area(filename);
+  }
+  return serial_prop_area_;
+}
+
+bool ContextsSplit::InitializePropertiesFromFile(const char* filename) {
+  FILE* file = fopen(filename, "re");
+  if (!file) {
+    return false;
+  }
+
+  char* buffer = nullptr;
+  size_t line_len;
+  char* prop_prefix = nullptr;
+  char* context = nullptr;
+
+  while (getline(&buffer, &line_len, file) > 0) {
+    int items = read_spec_entries(buffer, 2, &prop_prefix, &context);
+    if (items <= 0) {
+      continue;
+    }
+    if (items == 1) {
+      free(prop_prefix);
+      continue;
+    }
+
+    // init uses ctl.* properties as an IPC mechanism and does not write them
+    // to a property file, therefore we do not need to create property files
+    // to store them.
+    if (!strncmp(prop_prefix, "ctl.", 4)) {
+      free(prop_prefix);
+      free(context);
+      continue;
+    }
+
+    auto old_context = ListFind(
+        contexts_, [context](ContextListNode* l) { return !strcmp(l->context(), context); });
+    if (old_context) {
+      ListAddAfterLen(&prefixes_, prop_prefix, old_context);
+    } else {
+      ListAdd(&contexts_, context);
+      ListAddAfterLen(&prefixes_, prop_prefix, contexts_);
+    }
+    free(prop_prefix);
+    free(context);
+  }
+
+  free(buffer);
+  fclose(file);
+
+  return true;
+}
+
+bool ContextsSplit::InitializeProperties() {
+  // If we do find /property_contexts, then this is being
+  // run as part of the OTA updater on older release that had
+  // /property_contexts - b/34370523
+  if (InitializePropertiesFromFile("/property_contexts")) {
+    return true;
+  }
+
+  // Use property_contexts from /system & /vendor, fall back to those from /
+  if (access("/system/etc/selinux/plat_property_contexts", R_OK) != -1) {
+    if (!InitializePropertiesFromFile("/system/etc/selinux/plat_property_contexts")) {
+      return false;
+    }
+    // Don't check for failure here, so we always have a sane list of properties.
+    // 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");
+  } else {
+    if (!InitializePropertiesFromFile("/plat_property_contexts")) {
+      return false;
+    }
+    InitializePropertiesFromFile("/nonplat_property_contexts");
+  }
+
+  return true;
+}
+
+bool ContextsSplit::Initialize(bool writable) {
+  if (!InitializeProperties()) {
+    return false;
+  }
+
+  if (writable) {
+    mkdir(property_filename, S_IRWXU | S_IXGRP | S_IXOTH);
+    bool open_failed = false;
+    bool fsetxattr_failed = false;
+    ListForEach(contexts_, [&fsetxattr_failed, &open_failed](ContextListNode* l) {
+      if (!l->Open(true, &fsetxattr_failed)) {
+        open_failed = true;
+      }
+    });
+    if (open_failed || !MapSerialPropertyArea(true, &fsetxattr_failed)) {
+      FreeAndUnmap();
+      return false;
+    }
+
+    return !fsetxattr_failed;
+  } else {
+    if (!MapSerialPropertyArea(false, nullptr)) {
+      FreeAndUnmap();
+      return false;
+    }
+  }
+  return true;
+}
+
+prop_area* ContextsSplit::GetPropAreaForName(const char* name) {
+  auto entry = ListFind(prefixes_, [name](PrefixNode* l) {
+    return l->prefix[0] == '*' || !strncmp(l->prefix, name, l->prefix_len);
+  });
+  if (!entry) {
+    return nullptr;
+  }
+
+  auto cnode = entry->context;
+  if (!cnode->pa()) {
+    // We explicitly do not check no_access_ in this case because unlike the
+    // case of foreach(), we want to generate an selinux audit for each
+    // non-permitted property access in this function.
+    cnode->Open(false, nullptr);
+  }
+  return cnode->pa();
+}
+
+void ContextsSplit::ForEach(void (*propfn)(const prop_info* pi, void* cookie), void* cookie) {
+  ListForEach(contexts_, [propfn, cookie](ContextListNode* l) {
+    if (l->CheckAccessAndOpen()) {
+      l->pa()->foreach (propfn, cookie);
+    }
+  });
+}
+
+void ContextsSplit::ResetAccess() {
+  ListForEach(contexts_, [](ContextListNode* l) { l->ResetAccess(); });
+}
+
+void ContextsSplit::FreeAndUnmap() {
+  ListFree(&prefixes_);
+  ListFree(&contexts_);
+  prop_area::unmap_prop_area(&serial_prop_area_);
+}
diff --git a/libc/system_properties/contexts_split.h b/libc/system_properties/contexts_split.h
new file mode 100644
index 0000000..f98eb44
--- /dev/null
+++ b/libc/system_properties/contexts_split.h
@@ -0,0 +1,61 @@
+/*
+ * 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.
+ */
+
+#ifndef SYSTEM_PROPERTIES_CONTEXTS_SPLIT_H
+#define SYSTEM_PROPERTIES_CONTEXTS_SPLIT_H
+
+#include "contexts.h"
+
+struct PrefixNode;
+class ContextListNode;
+
+class ContextsSplit : public Contexts {
+ public:
+  virtual ~ContextsSplit() override {
+  }
+
+  virtual bool Initialize(bool writable) override;
+  virtual prop_area* GetPropAreaForName(const char* name) override;
+  virtual prop_area* GetSerialPropArea() override {
+    return serial_prop_area_;
+  }
+  virtual void ForEach(void (*propfn)(const prop_info* pi, void* cookie), void* cookie) override;
+  virtual void ResetAccess() override;
+  virtual void FreeAndUnmap() override;
+
+ private:
+  bool MapSerialPropertyArea(bool access_rw, bool* fsetxattr_failed);
+  bool InitializePropertiesFromFile(const char* filename);
+  bool InitializeProperties();
+
+  PrefixNode* prefixes_ = nullptr;
+  ContextListNode* contexts_ = nullptr;
+  prop_area* serial_prop_area_ = nullptr;
+};
+
+#endif
diff --git a/libc/system_properties/prop_area.cpp b/libc/system_properties/prop_area.cpp
new file mode 100644
index 0000000..e11f292
--- /dev/null
+++ b/libc/system_properties/prop_area.cpp
@@ -0,0 +1,372 @@
+/*
+ * 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 <fcntl.h>
+#include <stdlib.h>
+#include <sys/cdefs.h>
+#include <sys/stat.h>
+#include <sys/types.h>
+#include <sys/xattr.h>
+#include <unistd.h>
+
+#include <new>
+
+#include <async_safe/log.h>
+
+#include "prop_area.h"
+
+constexpr size_t PA_SIZE = 128 * 1024;
+constexpr uint32_t PROP_AREA_MAGIC = 0x504f5250;
+constexpr uint32_t PROP_AREA_VERSION = 0xfc6ed0ab;
+
+size_t prop_area::pa_size_ = 0;
+size_t prop_area::pa_data_size_ = 0;
+
+prop_area* prop_area::map_prop_area_rw(const char* filename, const char* context,
+                                       bool* fsetxattr_failed) {
+  /* dev is a tmpfs that we can use to carve a shared workspace
+   * out of, so let's do that...
+   */
+  const int fd = open(filename, O_RDWR | O_CREAT | O_NOFOLLOW | O_CLOEXEC | O_EXCL, 0444);
+
+  if (fd < 0) {
+    if (errno == EACCES) {
+      /* for consistency with the case where the process has already
+       * mapped the page in and segfaults when trying to write to it
+       */
+      abort();
+    }
+    return nullptr;
+  }
+
+  if (context) {
+    if (fsetxattr(fd, XATTR_NAME_SELINUX, context, strlen(context) + 1, 0) != 0) {
+      async_safe_format_log(ANDROID_LOG_ERROR, "libc",
+                            "fsetxattr failed to set context (%s) for \"%s\"", context, filename);
+      /*
+       * fsetxattr() will fail during system properties tests due to selinux policy.
+       * We do not want to create a custom policy for the tester, so we will continue in
+       * this function but set a flag that an error has occurred.
+       * Init, which is the only daemon that should ever call this function will abort
+       * when this error occurs.
+       * Otherwise, the tester will ignore it and continue, albeit without any selinux
+       * property separation.
+       */
+      if (fsetxattr_failed) {
+        *fsetxattr_failed = true;
+      }
+    }
+  }
+
+  if (ftruncate(fd, PA_SIZE) < 0) {
+    close(fd);
+    return nullptr;
+  }
+
+  pa_size_ = PA_SIZE;
+  pa_data_size_ = pa_size_ - sizeof(prop_area);
+
+  void* const memory_area = mmap(nullptr, pa_size_, PROT_READ | PROT_WRITE, MAP_SHARED, fd, 0);
+  if (memory_area == MAP_FAILED) {
+    close(fd);
+    return nullptr;
+  }
+
+  prop_area* pa = new (memory_area) prop_area(PROP_AREA_MAGIC, PROP_AREA_VERSION);
+
+  close(fd);
+  return pa;
+}
+
+prop_area* prop_area::map_fd_ro(const int fd) {
+  struct stat fd_stat;
+  if (fstat(fd, &fd_stat) < 0) {
+    return nullptr;
+  }
+
+  if ((fd_stat.st_uid != 0) || (fd_stat.st_gid != 0) ||
+      ((fd_stat.st_mode & (S_IWGRP | S_IWOTH)) != 0) ||
+      (fd_stat.st_size < static_cast<off_t>(sizeof(prop_area)))) {
+    return nullptr;
+  }
+
+  pa_size_ = fd_stat.st_size;
+  pa_data_size_ = pa_size_ - sizeof(prop_area);
+
+  void* const map_result = mmap(nullptr, pa_size_, PROT_READ, MAP_SHARED, fd, 0);
+  if (map_result == MAP_FAILED) {
+    return nullptr;
+  }
+
+  prop_area* pa = reinterpret_cast<prop_area*>(map_result);
+  if ((pa->magic() != PROP_AREA_MAGIC) || (pa->version() != PROP_AREA_VERSION)) {
+    munmap(pa, pa_size_);
+    return nullptr;
+  }
+
+  return pa;
+}
+
+prop_area* prop_area::map_prop_area(const char* filename) {
+  int fd = open(filename, O_CLOEXEC | O_NOFOLLOW | O_RDONLY);
+  if (fd == -1) return nullptr;
+
+  prop_area* map_result = map_fd_ro(fd);
+  close(fd);
+
+  return map_result;
+}
+
+void* prop_area::allocate_obj(const size_t size, uint_least32_t* const off) {
+  const size_t aligned = __BIONIC_ALIGN(size, sizeof(uint_least32_t));
+  if (bytes_used_ + aligned > pa_data_size_) {
+    return nullptr;
+  }
+
+  *off = bytes_used_;
+  bytes_used_ += aligned;
+  return data_ + *off;
+}
+
+prop_bt* prop_area::new_prop_bt(const char* name, uint32_t namelen, uint_least32_t* const off) {
+  uint_least32_t new_offset;
+  void* const p = allocate_obj(sizeof(prop_bt) + namelen + 1, &new_offset);
+  if (p != nullptr) {
+    prop_bt* bt = new (p) prop_bt(name, namelen);
+    *off = new_offset;
+    return bt;
+  }
+
+  return nullptr;
+}
+
+prop_info* prop_area::new_prop_info(const char* name, uint32_t namelen, const char* value,
+                                    uint32_t valuelen, uint_least32_t* const off) {
+  uint_least32_t new_offset;
+  void* const p = allocate_obj(sizeof(prop_info) + namelen + 1, &new_offset);
+  if (p == nullptr) return nullptr;
+
+  prop_info* info;
+  if (valuelen >= PROP_VALUE_MAX) {
+    uint32_t long_value_offset = 0;
+    char* long_location = reinterpret_cast<char*>(allocate_obj(valuelen + 1, &long_value_offset));
+    if (!long_location) return nullptr;
+
+    memcpy(long_location, value, valuelen);
+    long_location[valuelen] = '\0';
+
+    // Both new_offset and long_value_offset are offsets based off of data_, however prop_info
+    // does not know what data_ is, so we change this offset to be an offset from the prop_info
+    // pointer that contains it.
+    long_value_offset -= new_offset;
+
+    info = new (p) prop_info(name, namelen, long_value_offset);
+  } else {
+    info = new (p) prop_info(name, namelen, value, valuelen);
+  }
+  *off = new_offset;
+  return info;
+}
+
+void* prop_area::to_prop_obj(uint_least32_t off) {
+  if (off > pa_data_size_) return nullptr;
+
+  return (data_ + off);
+}
+
+inline prop_bt* prop_area::to_prop_bt(atomic_uint_least32_t* off_p) {
+  uint_least32_t off = atomic_load_explicit(off_p, memory_order_consume);
+  return reinterpret_cast<prop_bt*>(to_prop_obj(off));
+}
+
+inline prop_info* prop_area::to_prop_info(atomic_uint_least32_t* off_p) {
+  uint_least32_t off = atomic_load_explicit(off_p, memory_order_consume);
+  return reinterpret_cast<prop_info*>(to_prop_obj(off));
+}
+
+inline prop_bt* prop_area::root_node() {
+  return reinterpret_cast<prop_bt*>(to_prop_obj(0));
+}
+
+static int cmp_prop_name(const char* one, uint32_t one_len, const char* two, uint32_t two_len) {
+  if (one_len < two_len)
+    return -1;
+  else if (one_len > two_len)
+    return 1;
+  else
+    return strncmp(one, two, one_len);
+}
+
+prop_bt* prop_area::find_prop_bt(prop_bt* const bt, const char* name, uint32_t namelen,
+                                 bool alloc_if_needed) {
+  prop_bt* current = bt;
+  while (true) {
+    if (!current) {
+      return nullptr;
+    }
+
+    const int ret = cmp_prop_name(name, namelen, current->name, current->namelen);
+    if (ret == 0) {
+      return current;
+    }
+
+    if (ret < 0) {
+      uint_least32_t left_offset = atomic_load_explicit(&current->left, memory_order_relaxed);
+      if (left_offset != 0) {
+        current = to_prop_bt(&current->left);
+      } else {
+        if (!alloc_if_needed) {
+          return nullptr;
+        }
+
+        uint_least32_t new_offset;
+        prop_bt* new_bt = new_prop_bt(name, namelen, &new_offset);
+        if (new_bt) {
+          atomic_store_explicit(&current->left, new_offset, memory_order_release);
+        }
+        return new_bt;
+      }
+    } else {
+      uint_least32_t right_offset = atomic_load_explicit(&current->right, memory_order_relaxed);
+      if (right_offset != 0) {
+        current = to_prop_bt(&current->right);
+      } else {
+        if (!alloc_if_needed) {
+          return nullptr;
+        }
+
+        uint_least32_t new_offset;
+        prop_bt* new_bt = new_prop_bt(name, namelen, &new_offset);
+        if (new_bt) {
+          atomic_store_explicit(&current->right, new_offset, memory_order_release);
+        }
+        return new_bt;
+      }
+    }
+  }
+}
+
+const prop_info* prop_area::find_property(prop_bt* const trie, const char* name, uint32_t namelen,
+                                          const char* value, uint32_t valuelen,
+                                          bool alloc_if_needed) {
+  if (!trie) return nullptr;
+
+  const char* remaining_name = name;
+  prop_bt* current = trie;
+  while (true) {
+    const char* sep = strchr(remaining_name, '.');
+    const bool want_subtree = (sep != nullptr);
+    const uint32_t substr_size = (want_subtree) ? sep - remaining_name : strlen(remaining_name);
+
+    if (!substr_size) {
+      return nullptr;
+    }
+
+    prop_bt* root = nullptr;
+    uint_least32_t children_offset = atomic_load_explicit(&current->children, memory_order_relaxed);
+    if (children_offset != 0) {
+      root = to_prop_bt(&current->children);
+    } else if (alloc_if_needed) {
+      uint_least32_t new_offset;
+      root = new_prop_bt(remaining_name, substr_size, &new_offset);
+      if (root) {
+        atomic_store_explicit(&current->children, new_offset, memory_order_release);
+      }
+    }
+
+    if (!root) {
+      return nullptr;
+    }
+
+    current = find_prop_bt(root, remaining_name, substr_size, alloc_if_needed);
+    if (!current) {
+      return nullptr;
+    }
+
+    if (!want_subtree) break;
+
+    remaining_name = sep + 1;
+  }
+
+  uint_least32_t prop_offset = atomic_load_explicit(&current->prop, memory_order_relaxed);
+  if (prop_offset != 0) {
+    return to_prop_info(&current->prop);
+  } else if (alloc_if_needed) {
+    uint_least32_t new_offset;
+    prop_info* new_info = new_prop_info(name, namelen, value, valuelen, &new_offset);
+    if (new_info) {
+      atomic_store_explicit(&current->prop, new_offset, memory_order_release);
+    }
+
+    return new_info;
+  } else {
+    return nullptr;
+  }
+}
+
+bool prop_area::foreach_property(prop_bt* const trie,
+                                 void (*propfn)(const prop_info* pi, void* cookie), void* cookie) {
+  if (!trie) return false;
+
+  uint_least32_t left_offset = atomic_load_explicit(&trie->left, memory_order_relaxed);
+  if (left_offset != 0) {
+    const int err = foreach_property(to_prop_bt(&trie->left), propfn, cookie);
+    if (err < 0) return false;
+  }
+  uint_least32_t prop_offset = atomic_load_explicit(&trie->prop, memory_order_relaxed);
+  if (prop_offset != 0) {
+    prop_info* info = to_prop_info(&trie->prop);
+    if (!info) return false;
+    propfn(info, cookie);
+  }
+  uint_least32_t children_offset = atomic_load_explicit(&trie->children, memory_order_relaxed);
+  if (children_offset != 0) {
+    const int err = foreach_property(to_prop_bt(&trie->children), propfn, cookie);
+    if (err < 0) return false;
+  }
+  uint_least32_t right_offset = atomic_load_explicit(&trie->right, memory_order_relaxed);
+  if (right_offset != 0) {
+    const int err = foreach_property(to_prop_bt(&trie->right), propfn, cookie);
+    if (err < 0) return false;
+  }
+
+  return true;
+}
+
+const prop_info* prop_area::find(const char* name) {
+  return find_property(root_node(), name, strlen(name), nullptr, 0, false);
+}
+
+bool prop_area::add(const char* name, unsigned int namelen, const char* value,
+                    unsigned int valuelen) {
+  return find_property(root_node(), name, namelen, value, valuelen, true);
+}
+
+bool prop_area::foreach (void (*propfn)(const prop_info* pi, void* cookie), void* cookie) {
+  return foreach_property(root_node(), propfn, cookie);
+}
diff --git a/libc/system_properties/prop_area.h b/libc/system_properties/prop_area.h
new file mode 100644
index 0000000..10c1adb
--- /dev/null
+++ b/libc/system_properties/prop_area.h
@@ -0,0 +1,165 @@
+/*
+ * 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 <stdatomic.h>
+#include <stdint.h>
+#include <string.h>
+#include <sys/mman.h>
+
+#include "private/bionic_macros.h"
+
+#include "prop_info.h"
+
+#ifndef SYSTEM_PROPERTIES_PROP_AREA_H
+#define SYSTEM_PROPERTIES_PROP_AREA_H
+
+// Properties are stored in a hybrid trie/binary tree structure.
+// Each property's name is delimited at '.' characters, and the tokens are put
+// into a trie structure.  Siblings at each level of the trie are stored in a
+// binary tree.  For instance, "ro.secure"="1" could be stored as follows:
+//
+// +-----+   children    +----+   children    +--------+
+// |     |-------------->| ro |-------------->| secure |
+// +-----+               +----+               +--------+
+//                       /    \                /   |
+//                 left /      \ right   left /    |  prop   +===========+
+//                     v        v            v     +-------->| ro.secure |
+//                  +-----+   +-----+     +-----+            +-----------+
+//                  | net |   | sys |     | com |            |     1     |
+//                  +-----+   +-----+     +-----+            +===========+
+
+// Represents a node in the trie.
+struct prop_bt {
+  uint32_t namelen;
+
+  // The property trie is updated only by the init process (single threaded) which provides
+  // property service. And it can be read by multiple threads at the same time.
+  // As the property trie is not protected by locks, we use atomic_uint_least32_t types for the
+  // left, right, children "pointers" in the trie node. To make sure readers who see the
+  // change of "pointers" can also notice the change of prop_bt structure contents pointed by
+  // the "pointers", we always use release-consume ordering pair when accessing these "pointers".
+
+  // prop "points" to prop_info structure if there is a propery associated with the trie node.
+  // Its situation is similar to the left, right, children "pointers". So we use
+  // atomic_uint_least32_t and release-consume ordering to protect it as well.
+
+  // We should also avoid rereading these fields redundantly, since not
+  // all processor implementations ensure that multiple loads from the
+  // same field are carried out in the right order.
+  atomic_uint_least32_t prop;
+
+  atomic_uint_least32_t left;
+  atomic_uint_least32_t right;
+
+  atomic_uint_least32_t children;
+
+  char name[0];
+
+  prop_bt(const char* name, const uint32_t name_length) {
+    this->namelen = name_length;
+    memcpy(this->name, name, name_length);
+    this->name[name_length] = '\0';
+  }
+
+ private:
+  DISALLOW_COPY_AND_ASSIGN(prop_bt);
+};
+
+class prop_area {
+ public:
+  static prop_area* map_prop_area_rw(const char* filename, const char* context,
+                                     bool* fsetxattr_failed);
+  static prop_area* map_prop_area(const char* filename);
+  static void unmap_prop_area(prop_area** pa) {
+    if (*pa) {
+      munmap(*pa, pa_size_);
+      *pa = nullptr;
+    }
+  }
+
+  prop_area(const uint32_t magic, const uint32_t version) : magic_(magic), version_(version) {
+    atomic_init(&serial_, 0);
+    memset(reserved_, 0, sizeof(reserved_));
+    // Allocate enough space for the root node.
+    bytes_used_ = sizeof(prop_bt);
+  }
+
+  const prop_info* find(const char* name);
+  bool add(const char* name, unsigned int namelen, const char* value, unsigned int valuelen);
+
+  bool foreach (void (*propfn)(const prop_info* pi, void* cookie), void* cookie);
+
+  atomic_uint_least32_t* serial() {
+    return &serial_;
+  }
+  uint32_t magic() const {
+    return magic_;
+  }
+  uint32_t version() const {
+    return version_;
+  }
+
+ private:
+  static prop_area* map_fd_ro(const int fd);
+
+  void* allocate_obj(const size_t size, uint_least32_t* const off);
+  prop_bt* new_prop_bt(const char* name, uint32_t namelen, uint_least32_t* const off);
+  prop_info* new_prop_info(const char* name, uint32_t namelen, const char* value, uint32_t valuelen,
+                           uint_least32_t* const off);
+  void* to_prop_obj(uint_least32_t off);
+  prop_bt* to_prop_bt(atomic_uint_least32_t* off_p);
+  prop_info* to_prop_info(atomic_uint_least32_t* off_p);
+
+  prop_bt* root_node();
+
+  prop_bt* find_prop_bt(prop_bt* const bt, const char* name, uint32_t namelen, bool alloc_if_needed);
+
+  const prop_info* find_property(prop_bt* const trie, const char* name, uint32_t namelen,
+                                 const char* value, uint32_t valuelen, bool alloc_if_needed);
+
+  bool foreach_property(prop_bt* const trie, void (*propfn)(const prop_info* pi, void* cookie),
+                        void* cookie);
+
+  // The original design doesn't include pa_size or pa_data_size in the prop_area struct itself.
+  // Since we'll need to be backwards compatible with that design, we don't gain much by adding it
+  // now, especially since we don't have any plans to make different property areas different sizes,
+  // and thus we share these two variables among all instances.
+  static size_t pa_size_;
+  static size_t pa_data_size_;
+
+  uint32_t bytes_used_;
+  atomic_uint_least32_t serial_;
+  uint32_t magic_;
+  uint32_t version_;
+  uint32_t reserved_[28];
+  char data_[0];
+
+  DISALLOW_COPY_AND_ASSIGN(prop_area);
+};
+
+#endif
diff --git a/libc/system_properties/prop_info.cpp b/libc/system_properties/prop_info.cpp
new file mode 100644
index 0000000..5123f92
--- /dev/null
+++ b/libc/system_properties/prop_info.cpp
@@ -0,0 +1,55 @@
+/*
+ * 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 "prop_info.h"
+
+#include <string.h>
+
+constexpr static const char kLongLegacyError[] =
+    "Must use __system_property_read_callback() to read";
+static_assert(sizeof(kLongLegacyError) < prop_info::kLongLegacyErrorBufferSize,
+              "Error message for long properties read by legacy libc must fit within 56 chars");
+
+prop_info::prop_info(const char* name, uint32_t namelen, const char* value, uint32_t valuelen) {
+  memcpy(this->name, name, namelen);
+  this->name[namelen] = '\0';
+  atomic_init(&this->serial, valuelen << 24);
+  memcpy(this->value, value, valuelen);
+  this->value[valuelen] = '\0';
+}
+
+prop_info::prop_info(const char* name, uint32_t namelen, uint32_t long_offset) {
+  memcpy(this->name, name, namelen);
+  this->name[namelen] = '\0';
+
+  auto error_value_len = sizeof(kLongLegacyError) - 1;
+  atomic_init(&this->serial, error_value_len << 24 | kLongFlag);
+  memcpy(this->long_property.error_message, kLongLegacyError, sizeof(kLongLegacyError));
+
+  this->long_property.offset = long_offset;
+}
diff --git a/libc/system_properties/prop_info.h b/libc/system_properties/prop_info.h
new file mode 100644
index 0000000..99bcaaf
--- /dev/null
+++ b/libc/system_properties/prop_info.h
@@ -0,0 +1,92 @@
+/*
+ * 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 <stdatomic.h>
+#include <stdint.h>
+#include <sys/system_properties.h>
+
+#include "private/bionic_macros.h"
+
+#ifndef SYSTEM_PROPERTIES_PROP_INFO_H
+#define SYSTEM_PROPERTIES_PROP_INFO_H
+
+// The C11 standard doesn't allow atomic loads from const fields,
+// though C++11 does.  Fudge it until standards get straightened out.
+static inline uint_least32_t load_const_atomic(const atomic_uint_least32_t* s, memory_order mo) {
+  atomic_uint_least32_t* non_const_s = const_cast<atomic_uint_least32_t*>(s);
+  return atomic_load_explicit(non_const_s, mo);
+}
+
+struct prop_info {
+  // Read only properties will not set anything but the bottom most bit of serial and the top byte.
+  // We borrow the 2nd from the top byte for extra flags, and use the bottom most bit of that for
+  // our first user, kLongFlag.
+  constexpr static uint32_t kLongFlag = 1 << 16;
+
+  // The error message fits in part of a union with the previous 92 char property value so there
+  // must be room left over after the error message for the offset to the new longer property value
+  // and future expansion fields if needed. Note that this value cannot ever increase.  The offset
+  // to the new longer property value appears immediately after it, so an increase of this size will
+  // break compatibility.
+  constexpr static size_t kLongLegacyErrorBufferSize = 56;
+
+ public:
+  atomic_uint_least32_t serial;
+  // we need to keep this buffer around because the property
+  // value can be modified whereas name is constant.
+  union {
+    char value[PROP_VALUE_MAX];
+    struct {
+      char error_message[kLongLegacyErrorBufferSize];
+      uint32_t offset;
+    } long_property;
+  };
+  char name[0];
+
+  bool is_long() const {
+    return (load_const_atomic(&serial, memory_order_relaxed) & kLongFlag) != 0;
+  }
+
+  const char* long_value() const {
+    // We can't store pointers here since this is shared memory that will have different absolute
+    // pointers in different processes.  We don't have data_ from prop_area, but since we know
+    // `this` is data_ + some offset and long_value is data_ + some other offset, we calculate the
+    // offset from `this` to long_value and store it as long_property.offset.
+    return reinterpret_cast<const char*>(this) + long_property.offset;
+  }
+
+  prop_info(const char* name, uint32_t namelen, const char* value, uint32_t valuelen);
+  prop_info(const char* name, uint32_t namelen, uint32_t long_offset);
+
+ private:
+  DISALLOW_IMPLICIT_CONSTRUCTORS(prop_info);
+};
+
+static_assert(sizeof(prop_info) == 96, "sizeof struct prop_info must be 96 bytes");
+
+#endif
diff --git a/libc/dns/net/getservbyname.c b/libc/system_properties/property_filename.h
similarity index 78%
rename from libc/dns/net/getservbyname.c
rename to libc/system_properties/property_filename.h
index c32416c..0f7bcf7 100644
--- a/libc/dns/net/getservbyname.c
+++ b/libc/system_properties/property_filename.h
@@ -26,18 +26,12 @@
  * SUCH DAMAGE.
  */
 
-#include <netdb.h>
+#ifndef SYSTEM_PROPERTIES_PROPERTY_FILENAME_H
+#define SYSTEM_PROPERTIES_PROPERTY_FILENAME_H
 
-#include "servent.h"
+// These are globals set by __system_property_set_filename().
+// There isn't huge benefit in refactoring them, so they're alone in this header.
+constexpr int PROP_FILENAME_MAX = 1024;
+extern char property_filename[PROP_FILENAME_MAX];
 
-struct servent* getservbyname(const char* name, const char* proto) {
-  res_static rs = __res_get_static();
-  rs->servent_ptr = NULL;
-  struct servent* s;
-  while ((s = getservent_r(rs)) != NULL) {
-    if (strcmp(s->s_name, name) == 0 && (proto == NULL || strcmp(s->s_proto, proto) == 0)) {
-      return s;
-    }
-  }
-  return NULL;
-}
+#endif
diff --git a/libc/system_properties/system_properties.cpp b/libc/system_properties/system_properties.cpp
new file mode 100644
index 0000000..3f6601d
--- /dev/null
+++ b/libc/system_properties/system_properties.cpp
@@ -0,0 +1,675 @@
+/*
+ * 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 <fcntl.h>
+#include <netinet/in.h>
+#include <poll.h>
+#include <stdatomic.h>
+#include <stdint.h>
+#include <stdlib.h>
+#include <string.h>
+#include <sys/select.h>
+#include <sys/socket.h>
+#include <sys/stat.h>
+#include <sys/types.h>
+#include <sys/uio.h>
+#include <sys/un.h>
+#include <unistd.h>
+
+#define _REALLY_INCLUDE_SYS__SYSTEM_PROPERTIES_H_
+#include <sys/_system_properties.h>
+#include <sys/system_properties.h>
+
+#include <async_safe/log.h>
+
+#include "private/ErrnoRestorer.h"
+#include "private/bionic_defs.h"
+#include "private/bionic_futex.h"
+#include "private/bionic_macros.h"
+#include "private/bionic_sdk_version.h"
+
+#include "context_node.h"
+#include "contexts.h"
+#include "contexts_pre_split.h"
+#include "contexts_split.h"
+#include "prop_area.h"
+#include "prop_info.h"
+#include "property_filename.h"
+
+// We don't want to use new or malloc in properties (b/31659220), and since these classes are
+// small enough and don't have non-trivial constructors, it's easier to just statically declare
+// them than anything else.
+static ContextsSplit contexts_split;
+static ContextsPreSplit contexts_pre_split;
+static Contexts* contexts = nullptr;
+
+#define SERIAL_DIRTY(serial) ((serial)&1)
+#define SERIAL_VALUE_LEN(serial) ((serial) >> 24)
+
+static const char property_service_socket[] = "/dev/socket/" PROP_SERVICE_NAME;
+static const char* kServiceVersionPropertyName = "ro.property_service.version";
+
+// This is public because it was exposed in the NDK. As of 2017-01, ~60 apps reference this symbol.
+// It is set to nullptr and never modified.
+__BIONIC_WEAK_VARIABLE_FOR_NATIVE_BRIDGE
+prop_area* __system_property_area__ = nullptr;
+
+char property_filename[PROP_FILENAME_MAX] = PROP_FILENAME;
+
+class PropertyServiceConnection {
+ public:
+  PropertyServiceConnection() : last_error_(0) {
+    socket_ = ::socket(AF_LOCAL, SOCK_STREAM | SOCK_CLOEXEC, 0);
+    if (socket_ == -1) {
+      last_error_ = errno;
+      return;
+    }
+
+    const size_t namelen = strlen(property_service_socket);
+    sockaddr_un addr;
+    memset(&addr, 0, sizeof(addr));
+    strlcpy(addr.sun_path, property_service_socket, sizeof(addr.sun_path));
+    addr.sun_family = AF_LOCAL;
+    socklen_t alen = namelen + offsetof(sockaddr_un, sun_path) + 1;
+
+    if (TEMP_FAILURE_RETRY(connect(socket_, reinterpret_cast<sockaddr*>(&addr), alen)) == -1) {
+      last_error_ = errno;
+      close(socket_);
+      socket_ = -1;
+    }
+  }
+
+  bool IsValid() {
+    return socket_ != -1;
+  }
+
+  int GetLastError() {
+    return last_error_;
+  }
+
+  bool RecvInt32(int32_t* value) {
+    int result = TEMP_FAILURE_RETRY(recv(socket_, value, sizeof(*value), MSG_WAITALL));
+    return CheckSendRecvResult(result, sizeof(*value));
+  }
+
+  int socket() {
+    return socket_;
+  }
+
+  ~PropertyServiceConnection() {
+    if (socket_ != -1) {
+      close(socket_);
+    }
+  }
+
+ private:
+  bool CheckSendRecvResult(int result, int expected_len) {
+    if (result == -1) {
+      last_error_ = errno;
+    } else if (result != expected_len) {
+      last_error_ = -1;
+    } else {
+      last_error_ = 0;
+    }
+
+    return last_error_ == 0;
+  }
+
+  int socket_;
+  int last_error_;
+
+  friend class SocketWriter;
+};
+
+class SocketWriter {
+ public:
+  explicit SocketWriter(PropertyServiceConnection* connection)
+      : connection_(connection), iov_index_(0), uint_buf_index_(0) {
+  }
+
+  SocketWriter& WriteUint32(uint32_t value) {
+    CHECK(uint_buf_index_ < kUintBufSize);
+    CHECK(iov_index_ < kIovSize);
+    uint32_t* ptr = uint_buf_ + uint_buf_index_;
+    uint_buf_[uint_buf_index_++] = value;
+    iov_[iov_index_].iov_base = ptr;
+    iov_[iov_index_].iov_len = sizeof(*ptr);
+    ++iov_index_;
+    return *this;
+  }
+
+  SocketWriter& WriteString(const char* value) {
+    uint32_t valuelen = strlen(value);
+    WriteUint32(valuelen);
+    if (valuelen == 0) {
+      return *this;
+    }
+
+    CHECK(iov_index_ < kIovSize);
+    iov_[iov_index_].iov_base = const_cast<char*>(value);
+    iov_[iov_index_].iov_len = valuelen;
+    ++iov_index_;
+
+    return *this;
+  }
+
+  bool Send() {
+    if (!connection_->IsValid()) {
+      return false;
+    }
+
+    if (writev(connection_->socket(), iov_, iov_index_) == -1) {
+      connection_->last_error_ = errno;
+      return false;
+    }
+
+    iov_index_ = uint_buf_index_ = 0;
+    return true;
+  }
+
+ private:
+  static constexpr size_t kUintBufSize = 8;
+  static constexpr size_t kIovSize = 8;
+
+  PropertyServiceConnection* connection_;
+  iovec iov_[kIovSize];
+  size_t iov_index_;
+  uint32_t uint_buf_[kUintBufSize];
+  size_t uint_buf_index_;
+
+  DISALLOW_IMPLICIT_CONSTRUCTORS(SocketWriter);
+};
+
+struct prop_msg {
+  unsigned cmd;
+  char name[PROP_NAME_MAX];
+  char value[PROP_VALUE_MAX];
+};
+
+static int send_prop_msg(const prop_msg* msg) {
+  PropertyServiceConnection connection;
+  if (!connection.IsValid()) {
+    return connection.GetLastError();
+  }
+
+  int result = -1;
+  int s = connection.socket();
+
+  const int num_bytes = TEMP_FAILURE_RETRY(send(s, msg, sizeof(prop_msg), 0));
+  if (num_bytes == sizeof(prop_msg)) {
+    // We successfully wrote to the property server but now we
+    // wait for the property server to finish its work.  It
+    // acknowledges its completion by closing the socket so we
+    // poll here (on nothing), waiting for the socket to close.
+    // If you 'adb shell setprop foo bar' you'll see the POLLHUP
+    // once the socket closes.  Out of paranoia we cap our poll
+    // at 250 ms.
+    pollfd pollfds[1];
+    pollfds[0].fd = s;
+    pollfds[0].events = 0;
+    const int poll_result = TEMP_FAILURE_RETRY(poll(pollfds, 1, 250 /* ms */));
+    if (poll_result == 1 && (pollfds[0].revents & POLLHUP) != 0) {
+      result = 0;
+    } else {
+      // Ignore the timeout and treat it like a success anyway.
+      // The init process is single-threaded and its property
+      // service is sometimes slow to respond (perhaps it's off
+      // starting a child process or something) and thus this
+      // times out and the caller thinks it failed, even though
+      // it's still getting around to it.  So we fake it here,
+      // mostly for ctl.* properties, but we do try and wait 250
+      // ms so callers who do read-after-write can reliably see
+      // what they've written.  Most of the time.
+      // TODO: fix the system properties design.
+      async_safe_format_log(ANDROID_LOG_WARN, "libc",
+                            "Property service has timed out while trying to set \"%s\" to \"%s\"",
+                            msg->name, msg->value);
+      result = 0;
+    }
+  }
+
+  return result;
+}
+
+static bool is_dir(const char* pathname) {
+  struct stat info;
+  if (stat(pathname, &info) == -1) {
+    return false;
+  }
+  return S_ISDIR(info.st_mode);
+}
+
+__BIONIC_WEAK_FOR_NATIVE_BRIDGE
+int __system_properties_init() {
+  // This is called from __libc_init_common, and should leave errno at 0 (http://b/37248982).
+  ErrnoRestorer errno_restorer;
+
+  if (contexts != nullptr) {
+    contexts->ResetAccess();
+    return 0;
+  }
+  contexts = nullptr;
+  if (is_dir(property_filename)) {
+    if (!contexts_split.Initialize(false)) {
+      return -1;
+    }
+    contexts = &contexts_split;
+  } else {
+    if (!contexts_pre_split.Initialize(false)) {
+      return -1;
+    }
+    contexts = &contexts_pre_split;
+  }
+  return 0;
+}
+
+__BIONIC_WEAK_FOR_NATIVE_BRIDGE
+int __system_property_set_filename(const char* filename) {
+  size_t len = strlen(filename);
+  if (len >= sizeof(property_filename)) return -1;
+
+  strcpy(property_filename, filename);
+  return 0;
+}
+
+__BIONIC_WEAK_FOR_NATIVE_BRIDGE
+int __system_property_area_init() {
+  if (contexts != nullptr) {
+    contexts->FreeAndUnmap();
+  }
+  // We set this unconditionally as we want tests to continue on regardless of if this failed
+  // and property_service will abort on an error condition, so no harm done.
+  contexts = &contexts_split;
+  if (!contexts_split.Initialize(true)) {
+    return -1;
+  }
+  return 0;
+}
+
+__BIONIC_WEAK_FOR_NATIVE_BRIDGE
+uint32_t __system_property_area_serial() {
+  if (contexts == nullptr) {
+    return -1;
+  }
+
+  prop_area* pa = contexts->GetSerialPropArea();
+  if (!pa) {
+    return -1;
+  }
+
+  // Make sure this read fulfilled before __system_property_serial
+  return atomic_load_explicit(pa->serial(), memory_order_acquire);
+}
+
+__BIONIC_WEAK_FOR_NATIVE_BRIDGE
+const prop_info* __system_property_find(const char* name) {
+  if (contexts == nullptr) {
+    return nullptr;
+  }
+
+  prop_area* pa = contexts->GetPropAreaForName(name);
+  if (!pa) {
+    async_safe_format_log(ANDROID_LOG_ERROR, "libc", "Access denied finding property \"%s\"", name);
+    return nullptr;
+  }
+
+  return pa->find(name);
+}
+
+static bool is_read_only(const char* name) {
+  return strncmp(name, "ro.", 3) == 0;
+}
+
+__BIONIC_WEAK_FOR_NATIVE_BRIDGE
+int __system_property_read(const prop_info* pi, char* name, char* value) {
+  while (true) {
+    uint32_t serial = __system_property_serial(pi);  // acquire semantics
+    size_t len = SERIAL_VALUE_LEN(serial);
+    memcpy(value, pi->value, len + 1);
+    // TODO: Fix the synchronization scheme here.
+    // There is no fully supported way to implement this kind
+    // of synchronization in C++11, since the memcpy races with
+    // updates to pi, and the data being accessed is not atomic.
+    // The following fence is unintuitive, but would be the
+    // correct one if memcpy used memory_order_relaxed atomic accesses.
+    // In practice it seems unlikely that the generated code would
+    // would be any different, so this should be OK.
+    atomic_thread_fence(memory_order_acquire);
+    if (serial == load_const_atomic(&(pi->serial), memory_order_relaxed)) {
+      if (name != nullptr) {
+        size_t namelen = strlcpy(name, pi->name, PROP_NAME_MAX);
+        if (namelen >= PROP_NAME_MAX) {
+          async_safe_format_log(ANDROID_LOG_ERROR, "libc",
+                                "The property name length for \"%s\" is >= %d;"
+                                " please use __system_property_read_callback"
+                                " to read this property. (the name is truncated to \"%s\")",
+                                pi->name, PROP_NAME_MAX - 1, name);
+        }
+      }
+      if (is_read_only(pi->name) && pi->is_long()) {
+        async_safe_format_log(
+            ANDROID_LOG_ERROR, "libc",
+            "The property \"%s\" has a value with length %zu that is too large for"
+            " __system_property_get()/__system_property_read(); use"
+            " __system_property_read_callback() instead.",
+            pi->name, strlen(pi->long_value()));
+      }
+      return len;
+    }
+  }
+}
+
+__BIONIC_WEAK_FOR_NATIVE_BRIDGE
+void __system_property_read_callback(const prop_info* pi,
+                                     void (*callback)(void* cookie, const char* name,
+                                                      const char* value, uint32_t serial),
+                                     void* cookie) {
+  // Read only properties don't need to copy the value to a temporary buffer, since it can never
+  // change.
+  if (is_read_only(pi->name)) {
+    uint32_t serial = __system_property_serial(pi);
+    if (pi->is_long()) {
+      callback(cookie, pi->name, pi->long_value(), serial);
+    } else {
+      callback(cookie, pi->name, pi->value, serial);
+    }
+    return;
+  }
+
+  while (true) {
+    uint32_t serial = __system_property_serial(pi);  // acquire semantics
+    size_t len = SERIAL_VALUE_LEN(serial);
+    char value_buf[len + 1];
+
+    memcpy(value_buf, pi->value, len);
+    value_buf[len] = '\0';
+
+    // TODO: see todo in __system_property_read function
+    atomic_thread_fence(memory_order_acquire);
+    if (serial == load_const_atomic(&(pi->serial), memory_order_relaxed)) {
+      callback(cookie, pi->name, value_buf, serial);
+      return;
+    }
+  }
+}
+
+__BIONIC_WEAK_FOR_NATIVE_BRIDGE
+int __system_property_get(const char* name, char* value) {
+  const prop_info* pi = __system_property_find(name);
+
+  if (pi != 0) {
+    return __system_property_read(pi, nullptr, value);
+  } else {
+    value[0] = 0;
+    return 0;
+  }
+}
+
+static constexpr uint32_t kProtocolVersion1 = 1;
+static constexpr uint32_t kProtocolVersion2 = 2;  // current
+
+static atomic_uint_least32_t g_propservice_protocol_version = 0;
+
+static void detect_protocol_version() {
+  char value[PROP_VALUE_MAX];
+  if (__system_property_get(kServiceVersionPropertyName, value) == 0) {
+    g_propservice_protocol_version = kProtocolVersion1;
+    async_safe_format_log(ANDROID_LOG_WARN, "libc",
+                          "Using old property service protocol (\"%s\" is not set)",
+                          kServiceVersionPropertyName);
+  } else {
+    uint32_t version = static_cast<uint32_t>(atoll(value));
+    if (version >= kProtocolVersion2) {
+      g_propservice_protocol_version = kProtocolVersion2;
+    } else {
+      async_safe_format_log(ANDROID_LOG_WARN, "libc",
+                            "Using old property service protocol (\"%s\"=\"%s\")",
+                            kServiceVersionPropertyName, value);
+      g_propservice_protocol_version = kProtocolVersion1;
+    }
+  }
+}
+
+__BIONIC_WEAK_FOR_NATIVE_BRIDGE
+int __system_property_set(const char* key, const char* value) {
+  if (key == nullptr) return -1;
+  if (value == nullptr) value = "";
+
+  if (g_propservice_protocol_version == 0) {
+    detect_protocol_version();
+  }
+
+  if (g_propservice_protocol_version == kProtocolVersion1) {
+    // Old protocol does not support long names or values
+    if (strlen(key) >= PROP_NAME_MAX) return -1;
+    if (strlen(value) >= PROP_VALUE_MAX) return -1;
+
+    prop_msg msg;
+    memset(&msg, 0, sizeof msg);
+    msg.cmd = PROP_MSG_SETPROP;
+    strlcpy(msg.name, key, sizeof msg.name);
+    strlcpy(msg.value, value, sizeof msg.value);
+
+    return send_prop_msg(&msg);
+  } else {
+    // New protocol only allows long values for ro. properties only.
+    if (strlen(value) >= PROP_VALUE_MAX && !is_read_only(key)) return -1;
+    // Use proper protocol
+    PropertyServiceConnection connection;
+    if (!connection.IsValid()) {
+      errno = connection.GetLastError();
+      async_safe_format_log(
+          ANDROID_LOG_WARN, "libc",
+          "Unable to set property \"%s\" to \"%s\": connection failed; errno=%d (%s)", key, value,
+          errno, strerror(errno));
+      return -1;
+    }
+
+    SocketWriter writer(&connection);
+    if (!writer.WriteUint32(PROP_MSG_SETPROP2).WriteString(key).WriteString(value).Send()) {
+      errno = connection.GetLastError();
+      async_safe_format_log(ANDROID_LOG_WARN, "libc",
+                            "Unable to set property \"%s\" to \"%s\": write failed; errno=%d (%s)",
+                            key, value, errno, strerror(errno));
+      return -1;
+    }
+
+    int result = -1;
+    if (!connection.RecvInt32(&result)) {
+      errno = connection.GetLastError();
+      async_safe_format_log(ANDROID_LOG_WARN, "libc",
+                            "Unable to set property \"%s\" to \"%s\": recv failed; errno=%d (%s)",
+                            key, value, errno, strerror(errno));
+      return -1;
+    }
+
+    if (result != PROP_SUCCESS) {
+      async_safe_format_log(ANDROID_LOG_WARN, "libc",
+                            "Unable to set property \"%s\" to \"%s\": error code: 0x%x", key, value,
+                            result);
+      return -1;
+    }
+
+    return 0;
+  }
+}
+
+__BIONIC_WEAK_FOR_NATIVE_BRIDGE
+int __system_property_update(prop_info* pi, const char* value, unsigned int len) {
+  if (len >= PROP_VALUE_MAX) {
+    return -1;
+  }
+
+  if (contexts == nullptr) {
+    return -1;
+  }
+
+  prop_area* pa = contexts->GetSerialPropArea();
+  if (!pa) {
+    return -1;
+  }
+
+  uint32_t serial = atomic_load_explicit(&pi->serial, memory_order_relaxed);
+  serial |= 1;
+  atomic_store_explicit(&pi->serial, serial, memory_order_relaxed);
+  // The memcpy call here also races.  Again pretend it
+  // used memory_order_relaxed atomics, and use the analogous
+  // counterintuitive fence.
+  atomic_thread_fence(memory_order_release);
+  strlcpy(pi->value, value, len + 1);
+
+  atomic_store_explicit(&pi->serial, (len << 24) | ((serial + 1) & 0xffffff), memory_order_release);
+  __futex_wake(&pi->serial, INT32_MAX);
+
+  atomic_store_explicit(pa->serial(), atomic_load_explicit(pa->serial(), memory_order_relaxed) + 1,
+                        memory_order_release);
+  __futex_wake(pa->serial(), INT32_MAX);
+
+  return 0;
+}
+
+__BIONIC_WEAK_FOR_NATIVE_BRIDGE
+int __system_property_add(const char* name, unsigned int namelen, const char* value,
+                          unsigned int valuelen) {
+  if (valuelen >= PROP_VALUE_MAX && !is_read_only(name)) {
+    return -1;
+  }
+
+  if (namelen < 1) {
+    return -1;
+  }
+
+  if (contexts == nullptr) {
+    return -1;
+  }
+
+  prop_area* serial_pa = contexts->GetSerialPropArea();
+  if (serial_pa == nullptr) {
+    return -1;
+  }
+
+  prop_area* pa = contexts->GetPropAreaForName(name);
+  if (!pa) {
+    async_safe_format_log(ANDROID_LOG_ERROR, "libc", "Access denied adding property \"%s\"", name);
+    return -1;
+  }
+
+  bool ret = pa->add(name, namelen, value, valuelen);
+  if (!ret) {
+    return -1;
+  }
+
+  // There is only a single mutator, but we want to make sure that
+  // updates are visible to a reader waiting for the update.
+  atomic_store_explicit(serial_pa->serial(),
+                        atomic_load_explicit(serial_pa->serial(), memory_order_relaxed) + 1,
+                        memory_order_release);
+  __futex_wake(serial_pa->serial(), INT32_MAX);
+  return 0;
+}
+
+// Wait for non-locked serial, and retrieve it with acquire semantics.
+__BIONIC_WEAK_FOR_NATIVE_BRIDGE
+uint32_t __system_property_serial(const prop_info* pi) {
+  uint32_t serial = load_const_atomic(&pi->serial, memory_order_acquire);
+  while (SERIAL_DIRTY(serial)) {
+    __futex_wait(const_cast<_Atomic(uint_least32_t)*>(&pi->serial), serial, nullptr);
+    serial = load_const_atomic(&pi->serial, memory_order_acquire);
+  }
+  return serial;
+}
+
+__BIONIC_WEAK_FOR_NATIVE_BRIDGE
+uint32_t __system_property_wait_any(uint32_t old_serial) {
+  uint32_t new_serial;
+  __system_property_wait(nullptr, old_serial, &new_serial, nullptr);
+  return new_serial;
+}
+
+__BIONIC_WEAK_FOR_NATIVE_BRIDGE
+bool __system_property_wait(const prop_info* pi, uint32_t old_serial, uint32_t* new_serial_ptr,
+                            const timespec* relative_timeout) {
+  // Are we waiting on the global serial or a specific serial?
+  atomic_uint_least32_t* serial_ptr;
+  if (pi == nullptr) {
+    if (contexts == nullptr) {
+      return -1;
+    }
+
+    prop_area* serial_pa = contexts->GetSerialPropArea();
+    if (serial_pa == nullptr) {
+      return -1;
+    }
+
+    serial_ptr = serial_pa->serial();
+  } else {
+    serial_ptr = const_cast<atomic_uint_least32_t*>(&pi->serial);
+  }
+
+  uint32_t new_serial;
+  do {
+    int rc;
+    if ((rc = __futex_wait(serial_ptr, old_serial, relative_timeout)) != 0 && rc == -ETIMEDOUT) {
+      return false;
+    }
+    new_serial = load_const_atomic(serial_ptr, memory_order_acquire);
+  } while (new_serial == old_serial);
+
+  *new_serial_ptr = new_serial;
+  return true;
+}
+
+__BIONIC_WEAK_FOR_NATIVE_BRIDGE
+const prop_info* __system_property_find_nth(unsigned n) {
+  struct find_nth {
+    const uint32_t sought;
+    uint32_t current;
+    const prop_info* result;
+
+    explicit find_nth(uint32_t n) : sought(n), current(0), result(nullptr) {
+    }
+    static void fn(const prop_info* pi, void* ptr) {
+      find_nth* self = reinterpret_cast<find_nth*>(ptr);
+      if (self->current++ == self->sought) self->result = pi;
+    }
+  } state(n);
+  __system_property_foreach(find_nth::fn, &state);
+  return state.result;
+}
+
+__BIONIC_WEAK_FOR_NATIVE_BRIDGE
+int __system_property_foreach(void (*propfn)(const prop_info* pi, void* cookie), void* cookie) {
+  if (contexts == nullptr) {
+    return -1;
+  }
+
+  contexts->ForEach(propfn, cookie);
+
+  return 0;
+}
diff --git a/libc/tools/check-symbols-glibc.py b/libc/tools/check-symbols-glibc.py
index 9aba2e2..4de0181 100755
--- a/libc/tools/check-symbols-glibc.py
+++ b/libc/tools/check-symbols-glibc.py
@@ -184,19 +184,24 @@
 ])
 # POSIX has some stuff that's too stupid for words (a64l) or not actually
 # implemented in glibc unless you count always failing with ENOSYS as
-# being implemented (fattach).
+# being implemented (fattach). Other stuff (fmtmsg) isn't used in any
+# codebase I have access to, internal or external.
 in_posix_and_glibc_but_dead_or_useless = set([
   'a64l', # obsolete
   'confstr', # obsolete
-  'fattach', # obsolete
-  'fdetach', # obsolete
+  'endutxent', # no utmp on Android
+  'fattach', # <stropts.h> marked obsolescent
+  'fdetach', # <stropts.h> marked obsolescent
+  'fmtmsg', # unused
+  'getdate', # unused
+  'getdate_err', # unused
   'gethostid', # obsolete
-  'getmsg', # obsolete
-  'getpmsg', # obsolete
+  'getmsg', # <stropts.h> marked obsolescent
+  'getpmsg', # <stropts.h> marked obsolescent
   'getutxent', # no utmp on Android
   'getutxid', # no utmp on Android
   'getutxline', # no utmp on Android
-  'isastream', # obsolete
+  'isastream', # <stropts.h> marked obsolescent
   'l64a', # obsolete
   'mq_close', # disallowed by SELinux
   'mq_getattr', # disallowed by SELinux
@@ -208,15 +213,18 @@
   'mq_timedreceive', # disallowed by SELinux
   'mq_timedsend', # disallowed by SELinux
   'mq_unlink', # disallowed by SELinux
-  'putmsg', # obsolete
-  'putpmsg', # obsolete
+  'pthread_getconcurrency', # marked obsolescent
+  'pthread_setconcurrency', # marked obsolescent
+  'putmsg', # <stropts.h> marked obsolescent
+  'putpmsg', # <stropts.h> marked obsolescent
   'pututxline', # no utmp on Android
   'shm_open', # disallowed by SELinux
   'shm_unlink', # disallowed by SELinux
   'setutxent', # no utmp on Android
+  'sockatmark', # obsolete (https://tools.ietf.org/html/rfc6093)
   'strfmon', # icu4c
   'strfmon_l', # icu4c
-  'ulimit', # obsolete
+  'ulimit', # <ulimit.h> marked obsolescent
 ])
 
 posix = posix - in_posix_and_glibc_but_dead_or_useless
diff --git a/libc/tools/gensyscalls.py b/libc/tools/gensyscalls.py
index 46affb7..2fa4e0f 100755
--- a/libc/tools/gensyscalls.py
+++ b/libc/tools/gensyscalls.py
@@ -118,16 +118,16 @@
 
 mips_call = syscall_stub_header + """\
     .set noreorder
-    .cpload t9
-    li v0, %(__NR_name)s
+    .cpload $t9
+    li $v0, %(__NR_name)s
     syscall
-    bnez a3, 1f
-    move a0, v0
-    j ra
+    bnez $a3, 1f
+    move $a0, $v0
+    j $ra
     nop
 1:
-    la t9,__set_errno_internal
-    j t9
+    la $t9,__set_errno_internal
+    j $t9
     nop
     .set reorder
 END(%(func)s)
@@ -141,22 +141,22 @@
 mips64_call = syscall_stub_header + """\
     .set push
     .set noreorder
-    li v0, %(__NR_name)s
+    li $v0, %(__NR_name)s
     syscall
-    bnez a3, 1f
-    move a0, v0
-    j ra
+    bnez $a3, 1f
+    move $a0, $v0
+    j $ra
     nop
 1:
-    move t0, ra
-    bal     2f
+    move $t0, $ra
+    bal 2f
     nop
 2:
-    .cpsetup ra, t1, 2b
-    LA t9,__set_errno_internal
+    .cpsetup $ra, $t1, 2b
+    LA $t9, __set_errno_internal
     .cpreturn
-    j t9
-    move ra, t0
+    j $t9
+    move $ra, $t0
     .set pop
 END(%(func)s)
 """
diff --git a/libc/tzcode/bionic.cpp b/libc/tzcode/bionic.cpp
index b486174..9b59183 100644
--- a/libc/tzcode/bionic.cpp
+++ b/libc/tzcode/bionic.cpp
@@ -27,6 +27,7 @@
  */
 
 #include <arpa/inet.h> // For ntohl(3).
+#include <errno.h>
 #include <fcntl.h>
 #include <stdint.h>
 #include <stdlib.h>
diff --git a/libc/upstream-freebsd/android/include/collate.h b/libc/upstream-freebsd/android/include/collate.h
new file mode 100644
index 0000000..e69de29
--- /dev/null
+++ b/libc/upstream-freebsd/android/include/collate.h
diff --git a/libc/upstream-freebsd/android/include/freebsd-compat.h b/libc/upstream-freebsd/android/include/freebsd-compat.h
index 7acdf7c..e646e23 100644
--- a/libc/upstream-freebsd/android/include/freebsd-compat.h
+++ b/libc/upstream-freebsd/android/include/freebsd-compat.h
@@ -18,6 +18,10 @@
 #define _BIONIC_FREEBSD_COMPAT_H_included
 
 #define _BSD_SOURCE
+
+#include <sys/cdefs.h>
+#include <stddef.h> // For size_t.
+
 #define REPLACE_GETOPT
 
 /*
@@ -40,4 +44,10 @@
 /* Redirect internal C library calls to the public function. */
 #define _nanosleep nanosleep
 
+/* FreeBSD has this as API, but we just use it internally. */
+void* reallocarray(void*, size_t, size_t);
+
+/* FreeBSD has this, but we can't really implement it correctly on Linux. */
+#define issetugid() 0
+
 #endif
diff --git a/libc/upstream-freebsd/lib/libc/gen/glob.c b/libc/upstream-freebsd/lib/libc/gen/glob.c
new file mode 100644
index 0000000..026f68e
--- /dev/null
+++ b/libc/upstream-freebsd/lib/libc/gen/glob.c
@@ -0,0 +1,1125 @@
+/*
+ * Copyright (c) 1989, 1993
+ *	The Regents of the University of California.  All rights reserved.
+ *
+ * This code is derived from software contributed to Berkeley by
+ * Guido van Rossum.
+ *
+ * Copyright (c) 2011 The FreeBSD Foundation
+ * All rights reserved.
+ * Portions of this software were developed by David Chisnall
+ * under sponsorship from the FreeBSD Foundation.
+ *
+ * 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.
+ */
+
+#if defined(LIBC_SCCS) && !defined(lint)
+static char sccsid[] = "@(#)glob.c	8.3 (Berkeley) 10/13/93";
+#endif /* LIBC_SCCS and not lint */
+#include <sys/cdefs.h>
+__FBSDID("$FreeBSD: head/lib/libc/gen/glob.c 317913 2017-05-07 19:52:56Z jilles $");
+
+/*
+ * glob(3) -- a superset of the one defined in POSIX 1003.2.
+ *
+ * The [!...] convention to negate a range is supported (SysV, Posix, ksh).
+ *
+ * Optional extra services, controlled by flags not defined by POSIX:
+ *
+ * GLOB_QUOTE:
+ *	Escaping convention: \ inhibits any special meaning the following
+ *	character might have (except \ at end of string is retained).
+ * GLOB_MAGCHAR:
+ *	Set in gl_flags if pattern contained a globbing character.
+ * GLOB_NOMAGIC:
+ *	Same as GLOB_NOCHECK, but it will only append pattern if it did
+ *	not contain any magic characters.  [Used in csh style globbing]
+ * GLOB_ALTDIRFUNC:
+ *	Use alternately specified directory access functions.
+ * GLOB_TILDE:
+ *	expand ~user/foo to the /home/dir/of/user/foo
+ * GLOB_BRACE:
+ *	expand {1,2}{a,b} to 1a 1b 2a 2b
+ * gl_matchc:
+ *	Number of matches in the current invocation of glob.
+ */
+
+/*
+ * Some notes on multibyte character support:
+ * 1. Patterns with illegal byte sequences match nothing - even if
+ *    GLOB_NOCHECK is specified.
+ * 2. Illegal byte sequences in filenames are handled by treating them as
+ *    single-byte characters with a values of such bytes of the sequence
+ *    cast to wchar_t.
+ * 3. State-dependent encodings are not currently supported.
+ */
+
+#include <sys/param.h>
+#include <sys/stat.h>
+
+#include <ctype.h>
+#include <dirent.h>
+#include <errno.h>
+#include <glob.h>
+#include <limits.h>
+#include <pwd.h>
+#include <stdint.h>
+#include <stdio.h>
+#include <stdlib.h>
+#include <string.h>
+#include <unistd.h>
+#include <wchar.h>
+
+#include "collate.h"
+
+/*
+ * glob(3) expansion limits. Stop the expansion if any of these limits
+ * is reached. This caps the runtime in the face of DoS attacks. See
+ * also CVE-2010-2632
+ */
+#define	GLOB_LIMIT_BRACE	128	/* number of brace calls */
+#define	GLOB_LIMIT_PATH		65536	/* number of path elements */
+#define	GLOB_LIMIT_READDIR	16384	/* number of readdirs */
+#define	GLOB_LIMIT_STAT		1024	/* number of stat system calls */
+#define	GLOB_LIMIT_STRING	ARG_MAX	/* maximum total size for paths */
+
+struct glob_limit {
+	size_t	l_brace_cnt;
+	size_t	l_path_lim;
+	size_t	l_readdir_cnt;	
+	size_t	l_stat_cnt;	
+	size_t	l_string_cnt;
+};
+
+#define	DOT		L'.'
+#define	EOS		L'\0'
+#define	LBRACKET	L'['
+#define	NOT		L'!'
+#define	QUESTION	L'?'
+#define	QUOTE		L'\\'
+#define	RANGE		L'-'
+#define	RBRACKET	L']'
+#define	SEP		L'/'
+#define	STAR		L'*'
+#define	TILDE		L'~'
+#define	LBRACE		L'{'
+#define	RBRACE		L'}'
+#define	COMMA		L','
+
+#define	M_QUOTE		0x8000000000ULL
+#define	M_PROTECT	0x4000000000ULL
+#define	M_MASK		0xffffffffffULL
+#define	M_CHAR		0x00ffffffffULL
+
+typedef uint_fast64_t Char;
+
+#define	CHAR(c)		((Char)((c)&M_CHAR))
+#define	META(c)		((Char)((c)|M_QUOTE))
+#define	UNPROT(c)	((c) & ~M_PROTECT)
+#define	M_ALL		META(L'*')
+#define	M_END		META(L']')
+#define	M_NOT		META(L'!')
+#define	M_ONE		META(L'?')
+#define	M_RNG		META(L'-')
+#define	M_SET		META(L'[')
+#define	ismeta(c)	(((c)&M_QUOTE) != 0)
+#ifdef DEBUG
+#define	isprot(c)	(((c)&M_PROTECT) != 0)
+#endif
+
+static int	 compare(const void *, const void *);
+static int	 g_Ctoc(const Char *, char *, size_t);
+static int	 g_lstat(Char *, struct stat *, glob_t *);
+static DIR	*g_opendir(Char *, glob_t *);
+static const Char *g_strchr(const Char *, wchar_t);
+#ifdef notdef
+static Char	*g_strcat(Char *, const Char *);
+#endif
+static int	 g_stat(Char *, struct stat *, glob_t *);
+static int	 glob0(const Char *, glob_t *, struct glob_limit *,
+    const char *);
+static int	 glob1(Char *, glob_t *, struct glob_limit *);
+static int	 glob2(Char *, Char *, Char *, Char *, glob_t *,
+    struct glob_limit *);
+static int	 glob3(Char *, Char *, Char *, Char *, Char *, glob_t *,
+    struct glob_limit *);
+static int	 globextend(const Char *, glob_t *, struct glob_limit *,
+    const char *);
+static const Char *
+		 globtilde(const Char *, Char *, size_t, glob_t *);
+static int	 globexp0(const Char *, glob_t *, struct glob_limit *,
+    const char *);
+static int	 globexp1(const Char *, glob_t *, struct glob_limit *);
+static int	 globexp2(const Char *, const Char *, glob_t *,
+    struct glob_limit *);
+static int	 globfinal(glob_t *, struct glob_limit *, size_t,
+    const char *);
+static int	 match(Char *, Char *, Char *);
+static int	 err_nomatch(glob_t *, struct glob_limit *, const char *);
+static int	 err_aborted(glob_t *, int, char *);
+#ifdef DEBUG
+static void	 qprintf(const char *, Char *);
+#endif
+
+int
+glob(const char * __restrict pattern, int flags,
+	 int (*errfunc)(const char *, int), glob_t * __restrict pglob)
+{
+	struct glob_limit limit = { 0, 0, 0, 0, 0 };
+	const char *patnext;
+	Char *bufnext, *bufend, patbuf[MAXPATHLEN], prot;
+	mbstate_t mbs;
+	wchar_t wc;
+	size_t clen;
+	int too_long;
+
+	patnext = pattern;
+	if (!(flags & GLOB_APPEND)) {
+		pglob->gl_pathc = 0;
+		pglob->gl_pathv = NULL;
+		if (!(flags & GLOB_DOOFFS))
+			pglob->gl_offs = 0;
+	}
+	if (flags & GLOB_LIMIT) {
+		limit.l_path_lim = pglob->gl_matchc;
+		if (limit.l_path_lim == 0)
+			limit.l_path_lim = GLOB_LIMIT_PATH;
+	}
+	pglob->gl_flags = flags & ~GLOB_MAGCHAR;
+	pglob->gl_errfunc = errfunc;
+	pglob->gl_matchc = 0;
+
+	bufnext = patbuf;
+	bufend = bufnext + MAXPATHLEN - 1;
+	too_long = 1;
+	if (flags & GLOB_NOESCAPE) {
+		memset(&mbs, 0, sizeof(mbs));
+		while (bufnext <= bufend) {
+			clen = mbrtowc(&wc, patnext, MB_LEN_MAX, &mbs);
+			if (clen == (size_t)-1 || clen == (size_t)-2)
+				return (err_nomatch(pglob, &limit, pattern));
+			else if (clen == 0) {
+				too_long = 0;
+				break;
+			}
+			*bufnext++ = wc;
+			patnext += clen;
+		}
+	} else {
+		/* Protect the quoted characters. */
+		memset(&mbs, 0, sizeof(mbs));
+		while (bufnext <= bufend) {
+			if (*patnext == '\\') {
+				if (*++patnext == '\0') {
+					*bufnext++ = QUOTE;
+					continue;
+				}
+				prot = M_PROTECT;
+			} else
+				prot = 0;
+			clen = mbrtowc(&wc, patnext, MB_LEN_MAX, &mbs);
+			if (clen == (size_t)-1 || clen == (size_t)-2)
+				return (err_nomatch(pglob, &limit, pattern));
+			else if (clen == 0) {
+				too_long = 0;
+				break;
+			}
+			*bufnext++ = wc | prot;
+			patnext += clen;
+		}
+	}
+	if (too_long)
+		return (err_nomatch(pglob, &limit, pattern));
+	*bufnext = EOS;
+
+	if (flags & GLOB_BRACE)
+	    return (globexp0(patbuf, pglob, &limit, pattern));
+	else
+	    return (glob0(patbuf, pglob, &limit, pattern));
+}
+
+static int
+globexp0(const Char *pattern, glob_t *pglob, struct glob_limit *limit,
+    const char *origpat) {
+	int rv;
+	size_t oldpathc;
+
+	/* Protect a single {}, for find(1), like csh */
+	if (pattern[0] == LBRACE && pattern[1] == RBRACE && pattern[2] == EOS) {
+		if ((pglob->gl_flags & GLOB_LIMIT) &&
+		    limit->l_brace_cnt++ >= GLOB_LIMIT_BRACE) {
+			errno = E2BIG;
+			return (GLOB_NOSPACE);
+		}
+		return (glob0(pattern, pglob, limit, origpat));
+	}
+
+	oldpathc = pglob->gl_pathc;
+
+	if ((rv = globexp1(pattern, pglob, limit)) != 0)
+		return rv;
+
+	return (globfinal(pglob, limit, oldpathc, origpat));
+}
+
+/*
+ * Expand recursively a glob {} pattern. When there is no more expansion
+ * invoke the standard globbing routine to glob the rest of the magic
+ * characters
+ */
+static int
+globexp1(const Char *pattern, glob_t *pglob, struct glob_limit *limit)
+{
+	const Char* ptr;
+
+	if ((ptr = g_strchr(pattern, LBRACE)) != NULL) {
+		if ((pglob->gl_flags & GLOB_LIMIT) &&
+		    limit->l_brace_cnt++ >= GLOB_LIMIT_BRACE) {
+			errno = E2BIG;
+			return (GLOB_NOSPACE);
+		}
+		return (globexp2(ptr, pattern, pglob, limit));
+	}
+
+	return (glob0(pattern, pglob, limit, NULL));
+}
+
+
+/*
+ * Recursive brace globbing helper. Tries to expand a single brace.
+ * If it succeeds then it invokes globexp1 with the new pattern.
+ * If it fails then it tries to glob the rest of the pattern and returns.
+ */
+static int
+globexp2(const Char *ptr, const Char *pattern, glob_t *pglob,
+    struct glob_limit *limit)
+{
+	int     i, rv;
+	Char   *lm, *ls;
+	const Char *pe, *pm, *pm1, *pl;
+	Char    patbuf[MAXPATHLEN];
+
+	/* copy part up to the brace */
+	for (lm = patbuf, pm = pattern; pm != ptr; *lm++ = *pm++)
+		continue;
+	*lm = EOS;
+	ls = lm;
+
+	/* Find the balanced brace */
+	for (i = 0, pe = ++ptr; *pe != EOS; pe++)
+		if (*pe == LBRACKET) {
+			/* Ignore everything between [] */
+			for (pm = pe++; *pe != RBRACKET && *pe != EOS; pe++)
+				continue;
+			if (*pe == EOS) {
+				/*
+				 * We could not find a matching RBRACKET.
+				 * Ignore and just look for RBRACE
+				 */
+				pe = pm;
+			}
+		}
+		else if (*pe == LBRACE)
+			i++;
+		else if (*pe == RBRACE) {
+			if (i == 0)
+				break;
+			i--;
+		}
+
+	/* Non matching braces; just glob the pattern */
+	if (i != 0 || *pe == EOS)
+		return (glob0(pattern, pglob, limit, NULL));
+
+	for (i = 0, pl = pm = ptr; pm <= pe; pm++)
+		switch (*pm) {
+		case LBRACKET:
+			/* Ignore everything between [] */
+			for (pm1 = pm++; *pm != RBRACKET && *pm != EOS; pm++)
+				continue;
+			if (*pm == EOS) {
+				/*
+				 * We could not find a matching RBRACKET.
+				 * Ignore and just look for RBRACE
+				 */
+				pm = pm1;
+			}
+			break;
+
+		case LBRACE:
+			i++;
+			break;
+
+		case RBRACE:
+			if (i) {
+			    i--;
+			    break;
+			}
+			/* FALLTHROUGH */
+		case COMMA:
+			if (i && *pm == COMMA)
+				break;
+			else {
+				/* Append the current string */
+				for (lm = ls; (pl < pm); *lm++ = *pl++)
+					continue;
+				/*
+				 * Append the rest of the pattern after the
+				 * closing brace
+				 */
+				for (pl = pe + 1; (*lm++ = *pl++) != EOS;)
+					continue;
+
+				/* Expand the current pattern */
+#ifdef DEBUG
+				qprintf("globexp2:", patbuf);
+#endif
+				rv = globexp1(patbuf, pglob, limit);
+				if (rv)
+					return (rv);
+
+				/* move after the comma, to the next string */
+				pl = pm + 1;
+			}
+			break;
+
+		default:
+			break;
+		}
+	return (0);
+}
+
+
+
+/*
+ * expand tilde from the passwd file.
+ */
+static const Char *
+globtilde(const Char *pattern, Char *patbuf, size_t patbuf_len, glob_t *pglob)
+{
+	struct passwd *pwd;
+	char *h, *sc;
+	const Char *p;
+	Char *b, *eb;
+	wchar_t wc;
+	wchar_t wbuf[MAXPATHLEN];
+	wchar_t *wbufend, *dc;
+	size_t clen;
+	mbstate_t mbs;
+	int too_long;
+
+	if (*pattern != TILDE || !(pglob->gl_flags & GLOB_TILDE))
+		return (pattern);
+
+	/* 
+	 * Copy up to the end of the string or / 
+	 */
+	eb = &patbuf[patbuf_len - 1];
+	for (p = pattern + 1, b = patbuf;
+	    b < eb && *p != EOS && UNPROT(*p) != SEP; *b++ = *p++)
+		continue;
+
+	if (*p != EOS && UNPROT(*p) != SEP)
+		return (NULL);
+
+	*b = EOS;
+	h = NULL;
+
+	if (patbuf[0] == EOS) {
+		/*
+		 * handle a plain ~ or ~/ by expanding $HOME first (iff
+		 * we're not running setuid or setgid) and then trying
+		 * the password file
+		 */
+		if (issetugid() != 0 ||
+		    (h = getenv("HOME")) == NULL) {
+			if (((h = getlogin()) != NULL &&
+			     (pwd = getpwnam(h)) != NULL) ||
+			    (pwd = getpwuid(getuid())) != NULL)
+				h = pwd->pw_dir;
+			else
+				return (pattern);
+		}
+	}
+	else {
+		/*
+		 * Expand a ~user
+		 */
+		if (g_Ctoc(patbuf, (char *)wbuf, sizeof(wbuf)))
+			return (NULL);
+		if ((pwd = getpwnam((char *)wbuf)) == NULL)
+			return (pattern);
+		else
+			h = pwd->pw_dir;
+	}
+
+	/* Copy the home directory */
+	dc = wbuf;
+	sc = h;
+	wbufend = wbuf + MAXPATHLEN - 1;
+	too_long = 1;
+	memset(&mbs, 0, sizeof(mbs));
+	while (dc <= wbufend) {
+		clen = mbrtowc(&wc, sc, MB_LEN_MAX, &mbs);
+		if (clen == (size_t)-1 || clen == (size_t)-2) {
+			/* XXX See initial comment #2. */
+			wc = (unsigned char)*sc;
+			clen = 1;
+			memset(&mbs, 0, sizeof(mbs));
+		}
+		if ((*dc++ = wc) == EOS) {
+			too_long = 0;
+			break;
+		}
+		sc += clen;
+	}
+	if (too_long)
+		return (NULL);
+
+	dc = wbuf;
+	for (b = patbuf; b < eb && *dc != EOS; *b++ = *dc++ | M_PROTECT)
+		continue;
+	if (*dc != EOS)
+		return (NULL);
+
+	/* Append the rest of the pattern */
+	if (*p != EOS) {
+		too_long = 1;
+		while (b <= eb) {
+			if ((*b++ = *p++) == EOS) {
+				too_long = 0;
+				break;
+			}
+		}
+		if (too_long)
+			return (NULL);
+	} else
+		*b = EOS;
+
+	return (patbuf);
+}
+
+
+/*
+ * The main glob() routine: compiles the pattern (optionally processing
+ * quotes), calls glob1() to do the real pattern matching, and finally
+ * sorts the list (unless unsorted operation is requested).  Returns 0
+ * if things went well, nonzero if errors occurred.
+ */
+static int
+glob0(const Char *pattern, glob_t *pglob, struct glob_limit *limit,
+    const char *origpat) {
+	const Char *qpatnext;
+	int err;
+	size_t oldpathc;
+	Char *bufnext, c, patbuf[MAXPATHLEN];
+
+	qpatnext = globtilde(pattern, patbuf, MAXPATHLEN, pglob);
+	if (qpatnext == NULL) {
+		errno = E2BIG;
+		return (GLOB_NOSPACE);
+	}
+	oldpathc = pglob->gl_pathc;
+	bufnext = patbuf;
+
+	/* We don't need to check for buffer overflow any more. */
+	while ((c = *qpatnext++) != EOS) {
+		switch (c) {
+		case LBRACKET:
+			c = *qpatnext;
+			if (c == NOT)
+				++qpatnext;
+			if (*qpatnext == EOS ||
+			    g_strchr(qpatnext+1, RBRACKET) == NULL) {
+				*bufnext++ = LBRACKET;
+				if (c == NOT)
+					--qpatnext;
+				break;
+			}
+			*bufnext++ = M_SET;
+			if (c == NOT)
+				*bufnext++ = M_NOT;
+			c = *qpatnext++;
+			do {
+				*bufnext++ = CHAR(c);
+				if (*qpatnext == RANGE &&
+				    (c = qpatnext[1]) != RBRACKET) {
+					*bufnext++ = M_RNG;
+					*bufnext++ = CHAR(c);
+					qpatnext += 2;
+				}
+			} while ((c = *qpatnext++) != RBRACKET);
+			pglob->gl_flags |= GLOB_MAGCHAR;
+			*bufnext++ = M_END;
+			break;
+		case QUESTION:
+			pglob->gl_flags |= GLOB_MAGCHAR;
+			*bufnext++ = M_ONE;
+			break;
+		case STAR:
+			pglob->gl_flags |= GLOB_MAGCHAR;
+			/* collapse adjacent stars to one,
+			 * to ensure "**" at the end continues to match the
+			 * empty string
+			 */
+			if (bufnext == patbuf || bufnext[-1] != M_ALL)
+			    *bufnext++ = M_ALL;
+			break;
+		default:
+			*bufnext++ = CHAR(c);
+			break;
+		}
+	}
+	*bufnext = EOS;
+#ifdef DEBUG
+	qprintf("glob0:", patbuf);
+#endif
+
+	if ((err = glob1(patbuf, pglob, limit)) != 0)
+		return(err);
+
+	if (origpat != NULL)
+		return (globfinal(pglob, limit, oldpathc, origpat));
+
+	return (0);
+}
+
+static int
+globfinal(glob_t *pglob, struct glob_limit *limit, size_t oldpathc,
+    const char *origpat) {
+	if (pglob->gl_pathc == oldpathc)
+		return (err_nomatch(pglob, limit, origpat));
+
+	if (!(pglob->gl_flags & GLOB_NOSORT))
+		qsort(pglob->gl_pathv + pglob->gl_offs + oldpathc,
+		    pglob->gl_pathc - oldpathc, sizeof(char *), compare);
+
+	return (0);
+}
+
+static int
+compare(const void *p, const void *q)
+{
+	return (strcoll(*(char **)p, *(char **)q));
+}
+
+static int
+glob1(Char *pattern, glob_t *pglob, struct glob_limit *limit)
+{
+	Char pathbuf[MAXPATHLEN];
+
+	/* A null pathname is invalid -- POSIX 1003.1 sect. 2.4. */
+	if (*pattern == EOS)
+		return (0);
+	return (glob2(pathbuf, pathbuf, pathbuf + MAXPATHLEN - 1,
+	    pattern, pglob, limit));
+}
+
+/*
+ * The functions glob2 and glob3 are mutually recursive; there is one level
+ * of recursion for each segment in the pattern that contains one or more
+ * meta characters.
+ */
+static int
+glob2(Char *pathbuf, Char *pathend, Char *pathend_last, Char *pattern,
+      glob_t *pglob, struct glob_limit *limit)
+{
+	struct stat sb;
+	Char *p, *q;
+	int anymeta;
+
+	/*
+	 * Loop over pattern segments until end of pattern or until
+	 * segment with meta character found.
+	 */
+	for (anymeta = 0;;) {
+		if (*pattern == EOS) {		/* End of pattern? */
+			*pathend = EOS;
+			if (g_lstat(pathbuf, &sb, pglob))
+				return (0);
+
+			if ((pglob->gl_flags & GLOB_LIMIT) &&
+			    limit->l_stat_cnt++ >= GLOB_LIMIT_STAT) {
+				errno = E2BIG;
+				return (GLOB_NOSPACE);
+			}
+			if ((pglob->gl_flags & GLOB_MARK) &&
+			    UNPROT(pathend[-1]) != SEP &&
+			    (S_ISDIR(sb.st_mode) ||
+			    (S_ISLNK(sb.st_mode) &&
+			    g_stat(pathbuf, &sb, pglob) == 0 &&
+			    S_ISDIR(sb.st_mode)))) {
+				if (pathend + 1 > pathend_last) {
+					errno = E2BIG;
+					return (GLOB_NOSPACE);
+				}
+				*pathend++ = SEP;
+				*pathend = EOS;
+			}
+			++pglob->gl_matchc;
+			return (globextend(pathbuf, pglob, limit, NULL));
+		}
+
+		/* Find end of next segment, copy tentatively to pathend. */
+		q = pathend;
+		p = pattern;
+		while (*p != EOS && UNPROT(*p) != SEP) {
+			if (ismeta(*p))
+				anymeta = 1;
+			if (q + 1 > pathend_last) {
+				errno = E2BIG;
+				return (GLOB_NOSPACE);
+			}
+			*q++ = *p++;
+		}
+
+		if (!anymeta) {		/* No expansion, do next segment. */
+			pathend = q;
+			pattern = p;
+			while (UNPROT(*pattern) == SEP) {
+				if (pathend + 1 > pathend_last) {
+					errno = E2BIG;
+					return (GLOB_NOSPACE);
+				}
+				*pathend++ = *pattern++;
+			}
+		} else			/* Need expansion, recurse. */
+			return (glob3(pathbuf, pathend, pathend_last, pattern,
+			    p, pglob, limit));
+	}
+	/* NOTREACHED */
+}
+
+static int
+glob3(Char *pathbuf, Char *pathend, Char *pathend_last,
+      Char *pattern, Char *restpattern,
+      glob_t *pglob, struct glob_limit *limit)
+{
+	struct dirent *dp;
+	DIR *dirp;
+	int err, too_long, saverrno, saverrno2;
+	char buf[MAXPATHLEN + MB_LEN_MAX - 1];
+
+	struct dirent *(*readdirfunc)(DIR *);
+
+	if (pathend > pathend_last) {
+		errno = E2BIG;
+		return (GLOB_NOSPACE);
+	}
+	*pathend = EOS;
+	if (pglob->gl_errfunc != NULL &&
+	    g_Ctoc(pathbuf, buf, sizeof(buf))) {
+		errno = E2BIG;
+		return (GLOB_NOSPACE);
+	}
+
+	saverrno = errno;
+	errno = 0;
+	if ((dirp = g_opendir(pathbuf, pglob)) == NULL) {
+		if (errno == ENOENT || errno == ENOTDIR)
+			return (0);
+		err = err_aborted(pglob, errno, buf);
+		if (errno == 0)
+			errno = saverrno;
+		return (err);
+	}
+
+	err = 0;
+
+	/* pglob->gl_readdir takes a void *, fix this manually */
+	if (pglob->gl_flags & GLOB_ALTDIRFUNC)
+		readdirfunc = (struct dirent *(*)(DIR *))pglob->gl_readdir;
+	else
+		readdirfunc = readdir;
+
+	errno = 0;
+	/* Search directory for matching names. */
+	while ((dp = (*readdirfunc)(dirp)) != NULL) {
+		char *sc;
+		Char *dc;
+		wchar_t wc;
+		size_t clen;
+		mbstate_t mbs;
+
+		if ((pglob->gl_flags & GLOB_LIMIT) &&
+		    limit->l_readdir_cnt++ >= GLOB_LIMIT_READDIR) {
+			errno = E2BIG;
+			err = GLOB_NOSPACE;
+			break;
+		}
+
+		/* Initial DOT must be matched literally. */
+		if (dp->d_name[0] == '.' && UNPROT(*pattern) != DOT) {
+			errno = 0;
+			continue;
+		}
+		memset(&mbs, 0, sizeof(mbs));
+		dc = pathend;
+		sc = dp->d_name;
+		too_long = 1;
+		while (dc <= pathend_last) {
+			clen = mbrtowc(&wc, sc, MB_LEN_MAX, &mbs);
+			if (clen == (size_t)-1 || clen == (size_t)-2) {
+				/* XXX See initial comment #2. */
+				wc = (unsigned char)*sc;
+				clen = 1;
+				memset(&mbs, 0, sizeof(mbs));
+			}
+			if ((*dc++ = wc) == EOS) {
+				too_long = 0;
+				break;
+			}
+			sc += clen;
+		}
+		if (too_long && (err = err_aborted(pglob, ENAMETOOLONG,
+		    buf))) {
+			errno = ENAMETOOLONG;
+			break;
+		}
+		if (too_long || !match(pathend, pattern, restpattern)) {
+			*pathend = EOS;
+			errno = 0;
+			continue;
+		}
+		if (errno == 0)
+			errno = saverrno;
+		err = glob2(pathbuf, --dc, pathend_last, restpattern,
+		    pglob, limit);
+		if (err)
+			break;
+		errno = 0;
+	}
+
+	saverrno2 = errno;
+	if (pglob->gl_flags & GLOB_ALTDIRFUNC)
+		(*pglob->gl_closedir)(dirp);
+	else
+		closedir(dirp);
+	errno = saverrno2;
+
+	if (err)
+		return (err);
+
+	if (dp == NULL && errno != 0 &&
+	    (err = err_aborted(pglob, errno, buf)))
+		return (err);
+
+	if (errno == 0)
+		errno = saverrno;
+	return (0);
+}
+
+
+/*
+ * Extend the gl_pathv member of a glob_t structure to accommodate a new item,
+ * add the new item, and update gl_pathc.
+ *
+ * This assumes the BSD realloc, which only copies the block when its size
+ * crosses a power-of-two boundary; for v7 realloc, this would cause quadratic
+ * behavior.
+ *
+ * Return 0 if new item added, error code if memory couldn't be allocated.
+ *
+ * Invariant of the glob_t structure:
+ *	Either gl_pathc is zero and gl_pathv is NULL; or gl_pathc > 0 and
+ *	gl_pathv points to (gl_offs + gl_pathc + 1) items.
+ */
+static int
+globextend(const Char *path, glob_t *pglob, struct glob_limit *limit,
+    const char *origpat)
+{
+	char **pathv;
+	size_t i, newn, len;
+	char *copy;
+	const Char *p;
+
+	if ((pglob->gl_flags & GLOB_LIMIT) &&
+	    pglob->gl_matchc > limit->l_path_lim) {
+		errno = E2BIG;
+		return (GLOB_NOSPACE);
+	}
+
+	newn = 2 + pglob->gl_pathc + pglob->gl_offs;
+	/* reallocarray(NULL, newn, size) is equivalent to malloc(newn*size). */
+	pathv = reallocarray(pglob->gl_pathv, newn, sizeof(*pathv));
+	if (pathv == NULL)
+		return (GLOB_NOSPACE);
+
+	if (pglob->gl_pathv == NULL && pglob->gl_offs > 0) {
+		/* first time around -- clear initial gl_offs items */
+		pathv += pglob->gl_offs;
+		for (i = pglob->gl_offs + 1; --i > 0; )
+			*--pathv = NULL;
+	}
+	pglob->gl_pathv = pathv;
+
+	if (origpat != NULL)
+		copy = strdup(origpat);
+	else {
+		for (p = path; *p++ != EOS;)
+			continue;
+		len = MB_CUR_MAX * (size_t)(p - path); /* XXX overallocation */
+		if ((copy = malloc(len)) != NULL) {
+			if (g_Ctoc(path, copy, len)) {
+				free(copy);
+				errno = E2BIG;
+				return (GLOB_NOSPACE);
+			}
+		}
+	}
+	if (copy != NULL) {
+		limit->l_string_cnt += strlen(copy) + 1;
+		if ((pglob->gl_flags & GLOB_LIMIT) &&
+		    limit->l_string_cnt >= GLOB_LIMIT_STRING) {
+			free(copy);
+			errno = E2BIG;
+			return (GLOB_NOSPACE);
+		}
+		pathv[pglob->gl_offs + pglob->gl_pathc++] = copy;
+	}
+	pathv[pglob->gl_offs + pglob->gl_pathc] = NULL;
+	return (copy == NULL ? GLOB_NOSPACE : 0);
+}
+
+/*
+ * pattern matching function for filenames.
+ */
+static int
+match(Char *name, Char *pat, Char *patend)
+{
+	int ok, negate_range;
+	Char c, k, *nextp, *nextn;
+#if !defined(__BIONIC__)
+	struct xlocale_collate *table =
+		(struct xlocale_collate*)__get_locale()->components[XLC_COLLATE];
+#endif
+
+	nextn = NULL;
+	nextp = NULL;
+
+	while (1) {
+		while (pat < patend) {
+			c = *pat++;
+			switch (c & M_MASK) {
+			case M_ALL:
+				if (pat == patend)
+					return (1);
+				if (*name == EOS)
+					return (0);
+				nextn = name + 1;
+				nextp = pat - 1;
+				break;
+			case M_ONE:
+				if (*name++ == EOS)
+					goto fail;
+				break;
+			case M_SET:
+				ok = 0;
+				if ((k = *name++) == EOS)
+					goto fail;
+				negate_range = ((*pat & M_MASK) == M_NOT);
+				if (negate_range != 0)
+					++pat;
+				while (((c = *pat++) & M_MASK) != M_END)
+					if ((*pat & M_MASK) == M_RNG) {
+#if defined(__BIONIC__)
+						if (c <= k && k <= pat[1])
+#else
+						if (table->__collate_load_error ?
+						    CHAR(c) <= CHAR(k) &&
+						    CHAR(k) <= CHAR(pat[1]) :
+						    __wcollate_range_cmp(CHAR(c),
+						    CHAR(k)) <= 0 &&
+						    __wcollate_range_cmp(CHAR(k),
+						    CHAR(pat[1])) <= 0)
+#endif
+							ok = 1;
+						pat += 2;
+					} else if (c == k)
+						ok = 1;
+				if (ok == negate_range)
+					goto fail;
+				break;
+			default:
+				if (*name++ != c)
+					goto fail;
+				break;
+			}
+		}
+		if (*name == EOS)
+			return (1);
+
+	fail:
+		if (nextn == NULL)
+			break;
+		pat = nextp;
+		name = nextn;
+	}
+	return (0);
+}
+
+/* Free allocated data belonging to a glob_t structure. */
+void
+globfree(glob_t *pglob)
+{
+	size_t i;
+	char **pp;
+
+	if (pglob->gl_pathv != NULL) {
+		pp = pglob->gl_pathv + pglob->gl_offs;
+		for (i = pglob->gl_pathc; i--; ++pp)
+			if (*pp)
+				free(*pp);
+		free(pglob->gl_pathv);
+		pglob->gl_pathv = NULL;
+	}
+}
+
+static DIR *
+g_opendir(Char *str, glob_t *pglob)
+{
+	char buf[MAXPATHLEN + MB_LEN_MAX - 1];
+
+	if (*str == EOS)
+		strcpy(buf, ".");
+	else {
+		if (g_Ctoc(str, buf, sizeof(buf))) {
+			errno = ENAMETOOLONG;
+			return (NULL);
+		}
+	}
+
+	if (pglob->gl_flags & GLOB_ALTDIRFUNC)
+		return ((*pglob->gl_opendir)(buf));
+
+	return (opendir(buf));
+}
+
+static int
+g_lstat(Char *fn, struct stat *sb, glob_t *pglob)
+{
+	char buf[MAXPATHLEN + MB_LEN_MAX - 1];
+
+	if (g_Ctoc(fn, buf, sizeof(buf))) {
+		errno = ENAMETOOLONG;
+		return (-1);
+	}
+	if (pglob->gl_flags & GLOB_ALTDIRFUNC)
+		return((*pglob->gl_lstat)(buf, sb));
+	return (lstat(buf, sb));
+}
+
+static int
+g_stat(Char *fn, struct stat *sb, glob_t *pglob)
+{
+	char buf[MAXPATHLEN + MB_LEN_MAX - 1];
+
+	if (g_Ctoc(fn, buf, sizeof(buf))) {
+		errno = ENAMETOOLONG;
+		return (-1);
+	}
+	if (pglob->gl_flags & GLOB_ALTDIRFUNC)
+		return ((*pglob->gl_stat)(buf, sb));
+	return (stat(buf, sb));
+}
+
+static const Char *
+g_strchr(const Char *str, wchar_t ch)
+{
+
+	do {
+		if (*str == ch)
+			return (str);
+	} while (*str++);
+	return (NULL);
+}
+
+static int
+g_Ctoc(const Char *str, char *buf, size_t len)
+{
+	mbstate_t mbs;
+	size_t clen;
+
+	memset(&mbs, 0, sizeof(mbs));
+	while (len >= MB_CUR_MAX) {
+		clen = wcrtomb(buf, CHAR(*str), &mbs);
+		if (clen == (size_t)-1) {
+			/* XXX See initial comment #2. */
+			*buf = (char)CHAR(*str);
+			clen = 1;
+			memset(&mbs, 0, sizeof(mbs));
+		}
+		if (CHAR(*str) == EOS)
+			return (0);
+		str++;
+		buf += clen;
+		len -= clen;
+	}
+	return (1);
+}
+
+static int
+err_nomatch(glob_t *pglob, struct glob_limit *limit, const char *origpat) {
+	/*
+	 * If there was no match we are going to append the origpat
+	 * if GLOB_NOCHECK was specified or if GLOB_NOMAGIC was specified
+	 * and the origpat did not contain any magic characters
+	 * GLOB_NOMAGIC is there just for compatibility with csh.
+	 */
+	if ((pglob->gl_flags & GLOB_NOCHECK) ||
+	    ((pglob->gl_flags & GLOB_NOMAGIC) &&
+	    !(pglob->gl_flags & GLOB_MAGCHAR)))
+		return (globextend(NULL, pglob, limit, origpat));
+	return (GLOB_NOMATCH);
+}
+
+static int
+err_aborted(glob_t *pglob, int err, char *buf) {
+	if ((pglob->gl_errfunc != NULL && pglob->gl_errfunc(buf, err)) ||
+	    (pglob->gl_flags & GLOB_ERR))
+		return (GLOB_ABORTED);
+	return (0);
+}
+
+#ifdef DEBUG
+static void
+qprintf(const char *str, Char *s)
+{
+	Char *p;
+
+	(void)printf("%s\n", str);
+	if (s != NULL) {
+		for (p = s; *p != EOS; p++)
+			(void)printf("%c", (char)CHAR(*p));
+		(void)printf("\n");
+		for (p = s; *p != EOS; p++)
+			(void)printf("%c", (isprot(*p) ? '\\' : ' '));
+		(void)printf("\n");
+		for (p = s; *p != EOS; p++)
+			(void)printf("%c", (ismeta(*p) ? '_' : ' '));
+		(void)printf("\n");
+	}
+}
+#endif
diff --git a/libc/upstream-openbsd/android/include/arc4random.h b/libc/upstream-openbsd/android/include/arc4random.h
index 4c4be0e..afa8d14 100644
--- a/libc/upstream-openbsd/android/include/arc4random.h
+++ b/libc/upstream-openbsd/android/include/arc4random.h
@@ -22,10 +22,10 @@
  * Stub functions for portability.
  */
 
-#include <sys/mman.h>
-
+#include <errno.h>
 #include <pthread.h>
 #include <signal.h>
+#include <sys/mman.h>
 
 #include <async_safe/log.h>
 
diff --git a/libc/upstream-openbsd/android/include/openbsd-compat.h b/libc/upstream-openbsd/android/include/openbsd-compat.h
index d831435..f178149 100644
--- a/libc/upstream-openbsd/android/include/openbsd-compat.h
+++ b/libc/upstream-openbsd/android/include/openbsd-compat.h
@@ -18,10 +18,15 @@
 #define _BIONIC_OPENBSD_COMPAT_H_included
 
 #define _BSD_SOURCE
-
 #include <sys/cdefs.h>
+
 #include <stddef.h> // For size_t.
 
+// TODO: libandroid_support uses this file, so we need to wait for
+// <sys/random.h> to be in the NDK headers before we can lose this declaration.
+//#include <sys/random.h> // For getentropy.
+int getentropy(void*, size_t);
+
 #define __BEGIN_HIDDEN_DECLS _Pragma("GCC visibility push(hidden)")
 #define __END_HIDDEN_DECLS _Pragma("GCC visibility pop")
 
@@ -75,9 +80,6 @@
 __LIBC_HIDDEN__ extern const char* __bionic_get_shell_path();
 #define _PATH_BSHELL __bionic_get_shell_path()
 
-/* We have OpenBSD's getentropy_linux.c, but we don't mention getentropy in any header. */
-__LIBC_HIDDEN__ extern int getentropy(void*, size_t);
-
 /* OpenBSD has this as API, but we just use it internally. */
 __LIBC_HIDDEN__ void* reallocarray(void*, size_t, size_t);
 
diff --git a/libc/upstream-openbsd/lib/libc/stdio/fflush.c b/libc/upstream-openbsd/lib/libc/stdio/fflush.c
deleted file mode 100644
index fd1a4b3..0000000
--- a/libc/upstream-openbsd/lib/libc/stdio/fflush.c
+++ /dev/null
@@ -1,98 +0,0 @@
-/*	$OpenBSD: fflush.c,v 1.9 2015/08/31 02:53:57 guenther Exp $ */
-/*-
- * Copyright (c) 1990, 1993
- *	The Regents of the University of California.  All rights reserved.
- *
- * This code is derived from software contributed to Berkeley by
- * Chris Torek.
- *
- * Redistribution and use in source and binary forms, with or without
- * modification, are permitted provided that the following conditions
- * are met:
- * 1. Redistributions of source code must retain the above copyright
- *    notice, this list of conditions and the following disclaimer.
- * 2. Redistributions in binary form must reproduce the above copyright
- *    notice, this list of conditions and the following disclaimer in the
- *    documentation and/or other materials provided with the distribution.
- * 3. Neither the name of the University nor the names of its contributors
- *    may be used to endorse or promote products derived from this software
- *    without specific prior written permission.
- *
- * THIS SOFTWARE IS PROVIDED BY THE REGENTS AND CONTRIBUTORS ``AS IS'' AND
- * ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE
- * IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE
- * ARE DISCLAIMED.  IN NO EVENT SHALL THE REGENTS OR CONTRIBUTORS BE LIABLE
- * FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL
- * DAMAGES (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS
- * OR SERVICES; LOSS OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION)
- * HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT
- * LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY
- * OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF
- * SUCH DAMAGE.
- */
-
-#include <errno.h>
-#include <stdio.h>
-#include "local.h"
-
-/* Flush a single file, or (if fp is NULL) all files.  */
-int
-fflush(FILE *fp)
-{
-	int	r;
-
-	if (fp == NULL)
-		return (_fwalk(__sflush_locked));
-	FLOCKFILE(fp);
-	if ((fp->_flags & (__SWR | __SRW)) == 0) {
-		errno = EBADF;
-		r = EOF;
-	} else
-		r = __sflush(fp);
-	FUNLOCKFILE(fp);
-	return (r);
-}
-DEF_STRONG(fflush);
-
-int
-__sflush(FILE *fp)
-{
-	unsigned char *p;
-	int n, t;
-
-	t = fp->_flags;
-	if ((t & __SWR) == 0)
-		return (0);
-
-	if ((p = fp->_bf._base) == NULL)
-		return (0);
-
-	n = fp->_p - p;		/* write this much */
-
-	/*
-	 * Set these immediately to avoid problems with longjmp and to allow
-	 * exchange buffering (via setvbuf) in user write function.
-	 */
-	fp->_p = p;
-	fp->_w = t & (__SLBF|__SNBF) ? 0 : fp->_bf._size;
-
-	for (; n > 0; n -= t, p += t) {
-		t = (*fp->_write)(fp->_cookie, (char *)p, n);
-		if (t <= 0) {
-			fp->_flags |= __SERR;
-			return (EOF);
-		}
-	}
-	return (0);
-}
-
-int
-__sflush_locked(FILE *fp)
-{
-	int	r;
-
-	FLOCKFILE(fp);
-	r = __sflush(fp);
-	FUNLOCKFILE(fp);
-	return (r);
-}
diff --git a/libc/upstream-openbsd/lib/libc/stdio/fgets.c b/libc/upstream-openbsd/lib/libc/stdio/fgets.c
deleted file mode 100644
index 3cea8f7..0000000
--- a/libc/upstream-openbsd/lib/libc/stdio/fgets.c
+++ /dev/null
@@ -1,106 +0,0 @@
-/*	$OpenBSD: fgets.c,v 1.16 2016/09/21 04:38:56 guenther Exp $ */
-/*-
- * Copyright (c) 1990, 1993
- *	The Regents of the University of California.  All rights reserved.
- *
- * This code is derived from software contributed to Berkeley by
- * Chris Torek.
- *
- * Redistribution and use in source and binary forms, with or without
- * modification, are permitted provided that the following conditions
- * are met:
- * 1. Redistributions of source code must retain the above copyright
- *    notice, this list of conditions and the following disclaimer.
- * 2. Redistributions in binary form must reproduce the above copyright
- *    notice, this list of conditions and the following disclaimer in the
- *    documentation and/or other materials provided with the distribution.
- * 3. Neither the name of the University nor the names of its contributors
- *    may be used to endorse or promote products derived from this software
- *    without specific prior written permission.
- *
- * THIS SOFTWARE IS PROVIDED BY THE REGENTS AND CONTRIBUTORS ``AS IS'' AND
- * ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE
- * IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE
- * ARE DISCLAIMED.  IN NO EVENT SHALL THE REGENTS OR CONTRIBUTORS BE LIABLE
- * FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL
- * DAMAGES (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS
- * OR SERVICES; LOSS OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION)
- * HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT
- * LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY
- * OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF
- * SUCH DAMAGE.
- */
-
-#include <errno.h>
-#include <stdio.h>
-#include <string.h>
-#include "local.h"
-
-/*
- * Read at most n-1 characters from the given file.
- * Stop when a newline has been read, or the count runs out.
- * Return first argument, or NULL if no characters were read.
- * Do not return NULL if n == 1.
- */
-char *
-fgets(char *buf, int n, FILE *fp) __overloadable
-{
-	size_t len;
-	char *s;
-	unsigned char *p, *t;
-
-	if (n <= 0) {		/* sanity check */
-		errno = EINVAL;
-		return (NULL);
-	}
-
-	FLOCKFILE(fp);
-	_SET_ORIENTATION(fp, -1);
-	s = buf;
-	n--;			/* leave space for NUL */
-	while (n != 0) {
-		/*
-		 * If the buffer is empty, refill it.
-		 */
-		if (fp->_r <= 0) {
-			if (__srefill(fp)) {
-				/* EOF/error: stop with partial or no line */
-				if (s == buf) {
-					FUNLOCKFILE(fp);
-					return (NULL);
-				}
-				break;
-			}
-		}
-		len = fp->_r;
-		p = fp->_p;
-
-		/*
-		 * Scan through at most n bytes of the current buffer,
-		 * looking for '\n'.  If found, copy up to and including
-		 * newline, and stop.  Otherwise, copy entire chunk
-		 * and loop.
-		 */
-		if (len > n)
-			len = n;
-		t = memchr(p, '\n', len);
-		if (t != NULL) {
-			len = ++t - p;
-			fp->_r -= len;
-			fp->_p = t;
-			(void)memcpy(s, p, len);
-			s[len] = '\0';
-			FUNLOCKFILE(fp);
-			return (buf);
-		}
-		fp->_r -= len;
-		fp->_p += len;
-		(void)memcpy(s, p, len);
-		s += len;
-		n -= len;
-	}
-	*s = '\0';
-	FUNLOCKFILE(fp);
-	return (buf);
-}
-DEF_STRONG(fgets);
diff --git a/libc/upstream-openbsd/lib/libc/stdio/fputs.c b/libc/upstream-openbsd/lib/libc/stdio/fputs.c
deleted file mode 100644
index 05ead5c..0000000
--- a/libc/upstream-openbsd/lib/libc/stdio/fputs.c
+++ /dev/null
@@ -1,59 +0,0 @@
-/*	$OpenBSD: fputs.c,v 1.11 2015/08/31 02:53:57 guenther Exp $ */
-/*-
- * Copyright (c) 1990, 1993
- *	The Regents of the University of California.  All rights reserved.
- *
- * This code is derived from software contributed to Berkeley by
- * Chris Torek.
- *
- * Redistribution and use in source and binary forms, with or without
- * modification, are permitted provided that the following conditions
- * are met:
- * 1. Redistributions of source code must retain the above copyright
- *    notice, this list of conditions and the following disclaimer.
- * 2. Redistributions in binary form must reproduce the above copyright
- *    notice, this list of conditions and the following disclaimer in the
- *    documentation and/or other materials provided with the distribution.
- * 3. Neither the name of the University nor the names of its contributors
- *    may be used to endorse or promote products derived from this software
- *    without specific prior written permission.
- *
- * THIS SOFTWARE IS PROVIDED BY THE REGENTS AND CONTRIBUTORS ``AS IS'' AND
- * ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE
- * IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE
- * ARE DISCLAIMED.  IN NO EVENT SHALL THE REGENTS OR CONTRIBUTORS BE LIABLE
- * FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL
- * DAMAGES (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS
- * OR SERVICES; LOSS OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION)
- * HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT
- * LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY
- * OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF
- * SUCH DAMAGE.
- */
-
-#include <stdio.h>
-#include <string.h>
-#include "local.h"
-#include "fvwrite.h"
-
-/*
- * Write the given string to the given file.
- */
-int
-fputs(const char *s, FILE *fp)
-{
-	struct __suio uio;
-	struct __siov iov;
-	int ret;
-
-	iov.iov_base = (void *)s;
-	iov.iov_len = uio.uio_resid = strlen(s);
-	uio.uio_iov = &iov;
-	uio.uio_iovcnt = 1;
-	FLOCKFILE(fp);
-	_SET_ORIENTATION(fp, -1);
-	ret = __sfvwrite(fp, &uio);
-	FUNLOCKFILE(fp);
-	return (ret);
-}
-DEF_STRONG(fputs);
diff --git a/libc/upstream-openbsd/lib/libc/stdio/fvwrite.h b/libc/upstream-openbsd/lib/libc/stdio/fvwrite.h
index f04565b..d2257cc 100644
--- a/libc/upstream-openbsd/lib/libc/stdio/fvwrite.h
+++ b/libc/upstream-openbsd/lib/libc/stdio/fvwrite.h
@@ -32,20 +32,4 @@
  * SUCH DAMAGE.
  */
 
-/*
- * I/O descriptors for __sfvwrite().
- */
-struct __siov {
-	void	*iov_base;
-	size_t	iov_len;
-};
-struct __suio {
-	struct	__siov *uio_iov;
-	int	uio_iovcnt;
-	int	uio_resid;
-};
-
-__BEGIN_HIDDEN_DECLS
-extern int __sfvwrite(FILE *, struct __suio *);
-wint_t __fputwc_unlock(wchar_t wc, FILE *fp);
-__END_HIDDEN_DECLS
+/* Moved to "local.h". */
diff --git a/libc/upstream-openbsd/lib/libc/stdio/fwrite.c b/libc/upstream-openbsd/lib/libc/stdio/fwrite.c
deleted file mode 100644
index f829398..0000000
--- a/libc/upstream-openbsd/lib/libc/stdio/fwrite.c
+++ /dev/null
@@ -1,89 +0,0 @@
-/*	$OpenBSD: fwrite.c,v 1.12 2015/08/31 02:53:57 guenther Exp $ */
-/*-
- * Copyright (c) 1990, 1993
- *	The Regents of the University of California.  All rights reserved.
- *
- * This code is derived from software contributed to Berkeley by
- * Chris Torek.
- *
- * Redistribution and use in source and binary forms, with or without
- * modification, are permitted provided that the following conditions
- * are met:
- * 1. Redistributions of source code must retain the above copyright
- *    notice, this list of conditions and the following disclaimer.
- * 2. Redistributions in binary form must reproduce the above copyright
- *    notice, this list of conditions and the following disclaimer in the
- *    documentation and/or other materials provided with the distribution.
- * 3. Neither the name of the University nor the names of its contributors
- *    may be used to endorse or promote products derived from this software
- *    without specific prior written permission.
- *
- * THIS SOFTWARE IS PROVIDED BY THE REGENTS AND CONTRIBUTORS ``AS IS'' AND
- * ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE
- * IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE
- * ARE DISCLAIMED.  IN NO EVENT SHALL THE REGENTS OR CONTRIBUTORS BE LIABLE
- * FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL
- * DAMAGES (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS
- * OR SERVICES; LOSS OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION)
- * HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT
- * LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY
- * OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF
- * SUCH DAMAGE.
- */
-
-#include <stdio.h>
-#include <stdlib.h>
-#include <stdint.h>
-#include <errno.h>
-#include "local.h"
-#include "fvwrite.h"
-
-#define MUL_NO_OVERFLOW	(1UL << (sizeof(size_t) * 4))
-
-/*
- * Write `count' objects (each size `size') from memory to the given file.
- * Return the number of whole objects written.
- */
-size_t
-fwrite(const void *buf, size_t size, size_t count, FILE *fp) __overloadable
-{
-	size_t n;
-	struct __suio uio;
-	struct __siov iov;
-	int ret;
-
-	/*
-	 * Extension:  Catch integer overflow
-	 */
-	if ((size >= MUL_NO_OVERFLOW || count >= MUL_NO_OVERFLOW) &&
-	    size > 0 && SIZE_MAX / size < count) {
-		errno = EOVERFLOW;
-		fp->_flags |= __SERR;
-		return (0);
-	}
-
-	/*
-	 * ANSI and SUSv2 require a return value of 0 if size or count are 0.
-	 */
-	if ((n = count * size) == 0)
-		return (0);
-
-	iov.iov_base = (void *)buf;
-	uio.uio_resid = iov.iov_len = n;
-	uio.uio_iov = &iov;
-	uio.uio_iovcnt = 1;
-
-	/*
-	 * The usual case is success (__sfvwrite returns 0);
-	 * skip the divide if this happens, since divides are
-	 * generally slow and since this occurs whenever size==0.
-	 */
-	FLOCKFILE(fp);
-	_SET_ORIENTATION(fp, -1);
-	ret = __sfvwrite(fp, &uio);
-	FUNLOCKFILE(fp);
-	if (ret == 0)
-		return (count);
-	return ((n - uio.uio_resid) / size);
-}
-DEF_STRONG(fwrite);
diff --git a/libc/upstream-openbsd/lib/libc/stdio/perror.c b/libc/upstream-openbsd/lib/libc/stdio/perror.c
deleted file mode 100644
index fdd6120..0000000
--- a/libc/upstream-openbsd/lib/libc/stdio/perror.c
+++ /dev/null
@@ -1,63 +0,0 @@
-/*	$OpenBSD: perror.c,v 1.9 2015/08/31 02:53:57 guenther Exp $ */
-/*
- * Copyright (c) 1988, 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/types.h>
-#include <sys/uio.h>
-#include <unistd.h>
-#include <errno.h>
-#include <stdio.h>
-#include <string.h>
-#include <limits.h>
-
-void
-perror(const char *s)
-{
-	struct iovec *v;
-	struct iovec iov[4];
-	char buf[NL_TEXTMAX];
-
-	v = iov;
-	if (s && *s) {
-		v->iov_base = (char *)s;
-		v->iov_len = strlen(s);
-		v++;
-		v->iov_base = ": ";
-		v->iov_len = 2;
-		v++;
-	}
-	(void)strerror_r(errno, buf, sizeof(buf));
-	v->iov_base = buf;
-	v->iov_len = strlen(v->iov_base);
-	v++;
-	v->iov_base = "\n";
-	v->iov_len = 1;
-	(void)writev(STDERR_FILENO, iov, (v - iov) + 1);
-}
-DEF_STRONG(perror);
diff --git a/libc/upstream-openbsd/lib/libc/stdio/puts.c b/libc/upstream-openbsd/lib/libc/stdio/puts.c
deleted file mode 100644
index 57d4b78..0000000
--- a/libc/upstream-openbsd/lib/libc/stdio/puts.c
+++ /dev/null
@@ -1,63 +0,0 @@
-/*	$OpenBSD: puts.c,v 1.12 2015/08/31 02:53:57 guenther Exp $ */
-/*-
- * Copyright (c) 1990, 1993
- *	The Regents of the University of California.  All rights reserved.
- *
- * This code is derived from software contributed to Berkeley by
- * Chris Torek.
- *
- * Redistribution and use in source and binary forms, with or without
- * modification, are permitted provided that the following conditions
- * are met:
- * 1. Redistributions of source code must retain the above copyright
- *    notice, this list of conditions and the following disclaimer.
- * 2. Redistributions in binary form must reproduce the above copyright
- *    notice, this list of conditions and the following disclaimer in the
- *    documentation and/or other materials provided with the distribution.
- * 3. Neither the name of the University nor the names of its contributors
- *    may be used to endorse or promote products derived from this software
- *    without specific prior written permission.
- *
- * THIS SOFTWARE IS PROVIDED BY THE REGENTS AND CONTRIBUTORS ``AS IS'' AND
- * ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE
- * IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE
- * ARE DISCLAIMED.  IN NO EVENT SHALL THE REGENTS OR CONTRIBUTORS BE LIABLE
- * FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL
- * DAMAGES (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS
- * OR SERVICES; LOSS OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION)
- * HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT
- * LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY
- * OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF
- * SUCH DAMAGE.
- */
-
-#include <stdio.h>
-#include <string.h>
-#include "local.h"
-#include "fvwrite.h"
-
-/*
- * Write the given string to stdout, appending a newline.
- */
-int
-puts(const char *s)
-{
-	size_t c = strlen(s);
-	struct __suio uio;
-	struct __siov iov[2];
-	int ret;
-
-	iov[0].iov_base = (void *)s;
-	iov[0].iov_len = c;
-	iov[1].iov_base = "\n";
-	iov[1].iov_len = 1;
-	uio.uio_resid = c + 1;
-	uio.uio_iov = &iov[0];
-	uio.uio_iovcnt = 2;
-	FLOCKFILE(stdout);
-	_SET_ORIENTATION(stdout, -1);
-	ret = __sfvwrite(stdout, &uio);
-	FUNLOCKFILE(stdout);
-	return (ret ? EOF : '\n');
-}
-DEF_STRONG(puts);
diff --git a/libc/upstream-openbsd/lib/libc/stdio/vfprintf.c b/libc/upstream-openbsd/lib/libc/stdio/vfprintf.c
deleted file mode 100644
index 3d7d41e..0000000
--- a/libc/upstream-openbsd/lib/libc/stdio/vfprintf.c
+++ /dev/null
@@ -1,1561 +0,0 @@
-/*	$OpenBSD: vfprintf.c,v 1.71 2016/01/04 15:47:47 schwarze Exp $	*/
-/*-
- * Copyright (c) 1990 The Regents of the University of California.
- * All rights reserved.
- *
- * This code is derived from software contributed to Berkeley by
- * Chris Torek.
- *
- * Redistribution and use in source and binary forms, with or without
- * modification, are permitted provided that the following conditions
- * are met:
- * 1. Redistributions of source code must retain the above copyright
- *    notice, this list of conditions and the following disclaimer.
- * 2. Redistributions in binary form must reproduce the above copyright
- *    notice, this list of conditions and the following disclaimer in the
- *    documentation and/or other materials provided with the distribution.
- * 3. Neither the name of the University nor the names of its contributors
- *    may be used to endorse or promote products derived from this software
- *    without specific prior written permission.
- *
- * THIS SOFTWARE IS PROVIDED BY THE REGENTS AND CONTRIBUTORS ``AS IS'' AND
- * ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE
- * IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE
- * ARE DISCLAIMED.  IN NO EVENT SHALL THE REGENTS OR CONTRIBUTORS BE LIABLE
- * FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL
- * DAMAGES (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS
- * OR SERVICES; LOSS OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION)
- * HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT
- * LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY
- * OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF
- * SUCH DAMAGE.
- */
-
-/*
- * Actual printf innards.
- *
- * This code is large and complicated...
- */
-
-#include <sys/types.h>
-#include <sys/mman.h>
-
-#include <errno.h>
-#include <langinfo.h>
-#include <limits.h>
-#include <stdarg.h>
-#include <stddef.h>
-#include <stdio.h>
-#include <stdint.h>
-#include <stdlib.h>
-#include <string.h>
-#include <unistd.h>
-#include <wchar.h>
-
-#include "local.h"
-#include "fvwrite.h"
-
-union arg {
-	int			intarg;
-	unsigned int		uintarg;
-	long			longarg;
-	unsigned long		ulongarg;
-	long long		longlongarg;
-	unsigned long long	ulonglongarg;
-	ptrdiff_t		ptrdiffarg;
-	size_t			sizearg;
-	ssize_t			ssizearg;
-	intmax_t		intmaxarg;
-	uintmax_t		uintmaxarg;
-	void			*pvoidarg;
-	char			*pchararg;
-	signed char		*pschararg;
-	short			*pshortarg;
-	int			*pintarg;
-	long			*plongarg;
-	long long		*plonglongarg;
-	ptrdiff_t		*pptrdiffarg;
-	ssize_t			*pssizearg;
-	intmax_t		*pintmaxarg;
-#ifdef FLOATING_POINT
-	double			doublearg;
-	long double		longdoublearg;
-#endif
-#ifdef PRINTF_WIDE_CHAR
-	wint_t			wintarg;
-	wchar_t			*pwchararg;
-#endif
-};
-
-static int __find_arguments(const char *fmt0, va_list ap, union arg **argtable,
-    size_t *argtablesiz);
-static int __grow_type_table(unsigned char **typetable, int *tablesize);
-
-/*
- * Flush out all the vectors defined by the given uio,
- * then reset it so that it can be reused.
- */
-static int
-__sprint(FILE *fp, struct __suio *uio)
-{
-	int err;
-
-	if (uio->uio_resid == 0) {
-		uio->uio_iovcnt = 0;
-		return (0);
-	}
-	err = __sfvwrite(fp, uio);
-	uio->uio_resid = 0;
-	uio->uio_iovcnt = 0;
-	return (err);
-}
-
-/*
- * Helper function for `fprintf to unbuffered unix file': creates a
- * temporary buffer.  We only work on write-only files; this avoids
- * worries about ungetc buffers and so forth.
- */
-static int
-__sbprintf(FILE *fp, const char *fmt, va_list ap)
-{
-	int ret;
-	FILE fake;
-	struct __sfileext fakeext;
-	unsigned char buf[BUFSIZ];
-
-	_FILEEXT_SETUP(&fake, &fakeext);
-	/* copy the important variables */
-	fake._flags = fp->_flags & ~__SNBF;
-	fake._file = fp->_file;
-	fake._cookie = fp->_cookie;
-	fake._write = fp->_write;
-
-	/* set up the buffer */
-	fake._bf._base = fake._p = buf;
-	fake._bf._size = fake._w = sizeof(buf);
-	fake._lbfsize = 0;	/* not actually used, but Just In Case */
-
-	/* do the work, then copy any error status */
-	ret = __vfprintf(&fake, fmt, ap);
-	if (ret >= 0 && __sflush(&fake))
-		ret = EOF;
-	if (fake._flags & __SERR)
-		fp->_flags |= __SERR;
-	return (ret);
-}
-
-#ifdef PRINTF_WIDE_CHAR
-/*
- * Convert a wide character string argument for the %ls format to a multibyte
- * string representation. If not -1, prec specifies the maximum number of
- * bytes to output, and also means that we can't assume that the wide char
- * string is null-terminated.
- */
-static char *
-__wcsconv(wchar_t *wcsarg, int prec)
-{
-	mbstate_t mbs;
-	char buf[MB_LEN_MAX];
-	wchar_t *p;
-	char *convbuf;
-	size_t clen, nbytes;
-
-	/* Allocate space for the maximum number of bytes we could output. */
-	if (prec < 0) {
-		memset(&mbs, 0, sizeof(mbs));
-		p = wcsarg;
-		nbytes = wcsrtombs(NULL, (const wchar_t **)&p, 0, &mbs);
-		if (nbytes == (size_t)-1)
-			return (NULL);
-	} else {
-		/*
-		 * Optimisation: if the output precision is small enough,
-		 * just allocate enough memory for the maximum instead of
-		 * scanning the string.
-		 */
-		if (prec < 128)
-			nbytes = prec;
-		else {
-			nbytes = 0;
-			p = wcsarg;
-			memset(&mbs, 0, sizeof(mbs));
-			for (;;) {
-				clen = wcrtomb(buf, *p++, &mbs);
-				if (clen == 0 || clen == (size_t)-1 ||
-				    nbytes + clen > (size_t)prec)
-					break;
-				nbytes += clen;
-			}
-			if (clen == (size_t)-1)
-				return (NULL);
-		}
-	}
-	if ((convbuf = malloc(nbytes + 1)) == NULL)
-		return (NULL);
-
-	/* Fill the output buffer. */
-	p = wcsarg;
-	memset(&mbs, 0, sizeof(mbs));
-	if ((nbytes = wcsrtombs(convbuf, (const wchar_t **)&p,
-	    nbytes, &mbs)) == (size_t)-1) {
-		free(convbuf);
-		return (NULL);
-	}
-	convbuf[nbytes] = '\0';
-	return (convbuf);
-}
-#endif
-
-#ifdef FLOATING_POINT
-#include <float.h>
-#include <locale.h>
-#include <math.h>
-#include "floatio.h"
-#include "gdtoa.h"
-
-#define	DEFPREC		6
-
-static int exponent(char *, int, int);
-#endif /* FLOATING_POINT */
-
-/*
- * The size of the buffer we use as scratch space for integer
- * conversions, among other things.  Technically, we would need the
- * most space for base 10 conversions with thousands' grouping
- * characters between each pair of digits.  100 bytes is a
- * conservative overestimate even for a 128-bit uintmax_t.
- */
-#define BUF	100
-
-#define STATIC_ARG_TBL_SIZE 8	/* Size of static argument table. */
-
-
-/*
- * Macros for converting digits to letters and vice versa
- */
-#define	to_digit(c)	((c) - '0')
-#define is_digit(c)	((unsigned)to_digit(c) <= 9)
-#define	to_char(n)	((n) + '0')
-
-/*
- * Flags used during conversion.
- */
-#define	ALT		0x0001		/* alternate form */
-#define	LADJUST		0x0004		/* left adjustment */
-#define	LONGDBL		0x0008		/* long double */
-#define	LONGINT		0x0010		/* long integer */
-#define	LLONGINT	0x0020		/* long long integer */
-#define	SHORTINT	0x0040		/* short integer */
-#define	ZEROPAD		0x0080		/* zero (as opposed to blank) pad */
-#define FPT		0x0100		/* Floating point number */
-#define PTRINT		0x0200		/* (unsigned) ptrdiff_t */
-#define SIZEINT		0x0400		/* (signed) size_t */
-#define CHARINT		0x0800		/* 8 bit integer */
-#define MAXINT		0x1000		/* largest integer size (intmax_t) */
-
-int
-vfprintf(FILE *fp, const char *fmt0, __va_list ap)
-{
-	int ret;
-
-	FLOCKFILE(fp);
-	ret = __vfprintf(fp, fmt0, ap);
-	FUNLOCKFILE(fp);
-	return (ret);
-}
-DEF_STRONG(vfprintf);
-
-int
-__vfprintf(FILE *fp, const char *fmt0, __va_list ap)
-{
-	char *fmt;		/* format string */
-	int ch;			/* character from fmt */
-	int n, n2;		/* handy integers (short term usage) */
-	char *cp;		/* handy char pointer (short term usage) */
-	struct __siov *iovp;	/* for PRINT macro */
-	int flags;		/* flags as above */
-	int ret;		/* return value accumulator */
-	int width;		/* width from format (%8d), or 0 */
-	int prec;		/* precision from format; <0 for N/A */
-	char sign;		/* sign prefix (' ', '+', '-', or \0) */
-	wchar_t wc;
-	mbstate_t ps;
-#ifdef FLOATING_POINT
-	/*
-	 * We can decompose the printed representation of floating
-	 * point numbers into several parts, some of which may be empty:
-	 *
-	 * [+|-| ] [0x|0X] MMM . NNN [e|E|p|P] [+|-] ZZ
-	 *    A       B     ---C---      D       E   F
-	 *
-	 * A:	'sign' holds this value if present; '\0' otherwise
-	 * B:	ox[1] holds the 'x' or 'X'; '\0' if not hexadecimal
-	 * C:	cp points to the string MMMNNN.  Leading and trailing
-	 *	zeros are not in the string and must be added.
-	 * D:	expchar holds this character; '\0' if no exponent, e.g. %f
-	 * F:	at least two digits for decimal, at least one digit for hex
-	 */
-	char *decimal_point = NULL;
-	int signflag;		/* true if float is negative */
-	union {			/* floating point arguments %[aAeEfFgG] */
-		double dbl;
-		long double ldbl;
-	} fparg;
-	int expt;		/* integer value of exponent */
-	char expchar;		/* exponent character: [eEpP\0] */
-	char *dtoaend;		/* pointer to end of converted digits */
-	int expsize;		/* character count for expstr */
-	int lead;		/* sig figs before decimal or group sep */
-	int ndig;		/* actual number of digits returned by dtoa */
-	char expstr[MAXEXPDIG+2];	/* buffer for exponent string: e+ZZZ */
-	char *dtoaresult = NULL;
-#endif
-
-	uintmax_t _umax;	/* integer arguments %[diouxX] */
-	enum { OCT, DEC, HEX } base;	/* base for %[diouxX] conversion */
-	int dprec;		/* a copy of prec if %[diouxX], 0 otherwise */
-	int realsz;		/* field size expanded by dprec */
-	int size;		/* size of converted field or string */
-	const char *xdigs;	/* digits for %[xX] conversion */
-#define NIOV 8
-	struct __suio uio;	/* output information: summary */
-	struct __siov iov[NIOV];/* ... and individual io vectors */
-	char buf[BUF];		/* buffer with space for digits of uintmax_t */
-	char ox[2];		/* space for 0x; ox[1] is either x, X, or \0 */
-	union arg *argtable;	/* args, built due to positional arg */
-	union arg statargtable[STATIC_ARG_TBL_SIZE];
-	size_t argtablesiz;
-	int nextarg;		/* 1-based argument index */
-	va_list orgap;		/* original argument pointer */
-#ifdef PRINTF_WIDE_CHAR
-	char *convbuf;		/* buffer for wide to multi-byte conversion */
-#endif
-
-	/*
-	 * Choose PADSIZE to trade efficiency vs. size.  If larger printf
-	 * fields occur frequently, increase PADSIZE and make the initialisers
-	 * below longer.
-	 */
-#define	PADSIZE	16		/* pad chunk size */
-	static char blanks[PADSIZE] =
-	 {' ',' ',' ',' ',' ',' ',' ',' ',' ',' ',' ',' ',' ',' ',' ',' '};
-	static char zeroes[PADSIZE] =
-	 {'0','0','0','0','0','0','0','0','0','0','0','0','0','0','0','0'};
-
-	static const char xdigs_lower[16] = "0123456789abcdef";
-	static const char xdigs_upper[16] = "0123456789ABCDEF";
-
-	/*
-	 * BEWARE, these `goto error' on error, and PAD uses `n'.
-	 */
-#define	PRINT(ptr, len) do { \
-	iovp->iov_base = (ptr); \
-	iovp->iov_len = (len); \
-	uio.uio_resid += (len); \
-	iovp++; \
-	if (++uio.uio_iovcnt >= NIOV) { \
-		if (__sprint(fp, &uio)) \
-			goto error; \
-		iovp = iov; \
-	} \
-} while (0)
-#define	PAD(howmany, with) do { \
-	if ((n = (howmany)) > 0) { \
-		while (n > PADSIZE) { \
-			PRINT(with, PADSIZE); \
-			n -= PADSIZE; \
-		} \
-		PRINT(with, n); \
-	} \
-} while (0)
-#define	PRINTANDPAD(p, ep, len, with) do {	\
-	n2 = (ep) - (p);       			\
-	if (n2 > (len))				\
-		n2 = (len);			\
-	if (n2 > 0)				\
-		PRINT((p), n2);			\
-	PAD((len) - (n2 > 0 ? n2 : 0), (with));	\
-} while(0)
-#define	FLUSH() do { \
-	if (uio.uio_resid && __sprint(fp, &uio)) \
-		goto error; \
-	uio.uio_iovcnt = 0; \
-	iovp = iov; \
-} while (0)
-
-	/*
-	 * To extend shorts properly, we need both signed and unsigned
-	 * argument extraction methods.
-	 */
-#define	SARG() \
-	((intmax_t)(flags&MAXINT ? GETARG(intmax_t) : \
-	    flags&LLONGINT ? GETARG(long long) : \
-	    flags&LONGINT ? GETARG(long) : \
-	    flags&PTRINT ? GETARG(ptrdiff_t) : \
-	    flags&SIZEINT ? GETARG(ssize_t) : \
-	    flags&SHORTINT ? (short)GETARG(int) : \
-	    flags&CHARINT ? (signed char)GETARG(int) : \
-	    GETARG(int)))
-#define	UARG() \
-	((uintmax_t)(flags&MAXINT ? GETARG(uintmax_t) : \
-	    flags&LLONGINT ? GETARG(unsigned long long) : \
-	    flags&LONGINT ? GETARG(unsigned long) : \
-	    flags&PTRINT ? (uintptr_t)GETARG(ptrdiff_t) : /* XXX */ \
-	    flags&SIZEINT ? GETARG(size_t) : \
-	    flags&SHORTINT ? (unsigned short)GETARG(int) : \
-	    flags&CHARINT ? (unsigned char)GETARG(int) : \
-	    GETARG(unsigned int)))
-
-	/*
-	 * Append a digit to a value and check for overflow.
-	 */
-#define APPEND_DIGIT(val, dig) do { \
-	if ((val) > INT_MAX / 10) \
-		goto overflow; \
-	(val) *= 10; \
-	if ((val) > INT_MAX - to_digit((dig))) \
-		goto overflow; \
-	(val) += to_digit((dig)); \
-} while (0)
-
-	 /*
-	  * Get * arguments, including the form *nn$.  Preserve the nextarg
-	  * that the argument can be gotten once the type is determined.
-	  */
-#define GETASTER(val) \
-	n2 = 0; \
-	cp = fmt; \
-	while (is_digit(*cp)) { \
-		APPEND_DIGIT(n2, *cp); \
-		cp++; \
-	} \
-	if (*cp == '$') { \
-		int hold = nextarg; \
-		if (argtable == NULL) { \
-			argtable = statargtable; \
-			if (__find_arguments(fmt0, orgap, &argtable, \
-			    &argtablesiz) == -1) { \
-				ret = -1; \
-				goto error; \
-			} \
-		} \
-		nextarg = n2; \
-		val = GETARG(int); \
-		nextarg = hold; \
-		fmt = ++cp; \
-	} else { \
-		val = GETARG(int); \
-	}
-
-/*
-* Get the argument indexed by nextarg.   If the argument table is
-* built, use it to get the argument.  If its not, get the next
-* argument (and arguments must be gotten sequentially).
-*/
-#define GETARG(type) \
-	((argtable != NULL) ? *((type*)(&argtable[nextarg++])) : \
-		(nextarg++, va_arg(ap, type)))
-
-	_SET_ORIENTATION(fp, -1);
-	/* sorry, fprintf(read_only_file, "") returns EOF, not 0 */
-	if (cantwrite(fp)) {
-		errno = EBADF;
-		return (EOF);
-	}
-
-	/* optimise fprintf(stderr) (and other unbuffered Unix files) */
-	if ((fp->_flags & (__SNBF|__SWR|__SRW)) == (__SNBF|__SWR) &&
-	    fp->_file >= 0)
-		return (__sbprintf(fp, fmt0, ap));
-
-	fmt = (char *)fmt0;
-	argtable = NULL;
-	nextarg = 1;
-	va_copy(orgap, ap);
-	uio.uio_iov = iovp = iov;
-	uio.uio_resid = 0;
-	uio.uio_iovcnt = 0;
-	ret = 0;
-#ifdef PRINTF_WIDE_CHAR
-	convbuf = NULL;
-#endif
-
-	memset(&ps, 0, sizeof(ps));
-	/*
-	 * Scan the format for conversions (`%' character).
-	 */
-	for (;;) {
-		cp = fmt;
-		while ((n = mbrtowc(&wc, fmt, MB_CUR_MAX, &ps)) > 0) {
-			fmt += n;
-			if (wc == '%') {
-				fmt--;
-				break;
-			}
-		}
-		if (n < 0) {
-			ret = -1;
-			goto error;
-		}
-		if (fmt != cp) {
-			ptrdiff_t m = fmt - cp;
-			if (m < 0 || m > INT_MAX - ret)
-				goto overflow;
-			PRINT(cp, m);
-			ret += m;
-		}
-		if (n == 0)
-			goto done;
-		fmt++;		/* skip over '%' */
-
-		flags = 0;
-		dprec = 0;
-		width = 0;
-		prec = -1;
-		sign = '\0';
-		ox[1] = '\0';
-
-rflag:		ch = *fmt++;
-reswitch:	switch (ch) {
-		case ' ':
-			/*
-			 * ``If the space and + flags both appear, the space
-			 * flag will be ignored.''
-			 *	-- ANSI X3J11
-			 */
-			if (!sign)
-				sign = ' ';
-			goto rflag;
-		case '#':
-			flags |= ALT;
-			goto rflag;
-		case '\'':
-			/* grouping not implemented */
-			goto rflag;
-		case '*':
-			/*
-			 * ``A negative field width argument is taken as a
-			 * - flag followed by a positive field width.''
-			 *	-- ANSI X3J11
-			 * They don't exclude field widths read from args.
-			 */
-			GETASTER(width);
-			if (width >= 0)
-				goto rflag;
-			if (width == INT_MIN)
-				goto overflow;
-			width = -width;
-			/* FALLTHROUGH */
-		case '-':
-			flags |= LADJUST;
-			goto rflag;
-		case '+':
-			sign = '+';
-			goto rflag;
-		case '.':
-			if ((ch = *fmt++) == '*') {
-				GETASTER(n);
-				prec = n < 0 ? -1 : n;
-				goto rflag;
-			}
-			n = 0;
-			while (is_digit(ch)) {
-				APPEND_DIGIT(n, ch);
-				ch = *fmt++;
-			}
-			if (ch == '$') {
-				nextarg = n;
-				if (argtable == NULL) {
-					argtable = statargtable;
-					if (__find_arguments(fmt0, orgap,
-					    &argtable, &argtablesiz) == -1) {
-						ret = -1;
-						goto error;
-					}
-				}
-				goto rflag;
-			}
-			prec = n;
-			goto reswitch;
-		case '0':
-			/*
-			 * ``Note that 0 is taken as a flag, not as the
-			 * beginning of a field width.''
-			 *	-- ANSI X3J11
-			 */
-			flags |= ZEROPAD;
-			goto rflag;
-		case '1': case '2': case '3': case '4':
-		case '5': case '6': case '7': case '8': case '9':
-			n = 0;
-			do {
-				APPEND_DIGIT(n, ch);
-				ch = *fmt++;
-			} while (is_digit(ch));
-			if (ch == '$') {
-				nextarg = n;
-				if (argtable == NULL) {
-					argtable = statargtable;
-					if (__find_arguments(fmt0, orgap,
-					    &argtable, &argtablesiz) == -1) {
-						ret = -1;
-						goto error;
-					}
-				}
-				goto rflag;
-			}
-			width = n;
-			goto reswitch;
-#ifdef FLOATING_POINT
-		case 'L':
-			flags |= LONGDBL;
-			goto rflag;
-#endif
-		case 'h':
-			if (*fmt == 'h') {
-				fmt++;
-				flags |= CHARINT;
-			} else {
-				flags |= SHORTINT;
-			}
-			goto rflag;
-		case 'j':
-			flags |= MAXINT;
-			goto rflag;
-		case 'l':
-			if (*fmt == 'l') {
-				fmt++;
-				flags |= LLONGINT;
-			} else {
-				flags |= LONGINT;
-			}
-			goto rflag;
-		case 'q':
-			flags |= LLONGINT;
-			goto rflag;
-		case 't':
-			flags |= PTRINT;
-			goto rflag;
-		case 'z':
-			flags |= SIZEINT;
-			goto rflag;
-		case 'c':
-#ifdef PRINTF_WIDE_CHAR
-			if (flags & LONGINT) {
-				mbstate_t mbs;
-				size_t mbseqlen;
-
-				memset(&mbs, 0, sizeof(mbs));
-				mbseqlen = wcrtomb(buf,
-				    (wchar_t)GETARG(wint_t), &mbs);
-				if (mbseqlen == (size_t)-1) {
-					ret = -1;
-					goto error;
-				}
-				cp = buf;
-				size = (int)mbseqlen;
-			} else {
-#endif
-				*(cp = buf) = GETARG(int);
-				size = 1;
-#ifdef PRINTF_WIDE_CHAR
-			}
-#endif
-			sign = '\0';
-			break;
-		case 'D':
-			flags |= LONGINT;
-			/*FALLTHROUGH*/
-		case 'd':
-		case 'i':
-			_umax = SARG();
-			if ((intmax_t)_umax < 0) {
-				_umax = -_umax;
-				sign = '-';
-			}
-			base = DEC;
-			goto number;
-#ifdef FLOATING_POINT
-		case 'a':
-		case 'A':
-			if (ch == 'a') {
-				ox[1] = 'x';
-				xdigs = xdigs_lower;
-				expchar = 'p';
-			} else {
-				ox[1] = 'X';
-				xdigs = xdigs_upper;
-				expchar = 'P';
-			}
-			if (prec >= 0)
-				prec++;
-			if (dtoaresult)
-				__freedtoa(dtoaresult);
-			if (flags & LONGDBL) {
-				fparg.ldbl = GETARG(long double);
-				dtoaresult = cp =
-				    __hldtoa(fparg.ldbl, xdigs, prec,
-				    &expt, &signflag, &dtoaend);
-				if (dtoaresult == NULL) {
-					errno = ENOMEM;
-					goto error;
-				}
-			} else {
-				fparg.dbl = GETARG(double);
-				dtoaresult = cp =
-				    __hdtoa(fparg.dbl, xdigs, prec,
-				    &expt, &signflag, &dtoaend);
-				if (dtoaresult == NULL) {
-					errno = ENOMEM;
-					goto error;
-				}
-			}
-			if (prec < 0)
-				prec = dtoaend - cp;
-			if (expt == INT_MAX)
-				ox[1] = '\0';
-			goto fp_common;
-		case 'e':
-		case 'E':
-			expchar = ch;
-			if (prec < 0)	/* account for digit before decpt */
-				prec = DEFPREC + 1;
-			else
-				prec++;
-			goto fp_begin;
-		case 'f':
-		case 'F':
-			expchar = '\0';
-			goto fp_begin;
-		case 'g':
-		case 'G':
-			expchar = ch - ('g' - 'e');
- 			if (prec == 0)
- 				prec = 1;
-fp_begin:
-			if (prec < 0)
-				prec = DEFPREC;
-			if (dtoaresult)
-				__freedtoa(dtoaresult);
-			if (flags & LONGDBL) {
-				fparg.ldbl = GETARG(long double);
-				dtoaresult = cp =
-				    __ldtoa(&fparg.ldbl, expchar ? 2 : 3, prec,
-				    &expt, &signflag, &dtoaend);
-				if (dtoaresult == NULL) {
-					errno = ENOMEM;
-					goto error;
-				}
-			} else {
-				fparg.dbl = GETARG(double);
-				dtoaresult = cp =
-				    __dtoa(fparg.dbl, expchar ? 2 : 3, prec,
-				    &expt, &signflag, &dtoaend);
-				if (dtoaresult == NULL) {
-					errno = ENOMEM;
-					goto error;
-				}
-				if (expt == 9999)
-					expt = INT_MAX;
- 			}
-fp_common:
-			if (signflag)
-				sign = '-';
-			if (expt == INT_MAX) {	/* inf or nan */
-				if (*cp == 'N')
-					cp = (ch >= 'a') ? "nan" : "NAN";
-				else
-					cp = (ch >= 'a') ? "inf" : "INF";
- 				size = 3;
-				flags &= ~ZEROPAD;
- 				break;
- 			}
-			flags |= FPT;
-			ndig = dtoaend - cp;
- 			if (ch == 'g' || ch == 'G') {
-				if (expt > -4 && expt <= prec) {
-					/* Make %[gG] smell like %[fF] */
-					expchar = '\0';
-					if (flags & ALT)
-						prec -= expt;
-					else
-						prec = ndig - expt;
-					if (prec < 0)
-						prec = 0;
-				} else {
-					/*
-					 * Make %[gG] smell like %[eE], but
-					 * trim trailing zeroes if no # flag.
-					 */
-					if (!(flags & ALT))
-						prec = ndig;
-				}
- 			}
-			if (expchar) {
-				expsize = exponent(expstr, expt - 1, expchar);
-				size = expsize + prec;
-				if (prec > 1 || flags & ALT)
- 					++size;
-			} else {
-				/* space for digits before decimal point */
-				if (expt > 0)
-					size = expt;
-				else	/* "0" */
-					size = 1;
-				/* space for decimal pt and following digits */
-				if (prec || flags & ALT)
-					size += prec + 1;
-				lead = expt;
-			}
-			break;
-#endif /* FLOATING_POINT */
-#ifndef NO_PRINTF_PERCENT_N
-		case 'n':
-			if (flags & LLONGINT)
-				*GETARG(long long *) = ret;
-			else if (flags & LONGINT)
-				*GETARG(long *) = ret;
-			else if (flags & SHORTINT)
-				*GETARG(short *) = ret;
-			else if (flags & CHARINT)
-				*GETARG(signed char *) = ret;
-			else if (flags & PTRINT)
-				*GETARG(ptrdiff_t *) = ret;
-			else if (flags & SIZEINT)
-				*GETARG(ssize_t *) = ret;
-			else if (flags & MAXINT)
-				*GETARG(intmax_t *) = ret;
-			else
-				*GETARG(int *) = ret;
-			continue;	/* no output */
-#endif /* NO_PRINTF_PERCENT_N */
-		case 'O':
-			flags |= LONGINT;
-			/*FALLTHROUGH*/
-		case 'o':
-			_umax = UARG();
-			base = OCT;
-			goto nosign;
-		case 'p':
-			/*
-			 * ``The argument shall be a pointer to void.  The
-			 * value of the pointer is converted to a sequence
-			 * of printable characters, in an implementation-
-			 * defined manner.''
-			 *	-- ANSI X3J11
-			 */
-			_umax = (u_long)GETARG(void *);
-			base = HEX;
-			xdigs = xdigs_lower;
-			ox[1] = 'x';
-			goto nosign;
-		case 's':
-#ifdef PRINTF_WIDE_CHAR
-			if (flags & LONGINT) {
-				wchar_t *wcp;
-
-				free(convbuf);
-				convbuf = NULL;
-				if ((wcp = GETARG(wchar_t *)) == NULL) {
-					cp = "(null)";
-				} else {
-					convbuf = __wcsconv(wcp, prec);
-					if (convbuf == NULL) {
-						ret = -1;
-						goto error;
-					}
-					cp = convbuf;
-				}
-			} else
-#endif /* PRINTF_WIDE_CHAR */
-			if ((cp = GETARG(char *)) == NULL)
-				cp = "(null)";
-			if (prec >= 0) {
-				/*
-				 * can't use strlen; can only look for the
-				 * NUL in the first `prec' characters, and
-				 * strlen() will go further.
-				 */
-				char *p = memchr(cp, 0, prec);
-
-				size = p ? (p - cp) : prec;
-			} else {
-				size_t len;
-
-				if ((len = strlen(cp)) > INT_MAX)
-					goto overflow;
-				size = (int)len;
-			}
-			sign = '\0';
-			break;
-		case 'U':
-			flags |= LONGINT;
-			/*FALLTHROUGH*/
-		case 'u':
-			_umax = UARG();
-			base = DEC;
-			goto nosign;
-		case 'X':
-			xdigs = xdigs_upper;
-			goto hex;
-		case 'x':
-			xdigs = xdigs_lower;
-hex:			_umax = UARG();
-			base = HEX;
-			/* leading 0x/X only if non-zero */
-			if (flags & ALT && _umax != 0)
-				ox[1] = ch;
-
-			/* unsigned conversions */
-nosign:			sign = '\0';
-			/*
-			 * ``... diouXx conversions ... if a precision is
-			 * specified, the 0 flag will be ignored.''
-			 *	-- ANSI X3J11
-			 */
-number:			if ((dprec = prec) >= 0)
-				flags &= ~ZEROPAD;
-
-			/*
-			 * ``The result of converting a zero value with an
-			 * explicit precision of zero is no characters.''
-			 *	-- ANSI X3J11
-			 */
-			cp = buf + BUF;
-			if (_umax != 0 || prec != 0) {
-				/*
-				 * Unsigned mod is hard, and unsigned mod
-				 * by a constant is easier than that by
-				 * a variable; hence this switch.
-				 */
-				switch (base) {
-				case OCT:
-					do {
-						*--cp = to_char(_umax & 7);
-						_umax >>= 3;
-					} while (_umax);
-					/* handle octal leading 0 */
-					if (flags & ALT && *cp != '0')
-						*--cp = '0';
-					break;
-
-				case DEC:
-					/* many numbers are 1 digit */
-					while (_umax >= 10) {
-						*--cp = to_char(_umax % 10);
-						_umax /= 10;
-					}
-					*--cp = to_char(_umax);
-					break;
-
-				case HEX:
-					do {
-						*--cp = xdigs[_umax & 15];
-						_umax >>= 4;
-					} while (_umax);
-					break;
-
-				default:
-					cp = "bug in vfprintf: bad base";
-					size = strlen(cp);
-					goto skipsize;
-				}
-			}
-			size = buf + BUF - cp;
-			if (size > BUF)	/* should never happen */
-				abort();
-		skipsize:
-			break;
-		default:	/* "%?" prints ?, unless ? is NUL */
-			if (ch == '\0')
-				goto done;
-			/* pretend it was %c with argument ch */
-			cp = buf;
-			*cp = ch;
-			size = 1;
-			sign = '\0';
-			break;
-		}
-
-		/*
-		 * All reasonable formats wind up here.  At this point, `cp'
-		 * points to a string which (if not flags&LADJUST) should be
-		 * padded out to `width' places.  If flags&ZEROPAD, it should
-		 * first be prefixed by any sign or other prefix; otherwise,
-		 * it should be blank padded before the prefix is emitted.
-		 * After any left-hand padding and prefixing, emit zeroes
-		 * required by a decimal %[diouxX] precision, then print the
-		 * string proper, then emit zeroes required by any leftover
-		 * floating precision; finally, if LADJUST, pad with blanks.
-		 *
-		 * Compute actual size, so we know how much to pad.
-		 * size excludes decimal prec; realsz includes it.
-		 */
-		realsz = dprec > size ? dprec : size;
-		if (sign)
-			realsz++;
-		if (ox[1])
-			realsz+= 2;
-
-		/* right-adjusting blank padding */
-		if ((flags & (LADJUST|ZEROPAD)) == 0)
-			PAD(width - realsz, blanks);
-
-		/* prefix */
-		if (sign)
-			PRINT(&sign, 1);
-		if (ox[1]) {	/* ox[1] is either x, X, or \0 */
-			ox[0] = '0';
-			PRINT(ox, 2);
-		}
-
-		/* right-adjusting zero padding */
-		if ((flags & (LADJUST|ZEROPAD)) == ZEROPAD)
-			PAD(width - realsz, zeroes);
-
-		/* leading zeroes from decimal precision */
-		PAD(dprec - size, zeroes);
-
-		/* the string or number proper */
-#ifdef FLOATING_POINT
-		if ((flags & FPT) == 0) {
-			PRINT(cp, size);
-		} else {	/* glue together f_p fragments */
-			if (decimal_point == NULL)
-				decimal_point = nl_langinfo(RADIXCHAR);
-			if (!expchar) {	/* %[fF] or sufficiently short %[gG] */
-				if (expt <= 0) {
-					PRINT(zeroes, 1);
-					if (prec || flags & ALT)
-						PRINT(decimal_point, 1);
-					PAD(-expt, zeroes);
-					/* already handled initial 0's */
-					prec += expt;
- 				} else {
-					PRINTANDPAD(cp, dtoaend, lead, zeroes);
-					cp += lead;
-					if (prec || flags & ALT)
-						PRINT(decimal_point, 1);
-				}
-				PRINTANDPAD(cp, dtoaend, prec, zeroes);
-			} else {	/* %[eE] or sufficiently long %[gG] */
-				if (prec > 1 || flags & ALT) {
-					buf[0] = *cp++;
-					buf[1] = *decimal_point;
-					PRINT(buf, 2);
-					PRINT(cp, ndig-1);
-					PAD(prec - ndig, zeroes);
-				} else { /* XeYYY */
-					PRINT(cp, 1);
-				}
-				PRINT(expstr, expsize);
-			}
-		}
-#else
-		PRINT(cp, size);
-#endif
-		/* left-adjusting padding (always blank) */
-		if (flags & LADJUST)
-			PAD(width - realsz, blanks);
-
-		/* finally, adjust ret */
-		if (width < realsz)
-			width = realsz;
-		if (width > INT_MAX - ret)
-			goto overflow;
-		ret += width;
-
-		FLUSH();	/* copy out the I/O vectors */
-	}
-done:
-	FLUSH();
-error:
-	va_end(orgap);
-	if (__sferror(fp))
-		ret = -1;
-	goto finish;
-
-overflow:
-	errno = ENOMEM;
-	ret = -1;
-
-finish:
-#ifdef PRINTF_WIDE_CHAR
-	free(convbuf);
-#endif
-#ifdef FLOATING_POINT
-	if (dtoaresult)
-		__freedtoa(dtoaresult);
-#endif
-	if (argtable != NULL && argtable != statargtable) {
-		munmap(argtable, argtablesiz);
-		argtable = NULL;
-	}
-	return (ret);
-}
-
-/*
- * Type ids for argument type table.
- */
-#define T_UNUSED	0
-#define T_SHORT		1
-#define T_U_SHORT	2
-#define TP_SHORT	3
-#define T_INT		4
-#define T_U_INT		5
-#define TP_INT		6
-#define T_LONG		7
-#define T_U_LONG	8
-#define TP_LONG		9
-#define T_LLONG		10
-#define T_U_LLONG	11
-#define TP_LLONG	12
-#define T_DOUBLE	13
-#define T_LONG_DOUBLE	14
-#define TP_CHAR		15
-#define TP_VOID		16
-#define T_PTRINT	17
-#define TP_PTRINT	18
-#define T_SIZEINT	19
-#define T_SSIZEINT	20
-#define TP_SSIZEINT	21
-#define T_MAXINT	22
-#define T_MAXUINT	23
-#define TP_MAXINT	24
-#define T_CHAR		25
-#define T_U_CHAR	26
-#define T_WINT		27
-#define TP_WCHAR	28
-
-/*
- * Find all arguments when a positional parameter is encountered.  Returns a
- * table, indexed by argument number, of pointers to each arguments.  The
- * initial argument table should be an array of STATIC_ARG_TBL_SIZE entries.
- * It will be replaced with a mmap-ed one if it overflows (malloc cannot be
- * used since we are attempting to make snprintf thread safe, and alloca is
- * problematic since we have nested functions..)
- */
-static int
-__find_arguments(const char *fmt0, va_list ap, union arg **argtable,
-    size_t *argtablesiz)
-{
-	char *fmt;		/* format string */
-	int ch;			/* character from fmt */
-	int n, n2;		/* handy integer (short term usage) */
-	char *cp;		/* handy char pointer (short term usage) */
-	int flags;		/* flags as above */
-	unsigned char *typetable; /* table of types */
-	unsigned char stattypetable[STATIC_ARG_TBL_SIZE];
-	int tablesize;		/* current size of type table */
-	int tablemax;		/* largest used index in table */
-	int nextarg;		/* 1-based argument index */
-	int ret = 0;		/* return value */
-	wchar_t wc;
-	mbstate_t ps;
-
-	/*
-	 * Add an argument type to the table, expanding if necessary.
-	 */
-#define ADDTYPE(type) \
-	((nextarg >= tablesize) ? \
-		__grow_type_table(&typetable, &tablesize) : 0, \
-	(nextarg > tablemax) ? tablemax = nextarg : 0, \
-	typetable[nextarg++] = type)
-
-#define	ADDSARG() \
-        ((flags&MAXINT) ? ADDTYPE(T_MAXINT) : \
-	    ((flags&PTRINT) ? ADDTYPE(T_PTRINT) : \
-	    ((flags&SIZEINT) ? ADDTYPE(T_SSIZEINT) : \
-	    ((flags&LLONGINT) ? ADDTYPE(T_LLONG) : \
-	    ((flags&LONGINT) ? ADDTYPE(T_LONG) : \
-	    ((flags&SHORTINT) ? ADDTYPE(T_SHORT) : \
-	    ((flags&CHARINT) ? ADDTYPE(T_CHAR) : ADDTYPE(T_INT))))))))
-
-#define	ADDUARG() \
-        ((flags&MAXINT) ? ADDTYPE(T_MAXUINT) : \
-	    ((flags&PTRINT) ? ADDTYPE(T_PTRINT) : \
-	    ((flags&SIZEINT) ? ADDTYPE(T_SIZEINT) : \
-	    ((flags&LLONGINT) ? ADDTYPE(T_U_LLONG) : \
-	    ((flags&LONGINT) ? ADDTYPE(T_U_LONG) : \
-	    ((flags&SHORTINT) ? ADDTYPE(T_U_SHORT) : \
-	    ((flags&CHARINT) ? ADDTYPE(T_U_CHAR) : ADDTYPE(T_U_INT))))))))
-
-	/*
-	 * Add * arguments to the type array.
-	 */
-#define ADDASTER() \
-	n2 = 0; \
-	cp = fmt; \
-	while (is_digit(*cp)) { \
-		APPEND_DIGIT(n2, *cp); \
-		cp++; \
-	} \
-	if (*cp == '$') { \
-		int hold = nextarg; \
-		nextarg = n2; \
-		ADDTYPE(T_INT); \
-		nextarg = hold; \
-		fmt = ++cp; \
-	} else { \
-		ADDTYPE(T_INT); \
-	}
-	fmt = (char *)fmt0;
-	typetable = stattypetable;
-	tablesize = STATIC_ARG_TBL_SIZE;
-	tablemax = 0;
-	nextarg = 1;
-	memset(typetable, T_UNUSED, STATIC_ARG_TBL_SIZE);
-	memset(&ps, 0, sizeof(ps));
-
-	/*
-	 * Scan the format for conversions (`%' character).
-	 */
-	for (;;) {
-		cp = fmt;
-		while ((n = mbrtowc(&wc, fmt, MB_CUR_MAX, &ps)) > 0) {
-			fmt += n;
-			if (wc == '%') {
-				fmt--;
-				break;
-			}
-		}
-		if (n < 0)
-			return (-1);
-		if (n == 0)
-			goto done;
-		fmt++;		/* skip over '%' */
-
-		flags = 0;
-
-rflag:		ch = *fmt++;
-reswitch:	switch (ch) {
-		case ' ':
-		case '#':
-		case '\'':
-			goto rflag;
-		case '*':
-			ADDASTER();
-			goto rflag;
-		case '-':
-		case '+':
-			goto rflag;
-		case '.':
-			if ((ch = *fmt++) == '*') {
-				ADDASTER();
-				goto rflag;
-			}
-			while (is_digit(ch)) {
-				ch = *fmt++;
-			}
-			goto reswitch;
-		case '0':
-			goto rflag;
-		case '1': case '2': case '3': case '4':
-		case '5': case '6': case '7': case '8': case '9':
-			n = 0;
-			do {
-				APPEND_DIGIT(n ,ch);
-				ch = *fmt++;
-			} while (is_digit(ch));
-			if (ch == '$') {
-				nextarg = n;
-				goto rflag;
-			}
-			goto reswitch;
-#ifdef FLOATING_POINT
-		case 'L':
-			flags |= LONGDBL;
-			goto rflag;
-#endif
-		case 'h':
-			if (*fmt == 'h') {
-				fmt++;
-				flags |= CHARINT;
-			} else {
-				flags |= SHORTINT;
-			}
-			goto rflag;
-		case 'j':
-			flags |= MAXINT;
-			goto rflag;
-		case 'l':
-			if (*fmt == 'l') {
-				fmt++;
-				flags |= LLONGINT;
-			} else {
-				flags |= LONGINT;
-			}
-			goto rflag;
-		case 'q':
-			flags |= LLONGINT;
-			goto rflag;
-		case 't':
-			flags |= PTRINT;
-			goto rflag;
-		case 'z':
-			flags |= SIZEINT;
-			goto rflag;
-		case 'c':
-#ifdef PRINTF_WIDE_CHAR
-			if (flags & LONGINT)
-				ADDTYPE(T_WINT);
-			else
-#endif
-				ADDTYPE(T_INT);
-			break;
-		case 'D':
-			flags |= LONGINT;
-			/*FALLTHROUGH*/
-		case 'd':
-		case 'i':
-			ADDSARG();
-			break;
-#ifdef FLOATING_POINT
-		case 'a':
-		case 'A':
-		case 'e':
-		case 'E':
-		case 'f':
-		case 'F':
-		case 'g':
-		case 'G':
-			if (flags & LONGDBL)
-				ADDTYPE(T_LONG_DOUBLE);
-			else
-				ADDTYPE(T_DOUBLE);
-			break;
-#endif /* FLOATING_POINT */
-#ifndef NO_PRINTF_PERCENT_N
-		case 'n':
-			if (flags & LLONGINT)
-				ADDTYPE(TP_LLONG);
-			else if (flags & LONGINT)
-				ADDTYPE(TP_LONG);
-			else if (flags & SHORTINT)
-				ADDTYPE(TP_SHORT);
-			else if (flags & PTRINT)
-				ADDTYPE(TP_PTRINT);
-			else if (flags & SIZEINT)
-				ADDTYPE(TP_SSIZEINT);
-			else if (flags & MAXINT)
-				ADDTYPE(TP_MAXINT);
-			else
-				ADDTYPE(TP_INT);
-			continue;	/* no output */
-#endif /* NO_PRINTF_PERCENT_N */
-		case 'O':
-			flags |= LONGINT;
-			/*FALLTHROUGH*/
-		case 'o':
-			ADDUARG();
-			break;
-		case 'p':
-			ADDTYPE(TP_VOID);
-			break;
-		case 's':
-#ifdef PRINTF_WIDE_CHAR
-			if (flags & LONGINT)
-				ADDTYPE(TP_WCHAR);
-			else
-#endif
-				ADDTYPE(TP_CHAR);
-			break;
-		case 'U':
-			flags |= LONGINT;
-			/*FALLTHROUGH*/
-		case 'u':
-		case 'X':
-		case 'x':
-			ADDUARG();
-			break;
-		default:	/* "%?" prints ?, unless ? is NUL */
-			if (ch == '\0')
-				goto done;
-			break;
-		}
-	}
-done:
-	/*
-	 * Build the argument table.
-	 */
-	if (tablemax >= STATIC_ARG_TBL_SIZE) {
-		*argtablesiz = sizeof(union arg) * (tablemax + 1);
-		*argtable = mmap(NULL, *argtablesiz,
-		    PROT_WRITE|PROT_READ, MAP_ANON|MAP_PRIVATE, -1, 0);
-		if (*argtable == MAP_FAILED)
-			return (-1);
-	}
-
-#if 0
-	/* XXX is this required? */
-	(*argtable)[0].intarg = 0;
-#endif
-	for (n = 1; n <= tablemax; n++) {
-		switch (typetable[n]) {
-		case T_UNUSED:
-		case T_CHAR:
-		case T_U_CHAR:
-		case T_SHORT:
-		case T_U_SHORT:
-		case T_INT:
-			(*argtable)[n].intarg = va_arg(ap, int);
-			break;
-		case TP_SHORT:
-			(*argtable)[n].pshortarg = va_arg(ap, short *);
-			break;
-		case T_U_INT:
-			(*argtable)[n].uintarg = va_arg(ap, unsigned int);
-			break;
-		case TP_INT:
-			(*argtable)[n].pintarg = va_arg(ap, int *);
-			break;
-		case T_LONG:
-			(*argtable)[n].longarg = va_arg(ap, long);
-			break;
-		case T_U_LONG:
-			(*argtable)[n].ulongarg = va_arg(ap, unsigned long);
-			break;
-		case TP_LONG:
-			(*argtable)[n].plongarg = va_arg(ap, long *);
-			break;
-		case T_LLONG:
-			(*argtable)[n].longlongarg = va_arg(ap, long long);
-			break;
-		case T_U_LLONG:
-			(*argtable)[n].ulonglongarg = va_arg(ap, unsigned long long);
-			break;
-		case TP_LLONG:
-			(*argtable)[n].plonglongarg = va_arg(ap, long long *);
-			break;
-#ifdef FLOATING_POINT
-		case T_DOUBLE:
-			(*argtable)[n].doublearg = va_arg(ap, double);
-			break;
-		case T_LONG_DOUBLE:
-			(*argtable)[n].longdoublearg = va_arg(ap, long double);
-			break;
-#endif
-		case TP_CHAR:
-			(*argtable)[n].pchararg = va_arg(ap, char *);
-			break;
-		case TP_VOID:
-			(*argtable)[n].pvoidarg = va_arg(ap, void *);
-			break;
-		case T_PTRINT:
-			(*argtable)[n].ptrdiffarg = va_arg(ap, ptrdiff_t);
-			break;
-		case TP_PTRINT:
-			(*argtable)[n].pptrdiffarg = va_arg(ap, ptrdiff_t *);
-			break;
-		case T_SIZEINT:
-			(*argtable)[n].sizearg = va_arg(ap, size_t);
-			break;
-		case T_SSIZEINT:
-			(*argtable)[n].ssizearg = va_arg(ap, ssize_t);
-			break;
-		case TP_SSIZEINT:
-			(*argtable)[n].pssizearg = va_arg(ap, ssize_t *);
-			break;
-		case T_MAXINT:
-			(*argtable)[n].intmaxarg = va_arg(ap, intmax_t);
-			break;
-		case T_MAXUINT:
-			(*argtable)[n].uintmaxarg = va_arg(ap, uintmax_t);
-			break;
-		case TP_MAXINT:
-			(*argtable)[n].pintmaxarg = va_arg(ap, intmax_t *);
-			break;
-#ifdef PRINTF_WIDE_CHAR
-		case T_WINT:
-			(*argtable)[n].wintarg = va_arg(ap, wint_t);
-			break;
-		case TP_WCHAR:
-			(*argtable)[n].pwchararg = va_arg(ap, wchar_t *);
-			break;
-#endif
-		}
-	}
-	goto finish;
-
-overflow:
-	errno = ENOMEM;
-	ret = -1;
-
-finish:
-	if (typetable != NULL && typetable != stattypetable) {
-		munmap(typetable, *argtablesiz);
-		typetable = NULL;
-	}
-	return (ret);
-}
-
-/*
- * Increase the size of the type table.
- */
-static int
-__grow_type_table(unsigned char **typetable, int *tablesize)
-{
-	unsigned char *oldtable = *typetable;
-	int newsize = *tablesize * 2;
-
-	if (newsize < getpagesize())
-		newsize = getpagesize();
-
-	if (*tablesize == STATIC_ARG_TBL_SIZE) {
-		*typetable = mmap(NULL, newsize, PROT_WRITE|PROT_READ,
-		    MAP_ANON|MAP_PRIVATE, -1, 0);
-		if (*typetable == MAP_FAILED)
-			return (-1);
-		bcopy(oldtable, *typetable, *tablesize);
-	} else {
-		unsigned char *new = mmap(NULL, newsize, PROT_WRITE|PROT_READ,
-		    MAP_ANON|MAP_PRIVATE, -1, 0);
-		if (new == MAP_FAILED)
-			return (-1);
-		memmove(new, *typetable, *tablesize);
-		munmap(*typetable, *tablesize);
-		*typetable = new;
-	}
-	memset(*typetable + *tablesize, T_UNUSED, (newsize - *tablesize));
-
-	*tablesize = newsize;
-	return (0);
-}
-
- 
-#ifdef FLOATING_POINT
-static int
-exponent(char *p0, int exp, int fmtch)
-{
-	char *p, *t;
-	char expbuf[MAXEXPDIG];
-
-	p = p0;
-	*p++ = fmtch;
-	if (exp < 0) {
-		exp = -exp;
-		*p++ = '-';
-	} else
-		*p++ = '+';
-	t = expbuf + MAXEXPDIG;
-	if (exp > 9) {
-		do {
-			*--t = to_char(exp % 10);
-		} while ((exp /= 10) > 9);
-		*--t = to_char(exp);
-		for (; t < expbuf + MAXEXPDIG; *p++ = *t++)
-			/* nothing */;
-	} else {
-		/*
-		 * Exponents for decimal floating point conversions
-		 * (%[eEgG]) must be at least two characters long,
-		 * whereas exponents for hexadecimal conversions can
-		 * be only one character long.
-		 */
-		if (fmtch == 'e' || fmtch == 'E')
-			*p++ = '0';
-		*p++ = to_char(exp);
-	}
-	return (p - p0);
-}
-#endif /* FLOATING_POINT */
diff --git a/libc/upstream-openbsd/lib/libc/stdio/vfwprintf.c b/libc/upstream-openbsd/lib/libc/stdio/vfwprintf.c
deleted file mode 100644
index 520c8bc..0000000
--- a/libc/upstream-openbsd/lib/libc/stdio/vfwprintf.c
+++ /dev/null
@@ -1,1510 +0,0 @@
-/*	$OpenBSD: vfwprintf.c,v 1.15 2015/12/28 22:08:18 mmcc Exp $ */
-/*-
- * Copyright (c) 1990 The Regents of the University of California.
- * All rights reserved.
- *
- * This code is derived from software contributed to Berkeley by
- * Chris Torek.
- *
- * Redistribution and use in source and binary forms, with or without
- * modification, are permitted provided that the following conditions
- * are met:
- * 1. Redistributions of source code must retain the above copyright
- *    notice, this list of conditions and the following disclaimer.
- * 2. Redistributions in binary form must reproduce the above copyright
- *    notice, this list of conditions and the following disclaimer in the
- *    documentation and/or other materials provided with the distribution.
- * 3. Neither the name of the University nor the names of its contributors
- *    may be used to endorse or promote products derived from this software
- *    without specific prior written permission.
- *
- * THIS SOFTWARE IS PROVIDED BY THE REGENTS AND CONTRIBUTORS ``AS IS'' AND
- * ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE
- * IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE
- * ARE DISCLAIMED.  IN NO EVENT SHALL THE REGENTS OR CONTRIBUTORS BE LIABLE
- * FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL
- * DAMAGES (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS
- * OR SERVICES; LOSS OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION)
- * HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT
- * LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY
- * OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF
- * SUCH DAMAGE.
- */
-
-/*
- * Actual wprintf innards.
- *
- * This code is large and complicated...
- */
-
-#include <sys/types.h>
-#include <sys/mman.h>
-
-#include <errno.h>
-#include <langinfo.h>
-#include <limits.h>
-#include <stdarg.h>
-#include <stddef.h>
-#include <stdio.h>
-#include <stdint.h>
-#include <stdlib.h>
-#include <string.h>
-#include <unistd.h>
-
-#include "local.h"
-#include "fvwrite.h"
-
-union arg {
-	int			intarg;
-	unsigned int		uintarg;
-	long			longarg;
-	unsigned long		ulongarg;
-	long long		longlongarg;
-	unsigned long long	ulonglongarg;
-	ptrdiff_t		ptrdiffarg;
-	size_t			sizearg;
-	ssize_t			ssizearg;
-	intmax_t		intmaxarg;
-	uintmax_t		uintmaxarg;
-	void			*pvoidarg;
-	char			*pchararg;
-	signed char		*pschararg;
-	short			*pshortarg;
-	int			*pintarg;
-	long			*plongarg;
-	long long		*plonglongarg;
-	ptrdiff_t		*pptrdiffarg;
-	ssize_t			*pssizearg;
-	intmax_t		*pintmaxarg;
-#ifdef FLOATING_POINT
-	double			doublearg;
-	long double		longdoublearg;
-#endif
-	wint_t			wintarg;
-	wchar_t			*pwchararg;
-};
-
-static int __find_arguments(const wchar_t *fmt0, va_list ap, union arg **argtable,
-    size_t *argtablesiz);
-static int __grow_type_table(unsigned char **typetable, int *tablesize);
-
-/*
- * Helper function for `fprintf to unbuffered unix file': creates a
- * temporary buffer.  We only work on write-only files; this avoids
- * worries about ungetc buffers and so forth.
- */
-static int
-__sbprintf(FILE *fp, const wchar_t *fmt, va_list ap)
-{
-	int ret;
-	FILE fake;
-	struct __sfileext fakeext;
-	unsigned char buf[BUFSIZ];
-
-	_FILEEXT_SETUP(&fake, &fakeext);
-	/* copy the important variables */
-	fake._flags = fp->_flags & ~__SNBF;
-	fake._file = fp->_file;
-	fake._cookie = fp->_cookie;
-	fake._write = fp->_write;
-
-	/* set up the buffer */
-	fake._bf._base = fake._p = buf;
-	fake._bf._size = fake._w = sizeof(buf);
-	fake._lbfsize = 0;	/* not actually used, but Just In Case */
-
-	/* do the work, then copy any error status */
-	ret = __vfwprintf(&fake, fmt, ap);
-	if (ret >= 0 && __sflush(&fake))
-		ret = EOF;
-	if (fake._flags & __SERR)
-		fp->_flags |= __SERR;
-	return (ret);
-}
-
-/*
- * Like __fputwc_unlock, but handles fake string (__SSTR) files properly.
- * File must already be locked.
- */
-static wint_t
-__xfputwc(wchar_t wc, FILE *fp)
-{
-	mbstate_t mbs;
-	char buf[MB_LEN_MAX];
-	struct __suio uio;
-	struct __siov iov;
-	size_t len;
-
-	if ((fp->_flags & __SSTR) == 0)
-		return (__fputwc_unlock(wc, fp));
-
-	bzero(&mbs, sizeof(mbs));
-	len = wcrtomb(buf, wc, &mbs);
-	if (len == (size_t)-1) {
-		fp->_flags |= __SERR;
-		errno = EILSEQ;
-		return (WEOF);
-	}
-	uio.uio_iov = &iov;
-	uio.uio_resid = len;
-	uio.uio_iovcnt = 1;
-	iov.iov_base = buf;
-	iov.iov_len = len;
-	return (__sfvwrite(fp, &uio) != EOF ? (wint_t)wc : WEOF);
-}
-
-/*
- * Convert a multibyte character string argument for the %s format to a wide
- * string representation. ``prec'' specifies the maximum number of bytes
- * to output. If ``prec'' is greater than or equal to zero, we can't assume
- * that the multibyte character string ends in a null character.
- * 
- * Returns NULL on failure.
- * To find out what happened check errno for ENOMEM, EILSEQ and EINVAL.
- */
-static wchar_t *
-__mbsconv(char *mbsarg, int prec)
-{
-	mbstate_t mbs;
-	wchar_t *convbuf, *wcp;
-	const char *p;
-	size_t insize, nchars, nconv;
-
-	if (mbsarg == NULL)
-		return (NULL);
-
-	/*
-	 * Supplied argument is a multibyte string; convert it to wide
-	 * characters first.
-	 */
-	if (prec >= 0) {
-		/*
-		 * String is not guaranteed to be NUL-terminated. Find the
-		 * number of characters to print.
-		 */
-		p = mbsarg;
-		insize = nchars = nconv = 0;
-		bzero(&mbs, sizeof(mbs));
-		while (nchars != (size_t)prec) {
-			nconv = mbrlen(p, MB_CUR_MAX, &mbs);
-			if (nconv == (size_t)0 || nconv == (size_t)-1 ||
-			    nconv == (size_t)-2)
-				break;
-			p += nconv;
-			nchars++;
-			insize += nconv;
-		}
-		if (nconv == (size_t)-1 || nconv == (size_t)-2)
-			return (NULL);
-	} else
-		insize = strlen(mbsarg);
-
-	/*
-	 * Allocate buffer for the result and perform the conversion,
-	 * converting at most `size' bytes of the input multibyte string to
-	 * wide characters for printing.
-	 */
-	convbuf = calloc(insize + 1, sizeof(*convbuf));
-	if (convbuf == NULL)
-		return (NULL);
-	wcp = convbuf;
-	p = mbsarg;
-	bzero(&mbs, sizeof(mbs));
-	nconv = 0;
-	while (insize != 0) {
-		nconv = mbrtowc(wcp, p, insize, &mbs);
-		if (nconv == 0 || nconv == (size_t)-1 || nconv == (size_t)-2)
-			break;
-		wcp++;
-		p += nconv;
-		insize -= nconv;
-	}
-	if (nconv == (size_t)-1 || nconv == (size_t)-2) {
-		free(convbuf);
-		return (NULL);
-	}
-	*wcp = '\0';
-
-	return (convbuf);
-}
-
-#ifdef FLOATING_POINT
-#include <float.h>
-#include <locale.h>
-#include <math.h>
-#include "floatio.h"
-#include "gdtoa.h"
-
-#define	DEFPREC		6
-
-static int exponent(wchar_t *, int, int);
-#endif /* FLOATING_POINT */
-
-/*
- * The size of the buffer we use as scratch space for integer
- * conversions, among other things.  Technically, we would need the
- * most space for base 10 conversions with thousands' grouping
- * characters between each pair of digits.  100 bytes is a
- * conservative overestimate even for a 128-bit uintmax_t.
- */
-#define BUF	100
-
-#define STATIC_ARG_TBL_SIZE 8	/* Size of static argument table. */
-
-
-/*
- * Macros for converting digits to letters and vice versa
- */
-#define	to_digit(c)	((c) - '0')
-#define is_digit(c)	((unsigned)to_digit(c) <= 9)
-#define	to_char(n)	((wchar_t)((n) + '0'))
-
-/*
- * Flags used during conversion.
- */
-#define	ALT		0x0001		/* alternate form */
-#define	LADJUST		0x0004		/* left adjustment */
-#define	LONGDBL		0x0008		/* long double */
-#define	LONGINT		0x0010		/* long integer */
-#define	LLONGINT	0x0020		/* long long integer */
-#define	SHORTINT	0x0040		/* short integer */
-#define	ZEROPAD		0x0080		/* zero (as opposed to blank) pad */
-#define FPT		0x0100		/* Floating point number */
-#define PTRINT		0x0200		/* (unsigned) ptrdiff_t */
-#define SIZEINT		0x0400		/* (signed) size_t */
-#define CHARINT		0x0800		/* 8 bit integer */
-#define MAXINT		0x1000		/* largest integer size (intmax_t) */
-
-int
-__vfwprintf(FILE * __restrict fp, const wchar_t * __restrict fmt0, __va_list ap)
-{
-	wchar_t *fmt;		/* format string */
-	wchar_t ch;		/* character from fmt */
-	int n, n2, n3;		/* handy integers (short term usage) */
-	wchar_t *cp;		/* handy char pointer (short term usage) */
-	int flags;		/* flags as above */
-	int ret;		/* return value accumulator */
-	int width;		/* width from format (%8d), or 0 */
-	int prec;		/* precision from format; <0 for N/A */
-	wchar_t sign;		/* sign prefix (' ', '+', '-', or \0) */
-#ifdef FLOATING_POINT
-	/*
-	 * We can decompose the printed representation of floating
-	 * point numbers into several parts, some of which may be empty:
-	 *
-	 * [+|-| ] [0x|0X] MMM . NNN [e|E|p|P] [+|-] ZZ
-	 *    A       B     ---C---      D       E   F
-	 *
-	 * A:	'sign' holds this value if present; '\0' otherwise
-	 * B:	ox[1] holds the 'x' or 'X'; '\0' if not hexadecimal
-	 * C:	cp points to the string MMMNNN.  Leading and trailing
-	 *	zeros are not in the string and must be added.
-	 * D:	expchar holds this character; '\0' if no exponent, e.g. %f
-	 * F:	at least two digits for decimal, at least one digit for hex
-	 */
-	char *decimal_point = NULL;
-	int signflag;		/* true if float is negative */
-	union {			/* floating point arguments %[aAeEfFgG] */
-		double dbl;
-		long double ldbl;
-	} fparg;
-	int expt;		/* integer value of exponent */
-	char expchar;		/* exponent character: [eEpP\0] */
-	char *dtoaend;		/* pointer to end of converted digits */
-	int expsize;		/* character count for expstr */
-	int lead;		/* sig figs before decimal or group sep */
-	int ndig;		/* actual number of digits returned by dtoa */
-	wchar_t expstr[MAXEXPDIG+2];	/* buffer for exponent string: e+ZZZ */
-	char *dtoaresult = NULL;
-#endif
-
-	uintmax_t _umax;	/* integer arguments %[diouxX] */
-	enum { OCT, DEC, HEX } base;	/* base for %[diouxX] conversion */
-	int dprec;		/* a copy of prec if %[diouxX], 0 otherwise */
-	int realsz;		/* field size expanded by dprec */
-	int size;		/* size of converted field or string */
-	const char *xdigs;	/* digits for %[xX] conversion */
-	wchar_t buf[BUF];	/* buffer with space for digits of uintmax_t */
-	wchar_t ox[2];		/* space for 0x; ox[1] is either x, X, or \0 */
-	union arg *argtable;	/* args, built due to positional arg */
-	union arg statargtable[STATIC_ARG_TBL_SIZE];
-	size_t argtablesiz;
-	int nextarg;		/* 1-based argument index */
-	va_list orgap;		/* original argument pointer */
-	wchar_t *convbuf;	/* buffer for multibyte to wide conversion */
-
-	/*
-	 * Choose PADSIZE to trade efficiency vs. size.  If larger printf
-	 * fields occur frequently, increase PADSIZE and make the initialisers
-	 * below longer.
-	 */
-#define	PADSIZE	16		/* pad chunk size */
-	static wchar_t blanks[PADSIZE] =
-	 {' ',' ',' ',' ',' ',' ',' ',' ',' ',' ',' ',' ',' ',' ',' ',' '};
-	static wchar_t zeroes[PADSIZE] =
-	 {'0','0','0','0','0','0','0','0','0','0','0','0','0','0','0','0'};
-
-	static const char xdigs_lower[16] = "0123456789abcdef";
-	static const char xdigs_upper[16] = "0123456789ABCDEF";
-
-	/*
-	 * BEWARE, these `goto error' on error, PRINT uses 'n3',
-	 * PAD uses `n' and 'n3', and PRINTANDPAD uses 'n', 'n2', and 'n3'.
-	 */
-#define	PRINT(ptr, len)	do {	\
-	for (n3 = 0; n3 < (len); n3++) {	\
-		if ((__xfputwc((ptr)[n3], fp)) == WEOF)	\
-			goto error; \
-	} \
-} while (0)
-#define	PAD(howmany, with) do { \
-	if ((n = (howmany)) > 0) { \
-		while (n > PADSIZE) { \
-			PRINT(with, PADSIZE); \
-			n -= PADSIZE; \
-		} \
-		PRINT(with, n); \
-	} \
-} while (0)
-#define	PRINTANDPAD(p, ep, len, with) do {	\
-	n2 = (ep) - (p);       			\
-	if (n2 > (len))				\
-		n2 = (len);			\
-	if (n2 > 0)				\
-		PRINT((p), n2);			\
-	PAD((len) - (n2 > 0 ? n2 : 0), (with));	\
-} while(0)
-
-	/*
-	 * To extend shorts properly, we need both signed and unsigned
-	 * argument extraction methods.
-	 */
-#define	SARG() \
-	((intmax_t)(flags&MAXINT ? GETARG(intmax_t) : \
-	    flags&LLONGINT ? GETARG(long long) : \
-	    flags&LONGINT ? GETARG(long) : \
-	    flags&PTRINT ? GETARG(ptrdiff_t) : \
-	    flags&SIZEINT ? GETARG(ssize_t) : \
-	    flags&SHORTINT ? (short)GETARG(int) : \
-	    flags&CHARINT ? (signed char)GETARG(int) : \
-	    GETARG(int)))
-#define	UARG() \
-	((uintmax_t)(flags&MAXINT ? GETARG(uintmax_t) : \
-	    flags&LLONGINT ? GETARG(unsigned long long) : \
-	    flags&LONGINT ? GETARG(unsigned long) : \
-	    flags&PTRINT ? (uintptr_t)GETARG(ptrdiff_t) : /* XXX */ \
-	    flags&SIZEINT ? GETARG(size_t) : \
-	    flags&SHORTINT ? (unsigned short)GETARG(int) : \
-	    flags&CHARINT ? (unsigned char)GETARG(int) : \
-	    GETARG(unsigned int)))
-
-	/*
-	 * Append a digit to a value and check for overflow.
-	 */
-#define APPEND_DIGIT(val, dig) do { \
-	if ((val) > INT_MAX / 10) \
-		goto overflow; \
-	(val) *= 10; \
-	if ((val) > INT_MAX - to_digit((dig))) \
-		goto overflow; \
-	(val) += to_digit((dig)); \
-} while (0)
-
-	 /*
-	  * Get * arguments, including the form *nn$.  Preserve the nextarg
-	  * that the argument can be gotten once the type is determined.
-	  */
-#define GETASTER(val) \
-	n2 = 0; \
-	cp = fmt; \
-	while (is_digit(*cp)) { \
-		APPEND_DIGIT(n2, *cp); \
-		cp++; \
-	} \
-	if (*cp == '$') { \
-		int hold = nextarg; \
-		if (argtable == NULL) { \
-			argtable = statargtable; \
-			__find_arguments(fmt0, orgap, &argtable, &argtablesiz); \
-		} \
-		nextarg = n2; \
-		val = GETARG(int); \
-		nextarg = hold; \
-		fmt = ++cp; \
-	} else { \
-		val = GETARG(int); \
-	}
-
-/*
-* Get the argument indexed by nextarg.   If the argument table is
-* built, use it to get the argument.  If its not, get the next
-* argument (and arguments must be gotten sequentially).
-*/
-#define GETARG(type) \
-	((argtable != NULL) ? *((type*)(&argtable[nextarg++])) : \
-		(nextarg++, va_arg(ap, type)))
-
-	_SET_ORIENTATION(fp, 1);
-	/* sorry, fwprintf(read_only_file, "") returns EOF, not 0 */
-	if (cantwrite(fp)) {
-		errno = EBADF;
-		return (EOF);
-	}
-
-	/* optimise fwprintf(stderr) (and other unbuffered Unix files) */
-	if ((fp->_flags & (__SNBF|__SWR|__SRW)) == (__SNBF|__SWR) &&
-	    fp->_file >= 0)
-		return (__sbprintf(fp, fmt0, ap));
-
-	fmt = (wchar_t *)fmt0;
-	argtable = NULL;
-	nextarg = 1;
-	va_copy(orgap, ap);
-	ret = 0;
-	convbuf = NULL;
-
-	/*
-	 * Scan the format for conversions (`%' character).
-	 */
-	for (;;) {
-		for (cp = fmt; (ch = *fmt) != '\0' && ch != '%'; fmt++)
-			continue;
-		if (fmt != cp) {
-			ptrdiff_t m = fmt - cp;
-			if (m < 0 || m > INT_MAX - ret)
-				goto overflow;
-			PRINT(cp, m);
-			ret += m;
-		}
-		if (ch == '\0')
-			goto done;
-		fmt++;		/* skip over '%' */
-
-		flags = 0;
-		dprec = 0;
-		width = 0;
-		prec = -1;
-		sign = '\0';
-		ox[1] = '\0';
-
-rflag:		ch = *fmt++;
-reswitch:	switch (ch) {
-		case ' ':
-			/*
-			 * ``If the space and + flags both appear, the space
-			 * flag will be ignored.''
-			 *	-- ANSI X3J11
-			 */
-			if (!sign)
-				sign = ' ';
-			goto rflag;
-		case '#':
-			flags |= ALT;
-			goto rflag;
-		case '\'':
-			/* grouping not implemented */
-			goto rflag;
-		case '*':
-			/*
-			 * ``A negative field width argument is taken as a
-			 * - flag followed by a positive field width.''
-			 *	-- ANSI X3J11
-			 * They don't exclude field widths read from args.
-			 */
-			GETASTER(width);
-			if (width >= 0)
-				goto rflag;
-			if (width == INT_MIN)
-				goto overflow;
-			width = -width;
-			/* FALLTHROUGH */
-		case '-':
-			flags |= LADJUST;
-			goto rflag;
-		case '+':
-			sign = '+';
-			goto rflag;
-		case '.':
-			if ((ch = *fmt++) == '*') {
-				GETASTER(n);
-				prec = n < 0 ? -1 : n;
-				goto rflag;
-			}
-			n = 0;
-			while (is_digit(ch)) {
-				APPEND_DIGIT(n, ch);
-				ch = *fmt++;
-			}
-			if (ch == '$') {
-				nextarg = n;
-				if (argtable == NULL) {
-					argtable = statargtable;
-					__find_arguments(fmt0, orgap,
-					    &argtable, &argtablesiz);
-				}
-				goto rflag;
-			}
-			prec = n;
-			goto reswitch;
-		case '0':
-			/*
-			 * ``Note that 0 is taken as a flag, not as the
-			 * beginning of a field width.''
-			 *	-- ANSI X3J11
-			 */
-			flags |= ZEROPAD;
-			goto rflag;
-		case '1': case '2': case '3': case '4':
-		case '5': case '6': case '7': case '8': case '9':
-			n = 0;
-			do {
-				APPEND_DIGIT(n, ch);
-				ch = *fmt++;
-			} while (is_digit(ch));
-			if (ch == '$') {
-				nextarg = n;
-				if (argtable == NULL) {
-					argtable = statargtable;
-					__find_arguments(fmt0, orgap,
-					    &argtable, &argtablesiz);
-				}
-				goto rflag;
-			}
-			width = n;
-			goto reswitch;
-#ifdef FLOATING_POINT
-		case 'L':
-			flags |= LONGDBL;
-			goto rflag;
-#endif
-		case 'h':
-			if (*fmt == 'h') {
-				fmt++;
-				flags |= CHARINT;
-			} else {
-				flags |= SHORTINT;
-			}
-			goto rflag;
-		case 'j':
-			flags |= MAXINT;
-			goto rflag;
-		case 'l':
-			if (*fmt == 'l') {
-				fmt++;
-				flags |= LLONGINT;
-			} else {
-				flags |= LONGINT;
-			}
-			goto rflag;
-		case 'q':
-			flags |= LLONGINT;
-			goto rflag;
-		case 't':
-			flags |= PTRINT;
-			goto rflag;
-		case 'z':
-			flags |= SIZEINT;
-			goto rflag;
-		case 'C':
-			flags |= LONGINT;
-			/*FALLTHROUGH*/
-		case 'c':
-			if (flags & LONGINT)
-				*(cp = buf) = (wchar_t)GETARG(wint_t);
-			else
-				*(cp = buf) = (wchar_t)btowc(GETARG(int));
-			size = 1;
-			sign = '\0';
-			break;
-		case 'D':
-			flags |= LONGINT;
-			/*FALLTHROUGH*/
-		case 'd':
-		case 'i':
-			_umax = SARG();
-			if ((intmax_t)_umax < 0) {
-				_umax = -_umax;
-				sign = '-';
-			}
-			base = DEC;
-			goto number;
-#ifdef FLOATING_POINT
-		case 'a':
-		case 'A':
-			if (ch == 'a') {
-				ox[1] = 'x';
-				xdigs = xdigs_lower;
-				expchar = 'p';
-			} else {
-				ox[1] = 'X';
-				xdigs = xdigs_upper;
-				expchar = 'P';
-			}
-			if (prec >= 0)
-				prec++;
-			if (dtoaresult)
-				__freedtoa(dtoaresult);
-			if (flags & LONGDBL) {
-				fparg.ldbl = GETARG(long double);
-				dtoaresult =
-				    __hldtoa(fparg.ldbl, xdigs, prec,
-				    &expt, &signflag, &dtoaend);
-				if (dtoaresult == NULL) {
-					errno = ENOMEM;
-					goto error;
-				}
-			} else {
-				fparg.dbl = GETARG(double);
-				dtoaresult =
-				    __hdtoa(fparg.dbl, xdigs, prec,
-				    &expt, &signflag, &dtoaend);
-				if (dtoaresult == NULL) {
-					errno = ENOMEM;
-					goto error;
-				}
-			}
-			if (prec < 0)
-				prec = dtoaend - dtoaresult;
-			if (expt == INT_MAX)
-				ox[1] = '\0';
-			free(convbuf);
-			cp = convbuf = __mbsconv(dtoaresult, -1);
-			if (cp == NULL)
-				goto error;
-			ndig = dtoaend - dtoaresult;
-			goto fp_common;
-		case 'e':
-		case 'E':
-			expchar = ch;
-			if (prec < 0)	/* account for digit before decpt */
-				prec = DEFPREC + 1;
-			else
-				prec++;
-			goto fp_begin;
-		case 'f':
-		case 'F':
-			expchar = '\0';
-			goto fp_begin;
-		case 'g':
-		case 'G':
-			expchar = ch - ('g' - 'e');
- 			if (prec == 0)
- 				prec = 1;
-fp_begin:
-			if (prec < 0)
-				prec = DEFPREC;
-			if (dtoaresult)
-				__freedtoa(dtoaresult);
-			if (flags & LONGDBL) {
-				fparg.ldbl = GETARG(long double);
-				dtoaresult =
-				    __ldtoa(&fparg.ldbl, expchar ? 2 : 3, prec,
-				    &expt, &signflag, &dtoaend);
-				if (dtoaresult == NULL) {
-					errno = ENOMEM;
-					goto error;
-				}
-			} else {
-				fparg.dbl = GETARG(double);
-				dtoaresult =
-				    __dtoa(fparg.dbl, expchar ? 2 : 3, prec,
-				    &expt, &signflag, &dtoaend);
-				if (dtoaresult == NULL) {
-					errno = ENOMEM;
-					goto error;
-				}
-				if (expt == 9999)
-					expt = INT_MAX;
- 			}
-			free(convbuf);
-			cp = convbuf = __mbsconv(dtoaresult, -1);
-			if (cp == NULL)
-				goto error;
-			ndig = dtoaend - dtoaresult;
-fp_common:
-			if (signflag)
-				sign = '-';
-			if (expt == INT_MAX) {	/* inf or nan */
-				if (*cp == 'N')
-					cp = (ch >= 'a') ? L"nan" : L"NAN";
-				else
-					cp = (ch >= 'a') ? L"inf" : L"INF";
- 				size = 3;
-				flags &= ~ZEROPAD;
- 				break;
- 			}
-			flags |= FPT;
- 			if (ch == 'g' || ch == 'G') {
-				if (expt > -4 && expt <= prec) {
-					/* Make %[gG] smell like %[fF] */
-					expchar = '\0';
-					if (flags & ALT)
-						prec -= expt;
-					else
-						prec = ndig - expt;
-					if (prec < 0)
-						prec = 0;
-				} else {
-					/*
-					 * Make %[gG] smell like %[eE], but
-					 * trim trailing zeroes if no # flag.
-					 */
-					if (!(flags & ALT))
-						prec = ndig;
-				}
- 			}
-			if (expchar) {
-				expsize = exponent(expstr, expt - 1, expchar);
-				size = expsize + prec;
-				if (prec > 1 || flags & ALT)
- 					++size;
-			} else {
-				/* space for digits before decimal point */
-				if (expt > 0)
-					size = expt;
-				else	/* "0" */
-					size = 1;
-				/* space for decimal pt and following digits */
-				if (prec || flags & ALT)
-					size += prec + 1;
-				lead = expt;
-			}
-			break;
-#endif /* FLOATING_POINT */
-#ifndef NO_PRINTF_PERCENT_N
-		case 'n':
-			if (flags & LLONGINT)
-				*GETARG(long long *) = ret;
-			else if (flags & LONGINT)
-				*GETARG(long *) = ret;
-			else if (flags & SHORTINT)
-				*GETARG(short *) = ret;
-			else if (flags & CHARINT)
-				*GETARG(signed char *) = ret;
-			else if (flags & PTRINT)
-				*GETARG(ptrdiff_t *) = ret;
-			else if (flags & SIZEINT)
-				*GETARG(ssize_t *) = ret;
-			else if (flags & MAXINT)
-				*GETARG(intmax_t *) = ret;
-			else
-				*GETARG(int *) = ret;
-			continue;	/* no output */
-#endif /* NO_PRINTF_PERCENT_N */
-		case 'O':
-			flags |= LONGINT;
-			/*FALLTHROUGH*/
-		case 'o':
-			_umax = UARG();
-			base = OCT;
-			goto nosign;
-		case 'p':
-			/*
-			 * ``The argument shall be a pointer to void.  The
-			 * value of the pointer is converted to a sequence
-			 * of printable characters, in an implementation-
-			 * defined manner.''
-			 *	-- ANSI X3J11
-			 */
-			_umax = (u_long)GETARG(void *);
-			base = HEX;
-			xdigs = xdigs_lower;
-			ox[1] = 'x';
-			goto nosign;
-		case 'S':
-			flags |= LONGINT;
-			/*FALLTHROUGH*/
-		case 's':
-			if (flags & LONGINT) {
-				if ((cp = GETARG(wchar_t *)) == NULL)
-					cp = L"(null)";
-			} else {
-				char *mbsarg;
-				if ((mbsarg = GETARG(char *)) == NULL)
-					mbsarg = "(null)";
-				free(convbuf);
-				convbuf = __mbsconv(mbsarg, prec);
-				if (convbuf == NULL) {
-					fp->_flags |= __SERR;
-					goto error;
-				} else
-					cp = convbuf;
-			}
-			if (prec >= 0) {
-				/*
-				 * can't use wcslen; can only look for the
-				 * NUL in the first `prec' characters, and
-				 * wcslen() will go further.
-				 */
-				wchar_t *p = wmemchr(cp, 0, prec);
-
-				size = p ? (p - cp) : prec;
-			} else {
-				size_t len;
-
-				if ((len = wcslen(cp)) > INT_MAX)
-					goto overflow;
-				size = (int)len;
-			}
-			sign = '\0';
-			break;
-		case 'U':
-			flags |= LONGINT;
-			/*FALLTHROUGH*/
-		case 'u':
-			_umax = UARG();
-			base = DEC;
-			goto nosign;
-		case 'X':
-			xdigs = xdigs_upper;
-			goto hex;
-		case 'x':
-			xdigs = xdigs_lower;
-hex:			_umax = UARG();
-			base = HEX;
-			/* leading 0x/X only if non-zero */
-			if (flags & ALT && _umax != 0)
-				ox[1] = ch;
-
-			/* unsigned conversions */
-nosign:			sign = '\0';
-			/*
-			 * ``... diouXx conversions ... if a precision is
-			 * specified, the 0 flag will be ignored.''
-			 *	-- ANSI X3J11
-			 */
-number:			if ((dprec = prec) >= 0)
-				flags &= ~ZEROPAD;
-
-			/*
-			 * ``The result of converting a zero value with an
-			 * explicit precision of zero is no characters.''
-			 *	-- ANSI X3J11
-			 */
-			cp = buf + BUF;
-			if (_umax != 0 || prec != 0) {
-				/*
-				 * Unsigned mod is hard, and unsigned mod
-				 * by a constant is easier than that by
-				 * a variable; hence this switch.
-				 */
-				switch (base) {
-				case OCT:
-					do {
-						*--cp = to_char(_umax & 7);
-						_umax >>= 3;
-					} while (_umax);
-					/* handle octal leading 0 */
-					if (flags & ALT && *cp != '0')
-						*--cp = '0';
-					break;
-
-				case DEC:
-					/* many numbers are 1 digit */
-					while (_umax >= 10) {
-						*--cp = to_char(_umax % 10);
-						_umax /= 10;
-					}
-					*--cp = to_char(_umax);
-					break;
-
-				case HEX:
-					do {
-						*--cp = xdigs[_umax & 15];
-						_umax >>= 4;
-					} while (_umax);
-					break;
-
-				default:
-					cp = L"bug in vfwprintf: bad base";
-					size = wcslen(cp);
-					goto skipsize;
-				}
-			}
-			size = buf + BUF - cp;
-			if (size > BUF)	/* should never happen */
-				abort();
-		skipsize:
-			break;
-		default:	/* "%?" prints ?, unless ? is NUL */
-			if (ch == '\0')
-				goto done;
-			/* pretend it was %c with argument ch */
-			cp = buf;
-			*cp = ch;
-			size = 1;
-			sign = '\0';
-			break;
-		}
-
-		/*
-		 * All reasonable formats wind up here.  At this point, `cp'
-		 * points to a string which (if not flags&LADJUST) should be
-		 * padded out to `width' places.  If flags&ZEROPAD, it should
-		 * first be prefixed by any sign or other prefix; otherwise,
-		 * it should be blank padded before the prefix is emitted.
-		 * After any left-hand padding and prefixing, emit zeroes
-		 * required by a decimal %[diouxX] precision, then print the
-		 * string proper, then emit zeroes required by any leftover
-		 * floating precision; finally, if LADJUST, pad with blanks.
-		 *
-		 * Compute actual size, so we know how much to pad.
-		 * size excludes decimal prec; realsz includes it.
-		 */
-		realsz = dprec > size ? dprec : size;
-		if (sign)
-			realsz++;
-		if (ox[1])
-			realsz+= 2;
-
-		/* right-adjusting blank padding */
-		if ((flags & (LADJUST|ZEROPAD)) == 0)
-			PAD(width - realsz, blanks);
-
-		/* prefix */
-		if (sign)
-			PRINT(&sign, 1);
-		if (ox[1]) {	/* ox[1] is either x, X, or \0 */
-			ox[0] = '0';
-			PRINT(ox, 2);
-		}
-
-		/* right-adjusting zero padding */
-		if ((flags & (LADJUST|ZEROPAD)) == ZEROPAD)
-			PAD(width - realsz, zeroes);
-
-		/* leading zeroes from decimal precision */
-		PAD(dprec - size, zeroes);
-
-		/* the string or number proper */
-#ifdef FLOATING_POINT
-		if ((flags & FPT) == 0) {
-			PRINT(cp, size);
-		} else {	/* glue together f_p fragments */
-			if (decimal_point == NULL)
-				decimal_point = nl_langinfo(RADIXCHAR);
-			if (!expchar) {	/* %[fF] or sufficiently short %[gG] */
-				if (expt <= 0) {
-					PRINT(zeroes, 1);
-					if (prec || flags & ALT)
-						PRINT(decimal_point, 1);
-					PAD(-expt, zeroes);
-					/* already handled initial 0's */
-					prec += expt;
- 				} else {
-					PRINTANDPAD(cp, convbuf + ndig,
-					    lead, zeroes);
-					cp += lead;
-					if (prec || flags & ALT)
-						PRINT(decimal_point, 1);
-				}
-				PRINTANDPAD(cp, convbuf + ndig, prec, zeroes);
-			} else {	/* %[eE] or sufficiently long %[gG] */
-				if (prec > 1 || flags & ALT) {
-					buf[0] = *cp++;
-					buf[1] = *decimal_point;
-					PRINT(buf, 2);
-					PRINT(cp, ndig-1);
-					PAD(prec - ndig, zeroes);
-				} else { /* XeYYY */
-					PRINT(cp, 1);
-				}
-				PRINT(expstr, expsize);
-			}
-		}
-#else
-		PRINT(cp, size);
-#endif
-		/* left-adjusting padding (always blank) */
-		if (flags & LADJUST)
-			PAD(width - realsz, blanks);
-
-		/* finally, adjust ret */
-		if (width < realsz)
-			width = realsz;
-		if (width > INT_MAX - ret)
-			goto overflow;
-		ret += width;
-	}
-done:
-error:
-	va_end(orgap);
-	if (__sferror(fp))
-		ret = -1;
-	goto finish;
-
-overflow:
-	errno = ENOMEM;
-	ret = -1;
-
-finish:
-	free(convbuf);
-#ifdef FLOATING_POINT
-	if (dtoaresult)
-		__freedtoa(dtoaresult);
-#endif
-	if (argtable != NULL && argtable != statargtable) {
-		munmap(argtable, argtablesiz);
-		argtable = NULL;
-	}
-	return (ret);
-}
-
-int
-vfwprintf(FILE * __restrict fp, const wchar_t * __restrict fmt0, __va_list ap)
-{
-	int r;
-
-	FLOCKFILE(fp);
-	r = __vfwprintf(fp, fmt0, ap);
-	FUNLOCKFILE(fp);
-
-	return (r);
-}
-DEF_STRONG(vfwprintf);
-
-/*
- * Type ids for argument type table.
- */
-#define T_UNUSED	0
-#define T_SHORT		1
-#define T_U_SHORT	2
-#define TP_SHORT	3
-#define T_INT		4
-#define T_U_INT		5
-#define TP_INT		6
-#define T_LONG		7
-#define T_U_LONG	8
-#define TP_LONG		9
-#define T_LLONG		10
-#define T_U_LLONG	11
-#define TP_LLONG	12
-#define T_DOUBLE	13
-#define T_LONG_DOUBLE	14
-#define TP_CHAR		15
-#define TP_VOID		16
-#define T_PTRINT	17
-#define TP_PTRINT	18
-#define T_SIZEINT	19
-#define T_SSIZEINT	20
-#define TP_SSIZEINT	21
-#define T_MAXINT	22
-#define T_MAXUINT	23
-#define TP_MAXINT	24
-#define T_CHAR		25
-#define T_U_CHAR	26
-#define T_WINT		27
-#define TP_WCHAR	28
-
-/*
- * Find all arguments when a positional parameter is encountered.  Returns a
- * table, indexed by argument number, of pointers to each arguments.  The
- * initial argument table should be an array of STATIC_ARG_TBL_SIZE entries.
- * It will be replaced with a mmap-ed one if it overflows (malloc cannot be
- * used since we are attempting to make snprintf thread safe, and alloca is
- * problematic since we have nested functions..)
- */
-static int
-__find_arguments(const wchar_t *fmt0, va_list ap, union arg **argtable,
-    size_t *argtablesiz)
-{
-	wchar_t *fmt;		/* format string */
-	int ch;			/* character from fmt */
-	int n, n2;		/* handy integer (short term usage) */
-	wchar_t *cp;		/* handy char pointer (short term usage) */
-	int flags;		/* flags as above */
-	unsigned char *typetable; /* table of types */
-	unsigned char stattypetable[STATIC_ARG_TBL_SIZE];
-	int tablesize;		/* current size of type table */
-	int tablemax;		/* largest used index in table */
-	int nextarg;		/* 1-based argument index */
-	int ret = 0;		/* return value */
-
-	/*
-	 * Add an argument type to the table, expanding if necessary.
-	 */
-#define ADDTYPE(type) \
-	((nextarg >= tablesize) ? \
-		__grow_type_table(&typetable, &tablesize) : 0, \
-	(nextarg > tablemax) ? tablemax = nextarg : 0, \
-	typetable[nextarg++] = type)
-
-#define	ADDSARG() \
-        ((flags&MAXINT) ? ADDTYPE(T_MAXINT) : \
-	    ((flags&PTRINT) ? ADDTYPE(T_PTRINT) : \
-	    ((flags&SIZEINT) ? ADDTYPE(T_SSIZEINT) : \
-	    ((flags&LLONGINT) ? ADDTYPE(T_LLONG) : \
-	    ((flags&LONGINT) ? ADDTYPE(T_LONG) : \
-	    ((flags&SHORTINT) ? ADDTYPE(T_SHORT) : \
-	    ((flags&CHARINT) ? ADDTYPE(T_CHAR) : ADDTYPE(T_INT))))))))
-
-#define	ADDUARG() \
-        ((flags&MAXINT) ? ADDTYPE(T_MAXUINT) : \
-	    ((flags&PTRINT) ? ADDTYPE(T_PTRINT) : \
-	    ((flags&SIZEINT) ? ADDTYPE(T_SIZEINT) : \
-	    ((flags&LLONGINT) ? ADDTYPE(T_U_LLONG) : \
-	    ((flags&LONGINT) ? ADDTYPE(T_U_LONG) : \
-	    ((flags&SHORTINT) ? ADDTYPE(T_U_SHORT) : \
-	    ((flags&CHARINT) ? ADDTYPE(T_U_CHAR) : ADDTYPE(T_U_INT))))))))
-
-	/*
-	 * Add * arguments to the type array.
-	 */
-#define ADDASTER() \
-	n2 = 0; \
-	cp = fmt; \
-	while (is_digit(*cp)) { \
-		APPEND_DIGIT(n2, *cp); \
-		cp++; \
-	} \
-	if (*cp == '$') { \
-		int hold = nextarg; \
-		nextarg = n2; \
-		ADDTYPE(T_INT); \
-		nextarg = hold; \
-		fmt = ++cp; \
-	} else { \
-		ADDTYPE(T_INT); \
-	}
-	fmt = (wchar_t *)fmt0;
-	typetable = stattypetable;
-	tablesize = STATIC_ARG_TBL_SIZE;
-	tablemax = 0;
-	nextarg = 1;
-	memset(typetable, T_UNUSED, STATIC_ARG_TBL_SIZE);
-
-	/*
-	 * Scan the format for conversions (`%' character).
-	 */
-	for (;;) {
-		for (cp = fmt; (ch = *fmt) != '\0' && ch != '%'; fmt++)
-			continue;
-		if (ch == '\0')
-			goto done;
-		fmt++;		/* skip over '%' */
-
-		flags = 0;
-
-rflag:		ch = *fmt++;
-reswitch:	switch (ch) {
-		case ' ':
-		case '#':
-		case '\'':
-			goto rflag;
-		case '*':
-			ADDASTER();
-			goto rflag;
-		case '-':
-		case '+':
-			goto rflag;
-		case '.':
-			if ((ch = *fmt++) == '*') {
-				ADDASTER();
-				goto rflag;
-			}
-			while (is_digit(ch)) {
-				ch = *fmt++;
-			}
-			goto reswitch;
-		case '0':
-			goto rflag;
-		case '1': case '2': case '3': case '4':
-		case '5': case '6': case '7': case '8': case '9':
-			n = 0;
-			do {
-				APPEND_DIGIT(n ,ch);
-				ch = *fmt++;
-			} while (is_digit(ch));
-			if (ch == '$') {
-				nextarg = n;
-				goto rflag;
-			}
-			goto reswitch;
-#ifdef FLOATING_POINT
-		case 'L':
-			flags |= LONGDBL;
-			goto rflag;
-#endif
-		case 'h':
-			if (*fmt == 'h') {
-				fmt++;
-				flags |= CHARINT;
-			} else {
-				flags |= SHORTINT;
-			}
-			goto rflag;
-		case 'l':
-			if (*fmt == 'l') {
-				fmt++;
-				flags |= LLONGINT;
-			} else {
-				flags |= LONGINT;
-			}
-			goto rflag;
-		case 'q':
-			flags |= LLONGINT;
-			goto rflag;
-		case 't':
-			flags |= PTRINT;
-			goto rflag;
-		case 'z':
-			flags |= SIZEINT;
-			goto rflag;
-		case 'C':
-			flags |= LONGINT;
-			/*FALLTHROUGH*/
-		case 'c':
-			if (flags & LONGINT)
-				ADDTYPE(T_WINT);
-			else
-				ADDTYPE(T_INT);
-			break;
-		case 'D':
-			flags |= LONGINT;
-			/*FALLTHROUGH*/
-		case 'd':
-		case 'i':
-			ADDSARG();
-			break;
-#ifdef FLOATING_POINT
-		case 'a':
-		case 'A':
-		case 'e':
-		case 'E':
-		case 'f':
-		case 'F':
-		case 'g':
-		case 'G':
-			if (flags & LONGDBL)
-				ADDTYPE(T_LONG_DOUBLE);
-			else
-				ADDTYPE(T_DOUBLE);
-			break;
-#endif /* FLOATING_POINT */
-#ifndef NO_PRINTF_PERCENT_N
-		case 'n':
-			if (flags & LLONGINT)
-				ADDTYPE(TP_LLONG);
-			else if (flags & LONGINT)
-				ADDTYPE(TP_LONG);
-			else if (flags & SHORTINT)
-				ADDTYPE(TP_SHORT);
-			else if (flags & PTRINT)
-				ADDTYPE(TP_PTRINT);
-			else if (flags & SIZEINT)
-				ADDTYPE(TP_SSIZEINT);
-			else if (flags & MAXINT)
-				ADDTYPE(TP_MAXINT);
-			else
-				ADDTYPE(TP_INT);
-			continue;	/* no output */
-#endif /* NO_PRINTF_PERCENT_N */
-		case 'O':
-			flags |= LONGINT;
-			/*FALLTHROUGH*/
-		case 'o':
-			ADDUARG();
-			break;
-		case 'p':
-			ADDTYPE(TP_VOID);
-			break;
-		case 'S':
-			flags |= LONGINT;
-			/*FALLTHROUGH*/
-		case 's':
-			if (flags & LONGINT)
-				ADDTYPE(TP_CHAR);
-			else
-				ADDTYPE(TP_WCHAR);
-			break;
-		case 'U':
-			flags |= LONGINT;
-			/*FALLTHROUGH*/
-		case 'u':
-		case 'X':
-		case 'x':
-			ADDUARG();
-			break;
-		default:	/* "%?" prints ?, unless ? is NUL */
-			if (ch == '\0')
-				goto done;
-			break;
-		}
-	}
-done:
-	/*
-	 * Build the argument table.
-	 */
-	if (tablemax >= STATIC_ARG_TBL_SIZE) {
-		*argtablesiz = sizeof(union arg) * (tablemax + 1);
-		*argtable = mmap(NULL, *argtablesiz,
-		    PROT_WRITE|PROT_READ, MAP_ANON|MAP_PRIVATE, -1, 0);
-		if (*argtable == MAP_FAILED)
-			return (-1);
-	}
-
-#if 0
-	/* XXX is this required? */
-	(*argtable)[0].intarg = 0;
-#endif
-	for (n = 1; n <= tablemax; n++) {
-		switch (typetable[n]) {
-		case T_UNUSED:
-		case T_CHAR:
-		case T_U_CHAR:
-		case T_SHORT:
-		case T_U_SHORT:
-		case T_INT:
-			(*argtable)[n].intarg = va_arg(ap, int);
-			break;
-		case TP_SHORT:
-			(*argtable)[n].pshortarg = va_arg(ap, short *);
-			break;
-		case T_U_INT:
-			(*argtable)[n].uintarg = va_arg(ap, unsigned int);
-			break;
-		case TP_INT:
-			(*argtable)[n].pintarg = va_arg(ap, int *);
-			break;
-		case T_LONG:
-			(*argtable)[n].longarg = va_arg(ap, long);
-			break;
-		case T_U_LONG:
-			(*argtable)[n].ulongarg = va_arg(ap, unsigned long);
-			break;
-		case TP_LONG:
-			(*argtable)[n].plongarg = va_arg(ap, long *);
-			break;
-		case T_LLONG:
-			(*argtable)[n].longlongarg = va_arg(ap, long long);
-			break;
-		case T_U_LLONG:
-			(*argtable)[n].ulonglongarg = va_arg(ap, unsigned long long);
-			break;
-		case TP_LLONG:
-			(*argtable)[n].plonglongarg = va_arg(ap, long long *);
-			break;
-#ifdef FLOATING_POINT
-		case T_DOUBLE:
-			(*argtable)[n].doublearg = va_arg(ap, double);
-			break;
-		case T_LONG_DOUBLE:
-			(*argtable)[n].longdoublearg = va_arg(ap, long double);
-			break;
-#endif
-		case TP_CHAR:
-			(*argtable)[n].pchararg = va_arg(ap, char *);
-			break;
-		case TP_VOID:
-			(*argtable)[n].pvoidarg = va_arg(ap, void *);
-			break;
-		case T_PTRINT:
-			(*argtable)[n].ptrdiffarg = va_arg(ap, ptrdiff_t);
-			break;
-		case TP_PTRINT:
-			(*argtable)[n].pptrdiffarg = va_arg(ap, ptrdiff_t *);
-			break;
-		case T_SIZEINT:
-			(*argtable)[n].sizearg = va_arg(ap, size_t);
-			break;
-		case T_SSIZEINT:
-			(*argtable)[n].ssizearg = va_arg(ap, ssize_t);
-			break;
-		case TP_SSIZEINT:
-			(*argtable)[n].pssizearg = va_arg(ap, ssize_t *);
-			break;
-		case TP_MAXINT:
-			(*argtable)[n].intmaxarg = va_arg(ap, intmax_t);
-			break;
-		case T_WINT:
-			(*argtable)[n].wintarg = va_arg(ap, wint_t);
-			break;
-		case TP_WCHAR:
-			(*argtable)[n].pwchararg = va_arg(ap, wchar_t *);
-			break;
-		}
-	}
-	goto finish;
-
-overflow:
-	errno = ENOMEM;
-	ret = -1;
-
-finish:
-	if (typetable != NULL && typetable != stattypetable) {
-		munmap(typetable, *argtablesiz);
-		typetable = NULL;
-	}
-	return (ret);
-}
-
-/*
- * Increase the size of the type table.
- */
-static int
-__grow_type_table(unsigned char **typetable, int *tablesize)
-{
-	unsigned char *oldtable = *typetable;
-	int newsize = *tablesize * 2;
-
-	if (newsize < getpagesize())
-		newsize = getpagesize();
-
-	if (*tablesize == STATIC_ARG_TBL_SIZE) {
-		*typetable = mmap(NULL, newsize, PROT_WRITE|PROT_READ,
-		    MAP_ANON|MAP_PRIVATE, -1, 0);
-		if (*typetable == MAP_FAILED)
-			return (-1);
-		bcopy(oldtable, *typetable, *tablesize);
-	} else {
-		unsigned char *new = mmap(NULL, newsize, PROT_WRITE|PROT_READ,
-		    MAP_ANON|MAP_PRIVATE, -1, 0);
-		if (new == MAP_FAILED)
-			return (-1);
-		memmove(new, *typetable, *tablesize);
-		munmap(*typetable, *tablesize);
-		*typetable = new;
-	}
-	memset(*typetable + *tablesize, T_UNUSED, (newsize - *tablesize));
-
-	*tablesize = newsize;
-	return (0);
-}
-
- 
-#ifdef FLOATING_POINT
-static int
-exponent(wchar_t *p0, int exp, int fmtch)
-{
-	wchar_t *p, *t;
-	wchar_t expbuf[MAXEXPDIG];
-
-	p = p0;
-	*p++ = fmtch;
-	if (exp < 0) {
-		exp = -exp;
-		*p++ = '-';
-	} else
-		*p++ = '+';
-	t = expbuf + MAXEXPDIG;
-	if (exp > 9) {
-		do {
-			*--t = to_char(exp % 10);
-		} while ((exp /= 10) > 9);
-		*--t = to_char(exp);
-		for (; t < expbuf + MAXEXPDIG; *p++ = *t++)
-			/* nothing */;
-	} else {
-		/*
-		 * Exponents for decimal floating point conversions
-		 * (%[eEgG]) must be at least two characters long,
-		 * whereas exponents for hexadecimal conversions can
-		 * be only one character long.
-		 */
-		if (fmtch == 'e' || fmtch == 'E')
-			*p++ = '0';
-		*p++ = to_char(exp);
-	}
-	return (p - p0);
-}
-#endif /* FLOATING_POINT */
diff --git a/libc/versioner-dependencies/arm/arch-arm b/libc/versioner-dependencies/arm/arch-arm
deleted file mode 120000
index cc94225..0000000
--- a/libc/versioner-dependencies/arm/arch-arm
+++ /dev/null
@@ -1 +0,0 @@
-../../arch-arm/include/
\ No newline at end of file
diff --git a/libc/versioner-dependencies/arm64/arch-arm64 b/libc/versioner-dependencies/arm64/arch-arm64
deleted file mode 120000
index 2d9128a..0000000
--- a/libc/versioner-dependencies/arm64/arch-arm64
+++ /dev/null
@@ -1 +0,0 @@
-../../arch-arm64/include/
\ No newline at end of file
diff --git a/libc/versioner-dependencies/mips/arch-mips b/libc/versioner-dependencies/mips/arch-mips
deleted file mode 120000
index 56ed021..0000000
--- a/libc/versioner-dependencies/mips/arch-mips
+++ /dev/null
@@ -1 +0,0 @@
-../../arch-mips/include/
\ No newline at end of file
diff --git a/libc/versioner-dependencies/mips64/arch-mips64 b/libc/versioner-dependencies/mips64/arch-mips64
deleted file mode 120000
index 4893b57..0000000
--- a/libc/versioner-dependencies/mips64/arch-mips64
+++ /dev/null
@@ -1 +0,0 @@
-../../arch-mips64/include/
\ No newline at end of file
diff --git a/libc/versioner-dependencies/x86/arch-x86 b/libc/versioner-dependencies/x86/arch-x86
deleted file mode 120000
index 6426384..0000000
--- a/libc/versioner-dependencies/x86/arch-x86
+++ /dev/null
@@ -1 +0,0 @@
-../../arch-x86/include/
\ No newline at end of file
diff --git a/libc/versioner-dependencies/x86_64/arch-x86_64 b/libc/versioner-dependencies/x86_64/arch-x86_64
deleted file mode 120000
index 684d74e..0000000
--- a/libc/versioner-dependencies/x86_64/arch-x86_64
+++ /dev/null
@@ -1 +0,0 @@
-../../arch-x86_64/include/
\ No newline at end of file
diff --git a/libdl/Android.bp b/libdl/Android.bp
index 9f67ee8..44daaec 100644
--- a/libdl/Android.bp
+++ b/libdl/Android.bp
@@ -1,6 +1,28 @@
 //
 // libdl
 //
+cc_library_static {
+    name: "libdl_static",
+
+    srcs: ["libdl.cpp", "libdl_cfi.cpp"],
+
+    cflags: [
+        "-Wall",
+        "-Wextra",
+        "-Wunused",
+        "-Werror",
+    ],
+
+    // For private/CFIShadow.h.
+    include_dirs: ["bionic/libc"],
+
+    stl: "none",
+
+    sanitize: {
+        never: true,
+    },
+}
+
 cc_library {
     name: "libdl",
 
@@ -45,7 +67,7 @@
         },
     },
     shared: {
-        srcs: ["libdl.c", "libdl_cfi.cpp"],
+        whole_static_libs: ["libdl_static"],
     },
     static: {
         srcs: [ "libdl_static.c" ],
@@ -66,9 +88,6 @@
     allow_undefined_symbols: true,
     system_shared_libs: [],
 
-    // For private/CFIShadow.h.
-    include_dirs: ["bionic/libc"],
-
     // This is placeholder library the actual implementation is (currently)
     // provided by the linker.
     shared_libs: [ "ld-android" ],
diff --git a/libdl/libdl.arm.map b/libdl/libdl.arm.map
index 9fc9d23..1fcfc58 100644
--- a/libdl/libdl.arm.map
+++ b/libdl/libdl.arm.map
@@ -34,11 +34,11 @@
     dlvsym; # introduced=24
 } LIBC;
 
-LIBC_OMR1 { # future
+LIBC_OMR1 { # introduced=27
   global:
-    __cfi_shadow_size; # future
-    __cfi_slowpath; # future
-    __cfi_slowpath_diag; # future
+    __cfi_shadow_size;
+    __cfi_slowpath;
+    __cfi_slowpath_diag;
 } LIBC_N;
 
 LIBC_PLATFORM {
diff --git a/libdl/libdl.arm64.map b/libdl/libdl.arm64.map
index bde6cab..8d4019c 100644
--- a/libdl/libdl.arm64.map
+++ b/libdl/libdl.arm64.map
@@ -33,11 +33,11 @@
     dlvsym; # introduced=24
 } LIBC;
 
-LIBC_OMR1 { # future
+LIBC_OMR1 { # introduced=27
   global:
-    __cfi_shadow_size; # future
-    __cfi_slowpath; # future
-    __cfi_slowpath_diag; # future
+    __cfi_shadow_size;
+    __cfi_slowpath;
+    __cfi_slowpath_diag;
 } LIBC_N;
 
 LIBC_PLATFORM {
diff --git a/libdl/libdl.c b/libdl/libdl.cpp
similarity index 93%
rename from libdl/libdl.c
rename to libdl/libdl.cpp
index 1a65b67..c834088 100644
--- a/libdl/libdl.c
+++ b/libdl/libdl.cpp
@@ -17,17 +17,18 @@
 #include <dlfcn.h>
 #include <link.h>
 #include <stdlib.h>
-#include <stdbool.h>
 #include <android/dlext.h>
 
 // These functions are exported by the loader
 // TODO(dimitry): replace these with reference to libc.so
 
+extern "C" {
+
 __attribute__((__weak__, visibility("default")))
 void* __loader_dlopen(const char* filename, int flags, const void* caller_addr);
 
 __attribute__((__weak__, visibility("default")))
-void* __loader_dlerror();
+char* __loader_dlerror();
 
 __attribute__((__weak__, visibility("default")))
 void* __loader_dlsym(void* handle, const char* symbol, const void* caller_addr);
@@ -98,34 +99,41 @@
 struct android_namespace_t* __loader_android_get_exported_namespace(const char* name);
 
 // Proxy calls to bionic loader
+__attribute__((__weak__))
 void* dlopen(const char* filename, int flag) {
   const void* caller_addr = __builtin_return_address(0);
   return __loader_dlopen(filename, flag, caller_addr);
 }
 
+__attribute__((__weak__))
 char* dlerror() {
   return __loader_dlerror();
 }
 
+__attribute__((__weak__))
 void* dlsym(void* handle, const char* symbol) {
   const void* caller_addr = __builtin_return_address(0);
   return __loader_dlsym(handle, symbol, caller_addr);
 }
 
+__attribute__((__weak__))
 void* dlvsym(void* handle, const char* symbol, const char* version) {
   const void* caller_addr = __builtin_return_address(0);
   return __loader_dlvsym(handle, symbol, version, caller_addr);
 }
 
+__attribute__((__weak__))
 int dladdr(const void* addr, Dl_info* info) {
   return __loader_dladdr(addr, info);
 }
 
+__attribute__((__weak__))
 int dlclose(void* handle) {
   return __loader_dlclose(handle);
 }
 
 #if defined(__arm__)
+__attribute__((__weak__))
 _Unwind_Ptr dl_unwind_find_exidx(_Unwind_Ptr pc, int* pcount) {
   return __loader_dl_unwind_find_exidx(pc, pcount);
 }
@@ -140,31 +148,39 @@
   return __loader_dl_iterate_phdr(cb, data);
 }
 
+__attribute__((__weak__))
 void android_get_LD_LIBRARY_PATH(char* buffer, size_t buffer_size) {
   __loader_android_get_LD_LIBRARY_PATH(buffer, buffer_size);
 }
 
+__attribute__((__weak__))
 void android_update_LD_LIBRARY_PATH(const char* ld_library_path) {
   __loader_android_update_LD_LIBRARY_PATH(ld_library_path);
 }
 
+__attribute__((__weak__))
 void* android_dlopen_ext(const char* filename, int flag, const android_dlextinfo* extinfo) {
   const void* caller_addr = __builtin_return_address(0);
   return __loader_android_dlopen_ext(filename, flag, extinfo, caller_addr);
 }
 
+__attribute__((__weak__))
 void android_set_application_target_sdk_version(uint32_t target) {
   __loader_android_set_application_target_sdk_version(target);
 }
+
+__attribute__((__weak__))
 uint32_t android_get_application_target_sdk_version() {
   return __loader_android_get_application_target_sdk_version();
 }
 
+__attribute__((__weak__))
 bool android_init_anonymous_namespace(const char* shared_libs_sonames,
                                       const char* library_search_path) {
   return __loader_android_init_anonymous_namespace(shared_libs_sonames, library_search_path);
 }
 
+__attribute__((__weak__))
 struct android_namespace_t* android_create_namespace(const char* name,
                                                      const char* ld_library_path,
                                                      const char* default_library_path,
@@ -181,16 +197,21 @@
                                            caller_addr);
 }
 
+__attribute__((__weak__))
 bool android_link_namespaces(struct android_namespace_t* namespace_from,
                              struct android_namespace_t* namespace_to,
                              const char* shared_libs_sonames) {
   return __loader_android_link_namespaces(namespace_from, namespace_to, shared_libs_sonames);
 }
 
+__attribute__((__weak__))
 void android_dlwarning(void* obj, void (*f)(void*, const char*)) {
   __loader_android_dlwarning(obj, f);
 }
 
+__attribute__((__weak__))
 struct android_namespace_t* android_get_exported_namespace(const char* name) {
   return __loader_android_get_exported_namespace(name);
 }
+
+} // extern "C"
diff --git a/libdl/libdl.map.txt b/libdl/libdl.map.txt
index d1f4ab8..002e9f8 100644
--- a/libdl/libdl.map.txt
+++ b/libdl/libdl.map.txt
@@ -33,11 +33,11 @@
     dlvsym; # introduced=24
 } LIBC;
 
-LIBC_OMR1 { # future
+LIBC_OMR1 { # introduced=27
   global:
-    __cfi_shadow_size; # future
-    __cfi_slowpath; # future
-    __cfi_slowpath_diag; # future
+    __cfi_shadow_size;
+    __cfi_slowpath;
+    __cfi_slowpath_diag;
 } LIBC_N;
 
 LIBC_PLATFORM {
diff --git a/libdl/libdl.mips.map b/libdl/libdl.mips.map
index bde6cab..8d4019c 100644
--- a/libdl/libdl.mips.map
+++ b/libdl/libdl.mips.map
@@ -33,11 +33,11 @@
     dlvsym; # introduced=24
 } LIBC;
 
-LIBC_OMR1 { # future
+LIBC_OMR1 { # introduced=27
   global:
-    __cfi_shadow_size; # future
-    __cfi_slowpath; # future
-    __cfi_slowpath_diag; # future
+    __cfi_shadow_size;
+    __cfi_slowpath;
+    __cfi_slowpath_diag;
 } LIBC_N;
 
 LIBC_PLATFORM {
diff --git a/libdl/libdl.mips64.map b/libdl/libdl.mips64.map
index bde6cab..8d4019c 100644
--- a/libdl/libdl.mips64.map
+++ b/libdl/libdl.mips64.map
@@ -33,11 +33,11 @@
     dlvsym; # introduced=24
 } LIBC;
 
-LIBC_OMR1 { # future
+LIBC_OMR1 { # introduced=27
   global:
-    __cfi_shadow_size; # future
-    __cfi_slowpath; # future
-    __cfi_slowpath_diag; # future
+    __cfi_shadow_size;
+    __cfi_slowpath;
+    __cfi_slowpath_diag;
 } LIBC_N;
 
 LIBC_PLATFORM {
diff --git a/libdl/libdl.x86.map b/libdl/libdl.x86.map
index bde6cab..8d4019c 100644
--- a/libdl/libdl.x86.map
+++ b/libdl/libdl.x86.map
@@ -33,11 +33,11 @@
     dlvsym; # introduced=24
 } LIBC;
 
-LIBC_OMR1 { # future
+LIBC_OMR1 { # introduced=27
   global:
-    __cfi_shadow_size; # future
-    __cfi_slowpath; # future
-    __cfi_slowpath_diag; # future
+    __cfi_shadow_size;
+    __cfi_slowpath;
+    __cfi_slowpath_diag;
 } LIBC_N;
 
 LIBC_PLATFORM {
diff --git a/libdl/libdl.x86_64.map b/libdl/libdl.x86_64.map
index bde6cab..8d4019c 100644
--- a/libdl/libdl.x86_64.map
+++ b/libdl/libdl.x86_64.map
@@ -33,11 +33,11 @@
     dlvsym; # introduced=24
 } LIBC;
 
-LIBC_OMR1 { # future
+LIBC_OMR1 { # introduced=27
   global:
-    __cfi_shadow_size; # future
-    __cfi_slowpath; # future
-    __cfi_slowpath_diag; # future
+    __cfi_shadow_size;
+    __cfi_slowpath;
+    __cfi_slowpath_diag;
 } LIBC_N;
 
 LIBC_PLATFORM {
diff --git a/libm/Android.bp b/libm/Android.bp
index bf86264..6d6fafa 100644
--- a/libm/Android.bp
+++ b/libm/Android.bp
@@ -210,11 +210,9 @@
         "sincos.c",
         "fake_long_double.c",
 
-        // Modified versions of BSD code.
-        "signbit.c",
-
         // Home-grown stuff.
-        "fabs.cpp",
+        "builtins.cpp",
+        "signbit.cpp",
     ],
 
     multilib: {
@@ -304,7 +302,6 @@
             srcs: [
                 "arm64/ceil.S",
                 "arm64/fenv.c",
-                "arm64/fma.S",
                 "arm64/floor.S",
                 "arm64/lrint.S",
                 "arm64/rint.S",
@@ -316,16 +313,22 @@
                 "upstream-freebsd/lib/msun/src/e_sqrtf.c",
                 "upstream-freebsd/lib/msun/src/s_ceil.c",
                 "upstream-freebsd/lib/msun/src/s_ceilf.c",
-                "upstream-freebsd/lib/msun/src/s_fma.c",
-                "upstream-freebsd/lib/msun/src/s_fmaf.c",
                 "upstream-freebsd/lib/msun/src/s_floor.c",
                 "upstream-freebsd/lib/msun/src/s_floorf.c",
+                "upstream-freebsd/lib/msun/src/s_fma.c",
+                "upstream-freebsd/lib/msun/src/s_fmaf.c",
+                "upstream-freebsd/lib/msun/src/s_fmax.c",
+                "upstream-freebsd/lib/msun/src/s_fmaxf.c",
+                "upstream-freebsd/lib/msun/src/s_fmin.c",
+                "upstream-freebsd/lib/msun/src/s_fminf.c",
                 "upstream-freebsd/lib/msun/src/s_llrint.c",
                 "upstream-freebsd/lib/msun/src/s_llrintf.c",
                 "upstream-freebsd/lib/msun/src/s_lrint.c",
                 "upstream-freebsd/lib/msun/src/s_lrintf.c",
                 "upstream-freebsd/lib/msun/src/s_rint.c",
                 "upstream-freebsd/lib/msun/src/s_rintf.c",
+                "upstream-freebsd/lib/msun/src/s_round.c",
+                "upstream-freebsd/lib/msun/src/s_roundf.c",
                 "upstream-freebsd/lib/msun/src/s_trunc.c",
                 "upstream-freebsd/lib/msun/src/s_truncf.c",
             ],
diff --git a/libm/arm/fenv.c b/libm/arm/fenv.c
index 2124730..c988e4f 100644
--- a/libm/arm/fenv.c
+++ b/libm/arm/fenv.c
@@ -28,9 +28,6 @@
 
 #include <fenv.h>
 
-#define FPSCR_ENABLE_SHIFT 8
-#define FPSCR_ENABLE_MASK  (FE_ALL_EXCEPT << FPSCR_ENABLE_SHIFT)
-
 #define FPSCR_RMODE_SHIFT 22
 
 const fenv_t __fe_dfl_env = 0;
@@ -103,7 +100,7 @@
   fenv_t __env;
   fegetenv(&__env);
   *__envp = __env;
-  __env &= ~(FE_ALL_EXCEPT | FPSCR_ENABLE_MASK);
+  __env &= ~FE_ALL_EXCEPT;
   fesetenv(&__env);
   return 0;
 }
@@ -116,24 +113,14 @@
   return 0;
 }
 
-int feenableexcept(int __mask) {
-  fenv_t __old_fpscr, __new_fpscr;
-  fegetenv(&__old_fpscr);
-  __new_fpscr = __old_fpscr | (__mask & FE_ALL_EXCEPT) << FPSCR_ENABLE_SHIFT;
-  fesetenv(&__new_fpscr);
-  return ((__old_fpscr >> FPSCR_ENABLE_SHIFT) & FE_ALL_EXCEPT);
+int feenableexcept(int __mask __unused) {
+  return -1;
 }
 
-int fedisableexcept(int __mask) {
-  fenv_t __old_fpscr, __new_fpscr;
-  fegetenv(&__old_fpscr);
-  __new_fpscr = __old_fpscr & ~((__mask & FE_ALL_EXCEPT) << FPSCR_ENABLE_SHIFT);
-  fesetenv(&__new_fpscr);
-  return ((__old_fpscr >> FPSCR_ENABLE_SHIFT) & FE_ALL_EXCEPT);
+int fedisableexcept(int __mask __unused) {
+  return 0;
 }
 
 int fegetexcept(void) {
-  fenv_t __fpscr;
-  fegetenv(&__fpscr);
-  return ((__fpscr & FPSCR_ENABLE_MASK) >> FPSCR_ENABLE_SHIFT);
+  return 0;
 }
diff --git a/libm/arm64/fenv.c b/libm/arm64/fenv.c
index 19a2393..a99288b 100644
--- a/libm/arm64/fenv.c
+++ b/libm/arm64/fenv.c
@@ -29,9 +29,6 @@
 #include <stdint.h>
 #include <fenv.h>
 
-#define FPCR_EXCEPT_SHIFT 8
-#define FPCR_EXCEPT_MASK  (FE_ALL_EXCEPT << FPCR_EXCEPT_SHIFT)
-
 #define FPCR_RMODE_SHIFT 22
 
 const fenv_t __fe_dfl_env = { 0 /* control */, 0 /* status */};
@@ -137,22 +134,13 @@
 }
 
 int feholdexcept(fenv_t* envp) {
-  fenv_t env;
   fpu_status_t fpsr;
-  fpu_control_t fpcr, new_fpcr;
-
   __get_fpsr(fpsr);
+  fpu_control_t fpcr;
   __get_fpcr(fpcr);
-  env.__status = fpsr;
-  env.__control = fpcr;
+  fenv_t env = { .__status = fpsr, .__control = fpcr };
   *envp = env;
 
-  // Set exceptions to untrapped.
-  new_fpcr = fpcr & ~(FE_ALL_EXCEPT << FPCR_EXCEPT_SHIFT);
-  if (new_fpcr != fpcr) {
-    __set_fpcr(new_fpcr);
-  }
-
   // Clear all exceptions.
   fpsr &= ~FE_ALL_EXCEPT;
   __set_fpsr(fpsr);
@@ -176,31 +164,14 @@
   return 0;
 }
 
-int feenableexcept(int mask) {
-  fpu_control_t old_fpcr, new_fpcr;
-
-  __get_fpcr(old_fpcr);
-  new_fpcr = old_fpcr | ((mask & FE_ALL_EXCEPT) << FPCR_EXCEPT_SHIFT);
-  if (new_fpcr != old_fpcr) {
-    __set_fpcr(new_fpcr);
-  }
-  return ((old_fpcr >> FPCR_EXCEPT_SHIFT) & FE_ALL_EXCEPT);
+int feenableexcept(int mask __unused) {
+  return -1;
 }
 
-int fedisableexcept(int mask) {
-  fpu_control_t old_fpcr, new_fpcr;
-
-  __get_fpcr(old_fpcr);
-  new_fpcr = old_fpcr & ~((mask & FE_ALL_EXCEPT) << FPCR_EXCEPT_SHIFT);
-  if (new_fpcr != old_fpcr) {
-    __set_fpcr(new_fpcr);
-  }
-  return ((old_fpcr >> FPCR_EXCEPT_SHIFT) & FE_ALL_EXCEPT);
+int fedisableexcept(int mask __unused) {
+  return 0;
 }
 
 int fegetexcept(void) {
-  fpu_control_t fpcr;
-
-  __get_fpcr(fpcr);
-  return ((fpcr & FPCR_EXCEPT_MASK) >> FPCR_EXCEPT_SHIFT);
+  return 0;
 }
diff --git a/libm/fabs.cpp b/libm/builtins.cpp
similarity index 69%
rename from libm/fabs.cpp
rename to libm/builtins.cpp
index add73fe..2ea6305 100644
--- a/libm/fabs.cpp
+++ b/libm/builtins.cpp
@@ -44,3 +44,17 @@
   return fabs(x);
 }
 #endif
+
+#if defined(__aarch64__)
+float fmaf(float x, float y, float z) { return __builtin_fmaf(x, y, z); }
+double fma(double x, double y, double z) { return __builtin_fma(x, y, z); }
+
+float fmaxf(float x, float y) { return __builtin_fmaxf(x, y); }
+double fmax(double x, double y) { return __builtin_fmax(x, y); }
+
+float fminf(float x, float y) { return __builtin_fminf(x, y); }
+double fmin(double x, double y) { return __builtin_fmin(x, y); }
+
+float roundf(float x) { return __builtin_roundf(x); }
+double round(double x) { return __builtin_round(x); }
+#endif
diff --git a/libm/libm.arm.map b/libm/libm.arm.map
index 7e3175d..bee08d4 100644
--- a/libm/libm.arm.map
+++ b/libm/libm.arm.map
@@ -272,7 +272,7 @@
     *;
 };
 
-LIBC_O {
+LIBC_O { # introduced=O
   global:
     cacoshl;
     cacosl;
diff --git a/libm/libm.arm64.map b/libm/libm.arm64.map
index 3e259dd..550c39b 100644
--- a/libm/libm.arm64.map
+++ b/libm/libm.arm64.map
@@ -272,7 +272,7 @@
     *;
 };
 
-LIBC_O {
+LIBC_O { # introduced=O
   global:
     cacoshl;
     cacosl;
diff --git a/libm/libm.mips.map b/libm/libm.mips.map
index b368d41..0b6dc02 100644
--- a/libm/libm.mips.map
+++ b/libm/libm.mips.map
@@ -272,7 +272,7 @@
     *;
 };
 
-LIBC_O {
+LIBC_O { # introduced=O
   global:
     cacoshl;
     cacosl;
diff --git a/libm/libm.mips64.map b/libm/libm.mips64.map
index 3e259dd..550c39b 100644
--- a/libm/libm.mips64.map
+++ b/libm/libm.mips64.map
@@ -272,7 +272,7 @@
     *;
 };
 
-LIBC_O {
+LIBC_O { # introduced=O
   global:
     cacoshl;
     cacosl;
diff --git a/libm/libm.x86.map b/libm/libm.x86.map
index 3e259dd..550c39b 100644
--- a/libm/libm.x86.map
+++ b/libm/libm.x86.map
@@ -272,7 +272,7 @@
     *;
 };
 
-LIBC_O {
+LIBC_O { # introduced=O
   global:
     cacoshl;
     cacosl;
diff --git a/libm/libm.x86_64.map b/libm/libm.x86_64.map
index 3e259dd..550c39b 100644
--- a/libm/libm.x86_64.map
+++ b/libm/libm.x86_64.map
@@ -272,7 +272,7 @@
     *;
 };
 
-LIBC_O {
+LIBC_O { # introduced=O
   global:
     cacoshl;
     cacosl;
diff --git a/libm/signbit.c b/libm/signbit.c
deleted file mode 100644
index b98bf45..0000000
--- a/libm/signbit.c
+++ /dev/null
@@ -1,59 +0,0 @@
-/*-
- * Copyright (c) 2003 Mike Barcroft <mike@FreeBSD.org>
- * 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.
- *
- * THIS SOFTWARE IS PROVIDED BY THE AUTHOR 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 AUTHOR 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.
- *
- * $FreeBSD$
- */
-
-#include <math.h>
-
-#include "fpmath.h"
-
-int __signbit(double d)
-{
-  union IEEEd2bits u;
-
-  u.d = d;
-  return (u.bits.sign);
-}
-
-int __signbitf(float f)
-{
-  union IEEEf2bits u;
-
-  u.f = f;
-  return (u.bits.sign);
-}
-
-#ifdef __LP64__
-int __signbitl(long double e)
-{
-  union IEEEl2bits u;
-
-  u.e = e;
-  return (u.bits.sign);
-}
-#else // __LP32__
-__weak_reference(__signbit, __signbitl);
-#endif // __LP64__
diff --git a/libc/arch-mips/include/sgidefs.h b/libm/signbit.cpp
similarity index 77%
rename from libc/arch-mips/include/sgidefs.h
rename to libm/signbit.cpp
index 8b37bf0..b2a5d60 100644
--- a/libc/arch-mips/include/sgidefs.h
+++ b/libm/signbit.cpp
@@ -1,5 +1,5 @@
 /*
- * Copyright (C) 2014 The Android Open Source Project
+ * Copyright (C) 2017 The Android Open Source Project
  * All rights reserved.
  *
  * Redistribution and use in source and binary forms, with or without
@@ -26,9 +26,19 @@
  * SUCH DAMAGE.
  */
 
-#ifndef _SGIDEFS_H_
-#define _SGIDEFS_H_
+#include <math.h>
 
-#include <asm/sgidefs.h>
+// Legacy cruft from before we had builtin implementations of the standard macros.
+// No longer declared in our <math.h>.
 
-#endif /* _SGIDEFS_H_ */
+extern "C" int __signbit(double d) {
+  return signbit(d);
+}
+
+extern "C" int __signbitf(float f) {
+  return signbit(f);
+}
+
+extern "C" int __signbitl(long double ld) {
+  return signbit(ld);
+}
diff --git a/linker/Android.bp b/linker/Android.bp
index 9125fd6..f802f45 100644
--- a/linker/Android.bp
+++ b/linker/Android.bp
@@ -6,6 +6,7 @@
         "linker_allocator.cpp",
         "linker_memory.cpp",
     ],
+    cflags: ["-Wall", "-Werror"],
 
     // We need to access Bionic private headers in the linker.
     include_dirs: ["bionic/libc"],
@@ -26,7 +27,7 @@
     device_supported: false,
     target: {
         linux_bionic: { enabled: true },
-        linux: { enabled: false },
+        linux_glibc: { enabled: false },
         darwin: { enabled: false },
     },
 
diff --git a/linker/arch/arm/begin.S b/linker/arch/arm/begin.S
index 480047a..80d9fe1 100644
--- a/linker/arch/arm/begin.S
+++ b/linker/arch/arm/begin.S
@@ -29,6 +29,9 @@
 #include <private/bionic_asm.h>
 
 ENTRY(_start)
+  // Force unwinds to end in this function.
+  .cfi_undefined r14
+
   mov r0, sp
   bl __linker_init
 
diff --git a/linker/arch/arm64/begin.S b/linker/arch/arm64/begin.S
index a6ea583..a947475 100644
--- a/linker/arch/arm64/begin.S
+++ b/linker/arch/arm64/begin.S
@@ -29,6 +29,9 @@
 #include <private/bionic_asm.h>
 
 ENTRY(_start)
+  // Force unwinds to end in this function.
+  .cfi_undefined x30
+
   mov x0, sp
   bl __linker_init
 
diff --git a/linker/arch/mips64/begin.S b/linker/arch/mips64/begin.S
index b9637e7..60169b4 100644
--- a/linker/arch/mips64/begin.S
+++ b/linker/arch/mips64/begin.S
@@ -54,38 +54,38 @@
      nop
 1:
 #if (_MIPS_SIM == _ABIO32) || (_MIPS_SIM == _ABI32)
-    .cpload	ra
+    .cpload	$ra
 #else
-    .cpsetup	ra, $0, 1b
+    .cpsetup	$ra, $0, 1b
 #endif
     .set	reorder
 
     /* Discover the load address */
-    LA		t0, 1b
-    PTR_SUBU	t0, ra, t0
+    LA		$t0, 1b
+    PTR_SUBU	$t0, $ra, $t0
 
 #define DT_PLTGOT 3
 #define DT_MIPS_LOCAL_GOTNO 0x7000000a
 
     /* Search dynamic table for DT_MIPS_LOCAL_GOTNO and DT_PLTGOT values */
-    LA		t1, _DYNAMIC
-    PTR_ADDU	t1, t0
-    LI		t3, DT_PLTGOT
-    LI		ta0, DT_MIPS_LOCAL_GOTNO
+    LA		$t1, _DYNAMIC
+    PTR_ADDU	$t1, $t0
+    LI		$t3, DT_PLTGOT
+    LI		$ta0, DT_MIPS_LOCAL_GOTNO
 0:
-    REG_L	t2, ELF_DYN_TAG(t1)
-    beqz	t2, .Lrelocate_local_got
+    REG_L	$t2, ELF_DYN_TAG($t1)
+    beqz	$t2, .Lrelocate_local_got
 
-    bne		t2, t3, 1f	/* DT_PLTGOT? */
-    REG_L	s0, ELF_DYN_VAL(t1)
-    PTR_ADDU	s0, t0
+    bne		$t2, $t3, 1f	/* DT_PLTGOT? */
+    REG_L	$s0, ELF_DYN_VAL($t1)
+    PTR_ADDU	$s0, $t0
     b		2f
 
 1:
-    bne		t2, ta0, 2f    /* DT_MIPS_LOCAL_GOTNO? */
-    REG_L	s1, ELF_DYN_VAL(t1)
+    bne		$t2, $ta0, 2f    /* DT_MIPS_LOCAL_GOTNO? */
+    REG_L	$s1, ELF_DYN_VAL($t1)
 
-2:  PTR_ADDU    t1, ELF_DYNSZ
+2:  PTR_ADDU    $t1, ELF_DYNSZ
     b		0b
 
 .Lrelocate_local_got:
@@ -95,30 +95,30 @@
      * got[1] may be used for a GNU extension
      */
 
-    PTR_ADDU	s0, GOTENT_SZ
-    SUBU	s1, 1
-    PTR_L	t1, (s0)
-    bgez	t1, 9f
-    PTR_ADDU	s0, GOTENT_SZ
-    SUBU	s1, 1
+    PTR_ADDU	$s0, GOTENT_SZ
+    SUBU	$s1, 1
+    PTR_L	$t1, ($s0)
+    bgez	$t1, 9f
+    PTR_ADDU	$s0, GOTENT_SZ
+    SUBU	$s1, 1
     b		9f
 
-1:  PTR_L	t1, (s0)
-    PTR_ADDU	t1, t0
-    PTR_S	t1, (s0)
-    PTR_ADDU	s0, GOTENT_SZ
-9:  SUBU	s1, 1
-    bgez	s1, 1b
+1:  PTR_L	$t1, ($s0)
+    PTR_ADDU	$t1, $t0
+    PTR_S	$t1, ($s0)
+    PTR_ADDU	$s0, GOTENT_SZ
+9:  SUBU	$s1, 1
+    bgez	$s1, 1b
 
     /* call linker_init */
-    move	a0, sp
+    move	$a0, $sp
 #if (_MIPS_SIM == _ABIO32) || (_MIPS_SIM == _ABI32)
-    PTR_SUBU	sp, 4*REGSZ       /* space for arg saves in linker_init */
+    PTR_SUBU	$sp, 4*REGSZ       /* space for arg saves in linker_init */
 #endif
     jal		__linker_init
 #if (_MIPS_SIM == _ABIO32) || (_MIPS_SIM == _ABI32)
-    PTR_ADDU	sp, 4*REGSZ        /* restore sp */
+    PTR_ADDU	$sp, 4*REGSZ        /* restore sp */
 #endif
-    move	t9, v0
-    j		t9
+    move	$t9, $v0
+    j		$t9
     .end    __start
diff --git a/linker/arch/x86/begin.c b/linker/arch/x86/begin.c
index a734f25..331b79e 100644
--- a/linker/arch/x86/begin.c
+++ b/linker/arch/x86/begin.c
@@ -32,6 +32,9 @@
 extern unsigned __linker_init(void* raw_args);
 
 __LIBC_HIDDEN__ void _start() {
+  // Force unwinds to end in this function.
+  asm volatile(".cfi_undefined \%eip");
+
   void (*start)(void);
 
   void* raw_args = (void*) ((uintptr_t) __builtin_frame_address(0) + sizeof(void*));
diff --git a/linker/arch/x86_64/begin.S b/linker/arch/x86_64/begin.S
index 7945a31..4722301 100644
--- a/linker/arch/x86_64/begin.S
+++ b/linker/arch/x86_64/begin.S
@@ -29,6 +29,9 @@
 #include <private/bionic_asm.h>
 
 ENTRY(_start)
+  // Force unwinds to end in this function.
+  .cfi_undefined %rip
+
   mov %rsp, %rdi
   call __linker_init
 
diff --git a/linker/linker.cpp b/linker/linker.cpp
index f6ca430..85376e0 100644
--- a/linker/linker.cpp
+++ b/linker/linker.cpp
@@ -1433,6 +1433,8 @@
 
   if (search_linked_namespaces) {
     // if a library was not found - look into linked namespaces
+    // preserve current dlerror in the case it fails.
+    DlErrorRestorer dlerror_restorer;
     for (auto& linked_namespace : ns->linked_namespaces()) {
       if (find_library_in_linked_namespace(linked_namespace,
                                            task)) {
@@ -1621,11 +1623,13 @@
   }
 
   // Step 4-3: Add the new global group members to all the linked namespaces
-  for (auto si : new_global_group_members) {
+  if (namespaces != nullptr) {
     for (auto linked_ns : *namespaces) {
-      if (si->get_primary_namespace() != linked_ns) {
-        linked_ns->add_soinfo(si);
-        si->add_secondary_namespace(linked_ns);
+      for (auto si : new_global_group_members) {
+        if (si->get_primary_namespace() != linked_ns) {
+          linked_ns->add_soinfo(si);
+          si->add_secondary_namespace(linked_ns);
+        }
       }
     }
   }
@@ -1723,15 +1727,23 @@
   return si;
 }
 
-static void soinfo_unload(soinfo* root) {
-  if (root->is_linked()) {
-    root = root->get_local_group_root();
-  }
+static void soinfo_unload(soinfo* si) {
+  soinfo* root = si->is_linked() ? si->get_local_group_root() : si;
+
+  LD_LOG(kLogDlopen,
+         "... dlclose(realpath=\"%s\"@%p) ... load group root is \"%s\"@%p",
+         si->get_realpath(),
+         si,
+         root->get_realpath(),
+         root);
 
   ScopedTrace trace((std::string("unload ") + root->get_realpath()).c_str());
 
   if (!root->can_unload()) {
-    TRACE("not unloading \"%s\" - the binary is flagged with NODELETE", root->get_realpath());
+    LD_LOG(kLogDlopen,
+           "... dlclose(root=\"%s\"@%p) ... not unloading - the load group is flagged with NODELETE",
+           root->get_realpath(),
+           root);
     return;
   }
 
@@ -1758,11 +1770,17 @@
       if (ref_count == 0) {
         unload_list.push_back(si);
       } else {
-        TRACE("not unloading '%s' group, decrementing ref_count to %zd",
-            si->get_realpath(), ref_count);
+        LD_LOG(kLogDlopen,
+               "... dlclose(root=\"%s\"@%p) ... not unloading - decrementing ref_count to %zd",
+               si->get_realpath(),
+               si,
+               ref_count);
       }
     } else {
-      TRACE("not unloading '%s' - the binary is flagged with NODELETE", si->get_realpath());
+      LD_LOG(kLogDlopen,
+             "... dlclose(root=\"%s\"@%p) ... not unloading - the load group is flagged with NODELETE",
+             si->get_realpath(),
+             si);
       return;
     }
   }
@@ -1833,16 +1851,32 @@
   }
 
   local_unload_list.for_each([](soinfo* si) {
+    LD_LOG(kLogDlopen,
+           "... dlclose: calling destructors for \"%s\"@%p ... ",
+           si->get_realpath(),
+           si);
     si->call_destructors();
+    LD_LOG(kLogDlopen,
+           "... dlclose: calling destructors for \"%s\"@%p ... done",
+           si->get_realpath(),
+           si);
   });
 
   while ((si = local_unload_list.pop_front()) != nullptr) {
+    LD_LOG(kLogDlopen,
+           "... dlclose: unloading \"%s\"@%p ...",
+           si->get_realpath(),
+           si);
     notify_gdb_of_unload(si);
     get_cfi_shadow()->BeforeUnload(si);
     soinfo_free(si);
   }
 
   while ((si = external_unload_list.pop_front()) != nullptr) {
+    LD_LOG(kLogDlopen,
+           "... dlclose: unloading external reference \"%s\"@%p ...",
+           si->get_realpath(),
+           si);
     soinfo_unload(si);
   }
 }
@@ -2128,7 +2162,15 @@
     return -1;
   }
 
+  LD_LOG(kLogDlopen,
+         "dlclose(handle=%p, realpath=\"%s\"@%p) ...",
+         handle,
+         si->get_realpath(),
+         si);
   soinfo_unload(si);
+  LD_LOG(kLogDlopen,
+         "dlclose(handle=%p) ... done",
+         handle);
   return 0;
 }
 
diff --git a/linker/linker_allocator.h b/linker/linker_allocator.h
index 9c16828..7fc6cbf 100644
--- a/linker/linker_allocator.h
+++ b/linker/linker_allocator.h
@@ -29,6 +29,7 @@
 #ifndef __LINKER_ALLOCATOR_H
 #define __LINKER_ALLOCATOR_H
 
+#include <errno.h>
 #include <stdlib.h>
 #include <sys/cdefs.h>
 #include <sys/mman.h>
diff --git a/linker/linker_config.cpp b/linker/linker_config.cpp
index 2bdde1e..f7d2c53 100644
--- a/linker/linker_config.cpp
+++ b/linker/linker_config.cpp
@@ -43,6 +43,9 @@
 #include <string>
 #include <unordered_map>
 
+#define _REALLY_INCLUDE_SYS__SYSTEM_PROPERTIES_H_
+#include <sys/_system_properties.h>
+
 class ConfigParser {
  public:
   enum {
@@ -275,6 +278,15 @@
   return true;
 }
 
+static std::string getVndkVersionString() {
+  char vndk_version_str[1 + PROP_VALUE_MAX] = {};
+  __system_property_get("ro.vndk.version", vndk_version_str + 1);
+  if (strlen(vndk_version_str + 1) != 0 && strcmp(vndk_version_str + 1, "current") != 0) {
+    vndk_version_str[0] = '-';
+  }
+  return vndk_version_str;
+}
+
 static Config g_config;
 
 static constexpr const char* kDefaultConfigName = "default";
@@ -320,7 +332,7 @@
     return (it == properties_.end()) ? "" : it->second.value();
   }
 
-  std::vector<std::string> get_paths(const std::string& name, size_t* lineno = nullptr) {
+  std::vector<std::string> get_paths(const std::string& name, bool resolve, size_t* lineno = nullptr) {
     std::string paths_str = get_string(name, lineno);
 
     std::vector<std::string> paths;
@@ -334,16 +346,23 @@
       params.push_back({ "SDK_VER", buf });
     }
 
+    static std::string vndk = getVndkVersionString();
+    params.push_back({ "VNDK_VER", vndk });
+
     for (auto&& path : paths) {
       format_string(&path, params);
     }
 
-    std::vector<std::string> resolved_paths;
+    if (resolve) {
+      std::vector<std::string> resolved_paths;
 
-    // do not remove paths that do not exist
-    resolve_paths(paths, &resolved_paths);
+      // do not remove paths that do not exist
+      resolve_paths(paths, &resolved_paths);
 
-    return resolved_paths;
+      return resolved_paths;
+    } else {
+      return paths;
+    }
   }
 
   void set_target_sdk_version(int target_sdk_version) {
@@ -371,15 +390,6 @@
                                       bool is_asan,
                                       const Config** config,
                                       std::string* error_msg) {
-  // TODO(b/38114603) Currently, multiple namespaces does not support ASAN mode
-  // where some symbols should be intercepted via LD_PRELOAD; LD_PRELOADed libs
-  // are not being preloaded into the linked namespaces other than the default
-  // namespace. Until we fix the problem, we temporarily disable ld.config.txt
-  // in ASAN mode.
-  if (is_asan) {
-    return false;
-  }
-
   g_config.clear();
 
   std::unordered_map<std::string, PropertyValue> property_map;
@@ -474,8 +484,18 @@
       property_name_prefix += ".asan";
     }
 
-    ns_config->set_search_paths(properties.get_paths(property_name_prefix + ".search.paths"));
-    ns_config->set_permitted_paths(properties.get_paths(property_name_prefix + ".permitted.paths"));
+    // search paths are resolved (canonicalized). This is required mainly for
+    // the case when /vendor is a symlink to /system/vendor, which is true for
+    // non Treble-ized legacy devices.
+    ns_config->set_search_paths(properties.get_paths(property_name_prefix + ".search.paths", true));
+
+    // However, for permitted paths, we are not required to resolve the paths
+    // since they are only set for isolated namespaces, which implies the device
+    // is Treble-ized (= /vendor is not a symlink to /system/vendor).
+    // In fact, the resolving is causing an unexpected side effect of selinux
+    // denials on some executables which are not allowed to access some of the
+    // permitted paths.
+    ns_config->set_permitted_paths(properties.get_paths(property_name_prefix + ".permitted.paths", false));
   }
 
   failure_guard.Disable();
diff --git a/linker/linker_globals.h b/linker/linker_globals.h
index d8134af..11ccbd5 100644
--- a/linker/linker_globals.h
+++ b/linker/linker_globals.h
@@ -32,6 +32,7 @@
 #include <link.h>
 #include <stddef.h>
 
+#include <string>
 #include <unordered_map>
 
 #include <async_safe/log.h>
@@ -39,7 +40,6 @@
 #define DL_ERR(fmt, x...) \
     do { \
       async_safe_format_buffer(linker_get_error_buffer(), linker_get_error_buffer_size(), fmt, ##x); \
-      /* If LD_DEBUG is set high enough, log every dlerror(3) message. */ \
     } while (false)
 
 #define DL_WARN(fmt, x...) \
@@ -75,4 +75,16 @@
 char* linker_get_error_buffer();
 size_t linker_get_error_buffer_size();
 
+class DlErrorRestorer {
+ public:
+  DlErrorRestorer() {
+    saved_error_msg_ = linker_get_error_buffer();
+  }
+  ~DlErrorRestorer() {
+    strlcpy(linker_get_error_buffer(), saved_error_msg_.c_str(), linker_get_error_buffer_size());
+  }
+ private:
+  std::string saved_error_msg_;
+};
+
 #endif  /* __LINKER_GLOBALS_H */
diff --git a/linker/linker_main.cpp b/linker/linker_main.cpp
index 3862d8c..317f0d2 100644
--- a/linker/linker_main.cpp
+++ b/linker/linker_main.cpp
@@ -129,9 +129,9 @@
   if (path != nullptr) {
     // We have historically supported ':' as well as ' ' in LD_PRELOAD.
     g_ld_preload_names = android::base::Split(path, " :");
-    std::remove_if(g_ld_preload_names.begin(),
-                   g_ld_preload_names.end(),
-                   [] (const std::string& s) { return s.empty(); });
+    g_ld_preload_names.erase(std::remove_if(g_ld_preload_names.begin(), g_ld_preload_names.end(),
+                                            [](const std::string& s) { return s.empty(); }),
+                             g_ld_preload_names.end());
   }
 }
 
@@ -154,6 +154,10 @@
 
   si->prelink_image();
   si->link_image(g_empty_list, soinfo_list_t::make_list(si), nullptr);
+  // prevents accidental unloads...
+  si->set_dt_flags_1(si->get_dt_flags_1() | DF_1_NODELETE);
+  si->set_linked();
+  si->call_constructors();
 }
 
 /* gdb expects the linker to be in the debug shared object list.
@@ -204,7 +208,17 @@
 #endif
 
 static void __linker_cannot_link(const char* argv0) {
-  async_safe_fatal("CANNOT LINK EXECUTABLE \"%s\": %s", argv0, linker_get_error_buffer());
+  async_safe_format_fd(STDERR_FILENO,
+                       "CANNOT LINK EXECUTABLE \"%s\": %s\n",
+                       argv0,
+                       linker_get_error_buffer());
+
+  async_safe_format_log(ANDROID_LOG_FATAL,
+                        "linker",
+                        "CANNOT LINK EXECUTABLE \"%s\": %s",
+                        argv0,
+                        linker_get_error_buffer());
+  _exit(EXIT_FAILURE);
 }
 
 /*
@@ -352,6 +366,8 @@
     }
   }
 
+  add_vdso(args);
+
   // Load ld_preloads and dependencies.
   std::vector<const char*> needed_library_name_list;
   size_t ld_preloads_count = 0;
@@ -393,8 +409,6 @@
     si->increment_ref_count();
   }
 
-  add_vdso(args);
-
   if (!get_cfi_shadow()->InitialLinkDone(solist)) __linker_cannot_link(g_argv[0]);
 
   si->call_pre_init_constructors();
diff --git a/linker/linker_mips.cpp b/linker/linker_mips.cpp
index cd392dc..71a96e6 100644
--- a/linker/linker_mips.cpp
+++ b/linker/linker_mips.cpp
@@ -142,13 +142,12 @@
 
   // got[0] is the address of the lazy resolver function.
   // got[1] may be used for a GNU extension.
-  // Set it to a recognizable address in case someone calls it (should be _rtld_bind_start).
   // FIXME: maybe this should be in a separate routine?
   if ((flags_ & FLAG_LINKER) == 0) {
-    size_t g = 0;
-    got[g++] = reinterpret_cast<ElfW(Addr)*>(0xdeadbeef);
+    size_t g = 1;
+    // Check for the high bit to determine whether to skip got[1]
     if (reinterpret_cast<intptr_t>(got[g]) < 0) {
-      got[g++] = reinterpret_cast<ElfW(Addr)*>(0xdeadfeed);
+      g++;
     }
     // Relocate the local GOT entries.
     for (; g < mips_local_gotno_; g++) {
@@ -231,6 +230,7 @@
 #define MIPS_AFL_FLAGS1_ODDSPREG 1  // Uses odd-numbered single-prec fp regs
 
 // Some values of fp_abi:        via compiler flag:
+#define MIPS_ABI_FP_ANY    0  // Not tagged or not using any ABIs affected by the differences.
 #define MIPS_ABI_FP_DOUBLE 1  // -mdouble-float
 #define MIPS_ABI_FP_XX     5  // -mfpxx
 #define MIPS_ABI_FP_64A    7  // -mips32r* -mfp64 -mno-odd-spreg
@@ -277,6 +277,7 @@
 #if __mips_isa_rev >= 5
         mips_fpabi == MIPS_ABI_FP_64A    ||
 #endif
+        mips_fpabi == MIPS_ABI_FP_ANY    ||
         mips_fpabi == MIPS_ABI_FP_XX       )) {
     DL_ERR("Unsupported MIPS32 FloatPt ABI %d found in \"%s\"",
            mips_fpabi, get_realpath());
diff --git a/linker/tests/linker_config_test.cpp b/linker/tests/linker_config_test.cpp
index 87609d0..c6fade9 100644
--- a/linker/tests/linker_config_test.cpp
+++ b/linker/tests/linker_config_test.cpp
@@ -168,7 +168,6 @@
   run_linker_config_smoke_test(false);
 }
 
-// TODO(b/38114603) revive this test when ld.config.txt is enabled for ASAN mode
-//TEST(linker_config, asan_smoke) {
-//  run_linker_config_smoke_test(true);
-//}
+TEST(linker_config, asan_smoke) {
+  run_linker_config_smoke_test(true);
+}
diff --git a/tests/Android.bp b/tests/Android.bp
index 3731156..c045c1e 100644
--- a/tests/Android.bp
+++ b/tests/Android.bp
@@ -71,6 +71,7 @@
         "ftw_test.cpp",
         "getauxval_test.cpp",
         "getcwd_test.cpp",
+        "glob_test.cpp",
         "grp_pwd_test.cpp",
         "iconv_test.cpp",
         "ifaddrs_test.cpp",
@@ -95,7 +96,6 @@
         "nl_types_test.cpp",
         "pthread_test.cpp",
         "pty_test.cpp",
-        "qsort_test.cpp",
         "regex_test.cpp",
         "resolv_test.cpp",
         "sched_test.cpp",
@@ -104,6 +104,7 @@
         "semaphore_test.cpp",
         "setjmp_test.cpp",
         "signal_test.cpp",
+        "spawn_test.cpp",
         "stack_protector_test.cpp",
         "stack_protector_test_helper.cpp",
         "stack_unwinding_test.cpp",
@@ -131,6 +132,7 @@
         "sys_procfs_test.cpp",
         "sys_ptrace_test.cpp",
         "sys_quota_test.cpp",
+        "sys_random_test.cpp",
         "sys_resource_test.cpp",
         "sys_select_test.cpp",
         "sys_sem_test.cpp",
@@ -167,7 +169,7 @@
     ],
 
     target: {
-        android: {
+        bionic: {
             whole_static_libs: ["libasync_safe"],
         },
     },
@@ -177,7 +179,6 @@
         "liblog",
         "libbase",
     ],
-    host_ldlibs: ["-lrt"],
     shared: {
         enabled: false,
     },
@@ -192,7 +193,6 @@
 cc_defaults {
     name: "bionic_fortify_tests_defaults",
     cflags: [
-        "-Wno-error",
         "-U_FORTIFY_SOURCE",
     ],
     srcs: ["fortify_test_main.cpp"],
@@ -219,7 +219,21 @@
     ],
     // Ignore that we don't have ASAN symbols linked in.
     allow_undefined_symbols: true,
-    srcs: ["fortify_compilation_test.cpp"],
+    srcs: ["fortify_filecheck_diagnostics_test.cpp"],
+}
+
+// Ensure we don't use FORTIFY'ed functions with the static analyzer/clang-tidy:
+// it can confuse these tools pretty easily. If this builds successfully, then
+// __clang_analyzer__ overrode FORTIFY. Otherwise, FORTIFY was incorrectly
+// enabled. The library that results from building this is meant to be unused.
+cc_test_library {
+    name: "fortify_disabled_for_tidy",
+    cflags: [
+        "-Werror",
+        "-D_FORTIFY_SOURCE=2",
+        "-D__clang_analyzer__",
+    ],
+    srcs: ["fortify_filecheck_diagnostics_test.cpp"],
 }
 
 cc_test_library {
@@ -272,8 +286,9 @@
         "gtest_main.cpp",
         "gtest_globals.cpp",
     ],
-    static_libs: [
+    whole_static_libs: [
         "libbase",
+        "liblog",
     ],
     include_dirs: [
         "bionic/libc",
@@ -327,12 +342,6 @@
             ],
         }
     },
-
-    product_variables: {
-        debuggable: {
-            cppflags: ["-DUSE_LD_CONFIG_FILE"],
-        },
-    },
 }
 
 // -----------------------------------------------------------------------------
@@ -346,6 +355,9 @@
         "gtest_main.cpp",
         "gtest_globals_cts.cpp",
     ],
+    static_libs: [
+        "libbase",
+    ],
     cppflags: ["-DUSING_GTEST_OUTPUT_FORMAT"],
     shared: {
         enabled: false,
@@ -610,8 +622,6 @@
 
     host_ldlibs: [
         "-lresolv",
-        "-lrt",
-        "-ldl",
         "-lutil",
     ],
 
@@ -626,9 +636,9 @@
         never: false,
     },
 
-    product_variables: {
-        debuggable: {
-            cppflags: ["-DUSE_LD_CONFIG_FILE"],
+    target: {
+        linux_bionic: {
+            enabled: false,
         },
     },
 }
diff --git a/tests/Android.mk b/tests/Android.mk
index 24ff7f2..c945bab 100644
--- a/tests/Android.mk
+++ b/tests/Android.mk
@@ -75,10 +75,10 @@
 
 LOCAL_CLANG := false
 LOCAL_MODULE := bionic-compile-time-tests-g++
-LOCAL_CPPFLAGS := -Wall
+LOCAL_CPPFLAGS := -Wall -Werror
 # Disable color diagnostics so the warnings output matches the source
 LOCAL_CPPFLAGS += -fdiagnostics-color=never
-LOCAL_SRC_FILES := fortify_compilation_test.cpp
+LOCAL_SRC_FILES := fortify_filecheck_diagnostics_test.cpp
 include $(BUILD_STATIC_LIBRARY)
 
 include $(CLEAR_VARS)
@@ -94,9 +94,9 @@
 
 LOCAL_CLANG := true
 LOCAL_MODULE := bionic-compile-time-tests-clang++
-LOCAL_CPPFLAGS := -Wall
+LOCAL_CPPFLAGS := -Wall -Werror
 LOCAL_CPPFLAGS += -fno-color-diagnostics -ferror-limit=10000
-LOCAL_SRC_FILES := fortify_compilation_test.cpp
+LOCAL_SRC_FILES := fortify_filecheck_diagnostics_test.cpp
 include $(BUILD_STATIC_LIBRARY)
 
 endif # linux-x86
diff --git a/tests/BionicDeathTest.h b/tests/BionicDeathTest.h
index 31d2d6e..3e8d7b2 100644
--- a/tests/BionicDeathTest.h
+++ b/tests/BionicDeathTest.h
@@ -17,25 +17,29 @@
 #ifndef BIONIC_TESTS_BIONIC_DEATH_TEST_H_
 #define BIONIC_TESTS_BIONIC_DEATH_TEST_H_
 
-#include <gtest/gtest.h>
+#include <signal.h>
 
-#include <sys/prctl.h>
+#include <gtest/gtest.h>
 
 class BionicDeathTest : public testing::Test {
  protected:
   virtual void SetUp() {
     // Suppress debuggerd stack traces. Too slow.
-    old_dumpable_ = prctl(PR_GET_DUMPABLE, 0, 0, 0, 0);
-    prctl(PR_SET_DUMPABLE, 0, 0, 0, 0);
-    ::testing::FLAGS_gtest_death_test_style = "threadsafe";
+    for (int signo : { SIGABRT, SIGBUS, SIGSEGV, SIGSYS }) {
+      struct sigaction action = {};
+      action.sa_handler = SIG_DFL;
+      sigaction(signo, &action, &previous_);
+    }
   }
 
   virtual void TearDown() {
-    prctl(PR_SET_DUMPABLE, old_dumpable_, 0, 0, 0, 0);
+    for (int signo : { SIGABRT, SIGBUS, SIGSEGV, SIGSYS }) {
+      sigaction(signo, &previous_, nullptr);
+    }
   }
 
  private:
-  int old_dumpable_;
+  struct sigaction previous_;
 };
 
 #endif // BIONIC_TESTS_BIONIC_DEATH_TEST_H_
diff --git a/tests/dl_test.cpp b/tests/dl_test.cpp
index aaf2c37..d56b017 100644
--- a/tests/dl_test.cpp
+++ b/tests/dl_test.cpp
@@ -162,7 +162,7 @@
   chmod(helper.c_str(), 0755);
   ExecTestHelper eth;
   eth.SetArgs({ helper.c_str(), nullptr });
-  eth.Run([&]() { execve(helper.c_str(), eth.GetArgs(), eth.GetEnv()); }, -6, error_message.c_str());
+  eth.Run([&]() { execve(helper.c_str(), eth.GetArgs(), eth.GetEnv()); }, EXIT_FAILURE, error_message.c_str());
 #endif
 }
 
@@ -180,12 +180,20 @@
 }
 #endif
 
-#ifdef USE_LD_CONFIG_FILE
+#if defined(__BIONIC__)
+static bool is_debuggable_build() {
+  return android::base::GetBoolProperty("ro.debuggable", false);
+}
+#endif
 
 // _lib1.so and _lib2.so are now searchable by having another namespace 'ns2'
 // whose search paths include the 'ns2/' subdir.
 TEST(dl, exec_with_ld_config_file) {
 #if defined(__BIONIC__)
+  if (!is_debuggable_build()) {
+    // LD_CONFIG_FILE is not supported on user build
+    return;
+  }
   std::string helper = get_testlib_root() +
       "/ld_config_test_helper/ld_config_test_helper";
   std::string config_file = get_testlib_root() + "/ld.config.txt";
@@ -204,6 +212,10 @@
 // additional namespaces other than the default namespace.
 TEST(dl, exec_with_ld_config_file_with_ld_preload) {
 #if defined(__BIONIC__)
+  if (!is_debuggable_build()) {
+    // LD_CONFIG_FILE is not supported on user build
+    return;
+  }
   std::string helper = get_testlib_root() +
       "/ld_config_test_helper/ld_config_test_helper";
   std::string config_file = get_testlib_root() + "/ld.config.txt";
@@ -218,8 +230,6 @@
 #endif
 }
 
-#endif // USE_LD_CONFIG_FILE
-
 // ensures that LD_CONFIG_FILE env var does not work for production builds.
 // The test input is the same as exec_with_ld_config_file, but it must fail in
 // this case.
@@ -230,8 +240,7 @@
     // This test is only for CTS.
     return;
   }
-  std::string build_type = android::base::GetProperty("ro.build.type", "user");
-  if (build_type == "userdebug" || build_type == "eng") {
+  if (is_debuggable_build()) {
     // Skip the test for non production devices
     return;
   }
diff --git a/tests/dlext_test.cpp b/tests/dlext_test.cpp
index 0dc54d0..3f6da59 100644
--- a/tests/dlext_test.cpp
+++ b/tests/dlext_test.cpp
@@ -1589,6 +1589,54 @@
   ASSERT_STREQ("dlopen failed: library \"libnstest_public.so\" not found", dlerror());
 }
 
+TEST(dlext, ns_inaccessible_error_message) {
+  // We set up 2 namespaces (a and b) and link a->b with a shared library
+  // libtestshared.so. Then try to dlopen different library with the same
+  // name from in namespace a. Note that library should not be accessible
+  // in either namespace but since it's soname is in the list of shared libs
+  // the linker will attempt to find it in linked namespace.
+  //
+  // Check the error message and make sure it mentions correct namespace name.
+  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() + "/private_namespace_libs").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().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_a, ns_b, "libtestshared.so")) << dlerror();
+
+  android_dlextinfo extinfo;
+  extinfo.flags = ANDROID_DLEXT_USE_NAMESPACE;
+  extinfo.library_namespace = ns_a;
+
+  std::string library_path = get_testlib_root() + "/inaccessible_libs/libtestshared.so";
+
+  void* handle = android_dlopen_ext(library_path.c_str(), RTLD_NOW, &extinfo);
+  ASSERT_TRUE(handle == nullptr);
+  std::string expected_dlerror =
+      android::base::StringPrintf("dlopen failed: library \"%s\" needed or dlopened by \"%s\""
+                                  " is not accessible for the namespace \"ns_a\"",
+                                  library_path.c_str(),
+                                  get_executable_path().c_str());
+  ASSERT_EQ(expected_dlerror, dlerror());
+}
+
 TEST(dlext, ns_anonymous) {
   static const char* root_lib = "libnstest_root.so";
   std::string shared_libs = g_core_shared_libs + ":" + g_public_lib;
@@ -1635,6 +1683,7 @@
 
   uintptr_t addr_start = 0;
   uintptr_t addr_end = 0;
+  bool has_executable_segment = false;
   std::vector<map_record> maps_to_copy;
 
   for (const auto& rec : maps) {
@@ -1643,6 +1692,7 @@
         addr_start = rec.addr_start;
       }
       addr_end = rec.addr_end;
+      has_executable_segment = has_executable_segment || (rec.perms & PROT_EXEC) != 0;
 
       maps_to_copy.push_back(rec);
     }
@@ -1655,6 +1705,16 @@
   ASSERT_TRUE(ns_get_dlopened_string_addr > addr_start);
   ASSERT_TRUE(ns_get_dlopened_string_addr < addr_end);
 
+  if (!has_executable_segment) {
+    // For some natively bridged environments this code might be missing
+    // the executable flag. This is because the guest code is not supposed
+    // to be executed directly and making it non-executable is more secure.
+    // If this is the case we assume that the first segment is the one that
+    // has this flag.
+    ASSERT_TRUE((maps_to_copy[0].perms & PROT_WRITE) == 0);
+    maps_to_copy[0].perms |= PROT_EXEC;
+  }
+
   // copy
   uintptr_t reserved_addr = reinterpret_cast<uintptr_t>(mmap(nullptr, addr_end - addr_start,
                                                              PROT_NONE, MAP_ANON | MAP_PRIVATE,
diff --git a/tests/dlfcn_test.cpp b/tests/dlfcn_test.cpp
index 1e2b6c9..6bd6e0c 100644
--- a/tests/dlfcn_test.cpp
+++ b/tests/dlfcn_test.cpp
@@ -21,6 +21,10 @@
 #include <stdio.h>
 #include <stdint.h>
 #include <string.h>
+#if __has_include(<sys/auxv.h>)
+#include <sys/auxv.h>
+#endif
+#include <sys/user.h>
 
 #include <string>
 #include <thread>
@@ -245,6 +249,18 @@
   dlclose(handle);
 }
 
+TEST(dlfcn, dlopen_vdso) {
+#if __has_include(<sys/auxv.h>)
+  if (getauxval(AT_SYSINFO_EHDR) == 0) {
+    GTEST_LOG_(INFO) << "getauxval(AT_SYSINFO_EHDR) == 0, skipping this test.";
+    return;
+  }
+#endif
+  void* handle = dlopen("linux-vdso.so.1", RTLD_NOW);
+  ASSERT_TRUE(handle != nullptr) << dlerror();
+  dlclose(handle);
+}
+
 // mips doesn't support ifuncs
 #if !defined(__mips__)
 TEST(dlfcn, ifunc_variable) {
@@ -809,6 +825,21 @@
 #endif
 }
 
+TEST(dlfcn, dlclose_unload) {
+  void* handle = dlopen("libtest_simple.so", RTLD_NOW);
+  ASSERT_TRUE(handle != nullptr) << dlerror();
+  uint32_t* taxicab_number = static_cast<uint32_t*>(dlsym(handle, "dlopen_testlib_taxicab_number"));
+  ASSERT_TRUE(taxicab_number != nullptr) << dlerror();
+  EXPECT_EQ(1729U, *taxicab_number);
+  dlclose(handle);
+  // Making sure that the library has been unmapped as part of library unload
+  // process. Note that mprotect somewhat counter-intuitively returns ENOMEM in
+  // this case.
+  uintptr_t page_start = reinterpret_cast<uintptr_t>(taxicab_number) & ~(PAGE_SIZE - 1);
+  ASSERT_TRUE(mprotect(reinterpret_cast<void*>(page_start), PAGE_SIZE, PROT_NONE) != 0);
+  ASSERT_EQ(ENOMEM, errno) << strerror(errno);
+}
+
 static void ConcurrentDlErrorFn(std::string& error) {
   ASSERT_TRUE(dlerror() == nullptr);
 
@@ -1087,17 +1118,17 @@
 
 // Check that RTLD_NEXT of a libc symbol works in dlopened library
 TEST(dlfcn, rtld_next_from_library) {
-  void* library_with_close = dlopen("libtest_check_rtld_next_from_library.so", RTLD_NOW);
-  ASSERT_TRUE(library_with_close != nullptr) << dlerror();
-  void* expected_addr = dlsym(RTLD_DEFAULT, "close");
+  void* library_with_fclose = dlopen("libtest_check_rtld_next_from_library.so", RTLD_NOW);
+  ASSERT_TRUE(library_with_fclose != nullptr) << dlerror();
+  void* expected_addr = dlsym(RTLD_DEFAULT, "fclose");
   ASSERT_TRUE(expected_addr != nullptr) << dlerror();
-  typedef void* (*get_libc_close_ptr_fn_t)();
-  get_libc_close_ptr_fn_t get_libc_close_ptr =
-      reinterpret_cast<get_libc_close_ptr_fn_t>(dlsym(library_with_close, "get_libc_close_ptr"));
-  ASSERT_TRUE(get_libc_close_ptr != nullptr) << dlerror();
-  ASSERT_EQ(expected_addr, get_libc_close_ptr());
+  typedef void* (*get_libc_fclose_ptr_fn_t)();
+  get_libc_fclose_ptr_fn_t get_libc_fclose_ptr =
+      reinterpret_cast<get_libc_fclose_ptr_fn_t>(dlsym(library_with_fclose, "get_libc_fclose_ptr"));
+  ASSERT_TRUE(get_libc_fclose_ptr != nullptr) << dlerror();
+  ASSERT_EQ(expected_addr, get_libc_fclose_ptr());
 
-  dlclose(library_with_close);
+  dlclose(library_with_fclose);
 }
 
 
@@ -1481,4 +1512,9 @@
   ASSERT_SUBSTR(expected_dlerror.c_str(), dlerror());
 }
 
+TEST(dlfcn, dlopen_df_1_global) {
+  void* handle = dlopen("libtest_dlopen_df_1_global.so", RTLD_NOW);
+  ASSERT_TRUE(handle != nullptr) << dlerror();
+}
+
 #endif
diff --git a/tests/fcntl_test.cpp b/tests/fcntl_test.cpp
index 7e78830..0a83dff 100644
--- a/tests/fcntl_test.cpp
+++ b/tests/fcntl_test.cpp
@@ -207,7 +207,7 @@
 }
 
 TEST(fcntl, tee) {
-  char expected[256];
+  char expected[BUFSIZ];
   FILE* expected_fp = fopen("/proc/version", "r");
   ASSERT_TRUE(expected_fp != NULL);
   ASSERT_TRUE(fgets(expected, sizeof(expected), expected_fp) != NULL);
@@ -319,6 +319,9 @@
   ASSERT_EQ(0, fstat(fd, &sb));
   ASSERT_EQ(perms, (sb.st_mode & ~S_IFMT));
 
+  // On Android if we're not root, we won't be able to create links anyway...
+  if (getuid() != 0) return;
+
   std::string final_path = android::base::StringPrintf("%s/named_now", dir.dirname);
   ASSERT_EQ(0, linkat(AT_FDCWD, android::base::StringPrintf("/proc/self/fd/%d", fd).c_str(),
                       AT_FDCWD, final_path.c_str(),
diff --git a/tests/fenv_test.cpp b/tests/fenv_test.cpp
index db1bfc3..9fc7d96 100644
--- a/tests/fenv_test.cpp
+++ b/tests/fenv_test.cpp
@@ -16,6 +16,9 @@
 
 #include <gtest/gtest.h>
 
+#include "ScopedSignalHandler.h"
+#include "utils.h"
+
 #include <fenv.h>
 #include <stdint.h>
 
@@ -83,3 +86,130 @@
 TEST(fenv, FE_DFL_ENV_macro) {
   ASSERT_EQ(0, fesetenv(FE_DFL_ENV));
 }
+
+TEST(fenv, feraiseexcept) {
+  feclearexcept(FE_ALL_EXCEPT);
+  ASSERT_EQ(0, fetestexcept(FE_ALL_EXCEPT));
+
+  ASSERT_EQ(0, feraiseexcept(FE_DIVBYZERO | FE_OVERFLOW));
+  ASSERT_EQ(FE_DIVBYZERO | FE_OVERFLOW, fetestexcept(FE_ALL_EXCEPT));
+}
+
+TEST(fenv, fegetenv_fesetenv) {
+  // Set FE_OVERFLOW only.
+  feclearexcept(FE_ALL_EXCEPT);
+  ASSERT_EQ(0, fetestexcept(FE_ALL_EXCEPT));
+  ASSERT_EQ(0, feraiseexcept(FE_OVERFLOW));
+
+  // fegetenv (unlike feholdexcept) leaves the current state untouched...
+  fenv_t state;
+  ASSERT_EQ(0, fegetenv(&state));
+  ASSERT_EQ(FE_OVERFLOW, fetestexcept(FE_ALL_EXCEPT));
+
+  // Dividing by zero sets the appropriate flag...
+  DivideByZero();
+  ASSERT_EQ(FE_DIVBYZERO | FE_OVERFLOW, fetestexcept(FE_ALL_EXCEPT));
+
+  // And fesetenv (unlike feupdateenv) clobbers that to return to where
+  // we started.
+  ASSERT_EQ(0, fesetenv(&state));
+  ASSERT_EQ(FE_OVERFLOW, fetestexcept(FE_ALL_EXCEPT));
+}
+
+TEST(fenv, feholdexcept_feupdateenv) {
+  // Set FE_OVERFLOW only.
+  feclearexcept(FE_ALL_EXCEPT);
+  ASSERT_EQ(0, fetestexcept(FE_ALL_EXCEPT));
+  ASSERT_EQ(0, feraiseexcept(FE_OVERFLOW));
+
+  // feholdexcept (unlike fegetenv) clears everything...
+  fenv_t state;
+  ASSERT_EQ(0, feholdexcept(&state));
+  ASSERT_EQ(0, fetestexcept(FE_ALL_EXCEPT));
+
+  // Dividing by zero sets the appropriate flag...
+  DivideByZero();
+  ASSERT_EQ(FE_DIVBYZERO, fetestexcept(FE_ALL_EXCEPT));
+
+  // And feupdateenv (unlike fesetenv) merges what we started with
+  // (FE_OVERFLOW) with what we now have (FE_DIVBYZERO).
+  ASSERT_EQ(0, feupdateenv(&state));
+  ASSERT_EQ(FE_DIVBYZERO | FE_OVERFLOW, fetestexcept(FE_ALL_EXCEPT));
+}
+
+TEST(fenv, fegetexceptflag_fesetexceptflag) {
+  // Set three flags.
+  feclearexcept(FE_ALL_EXCEPT);
+  ASSERT_EQ(0, feraiseexcept(FE_DIVBYZERO | FE_OVERFLOW | FE_UNDERFLOW));
+  ASSERT_EQ(FE_DIVBYZERO | FE_OVERFLOW | FE_UNDERFLOW, fetestexcept(FE_ALL_EXCEPT));
+
+  fexcept_t all; // FE_DIVBYZERO | FE_OVERFLOW | FE_UNDERFLOW
+  fexcept_t two; // FE_OVERFLOW | FE_UNDERFLOW
+  ASSERT_EQ(0, fegetexceptflag(&all, FE_ALL_EXCEPT));
+  ASSERT_EQ(0, fegetexceptflag(&two, FE_OVERFLOW | FE_UNDERFLOW));
+
+  // Check we can restore all.
+  feclearexcept(FE_ALL_EXCEPT);
+  ASSERT_EQ(0, fesetexceptflag(&all, FE_ALL_EXCEPT));
+  ASSERT_EQ(FE_DIVBYZERO | FE_OVERFLOW | FE_UNDERFLOW, fetestexcept(FE_ALL_EXCEPT));
+
+  // Check that `two` only stored a subset.
+  feclearexcept(FE_ALL_EXCEPT);
+  ASSERT_EQ(0, fesetexceptflag(&two, FE_ALL_EXCEPT));
+  ASSERT_EQ(FE_OVERFLOW | FE_UNDERFLOW, fetestexcept(FE_ALL_EXCEPT));
+
+  // Check that we can restore a single flag.
+  feclearexcept(FE_ALL_EXCEPT);
+  ASSERT_EQ(0, fesetexceptflag(&all, FE_DIVBYZERO));
+  ASSERT_EQ(FE_DIVBYZERO, fetestexcept(FE_ALL_EXCEPT));
+
+  // Check that we can restore a subset of flags.
+  feclearexcept(FE_ALL_EXCEPT);
+  ASSERT_EQ(0, fesetexceptflag(&all, FE_OVERFLOW | FE_UNDERFLOW));
+  ASSERT_EQ(FE_OVERFLOW | FE_UNDERFLOW, fetestexcept(FE_ALL_EXCEPT));
+}
+
+TEST(fenv, fedisableexcept_fegetexcept) {
+  feclearexcept(FE_ALL_EXCEPT);
+  ASSERT_EQ(0, fetestexcept(FE_ALL_EXCEPT));
+
+  // No SIGFPE please...
+  ASSERT_EQ(0, fedisableexcept(FE_ALL_EXCEPT));
+  ASSERT_EQ(0, fegetexcept());
+  ASSERT_EQ(0, feraiseexcept(FE_INVALID));
+  ASSERT_EQ(FE_INVALID, fetestexcept(FE_ALL_EXCEPT));
+}
+
+TEST(fenv, feenableexcept_fegetexcept) {
+#if defined(__aarch64__) || defined(__arm__)
+  // ARM doesn't support this. They used to if you go back far enough, but it was removed in
+  // the Cortex-A8 between r3p1 and r3p2.
+  ASSERT_EQ(-1, feenableexcept(FE_INVALID));
+  ASSERT_EQ(0, fegetexcept());
+  ASSERT_EQ(-1, feenableexcept(FE_DIVBYZERO));
+  ASSERT_EQ(0, fegetexcept());
+  ASSERT_EQ(-1, feenableexcept(FE_OVERFLOW));
+  ASSERT_EQ(0, fegetexcept());
+  ASSERT_EQ(-1, feenableexcept(FE_UNDERFLOW));
+  ASSERT_EQ(0, fegetexcept());
+  ASSERT_EQ(-1, feenableexcept(FE_INEXACT));
+  ASSERT_EQ(0, fegetexcept());
+  ASSERT_EQ(-1, feenableexcept(FE_DENORMAL));
+  ASSERT_EQ(0, fegetexcept());
+#else
+  // We can't recover from SIGFPE, so sacrifice a child...
+  pid_t pid = fork();
+  ASSERT_NE(-1, pid) << strerror(errno);
+
+  if (pid == 0) {
+    feclearexcept(FE_ALL_EXCEPT);
+    ASSERT_EQ(0, fetestexcept(FE_ALL_EXCEPT));
+    ASSERT_EQ(0, feenableexcept(FE_INVALID));
+    ASSERT_EQ(FE_INVALID, fegetexcept());
+    ASSERT_EQ(0, feraiseexcept(FE_INVALID));
+    _exit(123);
+  }
+
+  AssertChildExited(pid, -SIGFPE);
+#endif
+}
diff --git a/tests/fortify_compilation_test.cpp b/tests/fortify_filecheck_diagnostics_test.cpp
similarity index 100%
rename from tests/fortify_compilation_test.cpp
rename to tests/fortify_filecheck_diagnostics_test.cpp
diff --git a/tests/fortify_test.cpp b/tests/fortify_test.cpp
index 2946e23..67c124d 100644
--- a/tests/fortify_test.cpp
+++ b/tests/fortify_test.cpp
@@ -219,6 +219,18 @@
 #endif // __BIONIC__
 }
 
+TEST_F(DEATHTEST, memrchr_fortified2) {
+#if defined(__BIONIC__)
+  foo myfoo;
+  volatile int asize = sizeof(myfoo.a) + 1;
+  memcpy(myfoo.a, "0123456789", sizeof(myfoo.a));
+  ASSERT_FORTIFY(printf("%s", memrchr(myfoo.a, 'a', asize)));
+  ASSERT_FORTIFY(printf("%s", memrchr(static_cast<const void*>(myfoo.a), 'a', asize)));
+#else // __BIONIC__
+  GTEST_LOG_(INFO) << "This test does nothing.\n";
+#endif // __BIONIC__
+}
+
 TEST_F(DEATHTEST, strlcpy_fortified2) {
 #if defined(__BIONIC__)
   foo myfoo;
diff --git a/tests/glob_test.cpp b/tests/glob_test.cpp
new file mode 100644
index 0000000..623a2a3
--- /dev/null
+++ b/tests/glob_test.cpp
@@ -0,0 +1,249 @@
+/*
+ * Copyright (C) 2017 The Android Open Source Project
+ *
+ * Licensed under the Apache License, Version 2.0 (the "License");
+ * you may not use this file except in compliance with the License.
+ * You may obtain a copy of the License at
+ *
+ *      http://www.apache.org/licenses/LICENSE-2.0
+ *
+ * Unless required by applicable law or agreed to in writing, software
+ * distributed under the License is distributed on an "AS IS" BASIS,
+ * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
+ * See the License for the specific language governing permissions and
+ * limitations under the License.
+ */
+
+#include <glob.h>
+
+#include <dirent.h>
+#include <gtest/gtest.h>
+
+#include <string>
+#include <vector>
+
+#include "TemporaryFile.h"
+
+#if defined(__BIONIC__)
+#define ASSERT_MATCH_COUNT(n_,g_) ASSERT_EQ(n_, g_.gl_matchc)
+#else
+#define ASSERT_MATCH_COUNT(n_,g_)
+#endif
+
+//
+// Helper for use with GLOB_ALTDIRFUNC to iterate over the elements of `fake_dir`.
+//
+
+static std::vector<std::string> fake_dir;
+static size_t fake_dir_offset;
+static void fake_closedir(void*) {
+}
+static dirent* fake_readdir(void*) {
+  static dirent d;
+  if (fake_dir_offset >= fake_dir.size()) return nullptr;
+  strcpy(d.d_name, fake_dir[fake_dir_offset++].c_str());
+  return &d;
+}
+static void* fake_opendir(const char* path) {
+  fake_dir_offset = 0;
+  if (strcmp(path, "/opendir-fail/") == 0) {
+    errno = EINVAL;
+    return nullptr;
+  }
+  return &fake_dir;
+}
+static int fake_lstat(const char*, struct stat*) {
+  return 0;
+}
+static int fake_stat(const char*, struct stat*) {
+  return 0;
+}
+static void InstallFake(glob_t* g) {
+  g->gl_closedir = fake_closedir;
+  g->gl_readdir = fake_readdir;
+  g->gl_opendir = fake_opendir;
+  g->gl_lstat = fake_lstat;
+  g->gl_stat = fake_stat;
+}
+
+TEST(glob, glob_result_GLOB_NOMATCH) {
+  glob_t g = {};
+  ASSERT_EQ(GLOB_NOMATCH, glob("/will/match/nothing", 0, nullptr, &g));
+  ASSERT_EQ(0U, g.gl_pathc);
+  ASSERT_MATCH_COUNT(0U, g);
+}
+
+TEST(glob, glob_GLOB_APPEND) {
+  glob_t g = {};
+  ASSERT_EQ(0, glob("/proc/version", 0, nullptr, &g));
+  ASSERT_EQ(1U, g.gl_pathc);
+  ASSERT_MATCH_COUNT(1U, g);
+  ASSERT_STREQ("/proc/version", g.gl_pathv[0]);
+  ASSERT_EQ(nullptr, g.gl_pathv[1]);
+  ASSERT_EQ(0, glob("/proc/version", GLOB_APPEND, nullptr, &g));
+  ASSERT_EQ(2U, g.gl_pathc);
+  ASSERT_MATCH_COUNT(1U, g);
+  ASSERT_STREQ("/proc/version", g.gl_pathv[0]);
+  ASSERT_STREQ("/proc/version", g.gl_pathv[1]);
+  ASSERT_EQ(nullptr, g.gl_pathv[2]);
+  globfree(&g);
+}
+
+TEST(glob, glob_GLOB_DOOFFS) {
+  glob_t g = {};
+  g.gl_offs = 2;
+  ASSERT_EQ(0, glob("/proc/version", GLOB_DOOFFS, nullptr, &g));
+  ASSERT_EQ(1U, g.gl_pathc);
+  ASSERT_MATCH_COUNT(1U, g);
+  ASSERT_EQ(nullptr, g.gl_pathv[0]);
+  ASSERT_EQ(nullptr, g.gl_pathv[1]);
+  ASSERT_STREQ("/proc/version", g.gl_pathv[2]);
+  ASSERT_EQ(nullptr, g.gl_pathv[3]);
+  globfree(&g);
+}
+
+static std::string g_failure_path;
+static int g_failure_errno;
+static int test_error_callback_result;
+static int test_error_callback(const char* failure_path, int failure_errno) {
+  g_failure_path = failure_path;
+  g_failure_errno = failure_errno;
+  return test_error_callback_result;
+}
+
+TEST(glob, glob_gl_errfunc) {
+  glob_t g = {};
+  InstallFake(&g);
+
+  test_error_callback_result = 0;
+  g_failure_errno = 0;
+  ASSERT_EQ(GLOB_NOMATCH, glob("/opendir-fail/x*", GLOB_ALTDIRFUNC, test_error_callback, &g));
+  ASSERT_EQ("/opendir-fail/", g_failure_path);
+  ASSERT_EQ(EINVAL, g_failure_errno);
+
+  test_error_callback_result = 1;
+  g_failure_errno = 0;
+  ASSERT_EQ(GLOB_ABORTED, glob("/opendir-fail/x*", GLOB_ALTDIRFUNC, test_error_callback, &g));
+  ASSERT_EQ("/opendir-fail/", g_failure_path);
+  ASSERT_EQ(EINVAL, g_failure_errno);
+}
+
+TEST(glob, glob_GLOB_ERR) {
+  glob_t g = {};
+  InstallFake(&g);
+
+  ASSERT_EQ(GLOB_NOMATCH, glob("/opendir-fail/x*", GLOB_ALTDIRFUNC, nullptr, &g));
+
+  ASSERT_EQ(GLOB_ABORTED, glob("/opendir-fail/x*", GLOB_ALTDIRFUNC | GLOB_ERR, nullptr, &g));
+}
+
+TEST(glob, glob_GLOB_MARK) {
+  TemporaryDir td;
+  // The pattern we're about to pass doesn't have a trailing '/'...
+  ASSERT_NE('/', std::string(td.dirname).back());
+
+  glob_t g = {};
+  // Using GLOB_MARK gets you a trailing '/' on a directory...
+  ASSERT_EQ(0, glob(td.dirname, GLOB_MARK, nullptr, &g));
+  ASSERT_EQ(1U, g.gl_pathc);
+  ASSERT_MATCH_COUNT(1U, g);
+  ASSERT_EQ(std::string(td.dirname) + "/", g.gl_pathv[0]);
+  ASSERT_EQ(nullptr, g.gl_pathv[1]);
+
+  TemporaryFile tf;
+  // But not on a file...
+  ASSERT_EQ(0, glob(tf.filename, GLOB_MARK, nullptr, &g));
+  ASSERT_EQ(1U, g.gl_pathc);
+  ASSERT_MATCH_COUNT(1U, g);
+  ASSERT_STREQ(tf.filename, g.gl_pathv[0]);
+  ASSERT_EQ(nullptr, g.gl_pathv[1]);
+
+  globfree(&g);
+}
+
+TEST(glob, glob_GLOB_NOCHECK) {
+  glob_t g = {};
+  ASSERT_EQ(0, glob("/will/match/nothing", GLOB_NOCHECK, nullptr, &g));
+  ASSERT_EQ(1U, g.gl_pathc);
+  ASSERT_MATCH_COUNT(0U, g);
+  ASSERT_STREQ("/will/match/nothing", g.gl_pathv[0]);
+  ASSERT_EQ(nullptr, g.gl_pathv[1]);
+  globfree(&g);
+}
+
+TEST(glob, glob_GLOB_NOSORT) {
+  fake_dir = { "c", "a", "d", "b" };
+
+  glob_t g = {};
+  InstallFake(&g);
+
+  ASSERT_EQ(0, glob("*", GLOB_ALTDIRFUNC, nullptr, &g));
+  ASSERT_EQ(4U, g.gl_pathc);
+  ASSERT_MATCH_COUNT(4U, g);
+  ASSERT_STREQ("a", g.gl_pathv[0]);
+  ASSERT_STREQ("b", g.gl_pathv[1]);
+  ASSERT_STREQ("c", g.gl_pathv[2]);
+  ASSERT_STREQ("d", g.gl_pathv[3]);
+  ASSERT_EQ(nullptr, g.gl_pathv[4]);
+
+  ASSERT_EQ(0, glob("*", GLOB_ALTDIRFUNC | GLOB_NOSORT, nullptr, &g));
+  ASSERT_EQ(4U, g.gl_pathc);
+  ASSERT_MATCH_COUNT(4U, g);
+  ASSERT_STREQ("c", g.gl_pathv[0]);
+  ASSERT_STREQ("a", g.gl_pathv[1]);
+  ASSERT_STREQ("d", g.gl_pathv[2]);
+  ASSERT_STREQ("b", g.gl_pathv[3]);
+  ASSERT_EQ(nullptr, g.gl_pathv[4]);
+}
+
+TEST(glob, glob_GLOB_MAGCHAR) {
+  glob_t g = {};
+  ASSERT_EQ(GLOB_NOMATCH, glob("/does-not-exist", 0, nullptr, &g));
+  ASSERT_TRUE((g.gl_flags & GLOB_MAGCHAR) == 0);
+  ASSERT_EQ(GLOB_NOMATCH, glob("/does-not-exist*", 0, nullptr, &g));
+  ASSERT_TRUE((g.gl_flags & GLOB_MAGCHAR) != 0);
+
+  // We can lie, but glob(3) will turn that into truth...
+  ASSERT_EQ(GLOB_NOMATCH, glob("/does-not-exist", GLOB_MAGCHAR, nullptr, &g));
+  ASSERT_TRUE((g.gl_flags & GLOB_MAGCHAR) == 0);
+}
+
+static void CheckGlob(const char* pattern, const std::vector<std::string>& expected_matches) {
+  glob_t g = {};
+  InstallFake(&g);
+
+  int expected_result = expected_matches.empty() ? GLOB_NOMATCH : 0;
+  ASSERT_EQ(expected_result, glob(pattern, GLOB_ALTDIRFUNC, nullptr, &g)) << pattern;
+  ASSERT_EQ(expected_matches.size(), g.gl_pathc);
+  ASSERT_MATCH_COUNT(expected_matches.size(), g);
+  for (size_t i = 0; i < expected_matches.size(); ++i) {
+    ASSERT_EQ(expected_matches[i], g.gl_pathv[i]);
+  }
+  if (!expected_matches.empty()) {
+    ASSERT_EQ(nullptr, g.gl_pathv[expected_matches.size()]);
+  }
+  globfree(&g);
+}
+
+TEST(glob, glob_globbing) {
+  fake_dir = { "f1", "f2", "f30", "f40" };
+
+  CheckGlob("f?", { "f1", "f2" });
+  CheckGlob("f??", { "f30", "f40" });
+  CheckGlob("f*", { "f1", "f2", "f30", "f40" });
+}
+
+TEST(glob, glob_globbing_rsc) {
+  // https://research.swtch.com/glob
+  fake_dir = { "axbxcxdxe" };
+  CheckGlob("a*b*c*d*e*", { "axbxcxdxe" });
+  fake_dir = { "axbxcxdxexxx" };
+  CheckGlob("a*b*c*d*e*", { "axbxcxdxexxx" });
+  fake_dir = { "abxbbxdbxebxczzx" };
+  CheckGlob("a*b?c*x", { "abxbbxdbxebxczzx" });
+  fake_dir = { "abxbbxdbxebxczzy" };
+  CheckGlob("a*b?c*x", {});
+
+  fake_dir = { std::string(100, 'a') };
+  CheckGlob("a*a*a*a*b", {});
+}
diff --git a/tests/grp_pwd_test.cpp b/tests/grp_pwd_test.cpp
index b8df8e7..61748c8 100644
--- a/tests/grp_pwd_test.cpp
+++ b/tests/grp_pwd_test.cpp
@@ -26,13 +26,17 @@
 #include <sys/types.h>
 #include <unistd.h>
 
-#include <bitset>
+#include <set>
+#include <vector>
 
+#include <android-base/strings.h>
 #include <private/android_filesystem_config.h>
 
 // Generated android_ids array
 #include "generated_android_ids.h"
 
+using android::base::Join;
+
 enum uid_type_t {
   TYPE_SYSTEM,
   TYPE_APP
@@ -42,20 +46,20 @@
 
 static void check_passwd(const passwd* pwd, const char* username, uid_t uid, uid_type_t uid_type) {
   ASSERT_TRUE(pwd != NULL);
-  ASSERT_STREQ(username, pwd->pw_name);
-  ASSERT_EQ(uid, pwd->pw_uid);
-  ASSERT_EQ(uid, pwd->pw_gid);
-  ASSERT_EQ(NULL, pwd->pw_passwd);
+  EXPECT_STREQ(username, pwd->pw_name);
+  EXPECT_EQ(uid, pwd->pw_uid);
+  EXPECT_EQ(uid, pwd->pw_gid);
+  EXPECT_EQ(NULL, pwd->pw_passwd);
 #ifdef __LP64__
-  ASSERT_EQ(NULL, pwd->pw_gecos);
+  EXPECT_EQ(NULL, pwd->pw_gecos);
 #endif
 
   if (uid_type == TYPE_SYSTEM) {
-    ASSERT_STREQ("/", pwd->pw_dir);
+    EXPECT_STREQ("/", pwd->pw_dir);
   } else {
-    ASSERT_STREQ("/data", pwd->pw_dir);
+    EXPECT_STREQ("/data", pwd->pw_dir);
   }
-  ASSERT_STREQ("/system/bin/sh", pwd->pw_shell);
+  EXPECT_STREQ("/system/bin/sh", pwd->pw_shell);
 }
 
 static void check_getpwuid(const char* username, uid_t uid, uid_type_t uid_type) {
@@ -186,60 +190,95 @@
   check_get_passwd("u1_i0", 199000, TYPE_APP);
 }
 
+template <typename T>
+static void expect_ids(const T& ids) {
+  std::set<typename T::key_type> expected_ids;
+  // Ensure that all android_ids are iterated through.
+  for (size_t n = 0; n < android_id_count; ++n) {
+    EXPECT_EQ(1U, ids.count(android_ids[n].aid)) << "android_ids[n].aid: " << android_ids[n].aid;
+    expected_ids.emplace(android_ids[n].aid);
+  }
+
+  auto expect_range = [&ids, &expected_ids](uid_t start, uid_t end) {
+    for (size_t n = start; n <= end; ++n) {
+      EXPECT_EQ(1U, ids.count(n)) << "n: " << n;
+      expected_ids.emplace(n);
+    }
+  };
+
+  // Ensure that all reserved ranges are iterated through.
+  expect_range(AID_OEM_RESERVED_START, AID_OEM_RESERVED_END);
+  expect_range(AID_OEM_RESERVED_2_START, AID_OEM_RESERVED_2_END);
+  expect_range(AID_APP_START, AID_APP_END);
+  expect_range(AID_CACHE_GID_START, AID_CACHE_GID_END);
+  expect_range(AID_EXT_GID_START, AID_EXT_GID_END);
+  expect_range(AID_EXT_CACHE_GID_START, AID_EXT_CACHE_GID_END);
+  expect_range(AID_SHARED_GID_START, AID_SHARED_GID_END);
+  expect_range(AID_ISOLATED_START, AID_ISOLATED_END);
+
+  // Ensure that no other ids were returned.
+  auto return_differences = [&ids, &expected_ids] {
+    std::vector<typename T::key_type> missing_from_ids;
+    std::set_difference(expected_ids.begin(), expected_ids.end(), ids.begin(), ids.end(),
+                        std::inserter(missing_from_ids, missing_from_ids.begin()));
+    std::vector<typename T::key_type> extra_in_ids;
+    std::set_difference(ids.begin(), ids.end(), expected_ids.begin(), expected_ids.end(),
+                        std::inserter(extra_in_ids, extra_in_ids.begin()));
+    std::string result;
+    if (!missing_from_ids.empty()) {
+      result += "Missing ids from results: " + Join(missing_from_ids, " ");
+    }
+    if (!extra_in_ids.empty()) {
+      if (!result.empty()) result += ", ";
+      result += "Extra ids in results: " + Join(extra_in_ids, " ");
+    }
+    return result;
+  };
+  EXPECT_EQ(expected_ids, ids) << return_differences();
+}
+
 TEST(pwd, getpwent_iterate) {
   passwd* pwd;
-  std::bitset<10000> exist;
-  bool application = false;
-
-  exist.reset();
+  std::set<uid_t> uids;
 
   setpwent();
   while ((pwd = getpwent()) != NULL) {
     ASSERT_TRUE(NULL != pwd->pw_name);
-    ASSERT_EQ(pwd->pw_gid, pwd->pw_uid);
-    ASSERT_EQ(NULL, pwd->pw_passwd);
+
+    EXPECT_EQ(pwd->pw_gid, pwd->pw_uid) << "pwd->pw_uid: " << pwd->pw_uid;
+    EXPECT_EQ(NULL, pwd->pw_passwd) << "pwd->pw_uid: " << pwd->pw_uid;
 #ifdef __LP64__
-    ASSERT_TRUE(NULL == pwd->pw_gecos);
+    EXPECT_TRUE(NULL == pwd->pw_gecos) << "pwd->pw_uid: " << pwd->pw_uid;
 #endif
-    ASSERT_TRUE(NULL != pwd->pw_shell);
-    if (pwd->pw_uid >= exist.size()) {
-      ASSERT_STREQ("/data", pwd->pw_dir);
-      application = true;
+    EXPECT_TRUE(NULL != pwd->pw_shell);
+    if (pwd->pw_uid < AID_APP_START || pwd->pw_uid == AID_OVERFLOWUID) {
+      EXPECT_STREQ("/", pwd->pw_dir) << "pwd->pw_uid: " << pwd->pw_uid;
     } else {
-      ASSERT_STREQ("/", pwd->pw_dir);
-      // TODO(b/27999086): fix this check with the OEM range
-      // If OEMs add their own AIDs to private/android_filesystem_config.h, this check will fail.
-      // Long term we want to create a better solution for OEMs adding AIDs, but we're not there
-      // yet, so therefore we do not check for uid's in the OEM range.
-      if (!(pwd->pw_uid >= 2900 && pwd->pw_uid <= 2999) &&
-          !(pwd->pw_uid >= 5000 && pwd->pw_uid <= 5999)) {
-        ASSERT_FALSE(exist[pwd->pw_uid]);
-      }
-      exist[pwd->pw_uid] = true;
+      EXPECT_STREQ("/data", pwd->pw_dir) << "pwd->pw_uid: " << pwd->pw_uid;
     }
+
+    // TODO(b/27999086): fix this check with the OEM range
+    // If OEMs add their own AIDs to private/android_filesystem_config.h, this check will fail.
+    // Long term we want to create a better solution for OEMs adding AIDs, but we're not there
+    // yet, so therefore we do not check for uid's in the OEM range.
+    if (!(pwd->pw_uid >= 2900 && pwd->pw_uid <= 2999) &&
+        !(pwd->pw_uid >= 5000 && pwd->pw_uid <= 5999)) {
+      EXPECT_EQ(0U, uids.count(pwd->pw_uid)) << "pwd->pw_uid: " << pwd->pw_uid;
+    }
+    uids.emplace(pwd->pw_uid);
   }
   endpwent();
 
-  // Required content
-  for (size_t n = 0; n < android_id_count; ++n) {
-    ASSERT_TRUE(exist[android_ids[n].aid]);
-  }
-  for (size_t n = 2900; n < 2999; ++n) {
-    ASSERT_TRUE(exist[n]);
-  }
-  for (size_t n = 5000; n < 5999; ++n) {
-    ASSERT_TRUE(exist[n]);
-  }
-  ASSERT_TRUE(application);
+  expect_ids(uids);
 }
 
 static void check_group(const group* grp, const char* group_name, gid_t gid) {
   ASSERT_TRUE(grp != NULL);
-  ASSERT_STREQ(group_name, grp->gr_name);
-  ASSERT_EQ(gid, grp->gr_gid);
+  EXPECT_STREQ(group_name, grp->gr_name);
+  EXPECT_EQ(gid, grp->gr_gid);
   ASSERT_TRUE(grp->gr_mem != NULL);
-  ASSERT_STREQ(group_name, grp->gr_mem[0]);
-  ASSERT_TRUE(grp->gr_mem[1] == NULL);
+  EXPECT_STREQ(group_name, grp->gr_mem[0]);
+  EXPECT_TRUE(grp->gr_mem[1] == NULL);
 }
 
 #if defined(__BIONIC__)
@@ -446,42 +485,26 @@
 
 TEST(grp, getgrent_iterate) {
   group* grp;
-  std::bitset<10000> exist;
-  bool application = false;
-
-  exist.reset();
+  std::set<gid_t> gids;
 
   setgrent();
   while ((grp = getgrent()) != NULL) {
-    ASSERT_TRUE(grp->gr_name != NULL);
-    ASSERT_TRUE(grp->gr_mem != NULL);
-    ASSERT_STREQ(grp->gr_name, grp->gr_mem[0]);
-    ASSERT_TRUE(grp->gr_mem[1] == NULL);
-    if (grp->gr_gid >= exist.size()) {
-      application = true;
-    } else {
-      // TODO(b/27999086): fix this check with the OEM range
-      // If OEMs add their own AIDs to private/android_filesystem_config.h, this check will fail.
-      // Long term we want to create a better solution for OEMs adding AIDs, but we're not there
-      // yet, so therefore we do not check for gid's in the OEM range.
-      if (!(grp->gr_gid >= 2900 && grp->gr_gid <= 2999) &&
-          !(grp->gr_gid >= 5000 && grp->gr_gid <= 5999)) {
-        ASSERT_FALSE(exist[grp->gr_gid]);
-      }
-      exist[grp->gr_gid] = true;
+    ASSERT_TRUE(grp->gr_name != NULL) << "grp->gr_gid: " << grp->gr_gid;
+    ASSERT_TRUE(grp->gr_mem != NULL) << "grp->gr_gid: " << grp->gr_gid;
+    EXPECT_STREQ(grp->gr_name, grp->gr_mem[0]) << "grp->gr_gid: " << grp->gr_gid;
+    EXPECT_TRUE(grp->gr_mem[1] == NULL) << "grp->gr_gid: " << grp->gr_gid;
+
+    // TODO(b/27999086): fix this check with the OEM range
+    // If OEMs add their own AIDs to private/android_filesystem_config.h, this check will fail.
+    // Long term we want to create a better solution for OEMs adding AIDs, but we're not there
+    // yet, so therefore we do not check for gid's in the OEM range.
+    if (!(grp->gr_gid >= 2900 && grp->gr_gid <= 2999) &&
+        !(grp->gr_gid >= 5000 && grp->gr_gid <= 5999)) {
+      EXPECT_EQ(0U, gids.count(grp->gr_gid)) << "grp->gr_gid: " << grp->gr_gid;
     }
+    gids.emplace(grp->gr_gid);
   }
   endgrent();
 
-  // Required content
-  for (size_t n = 0; n < android_id_count; ++n) {
-    ASSERT_TRUE(exist[android_ids[n].aid]);
-  }
-  for (size_t n = 2900; n < 2999; ++n) {
-    ASSERT_TRUE(exist[n]);
-  }
-  for (size_t n = 5000; n < 5999; ++n) {
-    ASSERT_TRUE(exist[n]);
-  }
-  ASSERT_TRUE(application);
+  expect_ids(gids);
 }
diff --git a/tests/gtest_main.cpp b/tests/gtest_main.cpp
index 9dcc000..3f59a9c 100644
--- a/tests/gtest_main.cpp
+++ b/tests/gtest_main.cpp
@@ -23,6 +23,7 @@
 #include <libgen.h>
 #include <limits.h>
 #include <signal.h>
+#include <spawn.h>
 #include <stdarg.h>
 #include <stdio.h>
 #include <string.h>
@@ -35,6 +36,10 @@
 #include <utility>
 #include <vector>
 
+#include <android-base/file.h>
+#include <android-base/strings.h>
+#include <android-base/unique_fd.h>
+
 #ifndef TEMP_FAILURE_RETRY
 
 /* Used to retry syscalls that can return EINTR. */
@@ -269,49 +274,61 @@
 }
 
 static bool EnumerateTests(int argc, char** argv, std::vector<TestCase>& testcase_list) {
-  std::string command;
-  for (int i = 0; i < argc; ++i) {
-    command += argv[i];
-    command += " ";
-  }
-  command += "--gtest_list_tests";
-  FILE* fp = popen(command.c_str(), "r");
-  if (fp == NULL) {
-    perror("popen");
+  std::vector<const char*> args;
+  for (int i = 0; i < argc; ++i) args.push_back(argv[i]);
+  args.push_back("--gtest_list_tests");
+  args.push_back(nullptr);
+
+  // We use posix_spawn(3) rather than the simpler popen(3) because we don't want an intervening
+  // surprise shell invocation making quoting interesting for --gtest_filter (http://b/68949647).
+
+  android::base::unique_fd read_fd;
+  android::base::unique_fd write_fd;
+  if (!android::base::Pipe(&read_fd, &write_fd)) {
+    perror("pipe");
     return false;
   }
 
-  char buf[200];
-  while (fgets(buf, sizeof(buf), fp) != NULL) {
-    char* p = buf;
+  posix_spawn_file_actions_t fa;
+  posix_spawn_file_actions_init(&fa);
+  posix_spawn_file_actions_addclose(&fa, read_fd);
+  posix_spawn_file_actions_adddup2(&fa, write_fd, 1);
+  posix_spawn_file_actions_adddup2(&fa, write_fd, 2);
+  posix_spawn_file_actions_addclose(&fa, write_fd);
 
-    while (*p != '\0' && isspace(*p)) {
-      ++p;
-    }
-    if (*p == '\0') continue;
-    char* start = p;
-    while (*p != '\0' && !isspace(*p)) {
-      ++p;
-    }
-    char* end = p;
-    while (*p != '\0' && isspace(*p)) {
-      ++p;
-    }
-    if (*p != '\0' && *p != '#') {
-      // This is not we want, gtest must meet with some error when parsing the arguments.
-      fprintf(stderr, "argument error, check with --help\n");
-      return false;
-    }
-    *end = '\0';
-    if (*(end - 1) == '.') {
-      *(end - 1) = '\0';
-      testcase_list.push_back(TestCase(start));
+  pid_t pid;
+  int result = posix_spawnp(&pid, argv[0], &fa, nullptr, const_cast<char**>(args.data()), nullptr);
+  posix_spawn_file_actions_destroy(&fa);
+  if (result == -1) {
+    perror("posix_spawn");
+    return false;
+  }
+  write_fd.reset();
+
+  std::string content;
+  if (!android::base::ReadFdToString(read_fd, &content)) {
+    perror("ReadFdToString");
+    return false;
+  }
+
+  for (auto& line : android::base::Split(content, "\n")) {
+    line = android::base::Split(line, "#")[0];
+    line = android::base::Trim(line);
+    if (line.empty()) continue;
+    if (android::base::EndsWith(line, ".")) {
+      line.pop_back();
+      testcase_list.push_back(TestCase(line.c_str()));
     } else {
-      testcase_list.back().AppendTest(start);
+      testcase_list.back().AppendTest(line.c_str());
     }
   }
-  int result = pclose(fp);
-  return (result != -1 && WEXITSTATUS(result) == 0);
+
+  int status;
+  if (waitpid(pid, &status, 0) != pid) {
+    perror("waitpid");
+    return false;
+  }
+  return (WIFEXITED(status) && WEXITSTATUS(status) == 0);
 }
 
 // Part of the following *Print functions are copied from external/gtest/src/gtest.cc:
@@ -1249,3 +1266,24 @@
 TEST_F(bionic_selftest_DeathTest, fail) {
   ASSERT_EXIT(deathtest_helper_fail(), ::testing::ExitedWithCode(0), "");
 }
+
+class BionicSelfTest : public ::testing::TestWithParam<bool> {
+};
+
+TEST_P(BionicSelfTest, test_success) {
+  ASSERT_EQ(GetParam(), GetParam());
+}
+
+INSTANTIATE_TEST_CASE_P(bionic_selftest, BionicSelfTest, ::testing::Values(true, false));
+
+template <typename T>
+class bionic_selftest_TestT : public ::testing::Test {
+};
+
+typedef ::testing::Types<char, int> MyTypes;
+
+TYPED_TEST_CASE(bionic_selftest_TestT, MyTypes);
+
+TYPED_TEST(bionic_selftest_TestT, test_success) {
+  ASSERT_EQ(true, true);
+}
diff --git a/tests/leak_test.cpp b/tests/leak_test.cpp
index a356640..de08869 100644
--- a/tests/leak_test.cpp
+++ b/tests/leak_test.cpp
@@ -35,20 +35,6 @@
 
 using namespace std::chrono_literals;
 
-static size_t GetMappingSize() {
-  std::vector<map_record> maps;
-  if (!Maps::parse_maps(&maps)) {
-    err(1, "failed to parse maps");
-  }
-
-  size_t result = 0;
-  for (const map_record& map : maps) {
-    result += map.addr_end - map.addr_start;
-  }
-
-  return result;
-}
-
 static void WaitUntilAllExited(pid_t* pids, size_t pid_count) {
   // Wait until all children have exited.
   bool alive = true;
@@ -70,6 +56,9 @@
 class LeakChecker {
  public:
   LeakChecker() {
+    // Avoid resizing and using memory later.
+    // 64Ki is the default limit on VMAs per process.
+    maps_.reserve(64*1024);
     Reset();
   }
 
@@ -87,6 +76,7 @@
 
  private:
   size_t previous_size_;
+  std::vector<map_record> maps_;
 
   void Check() {
     auto current_size = GetMappingSize();
@@ -94,6 +84,19 @@
       FAIL() << "increase in process map size: " << previous_size_ << " -> " << current_size;
     }
   }
+
+  size_t GetMappingSize() {
+    if (!Maps::parse_maps(&maps_)) {
+      err(1, "failed to parse maps");
+    }
+
+    size_t result = 0;
+    for (const map_record& map : maps_) {
+      result += map.addr_end - map.addr_start;
+    }
+
+    return result;
+  }
 };
 
 std::ostream& operator<<(std::ostream& os, const LeakChecker& lc) {
@@ -116,27 +119,24 @@
   LeakChecker lc;
 
   for (size_t pass = 0; pass < 2; ++pass) {
+    constexpr int kThreadCount = 100;
+    struct thread_data { pthread_barrier_t* barrier; pid_t* tid; } threads[kThreadCount] = {};
+
     pthread_barrier_t barrier;
-    constexpr int thread_count = 100;
-    ASSERT_EQ(pthread_barrier_init(&barrier, nullptr, thread_count + 1), 0);
+    ASSERT_EQ(pthread_barrier_init(&barrier, nullptr, kThreadCount + 1), 0);
 
     // Start child threads.
-    struct thread_data { pthread_barrier_t* barrier; pid_t* tid; };
-    pid_t tids[thread_count];
-    for (int i = 0; i < thread_count; ++i) {
-      thread_data* td = new thread_data{&barrier, &tids[i]};
+    pid_t tids[kThreadCount];
+    for (int i = 0; i < kThreadCount; ++i) {
+      threads[i] = {&barrier, &tids[i]};
       const auto thread_function = +[](void* ptr) -> void* {
         thread_data* data = static_cast<thread_data*>(ptr);
         *data->tid = gettid();
         pthread_barrier_wait(data->barrier);
-        // Doing this delete allocates new VMAs for jemalloc bookkeeping,
-        // but the two-pass nature of this test means we can check that
-        // it's a pool rather than an unbounded leak.
-        delete data;
         return nullptr;
       };
       pthread_t thread;
-      ASSERT_EQ(0, pthread_create(&thread, nullptr, thread_function, td));
+      ASSERT_EQ(0, pthread_create(&thread, nullptr, thread_function, &threads[i]));
       ASSERT_EQ(0, pthread_detach(thread));
     }
 
diff --git a/tests/libs/Android.bp b/tests/libs/Android.bp
index c1600cc..8d0271a 100644
--- a/tests/libs/Android.bp
+++ b/tests/libs/Android.bp
@@ -17,6 +17,10 @@
 cc_defaults {
     name: "bionic_testlib_defaults",
     host_supported: true,
+    cflags: [
+        "-Wall",
+        "-Werror",
+    ],
     ldflags: [
         "-Wl,--rpath,${ORIGIN}",
         "-Wl,--enable-new-dtags",
@@ -282,15 +286,6 @@
             enabled: false,
         },
     },
-
-    target: {
-        android: {
-            shared_libs: ["libdl"],
-        },
-        host: {
-            host_ldlibs: ["-ldl"],
-        },
-    },
 }
 
 cc_test_library {
@@ -307,15 +302,6 @@
             enabled: false,
         },
     },
-
-    target: {
-        android: {
-            shared_libs: ["libdl"],
-        },
-        host: {
-            host_ldlibs: ["-ldl"],
-        },
-    },
 }
 
 cc_test_library {
@@ -331,15 +317,6 @@
             enabled: false,
         },
     },
-
-    target: {
-        android: {
-            shared_libs: ["libdl"],
-        },
-        host: {
-            host_ldlibs: ["-ldl"],
-        },
-    },
 }
 
 // -----------------------------------------------------------------------------
@@ -400,6 +377,26 @@
 }
 
 // -----------------------------------------------------------------------------
+// Library with DF_1_GLOBAL which will be dlopened
+// (note: libdl_test_df_1_global above will be included in DT_NEEDED)
+// -----------------------------------------------------------------------------
+cc_test_library {
+    name: "libtest_dlopen_df_1_global",
+    defaults: ["bionic_testlib_defaults"],
+    srcs: ["dl_df_1_global_dummy.cpp"],
+    ldflags: ["-Wl,-z,global"],
+
+    target: {
+        host: {
+            // TODO (dimitry): host ld.gold does not yet support -z global
+            // remove this line once it is updated.
+            ldflags: ["-fuse-ld=bfd"],
+        },
+    },
+}
+
+
+// -----------------------------------------------------------------------------
 // Library with weak function
 // -----------------------------------------------------------------------------
 cc_test_library {
@@ -416,15 +413,6 @@
     defaults: ["bionic_testlib_defaults"],
     srcs: ["dlsym_from_this_symbol.cpp"],
     shared_libs: ["libtest_dlsym_from_this_child"],
-
-    target: {
-        android: {
-            shared_libs: ["libdl"],
-        },
-        host: {
-            host_ldlibs: ["-ldl"],
-        },
-    },
 }
 
 // -----------------------------------------------------------------------------
@@ -433,14 +421,6 @@
     defaults: ["bionic_testlib_defaults"],
     srcs: ["dlsym_from_this_functions.cpp"],
     shared_libs: ["libtest_dlsym_from_this_grandchild"],
-    target: {
-        android: {
-            shared_libs: ["libdl"],
-        },
-        host: {
-            host_ldlibs: ["-ldl"],
-        },
-    },
 }
 
 // -----------------------------------------------------------------------------
@@ -460,6 +440,16 @@
 }
 
 // -----------------------------------------------------------------------------
+// Library for inaccessible shared library test
+// -----------------------------------------------------------------------------
+cc_test_library {
+    name: "libtestshared",
+    defaults: ["bionic_testlib_defaults"],
+    srcs: ["empty.cpp"],
+    relative_install_path: "bionic-loader-test-libs/inaccessible_libs",
+}
+
+// -----------------------------------------------------------------------------
 // Library with weak undefined function
 // -----------------------------------------------------------------------------
 cc_test_library {
@@ -475,15 +465,6 @@
     name: "libtest_check_rtld_next_from_library",
     defaults: ["bionic_testlib_defaults"],
     srcs: ["check_rtld_next_from_library.cpp"],
-
-    target: {
-        android: {
-            shared_libs: ["libdl"],
-        },
-        host: {
-            host_ldlibs: ["-ldl"],
-        },
-    },
 }
 
 // -----------------------------------------------------------------------------
@@ -493,14 +474,6 @@
     name: "libtest_dlopen_from_ctor",
     defaults: ["bionic_testlib_defaults"],
     srcs: ["dlopen_testlib_dlopen_from_ctor.cpp"],
-    target: {
-        android: {
-            shared_libs: ["libdl"],
-        },
-        host: {
-            host_ldlibs: ["-ldl"],
-        },
-    },
 }
 
 // -----------------------------------------------------------------------------
@@ -656,7 +629,7 @@
     defaults: ["bionic_testlib_defaults"],
     srcs: ["ld_config_test_helper_lib1.cpp"],
     shared_libs: ["ld_config_test_helper_lib2"],
-    relative_install_path: "/ns2",
+    relative_install_path: "bionic-loader-test-libs/ns2",
 }
 
 cc_test_library {
@@ -664,7 +637,7 @@
     host_supported: false,
     defaults: ["bionic_testlib_defaults"],
     srcs: ["ld_config_test_helper_lib2.cpp"],
-    relative_install_path: "/ns2",
+    relative_install_path: "bionic-loader-test-libs/ns2",
 }
 
 cc_test_library {
diff --git a/tests/libs/Android.mk b/tests/libs/Android.mk
index a54318d..5bd028d 100644
--- a/tests/libs/Android.mk
+++ b/tests/libs/Android.mk
@@ -17,7 +17,7 @@
 LOCAL_PATH := $(call my-dir)
 TEST_PATH := $(LOCAL_PATH)/..
 
-common_cppflags :=
+common_cppflags := -Wall -Werror
 common_additional_dependencies := \
     $(LOCAL_PATH)/Android.mk \
     $(LOCAL_PATH)/Android.build.dt_runpath.mk \
diff --git a/tests/libs/check_rtld_next_from_library.cpp b/tests/libs/check_rtld_next_from_library.cpp
index 45d8eea..fb15e2a 100644
--- a/tests/libs/check_rtld_next_from_library.cpp
+++ b/tests/libs/check_rtld_next_from_library.cpp
@@ -15,22 +15,23 @@
  */
 
 #include <dlfcn.h>
+#include <stdio.h>
 #include <stdlib.h>
 
-static void* g_libc_close_ptr;
+static void* g_libc_fclose_ptr;
 
-static void __attribute__((constructor)) __libc_close_lookup() {
-  g_libc_close_ptr = dlsym(RTLD_NEXT, "close");
+static void __attribute__((constructor)) __libc_fclose_lookup() {
+  g_libc_fclose_ptr = dlsym(RTLD_NEXT, "fclose");
 }
 
-// A libc function used for RTLD_NEXT
-// This function in not supposed to be called
-extern "C" int __attribute__((weak)) close(int) {
+// A libc function used for RTLD_NEXT.
+// This function in not supposed to be called.
+extern "C" int __attribute__((weak)) fclose(FILE*) {
   abort();
 }
 
-extern "C" void* get_libc_close_ptr() {
-  return g_libc_close_ptr;
+extern "C" void* get_libc_fclose_ptr() {
+  return g_libc_fclose_ptr;
 }
 
 
diff --git a/libm/arm64/fma.S b/tests/libs/dl_df_1_global_dummy.cpp
similarity index 74%
rename from libm/arm64/fma.S
rename to tests/libs/dl_df_1_global_dummy.cpp
index 1a8a158..423247c 100644
--- a/libm/arm64/fma.S
+++ b/tests/libs/dl_df_1_global_dummy.cpp
@@ -1,5 +1,5 @@
 /*
- * Copyright (C) 2015 The Android Open Source Project
+ * Copyright (C) 2017 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.
@@ -14,14 +14,6 @@
  * limitations under the License.
  */
 
-#include <private/bionic_asm.h>
-
-ENTRY(fma)
-  fmadd d0, d0, d1, d2
-  ret
-END(fma)
-
-ENTRY(fmaf)
-  fmadd s0, s0, s1, s2
-  ret
-END(fmaf)
+extern "C" int foo() {
+  return 1;
+}
diff --git a/tests/limits_test.cpp b/tests/limits_test.cpp
index 1d48ffe..e5902ad 100644
--- a/tests/limits_test.cpp
+++ b/tests/limits_test.cpp
@@ -19,9 +19,9 @@
 #include <limits.h>
 
 TEST(limits, macros) {
-#if CHAR_BIT != 8
-#error Insane CHAR_BIT
-#endif
+  ASSERT_EQ(8, CHAR_BIT);
+  ASSERT_EQ(8 * static_cast<int>(sizeof(int)), WORD_BIT);
+  ASSERT_EQ(20, NZERO);
 #if !defined(MB_LEN_MAX)
 #error MB_LEN_MAX
 #endif
diff --git a/tests/linux_swab_test.cpp b/tests/linux_swab_test.cpp
index 6b964dc..ffd4072 100644
--- a/tests/linux_swab_test.cpp
+++ b/tests/linux_swab_test.cpp
@@ -21,7 +21,7 @@
 // This test makes sure that references to all of the kernel swab
 // macros/inline functions that are exported work properly.
 // Verifies that any kernel header updates do not break these macros.
-TEST(swab, fswa) {
+TEST(linux_swab, smoke) {
   EXPECT_EQ(0x3412U, __swab16(0x1234));
   EXPECT_EQ(0x78563412U, __swab32(0x12345678U));
   EXPECT_EQ(0xbaefcdab78563412ULL, __swab64(0x12345678abcdefbaULL));
diff --git a/tests/math_test.cpp b/tests/math_test.cpp
index 0fc4e50..d029311 100644
--- a/tests/math_test.cpp
+++ b/tests/math_test.cpp
@@ -176,6 +176,20 @@
   ASSERT_NE(0, test_capture_signbit(-1.0L));
 }
 
+// Historical BSD cruft that isn't exposed in <math.h> any more.
+extern "C" int __fpclassify(double);
+extern "C" int __fpclassifyd(double);
+extern "C" int __fpclassifyf(float);
+extern "C" int __fpclassifyl(long double);
+
+TEST(MATH_TEST, __fpclassify) {
+  ASSERT_EQ(FP_INFINITE, __fpclassify(HUGE_VAL));
+  ASSERT_EQ(FP_NAN, __fpclassify(nan("")));
+  ASSERT_EQ(FP_NORMAL, __fpclassify(1.0));
+  ASSERT_EQ(FP_SUBNORMAL, __fpclassify(double_subnormal()));
+  ASSERT_EQ(FP_ZERO, __fpclassify(0.0));
+}
+
 TEST(MATH_TEST, __fpclassifyd) {
 #if defined(__GLIBC__)
 #define __fpclassifyd __fpclassify
@@ -208,6 +222,11 @@
   ASSERT_FALSE(finitef(HUGE_VALF));
 }
 
+// Historical BSD cruft that isn't exposed in <math.h> any more.
+extern "C" int __isfinite(double);
+extern "C" int __isfinitef(float);
+extern "C" int __isfinitel(long double);
+
 TEST(MATH_TEST, __isfinite) {
 #if defined(__GLIBC__)
 #define __isfinite __finite
@@ -243,6 +262,16 @@
   ASSERT_TRUE((isinf)(HUGE_VAL));
 }
 
+// Historical BSD cruft that isn't exposed in <math.h> any more.
+extern "C" int __isinf(double);
+extern "C" int __isinff(float);
+extern "C" int __isinfl(long double);
+
+TEST(MATH_TEST, __isinf) {
+  ASSERT_FALSE(__isinf(123.0));
+  ASSERT_TRUE(__isinf(HUGE_VAL));
+}
+
 TEST(MATH_TEST, __isinff) {
   ASSERT_FALSE(__isinff(123.0f));
   ASSERT_TRUE(__isinff(HUGE_VALF));
@@ -259,6 +288,16 @@
   ASSERT_TRUE((isnan)(nan("")));
 }
 
+// Historical BSD cruft that isn't exposed in <math.h> any more.
+extern "C" int __isnan(double);
+extern "C" int __isnanf(float);
+extern "C" int __isnanl(long double);
+
+TEST(MATH_TEST, __isnan) {
+  ASSERT_FALSE(__isnan(123.0));
+  ASSERT_TRUE(__isnan(nan("")));
+}
+
 TEST(MATH_TEST, __isnanf) {
   ASSERT_FALSE(__isnanf(123.0f));
   ASSERT_TRUE(__isnanf(nanf("")));
@@ -274,6 +313,11 @@
   ASSERT_TRUE(isnanf(nanf("")));
 }
 
+// Historical BSD cruft that isn't exposed in <math.h> any more.
+extern "C" int __isnormal(double);
+extern "C" int __isnormalf(float);
+extern "C" int __isnormall(long double);
+
 TEST(MATH_TEST, __isnormal) {
 #if defined(__BIONIC__)
   ASSERT_TRUE(__isnormal(123.0));
@@ -301,6 +345,11 @@
 #endif // __BIONIC__
 }
 
+// Historical BSD cruft that isn't exposed in <math.h> any more.
+extern "C" int __signbit(double);
+extern "C" int __signbitf(float);
+extern "C" int __signbitl(long double);
+
 TEST(MATH_TEST, __signbit) {
   ASSERT_EQ(0, __signbit(0.0));
   ASSERT_EQ(0, __signbit(1.0));
diff --git a/tests/netdb_test.cpp b/tests/netdb_test.cpp
index a35f703..a624138 100644
--- a/tests/netdb_test.cpp
+++ b/tests/netdb_test.cpp
@@ -271,8 +271,9 @@
   char buf[4]; // Use too small buffer.
   int err;
   int result = gethostbyname_r("localhost", &hent, buf, sizeof(buf), &hp, &err);
-  ASSERT_EQ(ERANGE, result);
-  ASSERT_EQ(NULL, hp);
+  EXPECT_EQ(NETDB_INTERNAL, err);
+  EXPECT_EQ(ERANGE, result);
+  EXPECT_EQ(NULL, hp);
 }
 
 TEST(netdb, gethostbyname2_r_ERANGE) {
@@ -281,8 +282,9 @@
   char buf[4]; // Use too small buffer.
   int err;
   int result = gethostbyname2_r("localhost", AF_INET, &hent, buf, sizeof(buf), &hp, &err);
-  ASSERT_EQ(ERANGE, result);
-  ASSERT_EQ(NULL, hp);
+  EXPECT_EQ(NETDB_INTERNAL, err);
+  EXPECT_EQ(ERANGE, result);
+  EXPECT_EQ(NULL, hp);
 }
 
 TEST(netdb, gethostbyaddr_r_ERANGE) {
@@ -292,30 +294,193 @@
   char buf[4]; // Use too small buffer.
   int err;
   int result = gethostbyaddr_r(&addr, sizeof(addr), AF_INET, &hent, buf, sizeof(buf), &hp, &err);
-  ASSERT_EQ(ERANGE, result);
-  ASSERT_EQ(NULL, hp);
+  EXPECT_EQ(NETDB_INTERNAL, err);
+  EXPECT_EQ(ERANGE, result);
+  EXPECT_EQ(NULL, hp);
+}
+
+TEST(netdb, gethostbyname_r_HOST_NOT_FOUND) {
+  hostent hent;
+  hostent *hp;
+  char buf[BUFSIZ];
+  int err;
+  int result = gethostbyname_r("does.not.exist.google.com", &hent, buf, sizeof(buf), &hp, &err);
+  EXPECT_EQ(HOST_NOT_FOUND, err);
+  EXPECT_EQ(0, result);
+  EXPECT_EQ(NULL, hp);
+}
+
+TEST(netdb, gethostbyname2_r_HOST_NOT_FOUND) {
+  hostent hent;
+  hostent *hp;
+  char buf[BUFSIZ];
+  int err;
+  int result = gethostbyname2_r("does.not.exist.google.com", AF_INET, &hent, buf, sizeof(buf), &hp, &err);
+  EXPECT_EQ(HOST_NOT_FOUND, err);
+  EXPECT_EQ(0, result);
+  EXPECT_EQ(NULL, hp);
+}
+
+TEST(netdb, gethostbyaddr_r_HOST_NOT_FOUND) {
+  in_addr addr = { htonl(0xffffffff) };
+  hostent hent;
+  hostent *hp;
+  char buf[BUFSIZ];
+  int err;
+  int result = gethostbyaddr_r(&addr, sizeof(addr), AF_INET, &hent, buf, sizeof(buf), &hp, &err);
+  EXPECT_EQ(HOST_NOT_FOUND, err);
+  EXPECT_EQ(0, result);
+  EXPECT_EQ(NULL, hp);
 }
 
 TEST(netdb, getservbyname) {
   // smtp is TCP-only, so we know we'll get 25/tcp back.
-  servent* s = getservbyname("smtp", NULL);
-  ASSERT_TRUE(s != NULL);
+  servent* s = getservbyname("smtp", nullptr);
+  ASSERT_TRUE(s != nullptr);
+  ASSERT_STREQ("smtp", s->s_name);
   ASSERT_EQ(25, ntohs(s->s_port));
   ASSERT_STREQ("tcp", s->s_proto);
 
   // We get the same result by explicitly asking for tcp.
   s = getservbyname("smtp", "tcp");
-  ASSERT_TRUE(s != NULL);
+  ASSERT_TRUE(s != nullptr);
+  ASSERT_STREQ("smtp", s->s_name);
   ASSERT_EQ(25, ntohs(s->s_port));
   ASSERT_STREQ("tcp", s->s_proto);
 
   // And we get a failure if we explicitly ask for udp.
   s = getservbyname("smtp", "udp");
-  ASSERT_TRUE(s == NULL);
+  ASSERT_TRUE(s == nullptr);
 
   // But there are actually udp services.
   s = getservbyname("echo", "udp");
-  ASSERT_TRUE(s != NULL);
+  ASSERT_TRUE(s != nullptr);
+  ASSERT_STREQ("echo", s->s_name);
   ASSERT_EQ(7, ntohs(s->s_port));
   ASSERT_STREQ("udp", s->s_proto);
 }
+
+TEST(netdb, getservbyport) {
+  // smtp is TCP-only, so we know we'll get 25/tcp back.
+  servent* s = getservbyport(htons(25), nullptr);
+  ASSERT_TRUE(s != nullptr);
+  ASSERT_STREQ("smtp", s->s_name);
+  ASSERT_EQ(25, ntohs(s->s_port));
+  ASSERT_STREQ("tcp", s->s_proto);
+
+  // We get the same result by explicitly asking for tcp.
+  s = getservbyport(htons(25), "tcp");
+  ASSERT_TRUE(s != nullptr);
+  ASSERT_STREQ("smtp", s->s_name);
+  ASSERT_EQ(25, ntohs(s->s_port));
+  ASSERT_STREQ("tcp", s->s_proto);
+
+  // And we get a failure if we explicitly ask for udp.
+  s = getservbyport(htons(25), "udp");
+  ASSERT_TRUE(s == nullptr);
+
+  // But there are actually udp services.
+  s = getservbyport(htons(7), "udp");
+  ASSERT_TRUE(s != nullptr);
+  ASSERT_STREQ("echo", s->s_name);
+  ASSERT_EQ(7, ntohs(s->s_port));
+  ASSERT_STREQ("udp", s->s_proto);
+}
+
+TEST(netdb, endnetent_getnetent_setnetent) {
+  setnetent(0);
+  setnetent(1);
+  endnetent();
+  while (getnetent() != nullptr) {
+  }
+}
+
+TEST(netdb, getnetbyaddr) {
+  getnetbyaddr(0, 0);
+}
+
+TEST(netdb, getnetbyname) {
+  getnetbyname("x");
+}
+
+TEST(netdb, endprotoent_getprotoent_setprotoent) {
+  setprotoent(0);
+  setprotoent(1);
+  endprotoent();
+  while (getprotoent() != nullptr) {
+  }
+}
+
+TEST(netdb, getprotobyname) {
+  getprotobyname("tcp");
+}
+
+TEST(netdb, getprotobynumber) {
+  getprotobynumber(6);
+}
+
+TEST(netdb, endservent_getservent_setservent) {
+  setservent(0);
+  setservent(1);
+  endservent();
+  size_t service_count = 0;
+  while (getservent() != nullptr) {
+    ++service_count;
+  }
+  ASSERT_GT(service_count, 0U);
+}
+
+TEST(netdb, getservbyname_getservent_conflicts) {
+  // Calling getservbyname shouldn't affect getservent's iteration order.
+  endservent();
+  while (getservent() != nullptr) {
+    ASSERT_TRUE(getservbyname("smtp", "tcp") != nullptr);
+  }
+}
+
+TEST(netdb, getservbyport_getservent_conflicts) {
+  // Calling getservbyport shouldn't affect getservent's iteration order.
+  endservent();
+  while (getservent() != nullptr) {
+    ASSERT_TRUE(getservbyport(htons(25), "tcp") != nullptr);
+  }
+}
+
+TEST(netdb, endservent_resets) {
+  endservent();
+  std::string first_service(getservent()->s_name);
+  endservent();
+  ASSERT_EQ(first_service, std::string(getservent()->s_name));
+}
+
+TEST(netdb, setservent_resets) {
+  endservent();
+  std::string first_service(getservent()->s_name);
+  setservent(0);
+  ASSERT_EQ(first_service, std::string(getservent()->s_name));
+}
+
+TEST(netdb, endhostent_gethostent_sethostent) {
+  sethostent(0);
+  sethostent(1);
+  endhostent();
+  size_t host_count = 0;
+  while (gethostent() != nullptr) {
+    ++host_count;
+  }
+  ASSERT_GT(host_count, 0U);
+}
+
+TEST(netdb, endhostent_resets) {
+  endhostent();
+  std::string first_host(gethostent()->h_name);
+  endhostent();
+  ASSERT_EQ(first_host, std::string(gethostent()->h_name));
+}
+
+TEST(netdb, sethostent_resets) {
+  endhostent();
+  std::string first_host(gethostent()->h_name);
+  sethostent(0);
+  ASSERT_EQ(first_host, std::string(gethostent()->h_name));
+}
diff --git a/tests/pthread_test.cpp b/tests/pthread_test.cpp
index 46140bb..183312d 100755
--- a/tests/pthread_test.cpp
+++ b/tests/pthread_test.cpp
@@ -199,9 +199,11 @@
   SpinFunctionHelper() {
     SpinFunctionHelper::spin_flag_ = true;
   }
+
   ~SpinFunctionHelper() {
     UnSpin();
   }
+
   auto GetFunction() -> void* (*)(void*) {
     return SpinFunctionHelper::SpinFn;
   }
@@ -566,6 +568,18 @@
   EXPECT_EQ(ESRCH, pthread_setschedparam(null_thread, policy, &param));
 }
 
+TEST_F(pthread_DeathTest, pthread_setschedprio__no_such_thread) {
+  pthread_t dead_thread;
+  MakeDeadThread(dead_thread);
+
+  EXPECT_DEATH(pthread_setschedprio(dead_thread, 123), "invalid pthread_t");
+}
+
+TEST_F(pthread_DeathTest, pthread_setschedprio__null_thread) {
+  pthread_t null_thread = 0;
+  EXPECT_EQ(ESRCH, pthread_setschedprio(null_thread, 123));
+}
+
 TEST_F(pthread_DeathTest, pthread_join__no_such_thread) {
   pthread_t dead_thread;
   MakeDeadThread(dead_thread);
@@ -1515,7 +1529,7 @@
   ASSERT_EQ(0, pthread_create(&t, NULL,
             reinterpret_cast<void* (*)(void*)>(pthread_attr_getstack_18908062_helper),
             NULL));
-  pthread_join(t, NULL);
+  ASSERT_EQ(0, pthread_join(t, NULL));
 }
 
 #if defined(__BIONIC__)
@@ -1547,7 +1561,7 @@
 
   // Release the other thread and wait for it to exit.
   pthread_mutex_unlock(&pthread_gettid_np_mutex);
-  pthread_join(t, NULL);
+  ASSERT_EQ(0, pthread_join(t, NULL));
 
   ASSERT_EQ(t_gettid_result, t_pthread_gettid_np_result);
 #else
@@ -1588,7 +1602,7 @@
 TEST(pthread, pthread_cleanup_push__pthread_cleanup_pop) {
   pthread_t t;
   ASSERT_EQ(0, pthread_create(&t, NULL, PthreadCleanupStartRoutine, NULL));
-  pthread_join(t, NULL);
+  ASSERT_EQ(0, pthread_join(t, NULL));
   ASSERT_EQ(2U, cleanup_counter);
 }
 
@@ -2101,13 +2115,22 @@
   ASSERT_EQ(0, pthread_spin_destroy(&lock));
 }
 
-TEST(pthread, pthread_attr_setdetachstate) {
+TEST(pthread, pthread_attr_getdetachstate__pthread_attr_setdetachstate) {
   pthread_attr_t attr;
   ASSERT_EQ(0, pthread_attr_init(&attr));
 
+  int state;
   ASSERT_EQ(0, pthread_attr_setdetachstate(&attr, PTHREAD_CREATE_DETACHED));
+  ASSERT_EQ(0, pthread_attr_getdetachstate(&attr, &state));
+  ASSERT_EQ(PTHREAD_CREATE_DETACHED, state);
+
   ASSERT_EQ(0, pthread_attr_setdetachstate(&attr, PTHREAD_CREATE_JOINABLE));
+  ASSERT_EQ(0, pthread_attr_getdetachstate(&attr, &state));
+  ASSERT_EQ(PTHREAD_CREATE_JOINABLE, state);
+
   ASSERT_EQ(EINVAL, pthread_attr_setdetachstate(&attr, 123));
+  ASSERT_EQ(0, pthread_attr_getdetachstate(&attr, &state));
+  ASSERT_EQ(PTHREAD_CREATE_JOINABLE, state);
 }
 
 TEST(pthread, pthread_create__mmap_failures) {
@@ -2117,8 +2140,9 @@
 
   const auto kPageSize = sysconf(_SC_PAGE_SIZE);
 
-  // Use up all the VMAs. By default this is 64Ki.
+  // Use up all the VMAs. By default this is 64Ki (though some will already be in use).
   std::vector<void*> pages;
+  pages.reserve(64 * 1024);
   int prot = PROT_NONE;
   while (true) {
     void* page = mmap(nullptr, kPageSize, prot, MAP_ANON|MAP_PRIVATE, -1, 0);
@@ -2146,3 +2170,127 @@
     ASSERT_EQ(0, munmap(pages[i], kPageSize));
   }
 }
+
+TEST(pthread, pthread_setschedparam) {
+  sched_param p = { .sched_priority = INT_MIN };
+  ASSERT_EQ(EINVAL, pthread_setschedparam(pthread_self(), INT_MIN, &p));
+}
+
+TEST(pthread, pthread_setschedprio) {
+  ASSERT_EQ(EINVAL, pthread_setschedprio(pthread_self(), INT_MIN));
+}
+
+TEST(pthread, pthread_attr_getinheritsched__pthread_attr_setinheritsched) {
+  pthread_attr_t attr;
+  ASSERT_EQ(0, pthread_attr_init(&attr));
+
+  int state;
+  ASSERT_EQ(0, pthread_attr_setinheritsched(&attr, PTHREAD_INHERIT_SCHED));
+  ASSERT_EQ(0, pthread_attr_getinheritsched(&attr, &state));
+  ASSERT_EQ(PTHREAD_INHERIT_SCHED, state);
+
+  ASSERT_EQ(0, pthread_attr_setinheritsched(&attr, PTHREAD_EXPLICIT_SCHED));
+  ASSERT_EQ(0, pthread_attr_getinheritsched(&attr, &state));
+  ASSERT_EQ(PTHREAD_EXPLICIT_SCHED, state);
+
+  ASSERT_EQ(EINVAL, pthread_attr_setinheritsched(&attr, 123));
+  ASSERT_EQ(0, pthread_attr_getinheritsched(&attr, &state));
+  ASSERT_EQ(PTHREAD_EXPLICIT_SCHED, state);
+}
+
+TEST(pthread, pthread_attr_setinheritsched__PTHREAD_INHERIT_SCHED__PTHREAD_EXPLICIT_SCHED) {
+  pthread_attr_t attr;
+  ASSERT_EQ(0, pthread_attr_init(&attr));
+
+  // If we set invalid scheduling attributes but choose to inherit, everything's fine...
+  sched_param param = { .sched_priority = sched_get_priority_max(SCHED_FIFO) + 1 };
+  ASSERT_EQ(0, pthread_attr_setschedparam(&attr, &param));
+  ASSERT_EQ(0, pthread_attr_setschedpolicy(&attr, SCHED_FIFO));
+  ASSERT_EQ(0, pthread_attr_setinheritsched(&attr, PTHREAD_INHERIT_SCHED));
+
+  pthread_t t;
+  ASSERT_EQ(0, pthread_create(&t, &attr, IdFn, nullptr));
+  ASSERT_EQ(0, pthread_join(t, nullptr));
+
+#if defined(__LP64__)
+  // If we ask to use them, though, we'll see a failure...
+  ASSERT_EQ(0, pthread_attr_setinheritsched(&attr, PTHREAD_EXPLICIT_SCHED));
+  ASSERT_EQ(EINVAL, pthread_create(&t, &attr, IdFn, nullptr));
+#else
+  // For backwards compatibility with broken apps, we just ignore failures
+  // to set scheduler attributes on LP32.
+#endif
+}
+
+TEST(pthread, pthread_attr_setinheritsched_PTHREAD_INHERIT_SCHED_takes_effect) {
+  sched_param param = { .sched_priority = sched_get_priority_min(SCHED_FIFO) };
+  int rc = pthread_setschedparam(pthread_self(), SCHED_FIFO, &param);
+  if (rc == EPERM) {
+    GTEST_LOG_(INFO) << "pthread_setschedparam failed with EPERM, skipping test\n";
+    return;
+  }
+  ASSERT_EQ(0, rc);
+
+  pthread_attr_t attr;
+  ASSERT_EQ(0, pthread_attr_init(&attr));
+  ASSERT_EQ(0, pthread_attr_setinheritsched(&attr, PTHREAD_INHERIT_SCHED));
+
+  SpinFunctionHelper spin_helper;
+  pthread_t t;
+  ASSERT_EQ(0, pthread_create(&t, &attr, spin_helper.GetFunction(), nullptr));
+  int actual_policy;
+  sched_param actual_param;
+  ASSERT_EQ(0, pthread_getschedparam(t, &actual_policy, &actual_param));
+  ASSERT_EQ(SCHED_FIFO, actual_policy);
+  spin_helper.UnSpin();
+  ASSERT_EQ(0, pthread_join(t, nullptr));
+}
+
+TEST(pthread, pthread_attr_setinheritsched_PTHREAD_EXPLICIT_SCHED_takes_effect) {
+  sched_param param = { .sched_priority = sched_get_priority_min(SCHED_FIFO) };
+  int rc = pthread_setschedparam(pthread_self(), SCHED_FIFO, &param);
+  if (rc == EPERM) {
+    GTEST_LOG_(INFO) << "pthread_setschedparam failed with EPERM, skipping test\n";
+    return;
+  }
+  ASSERT_EQ(0, rc);
+
+  pthread_attr_t attr;
+  ASSERT_EQ(0, pthread_attr_init(&attr));
+  ASSERT_EQ(0, pthread_attr_setinheritsched(&attr, PTHREAD_EXPLICIT_SCHED));
+  ASSERT_EQ(0, pthread_attr_setschedpolicy(&attr, SCHED_OTHER));
+
+  SpinFunctionHelper spin_helper;
+  pthread_t t;
+  ASSERT_EQ(0, pthread_create(&t, &attr, spin_helper.GetFunction(), nullptr));
+  int actual_policy;
+  sched_param actual_param;
+  ASSERT_EQ(0, pthread_getschedparam(t, &actual_policy, &actual_param));
+  ASSERT_EQ(SCHED_OTHER, actual_policy);
+  spin_helper.UnSpin();
+  ASSERT_EQ(0, pthread_join(t, nullptr));
+}
+
+TEST(pthread, pthread_attr_setinheritsched__takes_effect_despite_SCHED_RESET_ON_FORK) {
+  sched_param param = { .sched_priority = sched_get_priority_min(SCHED_FIFO) };
+  int rc = pthread_setschedparam(pthread_self(), SCHED_FIFO | SCHED_RESET_ON_FORK, &param);
+  if (rc == EPERM) {
+    GTEST_LOG_(INFO) << "pthread_setschedparam failed with EPERM, skipping test\n";
+    return;
+  }
+  ASSERT_EQ(0, rc);
+
+  pthread_attr_t attr;
+  ASSERT_EQ(0, pthread_attr_init(&attr));
+  ASSERT_EQ(0, pthread_attr_setinheritsched(&attr, PTHREAD_INHERIT_SCHED));
+
+  SpinFunctionHelper spin_helper;
+  pthread_t t;
+  ASSERT_EQ(0, pthread_create(&t, &attr, spin_helper.GetFunction(), nullptr));
+  int actual_policy;
+  sched_param actual_param;
+  ASSERT_EQ(0, pthread_getschedparam(t, &actual_policy, &actual_param));
+  ASSERT_EQ(SCHED_FIFO  | SCHED_RESET_ON_FORK, actual_policy);
+  spin_helper.UnSpin();
+  ASSERT_EQ(0, pthread_join(t, nullptr));
+}
diff --git a/tests/pty_test.cpp b/tests/pty_test.cpp
index 74415d5..609f2dc 100644
--- a/tests/pty_test.cpp
+++ b/tests/pty_test.cpp
@@ -112,7 +112,7 @@
     GTEST_LOG_(INFO) << "This test tests bug happens only on multiprocessors.";
     return;
   }
-  constexpr uint32_t TEST_DATA_COUNT = 200000;
+  constexpr uint32_t TEST_DATA_COUNT = 2000000;
 
   // 1. Open raw pty.
   int master;
@@ -149,11 +149,16 @@
   ASSERT_EQ(0, sched_setaffinity(0, sizeof(cpu_set_t), &cpus));
 
   // 4. Send data to slave.
+  // Send a bunch of data at a time, so it is easier to catch the bug that some data isn't seen
+  // by the reader thread on another cpu.
+  uint32_t counter_buf[100];
   uint32_t counter = 0;
   while (counter <= TEST_DATA_COUNT) {
-    ASSERT_TRUE(android::base::WriteFully(master, &counter, sizeof(counter)));
+    for (size_t i = 0; i < sizeof(counter_buf) / sizeof(counter_buf[0]); ++i) {
+      counter_buf[i] = counter++;
+    }
+    ASSERT_TRUE(android::base::WriteFully(master, &counter_buf, sizeof(counter_buf)));
     ASSERT_TRUE(arg.matched) << "failed at count = " << counter;
-    counter++;
   }
   ASSERT_EQ(0, pthread_join(thread, nullptr));
   ASSERT_TRUE(arg.finished);
diff --git a/tests/qsort_test.cpp b/tests/qsort_test.cpp
deleted file mode 100644
index 95b4789..0000000
--- a/tests/qsort_test.cpp
+++ /dev/null
@@ -1,106 +0,0 @@
-/*
- * Copyright (C) 2017 The Android Open Source Project
- *
- * Licensed under the Apache License, Version 2.0 (the "License");
- * you may not use this file except in compliance with the License.
- * You may obtain a copy of the License at
- *
- *      http://www.apache.org/licenses/LICENSE-2.0
- *
- * Unless required by applicable law or agreed to in writing, software
- * distributed under the License is distributed on an "AS IS" BASIS,
- * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
- * See the License for the specific language governing permissions and
- * limitations under the License.
- */
-
-#include <stdlib.h>
-#include <sys/types.h>
-
-#include <gtest/gtest.h>
-
-#include "gtest_globals.h"
-
-#define BUFFER_SIZE 1024
-
-static int cmp_long(const void *l, const void *r)
-{
-
-  return (*(long *)l - *(long *)r);
-}
-
-static int cmp_int(const void *l, const void *r)
-{
-
-  return (*(int *)l - *(int *)r);
-}
-
-#ifndef arc4random_uniform
-static bool seeded;
-
-u_int32_t arc4random_uniform(uint32_t upper_bound)
-{
-  if (!seeded) {
-    srandom((int)time(NULL));
-    seeded = true;
-  }
-
-  return (random() % upper_bound);
-}
-#endif
-
-TEST(qsort_test, long_test) {
-  long buf[BUFFER_SIZE];
-  long i;
-
-  /* Initialize buffer with known numbers */
-  for (i=0; i<BUFFER_SIZE; i++)
-    buf[i] = i;
-
-  /* Stir 1/4 pairs in the buffer */
-  for (i=0; i<BUFFER_SIZE/4; i++) {
-    u_int32_t pos1, pos2;
-    long t;
-
-    pos1 = arc4random_uniform(BUFFER_SIZE);
-    pos2 = arc4random_uniform(BUFFER_SIZE);
-
-    t = buf[pos1];
-    buf[pos1] = buf[pos2];
-    buf[pos2] = t;
-  }
-
-  /* Sort */
-  qsort(buf, BUFFER_SIZE, sizeof(buf[0]), &cmp_long);
-
-  for (i=0; i<BUFFER_SIZE; i++)
-    EXPECT_EQ(i, buf[i]);
-}
-
-TEST(qsort_test, int_test) {
-  int buf[BUFFER_SIZE];
-  int i;
-
-  /* Initialize buffer with known numbers */
-  for (i=0; i<BUFFER_SIZE; i++)
-    buf[i] = i;
-
-  /* Stir 1/4 pairs in the buffer */
-  for (i=0; i<BUFFER_SIZE/4; i++) {
-    u_int32_t pos1, pos2;
-    int t;
-
-    pos1 = arc4random_uniform(BUFFER_SIZE);
-    pos2 = arc4random_uniform(BUFFER_SIZE);
-
-    t = buf[pos1];
-    buf[pos1] = buf[pos2];
-    buf[pos2] = t;
-  }
-
-  /* Sort */
-  qsort(buf, BUFFER_SIZE, sizeof(buf[0]), &cmp_int);
-
-  for (i=0; i<BUFFER_SIZE; i++)
-    EXPECT_EQ(i, buf[i]);
-}
diff --git a/tests/resolv_test.cpp b/tests/resolv_test.cpp
index 08f9d90..f1d82e4 100644
--- a/tests/resolv_test.cpp
+++ b/tests/resolv_test.cpp
@@ -42,3 +42,19 @@
   uint8_t buf[128];
   ASSERT_EQ(128, b64_pton(data, buf, sizeof(buf)));
 }
+
+TEST(resolv, b64_ntop) {
+  char buf[128];
+  memset(buf, 'x', sizeof(buf));
+  ASSERT_EQ(static_cast<int>(strlen("aGVsbG8=")),
+            b64_ntop(reinterpret_cast<u_char const*>("hello"), strlen("hello"),
+                     buf, sizeof(buf)));
+  ASSERT_STREQ(buf, "aGVsbG8=");
+}
+
+TEST(resolv, b64_pton) {
+  u_char buf[128];
+  memset(buf, 'x', sizeof(buf));
+  ASSERT_EQ(static_cast<int>(strlen("hello")), b64_pton("aGVsbG8=", buf, sizeof(buf)));
+  ASSERT_STREQ(reinterpret_cast<char*>(buf), "hello");
+}
diff --git a/tests/spawn_test.cpp b/tests/spawn_test.cpp
new file mode 100644
index 0000000..6a3920e
--- /dev/null
+++ b/tests/spawn_test.cpp
@@ -0,0 +1,388 @@
+/*
+ * Copyright (C) 2017 The Android Open Source Project
+ *
+ * Licensed under the Apache License, Version 2.0 (the "License");
+ * you may not use this file except in compliance with the License.
+ * You may obtain a copy of the License at
+ *
+ *      http://www.apache.org/licenses/LICENSE-2.0
+ *
+ * Unless required by applicable law or agreed to in writing, software
+ * distributed under the License is distributed on an "AS IS" BASIS,
+ * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
+ * See the License for the specific language governing permissions and
+ * limitations under the License.
+ */
+
+#include <spawn.h>
+
+#include <errno.h>
+#include <fcntl.h>
+#include <gtest/gtest.h>
+
+#include "utils.h"
+
+#include <android-base/file.h>
+#include <android-base/strings.h>
+
+// Old versions of glibc didn't have POSIX_SPAWN_SETSID.
+#if __GLIBC__
+# if !defined(POSIX_SPAWN_SETSID)
+#  define POSIX_SPAWN_SETSID 0
+# endif
+#endif
+
+TEST(spawn, posix_spawnattr_init_posix_spawnattr_destroy) {
+  posix_spawnattr_t sa;
+  ASSERT_EQ(0, posix_spawnattr_init(&sa));
+  ASSERT_EQ(0, posix_spawnattr_destroy(&sa));
+}
+
+TEST(spawn, posix_spawnattr_setflags_EINVAL) {
+  posix_spawnattr_t sa;
+  ASSERT_EQ(0, posix_spawnattr_init(&sa));
+  ASSERT_EQ(EINVAL, posix_spawnattr_setflags(&sa, ~0));
+  ASSERT_EQ(0, posix_spawnattr_destroy(&sa));
+}
+
+TEST(spawn, posix_spawnattr_setflags_posix_spawnattr_getflags) {
+  posix_spawnattr_t sa;
+  ASSERT_EQ(0, posix_spawnattr_init(&sa));
+
+  ASSERT_EQ(0, posix_spawnattr_setflags(&sa, POSIX_SPAWN_RESETIDS));
+  short flags;
+  ASSERT_EQ(0, posix_spawnattr_getflags(&sa, &flags));
+  ASSERT_EQ(POSIX_SPAWN_RESETIDS, flags);
+
+  constexpr short all_flags = POSIX_SPAWN_RESETIDS | POSIX_SPAWN_SETPGROUP | POSIX_SPAWN_SETSIGDEF |
+                              POSIX_SPAWN_SETSIGMASK | POSIX_SPAWN_SETSCHEDPARAM |
+                              POSIX_SPAWN_SETSCHEDULER | POSIX_SPAWN_USEVFORK | POSIX_SPAWN_SETSID;
+  ASSERT_EQ(0, posix_spawnattr_setflags(&sa, all_flags));
+  ASSERT_EQ(0, posix_spawnattr_getflags(&sa, &flags));
+  ASSERT_EQ(all_flags, flags);
+
+  ASSERT_EQ(0, posix_spawnattr_destroy(&sa));
+}
+
+TEST(spawn, posix_spawnattr_setpgroup_posix_spawnattr_getpgroup) {
+  posix_spawnattr_t sa;
+  ASSERT_EQ(0, posix_spawnattr_init(&sa));
+
+  ASSERT_EQ(0, posix_spawnattr_setpgroup(&sa, 123));
+  pid_t g;
+  ASSERT_EQ(0, posix_spawnattr_getpgroup(&sa, &g));
+  ASSERT_EQ(123, g);
+
+  ASSERT_EQ(0, posix_spawnattr_destroy(&sa));
+}
+
+TEST(spawn, posix_spawnattr_setsigmask_posix_spawnattr_getsigmask) {
+  posix_spawnattr_t sa;
+  ASSERT_EQ(0, posix_spawnattr_init(&sa));
+
+  sigset_t sigs;
+  ASSERT_EQ(0, posix_spawnattr_getsigmask(&sa, &sigs));
+  ASSERT_FALSE(sigismember(&sigs, SIGALRM));
+
+  sigset_t just_SIGALRM;
+  sigemptyset(&just_SIGALRM);
+  sigaddset(&just_SIGALRM, SIGALRM);
+  ASSERT_EQ(0, posix_spawnattr_setsigmask(&sa, &just_SIGALRM));
+
+  ASSERT_EQ(0, posix_spawnattr_getsigmask(&sa, &sigs));
+  ASSERT_TRUE(sigismember(&sigs, SIGALRM));
+
+  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));
+
+  sigset_t sigs;
+  ASSERT_EQ(0, posix_spawnattr_getsigdefault(&sa, &sigs));
+  ASSERT_FALSE(sigismember(&sigs, SIGALRM));
+
+  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_getsigdefault(&sa, &sigs));
+  ASSERT_TRUE(sigismember(&sigs, SIGALRM));
+
+  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));
+
+  sched_param sp;
+  ASSERT_EQ(0, posix_spawnattr_getschedparam(&sa, &sp));
+  ASSERT_EQ(0, sp.sched_priority);
+
+  sched_param sp123 = { .sched_priority = 123 };
+  ASSERT_EQ(0, posix_spawnattr_setschedparam(&sa, &sp123));
+
+  ASSERT_EQ(0, posix_spawnattr_getschedparam(&sa, &sp));
+  ASSERT_EQ(123, sp.sched_priority);
+
+  ASSERT_EQ(0, posix_spawnattr_destroy(&sa));
+}
+
+TEST(spawn, posix_spawnattr_setschedpolicy_posix_spawnattr_getschedpolicy) {
+  posix_spawnattr_t sa;
+  ASSERT_EQ(0, posix_spawnattr_init(&sa));
+
+  int p;
+  ASSERT_EQ(0, posix_spawnattr_getschedpolicy(&sa, &p));
+  ASSERT_EQ(0, p);
+
+  ASSERT_EQ(0, posix_spawnattr_setschedpolicy(&sa, SCHED_FIFO));
+
+  ASSERT_EQ(0, posix_spawnattr_getschedpolicy(&sa, &p));
+  ASSERT_EQ(SCHED_FIFO, p);
+
+  ASSERT_EQ(0, posix_spawnattr_destroy(&sa));
+}
+
+TEST(spawn, posix_spawn) {
+  ExecTestHelper eth;
+  eth.SetArgs({BIN_DIR "true", nullptr});
+  pid_t pid;
+  ASSERT_EQ(0, posix_spawn(&pid, eth.GetArg0(), nullptr, nullptr, eth.GetArgs(), nullptr));
+  AssertChildExited(pid, 0);
+}
+
+TEST(spawn, posix_spawn_not_found) {
+  ExecTestHelper eth;
+  eth.SetArgs({"true", nullptr});
+  pid_t pid;
+  ASSERT_EQ(0, posix_spawn(&pid, eth.GetArg0(), nullptr, nullptr, eth.GetArgs(), nullptr));
+  AssertChildExited(pid, 127);
+}
+
+TEST(spawn, posix_spawnp) {
+  ExecTestHelper eth;
+  eth.SetArgs({"true", nullptr});
+  pid_t pid;
+  ASSERT_EQ(0, posix_spawnp(&pid, eth.GetArg0(), nullptr, nullptr, eth.GetArgs(), nullptr));
+  AssertChildExited(pid, 0);
+}
+
+TEST(spawn, posix_spawnp_not_found) {
+  ExecTestHelper eth;
+  eth.SetArgs({"does-not-exist", nullptr});
+  pid_t pid;
+  ASSERT_EQ(0, posix_spawnp(&pid, eth.GetArg0(), nullptr, nullptr, eth.GetArgs(), nullptr));
+  AssertChildExited(pid, 127);
+}
+
+TEST(spawn, posix_spawn_environment) {
+  ExecTestHelper eth;
+  eth.SetArgs({"sh", "-c", "exit $posix_spawn_environment_test", nullptr});
+  eth.SetEnv({"posix_spawn_environment_test=66", nullptr});
+  pid_t pid;
+  ASSERT_EQ(0, posix_spawnp(&pid, eth.GetArg0(), nullptr, nullptr, eth.GetArgs(), eth.GetEnv()));
+  AssertChildExited(pid, 66);
+}
+
+TEST(spawn, posix_spawn_file_actions) {
+  int fds[2];
+  ASSERT_NE(-1, pipe(fds));
+
+  posix_spawn_file_actions_t fa;
+  ASSERT_EQ(0, posix_spawn_file_actions_init(&fa));
+
+  ASSERT_EQ(0, posix_spawn_file_actions_addclose(&fa, fds[0]));
+  ASSERT_EQ(0, posix_spawn_file_actions_adddup2(&fa, fds[1], 1));
+  ASSERT_EQ(0, posix_spawn_file_actions_addclose(&fa, fds[1]));
+  // Check that close(2) failures are ignored by closing the same fd again.
+  ASSERT_EQ(0, posix_spawn_file_actions_addclose(&fa, fds[1]));
+  ASSERT_EQ(0, posix_spawn_file_actions_addopen(&fa, 56, "/proc/version", O_RDONLY, 0));
+
+  ExecTestHelper eth;
+  eth.SetArgs({"ls", "-l", "/proc/self/fd", nullptr});
+  pid_t pid;
+  ASSERT_EQ(0, posix_spawnp(&pid, eth.GetArg0(), &fa, nullptr, eth.GetArgs(), eth.GetEnv()));
+  ASSERT_EQ(0, posix_spawn_file_actions_destroy(&fa));
+
+  ASSERT_EQ(0, close(fds[1]));
+  std::string content;
+  ASSERT_TRUE(android::base::ReadFdToString(fds[0], &content));
+  ASSERT_EQ(0, close(fds[0]));
+
+  AssertChildExited(pid, 0);
+
+  // We'll know the dup2 worked if we see any ls(1) output in our pipe.
+  // The open we can check manually...
+  bool open_to_fd_56_worked = false;
+  for (const auto& line : android::base::Split(content, "\n")) {
+    if (line.find(" 56 -> /proc/version") != std::string::npos) open_to_fd_56_worked = true;
+  }
+  ASSERT_TRUE(open_to_fd_56_worked);
+}
+
+static void CatFileToString(posix_spawnattr_t* sa, const char* path, std::string* content) {
+  int fds[2];
+  ASSERT_NE(-1, pipe(fds));
+
+  posix_spawn_file_actions_t fa;
+  ASSERT_EQ(0, posix_spawn_file_actions_init(&fa));
+  ASSERT_EQ(0, posix_spawn_file_actions_addclose(&fa, fds[0]));
+  ASSERT_EQ(0, posix_spawn_file_actions_adddup2(&fa, fds[1], 1));
+  ASSERT_EQ(0, posix_spawn_file_actions_addclose(&fa, fds[1]));
+
+  ExecTestHelper eth;
+  eth.SetArgs({"cat", path, nullptr});
+  pid_t pid;
+  ASSERT_EQ(0, posix_spawnp(&pid, eth.GetArg0(), &fa, sa, eth.GetArgs(), nullptr));
+  ASSERT_EQ(0, posix_spawn_file_actions_destroy(&fa));
+
+  ASSERT_EQ(0, close(fds[1]));
+  ASSERT_TRUE(android::base::ReadFdToString(fds[0], content));
+  ASSERT_EQ(0, close(fds[0]));
+  AssertChildExited(pid, 0);
+}
+
+struct ProcStat {
+  pid_t pid;
+  pid_t ppid;
+  pid_t pgrp;
+  pid_t sid;
+};
+
+static void GetChildStat(posix_spawnattr_t* sa, ProcStat* ps) {
+  std::string content;
+  CatFileToString(sa, "/proc/self/stat", &content);
+
+  ASSERT_EQ(4, sscanf(content.c_str(), "%d (cat) %*c %d %d %d", &ps->pid, &ps->ppid, &ps->pgrp,
+                      &ps->sid));
+
+  ASSERT_EQ(getpid(), ps->ppid);
+}
+
+struct ProcStatus {
+  uint64_t sigblk;
+  uint64_t sigign;
+};
+
+static void GetChildStatus(posix_spawnattr_t* sa, ProcStatus* ps) {
+  std::string content;
+  CatFileToString(sa, "/proc/self/status", &content);
+
+  bool saw_blk = false;
+  bool saw_ign = false;
+  for (const auto& line : android::base::Split(content, "\n")) {
+    if (sscanf(line.c_str(), "SigBlk: %" SCNx64, &ps->sigblk) == 1) saw_blk = true;
+    if (sscanf(line.c_str(), "SigIgn: %" SCNx64, &ps->sigign) == 1) saw_ign = true;
+  }
+  ASSERT_TRUE(saw_blk);
+  ASSERT_TRUE(saw_ign);
+}
+
+TEST(spawn, posix_spawn_POSIX_SPAWN_SETSID_clear) {
+  pid_t parent_sid = getsid(0);
+
+  posix_spawnattr_t sa;
+  ASSERT_EQ(0, posix_spawnattr_init(&sa));
+  ASSERT_EQ(0, posix_spawnattr_setflags(&sa, 0));
+
+  ProcStat ps = {};
+  GetChildStat(&sa, &ps);
+  ASSERT_EQ(parent_sid, ps.sid);
+  ASSERT_EQ(0, posix_spawnattr_destroy(&sa));
+}
+
+TEST(spawn, posix_spawn_POSIX_SPAWN_SETSID_set) {
+  pid_t parent_sid = getsid(0);
+
+  posix_spawnattr_t sa;
+  ASSERT_EQ(0, posix_spawnattr_init(&sa));
+  ASSERT_EQ(0, posix_spawnattr_setflags(&sa, POSIX_SPAWN_SETSID));
+
+  ProcStat ps = {};
+  GetChildStat(&sa, &ps);
+  ASSERT_NE(parent_sid, ps.sid);
+  ASSERT_EQ(0, posix_spawnattr_destroy(&sa));
+}
+
+TEST(spawn, posix_spawn_POSIX_SPAWN_SETPGROUP_clear) {
+  pid_t parent_pgrp = getpgrp();
+
+  posix_spawnattr_t sa;
+  ASSERT_EQ(0, posix_spawnattr_init(&sa));
+  ASSERT_EQ(0, posix_spawnattr_setflags(&sa, 0));
+
+  ProcStat ps = {};
+  GetChildStat(&sa, &ps);
+  ASSERT_EQ(parent_pgrp, ps.pgrp);
+  ASSERT_EQ(0, posix_spawnattr_destroy(&sa));
+}
+
+TEST(spawn, posix_spawn_POSIX_SPAWN_SETPGROUP_set) {
+  pid_t parent_pgrp = getpgrp();
+
+  posix_spawnattr_t sa;
+  ASSERT_EQ(0, posix_spawnattr_init(&sa));
+  ASSERT_EQ(0, posix_spawnattr_setpgroup(&sa, 0));
+  ASSERT_EQ(0, posix_spawnattr_setflags(&sa, POSIX_SPAWN_SETPGROUP));
+
+  ProcStat ps = {};
+  GetChildStat(&sa, &ps);
+  ASSERT_NE(parent_pgrp, ps.pgrp);
+  // Setting pgid 0 means "the same as the caller's pid".
+  ASSERT_EQ(ps.pid, ps.pgrp);
+  ASSERT_EQ(0, posix_spawnattr_destroy(&sa));
+}
+
+TEST(spawn, posix_spawn_POSIX_SPAWN_SETSIGMASK) {
+  // Block SIGBUS in the parent...
+  sigset_t just_SIGBUS;
+  sigemptyset(&just_SIGBUS);
+  sigaddset(&just_SIGBUS, SIGBUS);
+  ASSERT_EQ(0, sigprocmask(SIG_BLOCK, &just_SIGBUS, nullptr));
+
+  posix_spawnattr_t sa;
+  ASSERT_EQ(0, posix_spawnattr_init(&sa));
+
+  // Ask for only SIGALRM to be blocked in the child...
+  sigset_t just_SIGALRM;
+  sigemptyset(&just_SIGALRM);
+  sigaddset(&just_SIGALRM, SIGALRM);
+  ASSERT_EQ(0, posix_spawnattr_setsigmask(&sa, &just_SIGALRM));
+  ASSERT_EQ(0, posix_spawnattr_setflags(&sa, POSIX_SPAWN_SETSIGMASK));
+
+  // Check that's what happens...
+  ProcStatus ps = {};
+  GetChildStatus(&sa, &ps);
+  EXPECT_EQ(static_cast<uint64_t>(1 << (SIGALRM - 1)), ps.sigblk);
+  EXPECT_EQ(static_cast<uint64_t>(0), ps.sigign);
+
+  ASSERT_EQ(0, posix_spawnattr_destroy(&sa));
+}
+
+TEST(spawn, posix_spawn_POSIX_SPAWN_SETSIGDEF) {
+  // Ignore SIGALRM and SIGCONT in the parent...
+  ASSERT_NE(SIG_ERR, signal(SIGALRM, SIG_IGN));
+  ASSERT_NE(SIG_ERR, signal(SIGCONT, SIG_IGN));
+
+  posix_spawnattr_t sa;
+  ASSERT_EQ(0, posix_spawnattr_init(&sa));
+
+  // Ask for SIGALRM to be defaulted in the child...
+  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));
+
+  // Check that's what happens...
+  ProcStatus ps = {};
+  GetChildStatus(&sa, &ps);
+  EXPECT_EQ(static_cast<uint64_t>(0), ps.sigblk);
+  EXPECT_EQ(static_cast<uint64_t>(1 << (SIGCONT - 1)), ps.sigign);
+
+  ASSERT_EQ(0, posix_spawnattr_destroy(&sa));
+}
diff --git a/tests/stdio_test.cpp b/tests/stdio_test.cpp
index 7b7737d..05a19d1 100644
--- a/tests/stdio_test.cpp
+++ b/tests/stdio_test.cpp
@@ -302,6 +302,13 @@
   EXPECT_STREQ("<a>", buf);
 }
 
+TEST(STDIO_TEST, snprintf_C) { // Synonym for %lc.
+  char buf[BUFSIZ];
+  wchar_t wc = L'a';
+  EXPECT_EQ(3, snprintf(buf, sizeof(buf), "<%C>", wc));
+  EXPECT_STREQ("<a>", buf);
+}
+
 TEST(STDIO_TEST, snprintf_ls) {
   char buf[BUFSIZ];
   wchar_t* ws = NULL;
@@ -314,6 +321,18 @@
   EXPECT_STREQ("<hi>", buf);
 }
 
+TEST(STDIO_TEST, snprintf_S) { // Synonym for %ls.
+  char buf[BUFSIZ];
+  wchar_t* ws = NULL;
+  EXPECT_EQ(8, snprintf(buf, sizeof(buf), "<%S>", ws));
+  EXPECT_STREQ("<(null)>", buf);
+
+  wchar_t chars[] = { L'h', L'i', 0 };
+  ws = chars;
+  EXPECT_EQ(4, snprintf(buf, sizeof(buf), "<%S>", ws));
+  EXPECT_STREQ("<hi>", buf);
+}
+
 TEST(STDIO_TEST, snprintf_n) {
 #if defined(__BIONIC__)
   // http://b/14492135
@@ -584,6 +603,56 @@
   ASSERT_EQ(std::wstring(L"0x1.921fb54411744p+1"), buf);
 }
 
+TEST(STDIO_TEST, swprintf_lc) {
+  constexpr size_t nchars = 32;
+  wchar_t buf[nchars];
+
+  wint_t wc = L'a';
+  EXPECT_EQ(3, swprintf(buf, nchars, L"<%lc>", wc));
+  EXPECT_EQ(std::wstring(L"<a>"), buf);
+}
+
+TEST(STDIO_TEST, swprintf_C) { // Synonym for %lc.
+  constexpr size_t nchars = 32;
+  wchar_t buf[nchars];
+
+  wint_t wc = L'a';
+  EXPECT_EQ(3, swprintf(buf, nchars, L"<%C>", wc));
+  EXPECT_EQ(std::wstring(L"<a>"), buf);
+}
+
+TEST(STDIO_TEST, swprintf_jd_INTMAX_MAX) {
+  constexpr size_t nchars = 32;
+  wchar_t buf[nchars];
+
+  swprintf(buf, nchars, L"%jd", INTMAX_MAX);
+  EXPECT_EQ(std::wstring(L"9223372036854775807"), buf);
+}
+
+TEST(STDIO_TEST, swprintf_jd_INTMAX_MIN) {
+  constexpr size_t nchars = 32;
+  wchar_t buf[nchars];
+
+  swprintf(buf, nchars, L"%jd", INTMAX_MIN);
+  EXPECT_EQ(std::wstring(L"-9223372036854775808"), buf);
+}
+
+TEST(STDIO_TEST, swprintf_ju_UINTMAX_MAX) {
+  constexpr size_t nchars = 32;
+  wchar_t buf[nchars];
+
+  swprintf(buf, nchars, L"%ju", UINTMAX_MAX);
+  EXPECT_EQ(std::wstring(L"18446744073709551615"), buf);
+}
+
+TEST(STDIO_TEST, swprintf_1$ju_UINTMAX_MAX) {
+  constexpr size_t nchars = 32;
+  wchar_t buf[nchars];
+
+  swprintf(buf, nchars, L"%1$ju", UINTMAX_MAX);
+  EXPECT_EQ(std::wstring(L"18446744073709551615"), buf);
+}
+
 TEST(STDIO_TEST, swprintf_ls) {
   constexpr size_t nchars = 32;
   wchar_t buf[nchars];
@@ -595,6 +664,17 @@
   ASSERT_EQ(std::wstring(kWideString), buf);
 }
 
+TEST(STDIO_TEST, swprintf_S) { // Synonym for %ls.
+  constexpr size_t nchars = 32;
+  wchar_t buf[nchars];
+
+  static const wchar_t kWideString[] = L"Hello\uff41 World";
+  ASSERT_EQ(12, swprintf(buf, nchars, L"%S", kWideString));
+  ASSERT_EQ(std::wstring(kWideString), buf);
+  ASSERT_EQ(12, swprintf(buf, 13, L"%S", kWideString));
+  ASSERT_EQ(std::wstring(kWideString), buf);
+}
+
 TEST(STDIO_TEST, snprintf_d_INT_MAX) {
   char buf[BUFSIZ];
   snprintf(buf, sizeof(buf), "%d", INT_MAX);
@@ -607,6 +687,30 @@
   EXPECT_STREQ("-2147483648", buf);
 }
 
+TEST(STDIO_TEST, snprintf_jd_INTMAX_MAX) {
+  char buf[BUFSIZ];
+  snprintf(buf, sizeof(buf), "%jd", INTMAX_MAX);
+  EXPECT_STREQ("9223372036854775807", buf);
+}
+
+TEST(STDIO_TEST, snprintf_jd_INTMAX_MIN) {
+  char buf[BUFSIZ];
+  snprintf(buf, sizeof(buf), "%jd", INTMAX_MIN);
+  EXPECT_STREQ("-9223372036854775808", buf);
+}
+
+TEST(STDIO_TEST, snprintf_ju_UINTMAX_MAX) {
+  char buf[BUFSIZ];
+  snprintf(buf, sizeof(buf), "%ju", UINTMAX_MAX);
+  EXPECT_STREQ("18446744073709551615", buf);
+}
+
+TEST(STDIO_TEST, snprintf_1$ju_UINTMAX_MAX) {
+  char buf[BUFSIZ];
+  snprintf(buf, sizeof(buf), "%1$ju", UINTMAX_MAX);
+  EXPECT_STREQ("18446744073709551615", buf);
+}
+
 TEST(STDIO_TEST, snprintf_ld_LONG_MAX) {
   char buf[BUFSIZ];
   snprintf(buf, sizeof(buf), "%ld", LONG_MAX);
@@ -639,6 +743,30 @@
   EXPECT_STREQ("-9223372036854775808", buf);
 }
 
+TEST(STDIO_TEST, snprintf_o_UINT_MAX) {
+  char buf[BUFSIZ];
+  snprintf(buf, sizeof(buf), "%o", UINT_MAX);
+  EXPECT_STREQ("37777777777", buf);
+}
+
+TEST(STDIO_TEST, snprintf_u_UINT_MAX) {
+  char buf[BUFSIZ];
+  snprintf(buf, sizeof(buf), "%u", UINT_MAX);
+  EXPECT_STREQ("4294967295", buf);
+}
+
+TEST(STDIO_TEST, snprintf_x_UINT_MAX) {
+  char buf[BUFSIZ];
+  snprintf(buf, sizeof(buf), "%x", UINT_MAX);
+  EXPECT_STREQ("ffffffff", buf);
+}
+
+TEST(STDIO_TEST, snprintf_X_UINT_MAX) {
+  char buf[BUFSIZ];
+  snprintf(buf, sizeof(buf), "%X", UINT_MAX);
+  EXPECT_STREQ("FFFFFFFF", buf);
+}
+
 TEST(STDIO_TEST, snprintf_e) {
   char buf[BUFSIZ];
 
@@ -1962,3 +2090,95 @@
   ASSERT_LE(FILENAME_MAX, PATH_MAX);
   ASSERT_EQ(L_tmpnam, PATH_MAX);
 }
+
+TEST(STDIO_TEST, perror) {
+  ExecTestHelper eth;
+  eth.Run([&]() { errno = EINVAL; perror("a b c"); exit(0); }, 0, "a b c: Invalid argument\n");
+  eth.Run([&]() { errno = EINVAL; perror(nullptr); exit(0); }, 0, "Invalid argument\n");
+  eth.Run([&]() { errno = EINVAL; perror(""); exit(0); }, 0, "Invalid argument\n");
+}
+
+TEST(STDIO_TEST, puts) {
+  ExecTestHelper eth;
+  eth.Run([&]() { exit(puts("a b c")); }, 0, "a b c\n");
+}
+
+TEST(STDIO_TEST, unlocked) {
+  TemporaryFile tf;
+
+  FILE* fp = fopen(tf.filename, "w+");
+  ASSERT_TRUE(fp != nullptr);
+
+  clearerr_unlocked(fp);
+  ASSERT_FALSE(feof_unlocked(fp));
+  ASSERT_FALSE(ferror_unlocked(fp));
+
+  ASSERT_EQ(fileno(fp), fileno_unlocked(fp));
+
+  ASSERT_NE(EOF, putc_unlocked('a', fp));
+  ASSERT_NE(EOF, putc('b', fp));
+  ASSERT_NE(EOF, fputc_unlocked('c', fp));
+  ASSERT_NE(EOF, fputc('d', fp));
+
+  rewind(fp);
+  ASSERT_EQ('a', getc_unlocked(fp));
+  ASSERT_EQ('b', getc(fp));
+  ASSERT_EQ('c', fgetc_unlocked(fp));
+  ASSERT_EQ('d', fgetc(fp));
+
+  rewind(fp);
+  ASSERT_EQ(2U, fwrite_unlocked("AB", 1, 2, fp));
+  ASSERT_EQ(2U, fwrite("CD", 1, 2, fp));
+  ASSERT_EQ(0, fflush_unlocked(fp));
+
+  rewind(fp);
+  char buf[BUFSIZ] = {};
+  ASSERT_EQ(2U, fread_unlocked(&buf[0], 1, 2, fp));
+  ASSERT_EQ(2U, fread(&buf[2], 1, 2, fp));
+  ASSERT_STREQ("ABCD", buf);
+
+  rewind(fp);
+  ASSERT_NE(EOF, fputs("hello ", fp));
+  ASSERT_NE(EOF, fputs_unlocked("world", fp));
+  ASSERT_NE(EOF, fputc('\n', fp));
+
+  rewind(fp);
+  ASSERT_TRUE(fgets_unlocked(buf, sizeof(buf), fp) != nullptr);
+  ASSERT_STREQ("hello world\n", buf);
+
+  ASSERT_EQ(0, fclose(fp));
+}
+
+TEST(STDIO_TEST, fseek_64bit) {
+  TemporaryFile tf;
+  FILE* fp = fopen64(tf.filename, "w+");
+  ASSERT_TRUE(fp != nullptr);
+  ASSERT_EQ(0, fseeko64(fp, 0x2'0000'0000, SEEK_SET));
+  ASSERT_EQ(0x2'0000'0000, ftello64(fp));
+  ASSERT_EQ(0, fseeko64(fp, 0x1'0000'0000, SEEK_CUR));
+  ASSERT_EQ(0x3'0000'0000, ftello64(fp));
+  ASSERT_EQ(0, fclose(fp));
+}
+
+// POSIX requires that fseek/fseeko fail with EOVERFLOW if the new file offset
+// isn't representable in long/off_t.
+TEST(STDIO_TEST, fseek_overflow_32bit) {
+  TemporaryFile tf;
+  FILE* fp = fopen64(tf.filename, "w+");
+  ASSERT_EQ(0, ftruncate64(fileno(fp), 0x2'0000'0000));
+
+  // Bionic implements overflow checking for SEEK_CUR, but glibc doesn't.
+#if defined(__BIONIC__) && !defined(__LP64__)
+  ASSERT_EQ(0, fseek(fp, 0x7fff'ffff, SEEK_SET));
+  ASSERT_EQ(-1, fseek(fp, 1, SEEK_CUR));
+  ASSERT_EQ(EOVERFLOW, errno);
+#endif
+
+  // Neither Bionic nor glibc implement the overflow checking for SEEK_END.
+  // (Aside: FreeBSD's libc is an example of a libc that checks both SEEK_CUR
+  // and SEEK_END -- many C libraries check neither.)
+  ASSERT_EQ(0, fseek(fp, 0, SEEK_END));
+  ASSERT_EQ(0x2'0000'0000, ftello64(fp));
+
+  fclose(fp);
+}
diff --git a/tests/stdlib_test.cpp b/tests/stdlib_test.cpp
index 27495d8..0c40380 100644
--- a/tests/stdlib_test.cpp
+++ b/tests/stdlib_test.cpp
@@ -508,6 +508,16 @@
   close(fd);
 }
 
+TEST(stdlib, ttyname) {
+  int fd = getpt();
+  ASSERT_NE(-1, fd);
+
+  // ttyname returns "/dev/ptmx" for a pty.
+  ASSERT_STREQ("/dev/ptmx", ttyname(fd));
+
+  close(fd);
+}
+
 TEST(stdlib, ttyname_r) {
   int fd = getpt();
   ASSERT_NE(-1, fd);
diff --git a/tests/sys_random_test.cpp b/tests/sys_random_test.cpp
new file mode 100644
index 0000000..78cbf4a
--- /dev/null
+++ b/tests/sys_random_test.cpp
@@ -0,0 +1,105 @@
+/*
+ * Copyright (C) 2017 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.
+ */
+
+// <sys/random.h> was only added as of glibc version 2.25.
+// Don't try to compile this code on older glibc versions.
+
+#include <sys/cdefs.h>
+#if defined(__BIONIC__)
+  #define HAVE_SYS_RANDOM 1
+#elif defined(__GLIBC_PREREQ)
+  #if __GLIBC_PREREQ(2, 25)
+    #define HAVE_SYS_RANDOM 1
+  #endif
+#endif
+
+
+#if defined(HAVE_SYS_RANDOM)
+#include <sys/random.h>
+#endif
+
+#include <errno.h>
+#include <gtest/gtest.h>
+
+TEST(sys_random, getentropy) {
+#if defined(HAVE_SYS_RANDOM)
+  char buf1[64];
+  char buf2[64];
+
+  ASSERT_EQ(0, getentropy(buf1, sizeof(buf1)));
+  ASSERT_EQ(0, getentropy(buf2, sizeof(buf2)));
+  ASSERT_TRUE(memcmp(buf1, buf2, sizeof(buf1)) != 0);
+#else
+  GTEST_LOG_(INFO) << "This test requires a C library with <sys/random.h>.\n";
+#endif
+}
+
+TEST(sys_random, getentropy_EFAULT) {
+#if defined(HAVE_SYS_RANDOM)
+  errno = 0;
+  ASSERT_EQ(-1, getentropy(nullptr, 1));
+  ASSERT_EQ(EFAULT, errno);
+#else
+  GTEST_LOG_(INFO) << "This test requires a C library with <sys/random.h>.\n";
+#endif
+}
+
+TEST(sys_random, getentropy_EIO) {
+#if defined(HAVE_SYS_RANDOM)
+  char buf[BUFSIZ];
+  static_assert(BUFSIZ > 256, "BUFSIZ <= 256!");
+
+  errno = 0;
+  ASSERT_EQ(-1, getentropy(buf, sizeof(buf)));
+  ASSERT_EQ(EIO, errno);
+#else
+  GTEST_LOG_(INFO) << "This test requires a C library with <sys/random.h>.\n";
+#endif
+}
+
+TEST(sys_random, getrandom) {
+#if defined(HAVE_SYS_RANDOM)
+  char buf1[64];
+  char buf2[64];
+
+  ASSERT_EQ(64, getrandom(buf1, sizeof(buf1), 0));
+  ASSERT_EQ(64, getrandom(buf2, sizeof(buf2), 0));
+  ASSERT_TRUE(memcmp(buf1, buf2, sizeof(buf1)) != 0);
+#else
+  GTEST_LOG_(INFO) << "This test requires a C library with <sys/random.h>.\n";
+#endif
+}
+
+TEST(sys_random, getrandom_EFAULT) {
+#if defined(HAVE_SYS_RANDOM)
+  errno = 0;
+  ASSERT_EQ(-1, getrandom(nullptr, 256, 0));
+  ASSERT_EQ(EFAULT, errno);
+#else
+  GTEST_LOG_(INFO) << "This test requires a C library with <sys/random.h>.\n";
+#endif
+}
+
+TEST(sys_random, getrandom_EINVAL) {
+#if defined(HAVE_SYS_RANDOM)
+  errno = 0;
+  char buf[64];
+  ASSERT_EQ(-1, getrandom(buf, sizeof(buf), ~0));
+  ASSERT_EQ(EINVAL, errno);
+#else
+  GTEST_LOG_(INFO) << "This test requires a C library with <sys/random.h>.\n";
+#endif
+}
diff --git a/tests/system_properties_test.cpp b/tests/system_properties_test.cpp
index 7415b3c..69647bf 100644
--- a/tests/system_properties_test.cpp
+++ b/tests/system_properties_test.cpp
@@ -24,6 +24,8 @@
 #include <string>
 #include <thread>
 
+using namespace std::literals;
+
 #if defined(__BIONIC__)
 
 #define _REALLY_INCLUDE_SYS__SYSTEM_PROPERTIES_H_
@@ -452,3 +454,89 @@
   GTEST_LOG_(INFO) << "This test does nothing.\n";
 #endif // __BIONIC__
 }
+
+TEST(properties, __system_property_extra_long_read_only) {
+#if defined(__BIONIC__)
+  LocalPropertyTestState pa;
+  ASSERT_TRUE(pa.valid);
+
+  std::vector<std::pair<std::string, std::string>> short_properties = {
+    { "ro.0char", std::string() },
+    { "ro.50char", std::string(50, 'x') },
+    { "ro.91char", std::string(91, 'x') },
+  };
+
+  std::vector<std::pair<std::string, std::string>> long_properties = {
+    { "ro.92char", std::string(92, 'x') },
+    { "ro.93char", std::string(93, 'x') },
+    { "ro.1000char", std::string(1000, 'x') },
+  };
+
+  for (const auto& property : short_properties) {
+    const std::string& name = property.first;
+    const std::string& value = property.second;
+    ASSERT_EQ(0, __system_property_add(name.c_str(), name.size(), value.c_str(), value.size()));
+  }
+
+  for (const auto& property : long_properties) {
+    const std::string& name = property.first;
+    const std::string& value = property.second;
+    ASSERT_EQ(0, __system_property_add(name.c_str(), name.size(), value.c_str(), value.size()));
+  }
+
+  auto check_with_legacy_read = [](const std::string& name, const std::string& expected_value) {
+    char value[PROP_VALUE_MAX];
+    EXPECT_EQ(static_cast<int>(expected_value.size()), __system_property_get(name.c_str(), value))
+        << name;
+    EXPECT_EQ(expected_value, value) << name;
+  };
+
+  auto check_with_read_callback = [](const std::string& name, const std::string& expected_value) {
+    const prop_info* pi = __system_property_find(name.c_str());
+    ASSERT_NE(nullptr, pi);
+    std::string value;
+    __system_property_read_callback(pi,
+                                    [](void* cookie, const char*, const char* value, uint32_t) {
+                                      std::string* out_value =
+                                          reinterpret_cast<std::string*>(cookie);
+                                      *out_value = value;
+                                    },
+                                    &value);
+    EXPECT_EQ(expected_value, value) << name;
+  };
+
+  for (const auto& property : short_properties) {
+    const std::string& name = property.first;
+    const std::string& value = property.second;
+    check_with_legacy_read(name, value);
+    check_with_read_callback(name, value);
+  }
+
+  constexpr static const char* kExtraLongLegacyError =
+      "Must use __system_property_read_callback() to read";
+  for (const auto& property : long_properties) {
+    const std::string& name = property.first;
+    const std::string& value = property.second;
+    check_with_legacy_read(name, kExtraLongLegacyError);
+    check_with_read_callback(name, value);
+  }
+
+#else   // __BIONIC__
+  GTEST_LOG_(INFO) << "This test does nothing.\n";
+#endif  // __BIONIC__
+}
+
+// pa_size is 128 * 1024 currently, if a property is longer then we expect it to fail gracefully.
+TEST(properties, __system_property_extra_long_read_only_too_long) {
+#if defined(__BIONIC__)
+  LocalPropertyTestState pa;
+  ASSERT_TRUE(pa.valid);
+
+  auto name = "ro.super_long_property"s;
+  auto value = std::string(128 * 1024 + 1, 'x');
+  ASSERT_NE(0, __system_property_add(name.c_str(), name.size(), value.c_str(), value.size()));
+
+#else   // __BIONIC__
+  GTEST_LOG_(INFO) << "This test does nothing.\n";
+#endif  // __BIONIC__
+}
diff --git a/tests/time_test.cpp b/tests/time_test.cpp
index 4e3fa83..d553ff5 100644
--- a/tests/time_test.cpp
+++ b/tests/time_test.cpp
@@ -574,6 +574,31 @@
   ASSERT_LT(ts2.tv_nsec, 1000000);
 }
 
+TEST(time, clock_gettime_CLOCK_REALTIME) {
+  timespec ts;
+  ASSERT_EQ(0, clock_gettime(CLOCK_REALTIME, &ts));
+}
+
+TEST(time, clock_gettime_CLOCK_MONOTONIC) {
+  timespec ts;
+  ASSERT_EQ(0, clock_gettime(CLOCK_MONOTONIC, &ts));
+}
+
+TEST(time, clock_gettime_CLOCK_PROCESS_CPUTIME_ID) {
+  timespec ts;
+  ASSERT_EQ(0, clock_gettime(CLOCK_PROCESS_CPUTIME_ID, &ts));
+}
+
+TEST(time, clock_gettime_CLOCK_THREAD_CPUTIME_ID) {
+  timespec ts;
+  ASSERT_EQ(0, clock_gettime(CLOCK_THREAD_CPUTIME_ID, &ts));
+}
+
+TEST(time, clock_gettime_CLOCK_BOOTTIME) {
+  timespec ts;
+  ASSERT_EQ(0, clock_gettime(CLOCK_BOOTTIME, &ts));
+}
+
 TEST(time, clock) {
   // clock(3) is hard to test, but a 1s sleep should cost less than 1ms.
   clock_t t0 = clock();
diff --git a/tests/unistd_test.cpp b/tests/unistd_test.cpp
index 8af2263..022da4d 100644
--- a/tests/unistd_test.cpp
+++ b/tests/unistd_test.cpp
@@ -686,109 +686,131 @@
   ASSERT_TRUE(rc > 0 && powerof2(rc));
 }
 
-
-TEST(UNISTD_TEST, _POSIX_macros_smoke) {
+TEST(UNISTD_TEST, _POSIX_constants) {
   // Make a tight verification of _POSIX_* / _POSIX2_* / _XOPEN_* macros, to prevent change by mistake.
   // Verify according to POSIX.1-2008.
   EXPECT_EQ(200809L, _POSIX_VERSION);
 
+  EXPECT_EQ(2, _POSIX_AIO_LISTIO_MAX);
+  EXPECT_EQ(1, _POSIX_AIO_MAX);
+  EXPECT_EQ(4096, _POSIX_ARG_MAX);
+  EXPECT_EQ(25, _POSIX_CHILD_MAX);
+  EXPECT_EQ(20000000, _POSIX_CLOCKRES_MIN);
+  EXPECT_EQ(32, _POSIX_DELAYTIMER_MAX);
+  EXPECT_EQ(255, _POSIX_HOST_NAME_MAX);
+  EXPECT_EQ(8, _POSIX_LINK_MAX);
+  EXPECT_EQ(9, _POSIX_LOGIN_NAME_MAX);
+  EXPECT_EQ(255, _POSIX_MAX_CANON);
+  EXPECT_EQ(255, _POSIX_MAX_INPUT);
+  EXPECT_EQ(8, _POSIX_MQ_OPEN_MAX);
+  EXPECT_EQ(32, _POSIX_MQ_PRIO_MAX);
+  EXPECT_EQ(14, _POSIX_NAME_MAX);
+  EXPECT_EQ(8, _POSIX_NGROUPS_MAX);
+  EXPECT_EQ(20, _POSIX_OPEN_MAX);
+  EXPECT_EQ(256, _POSIX_PATH_MAX);
+  EXPECT_EQ(512, _POSIX_PIPE_BUF);
+  EXPECT_EQ(255, _POSIX_RE_DUP_MAX);
+  EXPECT_EQ(8, _POSIX_RTSIG_MAX);
+  EXPECT_EQ(256, _POSIX_SEM_NSEMS_MAX);
+  EXPECT_EQ(32767, _POSIX_SEM_VALUE_MAX);
+  EXPECT_EQ(32, _POSIX_SIGQUEUE_MAX);
+  EXPECT_EQ(32767, _POSIX_SSIZE_MAX);
+  EXPECT_EQ(8, _POSIX_STREAM_MAX);
+#if !defined(__GLIBC__)
+  EXPECT_EQ(4, _POSIX_SS_REPL_MAX);
+#endif
+  EXPECT_EQ(255, _POSIX_SYMLINK_MAX);
+  EXPECT_EQ(8, _POSIX_SYMLOOP_MAX);
+  EXPECT_EQ(4, _POSIX_THREAD_DESTRUCTOR_ITERATIONS);
+  EXPECT_EQ(128, _POSIX_THREAD_KEYS_MAX);
+  EXPECT_EQ(64, _POSIX_THREAD_THREADS_MAX);
+  EXPECT_EQ(32, _POSIX_TIMER_MAX);
+#if !defined(__GLIBC__)
+  EXPECT_EQ(30, _POSIX_TRACE_EVENT_NAME_MAX);
+  EXPECT_EQ(8, _POSIX_TRACE_NAME_MAX);
+  EXPECT_EQ(8, _POSIX_TRACE_SYS_MAX);
+  EXPECT_EQ(32, _POSIX_TRACE_USER_EVENT_MAX);
+#endif
+  EXPECT_EQ(9, _POSIX_TTY_NAME_MAX);
+  EXPECT_EQ(6, _POSIX_TZNAME_MAX);
+  EXPECT_EQ(99, _POSIX2_BC_BASE_MAX);
+  EXPECT_EQ(2048, _POSIX2_BC_DIM_MAX);
+  EXPECT_EQ(99, _POSIX2_BC_SCALE_MAX);
+  EXPECT_EQ(1000, _POSIX2_BC_STRING_MAX);
+  EXPECT_EQ(14, _POSIX2_CHARCLASS_NAME_MAX);
+  EXPECT_EQ(2, _POSIX2_COLL_WEIGHTS_MAX);
+  EXPECT_EQ(32, _POSIX2_EXPR_NEST_MAX);
+  EXPECT_EQ(2048, _POSIX2_LINE_MAX);
+  EXPECT_EQ(255, _POSIX2_RE_DUP_MAX);
+
+  EXPECT_EQ(16, _XOPEN_IOV_MAX);
+#if !defined(__GLIBC__)
+  EXPECT_EQ(255, _XOPEN_NAME_MAX);
+  EXPECT_EQ(1024, _XOPEN_PATH_MAX);
+#endif
+}
+
+TEST(UNISTD_TEST, _POSIX_options) {
   EXPECT_EQ(_POSIX_VERSION, _POSIX_ADVISORY_INFO);
-  EXPECT_GT(_POSIX_AIO_LISTIO_MAX, 0);
-  EXPECT_GT(_POSIX_AIO_MAX, 0);
-  EXPECT_GT(_POSIX_ARG_MAX, 0);
   EXPECT_GT(_POSIX_BARRIERS, 0);
   EXPECT_GT(_POSIX_SPIN_LOCKS, 0);
-  EXPECT_GT(_POSIX_CHILD_MAX, 0);
   EXPECT_NE(_POSIX_CHOWN_RESTRICTED, -1);
   EXPECT_EQ(_POSIX_VERSION, _POSIX_CLOCK_SELECTION);
-  EXPECT_EQ(0, _POSIX_CPUTIME);             // Use sysconf to detect support at runtime.
-  EXPECT_GT(_POSIX_DELAYTIMER_MAX, 0);
+#if !defined(__GLIBC__) // glibc supports ancient kernels.
+  EXPECT_EQ(_POSIX_VERSION, _POSIX_CPUTIME);
+#endif
   EXPECT_EQ(_POSIX_VERSION, _POSIX_FSYNC);
-  EXPECT_GT(_POSIX_HOST_NAME_MAX, 0);
   EXPECT_EQ(_POSIX_VERSION, _POSIX_IPV6);
   EXPECT_GT(_POSIX_JOB_CONTROL, 0);
-  EXPECT_GT(_POSIX_LINK_MAX, 0);
-  EXPECT_GT(_POSIX_LOGIN_NAME_MAX, 0);
   EXPECT_EQ(_POSIX_VERSION, _POSIX_MAPPED_FILES);
-  EXPECT_GT(_POSIX_MAX_CANON, 0);
-  EXPECT_GT(_POSIX_MAX_INPUT, 0);
   EXPECT_EQ(_POSIX_VERSION, _POSIX_MEMLOCK);
   EXPECT_EQ(_POSIX_VERSION, _POSIX_MEMLOCK_RANGE);
   EXPECT_EQ(_POSIX_VERSION, _POSIX_MEMORY_PROTECTION);
-  EXPECT_EQ(0, _POSIX_MONOTONIC_CLOCK);
-  EXPECT_GT(_POSIX_MQ_OPEN_MAX, 0);
-  EXPECT_GT(_POSIX_MQ_PRIO_MAX, 0);
-  EXPECT_GT(_POSIX_NAME_MAX, 0);
-  EXPECT_GT(_POSIX_NGROUPS_MAX, 0);
+#if !defined(__GLIBC__) // glibc supports ancient kernels.
+  EXPECT_EQ(_POSIX_VERSION, _POSIX_MONOTONIC_CLOCK);
+#endif
   EXPECT_GT(_POSIX_NO_TRUNC, 0);
-  EXPECT_GT(_POSIX_OPEN_MAX, 0);
-  EXPECT_GT(_POSIX_PATH_MAX, 0);
-  EXPECT_GT(_POSIX_PIPE_BUF, 0);
   EXPECT_EQ(_POSIX_VERSION, _POSIX_PRIORITY_SCHEDULING);
   EXPECT_EQ(_POSIX_VERSION, _POSIX_RAW_SOCKETS);
   EXPECT_EQ(_POSIX_VERSION, _POSIX_READER_WRITER_LOCKS);
   EXPECT_EQ(_POSIX_VERSION, _POSIX_REALTIME_SIGNALS);
   EXPECT_GT(_POSIX_REGEXP, 0);
-  EXPECT_GT(_POSIX_RE_DUP_MAX, 0);
   EXPECT_GT(_POSIX_SAVED_IDS, 0);
   EXPECT_EQ(_POSIX_VERSION, _POSIX_SEMAPHORES);
-  EXPECT_GT(_POSIX_SEM_NSEMS_MAX, 0);
-  EXPECT_GT(_POSIX_SEM_VALUE_MAX, 0);
   EXPECT_GT(_POSIX_SHELL, 0);
-  EXPECT_GT(_POSIX_SIGQUEUE_MAX, 0);
+  EXPECT_EQ(_POSIX_VERSION, _POSIX_SPAWN);
   EXPECT_EQ(-1, _POSIX_SPORADIC_SERVER);
-  EXPECT_GT(_POSIX_SSIZE_MAX, 0);
-  EXPECT_GT(_POSIX_STREAM_MAX, 0);
-  EXPECT_GT(_POSIX_SYMLINK_MAX, 0);
-  EXPECT_GT(_POSIX_SYMLOOP_MAX, 0);
   EXPECT_EQ(_POSIX_VERSION, _POSIX_SYNCHRONIZED_IO);
   EXPECT_EQ(_POSIX_VERSION, _POSIX_THREADS);
   EXPECT_EQ(_POSIX_VERSION, _POSIX_THREAD_ATTR_STACKADDR);
   EXPECT_EQ(_POSIX_VERSION, _POSIX_THREAD_ATTR_STACKSIZE);
-  EXPECT_EQ(0, _POSIX_THREAD_CPUTIME);       // Use sysconf to detect support at runtime.
-  EXPECT_GT(_POSIX_THREAD_DESTRUCTOR_ITERATIONS, 0);
-  EXPECT_EQ(_POSIX_THREAD_KEYS_MAX, 128);
+#if !defined(__GLIBC__) // glibc supports ancient kernels.
+  EXPECT_EQ(_POSIX_VERSION, _POSIX_THREAD_CPUTIME);
+#endif
   EXPECT_EQ(_POSIX_VERSION, _POSIX_THREAD_PRIORITY_SCHEDULING);
-  EXPECT_EQ(-1, _POSIX_THREAD_PRIO_INHERIT);
-  EXPECT_EQ(-1, _POSIX_THREAD_PRIO_PROTECT);
   EXPECT_EQ(_POSIX_VERSION, _POSIX_THREAD_PROCESS_SHARED);
   EXPECT_EQ(-1, _POSIX_THREAD_ROBUST_PRIO_PROTECT);
   EXPECT_EQ(_POSIX_VERSION, _POSIX_THREAD_SAFE_FUNCTIONS);
   EXPECT_EQ(-1, _POSIX_THREAD_SPORADIC_SERVER);
-  EXPECT_GT(_POSIX_THREAD_THREADS_MAX, 0);
   EXPECT_EQ(_POSIX_VERSION, _POSIX_TIMEOUTS);
   EXPECT_EQ(_POSIX_VERSION, _POSIX_TIMERS);
-  EXPECT_GT(_POSIX_TIMER_MAX, 0);
   EXPECT_EQ(-1, _POSIX_TRACE);
   EXPECT_EQ(-1, _POSIX_TRACE_EVENT_FILTER);
   EXPECT_EQ(-1, _POSIX_TRACE_INHERIT);
   EXPECT_EQ(-1, _POSIX_TRACE_LOG);
-  EXPECT_GT(_POSIX_TTY_NAME_MAX, 0);
   EXPECT_EQ(-1, _POSIX_TYPED_MEMORY_OBJECTS);
-  EXPECT_GT(_POSIX_TZNAME_MAX, 0);
   EXPECT_NE(-1, _POSIX_VDISABLE);
 
   EXPECT_EQ(_POSIX_VERSION, _POSIX2_VERSION);
-  EXPECT_GT(_POSIX2_BC_BASE_MAX, 0);
-  EXPECT_GT(_POSIX2_BC_DIM_MAX, 0);
-  EXPECT_GT(_POSIX2_BC_SCALE_MAX, 0);
-  EXPECT_GT(_POSIX2_BC_STRING_MAX, 0);
-  EXPECT_GT(_POSIX2_CHARCLASS_NAME_MAX, 0);
-  EXPECT_GT(_POSIX2_COLL_WEIGHTS_MAX, 0);
   EXPECT_EQ(_POSIX_VERSION, _POSIX2_C_BIND);
-  EXPECT_GT(_POSIX2_EXPR_NEST_MAX, 0);
-  EXPECT_GT(_POSIX2_LINE_MAX, 0);
-  EXPECT_GT(_POSIX2_RE_DUP_MAX, 0);
+  EXPECT_EQ(_POSIX_VERSION, _POSIX2_CHAR_TERM);
 
   EXPECT_EQ(700, _XOPEN_VERSION);
-  EXPECT_GT(_XOPEN_IOV_MAX, 0);
-  EXPECT_GT(_XOPEN_UNIX, 0);
-
-  // In O, the headers still have -1 (even though all the functionality has
-  // been there for a long time). This was fixed in O-DR, but there isn't a
-  // separate CTS for O-DR, so we'll accept both.
-  EXPECT_TRUE(_POSIX_THREAD_PROCESS_SHARED == -1 ||
-              _POSIX_THREAD_PROCESS_SHARED == _POSIX_VERSION);
+  EXPECT_EQ(1, _XOPEN_ENH_I18N);
+  EXPECT_EQ(1, _XOPEN_REALTIME);
+  EXPECT_EQ(1, _XOPEN_REALTIME_THREADS);
+  EXPECT_EQ(1, _XOPEN_SHM);
+  EXPECT_EQ(1, _XOPEN_UNIX);
 
 #if defined(__BIONIC__)
   // These tests only pass on bionic, as bionic and glibc has different support on these macros.
@@ -797,22 +819,20 @@
   EXPECT_EQ(-1, _POSIX_MESSAGE_PASSING);
   EXPECT_EQ(-1, _POSIX_PRIORITIZED_IO);
   EXPECT_EQ(-1, _POSIX_SHARED_MEMORY_OBJECTS);
-  EXPECT_EQ(-1, _POSIX_SPAWN);
+  EXPECT_EQ(-1, _POSIX_THREAD_PRIO_INHERIT);
+  EXPECT_EQ(-1, _POSIX_THREAD_PRIO_PROTECT);
   EXPECT_EQ(-1, _POSIX_THREAD_ROBUST_PRIO_INHERIT);
 
-  EXPECT_EQ(-1, _POSIX2_CHAR_TERM);
   EXPECT_EQ(-1, _POSIX2_C_DEV);
+  EXPECT_EQ(-1, _POSIX2_FORT_DEV);
+  EXPECT_EQ(-1, _POSIX2_FORT_RUN);
   EXPECT_EQ(-1, _POSIX2_LOCALEDEF);
   EXPECT_EQ(-1, _POSIX2_SW_DEV);
   EXPECT_EQ(-1, _POSIX2_UPE);
 
-  EXPECT_EQ(-1, _XOPEN_ENH_I18N);
   EXPECT_EQ(-1, _XOPEN_CRYPT);
   EXPECT_EQ(-1, _XOPEN_LEGACY);
-  EXPECT_EQ(-1, _XOPEN_REALTIME);
-  EXPECT_EQ(-1, _XOPEN_REALTIME_THREADS);
-  EXPECT_EQ(-1, _XOPEN_SHM);
-
+  EXPECT_EQ(-1, _XOPEN_STREAMS);
 #endif // defined(__BIONIC__)
 }
 
@@ -921,6 +941,7 @@
   VERIFY_SYSCONF_POSIX_VERSION(_SC_READER_WRITER_LOCKS);
   VERIFY_SYSCONF_POSITIVE(_SC_REGEXP);
   VERIFY_SYSCONF_POSITIVE(_SC_SHELL);
+  VERIFY_SYSCONF_POSIX_VERSION(_SC_SPAWN);
   VERIFY_SYSCONF_UNSUPPORTED(_SC_SPORADIC_SERVER);
   VERIFY_SYSCONF_POSITIVE(_SC_SYMLOOP_MAX);
   VERIFY_SYSCONF_POSIX_VERSION(_SC_THREAD_CPUTIME);
@@ -960,21 +981,15 @@
   VERIFY_SYSCONF_UNSUPPORTED(_SC_MESSAGE_PASSING);
   VERIFY_SYSCONF_UNSUPPORTED(_SC_PRIORITIZED_IO);
   VERIFY_SYSCONF_UNSUPPORTED(_SC_SHARED_MEMORY_OBJECTS);
-  VERIFY_SYSCONF_UNSUPPORTED(_SC_SPAWN);
   VERIFY_SYSCONF_UNSUPPORTED(_SC_THREAD_ROBUST_PRIO_INHERIT);
   VERIFY_SYSCONF_UNSUPPORTED(_SC_THREAD_ROBUST_PRIO_PROTECT);
 
   VERIFY_SYSCONF_UNSUPPORTED(_SC_2_C_DEV);
-  VERIFY_SYSCONF_UNSUPPORTED(_SC_2_CHAR_TERM);
   VERIFY_SYSCONF_UNSUPPORTED(_SC_2_LOCALEDEF);
   VERIFY_SYSCONF_UNSUPPORTED(_SC_2_SW_DEV);
 
   VERIFY_SYSCONF_UNSUPPORTED(_SC_XOPEN_CRYPT);
-  VERIFY_SYSCONF_UNSUPPORTED(_SC_XOPEN_ENH_I18N);
   VERIFY_SYSCONF_UNSUPPORTED(_SC_XOPEN_LEGACY);
-  VERIFY_SYSCONF_UNSUPPORTED(_SC_XOPEN_REALTIME);
-  VERIFY_SYSCONF_UNSUPPORTED(_SC_XOPEN_REALTIME_THREADS);
-  VERIFY_SYSCONF_UNSUPPORTED(_SC_XOPEN_SHM);
   VERIFY_SYSCONF_UNSUPPORTED(_SC_XOPEN_UUCP);
 #endif // defined(__BIONIC__)
 }
@@ -1002,36 +1017,11 @@
 }
 
 TEST(UNISTD_TEST, sysconf_SC_ARG_MAX) {
-  // Since Linux 2.6.23, ARG_MAX isn't a constant and depends on RLIMIT_STACK.
-
-  // Get our current limit, and set things up so we restore the limit.
-  rlimit rl;
-  ASSERT_EQ(0, getrlimit(RLIMIT_STACK, &rl));
-  uint64_t original_rlim_cur = rl.rlim_cur;
-  if (rl.rlim_cur == RLIM_INFINITY) {
-    rl.rlim_cur = 8 * 1024 * 1024; // Bionic reports unlimited stacks as 8MiB.
-  }
-  auto guard = android::base::make_scope_guard([&rl, original_rlim_cur]() {
-    rl.rlim_cur = original_rlim_cur;
-    ASSERT_EQ(0, setrlimit(RLIMIT_STACK, &rl));
-  });
-
-  // _SC_ARG_MAX should be 1/4 the stack size.
-  EXPECT_EQ(static_cast<long>(rl.rlim_cur / 4), sysconf(_SC_ARG_MAX));
-
-  // If you have a really small stack, the kernel still guarantees "32 pages" (fs/exec.c).
-  rl.rlim_cur = 1024;
-  rl.rlim_max = RLIM_INFINITY;
-  ASSERT_EQ(0, setrlimit(RLIMIT_STACK, &rl));
-
-  EXPECT_EQ(static_cast<long>(32 * sysconf(_SC_PAGE_SIZE)), sysconf(_SC_ARG_MAX));
-
-  // With a 128-page stack limit, we know exactly what _SC_ARG_MAX should be...
-  rl.rlim_cur = 128 * sysconf(_SC_PAGE_SIZE);
-  rl.rlim_max = RLIM_INFINITY;
-  ASSERT_EQ(0, setrlimit(RLIMIT_STACK, &rl));
-
-  EXPECT_EQ(static_cast<long>((128 * sysconf(_SC_PAGE_SIZE)) / 4), sysconf(_SC_ARG_MAX));
+  // https://lkml.org/lkml/2017/11/15/813.
+#if !defined(ARG_MAX)
+#define ARG_MAX 131072
+#endif
+  ASSERT_EQ(ARG_MAX, sysconf(_SC_ARG_MAX));
 }
 
 TEST(UNISTD_TEST, dup2_same) {
@@ -1218,12 +1208,6 @@
   }
 }
 
-#if defined(__GLIBC__)
-#define BIN_DIR "/bin/"
-#else
-#define BIN_DIR "/system/bin/"
-#endif
-
 TEST(UNISTD_TEST, execve_failure) {
   ExecTestHelper eth;
   errno = 0;
@@ -1388,9 +1372,87 @@
               "<unknown>: usage: run-as");
 }
 
+TEST(UNISTD_TEST, fexecve_failure) {
+  ExecTestHelper eth;
+  errno = 0;
+  int fd = open("/", O_RDONLY);
+  ASSERT_NE(-1, fd);
+  ASSERT_EQ(-1, fexecve(fd, eth.GetArgs(), eth.GetEnv()));
+  ASSERT_EQ(EACCES, errno);
+  close(fd);
+}
+
+TEST(UNISTD_TEST, fexecve_bad_fd) {
+  ExecTestHelper eth;
+  errno = 0;
+  ASSERT_EQ(-1, fexecve(-1, eth.GetArgs(), eth.GetEnv()));
+  ASSERT_EQ(EBADF, errno);
+}
+
+TEST(UNISTD_TEST, fexecve_args) {
+  // Test basic argument passing.
+  int echo_fd = open(BIN_DIR "echo", O_RDONLY | O_CLOEXEC);
+  ASSERT_NE(-1, echo_fd);
+  ExecTestHelper eth;
+  eth.SetArgs({"echo", "hello", "world", nullptr});
+  eth.Run([&]() { fexecve(echo_fd, eth.GetArgs(), eth.GetEnv()); }, 0, "hello world\n");
+  close(echo_fd);
+
+  // Test environment variable setting too.
+  int printenv_fd = open(BIN_DIR "printenv", O_RDONLY | O_CLOEXEC);
+  ASSERT_NE(-1, printenv_fd);
+  eth.SetArgs({"printenv", nullptr});
+  eth.SetEnv({"A=B", nullptr});
+  eth.Run([&]() { fexecve(printenv_fd, eth.GetArgs(), eth.GetEnv()); }, 0, "A=B\n");
+  close(printenv_fd);
+}
+
 TEST(UNISTD_TEST, getlogin_r) {
   char buf[LOGIN_NAME_MAX] = {};
   EXPECT_EQ(ERANGE, getlogin_r(buf, 0));
   EXPECT_EQ(0, getlogin_r(buf, sizeof(buf)));
   EXPECT_STREQ(getlogin(), buf);
 }
+
+TEST(UNISTD_TEST, swab) {
+  // POSIX: "The swab() function shall copy nbytes bytes, which are pointed to by src,
+  // to the object pointed to by dest, exchanging adjacent bytes."
+  char buf[BUFSIZ];
+  memset(buf, 'x', sizeof(buf));
+  swab("ehll oowlr\0d", buf, 12);
+  ASSERT_STREQ("hello world", buf);
+}
+
+TEST(UNISTD_TEST, swab_odd_byte_count) {
+  // POSIX: "If nbytes is odd, swab() copies and exchanges nbytes-1 bytes and the disposition
+  // of the last byte is unspecified."
+  // ...but it seems unreasonable to not just leave the last byte alone.
+  char buf[BUFSIZ];
+  memset(buf, 'x', sizeof(buf));
+  swab("012345", buf, 3);
+  ASSERT_EQ('1', buf[0]);
+  ASSERT_EQ('0', buf[1]);
+  ASSERT_EQ('x', buf[2]);
+}
+
+TEST(UNISTD_TEST, swab_overlap) {
+  // POSIX: "If copying takes place between objects that overlap, the behavior is undefined."
+  // ...but it seems unreasonable to not just do the right thing.
+  char buf[] = "012345";
+  swab(buf, buf, 4);
+  ASSERT_EQ('1', buf[0]);
+  ASSERT_EQ('0', buf[1]);
+  ASSERT_EQ('3', buf[2]);
+  ASSERT_EQ('2', buf[3]);
+  ASSERT_EQ('4', buf[4]);
+  ASSERT_EQ('5', buf[5]);
+  ASSERT_EQ(0, buf[6]);
+}
+
+TEST(UNISTD_TEST, swab_negative_byte_count) {
+  // POSIX: "If nbytes is negative, swab() does nothing."
+  char buf[BUFSIZ];
+  memset(buf, 'x', sizeof(buf));
+  swab("hello", buf, -1);
+  ASSERT_EQ('x', buf[0]);
+}
diff --git a/tests/utils.h b/tests/utils.h
index 8638850..ba006f1 100644
--- a/tests/utils.h
+++ b/tests/utils.h
@@ -38,6 +38,12 @@
 #define PATH_TO_SYSTEM_LIB "/system/lib/"
 #endif
 
+#if defined(__GLIBC__)
+#define BIN_DIR "/bin/"
+#else
+#define BIN_DIR "/system/bin/"
+#endif
+
 #if defined(__BIONIC__)
 #define KNOWN_FAILURE_ON_BIONIC(x) xfail_ ## x
 #else
@@ -71,15 +77,13 @@
 class Maps {
  public:
   static bool parse_maps(std::vector<map_record>* maps) {
-    FILE* fp = fopen("/proc/self/maps", "re");
-    if (fp == nullptr) {
-      return false;
-    }
+    maps->clear();
 
-    auto fp_guard = android::base::make_scope_guard([&]() { fclose(fp); });
+    std::unique_ptr<FILE, decltype(&fclose)> fp(fopen("/proc/self/maps", "re"), fclose);
+    if (!fp) return false;
 
     char line[BUFSIZ];
-    while (fgets(line, sizeof(line), fp) != nullptr) {
+    while (fgets(line, sizeof(line), fp.get()) != nullptr) {
       map_record record;
       uint32_t dev_major, dev_minor;
       int path_offset;
@@ -161,6 +165,9 @@
   char** GetArgs() {
     return const_cast<char**>(args_.data());
   }
+  const char* GetArg0() {
+    return args_[0];
+  }
   char** GetEnv() {
     return const_cast<char**>(env_.data());
   }
diff --git a/tools/relocation_packer/Android.bp b/tools/relocation_packer/Android.bp
index 2907b31..cd6053a 100644
--- a/tools/relocation_packer/Android.bp
+++ b/tools/relocation_packer/Android.bp
@@ -16,11 +16,13 @@
 
 cc_defaults {
     name: "relocation_packer_flags",
-    cppflags: [
+    cflags: [
         "-Wall",
+        "-Werror",
+    ],
+    cppflags: [
         "-Wextra",
         "-Wunused",
-        "-Werror",
         "-Wold-style-cast",
     ],
 
diff --git a/tools/relocation_packer/src/main.cc b/tools/relocation_packer/src/main.cc
index d0a0dd4..1589043 100644
--- a/tools/relocation_packer/src/main.cc
+++ b/tools/relocation_packer/src/main.cc
@@ -106,7 +106,7 @@
   // We need to detect elf class in order to create
   // correct implementation
   uint8_t e_ident[EI_NIDENT];
-  if (TEMP_FAILURE_RETRY(read(fd.get(), e_ident, EI_NIDENT) != EI_NIDENT)) {
+  if (TEMP_FAILURE_RETRY(read(fd.get(), e_ident, EI_NIDENT)) != EI_NIDENT) {
     LOG(ERROR) << file << ": failed to read elf header:" << strerror(errno);
     return 1;
   }
diff --git a/tools/update_notice.sh b/tools/update_notice.sh
index 9974da2..0b8a106 100755
--- a/tools/update_notice.sh
+++ b/tools/update_notice.sh
@@ -1,4 +1,4 @@
-#!/bin/sh
+#!/bin/bash
 DIR="$( cd "$( dirname "${BASH_SOURCE[0]}" )" && pwd )"
 cd $DIR/..
 ./libc/tools/generate-NOTICE.py libc libdl libm linker libstdc++ > libc/NOTICE
diff --git a/tools/update_seccomp.sh b/tools/update_seccomp.sh
new file mode 100755
index 0000000..b9e53aa
--- /dev/null
+++ b/tools/update_seccomp.sh
@@ -0,0 +1,7 @@
+#!/bin/bash
+DIR="$( cd "$( dirname "${BASH_SOURCE[0]}" )" && pwd )"
+cd $DIR/..
+./libc/tools/genseccomp.py
+
+git diff --exit-code HEAD libc/seccomp/
+exit $?
diff --git a/tools/update_syscalls.sh b/tools/update_syscalls.sh
new file mode 100755
index 0000000..5e7eb0a
--- /dev/null
+++ b/tools/update_syscalls.sh
@@ -0,0 +1,7 @@
+#!/bin/bash
+DIR="$( cd "$( dirname "${BASH_SOURCE[0]}" )" && pwd )"
+cd $DIR/..
+./libc/tools/gensyscalls.py
+
+git diff --exit-code HEAD libc/arch-*/syscalls/
+exit $?
diff --git a/tools/update_version_scripts.sh b/tools/update_version_scripts.sh
new file mode 100755
index 0000000..2c3a5b4
--- /dev/null
+++ b/tools/update_version_scripts.sh
@@ -0,0 +1,7 @@
+#!/bin/bash
+DIR="$( cd "$( dirname "${BASH_SOURCE[0]}" )" && pwd )"
+cd $DIR/..
+./libc/tools/genversion-scripts.py
+
+git diff --exit-code HEAD libc/*.map libdl/*.map libm/*.map linker/*.map
+exit $?
diff --git a/tools/versioner/src/Android.bp b/tools/versioner/src/Android.bp
index c5afa56..9151646 100644
--- a/tools/versioner/src/Android.bp
+++ b/tools/versioner/src/Android.bp
@@ -1,6 +1,8 @@
 cc_binary_host {
     name: "versioner",
 
+    cpp_std: "gnu++17",
+
     srcs: [
         "versioner.cpp",
         "Arch.cpp",
@@ -14,8 +16,8 @@
     ],
 
     shared_libs: [
-        "libclang",
-        "libLLVM",
+        "libclang_android",
+        "libLLVM_android",
         "libbase",
     ],
 
@@ -29,6 +31,7 @@
         "-Wextra",
         "-Werror",
         "-Wno-unused-parameter",
+        "-fno-omit-frame-pointer",
 
         "-D__STDC_CONSTANT_MACROS",
         "-D__STDC_LIMIT_MACROS",
@@ -37,7 +40,6 @@
     target: {
         host: {
             cppflags: [
-                "-std=gnu++1z",
                 "-fno-rtti",
             ],
         },
diff --git a/tools/versioner/src/Arch.h b/tools/versioner/src/Arch.h
index 0c6f514..ab05d5c 100644
--- a/tools/versioner/src/Arch.h
+++ b/tools/versioner/src/Arch.h
@@ -136,7 +136,7 @@
   { Arch::x86_64, "x86_64-linux-android" },
 };
 
-static const std::set<int> supported_levels = { 9, 12, 13, 14, 15, 16, 17, 18, 19, 21, 23, 24 };
+static const std::set<int> default_levels = { 14, 15, 16, 17, 18, 19, 21, 23, 24, 25, 26, 27 };
 
 static const ArchMap<int> arch_min_api = {
   { Arch::arm, 9 },
diff --git a/tools/versioner/src/CompilationType.cpp b/tools/versioner/src/CompilationType.cpp
index e9d31cb..7e7bb5d 100644
--- a/tools/versioner/src/CompilationType.cpp
+++ b/tools/versioner/src/CompilationType.cpp
@@ -21,6 +21,7 @@
 
 std::string to_string(const CompilationType& type) {
   std::stringstream ss;
-  ss << to_string(type.arch) << "-" << type.api_level << " [fob = " << type.file_offset_bits << "]";
+  ss << to_string(type.arch) << "-" << type.api_level << " [" << (type.cpp ? "c++" : "c")
+     << ", fob = " << type.file_offset_bits << "]";
   return ss.str();
 }
diff --git a/tools/versioner/src/CompilationType.h b/tools/versioner/src/CompilationType.h
index 7d516b2..2f4cf5c 100644
--- a/tools/versioner/src/CompilationType.h
+++ b/tools/versioner/src/CompilationType.h
@@ -25,12 +25,13 @@
 
 struct CompilationType {
   Arch arch;
+  bool cpp;
   int api_level;
   int file_offset_bits;
 
  private:
   auto tie() const {
-    return std::tie(arch, api_level, file_offset_bits);
+    return std::tie(arch, cpp, api_level, file_offset_bits);
   }
 
  public:
@@ -49,11 +50,13 @@
   size_t operator()(CompilationType type) const {
     struct {
       int32_t arch : 3;
+      int32_t cpp : 1;
       int32_t api_level : 6;
       int32_t file_offset_bits : 1;
-      int32_t padding : 22;
+      int32_t padding : 21;
     } packed;
     packed.arch = static_cast<int32_t>(type.arch);
+    packed.cpp = type.cpp;
     packed.api_level = type.api_level;
     packed.file_offset_bits = (type.file_offset_bits == 64);
     packed.padding = 0;
diff --git a/tools/versioner/src/DeclarationDatabase.cpp b/tools/versioner/src/DeclarationDatabase.cpp
index 247e58b..19c2f0d 100644
--- a/tools/versioner/src/DeclarationDatabase.cpp
+++ b/tools/versioner/src/DeclarationDatabase.cpp
@@ -35,6 +35,22 @@
 
 using namespace clang;
 
+static bool shouldMangle(MangleContext* mangler, NamedDecl* decl) {
+  // Passing a decl with static linkage to the mangler gives incorrect results.
+  // Check some things ourselves before handing it off to the mangler.
+  if (auto FD = dyn_cast<FunctionDecl>(decl)) {
+    if (FD->isExternC()) {
+      return false;
+    }
+
+    if (FD->isInExternCContext()) {
+      return false;
+    }
+  }
+
+  return mangler->shouldMangleDeclName(decl);
+}
+
 class Visitor : public RecursiveASTVisitor<Visitor> {
   HeaderDatabase& database;
   CompilationType type;
@@ -54,20 +70,27 @@
       }
     }
 
-    if (mangler->shouldMangleDeclName(decl)) {
-      std::string mangled;
-      llvm::raw_string_ostream ss(mangled);
-      mangler->mangleName(decl, ss);
-      return mangled;
+    // <math.h> maps fool onto foo on 32-bit, since long double is the same as double.
+    if (auto asm_attr = decl->getAttr<AsmLabelAttr>()) {
+      return asm_attr->getLabel();
     }
 
+    // The decl might not have a name (e.g. bitfields).
     if (auto identifier = decl->getIdentifier()) {
+      if (shouldMangle(mangler.get(), decl)) {
+        std::string mangled;
+        llvm::raw_string_ostream ss(mangled);
+        mangler->mangleName(decl, ss);
+        return mangled;
+      }
+
       return identifier->getName();
     }
-    return "<error>";
+
+    return "<unnamed>";
   }
 
-  bool VisitDecl(Decl* decl) {
+  bool VisitDeclaratorDecl(DeclaratorDecl* decl, SourceRange range) {
     // Skip declarations inside of functions (function arguments, variable declarations inside of
     // inline functions, etc).
     if (decl->getParentFunctionOrMethod()) {
@@ -120,21 +143,6 @@
       return true;
     }
 
-    auto start_loc = src_manager.getPresumedLoc(decl->getLocStart());
-    auto end_loc = src_manager.getPresumedLoc(decl->getLocEnd());
-
-    Location location = {
-      .filename = start_loc.getFilename(),
-      .start = {
-        .line = start_loc.getLine(),
-        .column = start_loc.getColumn(),
-      },
-      .end = {
-        .line = end_loc.getLine(),
-        .column = end_loc.getColumn(),
-      }
-    };
-
     DeclarationAvailability availability;
 
     // Find and parse __ANDROID_AVAILABILITY_DUMP__ annotations.
@@ -192,6 +200,24 @@
       std::tie(symbol_it, dummy) = database.symbols.insert({ declaration_name, symbol });
     }
 
+    auto expansion_range = src_manager.getExpansionRange(range);
+    auto filename = src_manager.getFilename(expansion_range.getBegin());
+    if (filename != src_manager.getFilename(expansion_range.getEnd())) {
+      errx(1, "expansion range filenames don't match");
+    }
+
+    Location location = {
+      .filename = filename,
+      .start = {
+        .line = src_manager.getExpansionLineNumber(expansion_range.getBegin()),
+        .column = src_manager.getExpansionColumnNumber(expansion_range.getBegin()),
+      },
+      .end = {
+        .line = src_manager.getExpansionLineNumber(expansion_range.getEnd()),
+        .column = src_manager.getExpansionColumnNumber(expansion_range.getEnd()),
+      }
+    };
+
     // Find or insert an entry for the declaration.
     if (auto declaration_it = symbol_it->second.declarations.find(location);
         declaration_it != symbol_it->second.declarations.end()) {
@@ -215,6 +241,38 @@
 
     return true;
   }
+
+  bool VisitDeclaratorDecl(DeclaratorDecl* decl) {
+    return VisitDeclaratorDecl(decl, decl->getSourceRange());
+  }
+
+  bool TraverseLinkageSpecDecl(LinkageSpecDecl* decl) {
+    // Make sure that we correctly calculate the SourceRange of a declaration that has a non-braced
+    // extern "C"/"C++".
+    if (!decl->hasBraces()) {
+      DeclaratorDecl* child = nullptr;
+      for (auto child_decl : decl->decls()) {
+        if (child != nullptr) {
+          errx(1, "LinkageSpecDecl has multiple children");
+        }
+
+        if (DeclaratorDecl* declarator_decl = dyn_cast<DeclaratorDecl>(child_decl)) {
+          child = declarator_decl;
+        } else {
+          errx(1, "child of LinkageSpecDecl is not a DeclaratorDecl");
+        }
+      }
+
+      return VisitDeclaratorDecl(child, decl->getSourceRange());
+    }
+
+    for (auto child : decl->decls()) {
+      if (!TraverseDecl(child)) {
+        return false;
+      }
+    }
+    return true;
+  }
 };
 
 bool DeclarationAvailability::merge(const DeclarationAvailability& other) {
diff --git a/tools/versioner/src/Driver.cpp b/tools/versioner/src/Driver.cpp
index 8a8e00a..8911190 100644
--- a/tools/versioner/src/Driver.cpp
+++ b/tools/versioner/src/Driver.cpp
@@ -98,9 +98,16 @@
                                    CompilationType type,
                                    const std::vector<std::string>& include_dirs) {
   std::vector<std::string> cmd = { "versioner" };
-  cmd.push_back("-std=c11");
-  cmd.push_back("-x");
-  cmd.push_back("c");
+  if (type.cpp) {
+    cmd.push_back("-std=gnu++11");
+    cmd.push_back("-x");
+    cmd.push_back("c++");
+  } else {
+    cmd.push_back("-std=gnu11");
+    cmd.push_back("-x");
+    cmd.push_back("c");
+  }
+
   cmd.push_back("-fsyntax-only");
 
   cmd.push_back("-Wall");
diff --git a/tools/versioner/src/SymbolDatabase.cpp b/tools/versioner/src/SymbolDatabase.cpp
index bd4b99d..8521f4d 100644
--- a/tools/versioner/src/SymbolDatabase.cpp
+++ b/tools/versioner/src/SymbolDatabase.cpp
@@ -70,11 +70,6 @@
   int api_level = type.api_level;
   std::ifstream stream;
   while (api_level >= arch_min_api[type.arch]) {
-    if (supported_levels.count(api_level) == 0) {
-      --api_level;
-      continue;
-    }
-
     std::string path = std::string(platform_dir) + "/android-" + std::to_string(api_level) +
                        "/arch-" + to_string(type.arch) + "/symbols/" + filename;
 
diff --git a/tools/versioner/src/versioner.cpp b/tools/versioner/src/versioner.cpp
index 8db75d7..a082f07 100644
--- a/tools/versioner/src/versioner.cpp
+++ b/tools/versioner/src/versioner.cpp
@@ -36,6 +36,7 @@
 #include <set>
 #include <sstream>
 #include <string>
+#include <string_view>
 #include <thread>
 #include <unordered_map>
 #include <vector>
@@ -82,18 +83,28 @@
 
 namespace {
 struct HeaderLocationInformation {
-  std::string header_dir;
+  std::string header_path;
   std::string dependency_dir;
   // Absolute paths to ignore all children -- including subdirectories -- of.
   std::unordered_set<std::string> ignored_directories;
 };
 }
 
+static bool is_dir(const std::string& path) {
+  struct stat st;
+  return stat(path.c_str(), &st) == 0 && S_ISDIR(st.st_mode);
+}
+
 static CompilationRequirements collectRequirements(const Arch& arch,
                                                    const HeaderLocationInformation& location) {
   std::vector<std::string> headers =
-      collectHeaders(location.header_dir, location.ignored_directories);
-  std::vector<std::string> dependencies = { location.header_dir };
+      collectHeaders(location.header_path, location.ignored_directories);
+  std::vector<std::string> dependencies;
+
+  if (is_dir(location.header_path)) {
+    dependencies.emplace_back(location.header_path);
+  }
+
   if (!location.dependency_dir.empty()) {
     auto collect_children = [&dependencies](const std::string& dir_path) {
       DIR* dir = opendir(dir_path.c_str());
@@ -159,10 +170,12 @@
       }
 
       for (int file_offset_bits : { 32, 64 }) {
-        CompilationType type = {
-          .arch = arch, .api_level = api_level, .file_offset_bits = file_offset_bits
-        };
-        result.insert(type);
+        for (bool cpp : { true, false }) {
+          CompilationType type = {
+            .arch = arch, .cpp = cpp, .api_level = api_level, .file_offset_bits = file_offset_bits
+          };
+          result.insert(type);
+        }
       }
     }
   }
@@ -175,7 +188,7 @@
     errx(1, "compileHeaders received no CompilationTypes");
   }
 
-  auto vfs = createCommonVFS(location.header_dir, location.dependency_dir, add_include);
+  auto vfs = createCommonVFS(location.header_path, location.dependency_dir, add_include);
 
   size_t thread_count = max_thread_count;
   std::vector<std::thread> threads;
@@ -282,7 +295,8 @@
       for (const auto& inline_def_it : inline_definitions) {
         auto intersection = Intersection(compilation_types, inline_def_it.second);
         if (!intersection.empty()) {
-          fprintf(stderr, "versioner: conflicting inline definitions:\n");
+          fprintf(stderr, "versioner: conflicting inline definitions for symbol %s:\n",
+                  symbol.name.c_str());
           fprintf(stderr, "  declarations visible in: %s\n", Join(intersection, ", ").c_str());
           decl->dump(cwd, stderr, 4);
           inline_def_it.first->dump(cwd, stderr, 4);
@@ -451,7 +465,7 @@
     fprintf(stderr, "\n");
     fprintf(stderr, "Target specification (defaults to all):\n");
     fprintf(stderr, "  -a API_LEVEL\tbuild with specified API level (can be repeated)\n");
-    fprintf(stderr, "    \t\tvalid levels are %s\n", Join(supported_levels).c_str());
+    fprintf(stderr, "    \t\tdefaults to %s\n", Join(default_levels).c_str());
     fprintf(stderr, "  -r ARCH\tbuild with specified architecture (can be repeated)\n");
     fprintf(stderr, "    \t\tvalid architectures are %s\n", Join(supported_archs).c_str());
     fprintf(stderr, "\n");
@@ -501,10 +515,6 @@
           usage();
         }
 
-        if (supported_levels.count(api_level) == 0) {
-          errx(1, "unsupported API level %d", api_level);
-        }
-
         selected_levels.insert(api_level);
         break;
       }
@@ -530,8 +540,8 @@
         if (stat(platform_dir.c_str(), &st) != 0) {
           err(1, "failed to stat platform directory '%s'", platform_dir.c_str());
         }
-        if (!S_ISDIR(st.st_mode)) {
-          errx(1, "'%s' is not a directory", optarg);
+        if (!S_ISDIR(st.st_mode) && !S_ISREG(st.st_mode)) {
+          errx(1, "'%s' is not a file or directory", optarg);
         }
         break;
       }
@@ -602,13 +612,13 @@
   if (optind == argc) {
     // Neither HEADER_PATH nor DEPS_PATH were specified, so try to figure them out.
     std::string versioner_dir = to_string(top) + "/bionic/tools/versioner";
-    location.header_dir = versioner_dir + "/current";
+    location.header_path = versioner_dir + "/current";
     location.dependency_dir = versioner_dir + "/dependencies";
     if (platform_dir.empty()) {
       platform_dir = versioner_dir + "/platforms";
     }
   } else {
-    if (!android::base::Realpath(argv[optind], &location.header_dir)) {
+    if (!android::base::Realpath(argv[optind], &location.header_path)) {
       err(1, "failed to get realpath for path '%s'", argv[optind]);
     }
 
@@ -620,8 +630,8 @@
   // Every file that lives in bits/fortify is logically a part of a header outside of bits/fortify.
   // This makes the files there impossible to build on their own.
   if (ignore_fortify_headers) {
-    std::string fortify_path = location.header_dir;
-    if (!android::base::EndsWith(location.header_dir, "/")) {
+    std::string fortify_path = location.header_path;
+    if (!android::base::EndsWith(location.header_path, "/")) {
       fortify_path += '/';
     }
     fortify_path += "bits/fortify";
@@ -629,7 +639,7 @@
   }
 
   if (selected_levels.empty()) {
-    selected_levels = supported_levels;
+    selected_levels = default_levels;
   }
 
   if (selected_architectures.empty()) {
@@ -638,10 +648,8 @@
 
 
   struct stat st;
-  if (const char *dir = location.header_dir.c_str(); stat(dir, &st) != 0) {
-    err(1, "failed to stat '%s'", dir);
-  } else if (!S_ISDIR(st.st_mode)) {
-    errx(1, "'%s' is not a directory", dir);
+  if (const char *path = location.header_path.c_str(); stat(path, &st) != 0) {
+    err(1, "failed to stat '%s'", path);
   }
 
   std::set<CompilationType> compilation_types;
@@ -667,7 +675,7 @@
 
   bool failed = false;
   if (dump) {
-    declaration_database->dump(location.header_dir + "/");
+    declaration_database->dump(location.header_path + "/");
   } else {
     if (!sanityCheck(declaration_database.get())) {
       printf("versioner: sanity check failed\n");
@@ -683,7 +691,8 @@
   }
 
   if (!preprocessor_output_path.empty() && (force || !failed)) {
-    failed = !preprocessHeaders(preprocessor_output_path, location.header_dir, declaration_database.get());
+    failed = !preprocessHeaders(preprocessor_output_path, location.header_path,
+                                declaration_database.get());
   }
   return failed;
 }
diff --git a/tools/versioner/tests/arch_specific/headers/foo.h b/tools/versioner/tests/arch_specific/headers/foo.h
index 34035b4..4830a68 100644
--- a/tools/versioner/tests/arch_specific/headers/foo.h
+++ b/tools/versioner/tests/arch_specific/headers/foo.h
@@ -1,5 +1,13 @@
+#if defined(__cplusplus)
+extern "C" {
+#endif
+
 int foo();
 
 #if defined(__i386__)
 int bar();
 #endif
+
+#if defined(__cplusplus)
+}
+#endif
diff --git a/tools/versioner/tests/compilation_error/headers/foo.h b/tools/versioner/tests/compilation_error/headers/foo.h
index c8c1473..51c087a 100644
--- a/tools/versioner/tests/compilation_error/headers/foo.h
+++ b/tools/versioner/tests/compilation_error/headers/foo.h
@@ -1 +1,9 @@
+#if defined(__cplusplus)
+extern "C" {
+#endif
+
 #error foo
+
+#if defined(__cplusplus)
+}
+#endif
diff --git a/tools/versioner/tests/dependencies/dependencies/arm/archdep/archdep.h b/tools/versioner/tests/dependencies/dependencies/arm/archdep/archdep.h
index 2005972..b2d357a 100644
--- a/tools/versioner/tests/dependencies/dependencies/arm/archdep/archdep.h
+++ b/tools/versioner/tests/dependencies/dependencies/arm/archdep/archdep.h
@@ -1 +1,9 @@
+#if defined(__cplusplus)
+extern "C" {
+#endif
+
 typedef int arm_t;
+
+#if defined(__cplusplus)
+}
+#endif
diff --git a/tools/versioner/tests/dependencies/dependencies/common/foo/foodep.h b/tools/versioner/tests/dependencies/dependencies/common/foo/foodep.h
index 9feeb6c..baa5857 100644
--- a/tools/versioner/tests/dependencies/dependencies/common/foo/foodep.h
+++ b/tools/versioner/tests/dependencies/dependencies/common/foo/foodep.h
@@ -1 +1,9 @@
+#if defined(__cplusplus)
+extern "C" {
+#endif
+
 typedef int foo_t;
+
+#if defined(__cplusplus)
+}
+#endif
diff --git a/tools/versioner/tests/dependencies/dependencies/x86/archdep/archdep.h b/tools/versioner/tests/dependencies/dependencies/x86/archdep/archdep.h
index 5cc7de2..b73f7cc 100644
--- a/tools/versioner/tests/dependencies/dependencies/x86/archdep/archdep.h
+++ b/tools/versioner/tests/dependencies/dependencies/x86/archdep/archdep.h
@@ -1 +1,9 @@
+#if defined(__cplusplus)
+extern "C" {
+#endif
+
 typedef int x86_t;
+
+#if defined(__cplusplus)
+}
+#endif
diff --git a/tools/versioner/tests/dependencies/headers/foo.h b/tools/versioner/tests/dependencies/headers/foo.h
index 4491f1c..875de1b 100644
--- a/tools/versioner/tests/dependencies/headers/foo.h
+++ b/tools/versioner/tests/dependencies/headers/foo.h
@@ -1,3 +1,7 @@
+#if defined(__cplusplus)
+extern "C" {
+#endif
+
 #include <archdep.h>
 #include <foodep.h>
 
@@ -6,3 +10,7 @@
 #elif defined(__arm__)
 arm_t foo(foo_t);
 #endif
+
+#if defined(__cplusplus)
+}
+#endif
diff --git a/tools/versioner/tests/extern_cpp/headers/string.h b/tools/versioner/tests/extern_cpp/headers/string.h
new file mode 100644
index 0000000..5ac43ac
--- /dev/null
+++ b/tools/versioner/tests/extern_cpp/headers/string.h
@@ -0,0 +1,18 @@
+#if defined(__cplusplus)
+extern "C" {
+#endif
+
+#define __RENAME(x) __asm__(#x)
+
+#if defined(__cplusplus)
+extern "C++" char* basename(char*) __RENAME(__gnu_basename) __INTRODUCED_IN(23);
+extern "C++" const char* basename(const char*) __RENAME(__gnu_basename) __INTRODUCED_IN(23);
+#else
+char* basename(const char*) __RENAME(__gnu_basename) __INTRODUCED_IN(23);
+#endif
+
+char* foo() __INTRODUCED_IN(8);
+
+#if defined(__cplusplus)
+}
+#endif
diff --git a/tools/versioner/tests/extern_cpp/platforms/android-21/arch-arm/symbols/libc.so.functions.txt b/tools/versioner/tests/extern_cpp/platforms/android-21/arch-arm/symbols/libc.so.functions.txt
new file mode 100644
index 0000000..8b13789
--- /dev/null
+++ b/tools/versioner/tests/extern_cpp/platforms/android-21/arch-arm/symbols/libc.so.functions.txt
@@ -0,0 +1 @@
+
diff --git a/tools/versioner/tests/extern_cpp/platforms/android-23/arch-arm/symbols/libc.so.functions.txt b/tools/versioner/tests/extern_cpp/platforms/android-23/arch-arm/symbols/libc.so.functions.txt
new file mode 100644
index 0000000..36fe04f
--- /dev/null
+++ b/tools/versioner/tests/extern_cpp/platforms/android-23/arch-arm/symbols/libc.so.functions.txt
@@ -0,0 +1 @@
+__gnu_basename
diff --git a/tools/versioner/tests/extern_cpp/run.sh b/tools/versioner/tests/extern_cpp/run.sh
new file mode 100644
index 0000000..e320c95
--- /dev/null
+++ b/tools/versioner/tests/extern_cpp/run.sh
@@ -0,0 +1 @@
+versioner headers -p platforms -r arm -a 21 -a 23 -i
diff --git a/tools/versioner/tests/extern_cpp_mismatch/headers/string.h b/tools/versioner/tests/extern_cpp_mismatch/headers/string.h
new file mode 100644
index 0000000..66133d8
--- /dev/null
+++ b/tools/versioner/tests/extern_cpp_mismatch/headers/string.h
@@ -0,0 +1,16 @@
+#if defined(__cplusplus)
+extern "C" {
+#endif
+
+#define __RENAME(x) __asm__(#x)
+
+#if defined(__cplusplus)
+extern "C++" char* basename(char*) __RENAME(__gnu_basename) __INTRODUCED_IN(23);
+extern "C++" const char* basename(const char*) __RENAME(__gnu_basename) __INTRODUCED_IN(23);
+#else
+char* basename(const char*) __RENAME(__gnu_basename) __INTRODUCED_IN(23);
+#endif
+
+#if defined(__cplusplus)
+}
+#endif
diff --git a/tools/versioner/tests/extern_cpp_mismatch/platforms/android-9/arch-arm/symbols/libc.so.functions.txt b/tools/versioner/tests/extern_cpp_mismatch/platforms/android-9/arch-arm/symbols/libc.so.functions.txt
new file mode 100644
index 0000000..257cc56
--- /dev/null
+++ b/tools/versioner/tests/extern_cpp_mismatch/platforms/android-9/arch-arm/symbols/libc.so.functions.txt
@@ -0,0 +1 @@
+foo
diff --git a/tools/versioner/tests/extern_cpp_mismatch/run.sh b/tools/versioner/tests/extern_cpp_mismatch/run.sh
new file mode 100644
index 0000000..a34fda8
--- /dev/null
+++ b/tools/versioner/tests/extern_cpp_mismatch/run.sh
@@ -0,0 +1 @@
+versioner headers -p platforms -r arm -a 9 -i
\ No newline at end of file
diff --git a/tools/versioner/tests/future/headers/foo.h b/tools/versioner/tests/future/headers/foo.h
index 54e8f0c..51a3a1c 100644
--- a/tools/versioner/tests/future/headers/foo.h
+++ b/tools/versioner/tests/future/headers/foo.h
@@ -1 +1,9 @@
+#if defined(__cplusplus)
+extern "C" {
+#endif
+
 int foo() __INTRODUCED_IN_FUTURE;
+
+#if defined(__cplusplus)
+}
+#endif
diff --git a/tools/versioner/tests/future_arch/headers/foo.h b/tools/versioner/tests/future_arch/headers/foo.h
index 9dd976e..a3258e7 100644
--- a/tools/versioner/tests/future_arch/headers/foo.h
+++ b/tools/versioner/tests/future_arch/headers/foo.h
@@ -1,5 +1,13 @@
+#if defined(__cplusplus)
+extern "C" {
+#endif
+
 #if defined(__arm__)
 int foo() __INTRODUCED_IN(9);
 #else
 int foo() __INTRODUCED_IN_FUTURE;
 #endif
+
+#if defined(__cplusplus)
+}
+#endif
diff --git a/tools/versioner/tests/inline/headers/foo.h b/tools/versioner/tests/inline/headers/foo.h
index a61b386..a337f9c 100644
--- a/tools/versioner/tests/inline/headers/foo.h
+++ b/tools/versioner/tests/inline/headers/foo.h
@@ -1,3 +1,7 @@
+#if defined(__cplusplus)
+extern "C" {
+#endif
+
 #if __ANDROID_API__ < 12
 static int foo() {
   return 0;
@@ -5,3 +9,7 @@
 #else
 int foo() __INTRODUCED_IN(12);
 #endif
+
+#if defined(__cplusplus)
+}
+#endif
diff --git a/tools/versioner/tests/missing_api/expected_fail b/tools/versioner/tests/missing_api/expected_fail
index 18e7845..9f097f7 100644
--- a/tools/versioner/tests/missing_api/expected_fail
+++ b/tools/versioner/tests/missing_api/expected_fail
@@ -1,4 +1,4 @@
   foo: introduced = 9
-    extern declaration @ headers/foo.h:1:1
+    extern declaration @ headers/foo.h:5:1
       introduced = 9
 versioner: version check failed
diff --git a/tools/versioner/tests/missing_api/headers/foo.h b/tools/versioner/tests/missing_api/headers/foo.h
index 3ff3ff7..c201dbb 100644
--- a/tools/versioner/tests/missing_api/headers/foo.h
+++ b/tools/versioner/tests/missing_api/headers/foo.h
@@ -1 +1,9 @@
-int foo() __INTRODUCED_IN(9);
\ No newline at end of file
+#if defined(__cplusplus)
+extern "C" {
+#endif
+
+int foo() __INTRODUCED_IN(9);
+
+#if defined(__cplusplus)
+}
+#endif
diff --git a/tools/versioner/tests/missing_arch/expected_fail b/tools/versioner/tests/missing_arch/expected_fail
index 82c2b28..7b33e19 100644
--- a/tools/versioner/tests/missing_arch/expected_fail
+++ b/tools/versioner/tests/missing_arch/expected_fail
@@ -1,4 +1,4 @@
   foo: no availability
-    extern declaration @ headers/foo.h:1:1
+    extern declaration @ headers/foo.h:5:1
       no availability
 versioner: version check failed
diff --git a/tools/versioner/tests/missing_arch/headers/foo.h b/tools/versioner/tests/missing_arch/headers/foo.h
index 176e7a3..5ba4794 100644
--- a/tools/versioner/tests/missing_arch/headers/foo.h
+++ b/tools/versioner/tests/missing_arch/headers/foo.h
@@ -1 +1,9 @@
-int foo();
\ No newline at end of file
+#if defined(__cplusplus)
+extern "C" {
+#endif
+
+int foo();
+
+#if defined(__cplusplus)
+}
+#endif
diff --git a/tools/versioner/tests/multiple_decl/headers/bar.h b/tools/versioner/tests/multiple_decl/headers/bar.h
index 1d3a28c..b16617b 100644
--- a/tools/versioner/tests/multiple_decl/headers/bar.h
+++ b/tools/versioner/tests/multiple_decl/headers/bar.h
@@ -1 +1,9 @@
-int foo() __REMOVED_IN(12);
\ No newline at end of file
+#if defined(__cplusplus)
+extern "C" {
+#endif
+
+int foo() __REMOVED_IN(12);
+
+#if defined(__cplusplus)
+}
+#endif
diff --git a/tools/versioner/tests/multiple_decl/headers/foo.h b/tools/versioner/tests/multiple_decl/headers/foo.h
index 1d3a28c..b16617b 100644
--- a/tools/versioner/tests/multiple_decl/headers/foo.h
+++ b/tools/versioner/tests/multiple_decl/headers/foo.h
@@ -1 +1,9 @@
-int foo() __REMOVED_IN(12);
\ No newline at end of file
+#if defined(__cplusplus)
+extern "C" {
+#endif
+
+int foo() __REMOVED_IN(12);
+
+#if defined(__cplusplus)
+}
+#endif
diff --git a/tools/versioner/tests/multiple_decl_mismatch/expected_fail b/tools/versioner/tests/multiple_decl_mismatch/expected_fail
index 8e8c846..1d1f266 100644
--- a/tools/versioner/tests/multiple_decl_mismatch/expected_fail
+++ b/tools/versioner/tests/multiple_decl_mismatch/expected_fail
@@ -1,8 +1,8 @@
 versioner: inconsistent availability for symbol 'foo'
 versioner: failed to calculate symbol availability
   foo: invalid
-    extern declaration @ headers/bar.h:1:1
+    extern declaration @ headers/bar.h:5:1
       obsoleted = 12
-    extern declaration @ headers/foo.h:1:1
+    extern declaration @ headers/foo.h:5:1
       obsoleted = 9
 versioner: sanity check failed
diff --git a/tools/versioner/tests/multiple_decl_mismatch/headers/bar.h b/tools/versioner/tests/multiple_decl_mismatch/headers/bar.h
index 1d3a28c..b16617b 100644
--- a/tools/versioner/tests/multiple_decl_mismatch/headers/bar.h
+++ b/tools/versioner/tests/multiple_decl_mismatch/headers/bar.h
@@ -1 +1,9 @@
-int foo() __REMOVED_IN(12);
\ No newline at end of file
+#if defined(__cplusplus)
+extern "C" {
+#endif
+
+int foo() __REMOVED_IN(12);
+
+#if defined(__cplusplus)
+}
+#endif
diff --git a/tools/versioner/tests/multiple_decl_mismatch/headers/foo.h b/tools/versioner/tests/multiple_decl_mismatch/headers/foo.h
index 49a73ec..8e8f98c 100644
--- a/tools/versioner/tests/multiple_decl_mismatch/headers/foo.h
+++ b/tools/versioner/tests/multiple_decl_mismatch/headers/foo.h
@@ -1 +1,9 @@
-int foo() __REMOVED_IN(9);
\ No newline at end of file
+#if defined(__cplusplus)
+extern "C" {
+#endif
+
+int foo() __REMOVED_IN(9);
+
+#if defined(__cplusplus)
+}
+#endif
diff --git a/tools/versioner/tests/multiple_definition/expected_fail b/tools/versioner/tests/multiple_definition/expected_fail
index 6c531bd..cb4acc6 100644
--- a/tools/versioner/tests/multiple_definition/expected_fail
+++ b/tools/versioner/tests/multiple_definition/expected_fail
@@ -1,7 +1,7 @@
-versioner: conflicting inline definitions:
-  declarations visible in: arm-9 [fob = 32], arm-9 [fob = 64], arm-12 [fob = 32], arm-12 [fob = 64]
-    static definition @ headers/foo.h:1:1
+versioner: conflicting inline definitions for symbol foo:
+  declarations visible in: arm-9 [c, fob = 32], arm-9 [c, fob = 64], arm-12 [c, fob = 32], arm-12 [c, fob = 64], arm-9 [c++, fob = 32], arm-9 [c++, fob = 64], arm-12 [c++, fob = 32], arm-12 [c++, fob = 64]
+    static definition @ headers/foo.h:5:1
       no availability
-    static definition @ headers/bar.h:1:1
+    static definition @ headers/bar.h:5:1
       no availability
 versioner: sanity check failed
diff --git a/tools/versioner/tests/multiple_definition/headers/bar.h b/tools/versioner/tests/multiple_definition/headers/bar.h
index a9d0197..29592c6 100644
--- a/tools/versioner/tests/multiple_definition/headers/bar.h
+++ b/tools/versioner/tests/multiple_definition/headers/bar.h
@@ -1,3 +1,11 @@
+#if defined(__cplusplus)
+extern "C" {
+#endif
+
 static int foo() {
   return 0;
 }
+
+#if defined(__cplusplus)
+}
+#endif
diff --git a/tools/versioner/tests/multiple_definition/headers/foo.h b/tools/versioner/tests/multiple_definition/headers/foo.h
index a9d0197..29592c6 100644
--- a/tools/versioner/tests/multiple_definition/headers/foo.h
+++ b/tools/versioner/tests/multiple_definition/headers/foo.h
@@ -1,3 +1,11 @@
+#if defined(__cplusplus)
+extern "C" {
+#endif
+
 static int foo() {
   return 0;
 }
+
+#if defined(__cplusplus)
+}
+#endif
diff --git a/tools/versioner/tests/multiple_definition_ok/headers/bar.h b/tools/versioner/tests/multiple_definition_ok/headers/bar.h
index c3c87bb..6eced51 100644
--- a/tools/versioner/tests/multiple_definition_ok/headers/bar.h
+++ b/tools/versioner/tests/multiple_definition_ok/headers/bar.h
@@ -1,5 +1,13 @@
+#if defined(__cplusplus)
+extern "C" {
+#endif
+
 #if __ANDROID_API__ == 12
 static int foo() {
   return 0;
 }
 #endif
+
+#if defined(__cplusplus)
+}
+#endif
diff --git a/tools/versioner/tests/multiple_definition_ok/headers/foo.h b/tools/versioner/tests/multiple_definition_ok/headers/foo.h
index 9da9b2a..773d274 100644
--- a/tools/versioner/tests/multiple_definition_ok/headers/foo.h
+++ b/tools/versioner/tests/multiple_definition_ok/headers/foo.h
@@ -1,5 +1,13 @@
+#if defined(__cplusplus)
+extern "C" {
+#endif
+
 #if __ANDROID_API__ == 9
 static int foo() {
   return 0;
 }
 #endif
+
+#if defined(__cplusplus)
+}
+#endif
diff --git a/tools/versioner/tests/obsoleted/headers/foo.h b/tools/versioner/tests/obsoleted/headers/foo.h
index 68f3d43..e9630e5 100644
--- a/tools/versioner/tests/obsoleted/headers/foo.h
+++ b/tools/versioner/tests/obsoleted/headers/foo.h
@@ -1 +1,9 @@
-int foo() __INTRODUCED_IN(9) __REMOVED_IN(11);
\ No newline at end of file
+#if defined(__cplusplus)
+extern "C" {
+#endif
+
+int foo() __INTRODUCED_IN(9) __REMOVED_IN(11);
+
+#if defined(__cplusplus)
+}
+#endif
diff --git a/tools/versioner/tests/preprocessor/expected/foo.h b/tools/versioner/tests/preprocessor/expected/foo.h
index 73947b2..cb719f0 100644
--- a/tools/versioner/tests/preprocessor/expected/foo.h
+++ b/tools/versioner/tests/preprocessor/expected/foo.h
@@ -1,3 +1,7 @@
+#if defined(__cplusplus)
+extern "C" {
+#endif
+
 int always_available();
 
 int also_always_available() __INTRODUCED_IN(9);
@@ -74,3 +78,7 @@
 int future() __INTRODUCED_IN_FUTURE;
 #endif /* __ANDROID_API__ >= __ANDROID_API_FUTURE__ */
 
+
+#if defined(__cplusplus)
+}
+#endif
diff --git a/tools/versioner/tests/preprocessor/headers/foo.h b/tools/versioner/tests/preprocessor/headers/foo.h
index 81c8b4b..2429334 100644
--- a/tools/versioner/tests/preprocessor/headers/foo.h
+++ b/tools/versioner/tests/preprocessor/headers/foo.h
@@ -1,3 +1,7 @@
+#if defined(__cplusplus)
+extern "C" {
+#endif
+
 int always_available();
 
 int also_always_available() __INTRODUCED_IN(9);
@@ -42,3 +46,7 @@
 int group_lp32() __INTRODUCED_IN_ARM(12) __INTRODUCED_IN_X86(12) __INTRODUCED_IN_MIPS(12);
 
 int future() __INTRODUCED_IN_FUTURE;
+
+#if defined(__cplusplus)
+}
+#endif
diff --git a/tools/versioner/tests/preprocessor/run.sh b/tools/versioner/tests/preprocessor/run.sh
index 60e7024..50d9b5c 100644
--- a/tools/versioner/tests/preprocessor/run.sh
+++ b/tools/versioner/tests/preprocessor/run.sh
@@ -4,7 +4,7 @@
   SRC=$1
   DST=$2
   rm -rf $2
-  versioner $1 -i -o $2
+  versioner -a 9 -a 12 -a 13 -a 14 -a 15 $1 -i -o $2
   diff -q -w -B $2 expected
 }
 
diff --git a/tools/versioner/tests/preprocessor_extern_cpp/expected/foo.h b/tools/versioner/tests/preprocessor_extern_cpp/expected/foo.h
new file mode 100644
index 0000000..9b2d122
--- /dev/null
+++ b/tools/versioner/tests/preprocessor_extern_cpp/expected/foo.h
@@ -0,0 +1,27 @@
+#define __RENAME(x) asm(#x)
+
+#if defined(__cplusplus)
+
+#if __ANDROID_API__ >= 24
+extern "C++" const char* strchrnul(const char*, int) __RENAME(strchrnul) __INTRODUCED_IN(24);
+#endif /* __ANDROID_API__ >= 24 */
+
+#endif
+
+#if defined(__cplusplus)
+extern "C" int foo();
+#endif
+
+#if defined(__cplusplus)
+extern "C" {
+#endif
+
+
+#if __ANDROID_API__ >= 24
+char* strchrnul(char*, int) __INTRODUCED_IN(24);
+#endif /* __ANDROID_API__ >= 24 */
+
+
+#if defined(__cplusplus)
+}
+#endif
diff --git a/tools/versioner/tests/preprocessor_extern_cpp/headers/foo.h b/tools/versioner/tests/preprocessor_extern_cpp/headers/foo.h
new file mode 100644
index 0000000..de26d21
--- /dev/null
+++ b/tools/versioner/tests/preprocessor_extern_cpp/headers/foo.h
@@ -0,0 +1,19 @@
+#define __RENAME(x) asm(#x)
+
+#if defined(__cplusplus)
+extern "C++" const char* strchrnul(const char*, int) __RENAME(strchrnul) __INTRODUCED_IN(24);
+#endif
+
+#if defined(__cplusplus)
+extern "C" int foo();
+#endif
+
+#if defined(__cplusplus)
+extern "C" {
+#endif
+
+char* strchrnul(char*, int) __INTRODUCED_IN(24);
+
+#if defined(__cplusplus)
+}
+#endif
diff --git a/tools/versioner/tests/preprocessor_extern_cpp/platforms/android-9/arch-arm/symbols/libc.so.functions.txt b/tools/versioner/tests/preprocessor_extern_cpp/platforms/android-9/arch-arm/symbols/libc.so.functions.txt
new file mode 100644
index 0000000..257cc56
--- /dev/null
+++ b/tools/versioner/tests/preprocessor_extern_cpp/platforms/android-9/arch-arm/symbols/libc.so.functions.txt
@@ -0,0 +1 @@
+foo
diff --git a/tools/versioner/tests/preprocessor_extern_cpp/run.sh b/tools/versioner/tests/preprocessor_extern_cpp/run.sh
new file mode 100644
index 0000000..50d9b5c
--- /dev/null
+++ b/tools/versioner/tests/preprocessor_extern_cpp/run.sh
@@ -0,0 +1,29 @@
+set -e
+
+function run_test {
+  SRC=$1
+  DST=$2
+  rm -rf $2
+  versioner -a 9 -a 12 -a 13 -a 14 -a 15 $1 -i -o $2
+  diff -q -w -B $2 expected
+}
+
+run_test headers out
+run_test headers/ out
+run_test headers out/
+run_test headers/ out/
+
+run_test `pwd`/headers out
+run_test `pwd`/headers/ out
+run_test `pwd`/headers out/
+run_test `pwd`/headers/ out/
+
+run_test headers `pwd`/out
+run_test headers/ `pwd`/out
+run_test headers `pwd`/out/
+run_test headers/ `pwd`/out/
+
+run_test `pwd`/headers `pwd`/out
+run_test `pwd`/headers/ `pwd`/out
+run_test `pwd`/headers `pwd`/out/
+run_test `pwd`/headers/ `pwd`/out/
diff --git a/tools/versioner/tests/preprocessor_file_offset_bits/expected/foo.h b/tools/versioner/tests/preprocessor_file_offset_bits/expected/foo.h
index 7d31ec3..dcfaaee 100644
--- a/tools/versioner/tests/preprocessor_file_offset_bits/expected/foo.h
+++ b/tools/versioner/tests/preprocessor_file_offset_bits/expected/foo.h
@@ -1,3 +1,7 @@
+#if defined(__cplusplus)
+extern "C" {
+#endif
+
 typedef int off_t;
 typedef int ssize_t;
 typedef unsigned size_t;
@@ -32,3 +36,7 @@
 #else
 off_t lseek(int __fd, off_t __offset, int __whence);
 #endif
+
+#if defined(__cplusplus)
+}
+#endif
diff --git a/tools/versioner/tests/preprocessor_file_offset_bits/headers/foo.h b/tools/versioner/tests/preprocessor_file_offset_bits/headers/foo.h
index 868d1fc..5ffffa8 100644
--- a/tools/versioner/tests/preprocessor_file_offset_bits/headers/foo.h
+++ b/tools/versioner/tests/preprocessor_file_offset_bits/headers/foo.h
@@ -1,3 +1,7 @@
+#if defined(__cplusplus)
+extern "C" {
+#endif
+
 typedef int off_t;
 typedef int ssize_t;
 typedef unsigned size_t;
@@ -28,3 +32,7 @@
 #else
 off_t lseek(int __fd, off_t __offset, int __whence);
 #endif
+
+#if defined(__cplusplus)
+}
+#endif
diff --git a/tools/versioner/tests/preprocessor_file_offset_bits/run.sh b/tools/versioner/tests/preprocessor_file_offset_bits/run.sh
index c503867..d974cba 100644
--- a/tools/versioner/tests/preprocessor_file_offset_bits/run.sh
+++ b/tools/versioner/tests/preprocessor_file_offset_bits/run.sh
@@ -1,5 +1,5 @@
 set -e
 
 rm -rf out
-versioner headers -i -o out
+versioner headers -a 9 -a 12 -a 13 -i -o out
 diff -q -w -B out expected
diff --git a/tools/versioner/tests/preprocessor_idempotence/expected/foo.h b/tools/versioner/tests/preprocessor_idempotence/expected/foo.h
index ed31e8b..bc442e5 100644
--- a/tools/versioner/tests/preprocessor_idempotence/expected/foo.h
+++ b/tools/versioner/tests/preprocessor_idempotence/expected/foo.h
@@ -1,3 +1,7 @@
+#if defined(__cplusplus)
+extern "C" {
+#endif
+
 #if __ANDROID_API__ >= 10
 int foo() __INTRODUCED_IN(10);
 #endif
@@ -10,3 +14,7 @@
 int multiple_1() __INTRODUCED_IN(10);
 int multiple_2() __INTRODUCED_IN(10);
 #endif
+
+#if defined(__cplusplus)
+}
+#endif
diff --git a/tools/versioner/tests/preprocessor_idempotence/headers/foo.h b/tools/versioner/tests/preprocessor_idempotence/headers/foo.h
index ed31e8b..bc442e5 100644
--- a/tools/versioner/tests/preprocessor_idempotence/headers/foo.h
+++ b/tools/versioner/tests/preprocessor_idempotence/headers/foo.h
@@ -1,3 +1,7 @@
+#if defined(__cplusplus)
+extern "C" {
+#endif
+
 #if __ANDROID_API__ >= 10
 int foo() __INTRODUCED_IN(10);
 #endif
@@ -10,3 +14,7 @@
 int multiple_1() __INTRODUCED_IN(10);
 int multiple_2() __INTRODUCED_IN(10);
 #endif
+
+#if defined(__cplusplus)
+}
+#endif
diff --git a/tools/versioner/tests/preprocessor_merging/expected/foo.h b/tools/versioner/tests/preprocessor_merging/expected/foo.h
index 45eb32d..ecd7f71 100644
--- a/tools/versioner/tests/preprocessor_merging/expected/foo.h
+++ b/tools/versioner/tests/preprocessor_merging/expected/foo.h
@@ -1,3 +1,7 @@
+#if defined(__cplusplus)
+extern "C" {
+#endif
+
 
 #if __ANDROID_API__ >= 10
 int block_merging_1() __INTRODUCED_IN(10); // foo
@@ -7,3 +11,7 @@
 int block_merging_4() __INTRODUCED_IN(10);
 #endif /* __ANDROID_API__ >= 10 */
 
+
+#if defined(__cplusplus)
+}
+#endif
diff --git a/tools/versioner/tests/preprocessor_merging/headers/foo.h b/tools/versioner/tests/preprocessor_merging/headers/foo.h
index ac9564b..7aaa471 100644
--- a/tools/versioner/tests/preprocessor_merging/headers/foo.h
+++ b/tools/versioner/tests/preprocessor_merging/headers/foo.h
@@ -1,5 +1,13 @@
+#if defined(__cplusplus)
+extern "C" {
+#endif
+
 int block_merging_1() __INTRODUCED_IN(10); // foo
 int block_merging_2() __INTRODUCED_IN(10); /* bar */
 int block_merging_3() __INTRODUCED_IN(10); /* baz
 //*/
 int block_merging_4() __INTRODUCED_IN(10);
+
+#if defined(__cplusplus)
+}
+#endif
diff --git a/tools/versioner/tests/preprocessor_merging/run.sh b/tools/versioner/tests/preprocessor_merging/run.sh
index 1b0aae2..1929757 100644
--- a/tools/versioner/tests/preprocessor_merging/run.sh
+++ b/tools/versioner/tests/preprocessor_merging/run.sh
@@ -1,4 +1,4 @@
 rm -rf out
 set -e
-versioner headers -i -o out
+versioner headers -a 9 -a 10 -a 11 -i -o out
 diff -q -w -B out expected
diff --git a/tools/versioner/tests/preprocessor_no_guard/expected/foo.h b/tools/versioner/tests/preprocessor_no_guard/expected/foo.h
index 2bf1dbf..3ef0c30 100644
--- a/tools/versioner/tests/preprocessor_no_guard/expected/foo.h
+++ b/tools/versioner/tests/preprocessor_no_guard/expected/foo.h
@@ -1 +1,9 @@
+#if defined(__cplusplus)
+extern "C" {
+#endif
+
 int foo() __VERSIONER_NO_GUARD __INTRODUCED_IN(14);
+
+#if defined(__cplusplus)
+}
+#endif
diff --git a/tools/versioner/tests/preprocessor_no_guard/headers/foo.h b/tools/versioner/tests/preprocessor_no_guard/headers/foo.h
index 2bf1dbf..3ef0c30 100644
--- a/tools/versioner/tests/preprocessor_no_guard/headers/foo.h
+++ b/tools/versioner/tests/preprocessor_no_guard/headers/foo.h
@@ -1 +1,9 @@
+#if defined(__cplusplus)
+extern "C" {
+#endif
+
 int foo() __VERSIONER_NO_GUARD __INTRODUCED_IN(14);
+
+#if defined(__cplusplus)
+}
+#endif
diff --git a/tools/versioner/tests/smoke/headers/foo.h b/tools/versioner/tests/smoke/headers/foo.h
index 3ff3ff7..c201dbb 100644
--- a/tools/versioner/tests/smoke/headers/foo.h
+++ b/tools/versioner/tests/smoke/headers/foo.h
@@ -1 +1,9 @@
-int foo() __INTRODUCED_IN(9);
\ No newline at end of file
+#if defined(__cplusplus)
+extern "C" {
+#endif
+
+int foo() __INTRODUCED_IN(9);
+
+#if defined(__cplusplus)
+}
+#endif
diff --git a/tools/versioner/tests/unnamed_bitfield/headers/foo.h b/tools/versioner/tests/unnamed_bitfield/headers/foo.h
new file mode 100644
index 0000000..58686c3
--- /dev/null
+++ b/tools/versioner/tests/unnamed_bitfield/headers/foo.h
@@ -0,0 +1,8 @@
+// <sys/timex.h> was causing a segfault when compiled in C++ mode because
+// versioner was trying to mangle the name of an unnamed bitfield.
+struct foo {
+  int : 32;
+  int : 32;
+  int : 32;
+  int : 32;
+};
diff --git a/tools/versioner/tests/unnamed_bitfield/platforms/android-9/arch-arm/symbols/libc.so.functions.txt b/tools/versioner/tests/unnamed_bitfield/platforms/android-9/arch-arm/symbols/libc.so.functions.txt
new file mode 100644
index 0000000..257cc56
--- /dev/null
+++ b/tools/versioner/tests/unnamed_bitfield/platforms/android-9/arch-arm/symbols/libc.so.functions.txt
@@ -0,0 +1 @@
+foo
diff --git a/tools/versioner/tests/unnamed_bitfield/run.sh b/tools/versioner/tests/unnamed_bitfield/run.sh
new file mode 100644
index 0000000..a34fda8
--- /dev/null
+++ b/tools/versioner/tests/unnamed_bitfield/run.sh
@@ -0,0 +1 @@
+versioner headers -p platforms -r arm -a 9 -i
\ No newline at end of file
diff --git a/tools/versioner/tests/version_mismatch/expected_fail b/tools/versioner/tests/version_mismatch/expected_fail
index f83f71c..f2143a3 100644
--- a/tools/versioner/tests/version_mismatch/expected_fail
+++ b/tools/versioner/tests/version_mismatch/expected_fail
@@ -1,8 +1,8 @@
 versioner: inconsistent availability for symbol 'foo'
 versioner: failed to calculate symbol availability
   foo: invalid
-    extern declaration @ headers/foo.h:2:1
+    extern declaration @ headers/foo.h:6:1
       introduced = 9
-    extern declaration @ headers/foo.h:4:1
+    extern declaration @ headers/foo.h:8:1
       introduced = 10
 versioner: sanity check failed
diff --git a/tools/versioner/tests/version_mismatch/headers/foo.h b/tools/versioner/tests/version_mismatch/headers/foo.h
index 4604092..ea35f36 100644
--- a/tools/versioner/tests/version_mismatch/headers/foo.h
+++ b/tools/versioner/tests/version_mismatch/headers/foo.h
@@ -1,5 +1,13 @@
+#if defined(__cplusplus)
+extern "C" {
+#endif
+
 #if __ANDROID_API__ <= 9
 int foo() __INTRODUCED_IN(9);
 #else
 int foo() __INTRODUCED_IN(10);
 #endif
+
+#if defined(__cplusplus)
+}
+#endif