Update timezone data to 2016f am: 88d23859e0 am: 6c4968a6e7
am: a884aa8df7

Change-Id: I84612c410e4fea54733ed340b6a6695771bba4d9
diff --git a/.clang-format b/.clang-format
new file mode 100644
index 0000000..9b7478c
--- /dev/null
+++ b/.clang-format
@@ -0,0 +1,15 @@
+BasedOnStyle: Google
+AllowShortBlocksOnASingleLine: false
+AllowShortFunctionsOnASingleLine: false
+
+ColumnLimit: 100
+CommentPragmas: NOLINT:.*
+DerivePointerAlignment: false
+IndentWidth: 2
+ContinuationIndentWidth: 2
+PointerAlignment: Left
+TabWidth: 2
+UseTab: Never
+PenaltyExcessCharacter: 32
+
+Cpp11BracedListStyle: false
diff --git a/Android.mk b/Android.mk
index 7c39751..9f0f0c3 100644
--- a/Android.mk
+++ b/Android.mk
@@ -16,4 +16,5 @@
 
 LOCAL_PATH := $(call my-dir)
 
-include $(call all-subdir-makefiles)
+include $(call all-makefiles-under,$(LOCAL_PATH)) \
+	$(call all-makefiles-under,$(LOCAL_PATH)/libc)
diff --git a/CleanSpec.mk b/CleanSpec.mk
index 841ad16..9421e26 100644
--- a/CleanSpec.mk
+++ b/CleanSpec.mk
@@ -48,6 +48,11 @@
 $(call add-clean-step, rm -rf $(PRODUCT_OUT)/obj/STATIC_LIBRARIES/libc_*)
 $(call add-clean-step, rm -rf $(PRODUCT_OUT)/obj/SHARED_LIBRARIES/libc_*)
 
+# Required due to the replacement of a symlink with a shared library
+# (commit b952f42bef69e5c in frameworks/native).
+$(call add-clean-step, rm -f $(PRODUCT_OUT)/system/lib/libGLES*)
+$(call add-clean-step, rm -f $(PRODUCT_OUT)/system/lib64/libGLES*)
+
 # ************************************************
 # NEWER CLEAN STEPS MUST BE AT THE END OF THE LIST
 # ************************************************
diff --git a/README.md b/README.md
index 79bb72a..c6b9278 100644
--- a/README.md
+++ b/README.md
@@ -96,7 +96,6 @@
   dns/
     # Contains the DNS resolver (originates from NetBSD code).
 
-  upstream-dlmalloc/
   upstream-freebsd/
   upstream-netbsd/
   upstream-openbsd/
@@ -119,6 +118,10 @@
     # current upstream source in one of the upstream directories or by
     # switching the file to C++ and cleaning it up.
 
+  malloc_debug/
+    # The code that implements the functionality to enable debugging of
+    # native allocation problems.
+
   stdio/
     # These are legacy files of dubious provenance. We're working to clean
     # this mess up, and this directory should disappear.
@@ -169,9 +172,10 @@
 Updating tzdata
 ---------------
 
-This is fully automated:
+This is fully automated (and these days handled by the libcore team, because
+they own icu, and that needs to be updated in sync with bionic):
 
-  1. Run update-tzdata.py.
+  1. Run update-tzdata.py in external/icu/tools/.
 
 
 Verifying changes
@@ -194,14 +198,15 @@
 ### Device tests
 
     $ mma
+    $ adb remount
     $ adb sync
     $ adb shell /data/nativetest/bionic-unit-tests/bionic-unit-tests32
     $ adb shell \
         /data/nativetest/bionic-unit-tests-static/bionic-unit-tests-static32
     # Only for 64-bit targets
-    $ adb shell /data/nativetest/bionic-unit-tests/bionic-unit-tests64
+    $ adb shell /data/nativetest64/bionic-unit-tests/bionic-unit-tests64
     $ adb shell \
-        /data/nativetest/bionic-unit-tests-static/bionic-unit-tests-static64
+        /data/nativetest64/bionic-unit-tests-static/bionic-unit-tests-static64
 
 ### Host tests
 
@@ -256,18 +261,33 @@
 The coverage report is now available at `covreport/index.html`.
 
 
-LP32 ABI bugs
--------------
+Attaching GDB to the tests
+--------------------------
+
+Bionic's test runner will run each test in its own process by default to prevent
+tests failures from impacting other tests. This also has the added benefit of
+running them in parallel, so they are much faster.
+
+However, this also makes it difficult to run the tests under GDB. To prevent
+each test from being forked, run the tests with the flag `--no-isolate`.
+
+
+32-bit ABI bugs
+---------------
 
 This probably belongs in the NDK documentation rather than here, but these
-are the known ABI bugs in LP32:
+are the known ABI bugs in the 32-bit ABI:
 
- * `time_t` is 32-bit. <http://b/5819737>
+ * `time_t` is 32-bit. <http://b/5819737>. In the 64-bit ABI, time_t is
+   64-bit.
 
- * `off_t` is 32-bit. There is `off64_t`, but no `_FILE_OFFSET_BITS` support.
-   Many of the `off64_t` functions are missing in older releases, and
-   stdio uses 32-bit offsets, so there's no way to fully implement
-   `_FILE_OFFSET_BITS`.
+ * `off_t` is 32-bit. There is `off64_t`, and in newer releases there is
+   almost-complete support for `_FILE_OFFSET_BITS`. Unfortunately our stdio
+   implementation uses 32-bit offsets and -- worse -- function pointers to
+   functions that use 32-bit offsets, so there's no good way to implement
+   the last few pieces <http://b/24807045>. In the 64-bit ABI, off_t is
+   off64_t.
 
  * `sigset_t` is too small on ARM and x86 (but correct on MIPS), so support
-   for real-time signals is broken. <http://b/5828899>
+   for real-time signals is broken. <http://b/5828899> In the 64-bit ABI,
+   `sigset_t` is the correct size for every architecture.
diff --git a/benchmarks/Android.mk b/benchmarks/Android.mk
index e1580fe..6f2651e 100644
--- a/benchmarks/Android.mk
+++ b/benchmarks/Android.mk
@@ -16,10 +16,6 @@
 
 LOCAL_PATH := $(call my-dir)
 
-# -----------------------------------------------------------------------------
-# Benchmarks library, usable by projects outside this directory.
-# -----------------------------------------------------------------------------
-
 benchmark_cflags := \
     -O2 \
     -fno-builtin \
@@ -29,40 +25,7 @@
     -Wunused \
 
 benchmark_cppflags := \
-    -std=gnu++11 \
 
-benchmarklib_src_files := \
-    Benchmark.cpp \
-    utils.cpp \
-    main.cpp \
-
-include $(CLEAR_VARS)
-LOCAL_MODULE := libbenchmark
-LOCAL_CFLAGS := $(benchmark_cflags)
-LOCAL_CPPFLAGS := $(benchmark_cppflags)
-LOCAL_SRC_FILES := $(benchmarklib_src_files)
-LOCAL_C_INCLUDES := $(benchmark_c_includes)
-LOCAL_STATIC_LIBRARIES := libbase
-include $(BUILD_STATIC_LIBRARY)
-
-# Only supported on linux systems.
-ifeq ($(HOST_OS),linux)
-
-include $(CLEAR_VARS)
-LOCAL_MODULE := libbenchmark
-LOCAL_CFLAGS := $(benchmark_cflags)
-LOCAL_CPPFLAGS := $(benchmark_cppflags)
-LOCAL_SRC_FILES := $(benchmarklib_src_files)
-LOCAL_C_INCLUDES := $(benchmark_c_includes)
-LOCAL_MULTILIB := both
-LOCAL_STATIC_LIBRARIES := libbase
-include $(BUILD_HOST_STATIC_LIBRARY)
-
-endif
-
-# -----------------------------------------------------------------------------
-# Benchmarks.
-# -----------------------------------------------------------------------------
 benchmark_src_files := \
     math_benchmark.cpp \
     property_benchmark.cpp \
@@ -84,8 +47,7 @@
 LOCAL_CFLAGS := $(benchmark_cflags)
 LOCAL_CPPFLAGS := $(benchmark_cppflags)
 LOCAL_SRC_FILES := $(benchmark_src_files)
-LOCAL_STATIC_LIBRARIES := libbenchmark libbase
-include $(BUILD_EXECUTABLE)
+include $(BUILD_NATIVE_BENCHMARK)
 
 # We don't build a static benchmark executable because it's not usually
 # useful. If you're trying to run the current benchmarks on an older
@@ -106,7 +68,8 @@
 LOCAL_CPPFLAGS := $(benchmark_cppflags)
 LOCAL_LDFLAGS := -lrt
 LOCAL_SRC_FILES := $(benchmark_src_files)
-LOCAL_STATIC_LIBRARIES := libbenchmark libbase
+LOCAL_STATIC_LIBRARIES := libgoogle-benchmark
+# TODO: BUILD_HOST_NATIVE_BENCHMARK
 include $(BUILD_HOST_EXECUTABLE)
 
 endif
diff --git a/benchmarks/Benchmark.cpp b/benchmarks/Benchmark.cpp
deleted file mode 100644
index ea6000fe..0000000
--- a/benchmarks/Benchmark.cpp
+++ /dev/null
@@ -1,159 +0,0 @@
-/*
- * Copyright (C) 2012 The Android Open Source Project
- *
- * Licensed under the Apache License, Version 2.0 (the "License");
- * you may not use this file except in compliance with the License.
- * You may obtain a copy of the License at
- *
- *      http://www.apache.org/licenses/LICENSE-2.0
- *
- * Unless required by applicable law or agreed to in writing, software
- * distributed under the License is distributed on an "AS IS" BASIS,
- * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
- * See the License for the specific language governing permissions and
- * limitations under the License.
- */
-
-#include <inttypes.h>
-#include <regex.h>
-#include <stdio.h>
-#include <stdint.h>
-#include <stdlib.h>
-#include <time.h>
-
-#include <string>
-#include <vector>
-
-#include <base/stringprintf.h>
-
-#include <benchmark/Benchmark.h>
-
-#include "utils.h"
-
-namespace testing {
-
-static uint64_t NanoTime() {
-  struct timespec t;
-  t.tv_sec = t.tv_nsec = 0;
-  clock_gettime(CLOCK_MONOTONIC, &t);
-  return static_cast<uint64_t>(t.tv_sec) * 1000000000LL + t.tv_nsec;
-}
-
-bool Benchmark::header_printed_;
-
-std::vector<Benchmark*>& Benchmark::List() {
-  static std::vector<Benchmark*> list;
-  return list;
-}
-
-int Benchmark::MaxNameColumnWidth() {
-  size_t max = 20;
-  for (auto& benchmark : List()) {
-    max = std::max(max, benchmark->NameColumnWidth());
-  }
-  return static_cast<int>(max);
-}
-
-size_t Benchmark::RunAll(std::vector<regex_t*>& regs) {
-  size_t benchmarks_run = 0;
-  header_printed_ = false;
-  for (auto& benchmark : List()) {
-    benchmarks_run += benchmark->RunAllArgs(regs);
-  }
-  return benchmarks_run;
-}
-
-void Benchmark::PrintHeader() {
-  if (!header_printed_) {
-    printf("%-*s %10s %10s\n", MaxNameColumnWidth(), "", "iterations", "ns/op");
-    header_printed_ = true;
-  }
-}
-
-template <typename T>
-bool BenchmarkT<T>::ShouldRun(std::vector<regex_t*>& regs, T arg) {
-  if (regs.empty()) {
-    return true;
-  }
-
-  for (const auto& re : regs) {
-    if (regexec(re, GetNameStr(arg).c_str(), 0, NULL, 0) != REG_NOMATCH) {
-      return true;
-    }
-  }
-  return false;
-}
-
-void Benchmark::StopBenchmarkTiming() {
-  if (start_time_ns_ != 0) {
-    total_time_ns_ += NanoTime() - start_time_ns_;
-  }
-  start_time_ns_ = 0;
-}
-
-void Benchmark::StartBenchmarkTiming() {
-  if (start_time_ns_ == 0) {
-    start_time_ns_ = NanoTime();
-  }
-}
-
-std::string BenchmarkWithoutArg::GetNameStr(void*) {
-  return Name();
-}
-
-template <>
-std::string BenchmarkWithArg<int>::GetNameStr(int arg) {
-  return Name() + "/" + PrettyInt(arg, 2);
-}
-
-template <>
-std::string BenchmarkWithArg<double>::GetNameStr(double arg) {
-  return Name() + "/" + android::base::StringPrintf("%0.6f", arg);
-}
-
-template<typename T>
-void BenchmarkT<T>::RunWithArg(T arg) {
-  int new_iterations = 1;
-  int iterations;
-  while (new_iterations < 1e8) {
-    bytes_processed_ = 0;
-    total_time_ns_ = 0;
-    start_time_ns_ = 0;
-
-    iterations = new_iterations;
-    RunIterations(iterations, arg);
-    if (total_time_ns_ >= 1e9) {
-      break;
-    }
-
-    if (total_time_ns_/iterations == 0) {
-      new_iterations = 1e9;
-    } else {
-      new_iterations = 1e9/ (total_time_ns_/iterations);
-    }
-    new_iterations = std::max(iterations + 1,
-                          std::min(new_iterations + new_iterations/2, 100*iterations));
-
-    new_iterations = Round(new_iterations);
-  }
-
-  printf("%-*s %10s %10" PRId64, MaxNameColumnWidth(), GetNameStr(arg).c_str(),
-         PrettyInt(iterations, 10).c_str(), total_time_ns_/iterations);
-
-  if (total_time_ns_ > 0 && bytes_processed_ > 0) {
-    double gib_processed = static_cast<double>(bytes_processed_)/1e9;
-    double seconds = static_cast<double>(total_time_ns_)/1e9;
-    printf(" %8.3f GiB/s", gib_processed/seconds);
-  }
-  printf("\n");
-  fflush(stdout);
-}
-
-template class BenchmarkT<int>;
-template class BenchmarkT<double>;
-template class BenchmarkT<void*>;
-
-template class BenchmarkWithArg<int>;
-template class BenchmarkWithArg<double>;
-
-}  // namespace testing
diff --git a/benchmarks/benchmark/Benchmark.h b/benchmarks/benchmark/Benchmark.h
deleted file mode 100644
index ae5c1a2..0000000
--- a/benchmarks/benchmark/Benchmark.h
+++ /dev/null
@@ -1,169 +0,0 @@
-/*
- * Copyright (C) 2012 The Android Open Source Project
- *
- * Licensed under the Apache License, Version 2.0 (the "License");
- * you may not use this file except in compliance with the License.
- * You may obtain a copy of the License at
- *
- *      http://www.apache.org/licenses/LICENSE-2.0
- *
- * Unless required by applicable law or agreed to in writing, software
- * distributed under the License is distributed on an "AS IS" BASIS,
- * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
- * See the License for the specific language governing permissions and
- * limitations under the License.
- */
-
-#ifndef BENCHMARKS_BENCHMARK_H_
-#define BENCHMARKS_BENCHMARK_H_
-
-#include <regex.h>
-#include <stdint.h>
-
-#include <string>
-#include <vector>
-
-namespace testing {
-
-class Benchmark {
-public:
-  Benchmark() {
-    List().push_back(this);
-  }
-  virtual ~Benchmark() {}
-
-  virtual std::string Name() = 0;
-
-  virtual size_t RunAllArgs(std::vector<regex_t*>&) = 0;
-
-  void SetBenchmarkBytesProcessed(uint64_t bytes) { bytes_processed_ += bytes; }
-  void StopBenchmarkTiming();
-  void StartBenchmarkTiming();
-
-  // Run all of the benchmarks that have registered.
-  static size_t RunAll(std::vector<regex_t*>&);
-
-  static std::vector<Benchmark*>& List();
-
-  static int MaxNameColumnWidth();
-
-protected:
-  virtual size_t NameColumnWidth() = 0;
-
-  uint64_t bytes_processed_;
-  uint64_t total_time_ns_;
-  uint64_t start_time_ns_;
-
-  static bool header_printed_;
-
-  static void PrintHeader();
-};
-
-template <typename T>
-class BenchmarkT : public Benchmark {
-public:
-  BenchmarkT() {}
-  virtual ~BenchmarkT() {}
-
-protected:
-  bool ShouldRun(std::vector<regex_t*>&, T arg);
-  void RunWithArg(T arg);
-  virtual void RunIterations(int, T) = 0;
-  virtual std::string GetNameStr(T) = 0;
-};
-
-class BenchmarkWithoutArg : public BenchmarkT<void*> {
-public:
-  BenchmarkWithoutArg() {}
-  virtual ~BenchmarkWithoutArg() {}
-
-protected:
-  virtual size_t RunAllArgs(std::vector<regex_t*>& regs) override {
-    size_t benchmarks_run = 0;
-    if (BenchmarkT<void*>::ShouldRun(regs, nullptr)) {
-      PrintHeader();
-      RunWithArg(nullptr);
-      benchmarks_run++;
-    }
-    return benchmarks_run;
-  }
-
-  virtual void RunIterations(int iters, void*) override {
-    Run(iters);
-  }
-
-  virtual void Run(int) = 0;
-
-  virtual size_t NameColumnWidth() override {
-    return Name().size();
-  }
-
-  virtual std::string GetNameStr(void *) override;
-};
-
-template<typename T>
-class BenchmarkWithArg : public BenchmarkT<T> {
-public:
-  BenchmarkWithArg() {}
-  virtual ~BenchmarkWithArg() {}
-
-  BenchmarkWithArg* Arg(T arg) {
-    args_.push_back(arg);
-    return this;
-  }
-
-protected:
-  virtual size_t NameColumnWidth() override {
-    size_t max = 0;
-    for (const auto& arg : args_) {
-      max = std::max(max, GetNameStr(arg).size());
-    }
-    return max;
-  }
-
-  std::string GetNameStr(T arg) override;
-
-  virtual size_t RunAllArgs(std::vector<regex_t*>& regs) override {
-    size_t benchmarks_run = 0;
-    for (T& arg : args_) {
-      if (BenchmarkT<T>::ShouldRun(regs, arg)) {
-        Benchmark::PrintHeader();
-        BenchmarkT<T>::RunWithArg(arg);
-        benchmarks_run++;
-      }
-    }
-    return benchmarks_run;
-  }
-
-  virtual void RunIterations(int iters, T arg) override {
-    Run(iters, arg);
-  }
-
-  virtual void Run(int iters, T arg) = 0;
-
-private:
-  std::vector<T> args_;
-};
-
-}  // namespace testing
-
-#define BENCHMARK_START(f, super_class) \
-  class f : public super_class { \
-  public: \
-    f() {} \
-    virtual ~f() {} \
-    virtual std::string Name() override { return #f; } \
-
-#define BENCHMARK_NO_ARG(f) \
-  BENCHMARK_START(f, ::testing::BenchmarkWithoutArg) \
-    virtual void Run(int) override; \
-  }; \
-  static ::testing::Benchmark* __benchmark_##f = new f()
-
-#define BENCHMARK_WITH_ARG(f, arg_type) \
-  BENCHMARK_START(f, ::testing::BenchmarkWithArg<arg_type>) \
-    virtual void Run(int, arg_type) override; \
-  }; \
-  static ::testing::BenchmarkWithArg<arg_type>* __benchmark_##f = (new f())
-
-#endif  // BENCHMARKS_BENCHMARK_H_
diff --git a/benchmarks/main.cpp b/benchmarks/main.cpp
deleted file mode 100644
index 5bce479..0000000
--- a/benchmarks/main.cpp
+++ /dev/null
@@ -1,61 +0,0 @@
-/*
- * Copyright (C) 2012 The Android Open Source Project
- *
- * Licensed under the Apache License, Version 2.0 (the "License");
- * you may not use this file except in compliance with the License.
- * You may obtain a copy of the License at
- *
- *      http://www.apache.org/licenses/LICENSE-2.0
- *
- * Unless required by applicable law or agreed to in writing, software
- * distributed under the License is distributed on an "AS IS" BASIS,
- * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
- * See the License for the specific language governing permissions and
- * limitations under the License.
- */
-
-
-#include <regex.h>
-#include <stdio.h>
-#include <stdlib.h>
-
-#include <vector>
-
-#include <benchmark/Benchmark.h>
-
-int main(int argc, char* argv[]) {
-  if (::testing::Benchmark::List().empty()) {
-    fprintf(stderr, "No benchmarks registered!\n");
-    exit(EXIT_FAILURE);
-  }
-
-  std::vector<regex_t*> regs;
-  for (int i = 1; i < argc; i++) {
-    regex_t* re = new regex_t;
-    int errcode = regcomp(re, argv[i], 0);
-    if (errcode != 0) {
-      size_t errbuf_size = regerror(errcode, re, NULL, 0);
-      if (errbuf_size > 0) {
-        char* errbuf = new char[errbuf_size];
-        regerror(errcode, re, errbuf, errbuf_size);
-        fprintf(stderr, "Couldn't compile \"%s\" as a regular expression: %s\n",
-                argv[i], errbuf);
-      } else {
-        fprintf(stderr, "Unknown compile error for \"%s\" as a regular expression!\n", argv[i]);
-      }
-      exit(EXIT_FAILURE);
-    }
-    regs.push_back(re);
-  }
-
-  if (::testing::Benchmark::RunAll(regs) == 0) {
-    fprintf(stderr, "No matching benchmarks!\n");
-    fprintf(stderr, "Available benchmarks:\n");
-    for (const auto& benchmark : ::testing::Benchmark::List()) {
-      fprintf(stderr, "  %s\n", benchmark->Name().c_str());
-    }
-    exit(EXIT_FAILURE);
-  }
-
-  return 0;
-}
diff --git a/benchmarks/math_benchmark.cpp b/benchmarks/math_benchmark.cpp
index 4de28d1..36ac301 100644
--- a/benchmarks/math_benchmark.cpp
+++ b/benchmarks/math_benchmark.cpp
@@ -17,120 +17,213 @@
 #include <fenv.h>
 #include <math.h>
 
-#include <benchmark/Benchmark.h>
+#include <benchmark/benchmark.h>
 
-#define AT_COMMON_VALS \
-    Arg(1234.0)->Arg(nan(""))->Arg(HUGE_VAL)->Arg(0.0)
+static const double values[] = { 1234.0, nan(""), HUGE_VAL, 0.0 };
+static const char* names[] = { "1234.0", "nan", "HUGE_VAL", "0.0" };
+
+#define BENCHMARK_COMMON_VALS(name) BENCHMARK(name)->Arg(0)->Arg(1)->Arg(2)->Arg(3)
+
+static void SetLabel(benchmark::State& state) {
+  state.SetLabel(names[state.range_x()]);
+}
 
 // Avoid optimization.
 volatile double d;
 volatile double v;
 
-BENCHMARK_NO_ARG(BM_math_sqrt);
-void BM_math_sqrt::Run(int iters) {
-  StartBenchmarkTiming();
-
+static void BM_math_sqrt(benchmark::State& state) {
   d = 0.0;
   v = 2.0;
-  for (int i = 0; i < iters; ++i) {
+  while (state.KeepRunning()) {
     d += sqrt(v);
   }
-
-  StopBenchmarkTiming();
 }
+BENCHMARK(BM_math_sqrt);
 
-BENCHMARK_NO_ARG(BM_math_log10);
-void BM_math_log10::Run(int iters) {
-  StartBenchmarkTiming();
-
+static void BM_math_log10(benchmark::State& state) {
   d = 0.0;
   v = 1234.0;
-  for (int i = 0; i < iters; ++i) {
+  while (state.KeepRunning()) {
     d += log10(v);
   }
-
-  StopBenchmarkTiming();
 }
+BENCHMARK(BM_math_log10);
 
-BENCHMARK_NO_ARG(BM_math_logb);
-void BM_math_logb::Run(int iters) {
-  StartBenchmarkTiming();
-
+static void BM_math_logb(benchmark::State& state) {
   d = 0.0;
   v = 1234.0;
-  for (int i = 0; i < iters; ++i) {
+  while (state.KeepRunning()) {
     d += logb(v);
   }
-
-  StopBenchmarkTiming();
 }
+BENCHMARK(BM_math_logb);
 
-BENCHMARK_WITH_ARG(BM_math_isinf, double)->AT_COMMON_VALS;
-void BM_math_isinf::Run(int iters, double value) {
-  StartBenchmarkTiming();
-
+static void BM_math_isfinite_macro(benchmark::State& state) {
   d = 0.0;
-  v = value;
-  for (int i = 0; i < iters; ++i) {
+  v = values[state.range_x()];
+  while (state.KeepRunning()) {
+    d += isfinite(v);
+  }
+  SetLabel(state);
+}
+BENCHMARK_COMMON_VALS(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_x()];
+  while (state.KeepRunning()) {
+    d += test_isfinite(v);
+  }
+  SetLabel(state);
+}
+BENCHMARK_COMMON_VALS(BM_math_isfinite);
+
+static void BM_math_isinf_macro(benchmark::State& state) {
+  d = 0.0;
+  v = values[state.range_x()];
+  while (state.KeepRunning()) {
+    d += isinf(v);
+  }
+  SetLabel(state);
+}
+BENCHMARK_COMMON_VALS(BM_math_isinf_macro);
+
+static void BM_math_isinf(benchmark::State& state) {
+  d = 0.0;
+  v = values[state.range_x()];
+  while (state.KeepRunning()) {
     d += (isinf)(v);
   }
-
-  StopBenchmarkTiming();
+  SetLabel(state);
 }
+BENCHMARK_COMMON_VALS(BM_math_isinf);
 
-BENCHMARK_NO_ARG(BM_math_sin_fast);
-void BM_math_sin_fast::Run(int iters) {
-  StartBenchmarkTiming();
+static void BM_math_isnan_macro(benchmark::State& state) {
+  d = 0.0;
+  v = values[state.range_x()];
+  while (state.KeepRunning()) {
+    d += isnan(v);
+  }
+  SetLabel(state);
+}
+BENCHMARK_COMMON_VALS(BM_math_isnan_macro);
 
+static void BM_math_isnan(benchmark::State& state) {
+  d = 0.0;
+  v = values[state.range_x()];
+  while (state.KeepRunning()) {
+    d += (isnan)(v);
+  }
+  SetLabel(state);
+}
+BENCHMARK_COMMON_VALS(BM_math_isnan);
+
+static void BM_math_isnormal_macro(benchmark::State& state) {
+  d = 0.0;
+  v = values[state.range_x()];
+  while (state.KeepRunning()) {
+    d += isnormal(v);
+  }
+  SetLabel(state);
+}
+BENCHMARK_COMMON_VALS(BM_math_isnormal_macro);
+
+#if defined(__BIONIC__)
+static void BM_math_isnormal(benchmark::State& state) {
+  d = 0.0;
+  v = values[state.range_x()];
+  while (state.KeepRunning()) {
+    d += (__isnormal)(v);
+  }
+  SetLabel(state);
+}
+BENCHMARK_COMMON_VALS(BM_math_isnormal);
+#endif
+
+static void BM_math_sin_fast(benchmark::State& state) {
   d = 1.0;
-  for (int i = 0; i < iters; ++i) {
+  while (state.KeepRunning()) {
     d += sin(d);
   }
-
-  StopBenchmarkTiming();
 }
+BENCHMARK(BM_math_sin_fast);
 
-BENCHMARK_NO_ARG(BM_math_sin_feupdateenv);
-void BM_math_sin_feupdateenv::Run(int iters) {
-  StartBenchmarkTiming();
-
+static void BM_math_sin_feupdateenv(benchmark::State& state) {
   d = 1.0;
-  for (int i = 0; i < iters; ++i) {
+  while (state.KeepRunning()) {
     fenv_t __libc_save_rm;
     feholdexcept(&__libc_save_rm);
     fesetround(FE_TONEAREST);
     d += sin(d);
     feupdateenv(&__libc_save_rm);
   }
-
-  StopBenchmarkTiming();
 }
+BENCHMARK(BM_math_sin_feupdateenv);
 
-BENCHMARK_NO_ARG(BM_math_sin_fesetenv);
-void BM_math_sin_fesetenv::Run(int iters) {
-  StartBenchmarkTiming();
-
+static void BM_math_sin_fesetenv(benchmark::State& state) {
   d = 1.0;
-  for (int i = 0; i < iters; ++i) {
+  while (state.KeepRunning()) {
     fenv_t __libc_save_rm;
     feholdexcept(&__libc_save_rm);
     fesetround(FE_TONEAREST);
     d += sin(d);
     fesetenv(&__libc_save_rm);
   }
-
-  StopBenchmarkTiming();
 }
+BENCHMARK(BM_math_sin_fesetenv);
 
-BENCHMARK_WITH_ARG(BM_math_fpclassify, double)->AT_COMMON_VALS;
-void BM_math_fpclassify::Run(int iters, double value) {
-  StartBenchmarkTiming();
-
+static void BM_math_fpclassify(benchmark::State& state) {
   d = 0.0;
-  v = value;
-  for (int i = 0; i < iters; ++i) {
+  v = values[state.range_x()];
+  while (state.KeepRunning()) {
     d += fpclassify(v);
   }
-
-  StopBenchmarkTiming();
+  SetLabel(state);
 }
+BENCHMARK_COMMON_VALS(BM_math_fpclassify);
+
+static void BM_math_signbit_macro(benchmark::State& state) {
+  d = 0.0;
+  v = values[state.range_x()];
+  while (state.KeepRunning()) {
+    d += signbit(v);
+  }
+  SetLabel(state);
+}
+BENCHMARK_COMMON_VALS(BM_math_signbit_macro);
+
+static void BM_math_signbit(benchmark::State& state) {
+  d = 0.0;
+  v = values[state.range_x()];
+  while (state.KeepRunning()) {
+    d += (__signbit)(v);
+  }
+  SetLabel(state);
+}
+BENCHMARK_COMMON_VALS(BM_math_signbit);
+
+static void BM_math_fabs_macro(benchmark::State& state) {
+  d = 0.0;
+  v = values[state.range_x()];
+  while (state.KeepRunning()) {
+    d += fabs(v);
+  }
+  SetLabel(state);
+}
+BENCHMARK_COMMON_VALS(BM_math_fabs_macro);
+
+static void BM_math_fabs(benchmark::State& state) {
+  d = 0.0;
+  v = values[state.range_x()];
+  while (state.KeepRunning()) {
+    d += (fabs)(v);
+  }
+  SetLabel(state);
+}
+BENCHMARK_COMMON_VALS(BM_math_fabs);
diff --git a/benchmarks/property_benchmark.cpp b/benchmarks/property_benchmark.cpp
index 944cd68..2f72d60 100644
--- a/benchmarks/property_benchmark.cpp
+++ b/benchmarks/property_benchmark.cpp
@@ -26,7 +26,7 @@
 #define _REALLY_INCLUDE_SYS__SYSTEM_PROPERTIES_H_
 #include <sys/_system_properties.h>
 
-#include <benchmark/Benchmark.h>
+#include <benchmark/benchmark.h>
 
 extern void* __system_property_area__;
 
@@ -126,7 +126,8 @@
     delete[] values;
     delete[] value_lens;
   }
-public:
+
+ public:
   const int nprops;
   char** names;
   int* name_lens;
@@ -134,100 +135,79 @@
   int* value_lens;
   bool valid;
 
-private:
+ private:
   std::string pa_dirname;
   std::string pa_filename;
   void* old_pa;
 };
 
-BENCHMARK_WITH_ARG(BM_property_get, int)->TEST_NUM_PROPS;
-void BM_property_get::Run(int iters, int nprops) {
-  StopBenchmarkTiming();
+static void BM_property_get(benchmark::State& state) {
+  const size_t nprops = state.range_x();
 
   LocalPropertyTestState pa(nprops);
-  char value[PROP_VALUE_MAX];
+  if (!pa.valid) return;
 
-  if (!pa.valid)
-    return;
-
-  srandom(iters * nprops);
-
-  StartBenchmarkTiming();
-
-  for (int i = 0; i < iters; i++) {
+  while (state.KeepRunning()) {
+    char value[PROP_VALUE_MAX];
     __system_property_get(pa.names[random() % nprops], value);
   }
-  StopBenchmarkTiming();
 }
+BENCHMARK(BM_property_get)->TEST_NUM_PROPS;
 
-BENCHMARK_WITH_ARG(BM_property_find, int)->TEST_NUM_PROPS;
-void BM_property_find::Run(int iters, int nprops) {
-  StopBenchmarkTiming();
+static void BM_property_find(benchmark::State& state) {
+  const size_t nprops = state.range_x();
 
   LocalPropertyTestState pa(nprops);
+  if (!pa.valid) return;
 
-  if (!pa.valid)
-    return;
-
-  srandom(iters * nprops);
-
-  StartBenchmarkTiming();
-
-  for (int i = 0; i < iters; i++) {
+  while (state.KeepRunning()) {
     __system_property_find(pa.names[random() % nprops]);
   }
-  StopBenchmarkTiming();
 }
+BENCHMARK(BM_property_find)->TEST_NUM_PROPS;
 
-BENCHMARK_WITH_ARG(BM_property_read, int)->TEST_NUM_PROPS;
-void BM_property_read::Run(int iters, int nprops) {
-  StopBenchmarkTiming();
+static void BM_property_read(benchmark::State& state) {
+  const size_t nprops = state.range_x();
 
   LocalPropertyTestState pa(nprops);
+  if (!pa.valid) return;
 
-  if (!pa.valid)
-    return;
-
-  srandom(iters * nprops);
-  const prop_info** pinfo = new const prop_info*[iters];
+  const prop_info** pinfo = new const prop_info*[nprops];
   char propvalue[PROP_VALUE_MAX];
 
-  for (int i = 0; i < iters; i++) {
+  for (size_t i = 0; i < nprops; ++i) {
     pinfo[i] = __system_property_find(pa.names[random() % nprops]);
   }
 
-  StartBenchmarkTiming();
-  for (int i = 0; i < iters; i++) {
+  size_t i = 0;
+  while (state.KeepRunning()) {
     __system_property_read(pinfo[i], 0, propvalue);
+    i = (i + 1) % nprops;
   }
-  StopBenchmarkTiming();
 
   delete[] pinfo;
 }
+BENCHMARK(BM_property_read)->TEST_NUM_PROPS;
 
-BENCHMARK_WITH_ARG(BM_property_serial, int)->TEST_NUM_PROPS;
-void BM_property_serial::Run(int iters, int nprops) {
-  StopBenchmarkTiming();
+static void BM_property_serial(benchmark::State& state) {
+  const size_t nprops = state.range_x();
 
   LocalPropertyTestState pa(nprops);
+  if (!pa.valid) return;
 
-  if (!pa.valid)
-    return;
-
-  srandom(iters * nprops);
-  const prop_info** pinfo = new const prop_info*[iters];
-
-  for (int i = 0; i < iters; i++) {
+  const prop_info** pinfo = new const prop_info*[nprops];
+  for (size_t i = 0; i < nprops; ++i) {
     pinfo[i] = __system_property_find(pa.names[random() % nprops]);
   }
 
-  StartBenchmarkTiming();
-  for (int i = 0; i < iters; i++) {
+  size_t i = 0;
+  while (state.KeepRunning()) {
     __system_property_serial(pinfo[i]);
+    i = (i + 1) % nprops;
   }
-  StopBenchmarkTiming();
 
   delete[] pinfo;
 }
+BENCHMARK(BM_property_serial)->TEST_NUM_PROPS;
 
 #endif  // __BIONIC__
diff --git a/benchmarks/pthread_benchmark.cpp b/benchmarks/pthread_benchmark.cpp
index ad31e7e..bf4d6cb 100644
--- a/benchmarks/pthread_benchmark.cpp
+++ b/benchmarks/pthread_benchmark.cpp
@@ -16,218 +16,178 @@
 
 #include <pthread.h>
 
-#include <benchmark/Benchmark.h>
+#include <benchmark/benchmark.h>
 
 // Stop GCC optimizing out our pure function.
 /* Must not be static! */ pthread_t (*pthread_self_fp)() = pthread_self;
 
-BENCHMARK_NO_ARG(BM_pthread_self);
-void BM_pthread_self::Run(int iters) {
-  StartBenchmarkTiming();
-
-  for (int i = 0; i < iters; ++i) {
+static void BM_pthread_self(benchmark::State& state) {
+  while (state.KeepRunning()) {
     pthread_self_fp();
   }
-
-  StopBenchmarkTiming();
 }
+BENCHMARK(BM_pthread_self);
 
-BENCHMARK_NO_ARG(BM_pthread_getspecific);
-void BM_pthread_getspecific::Run(int iters) {
-  StopBenchmarkTiming();
+static void BM_pthread_getspecific(benchmark::State& state) {
   pthread_key_t key;
   pthread_key_create(&key, NULL);
-  StartBenchmarkTiming();
 
-  for (int i = 0; i < iters; ++i) {
+  while (state.KeepRunning()) {
     pthread_getspecific(key);
   }
 
-  StopBenchmarkTiming();
   pthread_key_delete(key);
 }
+BENCHMARK(BM_pthread_getspecific);
 
-BENCHMARK_NO_ARG(BM_pthread_setspecific);
-void BM_pthread_setspecific::Run(int iters) {
-  StopBenchmarkTiming();
+static void BM_pthread_setspecific(benchmark::State& state) {
   pthread_key_t key;
   pthread_key_create(&key, NULL);
-  StartBenchmarkTiming();
 
-  for (int i = 0; i < iters; ++i) {
+  while (state.KeepRunning()) {
     pthread_setspecific(key, NULL);
   }
 
-  StopBenchmarkTiming();
   pthread_key_delete(key);
 }
+BENCHMARK(BM_pthread_setspecific);
 
 static void DummyPthreadOnceInitFunction() {
 }
 
-BENCHMARK_NO_ARG(BM_pthread_once);
-void BM_pthread_once::Run(int iters) {
-  StopBenchmarkTiming();
+static void BM_pthread_once(benchmark::State& state) {
   pthread_once_t once = PTHREAD_ONCE_INIT;
   pthread_once(&once, DummyPthreadOnceInitFunction);
-  StartBenchmarkTiming();
 
-  for (int i = 0; i < iters; ++i) {
+  while (state.KeepRunning()) {
     pthread_once(&once, DummyPthreadOnceInitFunction);
   }
-
-  StopBenchmarkTiming();
 }
+BENCHMARK(BM_pthread_once);
 
-BENCHMARK_NO_ARG(BM_pthread_mutex_lock);
-void BM_pthread_mutex_lock::Run(int iters) {
-  StopBenchmarkTiming();
+static void BM_pthread_mutex_lock(benchmark::State& state) {
   pthread_mutex_t mutex = PTHREAD_MUTEX_INITIALIZER;
-  StartBenchmarkTiming();
 
-  for (int i = 0; i < iters; ++i) {
+  while (state.KeepRunning()) {
     pthread_mutex_lock(&mutex);
     pthread_mutex_unlock(&mutex);
   }
-
-  StopBenchmarkTiming();
 }
+BENCHMARK(BM_pthread_mutex_lock);
 
-BENCHMARK_NO_ARG(BM_pthread_mutex_lock_ERRORCHECK);
-void BM_pthread_mutex_lock_ERRORCHECK::Run(int iters) {
-  StopBenchmarkTiming();
+static void BM_pthread_mutex_lock_ERRORCHECK(benchmark::State& state) {
   pthread_mutex_t mutex = PTHREAD_ERRORCHECK_MUTEX_INITIALIZER_NP;
-  StartBenchmarkTiming();
 
-  for (int i = 0; i < iters; ++i) {
+  while (state.KeepRunning()) {
     pthread_mutex_lock(&mutex);
     pthread_mutex_unlock(&mutex);
   }
-
-  StopBenchmarkTiming();
 }
+BENCHMARK(BM_pthread_mutex_lock_ERRORCHECK);
 
-BENCHMARK_NO_ARG(BM_pthread_mutex_lock_RECURSIVE);
-void BM_pthread_mutex_lock_RECURSIVE::Run(int iters) {
-  StopBenchmarkTiming();
+static void BM_pthread_mutex_lock_RECURSIVE(benchmark::State& state) {
   pthread_mutex_t mutex = PTHREAD_RECURSIVE_MUTEX_INITIALIZER_NP;
-  StartBenchmarkTiming();
 
-  for (int i = 0; i < iters; ++i) {
+  while (state.KeepRunning()) {
     pthread_mutex_lock(&mutex);
     pthread_mutex_unlock(&mutex);
   }
-
-  StopBenchmarkTiming();
 }
+BENCHMARK(BM_pthread_mutex_lock_RECURSIVE);
 
-BENCHMARK_NO_ARG(BM_pthread_rwlock_read);
-void BM_pthread_rwlock_read::Run(int iters) {
-  StopBenchmarkTiming();
+static void BM_pthread_rwlock_read(benchmark::State& state) {
   pthread_rwlock_t lock;
   pthread_rwlock_init(&lock, NULL);
-  StartBenchmarkTiming();
 
-  for (int i = 0; i < iters; ++i) {
+  while (state.KeepRunning()) {
     pthread_rwlock_rdlock(&lock);
     pthread_rwlock_unlock(&lock);
   }
 
-  StopBenchmarkTiming();
   pthread_rwlock_destroy(&lock);
 }
+BENCHMARK(BM_pthread_rwlock_read);
 
-BENCHMARK_NO_ARG(BM_pthread_rwlock_write);
-void BM_pthread_rwlock_write::Run(int iters) {
-  StopBenchmarkTiming();
+static void BM_pthread_rwlock_write(benchmark::State& state) {
   pthread_rwlock_t lock;
   pthread_rwlock_init(&lock, NULL);
-  StartBenchmarkTiming();
 
-  for (int i = 0; i < iters; ++i) {
+  while (state.KeepRunning()) {
     pthread_rwlock_wrlock(&lock);
     pthread_rwlock_unlock(&lock);
   }
 
-  StopBenchmarkTiming();
   pthread_rwlock_destroy(&lock);
 }
+BENCHMARK(BM_pthread_rwlock_write);
 
 static void* IdleThread(void*) {
   return NULL;
 }
 
-BENCHMARK_NO_ARG(BM_pthread_create);
-void BM_pthread_create::Run(int iters) {
-  StopBenchmarkTiming();
-  pthread_t thread;
-
-  for (int i = 0; i < iters; ++i) {
-    StartBenchmarkTiming();
+static void BM_pthread_create(benchmark::State& state) {
+  while (state.KeepRunning()) {
+    pthread_t thread;
     pthread_create(&thread, NULL, IdleThread, NULL);
-    StopBenchmarkTiming();
+    state.PauseTiming();
     pthread_join(thread, NULL);
+    state.ResumeTiming();
   }
 }
+BENCHMARK(BM_pthread_create);
 
 static void* RunThread(void* arg) {
-  ::testing::Benchmark* benchmark = reinterpret_cast<::testing::Benchmark*>(arg);
-  benchmark->StopBenchmarkTiming();
+  benchmark::State& state = *reinterpret_cast<benchmark::State*>(arg);
+  state.PauseTiming();
   return NULL;
 }
 
-BENCHMARK_NO_ARG(BM_pthread_create_and_run);
-void BM_pthread_create_and_run::Run(int iters) {
-  StopBenchmarkTiming();
-  pthread_t thread;
-
-  for (int i = 0; i < iters; ++i) {
-    StartBenchmarkTiming();
-    pthread_create(&thread, NULL, RunThread, this);
+static void BM_pthread_create_and_run(benchmark::State& state) {
+  while (state.KeepRunning()) {
+    pthread_t thread;
+    pthread_create(&thread, NULL, RunThread, &state);
     pthread_join(thread, NULL);
+    state.ResumeTiming();
   }
 }
+BENCHMARK(BM_pthread_create_and_run);
 
 static void* ExitThread(void* arg) {
-  ::testing::Benchmark* benchmark = reinterpret_cast<::testing::Benchmark*>(arg);
-  benchmark->StartBenchmarkTiming();
+  benchmark::State& state = *reinterpret_cast<benchmark::State*>(arg);
+  state.ResumeTiming();
   pthread_exit(NULL);
 }
 
-BENCHMARK_NO_ARG(BM_pthread_exit_and_join);
-void BM_pthread_exit_and_join::Run(int iters) {
-  StopBenchmarkTiming();
-  pthread_t thread;
-
-  for (int i = 0; i < iters; ++i) {
-    pthread_create(&thread, NULL, ExitThread, this);
+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_join(thread, NULL);
-    StopBenchmarkTiming();
   }
 }
+BENCHMARK(BM_pthread_exit_and_join);
 
-BENCHMARK_NO_ARG(BM_pthread_key_create);
-void BM_pthread_key_create::Run(int iters) {
-  StopBenchmarkTiming();
-  pthread_key_t key;
-
-  for (int i = 0; i < iters; ++i) {
-    StartBenchmarkTiming();
+static void BM_pthread_key_create(benchmark::State& state) {
+  while (state.KeepRunning()) {
+    pthread_key_t key;
     pthread_key_create(&key, NULL);
-    StopBenchmarkTiming();
+
+    state.PauseTiming();
+    pthread_key_delete(key);
+    state.ResumeTiming();
+  }
+}
+BENCHMARK(BM_pthread_key_create);
+
+static void BM_pthread_key_delete(benchmark::State& state) {
+  while (state.KeepRunning()) {
+    state.PauseTiming();
+    pthread_key_t key;
+    pthread_key_create(&key, NULL);
+    state.ResumeTiming();
+
     pthread_key_delete(key);
   }
 }
-
-BENCHMARK_NO_ARG(BM_pthread_key_delete);
-void BM_pthread_key_delete::Run(int iters) {
-  StopBenchmarkTiming();
-  pthread_key_t key;
-
-  for (int i = 0; i < iters; ++i) {
-    pthread_key_create(&key, NULL);
-    StartBenchmarkTiming();
-    pthread_key_delete(key);
-    StopBenchmarkTiming();
-  }
-}
+BENCHMARK(BM_pthread_key_delete);
diff --git a/benchmarks/semaphore_benchmark.cpp b/benchmarks/semaphore_benchmark.cpp
index 8dd5684..d260803 100644
--- a/benchmarks/semaphore_benchmark.cpp
+++ b/benchmarks/semaphore_benchmark.cpp
@@ -18,101 +18,112 @@
 #include <semaphore.h>
 #include <stdatomic.h>
 #include <stdio.h>
+#include <stdlib.h>
 
-#include <benchmark/Benchmark.h>
+#include <benchmark/benchmark.h>
 
-BENCHMARK_NO_ARG(BM_semaphore_sem_getvalue);
-void BM_semaphore_sem_getvalue::Run(int iters) {
-  StopBenchmarkTiming();
+static void BM_semaphore_sem_getvalue(benchmark::State& state) {
   sem_t semaphore;
   sem_init(&semaphore, 1, 1);
-  StartBenchmarkTiming();
 
-  for (int i = 0; i < iters; ++i) {
+  while (state.KeepRunning()) {
     int dummy;
     sem_getvalue(&semaphore, &dummy);
   }
-
-  StopBenchmarkTiming();
 }
+BENCHMARK(BM_semaphore_sem_getvalue);
 
-BENCHMARK_NO_ARG(BM_semaphore_sem_wait_sem_post);
-void BM_semaphore_sem_wait_sem_post::Run(int iters) {
-  StopBenchmarkTiming();
+static void BM_semaphore_sem_wait_sem_post(benchmark::State& state) {
   sem_t semaphore;
   sem_init(&semaphore, 1, 1);
-  StartBenchmarkTiming();
 
-  for (int i = 0; i < iters; ++i) {
+  while (state.KeepRunning()) {
     sem_wait(&semaphore);
     sem_post(&semaphore);
   }
-
-  StopBenchmarkTiming();
 }
+BENCHMARK(BM_semaphore_sem_wait_sem_post);
 
-/*
- *    This test reports the overhead of the underlying futex wake syscall on
- * the producer. It does not report the overhead from issuing the wake to the
- * point where the posted consumer thread wakes up. It suffers from
- * clock_gettime syscall overhead. Lock the CPU speed for consistent results
- * as we may not reach >50% cpu utilization.
- *
- *    We will run a background thread that catches the sem_post wakeup and
- * loops immediately returning back to sleep in sem_wait for the next one. This
- * thread is run with policy SCHED_OTHER (normal policy), a middle policy.
- *
- *    The primary thread will run at SCHED_IDLE (lowest priority policy) when
- * monitoring the background thread to detect when it hits sem_wait sleep. It
- * will do so with no clock running. Once we are ready, we will switch to
- * SCHED_FIFO (highest priority policy) to time the act of running sem_post
- * with the benchmark clock running. This ensures nothing else in the system
- * can preempt our timed activity, including the background thread. We are
- * also protected with the scheduling policy of letting a process hit a
- * resource limit rather than get hit with a context switch.
- *
- *    The background thread will start executing either on another CPU, or
- * after we back down from SCHED_FIFO, but certainly not in the context of
- * the timing of the sem_post.
- */
+// This test reports the overhead of the underlying futex wake syscall on
+// the producer. It does not report the overhead from issuing the wake to the
+// point where the posted consumer thread wakes up. It suffers from
+// clock_gettime syscall overhead. Lock the CPU speed for consistent results
+// as we may not reach >50% cpu utilization.
+//
+// We will run a background thread that catches the sem_post wakeup and
+// loops immediately returning back to sleep in sem_wait for the next one. This
+// thread is run with policy SCHED_OTHER (normal policy), a middle policy.
+//
+// The primary thread will run at SCHED_IDLE (lowest priority policy) when
+// monitoring the background thread to detect when it hits sem_wait sleep. It
+// will do so with no clock running. Once we are ready, we will switch to
+// SCHED_FIFO (highest priority policy) to time the act of running sem_post
+// with the benchmark clock running. This ensures nothing else in the system
+// can preempt our timed activity, including the background thread. We are
+// also protected with the scheduling policy of letting a process hit a
+// resource limit rather than get hit with a context switch.
+//
+// The background thread will start executing either on another CPU, or
+// after we back down from SCHED_FIFO, but certainly not in the context of
+// the timing of the sem_post.
+
 static atomic_int BM_semaphore_sem_post_running;
 
-static void *BM_semaphore_sem_post_start_thread(void *obj) {
-    sem_t *semaphore = reinterpret_cast<sem_t *>(obj);
-
-    while ((BM_semaphore_sem_post_running > 0) && !sem_wait(semaphore)) {
-        ;
-    }
-    BM_semaphore_sem_post_running = -1;
-    return NULL;
+static void* BM_semaphore_sem_post_start_thread(void* arg) {
+  sem_t* semaphore = reinterpret_cast<sem_t*>(arg);
+  while ((BM_semaphore_sem_post_running > 0) && !sem_wait(semaphore)) {
+  }
+  BM_semaphore_sem_post_running = -1;
+  return NULL;
 }
 
-BENCHMARK_NO_ARG(BM_semaphore_sem_post);
-void BM_semaphore_sem_post::Run(int iters) {
-  StopBenchmarkTiming();
+class SemaphoreFixture : public benchmark::Fixture {
+ public:
+  void SetUp(const benchmark::State&) {
+    sem_init(&semaphore, 0, 0);
+
+    pthread_attr_t attr;
+    pthread_attr_init(&attr);
+
+    memset(&param, 0, sizeof(param));
+    pthread_attr_setschedparam(&attr, &param);
+    pthread_attr_setschedpolicy(&attr, SCHED_OTHER);
+    pthread_attr_setdetachstate(&attr, PTHREAD_CREATE_DETACHED);
+    pthread_t pthread;
+    pthread_create(&pthread, &attr, BM_semaphore_sem_post_start_thread, &semaphore);
+    pthread_attr_destroy(&attr);
+
+    sched_setscheduler(0, SCHED_IDLE, &param);
+
+    BM_semaphore_sem_post_running = 1;
+  }
+
+  ~SemaphoreFixture() {
+    sched_setscheduler(0, SCHED_OTHER, &param);
+
+    if (BM_semaphore_sem_post_running > 0) {
+      BM_semaphore_sem_post_running = 0;
+    }
+    do {
+      sem_post(&semaphore);
+      sched_yield();
+    } while (BM_semaphore_sem_post_running != -1);
+  }
 
   sem_t semaphore;
-  sem_init(&semaphore, 0, 0);
+  sched_param param;
+};
 
-  pthread_attr_t attr;
-  pthread_attr_init(&attr);
-  BM_semaphore_sem_post_running = 1;
-  struct sched_param param = { 0, };
-  pthread_attr_setschedparam(&attr, &param);
-  pthread_attr_setschedpolicy(&attr, SCHED_OTHER);
-  pthread_attr_setdetachstate(&attr, PTHREAD_CREATE_DETACHED);
-  pthread_t pthread;
-  pthread_create(&pthread, &attr, BM_semaphore_sem_post_start_thread, &semaphore);
-  pthread_attr_destroy(&attr);
+BENCHMARK_F(SemaphoreFixture, semaphore_sem_post)(benchmark::State& state) {
+  while (state.KeepRunning()) {
+    state.PauseTiming();
 
-  sched_setscheduler((pid_t)0, SCHED_IDLE, &param);
-  for (int i = 0; i < iters; ++i) {
     int trys = 3, dummy = 0;
     do {
       if (BM_semaphore_sem_post_running < 0) {
-        sched_setscheduler((pid_t)0, SCHED_OTHER, &param);
+        sched_setscheduler(0, SCHED_OTHER, &param);
         fprintf(stderr, "BM_semaphore_sem_post: start_thread died unexpectedly\n");
-        return;
+        abort();
       }
       sched_yield();
       sem_getvalue(&semaphore, &dummy);
@@ -123,21 +134,14 @@
         --trys;
       }
     } while (trys);
-    param.sched_priority = 1;
-    sched_setscheduler((pid_t)0, SCHED_FIFO, &param);
-    StartBenchmarkTiming();
-    sem_post(&semaphore);
-    StopBenchmarkTiming(); // Remember to subtract clock syscall overhead
-    param.sched_priority = 0;
-    sched_setscheduler((pid_t)0, SCHED_IDLE, &param);
-  }
-  sched_setscheduler((pid_t)0, SCHED_OTHER, &param);
 
-  if (BM_semaphore_sem_post_running > 0) {
-    BM_semaphore_sem_post_running = 0;
-  }
-  do {
+    param.sched_priority = 1;
+    sched_setscheduler(0, SCHED_FIFO, &param);
+
+    state.ResumeTiming();
     sem_post(&semaphore);
-    sched_yield();
-  } while (!BM_semaphore_sem_post_running);
+
+    param.sched_priority = 0;
+    sched_setscheduler(0, SCHED_IDLE, &param);
+  }
 }
diff --git a/benchmarks/stdio_benchmark.cpp b/benchmarks/stdio_benchmark.cpp
index 342e561..cc07128 100644
--- a/benchmarks/stdio_benchmark.cpp
+++ b/benchmarks/stdio_benchmark.cpp
@@ -16,8 +16,9 @@
 
 #include <stdio.h>
 #include <stdio_ext.h>
+#include <stdlib.h>
 
-#include <benchmark/Benchmark.h>
+#include <benchmark/benchmark.h>
 
 #define KB 1024
 #define MB 1024*KB
@@ -27,67 +28,62 @@
     Arg(1*KB)->Arg(4*KB)->Arg(8*KB)->Arg(16*KB)->Arg(64*KB)
 
 template <typename Fn>
-void ReadWriteTest(::testing::Benchmark* benchmark, int iters, int chunk_size, Fn f, bool buffered) {
-  benchmark->StopBenchmarkTiming();
+void ReadWriteTest(benchmark::State& state, Fn f, bool buffered) {
+  size_t chunk_size = state.range_x();
+
   FILE* fp = fopen("/dev/zero", "rw");
   __fsetlocking(fp, FSETLOCKING_BYCALLER);
   char* buf = new char[chunk_size];
-  benchmark->StartBenchmarkTiming();
 
   if (!buffered) {
     setvbuf(fp, 0, _IONBF, 0);
   }
 
-  for (int i = 0; i < iters; ++i) {
+  while (state.KeepRunning()) {
     f(buf, chunk_size, 1, fp);
   }
 
-  benchmark->StopBenchmarkTiming();
-  benchmark->SetBenchmarkBytesProcessed(int64_t(iters) * int64_t(chunk_size));
+  state.SetBytesProcessed(int64_t(state.iterations()) * int64_t(chunk_size));
   delete[] buf;
   fclose(fp);
 }
 
-BENCHMARK_WITH_ARG(BM_stdio_fread, int)->AT_COMMON_SIZES;
-void BM_stdio_fread::Run(int iters, int chunk_size) {
-  ReadWriteTest(this, iters, chunk_size, fread, true);
+void BM_stdio_fread(benchmark::State& state) {
+  ReadWriteTest(state, fread, true);
 }
+BENCHMARK(BM_stdio_fread)->AT_COMMON_SIZES;
 
-BENCHMARK_WITH_ARG(BM_stdio_fwrite, int)->AT_COMMON_SIZES;
-void BM_stdio_fwrite::Run(int iters, int chunk_size) {
-  ReadWriteTest(this, iters, chunk_size, fwrite, true);
+void BM_stdio_fwrite(benchmark::State& state) {
+  ReadWriteTest(state, fwrite, true);
 }
+BENCHMARK(BM_stdio_fwrite)->AT_COMMON_SIZES;
 
-BENCHMARK_WITH_ARG(BM_stdio_fread_unbuffered, int)->AT_COMMON_SIZES;
-void BM_stdio_fread_unbuffered::Run(int iters, int chunk_size) {
-  ReadWriteTest(this, iters, chunk_size, fread, false);
+void BM_stdio_fread_unbuffered(benchmark::State& state) {
+  ReadWriteTest(state, fread, false);
 }
+BENCHMARK(BM_stdio_fread_unbuffered)->AT_COMMON_SIZES;
 
-BENCHMARK_WITH_ARG(BM_stdio_fwrite_unbuffered, int)->AT_COMMON_SIZES;
-void BM_stdio_fwrite_unbuffered::Run(int iters, int chunk_size) {
-  ReadWriteTest(this, iters, chunk_size, fwrite, false);
+void BM_stdio_fwrite_unbuffered(benchmark::State& state) {
+  ReadWriteTest(state, fwrite, false);
 }
+BENCHMARK(BM_stdio_fwrite_unbuffered)->AT_COMMON_SIZES;
 
-static void FopenFgetsFclose(int iters, bool no_locking) {
+static void FopenFgetsFclose(benchmark::State& state, bool no_locking) {
   char buf[1024];
-  for (int i = 0; i < iters; ++i) {
+  while (state.KeepRunning()) {
     FILE* fp = fopen("/proc/version", "re");
     if (no_locking) __fsetlocking(fp, FSETLOCKING_BYCALLER);
-    fgets(buf, sizeof(buf), fp);
+    if (fgets(buf, sizeof(buf), fp) == nullptr) abort();
     fclose(fp);
   }
 }
 
-BENCHMARK_NO_ARG(BM_stdio_fopen_fgets_fclose_locking);
-void BM_stdio_fopen_fgets_fclose_locking::Run(int iters) {
-  StartBenchmarkTiming();
-  FopenFgetsFclose(iters, false);
-  StopBenchmarkTiming();
+static void BM_stdio_fopen_fgets_fclose_locking(benchmark::State& state) {
+  FopenFgetsFclose(state, false);
 }
+BENCHMARK(BM_stdio_fopen_fgets_fclose_locking);
 
-BENCHMARK_NO_ARG(BM_stdio_fopen_fgets_fclose_no_locking);
-void BM_stdio_fopen_fgets_fclose_no_locking::Run(int iters) {
-  StartBenchmarkTiming();
-  FopenFgetsFclose(iters, true);
-  StopBenchmarkTiming();
+void BM_stdio_fopen_fgets_fclose_no_locking(benchmark::State& state) {
+  FopenFgetsFclose(state, true);
 }
+BENCHMARK(BM_stdio_fopen_fgets_fclose_no_locking);
diff --git a/benchmarks/string_benchmark.cpp b/benchmarks/string_benchmark.cpp
index 866aa00..c04409d 100644
--- a/benchmarks/string_benchmark.cpp
+++ b/benchmarks/string_benchmark.cpp
@@ -17,7 +17,7 @@
 #include <stdint.h>
 #include <string.h>
 
-#include <benchmark/Benchmark.h>
+#include <benchmark/benchmark.h>
 
 #define KB 1024
 #define MB 1024*KB
@@ -27,87 +27,77 @@
 
 // TODO: test unaligned operation too? (currently everything will be 8-byte aligned by malloc.)
 
-BENCHMARK_WITH_ARG(BM_string_memcmp, int)->AT_COMMON_SIZES;
-void BM_string_memcmp::Run(int iters, int nbytes) {
-  StopBenchmarkTiming();
+static void BM_string_memcmp(benchmark::State& state) {
+  const size_t nbytes = state.range_x();
   char* src = new char[nbytes]; char* dst = new char[nbytes];
   memset(src, 'x', nbytes);
   memset(dst, 'x', nbytes);
-  StartBenchmarkTiming();
 
   volatile int c __attribute__((unused)) = 0;
-  for (int i = 0; i < iters; ++i) {
+  while (state.KeepRunning()) {
     c += memcmp(dst, src, nbytes);
   }
 
-  StopBenchmarkTiming();
-  SetBenchmarkBytesProcessed(uint64_t(iters) * uint64_t(nbytes));
+  state.SetBytesProcessed(uint64_t(state.iterations()) * uint64_t(nbytes));
   delete[] src;
   delete[] dst;
 }
+BENCHMARK(BM_string_memcmp)->AT_COMMON_SIZES;
 
-BENCHMARK_WITH_ARG(BM_string_memcpy, int)->AT_COMMON_SIZES;
-void BM_string_memcpy::Run(int iters, int nbytes) {
-  StopBenchmarkTiming();
+static void BM_string_memcpy(benchmark::State& state) {
+  const size_t nbytes = state.range_x();
   char* src = new char[nbytes]; char* dst = new char[nbytes];
   memset(src, 'x', nbytes);
-  StartBenchmarkTiming();
 
-  for (int i = 0; i < iters; ++i) {
+  while (state.KeepRunning()) {
     memcpy(dst, src, nbytes);
   }
 
-  StopBenchmarkTiming();
-  SetBenchmarkBytesProcessed(uint64_t(iters) * uint64_t(nbytes));
+  state.SetBytesProcessed(uint64_t(state.iterations()) * uint64_t(nbytes));
   delete[] src;
   delete[] dst;
 }
+BENCHMARK(BM_string_memcpy)->AT_COMMON_SIZES;
 
-BENCHMARK_WITH_ARG(BM_string_memmove, int)->AT_COMMON_SIZES;
-void BM_string_memmove::Run(int iters, int nbytes) {
-  StopBenchmarkTiming();
+static void BM_string_memmove(benchmark::State& state) {
+  const size_t nbytes = state.range_x();
   char* buf = new char[nbytes + 64];
   memset(buf, 'x', nbytes + 64);
-  StartBenchmarkTiming();
 
-  for (int i = 0; i < iters; ++i) {
+  while (state.KeepRunning()) {
     memmove(buf, buf + 1, nbytes); // Worst-case overlap.
   }
 
-  StopBenchmarkTiming();
-  SetBenchmarkBytesProcessed(uint64_t(iters) * uint64_t(nbytes));
+  state.SetBytesProcessed(uint64_t(state.iterations()) * uint64_t(nbytes));
   delete[] buf;
 }
+BENCHMARK(BM_string_memmove)->AT_COMMON_SIZES;
 
-BENCHMARK_WITH_ARG(BM_string_memset, int)->AT_COMMON_SIZES;
-void BM_string_memset::Run(int iters, int nbytes) {
-  StopBenchmarkTiming();
+static void BM_string_memset(benchmark::State& state) {
+  const size_t nbytes = state.range_x();
   char* dst = new char[nbytes];
-  StartBenchmarkTiming();
 
-  for (int i = 0; i < iters; ++i) {
+  while (state.KeepRunning()) {
     memset(dst, 0, nbytes);
   }
 
-  StopBenchmarkTiming();
-  SetBenchmarkBytesProcessed(uint64_t(iters) * uint64_t(nbytes));
+  state.SetBytesProcessed(uint64_t(state.iterations()) * uint64_t(nbytes));
   delete[] dst;
 }
+BENCHMARK(BM_string_memset)->AT_COMMON_SIZES;
 
-BENCHMARK_WITH_ARG(BM_string_strlen, int)->AT_COMMON_SIZES;
-void BM_string_strlen::Run(int iters, int nbytes) {
-  StopBenchmarkTiming();
+static void BM_string_strlen(benchmark::State& state) {
+  const size_t nbytes = state.range_x();
   char* s = new char[nbytes];
   memset(s, 'x', nbytes);
   s[nbytes - 1] = 0;
-  StartBenchmarkTiming();
 
   volatile int c __attribute__((unused)) = 0;
-  for (int i = 0; i < iters; ++i) {
+  while (state.KeepRunning()) {
     c += strlen(s);
   }
 
-  StopBenchmarkTiming();
-  SetBenchmarkBytesProcessed(uint64_t(iters) * uint64_t(nbytes));
+  state.SetBytesProcessed(uint64_t(state.iterations()) * uint64_t(nbytes));
   delete[] s;
 }
+BENCHMARK(BM_string_strlen)->AT_COMMON_SIZES;
diff --git a/benchmarks/time_benchmark.cpp b/benchmarks/time_benchmark.cpp
index 6688bbc..4a5c2da 100644
--- a/benchmarks/time_benchmark.cpp
+++ b/benchmarks/time_benchmark.cpp
@@ -17,64 +17,45 @@
 #include <sys/syscall.h>
 #include <sys/time.h>
 #include <time.h>
+#include <unistd.h>
 
-#include <benchmark/Benchmark.h>
+#include <benchmark/benchmark.h>
 
-BENCHMARK_NO_ARG(BM_time_clock_gettime);
-void BM_time_clock_gettime::Run(int iters) {
-  StartBenchmarkTiming();
-
+static void BM_time_clock_gettime(benchmark::State& state) {
   timespec t;
-  for (int i = 0; i < iters; ++i) {
+  while (state.KeepRunning()) {
     clock_gettime(CLOCK_MONOTONIC, &t);
   }
-
-  StopBenchmarkTiming();
 }
+BENCHMARK(BM_time_clock_gettime);
 
-BENCHMARK_NO_ARG(BM_time_clock_gettime_syscall);
-void BM_time_clock_gettime_syscall::Run(int iters) {
-  StartBenchmarkTiming();
-
+static void BM_time_clock_gettime_syscall(benchmark::State& state) {
   timespec t;
-  for (int i = 0; i < iters; ++i) {
+  while (state.KeepRunning()) {
     syscall(__NR_clock_gettime, CLOCK_MONOTONIC, &t);
   }
-
-  StopBenchmarkTiming();
 }
+BENCHMARK(BM_time_clock_gettime_syscall);
 
-BENCHMARK_NO_ARG(BM_time_gettimeofday);
-void BM_time_gettimeofday::Run(int iters) {
-  StartBenchmarkTiming();
-
+static void BM_time_gettimeofday(benchmark::State& state) {
   timeval tv;
-  for (int i = 0; i < iters; ++i) {
+  while (state.KeepRunning()) {
     gettimeofday(&tv, NULL);
   }
-
-  StopBenchmarkTiming();
 }
+BENCHMARK(BM_time_gettimeofday);
 
-BENCHMARK_NO_ARG(BM_time_gettimeofday_syscall);
-void BM_time_gettimeofday_syscall::Run(int iters) {
-  StartBenchmarkTiming();
-
+void BM_time_gettimeofday_syscall(benchmark::State& state) {
   timeval tv;
-  for (int i = 0; i < iters; ++i) {
+  while (state.KeepRunning()) {
     syscall(__NR_gettimeofday, &tv, NULL);
   }
-
-  StopBenchmarkTiming();
 }
+BENCHMARK(BM_time_gettimeofday_syscall);
 
-BENCHMARK_NO_ARG(BM_time_time);
-void BM_time_time::Run(int iters) {
-  StartBenchmarkTiming();
-
-  for (int i = 0; i < iters; ++i) {
+void BM_time_time(benchmark::State& state) {
+  while (state.KeepRunning()) {
     time(NULL);
   }
-
-  StopBenchmarkTiming();
 }
+BENCHMARK(BM_time_time);
diff --git a/benchmarks/unistd_benchmark.cpp b/benchmarks/unistd_benchmark.cpp
index 09ca0e6..b78d3eb 100644
--- a/benchmarks/unistd_benchmark.cpp
+++ b/benchmarks/unistd_benchmark.cpp
@@ -17,55 +17,41 @@
 #include <sys/syscall.h>
 #include <unistd.h>
 
-#include <benchmark/Benchmark.h>
+#include <benchmark/benchmark.h>
 
-BENCHMARK_NO_ARG(BM_unistd_getpid);
-void BM_unistd_getpid::Run(int iters) {
-  StartBenchmarkTiming();
-
-  for (int i = 0; i < iters; ++i) {
+static void BM_unistd_getpid(benchmark::State& state) {
+  while (state.KeepRunning()) {
     getpid();
   }
-
-  StopBenchmarkTiming();
 }
+BENCHMARK(BM_unistd_getpid);
 
-BENCHMARK_NO_ARG(BM_unistd_getpid_syscall);
-void BM_unistd_getpid_syscall::Run(int iters) {
-  StartBenchmarkTiming();
-
-  for (int i = 0; i < iters; ++i) {
+static void BM_unistd_getpid_syscall(benchmark::State& state) {
+  while (state.KeepRunning()) {
     syscall(__NR_getpid);
   }
-
-  StopBenchmarkTiming();
 }
+BENCHMARK(BM_unistd_getpid_syscall);
 
 #if defined(__BIONIC__)
 
 // Stop GCC optimizing out our pure function.
 /* Must not be static! */ pid_t (*gettid_fp)() = gettid;
 
-BENCHMARK_NO_ARG(BM_unistd_gettid);
-void BM_unistd_gettid::Run(int iters) {
-  StartBenchmarkTiming();
-
-  for (int i = 0; i < iters; ++i) {
+static void BM_unistd_gettid(benchmark::State& state) {
+  while (state.KeepRunning()) {
     gettid_fp();
   }
-
-  StopBenchmarkTiming();
 }
+BENCHMARK(BM_unistd_gettid);
 
 #endif
 
-BENCHMARK_NO_ARG(BM_unistd_gettid_syscall);
-void BM_unistd_gettid_syscall::Run(int iters) {
-  StartBenchmarkTiming();
-
-  for (int i = 0; i < iters; ++i) {
+void BM_unistd_gettid_syscall(benchmark::State& state) {
+  while (state.KeepRunning()) {
     syscall(__NR_gettid);
   }
-
-  StopBenchmarkTiming();
 }
+BENCHMARK(BM_unistd_gettid_syscall);
+
+BENCHMARK_MAIN()
diff --git a/benchmarks/utils.cpp b/benchmarks/utils.cpp
deleted file mode 100644
index 863b9db..0000000
--- a/benchmarks/utils.cpp
+++ /dev/null
@@ -1,81 +0,0 @@
-/*
- * Copyright (C) 2012 The Android Open Source Project
- *
- * Licensed under the Apache License, Version 2.0 (the "License");
- * you may not use this file except in compliance with the License.
- * You may obtain a copy of the License at
- *
- *      http://www.apache.org/licenses/LICENSE-2.0
- *
- * Unless required by applicable law or agreed to in writing, software
- * distributed under the License is distributed on an "AS IS" BASIS,
- * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
- * See the License for the specific language governing permissions and
- * limitations under the License.
- */
-
-#include <inttypes.h>
-#include <stdio.h>
-#include <stdint.h>
-#include <stdlib.h>
-
-#include <string>
-
-#include "utils.h"
-
-int Round(int n) {
-  int base = 1;
-  while (base*10 < n) {
-    base *= 10;
-  }
-  if (n < 2*base) {
-    return 2*base;
-  }
-  if (n < 5*base) {
-    return 5*base;
-  }
-  return 10*base;
-}
-
-// Similar to the code in art, but supporting both binary and decimal prefixes.
-std::string PrettyInt(long value, size_t base) {
-  if (base != 2 && base != 10) abort();
-
-  uint64_t count = static_cast<uint64_t>(value);
-  bool negative_number = false;
-  if (value < 0) {
-    negative_number = true;
-    count = static_cast<uint64_t>(-value);
-  }
-
-  // The byte thresholds at which we display amounts. A count is displayed
-  // in unit U when kUnitThresholds[U] <= bytes < kUnitThresholds[U+1].
-  static const uint64_t kUnitThresholds2[] = {
-    1024*1024*1024 /* Gi */, 2*1024*1024 /* Mi */, 3*1024 /* Ki */, 0,
-  };
-  static const uint64_t kUnitThresholds10[] = {
-    1000*1000*1000 /* G */, 2*1000*1000 /* M */, 3*1000 /* k */, 0,
-  };
-  static const uint64_t kAmountPerUnit2[] = { 1024*1024*1024, 1024*1024, 1024, 1 };
-  static const uint64_t kAmountPerUnit10[] = { 1000*1000*1000, 1000*1000, 1000, 1 };
-  static const char* const kUnitStrings2[] = { "Gi", "Mi", "Ki", "" };
-  static const char* const kUnitStrings10[] = { "G", "M", "k", "" };
-
-  // Which set are we using?
-  const uint64_t* kUnitThresholds = ((base == 2) ? kUnitThresholds2 : kUnitThresholds10);
-  const uint64_t* kAmountPerUnit = ((base == 2) ? kAmountPerUnit2 : kAmountPerUnit10);
-  const char* const* kUnitStrings = ((base == 2) ? kUnitStrings2 : kUnitStrings10);
-
-  size_t i = 0;
-  for (; kUnitThresholds[i] != 0; ++i) {
-    if (count >= kUnitThresholds[i]) {
-      break;
-    }
-  }
-  char* s = NULL;
-  asprintf(&s, "%s%" PRId64 "%s", (negative_number ? "-" : ""),
-           count / kAmountPerUnit[i], kUnitStrings[i]);
-  std::string result(s);
-  free(s);
-  return result;
-}
diff --git a/libc/Android.bp b/libc/Android.bp
new file mode 100644
index 0000000..4cae16c
--- /dev/null
+++ b/libc/Android.bp
@@ -0,0 +1,2075 @@
+// Define the common source files for all the libc instances
+// =========================================================
+libc_common_src_files = [
+    "bionic/ether_aton.c",
+    "bionic/ether_ntoa.c",
+    "bionic/fts.c",
+    "bionic/getpriority.c",
+    "bionic/initgroups.c",
+    "bionic/isatty.c",
+    "bionic/memmem.c",
+    "bionic/pututline.c",
+    "bionic/sched_cpualloc.c",
+    "bionic/sched_cpucount.c",
+    "bionic/sigblock.c",
+    "bionic/siginterrupt.c",
+    "bionic/sigsetmask.c",
+    "bionic/system_properties_compat.c",
+    "stdio/fread.c",
+    "stdio/refill.c",
+    "stdio/snprintf.c",
+    "stdio/sprintf.c",
+    "stdio/stdio.cpp",
+    "stdio/stdio_ext.cpp",
+    "stdlib/atexit.c",
+    "stdlib/exit.c",
+
+    // Fortify implementations of libc functions.
+    "bionic/__FD_chk.cpp",
+    "bionic/__fgets_chk.cpp",
+    "bionic/__fread_chk.cpp",
+    "bionic/__fwrite_chk.cpp",
+    "bionic/__getcwd_chk.cpp",
+    "bionic/__memchr_chk.cpp",
+    "bionic/__memmove_chk.cpp",
+    "bionic/__memrchr_chk.cpp",
+    "bionic/__poll_chk.cpp",
+    "bionic/__pread64_chk.cpp",
+    "bionic/__pread_chk.cpp",
+    "bionic/__pwrite64_chk.cpp",
+    "bionic/__pwrite_chk.cpp",
+    "bionic/__read_chk.cpp",
+    "bionic/__readlink_chk.cpp",
+    "bionic/__readlinkat_chk.cpp",
+    "bionic/__recvfrom_chk.cpp",
+    "bionic/__stpcpy_chk.cpp",
+    "bionic/__stpncpy_chk.cpp",
+    "bionic/__strchr_chk.cpp",
+    "bionic/__strlcat_chk.cpp",
+    "bionic/__strlcpy_chk.cpp",
+    "bionic/__strlen_chk.cpp",
+    "bionic/__strncat_chk.cpp",
+    "bionic/__strncpy_chk.cpp",
+    "bionic/__strrchr_chk.cpp",
+    "bionic/__umask_chk.cpp",
+    "bionic/__vsnprintf_chk.cpp",
+    "bionic/__vsprintf_chk.cpp",
+    "bionic/__write_chk.cpp",
+]
+
+// Various kinds of cruft.
+// ========================================================
+libc_common_src_files += [
+    "bionic/ndk_cruft.cpp",
+]
+
+libc_common_src_files_32 = [
+    "bionic/legacy_32_bit_support.cpp",
+    "bionic/time64.c",
+]
+
+// Define some common cflags
+// ========================================================
+cc_defaults {
+    name: "libc_defaults",
+    cflags: [
+        "-D_LIBC=1",
+        "-Wall",
+        "-Wextra",
+        "-Wunused",
+
+        // Try to catch typical 32-bit assumptions that break with 64-bit pointers.
+        "-Werror=pointer-to-int-cast",
+        "-Werror=int-to-pointer-cast",
+        "-Werror=type-limits",
+        "-Werror",
+    ],
+    // TODO: split out the asflags.
+    asflags: [
+        "-D_LIBC=1",
+        "-Wall",
+        "-Wextra",
+        "-Wunused",
+
+        // Try to catch typical 32-bit assumptions that break with 64-bit pointers.
+        "-Werror=pointer-to-int-cast",
+        "-Werror=int-to-pointer-cast",
+        "-Werror=type-limits",
+        "-Werror",
+    ],
+    conlyflags: ["-std=gnu99"],
+    cppflags: [],
+    include_dirs: ["external/jemalloc/include"],
+
+    arch: {
+        // Clang/llvm has incompatible long double (fp128) for x86_64.
+        // https://llvm.org/bugs/show_bug.cgi?id=23897
+        x86_64: {
+            clang: false,
+        },
+        // b/25291096, Clang/llvm compiled libc.so for mips/mips64 failed to boot.
+        mips: {
+            clang: false,
+        },
+        mips64: {
+            clang: false,
+        },
+    },
+
+    stl: "none",
+    system_shared_libs: [],
+    sanitize: ["never"],
+    native_coverage: false,
+}
+
+// ANDROIDMK TRANSLATION ERROR: unsupported directive
+// ifeq ($(strip $(DEBUG_BIONIC_LIBC)),true)
+//libc_common_cflags += ["-DDEBUG"]
+// ANDROIDMK TRANSLATION ERROR: unsupported directive
+// endif
+
+// ========================================================
+// libc_stack_protector.a - stack protector code
+// ========================================================
+//
+// Code that implements the stack protector (or that runs
+// before TLS has been set up) needs to be compiled with
+// -fno-stack-protector, since it accesses the stack canary
+// TLS slot.
+
+cc_library_static {
+
+    srcs: [
+        "bionic/__libc_init_main_thread.cpp",
+        "bionic/__stack_chk_fail.cpp",
+    ],
+    arch: {
+        arm64: {
+            srcs: ["arch-arm64/bionic/__set_tls.c"],
+        },
+        x86: {
+            srcs: ["arch-x86/bionic/__set_tls.c"],
+        },
+        x86_64: {
+            srcs: ["arch-x86_64/bionic/__set_tls.c"],
+        },
+    },
+
+    defaults: ["libc_defaults"],
+    cflags: ["-fno-stack-protector"],
+    name: "libc_stack_protector",
+}
+
+// libc_init_static.cpp also needs to be built without stack protector,
+// because it's responsible for setting up TLS for static executables.
+// This isn't the case for dynamic executables because the dynamic linker
+// has already set up the main thread's TLS.
+
+cc_library_static {
+    name: "libc_init_static",
+    defaults: ["libc_defaults"],
+    srcs: ["bionic/libc_init_static.cpp"],
+    cflags: ["-fno-stack-protector"],
+}
+
+
+// ========================================================
+// libc_tzcode.a - upstream 'tzcode' code
+// ========================================================
+
+cc_library_static {
+
+    defaults: ["libc_defaults"],
+    srcs: [
+        "tzcode/**/*.c",
+        "upstream-openbsd/lib/libc/time/wcsftime.c", // tzcode doesn't include wcsftime, so we use the OpenBSD one.
+    ],
+
+    cflags: [
+        "-fvisibility=hidden",
+        "-Wno-unused-parameter",
+        // Don't use ridiculous amounts of stack.
+        "-DALL_STATE",
+        // Include tzsetwall, timelocal, timegm, time2posix, and posix2time.
+        "-DSTD_INSPIRED",
+        // Obviously, we want to be thread-safe.
+        "-DTHREAD_SAFE",
+        // The name of the tm_gmtoff field in our struct tm.
+        "-DTM_GMTOFF=tm_gmtoff",
+        // Where we store our tzdata.
+        "-DTZDIR=\\\"/system/usr/share/zoneinfo\\\"",
+        // Include timezone and daylight globals.
+        "-DUSG_COMPAT=1",
+        // Use the empty string (instead of "   ") as the timezone abbreviation
+        // fallback.
+        "-DWILDABBR=\\\"\\\"",
+        "-DNO_RUN_TIME_WARNINGS_ABOUT_YEAR_2000_PROBLEMS_THANK_YOU",
+        "-Dlint",
+    ],
+
+    local_include_dirs: ["tzcode/"],
+    name: "libc_tzcode",
+}
+
+// ========================================================
+// libc_dns.a - modified NetBSD DNS code
+// ========================================================
+
+cc_library_static {
+
+    defaults: ["libc_defaults"],
+    srcs: [
+        "dns/**/*.c",
+
+        "upstream-netbsd/lib/libc/isc/ev_streams.c",
+        "upstream-netbsd/lib/libc/isc/ev_timers.c",
+        "upstream-netbsd/lib/libc/resolv/mtctxres.c",
+    ],
+
+    cflags: [
+        "-DANDROID_CHANGES",
+        "-DINET6",
+        "-fvisibility=hidden",
+        "-Wno-unused-parameter",
+        "-include netbsd-compat.h",
+    ],
+
+    local_include_dirs: [
+        "dns/include",
+        "private",
+        "upstream-netbsd/lib/libc/include",
+        "upstream-netbsd/android/include",
+    ],
+
+    name: "libc_dns",
+}
+
+// ========================================================
+// libc_freebsd.a - upstream FreeBSD C library code
+// ========================================================
+//
+// These files are built with the freebsd-compat.h header file
+// automatically included.
+
+cc_library_static {
+    defaults: ["libc_defaults"],
+    srcs: [
+        "upstream-freebsd/lib/libc/gen/ldexp.c",
+        "upstream-freebsd/lib/libc/gen/sleep.c",
+        "upstream-freebsd/lib/libc/gen/usleep.c",
+        "upstream-freebsd/lib/libc/stdlib/getopt_long.c",
+        "upstream-freebsd/lib/libc/stdlib/qsort.c",
+        "upstream-freebsd/lib/libc/stdlib/quick_exit.c",
+        "upstream-freebsd/lib/libc/stdlib/realpath.c",
+        "upstream-freebsd/lib/libc/string/wcpcpy.c",
+        "upstream-freebsd/lib/libc/string/wcpncpy.c",
+        "upstream-freebsd/lib/libc/string/wcscasecmp.c",
+        "upstream-freebsd/lib/libc/string/wcscat.c",
+        "upstream-freebsd/lib/libc/string/wcschr.c",
+        "upstream-freebsd/lib/libc/string/wcscmp.c",
+        "upstream-freebsd/lib/libc/string/wcscpy.c",
+        "upstream-freebsd/lib/libc/string/wcscspn.c",
+        "upstream-freebsd/lib/libc/string/wcsdup.c",
+        "upstream-freebsd/lib/libc/string/wcslcat.c",
+        "upstream-freebsd/lib/libc/string/wcslen.c",
+        "upstream-freebsd/lib/libc/string/wcsncasecmp.c",
+        "upstream-freebsd/lib/libc/string/wcsncat.c",
+        "upstream-freebsd/lib/libc/string/wcsncmp.c",
+        "upstream-freebsd/lib/libc/string/wcsncpy.c",
+        "upstream-freebsd/lib/libc/string/wcsnlen.c",
+        "upstream-freebsd/lib/libc/string/wcspbrk.c",
+        "upstream-freebsd/lib/libc/string/wcsrchr.c",
+        "upstream-freebsd/lib/libc/string/wcsspn.c",
+        "upstream-freebsd/lib/libc/string/wcstok.c",
+        "upstream-freebsd/lib/libc/string/wmemchr.c",
+        "upstream-freebsd/lib/libc/string/wmemcmp.c",
+        "upstream-freebsd/lib/libc/string/wmemmove.c",
+        "upstream-freebsd/lib/libc/string/wmemset.c",
+    ],
+    arch: {
+        arm64: {
+            exclude_srcs: [
+                "upstream-freebsd/lib/libc/string/wmemmove.c",
+            ],
+        },
+        x86: {
+            exclude_srcs: [
+                "upstream-freebsd/lib/libc/string/wcschr.c",
+                "upstream-freebsd/lib/libc/string/wcscmp.c",
+                "upstream-freebsd/lib/libc/string/wcslen.c",
+                "upstream-freebsd/lib/libc/string/wcsrchr.c",
+            ],
+            atom: {
+                exclude_srcs: [
+                    "upstream-freebsd/lib/libc/string/wmemcmp.c",
+                ],
+            },
+            ssse3: {
+                exclude_srcs: [
+                    "upstream-freebsd/lib/libc/string/wcscat.c",
+                    "upstream-freebsd/lib/libc/string/wcscpy.c",
+                ],
+            },
+            sse4: {
+                exclude_srcs: [
+                    "upstream-freebsd/lib/libc/string/wmemcmp.c",
+                ],
+            },
+        },
+    },
+
+    cflags: [
+        "-Wno-sign-compare",
+        "-Wno-uninitialized",
+        "-include freebsd-compat.h",
+    ],
+
+    local_include_dirs: [
+        "upstream-freebsd/android/include",
+    ],
+
+    name: "libc_freebsd",
+}
+
+// ========================================================
+// libc_netbsd.a - upstream NetBSD C library code
+// ========================================================
+//
+// These files are built with the netbsd-compat.h header file
+// automatically included.
+
+cc_library_static {
+
+    defaults: ["libc_defaults"],
+    srcs: [
+        "upstream-netbsd/common/lib/libc/stdlib/random.c",
+        "upstream-netbsd/lib/libc/gen/ftw.c",
+        "upstream-netbsd/lib/libc/gen/nftw.c",
+        "upstream-netbsd/lib/libc/gen/nice.c",
+        "upstream-netbsd/lib/libc/gen/popen.c",
+        "upstream-netbsd/lib/libc/gen/psignal.c",
+        "upstream-netbsd/lib/libc/gen/utime.c",
+        "upstream-netbsd/lib/libc/gen/utmp.c",
+        "upstream-netbsd/lib/libc/inet/nsap_addr.c",
+        "upstream-netbsd/lib/libc/regex/regcomp.c",
+        "upstream-netbsd/lib/libc/regex/regerror.c",
+        "upstream-netbsd/lib/libc/regex/regexec.c",
+        "upstream-netbsd/lib/libc/regex/regfree.c",
+        "upstream-netbsd/lib/libc/stdlib/bsearch.c",
+        "upstream-netbsd/lib/libc/stdlib/div.c",
+        "upstream-netbsd/lib/libc/stdlib/drand48.c",
+        "upstream-netbsd/lib/libc/stdlib/erand48.c",
+        "upstream-netbsd/lib/libc/stdlib/jrand48.c",
+        "upstream-netbsd/lib/libc/stdlib/lcong48.c",
+        "upstream-netbsd/lib/libc/stdlib/ldiv.c",
+        "upstream-netbsd/lib/libc/stdlib/lldiv.c",
+        "upstream-netbsd/lib/libc/stdlib/lrand48.c",
+        "upstream-netbsd/lib/libc/stdlib/mrand48.c",
+        "upstream-netbsd/lib/libc/stdlib/nrand48.c",
+        "upstream-netbsd/lib/libc/stdlib/_rand48.c",
+        "upstream-netbsd/lib/libc/stdlib/rand_r.c",
+        "upstream-netbsd/lib/libc/stdlib/reallocarr.c",
+        "upstream-netbsd/lib/libc/stdlib/seed48.c",
+        "upstream-netbsd/lib/libc/stdlib/srand48.c",
+        "upstream-netbsd/lib/libc/string/memccpy.c",
+        "upstream-netbsd/lib/libc/string/strcasestr.c",
+        "upstream-netbsd/lib/libc/string/strcoll.c",
+        "upstream-netbsd/lib/libc/string/strxfrm.c",
+    ],
+    multilib: {
+        lib32: {
+            // LP32 cruft
+            srcs: ["upstream-netbsd/common/lib/libc/hash/sha1/sha1.c"],
+        },
+    },
+    cflags: [
+        "-Wno-sign-compare",
+        "-Wno-uninitialized",
+        "-Wno-unused-parameter",
+        "-DPOSIX_MISTAKE",
+        "-include netbsd-compat.h",
+    ],
+
+    local_include_dirs: [
+        "upstream-netbsd/android/include",
+        "upstream-netbsd/lib/libc/include",
+    ],
+
+    name: "libc_netbsd",
+}
+
+// ========================================================
+// libc_openbsd_ndk.a - upstream OpenBSD C library code
+// that can be safely included in the libc_ndk.a (doesn't
+// contain any troublesome global data or constructors).
+// ========================================================
+//
+// These files are built with the openbsd-compat.h header file
+// automatically included.
+
+cc_library_static {
+    name: "libc_openbsd_ndk",
+    defaults: ["libc_defaults"],
+    srcs: [
+        "upstream-openbsd/lib/libc/compat-43/killpg.c",
+        "upstream-openbsd/lib/libc/gen/alarm.c",
+        "upstream-openbsd/lib/libc/gen/ctype_.c",
+        "upstream-openbsd/lib/libc/gen/daemon.c",
+        "upstream-openbsd/lib/libc/gen/err.c",
+        "upstream-openbsd/lib/libc/gen/errx.c",
+        "upstream-openbsd/lib/libc/gen/exec.c",
+        "upstream-openbsd/lib/libc/gen/fnmatch.c",
+        "upstream-openbsd/lib/libc/gen/ftok.c",
+        "upstream-openbsd/lib/libc/gen/getprogname.c",
+        "upstream-openbsd/lib/libc/gen/isctype.c",
+        "upstream-openbsd/lib/libc/gen/setprogname.c",
+        "upstream-openbsd/lib/libc/gen/time.c",
+        "upstream-openbsd/lib/libc/gen/tolower_.c",
+        "upstream-openbsd/lib/libc/gen/toupper_.c",
+        "upstream-openbsd/lib/libc/gen/verr.c",
+        "upstream-openbsd/lib/libc/gen/verrx.c",
+        "upstream-openbsd/lib/libc/gen/vwarn.c",
+        "upstream-openbsd/lib/libc/gen/vwarnx.c",
+        "upstream-openbsd/lib/libc/gen/warn.c",
+        "upstream-openbsd/lib/libc/gen/warnx.c",
+        "upstream-openbsd/lib/libc/locale/btowc.c",
+        "upstream-openbsd/lib/libc/locale/mbrlen.c",
+        "upstream-openbsd/lib/libc/locale/mbstowcs.c",
+        "upstream-openbsd/lib/libc/locale/mbtowc.c",
+        "upstream-openbsd/lib/libc/locale/wcscoll.c",
+        "upstream-openbsd/lib/libc/locale/wcstod.c",
+        "upstream-openbsd/lib/libc/locale/wcstof.c",
+        "upstream-openbsd/lib/libc/locale/wcstoimax.c",
+        "upstream-openbsd/lib/libc/locale/wcstol.c",
+        "upstream-openbsd/lib/libc/locale/wcstold.c",
+        "upstream-openbsd/lib/libc/locale/wcstoll.c",
+        "upstream-openbsd/lib/libc/locale/wcstombs.c",
+        "upstream-openbsd/lib/libc/locale/wcstoul.c",
+        "upstream-openbsd/lib/libc/locale/wcstoull.c",
+        "upstream-openbsd/lib/libc/locale/wcstoumax.c",
+        "upstream-openbsd/lib/libc/locale/wcsxfrm.c",
+        "upstream-openbsd/lib/libc/locale/wctob.c",
+        "upstream-openbsd/lib/libc/locale/wctomb.c",
+        "upstream-openbsd/lib/libc/net/htonl.c",
+        "upstream-openbsd/lib/libc/net/htons.c",
+        "upstream-openbsd/lib/libc/net/inet_lnaof.c",
+        "upstream-openbsd/lib/libc/net/inet_makeaddr.c",
+        "upstream-openbsd/lib/libc/net/inet_netof.c",
+        "upstream-openbsd/lib/libc/net/inet_ntoa.c",
+        "upstream-openbsd/lib/libc/net/inet_ntop.c",
+        "upstream-openbsd/lib/libc/net/inet_pton.c",
+        "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/asprintf.c",
+        "upstream-openbsd/lib/libc/stdio/clrerr.c",
+        "upstream-openbsd/lib/libc/stdio/dprintf.c",
+        "upstream-openbsd/lib/libc/stdio/feof.c",
+        "upstream-openbsd/lib/libc/stdio/ferror.c",
+        "upstream-openbsd/lib/libc/stdio/fflush.c",
+        "upstream-openbsd/lib/libc/stdio/fgetc.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/fmemopen.c",
+        "upstream-openbsd/lib/libc/stdio/fprintf.c",
+        "upstream-openbsd/lib/libc/stdio/fpurge.c",
+        "upstream-openbsd/lib/libc/stdio/fputc.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/fscanf.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/fwprintf.c",
+        "upstream-openbsd/lib/libc/stdio/fwrite.c",
+        "upstream-openbsd/lib/libc/stdio/fwscanf.c",
+        "upstream-openbsd/lib/libc/stdio/getc.c",
+        "upstream-openbsd/lib/libc/stdio/getchar.c",
+        "upstream-openbsd/lib/libc/stdio/getdelim.c",
+        "upstream-openbsd/lib/libc/stdio/getline.c",
+        "upstream-openbsd/lib/libc/stdio/gets.c",
+        "upstream-openbsd/lib/libc/stdio/getwc.c",
+        "upstream-openbsd/lib/libc/stdio/getwchar.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/printf.c",
+        "upstream-openbsd/lib/libc/stdio/putc.c",
+        "upstream-openbsd/lib/libc/stdio/putchar.c",
+        "upstream-openbsd/lib/libc/stdio/puts.c",
+        "upstream-openbsd/lib/libc/stdio/putwc.c",
+        "upstream-openbsd/lib/libc/stdio/putwchar.c",
+        "upstream-openbsd/lib/libc/stdio/remove.c",
+        "upstream-openbsd/lib/libc/stdio/rewind.c",
+        "upstream-openbsd/lib/libc/stdio/rget.c",
+        "upstream-openbsd/lib/libc/stdio/scanf.c",
+        "upstream-openbsd/lib/libc/stdio/setbuf.c",
+        "upstream-openbsd/lib/libc/stdio/setbuffer.c",
+        "upstream-openbsd/lib/libc/stdio/setvbuf.c",
+        "upstream-openbsd/lib/libc/stdio/sscanf.c",
+        "upstream-openbsd/lib/libc/stdio/swprintf.c",
+        "upstream-openbsd/lib/libc/stdio/swscanf.c",
+        "upstream-openbsd/lib/libc/stdio/tempnam.c",
+        "upstream-openbsd/lib/libc/stdio/tmpnam.c",
+        "upstream-openbsd/lib/libc/stdio/ungetc.c",
+        "upstream-openbsd/lib/libc/stdio/ungetwc.c",
+        "upstream-openbsd/lib/libc/stdio/vasprintf.c",
+        "upstream-openbsd/lib/libc/stdio/vdprintf.c",
+        "upstream-openbsd/lib/libc/stdio/vfprintf.c",
+        "upstream-openbsd/lib/libc/stdio/vfscanf.c",
+        "upstream-openbsd/lib/libc/stdio/vfwprintf.c",
+        "upstream-openbsd/lib/libc/stdio/vfwscanf.c",
+        "upstream-openbsd/lib/libc/stdio/vprintf.c",
+        "upstream-openbsd/lib/libc/stdio/vscanf.c",
+        "upstream-openbsd/lib/libc/stdio/vsnprintf.c",
+        "upstream-openbsd/lib/libc/stdio/vsprintf.c",
+        "upstream-openbsd/lib/libc/stdio/vsscanf.c",
+        "upstream-openbsd/lib/libc/stdio/vswprintf.c",
+        "upstream-openbsd/lib/libc/stdio/vswscanf.c",
+        "upstream-openbsd/lib/libc/stdio/vwprintf.c",
+        "upstream-openbsd/lib/libc/stdio/vwscanf.c",
+        "upstream-openbsd/lib/libc/stdio/wbuf.c",
+        "upstream-openbsd/lib/libc/stdio/wprintf.c",
+        "upstream-openbsd/lib/libc/stdio/wscanf.c",
+        "upstream-openbsd/lib/libc/stdio/wsetup.c",
+        "upstream-openbsd/lib/libc/stdlib/abs.c",
+        "upstream-openbsd/lib/libc/stdlib/atoi.c",
+        "upstream-openbsd/lib/libc/stdlib/atol.c",
+        "upstream-openbsd/lib/libc/stdlib/atoll.c",
+        "upstream-openbsd/lib/libc/stdlib/getenv.c",
+        "upstream-openbsd/lib/libc/stdlib/insque.c",
+        "upstream-openbsd/lib/libc/stdlib/imaxabs.c",
+        "upstream-openbsd/lib/libc/stdlib/imaxdiv.c",
+        "upstream-openbsd/lib/libc/stdlib/labs.c",
+        "upstream-openbsd/lib/libc/stdlib/llabs.c",
+        "upstream-openbsd/lib/libc/stdlib/lsearch.c",
+        "upstream-openbsd/lib/libc/stdlib/reallocarray.c",
+        "upstream-openbsd/lib/libc/stdlib/remque.c",
+        "upstream-openbsd/lib/libc/stdlib/setenv.c",
+        "upstream-openbsd/lib/libc/stdlib/strtoimax.c",
+        "upstream-openbsd/lib/libc/stdlib/strtol.c",
+        "upstream-openbsd/lib/libc/stdlib/strtoll.c",
+        "upstream-openbsd/lib/libc/stdlib/strtoul.c",
+        "upstream-openbsd/lib/libc/stdlib/strtoull.c",
+        "upstream-openbsd/lib/libc/stdlib/strtoumax.c",
+        "upstream-openbsd/lib/libc/stdlib/system.c",
+        "upstream-openbsd/lib/libc/stdlib/tfind.c",
+        "upstream-openbsd/lib/libc/stdlib/tsearch.c",
+        "upstream-openbsd/lib/libc/string/strcasecmp.c",
+        "upstream-openbsd/lib/libc/string/strcspn.c",
+        "upstream-openbsd/lib/libc/string/strdup.c",
+        "upstream-openbsd/lib/libc/string/strndup.c",
+        "upstream-openbsd/lib/libc/string/strpbrk.c",
+        "upstream-openbsd/lib/libc/string/strsep.c",
+        "upstream-openbsd/lib/libc/string/strspn.c",
+        "upstream-openbsd/lib/libc/string/strstr.c",
+        "upstream-openbsd/lib/libc/string/strtok.c",
+        "upstream-openbsd/lib/libc/string/wmemcpy.c",
+        "upstream-openbsd/lib/libc/string/wcslcpy.c",
+        "upstream-openbsd/lib/libc/string/wcsstr.c",
+        "upstream-openbsd/lib/libc/string/wcswidth.c",
+    ],
+
+    cflags: [
+        "-Wno-sign-compare",
+        "-Wno-uninitialized",
+        "-Wno-unused-parameter",
+        "-include openbsd-compat.h",
+    ],
+
+    local_include_dirs: [
+        "private",
+        "stdio",
+        "upstream-openbsd/android/include",
+        "upstream-openbsd/lib/libc/include",
+        "upstream-openbsd/lib/libc/gdtoa/",
+    ],
+}
+
+// ========================================================
+// libc_openbsd.a - upstream OpenBSD C library code
+// ========================================================
+//
+// These files are built with the openbsd-compat.h header file
+// automatically included.
+cc_library_static {
+    defaults: ["libc_defaults"],
+    srcs: [
+        // These two depend on getentropy_linux.c, which isn't in libc_ndk.a.
+        "upstream-openbsd/lib/libc/crypt/arc4random.c",
+        "upstream-openbsd/lib/libc/crypt/arc4random_uniform.c",
+
+        // May be overriden by per-arch optimized versions
+        "upstream-openbsd/lib/libc/string/memchr.c",
+        "upstream-openbsd/lib/libc/string/memmove.c",
+        "upstream-openbsd/lib/libc/string/memrchr.c",
+        "upstream-openbsd/lib/libc/string/stpcpy.c",
+        "upstream-openbsd/lib/libc/string/stpncpy.c",
+        "upstream-openbsd/lib/libc/string/strcat.c",
+        "upstream-openbsd/lib/libc/string/strcpy.c",
+        "upstream-openbsd/lib/libc/string/strlcat.c",
+        "upstream-openbsd/lib/libc/string/strlcpy.c",
+        "upstream-openbsd/lib/libc/string/strncat.c",
+        "upstream-openbsd/lib/libc/string/strncmp.c",
+        "upstream-openbsd/lib/libc/string/strncpy.c",
+    ],
+    multilib: {
+        lib32: {
+            // LP32 cruft
+            srcs: ["upstream-openbsd/lib/libc/stdio/putw.c"],
+        },
+    },
+
+    arch: {
+        arm: {
+            exclude_srcs: [
+                "upstream-openbsd/lib/libc/string/strcpy.c",
+            ],
+            cortex_a7: {
+                exclude_srcs: [
+                    "upstream-openbsd/lib/libc/string/memmove.c",
+                    "upstream-openbsd/lib/libc/string/stpcpy.c",
+                    "upstream-openbsd/lib/libc/string/strcat.c",
+                ],
+            },
+            cortex_a53: {
+                exclude_srcs: [
+                    "upstream-openbsd/lib/libc/string/memmove.c",
+                    "upstream-openbsd/lib/libc/string/stpcpy.c",
+                    "upstream-openbsd/lib/libc/string/strcat.c",
+                ],
+            },
+            cortex_a53_a57: {
+                exclude_srcs: [
+                    "upstream-openbsd/lib/libc/string/memmove.c",
+                    "upstream-openbsd/lib/libc/string/stpcpy.c",
+                    "upstream-openbsd/lib/libc/string/strcat.c",
+                ],
+            },
+            cortex_a8: {
+                exclude_srcs: [
+                    "upstream-openbsd/lib/libc/string/memmove.c",
+                    "upstream-openbsd/lib/libc/string/stpcpy.c",
+                    "upstream-openbsd/lib/libc/string/strcat.c",
+                ],
+            },
+            cortex_a9: {
+                exclude_srcs: [
+                    "upstream-openbsd/lib/libc/string/memmove.c",
+                    "upstream-openbsd/lib/libc/string/stpcpy.c",
+                    "upstream-openbsd/lib/libc/string/strcat.c",
+                ],
+            },
+            cortex_a15: {
+                exclude_srcs: [
+                    "upstream-openbsd/lib/libc/string/memmove.c",
+                    "upstream-openbsd/lib/libc/string/stpcpy.c",
+                    "upstream-openbsd/lib/libc/string/strcat.c",
+                ],
+            },
+            denver: {
+                exclude_srcs: [
+                    "upstream-openbsd/lib/libc/string/memmove.c",
+                    "upstream-openbsd/lib/libc/string/stpcpy.c",
+                    "upstream-openbsd/lib/libc/string/strcat.c",
+                ],
+            },
+            krait: {
+                exclude_srcs: [
+                    "upstream-openbsd/lib/libc/string/memmove.c",
+                    "upstream-openbsd/lib/libc/string/stpcpy.c",
+                    "upstream-openbsd/lib/libc/string/strcat.c",
+                ],
+            },
+        },
+        arm64: {
+            exclude_srcs: [
+                "upstream-openbsd/lib/libc/string/memchr.c",
+                "upstream-openbsd/lib/libc/string/memmove.c",
+                "upstream-openbsd/lib/libc/string/stpcpy.c",
+                "upstream-openbsd/lib/libc/string/strcpy.c",
+                "upstream-openbsd/lib/libc/string/strncmp.c",
+            ],
+        },
+
+        x86: {
+            exclude_srcs: [
+                "upstream-openbsd/lib/libc/string/memchr.c",
+                "upstream-openbsd/lib/libc/string/memmove.c",
+                "upstream-openbsd/lib/libc/string/memrchr.c",
+                "upstream-openbsd/lib/libc/string/stpcpy.c",
+                "upstream-openbsd/lib/libc/string/stpncpy.c",
+                "upstream-openbsd/lib/libc/string/strcat.c",
+                "upstream-openbsd/lib/libc/string/strcpy.c",
+                "upstream-openbsd/lib/libc/string/strncmp.c",
+                "upstream-openbsd/lib/libc/string/strncpy.c",
+            ],
+            ssse3: {
+                exclude_srcs: [
+                    "upstream-openbsd/lib/libc/string/strlcat.c",
+                    "upstream-openbsd/lib/libc/string/strlcpy.c",
+                    "upstream-openbsd/lib/libc/string/strncat.c",
+                ],
+            },
+        },
+
+        x86_64: {
+            exclude_srcs: [
+                "upstream-openbsd/lib/libc/string/memmove.c",
+                "upstream-openbsd/lib/libc/string/stpcpy.c",
+                "upstream-openbsd/lib/libc/string/stpncpy.c",
+                "upstream-openbsd/lib/libc/string/strcat.c",
+                "upstream-openbsd/lib/libc/string/strcpy.c",
+                "upstream-openbsd/lib/libc/string/strlcat.c",
+                "upstream-openbsd/lib/libc/string/strlcpy.c",
+                "upstream-openbsd/lib/libc/string/strncat.c",
+                "upstream-openbsd/lib/libc/string/strncmp.c",
+                "upstream-openbsd/lib/libc/string/strncpy.c",
+            ],
+        },
+    },
+
+    cflags: [
+        "-Wno-sign-compare",
+        "-Wno-uninitialized",
+        "-Wno-unused-parameter",
+        "-include openbsd-compat.h",
+    ],
+
+    local_include_dirs: [
+        "private",
+        "stdio",
+        "upstream-openbsd/android/include",
+        "upstream-openbsd/lib/libc/include",
+        "upstream-openbsd/lib/libc/gdtoa/",
+    ],
+
+    name: "libc_openbsd",
+}
+
+// ========================================================
+// libc_gdtoa.a - upstream OpenBSD C library gdtoa code
+// ========================================================
+//
+// These files are built with the openbsd-compat.h header file
+// automatically included.
+
+cc_library_static {
+    defaults: ["libc_defaults"],
+    srcs: [
+        "upstream-openbsd/android/gdtoa_support.cpp",
+        "upstream-openbsd/lib/libc/gdtoa/dmisc.c",
+        "upstream-openbsd/lib/libc/gdtoa/dtoa.c",
+        "upstream-openbsd/lib/libc/gdtoa/gdtoa.c",
+        "upstream-openbsd/lib/libc/gdtoa/gethex.c",
+        "upstream-openbsd/lib/libc/gdtoa/gmisc.c",
+        "upstream-openbsd/lib/libc/gdtoa/hd_init.c",
+        "upstream-openbsd/lib/libc/gdtoa/hdtoa.c",
+        "upstream-openbsd/lib/libc/gdtoa/hexnan.c",
+        "upstream-openbsd/lib/libc/gdtoa/ldtoa.c",
+        "upstream-openbsd/lib/libc/gdtoa/misc.c",
+        "upstream-openbsd/lib/libc/gdtoa/smisc.c",
+        "upstream-openbsd/lib/libc/gdtoa/strtod.c",
+        "upstream-openbsd/lib/libc/gdtoa/strtodg.c",
+        "upstream-openbsd/lib/libc/gdtoa/strtof.c",
+        "upstream-openbsd/lib/libc/gdtoa/strtord.c",
+        "upstream-openbsd/lib/libc/gdtoa/sum.c",
+        "upstream-openbsd/lib/libc/gdtoa/ulp.c",
+    ],
+    multilib: {
+        lib64: {
+            srcs: ["upstream-openbsd/lib/libc/gdtoa/strtorQ.c"],
+        },
+    },
+
+    cflags: [
+        "-Wno-sign-compare",
+        "-Wno-uninitialized",
+        "-fvisibility=hidden",
+        "-include openbsd-compat.h",
+    ],
+
+    local_include_dirs: [
+        "private",
+        "upstream-openbsd/android/include",
+        "upstream-openbsd/lib/libc/include",
+    ],
+
+    name: "libc_gdtoa",
+}
+
+// ========================================================
+// libc_bionic.a - home-grown C library code
+// ========================================================
+
+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
+        // initialized, resulting in nullptr dereferences.
+        "bionic/getauxval.cpp",
+
+        // These four require getauxval, which isn't available on older
+        // platforms.
+        "bionic/getentropy_linux.c",
+        "bionic/sysconf.cpp",
+        "bionic/vdso.cpp",
+        "bionic/setjmp_cookie.cpp",
+
+        "bionic/__memcpy_chk.cpp",
+        "bionic/__memset_chk.cpp",
+        "bionic/__strcat_chk.cpp",
+        "bionic/__strcpy_chk.cpp",
+        "bionic/strchr.cpp",
+        "bionic/strnlen.c",
+        "bionic/strrchr.cpp",
+    ],
+    cflags: ["-Wframe-larger-than=2048"],
+
+    arch: {
+        arm: {
+            srcs: [
+                "arch-arm/generic/bionic/memcmp.S",
+                "arch-arm/generic/bionic/memcpy.S",
+                "arch-arm/generic/bionic/memset.S",
+                "arch-arm/generic/bionic/strcmp.S",
+                "arch-arm/generic/bionic/strcpy.S",
+                "arch-arm/generic/bionic/strlen.c",
+
+                "arch-arm/bionic/abort_arm.S",
+                "arch-arm/bionic/atomics_arm.c",
+                "arch-arm/bionic/__bionic_clone.S",
+                "arch-arm/bionic/_exit_with_stack_teardown.S",
+                "arch-arm/bionic/libgcc_compat.c",
+                "arch-arm/bionic/popcount_tab.c",
+                "arch-arm/bionic/__restore.S",
+                "arch-arm/bionic/setjmp.S",
+                "arch-arm/bionic/syscall.S",
+                "arch-arm/bionic/vfork.S",
+            ],
+            exclude_srcs: [
+                "bionic/__memcpy_chk.cpp",
+                "bionic/__memset_chk.cpp",
+            ],
+            cortex_a7: {
+                srcs: [
+                    "arch-arm/cortex-a7/bionic/memset.S",
+
+                    "arch-arm/cortex-a15/bionic/memcpy.S",
+                    "arch-arm/cortex-a15/bionic/stpcpy.S",
+                    "arch-arm/cortex-a15/bionic/strcat.S",
+                    "arch-arm/cortex-a15/bionic/__strcat_chk.S",
+                    "arch-arm/cortex-a15/bionic/strcmp.S",
+                    "arch-arm/cortex-a15/bionic/strcpy.S",
+                    "arch-arm/cortex-a15/bionic/__strcpy_chk.S",
+                    "arch-arm/cortex-a15/bionic/strlen.S",
+
+                    "arch-arm/denver/bionic/memmove.S",
+                ],
+                exclude_srcs: [
+                    "arch-arm/generic/bionic/memcpy.S",
+                    "arch-arm/generic/bionic/memset.S",
+                    "arch-arm/generic/bionic/strcmp.S",
+                    "arch-arm/generic/bionic/strcpy.S",
+                    "arch-arm/generic/bionic/strlen.c",
+                    "bionic/__strcat_chk.cpp",
+                    "bionic/__strcpy_chk.cpp",
+                ],
+            },
+            cortex_a53: {
+                srcs: [
+                    "arch-arm/cortex-a53/bionic/memcpy.S",
+                    "arch-arm/cortex-a53/bionic/__strcat_chk.S",
+                    "arch-arm/cortex-a53/bionic/__strcpy_chk.S",
+
+                    "arch-arm/cortex-a7/bionic/memset.S",
+
+                    "arch-arm/cortex-a15/bionic/stpcpy.S",
+                    "arch-arm/cortex-a15/bionic/strcat.S",
+                    "arch-arm/cortex-a15/bionic/strcmp.S",
+                    "arch-arm/cortex-a15/bionic/strcpy.S",
+                    "arch-arm/cortex-a15/bionic/strlen.S",
+
+                    "arch-arm/denver/bionic/memmove.S",
+                ],
+                exclude_srcs: [
+                    "arch-arm/generic/bionic/memcpy.S",
+                    "arch-arm/generic/bionic/memset.S",
+                    "arch-arm/generic/bionic/strcmp.S",
+                    "arch-arm/generic/bionic/strcpy.S",
+                    "arch-arm/generic/bionic/strlen.c",
+                    "bionic/__strcat_chk.cpp",
+                    "bionic/__strcpy_chk.cpp",
+                ],
+            },
+            cortex_a53_a57: {
+                srcs: [
+                    "arch-arm/cortex-a15/bionic/memcpy.S",
+                    "arch-arm/cortex-a15/bionic/memset.S",
+                    "arch-arm/cortex-a15/bionic/stpcpy.S",
+                    "arch-arm/cortex-a15/bionic/strcat.S",
+                    "arch-arm/cortex-a15/bionic/__strcat_chk.S",
+                    "arch-arm/cortex-a15/bionic/strcmp.S",
+                    "arch-arm/cortex-a15/bionic/strcpy.S",
+                    "arch-arm/cortex-a15/bionic/__strcpy_chk.S",
+                    "arch-arm/cortex-a15/bionic/strlen.S",
+
+                    "arch-arm/denver/bionic/memmove.S",
+                ],
+                exclude_srcs: [
+                    "arch-arm/generic/bionic/memcpy.S",
+                    "arch-arm/generic/bionic/memset.S",
+                    "arch-arm/generic/bionic/strcmp.S",
+                    "arch-arm/generic/bionic/strcpy.S",
+                    "arch-arm/generic/bionic/strlen.c",
+                    "bionic/__strcat_chk.cpp",
+                    "bionic/__strcpy_chk.cpp",
+                ],
+            },
+            cortex_a8: {
+                srcs: [
+                    "arch-arm/cortex-a15/bionic/memcpy.S",
+                    "arch-arm/cortex-a15/bionic/memset.S",
+                    "arch-arm/cortex-a15/bionic/stpcpy.S",
+                    "arch-arm/cortex-a15/bionic/strcat.S",
+                    "arch-arm/cortex-a15/bionic/__strcat_chk.S",
+                    "arch-arm/cortex-a15/bionic/strcmp.S",
+                    "arch-arm/cortex-a15/bionic/strcpy.S",
+                    "arch-arm/cortex-a15/bionic/__strcpy_chk.S",
+                    "arch-arm/cortex-a15/bionic/strlen.S",
+
+                    "arch-arm/denver/bionic/memmove.S",
+                ],
+                exclude_srcs: [
+                    "arch-arm/generic/bionic/memcpy.S",
+                    "arch-arm/generic/bionic/memset.S",
+                    "arch-arm/generic/bionic/strcmp.S",
+                    "arch-arm/generic/bionic/strcpy.S",
+                    "arch-arm/generic/bionic/strlen.c",
+                    "bionic/__strcat_chk.cpp",
+                    "bionic/__strcpy_chk.cpp",
+                ],
+            },
+            cortex_a9: {
+                srcs: [
+                    "arch-arm/cortex-a9/bionic/memcpy.S",
+                    "arch-arm/cortex-a9/bionic/memset.S",
+                    "arch-arm/cortex-a9/bionic/stpcpy.S",
+                    "arch-arm/cortex-a9/bionic/strcat.S",
+                    "arch-arm/cortex-a9/bionic/__strcat_chk.S",
+                    "arch-arm/cortex-a9/bionic/strcmp.S",
+                    "arch-arm/cortex-a9/bionic/strcpy.S",
+                    "arch-arm/cortex-a9/bionic/__strcpy_chk.S",
+                    "arch-arm/cortex-a9/bionic/strlen.S",
+
+                    "arch-arm/denver/bionic/memmove.S",
+                ],
+                exclude_srcs: [
+                    "arch-arm/generic/bionic/memcpy.S",
+                    "arch-arm/generic/bionic/memset.S",
+                    "arch-arm/generic/bionic/strcmp.S",
+                    "arch-arm/generic/bionic/strcpy.S",
+                    "arch-arm/generic/bionic/strlen.c",
+                    "bionic/__strcat_chk.cpp",
+                    "bionic/__strcpy_chk.cpp",
+                ],
+            },
+            cortex_a15: {
+                srcs: [
+                    "arch-arm/cortex-a15/bionic/memcpy.S",
+                    "arch-arm/cortex-a15/bionic/memset.S",
+                    "arch-arm/cortex-a15/bionic/stpcpy.S",
+                    "arch-arm/cortex-a15/bionic/strcat.S",
+                    "arch-arm/cortex-a15/bionic/__strcat_chk.S",
+                    "arch-arm/cortex-a15/bionic/strcmp.S",
+                    "arch-arm/cortex-a15/bionic/strcpy.S",
+                    "arch-arm/cortex-a15/bionic/__strcpy_chk.S",
+                    "arch-arm/cortex-a15/bionic/strlen.S",
+
+                    "arch-arm/denver/bionic/memmove.S",
+                ],
+                exclude_srcs: [
+                    "arch-arm/generic/bionic/memcpy.S",
+                    "arch-arm/generic/bionic/memset.S",
+                    "arch-arm/generic/bionic/strcmp.S",
+                    "arch-arm/generic/bionic/strcpy.S",
+                    "arch-arm/generic/bionic/strlen.c",
+                    "bionic/__strcat_chk.cpp",
+                    "bionic/__strcpy_chk.cpp",
+                ],
+            },
+            denver: {
+                srcs: [
+                    "arch-arm/denver/bionic/memcpy.S",
+                    "arch-arm/denver/bionic/memmove.S",
+                    "arch-arm/denver/bionic/memset.S",
+                    "arch-arm/denver/bionic/__strcat_chk.S",
+                    "arch-arm/denver/bionic/__strcpy_chk.S",
+
+                    // Use cortex-a15 versions of strcat/strcpy/strlen.
+                    "arch-arm/cortex-a15/bionic/stpcpy.S",
+                    "arch-arm/cortex-a15/bionic/strcat.S",
+                    "arch-arm/cortex-a15/bionic/strcmp.S",
+                    "arch-arm/cortex-a15/bionic/strcpy.S",
+                    "arch-arm/cortex-a15/bionic/strlen.S",
+                ],
+                exclude_srcs: [
+                    "arch-arm/generic/bionic/memcpy.S",
+                    "arch-arm/generic/bionic/memset.S",
+                    "arch-arm/generic/bionic/strcmp.S",
+                    "arch-arm/generic/bionic/strcpy.S",
+                    "arch-arm/generic/bionic/strlen.c",
+                    "bionic/__strcat_chk.cpp",
+                    "bionic/__strcpy_chk.cpp",
+                ],
+            },
+            krait: {
+                srcs: [
+                    "arch-arm/krait/bionic/memcpy.S",
+                    "arch-arm/krait/bionic/memset.S",
+                    "arch-arm/krait/bionic/strcmp.S",
+                    "arch-arm/krait/bionic/__strcat_chk.S",
+                    "arch-arm/krait/bionic/__strcpy_chk.S",
+
+                    // Use cortex-a15 versions of strcat/strcpy/strlen.
+                    "arch-arm/cortex-a15/bionic/stpcpy.S",
+                    "arch-arm/cortex-a15/bionic/strcat.S",
+                    "arch-arm/cortex-a15/bionic/strcpy.S",
+                    "arch-arm/cortex-a15/bionic/strlen.S",
+
+                    "arch-arm/denver/bionic/memmove.S",
+                ],
+                exclude_srcs: [
+                    "arch-arm/generic/bionic/memcpy.S",
+                    "arch-arm/generic/bionic/memset.S",
+                    "arch-arm/generic/bionic/strcmp.S",
+                    "arch-arm/generic/bionic/strcpy.S",
+                    "arch-arm/generic/bionic/strlen.c",
+                    "bionic/__strcat_chk.cpp",
+                    "bionic/__strcpy_chk.cpp",
+                ],
+            },
+
+        },
+        arm64: {
+            srcs: [
+                "arch-arm64/generic/bionic/memchr.S",
+                "arch-arm64/generic/bionic/memcmp.S",
+                "arch-arm64/generic/bionic/memcpy.S",
+                "arch-arm64/generic/bionic/memmove.S",
+                "arch-arm64/generic/bionic/memset.S",
+                "arch-arm64/generic/bionic/stpcpy.S",
+                "arch-arm64/generic/bionic/strchr.S",
+                "arch-arm64/generic/bionic/strcmp.S",
+                "arch-arm64/generic/bionic/strcpy.S",
+                "arch-arm64/generic/bionic/strlen.S",
+                "arch-arm64/generic/bionic/strncmp.S",
+                "arch-arm64/generic/bionic/strnlen.S",
+                "arch-arm64/generic/bionic/wmemmove.S",
+
+                "arch-arm64/bionic/__bionic_clone.S",
+                "arch-arm64/bionic/_exit_with_stack_teardown.S",
+                "arch-arm64/bionic/setjmp.S",
+                "arch-arm64/bionic/syscall.S",
+                "arch-arm64/bionic/vfork.S",
+            ],
+            exclude_srcs: [
+                "bionic/__memcpy_chk.cpp",
+                "bionic/strchr.cpp",
+                "bionic/strnlen.c",
+            ],
+            denver64: {
+                srcs: [
+                    "arch-arm64/denver64/bionic/memcpy.S",
+                    "arch-arm64/denver64/bionic/memset.S",
+                ],
+                exclude_srcs: [
+                    "arch-arm64/generic/bionic/memcpy.S",
+                    "arch-arm64/generic/bionic/memset.S",
+                ],
+            },
+        },
+
+        mips: {
+            srcs: [
+                "arch-mips/string/memcmp.c",
+                "arch-mips/string/memcpy.S",
+                "arch-mips/string/memset.S",
+                "arch-mips/string/strcmp.S",
+                "arch-mips/string/strlen.c",
+
+                "arch-mips/bionic/__bionic_clone.S",
+                "arch-mips/bionic/bzero.S",
+                "arch-mips/bionic/cacheflush.cpp",
+                "arch-mips/bionic/_exit_with_stack_teardown.S",
+                "arch-mips/bionic/setjmp.S",
+                "arch-mips/bionic/syscall.S",
+                "arch-mips/bionic/vfork.S",
+            ],
+            rev6: {
+                srcs: [
+                    "arch-mips/string/mips_strlen.c",
+                ],
+                exclude_srcs: [
+                    "arch-mips/string/strlen.c",
+                ],
+            },
+        },
+        mips64: {
+            srcs: [
+                "arch-mips/string/memcmp.c",
+                "arch-mips/string/memcpy.S",
+                "arch-mips/string/memset.S",
+                "arch-mips/string/strcmp.S",
+                "arch-mips/string/strlen.c",
+
+                "arch-mips64/bionic/__bionic_clone.S",
+                "arch-mips64/bionic/_exit_with_stack_teardown.S",
+                "arch-mips64/bionic/setjmp.S",
+                "arch-mips64/bionic/syscall.S",
+                "arch-mips64/bionic/vfork.S",
+                "arch-mips64/bionic/stat.cpp",
+            ],
+        },
+
+        x86: {
+            srcs: [
+                "arch-x86/generic/string/memcmp.S",
+                "arch-x86/generic/string/strcmp.S",
+                "arch-x86/generic/string/strncmp.S",
+                "arch-x86/generic/string/strcat.S",
+                "arch-x86/atom/string/sse2-memchr-atom.S",
+                "arch-x86/atom/string/sse2-memrchr-atom.S",
+                "arch-x86/atom/string/sse2-strchr-atom.S",
+                "arch-x86/atom/string/sse2-strnlen-atom.S",
+                "arch-x86/atom/string/sse2-strrchr-atom.S",
+                "arch-x86/atom/string/sse2-wcschr-atom.S",
+                "arch-x86/atom/string/sse2-wcsrchr-atom.S",
+                "arch-x86/atom/string/sse2-wcslen-atom.S",
+                "arch-x86/atom/string/sse2-wcscmp-atom.S",
+                "arch-x86/silvermont/string/sse2-bcopy-slm.S",
+                "arch-x86/silvermont/string/sse2-bzero-slm.S",
+                "arch-x86/silvermont/string/sse2-memcpy-slm.S",
+                "arch-x86/silvermont/string/sse2-memmove-slm.S",
+                "arch-x86/silvermont/string/sse2-memset-slm.S",
+                "arch-x86/silvermont/string/sse2-stpcpy-slm.S",
+                "arch-x86/silvermont/string/sse2-stpncpy-slm.S",
+                "arch-x86/silvermont/string/sse2-strcpy-slm.S",
+                "arch-x86/silvermont/string/sse2-strlen-slm.S",
+                "arch-x86/silvermont/string/sse2-strncpy-slm.S",
+
+                "arch-x86/bionic/__bionic_clone.S",
+                "arch-x86/bionic/_exit_with_stack_teardown.S",
+                "arch-x86/bionic/libgcc_compat.c",
+                "arch-x86/bionic/__restore.S",
+                "arch-x86/bionic/setjmp.S",
+                "arch-x86/bionic/syscall.S",
+                "arch-x86/bionic/vfork.S",
+            ],
+
+            exclude_srcs: [
+                "bionic/strchr.cpp",
+                "bionic/strnlen.c",
+                "bionic/strrchr.cpp",
+            ],
+            atom: {
+                srcs: [
+                    "arch-x86/atom/string/sse2-bzero-atom.S",
+                    "arch-x86/atom/string/sse2-memset-atom.S",
+                    "arch-x86/atom/string/sse2-strlen-atom.S",
+                    "arch-x86/atom/string/ssse3-bcopy-atom.S",
+                    "arch-x86/atom/string/ssse3-memcmp-atom.S",
+                    "arch-x86/atom/string/ssse3-memcpy-atom.S",
+                    "arch-x86/atom/string/ssse3-memmove-atom.S",
+                    "arch-x86/atom/string/ssse3-strcpy-atom.S",
+                    "arch-x86/atom/string/ssse3-strncpy-atom.S",
+                    "arch-x86/atom/string/ssse3-wmemcmp-atom.S",
+                ],
+                exclude_srcs: [
+                    "arch-x86/generic/string/memcmp.S",
+                    "arch-x86/silvermont/string/sse2-bcopy-slm.S",
+                    "arch-x86/silvermont/string/sse2-bzero-slm.S",
+                    "arch-x86/silvermont/string/sse2-memcpy-slm.S",
+                    "arch-x86/silvermont/string/sse2-memmove-slm.S",
+                    "arch-x86/silvermont/string/sse2-memset-slm.S",
+                    "arch-x86/silvermont/string/sse2-strcpy-slm.S",
+                    "arch-x86/silvermont/string/sse2-strlen-slm.S",
+                    "arch-x86/silvermont/string/sse2-strncpy-slm.S",
+                ],
+            },
+            ssse3: {
+                srcs: [
+                    "arch-x86/atom/string/ssse3-strncat-atom.S",
+                    "arch-x86/atom/string/ssse3-strlcat-atom.S",
+                    "arch-x86/atom/string/ssse3-strlcpy-atom.S",
+                    "arch-x86/atom/string/ssse3-strcat-atom.S",
+                    "arch-x86/atom/string/ssse3-strcmp-atom.S",
+                    "arch-x86/atom/string/ssse3-strncmp-atom.S",
+                    "arch-x86/atom/string/ssse3-wcscat-atom.S",
+                    "arch-x86/atom/string/ssse3-wcscpy-atom.S",
+                ],
+                exclude_srcs: [
+                    "arch-x86/generic/string/strcmp.S",
+                    "arch-x86/generic/string/strncmp.S",
+                    "arch-x86/generic/string/strcat.S",
+                ],
+            },
+            sse4: {
+                srcs: [
+                    "arch-x86/silvermont/string/sse4-memcmp-slm.S",
+                    "arch-x86/silvermont/string/sse4-wmemcmp-slm.S",
+                ],
+                exclude_srcs: [
+                    "arch-x86/generic/string/memcmp.S",
+                ],
+            },
+        },
+        x86_64: {
+            srcs: [
+                "arch-x86_64/string/sse2-memcpy-slm.S",
+                "arch-x86_64/string/sse2-memmove-slm.S",
+                "arch-x86_64/string/sse2-memset-slm.S",
+                "arch-x86_64/string/sse2-stpcpy-slm.S",
+                "arch-x86_64/string/sse2-stpncpy-slm.S",
+                "arch-x86_64/string/sse2-strcat-slm.S",
+                "arch-x86_64/string/sse2-strcpy-slm.S",
+                "arch-x86_64/string/sse2-strlcat-slm.S",
+                "arch-x86_64/string/sse2-strlcpy-slm.S",
+                "arch-x86_64/string/sse2-strlen-slm.S",
+                "arch-x86_64/string/sse2-strncat-slm.S",
+                "arch-x86_64/string/sse2-strncpy-slm.S",
+                "arch-x86_64/string/sse4-memcmp-slm.S",
+                "arch-x86_64/string/ssse3-strcmp-slm.S",
+                "arch-x86_64/string/ssse3-strncmp-slm.S",
+
+                "arch-x86_64/bionic/__bionic_clone.S",
+                "arch-x86_64/bionic/_exit_with_stack_teardown.S",
+                "arch-x86_64/bionic/__restore_rt.S",
+                "arch-x86_64/bionic/setjmp.S",
+                "arch-x86_64/bionic/syscall.S",
+                "arch-x86_64/bionic/vfork.S",
+            ],
+        },
+    },
+
+    cppflags: ["-Wold-style-cast"],
+    include_dirs: ["bionic/libstdc++/include"],
+    name: "libc_bionic",
+}
+
+// ========================================================
+// libc_bionic_ndk.a- The portions of libc_bionic that can
+// be safely used in libc_ndk.a (no troublesome global data
+// or constructors).
+// ========================================================
+cc_library_static {
+    defaults: ["libc_defaults"],
+    srcs: [
+        "bionic/abort.cpp",
+        "bionic/accept.cpp",
+        "bionic/accept4.cpp",
+        "bionic/access.cpp",
+        "bionic/arpa_inet.cpp",
+        "bionic/assert.cpp",
+        "bionic/atof.cpp",
+        "bionic/bionic_netlink.cpp",
+        "bionic/bionic_systrace.cpp",
+        "bionic/bionic_time_conversions.cpp",
+        "bionic/brk.cpp",
+        "bionic/c16rtomb.cpp",
+        "bionic/c32rtomb.cpp",
+        "bionic/chmod.cpp",
+        "bionic/chown.cpp",
+        "bionic/clearenv.cpp",
+        "bionic/clock.cpp",
+        "bionic/clock_getcpuclockid.cpp",
+        "bionic/clock_nanosleep.cpp",
+        "bionic/clone.cpp",
+        "bionic/close.cpp",
+        "bionic/__cmsg_nxthdr.cpp",
+        "bionic/connect.cpp",
+        "bionic/ctype.cpp",
+        "bionic/dirent.cpp",
+        "bionic/dup2.cpp",
+        "bionic/epoll_create.cpp",
+        "bionic/epoll_pwait.cpp",
+        "bionic/epoll_wait.cpp",
+        "bionic/__errno.cpp",
+        "bionic/error.cpp",
+        "bionic/eventfd_read.cpp",
+        "bionic/eventfd_write.cpp",
+        "bionic/faccessat.cpp",
+        "bionic/fchmod.cpp",
+        "bionic/fchmodat.cpp",
+        "bionic/ffs.cpp",
+        "bionic/fgetxattr.cpp",
+        "bionic/flistxattr.cpp",
+        "bionic/flockfile.cpp",
+        "bionic/fpclassify.cpp",
+        "bionic/fsetxattr.cpp",
+        "bionic/ftruncate.cpp",
+        "bionic/futimens.cpp",
+        "bionic/getcwd.cpp",
+        "bionic/gethostname.cpp",
+        "bionic/getpgrp.cpp",
+        "bionic/getpid.cpp",
+        "bionic/gettid.cpp",
+        "bionic/__gnu_basename.cpp",
+        "bionic/ifaddrs.cpp",
+        "bionic/inotify_init.cpp",
+        "bionic/ioctl.cpp",
+        "bionic/lchown.cpp",
+        "bionic/lfs64_support.cpp",
+        "bionic/__libc_current_sigrtmax.cpp",
+        "bionic/__libc_current_sigrtmin.cpp",
+        "bionic/libc_init_common.cpp",
+        "bionic/libc_logging.cpp",
+        "bionic/libgen.cpp",
+        "bionic/link.cpp",
+        "bionic/locale.cpp",
+        "bionic/lockf.cpp",
+        "bionic/lstat.cpp",
+        "bionic/malloc_info.cpp",
+        "bionic/mbrtoc16.cpp",
+        "bionic/mbrtoc32.cpp",
+        "bionic/mbstate.cpp",
+        "bionic/mempcpy.cpp",
+        "bionic/mkdir.cpp",
+        "bionic/mkfifo.cpp",
+        "bionic/mknod.cpp",
+        "bionic/mntent.cpp",
+        "bionic/mremap.cpp",
+        "bionic/NetdClientDispatch.cpp",
+        "bionic/net_if.cpp",
+        "bionic/netinet_in.cpp",
+        "bionic/open.cpp",
+        "bionic/pathconf.cpp",
+        "bionic/pause.cpp",
+        "bionic/pipe.cpp",
+        "bionic/poll.cpp",
+        "bionic/posix_fadvise.cpp",
+        "bionic/posix_fallocate.cpp",
+        "bionic/posix_madvise.cpp",
+        "bionic/posix_timers.cpp",
+        "bionic/ptrace.cpp",
+        "bionic/pty.cpp",
+        "bionic/raise.cpp",
+        "bionic/rand.cpp",
+        "bionic/readlink.cpp",
+        "bionic/reboot.cpp",
+        "bionic/recv.cpp",
+        "bionic/rename.cpp",
+        "bionic/rmdir.cpp",
+        "bionic/scandir.cpp",
+        "bionic/sched_getaffinity.cpp",
+        "bionic/sched_getcpu.cpp",
+        "bionic/semaphore.cpp",
+        "bionic/send.cpp",
+        "bionic/setegid.cpp",
+        "bionic/__set_errno.cpp",
+        "bionic/seteuid.cpp",
+        "bionic/setpgrp.cpp",
+        "bionic/sigaction.cpp",
+        "bionic/sigaddset.cpp",
+        "bionic/sigdelset.cpp",
+        "bionic/sigemptyset.cpp",
+        "bionic/sigfillset.cpp",
+        "bionic/sigismember.cpp",
+        "bionic/signal.cpp",
+        "bionic/signalfd.cpp",
+        "bionic/sigpending.cpp",
+        "bionic/sigprocmask.cpp",
+        "bionic/sigqueue.cpp",
+        "bionic/sigsuspend.cpp",
+        "bionic/sigtimedwait.cpp",
+        "bionic/sigwait.cpp",
+        "bionic/sigwaitinfo.cpp",
+        "bionic/socket.cpp",
+        "bionic/stat.cpp",
+        "bionic/statvfs.cpp",
+        "bionic/strchrnul.cpp",
+        "bionic/strerror.cpp",
+        "bionic/strerror_r.cpp",
+        "bionic/strsignal.cpp",
+        "bionic/strtold.cpp",
+        "bionic/stubs.cpp",
+        "bionic/symlink.cpp",
+        "bionic/sysinfo.cpp",
+        "bionic/syslog.cpp",
+        "bionic/sys_siglist.c",
+        "bionic/sys_signame.c",
+        "bionic/system_properties.cpp",
+        "bionic/tdestroy.cpp",
+        "bionic/termios.cpp",
+        "bionic/thread_private.cpp",
+        "bionic/tmpfile.cpp",
+        "bionic/umount.cpp",
+        "bionic/unlink.cpp",
+        "bionic/utimes.cpp",
+        "bionic/wait.cpp",
+        "bionic/wchar.cpp",
+        "bionic/wctype.cpp",
+        "bionic/wmempcpy.cpp",
+    ],
+    cflags: ["-Wframe-larger-than=2048"],
+
+    multilib: {
+        lib32: {
+            // LP32 cruft
+            srcs: ["bionic/mmap.cpp"],
+        },
+    },
+
+    cppflags: ["-Wold-style-cast"],
+    local_include_dirs: ["stdio"],
+    include_dirs: ["bionic/libstdc++/include"],
+    name: "libc_bionic_ndk",
+}
+
+// ========================================================
+// libc_pthread.a - pthreads parts that previously lived in
+// libc_bionic.a. Relocated to their own library because
+// they can't be included in libc_ndk.a (as they layout of
+// pthread_t has changed over the years and has ABI
+// compatibility issues).
+// ========================================================
+
+cc_library_static {
+    defaults: ["libc_defaults"],
+    srcs: [
+        "bionic/pthread_atfork.cpp",
+        "bionic/pthread_attr.cpp",
+        "bionic/pthread_barrier.cpp",
+        "bionic/pthread_cond.cpp",
+        "bionic/pthread_create.cpp",
+        "bionic/pthread_detach.cpp",
+        "bionic/pthread_equal.cpp",
+        "bionic/pthread_exit.cpp",
+        "bionic/pthread_getcpuclockid.cpp",
+        "bionic/pthread_getschedparam.cpp",
+        "bionic/pthread_gettid_np.cpp",
+        "bionic/pthread_internal.cpp",
+        "bionic/pthread_join.cpp",
+        "bionic/pthread_key.cpp",
+        "bionic/pthread_kill.cpp",
+        "bionic/pthread_mutex.cpp",
+        "bionic/pthread_once.cpp",
+        "bionic/pthread_rwlock.cpp",
+        "bionic/pthread_self.cpp",
+        "bionic/pthread_setname_np.cpp",
+        "bionic/pthread_setschedparam.cpp",
+        "bionic/pthread_sigmask.cpp",
+        "bionic/pthread_spinlock.cpp",
+    ],
+    cflags: ["-Wframe-larger-than=2048"],
+
+    cppflags: ["-Wold-style-cast"],
+    include_dirs: ["bionic/libstdc++/include"],
+    name: "libc_pthread",
+}
+
+// ========================================================
+// libc_cxa.a - Things traditionally in libstdc++
+// ========================================================
+
+cc_library_static {
+    defaults: ["libc_defaults"],
+    srcs: [
+        "bionic/__cxa_guard.cpp",
+        "bionic/__cxa_pure_virtual.cpp",
+        "bionic/new.cpp",
+    ],
+    cflags: ["-fvisibility=hidden"],
+    include_dirs: ["bionic/libstdc++/include"],
+    name: "libc_cxa",
+    clang: true, // GCC refuses to hide new/delete
+
+    // b/17574078: Need to disable coverage until we have a prebuilt libprofile_rt.
+    // Since this is a static library built with clang, it needs to link
+    // libprofile_rt when it is linked into the final binary. Since the final binary
+    // is built with GCC, it won't link libprofile_rt. We can't very easily just add
+    // libprofile_rt to all link lines the way we've done for libgcov because
+    // libprofile_rt isn't prebuilt, and it would be tricky to write a rule that
+    // would make sure libprofile_rt is built.
+    native_coverage: false,
+}
+
+// ========================================================
+// libc_syscalls.a
+// ========================================================
+
+cc_library_static {
+    arch: {
+        arm: {
+            srcs: ["arch-arm/syscalls/**/*.S"],
+        },
+        arm64: {
+            srcs: ["arch-arm64/syscalls/**/*.S"],
+        },
+        mips: {
+            srcs: ["arch-mips/syscalls/**/*.S"],
+        },
+        mips64: {
+            srcs: ["arch-mips64/syscalls/**/*.S"],
+        },
+        x86: {
+            srcs: ["arch-x86/syscalls/**/*.S"],
+        },
+        x86_64: {
+            srcs: ["arch-x86_64/syscalls/**/*.S"],
+        },
+    },
+    name: "libc_syscalls",
+}
+
+// ========================================================
+// libc_aeabi.a
+// This is an LP32 ARM-only library that needs to be built with -fno-builtin
+// to avoid infinite recursion. For the other architectures we just build an
+// empty library to keep this makefile simple.
+// ========================================================
+
+cc_library_static {
+    defaults: ["libc_defaults"],
+    arch: {
+        arm: {
+            srcs: ["arch-arm/bionic/__aeabi.c"],
+        },
+    },
+    name: "libc_aeabi",
+    cflags: ["-fno-builtin"],
+}
+
+// ========================================================
+// libc_ndk.a
+// Compatibility library for the NDK. This library contains
+// all the parts of libc that are safe to statically link.
+// We can't safely statically link things that can only run
+// on a certain version of the OS. Examples include
+// anything that talks to netd (a large portion of the DNS
+// code) and anything that is dependent on the layout of a
+// data structure that has changed across releases (such as
+// pthread_t).
+// ========================================================
+
+cc_library_static {
+    name: "libc_ndk",
+    defaults: ["libc_defaults"],
+    srcs: libc_common_src_files + ["bionic/malloc_common.cpp"],
+    multilib: {
+        lib32: {
+            srcs: libc_common_src_files_32,
+        },
+    },
+    arch: {
+        arm: {
+            srcs: [
+                "arch-arm/bionic/exidx_dynamic.c",
+                "arch-common/bionic/crtbegin_so.c",
+                "arch-arm/bionic/atexit_legacy.c",
+                "arch-common/bionic/crtend_so.S",
+            ],
+            whole_static_libs: ["libc_aeabi"],
+        },
+    },
+
+    cflags: [
+        "-fvisibility=hidden",
+        "-DLIBC_STATIC",
+    ],
+
+    whole_static_libs: [
+        "libc_bionic_ndk",
+        "libc_cxa",
+        "libc_freebsd",
+        "libc_gdtoa",
+        "libc_malloc",
+        "libc_netbsd",
+        "libc_openbsd_ndk",
+        "libc_stack_protector",
+        "libc_syscalls",
+        "libc_tzcode",
+        "libm",
+        "libjemalloc",
+    ],
+}
+
+// ========================================================
+// libc_common.a
+// ========================================================
+
+cc_library_static {
+    defaults: ["libc_defaults"],
+    srcs: libc_common_src_files,
+    multilib: {
+        lib32: {
+            srcs: libc_common_src_files_32,
+        },
+    },
+    name: "libc_common",
+
+    whole_static_libs: [
+        "libc_bionic",
+        "libc_bionic_ndk",
+        "libc_cxa",
+        "libc_dns",
+        "libc_freebsd",
+        "libc_gdtoa",
+        "libc_malloc",
+        "libc_netbsd",
+        "libc_openbsd",
+        "libc_openbsd_ndk",
+        "libc_pthread",
+        "libc_stack_protector",
+        "libc_syscalls",
+        "libc_tzcode",
+    ],
+
+    arch: {
+        arm: {
+            whole_static_libs: ["libc_aeabi"],
+        },
+    },
+}
+
+// ========================================================
+// libc_nomalloc.a
+// ========================================================
+//
+// This is a version of the static C library that does not
+// include malloc. It's useful in situations when the user wants
+// to provide their own malloc implementation, or wants to
+// explicitly disallow the use of malloc, such as in the
+// dynamic linker.
+
+cc_library_static {
+    defaults: ["libc_defaults"],
+    srcs: [
+        "bionic/dl_iterate_phdr_static.cpp",
+    ],
+
+    arch: {
+        arm: {
+            srcs: ["arch-arm/bionic/exidx_static.c"],
+        },
+    },
+
+    cflags: ["-DLIBC_STATIC"],
+
+    name: "libc_nomalloc",
+
+    whole_static_libs: [
+        "libc_common",
+        "libc_init_static",
+    ],
+}
+
+// ========================================================
+// libc_malloc.a: the _prefixed_ malloc functions (like dlcalloc).
+// ========================================================
+cc_library_static {
+    defaults: ["libc_defaults"],
+    srcs: ["bionic/jemalloc_wrapper.cpp"],
+    cflags: ["-fvisibility=hidden"],
+
+    name: "libc_malloc",
+}
+
+// ========================================================
+// libc.a + libc.so
+// ========================================================
+cc_library {
+    defaults: ["libc_defaults"],
+    name: "libc",
+    product_variables: {
+        platform_sdk_version: {
+            asflags: ["-DPLATFORM_SDK_VERSION=%d"],
+        },
+    },
+    srcs: ["bionic/malloc_common.cpp"],
+    static: {
+        srcs: [
+            "bionic/dl_iterate_phdr_static.cpp",
+            "bionic/libc_init_static.cpp",
+        ],
+        cflags: ["-DLIBC_STATIC"],
+        whole_static_libs: ["libc_init_static"],
+    },
+    shared: {
+        srcs: [
+            "arch-common/bionic/crtbegin_so.c",
+            "arch-common/bionic/crtbrand.S",
+            "bionic/libc_init_dynamic.cpp",
+            "bionic/NetdClient.cpp",
+            "arch-common/bionic/crtend_so.S",
+        ],
+    },
+
+    required: ["tzdata"],
+
+    // Leave the symbols in the shared library so that stack unwinders can produce
+    // meaningful name resolution.
+    strip: "keep_symbols",
+
+    // WARNING: The only library libc.so should depend on is libdl.so!  If you add other libraries,
+    // make sure to add -Wl,--exclude-libs=libgcc.a to the LOCAL_LDFLAGS for those libraries.  This
+    // ensures that symbols that are pulled into those new libraries from libgcc.a are not declared
+    // external; if that were the case, then libc would not pull those symbols from libgcc.a as it
+    // should, instead relying on the external symbols from the dependent libraries.  That would
+    // create a "cloaked" dependency on libgcc.a in libc though the libraries, which is not what
+    // you wanted!
+
+    shared_libs: ["libdl"],
+    whole_static_libs: ["libc_common", "libjemalloc"],
+
+    // We'd really like to do this for all architectures, but since this wasn't done
+    // before, these symbols must continue to be exported on LP32 for binary
+    // compatibility.
+    multilib: {
+        lib64: {
+            ldflags: ["-Wl,--exclude-libs,libgcc.a"],
+        },
+    },
+
+    nocrt: true,
+
+    arch: {
+        arm: {
+            //TODO: This is to work around b/24465209. Remove after root cause is fixed
+            ldflags: ["-Wl,--hash-style=both"],
+
+            // Don't re-export new/delete and friends, even if the compiler really wants to.
+            version_script: "libc.arm.map",
+            product_variables: {
+                brillo: {
+                    version_script: "libc.arm.brillo.map",
+                },
+            },
+
+            shared: {
+                srcs: ["arch-arm/bionic/exidx_dynamic.c"],
+            },
+            static: {
+                srcs: ["arch-arm/bionic/exidx_static.c"],
+            },
+
+            // special for arm
+            cflags: ["-DCRT_LEGACY_WORKAROUND"],
+            srcs: [
+                "arch-arm/bionic/atexit_legacy.c",
+            ],
+        },
+        arm64: {
+            // Don't re-export new/delete and friends, even if the compiler really wants to.
+            version_script: "libc.arm64.map",
+        },
+        mips: {
+            // Don't re-export new/delete and friends, even if the compiler really wants to.
+            version_script: "libc.mips.map",
+            product_variables: {
+                brillo: {
+                    version_script: "libc.mips.brillo.map",
+                },
+            },
+        },
+        mips64: {
+            // Don't re-export new/delete and friends, even if the compiler really wants to.
+            version_script: "libc.mips64.map",
+        },
+        x86: {
+            //TODO: This is to work around b/24465209. Remove after root cause is fixed
+            ldflags: ["-Wl,--hash-style=both"],
+
+            // Don't re-export new/delete and friends, even if the compiler really wants to.
+            version_script: "libc.x86.map",
+            product_variables: {
+                brillo: {
+                    version_script: "libc.x86.brillo.map",
+                },
+            },
+        },
+        x86_64: {
+            // Don't re-export new/delete and friends, even if the compiler really wants to.
+            version_script: "libc.x86_64.map",
+        },
+    },
+}
+
+// ========================================================
+// libc_logging.a
+// ========================================================
+cc_library_static {
+    defaults: ["libc_defaults"],
+
+    srcs: [
+        "bionic/libc_logging.cpp",
+    ],
+
+    name: "libc_logging",
+}
+
+// ========================================================
+// libstdc++.so + libstdc++.a
+// ========================================================
+cc_library {
+    defaults: ["libc_defaults"],
+    include_dirs: ["bionic/libstdc++/include"],
+    srcs: [
+        "bionic/__cxa_guard.cpp",
+        "bionic/__cxa_pure_virtual.cpp",
+        "bionic/new.cpp",
+    ],
+    name: "libstdc++",
+    system_shared_libs: ["libc"],
+    shared: {
+        static_libs: ["libc_logging"],
+    },
+
+    //TODO: This is to work around b/24465209. Remove after root cause is fixed
+    arch: {
+        arm: {
+            ldflags: ["-Wl,--hash-style=both"],
+        },
+        x86: {
+            ldflags: ["-Wl,--hash-style=both"],
+        },
+    },
+}
+
+cc_defaults {
+    name: "crt_defaults",
+
+    no_default_compiler_flags: true,
+
+    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"],
+        },
+    },
+    clang: false,
+}
+
+cc_defaults {
+    name: "crt_so_defaults",
+
+    arch: {
+        mips: {
+            cflags: ["-fPIC"],
+        },
+        mips64: {
+            cflags: ["-fPIC"],
+        },
+        x86: {
+            cflags: ["-fPIC"],
+        },
+        x86_64: {
+            cflags: ["-fPIC"],
+        },
+    },
+}
+
+// Android.mk:start
+// # crt obj files
+// # ========================================================
+// # crtbrand.c needs <stdint.h> and a #define for the platform SDK version.
+// libc_crt_target_cflags := \
+//    -I$(LOCAL_PATH)/include \
+//    -DPLATFORM_SDK_VERSION=$(PLATFORM_SDK_VERSION) \
+//
+// my_2nd_arch_prefix :=
+// include $(LOCAL_PATH)/arch-$(TARGET_ARCH)/$(TARGET_ARCH).mk
+// include $(LOCAL_PATH)/crt.mk
+// ifdef TARGET_2ND_ARCH
+// my_2nd_arch_prefix := $(TARGET_2ND_ARCH_VAR_PREFIX)
+// include $(LOCAL_PATH)/arch-$(TARGET_2ND_ARCH)/$(TARGET_2ND_ARCH).mk
+// include $(LOCAL_PATH)/crt.mk
+// my_2nd_arch_prefix :=
+// endif
+//
+// include $(call all-makefiles-under,$(LOCAL_PATH))
+// Android.mk:end
+cc_object {
+    name: "crtbrand",
+    local_include_dirs: ["include"],
+    product_variables: {
+        platform_sdk_version: {
+            asflags: ["-DPLATFORM_SDK_VERSION=%d"],
+        },
+    },
+    srcs: ["arch-common/bionic/crtbrand.S"],
+
+    defaults: [
+        "crt_defaults",
+        "crt_so_defaults",
+    ],
+}
+
+// Android.mk:ignore
+cc_object {
+    name: "crtbegin_so1",
+    local_include_dirs: ["include"],
+    srcs: ["arch-common/bionic/crtbegin_so.c"],
+
+    defaults: [
+        "crt_defaults",
+        "crt_so_defaults",
+    ],
+}
+
+// Android.mk:ignore
+cc_object {
+    name: "crtbegin_so",
+
+    defaults: [
+        "crt_defaults",
+        "crt_so_defaults",
+    ],
+    deps: [
+        "crtbegin_so1",
+        "crtbrand",
+    ],
+}
+
+// Android.mk:ignore
+cc_object {
+    name: "crtend_so",
+    local_include_dirs: ["include"],
+    srcs: ["arch-common/bionic/crtend_so.S"],
+
+    defaults: [
+        "crt_defaults",
+        "crt_so_defaults",
+    ],
+}
+
+// Android.mk:ignore
+cc_object {
+    name: "crtbegin_static1",
+    local_include_dirs: ["include"],
+    srcs: ["arch-common/bionic/crtbegin.c"],
+
+    arch: {
+        arm64: {
+            srcs: [
+                "arch-arm64/bionic/crtbegin.c",
+            ],
+            exclude_srcs: [
+                "arch-common/bionic/crtbegin.c",
+            ],
+        },
+        mips: {
+            srcs: [
+                "arch-mips/bionic/crtbegin.c",
+            ],
+            exclude_srcs: [
+                "arch-common/bionic/crtbegin.c",
+            ],
+        },
+        mips64: {
+            srcs: [
+                "arch-mips64/bionic/crtbegin.c",
+            ],
+            exclude_srcs: [
+                "arch-common/bionic/crtbegin.c",
+            ],
+        },
+    },
+
+    defaults: ["crt_defaults"],
+}
+
+// Android.mk:ignore
+cc_object {
+    name: "crtbegin_static",
+
+    deps: [
+        "crtbegin_static1",
+        "crtbrand",
+    ],
+    defaults: ["crt_defaults"],
+}
+
+// Android.mk:ignore
+cc_object {
+    name: "crtbegin_dynamic1",
+    local_include_dirs: ["include"],
+    srcs: ["arch-common/bionic/crtbegin.c"],
+
+    arch: {
+        arm64: {
+            srcs: [
+                "arch-arm64/bionic/crtbegin.c",
+            ],
+            exclude_srcs: [
+                "arch-common/bionic/crtbegin.c",
+            ],
+        },
+        mips: {
+            srcs: [
+                "arch-mips/bionic/crtbegin.c",
+            ],
+            exclude_srcs: [
+                "arch-common/bionic/crtbegin.c",
+            ],
+        },
+        mips64: {
+            srcs: [
+                "arch-mips64/bionic/crtbegin.c",
+            ],
+            exclude_srcs: [
+                "arch-common/bionic/crtbegin.c",
+            ],
+        },
+    },
+    defaults: ["crt_defaults"],
+}
+
+// Android.mk:ignore
+cc_object {
+    name: "crtbegin_dynamic",
+
+    deps: [
+        "crtbegin_dynamic1",
+        "crtbrand",
+    ],
+    defaults: ["crt_defaults"],
+}
+
+// Android.mk:ignore
+cc_object {
+    // We rename crtend.o to crtend_android.o to avoid a
+    // name clash between gcc and bionic.
+    name: "crtend_android",
+    local_include_dirs: ["include"],
+    srcs: ["arch-common/bionic/crtend.S"],
+
+    defaults: ["crt_defaults"],
+}
diff --git a/libc/Android.mk b/libc/Android.mk
index f0c5e9f..1ca84c1 100644
--- a/libc/Android.mk
+++ b/libc/Android.mk
@@ -1,6 +1,6 @@
 LOCAL_PATH := $(call my-dir)
 
-bionic_coverage := false
+bionic_coverage ?= false
 
 # Make everything depend on any changes to included makefiles.
 libc_common_additional_dependencies := $(LOCAL_PATH)/Android.mk
@@ -39,15 +39,11 @@
 # Define the common source files for all the libc instances
 # =========================================================
 libc_common_src_files := \
-    bionic/bindresvport.c \
     bionic/ether_aton.c \
     bionic/ether_ntoa.c \
     bionic/fts.c \
     bionic/getpriority.c \
-    bionic/if_indextoname.c \
-    bionic/if_nametoindex.c \
     bionic/initgroups.c \
-    bionic/ioctl.c \
     bionic/isatty.c \
     bionic/memmem.c \
     bionic/pututline.c \
@@ -57,11 +53,11 @@
     bionic/siginterrupt.c \
     bionic/sigsetmask.c \
     bionic/system_properties_compat.c \
-    stdio/findfp.c \
     stdio/fread.c \
+    stdio/refill.c \
     stdio/snprintf.c\
     stdio/sprintf.c \
-    stdio/stdio.c \
+    stdio/stdio.cpp \
     stdio/stdio_ext.cpp \
     stdlib/atexit.c \
     stdlib/exit.c \
@@ -70,12 +66,17 @@
 libc_common_src_files += \
     bionic/__FD_chk.cpp \
     bionic/__fgets_chk.cpp \
+    bionic/__fread_chk.cpp \
+    bionic/__fwrite_chk.cpp \
+    bionic/__getcwd_chk.cpp \
     bionic/__memchr_chk.cpp \
     bionic/__memmove_chk.cpp \
     bionic/__memrchr_chk.cpp \
     bionic/__poll_chk.cpp \
     bionic/__pread64_chk.cpp \
     bionic/__pread_chk.cpp \
+    bionic/__pwrite64_chk.cpp \
+    bionic/__pwrite_chk.cpp \
     bionic/__read_chk.cpp \
     bionic/__readlink_chk.cpp \
     bionic/__readlinkat_chk.cpp \
@@ -92,14 +93,17 @@
     bionic/__umask_chk.cpp \
     bionic/__vsnprintf_chk.cpp \
     bionic/__vsprintf_chk.cpp \
+    bionic/__write_chk.cpp
 
 libc_bionic_ndk_src_files := \
     bionic/abort.cpp \
     bionic/accept.cpp \
     bionic/accept4.cpp \
     bionic/access.cpp \
+    bionic/arpa_inet.cpp \
     bionic/assert.cpp \
     bionic/atof.cpp \
+    bionic/bionic_netlink.cpp \
     bionic/bionic_systrace.cpp \
     bionic/bionic_time_conversions.cpp \
     bionic/brk.cpp \
@@ -130,6 +134,7 @@
     bionic/fchmodat.cpp \
     bionic/ffs.cpp \
     bionic/fgetxattr.cpp \
+    bionic/flistxattr.cpp \
     bionic/flockfile.cpp \
     bionic/fpclassify.cpp \
     bionic/fsetxattr.cpp \
@@ -141,7 +146,9 @@
     bionic/getpid.cpp \
     bionic/gettid.cpp \
     bionic/__gnu_basename.cpp \
+    bionic/ifaddrs.cpp \
     bionic/inotify_init.cpp \
+    bionic/ioctl.cpp \
     bionic/lchown.cpp \
     bionic/lfs64_support.cpp \
     bionic/__libc_current_sigrtmax.cpp \
@@ -151,6 +158,7 @@
     bionic/libgen.cpp \
     bionic/link.cpp \
     bionic/locale.cpp \
+    bionic/lockf.cpp \
     bionic/lstat.cpp \
     bionic/malloc_info.cpp \
     bionic/mbrtoc16.cpp \
@@ -161,7 +169,10 @@
     bionic/mkfifo.cpp \
     bionic/mknod.cpp \
     bionic/mntent.cpp \
+    bionic/mremap.cpp \
     bionic/NetdClientDispatch.cpp \
+    bionic/net_if.cpp \
+    bionic/netinet_in.cpp \
     bionic/open.cpp \
     bionic/pathconf.cpp \
     bionic/pause.cpp \
@@ -207,6 +218,7 @@
     bionic/socket.cpp \
     bionic/stat.cpp \
     bionic/statvfs.cpp \
+    bionic/strchrnul.cpp \
     bionic/strerror.cpp \
     bionic/strerror_r.cpp \
     bionic/strsignal.cpp \
@@ -232,9 +244,11 @@
 
 libc_bionic_src_files :=
 
-# The fork implementation depends on pthread data, so we can't include it in
-# libc_ndk.a.
-libc_bionic_src_files += bionic/fork.cpp
+# The following implementations depend on pthread data, so we can't include
+# them in libc_ndk.a.
+libc_bionic_src_files += \
+    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
@@ -242,10 +256,20 @@
 # dereferences.
 libc_bionic_src_files += bionic/getauxval.cpp
 
-# These three require getauxval, which isn't available on older platforms.
+# These four require getauxval, which isn't available on older platforms.
 libc_bionic_src_files += bionic/getentropy_linux.c
 libc_bionic_src_files += bionic/sysconf.cpp
 libc_bionic_src_files += bionic/vdso.cpp
+libc_bionic_src_files += bionic/setjmp_cookie.cpp
+
+libc_bionic_src_files += \
+    bionic/__memcpy_chk.cpp \
+    bionic/__memset_chk.cpp \
+    bionic/__strcat_chk.cpp \
+    bionic/__strcpy_chk.cpp \
+    bionic/strchr.cpp \
+    bionic/strnlen.c \
+    bionic/strrchr.cpp \
 
 libc_cxa_src_files := \
     bionic/__cxa_guard.cpp \
@@ -256,30 +280,33 @@
     upstream-freebsd/lib/libc/gen/ldexp.c \
     upstream-freebsd/lib/libc/gen/sleep.c \
     upstream-freebsd/lib/libc/gen/usleep.c \
-    upstream-freebsd/lib/libc/stdlib/abs.c \
     upstream-freebsd/lib/libc/stdlib/getopt_long.c \
-    upstream-freebsd/lib/libc/stdlib/imaxabs.c \
-    upstream-freebsd/lib/libc/stdlib/imaxdiv.c \
-    upstream-freebsd/lib/libc/stdlib/labs.c \
-    upstream-freebsd/lib/libc/stdlib/llabs.c \
     upstream-freebsd/lib/libc/stdlib/qsort.c \
     upstream-freebsd/lib/libc/stdlib/quick_exit.c \
     upstream-freebsd/lib/libc/stdlib/realpath.c \
     upstream-freebsd/lib/libc/string/wcpcpy.c \
     upstream-freebsd/lib/libc/string/wcpncpy.c \
     upstream-freebsd/lib/libc/string/wcscasecmp.c \
+    upstream-freebsd/lib/libc/string/wcscat.c \
+    upstream-freebsd/lib/libc/string/wcschr.c \
+    upstream-freebsd/lib/libc/string/wcscmp.c \
+    upstream-freebsd/lib/libc/string/wcscpy.c \
     upstream-freebsd/lib/libc/string/wcscspn.c \
     upstream-freebsd/lib/libc/string/wcsdup.c \
     upstream-freebsd/lib/libc/string/wcslcat.c \
+    upstream-freebsd/lib/libc/string/wcslen.c \
     upstream-freebsd/lib/libc/string/wcsncasecmp.c \
     upstream-freebsd/lib/libc/string/wcsncat.c \
     upstream-freebsd/lib/libc/string/wcsncmp.c \
     upstream-freebsd/lib/libc/string/wcsncpy.c \
     upstream-freebsd/lib/libc/string/wcsnlen.c \
     upstream-freebsd/lib/libc/string/wcspbrk.c \
+    upstream-freebsd/lib/libc/string/wcsrchr.c \
     upstream-freebsd/lib/libc/string/wcsspn.c \
     upstream-freebsd/lib/libc/string/wcstok.c \
     upstream-freebsd/lib/libc/string/wmemchr.c \
+    upstream-freebsd/lib/libc/string/wmemcmp.c \
+    upstream-freebsd/lib/libc/string/wmemmove.c \
     upstream-freebsd/lib/libc/string/wmemset.c \
 
 libc_upstream_netbsd_src_files := \
@@ -344,11 +371,25 @@
     $(libc_upstream_openbsd_gdtoa_src_files) \
     upstream-openbsd/lib/libc/gdtoa/strtorQ.c \
 
-# These two depend on getentropy_linux.cpp, which isn't in libc_ndk.a.
+# These two depend on getentropy_linux.c, which isn't in libc_ndk.a.
 libc_upstream_openbsd_src_files := \
     upstream-openbsd/lib/libc/crypt/arc4random.c \
     upstream-openbsd/lib/libc/crypt/arc4random_uniform.c \
 
+libc_upstream_openbsd_src_files += \
+    upstream-openbsd/lib/libc/string/memchr.c \
+    upstream-openbsd/lib/libc/string/memmove.c \
+    upstream-openbsd/lib/libc/string/memrchr.c \
+    upstream-openbsd/lib/libc/string/stpcpy.c \
+    upstream-openbsd/lib/libc/string/stpncpy.c \
+    upstream-openbsd/lib/libc/string/strcat.c \
+    upstream-openbsd/lib/libc/string/strcpy.c \
+    upstream-openbsd/lib/libc/string/strlcat.c \
+    upstream-openbsd/lib/libc/string/strlcpy.c \
+    upstream-openbsd/lib/libc/string/strncat.c \
+    upstream-openbsd/lib/libc/string/strncmp.c \
+    upstream-openbsd/lib/libc/string/strncpy.c \
+
 libc_upstream_openbsd_ndk_src_files := \
     upstream-openbsd/lib/libc/compat-43/killpg.c \
     upstream-openbsd/lib/libc/gen/alarm.c \
@@ -391,46 +432,35 @@
     upstream-openbsd/lib/libc/locale/wctomb.c \
     upstream-openbsd/lib/libc/net/htonl.c \
     upstream-openbsd/lib/libc/net/htons.c \
-    upstream-openbsd/lib/libc/net/inet_addr.c \
     upstream-openbsd/lib/libc/net/inet_lnaof.c \
     upstream-openbsd/lib/libc/net/inet_makeaddr.c \
     upstream-openbsd/lib/libc/net/inet_netof.c \
-    upstream-openbsd/lib/libc/net/inet_network.c \
     upstream-openbsd/lib/libc/net/inet_ntoa.c \
     upstream-openbsd/lib/libc/net/inet_ntop.c \
     upstream-openbsd/lib/libc/net/inet_pton.c \
     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/asprintf.c \
     upstream-openbsd/lib/libc/stdio/clrerr.c \
     upstream-openbsd/lib/libc/stdio/dprintf.c \
-    upstream-openbsd/lib/libc/stdio/fclose.c \
-    upstream-openbsd/lib/libc/stdio/fdopen.c \
     upstream-openbsd/lib/libc/stdio/feof.c \
     upstream-openbsd/lib/libc/stdio/ferror.c \
     upstream-openbsd/lib/libc/stdio/fflush.c \
     upstream-openbsd/lib/libc/stdio/fgetc.c \
     upstream-openbsd/lib/libc/stdio/fgetln.c \
-    upstream-openbsd/lib/libc/stdio/fgetpos.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/fileno.c \
     upstream-openbsd/lib/libc/stdio/flags.c \
     upstream-openbsd/lib/libc/stdio/fmemopen.c \
-    upstream-openbsd/lib/libc/stdio/fopen.c \
     upstream-openbsd/lib/libc/stdio/fprintf.c \
     upstream-openbsd/lib/libc/stdio/fpurge.c \
     upstream-openbsd/lib/libc/stdio/fputc.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/freopen.c \
     upstream-openbsd/lib/libc/stdio/fscanf.c \
-    upstream-openbsd/lib/libc/stdio/fseek.c \
-    upstream-openbsd/lib/libc/stdio/fsetpos.c \
-    upstream-openbsd/lib/libc/stdio/ftell.c \
-    upstream-openbsd/lib/libc/stdio/funopen.c \
     upstream-openbsd/lib/libc/stdio/fvwrite.c \
     upstream-openbsd/lib/libc/stdio/fwalk.c \
     upstream-openbsd/lib/libc/stdio/fwide.c \
@@ -455,7 +485,6 @@
     upstream-openbsd/lib/libc/stdio/puts.c \
     upstream-openbsd/lib/libc/stdio/putwc.c \
     upstream-openbsd/lib/libc/stdio/putwchar.c \
-    upstream-openbsd/lib/libc/stdio/refill.c \
     upstream-openbsd/lib/libc/stdio/remove.c \
     upstream-openbsd/lib/libc/stdio/rewind.c \
     upstream-openbsd/lib/libc/stdio/rget.c \
@@ -489,11 +518,16 @@
     upstream-openbsd/lib/libc/stdio/wprintf.c \
     upstream-openbsd/lib/libc/stdio/wscanf.c \
     upstream-openbsd/lib/libc/stdio/wsetup.c \
+    upstream-openbsd/lib/libc/stdlib/abs.c \
     upstream-openbsd/lib/libc/stdlib/atoi.c \
     upstream-openbsd/lib/libc/stdlib/atol.c \
     upstream-openbsd/lib/libc/stdlib/atoll.c \
     upstream-openbsd/lib/libc/stdlib/getenv.c \
     upstream-openbsd/lib/libc/stdlib/insque.c \
+    upstream-openbsd/lib/libc/stdlib/imaxabs.c \
+    upstream-openbsd/lib/libc/stdlib/imaxdiv.c \
+    upstream-openbsd/lib/libc/stdlib/labs.c \
+    upstream-openbsd/lib/libc/stdlib/llabs.c \
     upstream-openbsd/lib/libc/stdlib/lsearch.c \
     upstream-openbsd/lib/libc/stdlib/reallocarray.c \
     upstream-openbsd/lib/libc/stdlib/remque.c \
@@ -524,6 +558,7 @@
 libc_pthread_src_files := \
     bionic/pthread_atfork.cpp \
     bionic/pthread_attr.cpp \
+    bionic/pthread_barrier.cpp \
     bionic/pthread_cond.cpp \
     bionic/pthread_create.cpp \
     bionic/pthread_detach.cpp \
@@ -543,9 +578,7 @@
     bionic/pthread_setname_np.cpp \
     bionic/pthread_setschedparam.cpp \
     bionic/pthread_sigmask.cpp \
-
-libc_thread_atexit_impl_src_files := \
-    bionic/__cxa_thread_atexit_impl.cpp \
+    bionic/pthread_spinlock.cpp \
 
 libc_arch_static_src_files := \
     bionic/dl_iterate_phdr_static.cpp \
@@ -575,15 +608,23 @@
     -D_LIBC=1 \
     -Wall -Wextra -Wunused \
 
-ifneq ($(TARGET_USES_LOGD),false)
-libc_common_cflags += -DTARGET_USES_LOGD
+use_clang := $(USE_CLANG_PLATFORM_BUILD)
+
+# Clang/llvm has incompatible long double (fp128) for x86_64.
+# https://llvm.org/bugs/show_bug.cgi?id=23897
+ifeq ($(TARGET_ARCH),x86_64)
+  use_clang := false
 endif
 
-use_clang := $(USE_CLANG_PLATFORM_BUILD)
-ifeq ($(use_clang),)
+# b/25291096, Clang/llvm compiled libc.so for mips/mips64 failed to boot.
+ifeq ($(TARGET_ARCH),$(filter $(TARGET_ARCH),mips mips64))
   use_clang := false
 endif
 
+ifeq ($(use_clang),)
+  use_clang := true
+endif
+
 # Try to catch typical 32-bit assumptions that break with 64-bit pointers.
 libc_common_cflags += \
     -Werror=pointer-to-int-cast \
@@ -595,21 +636,8 @@
   libc_common_cflags += -DDEBUG
 endif
 
-ifeq ($(MALLOC_IMPL),dlmalloc)
-  libc_common_cflags += -DUSE_DLMALLOC
-  libc_malloc_src := bionic/dlmalloc.c
-else
-  libc_common_cflags += -DUSE_JEMALLOC
-  libc_malloc_src := bionic/jemalloc_wrapper.cpp
-  libc_common_c_includes += external/jemalloc/include
-endif
-
-# To customize dlmalloc's alignment, set BOARD_MALLOC_ALIGNMENT in
-# the appropriate BoardConfig.mk file.
-#
-ifneq ($(BOARD_MALLOC_ALIGNMENT),)
-  libc_common_cflags += -DMALLOC_ALIGNMENT=$(BOARD_MALLOC_ALIGNMENT)
-endif
+libc_malloc_src := bionic/jemalloc_wrapper.cpp
+libc_common_c_includes += external/jemalloc/include
 
 # Define some common conlyflags
 libc_common_conlyflags := \
@@ -617,7 +645,6 @@
 
 # Define some common cppflags
 libc_common_cppflags := \
-    -std=gnu++11
 
 # Define some common includes
 # ========================================================
@@ -642,13 +669,21 @@
 # libc_stack_protector.a - stack protector code
 # ========================================================
 #
-# The stack protector code needs to be compiled
-# with -fno-stack-protector, since it modifies the
-# stack canary.
+# Code that implements the stack protector (or that runs
+# before TLS has been set up) needs to be compiled with
+# -fno-stack-protector, since it accesses the stack canary
+# TLS slot.
 
 include $(CLEAR_VARS)
 
-LOCAL_SRC_FILES := bionic/__stack_chk_fail.cpp
+LOCAL_SRC_FILES := \
+    bionic/__libc_init_main_thread.cpp \
+    bionic/__stack_chk_fail.cpp \
+
+LOCAL_SRC_FILES_arm64 := arch-arm64/bionic/__set_tls.c
+LOCAL_SRC_FILES_x86 := arch-x86/bionic/__set_tls.c
+LOCAL_SRC_FILES_x86_64 := arch-x86_64/bionic/__set_tls.c
+
 LOCAL_CFLAGS := $(libc_common_cflags) -fno-stack-protector
 LOCAL_CONLYFLAGS := $(libc_common_conlyflags)
 LOCAL_CPPFLAGS := $(libc_common_cppflags)
@@ -658,7 +693,31 @@
 LOCAL_ADDITIONAL_DEPENDENCIES := $(libc_common_additional_dependencies)
 LOCAL_CXX_STL := none
 LOCAL_SYSTEM_SHARED_LIBRARIES :=
-LOCAL_ADDRESS_SANITIZER := false
+LOCAL_SANITIZE := never
+LOCAL_NATIVE_COVERAGE := $(bionic_coverage)
+
+$(eval $(call patch-up-arch-specific-flags,LOCAL_CFLAGS,libc_common_cflags))
+include $(BUILD_STATIC_LIBRARY)
+
+
+# libc_init_static.cpp also needs to be built without stack protector,
+# because it's responsible for setting up TLS for static executables.
+# This isn't the case for dynamic executables because the dynamic linker
+# has already set up the main thread's TLS.
+
+include $(CLEAR_VARS)
+
+LOCAL_SRC_FILES := bionic/libc_init_static.cpp
+LOCAL_CFLAGS := $(libc_common_cflags) -fno-stack-protector
+LOCAL_CONLYFLAGS := $(libc_common_conlyflags)
+LOCAL_CPPFLAGS := $(libc_common_cppflags)
+LOCAL_C_INCLUDES := $(libc_common_c_includes)
+LOCAL_MODULE := libc_init_static
+LOCAL_CLANG := $(use_clang)
+LOCAL_ADDITIONAL_DEPENDENCIES := $(libc_common_additional_dependencies)
+LOCAL_CXX_STL := none
+LOCAL_SYSTEM_SHARED_LIBRARIES :=
+LOCAL_SANITIZE := never
 LOCAL_NATIVE_COVERAGE := $(bionic_coverage)
 
 $(eval $(call patch-up-arch-specific-flags,LOCAL_CFLAGS,libc_common_cflags))
@@ -677,17 +736,22 @@
 
 LOCAL_CFLAGS := $(libc_common_cflags) \
     -fvisibility=hidden \
+    -Wno-unused-parameter \
 
 # Don't use ridiculous amounts of stack.
 LOCAL_CFLAGS += -DALL_STATE
 # Include tzsetwall, timelocal, timegm, time2posix, and posix2time.
 LOCAL_CFLAGS += -DSTD_INSPIRED
+# Obviously, we want to be thread-safe.
+LOCAL_CFLAGS += -DTHREAD_SAFE
 # The name of the tm_gmtoff field in our struct tm.
 LOCAL_CFLAGS += -DTM_GMTOFF=tm_gmtoff
 # Where we store our tzdata.
 LOCAL_CFLAGS += -DTZDIR=\"/system/usr/share/zoneinfo\"
 # Include timezone and daylight globals.
 LOCAL_CFLAGS += -DUSG_COMPAT=1
+# Use the empty string (instead of "   ") as the timezone abbreviation fallback.
+LOCAL_CFLAGS += -DWILDABBR=\"\"
 LOCAL_CFLAGS += -DNO_RUN_TIME_WARNINGS_ABOUT_YEAR_2000_PROBLEMS_THANK_YOU
 LOCAL_CFLAGS += -Dlint
 
@@ -699,7 +763,7 @@
 LOCAL_ADDITIONAL_DEPENDENCIES := $(libc_common_additional_dependencies)
 LOCAL_CXX_STL := none
 LOCAL_SYSTEM_SHARED_LIBRARIES :=
-LOCAL_ADDRESS_SANITIZER := false
+LOCAL_SANITIZE := never
 LOCAL_NATIVE_COVERAGE := $(bionic_coverage)
 
 $(eval $(call patch-up-arch-specific-flags,LOCAL_CFLAGS,libc_common_cflags))
@@ -718,12 +782,6 @@
     upstream-netbsd/lib/libc/isc/ev_timers.c \
     upstream-netbsd/lib/libc/resolv/mtctxres.c \
 
-# We use the OpenBSD res_random.
-LOCAL_CFLAGS += \
-    -Dres_randomid=__res_randomid
-LOCAL_SRC_FILES += \
-    upstream-openbsd/lib/libc/net/res_random.c \
-
 LOCAL_CFLAGS += \
     $(libc_common_cflags) \
     -DANDROID_CHANGES \
@@ -745,7 +803,7 @@
 LOCAL_ADDITIONAL_DEPENDENCIES := $(libc_common_additional_dependencies)
 LOCAL_CXX_STL := none
 LOCAL_SYSTEM_SHARED_LIBRARIES :=
-LOCAL_ADDRESS_SANITIZER := false
+LOCAL_SANITIZE := never
 LOCAL_NATIVE_COVERAGE := $(bionic_coverage)
 
 $(eval $(call patch-up-arch-specific-flags,LOCAL_CFLAGS,libc_common_cflags))
@@ -778,11 +836,11 @@
 LOCAL_ADDITIONAL_DEPENDENCIES := $(libc_common_additional_dependencies)
 LOCAL_CXX_STL := none
 LOCAL_SYSTEM_SHARED_LIBRARIES :=
-LOCAL_ADDRESS_SANITIZER := false
+LOCAL_SANITIZE := never
 LOCAL_NATIVE_COVERAGE := $(bionic_coverage)
 
 $(eval $(call patch-up-arch-specific-flags,LOCAL_CFLAGS,libc_common_cflags))
-$(eval $(call patch-up-arch-specific-flags,LOCAL_SRC_FILES,libc_freebsd_src_files))
+$(eval $(call patch-up-arch-specific-flags,LOCAL_SRC_FILES_EXCLUDE,libc_freebsd_src_files_exclude))
 include $(BUILD_STATIC_LIBRARY)
 
 
@@ -798,7 +856,9 @@
 LOCAL_SRC_FILES := $(libc_upstream_netbsd_src_files)
 LOCAL_CFLAGS := \
     $(libc_common_cflags) \
-    -Wno-sign-compare -Wno-uninitialized \
+    -Wno-sign-compare \
+    -Wno-uninitialized \
+    -Wno-unused-parameter \
     -DPOSIX_MISTAKE \
     -include netbsd-compat.h \
 
@@ -813,7 +873,7 @@
 LOCAL_ADDITIONAL_DEPENDENCIES := $(libc_common_additional_dependencies)
 LOCAL_CXX_STL := none
 LOCAL_SYSTEM_SHARED_LIBRARIES :=
-LOCAL_ADDRESS_SANITIZER := false
+LOCAL_SANITIZE := never
 LOCAL_NATIVE_COVERAGE := $(bionic_coverage)
 
 $(eval $(call patch-up-arch-specific-flags,LOCAL_CFLAGS,libc_common_cflags))
@@ -854,7 +914,7 @@
 LOCAL_ADDITIONAL_DEPENDENCIES := $(libc_common_additional_dependencies)
 LOCAL_CXX_STL := none
 LOCAL_SYSTEM_SHARED_LIBRARIES :=
-LOCAL_ADDRESS_SANITIZER := false
+LOCAL_SANITIZE := never
 LOCAL_NATIVE_COVERAGE := $(bionic_coverage)
 
 $(eval $(call patch-up-arch-specific-flags,LOCAL_CFLAGS,libc_common_cflags))
@@ -892,11 +952,12 @@
 LOCAL_ADDITIONAL_DEPENDENCIES := $(libc_common_additional_dependencies)
 LOCAL_CXX_STL := none
 LOCAL_SYSTEM_SHARED_LIBRARIES :=
-LOCAL_ADDRESS_SANITIZER := false
+LOCAL_SANITIZE := never
 LOCAL_NATIVE_COVERAGE := $(bionic_coverage)
 
 $(eval $(call patch-up-arch-specific-flags,LOCAL_CFLAGS,libc_common_cflags))
 $(eval $(call patch-up-arch-specific-flags,LOCAL_SRC_FILES,libc_openbsd_src_files))
+$(eval $(call patch-up-arch-specific-flags,LOCAL_SRC_FILES_EXCLUDE,libc_openbsd_src_files_exclude))
 include $(BUILD_STATIC_LIBRARY)
 
 
@@ -930,7 +991,7 @@
 LOCAL_ADDITIONAL_DEPENDENCIES := $(libc_common_additional_dependencies)
 LOCAL_CXX_STL := none
 LOCAL_SYSTEM_SHARED_LIBRARIES :=
-LOCAL_ADDRESS_SANITIZER := false
+LOCAL_SANITIZE := never
 LOCAL_NATIVE_COVERAGE := $(bionic_coverage)
 
 $(eval $(call patch-up-arch-specific-flags,LOCAL_CFLAGS,libc_common_cflags))
@@ -955,11 +1016,12 @@
 LOCAL_ADDITIONAL_DEPENDENCIES := $(libc_common_additional_dependencies)
 LOCAL_CXX_STL := none
 LOCAL_SYSTEM_SHARED_LIBRARIES :=
-LOCAL_ADDRESS_SANITIZER := false
+LOCAL_SANITIZE := never
 LOCAL_NATIVE_COVERAGE := $(bionic_coverage)
 
 $(eval $(call patch-up-arch-specific-flags,LOCAL_CFLAGS,libc_common_cflags))
 $(eval $(call patch-up-arch-specific-flags,LOCAL_SRC_FILES,libc_bionic_src_files))
+$(eval $(call patch-up-arch-specific-flags,LOCAL_SRC_FILES_EXCLUDE,libc_bionic_src_files_exclude))
 include $(BUILD_STATIC_LIBRARY)
 
 
@@ -983,31 +1045,13 @@
 LOCAL_ADDITIONAL_DEPENDENCIES := $(libc_common_additional_dependencies)
 LOCAL_CXX_STL := none
 LOCAL_SYSTEM_SHARED_LIBRARIES :=
-LOCAL_ADDRESS_SANITIZER := false
+LOCAL_SANITIZE := never
 LOCAL_NATIVE_COVERAGE := $(bionic_coverage)
 
 $(eval $(call patch-up-arch-specific-flags,LOCAL_CFLAGS,libc_common_cflags))
 $(eval $(call patch-up-arch-specific-flags,LOCAL_SRC_FILES,libc_bionic_ndk_src_files))
 include $(BUILD_STATIC_LIBRARY)
 
-include $(CLEAR_VARS)
-LOCAL_SRC_FILES := $(libc_thread_atexit_impl_src_files)
-LOCAL_CFLAGS := $(libc_common_cflags) -Wframe-larger-than=2048
-
-LOCAL_CONLYFLAGS := $(libc_common_conlyflags)
-LOCAL_CPPFLAGS := $(libc_common_cppflags) -Wold-style-cast
-LOCAL_C_INCLUDES := $(libc_common_c_includes)
-LOCAL_MODULE := libc_thread_atexit_impl
-# TODO: Clang tries to use __tls_get_addr which is not supported yet
-# remove after it is implemented.
-LOCAL_CLANG := false
-LOCAL_ADDITIONAL_DEPENDENCIES := $(libc_common_additional_dependencies)
-LOCAL_CXX_STL := none
-LOCAL_SYSTEM_SHARED_LIBRARIES :=
-LOCAL_ADDRESS_SANITIZER := false
-LOCAL_NATIVE_COVERAGE := $(bionic_coverage)
-
-include $(BUILD_STATIC_LIBRARY)
 
 # ========================================================
 # libc_pthread.a - pthreads parts that previously lived in
@@ -1031,7 +1075,7 @@
 LOCAL_ADDITIONAL_DEPENDENCIES := $(libc_common_additional_dependencies)
 LOCAL_CXX_STL := none
 LOCAL_SYSTEM_SHARED_LIBRARIES :=
-LOCAL_ADDRESS_SANITIZER := false
+LOCAL_SANITIZE := never
 LOCAL_NATIVE_COVERAGE := $(bionic_coverage)
 
 include $(BUILD_STATIC_LIBRARY)
@@ -1055,7 +1099,7 @@
 LOCAL_ADDITIONAL_DEPENDENCIES := $(libc_common_additional_dependencies)
 LOCAL_CXX_STL := none
 LOCAL_SYSTEM_SHARED_LIBRARIES :=
-LOCAL_ADDRESS_SANITIZER := false
+LOCAL_SANITIZE := never
 # b/17574078: Need to disable coverage until we have a prebuilt libprofile_rt.
 # Since this is a static library built with clang, it needs to link
 # libprofile_rt when it is linked into the final binary. Since the final binary
@@ -1083,7 +1127,7 @@
 LOCAL_ADDITIONAL_DEPENDENCIES := $(libc_common_additional_dependencies)
 LOCAL_CXX_STL := none
 LOCAL_SYSTEM_SHARED_LIBRARIES :=
-LOCAL_ADDRESS_SANITIZER := false
+LOCAL_SANITIZE := never
 LOCAL_NATIVE_COVERAGE := $(bionic_coverage)
 
 include $(BUILD_STATIC_LIBRARY)
@@ -1105,7 +1149,7 @@
 LOCAL_ADDITIONAL_DEPENDENCIES := $(libc_common_additional_dependencies)
 LOCAL_CXX_STL := none
 LOCAL_SYSTEM_SHARED_LIBRARIES :=
-LOCAL_ADDRESS_SANITIZER := false
+LOCAL_SANITIZE := never
 LOCAL_NATIVE_COVERAGE := $(bionic_coverage)
 
 include $(BUILD_STATIC_LIBRARY)
@@ -1131,7 +1175,7 @@
 LOCAL_CFLAGS := $(libc_common_cflags) -fvisibility=hidden -O0
 LOCAL_CPPFLAGS := $(libc_common_cppflags)
 LOCAL_C_INCLUDES := $(libc_common_c_includes)
-LOCAL_ADDRESS_SANITIZER := false
+LOCAL_SANITIZE := never
 LOCAL_NATIVE_COVERAGE := $(bionic_coverage)
 LOCAL_SYSTEM_SHARED_LIBRARIES :=
 
@@ -1139,7 +1183,7 @@
     $(libc_common_src_files) \
     $(libc_arch_dynamic_src_files) \
     $(libc_ndk_stub_src_files) \
-    bionic/malloc_debug_common.cpp \
+    bionic/malloc_common.cpp \
 
 LOCAL_SRC_FILES_arm += \
     arch-common/bionic/crtbegin_so.c \
@@ -1161,14 +1205,11 @@
     libc_syscalls \
     libc_tzcode \
     libm \
+    libjemalloc \
 
 LOCAL_WHOLE_STATIC_LIBRARIES_arm := libc_aeabi
 LOCAL_CXX_STL := none
 
-ifneq ($(MALLOC_IMPL),dlmalloc)
-LOCAL_WHOLE_STATIC_LIBRARIES += libjemalloc
-endif
-
 $(eval $(call patch-up-arch-specific-flags,LOCAL_CFLAGS,libc_common_cflags))
 $(eval $(call patch-up-arch-specific-flags,LOCAL_SRC_FILES,libc_common_src_files))
 $(eval $(call patch-up-arch-specific-flags,LOCAL_SRC_FILES,libc_arch_dynamic_src_files))
@@ -1205,7 +1246,6 @@
     libc_pthread \
     libc_stack_protector \
     libc_syscalls \
-    libc_thread_atexit_impl \
     libc_tzcode \
 
 LOCAL_WHOLE_STATIC_LIBRARIES_arm := libc_aeabi
@@ -1215,7 +1255,7 @@
 
 # TODO: split out the asflags.
 LOCAL_ASFLAGS := $(LOCAL_CFLAGS)
-LOCAL_ADDRESS_SANITIZER := false
+LOCAL_SANITIZE := never
 LOCAL_NATIVE_COVERAGE := $(bionic_coverage)
 
 $(eval $(call patch-up-arch-specific-flags,LOCAL_CFLAGS,libc_common_cflags))
@@ -1238,7 +1278,6 @@
 
 LOCAL_SRC_FILES := \
     $(libc_arch_static_src_files) \
-    bionic/libc_init_static.cpp
 
 LOCAL_C_INCLUDES := $(libc_common_c_includes)
 LOCAL_CFLAGS := $(libc_common_cflags) \
@@ -1250,10 +1289,10 @@
 LOCAL_MODULE := libc_nomalloc
 LOCAL_CLANG := $(use_clang)
 LOCAL_ADDITIONAL_DEPENDENCIES := $(libc_common_additional_dependencies)
-LOCAL_WHOLE_STATIC_LIBRARIES := libc_common
+LOCAL_WHOLE_STATIC_LIBRARIES := libc_common libc_init_static
 LOCAL_CXX_STL := none
 LOCAL_SYSTEM_SHARED_LIBRARIES :=
-LOCAL_ADDRESS_SANITIZER := false
+LOCAL_SANITIZE := never
 LOCAL_NATIVE_COVERAGE := $(bionic_coverage)
 
 $(eval $(call patch-up-arch-specific-flags,LOCAL_CFLAGS,libc_common_cflags))
@@ -1276,7 +1315,7 @@
 LOCAL_MODULE := libc_malloc
 LOCAL_CLANG := $(use_clang)
 LOCAL_CXX_STL := none
-LOCAL_ADDRESS_SANITIZER := false
+LOCAL_SANITIZE := never
 LOCAL_NATIVE_COVERAGE := $(bionic_coverage)
 LOCAL_ADDITIONAL_DEPENDENCIES := $(libc_common_additional_dependencies)
 include $(BUILD_STATIC_LIBRARY)
@@ -1289,7 +1328,7 @@
 
 LOCAL_SRC_FILES := \
     $(libc_arch_static_src_files) \
-    bionic/malloc_debug_common.cpp \
+    bionic/malloc_common.cpp \
     bionic/libc_init_static.cpp \
 
 LOCAL_CFLAGS := $(libc_common_cflags) \
@@ -1301,15 +1340,11 @@
 LOCAL_MODULE := libc
 LOCAL_CLANG := $(use_clang)
 LOCAL_ADDITIONAL_DEPENDENCIES := $(libc_common_additional_dependencies)
-LOCAL_WHOLE_STATIC_LIBRARIES := libc_common
-
-ifneq ($(MALLOC_IMPL),dlmalloc)
-LOCAL_WHOLE_STATIC_LIBRARIES += libjemalloc
-endif
+LOCAL_WHOLE_STATIC_LIBRARIES := libc_common libc_init_static libjemalloc
 
 LOCAL_CXX_STL := none
 LOCAL_SYSTEM_SHARED_LIBRARIES :=
-LOCAL_ADDRESS_SANITIZER := false
+LOCAL_SANITIZE := never
 LOCAL_NATIVE_COVERAGE := $(bionic_coverage)
 
 $(eval $(call patch-up-arch-specific-flags,LOCAL_CFLAGS,libc_common_cflags))
@@ -1331,7 +1366,7 @@
     arch-common/bionic/crtbegin_so.c \
     arch-common/bionic/crtbrand.S \
     $(libc_arch_dynamic_src_files) \
-    bionic/malloc_debug_common.cpp \
+    bionic/malloc_common.cpp \
     bionic/libc_init_dynamic.cpp \
     bionic/NetdClient.cpp \
     arch-common/bionic/crtend_so.S \
@@ -1341,7 +1376,15 @@
 LOCAL_REQUIRED_MODULES := tzdata
 LOCAL_ADDITIONAL_DEPENDENCIES := \
     $(libc_common_additional_dependencies) \
-    $(LOCAL_PATH)/libc.map \
+    $(LOCAL_PATH)/libc.arm.map \
+    $(LOCAL_PATH)/libc.arm64.map \
+    $(LOCAL_PATH)/libc.mips.map \
+    $(LOCAL_PATH)/libc.mips64.map \
+    $(LOCAL_PATH)/libc.x86.map \
+    $(LOCAL_PATH)/libc.x86_64.map \
+    $(LOCAL_PATH)/libc.arm.brillo.map \
+    $(LOCAL_PATH)/libc.mips.brillo.map \
+    $(LOCAL_PATH)/libc.x86.brillo.map \
 
 # Leave the symbols in the shared library so that stack unwinders can produce
 # meaningful name resolution.
@@ -1359,26 +1402,38 @@
 # you wanted!
 
 LOCAL_SHARED_LIBRARIES := libdl
-LOCAL_WHOLE_STATIC_LIBRARIES := libc_common
-
-ifneq ($(MALLOC_IMPL),dlmalloc)
-LOCAL_WHOLE_STATIC_LIBRARIES += libjemalloc
-endif
+LOCAL_WHOLE_STATIC_LIBRARIES := libc_common libjemalloc
 
 LOCAL_CXX_STL := none
 LOCAL_SYSTEM_SHARED_LIBRARIES :=
 
+# TODO: This is to work around b/24465209. Remove after root cause is fixed
+LOCAL_LDFLAGS_arm := -Wl,--hash-style=both
+LOCAL_LDFLAGS_x86 := -Wl,--hash-style=both
+
 # Don't re-export new/delete and friends, even if the compiler really wants to.
-LOCAL_LDFLAGS := -Wl,--version-script,$(LOCAL_PATH)/libc.map
+ifdef BRILLO
+LOCAL_LDFLAGS_arm    += -Wl,--version-script,$(LOCAL_PATH)/libc.arm.brillo.map
+LOCAL_LDFLAGS_mips   += -Wl,--version-script,$(LOCAL_PATH)/libc.mips.brillo.map
+LOCAL_LDFLAGS_x86    += -Wl,--version-script,$(LOCAL_PATH)/libc.x86.brillo.map
+else
+LOCAL_LDFLAGS_arm    += -Wl,--version-script,$(LOCAL_PATH)/libc.arm.map
+LOCAL_LDFLAGS_mips   += -Wl,--version-script,$(LOCAL_PATH)/libc.mips.map
+LOCAL_LDFLAGS_x86    += -Wl,--version-script,$(LOCAL_PATH)/libc.x86.map
+endif
+
+LOCAL_LDFLAGS_arm64  += -Wl,--version-script,$(LOCAL_PATH)/libc.arm64.map
+LOCAL_LDFLAGS_mips64 += -Wl,--version-script,$(LOCAL_PATH)/libc.mips64.map
+LOCAL_LDFLAGS_x86_64 += -Wl,--version-script,$(LOCAL_PATH)/libc.x86_64.map
 
 # We'd really like to do this for all architectures, but since this wasn't done
 # before, these symbols must continue to be exported on LP32 for binary
 # compatibility.
 LOCAL_LDFLAGS_64 := -Wl,--exclude-libs,libgcc.a
 
-# TODO: This is to work around b/19059885. Remove after root cause is fixed
-LOCAL_LDFLAGS_arm := -Wl,--hash-style=both
-LOCAL_LDFLAGS_x86 := -Wl,--hash-style=both
+# Unfortunately --exclude-libs clobbers our version script, so we have to
+# prevent the build system from using this flag.
+LOCAL_NO_EXCLUDE_LIBS := true
 
 $(eval $(call patch-up-arch-specific-flags,LOCAL_CFLAGS,libc_common_cflags))
 $(eval $(call patch-up-arch-specific-flags,LOCAL_SRC_FILES,libc_arch_dynamic_src_files))
@@ -1391,107 +1446,35 @@
 LOCAL_SRC_FILES_arm += \
     arch-arm/bionic/atexit_legacy.c
 
-LOCAL_ADDRESS_SANITIZER := false
+LOCAL_SANITIZE := never
 LOCAL_NATIVE_COVERAGE := $(bionic_coverage)
 
 include $(BUILD_SHARED_LIBRARY)
 
-
-# For all builds, except for the -user build we will enable memory
-# allocation checking (including memory leaks, buffer overwrites, etc.)
-# Note that all these checks are also controlled by env. settings
-# that can enable, or disable specific checks. Note also that some of
-# the checks are available only in emulator and are implemeted in
-# libc_malloc_qemu_instrumented.so.
-ifneq ($(TARGET_BUILD_VARIANT),user)
-
 # ========================================================
-# libc_malloc_debug_leak.so
+# libc_logging.a
 # ========================================================
 include $(CLEAR_VARS)
 
 LOCAL_CFLAGS := $(libc_common_cflags)
 LOCAL_CONLYFLAGS := $(libc_common_conlyflags)
 LOCAL_CPPFLAGS := $(libc_common_cppflags)
-
-# Make sure that unwind.h comes from libunwind.
-LOCAL_C_INCLUDES := \
-    $(libc_common_c_includes) \
-
-LOCAL_SRC_FILES := \
-    bionic/debug_mapinfo.cpp \
-    bionic/debug_stacktrace.cpp \
-    bionic/libc_logging.cpp \
-    bionic/malloc_debug_leak.cpp \
-    bionic/malloc_debug_check.cpp \
-
-LOCAL_MODULE := libc_malloc_debug_leak
-LOCAL_CLANG := $(use_clang)
-LOCAL_ADDITIONAL_DEPENDENCIES := \
-    $(libc_common_additional_dependencies) \
-    $(LOCAL_PATH)/version_script.txt \
-
-LOCAL_SHARED_LIBRARIES := libc libdl
-LOCAL_CXX_STL := none
-LOCAL_SYSTEM_SHARED_LIBRARIES :=
-# Only need this for arm since libc++ uses its own unwind code that
-# doesn't mix with the other default unwind code.
-LOCAL_STATIC_LIBRARIES_arm := libunwind_llvm
-LOCAL_STATIC_LIBRARIES += libc++abi
-LOCAL_ALLOW_UNDEFINED_SYMBOLS := true
-
-# Don't re-export new/delete and friends, even if the compiler really wants to.
-LOCAL_LDFLAGS := -Wl,--version-script,$(LOCAL_PATH)/version_script.txt
-
-# Don't install on release build
-LOCAL_MODULE_TAGS := eng debug
-LOCAL_ADDRESS_SANITIZER := false
-LOCAL_NATIVE_COVERAGE := $(bionic_coverage)
-
-$(eval $(call patch-up-arch-specific-flags,LOCAL_CFLAGS,libc_common_cflags))
-include $(BUILD_SHARED_LIBRARY)
-
-
-# ========================================================
-# libc_malloc_debug_qemu.so
-# ========================================================
-include $(CLEAR_VARS)
-
-LOCAL_CFLAGS := \
-    $(libc_common_cflags) \
-    -DMALLOC_QEMU_INSTRUMENT \
-
-LOCAL_CONLYFLAGS := $(libc_common_conlyflags)
-LOCAL_CPPFLAGS := $(libc_common_cppflags)
-
 LOCAL_C_INCLUDES := $(libc_common_c_includes)
 
 LOCAL_SRC_FILES := \
     bionic/libc_logging.cpp \
-    bionic/malloc_debug_qemu.cpp \
 
-LOCAL_MODULE := libc_malloc_debug_qemu
+LOCAL_MODULE := libc_logging
+
 LOCAL_CLANG := $(use_clang)
-LOCAL_ADDITIONAL_DEPENDENCIES := \
-    $(libc_common_additional_dependencies) \
-    $(LOCAL_PATH)/version_script.txt \
-
-LOCAL_SHARED_LIBRARIES := libc libdl
-LOCAL_CXX_STL := none
+LOCAL_ADDITIONAL_DEPENDENCIES := $(libc_common_additional_dependencies)
 LOCAL_SYSTEM_SHARED_LIBRARIES :=
 
-# Don't re-export new/delete and friends, even if the compiler really wants to.
-LOCAL_LDFLAGS := -Wl,--version-script,$(LOCAL_PATH)/version_script.txt
-
-# Don't install on release build
-LOCAL_MODULE_TAGS := eng debug
-LOCAL_ADDRESS_SANITIZER := false
+LOCAL_SANITIZE := never
 LOCAL_NATIVE_COVERAGE := $(bionic_coverage)
 
 $(eval $(call patch-up-arch-specific-flags,LOCAL_CFLAGS,libc_common_cflags))
-include $(BUILD_SHARED_LIBRARY)
-
-endif  #!user
+include $(BUILD_STATIC_LIBRARY)
 
 # ========================================================
 # libstdc++.so
@@ -1500,14 +1483,13 @@
     bionic/__cxa_guard.cpp \
     bionic/__cxa_pure_virtual.cpp \
     bionic/new.cpp \
-    bionic/libc_logging.cpp \
 
 include $(CLEAR_VARS)
 LOCAL_C_INCLUDES := $(libc_common_c_includes) bionic/libstdc++/include
 LOCAL_CFLAGS := $(libc_common_cflags)
 LOCAL_CPPFLAGS := $(libc_common_cppflags)
 
-# TODO: This is to work around b/19059885. Remove after root cause is fixed
+# TODO: This is to work around b/24465209. Remove after root cause is fixed
 LOCAL_LDFLAGS_arm := -Wl,--hash-style=both
 LOCAL_LDFLAGS_x86 := -Wl,--hash-style=both
 
@@ -1516,7 +1498,8 @@
 LOCAL_ADDITIONAL_DEPENDENCIES := $(LOCAL_PATH)/Android.mk
 LOCAL_CXX_STL := none
 LOCAL_SYSTEM_SHARED_LIBRARIES := libc
-LOCAL_ADDRESS_SANITIZER := false
+LOCAL_STATIC_LIBRARIES := libc_logging
+LOCAL_SANITIZE := never
 LOCAL_NATIVE_COVERAGE := $(bionic_coverage)
 include $(BUILD_SHARED_LIBRARY)
 
@@ -1532,10 +1515,6 @@
 LOCAL_ADDITIONAL_DEPENDENCIES := $(LOCAL_PATH)/Android.mk
 LOCAL_CXX_STL := none
 LOCAL_SYSTEM_SHARED_LIBRARIES := libc
-LOCAL_ADDRESS_SANITIZER := false
+LOCAL_SANITIZE := never
 LOCAL_NATIVE_COVERAGE := $(bionic_coverage)
 include $(BUILD_STATIC_LIBRARY)
-
-
-# ========================================================
-include $(call all-makefiles-under,$(LOCAL_PATH))
diff --git a/libc/NOTICE b/libc/NOTICE
index dbe3944..2121246 100644
--- a/libc/NOTICE
+++ b/libc/NOTICE
@@ -85,6 +85,33 @@
 
 -------------------------------------------------------------------
 
+ Copyright (c) 2009-2013 The Linux Foundation. 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 Linux 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 COPYRIGHT HOLDERS AND CONTRIBUTORS "AS IS"
+ AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE
+ IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE
+ ARE DISCLAIMED. IN NO EVENT SHALL THE COPYRIGHT HOLDER OR CONTRIBUTORS BE
+ LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR
+ CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF
+ SUBSTITUTE GOODS OR SERVICES; LOSS OF USE, DATA, OR PROFITS; OR BUSINESS
+ INTERRUPTION) HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY, WHETHER IN
+ CONTRACT, STRICT LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE)
+ ARISING IN ANY WAY OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF THE
+ POSSIBILITY OF SUCH DAMAGE.
+
+-------------------------------------------------------------------
+
 ====================================================
 Copyright (C) 1993 by Sun Microsystems, Inc. All rights reserved.
 
@@ -308,22 +335,6 @@
 -------------------------------------------------------------------
 
 Copyright (C) 2009 The Android Open Source Project
-
-Licensed under the Apache License, Version 2.0 (the "License");
-you may not use this file except in compliance with the License.
-You may obtain a copy of the License at
-
-     http://www.apache.org/licenses/LICENSE-2.0
-
-Unless required by applicable law or agreed to in writing, software
-distributed under the License is distributed on an "AS IS" BASIS,
-WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
-See the License for the specific language governing permissions and
-limitations under the License.
-
--------------------------------------------------------------------
-
-Copyright (C) 2009 The Android Open Source Project
 All rights reserved.
 
 Redistribution and use in source and binary forms, with or without
@@ -688,6 +699,50 @@
 
 -------------------------------------------------------------------
 
+Copyright (C) 2016 The Android Open Source Project
+
+Licensed under the Apache License, Version 2.0 (the "License");
+you may not use this file except in compliance with the License.
+You may obtain a copy of the License at
+
+     http://www.apache.org/licenses/LICENSE-2.0
+
+Unless required by applicable law or agreed to in writing, software
+distributed under the License is distributed on an "AS IS" BASIS,
+WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
+See the License for the specific language governing permissions and
+limitations under the License.
+
+-------------------------------------------------------------------
+
+Copyright (C) 2016 The Android Open Source Project
+All rights reserved.
+
+Redistribution and use in source and binary forms, with or without
+modification, are permitted provided that the following conditions
+are met:
+ * Redistributions of source code must retain the above copyright
+   notice, this list of conditions and the following disclaimer.
+ * Redistributions in binary form must reproduce the above copyright
+   notice, this list of conditions and the following disclaimer in
+   the documentation and/or other materials provided with the
+   distribution.
+
+THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS
+"AS IS" AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT
+LIMITED TO, THE IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS
+FOR A PARTICULAR PURPOSE ARE DISCLAIMED. IN NO EVENT SHALL THE
+COPYRIGHT OWNER OR CONTRIBUTORS BE LIABLE FOR ANY DIRECT, INDIRECT,
+INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING,
+BUT NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; LOSS
+OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED
+AND ON ANY THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY,
+OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT
+OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF
+SUCH DAMAGE.
+
+-------------------------------------------------------------------
+
 Copyright (c) 1980, 1983, 1988, 1993
    The Regents of the University of California.  All rights reserved.
 
@@ -894,53 +949,6 @@
 
 -------------------------------------------------------------------
 
-Copyright (c) 1983, 1990, 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.
-
-Portions Copyright (c) 1993 by Digital Equipment Corporation.
-
-Permission to use, copy, modify, and distribute this software for any
-purpose with or without fee is hereby granted, provided that the above
-copyright notice and this permission notice appear in all copies, and that
-the name of Digital Equipment Corporation not be used in advertising or
-publicity pertaining to distribution of the document or software without
-specific, written prior permission.
-
-THE SOFTWARE IS PROVIDED "AS IS" AND DIGITAL EQUIPMENT CORP. DISCLAIMS ALL
-WARRANTIES WITH REGARD TO THIS SOFTWARE, INCLUDING ALL IMPLIED WARRANTIES
-OF MERCHANTABILITY AND FITNESS.   IN NO EVENT SHALL DIGITAL EQUIPMENT
-CORPORATION BE LIABLE FOR ANY SPECIAL, DIRECT, INDIRECT, OR CONSEQUENTIAL
-DAMAGES OR ANY DAMAGES WHATSOEVER RESULTING FROM LOSS OF USE, DATA OR
-PROFITS, WHETHER IN AN ACTION OF CONTRACT, NEGLIGENCE OR OTHER TORTIOUS
-ACTION, ARISING OUT OF OR IN CONNECTION WITH THE USE OR PERFORMANCE OF THIS
-SOFTWARE.
-
--------------------------------------------------------------------
-
 Copyright (c) 1983, 1993
    The Regents of the University of California.  All rights reserved.
 
@@ -1679,6 +1687,38 @@
 
 -------------------------------------------------------------------
 
+Copyright (c) 1990 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.
+
+-------------------------------------------------------------------
+
 Copyright (c) 1990 The Regents of the University of California.
 All rights reserved.
 
@@ -2889,22 +2929,6 @@
 -------------------------------------------------------------------
 
 Copyright (c) 1998 Todd C. Miller <Todd.Miller@courtesan.com>
-
-Permission to use, copy, modify, and distribute this software for any
-purpose with or without fee is hereby granted, provided that the above
-copyright notice and this permission notice appear in all copies.
-
-THE SOFTWARE IS PROVIDED "AS IS" AND THE AUTHOR DISCLAIMS ALL WARRANTIES
-WITH REGARD TO THIS SOFTWARE INCLUDING ALL IMPLIED WARRANTIES OF
-MERCHANTABILITY AND FITNESS. IN NO EVENT SHALL THE AUTHOR BE LIABLE FOR
-ANY SPECIAL, DIRECT, INDIRECT, OR CONSEQUENTIAL DAMAGES OR ANY DAMAGES
-WHATSOEVER RESULTING FROM LOSS OF USE, DATA OR PROFITS, WHETHER IN AN
-ACTION OF CONTRACT, NEGLIGENCE OR OTHER TORTIOUS ACTION, ARISING OUT OF
-OR IN CONNECTION WITH THE USE OR PERFORMANCE OF THIS SOFTWARE.
-
--------------------------------------------------------------------
-
-Copyright (c) 1998 Todd C. Miller <Todd.Miller@courtesan.com>
 All rights reserved.
 
 Redistribution and use in source and binary forms, with or without
@@ -2931,6 +2955,22 @@
 
 -------------------------------------------------------------------
 
+Copyright (c) 1998, 2015 Todd C. Miller <Todd.Miller@courtesan.com>
+
+Permission to use, copy, modify, and distribute this software for any
+purpose with or without fee is hereby granted, provided that the above
+copyright notice and this permission notice appear in all copies.
+
+THE SOFTWARE IS PROVIDED "AS IS" AND THE AUTHOR DISCLAIMS ALL WARRANTIES
+WITH REGARD TO THIS SOFTWARE INCLUDING ALL IMPLIED WARRANTIES OF
+MERCHANTABILITY AND FITNESS. IN NO EVENT SHALL THE AUTHOR BE LIABLE FOR
+ANY SPECIAL, DIRECT, INDIRECT, OR CONSEQUENTIAL DAMAGES OR ANY DAMAGES
+WHATSOEVER RESULTING FROM LOSS OF USE, DATA OR PROFITS, WHETHER IN AN
+ACTION OF CONTRACT, NEGLIGENCE OR OTHER TORTIOUS ACTION, ARISING OUT OF
+OR IN CONNECTION WITH THE USE OR PERFORMANCE OF THIS SOFTWARE.
+
+-------------------------------------------------------------------
+
 Copyright (c) 1999
    David E. O'Brien
 Copyright (c) 1988, 1993
@@ -3057,32 +3097,6 @@
 
 -------------------------------------------------------------------
 
-Copyright (c) 2001 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) 2001 Wasabi Systems, Inc.
 All rights reserved.
 
@@ -3921,35 +3935,6 @@
 
 -------------------------------------------------------------------
 
-Copyright (c) 2009
-     MIPS Technologies, Inc., California.
-
-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 MIPS Technologies, Inc., nor the names of its
-   contributors may be used to endorse or promote products derived from
-   this software without specific prior written permission.
-
-THIS SOFTWARE IS PROVIDED BY THE MIPS TECHNOLOGIES, INC. ``AS IS'' AND
-ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE
-IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE
-ARE DISCLAIMED.  IN NO EVENT SHALL THE MIPS TECHNOLOGIES, INC. BE LIABLE
-FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL
-DAMAGES (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS
-OR SERVICES; LOSS OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION)
-HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT
-LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY
-OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF
-SUCH DAMAGE.
-
--------------------------------------------------------------------
-
 Copyright (c) 2009 David Schultz <das@FreeBSD.org>
 All rights reserved.
 
@@ -4431,6 +4416,64 @@
 
 -------------------------------------------------------------------
 
+Copyright (c) 2012-2015
+     MIPS Technologies, Inc., California.
+
+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 MIPS Technologies, Inc., nor the names of its
+   contributors may be used to endorse or promote products derived from
+   this software without specific prior written permission.
+
+THIS SOFTWARE IS PROVIDED BY THE MIPS TECHNOLOGIES, INC. ``AS IS'' AND
+ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE
+IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE
+ARE DISCLAIMED.  IN NO EVENT SHALL THE MIPS TECHNOLOGIES, INC. BE LIABLE
+FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL
+DAMAGES (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS
+OR SERVICES; LOSS OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION)
+HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT
+LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY
+OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF
+SUCH DAMAGE.
+
+-------------------------------------------------------------------
+
+Copyright (c) 2013
+     MIPS Technologies, Inc., California.
+
+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 MIPS Technologies, Inc., nor the names of its
+   contributors may be used to endorse or promote products derived from
+   this software without specific prior written permission.
+
+THIS SOFTWARE IS PROVIDED BY THE MIPS TECHNOLOGIES, INC. ``AS IS'' AND
+ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE
+IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE
+ARE DISCLAIMED.  IN NO EVENT SHALL THE MIPS TECHNOLOGIES, INC. BE LIABLE
+FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL
+DAMAGES (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS
+OR SERVICES; LOSS OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION)
+HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT
+LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY
+OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF
+SUCH DAMAGE.
+
+-------------------------------------------------------------------
+
 Copyright (c) 2013 ARM Ltd
 All rights reserved.
 
@@ -4504,6 +4547,35 @@
 
 -------------------------------------------------------------------
 
+Copyright (c) 2014
+     Imagination Technologies Limited.
+
+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 MIPS Technologies, Inc., nor the names of its
+   contributors may be used to endorse or promote products derived from
+   this software without specific prior written permission.
+
+THIS SOFTWARE IS PROVIDED BY IMAGINATION TECHNOLOGIES LIMITED ``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 IMAGINATION TECHNOLOGIES LIMITED BE LIABLE
+FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL
+DAMAGES (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS
+OR SERVICES; LOSS OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION)
+HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT
+LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY
+OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF
+SUCH DAMAGE.
+
+-------------------------------------------------------------------
+
 Copyright (c) 2014 Theo de Raadt <deraadt@openbsd.org>
 Copyright (c) 2014 Bob Beck <beck@obtuse.com>
 
@@ -4582,6 +4654,35 @@
 
 -------------------------------------------------------------------
 
+Copyright (c) 2015 Joerg Sonnenberger <joerg@NetBSD.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 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 HOLDERS 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)1999 Citrus Project,
 All rights reserved.
 
diff --git a/libc/SYSCALLS.TXT b/libc/SYSCALLS.TXT
index 2e2cd11..d5dd206 100644
--- a/libc/SYSCALLS.TXT
+++ b/libc/SYSCALLS.TXT
@@ -77,7 +77,6 @@
 int     setgroups:setgroups32(int, const gid_t*)   arm,x86
 int     setgroups:setgroups(int, const gid_t*)     arm64,mips,mips64,x86_64
 int     setpgid(pid_t, pid_t)  all
-pid_t   vfork(void)  arm
 int     setregid:setregid32(gid_t, gid_t)  arm,x86
 int     setregid:setregid(gid_t, gid_t)    arm64,mips,mips64,x86_64
 int     chroot(const char*)  all
@@ -95,10 +94,20 @@
 ssize_t     pread64|pread(int, void*, size_t, off_t) arm64,mips64,x86_64
 ssize_t     pwrite64(int, void*, size_t, off64_t) arm,mips,x86
 ssize_t     pwrite64|pwrite(int, void*, size_t, off_t) arm64,mips64,x86_64
+
+# On LP32, preadv/pwritev don't use off64_t --- they use pairs of 32-bit
+# arguments to avoid problems on architectures like ARM where 64-bit arguments
+# must be in a register pair starting with an even-numbered register.
+# See linux/fs/read_write.c and https://lwn.net/Articles/311630/.
+ssize_t     __preadv64:preadv(int, const struct iovec*, int, long, long) arm,mips,x86
+ssize_t     preadv|preadv64(int, const struct iovec*, int, off_t) arm64,mips64,x86_64
+ssize_t     __pwritev64:pwritev(int, const struct iovec*, int, long, long) arm,mips,x86
+ssize_t     pwritev|pwritev64(int, const struct iovec*, int, off_t) arm64,mips64,x86_64
+
 int         ___close:close(int)  all
 pid_t       __getpid:getpid()  all
 int         munmap(void*, size_t)  all
-void*       mremap(void*, size_t, size_t, unsigned long)  all
+void*       ___mremap:mremap(void*, size_t, size_t, int, void*)  all
 int         msync(const void*, size_t, int)    all
 int         mprotect(const void*, size_t, int)  all
 int         madvise(void*, size_t, int)  all
@@ -124,7 +133,7 @@
 void        sync(void)  all
 int         ___fsetxattr:fsetxattr(int, const char*, const void*, size_t, int) all
 ssize_t     ___fgetxattr:fgetxattr(int, const char*, void*, size_t) all
-ssize_t     flistxattr(int, char*, size_t) all
+ssize_t     ___flistxattr:flistxattr(int, char*, size_t) all
 int         fremovexattr(int, const char*) all
 
 int __getdents64:getdents64(unsigned int, struct dirent*, unsigned int)   arm,arm64,mips,mips64,x86,x86_64
@@ -214,6 +223,8 @@
 int           timerfd_create(clockid_t, int)   all
 int           timerfd_settime(int, int, const struct itimerspec*, struct itimerspec*)   all
 int           timerfd_gettime(int, struct itimerspec*)   all
+int           adjtimex(struct timex*)   all
+int           clock_adjtime(clockid_t, struct timex*)   all
 
 # signals
 int     __sigaction:sigaction(int, const struct sigaction*, struct sigaction*)  arm,mips,x86
@@ -333,7 +344,7 @@
 int     __set_thread_area:set_thread_area(void*) x86
 
 # vdso stuff.
-int clock_gettime(clockid_t, timespec*)                 arm,mips,mips64,x86
-int __clock_gettime:clock_gettime(clockid_t, timespec*) arm64,x86_64
-int gettimeofday(timeval*, timezone*)                   arm,mips,mips64,x86
-int __gettimeofday:gettimeofday(timeval*, timezone*)    arm64,x86_64
+int clock_gettime(clockid_t, timespec*)                 arm,mips,mips64
+int __clock_gettime:clock_gettime(clockid_t, timespec*) arm64,x86,x86_64
+int gettimeofday(timeval*, timezone*)                   arm,mips,mips64
+int __gettimeofday:gettimeofday(timeval*, timezone*)    arm64,x86,x86_64
diff --git a/libc/arch-arm/arm.mk b/libc/arch-arm/arm.mk
index d72a160..76f465e 100644
--- a/libc/arch-arm/arm.mk
+++ b/libc/arch-arm/arm.mk
@@ -1,33 +1,19 @@
 # 32-bit arm.
 
-#
-# Default implementations of functions that are commonly optimized.
-#
-
 libc_bionic_src_files_arm += \
-    bionic/strchr.cpp \
-    bionic/strnlen.c \
-    bionic/strrchr.cpp \
+    arch-arm/generic/bionic/memcmp.S \
+    arch-arm/generic/bionic/memcpy.S \
+    arch-arm/generic/bionic/memset.S \
+    arch-arm/generic/bionic/strcmp.S \
+    arch-arm/generic/bionic/strcpy.S \
+    arch-arm/generic/bionic/strlen.c \
 
-libc_freebsd_src_files_arm += \
-    upstream-freebsd/lib/libc/string/wcscat.c \
-    upstream-freebsd/lib/libc/string/wcschr.c \
-    upstream-freebsd/lib/libc/string/wcscmp.c \
-    upstream-freebsd/lib/libc/string/wcscpy.c \
-    upstream-freebsd/lib/libc/string/wcslen.c \
-    upstream-freebsd/lib/libc/string/wcsrchr.c \
-    upstream-freebsd/lib/libc/string/wmemcmp.c \
-    upstream-freebsd/lib/libc/string/wmemmove.c \
+libc_bionic_src_files_exclude_arm += \
+    bionic/__memcpy_chk.cpp \
+    bionic/__memset_chk.cpp \
 
-libc_openbsd_src_files_arm += \
-    upstream-openbsd/lib/libc/string/memchr.c \
-    upstream-openbsd/lib/libc/string/memrchr.c \
-    upstream-openbsd/lib/libc/string/stpncpy.c \
-    upstream-openbsd/lib/libc/string/strlcat.c \
-    upstream-openbsd/lib/libc/string/strlcpy.c \
-    upstream-openbsd/lib/libc/string/strncat.c \
-    upstream-openbsd/lib/libc/string/strncmp.c \
-    upstream-openbsd/lib/libc/string/strncpy.c \
+libc_openbsd_src_files_exclude_arm += \
+    upstream-openbsd/lib/libc/string/strcpy.c \
 
 #
 # Inherently architecture-specific code.
@@ -39,9 +25,11 @@
     arch-arm/bionic/__bionic_clone.S \
     arch-arm/bionic/_exit_with_stack_teardown.S \
     arch-arm/bionic/libgcc_compat.c \
+    arch-arm/bionic/popcount_tab.c \
     arch-arm/bionic/__restore.S \
     arch-arm/bionic/setjmp.S \
     arch-arm/bionic/syscall.S \
+    arch-arm/bionic/vfork.S \
 
 libc_arch_static_src_files_arm := arch-arm/bionic/exidx_static.c
 libc_arch_dynamic_src_files_arm := arch-arm/bionic/exidx_dynamic.c
@@ -50,6 +38,7 @@
 ifeq ($(strip $(TARGET_$(my_2nd_arch_prefix)CPU_VARIANT)),)
   $(warning TARGET_$(my_2nd_arch_prefix)ARCH is arm, but TARGET_$(my_2nd_arch_prefix)CPU_VARIANT is not defined)
 endif
+ifneq ($(TARGET_$(my_2nd_arch_prefix)CPU_VARIANT),generic)
 cpu_variant_mk := $(LOCAL_PATH)/arch-arm/$(TARGET_$(my_2nd_arch_prefix)CPU_VARIANT)/$(TARGET_$(my_2nd_arch_prefix)CPU_VARIANT).mk
 ifeq ($(wildcard $(cpu_variant_mk)),)
 $(error "TARGET_$(my_2nd_arch_prefix)CPU_VARIANT not set or set to an unknown value. Possible values are cortex-a7, cortex-a8, cortex-a9, cortex-a15, krait, denver. Use generic for devices that do not have a CPU similar to any of the supported cpu variants.")
@@ -58,6 +47,7 @@
 libc_common_additional_dependencies += $(cpu_variant_mk)
 
 cpu_variant_mk :=
+endif
 
 
 libc_crt_target_cflags_arm := \
diff --git a/libc/arch-arm/bionic/__aeabi.c b/libc/arch-arm/bionic/__aeabi.c
index 254c7a6..1620d45 100644
--- a/libc/arch-arm/bionic/__aeabi.c
+++ b/libc/arch-arm/bionic/__aeabi.c
@@ -51,34 +51,62 @@
  */
 
 int __attribute__((weak))
-__aeabi_atexit(void *object, void (*destructor) (void *), void *dso_handle) {
+__aeabi_atexit_impl(void *object, void (*destructor) (void *), void *dso_handle) {
+    return __cxa_atexit(destructor, object, dso_handle);
+}
+
+int __attribute__((weak))
+__aeabi_atexit_impl2(void *object, void (*destructor) (void *), void *dso_handle) {
     return __cxa_atexit(destructor, object, dso_handle);
 }
 
 
-void __attribute__((weak))
-__aeabi_memcpy8(void *dest, const void *src, size_t n) {
+void __attribute__((weak)) __aeabi_memcpy8_impl(void *dest, const void *src, size_t n) {
     memcpy(dest, src, n);
 }
 
-void __attribute__((weak)) __aeabi_memcpy4(void *dest, const void *src, size_t n) {
+void __attribute__((weak)) __aeabi_memcpy4_impl(void *dest, const void *src, size_t n) {
     memcpy(dest, src, n);
 }
 
-void __attribute__((weak)) __aeabi_memcpy(void *dest, const void *src, size_t n) {
+void __attribute__((weak)) __aeabi_memcpy_impl(void *dest, const void *src, size_t n) {
+    memcpy(dest, src, n);
+}
+
+void __attribute__((weak)) __aeabi_memcpy8_impl2(void *dest, const void *src, size_t n) {
+    memcpy(dest, src, n);
+}
+
+void __attribute__((weak)) __aeabi_memcpy4_impl2(void *dest, const void *src, size_t n) {
+    memcpy(dest, src, n);
+}
+
+void __attribute__((weak)) __aeabi_memcpy_impl2(void *dest, const void *src, size_t n) {
     memcpy(dest, src, n);
 }
 
 
-void __attribute__((weak)) __aeabi_memmove8(void *dest, const void *src, size_t n) {
+void __attribute__((weak)) __aeabi_memmove8_impl(void *dest, const void *src, size_t n) {
     memmove(dest, src, n);
 }
 
-void __attribute__((weak)) __aeabi_memmove4(void *dest, const void *src, size_t n) {
+void __attribute__((weak)) __aeabi_memmove4_impl(void *dest, const void *src, size_t n) {
     memmove(dest, src, n);
 }
 
-void __attribute__((weak)) __aeabi_memmove(void *dest, const void *src, size_t n) {
+void __attribute__((weak)) __aeabi_memmove_impl(void *dest, const void *src, size_t n) {
+    memmove(dest, src, n);
+}
+
+void __attribute__((weak)) __aeabi_memmove8_impl2(void *dest, const void *src, size_t n) {
+    memmove(dest, src, n);
+}
+
+void __attribute__((weak)) __aeabi_memmove4_impl2(void *dest, const void *src, size_t n) {
+    memmove(dest, src, n);
+}
+
+void __attribute__((weak)) __aeabi_memmove_impl2(void *dest, const void *src, size_t n) {
     memmove(dest, src, n);
 }
 
@@ -87,27 +115,71 @@
  *  This allows __aeabi_memclr to tail-call __aeabi_memset
  */
 
-void __attribute__((weak)) __aeabi_memset8(void *dest, size_t n, int c) {
+void __attribute__((weak)) __aeabi_memset8_impl(void *dest, size_t n, int c) {
     memset(dest, c, n);
 }
 
-void __attribute__((weak)) __aeabi_memset4(void *dest, size_t n, int c) {
+void __attribute__((weak)) __aeabi_memset4_impl(void *dest, size_t n, int c) {
     memset(dest, c, n);
 }
 
-void __attribute__((weak)) __aeabi_memset(void *dest, size_t n, int c) {
+void __attribute__((weak)) __aeabi_memset_impl(void *dest, size_t n, int c) {
+    memset(dest, c, n);
+}
+
+void __attribute__((weak)) __aeabi_memset8_impl2(void *dest, size_t n, int c) {
+    memset(dest, c, n);
+}
+
+void __attribute__((weak)) __aeabi_memset4_impl2(void *dest, size_t n, int c) {
+    memset(dest, c, n);
+}
+
+void __attribute__((weak)) __aeabi_memset_impl2(void *dest, size_t n, int c) {
     memset(dest, c, n);
 }
 
 
-void __attribute__((weak)) __aeabi_memclr8(void *dest, size_t n) {
-    __aeabi_memset8(dest, n, 0);
+void __attribute__((weak)) __aeabi_memclr8_impl(void *dest, size_t n) {
+    __aeabi_memset8_impl(dest, n, 0);
 }
 
-void __attribute__((weak)) __aeabi_memclr4(void *dest, size_t n) {
-    __aeabi_memset4(dest, n, 0);
+void __attribute__((weak)) __aeabi_memclr4_impl(void *dest, size_t n) {
+    __aeabi_memset4_impl(dest, n, 0);
 }
 
-void __attribute__((weak)) __aeabi_memclr(void *dest, size_t n) {
-    __aeabi_memset(dest, n, 0);
+void __attribute__((weak)) __aeabi_memclr_impl(void *dest, size_t n) {
+    __aeabi_memset_impl(dest, n, 0);
 }
+
+void __attribute__((weak)) __aeabi_memclr8_impl2(void *dest, size_t n) {
+    __aeabi_memset8_impl(dest, n, 0);
+}
+
+void __attribute__((weak)) __aeabi_memclr4_impl2(void *dest, size_t n) {
+    __aeabi_memset4_impl(dest, n, 0);
+}
+
+void __attribute__((weak)) __aeabi_memclr_impl2(void *dest, size_t n) {
+    __aeabi_memset_impl(dest, n, 0);
+}
+
+#define __AEABI_SYMVERS(fn_name) \
+__asm__(".symver " #fn_name "_impl, " #fn_name "@@LIBC_N"); \
+__asm__(".symver " #fn_name "_impl2, " #fn_name "@LIBC_PRIVATE")
+
+__AEABI_SYMVERS(__aeabi_atexit);
+__AEABI_SYMVERS(__aeabi_memcpy8);
+__AEABI_SYMVERS(__aeabi_memcpy4);
+__AEABI_SYMVERS(__aeabi_memcpy);
+__AEABI_SYMVERS(__aeabi_memmove8);
+__AEABI_SYMVERS(__aeabi_memmove4);
+__AEABI_SYMVERS(__aeabi_memmove);
+__AEABI_SYMVERS(__aeabi_memset8);
+__AEABI_SYMVERS(__aeabi_memset4);
+__AEABI_SYMVERS(__aeabi_memset);
+__AEABI_SYMVERS(__aeabi_memclr8);
+__AEABI_SYMVERS(__aeabi_memclr4);
+__AEABI_SYMVERS(__aeabi_memclr);
+
+#undef __AEABI_SYMVERS
diff --git a/libc/arch-arm/bionic/__restore.S b/libc/arch-arm/bionic/__restore.S
index 9898125..8c1e41d 100644
--- a/libc/arch-arm/bionic/__restore.S
+++ b/libc/arch-arm/bionic/__restore.S
@@ -34,7 +34,9 @@
 // __restore_rt (but covered by the .fnstart/.fnend) so that although they're
 // not inside the functions from objdump's point of view, an unwinder that
 // blindly looks at the previous instruction (but is then smart enough to check
-// the DWARF information to find out where it landed) gets the right answer.
+// the unwind information to find out where it landed) gets the right answer.
+// Make sure not to have both DWARF and ARM unwind information, so only
+// use the ARM unwind information.
 
 // We need to place .fnstart ourselves (but we may as well keep the free .fnend).
 #undef __bionic_asm_custom_entry
@@ -44,18 +46,18 @@
   .save {r0-r15}
   .pad #32
   nop
-ENTRY_PRIVATE(__restore)
+ENTRY_PRIVATE_NO_DWARF(__restore)
   // This function must have exactly this instruction sequence.
   mov r7, #__NR_sigreturn
   swi #0
-END(__restore)
+END_NO_DWARF(__restore)
 
   .fnstart
   .save {r0-r15}
   .pad #160
   nop
-ENTRY_PRIVATE(__restore_rt)
+ENTRY_PRIVATE_NO_DWARF(__restore_rt)
   // This function must have exactly this instruction sequence.
   mov r7, #__NR_rt_sigreturn
   swi #0
-END(__restore_rt)
+END_NO_DWARF(__restore_rt)
diff --git a/libc/arch-arm/bionic/exidx_dynamic.c b/libc/arch-arm/bionic/exidx_dynamic.c
index c7b7156..60ac8af 100644
--- a/libc/arch-arm/bionic/exidx_dynamic.c
+++ b/libc/arch-arm/bionic/exidx_dynamic.c
@@ -37,7 +37,13 @@
  * the expectation that libc will define it and call through to
  * a differently-named function in the dynamic linker.
  */
-_Unwind_Ptr __gnu_Unwind_Find_exidx(_Unwind_Ptr pc, int *pcount)
-{
+_Unwind_Ptr __gnu_Unwind_Find_exidx_impl(_Unwind_Ptr pc, int *pcount) {
     return dl_unwind_find_exidx(pc, pcount);
 }
+
+_Unwind_Ptr __gnu_Unwind_Find_exidx_impl2(_Unwind_Ptr pc, int *pcount) {
+    return dl_unwind_find_exidx(pc, pcount);
+}
+
+__asm__(".symver __gnu_Unwind_Find_exidx_impl,__gnu_Unwind_Find_exidx@LIBC_PRIVATE");
+__asm__(".symver __gnu_Unwind_Find_exidx_impl2,__gnu_Unwind_Find_exidx@@LIBC_N");
diff --git a/libc/arch-arm/bionic/popcount_tab.c b/libc/arch-arm/bionic/popcount_tab.c
new file mode 100644
index 0000000..eb2faa9
--- /dev/null
+++ b/libc/arch-arm/bionic/popcount_tab.c
@@ -0,0 +1,42 @@
+/*
+ * Copyright (C) 2015 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.
+ */
+
+// Export this to maintain ABI compatibilty with libgcc, since compiler-rt
+// doesn't use a table-driven implementation of __popcount.
+const unsigned char __popcount_tab[256] = {
+  0, 1, 1, 2, 1, 2, 2, 3, 1, 2, 2, 3, 2, 3, 3, 4, 1, 2, 2, 3, 2, 3, 3, 4, 2, 3,
+  3, 4, 3, 4, 4, 5, 1, 2, 2, 3, 2, 3, 3, 4, 2, 3, 3, 4, 3, 4, 4, 5, 2, 3, 3, 4,
+  3, 4, 4, 5, 3, 4, 4, 5, 4, 5, 5, 6, 1, 2, 2, 3, 2, 3, 3, 4, 2, 3, 3, 4, 3, 4,
+  4, 5, 2, 3, 3, 4, 3, 4, 4, 5, 3, 4, 4, 5, 4, 5, 5, 6, 2, 3, 3, 4, 3, 4, 4, 5,
+  3, 4, 4, 5, 4, 5, 5, 6, 3, 4, 4, 5, 4, 5, 5, 6, 4, 5, 5, 6, 5, 6, 6, 7, 1, 2,
+  2, 3, 2, 3, 3, 4, 2, 3, 3, 4, 3, 4, 4, 5, 2, 3, 3, 4, 3, 4, 4, 5, 3, 4, 4, 5,
+  4, 5, 5, 6, 2, 3, 3, 4, 3, 4, 4, 5, 3, 4, 4, 5, 4, 5, 5, 6, 3, 4, 4, 5, 4, 5,
+  5, 6, 4, 5, 5, 6, 5, 6, 6, 7, 2, 3, 3, 4, 3, 4, 4, 5, 3, 4, 4, 5, 4, 5, 5, 6,
+  3, 4, 4, 5, 4, 5, 5, 6, 4, 5, 5, 6, 5, 6, 6, 7, 3, 4, 4, 5, 4, 5, 5, 6, 4, 5,
+  5, 6, 5, 6, 6, 7, 4, 5, 5, 6, 5, 6, 6, 7, 5, 6, 6, 7, 6, 7, 7, 8
+};
diff --git a/libc/arch-arm/bionic/setjmp.S b/libc/arch-arm/bionic/setjmp.S
index 8220c08..91d158a 100644
--- a/libc/arch-arm/bionic/setjmp.S
+++ b/libc/arch-arm/bionic/setjmp.S
@@ -36,10 +36,13 @@
 // According to the ARM AAPCS document, we only need to save
 // the following registers:
 //
-//  Core   r4-r14
+//  Core   r4-r11, sp, lr
+//    AAPCS 5.1.1:
+//      A subroutine must preserve the contents of the registers r4-r8, r10, r11
+//      and SP (and r9 in PCS variants that designate r9 as v6).
 //
-//  VFP    d8-d15  (see section 5.1.2.1)
-//
+//  VFP    d8-d15
+//    AAPCS 5.1.2.1:
 //      Registers s16-s31 (d8-d15, q4-q7) must be preserved across subroutine
 //      calls; registers s0-s15 (d0-d7, q0-q3) do not need to be preserved
 //      (and can be used for passing arguments or returning results in standard
@@ -49,15 +52,16 @@
 //  FPSCR  saved because glibc does.
 
 // The internal structure of a jmp_buf is totally private.
-// Current layout (may change in the future):
+// Current layout (changes from release to release):
 //
-// word   name         description
-// 0      magic        magic number
-// 1      sigmask      signal mask (not used with _setjmp / _longjmp)
-// 2      float_base   base of float registers (d8 to d15)
-// 18     float_state  floating-point status and control register
-// 19     core_base    base of core registers (r4 to r14)
-// 30     reserved     reserved entries (room to grow)
+// word   name            description
+// 0      sigflag/cookie  setjmp cookie in top 31 bits, signal mask flag in low bit
+// 1      sigmask         signal mask (not used with _setjmp / _longjmp)
+// 2      float_base      base of float registers (d8 to d15)
+// 18     float_state     floating-point status and control register
+// 19     core_base       base of core registers (r4-r11, r13-r14)
+// 29     checksum        checksum of all of the core registers, to give better error messages.
+// 30     reserved        reserved entries (room to grow)
 // 64
 //
 // NOTE: float_base must be at an even word index, since the
@@ -69,6 +73,7 @@
 #define _JB_FLOAT_BASE  (_JB_SIGMASK+1)
 #define _JB_FLOAT_STATE (_JB_FLOAT_BASE + (15-8+1)*2)
 #define _JB_CORE_BASE   (_JB_FLOAT_STATE+1)
+#define _JB_CHECKSUM    (_JB_CORE_BASE+10)
 
 ENTRY(setjmp)
   mov r1, #1
@@ -80,33 +85,91 @@
   b sigsetjmp
 END(_setjmp)
 
+#define MANGLE_REGISTERS 1
+#define USE_CHECKSUM 1
+
+.macro m_mangle_registers reg
+#if MANGLE_REGISTERS
+  eor r4, r4, \reg
+  eor r5, r5, \reg
+  eor r6, r6, \reg
+  eor r7, r7, \reg
+  eor r8, r8, \reg
+  eor r9, r9, \reg
+  eor r10, r10, \reg
+  eor r11, r11, \reg
+  eor r13, r13, \reg
+  eor r14, r14, \reg
+#endif
+.endm
+
+.macro m_unmangle_registers reg
+  m_mangle_registers \reg
+.endm
+
+.macro m_calculate_checksum dst, src, scratch
+  mov \dst, #0
+  .irp i,0,1,2,3,4,5,6,7,8,9,10,11,12,13,14,15,16,17,18,19,20,21,22,23,24,25,26,27,28
+    ldr \scratch, [\src, #(\i * 4)]
+    eor \dst, \dst, \scratch
+  .endr
+.endm
+
 // int sigsetjmp(sigjmp_buf env, int save_signal_mask);
 ENTRY(sigsetjmp)
-  // Record whether or not we're saving the signal mask.
+  stmfd sp!, {r0, lr}
+  .cfi_def_cfa_offset 8
+  .cfi_rel_offset r0, 0
+  .cfi_rel_offset lr, 4
+
+  mov r0, r1
+  bl __bionic_setjmp_cookie_get
+  mov r1, r0
+
+  ldmfd sp, {r0}
+
+  // Save the setjmp cookie for later.
+  bic r2, r1, #1
+  stmfd sp!, {r2}
+  .cfi_adjust_cfa_offset 4
+
+  // Record the setjmp cookie and whether or not we're saving the signal mask.
   str r1, [r0, #(_JB_SIGFLAG * 4)]
 
   // Do we need to save the signal mask?
-  teq r1, #0
+  tst r1, #1
   beq 1f
 
-  // Get current signal mask.
-  stmfd sp!, {r0, r14}
-  .cfi_def_cfa_offset 8
-  .cfi_rel_offset r0, 0
-  .cfi_rel_offset r14, 4
-  mov r0, #0
-  bl sigblock
-  mov r1, r0
-  ldmfd sp!, {r0, r14}
-  .cfi_def_cfa_offset 0
+  // Align the stack.
+  sub sp, #4
+  .cfi_adjust_cfa_offset 4
 
-  // Save the signal mask.
-  str r1, [r0, #(_JB_SIGMASK * 4)]
+  // Save the current signal mask.
+  add r2, r0, #(_JB_SIGMASK * 4)
+  mov r0, #2 // SIG_SETMASK
+  mov r1, #0
+  bl sigprocmask
+
+  // Unalign the stack.
+  add sp, #4
+  .cfi_adjust_cfa_offset -4
 
 1:
+  ldmfd sp!, {r2}
+  .cfi_adjust_cfa_offset -4
+  ldmfd sp!, {r0, lr}
+  .cfi_adjust_cfa_offset -8
+  .cfi_restore r0
+  .cfi_restore lr
+
   // Save core registers.
   add r1, r0, #(_JB_CORE_BASE * 4)
-  stmia r1, {r4-r14}
+  m_mangle_registers r2
+
+  // ARM deprecates using sp in the register list for stmia.
+  stmia r1, {r4-r11, lr}
+  str sp, [r1, #(9 * 4)]
+  m_unmangle_registers r2
 
   // Save floating-point registers.
   add r1, r0, #(_JB_FLOAT_BASE * 4)
@@ -116,35 +179,51 @@
   fmrx r1, fpscr
   str r1, [r0, #(_JB_FLOAT_STATE * 4)]
 
+#if USE_CHECKSUM
+  // Calculate the checksum.
+  m_calculate_checksum r12, r0, r2
+  str r12, [r0, #(_JB_CHECKSUM * 4)]
+#endif
+
   mov r0, #0
   bx lr
 END(sigsetjmp)
 
 // void siglongjmp(sigjmp_buf env, int value);
 ENTRY(siglongjmp)
-  // Do we need to restore the signal mask?
-  ldr r2, [r0, #(_JB_SIGFLAG * 4)]
-  teq r2, #0
-  beq 1f
-
-  // Restore the signal mask.
-  stmfd sp!, {r0, r1, r14}
+  stmfd sp!, {r0, r1, lr}
   .cfi_def_cfa_offset 12
   .cfi_rel_offset r0, 0
   .cfi_rel_offset r1, 4
-  .cfi_rel_offset r14, 8
-  sub sp, sp, #4 // Align the stack.
-  .cfi_adjust_cfa_offset 4
+  .cfi_rel_offset lr, 8
 
+#if USE_CHECKSUM
+  // Check the checksum before doing anything.
+  m_calculate_checksum r12, r0, r3
+  ldr r2, [r0, #(_JB_CHECKSUM * 4)]
+
+  teq r2, r12
+  bne __bionic_setjmp_checksum_mismatch
+#endif
+
+  // Fetch the signal flag.
+  ldr r1, [r0, #(_JB_SIGFLAG * 4)]
+
+  // Do we need to restore the signal mask?
+  ands r1, r1, #1
+  beq 1f
+
+  // Restore the signal mask.
   ldr r0, [r0, #(_JB_SIGMASK * 4)]
   bl sigsetmask
 
-  add sp, sp, #4 // Unalign the stack.
-  .cfi_adjust_cfa_offset -4
-  ldmfd sp!, {r0, r1, r14}
-  .cfi_def_cfa_offset 0
-
 1:
+  ldmfd sp!, {r0, r1, lr}
+  .cfi_adjust_cfa_offset -12
+  .cfi_restore r0
+  .cfi_restore r1
+  .cfi_restore lr
+
   // Restore floating-point registers.
   add r2, r0, #(_JB_FLOAT_BASE * 4)
   vldmia r2, {d8-d15}
@@ -153,17 +232,30 @@
   ldr r2, [r0, #(_JB_FLOAT_STATE * 4)]
   fmxr fpscr, r2
 
+  // Load the cookie.
+  ldr r3, [r0, #(_JB_SIGFLAG * 4)]
+  bic r3, r3, #1
+
   // Restore core registers.
   add r2, r0, #(_JB_CORE_BASE * 4)
-  ldmia r2, {r4-r14}
 
-  // Validate sp and r14.
-  teq sp, #0
-  teqne r14, #0
-  bleq longjmperror
+  // ARM deprecates using sp in the register list for ldmia.
+  ldmia r2, {r4-r11, lr}
+  ldr sp, [r2, #(9 * 4)]
+  m_unmangle_registers r3
 
-  // Set return value.
-  mov r0, r1
+  // Save the return value/address and check the setjmp cookie.
+  stmfd sp!, {r1, lr}
+  .cfi_adjust_cfa_offset 8
+  .cfi_rel_offset lr, 4
+  mov r0, r3
+  bl __bionic_setjmp_cookie_check
+
+  // Restore return value/address.
+  ldmfd sp!, {r0, lr}
+  .cfi_adjust_cfa_offset -8
+  .cfi_restore lr
+
   teq r0, #0
   moveq r0, #1
   bx lr
diff --git a/libc/include/sys/shm.h b/libc/arch-arm/bionic/vfork.S
similarity index 74%
copy from libc/include/sys/shm.h
copy to libc/arch-arm/bionic/vfork.S
index c691c29..1b7cbad 100644
--- a/libc/include/sys/shm.h
+++ b/libc/arch-arm/bionic/vfork.S
@@ -1,5 +1,5 @@
 /*
- * Copyright (C) 2014 The Android Open Source Project
+ * Copyright (C) 2015 The Android Open Source Project
  * All rights reserved.
  *
  * Redistribution and use in source and binary forms, with or without
@@ -26,9 +26,21 @@
  * SUCH DAMAGE.
  */
 
-#ifndef _SYS_SHM_H_
-#define _SYS_SHM_H_
+#include <private/bionic_asm.h>
 
-#include <linux/shm.h>
+ENTRY(vfork)
+    // __get_tls()[TLS_SLOT_THREAD_ID]->cached_pid_ = 0
+    mrc     p15, 0, r3, c13, c0, 3
+    ldr     r3, [r3, #4]
+    mov     r0, #0
+    str     r0, [r3, #12]
 
-#endif /* _SYS_SHM_H_ */
+    mov     ip, r7
+    ldr     r7, =__NR_vfork
+    swi     #0
+    mov     r7, ip
+    cmn     r0, #(MAX_ERRNO + 1)
+    bxls    lr
+    neg     r0, r0
+    b       __set_errno_internal
+END(vfork)
diff --git a/libc/arch-arm/cortex-a15/bionic/__strcat_chk.S b/libc/arch-arm/cortex-a15/bionic/__strcat_chk.S
index a2e9c22..3692f04 100644
--- a/libc/arch-arm/cortex-a15/bionic/__strcat_chk.S
+++ b/libc/arch-arm/cortex-a15/bionic/__strcat_chk.S
@@ -1,5 +1,5 @@
 /*
- * Copyright (C) 2013 The Android Open Source Project
+ * Copyright (C) 2015 The Android Open Source Project
  * All rights reserved.
  *
  * Redistribution and use in source and binary forms, with or without
@@ -26,191 +26,7 @@
  * SUCH DAMAGE.
  */
 
-#include <private/bionic_asm.h>
-#include <private/libc_events.h>
+// Indicate which memcpy base file to include.
+#define MEMCPY_BASE "memcpy_base.S"
 
-    .syntax unified
-
-    .thumb
-    .thumb_func
-
-// Get the length of src string, then get the source of the dst string.
-// Check that the two lengths together don't exceed the threshold, then
-// do a memcpy of the data.
-ENTRY(__strcat_chk)
-    pld     [r0, #0]
-    push    {r0, lr}
-    .cfi_def_cfa_offset 8
-    .cfi_rel_offset r0, 0
-    .cfi_rel_offset lr, 4
-    push    {r4, r5}
-    .cfi_adjust_cfa_offset 8
-    .cfi_rel_offset r4, 0
-    .cfi_rel_offset r5, 4
-
-    mov     lr, r2
-
-    // Save the dst register to r5
-    mov     r5, r0
-
-    // Zero out r4
-    eor     r4, r4, r4
-
-    // r1 contains the address of the string to count.
-.L_strlen_start:
-    mov     r0, r1
-    ands    r3, r1, #7
-    beq     .L_mainloop
-
-    // Align to a double word (64 bits).
-    rsb     r3, r3, #8
-    lsls    ip, r3, #31
-    beq     .L_align_to_32
-
-    ldrb    r2, [r1], #1
-    cbz     r2, .L_update_count_and_finish
-
-.L_align_to_32:
-    bcc     .L_align_to_64
-    ands    ip, r3, #2
-    beq     .L_align_to_64
-
-    ldrb    r2, [r1], #1
-    cbz     r2, .L_update_count_and_finish
-    ldrb    r2, [r1], #1
-    cbz     r2, .L_update_count_and_finish
-
-.L_align_to_64:
-    tst     r3, #4
-    beq     .L_mainloop
-    ldr     r3, [r1], #4
-
-    sub     ip, r3, #0x01010101
-    bic     ip, ip, r3
-    ands    ip, ip, #0x80808080
-    bne     .L_zero_in_second_register
-
-    .p2align 2
-.L_mainloop:
-    ldrd    r2, r3, [r1], #8
-
-    pld     [r1, #64]
-
-    sub     ip, r2, #0x01010101
-    bic     ip, ip, r2
-    ands    ip, ip, #0x80808080
-    bne     .L_zero_in_first_register
-
-    sub     ip, r3, #0x01010101
-    bic     ip, ip, r3
-    ands    ip, ip, #0x80808080
-    bne     .L_zero_in_second_register
-    b       .L_mainloop
-
-.L_update_count_and_finish:
-    sub     r3, r1, r0
-    sub     r3, r3, #1
-    b       .L_finish
-
-.L_zero_in_first_register:
-    sub     r3, r1, r0
-    lsls    r2, ip, #17
-    bne     .L_sub8_and_finish
-    bcs     .L_sub7_and_finish
-    lsls    ip, ip, #1
-    bne     .L_sub6_and_finish
-
-    sub     r3, r3, #5
-    b       .L_finish
-
-.L_sub8_and_finish:
-    sub     r3, r3, #8
-    b       .L_finish
-
-.L_sub7_and_finish:
-    sub     r3, r3, #7
-    b       .L_finish
-
-.L_sub6_and_finish:
-    sub     r3, r3, #6
-    b       .L_finish
-
-.L_zero_in_second_register:
-    sub     r3, r1, r0
-    lsls    r2, ip, #17
-    bne     .L_sub4_and_finish
-    bcs     .L_sub3_and_finish
-    lsls    ip, ip, #1
-    bne     .L_sub2_and_finish
-
-    sub     r3, r3, #1
-    b       .L_finish
-
-.L_sub4_and_finish:
-    sub     r3, r3, #4
-    b       .L_finish
-
-.L_sub3_and_finish:
-    sub     r3, r3, #3
-    b       .L_finish
-
-.L_sub2_and_finish:
-    sub     r3, r3, #2
-
-.L_finish:
-    cmp     r4, #0
-    bne     .L_strlen_done
-
-    // Time to get the dst string length.
-    mov     r1, r5
-
-    // Save the original source address to r5.
-    mov     r5, r0
-
-    // Save the current length (adding 1 for the terminator).
-    add     r4, r3, #1
-    b       .L_strlen_start
-
-    // r0 holds the pointer to the dst string.
-    // r3 holds the dst string length.
-    // r4 holds the src string length + 1.
-.L_strlen_done:
-    add     r2, r3, r4
-    cmp     r2, lr
-    bhi     __strcat_chk_failed
-
-    // Set up the registers for the memcpy code.
-    mov     r1, r5
-    pld     [r1, #64]
-    mov     r2, r4
-    add     r0, r0, r3
-    pop     {r4, r5}
-END(__strcat_chk)
-
-#define MEMCPY_BASE         __strcat_chk_memcpy_base
-#define MEMCPY_BASE_ALIGNED __strcat_chk_memcpy_base_aligned
-
-#include "memcpy_base.S"
-
-ENTRY_PRIVATE(__strcat_chk_failed)
-    .cfi_def_cfa_offset 8
-    .cfi_rel_offset r0, 0
-    .cfi_rel_offset lr, 4
-    .cfi_adjust_cfa_offset 8
-    .cfi_rel_offset r4, 0
-    .cfi_rel_offset r5, 4
-
-    ldr     r0, error_message
-    ldr     r1, error_code
-1:
-    add     r0, pc
-    bl      __fortify_chk_fail
-error_code:
-    .word   BIONIC_EVENT_STRCAT_BUFFER_OVERFLOW
-error_message:
-    .word   error_string-(1b+4)
-END(__strcat_chk_failed)
-
-    .data
-error_string:
-    .string "strcat: prevented write past end of buffer"
+#include "__strcat_chk_common.S"
diff --git a/libc/arch-arm/cortex-a15/bionic/__strcat_chk_common.S b/libc/arch-arm/cortex-a15/bionic/__strcat_chk_common.S
new file mode 100644
index 0000000..de66967
--- /dev/null
+++ b/libc/arch-arm/cortex-a15/bionic/__strcat_chk_common.S
@@ -0,0 +1,212 @@
+/*
+ * Copyright (C) 2013 The Android Open Source Project
+ * All rights reserved.
+ *
+ * Redistribution and use in source and binary forms, with or without
+ * modification, are permitted provided that the following conditions
+ * are met:
+ *  * Redistributions of source code must retain the above copyright
+ *    notice, this list of conditions and the following disclaimer.
+ *  * Redistributions in binary form must reproduce the above copyright
+ *    notice, this list of conditions and the following disclaimer in
+ *    the documentation and/or other materials provided with the
+ *    distribution.
+ *
+ * THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS
+ * "AS IS" AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT
+ * LIMITED TO, THE IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS
+ * FOR A PARTICULAR PURPOSE ARE DISCLAIMED. IN NO EVENT SHALL THE
+ * COPYRIGHT OWNER OR CONTRIBUTORS BE LIABLE FOR ANY DIRECT, INDIRECT,
+ * INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING,
+ * BUT NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; LOSS
+ * OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED
+ * AND ON ANY THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY,
+ * OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT
+ * OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF
+ * SUCH DAMAGE.
+ */
+
+#include <private/bionic_asm.h>
+#include <private/libc_events.h>
+
+    .syntax unified
+
+    .thumb
+    .thumb_func
+
+// Get the length of src string, then get the source of the dst string.
+// Check that the two lengths together don't exceed the threshold, then
+// do a memcpy of the data.
+ENTRY(__strcat_chk)
+    pld     [r0, #0]
+    push    {r0, lr}
+    .cfi_def_cfa_offset 8
+    .cfi_rel_offset r0, 0
+    .cfi_rel_offset lr, 4
+    push    {r4, r5}
+    .cfi_adjust_cfa_offset 8
+    .cfi_rel_offset r4, 0
+    .cfi_rel_offset r5, 4
+
+    mov     lr, r2
+
+    // Save the dst register to r5
+    mov     r5, r0
+
+    // Zero out r4
+    eor     r4, r4, r4
+
+    // r1 contains the address of the string to count.
+.L_strlen_start:
+    mov     r0, r1
+    ands    r3, r1, #7
+    beq     .L_mainloop
+
+    // Align to a double word (64 bits).
+    rsb     r3, r3, #8
+    lsls    ip, r3, #31
+    beq     .L_align_to_32
+
+    ldrb    r2, [r1], #1
+    cbz     r2, .L_update_count_and_finish
+
+.L_align_to_32:
+    bcc     .L_align_to_64
+    ands    ip, r3, #2
+    beq     .L_align_to_64
+
+    ldrb    r2, [r1], #1
+    cbz     r2, .L_update_count_and_finish
+    ldrb    r2, [r1], #1
+    cbz     r2, .L_update_count_and_finish
+
+.L_align_to_64:
+    tst     r3, #4
+    beq     .L_mainloop
+    ldr     r3, [r1], #4
+
+    sub     ip, r3, #0x01010101
+    bic     ip, ip, r3
+    ands    ip, ip, #0x80808080
+    bne     .L_zero_in_second_register
+
+    .p2align 2
+.L_mainloop:
+    ldrd    r2, r3, [r1], #8
+
+    pld     [r1, #64]
+
+    sub     ip, r2, #0x01010101
+    bic     ip, ip, r2
+    ands    ip, ip, #0x80808080
+    bne     .L_zero_in_first_register
+
+    sub     ip, r3, #0x01010101
+    bic     ip, ip, r3
+    ands    ip, ip, #0x80808080
+    bne     .L_zero_in_second_register
+    b       .L_mainloop
+
+.L_update_count_and_finish:
+    sub     r3, r1, r0
+    sub     r3, r3, #1
+    b       .L_finish
+
+.L_zero_in_first_register:
+    sub     r3, r1, r0
+    lsls    r2, ip, #17
+    bne     .L_sub8_and_finish
+    bcs     .L_sub7_and_finish
+    lsls    ip, ip, #1
+    bne     .L_sub6_and_finish
+
+    sub     r3, r3, #5
+    b       .L_finish
+
+.L_sub8_and_finish:
+    sub     r3, r3, #8
+    b       .L_finish
+
+.L_sub7_and_finish:
+    sub     r3, r3, #7
+    b       .L_finish
+
+.L_sub6_and_finish:
+    sub     r3, r3, #6
+    b       .L_finish
+
+.L_zero_in_second_register:
+    sub     r3, r1, r0
+    lsls    r2, ip, #17
+    bne     .L_sub4_and_finish
+    bcs     .L_sub3_and_finish
+    lsls    ip, ip, #1
+    bne     .L_sub2_and_finish
+
+    sub     r3, r3, #1
+    b       .L_finish
+
+.L_sub4_and_finish:
+    sub     r3, r3, #4
+    b       .L_finish
+
+.L_sub3_and_finish:
+    sub     r3, r3, #3
+    b       .L_finish
+
+.L_sub2_and_finish:
+    sub     r3, r3, #2
+
+.L_finish:
+    cmp     r4, #0
+    bne     .L_strlen_done
+
+    // Time to get the dst string length.
+    mov     r1, r5
+
+    // Save the original source address to r5.
+    mov     r5, r0
+
+    // Save the current length (adding 1 for the terminator).
+    add     r4, r3, #1
+    b       .L_strlen_start
+
+    // r0 holds the pointer to the dst string.
+    // r3 holds the dst string length.
+    // r4 holds the src string length + 1.
+.L_strlen_done:
+    add     r2, r3, r4
+    cmp     r2, lr
+    bhi     .L_strcat_chk_failed
+
+    // Set up the registers for the memcpy code.
+    mov     r1, r5
+    pld     [r1, #64]
+    mov     r2, r4
+    add     r0, r0, r3
+    pop     {r4, r5}
+    .cfi_adjust_cfa_offset -8
+    .cfi_restore r4
+    .cfi_restore r5
+
+#include MEMCPY_BASE
+
+    // Undo the above cfi directives
+    .cfi_adjust_cfa_offset 8
+    .cfi_rel_offset r4, 0
+    .cfi_rel_offset r5, 4
+.L_strcat_chk_failed:
+    ldr     r0, error_message
+    ldr     r1, error_code
+1:
+    add     r0, pc
+    bl      __fortify_chk_fail
+error_code:
+    .word   BIONIC_EVENT_STRCAT_BUFFER_OVERFLOW
+error_message:
+    .word   error_string-(1b+4)
+END(__strcat_chk)
+
+    .data
+error_string:
+    .string "strcat: prevented write past end of buffer"
diff --git a/libc/arch-arm/cortex-a15/bionic/__strcpy_chk.S b/libc/arch-arm/cortex-a15/bionic/__strcpy_chk.S
index db76686..d8cb3d9 100644
--- a/libc/arch-arm/cortex-a15/bionic/__strcpy_chk.S
+++ b/libc/arch-arm/cortex-a15/bionic/__strcpy_chk.S
@@ -1,5 +1,5 @@
 /*
- * Copyright (C) 2013 The Android Open Source Project
+ * Copyright (C) 2015 The Android Open Source Project
  * All rights reserved.
  *
  * Redistribution and use in source and binary forms, with or without
@@ -26,155 +26,7 @@
  * SUCH DAMAGE.
  */
 
-#include <private/bionic_asm.h>
-#include <private/libc_events.h>
+// Indicate which memcpy base file to include.
+#define MEMCPY_BASE "memcpy_base.S"
 
-    .syntax unified
-
-    .thumb
-    .thumb_func
-
-// Get the length of the source string first, then do a memcpy of the data
-// instead of a strcpy.
-ENTRY(__strcpy_chk)
-    pld     [r0, #0]
-    push    {r0, lr}
-    .cfi_def_cfa_offset 8
-    .cfi_rel_offset r0, 0
-    .cfi_rel_offset lr, 4
-
-    mov     lr, r2
-    mov     r0, r1
-
-    ands    r3, r1, #7
-    beq     .L_mainloop
-
-    // Align to a double word (64 bits).
-    rsb     r3, r3, #8
-    lsls    ip, r3, #31
-    beq     .L_align_to_32
-
-    ldrb    r2, [r0], #1
-    cbz     r2, .L_update_count_and_finish
-
-.L_align_to_32:
-    bcc     .L_align_to_64
-    ands    ip, r3, #2
-    beq     .L_align_to_64
-
-    ldrb    r2, [r0], #1
-    cbz     r2, .L_update_count_and_finish
-    ldrb    r2, [r0], #1
-    cbz     r2, .L_update_count_and_finish
-
-.L_align_to_64:
-    tst     r3, #4
-    beq     .L_mainloop
-    ldr     r3, [r0], #4
-
-    sub     ip, r3, #0x01010101
-    bic     ip, ip, r3
-    ands    ip, ip, #0x80808080
-    bne     .L_zero_in_second_register
-
-    .p2align 2
-.L_mainloop:
-    ldrd    r2, r3, [r0], #8
-
-    pld     [r0, #64]
-
-    sub     ip, r2, #0x01010101
-    bic     ip, ip, r2
-    ands    ip, ip, #0x80808080
-    bne     .L_zero_in_first_register
-
-    sub     ip, r3, #0x01010101
-    bic     ip, ip, r3
-    ands    ip, ip, #0x80808080
-    bne     .L_zero_in_second_register
-    b       .L_mainloop
-
-.L_update_count_and_finish:
-    sub     r3, r0, r1
-    sub     r3, r3, #1
-    b       .L_check_size
-
-.L_zero_in_first_register:
-    sub     r3, r0, r1
-    lsls    r2, ip, #17
-    bne     .L_sub8_and_finish
-    bcs     .L_sub7_and_finish
-    lsls    ip, ip, #1
-    bne     .L_sub6_and_finish
-
-    sub     r3, r3, #5
-    b       .L_check_size
-
-.L_sub8_and_finish:
-    sub     r3, r3, #8
-    b       .L_check_size
-
-.L_sub7_and_finish:
-    sub     r3, r3, #7
-    b       .L_check_size
-
-.L_sub6_and_finish:
-    sub     r3, r3, #6
-    b       .L_check_size
-
-.L_zero_in_second_register:
-    sub     r3, r0, r1
-    lsls    r2, ip, #17
-    bne     .L_sub4_and_finish
-    bcs     .L_sub3_and_finish
-    lsls    ip, ip, #1
-    bne     .L_sub2_and_finish
-
-    sub     r3, r3, #1
-    b       .L_check_size
-
-.L_sub4_and_finish:
-    sub     r3, r3, #4
-    b       .L_check_size
-
-.L_sub3_and_finish:
-    sub     r3, r3, #3
-    b       .L_check_size
-
-.L_sub2_and_finish:
-    sub     r3, r3, #2
-
-.L_check_size:
-    pld     [r1, #0]
-    pld     [r1, #64]
-    ldr     r0, [sp]
-    cmp     r3, lr
-    bhs     __strcpy_chk_failed
-
-    // Add 1 for copy length to get the string terminator.
-    add     r2, r3, #1
-END(__strcpy_chk)
-
-#define MEMCPY_BASE         __strcpy_chk_memcpy_base
-#define MEMCPY_BASE_ALIGNED __strcpy_chk_memcpy_base_aligned
-#include "memcpy_base.S"
-
-ENTRY_PRIVATE(__strcpy_chk_failed)
-    .cfi_def_cfa_offset 8
-    .cfi_rel_offset r0, 0
-    .cfi_rel_offset lr, 4
-
-    ldr     r0, error_message
-    ldr     r1, error_code
-1:
-    add     r0, pc
-    bl      __fortify_chk_fail
-error_code:
-    .word   BIONIC_EVENT_STRCPY_BUFFER_OVERFLOW
-error_message:
-    .word   error_string-(1b+4)
-END(__strcpy_chk_failed)
-
-    .data
-error_string:
-    .string "strcpy: prevented write past end of buffer"
+#include "__strcpy_chk_common.S"
diff --git a/libc/arch-arm/cortex-a15/bionic/__strcpy_chk_common.S b/libc/arch-arm/cortex-a15/bionic/__strcpy_chk_common.S
new file mode 100644
index 0000000..69ebcb4
--- /dev/null
+++ b/libc/arch-arm/cortex-a15/bionic/__strcpy_chk_common.S
@@ -0,0 +1,173 @@
+/*
+ * Copyright (C) 2013 The Android Open Source Project
+ * All rights reserved.
+ *
+ * Redistribution and use in source and binary forms, with or without
+ * modification, are permitted provided that the following conditions
+ * are met:
+ *  * Redistributions of source code must retain the above copyright
+ *    notice, this list of conditions and the following disclaimer.
+ *  * Redistributions in binary form must reproduce the above copyright
+ *    notice, this list of conditions and the following disclaimer in
+ *    the documentation and/or other materials provided with the
+ *    distribution.
+ *
+ * THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS
+ * "AS IS" AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT
+ * LIMITED TO, THE IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS
+ * FOR A PARTICULAR PURPOSE ARE DISCLAIMED. IN NO EVENT SHALL THE
+ * COPYRIGHT OWNER OR CONTRIBUTORS BE LIABLE FOR ANY DIRECT, INDIRECT,
+ * INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING,
+ * BUT NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; LOSS
+ * OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED
+ * AND ON ANY THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY,
+ * OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT
+ * OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF
+ * SUCH DAMAGE.
+ */
+
+#include <private/bionic_asm.h>
+#include <private/libc_events.h>
+
+    .syntax unified
+
+    .thumb
+    .thumb_func
+
+// Get the length of the source string first, then do a memcpy of the data
+// instead of a strcpy.
+ENTRY(__strcpy_chk)
+    pld     [r0, #0]
+    push    {r0, lr}
+    .cfi_def_cfa_offset 8
+    .cfi_rel_offset r0, 0
+    .cfi_rel_offset lr, 4
+
+    mov     lr, r2
+    mov     r0, r1
+
+    ands    r3, r1, #7
+    beq     .L_mainloop
+
+    // Align to a double word (64 bits).
+    rsb     r3, r3, #8
+    lsls    ip, r3, #31
+    beq     .L_align_to_32
+
+    ldrb    r2, [r0], #1
+    cbz     r2, .L_update_count_and_finish
+
+.L_align_to_32:
+    bcc     .L_align_to_64
+    ands    ip, r3, #2
+    beq     .L_align_to_64
+
+    ldrb    r2, [r0], #1
+    cbz     r2, .L_update_count_and_finish
+    ldrb    r2, [r0], #1
+    cbz     r2, .L_update_count_and_finish
+
+.L_align_to_64:
+    tst     r3, #4
+    beq     .L_mainloop
+    ldr     r3, [r0], #4
+
+    sub     ip, r3, #0x01010101
+    bic     ip, ip, r3
+    ands    ip, ip, #0x80808080
+    bne     .L_zero_in_second_register
+
+    .p2align 2
+.L_mainloop:
+    ldrd    r2, r3, [r0], #8
+
+    pld     [r0, #64]
+
+    sub     ip, r2, #0x01010101
+    bic     ip, ip, r2
+    ands    ip, ip, #0x80808080
+    bne     .L_zero_in_first_register
+
+    sub     ip, r3, #0x01010101
+    bic     ip, ip, r3
+    ands    ip, ip, #0x80808080
+    bne     .L_zero_in_second_register
+    b       .L_mainloop
+
+.L_update_count_and_finish:
+    sub     r3, r0, r1
+    sub     r3, r3, #1
+    b       .L_check_size
+
+.L_zero_in_first_register:
+    sub     r3, r0, r1
+    lsls    r2, ip, #17
+    bne     .L_sub8_and_finish
+    bcs     .L_sub7_and_finish
+    lsls    ip, ip, #1
+    bne     .L_sub6_and_finish
+
+    sub     r3, r3, #5
+    b       .L_check_size
+
+.L_sub8_and_finish:
+    sub     r3, r3, #8
+    b       .L_check_size
+
+.L_sub7_and_finish:
+    sub     r3, r3, #7
+    b       .L_check_size
+
+.L_sub6_and_finish:
+    sub     r3, r3, #6
+    b       .L_check_size
+
+.L_zero_in_second_register:
+    sub     r3, r0, r1
+    lsls    r2, ip, #17
+    bne     .L_sub4_and_finish
+    bcs     .L_sub3_and_finish
+    lsls    ip, ip, #1
+    bne     .L_sub2_and_finish
+
+    sub     r3, r3, #1
+    b       .L_check_size
+
+.L_sub4_and_finish:
+    sub     r3, r3, #4
+    b       .L_check_size
+
+.L_sub3_and_finish:
+    sub     r3, r3, #3
+    b       .L_check_size
+
+.L_sub2_and_finish:
+    sub     r3, r3, #2
+
+.L_check_size:
+    pld     [r1, #0]
+    pld     [r1, #64]
+    ldr     r0, [sp]
+    cmp     r3, lr
+    bhs     .L_strcpy_chk_failed
+
+    // Add 1 for copy length to get the string terminator.
+    add     r2, r3, #1
+
+#include MEMCPY_BASE
+
+.L_strcpy_chk_failed:
+    ldr     r0, error_message
+    ldr     r1, error_code
+1:
+    add     r0, pc
+    bl      __fortify_chk_fail
+error_code:
+    .word   BIONIC_EVENT_STRCPY_BUFFER_OVERFLOW
+error_message:
+    .word   error_string-(1b+4)
+END(__strcpy_chk)
+
+    .data
+error_string:
+    .string "strcpy: prevented write past end of buffer"
diff --git a/libc/arch-arm/cortex-a15/bionic/memcpy.S b/libc/arch-arm/cortex-a15/bionic/memcpy.S
index 410b663..537f3de 100644
--- a/libc/arch-arm/cortex-a15/bionic/memcpy.S
+++ b/libc/arch-arm/cortex-a15/bionic/memcpy.S
@@ -1,5 +1,5 @@
 /*
- * Copyright (C) 2008 The Android Open Source Project
+ * Copyright (C) 2015 The Android Open Source Project
  * All rights reserved.
  *
  * Redistribution and use in source and binary forms, with or without
@@ -25,79 +25,8 @@
  * OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF
  * SUCH DAMAGE.
  */
-/*
- * Copyright (c) 2013 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.
- */
 
-// Prototype: void *memcpy (void *dst, const void *src, size_t count).
+// Indicate which memcpy base file to include.
+#define MEMCPY_BASE "memcpy_base.S"
 
-#include <private/bionic_asm.h>
-#include <private/libc_events.h>
-
-        .text
-        .syntax unified
-        .fpu    neon
-
-ENTRY(__memcpy_chk)
-        cmp     r2, r3
-        bhi     __memcpy_chk_fail
-
-        // Fall through to memcpy...
-END(__memcpy_chk)
-
-ENTRY(memcpy)
-        pld     [r1, #64]
-        push    {r0, lr}
-        .cfi_def_cfa_offset 8
-        .cfi_rel_offset r0, 0
-        .cfi_rel_offset lr, 4
-END(memcpy)
-
-#define MEMCPY_BASE         __memcpy_base
-#define MEMCPY_BASE_ALIGNED __memcpy_base_aligned
-#include "memcpy_base.S"
-
-ENTRY_PRIVATE(__memcpy_chk_fail)
-        // Preserve lr for backtrace.
-        push    {lr}
-        .cfi_def_cfa_offset 4
-        .cfi_rel_offset lr, 0
-
-        ldr     r0, error_message
-        ldr     r1, error_code
-1:
-        add     r0, pc
-        bl      __fortify_chk_fail
-error_code:
-        .word   BIONIC_EVENT_MEMCPY_BUFFER_OVERFLOW
-error_message:
-        .word   error_string-(1b+8)
-END(__memcpy_chk_fail)
-
-        .data
-error_string:
-        .string "memcpy: prevented write past end of buffer"
+#include "memcpy_common.S"
diff --git a/libc/arch-arm/cortex-a15/bionic/memcpy_base.S b/libc/arch-arm/cortex-a15/bionic/memcpy_base.S
index 2a73852..aac737d 100644
--- a/libc/arch-arm/cortex-a15/bionic/memcpy_base.S
+++ b/libc/arch-arm/cortex-a15/bionic/memcpy_base.S
@@ -53,11 +53,7 @@
  * SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE.
  */
 
-ENTRY_PRIVATE(MEMCPY_BASE)
-        .cfi_def_cfa_offset 8
-        .cfi_rel_offset r0, 0
-        .cfi_rel_offset lr, 4
-
+.L_memcpy_base:
         // Assumes that n >= 0, and dst, src are valid pointers.
         // For any sizes less than 832 use the neon code that doesn't
         // care about the src alignment. This avoids any checks
@@ -168,12 +164,6 @@
         eor     r3, r0, r1
         ands    r3, r3, #0x3
         bne     .L_copy_unknown_alignment
-END(MEMCPY_BASE)
-
-ENTRY_PRIVATE(MEMCPY_BASE_ALIGNED)
-        .cfi_def_cfa_offset 8
-        .cfi_rel_offset r0, 0
-        .cfi_rel_offset lr, 4
 
         // To try and improve performance, stack layout changed,
         // i.e., not keeping the stack looking like users expect
@@ -185,7 +175,7 @@
         strd    r6, r7, [sp, #-8]!
         .cfi_adjust_cfa_offset 8
         .cfi_rel_offset r6, 0
-        .cfi_rel_offset r7, 0
+        .cfi_rel_offset r7, 4
         strd    r8, r9, [sp, #-8]!
         .cfi_adjust_cfa_offset 8
         .cfi_rel_offset r8, 0
@@ -291,10 +281,28 @@
 
         // Restore registers: optimized pop {r0, pc}
         ldrd    r8, r9, [sp], #8
+        .cfi_adjust_cfa_offset -8
+        .cfi_restore r8
+        .cfi_restore r9
         ldrd    r6, r7, [sp], #8
+        .cfi_adjust_cfa_offset -8
+        .cfi_restore r6
+        .cfi_restore r7
         ldrd    r4, r5, [sp], #8
+        .cfi_adjust_cfa_offset -8
+        .cfi_restore r4
+        .cfi_restore r5
         pop     {r0, pc}
 
+        // Put the cfi directives back for the below instructions.
+        .cfi_adjust_cfa_offset 24
+        .cfi_rel_offset r4, 0
+        .cfi_rel_offset r5, 4
+        .cfi_rel_offset r6, 8
+        .cfi_rel_offset r7, 12
+        .cfi_rel_offset r8, 16
+        .cfi_rel_offset r9, 20
+
 .L_dst_not_word_aligned:
         // Align dst to word.
         rsb     ip, ip, #4
@@ -315,4 +323,12 @@
 
         // Src is guaranteed to be at least word aligned by this point.
         b       .L_word_aligned
-END(MEMCPY_BASE_ALIGNED)
+
+        // Undo any cfi directives from above.
+        .cfi_adjust_cfa_offset -24
+        .cfi_restore r4
+        .cfi_restore r5
+        .cfi_restore r6
+        .cfi_restore r7
+        .cfi_restore r8
+        .cfi_restore r9
diff --git a/libc/arch-arm/cortex-a15/bionic/memcpy_common.S b/libc/arch-arm/cortex-a15/bionic/memcpy_common.S
new file mode 100644
index 0000000..464fb46
--- /dev/null
+++ b/libc/arch-arm/cortex-a15/bionic/memcpy_common.S
@@ -0,0 +1,103 @@
+/*
+ * 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.
+ */
+/*
+ * Copyright (c) 2013 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.
+ */
+
+#include <private/bionic_asm.h>
+#include <private/libc_events.h>
+
+        .text
+        .syntax unified
+        .fpu    neon
+
+ENTRY(__memcpy_chk)
+        cmp     r2, r3
+        bhi     .L_memcpy_chk_fail
+
+        // Fall through to memcpy...
+END(__memcpy_chk)
+
+// Prototype: void *memcpy (void *dst, const void *src, size_t count).
+ENTRY(memcpy)
+        pld     [r1, #64]
+        push    {r0, lr}
+        .cfi_def_cfa_offset 8
+        .cfi_rel_offset r0, 0
+        .cfi_rel_offset lr, 4
+
+#include MEMCPY_BASE
+
+        // Undo the cfi instructions from above.
+        .cfi_def_cfa_offset 0
+        .cfi_restore r0
+        .cfi_restore lr
+.L_memcpy_chk_fail:
+        // Preserve lr for backtrace.
+        push    {lr}
+        .cfi_adjust_cfa_offset 4
+        .cfi_rel_offset lr, 0
+
+        ldr     r0, error_message
+        ldr     r1, error_code
+1:
+        add     r0, pc
+        bl      __fortify_chk_fail
+error_code:
+        .word   BIONIC_EVENT_MEMCPY_BUFFER_OVERFLOW
+error_message:
+        .word   error_string-(1b+8)
+END(memcpy)
+
+        .data
+error_string:
+        .string "memcpy: prevented write past end of buffer"
diff --git a/libc/arch-arm/cortex-a15/bionic/strcat.S b/libc/arch-arm/cortex-a15/bionic/strcat.S
index b95be94..157cc9f 100644
--- a/libc/arch-arm/cortex-a15/bionic/strcat.S
+++ b/libc/arch-arm/cortex-a15/bionic/strcat.S
@@ -70,7 +70,7 @@
 
     .macro m_scan_byte
     ldrb    r3, [r0]
-    cbz     r3, strcat_r0_scan_done
+    cbz     r3, .L_strcat_r0_scan_done
     add     r0, #1
     .endm // m_scan_byte
 
@@ -84,10 +84,10 @@
     // Quick check to see if src is empty.
     ldrb    r2, [r1]
     pld     [r1, #0]
-    cbnz    r2, strcat_continue
+    cbnz    r2, .L_strcat_continue
     bx      lr
 
-strcat_continue:
+.L_strcat_continue:
     // To speed up really small dst strings, unroll checking the first 4 bytes.
     m_push
     m_scan_byte
@@ -96,95 +96,102 @@
     m_scan_byte
 
     ands    r3, r0, #7
-    beq     strcat_mainloop
+    beq     .L_strcat_mainloop
 
     // Align to a double word (64 bits).
     rsb     r3, r3, #8
     lsls    ip, r3, #31
-    beq     strcat_align_to_32
+    beq     .L_strcat_align_to_32
 
     ldrb    r5, [r0]
-    cbz     r5, strcat_r0_scan_done
+    cbz     r5, .L_strcat_r0_scan_done
     add     r0, r0, #1
 
-strcat_align_to_32:
-    bcc     strcat_align_to_64
+.L_strcat_align_to_32:
+    bcc     .L_strcat_align_to_64
 
     ldrb    r2, [r0]
-    cbz     r2, strcat_r0_scan_done
+    cbz     r2, .L_strcat_r0_scan_done
     add     r0, r0, #1
     ldrb    r4, [r0]
-    cbz     r4, strcat_r0_scan_done
+    cbz     r4, .L_strcat_r0_scan_done
     add     r0, r0, #1
 
-strcat_align_to_64:
+.L_strcat_align_to_64:
     tst     r3, #4
-    beq     strcat_mainloop
+    beq     .L_strcat_mainloop
     ldr     r3, [r0], #4
 
     sub     ip, r3, #0x01010101
     bic     ip, ip, r3
     ands    ip, ip, #0x80808080
-    bne     strcat_zero_in_second_register
-    b       strcat_mainloop
+    bne     .L_strcat_zero_in_second_register
+    b       .L_strcat_mainloop
 
-strcat_r0_scan_done:
+.L_strcat_r0_scan_done:
     // For short copies, hard-code checking the first 8 bytes since this
     // new code doesn't win until after about 8 bytes.
-    m_copy_byte reg=r2, cmd=cbz, label=strcpy_finish
-    m_copy_byte reg=r3, cmd=cbz, label=strcpy_finish
-    m_copy_byte reg=r4, cmd=cbz, label=strcpy_finish
-    m_copy_byte reg=r5, cmd=cbz, label=strcpy_finish
-    m_copy_byte reg=r2, cmd=cbz, label=strcpy_finish
-    m_copy_byte reg=r3, cmd=cbz, label=strcpy_finish
-    m_copy_byte reg=r4, cmd=cbz, label=strcpy_finish
-    m_copy_byte reg=r5, cmd=cbnz, label=strcpy_continue
+    m_copy_byte reg=r2, cmd=cbz, label=.L_strcpy_finish
+    m_copy_byte reg=r3, cmd=cbz, label=.L_strcpy_finish
+    m_copy_byte reg=r4, cmd=cbz, label=.L_strcpy_finish
+    m_copy_byte reg=r5, cmd=cbz, label=.L_strcpy_finish
+    m_copy_byte reg=r2, cmd=cbz, label=.L_strcpy_finish
+    m_copy_byte reg=r3, cmd=cbz, label=.L_strcpy_finish
+    m_copy_byte reg=r4, cmd=cbz, label=.L_strcpy_finish
+    m_copy_byte reg=r5, cmd=cbnz, label=.L_strcpy_continue
 
-strcpy_finish:
+.L_strcpy_finish:
     m_pop
 
-strcpy_continue:
+.L_strcpy_continue:
     ands    r3, r0, #7
-    beq     strcpy_check_src_align
+    beq     .L_strcpy_check_src_align
 
     // Align to a double word (64 bits).
     rsb     r3, r3, #8
     lsls    ip, r3, #31
-    beq     strcpy_align_to_32
+    beq     .L_strcpy_align_to_32
 
     ldrb    r2, [r1], #1
     strb    r2, [r0], #1
-    cbz     r2, strcpy_complete
+    cbz     r2, .L_strcpy_complete
 
-strcpy_align_to_32:
-    bcc     strcpy_align_to_64
+.L_strcpy_align_to_32:
+    bcc     .L_strcpy_align_to_64
 
     ldrb    r2, [r1], #1
     strb    r2, [r0], #1
-    cbz     r2, strcpy_complete
+    cbz     r2, .L_strcpy_complete
     ldrb    r2, [r1], #1
     strb    r2, [r0], #1
-    cbz     r2, strcpy_complete
+    cbz     r2, .L_strcpy_complete
 
-strcpy_align_to_64:
+.L_strcpy_align_to_64:
     tst     r3, #4
-    beq     strcpy_check_src_align
-    ldr     r2, [r1], #4
+    beq     .L_strcpy_check_src_align
+    // Read one byte at a time since we don't know the src alignment
+    // and we don't want to read into a different page.
+    ldrb    r2, [r1], #1
+    strb    r2, [r0], #1
+    cbz     r2, .L_strcpy_complete
+    ldrb    r2, [r1], #1
+    strb    r2, [r0], #1
+    cbz     r2, .L_strcpy_complete
+    ldrb    r2, [r1], #1
+    strb    r2, [r0], #1
+    cbz     r2, .L_strcpy_complete
+    ldrb    r2, [r1], #1
+    strb    r2, [r0], #1
+    cbz     r2, .L_strcpy_complete
 
-    sub     ip, r2, #0x01010101
-    bic     ip, ip, r2
-    ands    ip, ip, #0x80808080
-    bne     strcpy_zero_in_first_register
-    str     r2, [r0], #4
-
-strcpy_check_src_align:
+.L_strcpy_check_src_align:
     // At this point dst is aligned to a double word, check if src
     // is also aligned to a double word.
     ands    r3, r1, #7
-    bne     strcpy_unaligned_copy
+    bne     .L_strcpy_unaligned_copy
 
     .p2align 2
-strcpy_mainloop:
+.L_strcpy_mainloop:
     ldrd    r2, r3, [r1], #8
 
     pld     [r1, #64]
@@ -192,128 +199,128 @@
     sub     ip, r2, #0x01010101
     bic     ip, ip, r2
     ands    ip, ip, #0x80808080
-    bne     strcpy_zero_in_first_register
+    bne     .L_strcpy_zero_in_first_register
 
     sub     ip, r3, #0x01010101
     bic     ip, ip, r3
     ands    ip, ip, #0x80808080
-    bne     strcpy_zero_in_second_register
+    bne     .L_strcpy_zero_in_second_register
 
     strd    r2, r3, [r0], #8
-    b       strcpy_mainloop
+    b       .L_strcpy_mainloop
 
-strcpy_complete:
+.L_strcpy_complete:
     m_pop
 
-strcpy_zero_in_first_register:
+.L_strcpy_zero_in_first_register:
     lsls    lr, ip, #17
-    bne     strcpy_copy1byte
-    bcs     strcpy_copy2bytes
+    bne     .L_strcpy_copy1byte
+    bcs     .L_strcpy_copy2bytes
     lsls    ip, ip, #1
-    bne     strcpy_copy3bytes
+    bne     .L_strcpy_copy3bytes
 
-strcpy_copy4bytes:
+.L_strcpy_copy4bytes:
     // Copy 4 bytes to the destiniation.
     str     r2, [r0]
     m_pop
 
-strcpy_copy1byte:
+.L_strcpy_copy1byte:
     strb    r2, [r0]
     m_pop
 
-strcpy_copy2bytes:
+.L_strcpy_copy2bytes:
     strh    r2, [r0]
     m_pop
 
-strcpy_copy3bytes:
+.L_strcpy_copy3bytes:
     strh    r2, [r0], #2
     lsr     r2, #16
     strb    r2, [r0]
     m_pop
 
-strcpy_zero_in_second_register:
+.L_strcpy_zero_in_second_register:
     lsls    lr, ip, #17
-    bne     strcpy_copy5bytes
-    bcs     strcpy_copy6bytes
+    bne     .L_strcpy_copy5bytes
+    bcs     .L_strcpy_copy6bytes
     lsls    ip, ip, #1
-    bne     strcpy_copy7bytes
+    bne     .L_strcpy_copy7bytes
 
     // Copy 8 bytes to the destination.
     strd    r2, r3, [r0]
     m_pop
 
-strcpy_copy5bytes:
+.L_strcpy_copy5bytes:
     str     r2, [r0], #4
     strb    r3, [r0]
     m_pop
 
-strcpy_copy6bytes:
+.L_strcpy_copy6bytes:
     str     r2, [r0], #4
     strh    r3, [r0]
     m_pop
 
-strcpy_copy7bytes:
+.L_strcpy_copy7bytes:
     str     r2, [r0], #4
     strh    r3, [r0], #2
     lsr     r3, #16
     strb    r3, [r0]
     m_pop
 
-strcpy_unaligned_copy:
+.L_strcpy_unaligned_copy:
     // Dst is aligned to a double word, while src is at an unknown alignment.
     // There are 7 different versions of the unaligned copy code
     // to prevent overreading the src. The mainloop of every single version
     // will store 64 bits per loop. The difference is how much of src can
     // be read without potentially crossing a page boundary.
     tbb     [pc, r3]
-strcpy_unaligned_branchtable:
+.L_strcpy_unaligned_branchtable:
     .byte 0
-    .byte ((strcpy_unalign7 - strcpy_unaligned_branchtable)/2)
-    .byte ((strcpy_unalign6 - strcpy_unaligned_branchtable)/2)
-    .byte ((strcpy_unalign5 - strcpy_unaligned_branchtable)/2)
-    .byte ((strcpy_unalign4 - strcpy_unaligned_branchtable)/2)
-    .byte ((strcpy_unalign3 - strcpy_unaligned_branchtable)/2)
-    .byte ((strcpy_unalign2 - strcpy_unaligned_branchtable)/2)
-    .byte ((strcpy_unalign1 - strcpy_unaligned_branchtable)/2)
+    .byte ((.L_strcpy_unalign7 - .L_strcpy_unaligned_branchtable)/2)
+    .byte ((.L_strcpy_unalign6 - .L_strcpy_unaligned_branchtable)/2)
+    .byte ((.L_strcpy_unalign5 - .L_strcpy_unaligned_branchtable)/2)
+    .byte ((.L_strcpy_unalign4 - .L_strcpy_unaligned_branchtable)/2)
+    .byte ((.L_strcpy_unalign3 - .L_strcpy_unaligned_branchtable)/2)
+    .byte ((.L_strcpy_unalign2 - .L_strcpy_unaligned_branchtable)/2)
+    .byte ((.L_strcpy_unalign1 - .L_strcpy_unaligned_branchtable)/2)
 
     .p2align 2
     // Can read 7 bytes before possibly crossing a page.
-strcpy_unalign7:
+.L_strcpy_unalign7:
     ldr     r2, [r1], #4
 
     sub     ip, r2, #0x01010101
     bic     ip, ip, r2
     ands    ip, ip, #0x80808080
-    bne     strcpy_zero_in_first_register
+    bne     .L_strcpy_zero_in_first_register
 
     ldrb    r3, [r1]
-    cbz     r3, strcpy_unalign7_copy5bytes
+    cbz     r3, .L_strcpy_unalign7_copy5bytes
     ldrb    r4, [r1, #1]
-    cbz     r4, strcpy_unalign7_copy6bytes
+    cbz     r4, .L_strcpy_unalign7_copy6bytes
     ldrb    r5, [r1, #2]
-    cbz     r5, strcpy_unalign7_copy7bytes
+    cbz     r5, .L_strcpy_unalign7_copy7bytes
 
     ldr     r3, [r1], #4
     pld     [r1, #64]
 
     lsrs    ip, r3, #24
     strd    r2, r3, [r0], #8
-    beq     strcpy_unalign_return
-    b       strcpy_unalign7
+    beq     .L_strcpy_unalign_return
+    b       .L_strcpy_unalign7
 
-strcpy_unalign7_copy5bytes:
+.L_strcpy_unalign7_copy5bytes:
     str     r2, [r0], #4
     strb    r3, [r0]
-strcpy_unalign_return:
+.L_strcpy_unalign_return:
     m_pop
 
-strcpy_unalign7_copy6bytes:
+.L_strcpy_unalign7_copy6bytes:
     str     r2, [r0], #4
     strb    r3, [r0], #1
     strb    r4, [r0], #1
     m_pop
 
-strcpy_unalign7_copy7bytes:
+.L_strcpy_unalign7_copy7bytes:
     str     r2, [r0], #4
     strb    r3, [r0], #1
     strb    r4, [r0], #1
@@ -322,41 +329,41 @@
 
     .p2align 2
     // Can read 6 bytes before possibly crossing a page.
-strcpy_unalign6:
+.L_strcpy_unalign6:
     ldr     r2, [r1], #4
 
     sub     ip, r2, #0x01010101
     bic     ip, ip, r2
     ands    ip, ip, #0x80808080
-    bne     strcpy_zero_in_first_register
+    bne     .L_strcpy_zero_in_first_register
 
     ldrb    r4, [r1]
-    cbz     r4, strcpy_unalign_copy5bytes
+    cbz     r4, .L_strcpy_unalign_copy5bytes
     ldrb    r5, [r1, #1]
-    cbz     r5, strcpy_unalign_copy6bytes
+    cbz     r5, .L_strcpy_unalign_copy6bytes
 
     ldr     r3, [r1], #4
     pld     [r1, #64]
 
     tst     r3, #0xff0000
-    beq     strcpy_copy7bytes
+    beq     .L_strcpy_copy7bytes
     lsrs    ip, r3, #24
     strd    r2, r3, [r0], #8
-    beq     strcpy_unalign_return
-    b       strcpy_unalign6
+    beq     .L_strcpy_unalign_return
+    b       .L_strcpy_unalign6
 
     .p2align 2
     // Can read 5 bytes before possibly crossing a page.
-strcpy_unalign5:
+.L_strcpy_unalign5:
     ldr     r2, [r1], #4
 
     sub     ip, r2, #0x01010101
     bic     ip, ip, r2
     ands    ip, ip, #0x80808080
-    bne     strcpy_zero_in_first_register
+    bne     .L_strcpy_zero_in_first_register
 
     ldrb    r4, [r1]
-    cbz     r4, strcpy_unalign_copy5bytes
+    cbz     r4, .L_strcpy_unalign_copy5bytes
 
     ldr     r3, [r1], #4
 
@@ -365,17 +372,17 @@
     sub     ip, r3, #0x01010101
     bic     ip, ip, r3
     ands    ip, ip, #0x80808080
-    bne     strcpy_zero_in_second_register
+    bne     .L_strcpy_zero_in_second_register
 
     strd    r2, r3, [r0], #8
-    b       strcpy_unalign5
+    b       .L_strcpy_unalign5
 
-strcpy_unalign_copy5bytes:
+.L_strcpy_unalign_copy5bytes:
     str     r2, [r0], #4
     strb    r4, [r0]
     m_pop
 
-strcpy_unalign_copy6bytes:
+.L_strcpy_unalign_copy6bytes:
     str     r2, [r0], #4
     strb    r4, [r0], #1
     strb    r5, [r0]
@@ -383,13 +390,13 @@
 
     .p2align 2
     // Can read 4 bytes before possibly crossing a page.
-strcpy_unalign4:
+.L_strcpy_unalign4:
     ldr     r2, [r1], #4
 
     sub     ip, r2, #0x01010101
     bic     ip, ip, r2
     ands    ip, ip, #0x80808080
-    bne     strcpy_zero_in_first_register
+    bne     .L_strcpy_zero_in_first_register
 
     ldr     r3, [r1], #4
     pld     [r1, #64]
@@ -397,20 +404,20 @@
     sub     ip, r3, #0x01010101
     bic     ip, ip, r3
     ands    ip, ip, #0x80808080
-    bne     strcpy_zero_in_second_register
+    bne     .L_strcpy_zero_in_second_register
 
     strd    r2, r3, [r0], #8
-    b       strcpy_unalign4
+    b       .L_strcpy_unalign4
 
     .p2align 2
     // Can read 3 bytes before possibly crossing a page.
-strcpy_unalign3:
+.L_strcpy_unalign3:
     ldrb    r2, [r1]
-    cbz     r2, strcpy_unalign3_copy1byte
+    cbz     r2, .L_strcpy_unalign3_copy1byte
     ldrb    r3, [r1, #1]
-    cbz     r3, strcpy_unalign3_copy2bytes
+    cbz     r3, .L_strcpy_unalign3_copy2bytes
     ldrb    r4, [r1, #2]
-    cbz     r4, strcpy_unalign3_copy3bytes
+    cbz     r4, .L_strcpy_unalign3_copy3bytes
 
     ldr     r2, [r1], #4
     ldr     r3, [r1], #4
@@ -418,26 +425,26 @@
     pld     [r1, #64]
 
     lsrs    lr, r2, #24
-    beq     strcpy_copy4bytes
+    beq     .L_strcpy_copy4bytes
 
     sub     ip, r3, #0x01010101
     bic     ip, ip, r3
     ands    ip, ip, #0x80808080
-    bne     strcpy_zero_in_second_register
+    bne     .L_strcpy_zero_in_second_register
 
     strd    r2, r3, [r0], #8
-    b       strcpy_unalign3
+    b       .L_strcpy_unalign3
 
-strcpy_unalign3_copy1byte:
+.L_strcpy_unalign3_copy1byte:
     strb    r2, [r0]
     m_pop
 
-strcpy_unalign3_copy2bytes:
+.L_strcpy_unalign3_copy2bytes:
     strb    r2, [r0], #1
     strb    r3, [r0]
     m_pop
 
-strcpy_unalign3_copy3bytes:
+.L_strcpy_unalign3_copy3bytes:
     strb    r2, [r0], #1
     strb    r3, [r0], #1
     strb    r4, [r0]
@@ -445,34 +452,34 @@
 
     .p2align 2
     // Can read 2 bytes before possibly crossing a page.
-strcpy_unalign2:
+.L_strcpy_unalign2:
     ldrb    r2, [r1]
-    cbz     r2, strcpy_unalign_copy1byte
+    cbz     r2, .L_strcpy_unalign_copy1byte
     ldrb    r4, [r1, #1]
-    cbz     r4, strcpy_unalign_copy2bytes
+    cbz     r4, .L_strcpy_unalign_copy2bytes
 
     ldr     r2, [r1], #4
     ldr     r3, [r1], #4
     pld     [r1, #64]
 
     tst     r2, #0xff0000
-    beq     strcpy_copy3bytes
+    beq     .L_strcpy_copy3bytes
     lsrs    ip, r2, #24
-    beq     strcpy_copy4bytes
+    beq     .L_strcpy_copy4bytes
 
     sub     ip, r3, #0x01010101
     bic     ip, ip, r3
     ands    ip, ip, #0x80808080
-    bne     strcpy_zero_in_second_register
+    bne     .L_strcpy_zero_in_second_register
 
     strd    r2, r3, [r0], #8
-    b       strcpy_unalign2
+    b       .L_strcpy_unalign2
 
     .p2align 2
     // Can read 1 byte before possibly crossing a page.
-strcpy_unalign1:
+.L_strcpy_unalign1:
     ldrb    r2, [r1]
-    cbz     r2, strcpy_unalign_copy1byte
+    cbz     r2, .L_strcpy_unalign_copy1byte
 
     ldr     r2, [r1], #4
     ldr     r3, [r1], #4
@@ -482,27 +489,27 @@
     sub     ip, r2, #0x01010101
     bic     ip, ip, r2
     ands    ip, ip, #0x80808080
-    bne     strcpy_zero_in_first_register
+    bne     .L_strcpy_zero_in_first_register
 
     sub     ip, r3, #0x01010101
     bic     ip, ip, r3
     ands    ip, ip, #0x80808080
-    bne     strcpy_zero_in_second_register
+    bne     .L_strcpy_zero_in_second_register
 
     strd    r2, r3, [r0], #8
-    b       strcpy_unalign1
+    b       .L_strcpy_unalign1
 
-strcpy_unalign_copy1byte:
+.L_strcpy_unalign_copy1byte:
     strb    r2, [r0]
     m_pop
 
-strcpy_unalign_copy2bytes:
+.L_strcpy_unalign_copy2bytes:
     strb    r2, [r0], #1
     strb    r4, [r0]
     m_pop
 
     .p2align 2
-strcat_mainloop:
+.L_strcat_mainloop:
     ldrd    r2, r3, [r0], #8
 
     pld     [r0, #64]
@@ -510,59 +517,59 @@
     sub     ip, r2, #0x01010101
     bic     ip, ip, r2
     ands    ip, ip, #0x80808080
-    bne     strcat_zero_in_first_register
+    bne     .L_strcat_zero_in_first_register
 
     sub     ip, r3, #0x01010101
     bic     ip, ip, r3
     ands    ip, ip, #0x80808080
-    bne     strcat_zero_in_second_register
-    b       strcat_mainloop
+    bne     .L_strcat_zero_in_second_register
+    b       .L_strcat_mainloop
 
-strcat_zero_in_first_register:
+.L_strcat_zero_in_first_register:
     // Prefetch the src now, it's going to be used soon.
     pld     [r1, #0]
     lsls    lr, ip, #17
-    bne     strcat_sub8
-    bcs     strcat_sub7
+    bne     .L_strcat_sub8
+    bcs     .L_strcat_sub7
     lsls    ip, ip, #1
-    bne     strcat_sub6
+    bne     .L_strcat_sub6
 
     sub     r0, r0, #5
-    b       strcat_r0_scan_done
+    b       .L_strcat_r0_scan_done
 
-strcat_sub8:
+.L_strcat_sub8:
     sub     r0, r0, #8
-    b       strcat_r0_scan_done
+    b       .L_strcat_r0_scan_done
 
-strcat_sub7:
+.L_strcat_sub7:
     sub     r0, r0, #7
-    b       strcat_r0_scan_done
+    b       .L_strcat_r0_scan_done
 
-strcat_sub6:
+.L_strcat_sub6:
     sub     r0, r0, #6
-    b       strcat_r0_scan_done
+    b       .L_strcat_r0_scan_done
 
-strcat_zero_in_second_register:
+.L_strcat_zero_in_second_register:
     // Prefetch the src now, it's going to be used soon.
     pld     [r1, #0]
     lsls    lr, ip, #17
-    bne     strcat_sub4
-    bcs     strcat_sub3
+    bne     .L_strcat_sub4
+    bcs     .L_strcat_sub3
     lsls    ip, ip, #1
-    bne     strcat_sub2
+    bne     .L_strcat_sub2
 
     sub     r0, r0, #1
-    b       strcat_r0_scan_done
+    b       .L_strcat_r0_scan_done
 
-strcat_sub4:
+.L_strcat_sub4:
     sub     r0, r0, #4
-    b       strcat_r0_scan_done
+    b       .L_strcat_r0_scan_done
 
-strcat_sub3:
+.L_strcat_sub3:
     sub     r0, r0, #3
-    b       strcat_r0_scan_done
+    b       .L_strcat_r0_scan_done
 
-strcat_sub2:
+.L_strcat_sub2:
     sub     r0, r0, #2
-    b       strcat_r0_scan_done
+    b       .L_strcat_r0_scan_done
 END(strcat)
diff --git a/libc/arch-arm/cortex-a15/bionic/string_copy.S b/libc/arch-arm/cortex-a15/bionic/string_copy.S
index 20f0e91..92d1c98 100644
--- a/libc/arch-arm/cortex-a15/bionic/string_copy.S
+++ b/libc/arch-arm/cortex-a15/bionic/string_copy.S
@@ -149,13 +149,20 @@
 .Lstringcopy_align_to_64:
     tst     r3, #4
     beq     .Lstringcopy_check_src_align
-    ldr     r2, [r1], #4
-
-    sub     ip, r2, #0x01010101
-    bic     ip, ip, r2
-    ands    ip, ip, #0x80808080
-    bne     .Lstringcopy_zero_in_first_register
-    str     r2, [r0], #4
+    // Read one byte at a time since we don't have any idea about the alignment
+    // of the source and we don't want to read into a different page.
+    ldrb    r2, [r1], #1
+    strb    r2, [r0], #1
+    cbz     r2, .Lstringcopy_complete
+    ldrb    r2, [r1], #1
+    strb    r2, [r0], #1
+    cbz     r2, .Lstringcopy_complete
+    ldrb    r2, [r1], #1
+    strb    r2, [r0], #1
+    cbz     r2, .Lstringcopy_complete
+    ldrb    r2, [r1], #1
+    strb    r2, [r0], #1
+    cbz     r2, .Lstringcopy_complete
 
 .Lstringcopy_check_src_align:
     // At this point dst is aligned to a double word, check if src
diff --git a/libc/arch-arm/cortex-a15/bionic/strlen.S b/libc/arch-arm/cortex-a15/bionic/strlen.S
index 9a0ce62..4fd6284 100644
--- a/libc/arch-arm/cortex-a15/bionic/strlen.S
+++ b/libc/arch-arm/cortex-a15/bionic/strlen.S
@@ -65,38 +65,38 @@
     mov     r1, r0
 
     ands    r3, r0, #7
-    beq     mainloop
+    beq     .L_mainloop
 
     // Align to a double word (64 bits).
     rsb     r3, r3, #8
     lsls    ip, r3, #31
-    beq     align_to_32
+    beq     .L_align_to_32
 
     ldrb    r2, [r1], #1
-    cbz     r2, update_count_and_return
+    cbz     r2, .L_update_count_and_return
 
-align_to_32:
-    bcc     align_to_64
+.L_align_to_32:
+    bcc     .L_align_to_64
     ands    ip, r3, #2
-    beq     align_to_64
+    beq     .L_align_to_64
 
     ldrb    r2, [r1], #1
-    cbz     r2, update_count_and_return
+    cbz     r2, .L_update_count_and_return
     ldrb    r2, [r1], #1
-    cbz     r2, update_count_and_return
+    cbz     r2, .L_update_count_and_return
 
-align_to_64:
+.L_align_to_64:
     tst     r3, #4
-    beq     mainloop
+    beq     .L_mainloop
     ldr     r3, [r1], #4
 
     sub     ip, r3, #0x01010101
     bic     ip, ip, r3
     ands    ip, ip, #0x80808080
-    bne     zero_in_second_register
+    bne     .L_zero_in_second_register
 
     .p2align 2
-mainloop:
+.L_mainloop:
     ldrd    r2, r3, [r1], #8
 
     pld     [r1, #64]
@@ -104,62 +104,62 @@
     sub     ip, r2, #0x01010101
     bic     ip, ip, r2
     ands    ip, ip, #0x80808080
-    bne     zero_in_first_register
+    bne     .L_zero_in_first_register
 
     sub     ip, r3, #0x01010101
     bic     ip, ip, r3
     ands    ip, ip, #0x80808080
-    bne     zero_in_second_register
-    b       mainloop
+    bne     .L_zero_in_second_register
+    b       .L_mainloop
 
-update_count_and_return:
+.L_update_count_and_return:
     sub     r0, r1, r0
     sub     r0, r0, #1
     bx      lr
 
-zero_in_first_register:
+.L_zero_in_first_register:
     sub     r0, r1, r0
     lsls    r3, ip, #17
-    bne     sub8_and_return
-    bcs     sub7_and_return
+    bne     .L_sub8_and_return
+    bcs     .L_sub7_and_return
     lsls    ip, ip, #1
-    bne     sub6_and_return
+    bne     .L_sub6_and_return
 
     sub     r0, r0, #5
     bx      lr
 
-sub8_and_return:
+.L_sub8_and_return:
     sub     r0, r0, #8
     bx      lr
 
-sub7_and_return:
+.L_sub7_and_return:
     sub     r0, r0, #7
     bx      lr
 
-sub6_and_return:
+.L_sub6_and_return:
     sub     r0, r0, #6
     bx      lr
 
-zero_in_second_register:
+.L_zero_in_second_register:
     sub     r0, r1, r0
     lsls    r3, ip, #17
-    bne     sub4_and_return
-    bcs     sub3_and_return
+    bne     .L_sub4_and_return
+    bcs     .L_sub3_and_return
     lsls    ip, ip, #1
-    bne     sub2_and_return
+    bne     .L_sub2_and_return
 
     sub     r0, r0, #1
     bx      lr
 
-sub4_and_return:
+.L_sub4_and_return:
     sub     r0, r0, #4
     bx      lr
 
-sub3_and_return:
+.L_sub3_and_return:
     sub     r0, r0, #3
     bx      lr
 
-sub2_and_return:
+.L_sub2_and_return:
     sub     r0, r0, #2
     bx      lr
 END(strlen)
diff --git a/libc/arch-arm/cortex-a15/cortex-a15.mk b/libc/arch-arm/cortex-a15/cortex-a15.mk
index 6fa3270..20202a7 100644
--- a/libc/arch-arm/cortex-a15/cortex-a15.mk
+++ b/libc/arch-arm/cortex-a15/cortex-a15.mk
@@ -1,3 +1,17 @@
+libc_openbsd_src_files_exclude_arm += \
+    upstream-openbsd/lib/libc/string/memmove.c \
+    upstream-openbsd/lib/libc/string/stpcpy.c \
+    upstream-openbsd/lib/libc/string/strcat.c \
+
+libc_bionic_src_files_exclude_arm += \
+    arch-arm/generic/bionic/memcpy.S \
+    arch-arm/generic/bionic/memset.S \
+    arch-arm/generic/bionic/strcmp.S \
+    arch-arm/generic/bionic/strcpy.S \
+    arch-arm/generic/bionic/strlen.c \
+    bionic/__strcat_chk.cpp \
+    bionic/__strcpy_chk.cpp \
+
 libc_bionic_src_files_arm += \
     arch-arm/cortex-a15/bionic/memcpy.S \
     arch-arm/cortex-a15/bionic/memset.S \
@@ -10,7 +24,4 @@
     arch-arm/cortex-a15/bionic/strlen.S \
 
 libc_bionic_src_files_arm += \
-    arch-arm/generic/bionic/memcmp.S \
-
-libc_bionic_src_files_arm += \
     arch-arm/denver/bionic/memmove.S \
diff --git a/libc/arch-arm/cortex-a53.a57/cortex-a53.a57.mk b/libc/arch-arm/cortex-a53.a57/cortex-a53.a57.mk
new file mode 100644
index 0000000..6455d04
--- /dev/null
+++ b/libc/arch-arm/cortex-a53.a57/cortex-a53.a57.mk
@@ -0,0 +1,32 @@
+# This file represents the best optimized routines that are the middle
+# ground when running on a big/little system that is cortex-a57/cortex-a53.
+# The cortex-a7 optimized routines, and the cortex-a53 optimized routines
+# decrease performance on cortex-a57 processors by as much as 20%.
+
+libc_openbsd_src_files_exclude_arm += \
+    upstream-openbsd/lib/libc/string/memmove.c \
+    upstream-openbsd/lib/libc/string/stpcpy.c \
+    upstream-openbsd/lib/libc/string/strcat.c \
+
+libc_bionic_src_files_exclude_arm += \
+    arch-arm/generic/bionic/memcpy.S \
+    arch-arm/generic/bionic/memset.S \
+    arch-arm/generic/bionic/strcmp.S \
+    arch-arm/generic/bionic/strcpy.S \
+    arch-arm/generic/bionic/strlen.c \
+    bionic/__strcat_chk.cpp \
+    bionic/__strcpy_chk.cpp \
+
+libc_bionic_src_files_arm += \
+    arch-arm/cortex-a15/bionic/memcpy.S \
+    arch-arm/cortex-a15/bionic/memset.S \
+    arch-arm/cortex-a15/bionic/stpcpy.S \
+    arch-arm/cortex-a15/bionic/strcat.S \
+    arch-arm/cortex-a15/bionic/__strcat_chk.S \
+    arch-arm/cortex-a15/bionic/strcmp.S \
+    arch-arm/cortex-a15/bionic/strcpy.S \
+    arch-arm/cortex-a15/bionic/__strcpy_chk.S \
+    arch-arm/cortex-a15/bionic/strlen.S \
+
+libc_bionic_src_files_arm += \
+    arch-arm/denver/bionic/memmove.S \
diff --git a/libc/include/sys/shm.h b/libc/arch-arm/cortex-a53/bionic/__strcat_chk.S
similarity index 84%
copy from libc/include/sys/shm.h
copy to libc/arch-arm/cortex-a53/bionic/__strcat_chk.S
index c691c29..c5bc98a 100644
--- a/libc/include/sys/shm.h
+++ b/libc/arch-arm/cortex-a53/bionic/__strcat_chk.S
@@ -1,5 +1,5 @@
 /*
- * Copyright (C) 2014 The Android Open Source Project
+ * Copyright (C) 2015 The Android Open Source Project
  * All rights reserved.
  *
  * Redistribution and use in source and binary forms, with or without
@@ -26,9 +26,7 @@
  * SUCH DAMAGE.
  */
 
-#ifndef _SYS_SHM_H_
-#define _SYS_SHM_H_
+// Indicate which memcpy base file to include.
+#define MEMCPY_BASE "arch-arm/cortex-a53/bionic/memcpy_base.S"
 
-#include <linux/shm.h>
-
-#endif /* _SYS_SHM_H_ */
+#include "arch-arm/cortex-a15/bionic/__strcat_chk_common.S"
diff --git a/libc/include/sys/shm.h b/libc/arch-arm/cortex-a53/bionic/__strcpy_chk.S
similarity index 84%
copy from libc/include/sys/shm.h
copy to libc/arch-arm/cortex-a53/bionic/__strcpy_chk.S
index c691c29..1f8945d 100644
--- a/libc/include/sys/shm.h
+++ b/libc/arch-arm/cortex-a53/bionic/__strcpy_chk.S
@@ -1,5 +1,5 @@
 /*
- * Copyright (C) 2014 The Android Open Source Project
+ * Copyright (C) 2015 The Android Open Source Project
  * All rights reserved.
  *
  * Redistribution and use in source and binary forms, with or without
@@ -26,9 +26,7 @@
  * SUCH DAMAGE.
  */
 
-#ifndef _SYS_SHM_H_
-#define _SYS_SHM_H_
+// Indicate which memcpy base file to include.
+#define MEMCPY_BASE "arch-arm/cortex-a53/bionic/memcpy_base.S"
 
-#include <linux/shm.h>
-
-#endif /* _SYS_SHM_H_ */
+#include "arch-arm/cortex-a15/bionic/__strcpy_chk_common.S"
diff --git a/libc/include/sys/shm.h b/libc/arch-arm/cortex-a53/bionic/memcpy.S
similarity index 85%
rename from libc/include/sys/shm.h
rename to libc/arch-arm/cortex-a53/bionic/memcpy.S
index c691c29..664f574 100644
--- a/libc/include/sys/shm.h
+++ b/libc/arch-arm/cortex-a53/bionic/memcpy.S
@@ -1,5 +1,5 @@
 /*
- * Copyright (C) 2014 The Android Open Source Project
+ * Copyright (C) 2015 The Android Open Source Project
  * All rights reserved.
  *
  * Redistribution and use in source and binary forms, with or without
@@ -26,9 +26,7 @@
  * SUCH DAMAGE.
  */
 
-#ifndef _SYS_SHM_H_
-#define _SYS_SHM_H_
+// Indicate which memcpy base file to include.
+#define MEMCPY_BASE "arch-arm/cortex-a53/bionic/memcpy_base.S"
 
-#include <linux/shm.h>
-
-#endif /* _SYS_SHM_H_ */
+#include "arch-arm/cortex-a15/bionic/memcpy_common.S"
diff --git a/libc/arch-arm/cortex-a53/bionic/memcpy_base.S b/libc/arch-arm/cortex-a53/bionic/memcpy_base.S
new file mode 100644
index 0000000..2749fc8
--- /dev/null
+++ b/libc/arch-arm/cortex-a53/bionic/memcpy_base.S
@@ -0,0 +1,143 @@
+/*
+ * 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.
+ */
+/*
+ * Copyright (c) 2013 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.
+ */
+
+.L_memcpy_base:
+        // Assumes that n >= 0, and dst, src are valid pointers.
+        cmp     r2, #16
+        blo     .L_copy_less_than_16_unknown_align
+
+.L_copy_unknown_alignment:
+        // Unknown alignment of src and dst.
+        // Assumes that the first few bytes have already been prefetched.
+
+        // Align destination to 128 bits. The mainloop store instructions
+        // require this alignment or they will throw an exception.
+        rsb         r3, r0, #0
+        ands        r3, r3, #0xF
+        beq         2f
+
+        // Copy up to 15 bytes (count in r3).
+        sub         r2, r2, r3
+        movs        ip, r3, lsl #31
+
+        itt         mi
+        ldrbmi      lr, [r1], #1
+        strbmi      lr, [r0], #1
+        itttt       cs
+        ldrbcs      ip, [r1], #1
+        ldrbcs      lr, [r1], #1
+        strbcs      ip, [r0], #1
+        strbcs      lr, [r0], #1
+
+        movs        ip, r3, lsl #29
+        bge         1f
+        // Copies 4 bytes, dst 32 bits aligned before, at least 64 bits after.
+        vld4.8      {d0[0], d1[0], d2[0], d3[0]}, [r1]!
+        vst4.8      {d0[0], d1[0], d2[0], d3[0]}, [r0, :32]!
+1:      bcc         2f
+        // Copies 8 bytes, dst 64 bits aligned before, at least 128 bits after.
+        vld1.8      {d0}, [r1]!
+        vst1.8      {d0}, [r0, :64]!
+
+2:      // Make sure we have at least 64 bytes to copy.
+        subs        r2, r2, #64
+        blo         2f
+
+1:      // The main loop copies 64 bytes at a time.
+        vld1.8      {d0  - d3},   [r1]!
+        vld1.8      {d4  - d7},   [r1]!
+        subs        r2, r2, #64
+        vstmia      r0!, {d0 - d7}
+        pld         [r1, #(64*10)]
+        bhs         1b
+
+2:      // Fix-up the remaining count and make sure we have >= 32 bytes left.
+        adds        r2, r2, #32
+        blo         3f
+
+        // 32 bytes. These cache lines were already preloaded.
+        vld1.8      {d0 - d3},  [r1]!
+        sub         r2, r2, #32
+        vst1.8      {d0 - d3},  [r0, :128]!
+3:      // Less than 32 left.
+        add         r2, r2, #32
+        tst         r2, #0x10
+        beq         .L_copy_less_than_16_unknown_align
+        // Copies 16 bytes, destination 128 bits aligned.
+        vld1.8      {d0, d1}, [r1]!
+        vst1.8      {d0, d1}, [r0, :128]!
+
+.L_copy_less_than_16_unknown_align:
+        // Copy up to 15 bytes (count in r2).
+        movs        ip, r2, lsl #29
+        bcc         1f
+        vld1.8      {d0}, [r1]!
+        vst1.8      {d0}, [r0]!
+1:      bge         2f
+        vld4.8      {d0[0], d1[0], d2[0], d3[0]}, [r1]!
+        vst4.8      {d0[0], d1[0], d2[0], d3[0]}, [r0]!
+
+2:      // Copy 0 to 4 bytes.
+        lsls        r2, r2, #31
+        itt         ne
+        ldrbne      lr, [r1], #1
+        strbne      lr, [r0], #1
+        itttt       cs
+        ldrbcs      ip, [r1], #1
+        ldrbcs      lr, [r1]
+        strbcs      ip, [r0], #1
+        strbcs      lr, [r0]
+
+        pop         {r0, pc}
diff --git a/libc/arch-arm/cortex-a53/cortex-a53.mk b/libc/arch-arm/cortex-a53/cortex-a53.mk
index b5c337c..9b431ae 100644
--- a/libc/arch-arm/cortex-a53/cortex-a53.mk
+++ b/libc/arch-arm/cortex-a53/cortex-a53.mk
@@ -1 +1,31 @@
-include bionic/libc/arch-arm/cortex-a7/cortex-a7.mk
+libc_openbsd_src_files_exclude_arm += \
+    upstream-openbsd/lib/libc/string/memmove.c \
+    upstream-openbsd/lib/libc/string/stpcpy.c \
+    upstream-openbsd/lib/libc/string/strcat.c \
+
+libc_bionic_src_files_exclude_arm += \
+    arch-arm/generic/bionic/memcpy.S \
+    arch-arm/generic/bionic/memset.S \
+    arch-arm/generic/bionic/strcmp.S \
+    arch-arm/generic/bionic/strcpy.S \
+    arch-arm/generic/bionic/strlen.c \
+    bionic/__strcat_chk.cpp \
+    bionic/__strcpy_chk.cpp \
+
+libc_bionic_src_files_arm += \
+    arch-arm/cortex-a53/bionic/memcpy.S \
+    arch-arm/cortex-a53/bionic/__strcat_chk.S \
+    arch-arm/cortex-a53/bionic/__strcpy_chk.S \
+
+libc_bionic_src_files_arm += \
+    arch-arm/cortex-a7/bionic/memset.S \
+
+libc_bionic_src_files_arm += \
+    arch-arm/cortex-a15/bionic/stpcpy.S \
+    arch-arm/cortex-a15/bionic/strcat.S \
+    arch-arm/cortex-a15/bionic/strcmp.S \
+    arch-arm/cortex-a15/bionic/strcpy.S \
+    arch-arm/cortex-a15/bionic/strlen.S \
+
+libc_bionic_src_files_arm += \
+    arch-arm/denver/bionic/memmove.S \
diff --git a/libc/arch-arm/cortex-a7/bionic/memset.S b/libc/arch-arm/cortex-a7/bionic/memset.S
new file mode 100644
index 0000000..6365b06
--- /dev/null
+++ b/libc/arch-arm/cortex-a7/bionic/memset.S
@@ -0,0 +1,180 @@
+/*
+ * Copyright (C) 2013 The Android Open Source Project
+ * All rights reserved.
+ *
+ * Redistribution and use in source and binary forms, with or without
+ * modification, are permitted provided that the following conditions
+ * are met:
+ *  * Redistributions of source code must retain the above copyright
+ *    notice, this list of conditions and the following disclaimer.
+ *  * Redistributions in binary form must reproduce the above copyright
+ *    notice, this list of conditions and the following disclaimer in
+ *    the documentation and/or other materials provided with the
+ *    distribution.
+ *
+ * THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS
+ * "AS IS" AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT
+ * LIMITED TO, THE IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS
+ * FOR A PARTICULAR PURPOSE ARE DISCLAIMED. IN NO EVENT SHALL THE
+ * COPYRIGHT OWNER OR CONTRIBUTORS BE LIABLE FOR ANY DIRECT, INDIRECT,
+ * INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING,
+ * BUT NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; LOSS
+ * OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED
+ * AND ON ANY THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY,
+ * OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT
+ * OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF
+ * SUCH DAMAGE.
+ */
+
+#include <machine/cpu-features.h>
+#include <private/bionic_asm.h>
+#include <private/libc_events.h>
+
+        /*
+         * Optimized memset() for ARM.
+         *
+         * memset() returns its first argument.
+         */
+
+        .fpu        neon
+        .syntax     unified
+
+ENTRY(__memset_chk)
+        cmp         r2, r3
+        bls         .L_done
+
+        // Preserve lr for backtrace.
+        push        {lr}
+        .cfi_def_cfa_offset 4
+        .cfi_rel_offset lr, 0
+
+        ldr         r0, error_message
+        ldr         r1, error_code
+1:
+        add         r0, pc
+        bl          __fortify_chk_fail
+error_code:
+        .word       BIONIC_EVENT_MEMSET_BUFFER_OVERFLOW
+error_message:
+        .word       error_string-(1b+8)
+END(__memset_chk)
+
+ENTRY(bzero)
+        mov         r2, r1
+        mov         r1, #0
+.L_done:
+        // Fall through to memset...
+END(bzero)
+
+ENTRY(memset)
+        mov         r3, r0
+        // At this point only d0, d1 are going to be used below.
+        vdup.8      q0, r1
+        cmp         r2, #16
+        blo         .L_set_less_than_16_unknown_align
+
+.L_check_alignment:
+        // Align destination to a double word to avoid the store crossing
+        // a cache line boundary.
+        ands        ip, r3, #7
+        bne         .L_do_double_word_align
+
+.L_double_word_aligned:
+        // Duplicate since the less than 64 can use d2, d3.
+        vmov        q1, q0
+        subs        r2, #64
+        blo         .L_set_less_than_64
+
+        // Duplicate the copy value so that we can store 64 bytes at a time.
+        vmov        q2, q0
+        vmov        q3, q0
+
+1:      // Main loop stores 64 bytes at a time.
+        subs        r2, #64
+        vstmia      r3!, {d0 - d7}
+        bge         1b
+
+.L_set_less_than_64:
+        // Restore r2 to the count of bytes left to set.
+        add         r2, #64
+        lsls        ip, r2, #27
+        bcc         .L_set_less_than_32
+        // Set 32 bytes.
+        vstmia      r3!, {d0 - d3}
+
+.L_set_less_than_32:
+        bpl         .L_set_less_than_16
+        // Set 16 bytes.
+        vstmia      r3!, {d0, d1}
+
+.L_set_less_than_16:
+        // Less than 16 bytes to set.
+        lsls        ip, r2, #29
+        bcc         .L_set_less_than_8
+
+        // Set 8 bytes.
+        vstmia      r3!, {d0}
+
+.L_set_less_than_8:
+        bpl         .L_set_less_than_4
+        // Set 4 bytes
+        vst1.32     {d0[0]}, [r3]!
+
+.L_set_less_than_4:
+        lsls        ip, r2, #31
+        it          ne
+        strbne      r1, [r3], #1
+        itt         cs
+        strbcs      r1, [r3], #1
+        strbcs      r1, [r3]
+        bx          lr
+
+.L_do_double_word_align:
+        rsb         ip, ip, #8
+        sub         r2, r2, ip
+
+        // Do this comparison now, otherwise we'll need to save a
+        // register to the stack since we've used all available
+        // registers.
+        cmp         ip, #4
+        blo         1f
+
+        // Need to do a four byte copy.
+        movs        ip, ip, lsl #31
+        it          mi
+        strbmi      r1, [r3], #1
+        itt         cs
+        strbcs      r1, [r3], #1
+        strbcs      r1, [r3], #1
+        vst1.32     {d0[0]}, [r3]!
+        b           .L_double_word_aligned
+
+1:
+        // No four byte copy.
+        movs        ip, ip, lsl #31
+        it          mi
+        strbmi      r1, [r3], #1
+        itt         cs
+        strbcs      r1, [r3], #1
+        strbcs      r1, [r3], #1
+        b           .L_double_word_aligned
+
+.L_set_less_than_16_unknown_align:
+        // Set up to 15 bytes.
+        movs        ip, r2, lsl #29
+        bcc         1f
+        vst1.8      {d0}, [r3]!
+1:      bge         2f
+        vst1.32     {d0[0]}, [r3]!
+2:      movs        ip, r2, lsl #31
+        it          mi
+        strbmi      r1, [r3], #1
+        itt         cs
+        strbcs      r1, [r3], #1
+        strbcs      r1, [r3], #1
+        bx          lr
+END(memset)
+
+        .data
+error_string:
+        .string     "memset: prevented write past end of buffer"
diff --git a/libc/arch-arm/cortex-a7/cortex-a7.mk b/libc/arch-arm/cortex-a7/cortex-a7.mk
index 9af03d9..f570d0f 100644
--- a/libc/arch-arm/cortex-a7/cortex-a7.mk
+++ b/libc/arch-arm/cortex-a7/cortex-a7.mk
@@ -1 +1,29 @@
-include bionic/libc/arch-arm/cortex-a15/cortex-a15.mk
+libc_openbsd_src_files_exclude_arm += \
+    upstream-openbsd/lib/libc/string/memmove.c \
+    upstream-openbsd/lib/libc/string/stpcpy.c \
+    upstream-openbsd/lib/libc/string/strcat.c \
+
+libc_bionic_src_files_exclude_arm += \
+    arch-arm/generic/bionic/memcpy.S \
+    arch-arm/generic/bionic/memset.S \
+    arch-arm/generic/bionic/strcmp.S \
+    arch-arm/generic/bionic/strcpy.S \
+    arch-arm/generic/bionic/strlen.c \
+    bionic/__strcat_chk.cpp \
+    bionic/__strcpy_chk.cpp \
+
+libc_bionic_src_files_arm += \
+    arch-arm/cortex-a7/bionic/memset.S \
+
+libc_bionic_src_files_arm += \
+    arch-arm/cortex-a15/bionic/memcpy.S \
+    arch-arm/cortex-a15/bionic/stpcpy.S \
+    arch-arm/cortex-a15/bionic/strcat.S \
+    arch-arm/cortex-a15/bionic/__strcat_chk.S \
+    arch-arm/cortex-a15/bionic/strcmp.S \
+    arch-arm/cortex-a15/bionic/strcpy.S \
+    arch-arm/cortex-a15/bionic/__strcpy_chk.S \
+    arch-arm/cortex-a15/bionic/strlen.S \
+
+libc_bionic_src_files_arm += \
+    arch-arm/denver/bionic/memmove.S \
diff --git a/libc/arch-arm/cortex-a9/bionic/memcpy_base.S b/libc/arch-arm/cortex-a9/bionic/memcpy_base.S
index 5e81305..966b9b3 100644
--- a/libc/arch-arm/cortex-a9/bionic/memcpy_base.S
+++ b/libc/arch-arm/cortex-a9/bionic/memcpy_base.S
@@ -44,7 +44,7 @@
         /* check if buffers are aligned. If so, run arm-only version */
         eor         r3, r0, r1
         ands        r3, r3, #0x3
-        beq         __memcpy_base_aligned
+        beq         MEMCPY_BASE_ALIGNED
 
         /* Check the upper size limit for Neon unaligned memory access in memcpy */
         cmp         r2, #224
@@ -133,8 +133,7 @@
         strbcs      ip, [r0], #1
         strbcs      lr, [r0], #1
 
-        ldmfd       sp!, {r0, lr}
-        bx          lr
+        ldmfd       sp!, {r0, pc}
 END(MEMCPY_BASE)
 
 ENTRY_PRIVATE(MEMCPY_BASE_ALIGNED)
diff --git a/libc/arch-arm/cortex-a9/bionic/memset.S b/libc/arch-arm/cortex-a9/bionic/memset.S
index 8ee6ac2..b39fcc4 100644
--- a/libc/arch-arm/cortex-a9/bionic/memset.S
+++ b/libc/arch-arm/cortex-a9/bionic/memset.S
@@ -69,12 +69,9 @@
 ENTRY(memset)
         // The neon memset only wins for less than 132.
         cmp         r2, #132
-        bhi         __memset_large_copy
+        bhi         .L_memset_large_copy
 
-        stmfd       sp!, {r0}
-        .cfi_def_cfa_offset 4
-        .cfi_rel_offset r0, 0
-
+        mov         r3, r0
         vdup.8      q0, r1
 
         /* make sure we have at least 32 bytes to write */
@@ -84,7 +81,7 @@
 
 1:      /* The main loop writes 32 bytes at a time */
         subs        r2, r2, #32
-        vst1.8      {d0 - d3}, [r0]!
+        vst1.8      {d0 - d3}, [r3]!
         bhs         1b
 
 2:      /* less than 32 left */
@@ -93,22 +90,20 @@
         beq         3f
 
         // writes 16 bytes, 128-bits aligned
-        vst1.8      {d0, d1}, [r0]!
+        vst1.8      {d0, d1}, [r3]!
 3:      /* write up to 15-bytes (count in r2) */
         movs        ip, r2, lsl #29
         bcc         1f
-        vst1.8      {d0}, [r0]!
+        vst1.8      {d0}, [r3]!
 1:      bge         2f
-        vst1.32     {d0[0]}, [r0]!
+        vst1.32     {d0[0]}, [r3]!
 2:      movs        ip, r2, lsl #31
-        strbmi      r1, [r0], #1
-        strbcs      r1, [r0], #1
-        strbcs      r1, [r0], #1
-        ldmfd       sp!, {r0}
+        strbmi      r1, [r3], #1
+        strbcs      r1, [r3], #1
+        strbcs      r1, [r3], #1
         bx          lr
-END(memset)
 
-ENTRY_PRIVATE(__memset_large_copy)
+.L_memset_large_copy:
         /* compute the offset to align the destination
          * offset = (4-(src&3))&3 = -src & 3
          */
@@ -136,8 +131,7 @@
         strbcs      r1, [r0], #1
         strbmi      r1, [r0], #1
         subs        r2, r2, r3
-        popls       {r0, r4-r7, lr}   /* return */
-        bxls        lr
+        popls       {r0, r4-r7, pc}   /* return */
 
         /* align the destination to a cache-line */
         mov         r12, r1
@@ -180,9 +174,8 @@
         strhmi      r1, [r0], #2
         movs        r2, r2, lsl #2
         strbcs      r1, [r0]
-        ldmfd       sp!, {r0, r4-r7, lr}
-        bx          lr
-END(__memset_large_copy)
+        ldmfd       sp!, {r0, r4-r7, pc}
+END(memset)
 
         .data
 error_string:
diff --git a/libc/arch-arm/cortex-a9/bionic/strcat.S b/libc/arch-arm/cortex-a9/bionic/strcat.S
index f5a855e..9077a74 100644
--- a/libc/arch-arm/cortex-a9/bionic/strcat.S
+++ b/libc/arch-arm/cortex-a9/bionic/strcat.S
@@ -70,7 +70,7 @@
 
     .macro m_scan_byte
     ldrb    r3, [r0]
-    cbz     r3, strcat_r0_scan_done
+    cbz     r3, .Lstrcat_r0_scan_done
     add     r0, #1
     .endm // m_scan_byte
 
@@ -84,10 +84,10 @@
     // Quick check to see if src is empty.
     ldrb        r2, [r1]
     pld         [r1, #0]
-    cbnz        r2, strcat_continue
+    cbnz        r2, .Lstrcat_continue
     bx          lr
 
-strcat_continue:
+.Lstrcat_continue:
     // To speed up really small dst strings, unroll checking the first 4 bytes.
     m_push
     m_scan_byte
@@ -96,10 +96,10 @@
     m_scan_byte
 
     ands    r3, r0, #7
-    bne     strcat_align_src
+    bne     .Lstrcat_align_src
 
     .p2align 2
-strcat_mainloop:
+.Lstrcat_mainloop:
     ldmia   r0!, {r2, r3}
 
     pld     [r0, #64]
@@ -107,28 +107,28 @@
     sub     ip, r2, #0x01010101
     bic     ip, ip, r2
     ands    ip, ip, #0x80808080
-    bne     strcat_zero_in_first_register
+    bne     .Lstrcat_zero_in_first_register
 
     sub     ip, r3, #0x01010101
     bic     ip, ip, r3
     ands    ip, ip, #0x80808080
-    bne     strcat_zero_in_second_register
-    b       strcat_mainloop
+    bne     .Lstrcat_zero_in_second_register
+    b       .Lstrcat_mainloop
 
-strcat_zero_in_first_register:
+.Lstrcat_zero_in_first_register:
     sub     r0, r0, #4
 
-strcat_zero_in_second_register:
+.Lstrcat_zero_in_second_register:
     // Check for zero in byte 0.
     tst     ip, #0x80
     it      ne
     subne   r0, r0, #4
-    bne     strcat_r0_scan_done
+    bne     .Lstrcat_r0_scan_done
     // Check for zero in byte 1.
     tst     ip, #0x8000
     it      ne
     subne   r0, r0, #3
-    bne     strcat_r0_scan_done
+    bne     .Lstrcat_r0_scan_done
     // Check for zero in byte 2.
     tst     ip, #0x800000
     it      ne
@@ -137,33 +137,33 @@
     // Zero is in byte 3.
     subeq   r0, r0, #1
 
-strcat_r0_scan_done:
+.Lstrcat_r0_scan_done:
     // Unroll the first 8 bytes that will be copied.
-    m_copy_byte reg=r2, cmd=cbz, label=strcpy_finish
-    m_copy_byte reg=r3, cmd=cbz, label=strcpy_finish
-    m_copy_byte reg=r4, cmd=cbz, label=strcpy_finish
-    m_copy_byte reg=r5, cmd=cbz, label=strcpy_finish
-    m_copy_byte reg=r2, cmd=cbz, label=strcpy_finish
-    m_copy_byte reg=r3, cmd=cbz, label=strcpy_finish
-    m_copy_byte reg=r4, cmd=cbz, label=strcpy_finish
-    m_copy_byte reg=r5, cmd=cbnz, label=strcpy_continue
+    m_copy_byte reg=r2, cmd=cbz, label=.Lstrcpy_finish
+    m_copy_byte reg=r3, cmd=cbz, label=.Lstrcpy_finish
+    m_copy_byte reg=r4, cmd=cbz, label=.Lstrcpy_finish
+    m_copy_byte reg=r5, cmd=cbz, label=.Lstrcpy_finish
+    m_copy_byte reg=r2, cmd=cbz, label=.Lstrcpy_finish
+    m_copy_byte reg=r3, cmd=cbz, label=.Lstrcpy_finish
+    m_copy_byte reg=r4, cmd=cbz, label=.Lstrcpy_finish
+    m_copy_byte reg=r5, cmd=cbnz, label=.Lstrcpy_continue
 
-strcpy_finish:
+.Lstrcpy_finish:
     m_ret   inst=pop
 
-strcpy_continue:
+.Lstrcpy_continue:
     pld     [r1, #0]
     ands    r3, r0, #7
-    bne     strcpy_align_dst
+    bne     .Lstrcpy_align_dst
 
-strcpy_check_src_align:
+.Lstrcpy_check_src_align:
     // At this point dst is aligned to a double word, check if src
     // is also aligned to a double word.
     ands    r3, r1, #7
-    bne     strcpy_unaligned_copy
+    bne     .Lstrcpy_unaligned_copy
 
     .p2align 2
-strcpy_mainloop:
+.Lstrcpy_mainloop:
     ldmia   r1!, {r2, r3}
 
     pld     [r1, #64]
@@ -171,17 +171,17 @@
     sub     ip, r2, #0x01010101
     bic     ip, ip, r2
     ands    ip, ip, #0x80808080
-    bne     strcpy_zero_in_first_register
+    bne     .Lstrcpy_zero_in_first_register
 
     sub     ip, r3, #0x01010101
     bic     ip, ip, r3
     ands    ip, ip, #0x80808080
-    bne     strcpy_zero_in_second_register
+    bne     .Lstrcpy_zero_in_second_register
 
     stmia   r0!, {r2, r3}
-    b       strcpy_mainloop
+    b       .Lstrcpy_mainloop
 
-strcpy_zero_in_first_register:
+.Lstrcpy_zero_in_first_register:
     lsls    lr, ip, #17
     itt     ne
     strbne  r2, [r0]
@@ -198,7 +198,7 @@
     strb    r3, [r0]
     m_ret   inst=pop
 
-strcpy_zero_in_second_register:
+.Lstrcpy_zero_in_second_register:
     lsls    lr, ip, #17
     ittt    ne
     stmiane r0!, {r2}
@@ -218,18 +218,18 @@
     strb    r4, [r0]
     m_ret   inst=pop
 
-strcpy_align_dst:
+.Lstrcpy_align_dst:
     // Align to a double word (64 bits).
     rsb     r3, r3, #8
     lsls    ip, r3, #31
-    beq     strcpy_align_to_32
+    beq     .Lstrcpy_align_to_32
 
     ldrb    r2, [r1], #1
     strb    r2, [r0], #1
-    cbz     r2, strcpy_complete
+    cbz     r2, .Lstrcpy_complete
 
-strcpy_align_to_32:
-    bcc     strcpy_align_to_64
+.Lstrcpy_align_to_32:
+    bcc     .Lstrcpy_align_to_64
 
     ldrb    r4, [r1], #1
     strb    r4, [r0], #1
@@ -242,76 +242,83 @@
     it      eq
     m_ret   inst=popeq
 
-strcpy_align_to_64:
+.Lstrcpy_align_to_64:
     tst     r3, #4
-    beq     strcpy_check_src_align
-    ldr     r2, [r1], #4
+    beq     .Lstrcpy_check_src_align
+    // Read one byte at a time since we don't know the src alignment
+    // and we don't want to read into a different page.
+    ldrb    r4, [r1], #1
+    strb    r4, [r0], #1
+    cbz     r4, .Lstrcpy_complete
+    ldrb    r5, [r1], #1
+    strb    r5, [r0], #1
+    cbz     r5, .Lstrcpy_complete
+    ldrb    r4, [r1], #1
+    strb    r4, [r0], #1
+    cbz     r4, .Lstrcpy_complete
+    ldrb    r5, [r1], #1
+    strb    r5, [r0], #1
+    cbz     r5, .Lstrcpy_complete
+    b       .Lstrcpy_check_src_align
 
-    sub     ip, r2, #0x01010101
-    bic     ip, ip, r2
-    ands    ip, ip, #0x80808080
-    bne     strcpy_zero_in_first_register
-    stmia   r0!, {r2}
-    b       strcpy_check_src_align
-
-strcpy_complete:
+.Lstrcpy_complete:
     m_ret   inst=pop
 
-strcpy_unaligned_copy:
+.Lstrcpy_unaligned_copy:
     // Dst is aligned to a double word, while src is at an unknown alignment.
     // There are 7 different versions of the unaligned copy code
     // to prevent overreading the src. The mainloop of every single version
     // will store 64 bits per loop. The difference is how much of src can
     // be read without potentially crossing a page boundary.
     tbb     [pc, r3]
-strcpy_unaligned_branchtable:
+.Lstrcpy_unaligned_branchtable:
     .byte 0
-    .byte ((strcpy_unalign7 - strcpy_unaligned_branchtable)/2)
-    .byte ((strcpy_unalign6 - strcpy_unaligned_branchtable)/2)
-    .byte ((strcpy_unalign5 - strcpy_unaligned_branchtable)/2)
-    .byte ((strcpy_unalign4 - strcpy_unaligned_branchtable)/2)
-    .byte ((strcpy_unalign3 - strcpy_unaligned_branchtable)/2)
-    .byte ((strcpy_unalign2 - strcpy_unaligned_branchtable)/2)
-    .byte ((strcpy_unalign1 - strcpy_unaligned_branchtable)/2)
+    .byte ((.Lstrcpy_unalign7 - .Lstrcpy_unaligned_branchtable)/2)
+    .byte ((.Lstrcpy_unalign6 - .Lstrcpy_unaligned_branchtable)/2)
+    .byte ((.Lstrcpy_unalign5 - .Lstrcpy_unaligned_branchtable)/2)
+    .byte ((.Lstrcpy_unalign4 - .Lstrcpy_unaligned_branchtable)/2)
+    .byte ((.Lstrcpy_unalign3 - .Lstrcpy_unaligned_branchtable)/2)
+    .byte ((.Lstrcpy_unalign2 - .Lstrcpy_unaligned_branchtable)/2)
+    .byte ((.Lstrcpy_unalign1 - .Lstrcpy_unaligned_branchtable)/2)
 
     .p2align 2
     // Can read 7 bytes before possibly crossing a page.
-strcpy_unalign7:
+.Lstrcpy_unalign7:
     ldr     r2, [r1], #4
 
     sub     ip, r2, #0x01010101
     bic     ip, ip, r2
     ands    ip, ip, #0x80808080
-    bne     strcpy_zero_in_first_register
+    bne     .Lstrcpy_zero_in_first_register
 
     ldrb    r3, [r1]
-    cbz     r3, strcpy_unalign7_copy5bytes
+    cbz     r3, .Lstrcpy_unalign7_copy5bytes
     ldrb    r4, [r1, #1]
-    cbz     r4, strcpy_unalign7_copy6bytes
+    cbz     r4, .Lstrcpy_unalign7_copy6bytes
     ldrb    r5, [r1, #2]
-    cbz     r5, strcpy_unalign7_copy7bytes
+    cbz     r5, .Lstrcpy_unalign7_copy7bytes
 
     ldr     r3, [r1], #4
     pld     [r1, #64]
 
     lsrs    ip, r3, #24
     stmia   r0!, {r2, r3}
-    beq     strcpy_unalign_return
-    b       strcpy_unalign7
+    beq     .Lstrcpy_unalign_return
+    b       .Lstrcpy_unalign7
 
-strcpy_unalign7_copy5bytes:
+.Lstrcpy_unalign7_copy5bytes:
     stmia   r0!, {r2}
     strb    r3, [r0]
-strcpy_unalign_return:
+.Lstrcpy_unalign_return:
     m_ret   inst=pop
 
-strcpy_unalign7_copy6bytes:
+.Lstrcpy_unalign7_copy6bytes:
     stmia   r0!, {r2}
     strb    r3, [r0], #1
     strb    r4, [r0], #1
     m_ret   inst=pop
 
-strcpy_unalign7_copy7bytes:
+.Lstrcpy_unalign7_copy7bytes:
     stmia   r0!, {r2}
     strb    r3, [r0], #1
     strb    r4, [r0], #1
@@ -320,30 +327,30 @@
 
     .p2align 2
     // Can read 6 bytes before possibly crossing a page.
-strcpy_unalign6:
+.Lstrcpy_unalign6:
     ldr     r2, [r1], #4
 
     sub     ip, r2, #0x01010101
     bic     ip, ip, r2
     ands    ip, ip, #0x80808080
-    bne     strcpy_zero_in_first_register
+    bne     .Lstrcpy_zero_in_first_register
 
     ldrb    r4, [r1]
-    cbz     r4, strcpy_unalign_copy5bytes
+    cbz     r4, .Lstrcpy_unalign_copy5bytes
     ldrb    r5, [r1, #1]
-    cbz     r5, strcpy_unalign_copy6bytes
+    cbz     r5, .Lstrcpy_unalign_copy6bytes
 
     ldr     r3, [r1], #4
     pld     [r1, #64]
 
     tst     r3, #0xff0000
-    beq     strcpy_unalign6_copy7bytes
+    beq     .Lstrcpy_unalign6_copy7bytes
     lsrs    ip, r3, #24
     stmia   r0!, {r2, r3}
-    beq     strcpy_unalign_return
-    b       strcpy_unalign6
+    beq     .Lstrcpy_unalign_return
+    b       .Lstrcpy_unalign6
 
-strcpy_unalign6_copy7bytes:
+.Lstrcpy_unalign6_copy7bytes:
     stmia   r0!, {r2}
     strh    r3, [r0], #2
     lsr     r3, #16
@@ -352,16 +359,16 @@
 
     .p2align 2
     // Can read 5 bytes before possibly crossing a page.
-strcpy_unalign5:
+.Lstrcpy_unalign5:
     ldr     r2, [r1], #4
 
     sub     ip, r2, #0x01010101
     bic     ip, ip, r2
     ands    ip, ip, #0x80808080
-    bne     strcpy_zero_in_first_register
+    bne     .Lstrcpy_zero_in_first_register
 
     ldrb    r4, [r1]
-    cbz     r4, strcpy_unalign_copy5bytes
+    cbz     r4, .Lstrcpy_unalign_copy5bytes
 
     ldr     r3, [r1], #4
 
@@ -370,17 +377,17 @@
     sub     ip, r3, #0x01010101
     bic     ip, ip, r3
     ands    ip, ip, #0x80808080
-    bne     strcpy_zero_in_second_register
+    bne     .Lstrcpy_zero_in_second_register
 
     stmia   r0!, {r2, r3}
-    b       strcpy_unalign5
+    b       .Lstrcpy_unalign5
 
-strcpy_unalign_copy5bytes:
+.Lstrcpy_unalign_copy5bytes:
     stmia   r0!, {r2}
     strb    r4, [r0]
     m_ret   inst=pop
 
-strcpy_unalign_copy6bytes:
+.Lstrcpy_unalign_copy6bytes:
     stmia   r0!, {r2}
     strb    r4, [r0], #1
     strb    r5, [r0]
@@ -388,13 +395,13 @@
 
     .p2align 2
     // Can read 4 bytes before possibly crossing a page.
-strcpy_unalign4:
+.Lstrcpy_unalign4:
     ldmia   r1!, {r2}
 
     sub     ip, r2, #0x01010101
     bic     ip, ip, r2
     ands    ip, ip, #0x80808080
-    bne     strcpy_zero_in_first_register
+    bne     .Lstrcpy_zero_in_first_register
 
     ldmia   r1!, {r3}
     pld     [r1, #64]
@@ -402,20 +409,20 @@
     sub     ip, r3, #0x01010101
     bic     ip, ip, r3
     ands    ip, ip, #0x80808080
-    bne     strcpy_zero_in_second_register
+    bne     .Lstrcpy_zero_in_second_register
 
     stmia   r0!, {r2, r3}
-    b       strcpy_unalign4
+    b       .Lstrcpy_unalign4
 
     .p2align 2
     // Can read 3 bytes before possibly crossing a page.
-strcpy_unalign3:
+.Lstrcpy_unalign3:
     ldrb    r2, [r1]
-    cbz     r2, strcpy_unalign3_copy1byte
+    cbz     r2, .Lstrcpy_unalign3_copy1byte
     ldrb    r3, [r1, #1]
-    cbz     r3, strcpy_unalign3_copy2bytes
+    cbz     r3, .Lstrcpy_unalign3_copy2bytes
     ldrb    r4, [r1, #2]
-    cbz     r4, strcpy_unalign3_copy3bytes
+    cbz     r4, .Lstrcpy_unalign3_copy3bytes
 
     ldr     r2, [r1], #4
     ldr     r3, [r1], #4
@@ -423,26 +430,26 @@
     pld     [r1, #64]
 
     lsrs    lr, r2, #24
-    beq     strcpy_unalign_copy4bytes
+    beq     .Lstrcpy_unalign_copy4bytes
 
     sub     ip, r3, #0x01010101
     bic     ip, ip, r3
     ands    ip, ip, #0x80808080
-    bne     strcpy_zero_in_second_register
+    bne     .Lstrcpy_zero_in_second_register
 
     stmia   r0!, {r2, r3}
-    b       strcpy_unalign3
+    b       .Lstrcpy_unalign3
 
-strcpy_unalign3_copy1byte:
+.Lstrcpy_unalign3_copy1byte:
     strb    r2, [r0]
     m_ret   inst=pop
 
-strcpy_unalign3_copy2bytes:
+.Lstrcpy_unalign3_copy2bytes:
     strb    r2, [r0], #1
     strb    r3, [r0]
     m_ret   inst=pop
 
-strcpy_unalign3_copy3bytes:
+.Lstrcpy_unalign3_copy3bytes:
     strb    r2, [r0], #1
     strb    r3, [r0], #1
     strb    r4, [r0]
@@ -450,34 +457,34 @@
 
     .p2align 2
     // Can read 2 bytes before possibly crossing a page.
-strcpy_unalign2:
+.Lstrcpy_unalign2:
     ldrb    r2, [r1]
-    cbz     r2, strcpy_unalign_copy1byte
+    cbz     r2, .Lstrcpy_unalign_copy1byte
     ldrb    r3, [r1, #1]
-    cbz     r3, strcpy_unalign_copy2bytes
+    cbz     r3, .Lstrcpy_unalign_copy2bytes
 
     ldr     r2, [r1], #4
     ldr     r3, [r1], #4
     pld     [r1, #64]
 
     tst     r2, #0xff0000
-    beq     strcpy_unalign_copy3bytes
+    beq     .Lstrcpy_unalign_copy3bytes
     lsrs    ip, r2, #24
-    beq     strcpy_unalign_copy4bytes
+    beq     .Lstrcpy_unalign_copy4bytes
 
     sub     ip, r3, #0x01010101
     bic     ip, ip, r3
     ands    ip, ip, #0x80808080
-    bne     strcpy_zero_in_second_register
+    bne     .Lstrcpy_zero_in_second_register
 
     stmia   r0!, {r2, r3}
-    b       strcpy_unalign2
+    b       .Lstrcpy_unalign2
 
     .p2align 2
     // Can read 1 byte before possibly crossing a page.
-strcpy_unalign1:
+.Lstrcpy_unalign1:
     ldrb    r2, [r1]
-    cbz     r2, strcpy_unalign_copy1byte
+    cbz     r2, .Lstrcpy_unalign_copy1byte
 
     ldr     r2, [r1], #4
     ldr     r3, [r1], #4
@@ -487,62 +494,62 @@
     sub     ip, r2, #0x01010101
     bic     ip, ip, r2
     ands    ip, ip, #0x80808080
-    bne     strcpy_zero_in_first_register
+    bne     .Lstrcpy_zero_in_first_register
 
     sub     ip, r3, #0x01010101
     bic     ip, ip, r3
     ands    ip, ip, #0x80808080
-    bne     strcpy_zero_in_second_register
+    bne     .Lstrcpy_zero_in_second_register
 
     stmia   r0!, {r2, r3}
-    b       strcpy_unalign1
+    b       .Lstrcpy_unalign1
 
-strcpy_unalign_copy1byte:
+.Lstrcpy_unalign_copy1byte:
     strb    r2, [r0]
     m_ret   inst=pop
 
-strcpy_unalign_copy2bytes:
+.Lstrcpy_unalign_copy2bytes:
     strb    r2, [r0], #1
     strb    r3, [r0]
     m_ret   inst=pop
 
-strcpy_unalign_copy3bytes:
+.Lstrcpy_unalign_copy3bytes:
     strh    r2, [r0], #2
     lsr     r2, #16
     strb    r2, [r0]
     m_ret   inst=pop
 
-strcpy_unalign_copy4bytes:
+.Lstrcpy_unalign_copy4bytes:
     stmia   r0, {r2}
     m_ret   inst=pop
 
-strcat_align_src:
+.Lstrcat_align_src:
     // Align to a double word (64 bits).
     rsb     r3, r3, #8
     lsls    ip, r3, #31
-    beq     strcat_align_to_32
+    beq     .Lstrcat_align_to_32
     ldrb    r2, [r0], #1
-    cbz     r2, strcat_r0_update
+    cbz     r2, .Lstrcat_r0_update
 
-strcat_align_to_32:
-    bcc     strcat_align_to_64
+.Lstrcat_align_to_32:
+    bcc     .Lstrcat_align_to_64
     ldrb    r2, [r0], #1
-    cbz     r2, strcat_r0_update
+    cbz     r2, .Lstrcat_r0_update
     ldrb    r2, [r0], #1
-    cbz     r2, strcat_r0_update
+    cbz     r2, .Lstrcat_r0_update
 
-strcat_align_to_64:
+.Lstrcat_align_to_64:
     tst     r3, #4
-    beq     strcat_mainloop
+    beq     .Lstrcat_mainloop
     ldr     r3, [r0], #4
 
     sub     ip, r3, #0x01010101
     bic     ip, ip, r3
     ands    ip, ip, #0x80808080
-    bne     strcat_zero_in_second_register
-    b       strcat_mainloop
+    bne     .Lstrcat_zero_in_second_register
+    b       .Lstrcat_mainloop
 
-strcat_r0_update:
+.Lstrcat_r0_update:
     sub     r0, r0, #1
-    b strcat_r0_scan_done
+    b .Lstrcat_r0_scan_done
 END(strcat)
diff --git a/libc/arch-arm/cortex-a9/bionic/string_copy.S b/libc/arch-arm/cortex-a9/bionic/string_copy.S
index caf5a11..642db0f 100644
--- a/libc/arch-arm/cortex-a9/bionic/string_copy.S
+++ b/libc/arch-arm/cortex-a9/bionic/string_copy.S
@@ -244,13 +244,20 @@
 .Lstringcopy_align_to_64:
     tst     r3, #4
     beq     .Lstringcopy_check_src_align
-    ldr     r2, [r1], #4
-
-    sub     ip, r2, #0x01010101
-    bic     ip, ip, r2
-    ands    ip, ip, #0x80808080
-    bne     .Lstringcopy_zero_in_first_register
-    stmia   r0!, {r2}
+    // Read one byte at a time since we don't have any idea about the alignment
+    // of the source and we don't want to read into a different page.
+    ldrb    r2, [r1], #1
+    strb    r2, [r0], #1
+    cbz     r2, .Lstringcopy_complete
+    ldrb    r2, [r1], #1
+    strb    r2, [r0], #1
+    cbz     r2, .Lstringcopy_complete
+    ldrb    r2, [r1], #1
+    strb    r2, [r0], #1
+    cbz     r2, .Lstringcopy_complete
+    ldrb    r2, [r1], #1
+    strb    r2, [r0], #1
+    cbz     r2, .Lstringcopy_complete
     b       .Lstringcopy_check_src_align
 
 .Lstringcopy_complete:
diff --git a/libc/arch-arm/cortex-a9/cortex-a9.mk b/libc/arch-arm/cortex-a9/cortex-a9.mk
index 7b38de1..8a26d6b 100644
--- a/libc/arch-arm/cortex-a9/cortex-a9.mk
+++ b/libc/arch-arm/cortex-a9/cortex-a9.mk
@@ -1,3 +1,18 @@
+libc_openbsd_src_files_exclude_arm += \
+    upstream-openbsd/lib/libc/string/memmove.c \
+    upstream-openbsd/lib/libc/string/stpcpy.c \
+    upstream-openbsd/lib/libc/string/strcat.c \
+    upstream-openbsd/lib/libc/string/strcpy.c \
+
+libc_bionic_src_files_exclude_arm += \
+    arch-arm/generic/bionic/memcpy.S \
+    arch-arm/generic/bionic/memset.S \
+    arch-arm/generic/bionic/strcmp.S \
+    arch-arm/generic/bionic/strcpy.S \
+    arch-arm/generic/bionic/strlen.c \
+    bionic/__strcat_chk.cpp \
+    bionic/__strcpy_chk.cpp \
+
 libc_bionic_src_files_arm += \
     arch-arm/cortex-a9/bionic/memcpy.S \
     arch-arm/cortex-a9/bionic/memset.S \
@@ -10,7 +25,4 @@
     arch-arm/cortex-a9/bionic/strlen.S \
 
 libc_bionic_src_files_arm += \
-    arch-arm/generic/bionic/memcmp.S \
-
-libc_bionic_src_files_arm += \
     arch-arm/denver/bionic/memmove.S \
diff --git a/libc/arch-arm/denver/denver.mk b/libc/arch-arm/denver/denver.mk
index 5fddf95..f167991 100644
--- a/libc/arch-arm/denver/denver.mk
+++ b/libc/arch-arm/denver/denver.mk
@@ -1,5 +1,18 @@
+libc_openbsd_src_files_exclude_arm += \
+    upstream-openbsd/lib/libc/string/memmove.c \
+    upstream-openbsd/lib/libc/string/stpcpy.c \
+    upstream-openbsd/lib/libc/string/strcat.c \
+
+libc_bionic_src_files_exclude_arm += \
+    arch-arm/generic/bionic/memcpy.S \
+    arch-arm/generic/bionic/memset.S \
+    arch-arm/generic/bionic/strcmp.S \
+    arch-arm/generic/bionic/strcpy.S \
+    arch-arm/generic/bionic/strlen.c \
+    bionic/__strcat_chk.cpp \
+    bionic/__strcpy_chk.cpp \
+
 libc_bionic_src_files_arm += \
-    arch-arm/generic/bionic/memcmp.S \
     arch-arm/denver/bionic/memcpy.S \
     arch-arm/denver/bionic/memmove.S \
     arch-arm/denver/bionic/memset.S \
diff --git a/libc/arch-arm/generic/bionic/memcmp.S b/libc/arch-arm/generic/bionic/memcmp.S
index c78dbd4..6643d55 100644
--- a/libc/arch-arm/generic/bionic/memcmp.S
+++ b/libc/arch-arm/generic/bionic/memcmp.S
@@ -221,8 +221,7 @@
         bne         8b
 
 9:      /* restore registers and return */
-        ldmfd       sp!, {r4, lr}
-        bx          lr
+        ldmfd       sp!, {r4, pc}
 
 10:     /* process less than 12 bytes */
         cmp         r2, #0
diff --git a/libc/arch-arm/generic/bionic/memcpy.S b/libc/arch-arm/generic/bionic/memcpy.S
index ea5a399..65cba4c 100644
--- a/libc/arch-arm/generic/bionic/memcpy.S
+++ b/libc/arch-arm/generic/bionic/memcpy.S
@@ -194,8 +194,7 @@
 
         /* we're done! restore everything and return */
 1:      ldmfd       sp!, {r5-r11}
-        ldmfd       sp!, {r0, r4, lr}
-        bx          lr
+        ldmfd       sp!, {r0, r4, pc}
 
         /********************************************************************/
 
@@ -385,8 +384,7 @@
 
         /* we're done! restore sp and spilled registers and return */
         add         sp,  sp, #28
-        ldmfd       sp!, {r0, r4, lr}
-        bx          lr
+        ldmfd       sp!, {r0, r4, pc}
 END(memcpy)
 
         // Only reached when the __memcpy_chk check fails.
diff --git a/libc/arch-arm/generic/bionic/memset.S b/libc/arch-arm/generic/bionic/memset.S
index d17a9c4..b8eabbf 100644
--- a/libc/arch-arm/generic/bionic/memset.S
+++ b/libc/arch-arm/generic/bionic/memset.S
@@ -82,8 +82,7 @@
         strbcs      r1, [r0], #1
         strbmi      r1, [r0], #1
         subs        r2, r2, r3
-        popls       {r0, r4-r7, lr}    /* return */
-        bxls        lr
+        popls       {r0, r4-r7, pc}    /* return */
 
         /* align the destination to a cache-line */
         mov         r12, r1
@@ -126,8 +125,7 @@
         strhmi      r1, [r0], #2
         movs        r2, r2, lsl #2
         strbcs      r1, [r0]
-        ldmfd       sp!, {r0, r4-r7, lr}
-        bx          lr
+        ldmfd       sp!, {r0, r4-r7, pc}
 END(memset)
 
         .data
diff --git a/libc/arch-arm/generic/generic.mk b/libc/arch-arm/generic/generic.mk
deleted file mode 100644
index e49d6d2..0000000
--- a/libc/arch-arm/generic/generic.mk
+++ /dev/null
@@ -1,14 +0,0 @@
-libc_bionic_src_files_arm += \
-    arch-arm/generic/bionic/memcmp.S \
-    arch-arm/generic/bionic/memcpy.S \
-    arch-arm/generic/bionic/memset.S \
-    arch-arm/generic/bionic/strcmp.S \
-    arch-arm/generic/bionic/strcpy.S \
-    arch-arm/generic/bionic/strlen.c \
-    bionic/__strcat_chk.cpp \
-    bionic/__strcpy_chk.cpp \
-
-libc_openbsd_src_files_arm += \
-    upstream-openbsd/lib/libc/string/memmove.c \
-    upstream-openbsd/lib/libc/string/stpcpy.c \
-    upstream-openbsd/lib/libc/string/strcat.c \
diff --git a/libc/arch-arm/krait/bionic/__strcat_chk.S b/libc/arch-arm/krait/bionic/__strcat_chk.S
index 246f159..1a39c5b 100644
--- a/libc/arch-arm/krait/bionic/__strcat_chk.S
+++ b/libc/arch-arm/krait/bionic/__strcat_chk.S
@@ -40,7 +40,7 @@
 ENTRY(__strcat_chk)
     pld     [r0, #0]
     push    {r0, lr}
-    .cfi_def_cfa_offset 8
+    .cfi_adjust_cfa_offset 8
     .cfi_rel_offset r0, 0
     .cfi_rel_offset lr, 4
     push    {r4, r5}
@@ -177,7 +177,7 @@
 .L_strlen_done:
     add     r2, r3, r4
     cmp     r2, lr
-    bhi     __strcat_chk_failed
+    bhi     .L_strcat_chk_failed
 
     // Set up the registers for the memcpy code.
     mov     r1, r5
@@ -185,20 +185,17 @@
     mov     r2, r4
     add     r0, r0, r3
     pop     {r4, r5}
-END(__strcat_chk)
+    .cfi_adjust_cfa_offset -8
+    .cfi_restore r4
+    .cfi_restore r5
 
-#define MEMCPY_BASE         __strcat_chk_memcpy_base
-#define MEMCPY_BASE_ALIGNED __strcat_chk_memcpy_base_aligned
 #include "memcpy_base.S"
 
-ENTRY_PRIVATE(__strcat_chk_failed)
-    .cfi_def_cfa_offset 8
-    .cfi_rel_offset r0, 0
-    .cfi_rel_offset lr, 4
+    // Undo the above cfi directives.
     .cfi_adjust_cfa_offset 8
     .cfi_rel_offset r4, 0
     .cfi_rel_offset r5, 4
-
+.L_strcat_chk_failed:
     ldr     r0, error_message
     ldr     r1, error_code
 1:
@@ -208,7 +205,7 @@
     .word   BIONIC_EVENT_STRCAT_BUFFER_OVERFLOW
 error_message:
     .word   error_string-(1b+4)
-END(__strcat_chk_failed)
+END(__strcat_chk)
 
     .data
 error_string:
diff --git a/libc/arch-arm/krait/bionic/__strcpy_chk.S b/libc/arch-arm/krait/bionic/__strcpy_chk.S
index db76686..00202f3 100644
--- a/libc/arch-arm/krait/bionic/__strcpy_chk.S
+++ b/libc/arch-arm/krait/bionic/__strcpy_chk.S
@@ -39,7 +39,7 @@
 ENTRY(__strcpy_chk)
     pld     [r0, #0]
     push    {r0, lr}
-    .cfi_def_cfa_offset 8
+    .cfi_adjust_cfa_offset 8
     .cfi_rel_offset r0, 0
     .cfi_rel_offset lr, 4
 
@@ -149,21 +149,14 @@
     pld     [r1, #64]
     ldr     r0, [sp]
     cmp     r3, lr
-    bhs     __strcpy_chk_failed
+    bhs     .L_strcpy_chk_failed
 
     // Add 1 for copy length to get the string terminator.
     add     r2, r3, #1
-END(__strcpy_chk)
 
-#define MEMCPY_BASE         __strcpy_chk_memcpy_base
-#define MEMCPY_BASE_ALIGNED __strcpy_chk_memcpy_base_aligned
 #include "memcpy_base.S"
 
-ENTRY_PRIVATE(__strcpy_chk_failed)
-    .cfi_def_cfa_offset 8
-    .cfi_rel_offset r0, 0
-    .cfi_rel_offset lr, 4
-
+.L_strcpy_chk_failed:
     ldr     r0, error_message
     ldr     r1, error_code
 1:
@@ -173,7 +166,7 @@
     .word   BIONIC_EVENT_STRCPY_BUFFER_OVERFLOW
 error_message:
     .word   error_string-(1b+4)
-END(__strcpy_chk_failed)
+END(__strcpy_chk)
 
     .data
 error_string:
diff --git a/libc/arch-arm/krait/bionic/memcpy.S b/libc/arch-arm/krait/bionic/memcpy.S
index 9ff46a8..5d27b57 100644
--- a/libc/arch-arm/krait/bionic/memcpy.S
+++ b/libc/arch-arm/krait/bionic/memcpy.S
@@ -45,7 +45,7 @@
 
 ENTRY(__memcpy_chk)
         cmp         r2, r3
-        bhi         __memcpy_chk_fail
+        bhi         .L_memcpy_chk_fail
 
         // Fall through to memcpy...
 END(__memcpy_chk)
@@ -53,19 +53,20 @@
 ENTRY(memcpy)
         pld     [r1, #64]
         stmfd   sp!, {r0, lr}
-        .cfi_def_cfa_offset 8
+        .cfi_adjust_cfa_offset 8
         .cfi_rel_offset r0, 0
         .cfi_rel_offset lr, 4
-END(memcpy)
 
-#define MEMCPY_BASE         __memcpy_base
-#define MEMCPY_BASE_ALIGNED __memcpy_base_aligned
 #include "memcpy_base.S"
 
-ENTRY_PRIVATE(__memcpy_chk_fail)
+        // Undo the cfi directives from above.
+        .cfi_adjust_cfa_offset -8
+        .cfi_restore r0
+        .cfi_restore lr
+.L_memcpy_chk_fail:
         // Preserve lr for backtrace.
         push    {lr}
-        .cfi_def_cfa_offset 4
+        .cfi_adjust_cfa_offset 4
         .cfi_rel_offset lr, 0
 
         ldr     r0, error_message
@@ -77,7 +78,7 @@
         .word   BIONIC_EVENT_MEMCPY_BUFFER_OVERFLOW
 error_message:
         .word   error_string-(1b+4)
-END(__memcpy_chk_fail)
+END(memcpy)
 
         .data
 error_string:
diff --git a/libc/arch-arm/krait/bionic/memcpy_base.S b/libc/arch-arm/krait/bionic/memcpy_base.S
index 035dcf1..76c5a84 100644
--- a/libc/arch-arm/krait/bionic/memcpy_base.S
+++ b/libc/arch-arm/krait/bionic/memcpy_base.S
@@ -1,123 +1,191 @@
-/*
- * Copyright (C) 2013 The Android Open Source Project
- * All rights reserved.
- *
- * Redistribution and use in source and binary forms, with or without
- * modification, are permitted provided that the following conditions
- * are met:
- *  * Redistributions of source code must retain the above copyright
- *    notice, this list of conditions and the following disclaimer.
- *  * Redistributions in binary form must reproduce the above copyright
- *    notice, this list of conditions and the following disclaimer in
- *    the documentation and/or other materials provided with the
- *    distribution.
- *
- * THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS
- * "AS IS" AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT
- * LIMITED TO, THE IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS
- * FOR A PARTICULAR PURPOSE ARE DISCLAIMED. IN NO EVENT SHALL THE
- * COPYRIGHT OWNER OR CONTRIBUTORS BE LIABLE FOR ANY DIRECT, INDIRECT,
- * INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING,
- * BUT NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; LOSS
- * OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED
- * AND ON ANY THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY,
- * OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT
- * OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF
- * SUCH DAMAGE.
- */
+/***************************************************************************
+ Copyright (c) 2009-2013 The Linux Foundation. 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 Linux 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 code assumes it is running on a processor that supports all arm v7
- * instructions, that supports neon instructions, and that has a 32 byte
- * cache line.
- */
+ 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.
+  ***************************************************************************/
 
-// Assumes neon instructions and a cache line size of 32 bytes.
+/* Assumes neon instructions and a cache line size of 64 bytes. */
 
-ENTRY_PRIVATE(MEMCPY_BASE)
-        .cfi_def_cfa_offset 8
-        .cfi_rel_offset r0, 0
-        .cfi_rel_offset lr, 4
+#include <machine/cpu-features.h>
+#include <machine/asm.h>
 
-        /* do we have at least 16-bytes to copy (needed for alignment below) */
-        cmp         r2, #16
-        blo         5f
+#define PLDOFFS	(10)
+#define PLDTHRESH (PLDOFFS)
+#define BBTHRESH (4096/64)
+#define PLDSIZE (64)
 
-        /* align destination to cache-line for the write-buffer */
-        rsb         r3, r0, #0
-        ands        r3, r3, #0xF
-        beq         2f
+#if (PLDOFFS < 1)
+#error Routine does not support offsets less than 1
+#endif
 
-        /* copy up to 15-bytes (count in r3) */
-        sub         r2, r2, r3
-        movs        ip, r3, lsl #31
-        itt         mi
-        ldrbmi      lr, [r1], #1
-        strbmi      lr, [r0], #1
-        itttt       cs
-        ldrbcs      ip, [r1], #1
-        ldrbcs      lr, [r1], #1
-        strbcs      ip, [r0], #1
-        strbcs      lr, [r0], #1
-        movs        ip, r3, lsl #29
-        bge         1f
-        // copies 4 bytes, destination 32-bits aligned
-        vld4.8      {d0[0], d1[0], d2[0], d3[0]}, [r1]!
-        vst4.8      {d0[0], d1[0], d2[0], d3[0]}, [r0, :32]!
-1:      bcc         2f
-        // copies 8 bytes, destination 64-bits aligned
-        vld1.8      {d0}, [r1]!
-        vst1.8      {d0}, [r0, :64]!
+#if (PLDTHRESH < PLDOFFS)
+#error PLD threshold must be greater than or equal to the PLD offset
+#endif
 
-2:      /* make sure we have at least 64 bytes to copy */
-        subs        r2, r2, #64
-        blo         2f
+	.text
+	.fpu    neon
 
-1:      /* The main loop copies 64 bytes at a time */
-        vld1.8      {d0  - d3},   [r1]!
-        vld1.8      {d4  - d7},   [r1]!
-        pld         [r1, #(32*8)]
-        subs        r2, r2, #64
-        vst1.8      {d0  - d3},   [r0, :128]!
-        vst1.8      {d4  - d7},   [r0, :128]!
-        bhs         1b
+.L_memcpy_base:
+	cmp	r2, #4
+	blt	.L_neon_lt4
+	cmp	r2, #16
+	blt	.L_neon_lt16
+	cmp	r2, #32
+	blt	.L_neon_16
+	cmp	r2, #64
+	blt	.L_neon_copy_32_a
 
-2:      /* fix-up the remaining count and make sure we have >= 32 bytes left */
-        adds        r2, r2, #32
-        blo         4f
+	mov	r12, r2, lsr #6
+	cmp	r12, #PLDTHRESH
+	ble	.L_neon_copy_64_loop_nopld
 
-        /* Copy 32 bytes. These cache lines were already preloaded */
-        vld1.8      {d0 - d3},  [r1]!
-        sub         r2, r2, #32
-        vst1.8      {d0 - d3},  [r0, :128]!
+	push	{r9, r10}
+	.cfi_adjust_cfa_offset 8
+	.cfi_rel_offset r9, 0
+	.cfi_rel_offset r10, 4
 
-4:      /* less than 32 left */
-        add         r2, r2, #32
-        tst         r2, #0x10
-        beq         5f
-        // copies 16 bytes, 128-bits aligned
-        vld1.8      {d0, d1}, [r1]!
-        vst1.8      {d0, d1}, [r0, :128]!
+	cmp	r12, #BBTHRESH
+	ble	.L_neon_prime_pump
 
-5:      /* copy up to 15-bytes (count in r2) */
-        movs        ip, r2, lsl #29
-        bcc         1f
-        vld1.8      {d0}, [r1]!
-        vst1.8      {d0}, [r0]!
-1:      bge         2f
-        vld4.8      {d0[0], d1[0], d2[0], d3[0]}, [r1]!
-        vst4.8      {d0[0], d1[0], d2[0], d3[0]}, [r0]!
-2:      movs        ip, r2, lsl #31
-        itt         mi
-        ldrbmi      r3, [r1], #1
-        strbmi      r3, [r0], #1
-        itttt       cs
-        ldrbcs      ip, [r1], #1
-        ldrbcs      lr, [r1], #1
-        strbcs      ip, [r0], #1
-        strbcs      lr, [r0], #1
+	add	lr, r0, #0x400
+	add	r9, r1, #(PLDOFFS*PLDSIZE)
+	sub	lr, lr, r9
+	lsl	lr, lr, #21
+	lsr	lr, lr, #21
+	add	lr, lr, #(PLDOFFS*PLDSIZE)
+	cmp	r12, lr, lsr #6
+	ble	.L_neon_prime_pump
 
-        ldmfd       sp!, {r0, lr}
-        bx          lr
-END(MEMCPY_BASE)
+	itt	gt
+	movgt	r9, #(PLDOFFS)
+	rsbsgt	r9, r9, lr, lsr #6
+	ble	.L_neon_prime_pump
+
+	add	r10, r1, lr
+	bic	r10, #0x3F
+
+	sub	r12, r12, lr, lsr #6
+
+	cmp	r9, r12
+	itee	le
+	suble	r12, r12, r9
+	movgt	r9, r12
+	movgt	r12, #0
+
+	pld	[r1, #((PLDOFFS-1)*PLDSIZE)]
+.L_neon_copy_64_loop_outer_doublepld:
+	pld	[r1, #((PLDOFFS)*PLDSIZE)]
+	vld1.32	{q0, q1}, [r1]!
+	vld1.32	{q2, q3}, [r1]!
+	ldr	r3, [r10]
+	subs	r9, r9, #1
+	vst1.32	{q0, q1}, [r0]!
+	vst1.32	{q2, q3}, [r0]!
+	add	r10, #64
+	bne	.L_neon_copy_64_loop_outer_doublepld
+	cmp	r12, #0
+	beq	.L_neon_pop_before_nopld
+
+	cmp	r12, #(512*1024/64)
+	blt	.L_neon_copy_64_loop_outer
+
+.L_neon_copy_64_loop_ddr:
+	vld1.32	{q0, q1}, [r1]!
+	vld1.32	{q2, q3}, [r1]!
+	pld	[r10]
+	subs	r12, r12, #1
+	vst1.32	{q0, q1}, [r0]!
+	vst1.32	{q2, q3}, [r0]!
+	add	r10, #64
+	bne	.L_neon_copy_64_loop_ddr
+	b	.L_neon_pop_before_nopld
+
+.L_neon_prime_pump:
+	mov	lr, #(PLDOFFS*PLDSIZE)
+	add	r10, r1, #(PLDOFFS*PLDSIZE)
+	bic	r10, #0x3F
+	sub	r12, r12, #PLDOFFS
+	ldr	r3, [r10, #(-1*PLDSIZE)]
+
+.L_neon_copy_64_loop_outer:
+	vld1.32	{q0, q1}, [r1]!
+	vld1.32	{q2, q3}, [r1]!
+	ldr	r3, [r10]
+	subs	r12, r12, #1
+	vst1.32	{q0, q1}, [r0]!
+	vst1.32	{q2, q3}, [r0]!
+	add	r10, #64
+	bne	.L_neon_copy_64_loop_outer
+
+.L_neon_pop_before_nopld:
+	mov	r12, lr, lsr #6
+	pop	{r9, r10}
+	.cfi_adjust_cfa_offset -8
+	.cfi_restore r9
+	.cfi_restore r10
+
+.L_neon_copy_64_loop_nopld:
+	vld1.32	{q8, q9}, [r1]!
+	vld1.32	{q10, q11}, [r1]!
+	subs	r12, r12, #1
+	vst1.32	{q8, q9}, [r0]!
+	vst1.32	{q10, q11}, [r0]!
+	bne	.L_neon_copy_64_loop_nopld
+	ands	r2, r2, #0x3f
+	beq	.L_neon_exit
+
+.L_neon_copy_32_a:
+	movs	r3, r2, lsl #27
+	bcc	.L_neon_16
+	vld1.32	{q0,q1}, [r1]!
+	vst1.32	{q0,q1}, [r0]!
+
+.L_neon_16:
+	bpl	.L_neon_lt16
+	vld1.32	{q8}, [r1]!
+	vst1.32	{q8}, [r0]!
+	ands	r2, r2, #0x0f
+	beq	.L_neon_exit
+
+.L_neon_lt16:
+	movs	r3, r2, lsl #29
+	bcc	1f
+	vld1.8	{d0}, [r1]!
+	vst1.8	{d0}, [r0]!
+1:
+	bge	.L_neon_lt4
+	vld4.8	{d0[0], d1[0], d2[0], d3[0]}, [r1]!
+	vst4.8	{d0[0], d1[0], d2[0], d3[0]}, [r0]!
+
+.L_neon_lt4:
+	movs	r2, r2, lsl #31
+	itt	cs
+	ldrhcs	r3, [r1], #2
+	strhcs	r3, [r0], #2
+	itt	mi
+	ldrbmi	r3, [r1]
+	strbmi	r3, [r0]
+
+.L_neon_exit:
+	pop	{r0, pc}
diff --git a/libc/arch-arm/krait/bionic/memset.S b/libc/arch-arm/krait/bionic/memset.S
index a4fbe17..ae05965 100644
--- a/libc/arch-arm/krait/bionic/memset.S
+++ b/libc/arch-arm/krait/bionic/memset.S
@@ -69,10 +69,7 @@
 
 /* memset() returns its first argument.  */
 ENTRY(memset)
-        stmfd       sp!, {r0}
-        .cfi_def_cfa_offset 4
-        .cfi_rel_offset r0, 0
-
+        mov         r3, r0
         vdup.8      q0, r1
 
         /* make sure we have at least 32 bytes to write */
@@ -82,7 +79,7 @@
 
 1:      /* The main loop writes 32 bytes at a time */
         subs        r2, r2, #32
-        vst1.8      {d0 - d3}, [r0]!
+        vst1.8      {d0 - d3}, [r3]!
         bhs         1b
 
 2:      /* less than 32 left */
@@ -91,18 +88,17 @@
         beq         3f
 
         // writes 16 bytes, 128-bits aligned
-        vst1.8      {d0, d1}, [r0]!
+        vst1.8      {d0, d1}, [r3]!
 3:      /* write up to 15-bytes (count in r2) */
         movs        ip, r2, lsl #29
         bcc         1f
-        vst1.8      {d0}, [r0]!
+        vst1.8      {d0}, [r3]!
 1:      bge         2f
-        vst1.32     {d0[0]}, [r0]!
+        vst1.32     {d0[0]}, [r3]!
 2:      movs        ip, r2, lsl #31
-        strbmi      r1, [r0], #1
-        strbcs      r1, [r0], #1
-        strbcs      r1, [r0], #1
-        ldmfd       sp!, {r0}
+        strbmi      r1, [r3], #1
+        strbcs      r1, [r3], #1
+        strbcs      r1, [r3], #1
         bx          lr
 END(memset)
 
diff --git a/libc/arch-arm/krait/krait.mk b/libc/arch-arm/krait/krait.mk
index 88b4d66..f8e3452 100644
--- a/libc/arch-arm/krait/krait.mk
+++ b/libc/arch-arm/krait/krait.mk
@@ -1,3 +1,18 @@
+libc_openbsd_src_files_exclude_arm += \
+    upstream-openbsd/lib/libc/string/memmove.c \
+    upstream-openbsd/lib/libc/string/stpcpy.c \
+    upstream-openbsd/lib/libc/string/stpcpy.c \
+    upstream-openbsd/lib/libc/string/strcat.c \
+
+libc_bionic_src_files_exclude_arm += \
+    arch-arm/generic/bionic/memcpy.S \
+    arch-arm/generic/bionic/memset.S \
+    arch-arm/generic/bionic/strcmp.S \
+    arch-arm/generic/bionic/strcpy.S \
+    arch-arm/generic/bionic/strlen.c \
+    bionic/__strcat_chk.cpp \
+    bionic/__strcpy_chk.cpp \
+
 libc_bionic_src_files_arm += \
     arch-arm/krait/bionic/memcpy.S \
     arch-arm/krait/bionic/memset.S \
@@ -13,7 +28,4 @@
     arch-arm/cortex-a15/bionic/strlen.S \
 
 libc_bionic_src_files_arm += \
-    arch-arm/generic/bionic/memcmp.S \
-
-libc_bionic_src_files_arm += \
     arch-arm/denver/bionic/memmove.S \
diff --git a/libc/arch-arm/syscalls/___clock_nanosleep.S b/libc/arch-arm/syscalls/___clock_nanosleep.S
index 31420bb..ef8f065 100644
--- a/libc/arch-arm/syscalls/___clock_nanosleep.S
+++ b/libc/arch-arm/syscalls/___clock_nanosleep.S
@@ -4,9 +4,11 @@
 
 ENTRY(___clock_nanosleep)
     mov     ip, r7
+    .cfi_register r7, ip
     ldr     r7, =__NR_clock_nanosleep
     swi     #0
     mov     r7, ip
+    .cfi_restore r7
     cmn     r0, #(MAX_ERRNO + 1)
     bxls    lr
     neg     r0, r0
diff --git a/libc/arch-arm/syscalls/___close.S b/libc/arch-arm/syscalls/___close.S
index db8a230..05d3352 100644
--- a/libc/arch-arm/syscalls/___close.S
+++ b/libc/arch-arm/syscalls/___close.S
@@ -4,9 +4,11 @@
 
 ENTRY(___close)
     mov     ip, r7
+    .cfi_register r7, ip
     ldr     r7, =__NR_close
     swi     #0
     mov     r7, ip
+    .cfi_restore r7
     cmn     r0, #(MAX_ERRNO + 1)
     bxls    lr
     neg     r0, r0
diff --git a/libc/arch-arm/syscalls/___faccessat.S b/libc/arch-arm/syscalls/___faccessat.S
index 1d09cf7..8bb4cf8 100644
--- a/libc/arch-arm/syscalls/___faccessat.S
+++ b/libc/arch-arm/syscalls/___faccessat.S
@@ -4,9 +4,11 @@
 
 ENTRY(___faccessat)
     mov     ip, r7
+    .cfi_register r7, ip
     ldr     r7, =__NR_faccessat
     swi     #0
     mov     r7, ip
+    .cfi_restore r7
     cmn     r0, #(MAX_ERRNO + 1)
     bxls    lr
     neg     r0, r0
diff --git a/libc/arch-arm/syscalls/___fchmod.S b/libc/arch-arm/syscalls/___fchmod.S
index c6da4f8..b2312cb 100644
--- a/libc/arch-arm/syscalls/___fchmod.S
+++ b/libc/arch-arm/syscalls/___fchmod.S
@@ -4,9 +4,11 @@
 
 ENTRY(___fchmod)
     mov     ip, r7
+    .cfi_register r7, ip
     ldr     r7, =__NR_fchmod
     swi     #0
     mov     r7, ip
+    .cfi_restore r7
     cmn     r0, #(MAX_ERRNO + 1)
     bxls    lr
     neg     r0, r0
diff --git a/libc/arch-arm/syscalls/___fchmodat.S b/libc/arch-arm/syscalls/___fchmodat.S
index 91bbda5..4773610 100644
--- a/libc/arch-arm/syscalls/___fchmodat.S
+++ b/libc/arch-arm/syscalls/___fchmodat.S
@@ -4,9 +4,11 @@
 
 ENTRY(___fchmodat)
     mov     ip, r7
+    .cfi_register r7, ip
     ldr     r7, =__NR_fchmodat
     swi     #0
     mov     r7, ip
+    .cfi_restore r7
     cmn     r0, #(MAX_ERRNO + 1)
     bxls    lr
     neg     r0, r0
diff --git a/libc/arch-arm/syscalls/___fgetxattr.S b/libc/arch-arm/syscalls/___fgetxattr.S
index e776cd6..25be039 100644
--- a/libc/arch-arm/syscalls/___fgetxattr.S
+++ b/libc/arch-arm/syscalls/___fgetxattr.S
@@ -4,9 +4,11 @@
 
 ENTRY(___fgetxattr)
     mov     ip, r7
+    .cfi_register r7, ip
     ldr     r7, =__NR_fgetxattr
     swi     #0
     mov     r7, ip
+    .cfi_restore r7
     cmn     r0, #(MAX_ERRNO + 1)
     bxls    lr
     neg     r0, r0
diff --git a/libc/arch-arm/syscalls/flistxattr.S b/libc/arch-arm/syscalls/___flistxattr.S
similarity index 71%
rename from libc/arch-arm/syscalls/flistxattr.S
rename to libc/arch-arm/syscalls/___flistxattr.S
index ee09295..904e4ca 100644
--- a/libc/arch-arm/syscalls/flistxattr.S
+++ b/libc/arch-arm/syscalls/___flistxattr.S
@@ -2,13 +2,16 @@
 
 #include <private/bionic_asm.h>
 
-ENTRY(flistxattr)
+ENTRY(___flistxattr)
     mov     ip, r7
+    .cfi_register r7, ip
     ldr     r7, =__NR_flistxattr
     swi     #0
     mov     r7, ip
+    .cfi_restore r7
     cmn     r0, #(MAX_ERRNO + 1)
     bxls    lr
     neg     r0, r0
     b       __set_errno_internal
-END(flistxattr)
+END(___flistxattr)
+.hidden ___flistxattr
diff --git a/libc/arch-arm/syscalls/___mremap.S b/libc/arch-arm/syscalls/___mremap.S
new file mode 100644
index 0000000..ade8d78
--- /dev/null
+++ b/libc/arch-arm/syscalls/___mremap.S
@@ -0,0 +1,23 @@
+/* Generated by gensyscalls.py. Do not edit. */
+
+#include <private/bionic_asm.h>
+
+ENTRY(___mremap)
+    mov     ip, sp
+    stmfd   sp!, {r4, r5, r6, r7}
+    .cfi_def_cfa_offset 16
+    .cfi_rel_offset r4, 0
+    .cfi_rel_offset r5, 4
+    .cfi_rel_offset r6, 8
+    .cfi_rel_offset r7, 12
+    ldmfd   ip, {r4, r5, r6}
+    ldr     r7, =__NR_mremap
+    swi     #0
+    ldmfd   sp!, {r4, r5, r6, r7}
+    .cfi_def_cfa_offset 0
+    cmn     r0, #(MAX_ERRNO + 1)
+    bxls    lr
+    neg     r0, r0
+    b       __set_errno_internal
+END(___mremap)
+.hidden ___mremap
diff --git a/libc/arch-arm/syscalls/___rt_sigqueueinfo.S b/libc/arch-arm/syscalls/___rt_sigqueueinfo.S
index 25b0d57..1367e56 100644
--- a/libc/arch-arm/syscalls/___rt_sigqueueinfo.S
+++ b/libc/arch-arm/syscalls/___rt_sigqueueinfo.S
@@ -4,9 +4,11 @@
 
 ENTRY(___rt_sigqueueinfo)
     mov     ip, r7
+    .cfi_register r7, ip
     ldr     r7, =__NR_rt_sigqueueinfo
     swi     #0
     mov     r7, ip
+    .cfi_restore r7
     cmn     r0, #(MAX_ERRNO + 1)
     bxls    lr
     neg     r0, r0
diff --git a/libc/arch-arm/syscalls/__accept4.S b/libc/arch-arm/syscalls/__accept4.S
index dca5699..42aa47c 100644
--- a/libc/arch-arm/syscalls/__accept4.S
+++ b/libc/arch-arm/syscalls/__accept4.S
@@ -4,9 +4,11 @@
 
 ENTRY(__accept4)
     mov     ip, r7
+    .cfi_register r7, ip
     ldr     r7, =__NR_accept4
     swi     #0
     mov     r7, ip
+    .cfi_restore r7
     cmn     r0, #(MAX_ERRNO + 1)
     bxls    lr
     neg     r0, r0
diff --git a/libc/arch-arm/syscalls/__brk.S b/libc/arch-arm/syscalls/__brk.S
index be304da..246924c 100644
--- a/libc/arch-arm/syscalls/__brk.S
+++ b/libc/arch-arm/syscalls/__brk.S
@@ -4,9 +4,11 @@
 
 ENTRY(__brk)
     mov     ip, r7
+    .cfi_register r7, ip
     ldr     r7, =__NR_brk
     swi     #0
     mov     r7, ip
+    .cfi_restore r7
     cmn     r0, #(MAX_ERRNO + 1)
     bxls    lr
     neg     r0, r0
diff --git a/libc/arch-arm/syscalls/__connect.S b/libc/arch-arm/syscalls/__connect.S
index a2a997e..873b14d 100644
--- a/libc/arch-arm/syscalls/__connect.S
+++ b/libc/arch-arm/syscalls/__connect.S
@@ -4,9 +4,11 @@
 
 ENTRY(__connect)
     mov     ip, r7
+    .cfi_register r7, ip
     ldr     r7, =__NR_connect
     swi     #0
     mov     r7, ip
+    .cfi_restore r7
     cmn     r0, #(MAX_ERRNO + 1)
     bxls    lr
     neg     r0, r0
diff --git a/libc/arch-arm/syscalls/__exit.S b/libc/arch-arm/syscalls/__exit.S
index 6ebd5b3..4ed31b0 100644
--- a/libc/arch-arm/syscalls/__exit.S
+++ b/libc/arch-arm/syscalls/__exit.S
@@ -4,9 +4,11 @@
 
 ENTRY(__exit)
     mov     ip, r7
+    .cfi_register r7, ip
     ldr     r7, =__NR_exit
     swi     #0
     mov     r7, ip
+    .cfi_restore r7
     cmn     r0, #(MAX_ERRNO + 1)
     bxls    lr
     neg     r0, r0
diff --git a/libc/arch-arm/syscalls/__fcntl64.S b/libc/arch-arm/syscalls/__fcntl64.S
index 229c5c6..0afdbee 100644
--- a/libc/arch-arm/syscalls/__fcntl64.S
+++ b/libc/arch-arm/syscalls/__fcntl64.S
@@ -4,9 +4,11 @@
 
 ENTRY(__fcntl64)
     mov     ip, r7
+    .cfi_register r7, ip
     ldr     r7, =__NR_fcntl64
     swi     #0
     mov     r7, ip
+    .cfi_restore r7
     cmn     r0, #(MAX_ERRNO + 1)
     bxls    lr
     neg     r0, r0
diff --git a/libc/arch-arm/syscalls/__fstatfs64.S b/libc/arch-arm/syscalls/__fstatfs64.S
index 9c0c439..9117313 100644
--- a/libc/arch-arm/syscalls/__fstatfs64.S
+++ b/libc/arch-arm/syscalls/__fstatfs64.S
@@ -4,9 +4,11 @@
 
 ENTRY(__fstatfs64)
     mov     ip, r7
+    .cfi_register r7, ip
     ldr     r7, =__NR_fstatfs64
     swi     #0
     mov     r7, ip
+    .cfi_restore r7
     cmn     r0, #(MAX_ERRNO + 1)
     bxls    lr
     neg     r0, r0
diff --git a/libc/arch-arm/syscalls/__getcpu.S b/libc/arch-arm/syscalls/__getcpu.S
index d523d8e..430acb3 100644
--- a/libc/arch-arm/syscalls/__getcpu.S
+++ b/libc/arch-arm/syscalls/__getcpu.S
@@ -4,9 +4,11 @@
 
 ENTRY(__getcpu)
     mov     ip, r7
+    .cfi_register r7, ip
     ldr     r7, =__NR_getcpu
     swi     #0
     mov     r7, ip
+    .cfi_restore r7
     cmn     r0, #(MAX_ERRNO + 1)
     bxls    lr
     neg     r0, r0
diff --git a/libc/arch-arm/syscalls/__getcwd.S b/libc/arch-arm/syscalls/__getcwd.S
index 4ff6667..53000b8 100644
--- a/libc/arch-arm/syscalls/__getcwd.S
+++ b/libc/arch-arm/syscalls/__getcwd.S
@@ -4,9 +4,11 @@
 
 ENTRY(__getcwd)
     mov     ip, r7
+    .cfi_register r7, ip
     ldr     r7, =__NR_getcwd
     swi     #0
     mov     r7, ip
+    .cfi_restore r7
     cmn     r0, #(MAX_ERRNO + 1)
     bxls    lr
     neg     r0, r0
diff --git a/libc/arch-arm/syscalls/__getdents64.S b/libc/arch-arm/syscalls/__getdents64.S
index dac3bfc..0ea61b8 100644
--- a/libc/arch-arm/syscalls/__getdents64.S
+++ b/libc/arch-arm/syscalls/__getdents64.S
@@ -4,9 +4,11 @@
 
 ENTRY(__getdents64)
     mov     ip, r7
+    .cfi_register r7, ip
     ldr     r7, =__NR_getdents64
     swi     #0
     mov     r7, ip
+    .cfi_restore r7
     cmn     r0, #(MAX_ERRNO + 1)
     bxls    lr
     neg     r0, r0
diff --git a/libc/arch-arm/syscalls/__getpid.S b/libc/arch-arm/syscalls/__getpid.S
index dbb192e..b555385 100644
--- a/libc/arch-arm/syscalls/__getpid.S
+++ b/libc/arch-arm/syscalls/__getpid.S
@@ -4,9 +4,11 @@
 
 ENTRY(__getpid)
     mov     ip, r7
+    .cfi_register r7, ip
     ldr     r7, =__NR_getpid
     swi     #0
     mov     r7, ip
+    .cfi_restore r7
     cmn     r0, #(MAX_ERRNO + 1)
     bxls    lr
     neg     r0, r0
diff --git a/libc/arch-arm/syscalls/__getpriority.S b/libc/arch-arm/syscalls/__getpriority.S
index e637d6f..34f4bea 100644
--- a/libc/arch-arm/syscalls/__getpriority.S
+++ b/libc/arch-arm/syscalls/__getpriority.S
@@ -4,9 +4,11 @@
 
 ENTRY(__getpriority)
     mov     ip, r7
+    .cfi_register r7, ip
     ldr     r7, =__NR_getpriority
     swi     #0
     mov     r7, ip
+    .cfi_restore r7
     cmn     r0, #(MAX_ERRNO + 1)
     bxls    lr
     neg     r0, r0
diff --git a/libc/arch-arm/syscalls/__ioctl.S b/libc/arch-arm/syscalls/__ioctl.S
index fcd1157..5871e58 100644
--- a/libc/arch-arm/syscalls/__ioctl.S
+++ b/libc/arch-arm/syscalls/__ioctl.S
@@ -4,9 +4,11 @@
 
 ENTRY(__ioctl)
     mov     ip, r7
+    .cfi_register r7, ip
     ldr     r7, =__NR_ioctl
     swi     #0
     mov     r7, ip
+    .cfi_restore r7
     cmn     r0, #(MAX_ERRNO + 1)
     bxls    lr
     neg     r0, r0
diff --git a/libc/arch-arm/syscalls/__openat.S b/libc/arch-arm/syscalls/__openat.S
index 9b774db..403d9b5 100644
--- a/libc/arch-arm/syscalls/__openat.S
+++ b/libc/arch-arm/syscalls/__openat.S
@@ -4,9 +4,11 @@
 
 ENTRY(__openat)
     mov     ip, r7
+    .cfi_register r7, ip
     ldr     r7, =__NR_openat
     swi     #0
     mov     r7, ip
+    .cfi_restore r7
     cmn     r0, #(MAX_ERRNO + 1)
     bxls    lr
     neg     r0, r0
diff --git a/libc/arch-arm/syscalls/__preadv64.S b/libc/arch-arm/syscalls/__preadv64.S
new file mode 100644
index 0000000..19eaaa5
--- /dev/null
+++ b/libc/arch-arm/syscalls/__preadv64.S
@@ -0,0 +1,22 @@
+/* Generated by gensyscalls.py. Do not edit. */
+
+#include <private/bionic_asm.h>
+
+ENTRY(__preadv64)
+    mov     ip, sp
+    stmfd   sp!, {r4, r5, r6, r7}
+    .cfi_def_cfa_offset 16
+    .cfi_rel_offset r4, 0
+    .cfi_rel_offset r5, 4
+    .cfi_rel_offset r6, 8
+    .cfi_rel_offset r7, 12
+    ldmfd   ip, {r4, r5, r6}
+    ldr     r7, =__NR_preadv
+    swi     #0
+    ldmfd   sp!, {r4, r5, r6, r7}
+    .cfi_def_cfa_offset 0
+    cmn     r0, #(MAX_ERRNO + 1)
+    bxls    lr
+    neg     r0, r0
+    b       __set_errno_internal
+END(__preadv64)
diff --git a/libc/arch-arm/syscalls/__ptrace.S b/libc/arch-arm/syscalls/__ptrace.S
index 975ab0f..8ad554d 100644
--- a/libc/arch-arm/syscalls/__ptrace.S
+++ b/libc/arch-arm/syscalls/__ptrace.S
@@ -4,9 +4,11 @@
 
 ENTRY(__ptrace)
     mov     ip, r7
+    .cfi_register r7, ip
     ldr     r7, =__NR_ptrace
     swi     #0
     mov     r7, ip
+    .cfi_restore r7
     cmn     r0, #(MAX_ERRNO + 1)
     bxls    lr
     neg     r0, r0
diff --git a/libc/arch-arm/syscalls/__pwritev64.S b/libc/arch-arm/syscalls/__pwritev64.S
new file mode 100644
index 0000000..afcbe40
--- /dev/null
+++ b/libc/arch-arm/syscalls/__pwritev64.S
@@ -0,0 +1,22 @@
+/* Generated by gensyscalls.py. Do not edit. */
+
+#include <private/bionic_asm.h>
+
+ENTRY(__pwritev64)
+    mov     ip, sp
+    stmfd   sp!, {r4, r5, r6, r7}
+    .cfi_def_cfa_offset 16
+    .cfi_rel_offset r4, 0
+    .cfi_rel_offset r5, 4
+    .cfi_rel_offset r6, 8
+    .cfi_rel_offset r7, 12
+    ldmfd   ip, {r4, r5, r6}
+    ldr     r7, =__NR_pwritev
+    swi     #0
+    ldmfd   sp!, {r4, r5, r6, r7}
+    .cfi_def_cfa_offset 0
+    cmn     r0, #(MAX_ERRNO + 1)
+    bxls    lr
+    neg     r0, r0
+    b       __set_errno_internal
+END(__pwritev64)
diff --git a/libc/arch-arm/syscalls/__reboot.S b/libc/arch-arm/syscalls/__reboot.S
index 03f8c89..15ca814 100644
--- a/libc/arch-arm/syscalls/__reboot.S
+++ b/libc/arch-arm/syscalls/__reboot.S
@@ -4,9 +4,11 @@
 
 ENTRY(__reboot)
     mov     ip, r7
+    .cfi_register r7, ip
     ldr     r7, =__NR_reboot
     swi     #0
     mov     r7, ip
+    .cfi_restore r7
     cmn     r0, #(MAX_ERRNO + 1)
     bxls    lr
     neg     r0, r0
diff --git a/libc/arch-arm/syscalls/__rt_sigaction.S b/libc/arch-arm/syscalls/__rt_sigaction.S
index 2c21012..21d9977 100644
--- a/libc/arch-arm/syscalls/__rt_sigaction.S
+++ b/libc/arch-arm/syscalls/__rt_sigaction.S
@@ -4,9 +4,11 @@
 
 ENTRY(__rt_sigaction)
     mov     ip, r7
+    .cfi_register r7, ip
     ldr     r7, =__NR_rt_sigaction
     swi     #0
     mov     r7, ip
+    .cfi_restore r7
     cmn     r0, #(MAX_ERRNO + 1)
     bxls    lr
     neg     r0, r0
diff --git a/libc/arch-arm/syscalls/__rt_sigpending.S b/libc/arch-arm/syscalls/__rt_sigpending.S
index 6a32e50..b726b85 100644
--- a/libc/arch-arm/syscalls/__rt_sigpending.S
+++ b/libc/arch-arm/syscalls/__rt_sigpending.S
@@ -4,9 +4,11 @@
 
 ENTRY(__rt_sigpending)
     mov     ip, r7
+    .cfi_register r7, ip
     ldr     r7, =__NR_rt_sigpending
     swi     #0
     mov     r7, ip
+    .cfi_restore r7
     cmn     r0, #(MAX_ERRNO + 1)
     bxls    lr
     neg     r0, r0
diff --git a/libc/arch-arm/syscalls/__rt_sigprocmask.S b/libc/arch-arm/syscalls/__rt_sigprocmask.S
index 136dc79..11b326f 100644
--- a/libc/arch-arm/syscalls/__rt_sigprocmask.S
+++ b/libc/arch-arm/syscalls/__rt_sigprocmask.S
@@ -4,9 +4,11 @@
 
 ENTRY(__rt_sigprocmask)
     mov     ip, r7
+    .cfi_register r7, ip
     ldr     r7, =__NR_rt_sigprocmask
     swi     #0
     mov     r7, ip
+    .cfi_restore r7
     cmn     r0, #(MAX_ERRNO + 1)
     bxls    lr
     neg     r0, r0
diff --git a/libc/arch-arm/syscalls/__rt_sigsuspend.S b/libc/arch-arm/syscalls/__rt_sigsuspend.S
index 2cef4a4..5d06418 100644
--- a/libc/arch-arm/syscalls/__rt_sigsuspend.S
+++ b/libc/arch-arm/syscalls/__rt_sigsuspend.S
@@ -4,9 +4,11 @@
 
 ENTRY(__rt_sigsuspend)
     mov     ip, r7
+    .cfi_register r7, ip
     ldr     r7, =__NR_rt_sigsuspend
     swi     #0
     mov     r7, ip
+    .cfi_restore r7
     cmn     r0, #(MAX_ERRNO + 1)
     bxls    lr
     neg     r0, r0
diff --git a/libc/arch-arm/syscalls/__rt_sigtimedwait.S b/libc/arch-arm/syscalls/__rt_sigtimedwait.S
index cb43ad1..dc7c3e7 100644
--- a/libc/arch-arm/syscalls/__rt_sigtimedwait.S
+++ b/libc/arch-arm/syscalls/__rt_sigtimedwait.S
@@ -4,9 +4,11 @@
 
 ENTRY(__rt_sigtimedwait)
     mov     ip, r7
+    .cfi_register r7, ip
     ldr     r7, =__NR_rt_sigtimedwait
     swi     #0
     mov     r7, ip
+    .cfi_restore r7
     cmn     r0, #(MAX_ERRNO + 1)
     bxls    lr
     neg     r0, r0
diff --git a/libc/arch-arm/syscalls/__sched_getaffinity.S b/libc/arch-arm/syscalls/__sched_getaffinity.S
index 6613ea5..21f8330 100644
--- a/libc/arch-arm/syscalls/__sched_getaffinity.S
+++ b/libc/arch-arm/syscalls/__sched_getaffinity.S
@@ -4,9 +4,11 @@
 
 ENTRY(__sched_getaffinity)
     mov     ip, r7
+    .cfi_register r7, ip
     ldr     r7, =__NR_sched_getaffinity
     swi     #0
     mov     r7, ip
+    .cfi_restore r7
     cmn     r0, #(MAX_ERRNO + 1)
     bxls    lr
     neg     r0, r0
diff --git a/libc/arch-arm/syscalls/__set_tid_address.S b/libc/arch-arm/syscalls/__set_tid_address.S
index d3558f5..79dfd7f 100644
--- a/libc/arch-arm/syscalls/__set_tid_address.S
+++ b/libc/arch-arm/syscalls/__set_tid_address.S
@@ -4,9 +4,11 @@
 
 ENTRY(__set_tid_address)
     mov     ip, r7
+    .cfi_register r7, ip
     ldr     r7, =__NR_set_tid_address
     swi     #0
     mov     r7, ip
+    .cfi_restore r7
     cmn     r0, #(MAX_ERRNO + 1)
     bxls    lr
     neg     r0, r0
diff --git a/libc/arch-arm/syscalls/__set_tls.S b/libc/arch-arm/syscalls/__set_tls.S
index 4d5d963..a9a4b9a 100644
--- a/libc/arch-arm/syscalls/__set_tls.S
+++ b/libc/arch-arm/syscalls/__set_tls.S
@@ -4,9 +4,11 @@
 
 ENTRY(__set_tls)
     mov     ip, r7
+    .cfi_register r7, ip
     ldr     r7, =__ARM_NR_set_tls
     swi     #0
     mov     r7, ip
+    .cfi_restore r7
     cmn     r0, #(MAX_ERRNO + 1)
     bxls    lr
     neg     r0, r0
diff --git a/libc/arch-arm/syscalls/__sigaction.S b/libc/arch-arm/syscalls/__sigaction.S
index 600593d..8f3f143 100644
--- a/libc/arch-arm/syscalls/__sigaction.S
+++ b/libc/arch-arm/syscalls/__sigaction.S
@@ -4,9 +4,11 @@
 
 ENTRY(__sigaction)
     mov     ip, r7
+    .cfi_register r7, ip
     ldr     r7, =__NR_sigaction
     swi     #0
     mov     r7, ip
+    .cfi_restore r7
     cmn     r0, #(MAX_ERRNO + 1)
     bxls    lr
     neg     r0, r0
diff --git a/libc/arch-arm/syscalls/__signalfd4.S b/libc/arch-arm/syscalls/__signalfd4.S
index 630a71f..51a27c8 100644
--- a/libc/arch-arm/syscalls/__signalfd4.S
+++ b/libc/arch-arm/syscalls/__signalfd4.S
@@ -4,9 +4,11 @@
 
 ENTRY(__signalfd4)
     mov     ip, r7
+    .cfi_register r7, ip
     ldr     r7, =__NR_signalfd4
     swi     #0
     mov     r7, ip
+    .cfi_restore r7
     cmn     r0, #(MAX_ERRNO + 1)
     bxls    lr
     neg     r0, r0
diff --git a/libc/arch-arm/syscalls/__socket.S b/libc/arch-arm/syscalls/__socket.S
index fffe0cc..c50cd6f 100644
--- a/libc/arch-arm/syscalls/__socket.S
+++ b/libc/arch-arm/syscalls/__socket.S
@@ -4,9 +4,11 @@
 
 ENTRY(__socket)
     mov     ip, r7
+    .cfi_register r7, ip
     ldr     r7, =__NR_socket
     swi     #0
     mov     r7, ip
+    .cfi_restore r7
     cmn     r0, #(MAX_ERRNO + 1)
     bxls    lr
     neg     r0, r0
diff --git a/libc/arch-arm/syscalls/__statfs64.S b/libc/arch-arm/syscalls/__statfs64.S
index ec43218..320b0ee 100644
--- a/libc/arch-arm/syscalls/__statfs64.S
+++ b/libc/arch-arm/syscalls/__statfs64.S
@@ -4,9 +4,11 @@
 
 ENTRY(__statfs64)
     mov     ip, r7
+    .cfi_register r7, ip
     ldr     r7, =__NR_statfs64
     swi     #0
     mov     r7, ip
+    .cfi_restore r7
     cmn     r0, #(MAX_ERRNO + 1)
     bxls    lr
     neg     r0, r0
diff --git a/libc/arch-arm/syscalls/__timer_create.S b/libc/arch-arm/syscalls/__timer_create.S
index 2e4c634..fd7567b 100644
--- a/libc/arch-arm/syscalls/__timer_create.S
+++ b/libc/arch-arm/syscalls/__timer_create.S
@@ -4,9 +4,11 @@
 
 ENTRY(__timer_create)
     mov     ip, r7
+    .cfi_register r7, ip
     ldr     r7, =__NR_timer_create
     swi     #0
     mov     r7, ip
+    .cfi_restore r7
     cmn     r0, #(MAX_ERRNO + 1)
     bxls    lr
     neg     r0, r0
diff --git a/libc/arch-arm/syscalls/__timer_delete.S b/libc/arch-arm/syscalls/__timer_delete.S
index 237024c..6761abb 100644
--- a/libc/arch-arm/syscalls/__timer_delete.S
+++ b/libc/arch-arm/syscalls/__timer_delete.S
@@ -4,9 +4,11 @@
 
 ENTRY(__timer_delete)
     mov     ip, r7
+    .cfi_register r7, ip
     ldr     r7, =__NR_timer_delete
     swi     #0
     mov     r7, ip
+    .cfi_restore r7
     cmn     r0, #(MAX_ERRNO + 1)
     bxls    lr
     neg     r0, r0
diff --git a/libc/arch-arm/syscalls/__timer_getoverrun.S b/libc/arch-arm/syscalls/__timer_getoverrun.S
index f29d5b3..a925d83 100644
--- a/libc/arch-arm/syscalls/__timer_getoverrun.S
+++ b/libc/arch-arm/syscalls/__timer_getoverrun.S
@@ -4,9 +4,11 @@
 
 ENTRY(__timer_getoverrun)
     mov     ip, r7
+    .cfi_register r7, ip
     ldr     r7, =__NR_timer_getoverrun
     swi     #0
     mov     r7, ip
+    .cfi_restore r7
     cmn     r0, #(MAX_ERRNO + 1)
     bxls    lr
     neg     r0, r0
diff --git a/libc/arch-arm/syscalls/__timer_gettime.S b/libc/arch-arm/syscalls/__timer_gettime.S
index e6dc2ed..c0da770 100644
--- a/libc/arch-arm/syscalls/__timer_gettime.S
+++ b/libc/arch-arm/syscalls/__timer_gettime.S
@@ -4,9 +4,11 @@
 
 ENTRY(__timer_gettime)
     mov     ip, r7
+    .cfi_register r7, ip
     ldr     r7, =__NR_timer_gettime
     swi     #0
     mov     r7, ip
+    .cfi_restore r7
     cmn     r0, #(MAX_ERRNO + 1)
     bxls    lr
     neg     r0, r0
diff --git a/libc/arch-arm/syscalls/__timer_settime.S b/libc/arch-arm/syscalls/__timer_settime.S
index 4aea279..de4e7e6 100644
--- a/libc/arch-arm/syscalls/__timer_settime.S
+++ b/libc/arch-arm/syscalls/__timer_settime.S
@@ -4,9 +4,11 @@
 
 ENTRY(__timer_settime)
     mov     ip, r7
+    .cfi_register r7, ip
     ldr     r7, =__NR_timer_settime
     swi     #0
     mov     r7, ip
+    .cfi_restore r7
     cmn     r0, #(MAX_ERRNO + 1)
     bxls    lr
     neg     r0, r0
diff --git a/libc/arch-arm/syscalls/_exit.S b/libc/arch-arm/syscalls/_exit.S
index 77da743..1c3d174 100644
--- a/libc/arch-arm/syscalls/_exit.S
+++ b/libc/arch-arm/syscalls/_exit.S
@@ -4,9 +4,11 @@
 
 ENTRY(_exit)
     mov     ip, r7
+    .cfi_register r7, ip
     ldr     r7, =__NR_exit_group
     swi     #0
     mov     r7, ip
+    .cfi_restore r7
     cmn     r0, #(MAX_ERRNO + 1)
     bxls    lr
     neg     r0, r0
diff --git a/libc/arch-arm/syscalls/acct.S b/libc/arch-arm/syscalls/acct.S
index dbc5d58..cdf1099 100644
--- a/libc/arch-arm/syscalls/acct.S
+++ b/libc/arch-arm/syscalls/acct.S
@@ -4,9 +4,11 @@
 
 ENTRY(acct)
     mov     ip, r7
+    .cfi_register r7, ip
     ldr     r7, =__NR_acct
     swi     #0
     mov     r7, ip
+    .cfi_restore r7
     cmn     r0, #(MAX_ERRNO + 1)
     bxls    lr
     neg     r0, r0
diff --git a/libc/arch-arm/syscalls/vfork.S b/libc/arch-arm/syscalls/adjtimex.S
similarity index 68%
rename from libc/arch-arm/syscalls/vfork.S
rename to libc/arch-arm/syscalls/adjtimex.S
index 5f4cb3d..6ebae7e 100644
--- a/libc/arch-arm/syscalls/vfork.S
+++ b/libc/arch-arm/syscalls/adjtimex.S
@@ -2,13 +2,15 @@
 
 #include <private/bionic_asm.h>
 
-ENTRY(vfork)
+ENTRY(adjtimex)
     mov     ip, r7
-    ldr     r7, =__NR_vfork
+    .cfi_register r7, ip
+    ldr     r7, =__NR_adjtimex
     swi     #0
     mov     r7, ip
+    .cfi_restore r7
     cmn     r0, #(MAX_ERRNO + 1)
     bxls    lr
     neg     r0, r0
     b       __set_errno_internal
-END(vfork)
+END(adjtimex)
diff --git a/libc/arch-arm/syscalls/bind.S b/libc/arch-arm/syscalls/bind.S
index c901417..af518d8 100644
--- a/libc/arch-arm/syscalls/bind.S
+++ b/libc/arch-arm/syscalls/bind.S
@@ -4,9 +4,11 @@
 
 ENTRY(bind)
     mov     ip, r7
+    .cfi_register r7, ip
     ldr     r7, =__NR_bind
     swi     #0
     mov     r7, ip
+    .cfi_restore r7
     cmn     r0, #(MAX_ERRNO + 1)
     bxls    lr
     neg     r0, r0
diff --git a/libc/arch-arm/syscalls/cacheflush.S b/libc/arch-arm/syscalls/cacheflush.S
index 76f4623..752749a 100644
--- a/libc/arch-arm/syscalls/cacheflush.S
+++ b/libc/arch-arm/syscalls/cacheflush.S
@@ -4,9 +4,11 @@
 
 ENTRY(cacheflush)
     mov     ip, r7
+    .cfi_register r7, ip
     ldr     r7, =__ARM_NR_cacheflush
     swi     #0
     mov     r7, ip
+    .cfi_restore r7
     cmn     r0, #(MAX_ERRNO + 1)
     bxls    lr
     neg     r0, r0
diff --git a/libc/arch-arm/syscalls/capget.S b/libc/arch-arm/syscalls/capget.S
index 59a5a3c..9be110b 100644
--- a/libc/arch-arm/syscalls/capget.S
+++ b/libc/arch-arm/syscalls/capget.S
@@ -4,9 +4,11 @@
 
 ENTRY(capget)
     mov     ip, r7
+    .cfi_register r7, ip
     ldr     r7, =__NR_capget
     swi     #0
     mov     r7, ip
+    .cfi_restore r7
     cmn     r0, #(MAX_ERRNO + 1)
     bxls    lr
     neg     r0, r0
diff --git a/libc/arch-arm/syscalls/capset.S b/libc/arch-arm/syscalls/capset.S
index af284ab..0bd5009 100644
--- a/libc/arch-arm/syscalls/capset.S
+++ b/libc/arch-arm/syscalls/capset.S
@@ -4,9 +4,11 @@
 
 ENTRY(capset)
     mov     ip, r7
+    .cfi_register r7, ip
     ldr     r7, =__NR_capset
     swi     #0
     mov     r7, ip
+    .cfi_restore r7
     cmn     r0, #(MAX_ERRNO + 1)
     bxls    lr
     neg     r0, r0
diff --git a/libc/arch-arm/syscalls/chdir.S b/libc/arch-arm/syscalls/chdir.S
index 25f27ba..c75f5e2 100644
--- a/libc/arch-arm/syscalls/chdir.S
+++ b/libc/arch-arm/syscalls/chdir.S
@@ -4,9 +4,11 @@
 
 ENTRY(chdir)
     mov     ip, r7
+    .cfi_register r7, ip
     ldr     r7, =__NR_chdir
     swi     #0
     mov     r7, ip
+    .cfi_restore r7
     cmn     r0, #(MAX_ERRNO + 1)
     bxls    lr
     neg     r0, r0
diff --git a/libc/arch-arm/syscalls/chroot.S b/libc/arch-arm/syscalls/chroot.S
index 6f829a6..d197d42 100644
--- a/libc/arch-arm/syscalls/chroot.S
+++ b/libc/arch-arm/syscalls/chroot.S
@@ -4,9 +4,11 @@
 
 ENTRY(chroot)
     mov     ip, r7
+    .cfi_register r7, ip
     ldr     r7, =__NR_chroot
     swi     #0
     mov     r7, ip
+    .cfi_restore r7
     cmn     r0, #(MAX_ERRNO + 1)
     bxls    lr
     neg     r0, r0
diff --git a/libc/arch-arm/syscalls/vfork.S b/libc/arch-arm/syscalls/clock_adjtime.S
similarity index 65%
copy from libc/arch-arm/syscalls/vfork.S
copy to libc/arch-arm/syscalls/clock_adjtime.S
index 5f4cb3d..e59a240 100644
--- a/libc/arch-arm/syscalls/vfork.S
+++ b/libc/arch-arm/syscalls/clock_adjtime.S
@@ -2,13 +2,15 @@
 
 #include <private/bionic_asm.h>
 
-ENTRY(vfork)
+ENTRY(clock_adjtime)
     mov     ip, r7
-    ldr     r7, =__NR_vfork
+    .cfi_register r7, ip
+    ldr     r7, =__NR_clock_adjtime
     swi     #0
     mov     r7, ip
+    .cfi_restore r7
     cmn     r0, #(MAX_ERRNO + 1)
     bxls    lr
     neg     r0, r0
     b       __set_errno_internal
-END(vfork)
+END(clock_adjtime)
diff --git a/libc/arch-arm/syscalls/clock_getres.S b/libc/arch-arm/syscalls/clock_getres.S
index 48fa07c..e101127 100644
--- a/libc/arch-arm/syscalls/clock_getres.S
+++ b/libc/arch-arm/syscalls/clock_getres.S
@@ -4,9 +4,11 @@
 
 ENTRY(clock_getres)
     mov     ip, r7
+    .cfi_register r7, ip
     ldr     r7, =__NR_clock_getres
     swi     #0
     mov     r7, ip
+    .cfi_restore r7
     cmn     r0, #(MAX_ERRNO + 1)
     bxls    lr
     neg     r0, r0
diff --git a/libc/arch-arm/syscalls/clock_gettime.S b/libc/arch-arm/syscalls/clock_gettime.S
index 317481d..61a95dd 100644
--- a/libc/arch-arm/syscalls/clock_gettime.S
+++ b/libc/arch-arm/syscalls/clock_gettime.S
@@ -4,9 +4,11 @@
 
 ENTRY(clock_gettime)
     mov     ip, r7
+    .cfi_register r7, ip
     ldr     r7, =__NR_clock_gettime
     swi     #0
     mov     r7, ip
+    .cfi_restore r7
     cmn     r0, #(MAX_ERRNO + 1)
     bxls    lr
     neg     r0, r0
diff --git a/libc/arch-arm/syscalls/clock_settime.S b/libc/arch-arm/syscalls/clock_settime.S
index bf54702..f00a072 100644
--- a/libc/arch-arm/syscalls/clock_settime.S
+++ b/libc/arch-arm/syscalls/clock_settime.S
@@ -4,9 +4,11 @@
 
 ENTRY(clock_settime)
     mov     ip, r7
+    .cfi_register r7, ip
     ldr     r7, =__NR_clock_settime
     swi     #0
     mov     r7, ip
+    .cfi_restore r7
     cmn     r0, #(MAX_ERRNO + 1)
     bxls    lr
     neg     r0, r0
diff --git a/libc/arch-arm/syscalls/delete_module.S b/libc/arch-arm/syscalls/delete_module.S
index 57580c9..80dd0f5 100644
--- a/libc/arch-arm/syscalls/delete_module.S
+++ b/libc/arch-arm/syscalls/delete_module.S
@@ -4,9 +4,11 @@
 
 ENTRY(delete_module)
     mov     ip, r7
+    .cfi_register r7, ip
     ldr     r7, =__NR_delete_module
     swi     #0
     mov     r7, ip
+    .cfi_restore r7
     cmn     r0, #(MAX_ERRNO + 1)
     bxls    lr
     neg     r0, r0
diff --git a/libc/arch-arm/syscalls/dup.S b/libc/arch-arm/syscalls/dup.S
index 2cd69d7..0d06bdc 100644
--- a/libc/arch-arm/syscalls/dup.S
+++ b/libc/arch-arm/syscalls/dup.S
@@ -4,9 +4,11 @@
 
 ENTRY(dup)
     mov     ip, r7
+    .cfi_register r7, ip
     ldr     r7, =__NR_dup
     swi     #0
     mov     r7, ip
+    .cfi_restore r7
     cmn     r0, #(MAX_ERRNO + 1)
     bxls    lr
     neg     r0, r0
diff --git a/libc/arch-arm/syscalls/dup3.S b/libc/arch-arm/syscalls/dup3.S
index 4613d63..7dea858 100644
--- a/libc/arch-arm/syscalls/dup3.S
+++ b/libc/arch-arm/syscalls/dup3.S
@@ -4,9 +4,11 @@
 
 ENTRY(dup3)
     mov     ip, r7
+    .cfi_register r7, ip
     ldr     r7, =__NR_dup3
     swi     #0
     mov     r7, ip
+    .cfi_restore r7
     cmn     r0, #(MAX_ERRNO + 1)
     bxls    lr
     neg     r0, r0
diff --git a/libc/arch-arm/syscalls/epoll_create1.S b/libc/arch-arm/syscalls/epoll_create1.S
index 108c24f..8b413d9 100644
--- a/libc/arch-arm/syscalls/epoll_create1.S
+++ b/libc/arch-arm/syscalls/epoll_create1.S
@@ -4,9 +4,11 @@
 
 ENTRY(epoll_create1)
     mov     ip, r7
+    .cfi_register r7, ip
     ldr     r7, =__NR_epoll_create1
     swi     #0
     mov     r7, ip
+    .cfi_restore r7
     cmn     r0, #(MAX_ERRNO + 1)
     bxls    lr
     neg     r0, r0
diff --git a/libc/arch-arm/syscalls/epoll_ctl.S b/libc/arch-arm/syscalls/epoll_ctl.S
index 473af6a..807dd69 100644
--- a/libc/arch-arm/syscalls/epoll_ctl.S
+++ b/libc/arch-arm/syscalls/epoll_ctl.S
@@ -4,9 +4,11 @@
 
 ENTRY(epoll_ctl)
     mov     ip, r7
+    .cfi_register r7, ip
     ldr     r7, =__NR_epoll_ctl
     swi     #0
     mov     r7, ip
+    .cfi_restore r7
     cmn     r0, #(MAX_ERRNO + 1)
     bxls    lr
     neg     r0, r0
diff --git a/libc/arch-arm/syscalls/eventfd.S b/libc/arch-arm/syscalls/eventfd.S
index ca6bcee..51f4a49 100644
--- a/libc/arch-arm/syscalls/eventfd.S
+++ b/libc/arch-arm/syscalls/eventfd.S
@@ -4,9 +4,11 @@
 
 ENTRY(eventfd)
     mov     ip, r7
+    .cfi_register r7, ip
     ldr     r7, =__NR_eventfd2
     swi     #0
     mov     r7, ip
+    .cfi_restore r7
     cmn     r0, #(MAX_ERRNO + 1)
     bxls    lr
     neg     r0, r0
diff --git a/libc/arch-arm/syscalls/execve.S b/libc/arch-arm/syscalls/execve.S
index 3eca810..1b72f0e 100644
--- a/libc/arch-arm/syscalls/execve.S
+++ b/libc/arch-arm/syscalls/execve.S
@@ -4,9 +4,11 @@
 
 ENTRY(execve)
     mov     ip, r7
+    .cfi_register r7, ip
     ldr     r7, =__NR_execve
     swi     #0
     mov     r7, ip
+    .cfi_restore r7
     cmn     r0, #(MAX_ERRNO + 1)
     bxls    lr
     neg     r0, r0
diff --git a/libc/arch-arm/syscalls/fchdir.S b/libc/arch-arm/syscalls/fchdir.S
index 705ad32..dca18c4 100644
--- a/libc/arch-arm/syscalls/fchdir.S
+++ b/libc/arch-arm/syscalls/fchdir.S
@@ -4,9 +4,11 @@
 
 ENTRY(fchdir)
     mov     ip, r7
+    .cfi_register r7, ip
     ldr     r7, =__NR_fchdir
     swi     #0
     mov     r7, ip
+    .cfi_restore r7
     cmn     r0, #(MAX_ERRNO + 1)
     bxls    lr
     neg     r0, r0
diff --git a/libc/arch-arm/syscalls/fchown.S b/libc/arch-arm/syscalls/fchown.S
index 45ad9bf..51ee60c 100644
--- a/libc/arch-arm/syscalls/fchown.S
+++ b/libc/arch-arm/syscalls/fchown.S
@@ -4,9 +4,11 @@
 
 ENTRY(fchown)
     mov     ip, r7
+    .cfi_register r7, ip
     ldr     r7, =__NR_fchown32
     swi     #0
     mov     r7, ip
+    .cfi_restore r7
     cmn     r0, #(MAX_ERRNO + 1)
     bxls    lr
     neg     r0, r0
diff --git a/libc/arch-arm/syscalls/fdatasync.S b/libc/arch-arm/syscalls/fdatasync.S
index 7fefd22..f97adc6 100644
--- a/libc/arch-arm/syscalls/fdatasync.S
+++ b/libc/arch-arm/syscalls/fdatasync.S
@@ -4,9 +4,11 @@
 
 ENTRY(fdatasync)
     mov     ip, r7
+    .cfi_register r7, ip
     ldr     r7, =__NR_fdatasync
     swi     #0
     mov     r7, ip
+    .cfi_restore r7
     cmn     r0, #(MAX_ERRNO + 1)
     bxls    lr
     neg     r0, r0
diff --git a/libc/arch-arm/syscalls/flock.S b/libc/arch-arm/syscalls/flock.S
index c946fe9..e2874f6 100644
--- a/libc/arch-arm/syscalls/flock.S
+++ b/libc/arch-arm/syscalls/flock.S
@@ -4,9 +4,11 @@
 
 ENTRY(flock)
     mov     ip, r7
+    .cfi_register r7, ip
     ldr     r7, =__NR_flock
     swi     #0
     mov     r7, ip
+    .cfi_restore r7
     cmn     r0, #(MAX_ERRNO + 1)
     bxls    lr
     neg     r0, r0
diff --git a/libc/arch-arm/syscalls/fremovexattr.S b/libc/arch-arm/syscalls/fremovexattr.S
index f4e950b..89be704 100644
--- a/libc/arch-arm/syscalls/fremovexattr.S
+++ b/libc/arch-arm/syscalls/fremovexattr.S
@@ -4,9 +4,11 @@
 
 ENTRY(fremovexattr)
     mov     ip, r7
+    .cfi_register r7, ip
     ldr     r7, =__NR_fremovexattr
     swi     #0
     mov     r7, ip
+    .cfi_restore r7
     cmn     r0, #(MAX_ERRNO + 1)
     bxls    lr
     neg     r0, r0
diff --git a/libc/arch-arm/syscalls/fstat64.S b/libc/arch-arm/syscalls/fstat64.S
index 798bba7..c2c7101 100644
--- a/libc/arch-arm/syscalls/fstat64.S
+++ b/libc/arch-arm/syscalls/fstat64.S
@@ -4,9 +4,11 @@
 
 ENTRY(fstat64)
     mov     ip, r7
+    .cfi_register r7, ip
     ldr     r7, =__NR_fstat64
     swi     #0
     mov     r7, ip
+    .cfi_restore r7
     cmn     r0, #(MAX_ERRNO + 1)
     bxls    lr
     neg     r0, r0
diff --git a/libc/arch-arm/syscalls/fstatat64.S b/libc/arch-arm/syscalls/fstatat64.S
index 03e0052..545dc16 100644
--- a/libc/arch-arm/syscalls/fstatat64.S
+++ b/libc/arch-arm/syscalls/fstatat64.S
@@ -4,9 +4,11 @@
 
 ENTRY(fstatat64)
     mov     ip, r7
+    .cfi_register r7, ip
     ldr     r7, =__NR_fstatat64
     swi     #0
     mov     r7, ip
+    .cfi_restore r7
     cmn     r0, #(MAX_ERRNO + 1)
     bxls    lr
     neg     r0, r0
diff --git a/libc/arch-arm/syscalls/fsync.S b/libc/arch-arm/syscalls/fsync.S
index 1dfff05..24b9a87 100644
--- a/libc/arch-arm/syscalls/fsync.S
+++ b/libc/arch-arm/syscalls/fsync.S
@@ -4,9 +4,11 @@
 
 ENTRY(fsync)
     mov     ip, r7
+    .cfi_register r7, ip
     ldr     r7, =__NR_fsync
     swi     #0
     mov     r7, ip
+    .cfi_restore r7
     cmn     r0, #(MAX_ERRNO + 1)
     bxls    lr
     neg     r0, r0
diff --git a/libc/arch-arm/syscalls/ftruncate64.S b/libc/arch-arm/syscalls/ftruncate64.S
index ac0caa8..ee1a2a6 100644
--- a/libc/arch-arm/syscalls/ftruncate64.S
+++ b/libc/arch-arm/syscalls/ftruncate64.S
@@ -4,9 +4,11 @@
 
 ENTRY(ftruncate64)
     mov     ip, r7
+    .cfi_register r7, ip
     ldr     r7, =__NR_ftruncate64
     swi     #0
     mov     r7, ip
+    .cfi_restore r7
     cmn     r0, #(MAX_ERRNO + 1)
     bxls    lr
     neg     r0, r0
diff --git a/libc/arch-arm/syscalls/getegid.S b/libc/arch-arm/syscalls/getegid.S
index afa9cc8..f4e17b5 100644
--- a/libc/arch-arm/syscalls/getegid.S
+++ b/libc/arch-arm/syscalls/getegid.S
@@ -4,9 +4,11 @@
 
 ENTRY(getegid)
     mov     ip, r7
+    .cfi_register r7, ip
     ldr     r7, =__NR_getegid32
     swi     #0
     mov     r7, ip
+    .cfi_restore r7
     cmn     r0, #(MAX_ERRNO + 1)
     bxls    lr
     neg     r0, r0
diff --git a/libc/arch-arm/syscalls/geteuid.S b/libc/arch-arm/syscalls/geteuid.S
index 10c8a25..01898f8 100644
--- a/libc/arch-arm/syscalls/geteuid.S
+++ b/libc/arch-arm/syscalls/geteuid.S
@@ -4,9 +4,11 @@
 
 ENTRY(geteuid)
     mov     ip, r7
+    .cfi_register r7, ip
     ldr     r7, =__NR_geteuid32
     swi     #0
     mov     r7, ip
+    .cfi_restore r7
     cmn     r0, #(MAX_ERRNO + 1)
     bxls    lr
     neg     r0, r0
diff --git a/libc/arch-arm/syscalls/getgid.S b/libc/arch-arm/syscalls/getgid.S
index 8772762..ee124a6 100644
--- a/libc/arch-arm/syscalls/getgid.S
+++ b/libc/arch-arm/syscalls/getgid.S
@@ -4,9 +4,11 @@
 
 ENTRY(getgid)
     mov     ip, r7
+    .cfi_register r7, ip
     ldr     r7, =__NR_getgid32
     swi     #0
     mov     r7, ip
+    .cfi_restore r7
     cmn     r0, #(MAX_ERRNO + 1)
     bxls    lr
     neg     r0, r0
diff --git a/libc/arch-arm/syscalls/getgroups.S b/libc/arch-arm/syscalls/getgroups.S
index 366299b..4c1bfdb 100644
--- a/libc/arch-arm/syscalls/getgroups.S
+++ b/libc/arch-arm/syscalls/getgroups.S
@@ -4,9 +4,11 @@
 
 ENTRY(getgroups)
     mov     ip, r7
+    .cfi_register r7, ip
     ldr     r7, =__NR_getgroups32
     swi     #0
     mov     r7, ip
+    .cfi_restore r7
     cmn     r0, #(MAX_ERRNO + 1)
     bxls    lr
     neg     r0, r0
diff --git a/libc/arch-arm/syscalls/getitimer.S b/libc/arch-arm/syscalls/getitimer.S
index 80fb0f2..b9773ad 100644
--- a/libc/arch-arm/syscalls/getitimer.S
+++ b/libc/arch-arm/syscalls/getitimer.S
@@ -4,9 +4,11 @@
 
 ENTRY(getitimer)
     mov     ip, r7
+    .cfi_register r7, ip
     ldr     r7, =__NR_getitimer
     swi     #0
     mov     r7, ip
+    .cfi_restore r7
     cmn     r0, #(MAX_ERRNO + 1)
     bxls    lr
     neg     r0, r0
diff --git a/libc/arch-arm/syscalls/getpeername.S b/libc/arch-arm/syscalls/getpeername.S
index 25f0026..6bf6002 100644
--- a/libc/arch-arm/syscalls/getpeername.S
+++ b/libc/arch-arm/syscalls/getpeername.S
@@ -4,9 +4,11 @@
 
 ENTRY(getpeername)
     mov     ip, r7
+    .cfi_register r7, ip
     ldr     r7, =__NR_getpeername
     swi     #0
     mov     r7, ip
+    .cfi_restore r7
     cmn     r0, #(MAX_ERRNO + 1)
     bxls    lr
     neg     r0, r0
diff --git a/libc/arch-arm/syscalls/getpgid.S b/libc/arch-arm/syscalls/getpgid.S
index 36c4c19..d5c9c8a 100644
--- a/libc/arch-arm/syscalls/getpgid.S
+++ b/libc/arch-arm/syscalls/getpgid.S
@@ -4,9 +4,11 @@
 
 ENTRY(getpgid)
     mov     ip, r7
+    .cfi_register r7, ip
     ldr     r7, =__NR_getpgid
     swi     #0
     mov     r7, ip
+    .cfi_restore r7
     cmn     r0, #(MAX_ERRNO + 1)
     bxls    lr
     neg     r0, r0
diff --git a/libc/arch-arm/syscalls/getppid.S b/libc/arch-arm/syscalls/getppid.S
index 606b2e0..91db24e 100644
--- a/libc/arch-arm/syscalls/getppid.S
+++ b/libc/arch-arm/syscalls/getppid.S
@@ -4,9 +4,11 @@
 
 ENTRY(getppid)
     mov     ip, r7
+    .cfi_register r7, ip
     ldr     r7, =__NR_getppid
     swi     #0
     mov     r7, ip
+    .cfi_restore r7
     cmn     r0, #(MAX_ERRNO + 1)
     bxls    lr
     neg     r0, r0
diff --git a/libc/arch-arm/syscalls/getresgid.S b/libc/arch-arm/syscalls/getresgid.S
index a5e4689..8fb7f28 100644
--- a/libc/arch-arm/syscalls/getresgid.S
+++ b/libc/arch-arm/syscalls/getresgid.S
@@ -4,9 +4,11 @@
 
 ENTRY(getresgid)
     mov     ip, r7
+    .cfi_register r7, ip
     ldr     r7, =__NR_getresgid32
     swi     #0
     mov     r7, ip
+    .cfi_restore r7
     cmn     r0, #(MAX_ERRNO + 1)
     bxls    lr
     neg     r0, r0
diff --git a/libc/arch-arm/syscalls/getresuid.S b/libc/arch-arm/syscalls/getresuid.S
index 74c26a7..ebec6e1 100644
--- a/libc/arch-arm/syscalls/getresuid.S
+++ b/libc/arch-arm/syscalls/getresuid.S
@@ -4,9 +4,11 @@
 
 ENTRY(getresuid)
     mov     ip, r7
+    .cfi_register r7, ip
     ldr     r7, =__NR_getresuid32
     swi     #0
     mov     r7, ip
+    .cfi_restore r7
     cmn     r0, #(MAX_ERRNO + 1)
     bxls    lr
     neg     r0, r0
diff --git a/libc/arch-arm/syscalls/getrlimit.S b/libc/arch-arm/syscalls/getrlimit.S
index 166da63..0c9e662 100644
--- a/libc/arch-arm/syscalls/getrlimit.S
+++ b/libc/arch-arm/syscalls/getrlimit.S
@@ -4,9 +4,11 @@
 
 ENTRY(getrlimit)
     mov     ip, r7
+    .cfi_register r7, ip
     ldr     r7, =__NR_ugetrlimit
     swi     #0
     mov     r7, ip
+    .cfi_restore r7
     cmn     r0, #(MAX_ERRNO + 1)
     bxls    lr
     neg     r0, r0
diff --git a/libc/arch-arm/syscalls/getrusage.S b/libc/arch-arm/syscalls/getrusage.S
index 93979c6..e74a4ad 100644
--- a/libc/arch-arm/syscalls/getrusage.S
+++ b/libc/arch-arm/syscalls/getrusage.S
@@ -4,9 +4,11 @@
 
 ENTRY(getrusage)
     mov     ip, r7
+    .cfi_register r7, ip
     ldr     r7, =__NR_getrusage
     swi     #0
     mov     r7, ip
+    .cfi_restore r7
     cmn     r0, #(MAX_ERRNO + 1)
     bxls    lr
     neg     r0, r0
diff --git a/libc/arch-arm/syscalls/getsid.S b/libc/arch-arm/syscalls/getsid.S
index 87d38fb..c918820 100644
--- a/libc/arch-arm/syscalls/getsid.S
+++ b/libc/arch-arm/syscalls/getsid.S
@@ -4,9 +4,11 @@
 
 ENTRY(getsid)
     mov     ip, r7
+    .cfi_register r7, ip
     ldr     r7, =__NR_getsid
     swi     #0
     mov     r7, ip
+    .cfi_restore r7
     cmn     r0, #(MAX_ERRNO + 1)
     bxls    lr
     neg     r0, r0
diff --git a/libc/arch-arm/syscalls/getsockname.S b/libc/arch-arm/syscalls/getsockname.S
index 5dc4eab..a30a291 100644
--- a/libc/arch-arm/syscalls/getsockname.S
+++ b/libc/arch-arm/syscalls/getsockname.S
@@ -4,9 +4,11 @@
 
 ENTRY(getsockname)
     mov     ip, r7
+    .cfi_register r7, ip
     ldr     r7, =__NR_getsockname
     swi     #0
     mov     r7, ip
+    .cfi_restore r7
     cmn     r0, #(MAX_ERRNO + 1)
     bxls    lr
     neg     r0, r0
diff --git a/libc/arch-arm/syscalls/gettimeofday.S b/libc/arch-arm/syscalls/gettimeofday.S
index 174f94b..f5ed674 100644
--- a/libc/arch-arm/syscalls/gettimeofday.S
+++ b/libc/arch-arm/syscalls/gettimeofday.S
@@ -4,9 +4,11 @@
 
 ENTRY(gettimeofday)
     mov     ip, r7
+    .cfi_register r7, ip
     ldr     r7, =__NR_gettimeofday
     swi     #0
     mov     r7, ip
+    .cfi_restore r7
     cmn     r0, #(MAX_ERRNO + 1)
     bxls    lr
     neg     r0, r0
diff --git a/libc/arch-arm/syscalls/getuid.S b/libc/arch-arm/syscalls/getuid.S
index 3d07d3c..cdc86bc 100644
--- a/libc/arch-arm/syscalls/getuid.S
+++ b/libc/arch-arm/syscalls/getuid.S
@@ -4,9 +4,11 @@
 
 ENTRY(getuid)
     mov     ip, r7
+    .cfi_register r7, ip
     ldr     r7, =__NR_getuid32
     swi     #0
     mov     r7, ip
+    .cfi_restore r7
     cmn     r0, #(MAX_ERRNO + 1)
     bxls    lr
     neg     r0, r0
diff --git a/libc/arch-arm/syscalls/getxattr.S b/libc/arch-arm/syscalls/getxattr.S
index 6661aaf..116d917 100644
--- a/libc/arch-arm/syscalls/getxattr.S
+++ b/libc/arch-arm/syscalls/getxattr.S
@@ -4,9 +4,11 @@
 
 ENTRY(getxattr)
     mov     ip, r7
+    .cfi_register r7, ip
     ldr     r7, =__NR_getxattr
     swi     #0
     mov     r7, ip
+    .cfi_restore r7
     cmn     r0, #(MAX_ERRNO + 1)
     bxls    lr
     neg     r0, r0
diff --git a/libc/arch-arm/syscalls/init_module.S b/libc/arch-arm/syscalls/init_module.S
index 8251533..8fecf68 100644
--- a/libc/arch-arm/syscalls/init_module.S
+++ b/libc/arch-arm/syscalls/init_module.S
@@ -4,9 +4,11 @@
 
 ENTRY(init_module)
     mov     ip, r7
+    .cfi_register r7, ip
     ldr     r7, =__NR_init_module
     swi     #0
     mov     r7, ip
+    .cfi_restore r7
     cmn     r0, #(MAX_ERRNO + 1)
     bxls    lr
     neg     r0, r0
diff --git a/libc/arch-arm/syscalls/inotify_add_watch.S b/libc/arch-arm/syscalls/inotify_add_watch.S
index b945bd1..61e666c 100644
--- a/libc/arch-arm/syscalls/inotify_add_watch.S
+++ b/libc/arch-arm/syscalls/inotify_add_watch.S
@@ -4,9 +4,11 @@
 
 ENTRY(inotify_add_watch)
     mov     ip, r7
+    .cfi_register r7, ip
     ldr     r7, =__NR_inotify_add_watch
     swi     #0
     mov     r7, ip
+    .cfi_restore r7
     cmn     r0, #(MAX_ERRNO + 1)
     bxls    lr
     neg     r0, r0
diff --git a/libc/arch-arm/syscalls/inotify_init1.S b/libc/arch-arm/syscalls/inotify_init1.S
index 32090de..6cf066e 100644
--- a/libc/arch-arm/syscalls/inotify_init1.S
+++ b/libc/arch-arm/syscalls/inotify_init1.S
@@ -4,9 +4,11 @@
 
 ENTRY(inotify_init1)
     mov     ip, r7
+    .cfi_register r7, ip
     ldr     r7, =__NR_inotify_init1
     swi     #0
     mov     r7, ip
+    .cfi_restore r7
     cmn     r0, #(MAX_ERRNO + 1)
     bxls    lr
     neg     r0, r0
diff --git a/libc/arch-arm/syscalls/inotify_rm_watch.S b/libc/arch-arm/syscalls/inotify_rm_watch.S
index e8230e2..1455da1 100644
--- a/libc/arch-arm/syscalls/inotify_rm_watch.S
+++ b/libc/arch-arm/syscalls/inotify_rm_watch.S
@@ -4,9 +4,11 @@
 
 ENTRY(inotify_rm_watch)
     mov     ip, r7
+    .cfi_register r7, ip
     ldr     r7, =__NR_inotify_rm_watch
     swi     #0
     mov     r7, ip
+    .cfi_restore r7
     cmn     r0, #(MAX_ERRNO + 1)
     bxls    lr
     neg     r0, r0
diff --git a/libc/arch-arm/syscalls/kill.S b/libc/arch-arm/syscalls/kill.S
index 0b5f4a4..82df861 100644
--- a/libc/arch-arm/syscalls/kill.S
+++ b/libc/arch-arm/syscalls/kill.S
@@ -4,9 +4,11 @@
 
 ENTRY(kill)
     mov     ip, r7
+    .cfi_register r7, ip
     ldr     r7, =__NR_kill
     swi     #0
     mov     r7, ip
+    .cfi_restore r7
     cmn     r0, #(MAX_ERRNO + 1)
     bxls    lr
     neg     r0, r0
diff --git a/libc/arch-arm/syscalls/klogctl.S b/libc/arch-arm/syscalls/klogctl.S
index b76b2b5..47a03c6 100644
--- a/libc/arch-arm/syscalls/klogctl.S
+++ b/libc/arch-arm/syscalls/klogctl.S
@@ -4,9 +4,11 @@
 
 ENTRY(klogctl)
     mov     ip, r7
+    .cfi_register r7, ip
     ldr     r7, =__NR_syslog
     swi     #0
     mov     r7, ip
+    .cfi_restore r7
     cmn     r0, #(MAX_ERRNO + 1)
     bxls    lr
     neg     r0, r0
diff --git a/libc/arch-arm/syscalls/lgetxattr.S b/libc/arch-arm/syscalls/lgetxattr.S
index b033a9a..157271c 100644
--- a/libc/arch-arm/syscalls/lgetxattr.S
+++ b/libc/arch-arm/syscalls/lgetxattr.S
@@ -4,9 +4,11 @@
 
 ENTRY(lgetxattr)
     mov     ip, r7
+    .cfi_register r7, ip
     ldr     r7, =__NR_lgetxattr
     swi     #0
     mov     r7, ip
+    .cfi_restore r7
     cmn     r0, #(MAX_ERRNO + 1)
     bxls    lr
     neg     r0, r0
diff --git a/libc/arch-arm/syscalls/listen.S b/libc/arch-arm/syscalls/listen.S
index 3aaa801..5ad75c0 100644
--- a/libc/arch-arm/syscalls/listen.S
+++ b/libc/arch-arm/syscalls/listen.S
@@ -4,9 +4,11 @@
 
 ENTRY(listen)
     mov     ip, r7
+    .cfi_register r7, ip
     ldr     r7, =__NR_listen
     swi     #0
     mov     r7, ip
+    .cfi_restore r7
     cmn     r0, #(MAX_ERRNO + 1)
     bxls    lr
     neg     r0, r0
diff --git a/libc/arch-arm/syscalls/listxattr.S b/libc/arch-arm/syscalls/listxattr.S
index 51ff267..093927d 100644
--- a/libc/arch-arm/syscalls/listxattr.S
+++ b/libc/arch-arm/syscalls/listxattr.S
@@ -4,9 +4,11 @@
 
 ENTRY(listxattr)
     mov     ip, r7
+    .cfi_register r7, ip
     ldr     r7, =__NR_listxattr
     swi     #0
     mov     r7, ip
+    .cfi_restore r7
     cmn     r0, #(MAX_ERRNO + 1)
     bxls    lr
     neg     r0, r0
diff --git a/libc/arch-arm/syscalls/llistxattr.S b/libc/arch-arm/syscalls/llistxattr.S
index 46e8116..5d0e7c8 100644
--- a/libc/arch-arm/syscalls/llistxattr.S
+++ b/libc/arch-arm/syscalls/llistxattr.S
@@ -4,9 +4,11 @@
 
 ENTRY(llistxattr)
     mov     ip, r7
+    .cfi_register r7, ip
     ldr     r7, =__NR_llistxattr
     swi     #0
     mov     r7, ip
+    .cfi_restore r7
     cmn     r0, #(MAX_ERRNO + 1)
     bxls    lr
     neg     r0, r0
diff --git a/libc/arch-arm/syscalls/lremovexattr.S b/libc/arch-arm/syscalls/lremovexattr.S
index a945062..4e0bcec 100644
--- a/libc/arch-arm/syscalls/lremovexattr.S
+++ b/libc/arch-arm/syscalls/lremovexattr.S
@@ -4,9 +4,11 @@
 
 ENTRY(lremovexattr)
     mov     ip, r7
+    .cfi_register r7, ip
     ldr     r7, =__NR_lremovexattr
     swi     #0
     mov     r7, ip
+    .cfi_restore r7
     cmn     r0, #(MAX_ERRNO + 1)
     bxls    lr
     neg     r0, r0
diff --git a/libc/arch-arm/syscalls/lseek.S b/libc/arch-arm/syscalls/lseek.S
index 00aeab3..cbdc441 100644
--- a/libc/arch-arm/syscalls/lseek.S
+++ b/libc/arch-arm/syscalls/lseek.S
@@ -4,9 +4,11 @@
 
 ENTRY(lseek)
     mov     ip, r7
+    .cfi_register r7, ip
     ldr     r7, =__NR_lseek
     swi     #0
     mov     r7, ip
+    .cfi_restore r7
     cmn     r0, #(MAX_ERRNO + 1)
     bxls    lr
     neg     r0, r0
diff --git a/libc/arch-arm/syscalls/madvise.S b/libc/arch-arm/syscalls/madvise.S
index 4d3cdcd..c2d7d20 100644
--- a/libc/arch-arm/syscalls/madvise.S
+++ b/libc/arch-arm/syscalls/madvise.S
@@ -4,9 +4,11 @@
 
 ENTRY(madvise)
     mov     ip, r7
+    .cfi_register r7, ip
     ldr     r7, =__NR_madvise
     swi     #0
     mov     r7, ip
+    .cfi_restore r7
     cmn     r0, #(MAX_ERRNO + 1)
     bxls    lr
     neg     r0, r0
diff --git a/libc/arch-arm/syscalls/mincore.S b/libc/arch-arm/syscalls/mincore.S
index f1154d0..c93fe94 100644
--- a/libc/arch-arm/syscalls/mincore.S
+++ b/libc/arch-arm/syscalls/mincore.S
@@ -4,9 +4,11 @@
 
 ENTRY(mincore)
     mov     ip, r7
+    .cfi_register r7, ip
     ldr     r7, =__NR_mincore
     swi     #0
     mov     r7, ip
+    .cfi_restore r7
     cmn     r0, #(MAX_ERRNO + 1)
     bxls    lr
     neg     r0, r0
diff --git a/libc/arch-arm/syscalls/mkdirat.S b/libc/arch-arm/syscalls/mkdirat.S
index 1f8957b..4f93c61 100644
--- a/libc/arch-arm/syscalls/mkdirat.S
+++ b/libc/arch-arm/syscalls/mkdirat.S
@@ -4,9 +4,11 @@
 
 ENTRY(mkdirat)
     mov     ip, r7
+    .cfi_register r7, ip
     ldr     r7, =__NR_mkdirat
     swi     #0
     mov     r7, ip
+    .cfi_restore r7
     cmn     r0, #(MAX_ERRNO + 1)
     bxls    lr
     neg     r0, r0
diff --git a/libc/arch-arm/syscalls/mknodat.S b/libc/arch-arm/syscalls/mknodat.S
index 1a2bf6f..91baae8 100644
--- a/libc/arch-arm/syscalls/mknodat.S
+++ b/libc/arch-arm/syscalls/mknodat.S
@@ -4,9 +4,11 @@
 
 ENTRY(mknodat)
     mov     ip, r7
+    .cfi_register r7, ip
     ldr     r7, =__NR_mknodat
     swi     #0
     mov     r7, ip
+    .cfi_restore r7
     cmn     r0, #(MAX_ERRNO + 1)
     bxls    lr
     neg     r0, r0
diff --git a/libc/arch-arm/syscalls/mlock.S b/libc/arch-arm/syscalls/mlock.S
index 8a4fc7a..eb72f6f 100644
--- a/libc/arch-arm/syscalls/mlock.S
+++ b/libc/arch-arm/syscalls/mlock.S
@@ -4,9 +4,11 @@
 
 ENTRY(mlock)
     mov     ip, r7
+    .cfi_register r7, ip
     ldr     r7, =__NR_mlock
     swi     #0
     mov     r7, ip
+    .cfi_restore r7
     cmn     r0, #(MAX_ERRNO + 1)
     bxls    lr
     neg     r0, r0
diff --git a/libc/arch-arm/syscalls/mlockall.S b/libc/arch-arm/syscalls/mlockall.S
index b49ca05..2984087 100644
--- a/libc/arch-arm/syscalls/mlockall.S
+++ b/libc/arch-arm/syscalls/mlockall.S
@@ -4,9 +4,11 @@
 
 ENTRY(mlockall)
     mov     ip, r7
+    .cfi_register r7, ip
     ldr     r7, =__NR_mlockall
     swi     #0
     mov     r7, ip
+    .cfi_restore r7
     cmn     r0, #(MAX_ERRNO + 1)
     bxls    lr
     neg     r0, r0
diff --git a/libc/arch-arm/syscalls/mprotect.S b/libc/arch-arm/syscalls/mprotect.S
index cb51306..9bb1282 100644
--- a/libc/arch-arm/syscalls/mprotect.S
+++ b/libc/arch-arm/syscalls/mprotect.S
@@ -4,9 +4,11 @@
 
 ENTRY(mprotect)
     mov     ip, r7
+    .cfi_register r7, ip
     ldr     r7, =__NR_mprotect
     swi     #0
     mov     r7, ip
+    .cfi_restore r7
     cmn     r0, #(MAX_ERRNO + 1)
     bxls    lr
     neg     r0, r0
diff --git a/libc/arch-arm/syscalls/mremap.S b/libc/arch-arm/syscalls/mremap.S
deleted file mode 100644
index 505ea3c..0000000
--- a/libc/arch-arm/syscalls/mremap.S
+++ /dev/null
@@ -1,14 +0,0 @@
-/* Generated by gensyscalls.py. Do not edit. */
-
-#include <private/bionic_asm.h>
-
-ENTRY(mremap)
-    mov     ip, r7
-    ldr     r7, =__NR_mremap
-    swi     #0
-    mov     r7, ip
-    cmn     r0, #(MAX_ERRNO + 1)
-    bxls    lr
-    neg     r0, r0
-    b       __set_errno_internal
-END(mremap)
diff --git a/libc/arch-arm/syscalls/msync.S b/libc/arch-arm/syscalls/msync.S
index 220fb4d..bcbab04 100644
--- a/libc/arch-arm/syscalls/msync.S
+++ b/libc/arch-arm/syscalls/msync.S
@@ -4,9 +4,11 @@
 
 ENTRY(msync)
     mov     ip, r7
+    .cfi_register r7, ip
     ldr     r7, =__NR_msync
     swi     #0
     mov     r7, ip
+    .cfi_restore r7
     cmn     r0, #(MAX_ERRNO + 1)
     bxls    lr
     neg     r0, r0
diff --git a/libc/arch-arm/syscalls/munlock.S b/libc/arch-arm/syscalls/munlock.S
index 05bf941..bf1b814 100644
--- a/libc/arch-arm/syscalls/munlock.S
+++ b/libc/arch-arm/syscalls/munlock.S
@@ -4,9 +4,11 @@
 
 ENTRY(munlock)
     mov     ip, r7
+    .cfi_register r7, ip
     ldr     r7, =__NR_munlock
     swi     #0
     mov     r7, ip
+    .cfi_restore r7
     cmn     r0, #(MAX_ERRNO + 1)
     bxls    lr
     neg     r0, r0
diff --git a/libc/arch-arm/syscalls/munlockall.S b/libc/arch-arm/syscalls/munlockall.S
index e2c5dd5..b45a5a2 100644
--- a/libc/arch-arm/syscalls/munlockall.S
+++ b/libc/arch-arm/syscalls/munlockall.S
@@ -4,9 +4,11 @@
 
 ENTRY(munlockall)
     mov     ip, r7
+    .cfi_register r7, ip
     ldr     r7, =__NR_munlockall
     swi     #0
     mov     r7, ip
+    .cfi_restore r7
     cmn     r0, #(MAX_ERRNO + 1)
     bxls    lr
     neg     r0, r0
diff --git a/libc/arch-arm/syscalls/munmap.S b/libc/arch-arm/syscalls/munmap.S
index 740c360..2b7a121 100644
--- a/libc/arch-arm/syscalls/munmap.S
+++ b/libc/arch-arm/syscalls/munmap.S
@@ -4,9 +4,11 @@
 
 ENTRY(munmap)
     mov     ip, r7
+    .cfi_register r7, ip
     ldr     r7, =__NR_munmap
     swi     #0
     mov     r7, ip
+    .cfi_restore r7
     cmn     r0, #(MAX_ERRNO + 1)
     bxls    lr
     neg     r0, r0
diff --git a/libc/arch-arm/syscalls/nanosleep.S b/libc/arch-arm/syscalls/nanosleep.S
index fcd6e90..83fd323 100644
--- a/libc/arch-arm/syscalls/nanosleep.S
+++ b/libc/arch-arm/syscalls/nanosleep.S
@@ -4,9 +4,11 @@
 
 ENTRY(nanosleep)
     mov     ip, r7
+    .cfi_register r7, ip
     ldr     r7, =__NR_nanosleep
     swi     #0
     mov     r7, ip
+    .cfi_restore r7
     cmn     r0, #(MAX_ERRNO + 1)
     bxls    lr
     neg     r0, r0
diff --git a/libc/arch-arm/syscalls/personality.S b/libc/arch-arm/syscalls/personality.S
index d43d763..5ad6132 100644
--- a/libc/arch-arm/syscalls/personality.S
+++ b/libc/arch-arm/syscalls/personality.S
@@ -4,9 +4,11 @@
 
 ENTRY(personality)
     mov     ip, r7
+    .cfi_register r7, ip
     ldr     r7, =__NR_personality
     swi     #0
     mov     r7, ip
+    .cfi_restore r7
     cmn     r0, #(MAX_ERRNO + 1)
     bxls    lr
     neg     r0, r0
diff --git a/libc/arch-arm/syscalls/pipe2.S b/libc/arch-arm/syscalls/pipe2.S
index 1cbdfb2..f543f9d 100644
--- a/libc/arch-arm/syscalls/pipe2.S
+++ b/libc/arch-arm/syscalls/pipe2.S
@@ -4,9 +4,11 @@
 
 ENTRY(pipe2)
     mov     ip, r7
+    .cfi_register r7, ip
     ldr     r7, =__NR_pipe2
     swi     #0
     mov     r7, ip
+    .cfi_restore r7
     cmn     r0, #(MAX_ERRNO + 1)
     bxls    lr
     neg     r0, r0
diff --git a/libc/arch-arm/syscalls/prlimit64.S b/libc/arch-arm/syscalls/prlimit64.S
index 3ae9e1b..0f04aaa 100644
--- a/libc/arch-arm/syscalls/prlimit64.S
+++ b/libc/arch-arm/syscalls/prlimit64.S
@@ -4,9 +4,11 @@
 
 ENTRY(prlimit64)
     mov     ip, r7
+    .cfi_register r7, ip
     ldr     r7, =__NR_prlimit64
     swi     #0
     mov     r7, ip
+    .cfi_restore r7
     cmn     r0, #(MAX_ERRNO + 1)
     bxls    lr
     neg     r0, r0
diff --git a/libc/arch-arm/syscalls/read.S b/libc/arch-arm/syscalls/read.S
index 1c3b395..5051358 100644
--- a/libc/arch-arm/syscalls/read.S
+++ b/libc/arch-arm/syscalls/read.S
@@ -4,9 +4,11 @@
 
 ENTRY(read)
     mov     ip, r7
+    .cfi_register r7, ip
     ldr     r7, =__NR_read
     swi     #0
     mov     r7, ip
+    .cfi_restore r7
     cmn     r0, #(MAX_ERRNO + 1)
     bxls    lr
     neg     r0, r0
diff --git a/libc/arch-arm/syscalls/readlinkat.S b/libc/arch-arm/syscalls/readlinkat.S
index e7cc8ff..36d46fa 100644
--- a/libc/arch-arm/syscalls/readlinkat.S
+++ b/libc/arch-arm/syscalls/readlinkat.S
@@ -4,9 +4,11 @@
 
 ENTRY(readlinkat)
     mov     ip, r7
+    .cfi_register r7, ip
     ldr     r7, =__NR_readlinkat
     swi     #0
     mov     r7, ip
+    .cfi_restore r7
     cmn     r0, #(MAX_ERRNO + 1)
     bxls    lr
     neg     r0, r0
diff --git a/libc/arch-arm/syscalls/readv.S b/libc/arch-arm/syscalls/readv.S
index c7807bd..565af6a 100644
--- a/libc/arch-arm/syscalls/readv.S
+++ b/libc/arch-arm/syscalls/readv.S
@@ -4,9 +4,11 @@
 
 ENTRY(readv)
     mov     ip, r7
+    .cfi_register r7, ip
     ldr     r7, =__NR_readv
     swi     #0
     mov     r7, ip
+    .cfi_restore r7
     cmn     r0, #(MAX_ERRNO + 1)
     bxls    lr
     neg     r0, r0
diff --git a/libc/arch-arm/syscalls/recvmsg.S b/libc/arch-arm/syscalls/recvmsg.S
index 995a9e3..19a9fca 100644
--- a/libc/arch-arm/syscalls/recvmsg.S
+++ b/libc/arch-arm/syscalls/recvmsg.S
@@ -4,9 +4,11 @@
 
 ENTRY(recvmsg)
     mov     ip, r7
+    .cfi_register r7, ip
     ldr     r7, =__NR_recvmsg
     swi     #0
     mov     r7, ip
+    .cfi_restore r7
     cmn     r0, #(MAX_ERRNO + 1)
     bxls    lr
     neg     r0, r0
diff --git a/libc/arch-arm/syscalls/removexattr.S b/libc/arch-arm/syscalls/removexattr.S
index 3a32e5c..46f847d 100644
--- a/libc/arch-arm/syscalls/removexattr.S
+++ b/libc/arch-arm/syscalls/removexattr.S
@@ -4,9 +4,11 @@
 
 ENTRY(removexattr)
     mov     ip, r7
+    .cfi_register r7, ip
     ldr     r7, =__NR_removexattr
     swi     #0
     mov     r7, ip
+    .cfi_restore r7
     cmn     r0, #(MAX_ERRNO + 1)
     bxls    lr
     neg     r0, r0
diff --git a/libc/arch-arm/syscalls/renameat.S b/libc/arch-arm/syscalls/renameat.S
index 98e86dc..89fc513 100644
--- a/libc/arch-arm/syscalls/renameat.S
+++ b/libc/arch-arm/syscalls/renameat.S
@@ -4,9 +4,11 @@
 
 ENTRY(renameat)
     mov     ip, r7
+    .cfi_register r7, ip
     ldr     r7, =__NR_renameat
     swi     #0
     mov     r7, ip
+    .cfi_restore r7
     cmn     r0, #(MAX_ERRNO + 1)
     bxls    lr
     neg     r0, r0
diff --git a/libc/arch-arm/syscalls/sched_get_priority_max.S b/libc/arch-arm/syscalls/sched_get_priority_max.S
index 187e680..23b1d62 100644
--- a/libc/arch-arm/syscalls/sched_get_priority_max.S
+++ b/libc/arch-arm/syscalls/sched_get_priority_max.S
@@ -4,9 +4,11 @@
 
 ENTRY(sched_get_priority_max)
     mov     ip, r7
+    .cfi_register r7, ip
     ldr     r7, =__NR_sched_get_priority_max
     swi     #0
     mov     r7, ip
+    .cfi_restore r7
     cmn     r0, #(MAX_ERRNO + 1)
     bxls    lr
     neg     r0, r0
diff --git a/libc/arch-arm/syscalls/sched_get_priority_min.S b/libc/arch-arm/syscalls/sched_get_priority_min.S
index 68bf7df..65a967c 100644
--- a/libc/arch-arm/syscalls/sched_get_priority_min.S
+++ b/libc/arch-arm/syscalls/sched_get_priority_min.S
@@ -4,9 +4,11 @@
 
 ENTRY(sched_get_priority_min)
     mov     ip, r7
+    .cfi_register r7, ip
     ldr     r7, =__NR_sched_get_priority_min
     swi     #0
     mov     r7, ip
+    .cfi_restore r7
     cmn     r0, #(MAX_ERRNO + 1)
     bxls    lr
     neg     r0, r0
diff --git a/libc/arch-arm/syscalls/sched_getparam.S b/libc/arch-arm/syscalls/sched_getparam.S
index 32b97b8..700041e 100644
--- a/libc/arch-arm/syscalls/sched_getparam.S
+++ b/libc/arch-arm/syscalls/sched_getparam.S
@@ -4,9 +4,11 @@
 
 ENTRY(sched_getparam)
     mov     ip, r7
+    .cfi_register r7, ip
     ldr     r7, =__NR_sched_getparam
     swi     #0
     mov     r7, ip
+    .cfi_restore r7
     cmn     r0, #(MAX_ERRNO + 1)
     bxls    lr
     neg     r0, r0
diff --git a/libc/arch-arm/syscalls/sched_getscheduler.S b/libc/arch-arm/syscalls/sched_getscheduler.S
index 330c208..b4f5d13 100644
--- a/libc/arch-arm/syscalls/sched_getscheduler.S
+++ b/libc/arch-arm/syscalls/sched_getscheduler.S
@@ -4,9 +4,11 @@
 
 ENTRY(sched_getscheduler)
     mov     ip, r7
+    .cfi_register r7, ip
     ldr     r7, =__NR_sched_getscheduler
     swi     #0
     mov     r7, ip
+    .cfi_restore r7
     cmn     r0, #(MAX_ERRNO + 1)
     bxls    lr
     neg     r0, r0
diff --git a/libc/arch-arm/syscalls/sched_rr_get_interval.S b/libc/arch-arm/syscalls/sched_rr_get_interval.S
index 5d176ac..ea30b62 100644
--- a/libc/arch-arm/syscalls/sched_rr_get_interval.S
+++ b/libc/arch-arm/syscalls/sched_rr_get_interval.S
@@ -4,9 +4,11 @@
 
 ENTRY(sched_rr_get_interval)
     mov     ip, r7
+    .cfi_register r7, ip
     ldr     r7, =__NR_sched_rr_get_interval
     swi     #0
     mov     r7, ip
+    .cfi_restore r7
     cmn     r0, #(MAX_ERRNO + 1)
     bxls    lr
     neg     r0, r0
diff --git a/libc/arch-arm/syscalls/sched_setaffinity.S b/libc/arch-arm/syscalls/sched_setaffinity.S
index 6653471..636845b 100644
--- a/libc/arch-arm/syscalls/sched_setaffinity.S
+++ b/libc/arch-arm/syscalls/sched_setaffinity.S
@@ -4,9 +4,11 @@
 
 ENTRY(sched_setaffinity)
     mov     ip, r7
+    .cfi_register r7, ip
     ldr     r7, =__NR_sched_setaffinity
     swi     #0
     mov     r7, ip
+    .cfi_restore r7
     cmn     r0, #(MAX_ERRNO + 1)
     bxls    lr
     neg     r0, r0
diff --git a/libc/arch-arm/syscalls/sched_setparam.S b/libc/arch-arm/syscalls/sched_setparam.S
index 16e1997..f24b96e 100644
--- a/libc/arch-arm/syscalls/sched_setparam.S
+++ b/libc/arch-arm/syscalls/sched_setparam.S
@@ -4,9 +4,11 @@
 
 ENTRY(sched_setparam)
     mov     ip, r7
+    .cfi_register r7, ip
     ldr     r7, =__NR_sched_setparam
     swi     #0
     mov     r7, ip
+    .cfi_restore r7
     cmn     r0, #(MAX_ERRNO + 1)
     bxls    lr
     neg     r0, r0
diff --git a/libc/arch-arm/syscalls/sched_setscheduler.S b/libc/arch-arm/syscalls/sched_setscheduler.S
index 2ec9fec..5bfa202 100644
--- a/libc/arch-arm/syscalls/sched_setscheduler.S
+++ b/libc/arch-arm/syscalls/sched_setscheduler.S
@@ -4,9 +4,11 @@
 
 ENTRY(sched_setscheduler)
     mov     ip, r7
+    .cfi_register r7, ip
     ldr     r7, =__NR_sched_setscheduler
     swi     #0
     mov     r7, ip
+    .cfi_restore r7
     cmn     r0, #(MAX_ERRNO + 1)
     bxls    lr
     neg     r0, r0
diff --git a/libc/arch-arm/syscalls/sched_yield.S b/libc/arch-arm/syscalls/sched_yield.S
index 1ec328f..7b93a6e 100644
--- a/libc/arch-arm/syscalls/sched_yield.S
+++ b/libc/arch-arm/syscalls/sched_yield.S
@@ -4,9 +4,11 @@
 
 ENTRY(sched_yield)
     mov     ip, r7
+    .cfi_register r7, ip
     ldr     r7, =__NR_sched_yield
     swi     #0
     mov     r7, ip
+    .cfi_restore r7
     cmn     r0, #(MAX_ERRNO + 1)
     bxls    lr
     neg     r0, r0
diff --git a/libc/arch-arm/syscalls/sendfile.S b/libc/arch-arm/syscalls/sendfile.S
index afae021..52e78d0 100644
--- a/libc/arch-arm/syscalls/sendfile.S
+++ b/libc/arch-arm/syscalls/sendfile.S
@@ -4,9 +4,11 @@
 
 ENTRY(sendfile)
     mov     ip, r7
+    .cfi_register r7, ip
     ldr     r7, =__NR_sendfile
     swi     #0
     mov     r7, ip
+    .cfi_restore r7
     cmn     r0, #(MAX_ERRNO + 1)
     bxls    lr
     neg     r0, r0
diff --git a/libc/arch-arm/syscalls/sendfile64.S b/libc/arch-arm/syscalls/sendfile64.S
index d0ad0b8..416e9d2 100644
--- a/libc/arch-arm/syscalls/sendfile64.S
+++ b/libc/arch-arm/syscalls/sendfile64.S
@@ -4,9 +4,11 @@
 
 ENTRY(sendfile64)
     mov     ip, r7
+    .cfi_register r7, ip
     ldr     r7, =__NR_sendfile64
     swi     #0
     mov     r7, ip
+    .cfi_restore r7
     cmn     r0, #(MAX_ERRNO + 1)
     bxls    lr
     neg     r0, r0
diff --git a/libc/arch-arm/syscalls/sendmmsg.S b/libc/arch-arm/syscalls/sendmmsg.S
index 8bb5f80..f97d264 100644
--- a/libc/arch-arm/syscalls/sendmmsg.S
+++ b/libc/arch-arm/syscalls/sendmmsg.S
@@ -4,9 +4,11 @@
 
 ENTRY(sendmmsg)
     mov     ip, r7
+    .cfi_register r7, ip
     ldr     r7, =__NR_sendmmsg
     swi     #0
     mov     r7, ip
+    .cfi_restore r7
     cmn     r0, #(MAX_ERRNO + 1)
     bxls    lr
     neg     r0, r0
diff --git a/libc/arch-arm/syscalls/sendmsg.S b/libc/arch-arm/syscalls/sendmsg.S
index fd38140..215219a 100644
--- a/libc/arch-arm/syscalls/sendmsg.S
+++ b/libc/arch-arm/syscalls/sendmsg.S
@@ -4,9 +4,11 @@
 
 ENTRY(sendmsg)
     mov     ip, r7
+    .cfi_register r7, ip
     ldr     r7, =__NR_sendmsg
     swi     #0
     mov     r7, ip
+    .cfi_restore r7
     cmn     r0, #(MAX_ERRNO + 1)
     bxls    lr
     neg     r0, r0
diff --git a/libc/arch-arm/syscalls/setfsgid.S b/libc/arch-arm/syscalls/setfsgid.S
index f677a94..2f0f08c 100644
--- a/libc/arch-arm/syscalls/setfsgid.S
+++ b/libc/arch-arm/syscalls/setfsgid.S
@@ -4,9 +4,11 @@
 
 ENTRY(setfsgid)
     mov     ip, r7
+    .cfi_register r7, ip
     ldr     r7, =__NR_setfsgid
     swi     #0
     mov     r7, ip
+    .cfi_restore r7
     cmn     r0, #(MAX_ERRNO + 1)
     bxls    lr
     neg     r0, r0
diff --git a/libc/arch-arm/syscalls/setfsuid.S b/libc/arch-arm/syscalls/setfsuid.S
index 5d27a4d..ce663e0 100644
--- a/libc/arch-arm/syscalls/setfsuid.S
+++ b/libc/arch-arm/syscalls/setfsuid.S
@@ -4,9 +4,11 @@
 
 ENTRY(setfsuid)
     mov     ip, r7
+    .cfi_register r7, ip
     ldr     r7, =__NR_setfsuid
     swi     #0
     mov     r7, ip
+    .cfi_restore r7
     cmn     r0, #(MAX_ERRNO + 1)
     bxls    lr
     neg     r0, r0
diff --git a/libc/arch-arm/syscalls/setgid.S b/libc/arch-arm/syscalls/setgid.S
index d9b2b88..6f1cbed 100644
--- a/libc/arch-arm/syscalls/setgid.S
+++ b/libc/arch-arm/syscalls/setgid.S
@@ -4,9 +4,11 @@
 
 ENTRY(setgid)
     mov     ip, r7
+    .cfi_register r7, ip
     ldr     r7, =__NR_setgid32
     swi     #0
     mov     r7, ip
+    .cfi_restore r7
     cmn     r0, #(MAX_ERRNO + 1)
     bxls    lr
     neg     r0, r0
diff --git a/libc/arch-arm/syscalls/setgroups.S b/libc/arch-arm/syscalls/setgroups.S
index 169de73..1fb494c 100644
--- a/libc/arch-arm/syscalls/setgroups.S
+++ b/libc/arch-arm/syscalls/setgroups.S
@@ -4,9 +4,11 @@
 
 ENTRY(setgroups)
     mov     ip, r7
+    .cfi_register r7, ip
     ldr     r7, =__NR_setgroups32
     swi     #0
     mov     r7, ip
+    .cfi_restore r7
     cmn     r0, #(MAX_ERRNO + 1)
     bxls    lr
     neg     r0, r0
diff --git a/libc/arch-arm/syscalls/sethostname.S b/libc/arch-arm/syscalls/sethostname.S
index 0a98fd3..c4c2db5 100644
--- a/libc/arch-arm/syscalls/sethostname.S
+++ b/libc/arch-arm/syscalls/sethostname.S
@@ -4,9 +4,11 @@
 
 ENTRY(sethostname)
     mov     ip, r7
+    .cfi_register r7, ip
     ldr     r7, =__NR_sethostname
     swi     #0
     mov     r7, ip
+    .cfi_restore r7
     cmn     r0, #(MAX_ERRNO + 1)
     bxls    lr
     neg     r0, r0
diff --git a/libc/arch-arm/syscalls/setitimer.S b/libc/arch-arm/syscalls/setitimer.S
index 31b277b..511a5d1 100644
--- a/libc/arch-arm/syscalls/setitimer.S
+++ b/libc/arch-arm/syscalls/setitimer.S
@@ -4,9 +4,11 @@
 
 ENTRY(setitimer)
     mov     ip, r7
+    .cfi_register r7, ip
     ldr     r7, =__NR_setitimer
     swi     #0
     mov     r7, ip
+    .cfi_restore r7
     cmn     r0, #(MAX_ERRNO + 1)
     bxls    lr
     neg     r0, r0
diff --git a/libc/arch-arm/syscalls/setns.S b/libc/arch-arm/syscalls/setns.S
index 59203ef..b1902dc 100644
--- a/libc/arch-arm/syscalls/setns.S
+++ b/libc/arch-arm/syscalls/setns.S
@@ -4,9 +4,11 @@
 
 ENTRY(setns)
     mov     ip, r7
+    .cfi_register r7, ip
     ldr     r7, =__NR_setns
     swi     #0
     mov     r7, ip
+    .cfi_restore r7
     cmn     r0, #(MAX_ERRNO + 1)
     bxls    lr
     neg     r0, r0
diff --git a/libc/arch-arm/syscalls/setpgid.S b/libc/arch-arm/syscalls/setpgid.S
index 4a91520..fe05fc9 100644
--- a/libc/arch-arm/syscalls/setpgid.S
+++ b/libc/arch-arm/syscalls/setpgid.S
@@ -4,9 +4,11 @@
 
 ENTRY(setpgid)
     mov     ip, r7
+    .cfi_register r7, ip
     ldr     r7, =__NR_setpgid
     swi     #0
     mov     r7, ip
+    .cfi_restore r7
     cmn     r0, #(MAX_ERRNO + 1)
     bxls    lr
     neg     r0, r0
diff --git a/libc/arch-arm/syscalls/setpriority.S b/libc/arch-arm/syscalls/setpriority.S
index 2053ce1..960eee0 100644
--- a/libc/arch-arm/syscalls/setpriority.S
+++ b/libc/arch-arm/syscalls/setpriority.S
@@ -4,9 +4,11 @@
 
 ENTRY(setpriority)
     mov     ip, r7
+    .cfi_register r7, ip
     ldr     r7, =__NR_setpriority
     swi     #0
     mov     r7, ip
+    .cfi_restore r7
     cmn     r0, #(MAX_ERRNO + 1)
     bxls    lr
     neg     r0, r0
diff --git a/libc/arch-arm/syscalls/setregid.S b/libc/arch-arm/syscalls/setregid.S
index f1bdc60..0b5f444 100644
--- a/libc/arch-arm/syscalls/setregid.S
+++ b/libc/arch-arm/syscalls/setregid.S
@@ -4,9 +4,11 @@
 
 ENTRY(setregid)
     mov     ip, r7
+    .cfi_register r7, ip
     ldr     r7, =__NR_setregid32
     swi     #0
     mov     r7, ip
+    .cfi_restore r7
     cmn     r0, #(MAX_ERRNO + 1)
     bxls    lr
     neg     r0, r0
diff --git a/libc/arch-arm/syscalls/setresgid.S b/libc/arch-arm/syscalls/setresgid.S
index 9b8968a..64677d3 100644
--- a/libc/arch-arm/syscalls/setresgid.S
+++ b/libc/arch-arm/syscalls/setresgid.S
@@ -4,9 +4,11 @@
 
 ENTRY(setresgid)
     mov     ip, r7
+    .cfi_register r7, ip
     ldr     r7, =__NR_setresgid32
     swi     #0
     mov     r7, ip
+    .cfi_restore r7
     cmn     r0, #(MAX_ERRNO + 1)
     bxls    lr
     neg     r0, r0
diff --git a/libc/arch-arm/syscalls/setresuid.S b/libc/arch-arm/syscalls/setresuid.S
index c26a955..e3888f6 100644
--- a/libc/arch-arm/syscalls/setresuid.S
+++ b/libc/arch-arm/syscalls/setresuid.S
@@ -4,9 +4,11 @@
 
 ENTRY(setresuid)
     mov     ip, r7
+    .cfi_register r7, ip
     ldr     r7, =__NR_setresuid32
     swi     #0
     mov     r7, ip
+    .cfi_restore r7
     cmn     r0, #(MAX_ERRNO + 1)
     bxls    lr
     neg     r0, r0
diff --git a/libc/arch-arm/syscalls/setreuid.S b/libc/arch-arm/syscalls/setreuid.S
index 796191a..15c2665 100644
--- a/libc/arch-arm/syscalls/setreuid.S
+++ b/libc/arch-arm/syscalls/setreuid.S
@@ -4,9 +4,11 @@
 
 ENTRY(setreuid)
     mov     ip, r7
+    .cfi_register r7, ip
     ldr     r7, =__NR_setreuid32
     swi     #0
     mov     r7, ip
+    .cfi_restore r7
     cmn     r0, #(MAX_ERRNO + 1)
     bxls    lr
     neg     r0, r0
diff --git a/libc/arch-arm/syscalls/setrlimit.S b/libc/arch-arm/syscalls/setrlimit.S
index c87b21b..b9014eb 100644
--- a/libc/arch-arm/syscalls/setrlimit.S
+++ b/libc/arch-arm/syscalls/setrlimit.S
@@ -4,9 +4,11 @@
 
 ENTRY(setrlimit)
     mov     ip, r7
+    .cfi_register r7, ip
     ldr     r7, =__NR_setrlimit
     swi     #0
     mov     r7, ip
+    .cfi_restore r7
     cmn     r0, #(MAX_ERRNO + 1)
     bxls    lr
     neg     r0, r0
diff --git a/libc/arch-arm/syscalls/setsid.S b/libc/arch-arm/syscalls/setsid.S
index 83bda1b..fb71474 100644
--- a/libc/arch-arm/syscalls/setsid.S
+++ b/libc/arch-arm/syscalls/setsid.S
@@ -4,9 +4,11 @@
 
 ENTRY(setsid)
     mov     ip, r7
+    .cfi_register r7, ip
     ldr     r7, =__NR_setsid
     swi     #0
     mov     r7, ip
+    .cfi_restore r7
     cmn     r0, #(MAX_ERRNO + 1)
     bxls    lr
     neg     r0, r0
diff --git a/libc/arch-arm/syscalls/settimeofday.S b/libc/arch-arm/syscalls/settimeofday.S
index 5763f40..00dfdeb 100644
--- a/libc/arch-arm/syscalls/settimeofday.S
+++ b/libc/arch-arm/syscalls/settimeofday.S
@@ -4,9 +4,11 @@
 
 ENTRY(settimeofday)
     mov     ip, r7
+    .cfi_register r7, ip
     ldr     r7, =__NR_settimeofday
     swi     #0
     mov     r7, ip
+    .cfi_restore r7
     cmn     r0, #(MAX_ERRNO + 1)
     bxls    lr
     neg     r0, r0
diff --git a/libc/arch-arm/syscalls/setuid.S b/libc/arch-arm/syscalls/setuid.S
index 55b349c..447ed1b 100644
--- a/libc/arch-arm/syscalls/setuid.S
+++ b/libc/arch-arm/syscalls/setuid.S
@@ -4,9 +4,11 @@
 
 ENTRY(setuid)
     mov     ip, r7
+    .cfi_register r7, ip
     ldr     r7, =__NR_setuid32
     swi     #0
     mov     r7, ip
+    .cfi_restore r7
     cmn     r0, #(MAX_ERRNO + 1)
     bxls    lr
     neg     r0, r0
diff --git a/libc/arch-arm/syscalls/shutdown.S b/libc/arch-arm/syscalls/shutdown.S
index 889934a..51ed0cf 100644
--- a/libc/arch-arm/syscalls/shutdown.S
+++ b/libc/arch-arm/syscalls/shutdown.S
@@ -4,9 +4,11 @@
 
 ENTRY(shutdown)
     mov     ip, r7
+    .cfi_register r7, ip
     ldr     r7, =__NR_shutdown
     swi     #0
     mov     r7, ip
+    .cfi_restore r7
     cmn     r0, #(MAX_ERRNO + 1)
     bxls    lr
     neg     r0, r0
diff --git a/libc/arch-arm/syscalls/sigaltstack.S b/libc/arch-arm/syscalls/sigaltstack.S
index b61b25d..2f97800 100644
--- a/libc/arch-arm/syscalls/sigaltstack.S
+++ b/libc/arch-arm/syscalls/sigaltstack.S
@@ -4,9 +4,11 @@
 
 ENTRY(sigaltstack)
     mov     ip, r7
+    .cfi_register r7, ip
     ldr     r7, =__NR_sigaltstack
     swi     #0
     mov     r7, ip
+    .cfi_restore r7
     cmn     r0, #(MAX_ERRNO + 1)
     bxls    lr
     neg     r0, r0
diff --git a/libc/arch-arm/syscalls/socketpair.S b/libc/arch-arm/syscalls/socketpair.S
index f3c8a4b..e537235 100644
--- a/libc/arch-arm/syscalls/socketpair.S
+++ b/libc/arch-arm/syscalls/socketpair.S
@@ -4,9 +4,11 @@
 
 ENTRY(socketpair)
     mov     ip, r7
+    .cfi_register r7, ip
     ldr     r7, =__NR_socketpair
     swi     #0
     mov     r7, ip
+    .cfi_restore r7
     cmn     r0, #(MAX_ERRNO + 1)
     bxls    lr
     neg     r0, r0
diff --git a/libc/arch-arm/syscalls/swapoff.S b/libc/arch-arm/syscalls/swapoff.S
index a7aaa82..25832ef 100644
--- a/libc/arch-arm/syscalls/swapoff.S
+++ b/libc/arch-arm/syscalls/swapoff.S
@@ -4,9 +4,11 @@
 
 ENTRY(swapoff)
     mov     ip, r7
+    .cfi_register r7, ip
     ldr     r7, =__NR_swapoff
     swi     #0
     mov     r7, ip
+    .cfi_restore r7
     cmn     r0, #(MAX_ERRNO + 1)
     bxls    lr
     neg     r0, r0
diff --git a/libc/arch-arm/syscalls/swapon.S b/libc/arch-arm/syscalls/swapon.S
index 6ea93c3..df4c71e 100644
--- a/libc/arch-arm/syscalls/swapon.S
+++ b/libc/arch-arm/syscalls/swapon.S
@@ -4,9 +4,11 @@
 
 ENTRY(swapon)
     mov     ip, r7
+    .cfi_register r7, ip
     ldr     r7, =__NR_swapon
     swi     #0
     mov     r7, ip
+    .cfi_restore r7
     cmn     r0, #(MAX_ERRNO + 1)
     bxls    lr
     neg     r0, r0
diff --git a/libc/arch-arm/syscalls/symlinkat.S b/libc/arch-arm/syscalls/symlinkat.S
index d330a54..ec2ee4f 100644
--- a/libc/arch-arm/syscalls/symlinkat.S
+++ b/libc/arch-arm/syscalls/symlinkat.S
@@ -4,9 +4,11 @@
 
 ENTRY(symlinkat)
     mov     ip, r7
+    .cfi_register r7, ip
     ldr     r7, =__NR_symlinkat
     swi     #0
     mov     r7, ip
+    .cfi_restore r7
     cmn     r0, #(MAX_ERRNO + 1)
     bxls    lr
     neg     r0, r0
diff --git a/libc/arch-arm/syscalls/sync.S b/libc/arch-arm/syscalls/sync.S
index 48ecfc0..b73dcaa 100644
--- a/libc/arch-arm/syscalls/sync.S
+++ b/libc/arch-arm/syscalls/sync.S
@@ -4,9 +4,11 @@
 
 ENTRY(sync)
     mov     ip, r7
+    .cfi_register r7, ip
     ldr     r7, =__NR_sync
     swi     #0
     mov     r7, ip
+    .cfi_restore r7
     cmn     r0, #(MAX_ERRNO + 1)
     bxls    lr
     neg     r0, r0
diff --git a/libc/arch-arm/syscalls/sysinfo.S b/libc/arch-arm/syscalls/sysinfo.S
index 709478e..1584ea4 100644
--- a/libc/arch-arm/syscalls/sysinfo.S
+++ b/libc/arch-arm/syscalls/sysinfo.S
@@ -4,9 +4,11 @@
 
 ENTRY(sysinfo)
     mov     ip, r7
+    .cfi_register r7, ip
     ldr     r7, =__NR_sysinfo
     swi     #0
     mov     r7, ip
+    .cfi_restore r7
     cmn     r0, #(MAX_ERRNO + 1)
     bxls    lr
     neg     r0, r0
diff --git a/libc/arch-arm/syscalls/tee.S b/libc/arch-arm/syscalls/tee.S
index a019c00..efd12ca 100644
--- a/libc/arch-arm/syscalls/tee.S
+++ b/libc/arch-arm/syscalls/tee.S
@@ -4,9 +4,11 @@
 
 ENTRY(tee)
     mov     ip, r7
+    .cfi_register r7, ip
     ldr     r7, =__NR_tee
     swi     #0
     mov     r7, ip
+    .cfi_restore r7
     cmn     r0, #(MAX_ERRNO + 1)
     bxls    lr
     neg     r0, r0
diff --git a/libc/arch-arm/syscalls/tgkill.S b/libc/arch-arm/syscalls/tgkill.S
index 2068465..43fe62c 100644
--- a/libc/arch-arm/syscalls/tgkill.S
+++ b/libc/arch-arm/syscalls/tgkill.S
@@ -4,9 +4,11 @@
 
 ENTRY(tgkill)
     mov     ip, r7
+    .cfi_register r7, ip
     ldr     r7, =__NR_tgkill
     swi     #0
     mov     r7, ip
+    .cfi_restore r7
     cmn     r0, #(MAX_ERRNO + 1)
     bxls    lr
     neg     r0, r0
diff --git a/libc/arch-arm/syscalls/timerfd_create.S b/libc/arch-arm/syscalls/timerfd_create.S
index 89a80cd..4aa3107 100644
--- a/libc/arch-arm/syscalls/timerfd_create.S
+++ b/libc/arch-arm/syscalls/timerfd_create.S
@@ -4,9 +4,11 @@
 
 ENTRY(timerfd_create)
     mov     ip, r7
+    .cfi_register r7, ip
     ldr     r7, =__NR_timerfd_create
     swi     #0
     mov     r7, ip
+    .cfi_restore r7
     cmn     r0, #(MAX_ERRNO + 1)
     bxls    lr
     neg     r0, r0
diff --git a/libc/arch-arm/syscalls/timerfd_gettime.S b/libc/arch-arm/syscalls/timerfd_gettime.S
index 4a7df76..6ae93e4 100644
--- a/libc/arch-arm/syscalls/timerfd_gettime.S
+++ b/libc/arch-arm/syscalls/timerfd_gettime.S
@@ -4,9 +4,11 @@
 
 ENTRY(timerfd_gettime)
     mov     ip, r7
+    .cfi_register r7, ip
     ldr     r7, =__NR_timerfd_gettime
     swi     #0
     mov     r7, ip
+    .cfi_restore r7
     cmn     r0, #(MAX_ERRNO + 1)
     bxls    lr
     neg     r0, r0
diff --git a/libc/arch-arm/syscalls/timerfd_settime.S b/libc/arch-arm/syscalls/timerfd_settime.S
index 2e0fe93..2dd4aac 100644
--- a/libc/arch-arm/syscalls/timerfd_settime.S
+++ b/libc/arch-arm/syscalls/timerfd_settime.S
@@ -4,9 +4,11 @@
 
 ENTRY(timerfd_settime)
     mov     ip, r7
+    .cfi_register r7, ip
     ldr     r7, =__NR_timerfd_settime
     swi     #0
     mov     r7, ip
+    .cfi_restore r7
     cmn     r0, #(MAX_ERRNO + 1)
     bxls    lr
     neg     r0, r0
diff --git a/libc/arch-arm/syscalls/times.S b/libc/arch-arm/syscalls/times.S
index 289c185..1ff636d 100644
--- a/libc/arch-arm/syscalls/times.S
+++ b/libc/arch-arm/syscalls/times.S
@@ -4,9 +4,11 @@
 
 ENTRY(times)
     mov     ip, r7
+    .cfi_register r7, ip
     ldr     r7, =__NR_times
     swi     #0
     mov     r7, ip
+    .cfi_restore r7
     cmn     r0, #(MAX_ERRNO + 1)
     bxls    lr
     neg     r0, r0
diff --git a/libc/arch-arm/syscalls/truncate.S b/libc/arch-arm/syscalls/truncate.S
index bb33beb..0bee4d2 100644
--- a/libc/arch-arm/syscalls/truncate.S
+++ b/libc/arch-arm/syscalls/truncate.S
@@ -4,9 +4,11 @@
 
 ENTRY(truncate)
     mov     ip, r7
+    .cfi_register r7, ip
     ldr     r7, =__NR_truncate
     swi     #0
     mov     r7, ip
+    .cfi_restore r7
     cmn     r0, #(MAX_ERRNO + 1)
     bxls    lr
     neg     r0, r0
diff --git a/libc/arch-arm/syscalls/truncate64.S b/libc/arch-arm/syscalls/truncate64.S
index 9cafbb5..74e9eb2 100644
--- a/libc/arch-arm/syscalls/truncate64.S
+++ b/libc/arch-arm/syscalls/truncate64.S
@@ -4,9 +4,11 @@
 
 ENTRY(truncate64)
     mov     ip, r7
+    .cfi_register r7, ip
     ldr     r7, =__NR_truncate64
     swi     #0
     mov     r7, ip
+    .cfi_restore r7
     cmn     r0, #(MAX_ERRNO + 1)
     bxls    lr
     neg     r0, r0
diff --git a/libc/arch-arm/syscalls/umask.S b/libc/arch-arm/syscalls/umask.S
index 5dc4461..ca3e058 100644
--- a/libc/arch-arm/syscalls/umask.S
+++ b/libc/arch-arm/syscalls/umask.S
@@ -4,9 +4,11 @@
 
 ENTRY(umask)
     mov     ip, r7
+    .cfi_register r7, ip
     ldr     r7, =__NR_umask
     swi     #0
     mov     r7, ip
+    .cfi_restore r7
     cmn     r0, #(MAX_ERRNO + 1)
     bxls    lr
     neg     r0, r0
diff --git a/libc/arch-arm/syscalls/umount2.S b/libc/arch-arm/syscalls/umount2.S
index 435eda4..6e1ba32 100644
--- a/libc/arch-arm/syscalls/umount2.S
+++ b/libc/arch-arm/syscalls/umount2.S
@@ -4,9 +4,11 @@
 
 ENTRY(umount2)
     mov     ip, r7
+    .cfi_register r7, ip
     ldr     r7, =__NR_umount2
     swi     #0
     mov     r7, ip
+    .cfi_restore r7
     cmn     r0, #(MAX_ERRNO + 1)
     bxls    lr
     neg     r0, r0
diff --git a/libc/arch-arm/syscalls/uname.S b/libc/arch-arm/syscalls/uname.S
index 8af6123..4f2b8a20 100644
--- a/libc/arch-arm/syscalls/uname.S
+++ b/libc/arch-arm/syscalls/uname.S
@@ -4,9 +4,11 @@
 
 ENTRY(uname)
     mov     ip, r7
+    .cfi_register r7, ip
     ldr     r7, =__NR_uname
     swi     #0
     mov     r7, ip
+    .cfi_restore r7
     cmn     r0, #(MAX_ERRNO + 1)
     bxls    lr
     neg     r0, r0
diff --git a/libc/arch-arm/syscalls/unlinkat.S b/libc/arch-arm/syscalls/unlinkat.S
index 96257e6..ac7bfae 100644
--- a/libc/arch-arm/syscalls/unlinkat.S
+++ b/libc/arch-arm/syscalls/unlinkat.S
@@ -4,9 +4,11 @@
 
 ENTRY(unlinkat)
     mov     ip, r7
+    .cfi_register r7, ip
     ldr     r7, =__NR_unlinkat
     swi     #0
     mov     r7, ip
+    .cfi_restore r7
     cmn     r0, #(MAX_ERRNO + 1)
     bxls    lr
     neg     r0, r0
diff --git a/libc/arch-arm/syscalls/unshare.S b/libc/arch-arm/syscalls/unshare.S
index 8054171..4558a60 100644
--- a/libc/arch-arm/syscalls/unshare.S
+++ b/libc/arch-arm/syscalls/unshare.S
@@ -4,9 +4,11 @@
 
 ENTRY(unshare)
     mov     ip, r7
+    .cfi_register r7, ip
     ldr     r7, =__NR_unshare
     swi     #0
     mov     r7, ip
+    .cfi_restore r7
     cmn     r0, #(MAX_ERRNO + 1)
     bxls    lr
     neg     r0, r0
diff --git a/libc/arch-arm/syscalls/utimensat.S b/libc/arch-arm/syscalls/utimensat.S
index f3c2fa2..9524507 100644
--- a/libc/arch-arm/syscalls/utimensat.S
+++ b/libc/arch-arm/syscalls/utimensat.S
@@ -4,9 +4,11 @@
 
 ENTRY(utimensat)
     mov     ip, r7
+    .cfi_register r7, ip
     ldr     r7, =__NR_utimensat
     swi     #0
     mov     r7, ip
+    .cfi_restore r7
     cmn     r0, #(MAX_ERRNO + 1)
     bxls    lr
     neg     r0, r0
diff --git a/libc/arch-arm/syscalls/vmsplice.S b/libc/arch-arm/syscalls/vmsplice.S
index cc12ca5..90ab8b4 100644
--- a/libc/arch-arm/syscalls/vmsplice.S
+++ b/libc/arch-arm/syscalls/vmsplice.S
@@ -4,9 +4,11 @@
 
 ENTRY(vmsplice)
     mov     ip, r7
+    .cfi_register r7, ip
     ldr     r7, =__NR_vmsplice
     swi     #0
     mov     r7, ip
+    .cfi_restore r7
     cmn     r0, #(MAX_ERRNO + 1)
     bxls    lr
     neg     r0, r0
diff --git a/libc/arch-arm/syscalls/wait4.S b/libc/arch-arm/syscalls/wait4.S
index 26a4929..40bb5a5 100644
--- a/libc/arch-arm/syscalls/wait4.S
+++ b/libc/arch-arm/syscalls/wait4.S
@@ -4,9 +4,11 @@
 
 ENTRY(wait4)
     mov     ip, r7
+    .cfi_register r7, ip
     ldr     r7, =__NR_wait4
     swi     #0
     mov     r7, ip
+    .cfi_restore r7
     cmn     r0, #(MAX_ERRNO + 1)
     bxls    lr
     neg     r0, r0
diff --git a/libc/arch-arm/syscalls/write.S b/libc/arch-arm/syscalls/write.S
index bf89d7f..4abbe6b 100644
--- a/libc/arch-arm/syscalls/write.S
+++ b/libc/arch-arm/syscalls/write.S
@@ -4,9 +4,11 @@
 
 ENTRY(write)
     mov     ip, r7
+    .cfi_register r7, ip
     ldr     r7, =__NR_write
     swi     #0
     mov     r7, ip
+    .cfi_restore r7
     cmn     r0, #(MAX_ERRNO + 1)
     bxls    lr
     neg     r0, r0
diff --git a/libc/arch-arm/syscalls/writev.S b/libc/arch-arm/syscalls/writev.S
index 15b5275..3103237 100644
--- a/libc/arch-arm/syscalls/writev.S
+++ b/libc/arch-arm/syscalls/writev.S
@@ -4,9 +4,11 @@
 
 ENTRY(writev)
     mov     ip, r7
+    .cfi_register r7, ip
     ldr     r7, =__NR_writev
     swi     #0
     mov     r7, ip
+    .cfi_restore r7
     cmn     r0, #(MAX_ERRNO + 1)
     bxls    lr
     neg     r0, r0
diff --git a/libc/arch-arm64/arm64.mk b/libc/arch-arm64/arm64.mk
index 470a038..9a76072 100644
--- a/libc/arch-arm64/arm64.mk
+++ b/libc/arch-arm64/arm64.mk
@@ -1,32 +1,38 @@
 # 64-bit arm.
 
 #
-# Default implementations of functions that are commonly optimized.
+# Generic arm64 optimizations, may be overriden by CPU variants.
 #
 
 libc_bionic_src_files_arm64 += \
-    bionic/__memset_chk.cpp \
-    bionic/__strcpy_chk.cpp \
-    bionic/__strcat_chk.cpp \
-    bionic/strrchr.cpp \
+    arch-arm64/generic/bionic/memchr.S \
+    arch-arm64/generic/bionic/memcmp.S \
+    arch-arm64/generic/bionic/memcpy.S \
+    arch-arm64/generic/bionic/memmove.S \
+    arch-arm64/generic/bionic/memset.S \
+    arch-arm64/generic/bionic/stpcpy.S \
+    arch-arm64/generic/bionic/strchr.S \
+    arch-arm64/generic/bionic/strcmp.S \
+    arch-arm64/generic/bionic/strcpy.S \
+    arch-arm64/generic/bionic/strlen.S \
+    arch-arm64/generic/bionic/strncmp.S \
+    arch-arm64/generic/bionic/strnlen.S \
+    arch-arm64/generic/bionic/wmemmove.S \
 
-libc_freebsd_src_files_arm64 += \
-    upstream-freebsd/lib/libc/string/wcscat.c \
-    upstream-freebsd/lib/libc/string/wcschr.c \
-    upstream-freebsd/lib/libc/string/wcscmp.c \
-    upstream-freebsd/lib/libc/string/wcscpy.c \
-    upstream-freebsd/lib/libc/string/wcslen.c \
-    upstream-freebsd/lib/libc/string/wcsrchr.c \
-    upstream-freebsd/lib/libc/string/wmemcmp.c \
+libc_bionic_src_files_exclude_arm64 += \
+    bionic/__memcpy_chk.cpp \
+    bionic/strchr.cpp \
+    bionic/strnlen.c \
 
-libc_openbsd_src_files_arm64 += \
-    upstream-openbsd/lib/libc/string/memrchr.c \
-    upstream-openbsd/lib/libc/string/stpncpy.c \
-    upstream-openbsd/lib/libc/string/strcat.c \
-    upstream-openbsd/lib/libc/string/strlcat.c \
-    upstream-openbsd/lib/libc/string/strlcpy.c \
-    upstream-openbsd/lib/libc/string/strncat.c \
-    upstream-openbsd/lib/libc/string/strncpy.c \
+libc_freebsd_src_files_exclude_arm64 += \
+    upstream-freebsd/lib/libc/string/wmemmove.c \
+
+libc_openbsd_src_files_exclude_arm64 += \
+    upstream-openbsd/lib/libc/string/memchr.c \
+    upstream-openbsd/lib/libc/string/memmove.c \
+    upstream-openbsd/lib/libc/string/stpcpy.c \
+    upstream-openbsd/lib/libc/string/strcpy.c \
+    upstream-openbsd/lib/libc/string/strncmp.c \
 
 #
 # Inherently architecture-specific code.
@@ -36,7 +42,6 @@
     arch-arm64/bionic/__bionic_clone.S \
     arch-arm64/bionic/_exit_with_stack_teardown.S \
     arch-arm64/bionic/setjmp.S \
-    arch-arm64/bionic/__set_tls.c \
     arch-arm64/bionic/syscall.S \
     arch-arm64/bionic/vfork.S \
 
@@ -54,6 +59,7 @@
 ifeq ($(strip $(TARGET_CPU_VARIANT)),)
   $(warning TARGET_ARCH is arm64, but TARGET_CPU_VARIANT is not defined)
 endif
+ifneq ($(TARGET_CPU_VARIANT),generic)
 cpu_variant_mk := $(LOCAL_PATH)/arch-arm64/$(TARGET_CPU_VARIANT)/$(TARGET_CPU_VARIANT).mk
 ifeq ($(wildcard $(cpu_variant_mk)),)
 $(error "TARGET_CPU_VARIANT not set or set to an unknown value. Possible values are generic, denver64. Use generic for devices that do not have a CPU similar to any of the supported cpu variants.")
@@ -62,3 +68,4 @@
 libc_common_additional_dependencies += $(cpu_variant_mk)
 
 cpu_variant_mk :=
+endif
diff --git a/libc/arch-arm64/bionic/setjmp.S b/libc/arch-arm64/bionic/setjmp.S
index ba0a226..2550134 100644
--- a/libc/arch-arm64/bionic/setjmp.S
+++ b/libc/arch-arm64/bionic/setjmp.S
@@ -37,6 +37,18 @@
 // NOTE: All the registers saved here will have 64 bit vales.
 //       AAPCS mandates that the higher part of q registers do not need to
 //       be saved by the callee.
+//
+// The internal structure of a jmp_buf is totally private.
+// Current layout (changes from release to release):
+//
+// word   name            description
+// 0      sigflag/cookie  setjmp cookie in top 31 bits, signal mask flag in low bit
+// 1      sigmask         signal mask (not used with _setjmp / _longjmp)
+// 2      core_base       base of core registers (x19-x30, sp)
+// 15     float_base      base of float registers (d8-d15)
+// 23     checksum        checksum of core registers
+// 24     reserved        reserved entries (room to grow)
+// 32
 
 #define _JB_SIGFLAG     0
 #define _JB_SIGMASK     (_JB_SIGFLAG + 1)
@@ -51,6 +63,40 @@
 #define _JB_D12_D13     (_JB_D14_D15 + 2)
 #define _JB_D10_D11     (_JB_D12_D13 + 2)
 #define _JB_D8_D9       (_JB_D10_D11 + 2)
+#define _JB_CHECKSUM    (_JB_D8_D9 + 2)
+
+#define MANGLE_REGISTERS 1
+#define USE_CHECKSUM 1
+
+.macro m_mangle_registers reg, sp_reg
+#if MANGLE_REGISTERS
+  eor x19, x19, \reg
+  eor x20, x20, \reg
+  eor x21, x21, \reg
+  eor x22, x22, \reg
+  eor x23, x23, \reg
+  eor x24, x24, \reg
+  eor x25, x25, \reg
+  eor x26, x26, \reg
+  eor x27, x27, \reg
+  eor x28, x28, \reg
+  eor x29, x29, \reg
+  eor x30, x30, \reg
+  eor \sp_reg, \sp_reg, \reg
+#endif
+.endm
+
+.macro m_calculate_checksum dst, src, scratch
+  mov \dst, #0
+  .irp i,0,1,2,3,4,5,6,7,8,9,10,11,12,13,14,15,16,17,18,19,20,21,22
+    ldr \scratch, [\src, #(\i * 8)]
+    eor \dst, \dst, \scratch
+  .endr
+.endm
+
+.macro m_unmangle_registers reg, sp_reg
+  m_mangle_registers \reg, sp_reg=\sp_reg
+.endm
 
 ENTRY(setjmp)
   mov w1, #1
@@ -64,23 +110,47 @@
 
 // int sigsetjmp(sigjmp_buf env, int save_signal_mask);
 ENTRY(sigsetjmp)
-  // Record whether or not we're saving the signal mask.
-  str w1, [x0, #(_JB_SIGFLAG * 8)]
+  stp x0, x30, [sp, #-16]!
+  .cfi_def_cfa_offset 16
+  .cfi_rel_offset x0, 0
+  .cfi_rel_offset x30, 8
+
+  // Get the cookie and store it along with the signal flag.
+  mov x0, x1
+  bl __bionic_setjmp_cookie_get
+  mov x1, x0
+  ldr x0, [sp, #0]
+  str x1, [x0, #(_JB_SIGFLAG * 8)]
 
   // Do we need to save the signal mask?
-  cbz w1, 1f
+  tbz w1, #0, 1f
+
+  // Save the cookie for later.
+  stp x1, xzr, [sp, #-16]!
+  .cfi_adjust_cfa_offset 16
 
   // Save current signal mask.
-  stp x0, x30, [sp, #-16]!
   // The 'how' argument is ignored if new_mask is NULL.
   mov x1, #0 // NULL.
   add x2, x0, #(_JB_SIGMASK * 8) // old_mask.
   bl sigprocmask
-  ldp x0, x30, [sp], #16
+
+  ldp x1, xzr, [sp], #16
+  .cfi_adjust_cfa_offset -16
 
 1:
+  // Restore original x0 and lr.
+  ldp x0, x30, [sp], #16
+  .cfi_adjust_cfa_offset -16
+  .cfi_restore x0
+  .cfi_restore x30
+
+  // Mask off the signal flag bit.
+  bic x1, x1, #1
+
   // Save core registers.
   mov x10, sp
+  m_mangle_registers x1, sp_reg=x10
   stp x30, x10, [x0, #(_JB_X30_SP  * 8)]
   stp x28, x29, [x0, #(_JB_X28_X29 * 8)]
   stp x26, x27, [x0, #(_JB_X26_X27 * 8)]
@@ -88,6 +158,7 @@
   stp x22, x23, [x0, #(_JB_X22_X23 * 8)]
   stp x20, x21, [x0, #(_JB_X20_X21 * 8)]
   str x19,      [x0, #(_JB_X19     * 8)]
+  m_unmangle_registers x1, sp_reg=x10
 
   // Save floating point registers.
   stp d14, d15, [x0, #(_JB_D14_D15 * 8)]
@@ -95,37 +166,82 @@
   stp d10, d11, [x0, #(_JB_D10_D11 * 8)]
   stp d8,  d9,  [x0, #(_JB_D8_D9   * 8)]
 
+#if USE_CHECKSUM
+  // Calculate the checksum.
+  m_calculate_checksum x12, x0, x2
+  str x12, [x0, #(_JB_CHECKSUM * 8)]
+#endif
+
   mov w0, #0
   ret
 END(sigsetjmp)
 
 // void siglongjmp(sigjmp_buf env, int value);
 ENTRY(siglongjmp)
+#if USE_CHECKSUM
+  // Check the checksum before doing anything.
+  m_calculate_checksum x12, x0, x2
+  ldr x2, [x0, #(_JB_CHECKSUM * 8)]
+
+  cmp x2, x12
+  bne __bionic_setjmp_checksum_mismatch
+#endif
+
   // Do we need to restore the signal mask?
-  ldr w9, [x0, #(_JB_SIGFLAG * 8)]
-  cbz w9, 1f
+  ldr x2, [x0, #(_JB_SIGFLAG * 8)]
+  tbz w2, #0, 1f
+
+  stp x0, x30, [sp, #-16]!
+  .cfi_adjust_cfa_offset 16
+  .cfi_rel_offset x0, 0
+  .cfi_rel_offset x30, 8
 
   // Restore signal mask.
-  stp x0, x30, [sp, #-16]!
   mov x19, x1 // Save 'value'.
+
   mov x2, x0
   mov x0, #2 // SIG_SETMASK
   add x1, x2, #(_JB_SIGMASK * 8) // new_mask.
   mov x2, #0 // NULL.
   bl sigprocmask
   mov x1, x19 // Restore 'value'.
-  ldp x0, x30, [sp], #16
 
+  // Restore original x0 and lr.
+  ldp x0, x30, [sp], #16
+  .cfi_adjust_cfa_offset -16
+  .cfi_restore x0
+  .cfi_restore x30
+
+  ldr x2, [x0, #(_JB_SIGFLAG * 8)]
 1:
   // Restore core registers.
+  bic x2, x2, #1
   ldp x30, x10, [x0, #(_JB_X30_SP  * 8)]
-  mov sp, x10
   ldp x28, x29, [x0, #(_JB_X28_X29 * 8)]
   ldp x26, x27, [x0, #(_JB_X26_X27 * 8)]
   ldp x24, x25, [x0, #(_JB_X24_X25 * 8)]
   ldp x22, x23, [x0, #(_JB_X22_X23 * 8)]
   ldp x20, x21, [x0, #(_JB_X20_X21 * 8)]
   ldr x19,      [x0, #(_JB_X19     * 8)]
+  m_unmangle_registers x2, sp_reg=x10
+  mov sp, x10
+
+  stp x0, x1, [sp, #-16]!
+  .cfi_adjust_cfa_offset 16
+  .cfi_rel_offset x0, 0
+  .cfi_rel_offset x1, 8
+  stp x30, xzr, [sp, #-16]!
+  .cfi_adjust_cfa_offset 16
+  .cfi_rel_offset x30, 0
+  ldr x0, [x0, #(_JB_SIGFLAG * 8)]
+  bl __bionic_setjmp_cookie_check
+  ldp x30, xzr, [sp], #16
+  .cfi_adjust_cfa_offset -16
+  .cfi_restore x30
+  ldp x0, x1, [sp], #16
+  .cfi_adjust_cfa_offset -16
+  .cfi_restore x0
+  .cfi_restore x1
 
   // Restore floating point registers.
   ldp d14, d15, [x0, #(_JB_D14_D15 * 8)]
@@ -133,13 +249,6 @@
   ldp d10, d11, [x0, #(_JB_D10_D11 * 8)]
   ldp d8,  d9,  [x0, #(_JB_D8_D9   * 8)]
 
-  // Validate sp (sp mod 16 = 0) and lr (lr mod 4 = 0).
-  tst x30, #3
-  b.ne longjmperror
-  mov x10, sp
-  tst x10, #15
-  b.ne longjmperror
-
   // Set return value.
   cmp w1, wzr
   csinc w0, w1, wzr, ne
diff --git a/libc/arch-arm64/bionic/vfork.S b/libc/arch-arm64/bionic/vfork.S
index b6a672d..92fa333 100644
--- a/libc/arch-arm64/bionic/vfork.S
+++ b/libc/arch-arm64/bionic/vfork.S
@@ -31,6 +31,11 @@
 #include <linux/sched.h>
 
 ENTRY(vfork)
+    // __get_tls()[TLS_SLOT_THREAD_ID]->cached_pid_ = 0
+    mrs     x0, tpidr_el0
+    ldr     x0, [x0, #8]
+    str     wzr, [x0, #20]
+
     mov     x0, #(CLONE_VM | CLONE_VFORK | SIGCHLD)
     mov     x1, xzr
     mov     x2, xzr
diff --git a/libc/arch-arm64/cortex-a53/cortex-a53.mk b/libc/arch-arm64/cortex-a53/cortex-a53.mk
index 676e886..e69de29 100644
--- a/libc/arch-arm64/cortex-a53/cortex-a53.mk
+++ b/libc/arch-arm64/cortex-a53/cortex-a53.mk
@@ -1 +0,0 @@
-include bionic/libc/arch-arm64/generic/generic.mk
diff --git a/libc/arch-arm64/denver64/denver64.mk b/libc/arch-arm64/denver64/denver64.mk
index d619c11..703af45 100644
--- a/libc/arch-arm64/denver64/denver64.mk
+++ b/libc/arch-arm64/denver64/denver64.mk
@@ -1,14 +1,7 @@
 libc_bionic_src_files_arm64 += \
-    arch-arm64/generic/bionic/memchr.S \
-    arch-arm64/generic/bionic/memcmp.S \
     arch-arm64/denver64/bionic/memcpy.S \
-    arch-arm64/generic/bionic/memmove.S \
     arch-arm64/denver64/bionic/memset.S \
-    arch-arm64/generic/bionic/stpcpy.S \
-    arch-arm64/generic/bionic/strchr.S \
-    arch-arm64/generic/bionic/strcmp.S \
-    arch-arm64/generic/bionic/strcpy.S \
-    arch-arm64/generic/bionic/strlen.S \
-    arch-arm64/generic/bionic/strncmp.S \
-    arch-arm64/generic/bionic/strnlen.S \
-    arch-arm64/generic/bionic/wmemmove.S
+
+libc_bionic_src_files_exclude_arm64 += \
+    arch-arm64/generic/bionic/memcpy.S \
+    arch-arm64/generic/bionic/memset.S \
diff --git a/libc/arch-arm64/generic/bionic/memmove.S b/libc/arch-arm64/generic/bionic/memmove.S
index 8b366a3..739ce49 100644
--- a/libc/arch-arm64/generic/bionic/memmove.S
+++ b/libc/arch-arm64/generic/bionic/memmove.S
@@ -35,10 +35,6 @@
 #include <private/bionic_asm.h>
 
 /* Parameters and result.  */
-#ifdef BCOPY
-#define origdstin	x1
-#define origsrc	x0
-#endif
 #define dstin	x0
 #define src	x1
 #define count	x2
@@ -59,13 +55,7 @@
 #define D_l	x13
 #define D_h	x14
 
-#ifdef BCOPY
-ENTRY(bcopy)
-	/* Swap src and dst so that a branch to memcpy doesn't cause issues. */
-	mov	tmp1, origsrc
-	mov	origsrc, origdstin
-	mov	origdstin, tmp1
-#elif defined(WMEMMOVE)
+#if defined(WMEMMOVE)
 ENTRY(wmemmove)
 	lsl	count, count, #2
 #else
@@ -332,9 +322,7 @@
 	tst	count, #0x3f
 	b.ne	.Ltail63down
 	ret
-#ifdef BCOPY
-END(bcopy)
-#elif defined(WMEMMOVE)
+#if defined(WMEMMOVE)
 END(wmemmove)
 #else
 END(memmove)
diff --git a/libc/arch-arm64/generic/generic.mk b/libc/arch-arm64/generic/generic.mk
deleted file mode 100644
index 1b595aa..0000000
--- a/libc/arch-arm64/generic/generic.mk
+++ /dev/null
@@ -1,14 +0,0 @@
-libc_bionic_src_files_arm64 += \
-    arch-arm64/generic/bionic/memchr.S \
-    arch-arm64/generic/bionic/memcmp.S \
-    arch-arm64/generic/bionic/memcpy.S \
-    arch-arm64/generic/bionic/memmove.S \
-    arch-arm64/generic/bionic/memset.S \
-    arch-arm64/generic/bionic/stpcpy.S \
-    arch-arm64/generic/bionic/strchr.S \
-    arch-arm64/generic/bionic/strcmp.S \
-    arch-arm64/generic/bionic/strcpy.S \
-    arch-arm64/generic/bionic/strlen.S \
-    arch-arm64/generic/bionic/strncmp.S \
-    arch-arm64/generic/bionic/strnlen.S \
-    arch-arm64/generic/bionic/wmemmove.S
diff --git a/libc/arch-arm64/syscalls/flistxattr.S b/libc/arch-arm64/syscalls/___flistxattr.S
similarity index 78%
rename from libc/arch-arm64/syscalls/flistxattr.S
rename to libc/arch-arm64/syscalls/___flistxattr.S
index 8921bb4..02c8478 100644
--- a/libc/arch-arm64/syscalls/flistxattr.S
+++ b/libc/arch-arm64/syscalls/___flistxattr.S
@@ -2,7 +2,7 @@
 
 #include <private/bionic_asm.h>
 
-ENTRY(flistxattr)
+ENTRY(___flistxattr)
     mov     x8, __NR_flistxattr
     svc     #0
 
@@ -11,4 +11,5 @@
     b.hi    __set_errno_internal
 
     ret
-END(flistxattr)
+END(___flistxattr)
+.hidden ___flistxattr
diff --git a/libc/arch-arm64/syscalls/mremap.S b/libc/arch-arm64/syscalls/___mremap.S
similarity index 81%
rename from libc/arch-arm64/syscalls/mremap.S
rename to libc/arch-arm64/syscalls/___mremap.S
index 69b91d6..aeb93bc 100644
--- a/libc/arch-arm64/syscalls/mremap.S
+++ b/libc/arch-arm64/syscalls/___mremap.S
@@ -2,7 +2,7 @@
 
 #include <private/bionic_asm.h>
 
-ENTRY(mremap)
+ENTRY(___mremap)
     mov     x8, __NR_mremap
     svc     #0
 
@@ -11,4 +11,5 @@
     b.hi    __set_errno_internal
 
     ret
-END(mremap)
+END(___mremap)
+.hidden ___mremap
diff --git a/libc/arch-arm64/syscalls/mremap.S b/libc/arch-arm64/syscalls/adjtimex.S
similarity index 76%
copy from libc/arch-arm64/syscalls/mremap.S
copy to libc/arch-arm64/syscalls/adjtimex.S
index 69b91d6..712e468 100644
--- a/libc/arch-arm64/syscalls/mremap.S
+++ b/libc/arch-arm64/syscalls/adjtimex.S
@@ -2,8 +2,8 @@
 
 #include <private/bionic_asm.h>
 
-ENTRY(mremap)
-    mov     x8, __NR_mremap
+ENTRY(adjtimex)
+    mov     x8, __NR_adjtimex
     svc     #0
 
     cmn     x0, #(MAX_ERRNO + 1)
@@ -11,4 +11,4 @@
     b.hi    __set_errno_internal
 
     ret
-END(mremap)
+END(adjtimex)
diff --git a/libc/arch-arm64/syscalls/mremap.S b/libc/arch-arm64/syscalls/clock_adjtime.S
similarity index 72%
copy from libc/arch-arm64/syscalls/mremap.S
copy to libc/arch-arm64/syscalls/clock_adjtime.S
index 69b91d6..c2c191e 100644
--- a/libc/arch-arm64/syscalls/mremap.S
+++ b/libc/arch-arm64/syscalls/clock_adjtime.S
@@ -2,8 +2,8 @@
 
 #include <private/bionic_asm.h>
 
-ENTRY(mremap)
-    mov     x8, __NR_mremap
+ENTRY(clock_adjtime)
+    mov     x8, __NR_clock_adjtime
     svc     #0
 
     cmn     x0, #(MAX_ERRNO + 1)
@@ -11,4 +11,4 @@
     b.hi    __set_errno_internal
 
     ret
-END(mremap)
+END(clock_adjtime)
diff --git a/libc/arch-arm64/syscalls/mremap.S b/libc/arch-arm64/syscalls/preadv.S
similarity index 69%
copy from libc/arch-arm64/syscalls/mremap.S
copy to libc/arch-arm64/syscalls/preadv.S
index 69b91d6..cb8300d 100644
--- a/libc/arch-arm64/syscalls/mremap.S
+++ b/libc/arch-arm64/syscalls/preadv.S
@@ -2,8 +2,8 @@
 
 #include <private/bionic_asm.h>
 
-ENTRY(mremap)
-    mov     x8, __NR_mremap
+ENTRY(preadv)
+    mov     x8, __NR_preadv
     svc     #0
 
     cmn     x0, #(MAX_ERRNO + 1)
@@ -11,4 +11,6 @@
     b.hi    __set_errno_internal
 
     ret
-END(mremap)
+END(preadv)
+
+ALIAS_SYMBOL(preadv64, preadv)
diff --git a/libc/arch-arm64/syscalls/mremap.S b/libc/arch-arm64/syscalls/pwritev.S
similarity index 68%
copy from libc/arch-arm64/syscalls/mremap.S
copy to libc/arch-arm64/syscalls/pwritev.S
index 69b91d6..621466a 100644
--- a/libc/arch-arm64/syscalls/mremap.S
+++ b/libc/arch-arm64/syscalls/pwritev.S
@@ -2,8 +2,8 @@
 
 #include <private/bionic_asm.h>
 
-ENTRY(mremap)
-    mov     x8, __NR_mremap
+ENTRY(pwritev)
+    mov     x8, __NR_pwritev
     svc     #0
 
     cmn     x0, #(MAX_ERRNO + 1)
@@ -11,4 +11,6 @@
     b.hi    __set_errno_internal
 
     ret
-END(mremap)
+END(pwritev)
+
+ALIAS_SYMBOL(pwritev64, pwritev)
diff --git a/libc/arch-mips/bionic/setjmp.S b/libc/arch-mips/bionic/setjmp.S
index 3ef0f11..73002e8 100644
--- a/libc/arch-mips/bionic/setjmp.S
+++ b/libc/arch-mips/bionic/setjmp.S
@@ -132,10 +132,9 @@
 /*     	field:		byte offset:	size:						*/
 /*     	dynam filler	(0*4)		   0-4 bytes of rounddown filler, DON'T TOUCH!!
 						often overlays user storage!!		*/
-#define	SC_MAGIC_OFFSET	(1*4)		/* 4 bytes, identify jmpbuf, first actual field */
-#define	SC_FLAG_OFFSET	(2*4)		/* 4 bytes, savesigs flag */
-#define	SC_FPSR_OFFSET	(3*4)		/* 4 bytes, floating point control/status reg */
+#define	SC_FPSR_OFFSET	(1*4)		/* 4 bytes, floating point control/status reg */
 /* following fields are 8-byte aligned */
+#define	SC_FLAG_OFFSET	(2*4)		/* 8 bytes, cookie and savesigs flag, first actual field  */
 #define	SC_MASK_OFFSET	(4*4)		/* 16 bytes, mips32/mips64 version of sigset_t */
 #define	SC_SPARE_OFFSET	(8*4)		/* 8 bytes, reserved for future uses */
 
@@ -166,6 +165,16 @@
 #error _JBLEN is too small
 #endif
 
+.macro m_mangle_reg_and_store reg, cookie, temp, offset
+	xor	\temp, \reg, \cookie
+	REG_S	\temp, \offset
+.endm
+
+.macro m_unmangle_reg_and_load reg, cookie, temp, offset
+	REG_L	\temp, \offset
+	xor	\reg, \temp, \cookie
+.endm
+
 /*
  *
  *  GPOFF and FRAMESIZE must be the same for all setjmp/longjmp routines
@@ -190,36 +199,46 @@
 	li	t0, ~7
 	and	a0, t0				# round jmpbuf addr DOWN to 8-byte boundary
 #endif
-	sw	a1, SC_FLAG_OFFSET(a0)		# save savesigs flag
-	beqz	a1, 1f				# do saving of signal mask?
-
 	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
+	jal	__bionic_setjmp_cookie_get
+	REG_L	a0, A0OFF(sp)
+
+	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?
+
 	# 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
 	jal	sigprocmask			# get current signal mask
 	REG_L	a0, A0OFF(sp)
-	REG_L	ra, RAOFF(sp)
 1:
-	li	v0, 0xACEDBADE			# sigcontext magic number
-	sw	v0, SC_MAGIC_OFFSET(a0)
+	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:
-	REG_S	ra, SC_REGS+0*REGSZ(a0)
-	REG_S	s0, SC_REGS+1*REGSZ(a0)
-	REG_S	s1, SC_REGS+2*REGSZ(a0)
-	REG_S	s2, SC_REGS+3*REGSZ(a0)
-	REG_S	s3, SC_REGS+4*REGSZ(a0)
-	REG_S	s4, SC_REGS+5*REGSZ(a0)
-	REG_S	s5, SC_REGS+6*REGSZ(a0)
-	REG_S	s6, SC_REGS+7*REGSZ(a0)
-	REG_S	s7, SC_REGS+8*REGSZ(a0)
-	REG_S	s8, SC_REGS+9*REGSZ(a0)
-	REG_L	v0, GPOFF(sp)
-	REG_S	v0, SC_REGS+10*REGSZ(a0)	# save gp
-	PTR_ADDU v0, sp, FRAMESZ
-	REG_S	v0, SC_REGS+11*REGSZ(a0)	# 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)
 
 	cfc1	v0, $31
 
@@ -288,36 +307,41 @@
 	li	t0, ~7
 	and	a0, t0				# round jmpbuf addr DOWN to 8-byte boundary
 #endif
-	lw	v0, SC_MAGIC_OFFSET(a0)
-	li	t0, 0xACEDBADE
-	bne	v0, t0, longjmp_botch		# jump if error
 
-	lw	t0, SC_FLAG_OFFSET(a0)		# get savesigs flag
+	move	s1, a1				# temp spill
+	move	s0, a0
+
+	# extract savesigs flag
+	REG_L	s2, SC_FLAG_OFFSET(s0)
+	andi	t0, s2, 1
 	beqz	t0, 1f				# restore signal mask?
 
-	REG_S	a1, A1OFF(sp)			# temp spill
-	REG_S	a0, A0OFF(sp)
-        # call sigprocmask(int how SIG_SETMASK, sigset_t* SC_MASK(a0), sigset_t* null):
-	LA	a1, SC_MASK_OFFSET(a0)		# signals being restored
+	# 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
 	jal	sigprocmask			# restore signal mask
-	REG_L	a0, A0OFF(sp)
-	REG_L	a1, A1OFF(sp)
 1:
+	move	t0, s2				# get cookie to temp reg
+	move	a1, s1
+	move	a0, s0
+
 	# callee-saved long-sized regs:
-	REG_L	ra, SC_REGS+0*REGSZ(a0)
-	REG_L	s0, SC_REGS+1*REGSZ(a0)
-	REG_L	s1, SC_REGS+2*REGSZ(a0)
-	REG_L	s2, SC_REGS+3*REGSZ(a0)
-	REG_L	s3, SC_REGS+4*REGSZ(a0)
-	REG_L	s4, SC_REGS+5*REGSZ(a0)
-	REG_L	s5, SC_REGS+6*REGSZ(a0)
-	REG_L	s6, SC_REGS+7*REGSZ(a0)
-	REG_L	s7, SC_REGS+8*REGSZ(a0)
-	REG_L	s8, SC_REGS+9*REGSZ(a0)
-	REG_L	gp, SC_REGS+10*REGSZ(a0)
-	REG_L	sp, SC_REGS+11*REGSZ(a0)
+
+	# 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)
 
 	lw	v0, SC_FPSR_OFFSET(a0)
 	ctc1	v0, $31			# restore old fr mode before fp values
@@ -341,15 +365,22 @@
 	l.d	$f28, SC_FPREGS+4*REGSZ_FP(a0)
 	l.d	$f30, SC_FPREGS+5*REGSZ_FP(a0)
 #endif
-	bne	a1, zero, 1f
-	li	a1, 1			# never return 0!
-1:
-	move	v0, a1
-	j	ra			# return to setjmp call site
 
-longjmp_botch:
-	jal	longjmperror
-	jal	abort
+	# check cookie
+	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
+
+	sltiu	t0, a1, 1		# never return 0!
+	xor	v0, a1, t0
+	j	ra			# return to setjmp call site
 END(siglongjmp)
 
 ALIAS_SYMBOL(longjmp, siglongjmp)
diff --git a/libc/arch-mips/bionic/vfork.S b/libc/arch-mips/bionic/vfork.S
index 1849624..7ccf70b 100644
--- a/libc/arch-mips/bionic/vfork.S
+++ b/libc/arch-mips/bionic/vfork.S
@@ -37,6 +37,14 @@
 	.set	noreorder
 	.cpload	t9
 
+	// __get_tls()[TLS_SLOT_THREAD_ID]->cached_pid_ = 0
+	.set	push
+	.set	mips32r2
+	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
+
 	li	a0, (CLONE_VM | CLONE_VFORK | SIGCHLD)
 	li	a1, 0
 	li	a2, 0
diff --git a/libc/arch-mips/mips.mk b/libc/arch-mips/mips.mk
index 05e7198..b184abb 100644
--- a/libc/arch-mips/mips.mk
+++ b/libc/arch-mips/mips.mk
@@ -1,45 +1,10 @@
 # 32-bit mips.
 
-#
-# Default implementations of functions that are commonly optimized.
-#
-
 libc_bionic_src_files_mips += \
     arch-mips/string/memcmp.c \
     arch-mips/string/memcpy.S \
     arch-mips/string/memset.S \
     arch-mips/string/strcmp.S \
-    bionic/__memcpy_chk.cpp \
-    bionic/__memset_chk.cpp \
-    bionic/__strcpy_chk.cpp \
-    bionic/__strcat_chk.cpp \
-    bionic/strchr.cpp \
-    bionic/strnlen.c \
-    bionic/strrchr.cpp \
-
-libc_freebsd_src_files_mips += \
-    upstream-freebsd/lib/libc/string/wcscat.c \
-    upstream-freebsd/lib/libc/string/wcschr.c \
-    upstream-freebsd/lib/libc/string/wcscmp.c \
-    upstream-freebsd/lib/libc/string/wcscpy.c \
-    upstream-freebsd/lib/libc/string/wcslen.c \
-    upstream-freebsd/lib/libc/string/wcsrchr.c \
-    upstream-freebsd/lib/libc/string/wmemcmp.c \
-    upstream-freebsd/lib/libc/string/wmemmove.c \
-
-libc_openbsd_src_files_mips += \
-    upstream-openbsd/lib/libc/string/memchr.c \
-    upstream-openbsd/lib/libc/string/memmove.c \
-    upstream-openbsd/lib/libc/string/memrchr.c \
-    upstream-openbsd/lib/libc/string/stpcpy.c \
-    upstream-openbsd/lib/libc/string/stpncpy.c \
-    upstream-openbsd/lib/libc/string/strcat.c \
-    upstream-openbsd/lib/libc/string/strcpy.c \
-    upstream-openbsd/lib/libc/string/strlcat.c \
-    upstream-openbsd/lib/libc/string/strlcpy.c \
-    upstream-openbsd/lib/libc/string/strncat.c \
-    upstream-openbsd/lib/libc/string/strncmp.c \
-    upstream-openbsd/lib/libc/string/strncpy.c \
 
 #
 # Inherently architecture-specific code.
diff --git a/libc/arch-mips/syscalls/flistxattr.S b/libc/arch-mips/syscalls/___flistxattr.S
similarity index 81%
rename from libc/arch-mips/syscalls/flistxattr.S
rename to libc/arch-mips/syscalls/___flistxattr.S
index 0b71532..5a4a53d 100644
--- a/libc/arch-mips/syscalls/flistxattr.S
+++ b/libc/arch-mips/syscalls/___flistxattr.S
@@ -2,7 +2,7 @@
 
 #include <private/bionic_asm.h>
 
-ENTRY(flistxattr)
+ENTRY(___flistxattr)
     .set noreorder
     .cpload t9
     li v0, __NR_flistxattr
@@ -16,4 +16,5 @@
     j t9
     nop
     .set reorder
-END(flistxattr)
+END(___flistxattr)
+.hidden ___flistxattr
diff --git a/libc/arch-mips/syscalls/mremap.S b/libc/arch-mips/syscalls/___mremap.S
similarity index 84%
rename from libc/arch-mips/syscalls/mremap.S
rename to libc/arch-mips/syscalls/___mremap.S
index 7cbb94e..82e2eb3 100644
--- a/libc/arch-mips/syscalls/mremap.S
+++ b/libc/arch-mips/syscalls/___mremap.S
@@ -2,7 +2,7 @@
 
 #include <private/bionic_asm.h>
 
-ENTRY(mremap)
+ENTRY(___mremap)
     .set noreorder
     .cpload t9
     li v0, __NR_mremap
@@ -16,4 +16,5 @@
     j t9
     nop
     .set reorder
-END(mremap)
+END(___mremap)
+.hidden ___mremap
diff --git a/libc/arch-mips/syscalls/mremap.S b/libc/arch-mips/syscalls/__preadv64.S
similarity index 80%
copy from libc/arch-mips/syscalls/mremap.S
copy to libc/arch-mips/syscalls/__preadv64.S
index 7cbb94e..a46b869 100644
--- a/libc/arch-mips/syscalls/mremap.S
+++ b/libc/arch-mips/syscalls/__preadv64.S
@@ -2,10 +2,10 @@
 
 #include <private/bionic_asm.h>
 
-ENTRY(mremap)
+ENTRY(__preadv64)
     .set noreorder
     .cpload t9
-    li v0, __NR_mremap
+    li v0, __NR_preadv
     syscall
     bnez a3, 1f
     move a0, v0
@@ -16,4 +16,4 @@
     j t9
     nop
     .set reorder
-END(mremap)
+END(__preadv64)
diff --git a/libc/arch-mips/syscalls/mremap.S b/libc/arch-mips/syscalls/__pwritev64.S
similarity index 80%
copy from libc/arch-mips/syscalls/mremap.S
copy to libc/arch-mips/syscalls/__pwritev64.S
index 7cbb94e..1222942 100644
--- a/libc/arch-mips/syscalls/mremap.S
+++ b/libc/arch-mips/syscalls/__pwritev64.S
@@ -2,10 +2,10 @@
 
 #include <private/bionic_asm.h>
 
-ENTRY(mremap)
+ENTRY(__pwritev64)
     .set noreorder
     .cpload t9
-    li v0, __NR_mremap
+    li v0, __NR_pwritev
     syscall
     bnez a3, 1f
     move a0, v0
@@ -16,4 +16,4 @@
     j t9
     nop
     .set reorder
-END(mremap)
+END(__pwritev64)
diff --git a/libc/arch-mips/syscalls/mremap.S b/libc/arch-mips/syscalls/adjtimex.S
similarity index 81%
copy from libc/arch-mips/syscalls/mremap.S
copy to libc/arch-mips/syscalls/adjtimex.S
index 7cbb94e..fef215f 100644
--- a/libc/arch-mips/syscalls/mremap.S
+++ b/libc/arch-mips/syscalls/adjtimex.S
@@ -2,10 +2,10 @@
 
 #include <private/bionic_asm.h>
 
-ENTRY(mremap)
+ENTRY(adjtimex)
     .set noreorder
     .cpload t9
-    li v0, __NR_mremap
+    li v0, __NR_adjtimex
     syscall
     bnez a3, 1f
     move a0, v0
@@ -16,4 +16,4 @@
     j t9
     nop
     .set reorder
-END(mremap)
+END(adjtimex)
diff --git a/libc/arch-mips/syscalls/flistxattr.S b/libc/arch-mips/syscalls/clock_adjtime.S
similarity index 77%
copy from libc/arch-mips/syscalls/flistxattr.S
copy to libc/arch-mips/syscalls/clock_adjtime.S
index 0b71532..f8a4ce2 100644
--- a/libc/arch-mips/syscalls/flistxattr.S
+++ b/libc/arch-mips/syscalls/clock_adjtime.S
@@ -2,10 +2,10 @@
 
 #include <private/bionic_asm.h>
 
-ENTRY(flistxattr)
+ENTRY(clock_adjtime)
     .set noreorder
     .cpload t9
-    li v0, __NR_flistxattr
+    li v0, __NR_clock_adjtime
     syscall
     bnez a3, 1f
     move a0, v0
@@ -16,4 +16,4 @@
     j t9
     nop
     .set reorder
-END(flistxattr)
+END(clock_adjtime)
diff --git a/libc/arch-mips64/bionic/vfork.S b/libc/arch-mips64/bionic/vfork.S
index d180a8c..e0a39ed 100644
--- a/libc/arch-mips64/bionic/vfork.S
+++ b/libc/arch-mips64/bionic/vfork.S
@@ -46,6 +46,12 @@
 	PTR_SUBU sp, FRAMESZ
 #endif
 	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
+
 	LI	a0, (CLONE_VM | CLONE_VFORK | SIGCHLD)
 	move	a1, $0
 	move	a2, $0
diff --git a/libc/arch-mips64/mips64.mk b/libc/arch-mips64/mips64.mk
index 7757385..20ee639 100644
--- a/libc/arch-mips64/mips64.mk
+++ b/libc/arch-mips64/mips64.mk
@@ -1,46 +1,11 @@
 # 64-bit mips.
 
-#
-# Default implementations of functions that are commonly optimized.
-#
-
 libc_bionic_src_files_mips64 += \
     arch-mips/string/memcmp.c \
     arch-mips/string/memcpy.S \
     arch-mips/string/memset.S \
     arch-mips/string/strcmp.S \
     arch-mips/string/strlen.c \
-    bionic/__memcpy_chk.cpp \
-    bionic/__memset_chk.cpp \
-    bionic/__strcpy_chk.cpp \
-    bionic/__strcat_chk.cpp \
-    bionic/strchr.cpp \
-    bionic/strnlen.c \
-    bionic/strrchr.cpp \
-
-libc_freebsd_src_files_mips64 += \
-    upstream-freebsd/lib/libc/string/wcscat.c \
-    upstream-freebsd/lib/libc/string/wcschr.c \
-    upstream-freebsd/lib/libc/string/wcscmp.c \
-    upstream-freebsd/lib/libc/string/wcscpy.c \
-    upstream-freebsd/lib/libc/string/wcslen.c \
-    upstream-freebsd/lib/libc/string/wcsrchr.c \
-    upstream-freebsd/lib/libc/string/wmemcmp.c \
-    upstream-freebsd/lib/libc/string/wmemmove.c \
-
-libc_openbsd_src_files_mips64 += \
-    upstream-openbsd/lib/libc/string/memchr.c \
-    upstream-openbsd/lib/libc/string/memmove.c \
-    upstream-openbsd/lib/libc/string/memrchr.c \
-    upstream-openbsd/lib/libc/string/stpcpy.c \
-    upstream-openbsd/lib/libc/string/stpncpy.c \
-    upstream-openbsd/lib/libc/string/strcat.c \
-    upstream-openbsd/lib/libc/string/strcpy.c \
-    upstream-openbsd/lib/libc/string/strlcat.c \
-    upstream-openbsd/lib/libc/string/strlcpy.c \
-    upstream-openbsd/lib/libc/string/strncat.c \
-    upstream-openbsd/lib/libc/string/strncmp.c \
-    upstream-openbsd/lib/libc/string/strncpy.c \
 
 #
 # Inherently architecture-specific code.
diff --git a/libc/arch-mips64/syscalls/flistxattr.S b/libc/arch-mips64/syscalls/___flistxattr.S
similarity index 85%
rename from libc/arch-mips64/syscalls/flistxattr.S
rename to libc/arch-mips64/syscalls/___flistxattr.S
index 1d5b1b0..586bcf7 100644
--- a/libc/arch-mips64/syscalls/flistxattr.S
+++ b/libc/arch-mips64/syscalls/___flistxattr.S
@@ -2,7 +2,7 @@
 
 #include <private/bionic_asm.h>
 
-ENTRY(flistxattr)
+ENTRY(___flistxattr)
     .set push
     .set noreorder
     li v0, __NR_flistxattr
@@ -22,4 +22,5 @@
     j t9
     move ra, t0
     .set pop
-END(flistxattr)
+END(___flistxattr)
+.hidden ___flistxattr
diff --git a/libc/arch-mips64/syscalls/mremap.S b/libc/arch-mips64/syscalls/___mremap.S
similarity index 87%
rename from libc/arch-mips64/syscalls/mremap.S
rename to libc/arch-mips64/syscalls/___mremap.S
index cf7f1de..5004d50 100644
--- a/libc/arch-mips64/syscalls/mremap.S
+++ b/libc/arch-mips64/syscalls/___mremap.S
@@ -2,7 +2,7 @@
 
 #include <private/bionic_asm.h>
 
-ENTRY(mremap)
+ENTRY(___mremap)
     .set push
     .set noreorder
     li v0, __NR_mremap
@@ -22,4 +22,5 @@
     j t9
     move ra, t0
     .set pop
-END(mremap)
+END(___mremap)
+.hidden ___mremap
diff --git a/libc/arch-mips64/syscalls/mremap.S b/libc/arch-mips64/syscalls/adjtimex.S
similarity index 85%
copy from libc/arch-mips64/syscalls/mremap.S
copy to libc/arch-mips64/syscalls/adjtimex.S
index cf7f1de..57b012c 100644
--- a/libc/arch-mips64/syscalls/mremap.S
+++ b/libc/arch-mips64/syscalls/adjtimex.S
@@ -2,10 +2,10 @@
 
 #include <private/bionic_asm.h>
 
-ENTRY(mremap)
+ENTRY(adjtimex)
     .set push
     .set noreorder
-    li v0, __NR_mremap
+    li v0, __NR_adjtimex
     syscall
     bnez a3, 1f
     move a0, v0
@@ -22,4 +22,4 @@
     j t9
     move ra, t0
     .set pop
-END(mremap)
+END(adjtimex)
diff --git a/libc/arch-mips64/syscalls/mremap.S b/libc/arch-mips64/syscalls/clock_adjtime.S
similarity index 82%
copy from libc/arch-mips64/syscalls/mremap.S
copy to libc/arch-mips64/syscalls/clock_adjtime.S
index cf7f1de..206e9fd 100644
--- a/libc/arch-mips64/syscalls/mremap.S
+++ b/libc/arch-mips64/syscalls/clock_adjtime.S
@@ -2,10 +2,10 @@
 
 #include <private/bionic_asm.h>
 
-ENTRY(mremap)
+ENTRY(clock_adjtime)
     .set push
     .set noreorder
-    li v0, __NR_mremap
+    li v0, __NR_clock_adjtime
     syscall
     bnez a3, 1f
     move a0, v0
@@ -22,4 +22,4 @@
     j t9
     move ra, t0
     .set pop
-END(mremap)
+END(clock_adjtime)
diff --git a/libc/arch-mips64/syscalls/mremap.S b/libc/arch-mips64/syscalls/preadv.S
similarity index 80%
copy from libc/arch-mips64/syscalls/mremap.S
copy to libc/arch-mips64/syscalls/preadv.S
index cf7f1de..df43a8d 100644
--- a/libc/arch-mips64/syscalls/mremap.S
+++ b/libc/arch-mips64/syscalls/preadv.S
@@ -2,10 +2,10 @@
 
 #include <private/bionic_asm.h>
 
-ENTRY(mremap)
+ENTRY(preadv)
     .set push
     .set noreorder
-    li v0, __NR_mremap
+    li v0, __NR_preadv
     syscall
     bnez a3, 1f
     move a0, v0
@@ -22,4 +22,6 @@
     j t9
     move ra, t0
     .set pop
-END(mremap)
+END(preadv)
+
+ALIAS_SYMBOL(preadv64, preadv)
diff --git a/libc/arch-mips64/syscalls/mremap.S b/libc/arch-mips64/syscalls/pwritev.S
similarity index 79%
copy from libc/arch-mips64/syscalls/mremap.S
copy to libc/arch-mips64/syscalls/pwritev.S
index cf7f1de..f55cec0 100644
--- a/libc/arch-mips64/syscalls/mremap.S
+++ b/libc/arch-mips64/syscalls/pwritev.S
@@ -2,10 +2,10 @@
 
 #include <private/bionic_asm.h>
 
-ENTRY(mremap)
+ENTRY(pwritev)
     .set push
     .set noreorder
-    li v0, __NR_mremap
+    li v0, __NR_pwritev
     syscall
     bnez a3, 1f
     move a0, v0
@@ -22,4 +22,6 @@
     j t9
     move ra, t0
     .set pop
-END(mremap)
+END(pwritev)
+
+ALIAS_SYMBOL(pwritev64, pwritev)
diff --git a/libc/arch-x86/atom/atom.mk b/libc/arch-x86/atom/atom.mk
index 3f28fb2..1afabac 100644
--- a/libc/arch-x86/atom/atom.mk
+++ b/libc/arch-x86/atom/atom.mk
@@ -1,32 +1,27 @@
 libc_bionic_src_files_x86 += \
     arch-x86/atom/string/sse2-bzero-atom.S \
-    arch-x86/atom/string/sse2-memchr-atom.S \
-    arch-x86/atom/string/sse2-memrchr-atom.S \
     arch-x86/atom/string/sse2-memset-atom.S \
-    arch-x86/atom/string/sse2-strchr-atom.S \
     arch-x86/atom/string/sse2-strlen-atom.S \
-    arch-x86/atom/string/sse2-strnlen-atom.S \
-    arch-x86/atom/string/sse2-strrchr-atom.S \
-    arch-x86/atom/string/sse2-wcschr-atom.S \
-    arch-x86/atom/string/sse2-wcsrchr-atom.S \
-    arch-x86/atom/string/sse2-wcslen-atom.S \
-    arch-x86/atom/string/sse2-wcscmp-atom.S \
     arch-x86/atom/string/ssse3-bcopy-atom.S \
     arch-x86/atom/string/ssse3-memcmp-atom.S \
     arch-x86/atom/string/ssse3-memcpy-atom.S \
     arch-x86/atom/string/ssse3-memmove-atom.S \
-    arch-x86/atom/string/ssse3-strcat-atom.S \
-    arch-x86/atom/string/ssse3-strcmp-atom.S \
     arch-x86/atom/string/ssse3-strcpy-atom.S \
-    arch-x86/atom/string/ssse3-strlcat-atom.S \
-    arch-x86/atom/string/ssse3-strlcpy-atom.S \
-    arch-x86/atom/string/ssse3-strncat-atom.S \
-    arch-x86/atom/string/ssse3-strncmp-atom.S \
     arch-x86/atom/string/ssse3-strncpy-atom.S \
-    arch-x86/atom/string/ssse3-wcscat-atom.S \
-    arch-x86/atom/string/ssse3-wcscpy-atom.S \
     arch-x86/atom/string/ssse3-wmemcmp-atom.S
 
-libc_bionic_src_files_x86 += \
-    arch-x86/silvermont/string/sse2-stpcpy-slm.S \
-    arch-x86/silvermont/string/sse2-stpncpy-slm.S
+libc_bionic_src_files_exclude_x86 += \
+    arch-x86/generic/string/memcmp.S \
+
+libc_bionic_src_files_exclude_x86 += \
+    arch-x86/silvermont/string/sse2-bcopy-slm.S \
+    arch-x86/silvermont/string/sse2-bzero-slm.S \
+    arch-x86/silvermont/string/sse2-memcpy-slm.S \
+    arch-x86/silvermont/string/sse2-memmove-slm.S \
+    arch-x86/silvermont/string/sse2-memset-slm.S \
+    arch-x86/silvermont/string/sse2-strcpy-slm.S \
+    arch-x86/silvermont/string/sse2-strlen-slm.S \
+    arch-x86/silvermont/string/sse2-strncpy-slm.S \
+
+libc_freebsd_src_files_exclude_x86 += \
+    upstream-freebsd/lib/libc/string/wmemcmp.c \
diff --git a/libc/arch-x86/atom/string/sse2-strrchr-atom.S b/libc/arch-x86/atom/string/sse2-strrchr-atom.S
index da3dc3b..e916bc1 100644
--- a/libc/arch-x86/atom/string/sse2-strrchr-atom.S
+++ b/libc/arch-x86/atom/string/sse2-strrchr-atom.S
@@ -278,7 +278,7 @@
 	jnz	L(FindZeroExit2)
 	test	$0x04, %cl
 	jnz	L(FindZeroExit3)
-	and	$1 << 4 - 1, %eax
+	and	$(1 << 4) - 1, %eax
 	jz	L(return_value)
 
 	POP	(%ebx)
@@ -296,7 +296,7 @@
 	jnz	L(FindZeroExit6)
 	test	$0x40, %cl
 	jnz	L(FindZeroExit7)
-	and	$1 << 8 - 1, %eax
+	and	$(1 << 8) - 1, %eax
 	jz	L(return_value)
 
 	POP	(%ebx)
@@ -317,7 +317,7 @@
 	jnz	L(FindZeroExit10)
 	test	$0x04, %ch
 	jnz	L(FindZeroExit11)
-	and	$1 << 12 - 1, %eax
+	and	$(1 << 12) - 1, %eax
 	jz	L(return_value)
 
 	POP	(%ebx)
@@ -335,7 +335,7 @@
 	jnz	L(FindZeroExit14)
 	test	$0x40, %ch
 	jnz	L(FindZeroExit15)
-	and	$1 << 16 - 1, %eax
+	and	$(1 << 16) - 1, %eax
 	jz	L(return_value)
 
 	POP	(%ebx)
@@ -359,7 +359,7 @@
 
 	.p2align 4
 L(FindZeroExit2):
-	and	$1 << 2 - 1, %eax
+	and	$(1 << 2) - 1, %eax
 	jz	L(return_value)
 
 	POP	(%ebx)
@@ -371,7 +371,7 @@
 
 	.p2align 4
 L(FindZeroExit3):
-	and	$1 << 3 - 1, %eax
+	and	$(1 << 3) - 1, %eax
 	jz	L(return_value)
 
 	POP	(%ebx)
@@ -383,7 +383,7 @@
 
 	.p2align 4
 L(FindZeroExit5):
-	and	$1 << 5 - 1, %eax
+	and	$(1 << 5) - 1, %eax
 	jz	L(return_value)
 
 	POP	(%ebx)
@@ -395,7 +395,7 @@
 
 	.p2align 4
 L(FindZeroExit6):
-	and	$1 << 6 - 1, %eax
+	and	$(1 << 6) - 1, %eax
 	jz	L(return_value)
 
 	POP	(%ebx)
@@ -407,7 +407,7 @@
 
 	.p2align 4
 L(FindZeroExit7):
-	and	$1 << 7 - 1, %eax
+	and	$(1 << 7) - 1, %eax
 	jz	L(return_value)
 
 	POP	(%ebx)
@@ -419,7 +419,7 @@
 
 	.p2align 4
 L(FindZeroExit9):
-	and	$1 << 9 - 1, %eax
+	and	$(1 << 9) - 1, %eax
 	jz	L(return_value)
 
 	POP	(%ebx)
@@ -431,7 +431,7 @@
 
 	.p2align 4
 L(FindZeroExit10):
-	and	$1 << 10 - 1, %eax
+	and	$(1 << 10) - 1, %eax
 	jz	L(return_value)
 
 	POP	(%ebx)
@@ -443,7 +443,7 @@
 
 	.p2align 4
 L(FindZeroExit11):
-	and	$1 << 11 - 1, %eax
+	and	$(1 << 11) - 1, %eax
 	jz	L(return_value)
 
 	POP	(%ebx)
@@ -455,7 +455,7 @@
 
 	.p2align 4
 L(FindZeroExit13):
-	and	$1 << 13 - 1, %eax
+	and	$(1 << 13) - 1, %eax
 	jz	L(return_value)
 
 	POP	(%ebx)
@@ -467,7 +467,7 @@
 
 	.p2align 4
 L(FindZeroExit14):
-	and	$1 << 14 - 1, %eax
+	and	$(1 << 14) - 1, %eax
 	jz	L(return_value)
 
 	POP	(%ebx)
@@ -479,7 +479,7 @@
 
 	.p2align 4
 L(FindZeroExit15):
-	and	$1 << 15 - 1, %eax
+	and	$(1 << 15) - 1, %eax
 	jz	L(return_value)
 
 	POP	(%ebx)
@@ -619,7 +619,7 @@
 	jnz	L(PrologFindZeroExit2)
 	test	$0x04, %cl
 	jnz	L(PrologFindZeroExit3)
-	and	$1 << 4 - 1, %eax
+	and	$(1 << 4) - 1, %eax
 	jnz	L(match_case1)
 	xor	%eax, %eax
 	RETURN
@@ -632,7 +632,7 @@
 	jnz	L(PrologFindZeroExit6)
 	test	$0x40, %cl
 	jnz	L(PrologFindZeroExit7)
-	and	$1 << 8 - 1, %eax
+	and	$(1 << 8) - 1, %eax
 	jnz	L(match_case1)
 	xor	%eax, %eax
 	RETURN
@@ -648,7 +648,7 @@
 	jnz	L(PrologFindZeroExit10)
 	test	$0x04, %ch
 	jnz	L(PrologFindZeroExit11)
-	and	$1 << 12 - 1, %eax
+	and	$(1 << 12) - 1, %eax
 	jnz	L(match_case1)
 	xor	%eax, %eax
 	RETURN
@@ -661,7 +661,7 @@
 	jnz	L(PrologFindZeroExit14)
 	test	$0x40, %ch
 	jnz	L(PrologFindZeroExit15)
-	and	$1 << 16 - 1, %eax
+	and	$(1 << 16) - 1, %eax
 	jnz	L(match_case1)
 	xor	%eax, %eax
 	RETURN
@@ -675,77 +675,77 @@
 
 	.p2align 4
 L(PrologFindZeroExit2):
-	and	$1 << 2 - 1, %eax
+	and	$(1 << 2) - 1, %eax
 	jnz	L(match_case1)
 	xor	%eax, %eax
 	RETURN
 
 	.p2align 4
 L(PrologFindZeroExit3):
-	and	$1 << 3 - 1, %eax
+	and	$(1 << 3) - 1, %eax
 	jnz	L(match_case1)
 	xor	%eax, %eax
 	RETURN
 
 	.p2align 4
 L(PrologFindZeroExit5):
-	and	$1 << 5 - 1, %eax
+	and	$(1 << 5) - 1, %eax
 	jnz	L(match_case1)
 	xor	%eax, %eax
 	RETURN
 
 	.p2align 4
 L(PrologFindZeroExit6):
-	and	$1 << 6 - 1, %eax
+	and	$(1 << 6) - 1, %eax
 	jnz	L(match_case1)
 	xor	%eax, %eax
 	RETURN
 
 	.p2align 4
 L(PrologFindZeroExit7):
-	and	$1 << 7 - 1, %eax
+	and	$(1 << 7) - 1, %eax
 	jnz	L(match_case1)
 	xor	%eax, %eax
 	RETURN
 
 	.p2align 4
 L(PrologFindZeroExit9):
-	and	$1 << 9 - 1, %eax
+	and	$(1 << 9) - 1, %eax
 	jnz	L(match_case1)
 	xor	%eax, %eax
 	RETURN
 
 	.p2align 4
 L(PrologFindZeroExit10):
-	and	$1 << 10 - 1, %eax
+	and	$(1 << 10) - 1, %eax
 	jnz	L(match_case1)
 	xor	%eax, %eax
 	RETURN
 
 	.p2align 4
 L(PrologFindZeroExit11):
-	and	$1 << 11 - 1, %eax
+	and	$(1 << 11) - 1, %eax
 	jnz	L(match_case1)
 	xor	%eax, %eax
 	RETURN
 
 	.p2align 4
 L(PrologFindZeroExit13):
-	and	$1 << 13 - 1, %eax
+	and	$(1 << 13) - 1, %eax
 	jnz	L(match_case1)
 	xor	%eax, %eax
 	RETURN
 
 	.p2align 4
 L(PrologFindZeroExit14):
-	and	$1 << 14 - 1, %eax
+	and	$(1 << 14) - 1, %eax
 	jnz	L(match_case1)
 	xor	%eax, %eax
 	RETURN
 
 	.p2align 4
 L(PrologFindZeroExit15):
-	and	$1 << 15 - 1, %eax
+	and	$(1 << 15) - 1, %eax
 	jnz	L(match_case1)
 	xor	%eax, %eax
 	RETURN
diff --git a/libc/arch-x86/atom/string/sse2-wcsrchr-atom.S b/libc/arch-x86/atom/string/sse2-wcsrchr-atom.S
index e30779d..1a55df2 100644
--- a/libc/arch-x86/atom/string/sse2-wcsrchr-atom.S
+++ b/libc/arch-x86/atom/string/sse2-wcsrchr-atom.S
@@ -280,7 +280,7 @@
 
 	.p2align 4
 L(find_zero_in_second_wchar):
-	and	$1 << 5 - 1, %eax
+	and	$(1 << 5) - 1, %eax
 	jz	L(return_value)
 
 	POP	(%esi)
@@ -296,7 +296,7 @@
 L(find_zero_in_third_or_fourth_wchar):
 	test	$15, %ch
 	jz	L(find_zero_in_fourth_wchar)
-	and	$1 << 9 - 1, %eax
+	and	$(1 << 9) - 1, %eax
 	jz	L(return_value)
 
 	POP	(%esi)
@@ -368,7 +368,7 @@
 
 	.p2align 4
 L(prolog_find_zero_in_second_wchar):
-	and	$1 << 5 - 1, %eax
+	and	$(1 << 5) - 1, %eax
 	jz	L(return_null)
 
 	test	$15 << 4, %al
@@ -380,7 +380,7 @@
 L(prolog_find_zero_in_third_or_fourth_wchar):
 	test	$15, %ch
 	jz	L(prolog_find_zero_in_fourth_wchar)
-	and	$1 << 9 - 1, %eax
+	and	$(1 << 9) - 1, %eax
 	jz	L(return_null)
 
 	test	%ah, %ah
diff --git a/libc/arch-x86/atom/string/ssse3-strcmp-atom.S b/libc/arch-x86/atom/string/ssse3-strcmp-atom.S
index 1275379..ee253b9 100644
--- a/libc/arch-x86/atom/string/ssse3-strcmp-atom.S
+++ b/libc/arch-x86/atom/string/ssse3-strcmp-atom.S
@@ -115,6 +115,7 @@
 ENTRY (STRCMP)
 #ifdef USE_AS_STRNCMP
 	PUSH	(%ebp)
+	cfi_remember_state
 #endif
 	movl	STR1(%esp), %edx
 	movl	STR2(%esp), %eax
@@ -213,9 +214,6 @@
 	PUSH	(%ebx)
 	PUSH	(%edi)
 	PUSH	(%esi)
-#ifdef USE_AS_STRNCMP
-	cfi_remember_state
-#endif
 
 	movl	%edx, %edi
 	movl	%eax, %ecx
@@ -2103,7 +2101,6 @@
 	RETURN
 
 #ifdef USE_AS_STRNCMP
-	cfi_restore_state
 	.p2align 4
 L(more8byteseq):
 	POP	(%esi)
@@ -2120,7 +2117,7 @@
 	ret
 
 #ifdef USE_AS_STRNCMP
-	CFI_PUSH (%ebp)
+	cfi_restore_state
 
 	.p2align 4
 L(less16bytes_sncmp):
diff --git a/libc/arch-x86/atom/string/ssse3-strcpy-atom.S b/libc/arch-x86/atom/string/ssse3-strcpy-atom.S
index 30254ca..3690b0d 100644
--- a/libc/arch-x86/atom/string/ssse3-strcpy-atom.S
+++ b/libc/arch-x86/atom/string/ssse3-strcpy-atom.S
@@ -3147,7 +3147,7 @@
 #endif
 
 #ifdef USE_AS_STRNCPY
-# ifndef USE_AS_STRCAT
+# if !defined(USE_AS_STRCAT) && !defined(USE_AS_STRLCPY)
 	CFI_PUSH (%esi)
 	CFI_PUSH (%edi)
 # endif
diff --git a/libc/arch-x86/bionic/setjmp.S b/libc/arch-x86/bionic/setjmp.S
index 18ad810..efb6459 100644
--- a/libc/arch-x86/bionic/setjmp.S
+++ b/libc/arch-x86/bionic/setjmp.S
@@ -32,6 +32,21 @@
 
 #include <private/bionic_asm.h>
 
+// The internal structure of a jmp_buf is totally private.
+// Current layout (changes from release to release):
+//
+// word   name            description
+// 0      edx             registers
+// 1      ebx
+// 2      esp
+// 3      ebp
+// 4      esi
+// 5      edi
+// 6      sigmask         signal mask (not used with _setjmp / _longjmp)
+// 7      sigflag/cookie  setjmp cookie in top 31 bits, signal mask flag in low bit
+// 8      checksum        checksum of the core registers, to give better error messages.
+// 9      reserved
+
 #define _JB_EDX 0
 #define _JB_EBX 1
 #define _JB_ESP 2
@@ -40,31 +55,58 @@
 #define _JB_EDI 5
 #define _JB_SIGMASK 6
 #define _JB_SIGFLAG 7
+#define _JB_CHECKSUM 8
+
+.macro m_mangle_registers reg
+  xorl \reg,%edx
+  xorl \reg,%ebx
+  xorl \reg,%esp
+  xorl \reg,%ebp
+  xorl \reg,%esi
+  xorl \reg,%edi
+.endm
+
+.macro m_unmangle_registers reg
+  m_mangle_registers \reg
+.endm
+
+.macro m_calculate_checksum dst, src
+  movl $0, \dst
+  .irp i,0,1,2,3,4,5
+    xorl (\i*4)(\src), \dst
+  .endr
+.endm
 
 ENTRY(setjmp)
   movl 4(%esp),%ecx
-  movl $1,(_JB_SIGFLAG * 4)(%ecx)
-  jmp .L_sigsetjmp_signal_mask
+  mov $1,%eax
+  jmp .L_sigsetjmp
 END(setjmp)
 
 ENTRY(_setjmp)
   movl 4(%esp),%ecx
-  movl $0,(_JB_SIGFLAG * 4)(%ecx)
-  jmp .L_sigsetjmp_no_signal_mask
+  movl $0,%eax
+  jmp .L_sigsetjmp
 END(_setjmp)
 
 ENTRY(sigsetjmp)
   movl 4(%esp),%ecx
   movl 8(%esp),%eax
 
-  // Record whether or not the signal mask is valid.
+.L_sigsetjmp:
+  PIC_PROLOGUE
+  pushl %eax
+  call PIC_PLT(__bionic_setjmp_cookie_get)
+  addl $4,%esp
+  PIC_EPILOGUE
+
+  // Record the setjmp cookie and whether or not we're saving the signal mask.
   movl %eax,(_JB_SIGFLAG * 4)(%ecx)
 
   // Do we need to save the signal mask?
-  testl %eax,%eax
+  testl $1,%eax
   jz 1f
 
-.L_sigsetjmp_signal_mask:
   // Get the current signal mask.
   PIC_PROLOGUE
   pushl $0
@@ -76,25 +118,40 @@
   movl 4(%esp),%ecx
   movl %eax,(_JB_SIGMASK * 4)(%ecx)
 
-.L_sigsetjmp_no_signal_mask:
 1:
+  // Fetch the setjmp cookie and clear the signal flag bit.
+  movl (_JB_SIGFLAG * 4)(%ecx),%eax
+  andl $-2,%eax
+
   // Save the callee-save registers.
   movl 0(%esp),%edx
+  m_mangle_registers %eax
   movl %edx,(_JB_EDX * 4)(%ecx)
   movl %ebx,(_JB_EBX * 4)(%ecx)
   movl %esp,(_JB_ESP * 4)(%ecx)
   movl %ebp,(_JB_EBP * 4)(%ecx)
   movl %esi,(_JB_ESI * 4)(%ecx)
   movl %edi,(_JB_EDI * 4)(%ecx)
+  m_unmangle_registers %eax
+
+  m_calculate_checksum %eax, %ecx
+  movl %eax, (_JB_CHECKSUM * 4)(%ecx)
 
   xorl %eax,%eax
   ret
 END(sigsetjmp)
 
 ENTRY(siglongjmp)
-  // Do we have a signal mask to restore?
   movl 4(%esp),%edx
-  cmpl $0,(_JB_SIGFLAG * 4)(%edx)
+
+  // Check the checksum before doing anything.
+  m_calculate_checksum %eax, %edx
+  xorl (_JB_CHECKSUM * 4)(%edx), %eax
+  jnz 3f
+
+  // Do we have a signal mask to restore?
+  movl (_JB_SIGFLAG * 4)(%edx), %eax
+  testl $1,%eax
   jz 1f
 
   // Restore the signal mask.
@@ -108,12 +165,31 @@
   // Restore the callee-save registers.
   movl 4(%esp),%edx
   movl 8(%esp),%eax
-  movl (_JB_EDX * 4)(%edx),%ecx
-  movl (_JB_EBX * 4)(%edx),%ebx
-  movl (_JB_ESP * 4)(%edx),%esp
-  movl (_JB_EBP * 4)(%edx),%ebp
-  movl (_JB_ESI * 4)(%edx),%esi
-  movl (_JB_EDI * 4)(%edx),%edi
+
+  movl (_JB_SIGFLAG * 4)(%edx),%ecx
+  andl $-2,%ecx
+
+  movl %ecx,%ebx
+  movl %ecx,%esp
+  movl %ecx,%ebp
+  movl %ecx,%esi
+  movl %ecx,%edi
+  xorl (_JB_EDX * 4)(%edx),%ecx
+  xorl (_JB_EBX * 4)(%edx),%ebx
+  xorl (_JB_ESP * 4)(%edx),%esp
+  xorl (_JB_EBP * 4)(%edx),%ebp
+  xorl (_JB_ESI * 4)(%edx),%esi
+  xorl (_JB_EDI * 4)(%edx),%edi
+
+  PIC_PROLOGUE
+  pushl %eax
+  pushl %ecx
+  pushl (_JB_SIGFLAG * 4)(%edx)
+  call PIC_PLT(__bionic_setjmp_cookie_check)
+  addl $4,%esp
+  popl %ecx
+  popl %eax
+  PIC_EPILOGUE
 
   testl %eax,%eax
   jnz 2f
@@ -121,6 +197,11 @@
 2:
   movl %ecx,0(%esp)
   ret
+
+3:
+  PIC_PROLOGUE
+  pushl (_JB_SIGMASK * 4)(%edx)
+  call PIC_PLT(__bionic_setjmp_checksum_mismatch)
 END(siglongjmp)
 
 ALIAS_SYMBOL(longjmp, siglongjmp)
diff --git a/libc/arch-x86/bionic/syscall.S b/libc/arch-x86/bionic/syscall.S
index 2a15102..12402ac 100644
--- a/libc/arch-x86/bionic/syscall.S
+++ b/libc/arch-x86/bionic/syscall.S
@@ -27,18 +27,25 @@
     .cfi_adjust_cfa_offset 4
     .cfi_rel_offset ebp, 0
 
+    # Get and save the system call entry address.
+    call    __kernel_syscall
+    push    %eax
+    .cfi_adjust_cfa_offset 4
+    .cfi_rel_offset eax, 0
+
     # Load all the arguments from the calling frame.
     # (Not all will be valid, depending on the syscall.)
-    mov     20(%esp),%eax
-    mov     24(%esp),%ebx
-    mov     28(%esp),%ecx
-    mov     32(%esp),%edx
-    mov     36(%esp),%esi
-    mov     40(%esp),%edi
-    mov     44(%esp),%ebp
+    mov     24(%esp),%eax
+    mov     28(%esp),%ebx
+    mov     32(%esp),%ecx
+    mov     36(%esp),%edx
+    mov     40(%esp),%esi
+    mov     44(%esp),%edi
+    mov     48(%esp),%ebp
 
     # Make the system call.
-    int     $0x80
+    call    *(%esp)
+    addl    $4, %esp
 
     # Error?
     cmpl    $-MAX_ERRNO, %eax
diff --git a/libc/arch-x86/bionic/vfork.S b/libc/arch-x86/bionic/vfork.S
index ca7af0f..5c71b8d 100644
--- a/libc/arch-x86/bionic/vfork.S
+++ b/libc/arch-x86/bionic/vfork.S
@@ -34,6 +34,12 @@
   popl    %ecx  // Grab the return address.
   .cfi_adjust_cfa_offset 4
   .cfi_rel_offset ecx, 0
+
+  // __get_tls()[TLS_SLOT_THREAD_ID]->cached_pid_ = 0
+  movl    %gs:0, %eax
+  movl    4(%eax), %eax
+  movl    $0, 12(%eax)
+
   movl    $__NR_vfork, %eax
   int     $0x80
   cmpl    $-MAX_ERRNO, %eax
diff --git a/libc/arch-x86/generic/generic.mk b/libc/arch-x86/generic/generic.mk
deleted file mode 100644
index 4aee5dc..0000000
--- a/libc/arch-x86/generic/generic.mk
+++ /dev/null
@@ -1,52 +0,0 @@
-libc_bionic_src_files_x86 += \
-    arch-x86/atom/string/sse2-memchr-atom.S \
-    arch-x86/atom/string/sse2-memrchr-atom.S \
-    arch-x86/atom/string/sse2-strchr-atom.S \
-    arch-x86/atom/string/sse2-strnlen-atom.S \
-    arch-x86/atom/string/sse2-strrchr-atom.S \
-    arch-x86/atom/string/sse2-wcschr-atom.S \
-    arch-x86/atom/string/sse2-wcsrchr-atom.S \
-    arch-x86/atom/string/sse2-wcslen-atom.S \
-    arch-x86/atom/string/sse2-wcscmp-atom.S \
-    arch-x86/silvermont/string/sse2-bcopy-slm.S \
-    arch-x86/silvermont/string/sse2-bzero-slm.S \
-    arch-x86/silvermont/string/sse2-memcpy-slm.S \
-    arch-x86/silvermont/string/sse2-memmove-slm.S \
-    arch-x86/silvermont/string/sse2-memset-slm.S \
-    arch-x86/silvermont/string/sse2-stpcpy-slm.S \
-    arch-x86/silvermont/string/sse2-stpncpy-slm.S \
-    arch-x86/silvermont/string/sse2-strcpy-slm.S \
-    arch-x86/silvermont/string/sse2-strlen-slm.S \
-    arch-x86/silvermont/string/sse2-strncpy-slm.S
-
-ifeq ($(ARCH_X86_HAVE_SSSE3),true)
-libc_bionic_src_files_x86 += \
-    arch-x86/atom/string/ssse3-strncat-atom.S \
-    arch-x86/atom/string/ssse3-strlcat-atom.S \
-    arch-x86/atom/string/ssse3-strlcpy-atom.S \
-    arch-x86/atom/string/ssse3-strcmp-atom.S \
-    arch-x86/atom/string/ssse3-strncmp-atom.S \
-    arch-x86/atom/string/ssse3-strcat-atom.S \
-    arch-x86/atom/string/ssse3-wcscat-atom.S \
-    arch-x86/atom/string/ssse3-wcscpy-atom.S
-else
-libc_bionic_src_files_x86 += \
-    arch-x86/generic/string/strcmp.S \
-    arch-x86/generic/string/strncmp.S \
-    arch-x86/generic/string/strcat.S \
-    upstream-freebsd/lib/libc/string/wcscpy.c \
-    upstream-freebsd/lib/libc/string/wcscat.c \
-    upstream-openbsd/lib/libc/string/strlcat.c \
-    upstream-openbsd/lib/libc/string/strlcpy.c \
-    upstream-openbsd/lib/libc/string/strncat.c
-endif
-
-ifeq ($(ARCH_X86_HAVE_SSE4),true)
- libc_bionic_src_files_x86 += \
-    arch-x86/silvermont/string/sse4-memcmp-slm.S \
-    arch-x86/silvermont/string/sse4-wmemcmp-slm.S
-else
-libc_bionic_src_files_x86 += \
-    arch-x86/generic/string/memcmp.S \
-    upstream-freebsd/lib/libc/string/wmemcmp.c
-endif
diff --git a/libc/arch-x86/silvermont/silvermont.mk b/libc/arch-x86/silvermont/silvermont.mk
index 176bee3..e69de29 100644
--- a/libc/arch-x86/silvermont/silvermont.mk
+++ b/libc/arch-x86/silvermont/silvermont.mk
@@ -1,32 +0,0 @@
-libc_bionic_src_files_x86 += \
-    arch-x86/silvermont/string/sse2-bcopy-slm.S \
-    arch-x86/silvermont/string/sse2-bzero-slm.S \
-    arch-x86/silvermont/string/sse2-memcpy-slm.S \
-    arch-x86/silvermont/string/sse2-memmove-slm.S \
-    arch-x86/silvermont/string/sse2-memset-slm.S \
-    arch-x86/silvermont/string/sse2-stpcpy-slm.S \
-    arch-x86/silvermont/string/sse2-stpncpy-slm.S \
-    arch-x86/silvermont/string/sse2-strcpy-slm.S \
-    arch-x86/silvermont/string/sse2-strlen-slm.S \
-    arch-x86/silvermont/string/sse2-strncpy-slm.S \
-    arch-x86/silvermont/string/sse4-memcmp-slm.S \
-    arch-x86/silvermont/string/sse4-wmemcmp-slm.S
-
-libc_bionic_src_files_x86 += \
-    arch-x86/atom/string/sse2-memchr-atom.S \
-    arch-x86/atom/string/sse2-memrchr-atom.S \
-    arch-x86/atom/string/sse2-strchr-atom.S \
-    arch-x86/atom/string/sse2-strrchr-atom.S \
-    arch-x86/atom/string/sse2-strnlen-atom.S \
-    arch-x86/atom/string/sse2-wcschr-atom.S \
-    arch-x86/atom/string/sse2-wcsrchr-atom.S \
-    arch-x86/atom/string/sse2-wcslen-atom.S \
-    arch-x86/atom/string/sse2-wcscmp-atom.S \
-    arch-x86/atom/string/ssse3-strncat-atom.S \
-    arch-x86/atom/string/ssse3-strlcat-atom.S \
-    arch-x86/atom/string/ssse3-strlcpy-atom.S \
-    arch-x86/atom/string/ssse3-strcmp-atom.S \
-    arch-x86/atom/string/ssse3-strncmp-atom.S \
-    arch-x86/atom/string/ssse3-strcat-atom.S \
-    arch-x86/atom/string/ssse3-wcscat-atom.S \
-    arch-x86/atom/string/ssse3-wcscpy-atom.S
diff --git a/libc/arch-x86/silvermont/string/sse2-memmove-slm.S b/libc/arch-x86/silvermont/string/sse2-memmove-slm.S
index b971f0b..6a8f067 100644
--- a/libc/arch-x86/silvermont/string/sse2-memmove-slm.S
+++ b/libc/arch-x86/silvermont/string/sse2-memmove-slm.S
@@ -327,6 +327,9 @@
 	movq	%xmm1, -8(%edx, %ecx)
 	jmp	L(mm_return)
 
+	CFI_POP (%edi)
+	CFI_POP (%esi)
+
 L(mm_recalc_len):
 /* Compute in %ecx how many bytes are left to copy after
 	the main loop stops.  */
diff --git a/libc/arch-x86/syscalls/___clock_nanosleep.S b/libc/arch-x86/syscalls/___clock_nanosleep.S
index 088a92e..6998749 100644
--- a/libc/arch-x86/syscalls/___clock_nanosleep.S
+++ b/libc/arch-x86/syscalls/___clock_nanosleep.S
@@ -15,12 +15,20 @@
     pushl   %esi
     .cfi_adjust_cfa_offset 4
     .cfi_rel_offset esi, 0
-    mov     20(%esp), %ebx
-    mov     24(%esp), %ecx
-    mov     28(%esp), %edx
-    mov     32(%esp), %esi
+
+    call    __kernel_syscall
+    pushl   %eax
+    .cfi_adjust_cfa_offset 4
+    .cfi_rel_offset eax, 0
+
+    mov     24(%esp), %ebx
+    mov     28(%esp), %ecx
+    mov     32(%esp), %edx
+    mov     36(%esp), %esi
     movl    $__NR_clock_nanosleep, %eax
-    int     $0x80
+    call    *(%esp)
+    addl    $4, %esp
+
     cmpl    $-MAX_ERRNO, %eax
     jb      1f
     negl    %eax
diff --git a/libc/arch-x86/syscalls/___close.S b/libc/arch-x86/syscalls/___close.S
index 796944b..b9ebdaa 100644
--- a/libc/arch-x86/syscalls/___close.S
+++ b/libc/arch-x86/syscalls/___close.S
@@ -6,9 +6,17 @@
     pushl   %ebx
     .cfi_def_cfa_offset 8
     .cfi_rel_offset ebx, 0
-    mov     8(%esp), %ebx
+
+    call    __kernel_syscall
+    pushl   %eax
+    .cfi_adjust_cfa_offset 4
+    .cfi_rel_offset eax, 0
+
+    mov     12(%esp), %ebx
     movl    $__NR_close, %eax
-    int     $0x80
+    call    *(%esp)
+    addl    $4, %esp
+
     cmpl    $-MAX_ERRNO, %eax
     jb      1f
     negl    %eax
diff --git a/libc/arch-x86/syscalls/___faccessat.S b/libc/arch-x86/syscalls/___faccessat.S
index 361a6ea..b92b03d 100644
--- a/libc/arch-x86/syscalls/___faccessat.S
+++ b/libc/arch-x86/syscalls/___faccessat.S
@@ -12,11 +12,19 @@
     pushl   %edx
     .cfi_adjust_cfa_offset 4
     .cfi_rel_offset edx, 0
-    mov     16(%esp), %ebx
-    mov     20(%esp), %ecx
-    mov     24(%esp), %edx
+
+    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_faccessat, %eax
-    int     $0x80
+    call    *(%esp)
+    addl    $4, %esp
+
     cmpl    $-MAX_ERRNO, %eax
     jb      1f
     negl    %eax
diff --git a/libc/arch-x86/syscalls/___fchmod.S b/libc/arch-x86/syscalls/___fchmod.S
index 119a695..92e864c 100644
--- a/libc/arch-x86/syscalls/___fchmod.S
+++ b/libc/arch-x86/syscalls/___fchmod.S
@@ -9,10 +9,18 @@
     pushl   %ecx
     .cfi_adjust_cfa_offset 4
     .cfi_rel_offset ecx, 0
-    mov     12(%esp), %ebx
-    mov     16(%esp), %ecx
+
+    call    __kernel_syscall
+    pushl   %eax
+    .cfi_adjust_cfa_offset 4
+    .cfi_rel_offset eax, 0
+
+    mov     16(%esp), %ebx
+    mov     20(%esp), %ecx
     movl    $__NR_fchmod, %eax
-    int     $0x80
+    call    *(%esp)
+    addl    $4, %esp
+
     cmpl    $-MAX_ERRNO, %eax
     jb      1f
     negl    %eax
diff --git a/libc/arch-x86/syscalls/___fchmodat.S b/libc/arch-x86/syscalls/___fchmodat.S
index b15bb64..81edf96 100644
--- a/libc/arch-x86/syscalls/___fchmodat.S
+++ b/libc/arch-x86/syscalls/___fchmodat.S
@@ -12,11 +12,19 @@
     pushl   %edx
     .cfi_adjust_cfa_offset 4
     .cfi_rel_offset edx, 0
-    mov     16(%esp), %ebx
-    mov     20(%esp), %ecx
-    mov     24(%esp), %edx
+
+    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_fchmodat, %eax
-    int     $0x80
+    call    *(%esp)
+    addl    $4, %esp
+
     cmpl    $-MAX_ERRNO, %eax
     jb      1f
     negl    %eax
diff --git a/libc/arch-x86/syscalls/___fgetxattr.S b/libc/arch-x86/syscalls/___fgetxattr.S
index 2891511..712728d 100644
--- a/libc/arch-x86/syscalls/___fgetxattr.S
+++ b/libc/arch-x86/syscalls/___fgetxattr.S
@@ -15,12 +15,20 @@
     pushl   %esi
     .cfi_adjust_cfa_offset 4
     .cfi_rel_offset esi, 0
-    mov     20(%esp), %ebx
-    mov     24(%esp), %ecx
-    mov     28(%esp), %edx
-    mov     32(%esp), %esi
+
+    call    __kernel_syscall
+    pushl   %eax
+    .cfi_adjust_cfa_offset 4
+    .cfi_rel_offset eax, 0
+
+    mov     24(%esp), %ebx
+    mov     28(%esp), %ecx
+    mov     32(%esp), %edx
+    mov     36(%esp), %esi
     movl    $__NR_fgetxattr, %eax
-    int     $0x80
+    call    *(%esp)
+    addl    $4, %esp
+
     cmpl    $-MAX_ERRNO, %eax
     jb      1f
     negl    %eax
diff --git a/libc/arch-x86/syscalls/mremap.S b/libc/arch-x86/syscalls/___flistxattr.S
similarity index 73%
rename from libc/arch-x86/syscalls/mremap.S
rename to libc/arch-x86/syscalls/___flistxattr.S
index 869ef5d..a22ef35 100644
--- a/libc/arch-x86/syscalls/mremap.S
+++ b/libc/arch-x86/syscalls/___flistxattr.S
@@ -2,7 +2,7 @@
 
 #include <private/bionic_asm.h>
 
-ENTRY(mremap)
+ENTRY(___flistxattr)
     pushl   %ebx
     .cfi_def_cfa_offset 8
     .cfi_rel_offset ebx, 0
@@ -12,15 +12,19 @@
     pushl   %edx
     .cfi_adjust_cfa_offset 4
     .cfi_rel_offset edx, 0
-    pushl   %esi
+
+    call    __kernel_syscall
+    pushl   %eax
     .cfi_adjust_cfa_offset 4
-    .cfi_rel_offset esi, 0
+    .cfi_rel_offset eax, 0
+
     mov     20(%esp), %ebx
     mov     24(%esp), %ecx
     mov     28(%esp), %edx
-    mov     32(%esp), %esi
-    movl    $__NR_mremap, %eax
-    int     $0x80
+    movl    $__NR_flistxattr, %eax
+    call    *(%esp)
+    addl    $4, %esp
+
     cmpl    $-MAX_ERRNO, %eax
     jb      1f
     negl    %eax
@@ -28,9 +32,9 @@
     call    __set_errno_internal
     addl    $4, %esp
 1:
-    popl    %esi
     popl    %edx
     popl    %ecx
     popl    %ebx
     ret
-END(mremap)
+END(___flistxattr)
+.hidden ___flistxattr
diff --git a/libc/arch-x86/syscalls/___fsetxattr.S b/libc/arch-x86/syscalls/___fsetxattr.S
index 287dafc..b90c972 100644
--- a/libc/arch-x86/syscalls/___fsetxattr.S
+++ b/libc/arch-x86/syscalls/___fsetxattr.S
@@ -18,13 +18,21 @@
     pushl   %edi
     .cfi_adjust_cfa_offset 4
     .cfi_rel_offset edi, 0
-    mov     24(%esp), %ebx
-    mov     28(%esp), %ecx
-    mov     32(%esp), %edx
-    mov     36(%esp), %esi
-    mov     40(%esp), %edi
+
+    call    __kernel_syscall
+    pushl   %eax
+    .cfi_adjust_cfa_offset 4
+    .cfi_rel_offset eax, 0
+
+    mov     28(%esp), %ebx
+    mov     32(%esp), %ecx
+    mov     36(%esp), %edx
+    mov     40(%esp), %esi
+    mov     44(%esp), %edi
     movl    $__NR_fsetxattr, %eax
-    int     $0x80
+    call    *(%esp)
+    addl    $4, %esp
+
     cmpl    $-MAX_ERRNO, %eax
     jb      1f
     negl    %eax
diff --git a/libc/arch-x86/syscalls/___mremap.S b/libc/arch-x86/syscalls/___mremap.S
new file mode 100644
index 0000000..9d9bfcb
--- /dev/null
+++ b/libc/arch-x86/syscalls/___mremap.S
@@ -0,0 +1,50 @@
+/* Generated by gensyscalls.py. Do not edit. */
+
+#include <private/bionic_asm.h>
+
+ENTRY(___mremap)
+    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
+    pushl   %esi
+    .cfi_adjust_cfa_offset 4
+    .cfi_rel_offset esi, 0
+    pushl   %edi
+    .cfi_adjust_cfa_offset 4
+    .cfi_rel_offset edi, 0
+
+    call    __kernel_syscall
+    pushl   %eax
+    .cfi_adjust_cfa_offset 4
+    .cfi_rel_offset eax, 0
+
+    mov     28(%esp), %ebx
+    mov     32(%esp), %ecx
+    mov     36(%esp), %edx
+    mov     40(%esp), %esi
+    mov     44(%esp), %edi
+    movl    $__NR_mremap, %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    %edi
+    popl    %esi
+    popl    %edx
+    popl    %ecx
+    popl    %ebx
+    ret
+END(___mremap)
+.hidden ___mremap
diff --git a/libc/arch-x86/syscalls/___rt_sigqueueinfo.S b/libc/arch-x86/syscalls/___rt_sigqueueinfo.S
index 97d167f..e299707 100644
--- a/libc/arch-x86/syscalls/___rt_sigqueueinfo.S
+++ b/libc/arch-x86/syscalls/___rt_sigqueueinfo.S
@@ -12,11 +12,19 @@
     pushl   %edx
     .cfi_adjust_cfa_offset 4
     .cfi_rel_offset edx, 0
-    mov     16(%esp), %ebx
-    mov     20(%esp), %ecx
-    mov     24(%esp), %edx
+
+    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_rt_sigqueueinfo, %eax
-    int     $0x80
+    call    *(%esp)
+    addl    $4, %esp
+
     cmpl    $-MAX_ERRNO, %eax
     jb      1f
     negl    %eax
diff --git a/libc/arch-x86/syscalls/__accept4.S b/libc/arch-x86/syscalls/__accept4.S
index 7b16dd4..112a8a7 100644
--- a/libc/arch-x86/syscalls/__accept4.S
+++ b/libc/arch-x86/syscalls/__accept4.S
@@ -9,11 +9,19 @@
     pushl   %ecx
     .cfi_adjust_cfa_offset 4
     .cfi_rel_offset ecx, 0
+
+    call    __kernel_syscall
+    pushl   %eax
+    .cfi_adjust_cfa_offset 4
+    .cfi_rel_offset eax, 0
+
     mov     $18, %ebx
     mov     %esp, %ecx
-    addl    $12, %ecx
+    addl    $16, %ecx
     movl    $__NR_socketcall, %eax
-    int     $0x80
+    call    *(%esp)
+    addl    $4, %esp
+
     cmpl    $-MAX_ERRNO, %eax
     jb      1f
     negl    %eax
diff --git a/libc/arch-x86/syscalls/__brk.S b/libc/arch-x86/syscalls/__brk.S
index 22acdad..bf2f1d2 100644
--- a/libc/arch-x86/syscalls/__brk.S
+++ b/libc/arch-x86/syscalls/__brk.S
@@ -6,9 +6,17 @@
     pushl   %ebx
     .cfi_def_cfa_offset 8
     .cfi_rel_offset ebx, 0
-    mov     8(%esp), %ebx
+
+    call    __kernel_syscall
+    pushl   %eax
+    .cfi_adjust_cfa_offset 4
+    .cfi_rel_offset eax, 0
+
+    mov     12(%esp), %ebx
     movl    $__NR_brk, %eax
-    int     $0x80
+    call    *(%esp)
+    addl    $4, %esp
+
     cmpl    $-MAX_ERRNO, %eax
     jb      1f
     negl    %eax
diff --git a/libc/arch-x86/syscalls/flistxattr.S b/libc/arch-x86/syscalls/__clock_gettime.S
similarity index 70%
copy from libc/arch-x86/syscalls/flistxattr.S
copy to libc/arch-x86/syscalls/__clock_gettime.S
index fc81a37..0c0c1c4 100644
--- a/libc/arch-x86/syscalls/flistxattr.S
+++ b/libc/arch-x86/syscalls/__clock_gettime.S
@@ -2,21 +2,25 @@
 
 #include <private/bionic_asm.h>
 
-ENTRY(flistxattr)
+ENTRY(__clock_gettime)
     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
+
+    call    __kernel_syscall
+    pushl   %eax
     .cfi_adjust_cfa_offset 4
-    .cfi_rel_offset edx, 0
+    .cfi_rel_offset eax, 0
+
     mov     16(%esp), %ebx
     mov     20(%esp), %ecx
-    mov     24(%esp), %edx
-    movl    $__NR_flistxattr, %eax
-    int     $0x80
+    movl    $__NR_clock_gettime, %eax
+    call    *(%esp)
+    addl    $4, %esp
+
     cmpl    $-MAX_ERRNO, %eax
     jb      1f
     negl    %eax
@@ -24,8 +28,7 @@
     call    __set_errno_internal
     addl    $4, %esp
 1:
-    popl    %edx
     popl    %ecx
     popl    %ebx
     ret
-END(flistxattr)
+END(__clock_gettime)
diff --git a/libc/arch-x86/syscalls/__connect.S b/libc/arch-x86/syscalls/__connect.S
index 475d452..5ea160c 100644
--- a/libc/arch-x86/syscalls/__connect.S
+++ b/libc/arch-x86/syscalls/__connect.S
@@ -9,11 +9,19 @@
     pushl   %ecx
     .cfi_adjust_cfa_offset 4
     .cfi_rel_offset ecx, 0
+
+    call    __kernel_syscall
+    pushl   %eax
+    .cfi_adjust_cfa_offset 4
+    .cfi_rel_offset eax, 0
+
     mov     $3, %ebx
     mov     %esp, %ecx
-    addl    $12, %ecx
+    addl    $16, %ecx
     movl    $__NR_socketcall, %eax
-    int     $0x80
+    call    *(%esp)
+    addl    $4, %esp
+
     cmpl    $-MAX_ERRNO, %eax
     jb      1f
     negl    %eax
diff --git a/libc/arch-x86/syscalls/__epoll_pwait.S b/libc/arch-x86/syscalls/__epoll_pwait.S
index 171caa5..3750760 100644
--- a/libc/arch-x86/syscalls/__epoll_pwait.S
+++ b/libc/arch-x86/syscalls/__epoll_pwait.S
@@ -21,14 +21,22 @@
     pushl   %ebp
     .cfi_adjust_cfa_offset 4
     .cfi_rel_offset ebp, 0
-    mov     28(%esp), %ebx
-    mov     32(%esp), %ecx
-    mov     36(%esp), %edx
-    mov     40(%esp), %esi
-    mov     44(%esp), %edi
-    mov     48(%esp), %ebp
+
+    call    __kernel_syscall
+    pushl   %eax
+    .cfi_adjust_cfa_offset 4
+    .cfi_rel_offset eax, 0
+
+    mov     32(%esp), %ebx
+    mov     36(%esp), %ecx
+    mov     40(%esp), %edx
+    mov     44(%esp), %esi
+    mov     48(%esp), %edi
+    mov     52(%esp), %ebp
     movl    $__NR_epoll_pwait, %eax
-    int     $0x80
+    call    *(%esp)
+    addl    $4, %esp
+
     cmpl    $-MAX_ERRNO, %eax
     jb      1f
     negl    %eax
diff --git a/libc/arch-x86/syscalls/__exit.S b/libc/arch-x86/syscalls/__exit.S
index 8cf3663..841c8cf 100644
--- a/libc/arch-x86/syscalls/__exit.S
+++ b/libc/arch-x86/syscalls/__exit.S
@@ -6,9 +6,17 @@
     pushl   %ebx
     .cfi_def_cfa_offset 8
     .cfi_rel_offset ebx, 0
-    mov     8(%esp), %ebx
+
+    call    __kernel_syscall
+    pushl   %eax
+    .cfi_adjust_cfa_offset 4
+    .cfi_rel_offset eax, 0
+
+    mov     12(%esp), %ebx
     movl    $__NR_exit, %eax
-    int     $0x80
+    call    *(%esp)
+    addl    $4, %esp
+
     cmpl    $-MAX_ERRNO, %eax
     jb      1f
     negl    %eax
diff --git a/libc/arch-x86/syscalls/__fadvise64.S b/libc/arch-x86/syscalls/__fadvise64.S
index 6e4298a..d580a61 100644
--- a/libc/arch-x86/syscalls/__fadvise64.S
+++ b/libc/arch-x86/syscalls/__fadvise64.S
@@ -21,14 +21,22 @@
     pushl   %ebp
     .cfi_adjust_cfa_offset 4
     .cfi_rel_offset ebp, 0
-    mov     28(%esp), %ebx
-    mov     32(%esp), %ecx
-    mov     36(%esp), %edx
-    mov     40(%esp), %esi
-    mov     44(%esp), %edi
-    mov     48(%esp), %ebp
+
+    call    __kernel_syscall
+    pushl   %eax
+    .cfi_adjust_cfa_offset 4
+    .cfi_rel_offset eax, 0
+
+    mov     32(%esp), %ebx
+    mov     36(%esp), %ecx
+    mov     40(%esp), %edx
+    mov     44(%esp), %esi
+    mov     48(%esp), %edi
+    mov     52(%esp), %ebp
     movl    $__NR_fadvise64_64, %eax
-    int     $0x80
+    call    *(%esp)
+    addl    $4, %esp
+
     cmpl    $-MAX_ERRNO, %eax
     jb      1f
     negl    %eax
diff --git a/libc/arch-x86/syscalls/__fcntl64.S b/libc/arch-x86/syscalls/__fcntl64.S
index d900a52..c886411 100644
--- a/libc/arch-x86/syscalls/__fcntl64.S
+++ b/libc/arch-x86/syscalls/__fcntl64.S
@@ -12,11 +12,19 @@
     pushl   %edx
     .cfi_adjust_cfa_offset 4
     .cfi_rel_offset edx, 0
-    mov     16(%esp), %ebx
-    mov     20(%esp), %ecx
-    mov     24(%esp), %edx
+
+    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_fcntl64, %eax
-    int     $0x80
+    call    *(%esp)
+    addl    $4, %esp
+
     cmpl    $-MAX_ERRNO, %eax
     jb      1f
     negl    %eax
diff --git a/libc/arch-x86/syscalls/__fstatfs64.S b/libc/arch-x86/syscalls/__fstatfs64.S
index 9b44743..2c97435 100644
--- a/libc/arch-x86/syscalls/__fstatfs64.S
+++ b/libc/arch-x86/syscalls/__fstatfs64.S
@@ -12,11 +12,19 @@
     pushl   %edx
     .cfi_adjust_cfa_offset 4
     .cfi_rel_offset edx, 0
-    mov     16(%esp), %ebx
-    mov     20(%esp), %ecx
-    mov     24(%esp), %edx
+
+    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_fstatfs64, %eax
-    int     $0x80
+    call    *(%esp)
+    addl    $4, %esp
+
     cmpl    $-MAX_ERRNO, %eax
     jb      1f
     negl    %eax
diff --git a/libc/arch-x86/syscalls/__getcpu.S b/libc/arch-x86/syscalls/__getcpu.S
index bb4c41f..fde7306 100644
--- a/libc/arch-x86/syscalls/__getcpu.S
+++ b/libc/arch-x86/syscalls/__getcpu.S
@@ -12,11 +12,19 @@
     pushl   %edx
     .cfi_adjust_cfa_offset 4
     .cfi_rel_offset edx, 0
-    mov     16(%esp), %ebx
-    mov     20(%esp), %ecx
-    mov     24(%esp), %edx
+
+    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_getcpu, %eax
-    int     $0x80
+    call    *(%esp)
+    addl    $4, %esp
+
     cmpl    $-MAX_ERRNO, %eax
     jb      1f
     negl    %eax
diff --git a/libc/arch-x86/syscalls/__getcwd.S b/libc/arch-x86/syscalls/__getcwd.S
index 8decd99..dc0bded 100644
--- a/libc/arch-x86/syscalls/__getcwd.S
+++ b/libc/arch-x86/syscalls/__getcwd.S
@@ -9,10 +9,18 @@
     pushl   %ecx
     .cfi_adjust_cfa_offset 4
     .cfi_rel_offset ecx, 0
-    mov     12(%esp), %ebx
-    mov     16(%esp), %ecx
+
+    call    __kernel_syscall
+    pushl   %eax
+    .cfi_adjust_cfa_offset 4
+    .cfi_rel_offset eax, 0
+
+    mov     16(%esp), %ebx
+    mov     20(%esp), %ecx
     movl    $__NR_getcwd, %eax
-    int     $0x80
+    call    *(%esp)
+    addl    $4, %esp
+
     cmpl    $-MAX_ERRNO, %eax
     jb      1f
     negl    %eax
diff --git a/libc/arch-x86/syscalls/__getdents64.S b/libc/arch-x86/syscalls/__getdents64.S
index 5190a68..4228da2 100644
--- a/libc/arch-x86/syscalls/__getdents64.S
+++ b/libc/arch-x86/syscalls/__getdents64.S
@@ -12,11 +12,19 @@
     pushl   %edx
     .cfi_adjust_cfa_offset 4
     .cfi_rel_offset edx, 0
-    mov     16(%esp), %ebx
-    mov     20(%esp), %ecx
-    mov     24(%esp), %edx
+
+    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_getdents64, %eax
-    int     $0x80
+    call    *(%esp)
+    addl    $4, %esp
+
     cmpl    $-MAX_ERRNO, %eax
     jb      1f
     negl    %eax
diff --git a/libc/arch-x86/syscalls/__getpid.S b/libc/arch-x86/syscalls/__getpid.S
index 197202c..aa5d343 100644
--- a/libc/arch-x86/syscalls/__getpid.S
+++ b/libc/arch-x86/syscalls/__getpid.S
@@ -3,8 +3,16 @@
 #include <private/bionic_asm.h>
 
 ENTRY(__getpid)
+
+    call    __kernel_syscall
+    pushl   %eax
+    .cfi_adjust_cfa_offset 4
+    .cfi_rel_offset eax, 0
+
     movl    $__NR_getpid, %eax
-    int     $0x80
+    call    *(%esp)
+    addl    $4, %esp
+
     cmpl    $-MAX_ERRNO, %eax
     jb      1f
     negl    %eax
diff --git a/libc/arch-x86/syscalls/__getpriority.S b/libc/arch-x86/syscalls/__getpriority.S
index dd5591f..cf2fbc3 100644
--- a/libc/arch-x86/syscalls/__getpriority.S
+++ b/libc/arch-x86/syscalls/__getpriority.S
@@ -9,10 +9,18 @@
     pushl   %ecx
     .cfi_adjust_cfa_offset 4
     .cfi_rel_offset ecx, 0
-    mov     12(%esp), %ebx
-    mov     16(%esp), %ecx
+
+    call    __kernel_syscall
+    pushl   %eax
+    .cfi_adjust_cfa_offset 4
+    .cfi_rel_offset eax, 0
+
+    mov     16(%esp), %ebx
+    mov     20(%esp), %ecx
     movl    $__NR_getpriority, %eax
-    int     $0x80
+    call    *(%esp)
+    addl    $4, %esp
+
     cmpl    $-MAX_ERRNO, %eax
     jb      1f
     negl    %eax
diff --git a/libc/arch-x86/syscalls/flistxattr.S b/libc/arch-x86/syscalls/__gettimeofday.S
similarity index 71%
copy from libc/arch-x86/syscalls/flistxattr.S
copy to libc/arch-x86/syscalls/__gettimeofday.S
index fc81a37..4e24cdd6 100644
--- a/libc/arch-x86/syscalls/flistxattr.S
+++ b/libc/arch-x86/syscalls/__gettimeofday.S
@@ -2,21 +2,25 @@
 
 #include <private/bionic_asm.h>
 
-ENTRY(flistxattr)
+ENTRY(__gettimeofday)
     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
+
+    call    __kernel_syscall
+    pushl   %eax
     .cfi_adjust_cfa_offset 4
-    .cfi_rel_offset edx, 0
+    .cfi_rel_offset eax, 0
+
     mov     16(%esp), %ebx
     mov     20(%esp), %ecx
-    mov     24(%esp), %edx
-    movl    $__NR_flistxattr, %eax
-    int     $0x80
+    movl    $__NR_gettimeofday, %eax
+    call    *(%esp)
+    addl    $4, %esp
+
     cmpl    $-MAX_ERRNO, %eax
     jb      1f
     negl    %eax
@@ -24,8 +28,7 @@
     call    __set_errno_internal
     addl    $4, %esp
 1:
-    popl    %edx
     popl    %ecx
     popl    %ebx
     ret
-END(flistxattr)
+END(__gettimeofday)
diff --git a/libc/arch-x86/syscalls/__ioctl.S b/libc/arch-x86/syscalls/__ioctl.S
index b6ee9f2..2189638 100644
--- a/libc/arch-x86/syscalls/__ioctl.S
+++ b/libc/arch-x86/syscalls/__ioctl.S
@@ -12,11 +12,19 @@
     pushl   %edx
     .cfi_adjust_cfa_offset 4
     .cfi_rel_offset edx, 0
-    mov     16(%esp), %ebx
-    mov     20(%esp), %ecx
-    mov     24(%esp), %edx
+
+    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_ioctl, %eax
-    int     $0x80
+    call    *(%esp)
+    addl    $4, %esp
+
     cmpl    $-MAX_ERRNO, %eax
     jb      1f
     negl    %eax
diff --git a/libc/arch-x86/syscalls/__llseek.S b/libc/arch-x86/syscalls/__llseek.S
index 5cc907a..9213891 100644
--- a/libc/arch-x86/syscalls/__llseek.S
+++ b/libc/arch-x86/syscalls/__llseek.S
@@ -18,13 +18,21 @@
     pushl   %edi
     .cfi_adjust_cfa_offset 4
     .cfi_rel_offset edi, 0
-    mov     24(%esp), %ebx
-    mov     28(%esp), %ecx
-    mov     32(%esp), %edx
-    mov     36(%esp), %esi
-    mov     40(%esp), %edi
+
+    call    __kernel_syscall
+    pushl   %eax
+    .cfi_adjust_cfa_offset 4
+    .cfi_rel_offset eax, 0
+
+    mov     28(%esp), %ebx
+    mov     32(%esp), %ecx
+    mov     36(%esp), %edx
+    mov     40(%esp), %esi
+    mov     44(%esp), %edi
     movl    $__NR__llseek, %eax
-    int     $0x80
+    call    *(%esp)
+    addl    $4, %esp
+
     cmpl    $-MAX_ERRNO, %eax
     jb      1f
     negl    %eax
diff --git a/libc/arch-x86/syscalls/__mmap2.S b/libc/arch-x86/syscalls/__mmap2.S
index 08314c8..0904a3d 100644
--- a/libc/arch-x86/syscalls/__mmap2.S
+++ b/libc/arch-x86/syscalls/__mmap2.S
@@ -21,14 +21,22 @@
     pushl   %ebp
     .cfi_adjust_cfa_offset 4
     .cfi_rel_offset ebp, 0
-    mov     28(%esp), %ebx
-    mov     32(%esp), %ecx
-    mov     36(%esp), %edx
-    mov     40(%esp), %esi
-    mov     44(%esp), %edi
-    mov     48(%esp), %ebp
+
+    call    __kernel_syscall
+    pushl   %eax
+    .cfi_adjust_cfa_offset 4
+    .cfi_rel_offset eax, 0
+
+    mov     32(%esp), %ebx
+    mov     36(%esp), %ecx
+    mov     40(%esp), %edx
+    mov     44(%esp), %esi
+    mov     48(%esp), %edi
+    mov     52(%esp), %ebp
     movl    $__NR_mmap2, %eax
-    int     $0x80
+    call    *(%esp)
+    addl    $4, %esp
+
     cmpl    $-MAX_ERRNO, %eax
     jb      1f
     negl    %eax
diff --git a/libc/arch-x86/syscalls/__openat.S b/libc/arch-x86/syscalls/__openat.S
index 4c11709..03c03bd 100644
--- a/libc/arch-x86/syscalls/__openat.S
+++ b/libc/arch-x86/syscalls/__openat.S
@@ -15,12 +15,20 @@
     pushl   %esi
     .cfi_adjust_cfa_offset 4
     .cfi_rel_offset esi, 0
-    mov     20(%esp), %ebx
-    mov     24(%esp), %ecx
-    mov     28(%esp), %edx
-    mov     32(%esp), %esi
+
+    call    __kernel_syscall
+    pushl   %eax
+    .cfi_adjust_cfa_offset 4
+    .cfi_rel_offset eax, 0
+
+    mov     24(%esp), %ebx
+    mov     28(%esp), %ecx
+    mov     32(%esp), %edx
+    mov     36(%esp), %esi
     movl    $__NR_openat, %eax
-    int     $0x80
+    call    *(%esp)
+    addl    $4, %esp
+
     cmpl    $-MAX_ERRNO, %eax
     jb      1f
     negl    %eax
diff --git a/libc/arch-x86/syscalls/__ppoll.S b/libc/arch-x86/syscalls/__ppoll.S
index 2a1f76e..1a55b03 100644
--- a/libc/arch-x86/syscalls/__ppoll.S
+++ b/libc/arch-x86/syscalls/__ppoll.S
@@ -18,13 +18,21 @@
     pushl   %edi
     .cfi_adjust_cfa_offset 4
     .cfi_rel_offset edi, 0
-    mov     24(%esp), %ebx
-    mov     28(%esp), %ecx
-    mov     32(%esp), %edx
-    mov     36(%esp), %esi
-    mov     40(%esp), %edi
+
+    call    __kernel_syscall
+    pushl   %eax
+    .cfi_adjust_cfa_offset 4
+    .cfi_rel_offset eax, 0
+
+    mov     28(%esp), %ebx
+    mov     32(%esp), %ecx
+    mov     36(%esp), %edx
+    mov     40(%esp), %esi
+    mov     44(%esp), %edi
     movl    $__NR_ppoll, %eax
-    int     $0x80
+    call    *(%esp)
+    addl    $4, %esp
+
     cmpl    $-MAX_ERRNO, %eax
     jb      1f
     negl    %eax
diff --git a/libc/arch-x86/syscalls/__preadv64.S b/libc/arch-x86/syscalls/__preadv64.S
new file mode 100644
index 0000000..5db22a3
--- /dev/null
+++ b/libc/arch-x86/syscalls/__preadv64.S
@@ -0,0 +1,49 @@
+/* Generated by gensyscalls.py. Do not edit. */
+
+#include <private/bionic_asm.h>
+
+ENTRY(__preadv64)
+    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
+    pushl   %esi
+    .cfi_adjust_cfa_offset 4
+    .cfi_rel_offset esi, 0
+    pushl   %edi
+    .cfi_adjust_cfa_offset 4
+    .cfi_rel_offset edi, 0
+
+    call    __kernel_syscall
+    pushl   %eax
+    .cfi_adjust_cfa_offset 4
+    .cfi_rel_offset eax, 0
+
+    mov     28(%esp), %ebx
+    mov     32(%esp), %ecx
+    mov     36(%esp), %edx
+    mov     40(%esp), %esi
+    mov     44(%esp), %edi
+    movl    $__NR_preadv, %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    %edi
+    popl    %esi
+    popl    %edx
+    popl    %ecx
+    popl    %ebx
+    ret
+END(__preadv64)
diff --git a/libc/arch-x86/syscalls/__pselect6.S b/libc/arch-x86/syscalls/__pselect6.S
index 8ff102a..18327fd 100644
--- a/libc/arch-x86/syscalls/__pselect6.S
+++ b/libc/arch-x86/syscalls/__pselect6.S
@@ -21,14 +21,22 @@
     pushl   %ebp
     .cfi_adjust_cfa_offset 4
     .cfi_rel_offset ebp, 0
-    mov     28(%esp), %ebx
-    mov     32(%esp), %ecx
-    mov     36(%esp), %edx
-    mov     40(%esp), %esi
-    mov     44(%esp), %edi
-    mov     48(%esp), %ebp
+
+    call    __kernel_syscall
+    pushl   %eax
+    .cfi_adjust_cfa_offset 4
+    .cfi_rel_offset eax, 0
+
+    mov     32(%esp), %ebx
+    mov     36(%esp), %ecx
+    mov     40(%esp), %edx
+    mov     44(%esp), %esi
+    mov     48(%esp), %edi
+    mov     52(%esp), %ebp
     movl    $__NR_pselect6, %eax
-    int     $0x80
+    call    *(%esp)
+    addl    $4, %esp
+
     cmpl    $-MAX_ERRNO, %eax
     jb      1f
     negl    %eax
diff --git a/libc/arch-x86/syscalls/__ptrace.S b/libc/arch-x86/syscalls/__ptrace.S
index d982cec..a522e95 100644
--- a/libc/arch-x86/syscalls/__ptrace.S
+++ b/libc/arch-x86/syscalls/__ptrace.S
@@ -15,12 +15,20 @@
     pushl   %esi
     .cfi_adjust_cfa_offset 4
     .cfi_rel_offset esi, 0
-    mov     20(%esp), %ebx
-    mov     24(%esp), %ecx
-    mov     28(%esp), %edx
-    mov     32(%esp), %esi
+
+    call    __kernel_syscall
+    pushl   %eax
+    .cfi_adjust_cfa_offset 4
+    .cfi_rel_offset eax, 0
+
+    mov     24(%esp), %ebx
+    mov     28(%esp), %ecx
+    mov     32(%esp), %edx
+    mov     36(%esp), %esi
     movl    $__NR_ptrace, %eax
-    int     $0x80
+    call    *(%esp)
+    addl    $4, %esp
+
     cmpl    $-MAX_ERRNO, %eax
     jb      1f
     negl    %eax
diff --git a/libc/arch-x86/syscalls/__pwritev64.S b/libc/arch-x86/syscalls/__pwritev64.S
new file mode 100644
index 0000000..19f1865
--- /dev/null
+++ b/libc/arch-x86/syscalls/__pwritev64.S
@@ -0,0 +1,49 @@
+/* Generated by gensyscalls.py. Do not edit. */
+
+#include <private/bionic_asm.h>
+
+ENTRY(__pwritev64)
+    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
+    pushl   %esi
+    .cfi_adjust_cfa_offset 4
+    .cfi_rel_offset esi, 0
+    pushl   %edi
+    .cfi_adjust_cfa_offset 4
+    .cfi_rel_offset edi, 0
+
+    call    __kernel_syscall
+    pushl   %eax
+    .cfi_adjust_cfa_offset 4
+    .cfi_rel_offset eax, 0
+
+    mov     28(%esp), %ebx
+    mov     32(%esp), %ecx
+    mov     36(%esp), %edx
+    mov     40(%esp), %esi
+    mov     44(%esp), %edi
+    movl    $__NR_pwritev, %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    %edi
+    popl    %esi
+    popl    %edx
+    popl    %ecx
+    popl    %ebx
+    ret
+END(__pwritev64)
diff --git a/libc/arch-x86/syscalls/__reboot.S b/libc/arch-x86/syscalls/__reboot.S
index 3d169bf..711a4e6 100644
--- a/libc/arch-x86/syscalls/__reboot.S
+++ b/libc/arch-x86/syscalls/__reboot.S
@@ -15,12 +15,20 @@
     pushl   %esi
     .cfi_adjust_cfa_offset 4
     .cfi_rel_offset esi, 0
-    mov     20(%esp), %ebx
-    mov     24(%esp), %ecx
-    mov     28(%esp), %edx
-    mov     32(%esp), %esi
+
+    call    __kernel_syscall
+    pushl   %eax
+    .cfi_adjust_cfa_offset 4
+    .cfi_rel_offset eax, 0
+
+    mov     24(%esp), %ebx
+    mov     28(%esp), %ecx
+    mov     32(%esp), %edx
+    mov     36(%esp), %esi
     movl    $__NR_reboot, %eax
-    int     $0x80
+    call    *(%esp)
+    addl    $4, %esp
+
     cmpl    $-MAX_ERRNO, %eax
     jb      1f
     negl    %eax
diff --git a/libc/arch-x86/syscalls/__rt_sigaction.S b/libc/arch-x86/syscalls/__rt_sigaction.S
index 59c3882..ebc431d 100644
--- a/libc/arch-x86/syscalls/__rt_sigaction.S
+++ b/libc/arch-x86/syscalls/__rt_sigaction.S
@@ -15,12 +15,20 @@
     pushl   %esi
     .cfi_adjust_cfa_offset 4
     .cfi_rel_offset esi, 0
-    mov     20(%esp), %ebx
-    mov     24(%esp), %ecx
-    mov     28(%esp), %edx
-    mov     32(%esp), %esi
+
+    call    __kernel_syscall
+    pushl   %eax
+    .cfi_adjust_cfa_offset 4
+    .cfi_rel_offset eax, 0
+
+    mov     24(%esp), %ebx
+    mov     28(%esp), %ecx
+    mov     32(%esp), %edx
+    mov     36(%esp), %esi
     movl    $__NR_rt_sigaction, %eax
-    int     $0x80
+    call    *(%esp)
+    addl    $4, %esp
+
     cmpl    $-MAX_ERRNO, %eax
     jb      1f
     negl    %eax
diff --git a/libc/arch-x86/syscalls/__rt_sigpending.S b/libc/arch-x86/syscalls/__rt_sigpending.S
index 9c6a106..ecf2945 100644
--- a/libc/arch-x86/syscalls/__rt_sigpending.S
+++ b/libc/arch-x86/syscalls/__rt_sigpending.S
@@ -9,10 +9,18 @@
     pushl   %ecx
     .cfi_adjust_cfa_offset 4
     .cfi_rel_offset ecx, 0
-    mov     12(%esp), %ebx
-    mov     16(%esp), %ecx
+
+    call    __kernel_syscall
+    pushl   %eax
+    .cfi_adjust_cfa_offset 4
+    .cfi_rel_offset eax, 0
+
+    mov     16(%esp), %ebx
+    mov     20(%esp), %ecx
     movl    $__NR_rt_sigpending, %eax
-    int     $0x80
+    call    *(%esp)
+    addl    $4, %esp
+
     cmpl    $-MAX_ERRNO, %eax
     jb      1f
     negl    %eax
diff --git a/libc/arch-x86/syscalls/__rt_sigprocmask.S b/libc/arch-x86/syscalls/__rt_sigprocmask.S
index 9b1532f..cdd0f10 100644
--- a/libc/arch-x86/syscalls/__rt_sigprocmask.S
+++ b/libc/arch-x86/syscalls/__rt_sigprocmask.S
@@ -15,12 +15,20 @@
     pushl   %esi
     .cfi_adjust_cfa_offset 4
     .cfi_rel_offset esi, 0
-    mov     20(%esp), %ebx
-    mov     24(%esp), %ecx
-    mov     28(%esp), %edx
-    mov     32(%esp), %esi
+
+    call    __kernel_syscall
+    pushl   %eax
+    .cfi_adjust_cfa_offset 4
+    .cfi_rel_offset eax, 0
+
+    mov     24(%esp), %ebx
+    mov     28(%esp), %ecx
+    mov     32(%esp), %edx
+    mov     36(%esp), %esi
     movl    $__NR_rt_sigprocmask, %eax
-    int     $0x80
+    call    *(%esp)
+    addl    $4, %esp
+
     cmpl    $-MAX_ERRNO, %eax
     jb      1f
     negl    %eax
diff --git a/libc/arch-x86/syscalls/__rt_sigsuspend.S b/libc/arch-x86/syscalls/__rt_sigsuspend.S
index b05acd8..ef96949 100644
--- a/libc/arch-x86/syscalls/__rt_sigsuspend.S
+++ b/libc/arch-x86/syscalls/__rt_sigsuspend.S
@@ -9,10 +9,18 @@
     pushl   %ecx
     .cfi_adjust_cfa_offset 4
     .cfi_rel_offset ecx, 0
-    mov     12(%esp), %ebx
-    mov     16(%esp), %ecx
+
+    call    __kernel_syscall
+    pushl   %eax
+    .cfi_adjust_cfa_offset 4
+    .cfi_rel_offset eax, 0
+
+    mov     16(%esp), %ebx
+    mov     20(%esp), %ecx
     movl    $__NR_rt_sigsuspend, %eax
-    int     $0x80
+    call    *(%esp)
+    addl    $4, %esp
+
     cmpl    $-MAX_ERRNO, %eax
     jb      1f
     negl    %eax
diff --git a/libc/arch-x86/syscalls/__rt_sigtimedwait.S b/libc/arch-x86/syscalls/__rt_sigtimedwait.S
index 14cb70f..8205221 100644
--- a/libc/arch-x86/syscalls/__rt_sigtimedwait.S
+++ b/libc/arch-x86/syscalls/__rt_sigtimedwait.S
@@ -15,12 +15,20 @@
     pushl   %esi
     .cfi_adjust_cfa_offset 4
     .cfi_rel_offset esi, 0
-    mov     20(%esp), %ebx
-    mov     24(%esp), %ecx
-    mov     28(%esp), %edx
-    mov     32(%esp), %esi
+
+    call    __kernel_syscall
+    pushl   %eax
+    .cfi_adjust_cfa_offset 4
+    .cfi_rel_offset eax, 0
+
+    mov     24(%esp), %ebx
+    mov     28(%esp), %ecx
+    mov     32(%esp), %edx
+    mov     36(%esp), %esi
     movl    $__NR_rt_sigtimedwait, %eax
-    int     $0x80
+    call    *(%esp)
+    addl    $4, %esp
+
     cmpl    $-MAX_ERRNO, %eax
     jb      1f
     negl    %eax
diff --git a/libc/arch-x86/syscalls/__sched_getaffinity.S b/libc/arch-x86/syscalls/__sched_getaffinity.S
index 0b0a970..ba658af 100644
--- a/libc/arch-x86/syscalls/__sched_getaffinity.S
+++ b/libc/arch-x86/syscalls/__sched_getaffinity.S
@@ -12,11 +12,19 @@
     pushl   %edx
     .cfi_adjust_cfa_offset 4
     .cfi_rel_offset edx, 0
-    mov     16(%esp), %ebx
-    mov     20(%esp), %ecx
-    mov     24(%esp), %edx
+
+    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_sched_getaffinity, %eax
-    int     $0x80
+    call    *(%esp)
+    addl    $4, %esp
+
     cmpl    $-MAX_ERRNO, %eax
     jb      1f
     negl    %eax
diff --git a/libc/arch-x86/syscalls/__set_thread_area.S b/libc/arch-x86/syscalls/__set_thread_area.S
index 8cd6880..7fc04bd 100644
--- a/libc/arch-x86/syscalls/__set_thread_area.S
+++ b/libc/arch-x86/syscalls/__set_thread_area.S
@@ -6,9 +6,17 @@
     pushl   %ebx
     .cfi_def_cfa_offset 8
     .cfi_rel_offset ebx, 0
-    mov     8(%esp), %ebx
+
+    call    __kernel_syscall
+    pushl   %eax
+    .cfi_adjust_cfa_offset 4
+    .cfi_rel_offset eax, 0
+
+    mov     12(%esp), %ebx
     movl    $__NR_set_thread_area, %eax
-    int     $0x80
+    call    *(%esp)
+    addl    $4, %esp
+
     cmpl    $-MAX_ERRNO, %eax
     jb      1f
     negl    %eax
diff --git a/libc/arch-x86/syscalls/__set_tid_address.S b/libc/arch-x86/syscalls/__set_tid_address.S
index 08acce9..4301156 100644
--- a/libc/arch-x86/syscalls/__set_tid_address.S
+++ b/libc/arch-x86/syscalls/__set_tid_address.S
@@ -6,9 +6,17 @@
     pushl   %ebx
     .cfi_def_cfa_offset 8
     .cfi_rel_offset ebx, 0
-    mov     8(%esp), %ebx
+
+    call    __kernel_syscall
+    pushl   %eax
+    .cfi_adjust_cfa_offset 4
+    .cfi_rel_offset eax, 0
+
+    mov     12(%esp), %ebx
     movl    $__NR_set_tid_address, %eax
-    int     $0x80
+    call    *(%esp)
+    addl    $4, %esp
+
     cmpl    $-MAX_ERRNO, %eax
     jb      1f
     negl    %eax
diff --git a/libc/arch-x86/syscalls/__sigaction.S b/libc/arch-x86/syscalls/__sigaction.S
index 0238247..6b2b7f3 100644
--- a/libc/arch-x86/syscalls/__sigaction.S
+++ b/libc/arch-x86/syscalls/__sigaction.S
@@ -12,11 +12,19 @@
     pushl   %edx
     .cfi_adjust_cfa_offset 4
     .cfi_rel_offset edx, 0
-    mov     16(%esp), %ebx
-    mov     20(%esp), %ecx
-    mov     24(%esp), %edx
+
+    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_sigaction, %eax
-    int     $0x80
+    call    *(%esp)
+    addl    $4, %esp
+
     cmpl    $-MAX_ERRNO, %eax
     jb      1f
     negl    %eax
diff --git a/libc/arch-x86/syscalls/__signalfd4.S b/libc/arch-x86/syscalls/__signalfd4.S
index 02ddc73..ea817cf 100644
--- a/libc/arch-x86/syscalls/__signalfd4.S
+++ b/libc/arch-x86/syscalls/__signalfd4.S
@@ -15,12 +15,20 @@
     pushl   %esi
     .cfi_adjust_cfa_offset 4
     .cfi_rel_offset esi, 0
-    mov     20(%esp), %ebx
-    mov     24(%esp), %ecx
-    mov     28(%esp), %edx
-    mov     32(%esp), %esi
+
+    call    __kernel_syscall
+    pushl   %eax
+    .cfi_adjust_cfa_offset 4
+    .cfi_rel_offset eax, 0
+
+    mov     24(%esp), %ebx
+    mov     28(%esp), %ecx
+    mov     32(%esp), %edx
+    mov     36(%esp), %esi
     movl    $__NR_signalfd4, %eax
-    int     $0x80
+    call    *(%esp)
+    addl    $4, %esp
+
     cmpl    $-MAX_ERRNO, %eax
     jb      1f
     negl    %eax
diff --git a/libc/arch-x86/syscalls/__socket.S b/libc/arch-x86/syscalls/__socket.S
index 75952ee..06d1f1f 100644
--- a/libc/arch-x86/syscalls/__socket.S
+++ b/libc/arch-x86/syscalls/__socket.S
@@ -9,11 +9,19 @@
     pushl   %ecx
     .cfi_adjust_cfa_offset 4
     .cfi_rel_offset ecx, 0
+
+    call    __kernel_syscall
+    pushl   %eax
+    .cfi_adjust_cfa_offset 4
+    .cfi_rel_offset eax, 0
+
     mov     $1, %ebx
     mov     %esp, %ecx
-    addl    $12, %ecx
+    addl    $16, %ecx
     movl    $__NR_socketcall, %eax
-    int     $0x80
+    call    *(%esp)
+    addl    $4, %esp
+
     cmpl    $-MAX_ERRNO, %eax
     jb      1f
     negl    %eax
diff --git a/libc/arch-x86/syscalls/__statfs64.S b/libc/arch-x86/syscalls/__statfs64.S
index b9bccb0..79e1f4b 100644
--- a/libc/arch-x86/syscalls/__statfs64.S
+++ b/libc/arch-x86/syscalls/__statfs64.S
@@ -12,11 +12,19 @@
     pushl   %edx
     .cfi_adjust_cfa_offset 4
     .cfi_rel_offset edx, 0
-    mov     16(%esp), %ebx
-    mov     20(%esp), %ecx
-    mov     24(%esp), %edx
+
+    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_statfs64, %eax
-    int     $0x80
+    call    *(%esp)
+    addl    $4, %esp
+
     cmpl    $-MAX_ERRNO, %eax
     jb      1f
     negl    %eax
diff --git a/libc/arch-x86/syscalls/__timer_create.S b/libc/arch-x86/syscalls/__timer_create.S
index b22f408..4e16b1c 100644
--- a/libc/arch-x86/syscalls/__timer_create.S
+++ b/libc/arch-x86/syscalls/__timer_create.S
@@ -12,11 +12,19 @@
     pushl   %edx
     .cfi_adjust_cfa_offset 4
     .cfi_rel_offset edx, 0
-    mov     16(%esp), %ebx
-    mov     20(%esp), %ecx
-    mov     24(%esp), %edx
+
+    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_timer_create, %eax
-    int     $0x80
+    call    *(%esp)
+    addl    $4, %esp
+
     cmpl    $-MAX_ERRNO, %eax
     jb      1f
     negl    %eax
diff --git a/libc/arch-x86/syscalls/__timer_delete.S b/libc/arch-x86/syscalls/__timer_delete.S
index d77ae3e..fea422e 100644
--- a/libc/arch-x86/syscalls/__timer_delete.S
+++ b/libc/arch-x86/syscalls/__timer_delete.S
@@ -6,9 +6,17 @@
     pushl   %ebx
     .cfi_def_cfa_offset 8
     .cfi_rel_offset ebx, 0
-    mov     8(%esp), %ebx
+
+    call    __kernel_syscall
+    pushl   %eax
+    .cfi_adjust_cfa_offset 4
+    .cfi_rel_offset eax, 0
+
+    mov     12(%esp), %ebx
     movl    $__NR_timer_delete, %eax
-    int     $0x80
+    call    *(%esp)
+    addl    $4, %esp
+
     cmpl    $-MAX_ERRNO, %eax
     jb      1f
     negl    %eax
diff --git a/libc/arch-x86/syscalls/__timer_getoverrun.S b/libc/arch-x86/syscalls/__timer_getoverrun.S
index f21b08f..e921073 100644
--- a/libc/arch-x86/syscalls/__timer_getoverrun.S
+++ b/libc/arch-x86/syscalls/__timer_getoverrun.S
@@ -6,9 +6,17 @@
     pushl   %ebx
     .cfi_def_cfa_offset 8
     .cfi_rel_offset ebx, 0
-    mov     8(%esp), %ebx
+
+    call    __kernel_syscall
+    pushl   %eax
+    .cfi_adjust_cfa_offset 4
+    .cfi_rel_offset eax, 0
+
+    mov     12(%esp), %ebx
     movl    $__NR_timer_getoverrun, %eax
-    int     $0x80
+    call    *(%esp)
+    addl    $4, %esp
+
     cmpl    $-MAX_ERRNO, %eax
     jb      1f
     negl    %eax
diff --git a/libc/arch-x86/syscalls/__timer_gettime.S b/libc/arch-x86/syscalls/__timer_gettime.S
index 73c8539..4e20356 100644
--- a/libc/arch-x86/syscalls/__timer_gettime.S
+++ b/libc/arch-x86/syscalls/__timer_gettime.S
@@ -9,10 +9,18 @@
     pushl   %ecx
     .cfi_adjust_cfa_offset 4
     .cfi_rel_offset ecx, 0
-    mov     12(%esp), %ebx
-    mov     16(%esp), %ecx
+
+    call    __kernel_syscall
+    pushl   %eax
+    .cfi_adjust_cfa_offset 4
+    .cfi_rel_offset eax, 0
+
+    mov     16(%esp), %ebx
+    mov     20(%esp), %ecx
     movl    $__NR_timer_gettime, %eax
-    int     $0x80
+    call    *(%esp)
+    addl    $4, %esp
+
     cmpl    $-MAX_ERRNO, %eax
     jb      1f
     negl    %eax
diff --git a/libc/arch-x86/syscalls/__timer_settime.S b/libc/arch-x86/syscalls/__timer_settime.S
index 1a6a8ec..9b8af34 100644
--- a/libc/arch-x86/syscalls/__timer_settime.S
+++ b/libc/arch-x86/syscalls/__timer_settime.S
@@ -15,12 +15,20 @@
     pushl   %esi
     .cfi_adjust_cfa_offset 4
     .cfi_rel_offset esi, 0
-    mov     20(%esp), %ebx
-    mov     24(%esp), %ecx
-    mov     28(%esp), %edx
-    mov     32(%esp), %esi
+
+    call    __kernel_syscall
+    pushl   %eax
+    .cfi_adjust_cfa_offset 4
+    .cfi_rel_offset eax, 0
+
+    mov     24(%esp), %ebx
+    mov     28(%esp), %ecx
+    mov     32(%esp), %edx
+    mov     36(%esp), %esi
     movl    $__NR_timer_settime, %eax
-    int     $0x80
+    call    *(%esp)
+    addl    $4, %esp
+
     cmpl    $-MAX_ERRNO, %eax
     jb      1f
     negl    %eax
diff --git a/libc/arch-x86/syscalls/__waitid.S b/libc/arch-x86/syscalls/__waitid.S
index 2061abc..f134b42 100644
--- a/libc/arch-x86/syscalls/__waitid.S
+++ b/libc/arch-x86/syscalls/__waitid.S
@@ -18,13 +18,21 @@
     pushl   %edi
     .cfi_adjust_cfa_offset 4
     .cfi_rel_offset edi, 0
-    mov     24(%esp), %ebx
-    mov     28(%esp), %ecx
-    mov     32(%esp), %edx
-    mov     36(%esp), %esi
-    mov     40(%esp), %edi
+
+    call    __kernel_syscall
+    pushl   %eax
+    .cfi_adjust_cfa_offset 4
+    .cfi_rel_offset eax, 0
+
+    mov     28(%esp), %ebx
+    mov     32(%esp), %ecx
+    mov     36(%esp), %edx
+    mov     40(%esp), %esi
+    mov     44(%esp), %edi
     movl    $__NR_waitid, %eax
-    int     $0x80
+    call    *(%esp)
+    addl    $4, %esp
+
     cmpl    $-MAX_ERRNO, %eax
     jb      1f
     negl    %eax
diff --git a/libc/arch-x86/syscalls/_exit.S b/libc/arch-x86/syscalls/_exit.S
index 9945b35..1e89261 100644
--- a/libc/arch-x86/syscalls/_exit.S
+++ b/libc/arch-x86/syscalls/_exit.S
@@ -6,9 +6,17 @@
     pushl   %ebx
     .cfi_def_cfa_offset 8
     .cfi_rel_offset ebx, 0
-    mov     8(%esp), %ebx
+
+    call    __kernel_syscall
+    pushl   %eax
+    .cfi_adjust_cfa_offset 4
+    .cfi_rel_offset eax, 0
+
+    mov     12(%esp), %ebx
     movl    $__NR_exit_group, %eax
-    int     $0x80
+    call    *(%esp)
+    addl    $4, %esp
+
     cmpl    $-MAX_ERRNO, %eax
     jb      1f
     negl    %eax
diff --git a/libc/arch-x86/syscalls/acct.S b/libc/arch-x86/syscalls/acct.S
index d831771..48c4c5c 100644
--- a/libc/arch-x86/syscalls/acct.S
+++ b/libc/arch-x86/syscalls/acct.S
@@ -6,9 +6,17 @@
     pushl   %ebx
     .cfi_def_cfa_offset 8
     .cfi_rel_offset ebx, 0
-    mov     8(%esp), %ebx
+
+    call    __kernel_syscall
+    pushl   %eax
+    .cfi_adjust_cfa_offset 4
+    .cfi_rel_offset eax, 0
+
+    mov     12(%esp), %ebx
     movl    $__NR_acct, %eax
-    int     $0x80
+    call    *(%esp)
+    addl    $4, %esp
+
     cmpl    $-MAX_ERRNO, %eax
     jb      1f
     negl    %eax
diff --git a/libc/arch-x86/syscalls/gettimeofday.S b/libc/arch-x86/syscalls/adjtimex.S
similarity index 66%
rename from libc/arch-x86/syscalls/gettimeofday.S
rename to libc/arch-x86/syscalls/adjtimex.S
index a508c14..1b0d8b1 100644
--- a/libc/arch-x86/syscalls/gettimeofday.S
+++ b/libc/arch-x86/syscalls/adjtimex.S
@@ -2,17 +2,21 @@
 
 #include <private/bionic_asm.h>
 
-ENTRY(gettimeofday)
+ENTRY(adjtimex)
     pushl   %ebx
     .cfi_def_cfa_offset 8
     .cfi_rel_offset ebx, 0
-    pushl   %ecx
+
+    call    __kernel_syscall
+    pushl   %eax
     .cfi_adjust_cfa_offset 4
-    .cfi_rel_offset ecx, 0
+    .cfi_rel_offset eax, 0
+
     mov     12(%esp), %ebx
-    mov     16(%esp), %ecx
-    movl    $__NR_gettimeofday, %eax
-    int     $0x80
+    movl    $__NR_adjtimex, %eax
+    call    *(%esp)
+    addl    $4, %esp
+
     cmpl    $-MAX_ERRNO, %eax
     jb      1f
     negl    %eax
@@ -20,7 +24,6 @@
     call    __set_errno_internal
     addl    $4, %esp
 1:
-    popl    %ecx
     popl    %ebx
     ret
-END(gettimeofday)
+END(adjtimex)
diff --git a/libc/arch-x86/syscalls/bind.S b/libc/arch-x86/syscalls/bind.S
index 9ef817e..c1f84da 100644
--- a/libc/arch-x86/syscalls/bind.S
+++ b/libc/arch-x86/syscalls/bind.S
@@ -9,11 +9,19 @@
     pushl   %ecx
     .cfi_adjust_cfa_offset 4
     .cfi_rel_offset ecx, 0
+
+    call    __kernel_syscall
+    pushl   %eax
+    .cfi_adjust_cfa_offset 4
+    .cfi_rel_offset eax, 0
+
     mov     $2, %ebx
     mov     %esp, %ecx
-    addl    $12, %ecx
+    addl    $16, %ecx
     movl    $__NR_socketcall, %eax
-    int     $0x80
+    call    *(%esp)
+    addl    $4, %esp
+
     cmpl    $-MAX_ERRNO, %eax
     jb      1f
     negl    %eax
diff --git a/libc/arch-x86/syscalls/capget.S b/libc/arch-x86/syscalls/capget.S
index 81c24e8..fafde37 100644
--- a/libc/arch-x86/syscalls/capget.S
+++ b/libc/arch-x86/syscalls/capget.S
@@ -9,10 +9,18 @@
     pushl   %ecx
     .cfi_adjust_cfa_offset 4
     .cfi_rel_offset ecx, 0
-    mov     12(%esp), %ebx
-    mov     16(%esp), %ecx
+
+    call    __kernel_syscall
+    pushl   %eax
+    .cfi_adjust_cfa_offset 4
+    .cfi_rel_offset eax, 0
+
+    mov     16(%esp), %ebx
+    mov     20(%esp), %ecx
     movl    $__NR_capget, %eax
-    int     $0x80
+    call    *(%esp)
+    addl    $4, %esp
+
     cmpl    $-MAX_ERRNO, %eax
     jb      1f
     negl    %eax
diff --git a/libc/arch-x86/syscalls/capset.S b/libc/arch-x86/syscalls/capset.S
index 4e311e9..28e5338 100644
--- a/libc/arch-x86/syscalls/capset.S
+++ b/libc/arch-x86/syscalls/capset.S
@@ -9,10 +9,18 @@
     pushl   %ecx
     .cfi_adjust_cfa_offset 4
     .cfi_rel_offset ecx, 0
-    mov     12(%esp), %ebx
-    mov     16(%esp), %ecx
+
+    call    __kernel_syscall
+    pushl   %eax
+    .cfi_adjust_cfa_offset 4
+    .cfi_rel_offset eax, 0
+
+    mov     16(%esp), %ebx
+    mov     20(%esp), %ecx
     movl    $__NR_capset, %eax
-    int     $0x80
+    call    *(%esp)
+    addl    $4, %esp
+
     cmpl    $-MAX_ERRNO, %eax
     jb      1f
     negl    %eax
diff --git a/libc/arch-x86/syscalls/chdir.S b/libc/arch-x86/syscalls/chdir.S
index 2226a1a..4b639eb 100644
--- a/libc/arch-x86/syscalls/chdir.S
+++ b/libc/arch-x86/syscalls/chdir.S
@@ -6,9 +6,17 @@
     pushl   %ebx
     .cfi_def_cfa_offset 8
     .cfi_rel_offset ebx, 0
-    mov     8(%esp), %ebx
+
+    call    __kernel_syscall
+    pushl   %eax
+    .cfi_adjust_cfa_offset 4
+    .cfi_rel_offset eax, 0
+
+    mov     12(%esp), %ebx
     movl    $__NR_chdir, %eax
-    int     $0x80
+    call    *(%esp)
+    addl    $4, %esp
+
     cmpl    $-MAX_ERRNO, %eax
     jb      1f
     negl    %eax
diff --git a/libc/arch-x86/syscalls/chroot.S b/libc/arch-x86/syscalls/chroot.S
index 95ed0b5..8887f86 100644
--- a/libc/arch-x86/syscalls/chroot.S
+++ b/libc/arch-x86/syscalls/chroot.S
@@ -6,9 +6,17 @@
     pushl   %ebx
     .cfi_def_cfa_offset 8
     .cfi_rel_offset ebx, 0
-    mov     8(%esp), %ebx
+
+    call    __kernel_syscall
+    pushl   %eax
+    .cfi_adjust_cfa_offset 4
+    .cfi_rel_offset eax, 0
+
+    mov     12(%esp), %ebx
     movl    $__NR_chroot, %eax
-    int     $0x80
+    call    *(%esp)
+    addl    $4, %esp
+
     cmpl    $-MAX_ERRNO, %eax
     jb      1f
     negl    %eax
diff --git a/libc/arch-x86/syscalls/flistxattr.S b/libc/arch-x86/syscalls/clock_adjtime.S
similarity index 71%
rename from libc/arch-x86/syscalls/flistxattr.S
rename to libc/arch-x86/syscalls/clock_adjtime.S
index fc81a37..4ccf1a6 100644
--- a/libc/arch-x86/syscalls/flistxattr.S
+++ b/libc/arch-x86/syscalls/clock_adjtime.S
@@ -2,21 +2,25 @@
 
 #include <private/bionic_asm.h>
 
-ENTRY(flistxattr)
+ENTRY(clock_adjtime)
     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
+
+    call    __kernel_syscall
+    pushl   %eax
     .cfi_adjust_cfa_offset 4
-    .cfi_rel_offset edx, 0
+    .cfi_rel_offset eax, 0
+
     mov     16(%esp), %ebx
     mov     20(%esp), %ecx
-    mov     24(%esp), %edx
-    movl    $__NR_flistxattr, %eax
-    int     $0x80
+    movl    $__NR_clock_adjtime, %eax
+    call    *(%esp)
+    addl    $4, %esp
+
     cmpl    $-MAX_ERRNO, %eax
     jb      1f
     negl    %eax
@@ -24,8 +28,7 @@
     call    __set_errno_internal
     addl    $4, %esp
 1:
-    popl    %edx
     popl    %ecx
     popl    %ebx
     ret
-END(flistxattr)
+END(clock_adjtime)
diff --git a/libc/arch-x86/syscalls/clock_getres.S b/libc/arch-x86/syscalls/clock_getres.S
index 9501799..9466e08 100644
--- a/libc/arch-x86/syscalls/clock_getres.S
+++ b/libc/arch-x86/syscalls/clock_getres.S
@@ -9,10 +9,18 @@
     pushl   %ecx
     .cfi_adjust_cfa_offset 4
     .cfi_rel_offset ecx, 0
-    mov     12(%esp), %ebx
-    mov     16(%esp), %ecx
+
+    call    __kernel_syscall
+    pushl   %eax
+    .cfi_adjust_cfa_offset 4
+    .cfi_rel_offset eax, 0
+
+    mov     16(%esp), %ebx
+    mov     20(%esp), %ecx
     movl    $__NR_clock_getres, %eax
-    int     $0x80
+    call    *(%esp)
+    addl    $4, %esp
+
     cmpl    $-MAX_ERRNO, %eax
     jb      1f
     negl    %eax
diff --git a/libc/arch-x86/syscalls/clock_gettime.S b/libc/arch-x86/syscalls/clock_gettime.S
deleted file mode 100644
index 0875cfb..0000000
--- a/libc/arch-x86/syscalls/clock_gettime.S
+++ /dev/null
@@ -1,26 +0,0 @@
-/* Generated by gensyscalls.py. Do not edit. */
-
-#include <private/bionic_asm.h>
-
-ENTRY(clock_gettime)
-    pushl   %ebx
-    .cfi_def_cfa_offset 8
-    .cfi_rel_offset ebx, 0
-    pushl   %ecx
-    .cfi_adjust_cfa_offset 4
-    .cfi_rel_offset ecx, 0
-    mov     12(%esp), %ebx
-    mov     16(%esp), %ecx
-    movl    $__NR_clock_gettime, %eax
-    int     $0x80
-    cmpl    $-MAX_ERRNO, %eax
-    jb      1f
-    negl    %eax
-    pushl   %eax
-    call    __set_errno_internal
-    addl    $4, %esp
-1:
-    popl    %ecx
-    popl    %ebx
-    ret
-END(clock_gettime)
diff --git a/libc/arch-x86/syscalls/clock_settime.S b/libc/arch-x86/syscalls/clock_settime.S
index 96fafed..62dc021 100644
--- a/libc/arch-x86/syscalls/clock_settime.S
+++ b/libc/arch-x86/syscalls/clock_settime.S
@@ -9,10 +9,18 @@
     pushl   %ecx
     .cfi_adjust_cfa_offset 4
     .cfi_rel_offset ecx, 0
-    mov     12(%esp), %ebx
-    mov     16(%esp), %ecx
+
+    call    __kernel_syscall
+    pushl   %eax
+    .cfi_adjust_cfa_offset 4
+    .cfi_rel_offset eax, 0
+
+    mov     16(%esp), %ebx
+    mov     20(%esp), %ecx
     movl    $__NR_clock_settime, %eax
-    int     $0x80
+    call    *(%esp)
+    addl    $4, %esp
+
     cmpl    $-MAX_ERRNO, %eax
     jb      1f
     negl    %eax
diff --git a/libc/arch-x86/syscalls/delete_module.S b/libc/arch-x86/syscalls/delete_module.S
index 58b8d6b..b0c8ff9 100644
--- a/libc/arch-x86/syscalls/delete_module.S
+++ b/libc/arch-x86/syscalls/delete_module.S
@@ -9,10 +9,18 @@
     pushl   %ecx
     .cfi_adjust_cfa_offset 4
     .cfi_rel_offset ecx, 0
-    mov     12(%esp), %ebx
-    mov     16(%esp), %ecx
+
+    call    __kernel_syscall
+    pushl   %eax
+    .cfi_adjust_cfa_offset 4
+    .cfi_rel_offset eax, 0
+
+    mov     16(%esp), %ebx
+    mov     20(%esp), %ecx
     movl    $__NR_delete_module, %eax
-    int     $0x80
+    call    *(%esp)
+    addl    $4, %esp
+
     cmpl    $-MAX_ERRNO, %eax
     jb      1f
     negl    %eax
diff --git a/libc/arch-x86/syscalls/dup.S b/libc/arch-x86/syscalls/dup.S
index 0fd9cce..637cfae 100644
--- a/libc/arch-x86/syscalls/dup.S
+++ b/libc/arch-x86/syscalls/dup.S
@@ -6,9 +6,17 @@
     pushl   %ebx
     .cfi_def_cfa_offset 8
     .cfi_rel_offset ebx, 0
-    mov     8(%esp), %ebx
+
+    call    __kernel_syscall
+    pushl   %eax
+    .cfi_adjust_cfa_offset 4
+    .cfi_rel_offset eax, 0
+
+    mov     12(%esp), %ebx
     movl    $__NR_dup, %eax
-    int     $0x80
+    call    *(%esp)
+    addl    $4, %esp
+
     cmpl    $-MAX_ERRNO, %eax
     jb      1f
     negl    %eax
diff --git a/libc/arch-x86/syscalls/dup3.S b/libc/arch-x86/syscalls/dup3.S
index 8348660..4d08eab 100644
--- a/libc/arch-x86/syscalls/dup3.S
+++ b/libc/arch-x86/syscalls/dup3.S
@@ -12,11 +12,19 @@
     pushl   %edx
     .cfi_adjust_cfa_offset 4
     .cfi_rel_offset edx, 0
-    mov     16(%esp), %ebx
-    mov     20(%esp), %ecx
-    mov     24(%esp), %edx
+
+    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_dup3, %eax
-    int     $0x80
+    call    *(%esp)
+    addl    $4, %esp
+
     cmpl    $-MAX_ERRNO, %eax
     jb      1f
     negl    %eax
diff --git a/libc/arch-x86/syscalls/epoll_create1.S b/libc/arch-x86/syscalls/epoll_create1.S
index 0fcd09c..93d1c00 100644
--- a/libc/arch-x86/syscalls/epoll_create1.S
+++ b/libc/arch-x86/syscalls/epoll_create1.S
@@ -6,9 +6,17 @@
     pushl   %ebx
     .cfi_def_cfa_offset 8
     .cfi_rel_offset ebx, 0
-    mov     8(%esp), %ebx
+
+    call    __kernel_syscall
+    pushl   %eax
+    .cfi_adjust_cfa_offset 4
+    .cfi_rel_offset eax, 0
+
+    mov     12(%esp), %ebx
     movl    $__NR_epoll_create1, %eax
-    int     $0x80
+    call    *(%esp)
+    addl    $4, %esp
+
     cmpl    $-MAX_ERRNO, %eax
     jb      1f
     negl    %eax
diff --git a/libc/arch-x86/syscalls/epoll_ctl.S b/libc/arch-x86/syscalls/epoll_ctl.S
index 092c1e0..a2d8d27 100644
--- a/libc/arch-x86/syscalls/epoll_ctl.S
+++ b/libc/arch-x86/syscalls/epoll_ctl.S
@@ -15,12 +15,20 @@
     pushl   %esi
     .cfi_adjust_cfa_offset 4
     .cfi_rel_offset esi, 0
-    mov     20(%esp), %ebx
-    mov     24(%esp), %ecx
-    mov     28(%esp), %edx
-    mov     32(%esp), %esi
+
+    call    __kernel_syscall
+    pushl   %eax
+    .cfi_adjust_cfa_offset 4
+    .cfi_rel_offset eax, 0
+
+    mov     24(%esp), %ebx
+    mov     28(%esp), %ecx
+    mov     32(%esp), %edx
+    mov     36(%esp), %esi
     movl    $__NR_epoll_ctl, %eax
-    int     $0x80
+    call    *(%esp)
+    addl    $4, %esp
+
     cmpl    $-MAX_ERRNO, %eax
     jb      1f
     negl    %eax
diff --git a/libc/arch-x86/syscalls/eventfd.S b/libc/arch-x86/syscalls/eventfd.S
index cc165e5..89f9442 100644
--- a/libc/arch-x86/syscalls/eventfd.S
+++ b/libc/arch-x86/syscalls/eventfd.S
@@ -9,10 +9,18 @@
     pushl   %ecx
     .cfi_adjust_cfa_offset 4
     .cfi_rel_offset ecx, 0
-    mov     12(%esp), %ebx
-    mov     16(%esp), %ecx
+
+    call    __kernel_syscall
+    pushl   %eax
+    .cfi_adjust_cfa_offset 4
+    .cfi_rel_offset eax, 0
+
+    mov     16(%esp), %ebx
+    mov     20(%esp), %ecx
     movl    $__NR_eventfd2, %eax
-    int     $0x80
+    call    *(%esp)
+    addl    $4, %esp
+
     cmpl    $-MAX_ERRNO, %eax
     jb      1f
     negl    %eax
diff --git a/libc/arch-x86/syscalls/execve.S b/libc/arch-x86/syscalls/execve.S
index e1c0253..7695635 100644
--- a/libc/arch-x86/syscalls/execve.S
+++ b/libc/arch-x86/syscalls/execve.S
@@ -12,11 +12,19 @@
     pushl   %edx
     .cfi_adjust_cfa_offset 4
     .cfi_rel_offset edx, 0
-    mov     16(%esp), %ebx
-    mov     20(%esp), %ecx
-    mov     24(%esp), %edx
+
+    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_execve, %eax
-    int     $0x80
+    call    *(%esp)
+    addl    $4, %esp
+
     cmpl    $-MAX_ERRNO, %eax
     jb      1f
     negl    %eax
diff --git a/libc/arch-x86/syscalls/fallocate64.S b/libc/arch-x86/syscalls/fallocate64.S
index e2a7c3e..eabc642 100644
--- a/libc/arch-x86/syscalls/fallocate64.S
+++ b/libc/arch-x86/syscalls/fallocate64.S
@@ -21,14 +21,22 @@
     pushl   %ebp
     .cfi_adjust_cfa_offset 4
     .cfi_rel_offset ebp, 0
-    mov     28(%esp), %ebx
-    mov     32(%esp), %ecx
-    mov     36(%esp), %edx
-    mov     40(%esp), %esi
-    mov     44(%esp), %edi
-    mov     48(%esp), %ebp
+
+    call    __kernel_syscall
+    pushl   %eax
+    .cfi_adjust_cfa_offset 4
+    .cfi_rel_offset eax, 0
+
+    mov     32(%esp), %ebx
+    mov     36(%esp), %ecx
+    mov     40(%esp), %edx
+    mov     44(%esp), %esi
+    mov     48(%esp), %edi
+    mov     52(%esp), %ebp
     movl    $__NR_fallocate, %eax
-    int     $0x80
+    call    *(%esp)
+    addl    $4, %esp
+
     cmpl    $-MAX_ERRNO, %eax
     jb      1f
     negl    %eax
diff --git a/libc/arch-x86/syscalls/fchdir.S b/libc/arch-x86/syscalls/fchdir.S
index c40c2c1..5701644 100644
--- a/libc/arch-x86/syscalls/fchdir.S
+++ b/libc/arch-x86/syscalls/fchdir.S
@@ -6,9 +6,17 @@
     pushl   %ebx
     .cfi_def_cfa_offset 8
     .cfi_rel_offset ebx, 0
-    mov     8(%esp), %ebx
+
+    call    __kernel_syscall
+    pushl   %eax
+    .cfi_adjust_cfa_offset 4
+    .cfi_rel_offset eax, 0
+
+    mov     12(%esp), %ebx
     movl    $__NR_fchdir, %eax
-    int     $0x80
+    call    *(%esp)
+    addl    $4, %esp
+
     cmpl    $-MAX_ERRNO, %eax
     jb      1f
     negl    %eax
diff --git a/libc/arch-x86/syscalls/fchown.S b/libc/arch-x86/syscalls/fchown.S
index 1a4f749..0d41389 100644
--- a/libc/arch-x86/syscalls/fchown.S
+++ b/libc/arch-x86/syscalls/fchown.S
@@ -12,11 +12,19 @@
     pushl   %edx
     .cfi_adjust_cfa_offset 4
     .cfi_rel_offset edx, 0
-    mov     16(%esp), %ebx
-    mov     20(%esp), %ecx
-    mov     24(%esp), %edx
+
+    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_fchown32, %eax
-    int     $0x80
+    call    *(%esp)
+    addl    $4, %esp
+
     cmpl    $-MAX_ERRNO, %eax
     jb      1f
     negl    %eax
diff --git a/libc/arch-x86/syscalls/fchownat.S b/libc/arch-x86/syscalls/fchownat.S
index c2b358e..56b7777 100644
--- a/libc/arch-x86/syscalls/fchownat.S
+++ b/libc/arch-x86/syscalls/fchownat.S
@@ -18,13 +18,21 @@
     pushl   %edi
     .cfi_adjust_cfa_offset 4
     .cfi_rel_offset edi, 0
-    mov     24(%esp), %ebx
-    mov     28(%esp), %ecx
-    mov     32(%esp), %edx
-    mov     36(%esp), %esi
-    mov     40(%esp), %edi
+
+    call    __kernel_syscall
+    pushl   %eax
+    .cfi_adjust_cfa_offset 4
+    .cfi_rel_offset eax, 0
+
+    mov     28(%esp), %ebx
+    mov     32(%esp), %ecx
+    mov     36(%esp), %edx
+    mov     40(%esp), %esi
+    mov     44(%esp), %edi
     movl    $__NR_fchownat, %eax
-    int     $0x80
+    call    *(%esp)
+    addl    $4, %esp
+
     cmpl    $-MAX_ERRNO, %eax
     jb      1f
     negl    %eax
diff --git a/libc/arch-x86/syscalls/fdatasync.S b/libc/arch-x86/syscalls/fdatasync.S
index debd4e3..6ee9e15 100644
--- a/libc/arch-x86/syscalls/fdatasync.S
+++ b/libc/arch-x86/syscalls/fdatasync.S
@@ -6,9 +6,17 @@
     pushl   %ebx
     .cfi_def_cfa_offset 8
     .cfi_rel_offset ebx, 0
-    mov     8(%esp), %ebx
+
+    call    __kernel_syscall
+    pushl   %eax
+    .cfi_adjust_cfa_offset 4
+    .cfi_rel_offset eax, 0
+
+    mov     12(%esp), %ebx
     movl    $__NR_fdatasync, %eax
-    int     $0x80
+    call    *(%esp)
+    addl    $4, %esp
+
     cmpl    $-MAX_ERRNO, %eax
     jb      1f
     negl    %eax
diff --git a/libc/arch-x86/syscalls/flock.S b/libc/arch-x86/syscalls/flock.S
index 0fc76a8..b65543d 100644
--- a/libc/arch-x86/syscalls/flock.S
+++ b/libc/arch-x86/syscalls/flock.S
@@ -9,10 +9,18 @@
     pushl   %ecx
     .cfi_adjust_cfa_offset 4
     .cfi_rel_offset ecx, 0
-    mov     12(%esp), %ebx
-    mov     16(%esp), %ecx
+
+    call    __kernel_syscall
+    pushl   %eax
+    .cfi_adjust_cfa_offset 4
+    .cfi_rel_offset eax, 0
+
+    mov     16(%esp), %ebx
+    mov     20(%esp), %ecx
     movl    $__NR_flock, %eax
-    int     $0x80
+    call    *(%esp)
+    addl    $4, %esp
+
     cmpl    $-MAX_ERRNO, %eax
     jb      1f
     negl    %eax
diff --git a/libc/arch-x86/syscalls/fremovexattr.S b/libc/arch-x86/syscalls/fremovexattr.S
index 2053a9a..3511d5d 100644
--- a/libc/arch-x86/syscalls/fremovexattr.S
+++ b/libc/arch-x86/syscalls/fremovexattr.S
@@ -9,10 +9,18 @@
     pushl   %ecx
     .cfi_adjust_cfa_offset 4
     .cfi_rel_offset ecx, 0
-    mov     12(%esp), %ebx
-    mov     16(%esp), %ecx
+
+    call    __kernel_syscall
+    pushl   %eax
+    .cfi_adjust_cfa_offset 4
+    .cfi_rel_offset eax, 0
+
+    mov     16(%esp), %ebx
+    mov     20(%esp), %ecx
     movl    $__NR_fremovexattr, %eax
-    int     $0x80
+    call    *(%esp)
+    addl    $4, %esp
+
     cmpl    $-MAX_ERRNO, %eax
     jb      1f
     negl    %eax
diff --git a/libc/arch-x86/syscalls/fstat64.S b/libc/arch-x86/syscalls/fstat64.S
index ba385a4..16eca69 100644
--- a/libc/arch-x86/syscalls/fstat64.S
+++ b/libc/arch-x86/syscalls/fstat64.S
@@ -9,10 +9,18 @@
     pushl   %ecx
     .cfi_adjust_cfa_offset 4
     .cfi_rel_offset ecx, 0
-    mov     12(%esp), %ebx
-    mov     16(%esp), %ecx
+
+    call    __kernel_syscall
+    pushl   %eax
+    .cfi_adjust_cfa_offset 4
+    .cfi_rel_offset eax, 0
+
+    mov     16(%esp), %ebx
+    mov     20(%esp), %ecx
     movl    $__NR_fstat64, %eax
-    int     $0x80
+    call    *(%esp)
+    addl    $4, %esp
+
     cmpl    $-MAX_ERRNO, %eax
     jb      1f
     negl    %eax
diff --git a/libc/arch-x86/syscalls/fstatat64.S b/libc/arch-x86/syscalls/fstatat64.S
index 90e87b6..402cf60 100644
--- a/libc/arch-x86/syscalls/fstatat64.S
+++ b/libc/arch-x86/syscalls/fstatat64.S
@@ -15,12 +15,20 @@
     pushl   %esi
     .cfi_adjust_cfa_offset 4
     .cfi_rel_offset esi, 0
-    mov     20(%esp), %ebx
-    mov     24(%esp), %ecx
-    mov     28(%esp), %edx
-    mov     32(%esp), %esi
+
+    call    __kernel_syscall
+    pushl   %eax
+    .cfi_adjust_cfa_offset 4
+    .cfi_rel_offset eax, 0
+
+    mov     24(%esp), %ebx
+    mov     28(%esp), %ecx
+    mov     32(%esp), %edx
+    mov     36(%esp), %esi
     movl    $__NR_fstatat64, %eax
-    int     $0x80
+    call    *(%esp)
+    addl    $4, %esp
+
     cmpl    $-MAX_ERRNO, %eax
     jb      1f
     negl    %eax
diff --git a/libc/arch-x86/syscalls/fsync.S b/libc/arch-x86/syscalls/fsync.S
index b19a3ab..53aeee6 100644
--- a/libc/arch-x86/syscalls/fsync.S
+++ b/libc/arch-x86/syscalls/fsync.S
@@ -6,9 +6,17 @@
     pushl   %ebx
     .cfi_def_cfa_offset 8
     .cfi_rel_offset ebx, 0
-    mov     8(%esp), %ebx
+
+    call    __kernel_syscall
+    pushl   %eax
+    .cfi_adjust_cfa_offset 4
+    .cfi_rel_offset eax, 0
+
+    mov     12(%esp), %ebx
     movl    $__NR_fsync, %eax
-    int     $0x80
+    call    *(%esp)
+    addl    $4, %esp
+
     cmpl    $-MAX_ERRNO, %eax
     jb      1f
     negl    %eax
diff --git a/libc/arch-x86/syscalls/ftruncate64.S b/libc/arch-x86/syscalls/ftruncate64.S
index 7233447..2fa792f 100644
--- a/libc/arch-x86/syscalls/ftruncate64.S
+++ b/libc/arch-x86/syscalls/ftruncate64.S
@@ -12,11 +12,19 @@
     pushl   %edx
     .cfi_adjust_cfa_offset 4
     .cfi_rel_offset edx, 0
-    mov     16(%esp), %ebx
-    mov     20(%esp), %ecx
-    mov     24(%esp), %edx
+
+    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_ftruncate64, %eax
-    int     $0x80
+    call    *(%esp)
+    addl    $4, %esp
+
     cmpl    $-MAX_ERRNO, %eax
     jb      1f
     negl    %eax
diff --git a/libc/arch-x86/syscalls/getegid.S b/libc/arch-x86/syscalls/getegid.S
index 729b7ad..cb1921e 100644
--- a/libc/arch-x86/syscalls/getegid.S
+++ b/libc/arch-x86/syscalls/getegid.S
@@ -3,8 +3,16 @@
 #include <private/bionic_asm.h>
 
 ENTRY(getegid)
+
+    call    __kernel_syscall
+    pushl   %eax
+    .cfi_adjust_cfa_offset 4
+    .cfi_rel_offset eax, 0
+
     movl    $__NR_getegid32, %eax
-    int     $0x80
+    call    *(%esp)
+    addl    $4, %esp
+
     cmpl    $-MAX_ERRNO, %eax
     jb      1f
     negl    %eax
diff --git a/libc/arch-x86/syscalls/geteuid.S b/libc/arch-x86/syscalls/geteuid.S
index dcc76b1..c08d3ae 100644
--- a/libc/arch-x86/syscalls/geteuid.S
+++ b/libc/arch-x86/syscalls/geteuid.S
@@ -3,8 +3,16 @@
 #include <private/bionic_asm.h>
 
 ENTRY(geteuid)
+
+    call    __kernel_syscall
+    pushl   %eax
+    .cfi_adjust_cfa_offset 4
+    .cfi_rel_offset eax, 0
+
     movl    $__NR_geteuid32, %eax
-    int     $0x80
+    call    *(%esp)
+    addl    $4, %esp
+
     cmpl    $-MAX_ERRNO, %eax
     jb      1f
     negl    %eax
diff --git a/libc/arch-x86/syscalls/getgid.S b/libc/arch-x86/syscalls/getgid.S
index b36a2c9..9189ae9 100644
--- a/libc/arch-x86/syscalls/getgid.S
+++ b/libc/arch-x86/syscalls/getgid.S
@@ -3,8 +3,16 @@
 #include <private/bionic_asm.h>
 
 ENTRY(getgid)
+
+    call    __kernel_syscall
+    pushl   %eax
+    .cfi_adjust_cfa_offset 4
+    .cfi_rel_offset eax, 0
+
     movl    $__NR_getgid32, %eax
-    int     $0x80
+    call    *(%esp)
+    addl    $4, %esp
+
     cmpl    $-MAX_ERRNO, %eax
     jb      1f
     negl    %eax
diff --git a/libc/arch-x86/syscalls/getgroups.S b/libc/arch-x86/syscalls/getgroups.S
index 0a5de35..8737d51 100644
--- a/libc/arch-x86/syscalls/getgroups.S
+++ b/libc/arch-x86/syscalls/getgroups.S
@@ -9,10 +9,18 @@
     pushl   %ecx
     .cfi_adjust_cfa_offset 4
     .cfi_rel_offset ecx, 0
-    mov     12(%esp), %ebx
-    mov     16(%esp), %ecx
+
+    call    __kernel_syscall
+    pushl   %eax
+    .cfi_adjust_cfa_offset 4
+    .cfi_rel_offset eax, 0
+
+    mov     16(%esp), %ebx
+    mov     20(%esp), %ecx
     movl    $__NR_getgroups32, %eax
-    int     $0x80
+    call    *(%esp)
+    addl    $4, %esp
+
     cmpl    $-MAX_ERRNO, %eax
     jb      1f
     negl    %eax
diff --git a/libc/arch-x86/syscalls/getitimer.S b/libc/arch-x86/syscalls/getitimer.S
index a0cb761..e088114 100644
--- a/libc/arch-x86/syscalls/getitimer.S
+++ b/libc/arch-x86/syscalls/getitimer.S
@@ -9,10 +9,18 @@
     pushl   %ecx
     .cfi_adjust_cfa_offset 4
     .cfi_rel_offset ecx, 0
-    mov     12(%esp), %ebx
-    mov     16(%esp), %ecx
+
+    call    __kernel_syscall
+    pushl   %eax
+    .cfi_adjust_cfa_offset 4
+    .cfi_rel_offset eax, 0
+
+    mov     16(%esp), %ebx
+    mov     20(%esp), %ecx
     movl    $__NR_getitimer, %eax
-    int     $0x80
+    call    *(%esp)
+    addl    $4, %esp
+
     cmpl    $-MAX_ERRNO, %eax
     jb      1f
     negl    %eax
diff --git a/libc/arch-x86/syscalls/getpeername.S b/libc/arch-x86/syscalls/getpeername.S
index 6773e6a..40bb814 100644
--- a/libc/arch-x86/syscalls/getpeername.S
+++ b/libc/arch-x86/syscalls/getpeername.S
@@ -9,11 +9,19 @@
     pushl   %ecx
     .cfi_adjust_cfa_offset 4
     .cfi_rel_offset ecx, 0
+
+    call    __kernel_syscall
+    pushl   %eax
+    .cfi_adjust_cfa_offset 4
+    .cfi_rel_offset eax, 0
+
     mov     $7, %ebx
     mov     %esp, %ecx
-    addl    $12, %ecx
+    addl    $16, %ecx
     movl    $__NR_socketcall, %eax
-    int     $0x80
+    call    *(%esp)
+    addl    $4, %esp
+
     cmpl    $-MAX_ERRNO, %eax
     jb      1f
     negl    %eax
diff --git a/libc/arch-x86/syscalls/getpgid.S b/libc/arch-x86/syscalls/getpgid.S
index f702cfd..9d362e8 100644
--- a/libc/arch-x86/syscalls/getpgid.S
+++ b/libc/arch-x86/syscalls/getpgid.S
@@ -6,9 +6,17 @@
     pushl   %ebx
     .cfi_def_cfa_offset 8
     .cfi_rel_offset ebx, 0
-    mov     8(%esp), %ebx
+
+    call    __kernel_syscall
+    pushl   %eax
+    .cfi_adjust_cfa_offset 4
+    .cfi_rel_offset eax, 0
+
+    mov     12(%esp), %ebx
     movl    $__NR_getpgid, %eax
-    int     $0x80
+    call    *(%esp)
+    addl    $4, %esp
+
     cmpl    $-MAX_ERRNO, %eax
     jb      1f
     negl    %eax
diff --git a/libc/arch-x86/syscalls/getppid.S b/libc/arch-x86/syscalls/getppid.S
index edbe384..afb40a1 100644
--- a/libc/arch-x86/syscalls/getppid.S
+++ b/libc/arch-x86/syscalls/getppid.S
@@ -3,8 +3,16 @@
 #include <private/bionic_asm.h>
 
 ENTRY(getppid)
+
+    call    __kernel_syscall
+    pushl   %eax
+    .cfi_adjust_cfa_offset 4
+    .cfi_rel_offset eax, 0
+
     movl    $__NR_getppid, %eax
-    int     $0x80
+    call    *(%esp)
+    addl    $4, %esp
+
     cmpl    $-MAX_ERRNO, %eax
     jb      1f
     negl    %eax
diff --git a/libc/arch-x86/syscalls/getresgid.S b/libc/arch-x86/syscalls/getresgid.S
index 9f1a9dd..131c101 100644
--- a/libc/arch-x86/syscalls/getresgid.S
+++ b/libc/arch-x86/syscalls/getresgid.S
@@ -12,11 +12,19 @@
     pushl   %edx
     .cfi_adjust_cfa_offset 4
     .cfi_rel_offset edx, 0
-    mov     16(%esp), %ebx
-    mov     20(%esp), %ecx
-    mov     24(%esp), %edx
+
+    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_getresgid32, %eax
-    int     $0x80
+    call    *(%esp)
+    addl    $4, %esp
+
     cmpl    $-MAX_ERRNO, %eax
     jb      1f
     negl    %eax
diff --git a/libc/arch-x86/syscalls/getresuid.S b/libc/arch-x86/syscalls/getresuid.S
index 61e1370..94a8767 100644
--- a/libc/arch-x86/syscalls/getresuid.S
+++ b/libc/arch-x86/syscalls/getresuid.S
@@ -12,11 +12,19 @@
     pushl   %edx
     .cfi_adjust_cfa_offset 4
     .cfi_rel_offset edx, 0
-    mov     16(%esp), %ebx
-    mov     20(%esp), %ecx
-    mov     24(%esp), %edx
+
+    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_getresuid32, %eax
-    int     $0x80
+    call    *(%esp)
+    addl    $4, %esp
+
     cmpl    $-MAX_ERRNO, %eax
     jb      1f
     negl    %eax
diff --git a/libc/arch-x86/syscalls/getrlimit.S b/libc/arch-x86/syscalls/getrlimit.S
index c3acff3..c686f7c 100644
--- a/libc/arch-x86/syscalls/getrlimit.S
+++ b/libc/arch-x86/syscalls/getrlimit.S
@@ -9,10 +9,18 @@
     pushl   %ecx
     .cfi_adjust_cfa_offset 4
     .cfi_rel_offset ecx, 0
-    mov     12(%esp), %ebx
-    mov     16(%esp), %ecx
+
+    call    __kernel_syscall
+    pushl   %eax
+    .cfi_adjust_cfa_offset 4
+    .cfi_rel_offset eax, 0
+
+    mov     16(%esp), %ebx
+    mov     20(%esp), %ecx
     movl    $__NR_ugetrlimit, %eax
-    int     $0x80
+    call    *(%esp)
+    addl    $4, %esp
+
     cmpl    $-MAX_ERRNO, %eax
     jb      1f
     negl    %eax
diff --git a/libc/arch-x86/syscalls/getrusage.S b/libc/arch-x86/syscalls/getrusage.S
index 0d715cd..51d1df1 100644
--- a/libc/arch-x86/syscalls/getrusage.S
+++ b/libc/arch-x86/syscalls/getrusage.S
@@ -9,10 +9,18 @@
     pushl   %ecx
     .cfi_adjust_cfa_offset 4
     .cfi_rel_offset ecx, 0
-    mov     12(%esp), %ebx
-    mov     16(%esp), %ecx
+
+    call    __kernel_syscall
+    pushl   %eax
+    .cfi_adjust_cfa_offset 4
+    .cfi_rel_offset eax, 0
+
+    mov     16(%esp), %ebx
+    mov     20(%esp), %ecx
     movl    $__NR_getrusage, %eax
-    int     $0x80
+    call    *(%esp)
+    addl    $4, %esp
+
     cmpl    $-MAX_ERRNO, %eax
     jb      1f
     negl    %eax
diff --git a/libc/arch-x86/syscalls/getsid.S b/libc/arch-x86/syscalls/getsid.S
index e142c05..a4568e6 100644
--- a/libc/arch-x86/syscalls/getsid.S
+++ b/libc/arch-x86/syscalls/getsid.S
@@ -6,9 +6,17 @@
     pushl   %ebx
     .cfi_def_cfa_offset 8
     .cfi_rel_offset ebx, 0
-    mov     8(%esp), %ebx
+
+    call    __kernel_syscall
+    pushl   %eax
+    .cfi_adjust_cfa_offset 4
+    .cfi_rel_offset eax, 0
+
+    mov     12(%esp), %ebx
     movl    $__NR_getsid, %eax
-    int     $0x80
+    call    *(%esp)
+    addl    $4, %esp
+
     cmpl    $-MAX_ERRNO, %eax
     jb      1f
     negl    %eax
diff --git a/libc/arch-x86/syscalls/getsockname.S b/libc/arch-x86/syscalls/getsockname.S
index 6050190..0fd5836 100644
--- a/libc/arch-x86/syscalls/getsockname.S
+++ b/libc/arch-x86/syscalls/getsockname.S
@@ -9,11 +9,19 @@
     pushl   %ecx
     .cfi_adjust_cfa_offset 4
     .cfi_rel_offset ecx, 0
+
+    call    __kernel_syscall
+    pushl   %eax
+    .cfi_adjust_cfa_offset 4
+    .cfi_rel_offset eax, 0
+
     mov     $6, %ebx
     mov     %esp, %ecx
-    addl    $12, %ecx
+    addl    $16, %ecx
     movl    $__NR_socketcall, %eax
-    int     $0x80
+    call    *(%esp)
+    addl    $4, %esp
+
     cmpl    $-MAX_ERRNO, %eax
     jb      1f
     negl    %eax
diff --git a/libc/arch-x86/syscalls/getsockopt.S b/libc/arch-x86/syscalls/getsockopt.S
index aec40cf..fa6fccf 100644
--- a/libc/arch-x86/syscalls/getsockopt.S
+++ b/libc/arch-x86/syscalls/getsockopt.S
@@ -9,11 +9,19 @@
     pushl   %ecx
     .cfi_adjust_cfa_offset 4
     .cfi_rel_offset ecx, 0
+
+    call    __kernel_syscall
+    pushl   %eax
+    .cfi_adjust_cfa_offset 4
+    .cfi_rel_offset eax, 0
+
     mov     $15, %ebx
     mov     %esp, %ecx
-    addl    $12, %ecx
+    addl    $16, %ecx
     movl    $__NR_socketcall, %eax
-    int     $0x80
+    call    *(%esp)
+    addl    $4, %esp
+
     cmpl    $-MAX_ERRNO, %eax
     jb      1f
     negl    %eax
diff --git a/libc/arch-x86/syscalls/getuid.S b/libc/arch-x86/syscalls/getuid.S
index cc62884..11cc0c6 100644
--- a/libc/arch-x86/syscalls/getuid.S
+++ b/libc/arch-x86/syscalls/getuid.S
@@ -3,8 +3,16 @@
 #include <private/bionic_asm.h>
 
 ENTRY(getuid)
+
+    call    __kernel_syscall
+    pushl   %eax
+    .cfi_adjust_cfa_offset 4
+    .cfi_rel_offset eax, 0
+
     movl    $__NR_getuid32, %eax
-    int     $0x80
+    call    *(%esp)
+    addl    $4, %esp
+
     cmpl    $-MAX_ERRNO, %eax
     jb      1f
     negl    %eax
diff --git a/libc/arch-x86/syscalls/getxattr.S b/libc/arch-x86/syscalls/getxattr.S
index a2cf137..871362e 100644
--- a/libc/arch-x86/syscalls/getxattr.S
+++ b/libc/arch-x86/syscalls/getxattr.S
@@ -15,12 +15,20 @@
     pushl   %esi
     .cfi_adjust_cfa_offset 4
     .cfi_rel_offset esi, 0
-    mov     20(%esp), %ebx
-    mov     24(%esp), %ecx
-    mov     28(%esp), %edx
-    mov     32(%esp), %esi
+
+    call    __kernel_syscall
+    pushl   %eax
+    .cfi_adjust_cfa_offset 4
+    .cfi_rel_offset eax, 0
+
+    mov     24(%esp), %ebx
+    mov     28(%esp), %ecx
+    mov     32(%esp), %edx
+    mov     36(%esp), %esi
     movl    $__NR_getxattr, %eax
-    int     $0x80
+    call    *(%esp)
+    addl    $4, %esp
+
     cmpl    $-MAX_ERRNO, %eax
     jb      1f
     negl    %eax
diff --git a/libc/arch-x86/syscalls/init_module.S b/libc/arch-x86/syscalls/init_module.S
index 1d0f111..0147eee 100644
--- a/libc/arch-x86/syscalls/init_module.S
+++ b/libc/arch-x86/syscalls/init_module.S
@@ -12,11 +12,19 @@
     pushl   %edx
     .cfi_adjust_cfa_offset 4
     .cfi_rel_offset edx, 0
-    mov     16(%esp), %ebx
-    mov     20(%esp), %ecx
-    mov     24(%esp), %edx
+
+    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_init_module, %eax
-    int     $0x80
+    call    *(%esp)
+    addl    $4, %esp
+
     cmpl    $-MAX_ERRNO, %eax
     jb      1f
     negl    %eax
diff --git a/libc/arch-x86/syscalls/inotify_add_watch.S b/libc/arch-x86/syscalls/inotify_add_watch.S
index 8cadc6e..f196440 100644
--- a/libc/arch-x86/syscalls/inotify_add_watch.S
+++ b/libc/arch-x86/syscalls/inotify_add_watch.S
@@ -12,11 +12,19 @@
     pushl   %edx
     .cfi_adjust_cfa_offset 4
     .cfi_rel_offset edx, 0
-    mov     16(%esp), %ebx
-    mov     20(%esp), %ecx
-    mov     24(%esp), %edx
+
+    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_inotify_add_watch, %eax
-    int     $0x80
+    call    *(%esp)
+    addl    $4, %esp
+
     cmpl    $-MAX_ERRNO, %eax
     jb      1f
     negl    %eax
diff --git a/libc/arch-x86/syscalls/inotify_init1.S b/libc/arch-x86/syscalls/inotify_init1.S
index 23671e0..7f0dcfb 100644
--- a/libc/arch-x86/syscalls/inotify_init1.S
+++ b/libc/arch-x86/syscalls/inotify_init1.S
@@ -6,9 +6,17 @@
     pushl   %ebx
     .cfi_def_cfa_offset 8
     .cfi_rel_offset ebx, 0
-    mov     8(%esp), %ebx
+
+    call    __kernel_syscall
+    pushl   %eax
+    .cfi_adjust_cfa_offset 4
+    .cfi_rel_offset eax, 0
+
+    mov     12(%esp), %ebx
     movl    $__NR_inotify_init1, %eax
-    int     $0x80
+    call    *(%esp)
+    addl    $4, %esp
+
     cmpl    $-MAX_ERRNO, %eax
     jb      1f
     negl    %eax
diff --git a/libc/arch-x86/syscalls/inotify_rm_watch.S b/libc/arch-x86/syscalls/inotify_rm_watch.S
index c246c00..595e053 100644
--- a/libc/arch-x86/syscalls/inotify_rm_watch.S
+++ b/libc/arch-x86/syscalls/inotify_rm_watch.S
@@ -9,10 +9,18 @@
     pushl   %ecx
     .cfi_adjust_cfa_offset 4
     .cfi_rel_offset ecx, 0
-    mov     12(%esp), %ebx
-    mov     16(%esp), %ecx
+
+    call    __kernel_syscall
+    pushl   %eax
+    .cfi_adjust_cfa_offset 4
+    .cfi_rel_offset eax, 0
+
+    mov     16(%esp), %ebx
+    mov     20(%esp), %ecx
     movl    $__NR_inotify_rm_watch, %eax
-    int     $0x80
+    call    *(%esp)
+    addl    $4, %esp
+
     cmpl    $-MAX_ERRNO, %eax
     jb      1f
     negl    %eax
diff --git a/libc/arch-x86/syscalls/kill.S b/libc/arch-x86/syscalls/kill.S
index edc9cde..4ee56e6 100644
--- a/libc/arch-x86/syscalls/kill.S
+++ b/libc/arch-x86/syscalls/kill.S
@@ -9,10 +9,18 @@
     pushl   %ecx
     .cfi_adjust_cfa_offset 4
     .cfi_rel_offset ecx, 0
-    mov     12(%esp), %ebx
-    mov     16(%esp), %ecx
+
+    call    __kernel_syscall
+    pushl   %eax
+    .cfi_adjust_cfa_offset 4
+    .cfi_rel_offset eax, 0
+
+    mov     16(%esp), %ebx
+    mov     20(%esp), %ecx
     movl    $__NR_kill, %eax
-    int     $0x80
+    call    *(%esp)
+    addl    $4, %esp
+
     cmpl    $-MAX_ERRNO, %eax
     jb      1f
     negl    %eax
diff --git a/libc/arch-x86/syscalls/klogctl.S b/libc/arch-x86/syscalls/klogctl.S
index 5de9a31e..3d07942 100644
--- a/libc/arch-x86/syscalls/klogctl.S
+++ b/libc/arch-x86/syscalls/klogctl.S
@@ -12,11 +12,19 @@
     pushl   %edx
     .cfi_adjust_cfa_offset 4
     .cfi_rel_offset edx, 0
-    mov     16(%esp), %ebx
-    mov     20(%esp), %ecx
-    mov     24(%esp), %edx
+
+    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_syslog, %eax
-    int     $0x80
+    call    *(%esp)
+    addl    $4, %esp
+
     cmpl    $-MAX_ERRNO, %eax
     jb      1f
     negl    %eax
diff --git a/libc/arch-x86/syscalls/lgetxattr.S b/libc/arch-x86/syscalls/lgetxattr.S
index 55697a0..659b088 100644
--- a/libc/arch-x86/syscalls/lgetxattr.S
+++ b/libc/arch-x86/syscalls/lgetxattr.S
@@ -15,12 +15,20 @@
     pushl   %esi
     .cfi_adjust_cfa_offset 4
     .cfi_rel_offset esi, 0
-    mov     20(%esp), %ebx
-    mov     24(%esp), %ecx
-    mov     28(%esp), %edx
-    mov     32(%esp), %esi
+
+    call    __kernel_syscall
+    pushl   %eax
+    .cfi_adjust_cfa_offset 4
+    .cfi_rel_offset eax, 0
+
+    mov     24(%esp), %ebx
+    mov     28(%esp), %ecx
+    mov     32(%esp), %edx
+    mov     36(%esp), %esi
     movl    $__NR_lgetxattr, %eax
-    int     $0x80
+    call    *(%esp)
+    addl    $4, %esp
+
     cmpl    $-MAX_ERRNO, %eax
     jb      1f
     negl    %eax
diff --git a/libc/arch-x86/syscalls/linkat.S b/libc/arch-x86/syscalls/linkat.S
index 8b2646d..644172d 100644
--- a/libc/arch-x86/syscalls/linkat.S
+++ b/libc/arch-x86/syscalls/linkat.S
@@ -18,13 +18,21 @@
     pushl   %edi
     .cfi_adjust_cfa_offset 4
     .cfi_rel_offset edi, 0
-    mov     24(%esp), %ebx
-    mov     28(%esp), %ecx
-    mov     32(%esp), %edx
-    mov     36(%esp), %esi
-    mov     40(%esp), %edi
+
+    call    __kernel_syscall
+    pushl   %eax
+    .cfi_adjust_cfa_offset 4
+    .cfi_rel_offset eax, 0
+
+    mov     28(%esp), %ebx
+    mov     32(%esp), %ecx
+    mov     36(%esp), %edx
+    mov     40(%esp), %esi
+    mov     44(%esp), %edi
     movl    $__NR_linkat, %eax
-    int     $0x80
+    call    *(%esp)
+    addl    $4, %esp
+
     cmpl    $-MAX_ERRNO, %eax
     jb      1f
     negl    %eax
diff --git a/libc/arch-x86/syscalls/listen.S b/libc/arch-x86/syscalls/listen.S
index 8ae4186..ce7c3a9 100644
--- a/libc/arch-x86/syscalls/listen.S
+++ b/libc/arch-x86/syscalls/listen.S
@@ -9,11 +9,19 @@
     pushl   %ecx
     .cfi_adjust_cfa_offset 4
     .cfi_rel_offset ecx, 0
+
+    call    __kernel_syscall
+    pushl   %eax
+    .cfi_adjust_cfa_offset 4
+    .cfi_rel_offset eax, 0
+
     mov     $4, %ebx
     mov     %esp, %ecx
-    addl    $12, %ecx
+    addl    $16, %ecx
     movl    $__NR_socketcall, %eax
-    int     $0x80
+    call    *(%esp)
+    addl    $4, %esp
+
     cmpl    $-MAX_ERRNO, %eax
     jb      1f
     negl    %eax
diff --git a/libc/arch-x86/syscalls/listxattr.S b/libc/arch-x86/syscalls/listxattr.S
index a73dc1a..2fe799e 100644
--- a/libc/arch-x86/syscalls/listxattr.S
+++ b/libc/arch-x86/syscalls/listxattr.S
@@ -12,11 +12,19 @@
     pushl   %edx
     .cfi_adjust_cfa_offset 4
     .cfi_rel_offset edx, 0
-    mov     16(%esp), %ebx
-    mov     20(%esp), %ecx
-    mov     24(%esp), %edx
+
+    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_listxattr, %eax
-    int     $0x80
+    call    *(%esp)
+    addl    $4, %esp
+
     cmpl    $-MAX_ERRNO, %eax
     jb      1f
     negl    %eax
diff --git a/libc/arch-x86/syscalls/llistxattr.S b/libc/arch-x86/syscalls/llistxattr.S
index 63d4489..666d87e 100644
--- a/libc/arch-x86/syscalls/llistxattr.S
+++ b/libc/arch-x86/syscalls/llistxattr.S
@@ -12,11 +12,19 @@
     pushl   %edx
     .cfi_adjust_cfa_offset 4
     .cfi_rel_offset edx, 0
-    mov     16(%esp), %ebx
-    mov     20(%esp), %ecx
-    mov     24(%esp), %edx
+
+    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_llistxattr, %eax
-    int     $0x80
+    call    *(%esp)
+    addl    $4, %esp
+
     cmpl    $-MAX_ERRNO, %eax
     jb      1f
     negl    %eax
diff --git a/libc/arch-x86/syscalls/lremovexattr.S b/libc/arch-x86/syscalls/lremovexattr.S
index 42c7e0f..bda772b 100644
--- a/libc/arch-x86/syscalls/lremovexattr.S
+++ b/libc/arch-x86/syscalls/lremovexattr.S
@@ -9,10 +9,18 @@
     pushl   %ecx
     .cfi_adjust_cfa_offset 4
     .cfi_rel_offset ecx, 0
-    mov     12(%esp), %ebx
-    mov     16(%esp), %ecx
+
+    call    __kernel_syscall
+    pushl   %eax
+    .cfi_adjust_cfa_offset 4
+    .cfi_rel_offset eax, 0
+
+    mov     16(%esp), %ebx
+    mov     20(%esp), %ecx
     movl    $__NR_lremovexattr, %eax
-    int     $0x80
+    call    *(%esp)
+    addl    $4, %esp
+
     cmpl    $-MAX_ERRNO, %eax
     jb      1f
     negl    %eax
diff --git a/libc/arch-x86/syscalls/lseek.S b/libc/arch-x86/syscalls/lseek.S
index bfe9e63..9142b5c 100644
--- a/libc/arch-x86/syscalls/lseek.S
+++ b/libc/arch-x86/syscalls/lseek.S
@@ -12,11 +12,19 @@
     pushl   %edx
     .cfi_adjust_cfa_offset 4
     .cfi_rel_offset edx, 0
-    mov     16(%esp), %ebx
-    mov     20(%esp), %ecx
-    mov     24(%esp), %edx
+
+    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_lseek, %eax
-    int     $0x80
+    call    *(%esp)
+    addl    $4, %esp
+
     cmpl    $-MAX_ERRNO, %eax
     jb      1f
     negl    %eax
diff --git a/libc/arch-x86/syscalls/lsetxattr.S b/libc/arch-x86/syscalls/lsetxattr.S
index f36fc6a..fa977b3 100644
--- a/libc/arch-x86/syscalls/lsetxattr.S
+++ b/libc/arch-x86/syscalls/lsetxattr.S
@@ -18,13 +18,21 @@
     pushl   %edi
     .cfi_adjust_cfa_offset 4
     .cfi_rel_offset edi, 0
-    mov     24(%esp), %ebx
-    mov     28(%esp), %ecx
-    mov     32(%esp), %edx
-    mov     36(%esp), %esi
-    mov     40(%esp), %edi
+
+    call    __kernel_syscall
+    pushl   %eax
+    .cfi_adjust_cfa_offset 4
+    .cfi_rel_offset eax, 0
+
+    mov     28(%esp), %ebx
+    mov     32(%esp), %ecx
+    mov     36(%esp), %edx
+    mov     40(%esp), %esi
+    mov     44(%esp), %edi
     movl    $__NR_lsetxattr, %eax
-    int     $0x80
+    call    *(%esp)
+    addl    $4, %esp
+
     cmpl    $-MAX_ERRNO, %eax
     jb      1f
     negl    %eax
diff --git a/libc/arch-x86/syscalls/madvise.S b/libc/arch-x86/syscalls/madvise.S
index b69f5d4..21f472e 100644
--- a/libc/arch-x86/syscalls/madvise.S
+++ b/libc/arch-x86/syscalls/madvise.S
@@ -12,11 +12,19 @@
     pushl   %edx
     .cfi_adjust_cfa_offset 4
     .cfi_rel_offset edx, 0
-    mov     16(%esp), %ebx
-    mov     20(%esp), %ecx
-    mov     24(%esp), %edx
+
+    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_madvise, %eax
-    int     $0x80
+    call    *(%esp)
+    addl    $4, %esp
+
     cmpl    $-MAX_ERRNO, %eax
     jb      1f
     negl    %eax
diff --git a/libc/arch-x86/syscalls/mincore.S b/libc/arch-x86/syscalls/mincore.S
index 6d1df67..4179c9a 100644
--- a/libc/arch-x86/syscalls/mincore.S
+++ b/libc/arch-x86/syscalls/mincore.S
@@ -12,11 +12,19 @@
     pushl   %edx
     .cfi_adjust_cfa_offset 4
     .cfi_rel_offset edx, 0
-    mov     16(%esp), %ebx
-    mov     20(%esp), %ecx
-    mov     24(%esp), %edx
+
+    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_mincore, %eax
-    int     $0x80
+    call    *(%esp)
+    addl    $4, %esp
+
     cmpl    $-MAX_ERRNO, %eax
     jb      1f
     negl    %eax
diff --git a/libc/arch-x86/syscalls/mkdirat.S b/libc/arch-x86/syscalls/mkdirat.S
index 5b6ae18..6a9d94c 100644
--- a/libc/arch-x86/syscalls/mkdirat.S
+++ b/libc/arch-x86/syscalls/mkdirat.S
@@ -12,11 +12,19 @@
     pushl   %edx
     .cfi_adjust_cfa_offset 4
     .cfi_rel_offset edx, 0
-    mov     16(%esp), %ebx
-    mov     20(%esp), %ecx
-    mov     24(%esp), %edx
+
+    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_mkdirat, %eax
-    int     $0x80
+    call    *(%esp)
+    addl    $4, %esp
+
     cmpl    $-MAX_ERRNO, %eax
     jb      1f
     negl    %eax
diff --git a/libc/arch-x86/syscalls/mknodat.S b/libc/arch-x86/syscalls/mknodat.S
index b19d972..a1fae7f 100644
--- a/libc/arch-x86/syscalls/mknodat.S
+++ b/libc/arch-x86/syscalls/mknodat.S
@@ -15,12 +15,20 @@
     pushl   %esi
     .cfi_adjust_cfa_offset 4
     .cfi_rel_offset esi, 0
-    mov     20(%esp), %ebx
-    mov     24(%esp), %ecx
-    mov     28(%esp), %edx
-    mov     32(%esp), %esi
+
+    call    __kernel_syscall
+    pushl   %eax
+    .cfi_adjust_cfa_offset 4
+    .cfi_rel_offset eax, 0
+
+    mov     24(%esp), %ebx
+    mov     28(%esp), %ecx
+    mov     32(%esp), %edx
+    mov     36(%esp), %esi
     movl    $__NR_mknodat, %eax
-    int     $0x80
+    call    *(%esp)
+    addl    $4, %esp
+
     cmpl    $-MAX_ERRNO, %eax
     jb      1f
     negl    %eax
diff --git a/libc/arch-x86/syscalls/mlock.S b/libc/arch-x86/syscalls/mlock.S
index 517e5a5..1c57ac0 100644
--- a/libc/arch-x86/syscalls/mlock.S
+++ b/libc/arch-x86/syscalls/mlock.S
@@ -9,10 +9,18 @@
     pushl   %ecx
     .cfi_adjust_cfa_offset 4
     .cfi_rel_offset ecx, 0
-    mov     12(%esp), %ebx
-    mov     16(%esp), %ecx
+
+    call    __kernel_syscall
+    pushl   %eax
+    .cfi_adjust_cfa_offset 4
+    .cfi_rel_offset eax, 0
+
+    mov     16(%esp), %ebx
+    mov     20(%esp), %ecx
     movl    $__NR_mlock, %eax
-    int     $0x80
+    call    *(%esp)
+    addl    $4, %esp
+
     cmpl    $-MAX_ERRNO, %eax
     jb      1f
     negl    %eax
diff --git a/libc/arch-x86/syscalls/mlockall.S b/libc/arch-x86/syscalls/mlockall.S
index 756ca16..9f54de3 100644
--- a/libc/arch-x86/syscalls/mlockall.S
+++ b/libc/arch-x86/syscalls/mlockall.S
@@ -6,9 +6,17 @@
     pushl   %ebx
     .cfi_def_cfa_offset 8
     .cfi_rel_offset ebx, 0
-    mov     8(%esp), %ebx
+
+    call    __kernel_syscall
+    pushl   %eax
+    .cfi_adjust_cfa_offset 4
+    .cfi_rel_offset eax, 0
+
+    mov     12(%esp), %ebx
     movl    $__NR_mlockall, %eax
-    int     $0x80
+    call    *(%esp)
+    addl    $4, %esp
+
     cmpl    $-MAX_ERRNO, %eax
     jb      1f
     negl    %eax
diff --git a/libc/arch-x86/syscalls/mount.S b/libc/arch-x86/syscalls/mount.S
index 0537528..4a9f91a 100644
--- a/libc/arch-x86/syscalls/mount.S
+++ b/libc/arch-x86/syscalls/mount.S
@@ -18,13 +18,21 @@
     pushl   %edi
     .cfi_adjust_cfa_offset 4
     .cfi_rel_offset edi, 0
-    mov     24(%esp), %ebx
-    mov     28(%esp), %ecx
-    mov     32(%esp), %edx
-    mov     36(%esp), %esi
-    mov     40(%esp), %edi
+
+    call    __kernel_syscall
+    pushl   %eax
+    .cfi_adjust_cfa_offset 4
+    .cfi_rel_offset eax, 0
+
+    mov     28(%esp), %ebx
+    mov     32(%esp), %ecx
+    mov     36(%esp), %edx
+    mov     40(%esp), %esi
+    mov     44(%esp), %edi
     movl    $__NR_mount, %eax
-    int     $0x80
+    call    *(%esp)
+    addl    $4, %esp
+
     cmpl    $-MAX_ERRNO, %eax
     jb      1f
     negl    %eax
diff --git a/libc/arch-x86/syscalls/mprotect.S b/libc/arch-x86/syscalls/mprotect.S
index 1ba186c..5eec550 100644
--- a/libc/arch-x86/syscalls/mprotect.S
+++ b/libc/arch-x86/syscalls/mprotect.S
@@ -12,11 +12,19 @@
     pushl   %edx
     .cfi_adjust_cfa_offset 4
     .cfi_rel_offset edx, 0
-    mov     16(%esp), %ebx
-    mov     20(%esp), %ecx
-    mov     24(%esp), %edx
+
+    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_mprotect, %eax
-    int     $0x80
+    call    *(%esp)
+    addl    $4, %esp
+
     cmpl    $-MAX_ERRNO, %eax
     jb      1f
     negl    %eax
diff --git a/libc/arch-x86/syscalls/msync.S b/libc/arch-x86/syscalls/msync.S
index 81bd598..7754da6 100644
--- a/libc/arch-x86/syscalls/msync.S
+++ b/libc/arch-x86/syscalls/msync.S
@@ -12,11 +12,19 @@
     pushl   %edx
     .cfi_adjust_cfa_offset 4
     .cfi_rel_offset edx, 0
-    mov     16(%esp), %ebx
-    mov     20(%esp), %ecx
-    mov     24(%esp), %edx
+
+    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_msync, %eax
-    int     $0x80
+    call    *(%esp)
+    addl    $4, %esp
+
     cmpl    $-MAX_ERRNO, %eax
     jb      1f
     negl    %eax
diff --git a/libc/arch-x86/syscalls/munlock.S b/libc/arch-x86/syscalls/munlock.S
index 67ca3fe..d2ae9f0 100644
--- a/libc/arch-x86/syscalls/munlock.S
+++ b/libc/arch-x86/syscalls/munlock.S
@@ -9,10 +9,18 @@
     pushl   %ecx
     .cfi_adjust_cfa_offset 4
     .cfi_rel_offset ecx, 0
-    mov     12(%esp), %ebx
-    mov     16(%esp), %ecx
+
+    call    __kernel_syscall
+    pushl   %eax
+    .cfi_adjust_cfa_offset 4
+    .cfi_rel_offset eax, 0
+
+    mov     16(%esp), %ebx
+    mov     20(%esp), %ecx
     movl    $__NR_munlock, %eax
-    int     $0x80
+    call    *(%esp)
+    addl    $4, %esp
+
     cmpl    $-MAX_ERRNO, %eax
     jb      1f
     negl    %eax
diff --git a/libc/arch-x86/syscalls/munlockall.S b/libc/arch-x86/syscalls/munlockall.S
index bf0bfa1..e709b8c 100644
--- a/libc/arch-x86/syscalls/munlockall.S
+++ b/libc/arch-x86/syscalls/munlockall.S
@@ -3,8 +3,16 @@
 #include <private/bionic_asm.h>
 
 ENTRY(munlockall)
+
+    call    __kernel_syscall
+    pushl   %eax
+    .cfi_adjust_cfa_offset 4
+    .cfi_rel_offset eax, 0
+
     movl    $__NR_munlockall, %eax
-    int     $0x80
+    call    *(%esp)
+    addl    $4, %esp
+
     cmpl    $-MAX_ERRNO, %eax
     jb      1f
     negl    %eax
diff --git a/libc/arch-x86/syscalls/munmap.S b/libc/arch-x86/syscalls/munmap.S
index 272cb52..7ddc5aa 100644
--- a/libc/arch-x86/syscalls/munmap.S
+++ b/libc/arch-x86/syscalls/munmap.S
@@ -9,10 +9,18 @@
     pushl   %ecx
     .cfi_adjust_cfa_offset 4
     .cfi_rel_offset ecx, 0
-    mov     12(%esp), %ebx
-    mov     16(%esp), %ecx
+
+    call    __kernel_syscall
+    pushl   %eax
+    .cfi_adjust_cfa_offset 4
+    .cfi_rel_offset eax, 0
+
+    mov     16(%esp), %ebx
+    mov     20(%esp), %ecx
     movl    $__NR_munmap, %eax
-    int     $0x80
+    call    *(%esp)
+    addl    $4, %esp
+
     cmpl    $-MAX_ERRNO, %eax
     jb      1f
     negl    %eax
diff --git a/libc/arch-x86/syscalls/nanosleep.S b/libc/arch-x86/syscalls/nanosleep.S
index 5c46a4a..580f5e1 100644
--- a/libc/arch-x86/syscalls/nanosleep.S
+++ b/libc/arch-x86/syscalls/nanosleep.S
@@ -9,10 +9,18 @@
     pushl   %ecx
     .cfi_adjust_cfa_offset 4
     .cfi_rel_offset ecx, 0
-    mov     12(%esp), %ebx
-    mov     16(%esp), %ecx
+
+    call    __kernel_syscall
+    pushl   %eax
+    .cfi_adjust_cfa_offset 4
+    .cfi_rel_offset eax, 0
+
+    mov     16(%esp), %ebx
+    mov     20(%esp), %ecx
     movl    $__NR_nanosleep, %eax
-    int     $0x80
+    call    *(%esp)
+    addl    $4, %esp
+
     cmpl    $-MAX_ERRNO, %eax
     jb      1f
     negl    %eax
diff --git a/libc/arch-x86/syscalls/personality.S b/libc/arch-x86/syscalls/personality.S
index d60ced1..3e003c4 100644
--- a/libc/arch-x86/syscalls/personality.S
+++ b/libc/arch-x86/syscalls/personality.S
@@ -6,9 +6,17 @@
     pushl   %ebx
     .cfi_def_cfa_offset 8
     .cfi_rel_offset ebx, 0
-    mov     8(%esp), %ebx
+
+    call    __kernel_syscall
+    pushl   %eax
+    .cfi_adjust_cfa_offset 4
+    .cfi_rel_offset eax, 0
+
+    mov     12(%esp), %ebx
     movl    $__NR_personality, %eax
-    int     $0x80
+    call    *(%esp)
+    addl    $4, %esp
+
     cmpl    $-MAX_ERRNO, %eax
     jb      1f
     negl    %eax
diff --git a/libc/arch-x86/syscalls/pipe2.S b/libc/arch-x86/syscalls/pipe2.S
index ee49ff8..8a93281 100644
--- a/libc/arch-x86/syscalls/pipe2.S
+++ b/libc/arch-x86/syscalls/pipe2.S
@@ -9,10 +9,18 @@
     pushl   %ecx
     .cfi_adjust_cfa_offset 4
     .cfi_rel_offset ecx, 0
-    mov     12(%esp), %ebx
-    mov     16(%esp), %ecx
+
+    call    __kernel_syscall
+    pushl   %eax
+    .cfi_adjust_cfa_offset 4
+    .cfi_rel_offset eax, 0
+
+    mov     16(%esp), %ebx
+    mov     20(%esp), %ecx
     movl    $__NR_pipe2, %eax
-    int     $0x80
+    call    *(%esp)
+    addl    $4, %esp
+
     cmpl    $-MAX_ERRNO, %eax
     jb      1f
     negl    %eax
diff --git a/libc/arch-x86/syscalls/prctl.S b/libc/arch-x86/syscalls/prctl.S
index 496591e..22b4a83 100644
--- a/libc/arch-x86/syscalls/prctl.S
+++ b/libc/arch-x86/syscalls/prctl.S
@@ -18,13 +18,21 @@
     pushl   %edi
     .cfi_adjust_cfa_offset 4
     .cfi_rel_offset edi, 0
-    mov     24(%esp), %ebx
-    mov     28(%esp), %ecx
-    mov     32(%esp), %edx
-    mov     36(%esp), %esi
-    mov     40(%esp), %edi
+
+    call    __kernel_syscall
+    pushl   %eax
+    .cfi_adjust_cfa_offset 4
+    .cfi_rel_offset eax, 0
+
+    mov     28(%esp), %ebx
+    mov     32(%esp), %ecx
+    mov     36(%esp), %edx
+    mov     40(%esp), %esi
+    mov     44(%esp), %edi
     movl    $__NR_prctl, %eax
-    int     $0x80
+    call    *(%esp)
+    addl    $4, %esp
+
     cmpl    $-MAX_ERRNO, %eax
     jb      1f
     negl    %eax
diff --git a/libc/arch-x86/syscalls/pread64.S b/libc/arch-x86/syscalls/pread64.S
index 42e54ec..9002f17 100644
--- a/libc/arch-x86/syscalls/pread64.S
+++ b/libc/arch-x86/syscalls/pread64.S
@@ -18,13 +18,21 @@
     pushl   %edi
     .cfi_adjust_cfa_offset 4
     .cfi_rel_offset edi, 0
-    mov     24(%esp), %ebx
-    mov     28(%esp), %ecx
-    mov     32(%esp), %edx
-    mov     36(%esp), %esi
-    mov     40(%esp), %edi
+
+    call    __kernel_syscall
+    pushl   %eax
+    .cfi_adjust_cfa_offset 4
+    .cfi_rel_offset eax, 0
+
+    mov     28(%esp), %ebx
+    mov     32(%esp), %ecx
+    mov     36(%esp), %edx
+    mov     40(%esp), %esi
+    mov     44(%esp), %edi
     movl    $__NR_pread64, %eax
-    int     $0x80
+    call    *(%esp)
+    addl    $4, %esp
+
     cmpl    $-MAX_ERRNO, %eax
     jb      1f
     negl    %eax
diff --git a/libc/arch-x86/syscalls/prlimit64.S b/libc/arch-x86/syscalls/prlimit64.S
index 07b5585..13f6682 100644
--- a/libc/arch-x86/syscalls/prlimit64.S
+++ b/libc/arch-x86/syscalls/prlimit64.S
@@ -15,12 +15,20 @@
     pushl   %esi
     .cfi_adjust_cfa_offset 4
     .cfi_rel_offset esi, 0
-    mov     20(%esp), %ebx
-    mov     24(%esp), %ecx
-    mov     28(%esp), %edx
-    mov     32(%esp), %esi
+
+    call    __kernel_syscall
+    pushl   %eax
+    .cfi_adjust_cfa_offset 4
+    .cfi_rel_offset eax, 0
+
+    mov     24(%esp), %ebx
+    mov     28(%esp), %ecx
+    mov     32(%esp), %edx
+    mov     36(%esp), %esi
     movl    $__NR_prlimit64, %eax
-    int     $0x80
+    call    *(%esp)
+    addl    $4, %esp
+
     cmpl    $-MAX_ERRNO, %eax
     jb      1f
     negl    %eax
diff --git a/libc/arch-x86/syscalls/process_vm_readv.S b/libc/arch-x86/syscalls/process_vm_readv.S
index 64965f6..e2cd044 100644
--- a/libc/arch-x86/syscalls/process_vm_readv.S
+++ b/libc/arch-x86/syscalls/process_vm_readv.S
@@ -21,14 +21,22 @@
     pushl   %ebp
     .cfi_adjust_cfa_offset 4
     .cfi_rel_offset ebp, 0
-    mov     28(%esp), %ebx
-    mov     32(%esp), %ecx
-    mov     36(%esp), %edx
-    mov     40(%esp), %esi
-    mov     44(%esp), %edi
-    mov     48(%esp), %ebp
+
+    call    __kernel_syscall
+    pushl   %eax
+    .cfi_adjust_cfa_offset 4
+    .cfi_rel_offset eax, 0
+
+    mov     32(%esp), %ebx
+    mov     36(%esp), %ecx
+    mov     40(%esp), %edx
+    mov     44(%esp), %esi
+    mov     48(%esp), %edi
+    mov     52(%esp), %ebp
     movl    $__NR_process_vm_readv, %eax
-    int     $0x80
+    call    *(%esp)
+    addl    $4, %esp
+
     cmpl    $-MAX_ERRNO, %eax
     jb      1f
     negl    %eax
diff --git a/libc/arch-x86/syscalls/process_vm_writev.S b/libc/arch-x86/syscalls/process_vm_writev.S
index 555c822..de0d218 100644
--- a/libc/arch-x86/syscalls/process_vm_writev.S
+++ b/libc/arch-x86/syscalls/process_vm_writev.S
@@ -21,14 +21,22 @@
     pushl   %ebp
     .cfi_adjust_cfa_offset 4
     .cfi_rel_offset ebp, 0
-    mov     28(%esp), %ebx
-    mov     32(%esp), %ecx
-    mov     36(%esp), %edx
-    mov     40(%esp), %esi
-    mov     44(%esp), %edi
-    mov     48(%esp), %ebp
+
+    call    __kernel_syscall
+    pushl   %eax
+    .cfi_adjust_cfa_offset 4
+    .cfi_rel_offset eax, 0
+
+    mov     32(%esp), %ebx
+    mov     36(%esp), %ecx
+    mov     40(%esp), %edx
+    mov     44(%esp), %esi
+    mov     48(%esp), %edi
+    mov     52(%esp), %ebp
     movl    $__NR_process_vm_writev, %eax
-    int     $0x80
+    call    *(%esp)
+    addl    $4, %esp
+
     cmpl    $-MAX_ERRNO, %eax
     jb      1f
     negl    %eax
diff --git a/libc/arch-x86/syscalls/pwrite64.S b/libc/arch-x86/syscalls/pwrite64.S
index d5c9b31..7532729 100644
--- a/libc/arch-x86/syscalls/pwrite64.S
+++ b/libc/arch-x86/syscalls/pwrite64.S
@@ -18,13 +18,21 @@
     pushl   %edi
     .cfi_adjust_cfa_offset 4
     .cfi_rel_offset edi, 0
-    mov     24(%esp), %ebx
-    mov     28(%esp), %ecx
-    mov     32(%esp), %edx
-    mov     36(%esp), %esi
-    mov     40(%esp), %edi
+
+    call    __kernel_syscall
+    pushl   %eax
+    .cfi_adjust_cfa_offset 4
+    .cfi_rel_offset eax, 0
+
+    mov     28(%esp), %ebx
+    mov     32(%esp), %ecx
+    mov     36(%esp), %edx
+    mov     40(%esp), %esi
+    mov     44(%esp), %edi
     movl    $__NR_pwrite64, %eax
-    int     $0x80
+    call    *(%esp)
+    addl    $4, %esp
+
     cmpl    $-MAX_ERRNO, %eax
     jb      1f
     negl    %eax
diff --git a/libc/arch-x86/syscalls/read.S b/libc/arch-x86/syscalls/read.S
index c10a83b..d4b69b5 100644
--- a/libc/arch-x86/syscalls/read.S
+++ b/libc/arch-x86/syscalls/read.S
@@ -12,11 +12,19 @@
     pushl   %edx
     .cfi_adjust_cfa_offset 4
     .cfi_rel_offset edx, 0
-    mov     16(%esp), %ebx
-    mov     20(%esp), %ecx
-    mov     24(%esp), %edx
+
+    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_read, %eax
-    int     $0x80
+    call    *(%esp)
+    addl    $4, %esp
+
     cmpl    $-MAX_ERRNO, %eax
     jb      1f
     negl    %eax
diff --git a/libc/arch-x86/syscalls/readahead.S b/libc/arch-x86/syscalls/readahead.S
index 1c0ccfc..8ce22bb 100644
--- a/libc/arch-x86/syscalls/readahead.S
+++ b/libc/arch-x86/syscalls/readahead.S
@@ -15,12 +15,20 @@
     pushl   %esi
     .cfi_adjust_cfa_offset 4
     .cfi_rel_offset esi, 0
-    mov     20(%esp), %ebx
-    mov     24(%esp), %ecx
-    mov     28(%esp), %edx
-    mov     32(%esp), %esi
+
+    call    __kernel_syscall
+    pushl   %eax
+    .cfi_adjust_cfa_offset 4
+    .cfi_rel_offset eax, 0
+
+    mov     24(%esp), %ebx
+    mov     28(%esp), %ecx
+    mov     32(%esp), %edx
+    mov     36(%esp), %esi
     movl    $__NR_readahead, %eax
-    int     $0x80
+    call    *(%esp)
+    addl    $4, %esp
+
     cmpl    $-MAX_ERRNO, %eax
     jb      1f
     negl    %eax
diff --git a/libc/arch-x86/syscalls/readlinkat.S b/libc/arch-x86/syscalls/readlinkat.S
index 4a24c2c..8b74a4e 100644
--- a/libc/arch-x86/syscalls/readlinkat.S
+++ b/libc/arch-x86/syscalls/readlinkat.S
@@ -15,12 +15,20 @@
     pushl   %esi
     .cfi_adjust_cfa_offset 4
     .cfi_rel_offset esi, 0
-    mov     20(%esp), %ebx
-    mov     24(%esp), %ecx
-    mov     28(%esp), %edx
-    mov     32(%esp), %esi
+
+    call    __kernel_syscall
+    pushl   %eax
+    .cfi_adjust_cfa_offset 4
+    .cfi_rel_offset eax, 0
+
+    mov     24(%esp), %ebx
+    mov     28(%esp), %ecx
+    mov     32(%esp), %edx
+    mov     36(%esp), %esi
     movl    $__NR_readlinkat, %eax
-    int     $0x80
+    call    *(%esp)
+    addl    $4, %esp
+
     cmpl    $-MAX_ERRNO, %eax
     jb      1f
     negl    %eax
diff --git a/libc/arch-x86/syscalls/readv.S b/libc/arch-x86/syscalls/readv.S
index c18c1b1..a1cb08f 100644
--- a/libc/arch-x86/syscalls/readv.S
+++ b/libc/arch-x86/syscalls/readv.S
@@ -12,11 +12,19 @@
     pushl   %edx
     .cfi_adjust_cfa_offset 4
     .cfi_rel_offset edx, 0
-    mov     16(%esp), %ebx
-    mov     20(%esp), %ecx
-    mov     24(%esp), %edx
+
+    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_readv, %eax
-    int     $0x80
+    call    *(%esp)
+    addl    $4, %esp
+
     cmpl    $-MAX_ERRNO, %eax
     jb      1f
     negl    %eax
diff --git a/libc/arch-x86/syscalls/recvfrom.S b/libc/arch-x86/syscalls/recvfrom.S
index 88c9d0a..cedd703 100644
--- a/libc/arch-x86/syscalls/recvfrom.S
+++ b/libc/arch-x86/syscalls/recvfrom.S
@@ -9,11 +9,19 @@
     pushl   %ecx
     .cfi_adjust_cfa_offset 4
     .cfi_rel_offset ecx, 0
+
+    call    __kernel_syscall
+    pushl   %eax
+    .cfi_adjust_cfa_offset 4
+    .cfi_rel_offset eax, 0
+
     mov     $12, %ebx
     mov     %esp, %ecx
-    addl    $12, %ecx
+    addl    $16, %ecx
     movl    $__NR_socketcall, %eax
-    int     $0x80
+    call    *(%esp)
+    addl    $4, %esp
+
     cmpl    $-MAX_ERRNO, %eax
     jb      1f
     negl    %eax
diff --git a/libc/arch-x86/syscalls/recvmmsg.S b/libc/arch-x86/syscalls/recvmmsg.S
index 09404d4..130332a 100644
--- a/libc/arch-x86/syscalls/recvmmsg.S
+++ b/libc/arch-x86/syscalls/recvmmsg.S
@@ -9,11 +9,19 @@
     pushl   %ecx
     .cfi_adjust_cfa_offset 4
     .cfi_rel_offset ecx, 0
+
+    call    __kernel_syscall
+    pushl   %eax
+    .cfi_adjust_cfa_offset 4
+    .cfi_rel_offset eax, 0
+
     mov     $19, %ebx
     mov     %esp, %ecx
-    addl    $12, %ecx
+    addl    $16, %ecx
     movl    $__NR_socketcall, %eax
-    int     $0x80
+    call    *(%esp)
+    addl    $4, %esp
+
     cmpl    $-MAX_ERRNO, %eax
     jb      1f
     negl    %eax
diff --git a/libc/arch-x86/syscalls/recvmsg.S b/libc/arch-x86/syscalls/recvmsg.S
index 6cfcd63..c8d2a08 100644
--- a/libc/arch-x86/syscalls/recvmsg.S
+++ b/libc/arch-x86/syscalls/recvmsg.S
@@ -9,11 +9,19 @@
     pushl   %ecx
     .cfi_adjust_cfa_offset 4
     .cfi_rel_offset ecx, 0
+
+    call    __kernel_syscall
+    pushl   %eax
+    .cfi_adjust_cfa_offset 4
+    .cfi_rel_offset eax, 0
+
     mov     $17, %ebx
     mov     %esp, %ecx
-    addl    $12, %ecx
+    addl    $16, %ecx
     movl    $__NR_socketcall, %eax
-    int     $0x80
+    call    *(%esp)
+    addl    $4, %esp
+
     cmpl    $-MAX_ERRNO, %eax
     jb      1f
     negl    %eax
diff --git a/libc/arch-x86/syscalls/removexattr.S b/libc/arch-x86/syscalls/removexattr.S
index b067a9f..ab7891e 100644
--- a/libc/arch-x86/syscalls/removexattr.S
+++ b/libc/arch-x86/syscalls/removexattr.S
@@ -9,10 +9,18 @@
     pushl   %ecx
     .cfi_adjust_cfa_offset 4
     .cfi_rel_offset ecx, 0
-    mov     12(%esp), %ebx
-    mov     16(%esp), %ecx
+
+    call    __kernel_syscall
+    pushl   %eax
+    .cfi_adjust_cfa_offset 4
+    .cfi_rel_offset eax, 0
+
+    mov     16(%esp), %ebx
+    mov     20(%esp), %ecx
     movl    $__NR_removexattr, %eax
-    int     $0x80
+    call    *(%esp)
+    addl    $4, %esp
+
     cmpl    $-MAX_ERRNO, %eax
     jb      1f
     negl    %eax
diff --git a/libc/arch-x86/syscalls/renameat.S b/libc/arch-x86/syscalls/renameat.S
index bb2181e..40caaaf 100644
--- a/libc/arch-x86/syscalls/renameat.S
+++ b/libc/arch-x86/syscalls/renameat.S
@@ -15,12 +15,20 @@
     pushl   %esi
     .cfi_adjust_cfa_offset 4
     .cfi_rel_offset esi, 0
-    mov     20(%esp), %ebx
-    mov     24(%esp), %ecx
-    mov     28(%esp), %edx
-    mov     32(%esp), %esi
+
+    call    __kernel_syscall
+    pushl   %eax
+    .cfi_adjust_cfa_offset 4
+    .cfi_rel_offset eax, 0
+
+    mov     24(%esp), %ebx
+    mov     28(%esp), %ecx
+    mov     32(%esp), %edx
+    mov     36(%esp), %esi
     movl    $__NR_renameat, %eax
-    int     $0x80
+    call    *(%esp)
+    addl    $4, %esp
+
     cmpl    $-MAX_ERRNO, %eax
     jb      1f
     negl    %eax
diff --git a/libc/arch-x86/syscalls/sched_get_priority_max.S b/libc/arch-x86/syscalls/sched_get_priority_max.S
index be66cfb..637c9dd 100644
--- a/libc/arch-x86/syscalls/sched_get_priority_max.S
+++ b/libc/arch-x86/syscalls/sched_get_priority_max.S
@@ -6,9 +6,17 @@
     pushl   %ebx
     .cfi_def_cfa_offset 8
     .cfi_rel_offset ebx, 0
-    mov     8(%esp), %ebx
+
+    call    __kernel_syscall
+    pushl   %eax
+    .cfi_adjust_cfa_offset 4
+    .cfi_rel_offset eax, 0
+
+    mov     12(%esp), %ebx
     movl    $__NR_sched_get_priority_max, %eax
-    int     $0x80
+    call    *(%esp)
+    addl    $4, %esp
+
     cmpl    $-MAX_ERRNO, %eax
     jb      1f
     negl    %eax
diff --git a/libc/arch-x86/syscalls/sched_get_priority_min.S b/libc/arch-x86/syscalls/sched_get_priority_min.S
index 8dde67b..c38a3aa 100644
--- a/libc/arch-x86/syscalls/sched_get_priority_min.S
+++ b/libc/arch-x86/syscalls/sched_get_priority_min.S
@@ -6,9 +6,17 @@
     pushl   %ebx
     .cfi_def_cfa_offset 8
     .cfi_rel_offset ebx, 0
-    mov     8(%esp), %ebx
+
+    call    __kernel_syscall
+    pushl   %eax
+    .cfi_adjust_cfa_offset 4
+    .cfi_rel_offset eax, 0
+
+    mov     12(%esp), %ebx
     movl    $__NR_sched_get_priority_min, %eax
-    int     $0x80
+    call    *(%esp)
+    addl    $4, %esp
+
     cmpl    $-MAX_ERRNO, %eax
     jb      1f
     negl    %eax
diff --git a/libc/arch-x86/syscalls/sched_getparam.S b/libc/arch-x86/syscalls/sched_getparam.S
index d0551ef..09901bd 100644
--- a/libc/arch-x86/syscalls/sched_getparam.S
+++ b/libc/arch-x86/syscalls/sched_getparam.S
@@ -9,10 +9,18 @@
     pushl   %ecx
     .cfi_adjust_cfa_offset 4
     .cfi_rel_offset ecx, 0
-    mov     12(%esp), %ebx
-    mov     16(%esp), %ecx
+
+    call    __kernel_syscall
+    pushl   %eax
+    .cfi_adjust_cfa_offset 4
+    .cfi_rel_offset eax, 0
+
+    mov     16(%esp), %ebx
+    mov     20(%esp), %ecx
     movl    $__NR_sched_getparam, %eax
-    int     $0x80
+    call    *(%esp)
+    addl    $4, %esp
+
     cmpl    $-MAX_ERRNO, %eax
     jb      1f
     negl    %eax
diff --git a/libc/arch-x86/syscalls/sched_getscheduler.S b/libc/arch-x86/syscalls/sched_getscheduler.S
index 5b7c817..adc4023 100644
--- a/libc/arch-x86/syscalls/sched_getscheduler.S
+++ b/libc/arch-x86/syscalls/sched_getscheduler.S
@@ -6,9 +6,17 @@
     pushl   %ebx
     .cfi_def_cfa_offset 8
     .cfi_rel_offset ebx, 0
-    mov     8(%esp), %ebx
+
+    call    __kernel_syscall
+    pushl   %eax
+    .cfi_adjust_cfa_offset 4
+    .cfi_rel_offset eax, 0
+
+    mov     12(%esp), %ebx
     movl    $__NR_sched_getscheduler, %eax
-    int     $0x80
+    call    *(%esp)
+    addl    $4, %esp
+
     cmpl    $-MAX_ERRNO, %eax
     jb      1f
     negl    %eax
diff --git a/libc/arch-x86/syscalls/sched_rr_get_interval.S b/libc/arch-x86/syscalls/sched_rr_get_interval.S
index 073f3c7..818f62e 100644
--- a/libc/arch-x86/syscalls/sched_rr_get_interval.S
+++ b/libc/arch-x86/syscalls/sched_rr_get_interval.S
@@ -9,10 +9,18 @@
     pushl   %ecx
     .cfi_adjust_cfa_offset 4
     .cfi_rel_offset ecx, 0
-    mov     12(%esp), %ebx
-    mov     16(%esp), %ecx
+
+    call    __kernel_syscall
+    pushl   %eax
+    .cfi_adjust_cfa_offset 4
+    .cfi_rel_offset eax, 0
+
+    mov     16(%esp), %ebx
+    mov     20(%esp), %ecx
     movl    $__NR_sched_rr_get_interval, %eax
-    int     $0x80
+    call    *(%esp)
+    addl    $4, %esp
+
     cmpl    $-MAX_ERRNO, %eax
     jb      1f
     negl    %eax
diff --git a/libc/arch-x86/syscalls/sched_setaffinity.S b/libc/arch-x86/syscalls/sched_setaffinity.S
index 79ec113..b06d778 100644
--- a/libc/arch-x86/syscalls/sched_setaffinity.S
+++ b/libc/arch-x86/syscalls/sched_setaffinity.S
@@ -12,11 +12,19 @@
     pushl   %edx
     .cfi_adjust_cfa_offset 4
     .cfi_rel_offset edx, 0
-    mov     16(%esp), %ebx
-    mov     20(%esp), %ecx
-    mov     24(%esp), %edx
+
+    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_sched_setaffinity, %eax
-    int     $0x80
+    call    *(%esp)
+    addl    $4, %esp
+
     cmpl    $-MAX_ERRNO, %eax
     jb      1f
     negl    %eax
diff --git a/libc/arch-x86/syscalls/sched_setparam.S b/libc/arch-x86/syscalls/sched_setparam.S
index 970747d..dba5bc2 100644
--- a/libc/arch-x86/syscalls/sched_setparam.S
+++ b/libc/arch-x86/syscalls/sched_setparam.S
@@ -9,10 +9,18 @@
     pushl   %ecx
     .cfi_adjust_cfa_offset 4
     .cfi_rel_offset ecx, 0
-    mov     12(%esp), %ebx
-    mov     16(%esp), %ecx
+
+    call    __kernel_syscall
+    pushl   %eax
+    .cfi_adjust_cfa_offset 4
+    .cfi_rel_offset eax, 0
+
+    mov     16(%esp), %ebx
+    mov     20(%esp), %ecx
     movl    $__NR_sched_setparam, %eax
-    int     $0x80
+    call    *(%esp)
+    addl    $4, %esp
+
     cmpl    $-MAX_ERRNO, %eax
     jb      1f
     negl    %eax
diff --git a/libc/arch-x86/syscalls/sched_setscheduler.S b/libc/arch-x86/syscalls/sched_setscheduler.S
index da50aaf..466a425 100644
--- a/libc/arch-x86/syscalls/sched_setscheduler.S
+++ b/libc/arch-x86/syscalls/sched_setscheduler.S
@@ -12,11 +12,19 @@
     pushl   %edx
     .cfi_adjust_cfa_offset 4
     .cfi_rel_offset edx, 0
-    mov     16(%esp), %ebx
-    mov     20(%esp), %ecx
-    mov     24(%esp), %edx
+
+    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_sched_setscheduler, %eax
-    int     $0x80
+    call    *(%esp)
+    addl    $4, %esp
+
     cmpl    $-MAX_ERRNO, %eax
     jb      1f
     negl    %eax
diff --git a/libc/arch-x86/syscalls/sched_yield.S b/libc/arch-x86/syscalls/sched_yield.S
index e3878e3..b17b14e 100644
--- a/libc/arch-x86/syscalls/sched_yield.S
+++ b/libc/arch-x86/syscalls/sched_yield.S
@@ -6,9 +6,17 @@
     pushl   %ebx
     .cfi_def_cfa_offset 8
     .cfi_rel_offset ebx, 0
-    mov     8(%esp), %ebx
+
+    call    __kernel_syscall
+    pushl   %eax
+    .cfi_adjust_cfa_offset 4
+    .cfi_rel_offset eax, 0
+
+    mov     12(%esp), %ebx
     movl    $__NR_sched_yield, %eax
-    int     $0x80
+    call    *(%esp)
+    addl    $4, %esp
+
     cmpl    $-MAX_ERRNO, %eax
     jb      1f
     negl    %eax
diff --git a/libc/arch-x86/syscalls/sendfile.S b/libc/arch-x86/syscalls/sendfile.S
index c5f9a2d..e091706 100644
--- a/libc/arch-x86/syscalls/sendfile.S
+++ b/libc/arch-x86/syscalls/sendfile.S
@@ -15,12 +15,20 @@
     pushl   %esi
     .cfi_adjust_cfa_offset 4
     .cfi_rel_offset esi, 0
-    mov     20(%esp), %ebx
-    mov     24(%esp), %ecx
-    mov     28(%esp), %edx
-    mov     32(%esp), %esi
+
+    call    __kernel_syscall
+    pushl   %eax
+    .cfi_adjust_cfa_offset 4
+    .cfi_rel_offset eax, 0
+
+    mov     24(%esp), %ebx
+    mov     28(%esp), %ecx
+    mov     32(%esp), %edx
+    mov     36(%esp), %esi
     movl    $__NR_sendfile, %eax
-    int     $0x80
+    call    *(%esp)
+    addl    $4, %esp
+
     cmpl    $-MAX_ERRNO, %eax
     jb      1f
     negl    %eax
diff --git a/libc/arch-x86/syscalls/sendfile64.S b/libc/arch-x86/syscalls/sendfile64.S
index bc5d0dd..317c4f4 100644
--- a/libc/arch-x86/syscalls/sendfile64.S
+++ b/libc/arch-x86/syscalls/sendfile64.S
@@ -15,12 +15,20 @@
     pushl   %esi
     .cfi_adjust_cfa_offset 4
     .cfi_rel_offset esi, 0
-    mov     20(%esp), %ebx
-    mov     24(%esp), %ecx
-    mov     28(%esp), %edx
-    mov     32(%esp), %esi
+
+    call    __kernel_syscall
+    pushl   %eax
+    .cfi_adjust_cfa_offset 4
+    .cfi_rel_offset eax, 0
+
+    mov     24(%esp), %ebx
+    mov     28(%esp), %ecx
+    mov     32(%esp), %edx
+    mov     36(%esp), %esi
     movl    $__NR_sendfile64, %eax
-    int     $0x80
+    call    *(%esp)
+    addl    $4, %esp
+
     cmpl    $-MAX_ERRNO, %eax
     jb      1f
     negl    %eax
diff --git a/libc/arch-x86/syscalls/sendmmsg.S b/libc/arch-x86/syscalls/sendmmsg.S
index 784c6b6..c0097f8 100644
--- a/libc/arch-x86/syscalls/sendmmsg.S
+++ b/libc/arch-x86/syscalls/sendmmsg.S
@@ -9,11 +9,19 @@
     pushl   %ecx
     .cfi_adjust_cfa_offset 4
     .cfi_rel_offset ecx, 0
+
+    call    __kernel_syscall
+    pushl   %eax
+    .cfi_adjust_cfa_offset 4
+    .cfi_rel_offset eax, 0
+
     mov     $20, %ebx
     mov     %esp, %ecx
-    addl    $12, %ecx
+    addl    $16, %ecx
     movl    $__NR_socketcall, %eax
-    int     $0x80
+    call    *(%esp)
+    addl    $4, %esp
+
     cmpl    $-MAX_ERRNO, %eax
     jb      1f
     negl    %eax
diff --git a/libc/arch-x86/syscalls/sendmsg.S b/libc/arch-x86/syscalls/sendmsg.S
index bf0d1fb..775ebee 100644
--- a/libc/arch-x86/syscalls/sendmsg.S
+++ b/libc/arch-x86/syscalls/sendmsg.S
@@ -9,11 +9,19 @@
     pushl   %ecx
     .cfi_adjust_cfa_offset 4
     .cfi_rel_offset ecx, 0
+
+    call    __kernel_syscall
+    pushl   %eax
+    .cfi_adjust_cfa_offset 4
+    .cfi_rel_offset eax, 0
+
     mov     $16, %ebx
     mov     %esp, %ecx
-    addl    $12, %ecx
+    addl    $16, %ecx
     movl    $__NR_socketcall, %eax
-    int     $0x80
+    call    *(%esp)
+    addl    $4, %esp
+
     cmpl    $-MAX_ERRNO, %eax
     jb      1f
     negl    %eax
diff --git a/libc/arch-x86/syscalls/sendto.S b/libc/arch-x86/syscalls/sendto.S
index b39eaf0..2df5e4f 100644
--- a/libc/arch-x86/syscalls/sendto.S
+++ b/libc/arch-x86/syscalls/sendto.S
@@ -9,11 +9,19 @@
     pushl   %ecx
     .cfi_adjust_cfa_offset 4
     .cfi_rel_offset ecx, 0
+
+    call    __kernel_syscall
+    pushl   %eax
+    .cfi_adjust_cfa_offset 4
+    .cfi_rel_offset eax, 0
+
     mov     $11, %ebx
     mov     %esp, %ecx
-    addl    $12, %ecx
+    addl    $16, %ecx
     movl    $__NR_socketcall, %eax
-    int     $0x80
+    call    *(%esp)
+    addl    $4, %esp
+
     cmpl    $-MAX_ERRNO, %eax
     jb      1f
     negl    %eax
diff --git a/libc/arch-x86/syscalls/setfsgid.S b/libc/arch-x86/syscalls/setfsgid.S
index dc81f72..af4ef89 100644
--- a/libc/arch-x86/syscalls/setfsgid.S
+++ b/libc/arch-x86/syscalls/setfsgid.S
@@ -6,9 +6,17 @@
     pushl   %ebx
     .cfi_def_cfa_offset 8
     .cfi_rel_offset ebx, 0
-    mov     8(%esp), %ebx
+
+    call    __kernel_syscall
+    pushl   %eax
+    .cfi_adjust_cfa_offset 4
+    .cfi_rel_offset eax, 0
+
+    mov     12(%esp), %ebx
     movl    $__NR_setfsgid, %eax
-    int     $0x80
+    call    *(%esp)
+    addl    $4, %esp
+
     cmpl    $-MAX_ERRNO, %eax
     jb      1f
     negl    %eax
diff --git a/libc/arch-x86/syscalls/setfsuid.S b/libc/arch-x86/syscalls/setfsuid.S
index fdf7850..8001e42 100644
--- a/libc/arch-x86/syscalls/setfsuid.S
+++ b/libc/arch-x86/syscalls/setfsuid.S
@@ -6,9 +6,17 @@
     pushl   %ebx
     .cfi_def_cfa_offset 8
     .cfi_rel_offset ebx, 0
-    mov     8(%esp), %ebx
+
+    call    __kernel_syscall
+    pushl   %eax
+    .cfi_adjust_cfa_offset 4
+    .cfi_rel_offset eax, 0
+
+    mov     12(%esp), %ebx
     movl    $__NR_setfsuid, %eax
-    int     $0x80
+    call    *(%esp)
+    addl    $4, %esp
+
     cmpl    $-MAX_ERRNO, %eax
     jb      1f
     negl    %eax
diff --git a/libc/arch-x86/syscalls/setgid.S b/libc/arch-x86/syscalls/setgid.S
index ce6ee26..c0ddec4 100644
--- a/libc/arch-x86/syscalls/setgid.S
+++ b/libc/arch-x86/syscalls/setgid.S
@@ -6,9 +6,17 @@
     pushl   %ebx
     .cfi_def_cfa_offset 8
     .cfi_rel_offset ebx, 0
-    mov     8(%esp), %ebx
+
+    call    __kernel_syscall
+    pushl   %eax
+    .cfi_adjust_cfa_offset 4
+    .cfi_rel_offset eax, 0
+
+    mov     12(%esp), %ebx
     movl    $__NR_setgid32, %eax
-    int     $0x80
+    call    *(%esp)
+    addl    $4, %esp
+
     cmpl    $-MAX_ERRNO, %eax
     jb      1f
     negl    %eax
diff --git a/libc/arch-x86/syscalls/setgroups.S b/libc/arch-x86/syscalls/setgroups.S
index 7e46ad0..7bd3bfc 100644
--- a/libc/arch-x86/syscalls/setgroups.S
+++ b/libc/arch-x86/syscalls/setgroups.S
@@ -9,10 +9,18 @@
     pushl   %ecx
     .cfi_adjust_cfa_offset 4
     .cfi_rel_offset ecx, 0
-    mov     12(%esp), %ebx
-    mov     16(%esp), %ecx
+
+    call    __kernel_syscall
+    pushl   %eax
+    .cfi_adjust_cfa_offset 4
+    .cfi_rel_offset eax, 0
+
+    mov     16(%esp), %ebx
+    mov     20(%esp), %ecx
     movl    $__NR_setgroups32, %eax
-    int     $0x80
+    call    *(%esp)
+    addl    $4, %esp
+
     cmpl    $-MAX_ERRNO, %eax
     jb      1f
     negl    %eax
diff --git a/libc/arch-x86/syscalls/sethostname.S b/libc/arch-x86/syscalls/sethostname.S
index bfcfd73..26ff1e7 100644
--- a/libc/arch-x86/syscalls/sethostname.S
+++ b/libc/arch-x86/syscalls/sethostname.S
@@ -9,10 +9,18 @@
     pushl   %ecx
     .cfi_adjust_cfa_offset 4
     .cfi_rel_offset ecx, 0
-    mov     12(%esp), %ebx
-    mov     16(%esp), %ecx
+
+    call    __kernel_syscall
+    pushl   %eax
+    .cfi_adjust_cfa_offset 4
+    .cfi_rel_offset eax, 0
+
+    mov     16(%esp), %ebx
+    mov     20(%esp), %ecx
     movl    $__NR_sethostname, %eax
-    int     $0x80
+    call    *(%esp)
+    addl    $4, %esp
+
     cmpl    $-MAX_ERRNO, %eax
     jb      1f
     negl    %eax
diff --git a/libc/arch-x86/syscalls/setitimer.S b/libc/arch-x86/syscalls/setitimer.S
index 370ab5e..063847b 100644
--- a/libc/arch-x86/syscalls/setitimer.S
+++ b/libc/arch-x86/syscalls/setitimer.S
@@ -12,11 +12,19 @@
     pushl   %edx
     .cfi_adjust_cfa_offset 4
     .cfi_rel_offset edx, 0
-    mov     16(%esp), %ebx
-    mov     20(%esp), %ecx
-    mov     24(%esp), %edx
+
+    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_setitimer, %eax
-    int     $0x80
+    call    *(%esp)
+    addl    $4, %esp
+
     cmpl    $-MAX_ERRNO, %eax
     jb      1f
     negl    %eax
diff --git a/libc/arch-x86/syscalls/setns.S b/libc/arch-x86/syscalls/setns.S
index 736df59..28d838e 100644
--- a/libc/arch-x86/syscalls/setns.S
+++ b/libc/arch-x86/syscalls/setns.S
@@ -9,10 +9,18 @@
     pushl   %ecx
     .cfi_adjust_cfa_offset 4
     .cfi_rel_offset ecx, 0
-    mov     12(%esp), %ebx
-    mov     16(%esp), %ecx
+
+    call    __kernel_syscall
+    pushl   %eax
+    .cfi_adjust_cfa_offset 4
+    .cfi_rel_offset eax, 0
+
+    mov     16(%esp), %ebx
+    mov     20(%esp), %ecx
     movl    $__NR_setns, %eax
-    int     $0x80
+    call    *(%esp)
+    addl    $4, %esp
+
     cmpl    $-MAX_ERRNO, %eax
     jb      1f
     negl    %eax
diff --git a/libc/arch-x86/syscalls/setpgid.S b/libc/arch-x86/syscalls/setpgid.S
index 0bff10a..c5d0d27 100644
--- a/libc/arch-x86/syscalls/setpgid.S
+++ b/libc/arch-x86/syscalls/setpgid.S
@@ -9,10 +9,18 @@
     pushl   %ecx
     .cfi_adjust_cfa_offset 4
     .cfi_rel_offset ecx, 0
-    mov     12(%esp), %ebx
-    mov     16(%esp), %ecx
+
+    call    __kernel_syscall
+    pushl   %eax
+    .cfi_adjust_cfa_offset 4
+    .cfi_rel_offset eax, 0
+
+    mov     16(%esp), %ebx
+    mov     20(%esp), %ecx
     movl    $__NR_setpgid, %eax
-    int     $0x80
+    call    *(%esp)
+    addl    $4, %esp
+
     cmpl    $-MAX_ERRNO, %eax
     jb      1f
     negl    %eax
diff --git a/libc/arch-x86/syscalls/setpriority.S b/libc/arch-x86/syscalls/setpriority.S
index 4233871..17c81c6 100644
--- a/libc/arch-x86/syscalls/setpriority.S
+++ b/libc/arch-x86/syscalls/setpriority.S
@@ -12,11 +12,19 @@
     pushl   %edx
     .cfi_adjust_cfa_offset 4
     .cfi_rel_offset edx, 0
-    mov     16(%esp), %ebx
-    mov     20(%esp), %ecx
-    mov     24(%esp), %edx
+
+    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_setpriority, %eax
-    int     $0x80
+    call    *(%esp)
+    addl    $4, %esp
+
     cmpl    $-MAX_ERRNO, %eax
     jb      1f
     negl    %eax
diff --git a/libc/arch-x86/syscalls/setregid.S b/libc/arch-x86/syscalls/setregid.S
index a56ccfd..dd8101a 100644
--- a/libc/arch-x86/syscalls/setregid.S
+++ b/libc/arch-x86/syscalls/setregid.S
@@ -9,10 +9,18 @@
     pushl   %ecx
     .cfi_adjust_cfa_offset 4
     .cfi_rel_offset ecx, 0
-    mov     12(%esp), %ebx
-    mov     16(%esp), %ecx
+
+    call    __kernel_syscall
+    pushl   %eax
+    .cfi_adjust_cfa_offset 4
+    .cfi_rel_offset eax, 0
+
+    mov     16(%esp), %ebx
+    mov     20(%esp), %ecx
     movl    $__NR_setregid32, %eax
-    int     $0x80
+    call    *(%esp)
+    addl    $4, %esp
+
     cmpl    $-MAX_ERRNO, %eax
     jb      1f
     negl    %eax
diff --git a/libc/arch-x86/syscalls/setresgid.S b/libc/arch-x86/syscalls/setresgid.S
index 2299831..6f6de5a 100644
--- a/libc/arch-x86/syscalls/setresgid.S
+++ b/libc/arch-x86/syscalls/setresgid.S
@@ -12,11 +12,19 @@
     pushl   %edx
     .cfi_adjust_cfa_offset 4
     .cfi_rel_offset edx, 0
-    mov     16(%esp), %ebx
-    mov     20(%esp), %ecx
-    mov     24(%esp), %edx
+
+    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_setresgid32, %eax
-    int     $0x80
+    call    *(%esp)
+    addl    $4, %esp
+
     cmpl    $-MAX_ERRNO, %eax
     jb      1f
     negl    %eax
diff --git a/libc/arch-x86/syscalls/setresuid.S b/libc/arch-x86/syscalls/setresuid.S
index 8624e15..ab0059c 100644
--- a/libc/arch-x86/syscalls/setresuid.S
+++ b/libc/arch-x86/syscalls/setresuid.S
@@ -12,11 +12,19 @@
     pushl   %edx
     .cfi_adjust_cfa_offset 4
     .cfi_rel_offset edx, 0
-    mov     16(%esp), %ebx
-    mov     20(%esp), %ecx
-    mov     24(%esp), %edx
+
+    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_setresuid32, %eax
-    int     $0x80
+    call    *(%esp)
+    addl    $4, %esp
+
     cmpl    $-MAX_ERRNO, %eax
     jb      1f
     negl    %eax
diff --git a/libc/arch-x86/syscalls/setreuid.S b/libc/arch-x86/syscalls/setreuid.S
index 9f6e117..7fda62e 100644
--- a/libc/arch-x86/syscalls/setreuid.S
+++ b/libc/arch-x86/syscalls/setreuid.S
@@ -9,10 +9,18 @@
     pushl   %ecx
     .cfi_adjust_cfa_offset 4
     .cfi_rel_offset ecx, 0
-    mov     12(%esp), %ebx
-    mov     16(%esp), %ecx
+
+    call    __kernel_syscall
+    pushl   %eax
+    .cfi_adjust_cfa_offset 4
+    .cfi_rel_offset eax, 0
+
+    mov     16(%esp), %ebx
+    mov     20(%esp), %ecx
     movl    $__NR_setreuid32, %eax
-    int     $0x80
+    call    *(%esp)
+    addl    $4, %esp
+
     cmpl    $-MAX_ERRNO, %eax
     jb      1f
     negl    %eax
diff --git a/libc/arch-x86/syscalls/setrlimit.S b/libc/arch-x86/syscalls/setrlimit.S
index 2024688..595633e 100644
--- a/libc/arch-x86/syscalls/setrlimit.S
+++ b/libc/arch-x86/syscalls/setrlimit.S
@@ -9,10 +9,18 @@
     pushl   %ecx
     .cfi_adjust_cfa_offset 4
     .cfi_rel_offset ecx, 0
-    mov     12(%esp), %ebx
-    mov     16(%esp), %ecx
+
+    call    __kernel_syscall
+    pushl   %eax
+    .cfi_adjust_cfa_offset 4
+    .cfi_rel_offset eax, 0
+
+    mov     16(%esp), %ebx
+    mov     20(%esp), %ecx
     movl    $__NR_setrlimit, %eax
-    int     $0x80
+    call    *(%esp)
+    addl    $4, %esp
+
     cmpl    $-MAX_ERRNO, %eax
     jb      1f
     negl    %eax
diff --git a/libc/arch-x86/syscalls/setsid.S b/libc/arch-x86/syscalls/setsid.S
index dda6ad8..80ad8a9 100644
--- a/libc/arch-x86/syscalls/setsid.S
+++ b/libc/arch-x86/syscalls/setsid.S
@@ -3,8 +3,16 @@
 #include <private/bionic_asm.h>
 
 ENTRY(setsid)
+
+    call    __kernel_syscall
+    pushl   %eax
+    .cfi_adjust_cfa_offset 4
+    .cfi_rel_offset eax, 0
+
     movl    $__NR_setsid, %eax
-    int     $0x80
+    call    *(%esp)
+    addl    $4, %esp
+
     cmpl    $-MAX_ERRNO, %eax
     jb      1f
     negl    %eax
diff --git a/libc/arch-x86/syscalls/setsockopt.S b/libc/arch-x86/syscalls/setsockopt.S
index 29e73bb..bca34e1 100644
--- a/libc/arch-x86/syscalls/setsockopt.S
+++ b/libc/arch-x86/syscalls/setsockopt.S
@@ -9,11 +9,19 @@
     pushl   %ecx
     .cfi_adjust_cfa_offset 4
     .cfi_rel_offset ecx, 0
+
+    call    __kernel_syscall
+    pushl   %eax
+    .cfi_adjust_cfa_offset 4
+    .cfi_rel_offset eax, 0
+
     mov     $14, %ebx
     mov     %esp, %ecx
-    addl    $12, %ecx
+    addl    $16, %ecx
     movl    $__NR_socketcall, %eax
-    int     $0x80
+    call    *(%esp)
+    addl    $4, %esp
+
     cmpl    $-MAX_ERRNO, %eax
     jb      1f
     negl    %eax
diff --git a/libc/arch-x86/syscalls/settimeofday.S b/libc/arch-x86/syscalls/settimeofday.S
index 4a861ab..31437d0 100644
--- a/libc/arch-x86/syscalls/settimeofday.S
+++ b/libc/arch-x86/syscalls/settimeofday.S
@@ -9,10 +9,18 @@
     pushl   %ecx
     .cfi_adjust_cfa_offset 4
     .cfi_rel_offset ecx, 0
-    mov     12(%esp), %ebx
-    mov     16(%esp), %ecx
+
+    call    __kernel_syscall
+    pushl   %eax
+    .cfi_adjust_cfa_offset 4
+    .cfi_rel_offset eax, 0
+
+    mov     16(%esp), %ebx
+    mov     20(%esp), %ecx
     movl    $__NR_settimeofday, %eax
-    int     $0x80
+    call    *(%esp)
+    addl    $4, %esp
+
     cmpl    $-MAX_ERRNO, %eax
     jb      1f
     negl    %eax
diff --git a/libc/arch-x86/syscalls/setuid.S b/libc/arch-x86/syscalls/setuid.S
index 048e0c1..2461182 100644
--- a/libc/arch-x86/syscalls/setuid.S
+++ b/libc/arch-x86/syscalls/setuid.S
@@ -6,9 +6,17 @@
     pushl   %ebx
     .cfi_def_cfa_offset 8
     .cfi_rel_offset ebx, 0
-    mov     8(%esp), %ebx
+
+    call    __kernel_syscall
+    pushl   %eax
+    .cfi_adjust_cfa_offset 4
+    .cfi_rel_offset eax, 0
+
+    mov     12(%esp), %ebx
     movl    $__NR_setuid32, %eax
-    int     $0x80
+    call    *(%esp)
+    addl    $4, %esp
+
     cmpl    $-MAX_ERRNO, %eax
     jb      1f
     negl    %eax
diff --git a/libc/arch-x86/syscalls/setxattr.S b/libc/arch-x86/syscalls/setxattr.S
index 1e87bf0..787891e 100644
--- a/libc/arch-x86/syscalls/setxattr.S
+++ b/libc/arch-x86/syscalls/setxattr.S
@@ -18,13 +18,21 @@
     pushl   %edi
     .cfi_adjust_cfa_offset 4
     .cfi_rel_offset edi, 0
-    mov     24(%esp), %ebx
-    mov     28(%esp), %ecx
-    mov     32(%esp), %edx
-    mov     36(%esp), %esi
-    mov     40(%esp), %edi
+
+    call    __kernel_syscall
+    pushl   %eax
+    .cfi_adjust_cfa_offset 4
+    .cfi_rel_offset eax, 0
+
+    mov     28(%esp), %ebx
+    mov     32(%esp), %ecx
+    mov     36(%esp), %edx
+    mov     40(%esp), %esi
+    mov     44(%esp), %edi
     movl    $__NR_setxattr, %eax
-    int     $0x80
+    call    *(%esp)
+    addl    $4, %esp
+
     cmpl    $-MAX_ERRNO, %eax
     jb      1f
     negl    %eax
diff --git a/libc/arch-x86/syscalls/shutdown.S b/libc/arch-x86/syscalls/shutdown.S
index f224fc6..46e5c18 100644
--- a/libc/arch-x86/syscalls/shutdown.S
+++ b/libc/arch-x86/syscalls/shutdown.S
@@ -9,11 +9,19 @@
     pushl   %ecx
     .cfi_adjust_cfa_offset 4
     .cfi_rel_offset ecx, 0
+
+    call    __kernel_syscall
+    pushl   %eax
+    .cfi_adjust_cfa_offset 4
+    .cfi_rel_offset eax, 0
+
     mov     $13, %ebx
     mov     %esp, %ecx
-    addl    $12, %ecx
+    addl    $16, %ecx
     movl    $__NR_socketcall, %eax
-    int     $0x80
+    call    *(%esp)
+    addl    $4, %esp
+
     cmpl    $-MAX_ERRNO, %eax
     jb      1f
     negl    %eax
diff --git a/libc/arch-x86/syscalls/sigaltstack.S b/libc/arch-x86/syscalls/sigaltstack.S
index 875ef8c..90eae16 100644
--- a/libc/arch-x86/syscalls/sigaltstack.S
+++ b/libc/arch-x86/syscalls/sigaltstack.S
@@ -9,10 +9,18 @@
     pushl   %ecx
     .cfi_adjust_cfa_offset 4
     .cfi_rel_offset ecx, 0
-    mov     12(%esp), %ebx
-    mov     16(%esp), %ecx
+
+    call    __kernel_syscall
+    pushl   %eax
+    .cfi_adjust_cfa_offset 4
+    .cfi_rel_offset eax, 0
+
+    mov     16(%esp), %ebx
+    mov     20(%esp), %ecx
     movl    $__NR_sigaltstack, %eax
-    int     $0x80
+    call    *(%esp)
+    addl    $4, %esp
+
     cmpl    $-MAX_ERRNO, %eax
     jb      1f
     negl    %eax
diff --git a/libc/arch-x86/syscalls/socketpair.S b/libc/arch-x86/syscalls/socketpair.S
index 4c5154e..c9c7595 100644
--- a/libc/arch-x86/syscalls/socketpair.S
+++ b/libc/arch-x86/syscalls/socketpair.S
@@ -9,11 +9,19 @@
     pushl   %ecx
     .cfi_adjust_cfa_offset 4
     .cfi_rel_offset ecx, 0
+
+    call    __kernel_syscall
+    pushl   %eax
+    .cfi_adjust_cfa_offset 4
+    .cfi_rel_offset eax, 0
+
     mov     $8, %ebx
     mov     %esp, %ecx
-    addl    $12, %ecx
+    addl    $16, %ecx
     movl    $__NR_socketcall, %eax
-    int     $0x80
+    call    *(%esp)
+    addl    $4, %esp
+
     cmpl    $-MAX_ERRNO, %eax
     jb      1f
     negl    %eax
diff --git a/libc/arch-x86/syscalls/splice.S b/libc/arch-x86/syscalls/splice.S
index 1dc9037..2d82a3d 100644
--- a/libc/arch-x86/syscalls/splice.S
+++ b/libc/arch-x86/syscalls/splice.S
@@ -21,14 +21,22 @@
     pushl   %ebp
     .cfi_adjust_cfa_offset 4
     .cfi_rel_offset ebp, 0
-    mov     28(%esp), %ebx
-    mov     32(%esp), %ecx
-    mov     36(%esp), %edx
-    mov     40(%esp), %esi
-    mov     44(%esp), %edi
-    mov     48(%esp), %ebp
+
+    call    __kernel_syscall
+    pushl   %eax
+    .cfi_adjust_cfa_offset 4
+    .cfi_rel_offset eax, 0
+
+    mov     32(%esp), %ebx
+    mov     36(%esp), %ecx
+    mov     40(%esp), %edx
+    mov     44(%esp), %esi
+    mov     48(%esp), %edi
+    mov     52(%esp), %ebp
     movl    $__NR_splice, %eax
-    int     $0x80
+    call    *(%esp)
+    addl    $4, %esp
+
     cmpl    $-MAX_ERRNO, %eax
     jb      1f
     negl    %eax
diff --git a/libc/arch-x86/syscalls/swapoff.S b/libc/arch-x86/syscalls/swapoff.S
index 0788529..d10a748 100644
--- a/libc/arch-x86/syscalls/swapoff.S
+++ b/libc/arch-x86/syscalls/swapoff.S
@@ -6,9 +6,17 @@
     pushl   %ebx
     .cfi_def_cfa_offset 8
     .cfi_rel_offset ebx, 0
-    mov     8(%esp), %ebx
+
+    call    __kernel_syscall
+    pushl   %eax
+    .cfi_adjust_cfa_offset 4
+    .cfi_rel_offset eax, 0
+
+    mov     12(%esp), %ebx
     movl    $__NR_swapoff, %eax
-    int     $0x80
+    call    *(%esp)
+    addl    $4, %esp
+
     cmpl    $-MAX_ERRNO, %eax
     jb      1f
     negl    %eax
diff --git a/libc/arch-x86/syscalls/swapon.S b/libc/arch-x86/syscalls/swapon.S
index 1070d8e..dc7db64 100644
--- a/libc/arch-x86/syscalls/swapon.S
+++ b/libc/arch-x86/syscalls/swapon.S
@@ -9,10 +9,18 @@
     pushl   %ecx
     .cfi_adjust_cfa_offset 4
     .cfi_rel_offset ecx, 0
-    mov     12(%esp), %ebx
-    mov     16(%esp), %ecx
+
+    call    __kernel_syscall
+    pushl   %eax
+    .cfi_adjust_cfa_offset 4
+    .cfi_rel_offset eax, 0
+
+    mov     16(%esp), %ebx
+    mov     20(%esp), %ecx
     movl    $__NR_swapon, %eax
-    int     $0x80
+    call    *(%esp)
+    addl    $4, %esp
+
     cmpl    $-MAX_ERRNO, %eax
     jb      1f
     negl    %eax
diff --git a/libc/arch-x86/syscalls/symlinkat.S b/libc/arch-x86/syscalls/symlinkat.S
index e7fe69e..51b1330 100644
--- a/libc/arch-x86/syscalls/symlinkat.S
+++ b/libc/arch-x86/syscalls/symlinkat.S
@@ -12,11 +12,19 @@
     pushl   %edx
     .cfi_adjust_cfa_offset 4
     .cfi_rel_offset edx, 0
-    mov     16(%esp), %ebx
-    mov     20(%esp), %ecx
-    mov     24(%esp), %edx
+
+    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_symlinkat, %eax
-    int     $0x80
+    call    *(%esp)
+    addl    $4, %esp
+
     cmpl    $-MAX_ERRNO, %eax
     jb      1f
     negl    %eax
diff --git a/libc/arch-x86/syscalls/sync.S b/libc/arch-x86/syscalls/sync.S
index 252c666..c75e9f9 100644
--- a/libc/arch-x86/syscalls/sync.S
+++ b/libc/arch-x86/syscalls/sync.S
@@ -6,9 +6,17 @@
     pushl   %ebx
     .cfi_def_cfa_offset 8
     .cfi_rel_offset ebx, 0
-    mov     8(%esp), %ebx
+
+    call    __kernel_syscall
+    pushl   %eax
+    .cfi_adjust_cfa_offset 4
+    .cfi_rel_offset eax, 0
+
+    mov     12(%esp), %ebx
     movl    $__NR_sync, %eax
-    int     $0x80
+    call    *(%esp)
+    addl    $4, %esp
+
     cmpl    $-MAX_ERRNO, %eax
     jb      1f
     negl    %eax
diff --git a/libc/arch-x86/syscalls/sysinfo.S b/libc/arch-x86/syscalls/sysinfo.S
index f59a0c3..a40d664 100644
--- a/libc/arch-x86/syscalls/sysinfo.S
+++ b/libc/arch-x86/syscalls/sysinfo.S
@@ -6,9 +6,17 @@
     pushl   %ebx
     .cfi_def_cfa_offset 8
     .cfi_rel_offset ebx, 0
-    mov     8(%esp), %ebx
+
+    call    __kernel_syscall
+    pushl   %eax
+    .cfi_adjust_cfa_offset 4
+    .cfi_rel_offset eax, 0
+
+    mov     12(%esp), %ebx
     movl    $__NR_sysinfo, %eax
-    int     $0x80
+    call    *(%esp)
+    addl    $4, %esp
+
     cmpl    $-MAX_ERRNO, %eax
     jb      1f
     negl    %eax
diff --git a/libc/arch-x86/syscalls/tee.S b/libc/arch-x86/syscalls/tee.S
index b47c460..693ad1e 100644
--- a/libc/arch-x86/syscalls/tee.S
+++ b/libc/arch-x86/syscalls/tee.S
@@ -15,12 +15,20 @@
     pushl   %esi
     .cfi_adjust_cfa_offset 4
     .cfi_rel_offset esi, 0
-    mov     20(%esp), %ebx
-    mov     24(%esp), %ecx
-    mov     28(%esp), %edx
-    mov     32(%esp), %esi
+
+    call    __kernel_syscall
+    pushl   %eax
+    .cfi_adjust_cfa_offset 4
+    .cfi_rel_offset eax, 0
+
+    mov     24(%esp), %ebx
+    mov     28(%esp), %ecx
+    mov     32(%esp), %edx
+    mov     36(%esp), %esi
     movl    $__NR_tee, %eax
-    int     $0x80
+    call    *(%esp)
+    addl    $4, %esp
+
     cmpl    $-MAX_ERRNO, %eax
     jb      1f
     negl    %eax
diff --git a/libc/arch-x86/syscalls/tgkill.S b/libc/arch-x86/syscalls/tgkill.S
index 7a43a01..5cce4d8 100644
--- a/libc/arch-x86/syscalls/tgkill.S
+++ b/libc/arch-x86/syscalls/tgkill.S
@@ -12,11 +12,19 @@
     pushl   %edx
     .cfi_adjust_cfa_offset 4
     .cfi_rel_offset edx, 0
-    mov     16(%esp), %ebx
-    mov     20(%esp), %ecx
-    mov     24(%esp), %edx
+
+    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_tgkill, %eax
-    int     $0x80
+    call    *(%esp)
+    addl    $4, %esp
+
     cmpl    $-MAX_ERRNO, %eax
     jb      1f
     negl    %eax
diff --git a/libc/arch-x86/syscalls/timerfd_create.S b/libc/arch-x86/syscalls/timerfd_create.S
index ad099a5..335b7a6 100644
--- a/libc/arch-x86/syscalls/timerfd_create.S
+++ b/libc/arch-x86/syscalls/timerfd_create.S
@@ -9,10 +9,18 @@
     pushl   %ecx
     .cfi_adjust_cfa_offset 4
     .cfi_rel_offset ecx, 0
-    mov     12(%esp), %ebx
-    mov     16(%esp), %ecx
+
+    call    __kernel_syscall
+    pushl   %eax
+    .cfi_adjust_cfa_offset 4
+    .cfi_rel_offset eax, 0
+
+    mov     16(%esp), %ebx
+    mov     20(%esp), %ecx
     movl    $__NR_timerfd_create, %eax
-    int     $0x80
+    call    *(%esp)
+    addl    $4, %esp
+
     cmpl    $-MAX_ERRNO, %eax
     jb      1f
     negl    %eax
diff --git a/libc/arch-x86/syscalls/timerfd_gettime.S b/libc/arch-x86/syscalls/timerfd_gettime.S
index c679b7c..9dc1a2f 100644
--- a/libc/arch-x86/syscalls/timerfd_gettime.S
+++ b/libc/arch-x86/syscalls/timerfd_gettime.S
@@ -9,10 +9,18 @@
     pushl   %ecx
     .cfi_adjust_cfa_offset 4
     .cfi_rel_offset ecx, 0
-    mov     12(%esp), %ebx
-    mov     16(%esp), %ecx
+
+    call    __kernel_syscall
+    pushl   %eax
+    .cfi_adjust_cfa_offset 4
+    .cfi_rel_offset eax, 0
+
+    mov     16(%esp), %ebx
+    mov     20(%esp), %ecx
     movl    $__NR_timerfd_gettime, %eax
-    int     $0x80
+    call    *(%esp)
+    addl    $4, %esp
+
     cmpl    $-MAX_ERRNO, %eax
     jb      1f
     negl    %eax
diff --git a/libc/arch-x86/syscalls/timerfd_settime.S b/libc/arch-x86/syscalls/timerfd_settime.S
index 4e889ea..477b5bb 100644
--- a/libc/arch-x86/syscalls/timerfd_settime.S
+++ b/libc/arch-x86/syscalls/timerfd_settime.S
@@ -15,12 +15,20 @@
     pushl   %esi
     .cfi_adjust_cfa_offset 4
     .cfi_rel_offset esi, 0
-    mov     20(%esp), %ebx
-    mov     24(%esp), %ecx
-    mov     28(%esp), %edx
-    mov     32(%esp), %esi
+
+    call    __kernel_syscall
+    pushl   %eax
+    .cfi_adjust_cfa_offset 4
+    .cfi_rel_offset eax, 0
+
+    mov     24(%esp), %ebx
+    mov     28(%esp), %ecx
+    mov     32(%esp), %edx
+    mov     36(%esp), %esi
     movl    $__NR_timerfd_settime, %eax
-    int     $0x80
+    call    *(%esp)
+    addl    $4, %esp
+
     cmpl    $-MAX_ERRNO, %eax
     jb      1f
     negl    %eax
diff --git a/libc/arch-x86/syscalls/times.S b/libc/arch-x86/syscalls/times.S
index 0ba0b6f..14fe221 100644
--- a/libc/arch-x86/syscalls/times.S
+++ b/libc/arch-x86/syscalls/times.S
@@ -6,9 +6,17 @@
     pushl   %ebx
     .cfi_def_cfa_offset 8
     .cfi_rel_offset ebx, 0
-    mov     8(%esp), %ebx
+
+    call    __kernel_syscall
+    pushl   %eax
+    .cfi_adjust_cfa_offset 4
+    .cfi_rel_offset eax, 0
+
+    mov     12(%esp), %ebx
     movl    $__NR_times, %eax
-    int     $0x80
+    call    *(%esp)
+    addl    $4, %esp
+
     cmpl    $-MAX_ERRNO, %eax
     jb      1f
     negl    %eax
diff --git a/libc/arch-x86/syscalls/truncate.S b/libc/arch-x86/syscalls/truncate.S
index 31fec17..dd99942 100644
--- a/libc/arch-x86/syscalls/truncate.S
+++ b/libc/arch-x86/syscalls/truncate.S
@@ -9,10 +9,18 @@
     pushl   %ecx
     .cfi_adjust_cfa_offset 4
     .cfi_rel_offset ecx, 0
-    mov     12(%esp), %ebx
-    mov     16(%esp), %ecx
+
+    call    __kernel_syscall
+    pushl   %eax
+    .cfi_adjust_cfa_offset 4
+    .cfi_rel_offset eax, 0
+
+    mov     16(%esp), %ebx
+    mov     20(%esp), %ecx
     movl    $__NR_truncate, %eax
-    int     $0x80
+    call    *(%esp)
+    addl    $4, %esp
+
     cmpl    $-MAX_ERRNO, %eax
     jb      1f
     negl    %eax
diff --git a/libc/arch-x86/syscalls/truncate64.S b/libc/arch-x86/syscalls/truncate64.S
index 45e24d0..35e4037 100644
--- a/libc/arch-x86/syscalls/truncate64.S
+++ b/libc/arch-x86/syscalls/truncate64.S
@@ -12,11 +12,19 @@
     pushl   %edx
     .cfi_adjust_cfa_offset 4
     .cfi_rel_offset edx, 0
-    mov     16(%esp), %ebx
-    mov     20(%esp), %ecx
-    mov     24(%esp), %edx
+
+    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_truncate64, %eax
-    int     $0x80
+    call    *(%esp)
+    addl    $4, %esp
+
     cmpl    $-MAX_ERRNO, %eax
     jb      1f
     negl    %eax
diff --git a/libc/arch-x86/syscalls/umask.S b/libc/arch-x86/syscalls/umask.S
index 9b4d3c7..3333fac 100644
--- a/libc/arch-x86/syscalls/umask.S
+++ b/libc/arch-x86/syscalls/umask.S
@@ -6,9 +6,17 @@
     pushl   %ebx
     .cfi_def_cfa_offset 8
     .cfi_rel_offset ebx, 0
-    mov     8(%esp), %ebx
+
+    call    __kernel_syscall
+    pushl   %eax
+    .cfi_adjust_cfa_offset 4
+    .cfi_rel_offset eax, 0
+
+    mov     12(%esp), %ebx
     movl    $__NR_umask, %eax
-    int     $0x80
+    call    *(%esp)
+    addl    $4, %esp
+
     cmpl    $-MAX_ERRNO, %eax
     jb      1f
     negl    %eax
diff --git a/libc/arch-x86/syscalls/umount2.S b/libc/arch-x86/syscalls/umount2.S
index 13757ab..48e1eb5 100644
--- a/libc/arch-x86/syscalls/umount2.S
+++ b/libc/arch-x86/syscalls/umount2.S
@@ -9,10 +9,18 @@
     pushl   %ecx
     .cfi_adjust_cfa_offset 4
     .cfi_rel_offset ecx, 0
-    mov     12(%esp), %ebx
-    mov     16(%esp), %ecx
+
+    call    __kernel_syscall
+    pushl   %eax
+    .cfi_adjust_cfa_offset 4
+    .cfi_rel_offset eax, 0
+
+    mov     16(%esp), %ebx
+    mov     20(%esp), %ecx
     movl    $__NR_umount2, %eax
-    int     $0x80
+    call    *(%esp)
+    addl    $4, %esp
+
     cmpl    $-MAX_ERRNO, %eax
     jb      1f
     negl    %eax
diff --git a/libc/arch-x86/syscalls/uname.S b/libc/arch-x86/syscalls/uname.S
index dab7e0d..9eea2c1 100644
--- a/libc/arch-x86/syscalls/uname.S
+++ b/libc/arch-x86/syscalls/uname.S
@@ -6,9 +6,17 @@
     pushl   %ebx
     .cfi_def_cfa_offset 8
     .cfi_rel_offset ebx, 0
-    mov     8(%esp), %ebx
+
+    call    __kernel_syscall
+    pushl   %eax
+    .cfi_adjust_cfa_offset 4
+    .cfi_rel_offset eax, 0
+
+    mov     12(%esp), %ebx
     movl    $__NR_uname, %eax
-    int     $0x80
+    call    *(%esp)
+    addl    $4, %esp
+
     cmpl    $-MAX_ERRNO, %eax
     jb      1f
     negl    %eax
diff --git a/libc/arch-x86/syscalls/unlinkat.S b/libc/arch-x86/syscalls/unlinkat.S
index 6faf71e..e039a34 100644
--- a/libc/arch-x86/syscalls/unlinkat.S
+++ b/libc/arch-x86/syscalls/unlinkat.S
@@ -12,11 +12,19 @@
     pushl   %edx
     .cfi_adjust_cfa_offset 4
     .cfi_rel_offset edx, 0
-    mov     16(%esp), %ebx
-    mov     20(%esp), %ecx
-    mov     24(%esp), %edx
+
+    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_unlinkat, %eax
-    int     $0x80
+    call    *(%esp)
+    addl    $4, %esp
+
     cmpl    $-MAX_ERRNO, %eax
     jb      1f
     negl    %eax
diff --git a/libc/arch-x86/syscalls/unshare.S b/libc/arch-x86/syscalls/unshare.S
index b724798c..ae68d7e 100644
--- a/libc/arch-x86/syscalls/unshare.S
+++ b/libc/arch-x86/syscalls/unshare.S
@@ -6,9 +6,17 @@
     pushl   %ebx
     .cfi_def_cfa_offset 8
     .cfi_rel_offset ebx, 0
-    mov     8(%esp), %ebx
+
+    call    __kernel_syscall
+    pushl   %eax
+    .cfi_adjust_cfa_offset 4
+    .cfi_rel_offset eax, 0
+
+    mov     12(%esp), %ebx
     movl    $__NR_unshare, %eax
-    int     $0x80
+    call    *(%esp)
+    addl    $4, %esp
+
     cmpl    $-MAX_ERRNO, %eax
     jb      1f
     negl    %eax
diff --git a/libc/arch-x86/syscalls/utimensat.S b/libc/arch-x86/syscalls/utimensat.S
index 07eca45..43eebc7 100644
--- a/libc/arch-x86/syscalls/utimensat.S
+++ b/libc/arch-x86/syscalls/utimensat.S
@@ -15,12 +15,20 @@
     pushl   %esi
     .cfi_adjust_cfa_offset 4
     .cfi_rel_offset esi, 0
-    mov     20(%esp), %ebx
-    mov     24(%esp), %ecx
-    mov     28(%esp), %edx
-    mov     32(%esp), %esi
+
+    call    __kernel_syscall
+    pushl   %eax
+    .cfi_adjust_cfa_offset 4
+    .cfi_rel_offset eax, 0
+
+    mov     24(%esp), %ebx
+    mov     28(%esp), %ecx
+    mov     32(%esp), %edx
+    mov     36(%esp), %esi
     movl    $__NR_utimensat, %eax
-    int     $0x80
+    call    *(%esp)
+    addl    $4, %esp
+
     cmpl    $-MAX_ERRNO, %eax
     jb      1f
     negl    %eax
diff --git a/libc/arch-x86/syscalls/vmsplice.S b/libc/arch-x86/syscalls/vmsplice.S
index f12cc65..195b0bf 100644
--- a/libc/arch-x86/syscalls/vmsplice.S
+++ b/libc/arch-x86/syscalls/vmsplice.S
@@ -15,12 +15,20 @@
     pushl   %esi
     .cfi_adjust_cfa_offset 4
     .cfi_rel_offset esi, 0
-    mov     20(%esp), %ebx
-    mov     24(%esp), %ecx
-    mov     28(%esp), %edx
-    mov     32(%esp), %esi
+
+    call    __kernel_syscall
+    pushl   %eax
+    .cfi_adjust_cfa_offset 4
+    .cfi_rel_offset eax, 0
+
+    mov     24(%esp), %ebx
+    mov     28(%esp), %ecx
+    mov     32(%esp), %edx
+    mov     36(%esp), %esi
     movl    $__NR_vmsplice, %eax
-    int     $0x80
+    call    *(%esp)
+    addl    $4, %esp
+
     cmpl    $-MAX_ERRNO, %eax
     jb      1f
     negl    %eax
diff --git a/libc/arch-x86/syscalls/wait4.S b/libc/arch-x86/syscalls/wait4.S
index bed7c40..281d5f2 100644
--- a/libc/arch-x86/syscalls/wait4.S
+++ b/libc/arch-x86/syscalls/wait4.S
@@ -15,12 +15,20 @@
     pushl   %esi
     .cfi_adjust_cfa_offset 4
     .cfi_rel_offset esi, 0
-    mov     20(%esp), %ebx
-    mov     24(%esp), %ecx
-    mov     28(%esp), %edx
-    mov     32(%esp), %esi
+
+    call    __kernel_syscall
+    pushl   %eax
+    .cfi_adjust_cfa_offset 4
+    .cfi_rel_offset eax, 0
+
+    mov     24(%esp), %ebx
+    mov     28(%esp), %ecx
+    mov     32(%esp), %edx
+    mov     36(%esp), %esi
     movl    $__NR_wait4, %eax
-    int     $0x80
+    call    *(%esp)
+    addl    $4, %esp
+
     cmpl    $-MAX_ERRNO, %eax
     jb      1f
     negl    %eax
diff --git a/libc/arch-x86/syscalls/write.S b/libc/arch-x86/syscalls/write.S
index e147208..e9e5f4e 100644
--- a/libc/arch-x86/syscalls/write.S
+++ b/libc/arch-x86/syscalls/write.S
@@ -12,11 +12,19 @@
     pushl   %edx
     .cfi_adjust_cfa_offset 4
     .cfi_rel_offset edx, 0
-    mov     16(%esp), %ebx
-    mov     20(%esp), %ecx
-    mov     24(%esp), %edx
+
+    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_write, %eax
-    int     $0x80
+    call    *(%esp)
+    addl    $4, %esp
+
     cmpl    $-MAX_ERRNO, %eax
     jb      1f
     negl    %eax
diff --git a/libc/arch-x86/syscalls/writev.S b/libc/arch-x86/syscalls/writev.S
index 07ba7b5..6649905 100644
--- a/libc/arch-x86/syscalls/writev.S
+++ b/libc/arch-x86/syscalls/writev.S
@@ -12,11 +12,19 @@
     pushl   %edx
     .cfi_adjust_cfa_offset 4
     .cfi_rel_offset edx, 0
-    mov     16(%esp), %ebx
-    mov     20(%esp), %ecx
-    mov     24(%esp), %edx
+
+    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_writev, %eax
-    int     $0x80
+    call    *(%esp)
+    addl    $4, %esp
+
     cmpl    $-MAX_ERRNO, %eax
     jb      1f
     negl    %eax
diff --git a/libc/arch-x86/x86.mk b/libc/arch-x86/x86.mk
index e5d70a9..1d717aa 100644
--- a/libc/arch-x86/x86.mk
+++ b/libc/arch-x86/x86.mk
@@ -1,17 +1,103 @@
 # 32-bit x86.
 
 #
-# Default implementations of functions that are commonly optimized.
+# Generic x86 optimizations, may be overriden by CPU variants.
 #
 
-libc_common_src_files_x86 += \
-    bionic/__memcpy_chk.cpp \
-    bionic/__memset_chk.cpp \
-    bionic/__strcpy_chk.cpp \
-    bionic/__strcat_chk.cpp \
+libc_bionic_src_files_x86 += \
+    arch-x86/atom/string/sse2-memchr-atom.S \
+    arch-x86/atom/string/sse2-memrchr-atom.S \
+    arch-x86/atom/string/sse2-strchr-atom.S \
+    arch-x86/atom/string/sse2-strnlen-atom.S \
+    arch-x86/atom/string/sse2-strrchr-atom.S \
+    arch-x86/atom/string/sse2-wcschr-atom.S \
+    arch-x86/atom/string/sse2-wcsrchr-atom.S \
+    arch-x86/atom/string/sse2-wcslen-atom.S \
+    arch-x86/atom/string/sse2-wcscmp-atom.S \
+    arch-x86/silvermont/string/sse2-bcopy-slm.S \
+    arch-x86/silvermont/string/sse2-bzero-slm.S \
+    arch-x86/silvermont/string/sse2-memcpy-slm.S \
+    arch-x86/silvermont/string/sse2-memmove-slm.S \
+    arch-x86/silvermont/string/sse2-memset-slm.S \
+    arch-x86/silvermont/string/sse2-stpcpy-slm.S \
+    arch-x86/silvermont/string/sse2-stpncpy-slm.S \
+    arch-x86/silvermont/string/sse2-strcpy-slm.S \
+    arch-x86/silvermont/string/sse2-strlen-slm.S \
+    arch-x86/silvermont/string/sse2-strncpy-slm.S
 
-libc_freebsd_src_files_x86 += \
-    upstream-freebsd/lib/libc/string/wmemmove.c \
+libc_bionic_src_files_x86 += \
+    arch-x86/generic/string/memcmp.S \
+    arch-x86/generic/string/strcmp.S \
+    arch-x86/generic/string/strncmp.S \
+    arch-x86/generic/string/strcat.S
+
+ifeq ($(ARCH_X86_HAVE_SSSE3),true)
+libc_bionic_src_files_x86 += \
+    arch-x86/atom/string/ssse3-strncat-atom.S \
+    arch-x86/atom/string/ssse3-strlcat-atom.S \
+    arch-x86/atom/string/ssse3-strlcpy-atom.S \
+    arch-x86/atom/string/ssse3-strcmp-atom.S \
+    arch-x86/atom/string/ssse3-strncmp-atom.S \
+    arch-x86/atom/string/ssse3-strcat-atom.S \
+    arch-x86/atom/string/ssse3-wcscat-atom.S \
+    arch-x86/atom/string/ssse3-wcscpy-atom.S
+libc_bionic_src_files_exclude_x86 += \
+    arch-x86/generic/string/strcmp.S \
+    arch-x86/generic/string/strncmp.S \
+    arch-x86/generic/string/strcat.S
+endif
+
+ifeq ($(ARCH_X86_HAVE_SSE4),true)
+libc_bionic_src_files_x86 += \
+    arch-x86/silvermont/string/sse4-memcmp-slm.S \
+    arch-x86/silvermont/string/sse4-wmemcmp-slm.S
+libc_bionic_src_files_exclude_x86 += \
+    arch-x86/generic/string/memcmp.S
+endif
+
+#
+# Remove default implementations that we have optimized versions of.
+#
+
+libc_freebsd_src_files_exclude_x86 += \
+    upstream-freebsd/lib/libc/string/wcschr.c \
+    upstream-freebsd/lib/libc/string/wcscmp.c \
+    upstream-freebsd/lib/libc/string/wcslen.c \
+    upstream-freebsd/lib/libc/string/wcsrchr.c \
+
+ifeq ($(ARCH_X86_HAVE_SSSE3),true)
+libc_freebsd_src_files_exclude_x86 += \
+    upstream-freebsd/lib/libc/string/wcscat.c \
+    upstream-freebsd/lib/libc/string/wcscpy.c
+endif
+
+ifeq ($(ARCH_X86_HAVE_SSE4),true)
+libc_freebsd_src_files_exclude_x86 += \
+    upstream-freebsd/lib/libc/string/wmemcmp.c
+endif
+
+libc_openbsd_src_files_exclude_x86 += \
+    upstream-openbsd/lib/libc/string/memchr.c \
+    upstream-openbsd/lib/libc/string/memmove.c \
+    upstream-openbsd/lib/libc/string/memrchr.c \
+    upstream-openbsd/lib/libc/string/stpcpy.c \
+    upstream-openbsd/lib/libc/string/stpncpy.c \
+    upstream-openbsd/lib/libc/string/strcat.c \
+    upstream-openbsd/lib/libc/string/strcpy.c \
+    upstream-openbsd/lib/libc/string/strncmp.c \
+    upstream-openbsd/lib/libc/string/strncpy.c \
+
+ifeq ($(ARCH_X86_HAVE_SSSE3),true)
+libc_openbsd_src_files_exclude_x86 += \
+    upstream-openbsd/lib/libc/string/strlcat.c \
+    upstream-openbsd/lib/libc/string/strlcpy.c \
+    upstream-openbsd/lib/libc/string/strncat.c
+endif
+
+libc_bionic_src_files_exclude_x86 += \
+    bionic/strchr.cpp \
+    bionic/strnlen.c \
+    bionic/strrchr.cpp \
 
 #
 # Inherently architecture-specific functions.
@@ -23,19 +109,20 @@
     arch-x86/bionic/libgcc_compat.c \
     arch-x86/bionic/__restore.S \
     arch-x86/bionic/setjmp.S \
-    arch-x86/bionic/__set_tls.c \
     arch-x86/bionic/syscall.S \
     arch-x86/bionic/vfork.S \
 
 ## ARCH variant specific source files
 arch_variant_mk := $(LOCAL_PATH)/arch-x86/$(TARGET_ARCH_VARIANT)/$(TARGET_ARCH_VARIANT).mk
 ifeq ($(wildcard $(arch_variant_mk)),)
-    arch_variant_mk := $(LOCAL_PATH)/arch-x86/generic/generic.mk
+    arch_variant_mk :=
 endif
+ifneq ($(arch_variant_mk),)
 include $(arch_variant_mk)
 libc_common_additional_dependencies += $(arch_variant_mk)
 
 arch_variant_mk :=
+endif
 
 libc_crt_target_cflags_x86 := \
     -m32 \
diff --git a/libc/arch-x86_64/bionic/setjmp.S b/libc/arch-x86_64/bionic/setjmp.S
index 5559f54..34b4365 100644
--- a/libc/arch-x86_64/bionic/setjmp.S
+++ b/libc/arch-x86_64/bionic/setjmp.S
@@ -35,8 +35,22 @@
 
 #include <private/bionic_asm.h>
 
-// These are only the callee-saved registers. Code calling setjmp
-// will expect the rest to be clobbered anyway.
+
+// The internal structure of a jmp_buf is totally private.
+// Current layout (changes from release to release):
+//
+// word   name            description
+// 0      rbx             registers
+// 1      rbp
+// 2      r12
+// 3      r13
+// 4      r14
+// 5      r15
+// 6      rsp
+// 7      pc
+// 8      sigflag/cookie  setjmp cookie in top 31 bits, signal mask flag in low bit
+// 9      sigmask         signal mask (includes rt signals as well)
+// 10     checksum        checksum of the core registers, to give better error messages.
 
 #define _JB_RBX 0
 #define _JB_RBP 1
@@ -48,7 +62,33 @@
 #define _JB_PC 7
 #define _JB_SIGFLAG 8
 #define _JB_SIGMASK 9
-#define _JB_SIGMASK_RT 10 // sigprocmask will write here too.
+#define _JB_CHECKSUM 10
+
+#define MANGLE_REGISTERS 1
+
+.macro m_mangle_registers reg
+#if MANGLE_REGISTERS
+  xorq \reg,%rbx
+  xorq \reg,%rbp
+  xorq \reg,%r12
+  xorq \reg,%r13
+  xorq \reg,%r14
+  xorq \reg,%r15
+  xorq \reg,%rsp
+  xorq \reg,%r11
+#endif
+.endm
+
+.macro m_unmangle_registers reg
+  m_mangle_registers \reg
+.endm
+
+.macro m_calculate_checksum dst, src
+  movq $0, \dst
+  .irp i,0,1,2,3,4,5,6,7
+    xorq (\i*8)(\src), \dst
+  .endr
+.endm
 
 ENTRY(setjmp)
   movl $1,%esi
@@ -62,11 +102,17 @@
 
 // int sigsetjmp(sigjmp_buf env, int save_signal_mask);
 ENTRY(sigsetjmp)
-  // Record whether or not we're saving the signal mask.
-  movl %esi,(_JB_SIGFLAG * 8)(%rdi)
+  pushq %rdi
+  movq %rsi,%rdi
+  call PIC_PLT(__bionic_setjmp_cookie_get)
+  popq %rdi
+
+  // Record setjmp cookie and whether or not we're saving the signal mask.
+  movq %rax,(_JB_SIGFLAG * 8)(%rdi)
+  pushq %rax
 
   // Do we need to save the signal mask?
-  testl %esi,%esi
+  testq $1,%rax
   jz 2f
 
   // Save current signal mask.
@@ -79,7 +125,10 @@
 
 2:
   // Save the callee-save registers.
+  popq %rax
+  andq $-2,%rax
   movq (%rsp),%r11
+  m_mangle_registers %rax
   movq %rbx,(_JB_RBX * 8)(%rdi)
   movq %rbp,(_JB_RBP * 8)(%rdi)
   movq %r12,(_JB_R12 * 8)(%rdi)
@@ -88,6 +137,10 @@
   movq %r15,(_JB_R15 * 8)(%rdi)
   movq %rsp,(_JB_RSP * 8)(%rdi)
   movq %r11,(_JB_PC  * 8)(%rdi)
+  m_unmangle_registers %rax
+
+  m_calculate_checksum %rax, %rdi
+  movq %rax, (_JB_CHECKSUM * 8)(%rdi)
 
   xorl %eax,%eax
   ret
@@ -98,8 +151,14 @@
   movq %rdi,%r12
   pushq %rsi // Push 'value'.
 
+  m_calculate_checksum %rax, %rdi
+  xorq (_JB_CHECKSUM * 8)(%rdi), %rax
+  jnz 3f
+
   // Do we need to restore the signal mask?
-  cmpl $0,(_JB_SIGFLAG * 8)(%rdi)
+  movq (_JB_SIGFLAG * 8)(%rdi), %rdi
+  pushq %rdi // Push cookie
+  testq $1, %rdi
   jz 2f
 
   // Restore the signal mask.
@@ -109,6 +168,10 @@
   call PIC_PLT(sigprocmask)
 
 2:
+  // Fetch the setjmp cookie and clear the signal flag bit.
+  popq %rcx
+  andq $-2, %rcx
+
   popq %rax // Pop 'value'.
 
   // Restore the callee-save registers.
@@ -120,13 +183,26 @@
   movq (_JB_RSP * 8)(%r12),%rsp
   movq (_JB_PC  * 8)(%r12),%r11
   movq (_JB_R12 * 8)(%r12),%r12
+  m_unmangle_registers %rcx
 
+  // Check the cookie.
+  pushq %rax
+  pushq %r11
+  movq %rcx, %rdi
+  call PIC_PLT(__bionic_setjmp_cookie_check)
+  popq %r11
+  popq %rax
+
+  // Return 1 if value is 0.
   testl %eax,%eax
   jnz 1f
   incl %eax
 1:
   movq %r11,0(%rsp)
   ret
+
+3:
+  call PIC_PLT(__bionic_setjmp_checksum_mismatch)
 END(siglongjmp)
 
 ALIAS_SYMBOL(longjmp, siglongjmp)
diff --git a/libc/arch-x86_64/bionic/vfork.S b/libc/arch-x86_64/bionic/vfork.S
index 129f1db..3b32c66 100644
--- a/libc/arch-x86_64/bionic/vfork.S
+++ b/libc/arch-x86_64/bionic/vfork.S
@@ -32,6 +32,12 @@
 
 ENTRY(vfork)
   popq    %rdi  // Grab the return address.
+
+  // __get_tls()[TLS_SLOT_THREAD_ID]->cached_pid_ = 0
+  mov    %fs:0, %rax
+  mov    8(%rax), %rax
+  movl   $0, 20(%rax)
+
   movl    $__NR_vfork, %eax
   syscall
   pushq   %rdi  // Restore the return address.
diff --git a/libc/arch-x86_64/string/sse2-memmove-slm.S b/libc/arch-x86_64/string/sse2-memmove-slm.S
index 0dbffad..6a5afd6 100644
--- a/libc/arch-x86_64/string/sse2-memmove-slm.S
+++ b/libc/arch-x86_64/string/sse2-memmove-slm.S
@@ -91,9 +91,6 @@
 	.section .text.sse2,"ax",@progbits
 ENTRY (MEMMOVE)
 	ENTRANCE
-#ifdef USE_AS_BCOPY
-	xchg	%rsi, %rdi
-#endif
 	mov	%rdi, %rax
 
 /* Check whether we should copy backward or forward.  */
diff --git a/libc/arch-x86_64/syscalls/flistxattr.S b/libc/arch-x86_64/syscalls/___flistxattr.S
similarity index 80%
rename from libc/arch-x86_64/syscalls/flistxattr.S
rename to libc/arch-x86_64/syscalls/___flistxattr.S
index aa02db1..b4695cc 100644
--- a/libc/arch-x86_64/syscalls/flistxattr.S
+++ b/libc/arch-x86_64/syscalls/___flistxattr.S
@@ -2,7 +2,7 @@
 
 #include <private/bionic_asm.h>
 
-ENTRY(flistxattr)
+ENTRY(___flistxattr)
     movl    $__NR_flistxattr, %eax
     syscall
     cmpq    $-MAX_ERRNO, %rax
@@ -12,4 +12,5 @@
     call    __set_errno_internal
 1:
     ret
-END(flistxattr)
+END(___flistxattr)
+.hidden ___flistxattr
diff --git a/libc/arch-x86_64/syscalls/mremap.S b/libc/arch-x86_64/syscalls/___mremap.S
similarity index 84%
rename from libc/arch-x86_64/syscalls/mremap.S
rename to libc/arch-x86_64/syscalls/___mremap.S
index a6042cb..cc6dee9 100644
--- a/libc/arch-x86_64/syscalls/mremap.S
+++ b/libc/arch-x86_64/syscalls/___mremap.S
@@ -2,7 +2,7 @@
 
 #include <private/bionic_asm.h>
 
-ENTRY(mremap)
+ENTRY(___mremap)
     movq    %rcx, %r10
     movl    $__NR_mremap, %eax
     syscall
@@ -13,4 +13,5 @@
     call    __set_errno_internal
 1:
     ret
-END(mremap)
+END(___mremap)
+.hidden ___mremap
diff --git a/libc/arch-x86_64/syscalls/flistxattr.S b/libc/arch-x86_64/syscalls/adjtimex.S
similarity index 76%
copy from libc/arch-x86_64/syscalls/flistxattr.S
copy to libc/arch-x86_64/syscalls/adjtimex.S
index aa02db1..292b9f3 100644
--- a/libc/arch-x86_64/syscalls/flistxattr.S
+++ b/libc/arch-x86_64/syscalls/adjtimex.S
@@ -2,8 +2,8 @@
 
 #include <private/bionic_asm.h>
 
-ENTRY(flistxattr)
-    movl    $__NR_flistxattr, %eax
+ENTRY(adjtimex)
+    movl    $__NR_adjtimex, %eax
     syscall
     cmpq    $-MAX_ERRNO, %rax
     jb      1f
@@ -12,4 +12,4 @@
     call    __set_errno_internal
 1:
     ret
-END(flistxattr)
+END(adjtimex)
diff --git a/libc/arch-x86_64/syscalls/flistxattr.S b/libc/arch-x86_64/syscalls/clock_adjtime.S
similarity index 73%
copy from libc/arch-x86_64/syscalls/flistxattr.S
copy to libc/arch-x86_64/syscalls/clock_adjtime.S
index aa02db1..0601930 100644
--- a/libc/arch-x86_64/syscalls/flistxattr.S
+++ b/libc/arch-x86_64/syscalls/clock_adjtime.S
@@ -2,8 +2,8 @@
 
 #include <private/bionic_asm.h>
 
-ENTRY(flistxattr)
-    movl    $__NR_flistxattr, %eax
+ENTRY(clock_adjtime)
+    movl    $__NR_clock_adjtime, %eax
     syscall
     cmpq    $-MAX_ERRNO, %rax
     jb      1f
@@ -12,4 +12,4 @@
     call    __set_errno_internal
 1:
     ret
-END(flistxattr)
+END(clock_adjtime)
diff --git a/libc/arch-x86_64/syscalls/mremap.S b/libc/arch-x86_64/syscalls/preadv.S
similarity index 73%
copy from libc/arch-x86_64/syscalls/mremap.S
copy to libc/arch-x86_64/syscalls/preadv.S
index a6042cb..7771a44 100644
--- a/libc/arch-x86_64/syscalls/mremap.S
+++ b/libc/arch-x86_64/syscalls/preadv.S
@@ -2,9 +2,9 @@
 
 #include <private/bionic_asm.h>
 
-ENTRY(mremap)
+ENTRY(preadv)
     movq    %rcx, %r10
-    movl    $__NR_mremap, %eax
+    movl    $__NR_preadv, %eax
     syscall
     cmpq    $-MAX_ERRNO, %rax
     jb      1f
@@ -13,4 +13,6 @@
     call    __set_errno_internal
 1:
     ret
-END(mremap)
+END(preadv)
+
+ALIAS_SYMBOL(preadv64, preadv)
diff --git a/libc/arch-x86_64/syscalls/mremap.S b/libc/arch-x86_64/syscalls/pwritev.S
similarity index 72%
copy from libc/arch-x86_64/syscalls/mremap.S
copy to libc/arch-x86_64/syscalls/pwritev.S
index a6042cb..d3bd8fa 100644
--- a/libc/arch-x86_64/syscalls/mremap.S
+++ b/libc/arch-x86_64/syscalls/pwritev.S
@@ -2,9 +2,9 @@
 
 #include <private/bionic_asm.h>
 
-ENTRY(mremap)
+ENTRY(pwritev)
     movq    %rcx, %r10
-    movl    $__NR_mremap, %eax
+    movl    $__NR_pwritev, %eax
     syscall
     cmpq    $-MAX_ERRNO, %rax
     jb      1f
@@ -13,4 +13,6 @@
     call    __set_errno_internal
 1:
     ret
-END(mremap)
+END(pwritev)
+
+ALIAS_SYMBOL(pwritev64, pwritev)
diff --git a/libc/arch-x86_64/x86_64.mk b/libc/arch-x86_64/x86_64.mk
index 06d3185..ce06217 100644
--- a/libc/arch-x86_64/x86_64.mk
+++ b/libc/arch-x86_64/x86_64.mk
@@ -1,31 +1,20 @@
 # 64-bit x86.
 
 #
-# Default implementations of functions that are commonly optimized.
+# Remove default implementations that we have optimized versions of.
 #
 
-libc_bionic_src_files_x86_64 += \
-    bionic/__memcpy_chk.cpp \
-    bionic/__memset_chk.cpp \
-    bionic/__strcpy_chk.cpp \
-    bionic/__strcat_chk.cpp \
-    bionic/strchr.cpp \
-    bionic/strnlen.c \
-    bionic/strrchr.cpp \
-
-libc_freebsd_src_files_x86_64 += \
-    upstream-freebsd/lib/libc/string/wcscat.c \
-    upstream-freebsd/lib/libc/string/wcschr.c \
-    upstream-freebsd/lib/libc/string/wcscmp.c \
-    upstream-freebsd/lib/libc/string/wcscpy.c \
-    upstream-freebsd/lib/libc/string/wcslen.c \
-    upstream-freebsd/lib/libc/string/wcsrchr.c \
-    upstream-freebsd/lib/libc/string/wmemcmp.c \
-    upstream-freebsd/lib/libc/string/wmemmove.c \
-
-libc_openbsd_src_files_x86_64 += \
-    upstream-openbsd/lib/libc/string/memchr.c \
-    upstream-openbsd/lib/libc/string/memrchr.c \
+libc_openbsd_src_files_exclude_x86_64 += \
+    upstream-openbsd/lib/libc/string/memmove.c \
+    upstream-openbsd/lib/libc/string/stpcpy.c \
+    upstream-openbsd/lib/libc/string/stpncpy.c \
+    upstream-openbsd/lib/libc/string/strcat.c \
+    upstream-openbsd/lib/libc/string/strcpy.c \
+    upstream-openbsd/lib/libc/string/strlcat.c \
+    upstream-openbsd/lib/libc/string/strlcpy.c \
+    upstream-openbsd/lib/libc/string/strncat.c \
+    upstream-openbsd/lib/libc/string/strncmp.c \
+    upstream-openbsd/lib/libc/string/strncpy.c \
 
 #
 # Inherently architecture-specific code.
@@ -36,7 +25,6 @@
     arch-x86_64/bionic/_exit_with_stack_teardown.S \
     arch-x86_64/bionic/__restore_rt.S \
     arch-x86_64/bionic/setjmp.S \
-    arch-x86_64/bionic/__set_tls.c \
     arch-x86_64/bionic/syscall.S \
     arch-x86_64/bionic/vfork.S \
 
diff --git a/libc/bionic/__cxa_guard.cpp b/libc/bionic/__cxa_guard.cpp
index 5b34b58..97284d5 100644
--- a/libc/bionic/__cxa_guard.cpp
+++ b/libc/bionic/__cxa_guard.cpp
@@ -109,7 +109,7 @@
       }
     }
 
-    __futex_wait_ex(&gv->state, false, CONSTRUCTION_UNDERWAY_WITH_WAITER, NULL);
+    __futex_wait_ex(&gv->state, false, CONSTRUCTION_UNDERWAY_WITH_WAITER, false, nullptr);
     old_value = atomic_load_explicit(&gv->state, memory_order_relaxed);
   }
 }
diff --git a/libc/bionic/__cxa_thread_atexit_impl.cpp b/libc/bionic/__cxa_thread_atexit_impl.cpp
index 0e427d3..6284b12 100644
--- a/libc/bionic/__cxa_thread_atexit_impl.cpp
+++ b/libc/bionic/__cxa_thread_atexit_impl.cpp
@@ -15,32 +15,34 @@
  */
 #include <sys/cdefs.h>
 
-struct thread_local_dtor {
+#include "pthread_internal.h"
+
+class thread_local_dtor {
+ public:
   void (*func) (void *);
   void *arg;
   void *dso_handle; // unused...
   thread_local_dtor* next;
 };
 
-static __thread thread_local_dtor* thread_local_dtors = nullptr;
-
 extern "C" int __cxa_thread_atexit_impl(void (*func) (void *), void *arg, void *dso_handle) {
   thread_local_dtor* dtor = new thread_local_dtor();
 
   dtor->func = func;
   dtor->arg = arg;
   dtor->dso_handle = dso_handle;
-  dtor->next = thread_local_dtors;
 
-  thread_local_dtors = dtor;
-
+  pthread_internal_t* thread = __get_thread();
+  dtor->next = thread->thread_local_dtors;
+  thread->thread_local_dtors = dtor;
   return 0;
 }
 
 extern "C" __LIBC_HIDDEN__ void __cxa_thread_finalize() {
-  while (thread_local_dtors != nullptr) {
-    thread_local_dtor* current = thread_local_dtors;
-    thread_local_dtors = current->next;
+  pthread_internal_t* thread = __get_thread();
+  while (thread->thread_local_dtors != nullptr) {
+    thread_local_dtor* current = thread->thread_local_dtors;
+    thread->thread_local_dtors = current->next;
 
     current->func(current->arg);
     delete current;
diff --git a/libc/bionic/debug_stacktrace.h b/libc/bionic/__fread_chk.cpp
similarity index 68%
copy from libc/bionic/debug_stacktrace.h
copy to libc/bionic/__fread_chk.cpp
index 2cf8636..afc8d90 100644
--- a/libc/bionic/debug_stacktrace.h
+++ b/libc/bionic/__fread_chk.cpp
@@ -1,5 +1,5 @@
 /*
- * Copyright (C) 2013 The Android Open Source Project
+ * Copyright (C) 2015 The Android Open Source Project
  * All rights reserved.
  *
  * Redistribution and use in source and binary forms, with or without
@@ -26,15 +26,22 @@
  * SUCH DAMAGE.
  */
 
-#ifndef DEBUG_STACKTRACE_H
-#define DEBUG_STACKTRACE_H
-
-#include <stdint.h>
+#undef _FORTIFY_SOURCE
+#include <stdio.h>
 #include <sys/cdefs.h>
+#include "private/libc_logging.h"
 
-__LIBC_HIDDEN__ void backtrace_startup();
-__LIBC_HIDDEN__ void backtrace_shutdown();
-__LIBC_HIDDEN__ int get_backtrace(uintptr_t* stack_frames, size_t max_depth);
-__LIBC_HIDDEN__ void log_backtrace(uintptr_t* stack_frames, size_t frame_count);
+extern "C" size_t __fread_chk(void * __restrict buf, size_t size, size_t count,
+                              FILE * __restrict stream, size_t buf_size) {
+  size_t total;
+  if (__predict_false(__size_mul_overflow(size, count, &total))) {
+    // overflow: trigger the error path in fread
+    return fread(buf, size, count, stream);
+  }
 
-#endif /* DEBUG_STACKTRACE_H */
+  if (__predict_false(total > buf_size)) {
+    __fortify_chk_fail("fread: prevented write past end of buffer", 0);
+  }
+
+  return fread(buf, size, count, stream);
+}
diff --git a/libc/bionic/debug_stacktrace.h b/libc/bionic/__fwrite_chk.cpp
similarity index 68%
copy from libc/bionic/debug_stacktrace.h
copy to libc/bionic/__fwrite_chk.cpp
index 2cf8636..2af13d6 100644
--- a/libc/bionic/debug_stacktrace.h
+++ b/libc/bionic/__fwrite_chk.cpp
@@ -1,5 +1,5 @@
 /*
- * Copyright (C) 2013 The Android Open Source Project
+ * Copyright (C) 2015 The Android Open Source Project
  * All rights reserved.
  *
  * Redistribution and use in source and binary forms, with or without
@@ -26,15 +26,22 @@
  * SUCH DAMAGE.
  */
 
-#ifndef DEBUG_STACKTRACE_H
-#define DEBUG_STACKTRACE_H
-
-#include <stdint.h>
+#undef _FORTIFY_SOURCE
+#include <stdio.h>
 #include <sys/cdefs.h>
+#include "private/libc_logging.h"
 
-__LIBC_HIDDEN__ void backtrace_startup();
-__LIBC_HIDDEN__ void backtrace_shutdown();
-__LIBC_HIDDEN__ int get_backtrace(uintptr_t* stack_frames, size_t max_depth);
-__LIBC_HIDDEN__ void log_backtrace(uintptr_t* stack_frames, size_t frame_count);
+extern "C" size_t __fwrite_chk(const void * __restrict buf, size_t size, size_t count,
+                               FILE * __restrict stream, size_t buf_size) {
+  size_t total;
+  if (__predict_false(__size_mul_overflow(size, count, &total))) {
+    // overflow: trigger the error path in fwrite
+    return fwrite(buf, size, count, stream);
+  }
 
-#endif /* DEBUG_STACKTRACE_H */
+  if (__predict_false(total > buf_size)) {
+    __fortify_chk_fail("fwrite: prevented read past end of buffer", 0);
+  }
+
+  return fwrite(buf, size, count, stream);
+}
diff --git a/libc/bionic/ioctl.c b/libc/bionic/__getcwd_chk.cpp
similarity index 79%
copy from libc/bionic/ioctl.c
copy to libc/bionic/__getcwd_chk.cpp
index 6dd95d0..b53ab5c 100644
--- a/libc/bionic/ioctl.c
+++ b/libc/bionic/__getcwd_chk.cpp
@@ -1,5 +1,5 @@
 /*
- * Copyright (C) 2008 The Android Open Source Project
+ * Copyright (C) 2015 The Android Open Source Project
  * All rights reserved.
  *
  * Redistribution and use in source and binary forms, with or without
@@ -25,19 +25,16 @@
  * OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF
  * SUCH DAMAGE.
  */
-#include <stdarg.h>
 
-extern int __ioctl(int, int, void *);
+#undef _FORTIFY_SOURCE
 
-int ioctl(int fd, int request, ...)
-{
-    va_list ap;
-    void * arg;
+#include <unistd.h>
+#include "private/libc_logging.h"
 
-    va_start(ap, request);
-    arg = va_arg(ap, void *);
-    va_end(ap);
+extern char* __getcwd_chk(char* buf, size_t len, size_t buflen) {
+  if (__predict_false(len > buflen)) {
+    __fortify_chk_fail("getcwd: prevented write past end of buffer", 0);
+  }
 
-    return __ioctl(fd, request, arg);
+  return getcwd(buf, len);
 }
-
diff --git a/libc/bionic/__libc_init_main_thread.cpp b/libc/bionic/__libc_init_main_thread.cpp
new file mode 100644
index 0000000..01bb9bb
--- /dev/null
+++ b/libc/bionic/__libc_init_main_thread.cpp
@@ -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 "libc_init_common.h"
+
+#include "private/bionic_auxv.h"
+#include "private/bionic_globals.h"
+#include "private/KernelArgumentBlock.h"
+#include "pthread_internal.h"
+
+extern "C" int __set_tls(void* ptr);
+extern "C" int __set_tid_address(int* tid_address);
+
+// Setup for the main thread. For dynamic executables, this is called by the
+// linker _before_ libc is mapped in memory. This means that all writes to
+// globals from this function will apply to linker-private copies and will not
+// be visible from libc later on.
+//
+// Note: this function creates a pthread_internal_t for the initial thread and
+// stores the pointer in TLS, but does not add it to pthread's thread list. This
+// has to be done later from libc itself (see __libc_init_common).
+//
+// This is in a file by itself because it needs to be built with
+// -fno-stack-protector because it's responsible for setting up the main
+// thread's TLS (which stack protector relies on).
+
+void __libc_init_main_thread(KernelArgumentBlock& args) {
+  __libc_auxv = args.auxv;
+#if defined(__i386__)
+  __libc_init_sysinfo(args);
+#endif
+
+  static pthread_internal_t main_thread;
+
+  // The -fstack-protector implementation uses TLS, so make sure that's
+  // set up before we call any function that might get a stack check inserted.
+  __set_tls(main_thread.tls);
+
+  // Tell the kernel to clear our tid field when we exit, so we're like any other pthread.
+  // As a side-effect, this tells us our pid (which is the same as the main thread's tid).
+  main_thread.tid = __set_tid_address(&main_thread.tid);
+  main_thread.set_cached_pid(main_thread.tid);
+
+  // We don't want to free the main thread's stack even when the main thread exits
+  // because things like environment variables with global scope live on it.
+  // We also can't free the pthread_internal_t itself, since that lives on the main
+  // 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.
+
+  // The TLS stack guard is set from the global, so ensure that we've initialized the global
+  // before we initialize the TLS.
+  __libc_init_global_stack_chk_guard(args);
+
+  __init_thread(&main_thread);
+  __init_tls(&main_thread);
+
+  // Store a pointer to the kernel argument block in a TLS slot to be
+  // picked up by the libc constructor.
+  main_thread.tls[TLS_SLOT_BIONIC_PREINIT] = &args;
+
+  __init_alternate_signal_stack(&main_thread);
+}
diff --git a/libc/bionic/ioctl.c b/libc/bionic/__pwrite64_chk.cpp
similarity index 71%
copy from libc/bionic/ioctl.c
copy to libc/bionic/__pwrite64_chk.cpp
index 6dd95d0..e488ca1 100644
--- a/libc/bionic/ioctl.c
+++ b/libc/bionic/__pwrite64_chk.cpp
@@ -1,5 +1,5 @@
 /*
- * Copyright (C) 2008 The Android Open Source Project
+ * Copyright (C) 2015 The Android Open Source Project
  * All rights reserved.
  *
  * Redistribution and use in source and binary forms, with or without
@@ -25,19 +25,20 @@
  * OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF
  * SUCH DAMAGE.
  */
-#include <stdarg.h>
 
-extern int __ioctl(int, int, void *);
+#undef _FORTIFY_SOURCE
+#include <unistd.h>
+#include "private/libc_logging.h"
 
-int ioctl(int fd, int request, ...)
-{
-    va_list ap;
-    void * arg;
+extern "C" ssize_t __pwrite64_chk(int fd, const void* buf, size_t count, off64_t offset,
+                                  size_t buf_size) {
+  if (__predict_false(count > buf_size)) {
+    __fortify_chk_fail("pwrite64: prevented read past end of buffer", 0);
+  }
 
-    va_start(ap, request);
-    arg = va_arg(ap, void *);
-    va_end(ap);
+  if (__predict_false(count > SSIZE_MAX)) {
+    __fortify_chk_fail("pwrite64: count > SSIZE_MAX", 0);
+  }
 
-    return __ioctl(fd, request, arg);
+  return pwrite64(fd, buf, count, offset);
 }
-
diff --git a/libc/include/machine/timespec.h b/libc/bionic/__pwrite_chk.cpp
similarity index 71%
copy from libc/include/machine/timespec.h
copy to libc/bionic/__pwrite_chk.cpp
index 11779ae..a889ef6 100644
--- a/libc/include/machine/timespec.h
+++ b/libc/bionic/__pwrite_chk.cpp
@@ -1,5 +1,5 @@
 /*
- * Copyright (C) 2014 The Android Open Source Project
+ * Copyright (C) 2015 The Android Open Source Project
  * All rights reserved.
  *
  * Redistribution and use in source and binary forms, with or without
@@ -26,21 +26,19 @@
  * SUCH DAMAGE.
  */
 
-#ifndef _MACHINE_TIMESPEC_H_
-#define _MACHINE_TIMESPEC_H_
+#undef _FORTIFY_SOURCE
+#include <unistd.h>
+#include "private/libc_logging.h"
 
-#include <sys/types.h>
+extern "C" ssize_t __pwrite_chk(int fd, const void* buf, size_t count, off_t offset,
+                                size_t buf_size) {
+  if (__predict_false(count > buf_size)) {
+    __fortify_chk_fail("pwrite: prevented read past end of buffer", 0);
+  }
 
-/*
- * This file is used to include timespec definition without introducing the whole
- * <linux/time.h>, <sys/time.h> or <time.h>.
- */
-#ifndef _STRUCT_TIMESPEC
-#define _STRUCT_TIMESPEC
-struct timespec {
-  time_t tv_sec;
-  long tv_nsec;
-};
-#endif
+  if (__predict_false(count > SSIZE_MAX)) {
+    __fortify_chk_fail("pwrite: count > SSIZE_MAX", 0);
+  }
 
-#endif /* _MACHINE_TIMESPEC_H_ */
+  return pwrite(fd, buf, count, offset);
+}
diff --git a/libc/bionic/__set_errno.cpp b/libc/bionic/__set_errno.cpp
index 30df350..9ef0047 100644
--- a/libc/bionic/__set_errno.cpp
+++ b/libc/bionic/__set_errno.cpp
@@ -36,20 +36,13 @@
 // system these are the same size, but on a 64-bit system they're not.
 // 'long' gives us 32-bit on 32-bit systems, 64-bit on 64-bit systems.
 
-// __set_errno was mistakenly exposed in <errno.h> in the 32-bit NDK.
-// We need the extra level of indirection so that the .hidden directives
-// in the system call stubs don't cause __set_errno to be hidden, breaking
-// old NDK apps.
+// Since __set_errno was mistakenly exposed in <errno.h> in the 32-bit
+// NDK, use a differently named internal function for the system call
+// stubs. This avoids having the stubs .hidden directives accidentally
+// hide __set_errno for old NDK apps.
 
 // This one is for internal use only and used by both LP32 and LP64 assembler.
 extern "C" __LIBC_HIDDEN__ long __set_errno_internal(int n) {
   errno = n;
   return -1;
 }
-
-// This one exists for the LP32 NDK and is not present at all in LP64.
-#if !defined(__LP64__)
-extern "C" long __set_errno(int n) {
-  return __set_errno_internal(n);
-}
-#endif
diff --git a/libc/include/sys/shm.h b/libc/bionic/__write_chk.cpp
similarity index 73%
copy from libc/include/sys/shm.h
copy to libc/bionic/__write_chk.cpp
index c691c29..cbd247a 100644
--- a/libc/include/sys/shm.h
+++ b/libc/bionic/__write_chk.cpp
@@ -1,5 +1,5 @@
 /*
- * Copyright (C) 2014 The Android Open Source Project
+ * Copyright (C) 2015 The Android Open Source Project
  * All rights reserved.
  *
  * Redistribution and use in source and binary forms, with or without
@@ -26,9 +26,18 @@
  * SUCH DAMAGE.
  */
 
-#ifndef _SYS_SHM_H_
-#define _SYS_SHM_H_
+#undef _FORTIFY_SOURCE
+#include <unistd.h>
+#include "private/libc_logging.h"
 
-#include <linux/shm.h>
+extern "C" ssize_t __write_chk(int fd, const void* buf, size_t count, size_t buf_size) {
+  if (__predict_false(count > buf_size)) {
+    __fortify_chk_fail("write: prevented read past end of buffer", 0);
+  }
 
-#endif /* _SYS_SHM_H_ */
+  if (__predict_false(count > SSIZE_MAX)) {
+    __fortify_chk_fail("write: count > SSIZE_MAX", 0);
+  }
+
+  return write(fd, buf, count);
+}
diff --git a/libc/bionic/arpa_inet.cpp b/libc/bionic/arpa_inet.cpp
new file mode 100644
index 0000000..9d4afe3
--- /dev/null
+++ b/libc/bionic/arpa_inet.cpp
@@ -0,0 +1,72 @@
+/*
+ * Copyright (C) 2015 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 <arpa/inet.h>
+#include <netinet/in.h>
+#include <stdlib.h>
+
+#include "private/ErrnoRestorer.h"
+
+// The difference between inet_network(3) and inet_addr(3) is that
+// inet_network uses host order and inet_addr network order.
+in_addr_t inet_network(const char* cp) {
+  in_addr_t network_order = inet_addr(cp);
+  return ntohl(network_order);
+}
+
+in_addr_t inet_addr(const char* cp) {
+  in_addr addr;
+  return inet_aton(cp, &addr) ? addr.s_addr : INADDR_NONE;
+}
+
+int inet_aton(const char* cp, in_addr* addr) {
+  ErrnoRestorer errno_restorer;
+
+  unsigned long parts[4];
+  size_t i;
+  for (i = 0; i < 4; ++i) {
+    char* end;
+    errno = 0;
+    parts[i] = strtoul(cp, &end, 0);
+    if (errno != 0 || end == cp || (*end != '.' && *end != '\0')) return 0;
+    if (*end == '\0') break;
+    cp = end + 1;
+  }
+
+  uint32_t result = 0;
+  if (i == 0) {
+    // a (a 32-bit).
+    if (parts[0] > 0xffffffff) return 0;
+    result = parts[0];
+  } else if (i == 1) {
+    // a.b (b 24-bit).
+    if (parts[0] > 0xff || parts[1] > 0xffffff) return 0;
+    result = (parts[0] << 24) | parts[1];
+  } else if (i == 2) {
+    // a.b.c (c 16-bit).
+    if (parts[0] > 0xff || parts[1] > 0xff || parts[2] > 0xffff) return 0;
+    result = (parts[0] << 24) | (parts[1] << 16) | parts[2];
+  } else if (i == 3) {
+    // a.b.c.d (d 8-bit).
+    if (parts[0] > 0xff || parts[1] > 0xff || parts[2] > 0xff || parts[3] > 0xff) return 0;
+    result = (parts[0] << 24) | (parts[1] << 16) | (parts[2] << 8) | parts[3];
+  } else {
+    return 0;
+  }
+
+  if (addr != nullptr) addr->s_addr = htonl(result);
+  return 1;
+}
diff --git a/libc/bionic/bionic_netlink.cpp b/libc/bionic/bionic_netlink.cpp
new file mode 100644
index 0000000..19ca88d
--- /dev/null
+++ b/libc/bionic/bionic_netlink.cpp
@@ -0,0 +1,93 @@
+/*
+ * Copyright (C) 2015 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 "bionic_netlink.h"
+
+#include <errno.h>
+#include <linux/netlink.h>
+#include <linux/rtnetlink.h>
+#include <string.h>
+#include <stdlib.h>
+#include <sys/socket.h>
+#include <unistd.h>
+
+#include "private/ErrnoRestorer.h"
+
+NetlinkConnection::NetlinkConnection() {
+  fd_ = -1;
+
+  // The kernel keeps packets under 8KiB (NLMSG_GOODSIZE),
+  // but that's a bit too large to go on the stack.
+  size_ = 8192;
+  data_ = new char[size_];
+}
+
+NetlinkConnection::~NetlinkConnection() {
+  ErrnoRestorer errno_restorer;
+  if (fd_ != -1) close(fd_);
+  delete[] data_;
+}
+
+bool NetlinkConnection::SendRequest(int type) {
+  // Rather than force all callers to check for the unlikely event of being
+  // unable to allocate 8KiB, check here.
+  if (data_ == nullptr) return false;
+
+  // Did we open a netlink socket yet?
+  if (fd_ == -1) {
+    fd_ = socket(PF_NETLINK, SOCK_RAW | SOCK_CLOEXEC, NETLINK_ROUTE);
+  }
+
+  // Construct and send the message.
+  struct NetlinkMessage {
+    nlmsghdr hdr;
+    rtgenmsg msg;
+  } request;
+  memset(&request, 0, sizeof(request));
+  request.hdr.nlmsg_flags = NLM_F_DUMP | NLM_F_REQUEST;
+  request.hdr.nlmsg_type = type;
+  request.hdr.nlmsg_len = sizeof(request);
+  request.msg.rtgen_family = AF_UNSPEC; // All families.
+  return (TEMP_FAILURE_RETRY(send(fd_, &request, sizeof(request), 0)) == sizeof(request));
+}
+
+bool NetlinkConnection::ReadResponses(void callback(void*, nlmsghdr*), void* context) {
+  // Read through all the responses, handing interesting ones to the callback.
+  ssize_t bytes_read;
+  while ((bytes_read = TEMP_FAILURE_RETRY(recv(fd_, data_, size_, 0))) > 0) {
+    nlmsghdr* hdr = reinterpret_cast<nlmsghdr*>(data_);
+    for (; NLMSG_OK(hdr, static_cast<size_t>(bytes_read)); hdr = NLMSG_NEXT(hdr, bytes_read)) {
+      if (hdr->nlmsg_type == NLMSG_DONE) return true;
+      if (hdr->nlmsg_type == NLMSG_ERROR) return false;
+      callback(context, hdr);
+    }
+  }
+
+  // We only get here if recv fails before we see a NLMSG_DONE.
+  return false;
+}
diff --git a/libc/include/machine/timespec.h b/libc/bionic/bionic_netlink.h
similarity index 68%
copy from libc/include/machine/timespec.h
copy to libc/bionic/bionic_netlink.h
index 11779ae..4b103f3 100644
--- a/libc/include/machine/timespec.h
+++ b/libc/bionic/bionic_netlink.h
@@ -1,5 +1,5 @@
 /*
- * Copyright (C) 2014 The Android Open Source Project
+ * Copyright (C) 2016 The Android Open Source Project
  * All rights reserved.
  *
  * Redistribution and use in source and binary forms, with or without
@@ -26,21 +26,34 @@
  * SUCH DAMAGE.
  */
 
-#ifndef _MACHINE_TIMESPEC_H_
-#define _MACHINE_TIMESPEC_H_
+#ifndef BIONIC_NETLINK_H
+#define BIONIC_NETLINK_H
 
 #include <sys/types.h>
 
-/*
- * This file is used to include timespec definition without introducing the whole
- * <linux/time.h>, <sys/time.h> or <time.h>.
- */
-#ifndef _STRUCT_TIMESPEC
-#define _STRUCT_TIMESPEC
-struct timespec {
-  time_t tv_sec;
-  long tv_nsec;
+#include <linux/netlink.h>
+#include <linux/rtnetlink.h>
+
+struct nlmsghdr;
+
+class NetlinkConnection {
+ public:
+  NetlinkConnection();
+  ~NetlinkConnection();
+
+  bool SendRequest(int type);
+  bool ReadResponses(void callback(void*, nlmsghdr*), void* context);
+
+ private:
+  int fd_;
+  char* data_;
+  size_t size_;
 };
+
+#if !defined(__clang__)
+// GCC gets confused by NLMSG_DATA and doesn't realize that the old-style
+// cast is from a system header and should be ignored.
+#pragma GCC diagnostic ignored "-Wold-style-cast"
 #endif
 
-#endif /* _MACHINE_TIMESPEC_H_ */
+#endif
diff --git a/libc/bionic/bionic_systrace.cpp b/libc/bionic/bionic_systrace.cpp
index 103aa8f..b522b10 100644
--- a/libc/bionic/bionic_systrace.cpp
+++ b/libc/bionic/bionic_systrace.cpp
@@ -34,27 +34,25 @@
 
 static Lock g_lock;
 static const prop_info* g_pinfo;
-static uint32_t g_serial = -1;
+static uint32_t g_property_serial = -1;
+static uint32_t g_property_area_serial = -1;
 static uint64_t g_tags;
 static int g_trace_marker_fd = -1;
 
 static bool should_trace() {
   bool result = false;
   g_lock.lock();
-  // If g_pinfo is null, this means that systrace hasn't been run and it's safe to
-  // assume that no trace writing will need to take place.  However, to avoid running
-  // this costly find check each time, we set it to a non-tracing value so that next
-  // time, it will just check the serial to see if the value has been changed.
-  // this function also deals with the bootup case, during which the call to property
-  // set will fail if the property server hasn't yet started.
-  if (g_pinfo == NULL) {
+  // debug.atrace.tags.enableflags is set to a safe non-tracing value during property
+  // space initialization, so it should only be null in two cases, if there are
+  // insufficient permissions for this process to access the property, in which
+  // case an audit will be logged, and during boot before the property server has
+  // been started, in which case we store the global property_area serial to prevent
+  // the costly find operation until we see a changed property_area.
+  if (!g_pinfo && g_property_area_serial != __system_property_area_serial()) {
+    g_property_area_serial = __system_property_area_serial();
     g_pinfo = __system_property_find(SYSTRACE_PROPERTY_NAME);
-    if (g_pinfo == NULL) {
-      __system_property_set(SYSTRACE_PROPERTY_NAME, "0");
-      g_pinfo = __system_property_find(SYSTRACE_PROPERTY_NAME);
-    }
   }
-  if (g_pinfo != NULL) {
+  if (g_pinfo) {
     // Find out which tags have been enabled on the command line and set
     // the value of tags accordingly.  If the value of the property changes,
     // the serial will also change, so the costly system_property_read function
@@ -62,11 +60,11 @@
     // first.  The values within pinfo may change, but its location is guaranteed
     // not to move.
     uint32_t cur_serial = __system_property_serial(g_pinfo);
-    if (cur_serial != g_serial) {
-      g_serial = cur_serial;
+    if (cur_serial != g_property_serial) {
+      g_property_serial = cur_serial;
       char value[PROP_VALUE_MAX];
       __system_property_read(g_pinfo, 0, value);
-      g_tags = strtoull(value, NULL, 0);
+      g_tags = strtoull(value, nullptr, 0);
     }
     result = ((g_tags & ATRACE_TAG_BIONIC) != 0);
   }
diff --git a/libc/bionic/bionic_time_conversions.cpp b/libc/bionic/bionic_time_conversions.cpp
index 75e8d49..f3ca46a 100644
--- a/libc/bionic/bionic_time_conversions.cpp
+++ b/libc/bionic/bionic_time_conversions.cpp
@@ -52,18 +52,12 @@
   tv.tv_usec = ts.tv_nsec / 1000;
 }
 
-// Initializes 'ts' with the difference between 'abs_ts' and the current time
-// according to 'clock'. Returns false if abstime already expired, true otherwise.
-bool timespec_from_absolute_timespec(timespec& ts, const timespec& abs_ts, clockid_t clock) {
-  clock_gettime(clock, &ts);
-  ts.tv_sec = abs_ts.tv_sec - ts.tv_sec;
-  ts.tv_nsec = abs_ts.tv_nsec - ts.tv_nsec;
-  if (ts.tv_nsec < 0) {
-    ts.tv_sec--;
-    ts.tv_nsec += NS_PER_S;
+void absolute_timespec_from_timespec(timespec& abs_ts, const timespec& ts, clockid_t clock) {
+  clock_gettime(clock, &abs_ts);
+  abs_ts.tv_sec += ts.tv_sec;
+  abs_ts.tv_nsec += ts.tv_nsec;
+  if (abs_ts.tv_nsec >= NS_PER_S) {
+    abs_ts.tv_nsec -= NS_PER_S;
+    abs_ts.tv_sec++;
   }
-  if (ts.tv_nsec < 0 || ts.tv_sec < 0) {
-    return false;
-  }
-  return true;
 }
diff --git a/libc/bionic/debug_mapinfo.cpp b/libc/bionic/debug_mapinfo.cpp
deleted file mode 100644
index de72cb2..0000000
--- a/libc/bionic/debug_mapinfo.cpp
+++ /dev/null
@@ -1,172 +0,0 @@
-/*
- * Copyright (C) 2012 The Android Open Source Project
- * All rights reserved.
- *
- * Redistribution and use in source and binary forms, with or without
- * modification, are permitted provided that the following conditions
- * are met:
- *  * Redistributions of source code must retain the above copyright
- *    notice, this list of conditions and the following disclaimer.
- *  * Redistributions in binary form must reproduce the above copyright
- *    notice, this list of conditions and the following disclaimer in
- *    the documentation and/or other materials provided with the
- *    distribution.
- *
- * THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS
- * "AS IS" AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT
- * LIMITED TO, THE IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS
- * FOR A PARTICULAR PURPOSE ARE DISCLAIMED. IN NO EVENT SHALL THE
- * COPYRIGHT OWNER OR CONTRIBUTORS BE LIABLE FOR ANY DIRECT, INDIRECT,
- * INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING,
- * BUT NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; LOSS
- * OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED
- * AND ON ANY THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY,
- * OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT
- * OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF
- * SUCH DAMAGE.
- */
-
-#include <ctype.h>
-#include <elf.h>
-#include <inttypes.h>
-#include <stdio.h>
-#include <string.h>
-#include <stdlib.h>
-
-#include "debug_mapinfo.h"
-#include "malloc_debug_disable.h"
-
-#if defined(__LP64__)
-#define Elf_W(x) Elf64_##x
-#else
-#define Elf_W(x) Elf32_##x
-#endif
-
-// Format of /proc/<PID>/maps:
-//   6f000000-6f01e000 rwxp 00000000 00:0c 16389419   /system/lib/libcomposer.so
-static mapinfo_t* parse_maps_line(char* line) {
-  uintptr_t start;
-  uintptr_t end;
-  uintptr_t offset;
-  char permissions[4];
-  int name_pos;
-  if (sscanf(line, "%" PRIxPTR "-%" PRIxPTR " %4s %" PRIxPTR " %*x:%*x %*d%n", &start,
-             &end, permissions, &offset, &name_pos) < 2) {
-    return NULL;
-  }
-
-  while (isspace(line[name_pos])) {
-    name_pos += 1;
-  }
-  const char* name = line + name_pos;
-  size_t name_len = strlen(name);
-  if (name_len && name[name_len - 1] == '\n') {
-    name_len -= 1;
-  }
-
-  mapinfo_t* mi = reinterpret_cast<mapinfo_t*>(calloc(1, sizeof(mapinfo_t) + name_len + 1));
-  if (mi) {
-    mi->start = start;
-    mi->end = end;
-    mi->offset = offset;
-    if (permissions[0] != 'r') {
-      // Any unreadable map will just get a zero load base.
-      mi->load_base = 0;
-      mi->load_base_read = true;
-    } else {
-      mi->load_base_read = false;
-    }
-    memcpy(mi->name, name, name_len);
-    mi->name[name_len] = '\0';
-  }
-  return mi;
-}
-
-__LIBC_HIDDEN__ mapinfo_t* mapinfo_create(pid_t pid) {
-  ScopedDisableDebugCalls disable;
-
-  struct mapinfo_t* milist = NULL;
-  char data[1024]; // Used to read lines as well as to construct the filename.
-  snprintf(data, sizeof(data), "/proc/%d/maps", pid);
-  FILE* fp = fopen(data, "re");
-  if (fp != NULL) {
-    while (fgets(data, sizeof(data), fp) != NULL) {
-      mapinfo_t* mi = parse_maps_line(data);
-      if (mi) {
-        mi->next = milist;
-        milist = mi;
-      }
-    }
-    fclose(fp);
-  }
-  return milist;
-}
-
-__LIBC_HIDDEN__ void mapinfo_destroy(mapinfo_t* mi) {
-  ScopedDisableDebugCalls disable;
-
-  while (mi != NULL) {
-    mapinfo_t* del = mi;
-    mi = mi->next;
-    free(del);
-  }
-}
-
-template<typename T>
-static inline bool get_val(mapinfo_t* mi, uintptr_t addr, T* store) {
-  if (addr < mi->start || addr + sizeof(T) > mi->end) {
-    return false;
-  }
-  // Make sure the address is aligned properly.
-  if (addr & (sizeof(T)-1)) {
-    return false;
-  }
-  *store = *reinterpret_cast<T*>(addr);
-  return true;
-}
-
-__LIBC_HIDDEN__ void mapinfo_read_loadbase(mapinfo_t* mi) {
-  mi->load_base = 0;
-  mi->load_base_read = true;
-  uintptr_t addr = mi->start;
-  Elf_W(Ehdr) ehdr;
-  if (!get_val<Elf_W(Half)>(mi, addr + offsetof(Elf_W(Ehdr), e_phnum), &ehdr.e_phnum)) {
-    return;
-  }
-  if (!get_val<Elf_W(Off)>(mi, addr + offsetof(Elf_W(Ehdr), e_phoff), &ehdr.e_phoff)) {
-    return;
-  }
-  addr += ehdr.e_phoff;
-  for (size_t i = 0; i < ehdr.e_phnum; i++) {
-    Elf_W(Phdr) phdr;
-    if (!get_val<Elf_W(Word)>(mi, addr + offsetof(Elf_W(Phdr), p_type), &phdr.p_type)) {
-      return;
-    }
-    if (!get_val<Elf_W(Off)>(mi, addr + offsetof(Elf_W(Phdr), p_offset), &phdr.p_offset)) {
-      return;
-    }
-    if (phdr.p_type == PT_LOAD && phdr.p_offset == mi->offset) {
-      if (!get_val<Elf_W(Addr)>(mi, addr + offsetof(Elf_W(Phdr), p_vaddr), &phdr.p_vaddr)) {
-        return;
-      }
-      mi->load_base = phdr.p_vaddr;
-      return;
-    }
-    addr += sizeof(phdr);
-  }
-}
-
-// Find the containing map info for the PC.
-__LIBC_HIDDEN__ const mapinfo_t* mapinfo_find(mapinfo_t* mi, uintptr_t pc, uintptr_t* rel_pc) {
-  for (; mi != NULL; mi = mi->next) {
-    if ((pc >= mi->start) && (pc < mi->end)) {
-      if (!mi->load_base_read) {
-        mapinfo_read_loadbase(mi);
-      }
-      *rel_pc = pc - mi->start + mi->load_base;
-      return mi;
-    }
-  }
-  *rel_pc = pc;
-  return NULL;
-}
diff --git a/libc/bionic/debug_stacktrace.cpp b/libc/bionic/debug_stacktrace.cpp
deleted file mode 100644
index 71e876b..0000000
--- a/libc/bionic/debug_stacktrace.cpp
+++ /dev/null
@@ -1,161 +0,0 @@
-/*
- * Copyright (C) 2012 The Android Open Source Project
- * All rights reserved.
- *
- * Redistribution and use in source and binary forms, with or without
- * modification, are permitted provided that the following conditions
- * are met:
- *  * Redistributions of source code must retain the above copyright
- *    notice, this list of conditions and the following disclaimer.
- *  * Redistributions in binary form must reproduce the above copyright
- *    notice, this list of conditions and the following disclaimer in
- *    the documentation and/or other materials provided with the
- *    distribution.
- *
- * THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS
- * "AS IS" AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT
- * LIMITED TO, THE IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS
- * FOR A PARTICULAR PURPOSE ARE DISCLAIMED. IN NO EVENT SHALL THE
- * COPYRIGHT OWNER OR CONTRIBUTORS BE LIABLE FOR ANY DIRECT, INDIRECT,
- * INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING,
- * BUT NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; LOSS
- * OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED
- * AND ON ANY THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY,
- * OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT
- * OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF
- * SUCH DAMAGE.
- */
-
-#include "debug_stacktrace.h"
-
-#include <dlfcn.h>
-#include <inttypes.h>
-#include <malloc.h>
-#include <unistd.h>
-#include <unwind.h>
-#include <sys/types.h>
-
-#include "debug_mapinfo.h"
-#include "malloc_debug_disable.h"
-#include "private/libc_logging.h"
-
-#if defined(__LP64__)
-#define PAD_PTR "016" PRIxPTR
-#else
-#define PAD_PTR "08" PRIxPTR
-#endif
-
-typedef struct _Unwind_Context __unwind_context;
-
-extern "C" char* __cxa_demangle(const char*, char*, size_t*, int*);
-
-static mapinfo_t* g_map_info = NULL;
-
-__LIBC_HIDDEN__ void backtrace_startup() {
-  ScopedDisableDebugCalls disable;
-
-  g_map_info = mapinfo_create(getpid());
-}
-
-__LIBC_HIDDEN__ void backtrace_shutdown() {
-  ScopedDisableDebugCalls disable;
-
-  mapinfo_destroy(g_map_info);
-}
-
-struct stack_crawl_state_t {
-  uintptr_t* frames;
-  size_t frame_count;
-  size_t max_depth;
-  bool have_skipped_self;
-
-  stack_crawl_state_t(uintptr_t* frames, size_t max_depth)
-      : frames(frames), frame_count(0), max_depth(max_depth), have_skipped_self(false) {
-  }
-};
-
-static _Unwind_Reason_Code trace_function(__unwind_context* context, void* arg) {
-  stack_crawl_state_t* state = static_cast<stack_crawl_state_t*>(arg);
-
-  uintptr_t ip = _Unwind_GetIP(context);
-
-  // The first stack frame is get_backtrace itself. Skip it.
-  if (ip != 0 && !state->have_skipped_self) {
-    state->have_skipped_self = true;
-    return _URC_NO_REASON;
-  }
-
-#if defined(__arm__)
-  /*
-   * The instruction pointer is pointing at the instruction after the bl(x), and
-   * the _Unwind_Backtrace routine already masks the Thumb mode indicator (LSB
-   * in PC). So we need to do a quick check here to find out if the previous
-   * instruction is a Thumb-mode BLX(2). If so subtract 2 otherwise 4 from PC.
-   */
-  if (ip != 0) {
-    short* ptr = reinterpret_cast<short*>(ip);
-    // Thumb BLX(2)
-    if ((*(ptr-1) & 0xff80) == 0x4780) {
-      ip -= 2;
-    } else {
-      ip -= 4;
-    }
-  }
-#endif
-
-  state->frames[state->frame_count++] = ip;
-  return (state->frame_count >= state->max_depth) ? _URC_END_OF_STACK : _URC_NO_REASON;
-}
-
-__LIBC_HIDDEN__ int get_backtrace(uintptr_t* frames, size_t max_depth) {
-  ScopedDisableDebugCalls disable;
-
-  stack_crawl_state_t state(frames, max_depth);
-  _Unwind_Backtrace(trace_function, &state);
-  return state.frame_count;
-}
-
-__LIBC_HIDDEN__ void log_backtrace(uintptr_t* frames, size_t frame_count) {
-  ScopedDisableDebugCalls disable;
-
-  uintptr_t self_bt[16];
-  if (frames == NULL) {
-    frame_count = get_backtrace(self_bt, 16);
-    frames = self_bt;
-  }
-
-  __libc_format_log(ANDROID_LOG_ERROR, "libc",
-                    "*** *** *** *** *** *** *** *** *** *** *** *** *** *** *** ***\n");
-
-  for (size_t i = 0 ; i < frame_count; ++i) {
-    uintptr_t offset = 0;
-    const char* symbol = NULL;
-
-    Dl_info info;
-    if (dladdr((void*) frames[i], &info) != 0) {
-      offset = reinterpret_cast<uintptr_t>(info.dli_saddr);
-      symbol = info.dli_sname;
-    }
-
-    uintptr_t rel_pc = offset;
-    const mapinfo_t* mi = (g_map_info != NULL) ? mapinfo_find(g_map_info, frames[i], &rel_pc) : NULL;
-    const char* soname = (mi != NULL) ? mi->name : info.dli_fname;
-    if (soname == NULL) {
-      soname = "<unknown>";
-    }
-    if (symbol != NULL) {
-      char* demangled_symbol = __cxa_demangle(symbol, NULL, NULL, NULL);
-      const char* best_name = (demangled_symbol != NULL) ? demangled_symbol : symbol;
-
-      __libc_format_log(ANDROID_LOG_ERROR, "libc",
-                        "          #%02zd  pc %" PAD_PTR "  %s (%s+%" PRIuPTR ")",
-                        i, rel_pc, soname, best_name, frames[i] - offset);
-
-      free(demangled_symbol);
-    } else {
-      __libc_format_log(ANDROID_LOG_ERROR, "libc",
-                        "          #%02zd  pc %" PAD_PTR "  %s",
-                        i, rel_pc, soname);
-    }
-  }
-}
diff --git a/libc/bionic/dlmalloc.c b/libc/bionic/dlmalloc.c
deleted file mode 100644
index 5853e7c..0000000
--- a/libc/bionic/dlmalloc.c
+++ /dev/null
@@ -1,79 +0,0 @@
-/*
- * Copyright (C) 2012 The Android Open Source Project
- *
- * Licensed under the Apache License, Version 2.0 (the "License");
- * you may not use this file except in compliance with the License.
- * You may obtain a copy of the License at
- *
- *      http://www.apache.org/licenses/LICENSE-2.0
- *
- * Unless required by applicable law or agreed to in writing, software
- * distributed under the License is distributed on an "AS IS" BASIS,
- * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
- * See the License for the specific language governing permissions and
- * limitations under the License.
- */
-
-#include "dlmalloc.h"
-
-#include "malloc.h"
-#include "private/bionic_prctl.h"
-#include "private/libc_logging.h"
-
-// Send dlmalloc errors to the log.
-static void __bionic_heap_corruption_error(const char* function);
-static void __bionic_heap_usage_error(const char* function, void* address);
-#define PROCEED_ON_ERROR 0
-#define CORRUPTION_ERROR_ACTION(m) __bionic_heap_corruption_error(__FUNCTION__)
-#define USAGE_ERROR_ACTION(m,p) __bionic_heap_usage_error(__FUNCTION__, p)
-
-// Bionic named anonymous memory declarations.
-static void* named_anonymous_mmap(size_t length);
-#define MMAP(s) named_anonymous_mmap(s)
-#define DIRECT_MMAP(s) named_anonymous_mmap(s)
-
-// Ugly inclusion of C file so that bionic specific #defines configure dlmalloc.
-#include "../upstream-dlmalloc/malloc.c"
-
-static void __bionic_heap_corruption_error(const char* function) {
-  __libc_fatal("heap corruption detected by %s", function);
-}
-
-static void __bionic_heap_usage_error(const char* function, void* address) {
-  __libc_fatal_no_abort("invalid address or address of corrupt block %p passed to %s",
-               address, function);
-  // So that debuggerd gives us a memory dump around the specific address.
-  // TODO: improve the debuggerd protocol so we can tell it to dump an address when we abort.
-  *((int**) 0xdeadbaad) = (int*) address;
-}
-
-static void* named_anonymous_mmap(size_t length) {
-  void* map = mmap(NULL, length, PROT_READ|PROT_WRITE, MAP_PRIVATE|MAP_ANONYMOUS, -1, 0);
-  if (map == MAP_FAILED) {
-    return map;
-  }
-  prctl(PR_SET_VMA, PR_SET_VMA_ANON_NAME, map, length, "libc_malloc");
-  return map;
-}
-
-// Since dlmalloc isn't the default, we'll leave this unimplemented for now. If
-// we decide we need it later, we can fill it in.
-size_t __mallinfo_narenas() {
-  return 0;
-}
-
-size_t __mallinfo_nbins() {
-  return 0;
-}
-
-struct mallinfo __mallinfo_arena_info(size_t aidx __unused) {
-  struct mallinfo mi;
-  memset(&mi, 0, sizeof(mi));
-  return mi;
-}
-
-struct mallinfo __mallinfo_bin_info(size_t aidx __unused, size_t bidx __unused) {
-  struct mallinfo mi;
-  memset(&mi, 0, sizeof(mi));
-  return mi;
-}
diff --git a/libc/bionic/dlmalloc.h b/libc/bionic/dlmalloc.h
deleted file mode 100644
index 054bd4f..0000000
--- a/libc/bionic/dlmalloc.h
+++ /dev/null
@@ -1,58 +0,0 @@
-/*
- * Copyright (C) 2012 The Android Open Source Project
- *
- * Licensed under the Apache License, Version 2.0 (the "License");
- * you may not use this file except in compliance with the License.
- * You may obtain a copy of the License at
- *
- *      http://www.apache.org/licenses/LICENSE-2.0
- *
- * Unless required by applicable law or agreed to in writing, software
- * distributed under the License is distributed on an "AS IS" BASIS,
- * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
- * See the License for the specific language governing permissions and
- * limitations under the License.
- */
-
-#ifndef LIBC_BIONIC_DLMALLOC_H_
-#define LIBC_BIONIC_DLMALLOC_H_
-
-#include <sys/cdefs.h>
-#include <stddef.h>
-
-/* Configure dlmalloc. */
-#define HAVE_GETPAGESIZE 1
-#define MALLOC_INSPECT_ALL 1
-#define MSPACES 0
-#define REALLOC_ZERO_BYTES_FREES 1
-#define USE_DL_PREFIX 1
-#define USE_LOCKS 1
-#define LOCK_AT_FORK 1
-#define USE_RECURSIVE_LOCK 0
-#define USE_SPIN_LOCKS 0
-#define DEFAULT_MMAP_THRESHOLD (64U * 1024U)
-
-#define malloc_getpagesize getpagesize()
-
-#if !defined(__LP64__)
-/* dlmalloc_usable_size and dlmalloc were exposed in the NDK and some
- * apps actually used them. Rename these functions out of the way
- * for 32 bit architectures so that ndk_cruft.cpp can expose
- * compatibility shims with these names.
- */
-#define dlmalloc_usable_size dlmalloc_usable_size_real
-#define dlmalloc dlmalloc_real
-#endif
-
-/* These two symbols are exported on devices that use dlmalloc.
- * In order to be consistent across all devices, they will
- * be exported everywhere. Move the real symbols out of the way
- * so that ndk_cruft.cpp can export these symbols.
- */
-#define dlmalloc_inspect_all dlmalloc_inspect_all_real
-#define dlmalloc_trim dlmalloc_trim_real
-
-/* Include the proper definitions. */
-#include "../upstream-dlmalloc/malloc.h"
-
-#endif  // LIBC_BIONIC_DLMALLOC_H_
diff --git a/libc/include/machine/timespec.h b/libc/bionic/flistxattr.cpp
similarity index 61%
copy from libc/include/machine/timespec.h
copy to libc/bionic/flistxattr.cpp
index 11779ae..05a96d2 100644
--- a/libc/include/machine/timespec.h
+++ b/libc/bionic/flistxattr.cpp
@@ -1,5 +1,5 @@
 /*
- * Copyright (C) 2014 The Android Open Source Project
+ * Copyright (C) 2015 The Android Open Source Project
  * All rights reserved.
  *
  * Redistribution and use in source and binary forms, with or without
@@ -26,21 +26,34 @@
  * SUCH DAMAGE.
  */
 
-#ifndef _MACHINE_TIMESPEC_H_
-#define _MACHINE_TIMESPEC_H_
-
+#include <sys/stat.h>
 #include <sys/types.h>
+#include <sys/xattr.h>
+#include <errno.h>
+#include <fcntl.h>
+#include <stdio.h>
 
-/*
- * This file is used to include timespec definition without introducing the whole
- * <linux/time.h>, <sys/time.h> or <time.h>.
- */
-#ifndef _STRUCT_TIMESPEC
-#define _STRUCT_TIMESPEC
-struct timespec {
-  time_t tv_sec;
-  long tv_nsec;
-};
-#endif
+extern "C" ssize_t ___flistxattr(int, char*, size_t);
 
-#endif /* _MACHINE_TIMESPEC_H_ */
+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)) {
+    return result;
+  }
+
+  // fd could be an O_PATH file descriptor, and the kernel
+  // 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)) {
+    errno = EBADF;
+    return -1;
+  }
+
+  char buf[40];
+  snprintf(buf, sizeof(buf), "/proc/self/fd/%d", fd);
+  errno = saved_errno;
+  return listxattr(buf, list, size);
+}
diff --git a/libc/bionic/flockfile.cpp b/libc/bionic/flockfile.cpp
index b73907cb..db53828 100644
--- a/libc/bionic/flockfile.cpp
+++ b/libc/bionic/flockfile.cpp
@@ -36,23 +36,15 @@
 // struct __sfileext (see fileext.h).
 
 void flockfile(FILE* fp) {
-  if (!__sdidinit) {
-    __sinit();
-  }
-
-  if (fp != NULL) {
+  if (fp != nullptr) {
     pthread_mutex_lock(&_FLOCK(fp));
   }
 }
 
 int ftrylockfile(FILE* fp) {
-  if (!__sdidinit) {
-    __sinit();
-  }
-
   // The specification for ftrylockfile() says it returns 0 on success,
   // or non-zero on error. So return an errno code directly on error.
-  if (fp == NULL) {
+  if (fp == nullptr) {
     return EINVAL;
   }
 
@@ -60,11 +52,7 @@
 }
 
 void funlockfile(FILE* fp) {
-  if (!__sdidinit) {
-    __sinit();
-  }
-
-  if (fp != NULL) {
+  if (fp != nullptr) {
     pthread_mutex_unlock(&_FLOCK(fp));
   }
 }
diff --git a/libc/bionic/getcwd.cpp b/libc/bionic/getcwd.cpp
index a8bbcf3..bcd6a57 100644
--- a/libc/bionic/getcwd.cpp
+++ b/libc/bionic/getcwd.cpp
@@ -26,6 +26,7 @@
  * SUCH DAMAGE.
  */
 
+#undef _FORTIFY_SOURCE
 #include <errno.h>
 #include <malloc.h>
 #include <string.h>
diff --git a/libc/bionic/if_nametoindex.c b/libc/bionic/if_nametoindex.c
deleted file mode 100644
index d670e43..0000000
--- a/libc/bionic/if_nametoindex.c
+++ /dev/null
@@ -1,58 +0,0 @@
-/*
- * Copyright (C) 2008 The Android Open Source Project
- * All rights reserved.
- *
- * Redistribution and use in source and binary forms, with or without
- * modification, are permitted provided that the following conditions
- * are met:
- *  * Redistributions of source code must retain the above copyright
- *    notice, this list of conditions and the following disclaimer.
- *  * Redistributions in binary form must reproduce the above copyright
- *    notice, this list of conditions and the following disclaimer in
- *    the documentation and/or other materials provided with the
- *    distribution.
- *
- * THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS
- * "AS IS" AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT
- * LIMITED TO, THE IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS
- * FOR A PARTICULAR PURPOSE ARE DISCLAIMED. IN NO EVENT SHALL THE
- * COPYRIGHT OWNER OR CONTRIBUTORS BE LIABLE FOR ANY DIRECT, INDIRECT,
- * INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING,
- * BUT NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; LOSS
- * OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED
- * AND ON ANY THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY,
- * OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT
- * OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF
- * SUCH DAMAGE.
- */
-
-#include <string.h>
-#include <unistd.h>
-#include <linux/sockios.h>
-#include <net/if.h>
-#include <sys/socket.h>
-#include <sys/ioctl.h>
-
-/*
- * Map an interface name into its corresponding index.
- * Returns 0 on error, as 0 is not a valid index.
- */
-unsigned int if_nametoindex(const char *ifname)
-{
-    int index;
-    int ctl_sock;
-    struct ifreq ifr;
-
-    memset(&ifr, 0, sizeof(struct ifreq));
-    strncpy(ifr.ifr_name, ifname, IFNAMSIZ);
-    ifr.ifr_name[IFNAMSIZ - 1] = 0;
-
-    index = 0;
-    if ((ctl_sock = socket(AF_INET, SOCK_DGRAM, 0)) >= 0) {
-        if (ioctl(ctl_sock, SIOCGIFINDEX, &ifr) >= 0) {
-            index = ifr.ifr_ifindex;
-        }
-        close(ctl_sock);
-    }
-    return index;
-}
diff --git a/libc/bionic/ifaddrs.cpp b/libc/bionic/ifaddrs.cpp
new file mode 100644
index 0000000..408949c
--- /dev/null
+++ b/libc/bionic/ifaddrs.cpp
@@ -0,0 +1,260 @@
+/*
+ * Copyright (C) 2015 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 <ifaddrs.h>
+
+#include <errno.h>
+#include <linux/if_packet.h>
+#include <net/if.h>
+#include <netinet/in.h>
+#include <stdint.h>
+#include <stdio.h>
+#include <stdlib.h>
+#include <string.h>
+#include <unistd.h>
+
+#include "private/ErrnoRestorer.h"
+
+#include "bionic_netlink.h"
+
+// The public ifaddrs struct is full of pointers. Rather than track several
+// different allocations, we use a maximally-sized structure with the public
+// part at offset 0, and pointers into its hidden tail.
+struct ifaddrs_storage {
+  // Must come first, so that `ifaddrs_storage` is-a `ifaddrs`.
+  ifaddrs ifa;
+
+  // The interface index, so we can match RTM_NEWADDR messages with
+  // earlier RTM_NEWLINK messages (to copy the interface flags).
+  int interface_index;
+
+  // Storage for the pointers in `ifa`.
+  sockaddr_storage addr;
+  sockaddr_storage netmask;
+  sockaddr_storage ifa_ifu;
+  char name[IFNAMSIZ + 1];
+
+  ifaddrs_storage(ifaddrs** list) {
+    memset(this, 0, sizeof(*this));
+
+    // push_front onto `list`.
+    ifa.ifa_next = *list;
+    *list = reinterpret_cast<ifaddrs*>(this);
+  }
+
+  void SetAddress(int family, const void* data, size_t byteCount) {
+    // The kernel currently uses the order IFA_ADDRESS, IFA_LOCAL, IFA_BROADCAST
+    // in inet_fill_ifaddr, but let's not assume that will always be true...
+    if (ifa.ifa_addr == nullptr) {
+      // This is an IFA_ADDRESS and haven't seen an IFA_LOCAL yet, so assume this is the
+      // local address. SetLocalAddress will fix things if we later see an IFA_LOCAL.
+      ifa.ifa_addr = CopyAddress(family, data, byteCount, &addr);
+    } else {
+      // We already saw an IFA_LOCAL, which implies this is a destination address.
+      ifa.ifa_dstaddr = CopyAddress(family, data, byteCount, &ifa_ifu);
+    }
+  }
+
+  void SetBroadcastAddress(int family, const void* data, size_t byteCount) {
+    // ifa_broadaddr and ifa_dstaddr overlap in a union. Unfortunately, it's possible
+    // to have an interface with both. Keeping the last thing the kernel gives us seems
+    // to be glibc 2.19's behavior too, so our choice is being source compatible with
+    // badly-written code that assumes ifa_broadaddr and ifa_dstaddr are interchangeable
+    // or supporting interfaces with both addresses configured. My assumption is that
+    // bad code is more common than weird network interfaces...
+    ifa.ifa_broadaddr = CopyAddress(family, data, byteCount, &ifa_ifu);
+  }
+
+  void SetLocalAddress(int family, const void* data, size_t byteCount) {
+    // The kernel source says "for point-to-point IFA_ADDRESS is DESTINATION address,
+    // local address is supplied in IFA_LOCAL attribute".
+    //   -- http://lxr.free-electrons.com/source/include/uapi/linux/if_addr.h#L17
+
+    // So copy any existing IFA_ADDRESS into ifa_dstaddr...
+    if (ifa.ifa_addr != nullptr) {
+      ifa.ifa_dstaddr = reinterpret_cast<sockaddr*>(memcpy(&ifa_ifu, &addr, sizeof(addr)));
+    }
+    // ...and then put this IFA_LOCAL into ifa_addr.
+    ifa.ifa_addr = CopyAddress(family, data, byteCount, &addr);
+  }
+
+  // Netlink gives us the prefix length as a bit count. We need to turn
+  // that into a BSD-compatible netmask represented by a sockaddr*.
+  void SetNetmask(int family, size_t prefix_length) {
+    // ...and work out the netmask from the prefix length.
+    netmask.ss_family = family;
+    uint8_t* dst = SockaddrBytes(family, &netmask);
+    memset(dst, 0xff, prefix_length / 8);
+    if ((prefix_length % 8) != 0) {
+      dst[prefix_length/8] = (0xff << (8 - (prefix_length % 8)));
+    }
+    ifa.ifa_netmask = reinterpret_cast<sockaddr*>(&netmask);
+  }
+
+  void SetPacketAttributes(int ifindex, unsigned short hatype, unsigned char halen) {
+    sockaddr_ll* sll = reinterpret_cast<sockaddr_ll*>(&addr);
+    sll->sll_ifindex = ifindex;
+    sll->sll_hatype = hatype;
+    sll->sll_halen = halen;
+  }
+
+ private:
+  sockaddr* CopyAddress(int family, const void* data, size_t byteCount, sockaddr_storage* ss) {
+    // Netlink gives us the address family in the header, and the
+    // sockaddr_in or sockaddr_in6 bytes as the payload. We need to
+    // stitch the two bits together into the sockaddr that's part of
+    // our portable interface.
+    ss->ss_family = family;
+    memcpy(SockaddrBytes(family, ss), data, byteCount);
+
+    // For IPv6 we might also have to set the scope id.
+    if (family == AF_INET6 && (IN6_IS_ADDR_LINKLOCAL(data) || IN6_IS_ADDR_MC_LINKLOCAL(data))) {
+      reinterpret_cast<sockaddr_in6*>(ss)->sin6_scope_id = interface_index;
+    }
+
+    return reinterpret_cast<sockaddr*>(ss);
+  }
+
+  // Returns a pointer to the first byte in the address data (which is
+  // stored in network byte order).
+  uint8_t* SockaddrBytes(int family, sockaddr_storage* ss) {
+    if (family == AF_INET) {
+      sockaddr_in* ss4 = reinterpret_cast<sockaddr_in*>(ss);
+      return reinterpret_cast<uint8_t*>(&ss4->sin_addr);
+    } else if (family == AF_INET6) {
+      sockaddr_in6* ss6 = reinterpret_cast<sockaddr_in6*>(ss);
+      return reinterpret_cast<uint8_t*>(&ss6->sin6_addr);
+    } else if (family == AF_PACKET) {
+      sockaddr_ll* sll = reinterpret_cast<sockaddr_ll*>(ss);
+      return reinterpret_cast<uint8_t*>(&sll->sll_addr);
+    }
+    return nullptr;
+  }
+};
+
+static void __getifaddrs_callback(void* context, nlmsghdr* hdr) {
+  ifaddrs** out = reinterpret_cast<ifaddrs**>(context);
+
+  if (hdr->nlmsg_type == RTM_NEWLINK) {
+    ifinfomsg* ifi = reinterpret_cast<ifinfomsg*>(NLMSG_DATA(hdr));
+
+    // Create a new ifaddr entry, and set the interface index and flags.
+    ifaddrs_storage* new_addr = new ifaddrs_storage(out);
+    new_addr->interface_index = ifi->ifi_index;
+    new_addr->ifa.ifa_flags = ifi->ifi_flags;
+
+    // Go through the various bits of information and find the name.
+    rtattr* rta = IFLA_RTA(ifi);
+    size_t rta_len = IFLA_PAYLOAD(hdr);
+    while (RTA_OK(rta, rta_len)) {
+      if (rta->rta_type == IFLA_ADDRESS) {
+          if (RTA_PAYLOAD(rta) < sizeof(new_addr->addr)) {
+            new_addr->SetAddress(AF_PACKET, RTA_DATA(rta), RTA_PAYLOAD(rta));
+            new_addr->SetPacketAttributes(ifi->ifi_index, ifi->ifi_type, RTA_PAYLOAD(rta));
+          }
+      } else if (rta->rta_type == IFLA_BROADCAST) {
+          if (RTA_PAYLOAD(rta) < sizeof(new_addr->ifa_ifu)) {
+            new_addr->SetBroadcastAddress(AF_PACKET, RTA_DATA(rta), RTA_PAYLOAD(rta));
+            new_addr->SetPacketAttributes(ifi->ifi_index, ifi->ifi_type, RTA_PAYLOAD(rta));
+          }
+      } else if (rta->rta_type == IFLA_IFNAME) {
+          if (RTA_PAYLOAD(rta) < sizeof(new_addr->name)) {
+            memcpy(new_addr->name, RTA_DATA(rta), RTA_PAYLOAD(rta));
+            new_addr->ifa.ifa_name = new_addr->name;
+          }
+      }
+      rta = RTA_NEXT(rta, rta_len);
+    }
+  } else if (hdr->nlmsg_type == RTM_NEWADDR) {
+    ifaddrmsg* msg = reinterpret_cast<ifaddrmsg*>(NLMSG_DATA(hdr));
+
+    // We should already know about this from an RTM_NEWLINK message.
+    const ifaddrs_storage* addr = reinterpret_cast<const ifaddrs_storage*>(*out);
+    while (addr != nullptr && addr->interface_index != static_cast<int>(msg->ifa_index)) {
+      addr = reinterpret_cast<const ifaddrs_storage*>(addr->ifa.ifa_next);
+    }
+    // If this is an unknown interface, ignore whatever we're being told about it.
+    if (addr == nullptr) return;
+
+    // Create a new ifaddr entry and copy what we already know.
+    ifaddrs_storage* new_addr = new ifaddrs_storage(out);
+    // We can just copy the name rather than look for IFA_LABEL.
+    strcpy(new_addr->name, addr->name);
+    new_addr->ifa.ifa_name = new_addr->name;
+    new_addr->ifa.ifa_flags = addr->ifa.ifa_flags;
+    new_addr->interface_index = addr->interface_index;
+
+    // Go through the various bits of information and find the address
+    // and any broadcast/destination address.
+    rtattr* rta = IFA_RTA(msg);
+    size_t rta_len = IFA_PAYLOAD(hdr);
+    while (RTA_OK(rta, rta_len)) {
+      if (rta->rta_type == IFA_ADDRESS) {
+        if (msg->ifa_family == AF_INET || msg->ifa_family == AF_INET6) {
+          new_addr->SetAddress(msg->ifa_family, RTA_DATA(rta), RTA_PAYLOAD(rta));
+          new_addr->SetNetmask(msg->ifa_family, msg->ifa_prefixlen);
+        }
+      } else if (rta->rta_type == IFA_BROADCAST) {
+        if (msg->ifa_family == AF_INET) {
+          new_addr->SetBroadcastAddress(msg->ifa_family, RTA_DATA(rta), RTA_PAYLOAD(rta));
+        }
+      } else if (rta->rta_type == IFA_LOCAL) {
+        if (msg->ifa_family == AF_INET || msg->ifa_family == AF_INET6) {
+          new_addr->SetLocalAddress(msg->ifa_family, RTA_DATA(rta), RTA_PAYLOAD(rta));
+        }
+      }
+      rta = RTA_NEXT(rta, rta_len);
+    }
+  }
+}
+
+int getifaddrs(ifaddrs** out) {
+  // We construct the result directly into `out`, so terminate the list.
+  *out = nullptr;
+
+  // Open the netlink socket and ask for all the links and addresses.
+  NetlinkConnection nc;
+  bool okay = nc.SendRequest(RTM_GETLINK) && nc.ReadResponses(__getifaddrs_callback, out) &&
+              nc.SendRequest(RTM_GETADDR) && nc.ReadResponses(__getifaddrs_callback, out);
+  if (!okay) {
+    freeifaddrs(*out);
+    // Ensure that callers crash if they forget to check for success.
+    *out = nullptr;
+    return -1;
+  }
+
+  return 0;
+}
+
+void freeifaddrs(ifaddrs* list) {
+  while (list != nullptr) {
+    ifaddrs* current = list;
+    list = list->ifa_next;
+    free(current);
+  }
+}
diff --git a/libc/bionic/ioctl.c b/libc/bionic/ioctl.cpp
similarity index 85%
rename from libc/bionic/ioctl.c
rename to libc/bionic/ioctl.cpp
index 6dd95d0..db85132 100644
--- a/libc/bionic/ioctl.c
+++ b/libc/bionic/ioctl.cpp
@@ -25,19 +25,16 @@
  * OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF
  * SUCH DAMAGE.
  */
+
+#include <sys/ioctl.h>
 #include <stdarg.h>
 
-extern int __ioctl(int, int, void *);
+extern "C" int __ioctl(int, int, void *);
 
-int ioctl(int fd, int request, ...)
-{
-    va_list ap;
-    void * arg;
-
-    va_start(ap, request);
-    arg = va_arg(ap, void *);
-    va_end(ap);
-
-    return __ioctl(fd, request, arg);
+int ioctl(int fd, int request, ...) {
+  va_list ap;
+  va_start(ap, request);
+  void* arg = va_arg(ap, void*);
+  va_end(ap);
+  return __ioctl(fd, request, arg);
 }
-
diff --git a/libc/bionic/jemalloc.h b/libc/bionic/jemalloc.h
index 98ea0ee..fceb323 100644
--- a/libc/bionic/jemalloc.h
+++ b/libc/bionic/jemalloc.h
@@ -26,6 +26,10 @@
 __BEGIN_DECLS
 
 struct mallinfo je_mallinfo();
+int je_iterate(uintptr_t, size_t, void (*)(uintptr_t, size_t, void*), void*);
+void je_malloc_disable();
+void je_malloc_enable();
+int je_mallctl(const char *name, void *oldp, size_t *oldlenp, void *newp, size_t newlen);
 void* je_memalign_round_up_boundary(size_t, size_t);
 void* je_pvalloc(size_t);
 
diff --git a/libc/bionic/legacy_32_bit_support.cpp b/libc/bionic/legacy_32_bit_support.cpp
index a107664..f2bb37d 100644
--- a/libc/bionic/legacy_32_bit_support.cpp
+++ b/libc/bionic/legacy_32_bit_support.cpp
@@ -33,6 +33,7 @@
 #include <stdarg.h>
 #include <sys/resource.h>
 #include <sys/types.h>
+#include <sys/uio.h>
 #include <sys/vfs.h>
 #include <unistd.h>
 
@@ -43,6 +44,8 @@
 // System calls we need.
 extern "C" int __fcntl64(int, int, void*);
 extern "C" int __llseek(int, unsigned long, unsigned long, off64_t*, int);
+extern "C" int __preadv64(int, const struct iovec*, int, long, long);
+extern "C" int __pwritev64(int, const struct iovec*, int, long, long);
 
 // For fcntl we use the fcntl64 system call to signal that we're using struct flock64.
 int fcntl(int fd, int cmd, ...) {
@@ -77,6 +80,23 @@
   return pwrite64(fd, buf, byte_count, static_cast<off64_t>(offset));
 }
 
+// On LP32, there is no off_t preadv/pwritev, and even the 64-bit preadv/pwritev
+// don't use off64_t (see SYSCALLS.TXT for more). Here, this means that we need
+// to implement all four functions because the two system calls don't match any
+// of the userspace functions. Unlike llseek, the pair is split lo-hi, not hi-lo.
+ssize_t preadv(int fd, const struct iovec* ios, int count, off_t offset) {
+  return __preadv64(fd, ios, count, offset, 0);
+}
+ssize_t preadv64(int fd, const struct iovec* ios, int count, off64_t offset) {
+  return __preadv64(fd, ios, count, offset, offset >> 32);
+}
+ssize_t pwritev(int fd, const struct iovec* ios, int count, off_t offset) {
+  return __pwritev64(fd, ios, count, offset, 0);
+}
+ssize_t pwritev64(int fd, const struct iovec* ios, int count, off64_t offset) {
+  return __pwritev64(fd, ios, count, offset, offset >> 32);
+}
+
 // There is no fallocate for 32-bit off_t, so we need to widen and call fallocate64.
 int fallocate(int fd, int mode, off_t offset, off_t length) {
   return fallocate64(fd, mode, static_cast<off64_t>(offset), static_cast<off64_t>(length));
@@ -91,3 +111,22 @@
 int setrlimit64(int resource, const rlimit64* limits64) {
   return prlimit64(0, resource, limits64, NULL);
 }
+
+// There is no prlimit system call, so we need to use prlimit64.
+int prlimit(pid_t pid, int resource, const rlimit* n32, rlimit* o32) {
+  rlimit64 n64;
+  if (n32 != nullptr) {
+    n64.rlim_cur = (n32->rlim_cur == RLIM_INFINITY) ? RLIM64_INFINITY : n32->rlim_cur;
+    n64.rlim_max = (n32->rlim_max == RLIM_INFINITY) ? RLIM64_INFINITY : n32->rlim_max;
+  }
+
+  rlimit64 o64;
+  int result = prlimit64(pid, resource,
+                         (n32 != nullptr) ? &n64 : nullptr,
+                         (o32 != nullptr) ? &o64 : nullptr);
+  if (result != -1 && o32 != nullptr) {
+    o32->rlim_cur = (o64.rlim_cur == RLIM64_INFINITY) ? RLIM_INFINITY : o64.rlim_cur;
+    o32->rlim_max = (o64.rlim_max == RLIM64_INFINITY) ? RLIM_INFINITY : o64.rlim_max;
+  }
+  return result;
+}
diff --git a/libc/bionic/libc_init_common.cpp b/libc/bionic/libc_init_common.cpp
index bd71628..4f1226d 100644
--- a/libc/bionic/libc_init_common.cpp
+++ b/libc/bionic/libc_init_common.cpp
@@ -42,18 +42,18 @@
 #include <unistd.h>
 
 #include "private/bionic_auxv.h"
+#include "private/bionic_globals.h"
 #include "private/bionic_ssp.h"
 #include "private/bionic_tls.h"
 #include "private/KernelArgumentBlock.h"
 #include "private/libc_logging.h"
+#include "private/WriteProtected.h"
 #include "pthread_internal.h"
 
 extern "C" abort_msg_t** __abort_message_ptr;
 extern "C" int __system_properties_init(void);
-extern "C" int __set_tls(void* ptr);
-extern "C" int __set_tid_address(int* tid_address);
 
-__LIBC_HIDDEN__ void __libc_init_vdso();
+__LIBC_HIDDEN__ WriteProtected<libc_globals> __libc_globals;
 
 // Not public, but well-known in the BSDs.
 const char* __progname;
@@ -64,64 +64,53 @@
 // Declared in "private/bionic_ssp.h".
 uintptr_t __stack_chk_guard = 0;
 
-/* Init TLS for the initial thread. Called by the linker _before_ libc is mapped
- * in memory. Beware: all writes to libc globals from this function will
- * apply to linker-private copies and will not be visible from libc later on.
- *
- * Note: this function creates a pthread_internal_t for the initial thread and
- * stores the pointer in TLS, but does not add it to pthread's thread list. This
- * has to be done later from libc itself (see __libc_init_common).
- *
- * This function also stores a pointer to the kernel argument block in a TLS slot to be
- * picked up by the libc constructor.
- */
-void __libc_init_tls(KernelArgumentBlock& args) {
+void __libc_init_global_stack_chk_guard(KernelArgumentBlock& args) {
+  // AT_RANDOM is a pointer to 16 bytes of randomness on the stack.
+  // Take the first 4/8 for the -fstack-protector implementation.
+  __stack_chk_guard = *reinterpret_cast<uintptr_t*>(args.getauxval(AT_RANDOM));
+}
+
+#if defined(__i386__)
+__LIBC_HIDDEN__ void* __libc_sysinfo = nullptr;
+
+__LIBC_HIDDEN__ void __libc_init_sysinfo(KernelArgumentBlock& args) {
+  __libc_sysinfo = reinterpret_cast<void*>(args.getauxval(AT_SYSINFO));
+}
+
+// TODO: lose this function and just access __libc_sysinfo directly.
+extern "C" void* __kernel_syscall() {
+  return __libc_sysinfo;
+}
+#endif
+
+void __libc_init_globals(KernelArgumentBlock& args) {
+#if defined(__i386__)
+  __libc_init_sysinfo(args);
+#endif
+  // Initialize libc globals that are needed in both the linker and in libc.
+  // In dynamic binaries, this is run at least twice for different copies of the
+  // globals, once for the linker's copy and once for the one in libc.so.
+  __libc_init_global_stack_chk_guard(args);
   __libc_auxv = args.auxv;
-
-  static pthread_internal_t main_thread;
-
-  // Tell the kernel to clear our tid field when we exit, so we're like any other pthread.
-  // As a side-effect, this tells us our pid (which is the same as the main thread's tid).
-  main_thread.tid = __set_tid_address(&main_thread.tid);
-  main_thread.set_cached_pid(main_thread.tid);
-
-  // We don't want to free the main thread's stack even when the main thread exits
-  // because things like environment variables with global scope live on it.
-  // We also can't free the pthread_internal_t itself, since that lives on the main
-  // 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.
-
-  __init_thread(&main_thread);
-  __init_tls(&main_thread);
-  __set_tls(main_thread.tls);
-  main_thread.tls[TLS_SLOT_BIONIC_PREINIT] = &args;
-
-  __init_alternate_signal_stack(&main_thread);
+  __libc_globals.initialize();
+  __libc_globals.mutate([&args](libc_globals* globals) {
+    __libc_init_vdso(globals, args);
+    __libc_init_setjmp_cookie(globals, args);
+  });
 }
 
 void __libc_init_common(KernelArgumentBlock& args) {
   // Initialize various globals.
   environ = args.envp;
   errno = 0;
-  __libc_auxv = args.auxv;
   __progname = args.argv[0] ? args.argv[0] : "<unknown>";
   __abort_message_ptr = args.abort_message_ptr;
 
-  // AT_RANDOM is a pointer to 16 bytes of randomness on the stack.
-  __stack_chk_guard = *reinterpret_cast<uintptr_t*>(getauxval(AT_RANDOM));
-
   // Get the main thread from TLS and add it to the thread list.
   pthread_internal_t* main_thread = __get_thread();
   __pthread_internal_add(main_thread);
 
   __system_properties_init(); // Requires 'environ'.
-
-  __libc_init_vdso();
 }
 
 __noreturn static void __early_abort(int line) {
@@ -234,39 +223,42 @@
 }
 
 static bool __is_unsafe_environment_variable(const char* name) {
-  // None of these should be allowed in setuid programs.
-  static const char* const UNSAFE_VARIABLE_NAMES[] = {
-      "GCONV_PATH",
-      "GETCONF_DIR",
-      "HOSTALIASES",
-      "JE_MALLOC_CONF",
-      "LD_AOUT_LIBRARY_PATH",
-      "LD_AOUT_PRELOAD",
-      "LD_AUDIT",
-      "LD_DEBUG",
-      "LD_DEBUG_OUTPUT",
-      "LD_DYNAMIC_WEAK",
-      "LD_LIBRARY_PATH",
-      "LD_ORIGIN_PATH",
-      "LD_PRELOAD",
-      "LD_PROFILE",
-      "LD_SHOW_AUXV",
-      "LD_USE_LOAD_BIAS",
-      "LOCALDOMAIN",
-      "LOCPATH",
-      "MALLOC_CHECK_",
-      "MALLOC_CONF",
-      "MALLOC_TRACE",
-      "NIS_PATH",
-      "NLSPATH",
-      "RESOLV_HOST_CONF",
-      "RES_OPTIONS",
-      "TMPDIR",
-      "TZDIR",
-      nullptr
+  // None of these should be allowed when the AT_SECURE auxv
+  // flag is set. This flag is set to inform userspace that a
+  // security transition has occurred, for example, as a result
+  // of executing a setuid program or the result of an SELinux
+  // security transition.
+  static constexpr const char* UNSAFE_VARIABLE_NAMES[] = {
+    "GCONV_PATH",
+    "GETCONF_DIR",
+    "HOSTALIASES",
+    "JE_MALLOC_CONF",
+    "LD_AOUT_LIBRARY_PATH",
+    "LD_AOUT_PRELOAD",
+    "LD_AUDIT",
+    "LD_DEBUG",
+    "LD_DEBUG_OUTPUT",
+    "LD_DYNAMIC_WEAK",
+    "LD_LIBRARY_PATH",
+    "LD_ORIGIN_PATH",
+    "LD_PRELOAD",
+    "LD_PROFILE",
+    "LD_SHOW_AUXV",
+    "LD_USE_LOAD_BIAS",
+    "LOCALDOMAIN",
+    "LOCPATH",
+    "MALLOC_CHECK_",
+    "MALLOC_CONF",
+    "MALLOC_TRACE",
+    "NIS_PATH",
+    "NLSPATH",
+    "RESOLV_HOST_CONF",
+    "RES_OPTIONS",
+    "TMPDIR",
+    "TZDIR",
   };
-  for (size_t i = 0; UNSAFE_VARIABLE_NAMES[i] != nullptr; ++i) {
-    if (env_match(name, UNSAFE_VARIABLE_NAMES[i]) != nullptr) {
+  for (const auto& unsafe_variable_name : UNSAFE_VARIABLE_NAMES) {
+    if (env_match(name, unsafe_variable_name) != nullptr) {
       return true;
     }
   }
@@ -319,7 +311,7 @@
 
   if (getauxval(AT_SECURE)) {
     // If this is a setuid/setgid program, close the security hole described in
-    // ftp://ftp.freebsd.org/pub/FreeBSD/CERT/advisories/FreeBSD-SA-02:23.stdio.asc
+    // https://www.freebsd.org/security/advisories/FreeBSD-SA-02:23.stdio.asc
     __nullify_closed_stdio();
 
     __sanitize_environment_variables(args.envp);
@@ -368,13 +360,4 @@
 
     dtor();
   }
-
-#ifndef LIBC_STATIC
-  {
-    extern void __libc_postfini(void) __attribute__((weak));
-    if (__libc_postfini) {
-      __libc_postfini();
-    }
-  }
-#endif
 }
diff --git a/libc/bionic/libc_init_common.h b/libc/bionic/libc_init_common.h
index 673ad5b..5066652 100644
--- a/libc/bionic/libc_init_common.h
+++ b/libc/bionic/libc_init_common.h
@@ -51,6 +51,9 @@
 #if defined(__cplusplus)
 
 class KernelArgumentBlock;
+
+__LIBC_HIDDEN__ void __libc_init_globals(KernelArgumentBlock& args);
+
 __LIBC_HIDDEN__ void __libc_init_common(KernelArgumentBlock& args);
 
 __LIBC_HIDDEN__ void __libc_init_AT_SECURE(KernelArgumentBlock& args);
diff --git a/libc/bionic/libc_init_dynamic.cpp b/libc/bionic/libc_init_dynamic.cpp
index 78125f9..ab48fb8 100644
--- a/libc/bionic/libc_init_dynamic.cpp
+++ b/libc/bionic/libc_init_dynamic.cpp
@@ -25,6 +25,7 @@
  * OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF
  * SUCH DAMAGE.
  */
+
 /*
  * libc_init_dynamic.c
  *
@@ -50,12 +51,11 @@
 #include <elf.h>
 #include "libc_init_common.h"
 
+#include "private/bionic_globals.h"
 #include "private/bionic_tls.h"
 #include "private/KernelArgumentBlock.h"
 
 extern "C" {
-  extern void malloc_debug_init(void);
-  extern void malloc_debug_fini(void);
   extern void netdClientInit(void);
   extern int __cxa_atexit(void (*)(void *), void *, void *);
 };
@@ -74,18 +74,14 @@
   // __libc_init_common() will change the TLS area so the old one won't be accessible anyway.
   *args_slot = NULL;
 
+  __libc_init_globals(*args);
   __libc_init_common(*args);
 
   // Hooks for various libraries to let them know that we're starting up.
-  malloc_debug_init();
+  __libc_globals.mutate(__libc_init_malloc);
   netdClientInit();
 }
 
-__LIBC_HIDDEN__ void __libc_postfini() {
-  // A hook for the debug malloc library to let it know that we're shutting down.
-  malloc_debug_fini();
-}
-
 // This function is called from the executable's _start entry point
 // (see arch-$ARCH/bionic/crtbegin_dynamic.S), which is itself
 // called by the dynamic linker after it has loaded all shared
@@ -112,3 +108,9 @@
 
   exit(slingshot(args.argc, args.argv, args.envp));
 }
+
+extern "C" uint32_t android_get_application_target_sdk_version();
+
+uint32_t bionic_get_application_target_sdk_version() {
+  return android_get_application_target_sdk_version();
+}
diff --git a/libc/bionic/libc_init_static.cpp b/libc/bionic/libc_init_static.cpp
index 7794fbe..d1494d7 100644
--- a/libc/bionic/libc_init_static.cpp
+++ b/libc/bionic/libc_init_static.cpp
@@ -25,18 +25,8 @@
  * OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF
  * SUCH DAMAGE.
  */
-/*
- * libc_init_static.c
- *
- * The program startup function __libc_init() defined here is
- * used for static executables only (i.e. those that don't depend
- * on shared libraries). It is called from arch-$ARCH/bionic/crtbegin_static.S
- * which is directly invoked by the kernel when the program is launched.
- *
- * The 'structors' parameter contains pointers to various initializer
- * arrays that must be run before the program's 'main' routine is launched.
- */
 
+#include <android/api-level.h>
 #include <elf.h>
 #include <errno.h>
 #include <stddef.h>
@@ -49,16 +39,10 @@
 #include "libc_init_common.h"
 #include "pthread_internal.h"
 
+#include "private/bionic_page.h"
 #include "private/bionic_tls.h"
 #include "private/KernelArgumentBlock.h"
 
-// Returns the address of the page containing address 'x'.
-#define PAGE_START(x)  ((x) & PAGE_MASK)
-
-// Returns the address of the next page after address 'x', unless 'x' is
-// itself at the start of a page.
-#define PAGE_END(x)    PAGE_START((x) + (PAGE_SIZE-1))
-
 extern "C" int __cxa_atexit(void (*)(void *), void *, void *);
 
 static void call_array(void(**list)()) {
@@ -85,12 +69,24 @@
   }
 }
 
+// The program startup function __libc_init() defined here is
+// used for static executables only (i.e. those that don't depend
+// on shared libraries). It is called from arch-$ARCH/bionic/crtbegin_static.S
+// which is directly invoked by the kernel when the program is launched.
+//
+// The 'structors' parameter contains pointers to various initializer
+// arrays that must be run before the program's 'main' routine is launched.
+
 __noreturn void __libc_init(void* raw_args,
                             void (*onexit)(void) __unused,
                             int (*slingshot)(int, char**, char**),
                             structors_array_t const * const structors) {
   KernelArgumentBlock args(raw_args);
-  __libc_init_tls(args);
+  __libc_init_main_thread(args);
+
+  // Initializing the globals requires TLS to be available for errno.
+  __libc_init_globals(args);
+
   __libc_init_AT_SECURE(args);
   __libc_init_common(args);
 
@@ -111,3 +107,7 @@
 
   exit(slingshot(args.argc, args.argv, args.envp));
 }
+
+uint32_t bionic_get_application_target_sdk_version() {
+  return __ANDROID_API__;
+}
diff --git a/libc/bionic/libc_logging.cpp b/libc/bionic/libc_logging.cpp
index cb0b334..fffaea8 100644
--- a/libc/bionic/libc_logging.cpp
+++ b/libc/bionic/libc_logging.cpp
@@ -31,6 +31,7 @@
 
 #include <android/set_abort_message.h>
 #include <assert.h>
+#include <ctype.h>
 #include <errno.h>
 #include <fcntl.h>
 #include <pthread.h>
@@ -46,6 +47,9 @@
 #include <time.h>
 #include <unistd.h>
 
+#define _REALLY_INCLUDE_SYS__SYSTEM_PROPERTIES_H_
+#include <sys/_system_properties.h>
+
 static pthread_mutex_t g_abort_msg_lock = PTHREAD_MUTEX_INITIALIZER;
 
 __LIBC_HIDDEN__ abort_msg_t** __abort_message_ptr; // Accessible to __libc_init_common.
@@ -448,7 +452,6 @@
   return result;
 }
 
-#ifdef TARGET_USES_LOGD
 static int __libc_open_log_socket() {
   // ToDo: Ideally we want this to fail if the gid of the current
   // process is AID_LOGD, but will have to wait until we have
@@ -482,14 +485,70 @@
   return log_fd;
 }
 
+struct cache {
+  const prop_info* pinfo;
+  uint32_t serial;
+  char c;
+};
+
+static void refresh_cache(struct cache *cache, const char *key)
+{
+  if (!cache->pinfo) {
+    cache->pinfo = __system_property_find(key);
+    if (!cache->pinfo) {
+      return;
+    }
+  }
+  uint32_t serial = __system_property_serial(cache->pinfo);
+  if (serial == cache->serial) {
+    return;
+  }
+  cache->serial = serial;
+
+  char buf[PROP_VALUE_MAX];
+  __system_property_read(cache->pinfo, 0, buf);
+  cache->c = buf[0];
+}
+
+// Timestamp state generally remains constant, since a change is
+// rare, we can accept a trylock failure gracefully.
+static pthread_mutex_t lock_clockid = PTHREAD_MUTEX_INITIALIZER;
+
+static clockid_t __android_log_clockid()
+{
+  static struct cache r_time_cache = { NULL, static_cast<uint32_t>(-1), 0 };
+  static struct cache p_time_cache = { NULL, static_cast<uint32_t>(-1), 0 };
+  char c;
+
+  if (pthread_mutex_trylock(&lock_clockid)) {
+    // We are willing to accept some race in this context
+    if (!(c = p_time_cache.c)) {
+      c = r_time_cache.c;
+    }
+  } else {
+    static uint32_t serial;
+    uint32_t current_serial = __system_property_area_serial();
+    if (current_serial != serial) {
+      refresh_cache(&r_time_cache, "ro.logd.timestamp");
+      refresh_cache(&p_time_cache, "persist.logd.timestamp");
+      serial = current_serial;
+    }
+    if (!(c = p_time_cache.c)) {
+      c = r_time_cache.c;
+    }
+
+    pthread_mutex_unlock(&lock_clockid);
+  }
+
+  return (tolower(c) == 'm') ? CLOCK_MONOTONIC : CLOCK_REALTIME;
+}
+
 struct log_time { // Wire format
   uint32_t tv_sec;
   uint32_t tv_nsec;
 };
-#endif
 
-static int __libc_write_log(int priority, const char* tag, const char* msg) {
-#ifdef TARGET_USES_LOGD
+int __libc_write_log(int priority, const char* tag, const char* msg) {
   int main_log_fd = __libc_open_log_socket();
   if (main_log_fd == -1) {
     // Try stderr instead.
@@ -504,7 +563,7 @@
   vec[1].iov_base = &tid;
   vec[1].iov_len = sizeof(tid);
   timespec ts;
-  clock_gettime(CLOCK_REALTIME, &ts);
+  clock_gettime(__android_log_clockid(), &ts);
   log_time realtime_ts;
   realtime_ts.tv_sec = ts.tv_sec;
   realtime_ts.tv_nsec = ts.tv_nsec;
@@ -517,24 +576,6 @@
   vec[4].iov_len = strlen(tag) + 1;
   vec[5].iov_base = const_cast<char*>(msg);
   vec[5].iov_len = strlen(msg) + 1;
-#else
-  int main_log_fd = TEMP_FAILURE_RETRY(open("/dev/log/main", O_CLOEXEC | O_WRONLY));
-  if (main_log_fd == -1) {
-    if (errno == ENOTDIR) {
-      // /dev/log isn't a directory? Maybe we're running on the host? Try stderr instead.
-      return __libc_write_stderr(tag, msg);
-    }
-    return -1;
-  }
-
-  iovec vec[3];
-  vec[0].iov_base = &priority;
-  vec[0].iov_len = 1;
-  vec[1].iov_base = const_cast<char*>(tag);
-  vec[1].iov_len = strlen(tag) + 1;
-  vec[2].iov_base = const_cast<char*>(msg);
-  vec[2].iov_len = strlen(msg) + 1;
-#endif
 
   int result = TEMP_FAILURE_RETRY(writev(main_log_fd, vec, sizeof(vec) / sizeof(vec[0])));
   close(main_log_fd);
@@ -557,7 +598,6 @@
 }
 
 static int __libc_android_log_event(int32_t tag, char type, const void* payload, size_t len) {
-#ifdef TARGET_USES_LOGD
   iovec vec[6];
   char log_id = LOG_ID_EVENTS;
   vec[0].iov_base = &log_id;
@@ -566,7 +606,7 @@
   vec[1].iov_base = &tid;
   vec[1].iov_len = sizeof(tid);
   timespec ts;
-  clock_gettime(CLOCK_REALTIME, &ts);
+  clock_gettime(__android_log_clockid(), &ts);
   log_time realtime_ts;
   realtime_ts.tv_sec = ts.tv_sec;
   realtime_ts.tv_nsec = ts.tv_nsec;
@@ -581,17 +621,6 @@
   vec[5].iov_len = len;
 
   int event_log_fd = __libc_open_log_socket();
-#else
-  iovec vec[3];
-  vec[0].iov_base = &tag;
-  vec[0].iov_len = sizeof(tag);
-  vec[1].iov_base = &type;
-  vec[1].iov_len = sizeof(type);
-  vec[2].iov_base = const_cast<void*>(payload);
-  vec[2].iov_len = len;
-
-  int event_log_fd = TEMP_FAILURE_RETRY(open("/dev/log/events", O_CLOEXEC | O_WRONLY));
-#endif
 
   if (event_log_fd == -1) {
     return -1;
diff --git a/libc/bionic/libgen.cpp b/libc/bionic/libgen.cpp
index 2f29d7b..c415c0f 100644
--- a/libc/bionic/libgen.cpp
+++ b/libc/bionic/libgen.cpp
@@ -39,7 +39,7 @@
 static ThreadLocalBuffer<char, MAXPATHLEN> g_basename_tls_buffer;
 static ThreadLocalBuffer<char, MAXPATHLEN> g_dirname_tls_buffer;
 
-__LIBC64_HIDDEN__ int basename_r(const char* path, char* buffer, size_t buffer_size) {
+static int __basename_r(const char* path, char* buffer, size_t buffer_size) {
   const char* startp = NULL;
   const char* endp = NULL;
   int len;
@@ -91,7 +91,12 @@
   return result;
 }
 
-__LIBC64_HIDDEN__ int dirname_r(const char* path, char* buffer, size_t buffer_size) {
+// Since this is a non-standard symbol, it might be hijacked by a basename_r in the executable.
+__LIBC32_LEGACY_PUBLIC__ int basename_r(const char* path, char* buffer, size_t buffer_size) {
+  return __basename_r(path, buffer, buffer_size);
+}
+
+static int __dirname_r(const char* path, char* buffer, size_t buffer_size) {
   const char* endp = NULL;
   int len;
   int result;
@@ -150,14 +155,19 @@
   return result;
 }
 
+// Since this is a non-standard symbol, it might be hijacked by a basename_r in the executable.
+__LIBC32_LEGACY_PUBLIC__ int dirname_r(const char* path, char* buffer, size_t buffer_size) {
+  return __dirname_r(path, buffer, buffer_size);
+}
+
 char* basename(const char* path) {
   char* buf = g_basename_tls_buffer.get();
-  int rc = basename_r(path, buf, g_basename_tls_buffer.size());
+  int rc = __basename_r(path, buf, g_basename_tls_buffer.size());
   return (rc < 0) ? NULL : buf;
 }
 
 char* dirname(const char* path) {
   char* buf = g_dirname_tls_buffer.get();
-  int rc = dirname_r(path, buf, g_dirname_tls_buffer.size());
+  int rc = __dirname_r(path, buf, g_dirname_tls_buffer.size());
   return (rc < 0) ? NULL : buf;
 }
diff --git a/libc/bionic/if_indextoname.c b/libc/bionic/lockf.cpp
similarity index 61%
rename from libc/bionic/if_indextoname.c
rename to libc/bionic/lockf.cpp
index f0db512..804ad68 100644
--- a/libc/bionic/if_indextoname.c
+++ b/libc/bionic/lockf.cpp
@@ -1,5 +1,5 @@
 /*
- * Copyright (C) 2008 The Android Open Source Project
+ * Copyright (C) 2016 The Android Open Source Project
  * All rights reserved.
  *
  * Redistribution and use in source and binary forms, with or without
@@ -26,37 +26,48 @@
  * SUCH DAMAGE.
  */
 
-#include <string.h>
 #include <unistd.h>
-#include <linux/sockios.h>
-#include <net/if.h>
-#include <sys/socket.h>
-#include <sys/ioctl.h>
+
 #include <errno.h>
+#include <fcntl.h>
+#include <string.h>
 
-/*
- * Map an interface index into its name.
- * Returns NULL on error.
- */
-char*
-if_indextoname(unsigned ifindex, char *ifname)
-{
-    int ctl_sock;
-    struct ifreq ifr;
-    char*  ret = NULL;
+int lockf64(int fd, int cmd, off64_t length) {
+  // Translate POSIX lockf into fcntl.
+  struct flock64 fl;
+  memset(&fl, 0, sizeof(fl));
+  fl.l_whence = SEEK_CUR;
+  fl.l_start = 0;
+  fl.l_len = length;
 
-    memset(&ifr, 0, sizeof(struct ifreq));
-    ifr.ifr_ifindex = ifindex;
+  if (cmd == F_ULOCK) {
+    fl.l_type = F_UNLCK;
+    cmd = F_SETLK64;
+    return fcntl(fd, F_SETLK64, &fl);
+  }
 
-    if ((ctl_sock = socket(AF_INET, SOCK_DGRAM, 0)) >= 0) {
-        if (ioctl(ctl_sock, SIOCGIFNAME, &ifr) >= 0) {
-            ret = strncpy (ifname, ifr.ifr_name, IFNAMSIZ);
-        } else {
-            /* Posix requires ENXIO */
-            if (errno == ENODEV)
-                errno = ENXIO;
-        }
-        close(ctl_sock);
-    }
-    return ret;
+  if (cmd == F_LOCK) {
+    fl.l_type = F_WRLCK;
+    return fcntl(fd, F_SETLKW64, &fl);
+  }
+
+  if (cmd == F_TLOCK) {
+    fl.l_type = F_WRLCK;
+    return fcntl(fd, F_SETLK64, &fl);
+  }
+
+  if (cmd == F_TEST) {
+    fl.l_type = F_RDLCK;
+    if (fcntl(fd, F_GETLK64, &fl) == -1) return -1;
+    if (fl.l_type == F_UNLCK || fl.l_pid == getpid()) return 0;
+    errno = EACCES;
+    return -1;
+  }
+
+  errno = EINVAL;
+  return -1;
+}
+
+int lockf(int fd, int cmd, off_t length) {
+  return lockf64(fd, cmd, length);
 }
diff --git a/libc/bionic/malloc_common.cpp b/libc/bionic/malloc_common.cpp
new file mode 100644
index 0000000..e050619
--- /dev/null
+++ b/libc/bionic/malloc_common.cpp
@@ -0,0 +1,464 @@
+/*
+ * Copyright (C) 2009 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.
+ */
+
+// Contains a thin layer that calls whatever real native allocator
+// has been defined. For the libc shared library, this allows the
+// implementation of a debug malloc that can intercept all of the allocation
+// calls and add special debugging code to attempt to catch allocation
+// errors. All of the debugging code is implemented in a separate shared
+// library that is only loaded when the property "libc.debug.malloc.options"
+// is set to a non-zero value. There are two functions exported to
+// allow ddms, or other external users to get information from the debug
+// allocation.
+//   get_malloc_leak_info: Returns information about all of the known native
+//                         allocations that are currently in use.
+//   free_malloc_leak_info: Frees the data allocated by the call to
+//                          get_malloc_leak_info.
+
+#include <pthread.h>
+
+#include <private/bionic_config.h>
+#include <private/bionic_globals.h>
+#include <private/bionic_malloc_dispatch.h>
+
+#include "jemalloc.h"
+#define Malloc(function)  je_ ## function
+
+static constexpr MallocDispatch __libc_malloc_default_dispatch
+  __attribute__((unused)) = {
+    Malloc(calloc),
+    Malloc(free),
+    Malloc(mallinfo),
+    Malloc(malloc),
+    Malloc(malloc_usable_size),
+    Malloc(memalign),
+    Malloc(posix_memalign),
+#if defined(HAVE_DEPRECATED_MALLOC_FUNCS)
+    Malloc(pvalloc),
+#endif
+    Malloc(realloc),
+#if defined(HAVE_DEPRECATED_MALLOC_FUNCS)
+    Malloc(valloc),
+#endif
+    Malloc(iterate),
+    Malloc(malloc_disable),
+    Malloc(malloc_enable),
+  };
+
+// In a VM process, this is set to 1 after fork()ing out of zygote.
+int gMallocLeakZygoteChild = 0;
+
+// =============================================================================
+// Allocation functions
+// =============================================================================
+extern "C" void* calloc(size_t n_elements, size_t elem_size) {
+  auto _calloc = __libc_globals->malloc_dispatch.calloc;
+  if (__predict_false(_calloc != nullptr)) {
+    return _calloc(n_elements, elem_size);
+  }
+  return Malloc(calloc)(n_elements, elem_size);
+}
+
+extern "C" void free(void* mem) {
+  auto _free = __libc_globals->malloc_dispatch.free;
+  if (__predict_false(_free != nullptr)) {
+    _free(mem);
+  } else {
+    Malloc(free)(mem);
+  }
+}
+
+extern "C" struct mallinfo mallinfo() {
+  auto _mallinfo = __libc_globals->malloc_dispatch.mallinfo;
+  if (__predict_false(_mallinfo != nullptr)) {
+    return _mallinfo();
+  }
+  return Malloc(mallinfo)();
+}
+
+extern "C" void* malloc(size_t bytes) {
+  auto _malloc = __libc_globals->malloc_dispatch.malloc;
+  if (__predict_false(_malloc != nullptr)) {
+    return _malloc(bytes);
+  }
+  return Malloc(malloc)(bytes);
+}
+
+extern "C" size_t malloc_usable_size(const void* mem) {
+  auto _malloc_usable_size = __libc_globals->malloc_dispatch.malloc_usable_size;
+  if (__predict_false(_malloc_usable_size != nullptr)) {
+    return _malloc_usable_size(mem);
+  }
+  return Malloc(malloc_usable_size)(mem);
+}
+
+extern "C" void* memalign(size_t alignment, size_t bytes) {
+  auto _memalign = __libc_globals->malloc_dispatch.memalign;
+  if (__predict_false(_memalign != nullptr)) {
+    return _memalign(alignment, bytes);
+  }
+  return Malloc(memalign)(alignment, bytes);
+}
+
+extern "C" int posix_memalign(void** memptr, size_t alignment, size_t size) {
+  auto _posix_memalign = __libc_globals->malloc_dispatch.posix_memalign;
+  if (__predict_false(_posix_memalign != nullptr)) {
+    return _posix_memalign(memptr, alignment, size);
+  }
+  return Malloc(posix_memalign)(memptr, alignment, size);
+}
+
+extern "C" void* realloc(void* old_mem, size_t bytes) {
+  auto _realloc = __libc_globals->malloc_dispatch.realloc;
+  if (__predict_false(_realloc != nullptr)) {
+    return _realloc(old_mem, bytes);
+  }
+  return Malloc(realloc)(old_mem, bytes);
+}
+
+#if defined(HAVE_DEPRECATED_MALLOC_FUNCS)
+extern "C" void* pvalloc(size_t bytes) {
+  auto _pvalloc = __libc_globals->malloc_dispatch.pvalloc;
+  if (__predict_false(_pvalloc != nullptr)) {
+    return _pvalloc(bytes);
+  }
+  return Malloc(pvalloc)(bytes);
+}
+
+extern "C" void* valloc(size_t bytes) {
+  auto _valloc = __libc_globals->malloc_dispatch.valloc;
+  if (__predict_false(_valloc != nullptr)) {
+    return _valloc(bytes);
+  }
+  return Malloc(valloc)(bytes);
+}
+#endif
+
+// We implement malloc debugging only in libc.so, so the code below
+// must be excluded if we compile this file for static libc.a
+#if !defined(LIBC_STATIC)
+
+#include <dlfcn.h>
+#include <stdio.h>
+#include <stdlib.h>
+
+#include <private/libc_logging.h>
+#include <sys/system_properties.h>
+
+extern "C" int __cxa_atexit(void (*func)(void *), void *arg, void *dso);
+
+static const char* DEBUG_SHARED_LIB = "libc_malloc_debug.so";
+static const char* DEBUG_MALLOC_PROPERTY_OPTIONS = "libc.debug.malloc.options";
+static const char* DEBUG_MALLOC_PROPERTY_PROGRAM = "libc.debug.malloc.program";
+static const char* DEBUG_MALLOC_PROPERTY_ENV_ENABLED = "libc.debug.malloc.env_enabled";
+static const char* DEBUG_MALLOC_ENV_ENABLE = "LIBC_DEBUG_MALLOC_ENABLE";
+
+static void* libc_malloc_impl_handle = nullptr;
+
+static void (*g_debug_finalize_func)();
+static void (*g_debug_get_malloc_leak_info_func)(uint8_t**, size_t*, size_t*, size_t*, size_t*);
+static void (*g_debug_free_malloc_leak_info_func)(uint8_t*);
+static ssize_t (*g_debug_malloc_backtrace_func)(void*, uintptr_t*, size_t);
+
+// =============================================================================
+// Log functions
+// =============================================================================
+#define error_log(format, ...)  \
+    __libc_format_log(ANDROID_LOG_ERROR, "libc", (format), ##__VA_ARGS__ )
+#define info_log(format, ...)  \
+    __libc_format_log(ANDROID_LOG_INFO, "libc", (format), ##__VA_ARGS__ )
+// =============================================================================
+
+// =============================================================================
+// Exported for use by ddms.
+// =============================================================================
+
+// Retrieve native heap information.
+//
+// "*info" is set to a buffer we allocate
+// "*overall_size" is set to the size of the "info" buffer
+// "*info_size" is set to the size of a single entry
+// "*total_memory" is set to the sum of all allocations we're tracking; does
+//   not include heap overhead
+// "*backtrace_size" is set to the maximum number of entries in the back trace
+extern "C" void get_malloc_leak_info(uint8_t** info, size_t* overall_size,
+    size_t* info_size, size_t* total_memory, size_t* backtrace_size) {
+  if (g_debug_get_malloc_leak_info_func == nullptr) {
+    return;
+  }
+  g_debug_get_malloc_leak_info_func(info, overall_size, info_size, total_memory, backtrace_size);
+}
+
+extern "C" void free_malloc_leak_info(uint8_t* info) {
+  if (g_debug_free_malloc_leak_info_func == nullptr) {
+    return;
+  }
+  g_debug_free_malloc_leak_info_func(info);
+}
+
+// =============================================================================
+
+template<typename FunctionType>
+static bool InitMallocFunction(void* malloc_impl_handler, FunctionType* func, const char* prefix, const char* suffix) {
+  char symbol[128];
+  snprintf(symbol, sizeof(symbol), "%s_%s", prefix, suffix);
+  *func = reinterpret_cast<FunctionType>(dlsym(malloc_impl_handler, symbol));
+  if (*func == nullptr) {
+    error_log("%s: dlsym(\"%s\") failed", getprogname(), symbol);
+    return false;
+  }
+  return true;
+}
+
+static bool InitMalloc(void* malloc_impl_handler, MallocDispatch* table, const char* prefix) {
+  if (!InitMallocFunction<MallocCalloc>(malloc_impl_handler, &table->calloc,
+                                        prefix, "calloc")) {
+    return false;
+  }
+  if (!InitMallocFunction<MallocFree>(malloc_impl_handler, &table->free,
+                                      prefix, "free")) {
+    return false;
+  }
+  if (!InitMallocFunction<MallocMallinfo>(malloc_impl_handler, &table->mallinfo,
+                                          prefix, "mallinfo")) {
+    return false;
+  }
+  if (!InitMallocFunction<MallocMalloc>(malloc_impl_handler, &table->malloc,
+                                        prefix, "malloc")) {
+    return false;
+  }
+  if (!InitMallocFunction<MallocMallocUsableSize>(
+      malloc_impl_handler, &table->malloc_usable_size, prefix, "malloc_usable_size")) {
+    return false;
+  }
+  if (!InitMallocFunction<MallocMemalign>(malloc_impl_handler, &table->memalign,
+                                          prefix, "memalign")) {
+    return false;
+  }
+  if (!InitMallocFunction<MallocPosixMemalign>(malloc_impl_handler, &table->posix_memalign,
+                                               prefix, "posix_memalign")) {
+    return false;
+  }
+  if (!InitMallocFunction<MallocRealloc>(malloc_impl_handler, &table->realloc,
+                                         prefix, "realloc")) {
+    return false;
+  }
+  if (!InitMallocFunction<MallocIterate>(malloc_impl_handler, &table->iterate,
+                                         prefix, "iterate")) {
+    return false;
+  }
+  if (!InitMallocFunction<MallocMallocDisable>(malloc_impl_handler, &table->malloc_disable,
+                                         prefix, "malloc_disable")) {
+    return false;
+  }
+  if (!InitMallocFunction<MallocMallocEnable>(malloc_impl_handler, &table->malloc_enable,
+                                         prefix, "malloc_enable")) {
+    return false;
+  }
+#if defined(HAVE_DEPRECATED_MALLOC_FUNCS)
+  if (!InitMallocFunction<MallocPvalloc>(malloc_impl_handler, &table->pvalloc,
+                                         prefix, "pvalloc")) {
+    return false;
+  }
+  if (!InitMallocFunction<MallocValloc>(malloc_impl_handler, &table->valloc,
+                                        prefix, "valloc")) {
+    return false;
+  }
+#endif
+
+  return true;
+}
+
+static void malloc_fini_impl(void*) {
+  // Our BSD stdio implementation doesn't close the standard streams,
+  // it only flushes them. Other unclosed FILE*s will show up as
+  // malloc leaks, but to avoid the standard streams showing up in
+  // leak reports, close them here.
+  fclose(stdin);
+  fclose(stdout);
+  fclose(stderr);
+
+  g_debug_finalize_func();
+}
+
+// Initializes memory allocation framework once per process.
+static void malloc_init_impl(libc_globals* globals) {
+  char value[PROP_VALUE_MAX];
+  if (__system_property_get(DEBUG_MALLOC_PROPERTY_OPTIONS, value) == 0 || value[0] == '\0') {
+    return;
+  }
+
+  // Check to see if only a specific program should have debug malloc enabled.
+  if (__system_property_get(DEBUG_MALLOC_PROPERTY_PROGRAM, value) != 0 &&
+      strstr(getprogname(), value) == nullptr) {
+    return;
+  }
+
+  // Check for the special environment variable instead.
+  if (__system_property_get(DEBUG_MALLOC_PROPERTY_ENV_ENABLED, value) != 0
+      && value[0] != '\0' && getenv(DEBUG_MALLOC_ENV_ENABLE) == nullptr) {
+    return;
+  }
+
+  // Load the debug malloc shared library.
+  void* malloc_impl_handle = dlopen(DEBUG_SHARED_LIB, RTLD_NOW | RTLD_LOCAL);
+  if (malloc_impl_handle == nullptr) {
+    error_log("%s: Unable to open debug malloc shared library %s: %s",
+              getprogname(), DEBUG_SHARED_LIB, dlerror());
+    return;
+  }
+
+  // Initialize malloc debugging in the loaded module.
+  auto init_func = reinterpret_cast<bool (*)(const MallocDispatch*, int*)>(
+      dlsym(malloc_impl_handle, "debug_initialize"));
+  if (init_func == nullptr) {
+    error_log("%s: debug_initialize routine not found in %s", getprogname(), DEBUG_SHARED_LIB);
+    dlclose(malloc_impl_handle);
+    return;
+  }
+
+  // Get the syms for the external functions.
+  void* finalize_sym = dlsym(malloc_impl_handle, "debug_finalize");
+  if (finalize_sym == nullptr) {
+    error_log("%s: debug_finalize routine not found in %s", getprogname(), DEBUG_SHARED_LIB);
+    dlclose(malloc_impl_handle);
+    return;
+  }
+
+  void* get_leak_info_sym = dlsym(malloc_impl_handle, "debug_get_malloc_leak_info");
+  if (get_leak_info_sym == nullptr) {
+    error_log("%s: debug_get_malloc_leak_info routine not found in %s", getprogname(),
+              DEBUG_SHARED_LIB);
+    dlclose(malloc_impl_handle);
+    return;
+  }
+
+  void* free_leak_info_sym = dlsym(malloc_impl_handle, "debug_free_malloc_leak_info");
+  if (free_leak_info_sym == nullptr) {
+    error_log("%s: debug_free_malloc_leak_info routine not found in %s", getprogname(),
+              DEBUG_SHARED_LIB);
+    dlclose(malloc_impl_handle);
+    return;
+  }
+
+  void* malloc_backtrace_sym = dlsym(malloc_impl_handle, "debug_malloc_backtrace");
+  if (malloc_backtrace_sym == nullptr) {
+    error_log("%s: debug_malloc_backtrace routine not found in %s", getprogname(),
+              DEBUG_SHARED_LIB);
+    dlclose(malloc_impl_handle);
+    return;
+  }
+
+  if (!init_func(&__libc_malloc_default_dispatch, &gMallocLeakZygoteChild)) {
+    dlclose(malloc_impl_handle);
+    return;
+  }
+
+  MallocDispatch malloc_dispatch_table;
+  if (!InitMalloc(malloc_impl_handle, &malloc_dispatch_table, "debug")) {
+    auto finalize_func = reinterpret_cast<void (*)()>(finalize_sym);
+    finalize_func();
+    dlclose(malloc_impl_handle);
+    return;
+  }
+
+  g_debug_finalize_func = reinterpret_cast<void (*)()>(finalize_sym);
+  g_debug_get_malloc_leak_info_func = reinterpret_cast<void (*)(
+      uint8_t**, size_t*, size_t*, size_t*, size_t*)>(get_leak_info_sym);
+  g_debug_free_malloc_leak_info_func = reinterpret_cast<void (*)(uint8_t*)>(free_leak_info_sym);
+  g_debug_malloc_backtrace_func = reinterpret_cast<ssize_t (*)(
+      void*, uintptr_t*, size_t)>(malloc_backtrace_sym);
+
+  globals->malloc_dispatch = malloc_dispatch_table;
+  libc_malloc_impl_handle = malloc_impl_handle;
+
+  info_log("%s: malloc debug enabled", getprogname());
+
+  // Use atexit to trigger the cleanup function. This avoids a problem
+  // where another atexit function is used to cleanup allocated memory,
+  // but the finalize function was already called. This particular error
+  // seems to be triggered by a zygote spawned process calling exit.
+  int ret_value = __cxa_atexit(malloc_fini_impl, nullptr, nullptr);
+  if (ret_value != 0) {
+    error_log("failed to set atexit cleanup function: %d", ret_value);
+  }
+}
+
+// Initializes memory allocation framework.
+// This routine is called from __libc_init routines in libc_init_dynamic.cpp.
+__LIBC_HIDDEN__ void __libc_init_malloc(libc_globals* globals) {
+  malloc_init_impl(globals);
+}
+#endif  // !LIBC_STATIC
+
+// =============================================================================
+// Exported for use by libmemunreachable.
+// =============================================================================
+
+// Calls callback for every allocation in the anonymous heap mapping
+// [base, base+size).  Must be called between malloc_disable and malloc_enable.
+extern "C" int malloc_iterate(uintptr_t base, size_t size,
+    void (*callback)(uintptr_t base, size_t size, void* arg), void* arg) {
+  auto _iterate = __libc_globals->malloc_dispatch.iterate;
+  if (__predict_false(_iterate != nullptr)) {
+    return _iterate(base, size, callback, arg);
+  }
+  return Malloc(iterate)(base, size, callback, arg);
+}
+
+// Disable calls to malloc so malloc_iterate gets a consistent view of
+// allocated memory.
+extern "C" void malloc_disable() {
+  auto _malloc_disable = __libc_globals->malloc_dispatch.malloc_disable;
+  if (__predict_false(_malloc_disable != nullptr)) {
+    return _malloc_disable();
+  }
+  return Malloc(malloc_disable)();
+}
+
+// Re-enable calls to malloc after a previous call to malloc_disable.
+extern "C" void malloc_enable() {
+  auto _malloc_enable = __libc_globals->malloc_dispatch.malloc_enable;
+  if (__predict_false(_malloc_enable != nullptr)) {
+    return _malloc_enable();
+  }
+  return Malloc(malloc_enable)();
+}
+
+#ifndef LIBC_STATIC
+extern "C" ssize_t malloc_backtrace(void* pointer, uintptr_t* frames, size_t frame_count) {
+  if (g_debug_malloc_backtrace_func == nullptr) {
+    return 0;
+  }
+  return g_debug_malloc_backtrace_func(pointer, frames, frame_count);
+}
+#else
+extern "C" ssize_t malloc_backtrace(void*, uintptr_t*, size_t) {
+  return 0;
+}
+#endif
diff --git a/libc/bionic/malloc_debug_backtrace.h b/libc/bionic/malloc_debug_backtrace.h
deleted file mode 100644
index 774548b..0000000
--- a/libc/bionic/malloc_debug_backtrace.h
+++ /dev/null
@@ -1,37 +0,0 @@
-/*
- * Copyright (C) 2014 The Android Open Source Project
- * All rights reserved.
- *
- * Redistribution and use in source and binary forms, with or without
- * modification, are permitted provided that the following conditions
- * are met:
- *  * Redistributions of source code must retain the above copyright
- *    notice, this list of conditions and the following disclaimer.
- *  * Redistributions in binary form must reproduce the above copyright
- *    notice, this list of conditions and the following disclaimer in
- *    the documentation and/or other materials provided with the
- *    distribution.
- *
- * THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS
- * "AS IS" AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT
- * LIMITED TO, THE IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS
- * FOR A PARTICULAR PURPOSE ARE DISCLAIMED. IN NO EVENT SHALL THE
- * COPYRIGHT OWNER OR CONTRIBUTORS BE LIABLE FOR ANY DIRECT, INDIRECT,
- * INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING,
- * BUT NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; LOSS
- * OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED
- * AND ON ANY THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY,
- * OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT
- * OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF
- * SUCH DAMAGE.
- */
-
-#ifndef MALLOC_DEBUG_BACKTRACE_H
-#define MALLOC_DEBUG_BACKTRACE_H
-
-extern bool g_backtrace_enabled;
-
-#define GET_BACKTRACE(bt, depth) \
-  (g_backtrace_enabled ? get_backtrace(bt, depth) : 0)
-
-#endif  // MALLOC_DEBUG_BACKTRACE_H
diff --git a/libc/bionic/malloc_debug_check.cpp b/libc/bionic/malloc_debug_check.cpp
deleted file mode 100644
index dee03fa..0000000
--- a/libc/bionic/malloc_debug_check.cpp
+++ /dev/null
@@ -1,676 +0,0 @@
-/*
- * Copyright (C) 2012 The Android Open Source Project
- * All rights reserved.
- *
- * Redistribution and use in source and binary forms, with or without
- * modification, are permitted provided that the following conditions
- * are met:
- *  * Redistributions of source code must retain the above copyright
- *    notice, this list of conditions and the following disclaimer.
- *  * Redistributions in binary form must reproduce the above copyright
- *    notice, this list of conditions and the following disclaimer in
- *    the documentation and/or other materials provided with the
- *    distribution.
- *
- * THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS
- * "AS IS" AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT
- * LIMITED TO, THE IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS
- * FOR A PARTICULAR PURPOSE ARE DISCLAIMED. IN NO EVENT SHALL THE
- * COPYRIGHT OWNER OR CONTRIBUTORS BE LIABLE FOR ANY DIRECT, INDIRECT,
- * INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING,
- * BUT NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; LOSS
- * OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED
- * AND ON ANY THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY,
- * OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT
- * OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF
- * SUCH DAMAGE.
- */
-
-#include <arpa/inet.h>
-#include <dlfcn.h>
-#include <errno.h>
-#include <errno.h>
-#include <fcntl.h>
-#include <pthread.h>
-#include <stdarg.h>
-#include <stdbool.h>
-#include <stddef.h>
-#include <stdio.h>
-#include <stdlib.h>
-#include <string.h>
-#include <sys/param.h>
-#include <sys/socket.h>
-#include <sys/system_properties.h>
-#include <sys/types.h>
-#include <time.h>
-#include <unistd.h>
-#include <unwind.h>
-
-#include "debug_mapinfo.h"
-#include "debug_stacktrace.h"
-#include "malloc_debug_backtrace.h"
-#include "malloc_debug_common.h"
-#include "malloc_debug_disable.h"
-#include "private/bionic_macros.h"
-#include "private/libc_logging.h"
-#include "private/ScopedPthreadMutexLocker.h"
-
-#define MAX_BACKTRACE_DEPTH 16
-#define ALLOCATION_TAG      0x1ee7d00d
-#define BACKLOG_TAG         0xbabecafe
-#define FREE_POISON         0xa5
-#define FRONT_GUARD         0xaa
-#define FRONT_GUARD_LEN     (1<<5)
-#define REAR_GUARD          0xbb
-#define REAR_GUARD_LEN      (1<<5)
-
-static void log_message(const char* format, ...) {
-  va_list args;
-  va_start(args, format);
-  __libc_format_log_va_list(ANDROID_LOG_ERROR, "libc", format, args);
-  va_end(args);
-}
-
-struct hdr_t {
-    uint32_t tag;
-    void* base;  // Always points to the memory allocated using malloc.
-                 // For memory allocated in chk_memalign, this value will
-                 // not be the same as the location of the start of this
-                 // structure.
-    hdr_t* prev;
-    hdr_t* next;
-    uintptr_t bt[MAX_BACKTRACE_DEPTH];
-    int bt_depth;
-    uintptr_t freed_bt[MAX_BACKTRACE_DEPTH];
-    int freed_bt_depth;
-    size_t size;
-    uint8_t front_guard[FRONT_GUARD_LEN];
-} __attribute__((packed, aligned(MALLOC_ALIGNMENT)));
-
-struct ftr_t {
-    uint8_t rear_guard[REAR_GUARD_LEN];
-} __attribute__((packed));
-
-static inline ftr_t* to_ftr(hdr_t* hdr) {
-    return reinterpret_cast<ftr_t*>(reinterpret_cast<char*>(hdr + 1) + hdr->size);
-}
-
-static inline void* user(hdr_t* hdr) {
-    return hdr + 1;
-}
-
-static inline hdr_t* meta(void* user) {
-    return reinterpret_cast<hdr_t*>(user) - 1;
-}
-
-static inline const hdr_t* const_meta(const void* user) {
-    return reinterpret_cast<const hdr_t*>(user) - 1;
-}
-
-// TODO: introduce a struct for this global state.
-// There are basically two lists here, the regular list and the backlog list.
-// We should be able to remove the duplication.
-static unsigned g_allocated_block_count;
-static hdr_t* tail;
-static hdr_t* head;
-static pthread_mutex_t lock = PTHREAD_MUTEX_INITIALIZER;
-
-static unsigned backlog_num;
-static hdr_t* backlog_tail;
-static hdr_t* backlog_head;
-static pthread_mutex_t backlog_lock = PTHREAD_MUTEX_INITIALIZER;
-
-// This variable is set to the value of property libc.debug.malloc.backlog.
-// It determines the size of the backlog we use to detect multiple frees.
-static unsigned g_malloc_debug_backlog = 100;
-
-// This variable is set to false if the property libc.debug.malloc.nobacktrace
-// is set to non-zero.
-__LIBC_HIDDEN__ bool g_backtrace_enabled = true;
-
-__LIBC_HIDDEN__ HashTable* g_hash_table;
-__LIBC_HIDDEN__ const MallocDebug* g_malloc_dispatch;
-
-static inline void init_front_guard(hdr_t* hdr) {
-    memset(hdr->front_guard, FRONT_GUARD, FRONT_GUARD_LEN);
-}
-
-static inline bool is_front_guard_valid(hdr_t* hdr) {
-    for (size_t i = 0; i < FRONT_GUARD_LEN; i++) {
-        if (hdr->front_guard[i] != FRONT_GUARD) {
-            return false;
-        }
-    }
-    return true;
-}
-
-static inline void init_rear_guard(hdr_t* hdr) {
-    ftr_t* ftr = to_ftr(hdr);
-    memset(ftr->rear_guard, REAR_GUARD, REAR_GUARD_LEN);
-}
-
-static inline bool is_rear_guard_valid(hdr_t* hdr) {
-    unsigned i;
-    int valid = 1;
-    int first_mismatch = -1;
-    ftr_t* ftr = to_ftr(hdr);
-    for (i = 0; i < REAR_GUARD_LEN; i++) {
-        if (ftr->rear_guard[i] != REAR_GUARD) {
-            if (first_mismatch < 0)
-                first_mismatch = i;
-            valid = 0;
-        } else if (first_mismatch >= 0) {
-            log_message("+++ REAR GUARD MISMATCH [%d, %d)\n", first_mismatch, i);
-            first_mismatch = -1;
-        }
-    }
-
-    if (first_mismatch >= 0)
-        log_message("+++ REAR GUARD MISMATCH [%d, %d)\n", first_mismatch, i);
-    return valid;
-}
-
-static inline void add_locked(hdr_t* hdr, hdr_t** tail, hdr_t** head) {
-    hdr->prev = NULL;
-    hdr->next = *head;
-    if (*head)
-        (*head)->prev = hdr;
-    else
-        *tail = hdr;
-    *head = hdr;
-}
-
-static inline int del_locked(hdr_t* hdr, hdr_t** tail, hdr_t** head) {
-    if (hdr->prev) {
-        hdr->prev->next = hdr->next;
-    } else {
-        *head = hdr->next;
-    }
-    if (hdr->next) {
-        hdr->next->prev = hdr->prev;
-    } else {
-        *tail = hdr->prev;
-    }
-    return 0;
-}
-
-static inline void add(hdr_t* hdr, size_t size) {
-    ScopedPthreadMutexLocker locker(&lock);
-    hdr->tag = ALLOCATION_TAG;
-    hdr->size = size;
-    init_front_guard(hdr);
-    init_rear_guard(hdr);
-    ++g_allocated_block_count;
-    add_locked(hdr, &tail, &head);
-}
-
-static inline int del(hdr_t* hdr) {
-    if (hdr->tag != ALLOCATION_TAG) {
-        return -1;
-    }
-
-    ScopedPthreadMutexLocker locker(&lock);
-    del_locked(hdr, &tail, &head);
-    --g_allocated_block_count;
-    return 0;
-}
-
-static inline void poison(hdr_t* hdr) {
-    memset(user(hdr), FREE_POISON, hdr->size);
-}
-
-static bool was_used_after_free(hdr_t* hdr) {
-    const uint8_t* data = reinterpret_cast<const uint8_t*>(user(hdr));
-    for (size_t i = 0; i < hdr->size; i++) {
-        if (data[i] != FREE_POISON) {
-            return true;
-        }
-    }
-    return false;
-}
-
-/* returns 1 if valid, *safe == 1 if safe to dump stack */
-static inline int check_guards(hdr_t* hdr, int* safe) {
-    *safe = 1;
-    if (!is_front_guard_valid(hdr)) {
-        if (hdr->front_guard[0] == FRONT_GUARD) {
-            log_message("+++ ALLOCATION %p SIZE %d HAS A CORRUPTED FRONT GUARD\n",
-                       user(hdr), hdr->size);
-        } else {
-            log_message("+++ ALLOCATION %p HAS A CORRUPTED FRONT GUARD "\
-                      "(NOT DUMPING STACKTRACE)\n", user(hdr));
-            /* Allocation header is probably corrupt, do not print stack trace */
-            *safe = 0;
-        }
-        return 0;
-    }
-
-    if (!is_rear_guard_valid(hdr)) {
-        log_message("+++ ALLOCATION %p SIZE %d HAS A CORRUPTED REAR GUARD\n",
-                   user(hdr), hdr->size);
-        return 0;
-    }
-
-    return 1;
-}
-
-/* returns 1 if valid, *safe == 1 if safe to dump stack */
-static inline int check_allocation_locked(hdr_t* hdr, int* safe) {
-    int valid = 1;
-    *safe = 1;
-
-    if (hdr->tag != ALLOCATION_TAG && hdr->tag != BACKLOG_TAG) {
-        log_message("+++ ALLOCATION %p HAS INVALID TAG %08x (NOT DUMPING STACKTRACE)\n",
-                   user(hdr), hdr->tag);
-        // Allocation header is probably corrupt, do not dequeue or dump stack
-        // trace.
-        *safe = 0;
-        return 0;
-    }
-
-    if (hdr->tag == BACKLOG_TAG && was_used_after_free(hdr)) {
-        log_message("+++ ALLOCATION %p SIZE %d WAS USED AFTER BEING FREED\n",
-                   user(hdr), hdr->size);
-        valid = 0;
-        /* check the guards to see if it's safe to dump a stack trace */
-        check_guards(hdr, safe);
-    } else {
-        valid = check_guards(hdr, safe);
-    }
-
-    if (!valid && *safe && g_backtrace_enabled) {
-        log_message("+++ ALLOCATION %p SIZE %d ALLOCATED HERE:\n",
-                        user(hdr), hdr->size);
-        log_backtrace(hdr->bt, hdr->bt_depth);
-        if (hdr->tag == BACKLOG_TAG) {
-            log_message("+++ ALLOCATION %p SIZE %d FREED HERE:\n",
-                       user(hdr), hdr->size);
-            log_backtrace(hdr->freed_bt, hdr->freed_bt_depth);
-        }
-    }
-
-    return valid;
-}
-
-static inline int del_and_check_locked(hdr_t* hdr,
-                                       hdr_t** tail, hdr_t** head, unsigned* cnt,
-                                       int* safe) {
-    int valid = check_allocation_locked(hdr, safe);
-    if (safe) {
-        (*cnt)--;
-        del_locked(hdr, tail, head);
-    }
-    return valid;
-}
-
-static inline void del_from_backlog_locked(hdr_t* hdr) {
-    int safe;
-    del_and_check_locked(hdr,
-                         &backlog_tail, &backlog_head, &backlog_num,
-                         &safe);
-    hdr->tag = 0; /* clear the tag */
-}
-
-static inline void del_from_backlog(hdr_t* hdr) {
-    ScopedPthreadMutexLocker locker(&backlog_lock);
-    del_from_backlog_locked(hdr);
-}
-
-static inline int del_leak(hdr_t* hdr, int* safe) {
-    ScopedPthreadMutexLocker locker(&lock);
-    return del_and_check_locked(hdr, &tail, &head, &g_allocated_block_count, safe);
-}
-
-static inline void add_to_backlog(hdr_t* hdr) {
-    ScopedPthreadMutexLocker locker(&backlog_lock);
-    hdr->tag = BACKLOG_TAG;
-    backlog_num++;
-    add_locked(hdr, &backlog_tail, &backlog_head);
-    poison(hdr);
-    /* If we've exceeded the maximum backlog, clear it up */
-    while (backlog_num > g_malloc_debug_backlog) {
-        hdr_t* gone = backlog_tail;
-        del_from_backlog_locked(gone);
-        g_malloc_dispatch->free(gone->base);
-    }
-}
-
-extern "C" void* chk_malloc(size_t bytes) {
-//  log_message("%s: %s\n", __FILE__, __FUNCTION__);
-    if (DebugCallsDisabled()) {
-        return g_malloc_dispatch->malloc(bytes);
-    }
-
-    size_t size = sizeof(hdr_t) + bytes + sizeof(ftr_t);
-    if (size < bytes) { // Overflow
-        errno = ENOMEM;
-        return NULL;
-    }
-    hdr_t* hdr = static_cast<hdr_t*>(g_malloc_dispatch->malloc(size));
-    if (hdr) {
-        hdr->base = hdr;
-        hdr->bt_depth = GET_BACKTRACE(hdr->bt, MAX_BACKTRACE_DEPTH);
-        add(hdr, bytes);
-        return user(hdr);
-    }
-    return NULL;
-}
-
-extern "C" void* chk_memalign(size_t alignment, size_t bytes) {
-    if (DebugCallsDisabled()) {
-        return g_malloc_dispatch->memalign(alignment, bytes);
-    }
-
-    if (alignment <= MALLOC_ALIGNMENT) {
-        return chk_malloc(bytes);
-    }
-
-    // Make the alignment a power of two.
-    if (!powerof2(alignment)) {
-        alignment = BIONIC_ROUND_UP_POWER_OF_2(alignment);
-    }
-
-    // here, alignment is at least MALLOC_ALIGNMENT<<1 bytes
-    // we will align by at least MALLOC_ALIGNMENT bytes
-    // and at most alignment-MALLOC_ALIGNMENT bytes
-    size_t size = (alignment-MALLOC_ALIGNMENT) + bytes;
-    if (size < bytes) { // Overflow.
-        return NULL;
-    }
-
-    void* base = g_malloc_dispatch->malloc(sizeof(hdr_t) + size + sizeof(ftr_t));
-    if (base != NULL) {
-        // Check that the actual pointer that will be returned is aligned
-        // properly.
-        uintptr_t ptr = reinterpret_cast<uintptr_t>(user(reinterpret_cast<hdr_t*>(base)));
-        if ((ptr % alignment) != 0) {
-            // Align the pointer.
-            ptr += ((-ptr) % alignment);
-        }
-
-        hdr_t* hdr = meta(reinterpret_cast<void*>(ptr));
-        hdr->base = base;
-        hdr->bt_depth = GET_BACKTRACE(hdr->bt, MAX_BACKTRACE_DEPTH);
-        add(hdr, bytes);
-        return user(hdr);
-    }
-    return base;
-}
-
-extern "C" void chk_free(void* ptr) {
-//  log_message("%s: %s\n", __FILE__, __FUNCTION__);
-    if (DebugCallsDisabled()) {
-        return g_malloc_dispatch->free(ptr);
-    }
-
-    if (!ptr) /* ignore free(NULL) */
-        return;
-
-    hdr_t* hdr = meta(ptr);
-
-    if (del(hdr) < 0) {
-        uintptr_t bt[MAX_BACKTRACE_DEPTH];
-        int depth = GET_BACKTRACE(bt, MAX_BACKTRACE_DEPTH);
-        if (hdr->tag == BACKLOG_TAG) {
-            log_message("+++ ALLOCATION %p SIZE %d BYTES MULTIPLY FREED!\n",
-                       user(hdr), hdr->size);
-            if (g_backtrace_enabled) {
-                log_message("+++ ALLOCATION %p SIZE %d ALLOCATED HERE:\n",
-                          user(hdr), hdr->size);
-                log_backtrace(hdr->bt, hdr->bt_depth);
-                /* hdr->freed_bt_depth should be nonzero here */
-                log_message("+++ ALLOCATION %p SIZE %d FIRST FREED HERE:\n",
-                          user(hdr), hdr->size);
-                log_backtrace(hdr->freed_bt, hdr->freed_bt_depth);
-                log_message("+++ ALLOCATION %p SIZE %d NOW BEING FREED HERE:\n",
-                          user(hdr), hdr->size);
-                log_backtrace(bt, depth);
-            }
-        } else {
-            log_message("+++ ALLOCATION %p IS CORRUPTED OR NOT ALLOCATED VIA TRACKER!\n",
-                       user(hdr));
-            if (g_backtrace_enabled) {
-                log_backtrace(bt, depth);
-            }
-        }
-    } else {
-        hdr->freed_bt_depth = GET_BACKTRACE(hdr->freed_bt, MAX_BACKTRACE_DEPTH);
-        add_to_backlog(hdr);
-    }
-}
-
-extern "C" void* chk_realloc(void* ptr, size_t bytes) {
-//  log_message("%s: %s\n", __FILE__, __FUNCTION__);
-    if (DebugCallsDisabled()) {
-        return g_malloc_dispatch->realloc(ptr, bytes);
-    }
-
-    if (!ptr) {
-        return chk_malloc(bytes);
-    }
-
-#ifdef REALLOC_ZERO_BYTES_FREE
-    if (!bytes) {
-        chk_free(ptr);
-        return NULL;
-    }
-#endif
-
-    hdr_t* hdr = meta(ptr);
-
-    if (del(hdr) < 0) {
-        uintptr_t bt[MAX_BACKTRACE_DEPTH];
-        int depth = GET_BACKTRACE(bt, MAX_BACKTRACE_DEPTH);
-        if (hdr->tag == BACKLOG_TAG) {
-            log_message("+++ REALLOCATION %p SIZE %d OF FREED MEMORY!\n",
-                       user(hdr), bytes, hdr->size);
-            if (g_backtrace_enabled) {
-                log_message("+++ ALLOCATION %p SIZE %d ALLOCATED HERE:\n",
-                          user(hdr), hdr->size);
-                log_backtrace(hdr->bt, hdr->bt_depth);
-                /* hdr->freed_bt_depth should be nonzero here */
-                log_message("+++ ALLOCATION %p SIZE %d FIRST FREED HERE:\n",
-                          user(hdr), hdr->size);
-                log_backtrace(hdr->freed_bt, hdr->freed_bt_depth);
-                log_message("+++ ALLOCATION %p SIZE %d NOW BEING REALLOCATED HERE:\n",
-                          user(hdr), hdr->size);
-                log_backtrace(bt, depth);
-            }
-
-            /* We take the memory out of the backlog and fall through so the
-             * reallocation below succeeds.  Since we didn't really free it, we
-             * can default to this behavior.
-             */
-            del_from_backlog(hdr);
-        } else {
-            log_message("+++ REALLOCATION %p SIZE %d IS CORRUPTED OR NOT ALLOCATED VIA TRACKER!\n",
-                       user(hdr), bytes);
-            if (g_backtrace_enabled) {
-                log_backtrace(bt, depth);
-            }
-            // just get a whole new allocation and leak the old one
-            return g_malloc_dispatch->realloc(0, bytes);
-            // return realloc(user(hdr), bytes); // assuming it was allocated externally
-        }
-    }
-
-    size_t size = sizeof(hdr_t) + bytes + sizeof(ftr_t);
-    if (size < bytes) { // Overflow
-        errno = ENOMEM;
-        return NULL;
-    }
-    if (hdr->base != hdr) {
-        // An allocation from memalign, so create another allocation and
-        // copy the data out.
-        void* newMem = g_malloc_dispatch->malloc(size);
-        if (newMem == NULL) {
-            return NULL;
-        }
-        memcpy(newMem, hdr, sizeof(hdr_t) + hdr->size);
-        g_malloc_dispatch->free(hdr->base);
-        hdr = static_cast<hdr_t*>(newMem);
-    } else {
-        hdr = static_cast<hdr_t*>(g_malloc_dispatch->realloc(hdr, size));
-    }
-    if (hdr) {
-        hdr->base = hdr;
-        hdr->bt_depth = GET_BACKTRACE(hdr->bt, MAX_BACKTRACE_DEPTH);
-        add(hdr, bytes);
-        return user(hdr);
-    }
-    return NULL;
-}
-
-extern "C" void* chk_calloc(size_t nmemb, size_t bytes) {
-//  log_message("%s: %s\n", __FILE__, __FUNCTION__);
-    if (DebugCallsDisabled()) {
-        return g_malloc_dispatch->calloc(nmemb, bytes);
-    }
-
-    size_t total_bytes = nmemb * bytes;
-    size_t size = sizeof(hdr_t) + total_bytes + sizeof(ftr_t);
-    if (size < total_bytes || (nmemb && SIZE_MAX / nmemb < bytes)) { // Overflow
-        errno = ENOMEM;
-        return NULL;
-    }
-    hdr_t* hdr = static_cast<hdr_t*>(g_malloc_dispatch->calloc(1, size));
-    if (hdr) {
-        hdr->base = hdr;
-        hdr->bt_depth = GET_BACKTRACE(hdr->bt, MAX_BACKTRACE_DEPTH);
-        add(hdr, total_bytes);
-        return user(hdr);
-    }
-    return NULL;
-}
-
-extern "C" size_t chk_malloc_usable_size(const void* ptr) {
-    if (DebugCallsDisabled()) {
-        return g_malloc_dispatch->malloc_usable_size(ptr);
-    }
-
-    // malloc_usable_size returns 0 for NULL and unknown blocks.
-    if (ptr == NULL)
-        return 0;
-
-    const hdr_t* hdr = const_meta(ptr);
-
-    // The sentinel tail is written just after the request block bytes
-    // so there is no extra room we can report here.
-    return hdr->size;
-}
-
-extern "C" struct mallinfo chk_mallinfo() {
-  return g_malloc_dispatch->mallinfo();
-}
-
-extern "C" int chk_posix_memalign(void** memptr, size_t alignment, size_t size) {
-  if (DebugCallsDisabled()) {
-    return g_malloc_dispatch->posix_memalign(memptr, alignment, size);
-  }
-
-  if (!powerof2(alignment)) {
-    return EINVAL;
-  }
-  int saved_errno = errno;
-  *memptr = chk_memalign(alignment, size);
-  errno = saved_errno;
-  return (*memptr != NULL) ? 0 : ENOMEM;
-}
-
-#if defined(HAVE_DEPRECATED_MALLOC_FUNCS)
-extern "C" void* chk_pvalloc(size_t bytes) {
-  if (DebugCallsDisabled()) {
-    return g_malloc_dispatch->pvalloc(bytes);
-  }
-
-  size_t pagesize = getpagesize();
-  size_t size = BIONIC_ALIGN(bytes, pagesize);
-  if (size < bytes) { // Overflow
-    return NULL;
-  }
-  return chk_memalign(pagesize, size);
-}
-
-extern "C" void* chk_valloc(size_t size) {
-  if (DebugCallsDisabled()) {
-    return g_malloc_dispatch->valloc(size);
-  }
-  return chk_memalign(getpagesize(), size);
-}
-#endif
-
-static void ReportMemoryLeaks() {
-  ScopedDisableDebugCalls disable;
-
-  // Use /proc/self/exe link to obtain the program name for logging
-  // purposes. If it's not available, we set it to "<unknown>".
-  char exe[PATH_MAX];
-  int count;
-  if ((count = readlink("/proc/self/exe", exe, sizeof(exe) - 1)) == -1) {
-    strlcpy(exe, "<unknown>", sizeof(exe));
-  } else {
-    exe[count] = '\0';
-  }
-
-  if (g_allocated_block_count == 0) {
-    log_message("+++ %s did not leak", exe);
-    return;
-  }
-
-  size_t index = 1;
-  const size_t total = g_allocated_block_count;
-  while (head != NULL) {
-    int safe;
-    hdr_t* block = head;
-    log_message("+++ %s leaked block of size %d at %p (leak %d of %d)",
-                exe, block->size, user(block), index++, total);
-    if (del_leak(block, &safe) && g_backtrace_enabled) {
-      /* safe == 1, because the allocation is valid */
-      log_backtrace(block->bt, block->bt_depth);
-    }
-  }
-
-  while (backlog_head != NULL) {
-    del_from_backlog(backlog_tail);
-  }
-}
-
-pthread_key_t g_debug_calls_disabled;
-
-extern "C" bool malloc_debug_initialize(HashTable* hash_table, const MallocDebug* malloc_dispatch) {
-  g_hash_table = hash_table;
-  g_malloc_dispatch = malloc_dispatch;
-
-  pthread_key_create(&g_debug_calls_disabled, NULL);
-
-  char debug_backlog[PROP_VALUE_MAX];
-  if (__system_property_get("libc.debug.malloc.backlog", debug_backlog)) {
-    g_malloc_debug_backlog = atoi(debug_backlog);
-    info_log("%s: setting backlog length to %d\n", getprogname(), g_malloc_debug_backlog);
-  }
-
-  // Check if backtracing should be disabled.
-  char env[PROP_VALUE_MAX];
-  if (__system_property_get("libc.debug.malloc.nobacktrace", env) && atoi(env) != 0) {
-    g_backtrace_enabled = false;
-    __libc_format_log(ANDROID_LOG_INFO, "libc", "not gathering backtrace information\n");
-  }
-
-  if (g_backtrace_enabled) {
-    backtrace_startup();
-  }
-
-  return true;
-}
-
-extern "C" void malloc_debug_finalize(int malloc_debug_level) {
-  // We only track leaks at level 10.
-  if (malloc_debug_level == 10) {
-    ReportMemoryLeaks();
-  }
-  if (g_backtrace_enabled) {
-    backtrace_shutdown();
-  }
-
-  pthread_setspecific(g_debug_calls_disabled, NULL);
-}
diff --git a/libc/bionic/malloc_debug_common.cpp b/libc/bionic/malloc_debug_common.cpp
deleted file mode 100644
index ee796c6..0000000
--- a/libc/bionic/malloc_debug_common.cpp
+++ /dev/null
@@ -1,527 +0,0 @@
-/*
- * Copyright (C) 2009 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.
- */
-
-// Contains definition of structures, global variables, and implementation of
-// routines that are used by malloc leak detection code and other components in
-// the system. The trick is that some components expect these data and
-// routines to be defined / implemented in libc.so, regardless whether or not
-// malloc leak detection code is going to run. To make things even more tricky,
-// malloc leak detection code, implemented in libc_malloc_debug.so also
-// requires access to these variables and routines (to fill allocation entry
-// hash table, for example). So, all relevant variables and routines are
-// defined / implemented here and exported to all, leak detection code and
-// other components via dynamic (libc.so), or static (libc.a) linking.
-
-#include "malloc_debug_common.h"
-
-#include <pthread.h>
-#include <stdlib.h>
-#include <string.h>
-#include <unistd.h>
-
-#include "private/ScopedPthreadMutexLocker.h"
-
-#if defined(USE_JEMALLOC)
-#include "jemalloc.h"
-#define Malloc(function)  je_ ## function
-#elif defined(USE_DLMALLOC)
-#include "dlmalloc.h"
-#define Malloc(function)  dl ## function
-#else
-#error "Either one of USE_DLMALLOC or USE_JEMALLOC must be defined."
-#endif
-
-// In a VM process, this is set to 1 after fork()ing out of zygote.
-int gMallocLeakZygoteChild = 0;
-
-static HashTable g_hash_table;
-
-// Support for malloc debugging.
-// Table for dispatching malloc calls, initialized with default dispatchers.
-static const MallocDebug __libc_malloc_default_dispatch __attribute__((aligned(32))) = {
-  Malloc(calloc),
-  Malloc(free),
-  Malloc(mallinfo),
-  Malloc(malloc),
-  Malloc(malloc_usable_size),
-  Malloc(memalign),
-  Malloc(posix_memalign),
-#if defined(HAVE_DEPRECATED_MALLOC_FUNCS)
-  Malloc(pvalloc),
-#endif
-  Malloc(realloc),
-#if defined(HAVE_DEPRECATED_MALLOC_FUNCS)
-  Malloc(valloc),
-#endif
-};
-
-// Selector of dispatch table to use for dispatching malloc calls.
-static const MallocDebug* __libc_malloc_dispatch = &__libc_malloc_default_dispatch;
-
-// Handle to shared library where actual memory allocation is implemented.
-// This library is loaded and memory allocation calls are redirected there
-// when libc.debug.malloc environment variable contains value other than
-// zero:
-// 1  - For memory leak detections.
-// 5  - For filling allocated / freed memory with patterns defined by
-//      CHK_SENTINEL_VALUE, and CHK_FILL_FREE macros.
-// 10 - For adding pre-, and post- allocation stubs in order to detect
-//      buffer overruns.
-// Note that emulator's memory allocation instrumentation is not controlled by
-// libc.debug.malloc value, but rather by emulator, started with -memcheck
-// option. Note also, that if emulator has started with -memcheck option,
-// emulator's instrumented memory allocation will take over value saved in
-// libc.debug.malloc. In other words, if emulator has started with -memcheck
-// option, libc.debug.malloc value is ignored.
-// Actual functionality for debug levels 1-10 is implemented in
-// libc_malloc_debug_leak.so, while functionality for emulator's instrumented
-// allocations is implemented in libc_malloc_debug_qemu.so and can be run inside
-// the emulator only.
-#if !defined(LIBC_STATIC)
-static void* libc_malloc_impl_handle = NULL;
-#endif
-
-
-// The value of libc.debug.malloc.
-#if !defined(LIBC_STATIC)
-static int g_malloc_debug_level = 0;
-#endif
-
-// =============================================================================
-// output functions
-// =============================================================================
-
-static int hash_entry_compare(const void* arg1, const void* arg2) {
-  int result;
-
-  const HashEntry* e1 = *static_cast<HashEntry* const*>(arg1);
-  const HashEntry* e2 = *static_cast<HashEntry* const*>(arg2);
-
-  // if one or both arg pointers are null, deal gracefully
-  if (e1 == NULL) {
-    result = (e2 == NULL) ? 0 : 1;
-  } else if (e2 == NULL) {
-    result = -1;
-  } else {
-    size_t nbAlloc1 = e1->allocations;
-    size_t nbAlloc2 = e2->allocations;
-    size_t size1 = e1->size & ~SIZE_FLAG_MASK;
-    size_t size2 = e2->size & ~SIZE_FLAG_MASK;
-    size_t alloc1 = nbAlloc1 * size1;
-    size_t alloc2 = nbAlloc2 * size2;
-
-    // sort in descending order by:
-    // 1) total size
-    // 2) number of allocations
-    //
-    // This is used for sorting, not determination of equality, so we don't
-    // need to compare the bit flags.
-    if (alloc1 > alloc2) {
-      result = -1;
-    } else if (alloc1 < alloc2) {
-      result = 1;
-    } else {
-      if (nbAlloc1 > nbAlloc2) {
-        result = -1;
-      } else if (nbAlloc1 < nbAlloc2) {
-        result = 1;
-      } else {
-        result = 0;
-      }
-    }
-  }
-  return result;
-}
-
-// Retrieve native heap information.
-//
-// "*info" is set to a buffer we allocate
-// "*overallSize" is set to the size of the "info" buffer
-// "*infoSize" is set to the size of a single entry
-// "*totalMemory" is set to the sum of all allocations we're tracking; does
-//   not include heap overhead
-// "*backtraceSize" is set to the maximum number of entries in the back trace
-
-// =============================================================================
-// Exported for use by ddms.
-// =============================================================================
-extern "C" void get_malloc_leak_info(uint8_t** info, size_t* overallSize,
-    size_t* infoSize, size_t* totalMemory, size_t* backtraceSize) {
-  // Don't do anything if we have invalid arguments.
-  if (info == NULL || overallSize == NULL || infoSize == NULL ||
-    totalMemory == NULL || backtraceSize == NULL) {
-    return;
-  }
-  *totalMemory = 0;
-
-  ScopedPthreadMutexLocker locker(&g_hash_table.lock);
-  if (g_hash_table.count == 0) {
-    *info = NULL;
-    *overallSize = 0;
-    *infoSize = 0;
-    *backtraceSize = 0;
-    return;
-  }
-
-  HashEntry** list = static_cast<HashEntry**>(Malloc(malloc)(sizeof(void*) * g_hash_table.count));
-
-  // Get the entries into an array to be sorted.
-  size_t index = 0;
-  for (size_t i = 0 ; i < HASHTABLE_SIZE ; ++i) {
-    HashEntry* entry = g_hash_table.slots[i];
-    while (entry != NULL) {
-      list[index] = entry;
-      *totalMemory = *totalMemory + ((entry->size & ~SIZE_FLAG_MASK) * entry->allocations);
-      index++;
-      entry = entry->next;
-    }
-  }
-
-  // XXX: the protocol doesn't allow variable size for the stack trace (yet)
-  *infoSize = (sizeof(size_t) * 2) + (sizeof(uintptr_t) * BACKTRACE_SIZE);
-  *overallSize = *infoSize * g_hash_table.count;
-  *backtraceSize = BACKTRACE_SIZE;
-
-  // now get a byte array big enough for this
-  *info = static_cast<uint8_t*>(Malloc(malloc)(*overallSize));
-  if (*info == NULL) {
-    *overallSize = 0;
-    Malloc(free)(list);
-    return;
-  }
-
-  qsort(list, g_hash_table.count, sizeof(void*), hash_entry_compare);
-
-  uint8_t* head = *info;
-  const size_t count = g_hash_table.count;
-  for (size_t i = 0 ; i < count ; ++i) {
-    HashEntry* entry = list[i];
-    size_t entrySize = (sizeof(size_t) * 2) + (sizeof(uintptr_t) * entry->numEntries);
-    if (entrySize < *infoSize) {
-      // We're writing less than a full entry, clear out the rest.
-      memset(head + entrySize, 0, *infoSize - entrySize);
-    } else {
-      // Make sure the amount we're copying doesn't exceed the limit.
-      entrySize = *infoSize;
-    }
-    memcpy(head, &(entry->size), entrySize);
-    head += *infoSize;
-  }
-
-  Malloc(free)(list);
-}
-
-extern "C" void free_malloc_leak_info(uint8_t* info) {
-  Malloc(free)(info);
-}
-
-// =============================================================================
-// Allocation functions
-// =============================================================================
-extern "C" void* calloc(size_t n_elements, size_t elem_size) {
-  return __libc_malloc_dispatch->calloc(n_elements, elem_size);
-}
-
-extern "C" void free(void* mem) {
-  __libc_malloc_dispatch->free(mem);
-}
-
-extern "C" struct mallinfo mallinfo() {
-  return __libc_malloc_dispatch->mallinfo();
-}
-
-extern "C" void* malloc(size_t bytes) {
-  return __libc_malloc_dispatch->malloc(bytes);
-}
-
-extern "C" size_t malloc_usable_size(const void* mem) {
-  return __libc_malloc_dispatch->malloc_usable_size(mem);
-}
-
-extern "C" void* memalign(size_t alignment, size_t bytes) {
-  return __libc_malloc_dispatch->memalign(alignment, bytes);
-}
-
-extern "C" int posix_memalign(void** memptr, size_t alignment, size_t size) {
-  return __libc_malloc_dispatch->posix_memalign(memptr, alignment, size);
-}
-
-#if defined(HAVE_DEPRECATED_MALLOC_FUNCS)
-extern "C" void* pvalloc(size_t bytes) {
-  return __libc_malloc_dispatch->pvalloc(bytes);
-}
-#endif
-
-extern "C" void* realloc(void* oldMem, size_t bytes) {
-  return __libc_malloc_dispatch->realloc(oldMem, bytes);
-}
-
-#if defined(HAVE_DEPRECATED_MALLOC_FUNCS)
-extern "C" void* valloc(size_t bytes) {
-  return __libc_malloc_dispatch->valloc(bytes);
-}
-#endif
-
-// We implement malloc debugging only in libc.so, so the code below
-// must be excluded if we compile this file for static libc.a
-#ifndef LIBC_STATIC
-#include <sys/system_properties.h>
-#include <dlfcn.h>
-#include <stdio.h>
-#include "private/libc_logging.h"
-
-template<typename FunctionType>
-static void InitMallocFunction(void* malloc_impl_handler, FunctionType* func, const char* prefix, const char* suffix) {
-  char symbol[128];
-  snprintf(symbol, sizeof(symbol), "%s_%s", prefix, suffix);
-  *func = reinterpret_cast<FunctionType>(dlsym(malloc_impl_handler, symbol));
-  if (*func == NULL) {
-    error_log("%s: dlsym(\"%s\") failed", getprogname(), symbol);
-  }
-}
-
-static void InitMalloc(void* malloc_impl_handler, MallocDebug* table, const char* prefix) {
-  __libc_format_log(ANDROID_LOG_INFO, "libc", "%s: using libc.debug.malloc %d (%s)\n",
-                    getprogname(), g_malloc_debug_level, prefix);
-
-  InitMallocFunction<MallocDebugCalloc>(malloc_impl_handler, &table->calloc, prefix, "calloc");
-  InitMallocFunction<MallocDebugFree>(malloc_impl_handler, &table->free, prefix, "free");
-  InitMallocFunction<MallocDebugMallinfo>(malloc_impl_handler, &table->mallinfo, prefix, "mallinfo");
-  InitMallocFunction<MallocDebugMalloc>(malloc_impl_handler, &table->malloc, prefix, "malloc");
-  InitMallocFunction<MallocDebugMallocUsableSize>(malloc_impl_handler, &table->malloc_usable_size, prefix, "malloc_usable_size");
-  InitMallocFunction<MallocDebugMemalign>(malloc_impl_handler, &table->memalign, prefix, "memalign");
-  InitMallocFunction<MallocDebugPosixMemalign>(malloc_impl_handler, &table->posix_memalign, prefix, "posix_memalign");
-#if defined(HAVE_DEPRECATED_MALLOC_FUNCS)
-  InitMallocFunction<MallocDebugPvalloc>(malloc_impl_handler, &table->pvalloc, prefix, "pvalloc");
-#endif
-  InitMallocFunction<MallocDebugRealloc>(malloc_impl_handler, &table->realloc, prefix, "realloc");
-#if defined(HAVE_DEPRECATED_MALLOC_FUNCS)
-  InitMallocFunction<MallocDebugValloc>(malloc_impl_handler, &table->valloc, prefix, "valloc");
-#endif
-}
-
-// Initializes memory allocation framework once per process.
-static void malloc_init_impl() {
-  const char* so_name = NULL;
-  MallocDebugInit malloc_debug_initialize = NULL;
-  unsigned int qemu_running = 0;
-  unsigned int memcheck_enabled = 0;
-  char env[PROP_VALUE_MAX];
-  char memcheck_tracing[PROP_VALUE_MAX];
-  char debug_program[PROP_VALUE_MAX];
-
-  // Get custom malloc debug level. Note that emulator started with
-  // memory checking option will have priority over debug level set in
-  // libc.debug.malloc system property.
-  if (__system_property_get("ro.kernel.qemu", env) && atoi(env)) {
-    qemu_running = 1;
-    if (__system_property_get("ro.kernel.memcheck", memcheck_tracing)) {
-      if (memcheck_tracing[0] != '0') {
-        // Emulator has started with memory tracing enabled. Enforce it.
-        g_malloc_debug_level = 20;
-        memcheck_enabled = 1;
-      }
-    }
-  }
-
-  // If debug level has not been set by memcheck option in the emulator,
-  // lets grab it from libc.debug.malloc system property.
-  if (g_malloc_debug_level == 0 && __system_property_get("libc.debug.malloc", env)) {
-    g_malloc_debug_level = atoi(env);
-  }
-
-  // Debug level 0 means that we should use default allocation routines.
-  if (g_malloc_debug_level == 0) {
-    return;
-  }
-
-  // If libc.debug.malloc.program is set and is not a substring of progname,
-  // then exit.
-  if (__system_property_get("libc.debug.malloc.program", debug_program)) {
-    if (!strstr(getprogname(), debug_program)) {
-      return;
-    }
-  }
-
-  // mksh is way too leaky. http://b/7291287.
-  if (g_malloc_debug_level >= 10) {
-    if (strcmp(getprogname(), "sh") == 0 || strcmp(getprogname(), "/system/bin/sh") == 0) {
-      return;
-    }
-  }
-
-  // Choose the appropriate .so for the requested debug level.
-  switch (g_malloc_debug_level) {
-    case 1:
-    case 5:
-    case 10:
-      so_name = "libc_malloc_debug_leak.so";
-      break;
-    case 20:
-      // Quick check: debug level 20 can only be handled in emulator.
-      if (!qemu_running) {
-        error_log("%s: Debug level %d can only be set in emulator\n",
-                  getprogname(), g_malloc_debug_level);
-        return;
-      }
-      // Make sure that memory checking has been enabled in emulator.
-      if (!memcheck_enabled) {
-        error_log("%s: Memory checking is not enabled in the emulator\n", getprogname());
-        return;
-      }
-      so_name = "libc_malloc_debug_qemu.so";
-      break;
-    default:
-      error_log("%s: Debug level %d is unknown\n", getprogname(), g_malloc_debug_level);
-      return;
-  }
-
-  // Load .so that implements the required malloc debugging functionality.
-  void* malloc_impl_handle = dlopen(so_name, RTLD_NOW);
-  if (malloc_impl_handle == NULL) {
-    error_log("%s: Missing module %s required for malloc debug level %d: %s",
-              getprogname(), so_name, g_malloc_debug_level, dlerror());
-    return;
-  }
-
-  // Initialize malloc debugging in the loaded module.
-  malloc_debug_initialize = reinterpret_cast<MallocDebugInit>(dlsym(malloc_impl_handle,
-                                                                    "malloc_debug_initialize"));
-  if (malloc_debug_initialize == NULL) {
-    error_log("%s: Initialization routine is not found in %s\n", getprogname(), so_name);
-    dlclose(malloc_impl_handle);
-    return;
-  }
-  if (!malloc_debug_initialize(&g_hash_table, &__libc_malloc_default_dispatch)) {
-    dlclose(malloc_impl_handle);
-    return;
-  }
-
-  if (g_malloc_debug_level == 20) {
-    // For memory checker we need to do extra initialization.
-    typedef int (*MemCheckInit)(int, const char*);
-    MemCheckInit memcheck_initialize =
-      reinterpret_cast<MemCheckInit>(dlsym(malloc_impl_handle, "memcheck_initialize"));
-    if (memcheck_initialize == NULL) {
-      error_log("%s: memcheck_initialize routine is not found in %s\n",
-                getprogname(), so_name);
-      dlclose(malloc_impl_handle);
-      return;
-    }
-
-    if (memcheck_initialize(MALLOC_ALIGNMENT, memcheck_tracing)) {
-      dlclose(malloc_impl_handle);
-      return;
-    }
-  }
-
-  // No need to init the dispatch table because we can only get
-  // here if debug level is 1, 5, 10, or 20.
-  static MallocDebug malloc_dispatch_table __attribute__((aligned(32)));
-  switch (g_malloc_debug_level) {
-    case 1:
-      InitMalloc(malloc_impl_handle, &malloc_dispatch_table, "leak");
-      break;
-    case 5:
-      InitMalloc(malloc_impl_handle, &malloc_dispatch_table, "fill");
-      break;
-    case 10:
-      InitMalloc(malloc_impl_handle, &malloc_dispatch_table, "chk");
-      break;
-    case 20:
-      InitMalloc(malloc_impl_handle, &malloc_dispatch_table, "qemu_instrumented");
-      break;
-    default:
-      break;
-  }
-
-  // Make sure dispatch table is initialized
-  if ((malloc_dispatch_table.calloc == NULL) ||
-      (malloc_dispatch_table.free == NULL) ||
-      (malloc_dispatch_table.mallinfo == NULL) ||
-      (malloc_dispatch_table.malloc == NULL) ||
-      (malloc_dispatch_table.malloc_usable_size == NULL) ||
-      (malloc_dispatch_table.memalign == NULL) ||
-      (malloc_dispatch_table.posix_memalign == NULL) ||
-#if defined(HAVE_DEPRECATED_MALLOC_FUNCS)
-      (malloc_dispatch_table.pvalloc == NULL) ||
-#endif
-      (malloc_dispatch_table.realloc == NULL)
-#if defined(HAVE_DEPRECATED_MALLOC_FUNCS)
-      || (malloc_dispatch_table.valloc == NULL)
-#endif
-      ) {
-    error_log("%s: some symbols for libc.debug.malloc level %d were not found (see above)",
-              getprogname(), g_malloc_debug_level);
-    dlclose(malloc_impl_handle);
-  } else {
-    __libc_malloc_dispatch = &malloc_dispatch_table;
-    libc_malloc_impl_handle = malloc_impl_handle;
-  }
-}
-
-static void malloc_fini_impl() {
-  // Our BSD stdio implementation doesn't close the standard streams, it only flushes them.
-  // And it doesn't do that until its atexit handler is run, and we run first!
-  // It's great that other unclosed FILE*s show up as malloc leaks, but we need to manually
-  // clean up the standard streams ourselves.
-  fclose(stdin);
-  fclose(stdout);
-  fclose(stderr);
-
-  if (libc_malloc_impl_handle != NULL) {
-    MallocDebugFini malloc_debug_finalize =
-      reinterpret_cast<MallocDebugFini>(dlsym(libc_malloc_impl_handle, "malloc_debug_finalize"));
-    if (malloc_debug_finalize != NULL) {
-      malloc_debug_finalize(g_malloc_debug_level);
-    }
-  }
-}
-
-#endif  // !LIBC_STATIC
-
-// Initializes memory allocation framework.
-// This routine is called from __libc_init routines implemented
-// in libc_init_static.c and libc_init_dynamic.c files.
-extern "C" __LIBC_HIDDEN__ void malloc_debug_init() {
-#if !defined(LIBC_STATIC)
-  static pthread_once_t malloc_init_once_ctl = PTHREAD_ONCE_INIT;
-  if (pthread_once(&malloc_init_once_ctl, malloc_init_impl)) {
-    error_log("Unable to initialize malloc_debug component.");
-  }
-#endif  // !LIBC_STATIC
-}
-
-extern "C" __LIBC_HIDDEN__ void malloc_debug_fini() {
-#if !defined(LIBC_STATIC)
-  static pthread_once_t malloc_fini_once_ctl = PTHREAD_ONCE_INIT;
-  if (pthread_once(&malloc_fini_once_ctl, malloc_fini_impl)) {
-    error_log("Unable to finalize malloc_debug component.");
-  }
-#endif  // !LIBC_STATIC
-}
diff --git a/libc/bionic/malloc_debug_common.h b/libc/bionic/malloc_debug_common.h
deleted file mode 100644
index 5c73da3..0000000
--- a/libc/bionic/malloc_debug_common.h
+++ /dev/null
@@ -1,122 +0,0 @@
-/*
- * Copyright (C) 2009 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.
- */
-
-/*
- * Contains declarations of types and constants used by malloc leak
- * detection code in both, libc and libc_malloc_debug libraries.
- */
-#ifndef MALLOC_DEBUG_COMMON_H
-#define MALLOC_DEBUG_COMMON_H
-
-#include <pthread.h>
-#include <stdint.h>
-#include <stdlib.h>
-
-#include "private/bionic_config.h"
-#include "private/libc_logging.h"
-
-#define HASHTABLE_SIZE      1543
-#define BACKTRACE_SIZE      32
-/* flag definitions, currently sharing storage with "size" */
-#define SIZE_FLAG_ZYGOTE_CHILD  (1<<31)
-#define SIZE_FLAG_MASK          (SIZE_FLAG_ZYGOTE_CHILD)
-
-// This must match the alignment used by the malloc implementation.
-#ifndef MALLOC_ALIGNMENT
-#define MALLOC_ALIGNMENT ((size_t)(2 * sizeof(void *)))
-#endif
-
-// =============================================================================
-// Structures
-// =============================================================================
-
-struct HashEntry {
-    size_t slot;
-    HashEntry* prev;
-    HashEntry* next;
-    size_t numEntries;
-    // fields above "size" are NOT sent to the host
-    size_t size;
-    size_t allocations;
-    uintptr_t backtrace[0];
-};
-
-struct HashTable {
-    pthread_mutex_t lock;
-    size_t count;
-    HashEntry* slots[HASHTABLE_SIZE];
-};
-
-/* Entry in malloc dispatch table. */
-typedef void* (*MallocDebugCalloc)(size_t, size_t);
-typedef void (*MallocDebugFree)(void*);
-typedef struct mallinfo (*MallocDebugMallinfo)();
-typedef void* (*MallocDebugMalloc)(size_t);
-typedef size_t (*MallocDebugMallocUsableSize)(const void*);
-typedef void* (*MallocDebugMemalign)(size_t, size_t);
-typedef int (*MallocDebugPosixMemalign)(void**, size_t, size_t);
-#if defined(HAVE_DEPRECATED_MALLOC_FUNCS)
-typedef void* (*MallocDebugPvalloc)(size_t);
-#endif
-typedef void* (*MallocDebugRealloc)(void*, size_t);
-#if defined(HAVE_DEPRECATED_MALLOC_FUNCS)
-typedef void* (*MallocDebugValloc)(size_t);
-#endif
-
-struct MallocDebug {
-  MallocDebugCalloc calloc;
-  MallocDebugFree free;
-  MallocDebugMallinfo mallinfo;
-  MallocDebugMalloc malloc;
-  MallocDebugMallocUsableSize malloc_usable_size;
-  MallocDebugMemalign memalign;
-  MallocDebugPosixMemalign posix_memalign;
-#if defined(HAVE_DEPRECATED_MALLOC_FUNCS)
-  MallocDebugPvalloc pvalloc;
-#endif
-  MallocDebugRealloc realloc;
-#if defined(HAVE_DEPRECATED_MALLOC_FUNCS)
-  MallocDebugValloc valloc;
-#endif
-};
-
-typedef bool (*MallocDebugInit)(HashTable*, const MallocDebug*);
-typedef void (*MallocDebugFini)(int);
-
-// =============================================================================
-// log functions
-// =============================================================================
-
-#define debug_log(format, ...)  \
-    __libc_format_log(ANDROID_LOG_DEBUG, "malloc_leak_check", (format), ##__VA_ARGS__ )
-#define error_log(format, ...)  \
-    __libc_format_log(ANDROID_LOG_ERROR, "malloc_leak_check", (format), ##__VA_ARGS__ )
-#define info_log(format, ...)  \
-    __libc_format_log(ANDROID_LOG_INFO, "malloc_leak_check", (format), ##__VA_ARGS__ )
-
-#endif  // MALLOC_DEBUG_COMMON_H
diff --git a/libc/bionic/malloc_debug_leak.cpp b/libc/bionic/malloc_debug_leak.cpp
deleted file mode 100644
index 6a46667..0000000
--- a/libc/bionic/malloc_debug_leak.cpp
+++ /dev/null
@@ -1,525 +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 <arpa/inet.h>
-#include <dlfcn.h>
-#include <errno.h>
-#include <fcntl.h>
-#include <pthread.h>
-#include <stdarg.h>
-#include <stddef.h>
-#include <stdint.h>
-#include <stdio.h>
-#include <stdlib.h>
-#include <string.h>
-#include <sys/param.h>
-#include <sys/select.h>
-#include <sys/socket.h>
-#include <sys/system_properties.h>
-#include <sys/types.h>
-#include <sys/un.h>
-#include <unistd.h>
-#include <unwind.h>
-
-#include "debug_stacktrace.h"
-#include "malloc_debug_backtrace.h"
-#include "malloc_debug_common.h"
-#include "malloc_debug_disable.h"
-
-#include "private/bionic_macros.h"
-#include "private/libc_logging.h"
-#include "private/ScopedPthreadMutexLocker.h"
-
-extern int gMallocLeakZygoteChild;
-extern HashTable* g_hash_table;
-extern const MallocDebug* g_malloc_dispatch;
-
-// =============================================================================
-// stack trace functions
-// =============================================================================
-
-#define GUARD               0x48151642
-#define DEBUG               0
-
-// =============================================================================
-// Structures
-// =============================================================================
-
-struct AllocationEntry {
-    HashEntry* entry;
-    uint32_t guard;
-} __attribute__((aligned(MALLOC_ALIGNMENT)));
-
-static inline AllocationEntry* to_header(void* mem) {
-  return reinterpret_cast<AllocationEntry*>(mem) - 1;
-}
-
-static inline const AllocationEntry* const_to_header(const void* mem) {
-  return reinterpret_cast<const AllocationEntry*>(mem) - 1;
-}
-
-// =============================================================================
-// Hash Table functions
-// =============================================================================
-
-static uint32_t get_hash(uintptr_t* backtrace, size_t numEntries) {
-    if (backtrace == NULL) return 0;
-
-    int hash = 0;
-    size_t i;
-    for (i = 0 ; i < numEntries ; i++) {
-        hash = (hash * 33) + (backtrace[i] >> 2);
-    }
-
-    return hash;
-}
-
-static HashEntry* find_entry(HashTable* table, int slot,
-                             uintptr_t* backtrace, size_t numEntries, size_t size) {
-    HashEntry* entry = table->slots[slot];
-    while (entry != NULL) {
-        //debug_log("backtrace: %p, entry: %p entry->backtrace: %p\n",
-        //        backtrace, entry, (entry != NULL) ? entry->backtrace : NULL);
-        /*
-         * See if the entry matches exactly.  We compare the "size" field,
-         * including the flag bits.
-         */
-        if (entry->size == size && entry->numEntries == numEntries &&
-                !memcmp(backtrace, entry->backtrace, numEntries * sizeof(uintptr_t))) {
-            return entry;
-        }
-
-        entry = entry->next;
-    }
-
-    return NULL;
-}
-
-static HashEntry* record_backtrace(uintptr_t* backtrace, size_t numEntries, size_t size) {
-    size_t hash = get_hash(backtrace, numEntries);
-    size_t slot = hash % HASHTABLE_SIZE;
-
-    if (size & SIZE_FLAG_MASK) {
-        debug_log("malloc_debug: allocation %zx exceeds bit width\n", size);
-        abort();
-    }
-
-    if (gMallocLeakZygoteChild) {
-        size |= SIZE_FLAG_ZYGOTE_CHILD;
-    }
-
-    // Keep the lock held for as little time as possible to prevent deadlocks.
-    ScopedPthreadMutexLocker locker(&g_hash_table->lock);
-    HashEntry* entry = find_entry(g_hash_table, slot, backtrace, numEntries, size);
-    if (entry != NULL) {
-        entry->allocations++;
-    } else {
-        // create a new entry
-        entry = static_cast<HashEntry*>(g_malloc_dispatch->malloc(sizeof(HashEntry) + numEntries*sizeof(uintptr_t)));
-        if (!entry) {
-            return NULL;
-        }
-        entry->allocations = 1;
-        entry->slot = slot;
-        entry->prev = NULL;
-        entry->next = g_hash_table->slots[slot];
-        entry->numEntries = numEntries;
-        entry->size = size;
-
-        memcpy(entry->backtrace, backtrace, numEntries * sizeof(uintptr_t));
-
-        g_hash_table->slots[slot] = entry;
-
-        if (entry->next != NULL) {
-            entry->next->prev = entry;
-        }
-
-        // we just added an entry, increase the size of the hashtable
-        g_hash_table->count++;
-    }
-
-    return entry;
-}
-
-static int is_valid_entry(HashEntry* entry) {
-  if (entry != NULL) {
-    for (size_t i = 0; i < HASHTABLE_SIZE; ++i) {
-      HashEntry* e1 = g_hash_table->slots[i];
-      while (e1 != NULL) {
-        if (e1 == entry) {
-          return 1;
-        }
-        e1 = e1->next;
-      }
-    }
-  }
-  return 0;
-}
-
-static void remove_entry(HashEntry* entry) {
-  HashEntry* prev = entry->prev;
-  HashEntry* next = entry->next;
-
-  if (prev != NULL) entry->prev->next = next;
-  if (next != NULL) entry->next->prev = prev;
-
-  if (prev == NULL) {
-    // we are the head of the list. set the head to be next
-    g_hash_table->slots[entry->slot] = entry->next;
-  }
-
-  // we just removed and entry, decrease the size of the hashtable
-  g_hash_table->count--;
-}
-
-// =============================================================================
-// malloc fill functions
-// =============================================================================
-
-#define CHK_FILL_FREE           0xef
-#define CHK_SENTINEL_VALUE      0xeb
-
-extern "C" void* fill_calloc(size_t n_elements, size_t elem_size) {
-    return g_malloc_dispatch->calloc(n_elements, elem_size);
-}
-
-extern "C" void* fill_malloc(size_t bytes) {
-    void* buffer = g_malloc_dispatch->malloc(bytes);
-    if (buffer) {
-        memset(buffer, CHK_SENTINEL_VALUE, bytes);
-    }
-    return buffer;
-}
-
-extern "C" void fill_free(void* mem) {
-    size_t bytes = g_malloc_dispatch->malloc_usable_size(mem);
-    memset(mem, CHK_FILL_FREE, bytes);
-    g_malloc_dispatch->free(mem);
-}
-
-extern "C" void* fill_realloc(void* mem, size_t bytes) {
-    size_t oldSize = g_malloc_dispatch->malloc_usable_size(mem);
-    void* newMem = g_malloc_dispatch->realloc(mem, bytes);
-    if (newMem) {
-        // If this is larger than before, fill the extra with our pattern.
-        size_t newSize = g_malloc_dispatch->malloc_usable_size(newMem);
-        if (newSize > oldSize) {
-            memset(reinterpret_cast<void*>(reinterpret_cast<uintptr_t>(newMem)+oldSize), CHK_FILL_FREE, newSize-oldSize);
-        }
-    }
-    return newMem;
-}
-
-extern "C" void* fill_memalign(size_t alignment, size_t bytes) {
-    void* buffer = g_malloc_dispatch->memalign(alignment, bytes);
-    if (buffer) {
-        memset(buffer, CHK_SENTINEL_VALUE, bytes);
-    }
-    return buffer;
-}
-
-extern "C" size_t fill_malloc_usable_size(const void* mem) {
-    // Since we didn't allocate extra bytes before or after, we can
-    // report the normal usable size here.
-    return g_malloc_dispatch->malloc_usable_size(mem);
-}
-
-extern "C" struct mallinfo fill_mallinfo() {
-  return g_malloc_dispatch->mallinfo();
-}
-
-extern "C" int fill_posix_memalign(void** memptr, size_t alignment, size_t size) {
-  if (!powerof2(alignment)) {
-    return EINVAL;
-  }
-  int saved_errno = errno;
-  *memptr = fill_memalign(alignment, size);
-  errno = saved_errno;
-  return (*memptr != NULL) ? 0 : ENOMEM;
-}
-
-#if defined(HAVE_DEPRECATED_MALLOC_FUNCS)
-extern "C" void* fill_pvalloc(size_t bytes) {
-  size_t pagesize = getpagesize();
-  size_t size = BIONIC_ALIGN(bytes, pagesize);
-  if (size < bytes) { // Overflow
-    return NULL;
-  }
-  return fill_memalign(pagesize, size);
-}
-
-extern "C" void* fill_valloc(size_t size) {
-  return fill_memalign(getpagesize(), size);
-}
-#endif
-
-// =============================================================================
-// malloc leak functions
-// =============================================================================
-
-static uint32_t MEMALIGN_GUARD      = 0xA1A41520;
-
-extern "C" void* leak_malloc(size_t bytes) {
-    if (DebugCallsDisabled()) {
-        return g_malloc_dispatch->malloc(bytes);
-    }
-
-    // allocate enough space infront of the allocation to store the pointer for
-    // the alloc structure. This will making free'ing the structer really fast!
-
-    // 1. allocate enough memory and include our header
-    // 2. set the base pointer to be right after our header
-
-    size_t size = bytes + sizeof(AllocationEntry);
-    if (size < bytes) { // Overflow.
-        errno = ENOMEM;
-        return NULL;
-    }
-
-    void* base = g_malloc_dispatch->malloc(size);
-    if (base != NULL) {
-        uintptr_t backtrace[BACKTRACE_SIZE];
-        size_t numEntries = GET_BACKTRACE(backtrace, BACKTRACE_SIZE);
-
-        AllocationEntry* header = reinterpret_cast<AllocationEntry*>(base);
-        header->entry = record_backtrace(backtrace, numEntries, bytes);
-        header->guard = GUARD;
-
-        // now increment base to point to after our header.
-        // this should just work since our header is 8 bytes.
-        base = reinterpret_cast<AllocationEntry*>(base) + 1;
-    }
-
-    return base;
-}
-
-extern "C" void leak_free(void* mem) {
-  if (DebugCallsDisabled()) {
-    return g_malloc_dispatch->free(mem);
-  }
-
-  if (mem == NULL) {
-    return;
-  }
-
-  // check the guard to make sure it is valid
-  AllocationEntry* header = to_header(mem);
-
-  if (header->guard != GUARD) {
-    // could be a memaligned block
-    if (header->guard == MEMALIGN_GUARD) {
-      // For memaligned blocks, header->entry points to the memory
-      // allocated through leak_malloc.
-      header = to_header(header->entry);
-    }
-  }
-
-  ScopedPthreadMutexLocker locker(&g_hash_table->lock);
-  if (header->guard == GUARD || is_valid_entry(header->entry)) {
-    // decrement the allocations
-    HashEntry* entry = header->entry;
-    entry->allocations--;
-    if (entry->allocations <= 0) {
-      remove_entry(entry);
-      g_malloc_dispatch->free(entry);
-    }
-
-    // now free the memory!
-    g_malloc_dispatch->free(header);
-  } else {
-    debug_log("WARNING bad header guard: '0x%x'! and invalid entry: %p\n",
-              header->guard, header->entry);
-  }
-}
-
-extern "C" void* leak_calloc(size_t n_elements, size_t elem_size) {
-    if (DebugCallsDisabled()) {
-        return g_malloc_dispatch->calloc(n_elements, elem_size);
-    }
-
-    // Fail on overflow - just to be safe even though this code runs only
-    // within the debugging C library, not the production one.
-    if (n_elements && SIZE_MAX / n_elements < elem_size) {
-        errno = ENOMEM;
-        return NULL;
-    }
-    size_t size = n_elements * elem_size;
-    void* ptr  = leak_malloc(size);
-    if (ptr != NULL) {
-        memset(ptr, 0, size);
-    }
-    return ptr;
-}
-
-extern "C" size_t leak_malloc_usable_size(const void* mem) {
-    if (DebugCallsDisabled()) {
-        return g_malloc_dispatch->malloc_usable_size(mem);
-    }
-
-    if (mem == NULL) {
-        return 0;
-    }
-
-    // Check the guard to make sure it is valid.
-    const AllocationEntry* header = const_to_header(mem);
-
-    if (header->guard == MEMALIGN_GUARD) {
-        // If this is a memalign'd pointer, then grab the header from
-        // entry.
-        header = const_to_header(header->entry);
-    } else if (header->guard != GUARD) {
-        debug_log("WARNING bad header guard: '0x%x'! and invalid entry: %p\n",
-                  header->guard, header->entry);
-        return 0;
-    }
-
-    size_t ret = g_malloc_dispatch->malloc_usable_size(header);
-    if (ret != 0) {
-        // The usable area starts at 'mem' and stops at 'header+ret'.
-        return reinterpret_cast<uintptr_t>(header) + ret - reinterpret_cast<uintptr_t>(mem);
-    }
-    return 0;
-}
-
-extern "C" void* leak_realloc(void* oldMem, size_t bytes) {
-    if (DebugCallsDisabled()) {
-        return g_malloc_dispatch->realloc(oldMem, bytes);
-    }
-
-    if (oldMem == NULL) {
-        return leak_malloc(bytes);
-    }
-
-    void* newMem = NULL;
-    AllocationEntry* header = to_header(oldMem);
-    if (header->guard == MEMALIGN_GUARD) {
-        // Get the real header.
-        header = to_header(header->entry);
-    } else if (header->guard != GUARD) {
-        debug_log("WARNING bad header guard: '0x%x'! and invalid entry: %p\n",
-                   header->guard, header->entry);
-        errno = ENOMEM;
-        return NULL;
-    }
-
-    newMem = leak_malloc(bytes);
-    if (newMem != NULL) {
-        size_t oldSize = leak_malloc_usable_size(oldMem);
-        size_t copySize = (oldSize <= bytes) ? oldSize : bytes;
-        memcpy(newMem, oldMem, copySize);
-        leak_free(oldMem);
-    }
-
-    return newMem;
-}
-
-extern "C" void* leak_memalign(size_t alignment, size_t bytes) {
-    if (DebugCallsDisabled()) {
-        return g_malloc_dispatch->memalign(alignment, bytes);
-    }
-
-    // we can just use malloc
-    if (alignment <= MALLOC_ALIGNMENT) {
-        return leak_malloc(bytes);
-    }
-
-    // need to make sure it's a power of two
-    if (!powerof2(alignment)) {
-        alignment = BIONIC_ROUND_UP_POWER_OF_2(alignment);
-    }
-
-    // here, alignment is at least MALLOC_ALIGNMENT<<1 bytes
-    // we will align by at least MALLOC_ALIGNMENT bytes
-    // and at most alignment-MALLOC_ALIGNMENT bytes
-    size_t size = (alignment-MALLOC_ALIGNMENT) + bytes;
-    if (size < bytes) { // Overflow.
-        return NULL;
-    }
-
-    void* base = leak_malloc(size);
-    if (base != NULL) {
-        uintptr_t ptr = reinterpret_cast<uintptr_t>(base);
-        if ((ptr % alignment) == 0) {
-            return base;
-        }
-
-        // align the pointer
-        ptr += ((-ptr) % alignment);
-
-        // Already allocated enough space for the header. This assumes
-        // that the malloc alignment is at least 8, otherwise, this is
-        // not guaranteed to have the space for the header.
-        AllocationEntry* header = to_header(reinterpret_cast<void*>(ptr));
-        header->guard = MEMALIGN_GUARD;
-        header->entry = reinterpret_cast<HashEntry*>(base);
-
-        return reinterpret_cast<void*>(ptr);
-    }
-    return base;
-}
-
-extern "C" struct mallinfo leak_mallinfo() {
-  return g_malloc_dispatch->mallinfo();
-}
-
-extern "C" int leak_posix_memalign(void** memptr, size_t alignment, size_t size) {
-  if (DebugCallsDisabled()) {
-    return g_malloc_dispatch->posix_memalign(memptr, alignment, size);
-  }
-
-  if (!powerof2(alignment)) {
-    return EINVAL;
-  }
-  int saved_errno = errno;
-  *memptr = leak_memalign(alignment, size);
-  errno = saved_errno;
-  return (*memptr != NULL) ? 0 : ENOMEM;
-}
-
-#if defined(HAVE_DEPRECATED_MALLOC_FUNCS)
-extern "C" void* leak_pvalloc(size_t bytes) {
-  if (DebugCallsDisabled()) {
-    return g_malloc_dispatch->pvalloc(bytes);
-  }
-
-  size_t pagesize = getpagesize();
-  size_t size = BIONIC_ALIGN(bytes, pagesize);
-  if (size < bytes) { // Overflow
-    return NULL;
-  }
-  return leak_memalign(pagesize, size);
-}
-
-extern "C" void* leak_valloc(size_t size) {
-  if (DebugCallsDisabled()) {
-    return g_malloc_dispatch->valloc(size);
-  }
-
-  return leak_memalign(getpagesize(), size);
-}
-#endif
diff --git a/libc/bionic/malloc_debug_qemu.cpp b/libc/bionic/malloc_debug_qemu.cpp
deleted file mode 100644
index fa40b35..0000000
--- a/libc/bionic/malloc_debug_qemu.cpp
+++ /dev/null
@@ -1,1069 +0,0 @@
-/*
- * Copyright (C) 2009 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.
- */
-
-/*
- * Contains implementation of memory allocation routines instrumented for
- * usage in the emulator to detect memory allocation violations, such as
- * memory leaks, buffer overruns, etc.
- * Code, implemented here is intended to run in the emulated environment only,
- * and serves simply as hooks into memory allocation routines. Main job of this
- * code is to notify the emulator about memory being allocated/deallocated,
- * providing information about each allocation. The idea is that emulator will
- * keep list of currently allocated blocks, and, knowing boundaries of each
- * block it will be able to verify that ld/st access to these blocks don't step
- * over boundaries set for the user. To enforce that, each memory block
- * allocated by this code is guarded with "prefix" and "suffix" areas, so
- * every time emulator detects access to any of these guarding areas, it can be
- * considered as access violation.
- */
-
-#include <stdlib.h>
-#include <stddef.h>
-#include <stdio.h>
-#include <string.h>
-#include <fcntl.h>
-#include <sys/mman.h>
-#include <sys/param.h>
-#include <pthread.h>
-#include <unistd.h>
-#include <errno.h>
-#include "malloc_debug_common.h"
-#include "private/bionic_macros.h"
-#include "private/libc_logging.h"
-
-/* This file should be included into the build only when
- * MALLOC_QEMU_INSTRUMENT macro is defined. */
-#ifndef MALLOC_QEMU_INSTRUMENT
-#error MALLOC_QEMU_INSTRUMENT is not defined.
-#endif  // !MALLOC_QEMU_INSTRUMENT
-
-/* Controls access violation test performed to make sure that we catch AVs
- * all the time they occur. See test_access_violation for more info. This macro
- * is used for internal testing purposes and should always be set to zero for
- * the production builds. */
-#define TEST_ACCESS_VIOLATIONS  0
-
-// =============================================================================
-// Communication structures
-// =============================================================================
-
-/* Describes memory block allocated from the heap. This structure is passed
- * along with TRACE_DEV_REG_MALLOC event. This descriptor is used to inform
- * the emulator about new memory block being allocated from the heap. The entire
- * structure is initialized by the guest system before event is fired up. It is
- * important to remember that same structure (an exact copy, except for
- * replacing pointers with target_ulong) is also declared in the emulator's
- * sources (file memcheck/memcheck_common.h). So, every time a change is made to
- * any of these two declaration, another one must be also updated accordingly.
- */
-struct MallocDesc {
-    /* Pointer to the memory block actually allocated from the heap. Note that
-     * this is not the pointer that is returned to the malloc's caller. Pointer
-     * returned to the caller is calculated by adding value stored in this field
-     * to the value stored in prefix_size field of this structure.
-     */
-    void*       ptr;
-
-    /* Number of bytes requested by the malloc's caller. */
-    uint32_t    requested_bytes;
-
-    /* Byte size of the prefix data. Actual pointer returned to the malloc's
-     * caller is calculated by adding value stored in this field to the value
-     * stored in in the ptr field of this structure.
-     */
-    uint32_t    prefix_size;
-
-    /* Byte size of the suffix data. */
-    uint32_t    suffix_size;
-
-    /* Id of the process that initialized libc instance, in which allocation
-     * has occurred. This field is used by the emulator to report errors in
-     * the course of TRACE_DEV_REG_MALLOC event handling. In case of an error,
-     * emulator sets this field to zero (invalid value for a process ID).
-     */
-    uint32_t    libc_pid;
-
-    /* Id of the process in context of which allocation has occurred.
-     * Value in this field may differ from libc_pid value, if process that
-     * is doing allocation has been forked from the process that initialized
-     * libc instance.
-     */
-    uint32_t    allocator_pid;
-
-    /* Number of access violations detected on this allocation. */
-    uint32_t    av_count;
-};
-
-/* Describes memory block info queried from emulator. This structure is passed
- * along with TRACE_DEV_REG_QUERY_MALLOC event. When handling free and realloc
- * calls, it is required that we have information about memory blocks that were
- * actually allocated in previous calls to malloc, calloc, memalign, or realloc.
- * Since we don't keep this information directly in the allocated block, but
- * rather we keep it in the emulator, we need to query emulator for that
- * information with TRACE_DEV_REG_QUERY_MALLOC query. The entire structure is
- * initialized by the guest system before event is fired up. It is important to
- * remember that same structure (an exact copy, except for replacing pointers
- * with target_ulong) is also declared in the emulator's sources (file
- * memcheck/memecheck_common.h). So, every time a change is made to any of these
- * two declaration, another one must be also updated accordingly.
- */
-struct MallocDescQuery {
-    /* Pointer, for which information is queried. Note that this pointer doesn't
-     * have to be exact pointer returned to malloc's caller, but can point
-     * anywhere inside an allocated block, including guarding areas. Emulator
-     * will respond with information about allocated block that contains this
-     * pointer.
-     */
-    const void*       ptr;
-
-    /* Id of the process that initialized libc instance, in which this query
-     * is called. This field is used by the emulator to report errors in
-     * the course of TRACE_DEV_REG_QUERY_MALLOC event handling. In case of an
-     * error, emulator sets this field to zero (invalid value for a process ID).
-     */
-    uint32_t    libc_pid;
-
-    /* Process ID in context of which query is made. */
-    uint32_t    query_pid;
-
-    /* Code of the allocation routine, in context of which query has been made:
-     *  1 - free
-     *  2 - realloc
-     */
-    uint32_t    routine;
-
-    /* Address of memory allocation descriptor for the queried pointer.
-     * Descriptor, addressed by this field is initialized by the emulator in
-     * response to the query.
-     */
-    MallocDesc*  desc;
-};
-
-/* Describes memory block that is being freed back to the heap. This structure
- * is passed along with TRACE_DEV_REG_FREE_PTR event. The entire structure is
- * initialized by the guest system before event is fired up. It is important to
- * remember that same structure (an exact copy, except for replacing pointers
- * with target_ulong) is also declared in the emulator's sources (file
- * memcheck/memecheck_common.h). So, every time a change is made to any of these
- * two declaration, another one must be also updated accordingly.
- */
-struct MallocFree {
-    /* Pointer to be freed. */
-    void*       ptr;
-
-    /* Id of the process that initialized libc instance, in which this free
-     * is called. This field is used by the emulator to report errors in
-     * the course of TRACE_DEV_REG_FREE_PTR event handling. In case of an
-     * error, emulator sets this field to zero (invalid value for a process ID).
-     */
-    uint32_t    libc_pid;
-
-    /* Process ID in context of which memory is being freed. */
-    uint32_t    free_pid;
-};
-
-// =============================================================================
-// Communication events
-// =============================================================================
-
-/* Notifies the emulator that libc has been initialized for a process.
- * Event's value parameter is PID for the process in context of which libc has
- * been initialized.
- */
-#define TRACE_DEV_REG_LIBC_INIT             1536
-
-/* Notifies the emulator about new memory block been allocated.
- * Event's value parameter points to MallocDesc instance that contains
- * allocated block information. Note that 'libc_pid' field of the descriptor
- * is used by emulator to report failure in handling this event. In case
- * of a failure emulator will zero that field before completing this event.
- */
-#define TRACE_DEV_REG_MALLOC                1537
-
-/* Notifies the emulator about memory block being freed.
- * Event's value parameter points to MallocFree descriptor that contains
- * information about block that's being freed. Note that 'libc_pid' field
- * of the descriptor is used by emulator to report failure in handling this
- * event. In case of a failure emulator will zero that field before completing
- * this event.
- */
-#define TRACE_DEV_REG_FREE_PTR              1538
-
-/* Queries the emulator about allocated memory block information.
- * Event's value parameter points to MallocDescQuery descriptor that contains
- * query parameters. Note that 'libc_pid' field of the descriptor is used by
- * emulator to report failure in handling this event. In case of a failure
- * emulator will zero that field before completing this event.
- */
-#define TRACE_DEV_REG_QUERY_MALLOC          1539
-
-/* Queries the emulator to print a string to its stdout.
- * Event's value parameter points to a zero-terminated string to be printed.
- */
-#define TRACE_DEV_REG_PRINT_USER_STR        1540
-
-static void notify_qemu_string(const char* str);
-static void qemu_log(int prio, const char* fmt, ...);
-static void dump_malloc_descriptor(char* str,
-                                   size_t str_buf_size,
-                                   const MallocDesc* desc);
-
-// =============================================================================
-// Macros
-// =============================================================================
-
-/* Defines default size of allocation prefix.
- * Note that we make prefix area quite large in order to increase chances of
- * catching buffer overflow. */
-#define DEFAULT_PREFIX_SIZE     (malloc_alignment * 4)
-
-/* Defines default size of allocation suffix.
- * Note that we make suffix area quite large in order to increase chances of
- * catching buffer overflow. */
-#define DEFAULT_SUFFIX_SIZE     (malloc_alignment * 4)
-
-/* Debug tracing has been enabled by the emulator. */
-#define DEBUG_TRACING_ENABLED   0x00000001
-/* Error tracing has been enabled by the emulator. */
-#define ERROR_TRACING_ENABLED   0x00000002
-/* Info tracing has been enabled by the emulator. */
-#define INFO_TRACING_ENABLED    0x00000004
-/* All tracing flags combined. */
-#define ALL_TRACING_ENABLED (DEBUG_TRACING_ENABLED |    \
-                             ERROR_TRACING_ENABLED |    \
-                             INFO_TRACING_ENABLED)
-
-/* Prints a string to the emulator's stdout.
- * In early stages of system loading, logging messages to logcat
- * is not available, because ADB API has not been
- * hooked up yet. So, in order to see such messages we need to print them to
- * the emulator's stdout.
- * Parameters passed to this macro are the same as parameters for printf
- * routine.
- */
-#define TR(...)                                         \
-    do {                                                \
-        char tr_str[4096];                              \
-        snprintf(tr_str, sizeof(tr_str), __VA_ARGS__);  \
-        tr_str[sizeof(tr_str) - 1] = '\0';              \
-        notify_qemu_string(&tr_str[0]);                 \
-    } while (0)
-
-// =============================================================================
-// Logging macros. Note that we simultaneously log messages to ADB and emulator.
-// =============================================================================
-
-/*
- * Helper macros for checking if particular trace level is enabled.
- */
-#define debug_LOG_ENABLED       ((tracing_flags & DEBUG_TRACING_ENABLED) != 0)
-#define error_LOG_ENABLED       ((tracing_flags & ERROR_TRACING_ENABLED) != 0)
-#define info_LOG_ENABLED        ((tracing_flags & INFO_TRACING_ENABLED)  != 0)
-#define tracing_enabled(type)   (type##_LOG_ENABLED)
-
-/*
- * Logging helper macros.
- */
-#define qemu_debug_log(format, ...)                                         \
-    do {                                                                    \
-        __libc_format_log(ANDROID_LOG_DEBUG, "memcheck", (format), ##__VA_ARGS__); \
-        if (tracing_flags & DEBUG_TRACING_ENABLED) {                        \
-            qemu_log(ANDROID_LOG_DEBUG, (format), ##__VA_ARGS__);           \
-        }                                                                   \
-    } while (0)
-
-#define qemu_error_log(format, ...)                                         \
-    do {                                                                    \
-        __libc_format_log(ANDROID_LOG_ERROR, "memcheck", (format), ##__VA_ARGS__); \
-        if (tracing_flags & ERROR_TRACING_ENABLED) {                        \
-            qemu_log(ANDROID_LOG_ERROR, (format), ##__VA_ARGS__);           \
-        }                                                                   \
-    } while (0)
-
-#define qemu_info_log(format, ...)                                          \
-    do {                                                                    \
-        __libc_format_log(ANDROID_LOG_INFO, "memcheck", (format), ##__VA_ARGS__); \
-        if (tracing_flags & INFO_TRACING_ENABLED) {                         \
-            qemu_log(ANDROID_LOG_INFO, (format), ##__VA_ARGS__);            \
-        }                                                                   \
-    } while (0)
-
-/* Logs message dumping MallocDesc instance at the end of the message.
- * Param:
- *  type - Message type: debug, error, or info
- *  desc - MallocDesc instance to dump.
- *  fmt + rest - Formats message preceding dumped descriptor.
-*/
-#define log_mdesc(type, desc, fmt, ...)                                    \
-    do {                                                                    \
-        if (tracing_enabled(type)) {                                        \
-            char log_str[4096];                                             \
-            __libc_format_buffer(log_str, sizeof(log_str), fmt, ##__VA_ARGS__); \
-            log_str[sizeof(log_str) - 1] = '\0';                            \
-            size_t str_len = strlen(log_str);                               \
-            dump_malloc_descriptor(log_str + str_len,                       \
-                                   sizeof(log_str) - str_len,               \
-                                   (desc));                                 \
-            type##_log("%s", log_str);                                      \
-        }                                                                   \
-    } while (0)
-
-// =============================================================================
-// Static data
-// =============================================================================
-
-// The underlying malloc implementation to use to get memory.
-static const MallocDebug* g_malloc_dispatch = NULL;
-
-/* Emulator's magic page address.
- * This page (mapped on /dev/qemu_trace device) is used to fire up events
- * in the emulator. */
-static volatile void* qtrace = NULL;
-
-/* Cached PID of the process in context of which this libc instance
- * has been initialized. */
-static uint32_t malloc_pid = 0;
-
-/* Memory allocation alignment that is used in the malloc implementation.
- * This variable is updated by memcheck_initialize routine. */
-static uint32_t malloc_alignment = 8;
-
-/* Tracing flags. These flags control which types of logging messages are
- * enabled by the emulator. See XXX_TRACING_ENABLED for the values of flags
- * stored in this variable. This variable is updated by memcheck_initialize
- * routine. */
-static uint32_t tracing_flags = 0;
-
-// =============================================================================
-// Static routines
-// =============================================================================
-
-/* Gets pointer, returned to malloc caller for the given allocation decriptor.
- * Param:
- *  desc - Allocation descriptor.
- * Return:
- *  Pointer to the allocated memory returned to the malloc caller.
- */
-static inline void* mallocdesc_user_ptr(const MallocDesc* desc) {
-    return static_cast<char*>(desc->ptr) + desc->prefix_size;
-}
-
-/* Gets size of memory block actually allocated from the heap for the given
- * allocation decriptor.
- * Param:
- *  desc - Allocation descriptor.
- * Return:
- *  Size of memory block actually allocated from the heap.
- */
-static inline uint32_t mallocdesc_alloc_size(const MallocDesc* desc) {
-    return desc->prefix_size + desc->requested_bytes + desc->suffix_size;
-}
-
-/* Gets pointer to the end of the allocated block for the given descriptor.
- * Param:
- *  desc - Descriptor for the memory block, allocated in malloc handler.
- * Return:
- *  Pointer to the end of (one byte past) the allocated block.
- */
-static inline void* mallocdesc_alloc_end(const MallocDesc* desc) {
-    return static_cast<char*>(desc->ptr) + mallocdesc_alloc_size(desc);
-}
-
-/* Fires up an event in the emulator.
- * Param:
- *  code - Event code (one of the TRACE_DEV_XXX).
- *  val  - Event's value parameter.
- */
-static inline void notify_qemu(uint32_t code, uintptr_t val) {
-    if (NULL != qtrace) {
-        *(volatile uintptr_t*)((uintptr_t)qtrace + ((code - 1024) << 2)) = val;
-    }
-}
-
-/* Prints a zero-terminated string to the emulator's stdout (fires up
- * TRACE_DEV_REG_PRINT_USER_STR event in the emulator).
- * Param:
- *  str - Zero-terminated string to print.
- */
-static void notify_qemu_string(const char* str) {
-    if (str != NULL) {
-        notify_qemu(TRACE_DEV_REG_PRINT_USER_STR, reinterpret_cast<uintptr_t>(str));
-    }
-}
-
-/* Fires up TRACE_DEV_REG_LIBC_INIT event in the emulator.
- * Param:
- *  pid - ID of the process that initialized libc.
- */
-static void notify_qemu_libc_initialized(uint32_t pid) {
-    notify_qemu(TRACE_DEV_REG_LIBC_INIT, pid);
-}
-
-/* Fires up TRACE_DEV_REG_MALLOC event in the emulator.
- * Param:
- *  desc - Pointer to MallocDesc instance containing allocated block
- *      information.
- * Return:
- *  Zero on success, or -1 on failure. Note that on failure libc_pid field of
- *  the desc parameter passed to this routine has been zeroed out by the
- *  emulator.
- */
-static inline int notify_qemu_malloc(volatile MallocDesc* desc) {
-    desc->libc_pid = malloc_pid;
-    desc->allocator_pid = getpid();
-    desc->av_count = 0;
-    notify_qemu(TRACE_DEV_REG_MALLOC, reinterpret_cast<uintptr_t>(desc));
-
-    /* Emulator reports failure by zeroing libc_pid field of the
-     * descriptor. */
-    return desc->libc_pid != 0 ? 0 : -1;
-}
-
-/* Fires up TRACE_DEV_REG_FREE_PTR event in the emulator.
- * Param:
- *  ptr - Pointer to the memory block that's being freed.
- * Return:
- *  Zero on success, or -1 on failure.
- */
-static inline int notify_qemu_free(void* ptr_to_free) {
-    volatile MallocFree free_desc;
-
-    free_desc.ptr = ptr_to_free;
-    free_desc.libc_pid = malloc_pid;
-    free_desc.free_pid = getpid();
-    notify_qemu(TRACE_DEV_REG_FREE_PTR, reinterpret_cast<uintptr_t>(&free_desc));
-
-    /* Emulator reports failure by zeroing libc_pid field of the
-     * descriptor. */
-    return free_desc.libc_pid != 0 ? 0 : -1;
-}
-
-/* Fires up TRACE_DEV_REG_QUERY_MALLOC event in the emulator.
- * Param:
- *  ptr - Pointer to request allocation information for.
- *  desc - Pointer to MallocDesc instance that will receive allocation
- *      information.
- *  routine - Code of the allocation routine, in context of which query is made:
- *      1 - free
- *      2 - realloc
- * Return:
- *  Zero on success, or -1 on failure.
- */
-static inline int query_qemu_malloc_info(const void* ptr, MallocDesc* desc, uint32_t routine) {
-    volatile MallocDescQuery query;
-
-    query.ptr = ptr;
-    query.libc_pid = malloc_pid;
-    query.query_pid = getpid();
-    query.routine = routine;
-    query.desc = desc;
-    notify_qemu(TRACE_DEV_REG_QUERY_MALLOC, reinterpret_cast<uintptr_t>(&query));
-
-    /* Emulator reports failure by zeroing libc_pid field of the
-     * descriptor. */
-    return query.libc_pid != 0 ? 0 : -1;
-}
-
-/* Logs a message to emulator's stdout.
- * Param:
- *  prio - Message priority (debug, info, or error)
- *  fmt + rest - Message format and parameters.
- */
-static void qemu_log(int prio, const char* fmt, ...) {
-    va_list ap;
-    char buf[4096];
-    const char* prefix;
-
-    /* Choose message prefix depending on the priority value. */
-    switch (prio) {
-        case ANDROID_LOG_ERROR:
-            if (!tracing_enabled(error)) {
-                return;
-            }
-            prefix = "E";
-            break;
-        case ANDROID_LOG_INFO:
-            if (!tracing_enabled(info)) {
-                return;
-            }
-            prefix = "I";
-            break;
-        case ANDROID_LOG_DEBUG:
-        default:
-            if (!tracing_enabled(debug)) {
-                return;
-            }
-            prefix = "D";
-            break;
-    }
-
-    va_start(ap, fmt);
-    vsnprintf(buf, sizeof(buf), fmt, ap);
-    va_end(ap);
-    buf[sizeof(buf) - 1] = '\0';
-
-    TR("%s/memcheck: %s\n", prefix, buf);
-}
-
-/* Dumps content of memory allocation descriptor to a string.
- * Param:
- *  str - String to dump descriptor to.
- *  str_buf_size - Size of string's buffer.
- *  desc - Descriptor to dump.
- */
-static void dump_malloc_descriptor(char* str, size_t str_buf_size, const MallocDesc* desc) {
-    if (str_buf_size) {
-        snprintf(str, str_buf_size,
-                 "MDesc: %p: %p <-> %p [%u + %u + %u] by pid=%03u in libc_pid=%03u",
-                 mallocdesc_user_ptr(desc), desc->ptr,
-                 mallocdesc_alloc_end(desc), desc->prefix_size,
-                 desc->requested_bytes, desc->suffix_size, desc->allocator_pid,
-                 desc->libc_pid);
-        str[str_buf_size - 1] = '\0';
-    }
-}
-
-#if TEST_ACCESS_VIOLATIONS
-/* Causes an access violation on allocation descriptor, and verifies that
- * violation has been detected by memory checker in the emulator.
- */
-static void test_access_violation(const MallocDesc* desc) {
-    MallocDesc desc_chk;
-    char ch;
-    volatile char* prefix = (volatile char*)desc->ptr;
-    volatile char* suffix = (volatile char*)mallocdesc_user_ptr(desc) +
-                                            desc->requested_bytes;
-    /* We're causing AV by reading from the prefix and suffix areas of the
-     * allocated block. This should produce two access violations, so when we
-     * get allocation descriptor from QEMU, av_counter should be bigger than
-     * av_counter of the original descriptor by 2. */
-    ch = *prefix;
-    ch = *suffix;
-    if (!query_qemu_malloc_info(mallocdesc_user_ptr(desc), &desc_chk, 2) &&
-        desc_chk.av_count != (desc->av_count + 2)) {
-        log_mdesc(error, &desc_chk,
-                  "<libc_pid=%03u, pid=%03u>: malloc: Access violation test failed:\n"
-                  "Expected violations count %u is not equal to the actually reported %u",
-                  malloc_pid, getpid(), desc->av_count + 2,
-                  desc_chk.av_count);
-    }
-}
-#endif  // TEST_ACCESS_VIOLATIONS
-
-// =============================================================================
-// API routines
-// =============================================================================
-
-extern "C" void* qemu_instrumented_calloc(size_t, size_t);
-extern "C" void  qemu_instrumented_free(void*);
-extern "C" struct mallinfo qemu_instrumented_mallinfo();
-extern "C" void* qemu_instrumented_malloc(size_t);
-extern "C" size_t qemu_instrumented_malloc_usable_size(const void*);
-extern "C" void* qemu_instrumented_memalign(size_t, size_t);
-extern "C" int qemu_instrumented_posix_memalign(void**, size_t, size_t);
-extern "C" void* qemu_instrumented_pvalloc(size_t);
-extern "C" void* qemu_instrumented_realloc(void*, size_t);
-extern "C" void* qemu_instrumented_valloc(size_t);
-
-/* Initializes malloc debugging instrumentation for the emulator.
- * This routine is called from malloc_init_impl routine implemented in
- * bionic/libc/bionic/malloc_debug_common.c when malloc debugging gets
- * initialized for a process. The way malloc debugging implementation is
- * done, it is guaranteed that this routine will be called just once per
- * process.
- * Return:
- *  0 on success, or -1 on failure.
-*/
-extern "C" bool malloc_debug_initialize(HashTable*, const MallocDebug* malloc_dispatch) {
-    g_malloc_dispatch = malloc_dispatch;
-
-    /* We will be using emulator's magic page to report memory allocation
-     * activities. In essence, what magic page does, it translates writes to
-     * the memory mapped spaces into writes to an I/O port that emulator
-     * "listens to" on the other end. Note that until we open and map that
-     * device, logging to emulator's stdout will not be available. */
-    int fd = open("/dev/qemu_trace", O_CLOEXEC | O_RDWR);
-    if (fd < 0) {
-        error_log("Unable to open /dev/qemu_trace");
-        return false;
-    } else {
-        qtrace = mmap(NULL, PAGESIZE, PROT_READ | PROT_WRITE, MAP_SHARED, fd, 0);
-        close(fd);
-
-        if (qtrace == MAP_FAILED) {
-            qtrace = NULL;
-            error_log("Unable to mmap /dev/qemu_trace");
-            return false;
-        }
-    }
-
-    /* Cache pid of the process this library has been initialized for. */
-    malloc_pid = getpid();
-    return true;
-}
-
-/* Completes malloc debugging instrumentation for the emulator.
- * Note that this routine is called after successful return from
- * malloc_debug_initialize, which means that connection to the emulator via
- * "magic page" has been established.
- * Param:
- *  alignment - Alignment requirement set for memiry allocations.
- *  memcheck_param - Emulator's -memcheck option parameters. This string
- *      contains abbreviation for guest events that are enabled for tracing.
- * Return:
- *  0 on success, or -1 on failure.
-*/
-extern "C" int memcheck_initialize(int alignment, const char* memcheck_param) {
-    malloc_alignment = alignment;
-
-    /* Parse -memcheck parameter for the guest tracing flags. */
-    while (*memcheck_param != '\0') {
-        switch (*memcheck_param) {
-            case 'a':
-                // Enable all messages from the guest.
-                tracing_flags |= ALL_TRACING_ENABLED;
-                break;
-            case 'd':
-                // Enable debug messages from the guest.
-                tracing_flags |= DEBUG_TRACING_ENABLED;
-                break;
-            case 'e':
-                // Enable error messages from the guest.
-                tracing_flags |= ERROR_TRACING_ENABLED;
-                break;
-            case 'i':
-                // Enable info messages from the guest.
-                tracing_flags |= INFO_TRACING_ENABLED;
-                break;
-            default:
-                break;
-        }
-        if (tracing_flags == ALL_TRACING_ENABLED) {
-            break;
-        }
-        memcheck_param++;
-    }
-
-    notify_qemu_libc_initialized(malloc_pid);
-
-    qemu_debug_log("Instrumented for pid=%03u: malloc=%p, free=%p, calloc=%p, realloc=%p, memalign=%p",
-              malloc_pid, qemu_instrumented_malloc, qemu_instrumented_free,
-              qemu_instrumented_calloc, qemu_instrumented_realloc,
-              qemu_instrumented_memalign);
-
-    return 0;
-}
-
-/* This routine serves as entry point for 'malloc'.
- * Primary responsibility of this routine is to allocate requested number of
- * bytes (plus prefix, and suffix guards), and report allocation to the
- * emulator.
- */
-extern "C" void* qemu_instrumented_malloc(size_t bytes) {
-    MallocDesc desc;
-
-    /* Initialize block descriptor and allocate memory. Note that malloc
-     * returns a valid pointer on zero allocation. Lets mimic this behavior. */
-    desc.prefix_size = DEFAULT_PREFIX_SIZE;
-    desc.requested_bytes = bytes;
-    desc.suffix_size = DEFAULT_SUFFIX_SIZE;
-    size_t size = mallocdesc_alloc_size(&desc);
-    if (size < bytes) { // Overflow
-        qemu_error_log("<libc_pid=%03u, pid=%03u> malloc: malloc(%zu) overflow caused failure.",
-                       malloc_pid, getpid(), bytes);
-        errno = ENOMEM;
-        return NULL;
-    }
-    desc.ptr = g_malloc_dispatch->malloc(size);
-    if (desc.ptr == NULL) {
-        qemu_error_log("<libc_pid=%03u, pid=%03u> malloc(%zu): malloc(%zu) failed.",
-                       malloc_pid, getpid(), bytes, size);
-        return NULL;
-    }
-
-    // Fire up event in the emulator.
-    if (notify_qemu_malloc(&desc)) {
-        log_mdesc(error, &desc, "<libc_pid=%03u, pid=%03u>: malloc: notify_malloc failed for ",
-                  malloc_pid, getpid());
-        g_malloc_dispatch->free(desc.ptr);
-        errno = ENOMEM;
-        return NULL;
-    } else {
-#if TEST_ACCESS_VIOLATIONS
-        test_access_violation(&desc);
-#endif  // TEST_ACCESS_VIOLATIONS
-        log_mdesc(info, &desc, "+++ <libc_pid=%03u, pid=%03u> malloc(%zu) -> ",
-                  malloc_pid, getpid(), bytes);
-        return mallocdesc_user_ptr(&desc);
-    }
-}
-
-/* This routine serves as entry point for 'malloc'.
- * Primary responsibility of this routine is to free requested memory, and
- * report free block to the emulator.
- */
-extern "C" void qemu_instrumented_free(void* mem) {
-    MallocDesc desc;
-
-    if (mem == NULL) {
-        // Just let go NULL free
-        g_malloc_dispatch->free(mem);
-        return;
-    }
-
-    // Query emulator for the freeing block information.
-    if (query_qemu_malloc_info(mem, &desc, 1)) {
-        error_log("<libc_pid=%03u, pid=%03u>: free(%p) query_info failed.",
-                  malloc_pid, getpid(), mem);
-        return;
-    }
-
-#if TEST_ACCESS_VIOLATIONS
-    test_access_violation(&desc);
-#endif  // TEST_ACCESS_VIOLATIONS
-
-    /* Make sure that pointer that's being freed matches what we expect
-     * for this memory block. Note that this violation should be already
-     * caught in the emulator. */
-    if (mem != mallocdesc_user_ptr(&desc)) {
-        log_mdesc(error, &desc, "<libc_pid=%03u, pid=%03u>: free(%p) is invalid for ",
-                  malloc_pid, getpid(), mem);
-        return;
-    }
-
-    // Fire up event in the emulator and free block that was actually allocated.
-    if (notify_qemu_free(mem)) {
-        log_mdesc(error, &desc, "<libc_pid=%03u, pid=%03u>: free(%p) notify_free failed for ",
-                  malloc_pid, getpid(), mem);
-    } else {
-        log_mdesc(info, &desc, "--- <libc_pid=%03u, pid=%03u> free(%p) -> ",
-                  malloc_pid, getpid(), mem);
-        g_malloc_dispatch->free(desc.ptr);
-    }
-}
-
-/* This routine serves as entry point for 'calloc'.
- * This routine behaves similarly to qemu_instrumented_malloc.
- */
-extern "C" void* qemu_instrumented_calloc(size_t n_elements, size_t elem_size) {
-    if (n_elements == 0 || elem_size == 0) {
-        // Just let go zero bytes allocation.
-        qemu_info_log("::: <libc_pid=%03u, pid=%03u>: Zero calloc redir to malloc",
-                      malloc_pid, getpid());
-        return qemu_instrumented_malloc(0);
-    }
-
-    // Fail on overflow - just to be safe even though this code runs only
-    // within the debugging C library, not the production one.
-    if (n_elements && SIZE_MAX / n_elements < elem_size) {
-        qemu_error_log("<libc_pid=%03u, pid=%03u> calloc: calloc(%zu, %zu) overflow caused failure.",
-                       malloc_pid, getpid(), n_elements, elem_size);
-        errno = ENOMEM;
-        return NULL;
-    }
-
-    MallocDesc desc;
-
-    /* Calculating prefix size. The trick here is to make sure that
-     * first element (returned to the caller) is properly aligned. */
-    if (DEFAULT_PREFIX_SIZE >= elem_size) {
-        /* If default alignment is bigger than element size, we will
-         * set our prefix size to the default alignment size. */
-        desc.prefix_size = DEFAULT_PREFIX_SIZE;
-        /* For the suffix we will use whatever bytes remain from the prefix
-         * allocation size, aligned to the size of an element, plus the usual
-         * default suffix size. */
-        desc.suffix_size = (DEFAULT_PREFIX_SIZE % elem_size) +
-                           DEFAULT_SUFFIX_SIZE;
-    } else {
-        /* Make sure that prefix, and suffix sizes is at least elem_size,
-         * and first element returned to the caller is properly aligned. */
-        desc.prefix_size = elem_size + DEFAULT_PREFIX_SIZE - 1;
-        desc.prefix_size &= ~(malloc_alignment - 1);
-        desc.suffix_size = DEFAULT_SUFFIX_SIZE;
-    }
-    desc.requested_bytes = n_elements * elem_size;
-    size_t total_size = desc.requested_bytes + desc.prefix_size + desc.suffix_size;
-    if (total_size < desc.requested_bytes) { // Overflow
-        qemu_error_log("<libc_pid=%03u, pid=%03u> calloc: calloc(%zu, %zu) overflow caused failure.",
-                       malloc_pid, getpid(), n_elements, elem_size);
-        errno = ENOMEM;
-        return NULL;
-    }
-    size_t total_elements = total_size / elem_size;
-    total_size %= elem_size;
-    if (total_size != 0) {
-        // Add extra to the suffix area.
-        total_elements++;
-        desc.suffix_size += (elem_size - total_size);
-    }
-    desc.ptr = g_malloc_dispatch->calloc(total_elements, elem_size);
-    if (desc.ptr == NULL) {
-        error_log("<libc_pid=%03u, pid=%03u> calloc: calloc(%zu(%zu), %zu) (prx=%u, sfx=%u) failed.",
-                   malloc_pid, getpid(), n_elements, total_elements, elem_size,
-                   desc.prefix_size, desc.suffix_size);
-        return NULL;
-    }
-
-    if (notify_qemu_malloc(&desc)) {
-        log_mdesc(error, &desc, "<libc_pid=%03u, pid=%03u>: calloc(%zu(%zu), %zu): notify_malloc failed for ",
-                  malloc_pid, getpid(), n_elements, total_elements, elem_size);
-        g_malloc_dispatch->free(desc.ptr);
-        errno = ENOMEM;
-        return NULL;
-    } else {
-#if TEST_ACCESS_VIOLATIONS
-        test_access_violation(&desc);
-#endif  // TEST_ACCESS_VIOLATIONS
-        log_mdesc(info, &desc, "### <libc_pid=%03u, pid=%03u> calloc(%zu(%zu), %zu) -> ",
-                  malloc_pid, getpid(), n_elements, total_elements, elem_size);
-        return mallocdesc_user_ptr(&desc);
-    }
-}
-
-/* This routine serves as entry point for 'realloc'.
- * This routine behaves similarly to qemu_instrumented_free +
- * qemu_instrumented_malloc. Note that this modifies behavior of "shrinking" an
- * allocation, but overall it doesn't seem to matter, as caller of realloc
- * should not expect that pointer returned after shrinking will remain the same.
- */
-extern "C" void* qemu_instrumented_realloc(void* mem, size_t bytes) {
-    if (mem == NULL) {
-        // Nothing to realloc. just do regular malloc.
-        qemu_info_log("::: <libc_pid=%03u, pid=%03u>: realloc(%p, %zu) redir to malloc",
-                      malloc_pid, getpid(), mem, bytes);
-        return qemu_instrumented_malloc(bytes);
-    }
-
-    if (bytes == 0) {
-        // This is a "free" condition.
-        qemu_info_log("::: <libc_pid=%03u, pid=%03u>: realloc(%p, %zu) redir to free and malloc",
-                      malloc_pid, getpid(), mem, bytes);
-        qemu_instrumented_free(mem);
-
-        // This is what realloc does for a "free" realloc.
-        return NULL;
-    }
-
-    // Query emulator for the reallocating block information.
-    MallocDesc cur_desc;
-    if (query_qemu_malloc_info(mem, &cur_desc, 2)) {
-        // Note that this violation should be already caught in the emulator.
-        error_log("<libc_pid=%03u, pid=%03u>: realloc(%p, %zu) query_info failed.",
-                  malloc_pid, getpid(), mem, bytes);
-        errno = ENOMEM;
-        return NULL;
-    }
-
-#if TEST_ACCESS_VIOLATIONS
-    test_access_violation(&cur_desc);
-#endif  // TEST_ACCESS_VIOLATIONS
-
-    /* Make sure that reallocating pointer value is what we would expect
-     * for this memory block. Note that this violation should be already caught
-     * in the emulator.*/
-    if (mem != mallocdesc_user_ptr(&cur_desc)) {
-        log_mdesc(error, &cur_desc, "<libc_pid=%03u, pid=%03u>: realloc(%p, %zu) is invalid for ",
-                  malloc_pid, getpid(), mem, bytes);
-        errno = ENOMEM;
-        return NULL;
-    }
-
-    /* TODO: We're a bit inefficient here, always allocating new block from
-     * the heap. If this realloc shrinks current buffer, we can just do the
-     * shrinking "in place", adjusting suffix_size in the allocation descriptor
-     * for this block that is stored in the emulator. */
-
-    // Initialize descriptor for the new block.
-    MallocDesc new_desc;
-    new_desc.prefix_size = DEFAULT_PREFIX_SIZE;
-    new_desc.requested_bytes = bytes;
-    new_desc.suffix_size = DEFAULT_SUFFIX_SIZE;
-    size_t new_size = mallocdesc_alloc_size(&new_desc);
-    if (new_size < bytes) { // Overflow
-        qemu_error_log("<libc_pid=%03u, pid=%03u>: realloc(%p, %zu): malloc(%zu) failed due to overflow",
-                       malloc_pid, getpid(), mem, bytes, new_size);
-        errno = ENOMEM;
-        return NULL;
-    }
-    new_desc.ptr = g_malloc_dispatch->malloc(new_size);
-    if (new_desc.ptr == NULL) {
-        log_mdesc(error, &cur_desc, "<libc_pid=%03u, pid=%03u>: realloc(%p, %zu): malloc(%zu) failed on ",
-                  malloc_pid, getpid(), mem, bytes, new_size);
-        return NULL;
-    }
-    void* new_mem = mallocdesc_user_ptr(&new_desc);
-
-    // Copy user data from old block to the new one.
-    size_t to_copy = bytes < cur_desc.requested_bytes ? bytes : cur_desc.requested_bytes;
-    if (to_copy != 0) {
-        memcpy(new_mem, mallocdesc_user_ptr(&cur_desc), to_copy);
-    }
-
-    // Register new block with emulator.
-    if (notify_qemu_malloc(&new_desc)) {
-        log_mdesc(error, &new_desc, "<libc_pid=%03u, pid=%03u>: realloc(%p, %zu) notify_malloc failed -> ",
-                  malloc_pid, getpid(), mem, bytes);
-        log_mdesc(error, &cur_desc, "                                                                <- ");
-        g_malloc_dispatch->free(new_desc.ptr);
-        errno = ENOMEM;
-        return NULL;
-    }
-
-#if TEST_ACCESS_VIOLATIONS
-    test_access_violation(&new_desc);
-#endif  // TEST_ACCESS_VIOLATIONS
-
-    // Free old block.
-    if (notify_qemu_free(mem)) {
-        log_mdesc(error, &cur_desc, "<libc_pid=%03u, pid=%03u>: realloc(%p, %zu): notify_free failed for ",
-                  malloc_pid, getpid(), mem, bytes);
-        /* Since we registered new decriptor with the emulator, we need
-         * to unregister it before freeing newly allocated block. */
-        notify_qemu_free(mallocdesc_user_ptr(&new_desc));
-        g_malloc_dispatch->free(new_desc.ptr);
-        errno = ENOMEM;
-        return NULL;
-    }
-    g_malloc_dispatch->free(cur_desc.ptr);
-
-    log_mdesc(info, &new_desc, "=== <libc_pid=%03u, pid=%03u>: realloc(%p, %zu) -> ",
-              malloc_pid, getpid(), mem, bytes);
-    log_mdesc(info, &cur_desc, "                                               <- ");
-
-    return new_mem;
-}
-
-/* This routine serves as entry point for 'memalign'.
- * This routine behaves similarly to qemu_instrumented_malloc.
- */
-extern "C" void* qemu_instrumented_memalign(size_t alignment, size_t bytes) {
-    MallocDesc desc;
-
-    if (bytes == 0) {
-        // Just let go zero bytes allocation.
-        qemu_info_log("::: <libc_pid=%03u, pid=%03u>: memalign(%zx, %zu) redir to malloc",
-                 malloc_pid, getpid(), alignment, bytes);
-        return qemu_instrumented_malloc(0);
-    }
-
-    // Prefix size for aligned allocation must be equal to the alignment used
-    // for allocation in order to ensure proper alignment of the returned
-    // pointer. in case that alignment requirement is greater than prefix
-    // size.
-    if (alignment < DEFAULT_PREFIX_SIZE) {
-        alignment = DEFAULT_PREFIX_SIZE;
-    } else if (!powerof2(alignment)) {
-        alignment = BIONIC_ROUND_UP_POWER_OF_2(alignment);
-    }
-    desc.prefix_size = alignment;
-    desc.requested_bytes = bytes;
-    desc.suffix_size = DEFAULT_SUFFIX_SIZE;
-    size_t size = mallocdesc_alloc_size(&desc);
-    if (size < bytes) { // Overflow
-        qemu_error_log("<libc_pid=%03u, pid=%03u> memalign(%zx, %zu): malloc(%zu) failed due to overflow.",
-                       malloc_pid, getpid(), alignment, bytes, size);
-
-        return NULL;
-    }
-    desc.ptr = g_malloc_dispatch->memalign(desc.prefix_size, size);
-    if (desc.ptr == NULL) {
-        error_log("<libc_pid=%03u, pid=%03u> memalign(%zx, %zu): malloc(%zu) failed.",
-                  malloc_pid, getpid(), alignment, bytes, size);
-        return NULL;
-    }
-    if (notify_qemu_malloc(&desc)) {
-        log_mdesc(error, &desc, "<libc_pid=%03u, pid=%03u>: memalign(%zx, %zu): notify_malloc failed for ",
-                  malloc_pid, getpid(), alignment, bytes);
-        g_malloc_dispatch->free(desc.ptr);
-        return NULL;
-    }
-
-#if TEST_ACCESS_VIOLATIONS
-    test_access_violation(&desc);
-#endif  // TEST_ACCESS_VIOLATIONS
-
-    log_mdesc(info, &desc, "@@@ <libc_pid=%03u, pid=%03u> memalign(%zx, %zu) -> ",
-              malloc_pid, getpid(), alignment, bytes);
-    return mallocdesc_user_ptr(&desc);
-}
-
-extern "C" size_t qemu_instrumented_malloc_usable_size(const void* mem) {
-    MallocDesc cur_desc;
-
-    // Query emulator for the reallocating block information.
-    if (query_qemu_malloc_info(mem, &cur_desc, 2)) {
-        // Note that this violation should be already caught in the emulator.
-        error_log("<libc_pid=%03u, pid=%03u>: malloc_usable_size(%p) query_info failed.",
-                  malloc_pid, getpid(), mem);
-        return 0;
-    }
-
-    /* Make sure that reallocating pointer value is what we would expect
-     * for this memory block. Note that this violation should be already caught
-     * in the emulator.*/
-    if (mem != mallocdesc_user_ptr(&cur_desc)) {
-        log_mdesc(error, &cur_desc, "<libc_pid=%03u, pid=%03u>: malloc_usable_size(%p) is invalid for ",
-                  malloc_pid, getpid(), mem);
-        return 0;
-    }
-
-    /* during instrumentation, we can't really report anything more than requested_bytes */
-    return cur_desc.requested_bytes;
-}
-
-extern "C" struct mallinfo qemu_instrumented_mallinfo() {
-  return g_malloc_dispatch->mallinfo();
-}
-
-extern "C" int qemu_instrumented_posix_memalign(void** memptr, size_t alignment, size_t size) {
-  if ((alignment & (alignment - 1)) != 0) {
-    qemu_error_log("<libc_pid=%03u, pid=%03u> posix_memalign(%p, %zu, %zu): invalid alignment.",
-                   malloc_pid, getpid(), memptr, alignment, size);
-    return EINVAL;
-  }
-  int saved_errno = errno;
-  *memptr = qemu_instrumented_memalign(alignment, size);
-  errno = saved_errno;
-  return (*memptr != NULL) ? 0 : ENOMEM;
-}
-
-extern "C" void* qemu_instrumented_pvalloc(size_t bytes) {
-  size_t pagesize = getpagesize();
-  size_t size = BIONIC_ALIGN(bytes, pagesize);
-  if (size < bytes) { // Overflow
-    qemu_error_log("<libc_pid=%03u, pid=%03u> pvalloc(%zu): overflow (%zu).",
-                   malloc_pid, getpid(), bytes, size);
-    return NULL;
-  }
-  return qemu_instrumented_memalign(pagesize, size);
-}
-
-extern "C" void* qemu_instrumented_valloc(size_t size) {
-  return qemu_instrumented_memalign(getpagesize(), size);
-}
diff --git a/libc/bionic/mmap.cpp b/libc/bionic/mmap.cpp
index 8f25a89..57a8cdf 100644
--- a/libc/bionic/mmap.cpp
+++ b/libc/bionic/mmap.cpp
@@ -27,9 +27,11 @@
  */
 
 #include <errno.h>
+#include <stdint.h>
 #include <sys/mman.h>
 #include <unistd.h>
 
+#include "private/bionic_macros.h"
 #include "private/ErrnoRestorer.h"
 
 // mmap2(2) is like mmap(2), but the offset is in 4096-byte blocks, not bytes.
@@ -45,10 +47,21 @@
     return MAP_FAILED;
   }
 
-  bool is_private_anonymous = (flags & (MAP_PRIVATE | MAP_ANONYMOUS)) != 0;
+  // 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;
+  }
+
+  bool is_private_anonymous =
+      (flags & (MAP_PRIVATE | MAP_ANONYMOUS)) == (MAP_PRIVATE | MAP_ANONYMOUS);
+  bool is_stack_or_grows_down = (flags & (MAP_STACK | MAP_GROWSDOWN)) != 0;
+
   void* result = __mmap2(addr, size, prot, flags, fd, offset >> MMAP2_SHIFT);
 
-  if (result != MAP_FAILED && kernel_has_MADV_MERGEABLE && is_private_anonymous) {
+  if (result != MAP_FAILED && kernel_has_MADV_MERGEABLE &&
+      is_private_anonymous && !is_stack_or_grows_down) {
     ErrnoRestorer errno_restorer;
     int rc = madvise(result, size, MADV_MERGEABLE);
     if (rc == -1 && errno == EINVAL) {
diff --git a/libc/bionic/ioctl.c b/libc/bionic/mremap.cpp
similarity index 61%
copy from libc/bionic/ioctl.c
copy to libc/bionic/mremap.cpp
index 6dd95d0..6653d43 100644
--- a/libc/bionic/ioctl.c
+++ b/libc/bionic/mremap.cpp
@@ -1,5 +1,5 @@
 /*
- * Copyright (C) 2008 The Android Open Source Project
+ * Copyright (C) 2015 The Android Open Source Project
  * All rights reserved.
  *
  * Redistribution and use in source and binary forms, with or without
@@ -25,19 +25,33 @@
  * OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF
  * SUCH DAMAGE.
  */
+
+#include <errno.h>
+#include <sys/mman.h>
 #include <stdarg.h>
+#include <stdint.h>
+#include <unistd.h>
 
-extern int __ioctl(int, int, void *);
+#include "private/bionic_macros.h"
 
-int ioctl(int fd, int request, ...)
-{
+extern "C" void* ___mremap(void*, size_t, size_t, int, void*);
+
+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);
+  if (rounded < new_size || rounded > PTRDIFF_MAX) {
+    errno = ENOMEM;
+    return MAP_FAILED;
+  }
+
+  void* new_address = nullptr;
+  // The optional argument is only valid if the MREMAP_FIXED flag is set,
+  // so we assume it's not present otherwise.
+  if ((flags & MREMAP_FIXED) != 0) {
     va_list ap;
-    void * arg;
-
-    va_start(ap, request);
-    arg = va_arg(ap, void *);
+    va_start(ap, flags);
+    new_address = va_arg(ap, void*);
     va_end(ap);
-
-    return __ioctl(fd, request, arg);
+  }
+  return ___mremap(old_address, old_size, new_size, flags, new_address);
 }
-
diff --git a/libc/bionic/ndk_cruft.cpp b/libc/bionic/ndk_cruft.cpp
index b299684..3ac88f8 100644
--- a/libc/bionic/ndk_cruft.cpp
+++ b/libc/bionic/ndk_cruft.cpp
@@ -47,34 +47,34 @@
 
 #include "private/libc_logging.h"
 
-// The part is only for 32-bit targets.
-#if !defined(__LP64__)
+extern "C" {
+
+// Brillo and LP64 don't need to support any legacy cruft.
+#if !defined(__BRILLO__) && !defined(__LP64__)
 
 // These were accidentally declared in <unistd.h> because we stupidly used to inline
 // getpagesize() and __getpageshift(). Needed for backwards compatibility with old NDK apps.
-extern "C" {
-  unsigned int __page_size = PAGE_SIZE;
-  unsigned int __page_shift = 12;
-}
+unsigned int __page_size = PAGE_SIZE;
+unsigned int __page_shift = 12;
 
 // TODO: remove this backward compatibility hack (for jb-mr1 strace binaries).
-extern "C" pid_t __wait4(pid_t pid, int* status, int options, struct rusage* rusage) {
+pid_t __wait4(pid_t pid, int* status, int options, struct rusage* rusage) {
   return wait4(pid, status, options, rusage);
 }
 
 // TODO: does anything still need this?
-extern "C" int __open() {
+int __open() {
   abort();
 }
 
 // TODO: does anything still need this?
-extern "C" void** __get_tls() {
+void** __get_tls() {
 #include "private/__get_tls.h"
   return __get_tls();
 }
 
 // This non-standard function was in our <string.h> for some reason.
-extern "C" void memswap(void* m1, void* m2, size_t n) {
+void memswap(void* m1, void* m2, size_t n) {
   char* p = reinterpret_cast<char*>(m1);
   char* p_end = p + n;
   char* q = reinterpret_cast<char*>(m2);
@@ -87,13 +87,13 @@
   }
 }
 
-extern "C" int pthread_attr_setstackaddr(pthread_attr_t*, void*) {
+int pthread_attr_setstackaddr(pthread_attr_t*, void*) {
   // This was removed from POSIX.1-2008, and is not implemented on bionic.
   // Needed for ABI compatibility with the NDK.
   return ENOSYS;
 }
 
-extern "C" int pthread_attr_getstackaddr(const pthread_attr_t* attr, void** stack_addr) {
+int pthread_attr_getstackaddr(const pthread_attr_t* attr, void** stack_addr) {
   // This was removed from POSIX.1-2008.
   // Needed for ABI compatibility with the NDK.
   *stack_addr = (char*)attr->stack_base + attr->stack_size;
@@ -101,7 +101,7 @@
 }
 
 // Non-standard cruft that should only ever have been in system/core/toolbox.
-extern "C" char* strtotimeval(const char* str, struct timeval* ts) {
+char* strtotimeval(const char* str, struct timeval* ts) {
   char* s;
   ts->tv_sec = strtoumax(str, &s, 10);
 
@@ -143,7 +143,7 @@
 }
 
 // This non-standard function was in our <inttypes.h> for some reason.
-extern "C" uintmax_t strntoumax(const char *nptr, char **endptr, int base, size_t n) {
+uintmax_t strntoumax(const char *nptr, char **endptr, int base, size_t n) {
   const unsigned char*  p   = (const unsigned char *)nptr;
   const unsigned char*  end = p + n;
   int                   minus = 0;
@@ -191,12 +191,12 @@
 }
 
 // This non-standard function was in our <inttypes.h> for some reason.
-extern "C" intmax_t strntoimax(const char* nptr, char** endptr, int base, size_t n) {
+intmax_t strntoimax(const char* nptr, char** endptr, int base, size_t n) {
   return (intmax_t) strntoumax(nptr, endptr, base, n);
 }
 
 // POSIX calls this dprintf, but LP32 Android had fdprintf instead.
-extern "C" int fdprintf(int fd, const char* fmt, ...) {
+int fdprintf(int fd, const char* fmt, ...) {
   va_list ap;
   va_start(ap, fmt);
   int rc = vdprintf(fd, fmt, ap);
@@ -205,7 +205,7 @@
 }
 
 // POSIX calls this vdprintf, but LP32 Android had fdprintf instead.
-extern "C" int vfdprintf(int fd, const char* fmt, va_list ap) {
+int vfdprintf(int fd, const char* fmt, va_list ap) {
   return vdprintf(fd, fmt, ap);
 }
 
@@ -216,64 +216,64 @@
 #undef __futex_wait
 
 // This used to be in <sys/atomics.h>.
-extern "C" int __futex_wake(volatile void* ftx, int count) {
+int __futex_wake(volatile void* ftx, int count) {
   return __real_futex_wake(ftx, count);
 }
 
 // This used to be in <sys/atomics.h>.
-extern "C" int __futex_wait(volatile void* ftx, int value, const struct timespec* timeout) {
+int __futex_wait(volatile void* ftx, int value, const struct timespec* timeout) {
   return __real_futex_wait(ftx, value, timeout);
 }
 
 // Unity's libmono uses this.
-extern "C" int tkill(pid_t tid, int sig) {
+int tkill(pid_t tid, int sig) {
   return syscall(__NR_tkill, tid, sig);
 }
 
 // This was removed from POSIX 2008.
-extern "C" wchar_t* wcswcs(wchar_t* haystack, wchar_t* needle) {
+wchar_t* wcswcs(wchar_t* haystack, wchar_t* needle) {
   return wcsstr(haystack, needle);
 }
 
 // This was removed from POSIX 2008.
-extern "C" sighandler_t bsd_signal(int signum, sighandler_t handler) {
+sighandler_t bsd_signal(int signum, sighandler_t handler) {
   return signal(signum, handler);
 }
 
 #if !defined(__i386__)
 // This was removed from POSIX 2008.
 #undef bcopy
-extern "C" void bcopy(const void* src, void* dst, size_t n) {
-  memcpy(dst, src, n);
+void bcopy(const void* src, void* dst, size_t n) {
+  memmove(dst, src, n);
 }
 #else
 // x86 has an assembler implementation.
 #endif
 
 // sysv_signal() was never in POSIX.
-extern sighandler_t _signal(int signum, sighandler_t handler, int flags);
-extern "C" sighandler_t sysv_signal(int signum, sighandler_t handler) {
+extern "C++" sighandler_t _signal(int signum, sighandler_t handler, int flags);
+sighandler_t sysv_signal(int signum, sighandler_t handler) {
   return _signal(signum, handler, SA_RESETHAND);
 }
 
 // This is a system call that was never in POSIX. Use readdir(3) instead.
-extern "C" int __getdents64(unsigned int, dirent*, unsigned int);
-extern "C" int getdents(unsigned int fd, dirent* dirp, unsigned int count) {
+int __getdents64(unsigned int, dirent*, unsigned int);
+int getdents(unsigned int fd, dirent* dirp, unsigned int count) {
   return __getdents64(fd, dirp, count);
 }
 
 // This is a BSDism that we never implemented correctly. Used by Firefox.
-extern "C" int issetugid() {
+int issetugid() {
   return 0;
 }
 
 // This was removed from POSIX 2004.
-extern "C" pid_t wait3(int* status, int options, struct rusage* rusage) {
+pid_t wait3(int* status, int options, struct rusage* rusage) {
   return wait4(-1, status, options, rusage);
 }
 
 // This was removed from POSIX 2004.
-extern "C" int getdtablesize() {
+int getdtablesize() {
   struct rlimit r;
 
   if (getrlimit(RLIMIT_NOFILE, &r) < 0) {
@@ -283,6 +283,10 @@
   return r.rlim_cur;
 }
 
+// A leaked BSD stdio implementation detail that's now a no-op.
+void __sinit() {}
+int __sdidinit = 1;
+
 // Only used by ftime, which was removed from POSIX 2008.
 struct timeb {
   time_t          time;
@@ -292,7 +296,7 @@
 };
 
 // This was removed from POSIX 2008.
-extern "C" int ftime(struct timeb* tb) {
+int ftime(struct timeb* tb) {
   struct timeval  tv;
   struct timezone tz;
 
@@ -314,35 +318,35 @@
 }
 
 // This was removed from POSIX 2008.
-extern "C" char* index(const char* str, int ch) {
+char* index(const char* str, int ch) {
   return strchr(str, ch);
 }
 
 // This was removed from BSD.
-extern "C" void arc4random_stir(void) {
+void arc4random_stir(void) {
   // The current implementation stirs itself as needed.
 }
 
 // This was removed from BSD.
-extern "C" void arc4random_addrandom(unsigned char*, int) {
+void arc4random_addrandom(unsigned char*, int) {
   // The current implementation adds randomness as needed.
 }
 
 // Old versions of the NDK did not export malloc_usable_size, but did
 // export dlmalloc_usable_size. We are moving away from dlmalloc in L
 // so make this call malloc_usable_size.
-extern "C" size_t dlmalloc_usable_size(void* ptr) {
+size_t dlmalloc_usable_size(void* ptr) {
   return malloc_usable_size(ptr);
 }
 
 // In L we added a public pthread_gettid_np, but some apps were using the private API.
-extern "C" pid_t __pthread_gettid(pthread_t t) {
+pid_t __pthread_gettid(pthread_t t) {
   return pthread_gettid_np(t);
 }
 
 // Older versions of apportable used dlmalloc directly instead of malloc,
 // so export this compatibility shim that simply calls malloc.
-extern "C" void* dlmalloc(size_t size) {
+void* dlmalloc(size_t size) {
   return malloc(size);
 }
 
@@ -350,45 +354,28 @@
 #include "pthread_internal.h"
 #undef __get_thread
 // Various third-party apps contain a backport of our pthread_rwlock implementation that uses this.
-extern "C" pthread_internal_t* __get_thread() {
+pthread_internal_t* __get_thread() {
   return __real_get_thread();
 }
 
-#endif // !defined(__LP64__)
-
-// This is never implemented in bionic, only needed for ABI compatibility with the NDK.
-extern "C" char* getusershell() {
-  return NULL;
+// This one exists only for the LP32 NDK and is not present anywhere else.
+extern long __set_errno_internal(int);
+long __set_errno(int n) {
+  return __set_errno_internal(n);
 }
 
-// This is never implemented in bionic, only needed for ABI compatibility with the NDK.
-extern "C" void setusershell() { }
-
-// This is never implemented in bionic, only needed for ABI compatibility with the NDK.
-extern "C" void endusershell() { }
-
-// This is never implemented in bionic, only needed for ABI compatibility with the NDK.
-extern "C" void endpwent() { }
+// This was never implemented in bionic, only needed for ABI compatibility with the NDK.
+// In the M time frame, over 1000 apps have a reference to this!
+void endpwent() { }
 
 // Since dlmalloc_inspect_all and dlmalloc_trim are exported for systems
 // that use dlmalloc, be consistent and export them everywhere.
-#if defined(USE_JEMALLOC)
-extern "C" void dlmalloc_inspect_all(void (*)(void*, void*, size_t, void*), void*) {
+void dlmalloc_inspect_all(void (*)(void*, void*, size_t, void*), void*) {
 }
-#else
-extern "C" void dlmalloc_inspect_all_real(void (*)(void*, void*, size_t, void*), void*);
-extern "C" void dlmalloc_inspect_all(void (*handler)(void*, void*, size_t, void*), void* arg) {
-  dlmalloc_inspect_all_real(handler, arg);
+int dlmalloc_trim(size_t) {
+    return 0;
 }
-#endif
 
-#if defined(USE_JEMALLOC)
-extern "C" int dlmalloc_trim(size_t) {
-  return 0;
-}
-#else
-extern "C" int dlmalloc_trim_real(size_t);
-extern "C" int dlmalloc_trim(size_t pad) {
-  return dlmalloc_trim_real(pad);
-}
-#endif
+#endif // !defined(__BRILLO__) && !defined (__LP64__)
+
+} // extern "C"
diff --git a/libc/bionic/net_if.cpp b/libc/bionic/net_if.cpp
new file mode 100644
index 0000000..f8d73bd
--- /dev/null
+++ b/libc/bionic/net_if.cpp
@@ -0,0 +1,163 @@
+/*
+ * 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 <net/if.h>
+
+#include <errno.h>
+#include <ifaddrs.h>
+#include <linux/if_packet.h>
+#include <linux/netlink.h>
+#include <linux/rtnetlink.h>
+#include <linux/sockios.h>
+#include <stdlib.h>
+#include <string.h>
+#include <sys/ioctl.h>
+#include <sys/socket.h>
+#include <unistd.h>
+
+#include "private/ErrnoRestorer.h"
+
+#include "bionic_netlink.h"
+
+char* if_indextoname(unsigned ifindex, char* ifname) {
+  int s = socket(AF_INET, SOCK_DGRAM|SOCK_CLOEXEC, 0);
+  if (s == -1) return nullptr;
+
+  struct ifreq ifr;
+  memset(&ifr, 0, sizeof(ifr));
+  ifr.ifr_ifindex = ifindex;
+
+  int rc = ioctl(s, SIOCGIFNAME, &ifr);
+  ErrnoRestorer errno_restorer;
+  close(s);
+  return (rc == -1) ? nullptr : strncpy(ifname, ifr.ifr_name, IFNAMSIZ);
+}
+
+unsigned if_nametoindex(const char* ifname) {
+  int s = socket(AF_INET, SOCK_DGRAM|SOCK_CLOEXEC, 0);
+  if (s == -1) return 0;
+
+  struct ifreq ifr;
+  memset(&ifr, 0, sizeof(ifr));
+  strncpy(ifr.ifr_name, ifname, sizeof(ifr.ifr_name));
+  ifr.ifr_name[IFNAMSIZ - 1] = 0;
+
+  int rc = ioctl(s, SIOCGIFINDEX, &ifr);
+  ErrnoRestorer errno_restorer;
+  close(s);
+  return (rc == -1) ? 0 : ifr.ifr_ifindex;
+}
+
+struct if_list {
+  if_list* next;
+  struct if_nameindex data;
+
+  if_list(if_list** list) {
+    // push_front onto `list`.
+    next = *list;
+    *list = this;
+  }
+
+  static void Free(if_list* list, bool names_too) {
+    while (list) {
+      if_list* it = list;
+      list = it->next;
+      if (names_too) free(it->data.if_name);
+      free(it);
+    }
+  }
+};
+
+static void __if_nameindex_callback(void* context, nlmsghdr* hdr) {
+  if_list** list = reinterpret_cast<if_list**>(context);
+  if (hdr->nlmsg_type == RTM_NEWLINK) {
+    ifinfomsg* ifi = reinterpret_cast<ifinfomsg*>(NLMSG_DATA(hdr));
+
+    // Create a new entry and set the interface index.
+    if_list* new_link = new if_list(list);
+    new_link->data.if_index = ifi->ifi_index;
+
+    // Go through the various bits of information and find the name.
+    rtattr* rta = IFLA_RTA(ifi);
+    size_t rta_len = IFLA_PAYLOAD(hdr);
+    while (RTA_OK(rta, rta_len)) {
+      if (rta->rta_type == IFLA_IFNAME) {
+        new_link->data.if_name = strndup(reinterpret_cast<char*>(RTA_DATA(rta)), RTA_PAYLOAD(rta));
+      }
+      rta = RTA_NEXT(rta, rta_len);
+    }
+  }
+}
+
+struct if_nameindex* if_nameindex() {
+  if_list* list = nullptr;
+
+  // Open the netlink socket and ask for all the links;
+  NetlinkConnection nc;
+  bool okay = nc.SendRequest(RTM_GETLINK) && nc.ReadResponses(__if_nameindex_callback, &list);
+  if (!okay) {
+    if_list::Free(list, true);
+    return nullptr;
+  }
+
+  // Count the interfaces.
+  size_t interface_count = 0;
+  for (if_list* it = list; it != nullptr; it = it->next) {
+    ++interface_count;
+  }
+
+  // Build the array POSIX requires us to return.
+  struct if_nameindex* result = new struct if_nameindex[interface_count + 1];
+  if (result) {
+    struct if_nameindex* out = result;
+    for (if_list* it = list; it != nullptr; it = it->next) {
+      out->if_index = it->data.if_index;
+      out->if_name = it->data.if_name;
+      ++out;
+    }
+    out->if_index = 0;
+    out->if_name = nullptr;
+  }
+
+  // Free temporary storage.
+  if_list::Free(list, false);
+
+  return result;
+}
+
+void if_freenameindex(struct if_nameindex* array) {
+  if (array == nullptr) return;
+
+  struct if_nameindex* ptr = array;
+  while (ptr->if_index != 0 || ptr->if_name != nullptr) {
+    free(ptr->if_name);
+    ++ptr;
+  }
+
+  delete[] array;
+}
diff --git a/libc/bionic/bindresvport.c b/libc/bionic/netinet_in.cpp
similarity index 63%
rename from libc/bionic/bindresvport.c
rename to libc/bionic/netinet_in.cpp
index 5d9ad2b..dfa5d8d 100644
--- a/libc/bionic/bindresvport.c
+++ b/libc/bionic/netinet_in.cpp
@@ -25,48 +25,46 @@
  * OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF
  * SUCH DAMAGE.
  */
+
+#include <netinet/in.h>
+
 #include <errno.h>
 #include <sys/types.h>
 #include <sys/socket.h>
-#include <netinet/in.h>
 #include <string.h>
 #include <unistd.h>
 
-#define START_PORT	600
-#define END_PORT	IPPORT_RESERVED
-#define NUM_PORTS	(END_PORT - START_PORT)
+constexpr int START_PORT = 600;
+constexpr int END_PORT = IPPORT_RESERVED;
+constexpr int NUM_PORTS = (END_PORT - START_PORT);
 
-int bindresvport(int sd, struct sockaddr_in *sin)
-{
-    static short        port;
-    struct sockaddr_in  sin0;
-    int                 nn, ret;
+int bindresvport(int sd, struct sockaddr_in* sin) {
+  sockaddr_in sin0;
+  if (sin == nullptr) {
+    memset(&sin0, 0, sizeof(sin0));
+    sin = &sin0;
+    sin->sin_family = AF_INET;
+  }
 
-    if (sin == NULL) {
-        sin = &sin0;
-        memset( sin, 0, sizeof *sin );
-        sin->sin_family = AF_INET;
-    } else if (sin->sin_family != AF_INET) {
-        errno = EPFNOSUPPORT;
-        return -1;
-    }
+  if (sin->sin_family != AF_INET) {
+    errno = EPFNOSUPPORT;
+    return -1;
+  }
 
-    if (port == 0) {
-        port = START_PORT + (getpid() % NUM_PORTS);
-    }
+  // TODO: thread safety!
+  static short port;
+  if (port == 0) {
+    port = START_PORT + (getpid() % NUM_PORTS);
+  }
 
-    for (nn = NUM_PORTS; nn > 0; nn--, port++) 
-    {
-        if (port == END_PORT)
-            port = START_PORT;
-
-        sin->sin_port = htons(port);
-        do {
-            ret = bind(sd, (struct sockaddr*)sin, sizeof(*sin));
-        } while (ret < 0 && errno == EINTR);
-
-        if (!ret)
-            break;
-    }
-    return ret;
+  for (size_t i = NUM_PORTS; i > 0; i--, port++) {
+    if (port == END_PORT) port = START_PORT;
+    sin->sin_port = htons(port);
+    int rc = TEMP_FAILURE_RETRY(bind(sd, reinterpret_cast<sockaddr*>(sin), sizeof(*sin)));
+    if (rc >= 0) return rc;
+  }
+  return -1;
 }
+
+const in6_addr in6addr_any = IN6ADDR_ANY_INIT;
+const in6_addr in6addr_loopback = IN6ADDR_LOOPBACK_INIT;
diff --git a/libc/bionic/pthread_atfork.cpp b/libc/bionic/pthread_atfork.cpp
index 093ffd2..2200a6c 100644
--- a/libc/bionic/pthread_atfork.cpp
+++ b/libc/bionic/pthread_atfork.cpp
@@ -45,7 +45,7 @@
 
 class atfork_list_t {
  public:
-  atfork_list_t() : first_(nullptr), last_(nullptr) {}
+  constexpr atfork_list_t() : first_(nullptr), last_(nullptr) {}
 
   template<typename F>
   void walk_forward(F f) {
diff --git a/libc/bionic/pthread_attr.cpp b/libc/bionic/pthread_attr.cpp
index 7ad3431..cfa58fc 100644
--- a/libc/bionic/pthread_attr.cpp
+++ b/libc/bionic/pthread_attr.cpp
@@ -114,6 +114,36 @@
   return 0;
 }
 
+static uintptr_t __get_main_stack_startstack() {
+  FILE* fp = fopen("/proc/self/stat", "re");
+  if (fp == nullptr) {
+    __libc_fatal("couldn't open /proc/self/stat: %s", strerror(errno));
+  }
+
+  char line[BUFSIZ];
+  if (fgets(line, sizeof(line), fp) == nullptr) {
+    __libc_fatal("couldn't read /proc/self/stat: %s", strerror(errno));
+  }
+
+  fclose(fp);
+
+  // See man 5 proc. There's no reason comm can't contain ' ' or ')',
+  // so we search backwards for the end of it. We're looking for this field:
+  //
+  //  startstack %lu (28) The address of the start (i.e., bottom) of the stack.
+  uintptr_t startstack = 0;
+  const char* end_of_comm = strrchr(line, ')');
+  if (sscanf(end_of_comm + 1, " %*c "
+             "%*d %*d %*d %*d %*d "
+             "%*u %*u %*u %*u %*u %*u %*u "
+             "%*d %*d %*d %*d %*d %*d "
+             "%*u %*u %*d %*u %*u %*u %" SCNuPTR, &startstack) != 1) {
+    __libc_fatal("couldn't parse /proc/self/stat");
+  }
+
+  return startstack;
+}
+
 static int __pthread_attr_getstack_main_thread(void** stack_base, size_t* stack_size) {
   ErrnoRestorer errno_restorer;
 
@@ -127,20 +157,19 @@
     stack_limit.rlim_cur = 8 * 1024 * 1024;
   }
 
-  // It shouldn't matter which thread we are because we're just looking for "[stack]", but
-  // valgrind seems to mess with the stack enough that the kernel will report "[stack:pid]"
-  // instead if you look in /proc/self/maps, so we need to look in /proc/pid/task/pid/maps.
-  char path[64];
-  snprintf(path, sizeof(path), "/proc/self/task/%d/maps", getpid());
-  FILE* fp = fopen(path, "re");
-  if (fp == NULL) {
-    return errno;
+  // Ask the kernel where our main thread's stack started.
+  uintptr_t startstack = __get_main_stack_startstack();
+
+  // Hunt for the region that contains that address.
+  FILE* fp = fopen("/proc/self/maps", "re");
+  if (fp == nullptr) {
+    __libc_fatal("couldn't open /proc/self/maps");
   }
   char line[BUFSIZ];
   while (fgets(line, sizeof(line), fp) != NULL) {
-    if (ends_with(line, " [stack]\n")) {
-      uintptr_t lo, hi;
-      if (sscanf(line, "%" SCNxPTR "-%" SCNxPTR, &lo, &hi) == 2) {
+    uintptr_t lo, hi;
+    if (sscanf(line, "%" SCNxPTR "-%" SCNxPTR, &lo, &hi) == 2) {
+      if (lo <= startstack && startstack <= hi) {
         *stack_size = stack_limit.rlim_cur;
         *stack_base = reinterpret_cast<void*>(hi - *stack_size);
         fclose(fp);
@@ -148,7 +177,7 @@
       }
     }
   }
-  __libc_fatal("No [stack] line found in \"%s\"!", path);
+  __libc_fatal("Stack not found in /proc/self/maps");
 }
 
 int pthread_attr_getstack(const pthread_attr_t* attr, void** stack_base, size_t* stack_size) {
diff --git a/libc/bionic/pthread_barrier.cpp b/libc/bionic/pthread_barrier.cpp
new file mode 100644
index 0000000..1bcd12a
--- /dev/null
+++ b/libc/bionic/pthread_barrier.cpp
@@ -0,0 +1,183 @@
+/*
+ * Copyright (C) 2015 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 <pthread.h>
+#include <stdatomic.h>
+#include <stdint.h>
+
+#include "private/bionic_futex.h"
+
+int pthread_barrierattr_init(pthread_barrierattr_t* attr) {
+  *attr = 0;
+  return 0;
+}
+
+int pthread_barrierattr_destroy(pthread_barrierattr_t* attr) {
+  *attr = 0;
+  return 0;
+}
+
+int pthread_barrierattr_getpshared(pthread_barrierattr_t* attr, int* pshared) {
+  *pshared = (*attr & 1) ? PTHREAD_PROCESS_SHARED : PTHREAD_PROCESS_PRIVATE;
+  return 0;
+}
+
+int pthread_barrierattr_setpshared(pthread_barrierattr_t* attr, int pshared) {
+  if (pshared == PTHREAD_PROCESS_SHARED) {
+    *attr |= 1;
+  } else {
+    *attr &= ~1;
+  }
+  return 0;
+}
+
+enum BarrierState {
+  WAIT,
+  RELEASE,
+};
+
+struct pthread_barrier_internal_t {
+  // One barrier can be used for unlimited number of cycles. In each cycle, [init_count]
+  // threads must call pthread_barrier_wait() before any of them successfully return from
+  // the call. It is undefined behavior if there are more than [init_count] threads call
+  // pthread_barrier_wait() in one cycle.
+  uint32_t init_count;
+  // Barrier state. It is WAIT if waiting for more threads to enter the barrier in this cycle,
+  // otherwise threads are leaving the barrier.
+  _Atomic(BarrierState) state;
+  // Number of threads having entered but not left the barrier in this cycle.
+  atomic_uint wait_count;
+  // Whether the barrier is shared across processes.
+  bool pshared;
+  uint32_t __reserved[4];
+};
+
+static_assert(sizeof(pthread_barrier_t) == sizeof(pthread_barrier_internal_t),
+              "pthread_barrier_t should actually be pthread_barrier_internal_t in implementation."
+              );
+
+static_assert(alignof(pthread_barrier_t) >= 4,
+              "pthread_barrier_t should fulfill the alignment of pthread_barrier_internal_t.");
+
+static inline pthread_barrier_internal_t* __get_internal_barrier(pthread_barrier_t* barrier) {
+  return reinterpret_cast<pthread_barrier_internal_t*>(barrier);
+}
+
+int pthread_barrier_init(pthread_barrier_t* barrier_interface, const pthread_barrierattr_t* attr,
+                         unsigned count) {
+  pthread_barrier_internal_t* barrier = __get_internal_barrier(barrier_interface);
+  if (count == 0) {
+    return EINVAL;
+  }
+  barrier->init_count = count;
+  atomic_init(&barrier->state, WAIT);
+  atomic_init(&barrier->wait_count, 0);
+  barrier->pshared = false;
+  if (attr != nullptr && (*attr & 1)) {
+    barrier->pshared = true;
+  }
+  return 0;
+}
+
+// According to POSIX standard, pthread_barrier_wait() synchronizes memory between participating
+// threads. It means all memory operations made by participating threads before calling
+// pthread_barrier_wait() can be seen by all participating threads after the function call.
+// We establish this by making a happens-before relation between all threads entering the barrier
+// with the last thread entering the barrier, and a happens-before relation between the last
+// thread entering the barrier with all threads leaving the barrier.
+int pthread_barrier_wait(pthread_barrier_t* barrier_interface) {
+  pthread_barrier_internal_t* barrier = __get_internal_barrier(barrier_interface);
+
+  // Wait until all threads for the previous cycle have left the barrier. This is needed
+  // as a participating thread can call pthread_barrier_wait() again before other
+  // threads have left the barrier. Use acquire operation here to synchronize with
+  // the last thread leaving the previous cycle, so we can read correct wait_count below.
+  while(atomic_load_explicit(&barrier->state, memory_order_acquire) == RELEASE) {
+    __futex_wait_ex(&barrier->state, barrier->pshared, RELEASE, false, nullptr);
+  }
+
+  uint32_t prev_wait_count = atomic_load_explicit(&barrier->wait_count, memory_order_relaxed);
+  while (true) {
+    // It happens when there are more than [init_count] threads trying to enter the barrier
+    // at one cycle. We read the POSIX standard as disallowing this, since additional arriving
+    // threads are not synchronized with respect to the barrier reset. We also don't know of
+    // any reasonable cases in which this would be intentional.
+    if (prev_wait_count >= barrier->init_count) {
+      return EINVAL;
+    }
+    // Use memory_order_acq_rel operation here to synchronize between all threads entering
+    // the barrier with the last thread entering the barrier.
+    if (atomic_compare_exchange_weak_explicit(&barrier->wait_count, &prev_wait_count,
+                                              prev_wait_count + 1u, memory_order_acq_rel,
+                                              memory_order_relaxed)) {
+      break;
+    }
+  }
+
+  int result = 0;
+  if (prev_wait_count + 1 == barrier->init_count) {
+    result = PTHREAD_BARRIER_SERIAL_THREAD;
+    if (prev_wait_count != 0) {
+      // Use release operation here to synchronize between the last thread entering the
+      // barrier with all threads leaving the barrier.
+      atomic_store_explicit(&barrier->state, RELEASE, memory_order_release);
+      __futex_wake_ex(&barrier->state, barrier->pshared, prev_wait_count);
+    }
+  } else {
+    // Use acquire operation here to synchronize between the last thread entering the
+    // barrier with all threads leaving the barrier.
+    while (atomic_load_explicit(&barrier->state, memory_order_acquire) == WAIT) {
+      __futex_wait_ex(&barrier->state, barrier->pshared, WAIT, false, nullptr);
+    }
+  }
+  // Use release operation here to make it not reordered with previous operations.
+  if (atomic_fetch_sub_explicit(&barrier->wait_count, 1, memory_order_release) == 1) {
+    // Use release operation here to synchronize with threads entering the barrier for
+    // the next cycle, or the thread calling pthread_barrier_destroy().
+    atomic_store_explicit(&barrier->state, WAIT, memory_order_release);
+    __futex_wake_ex(&barrier->state, barrier->pshared, barrier->init_count);
+  }
+  return result;
+}
+
+int pthread_barrier_destroy(pthread_barrier_t* barrier_interface) {
+  pthread_barrier_internal_t* barrier = __get_internal_barrier(barrier_interface);
+  if (barrier->init_count == 0) {
+    return EINVAL;
+  }
+  // Use acquire operation here to synchronize with the last thread leaving the barrier.
+  // So we can read correct wait_count below.
+  while (atomic_load_explicit(&barrier->state, memory_order_acquire) == RELEASE) {
+    __futex_wait_ex(&barrier->state, barrier->pshared, RELEASE, false, nullptr);
+  }
+  if (atomic_load_explicit(&barrier->wait_count, memory_order_relaxed) != 0) {
+    return EBUSY;
+  }
+  barrier->init_count = 0;
+  return 0;
+}
diff --git a/libc/bionic/pthread_cond.cpp b/libc/bionic/pthread_cond.cpp
index 4a69da5..d36426c 100644
--- a/libc/bionic/pthread_cond.cpp
+++ b/libc/bionic/pthread_cond.cpp
@@ -111,8 +111,8 @@
     return COND_IS_SHARED(atomic_load_explicit(&state, memory_order_relaxed));
   }
 
-  int get_clock() {
-    return COND_GET_CLOCK(atomic_load_explicit(&state, memory_order_relaxed));
+  bool use_realtime_clock() {
+    return COND_GET_CLOCK(atomic_load_explicit(&state, memory_order_relaxed)) == CLOCK_REALTIME;
   }
 
 #if defined(__LP64__)
@@ -170,12 +170,17 @@
   return 0;
 }
 
-static int __pthread_cond_timedwait_relative(pthread_cond_internal_t* cond, pthread_mutex_t* mutex,
-                                             const timespec* rel_timeout_or_null) {
-  unsigned int old_state = atomic_load_explicit(&cond->state, memory_order_relaxed);
+static int __pthread_cond_timedwait(pthread_cond_internal_t* cond, pthread_mutex_t* mutex,
+                                    bool use_realtime_clock, const timespec* abs_timeout_or_null) {
+  int result = check_timespec(abs_timeout_or_null, true);
+  if (result != 0) {
+    return result;
+  }
 
+  unsigned int old_state = atomic_load_explicit(&cond->state, memory_order_relaxed);
   pthread_mutex_unlock(mutex);
-  int status = __futex_wait_ex(&cond->state, cond->process_shared(), old_state, rel_timeout_or_null);
+  int status = __futex_wait_ex(&cond->state, cond->process_shared(), old_state,
+                               use_realtime_clock, abs_timeout_or_null);
   pthread_mutex_lock(mutex);
 
   if (status == -ETIMEDOUT) {
@@ -184,21 +189,6 @@
   return 0;
 }
 
-static int __pthread_cond_timedwait(pthread_cond_internal_t* cond, pthread_mutex_t* mutex,
-                                    const timespec* abs_timeout_or_null, clockid_t clock) {
-  timespec ts;
-  timespec* rel_timeout = NULL;
-
-  if (abs_timeout_or_null != NULL) {
-    rel_timeout = &ts;
-    if (!timespec_from_absolute_timespec(*rel_timeout, *abs_timeout_or_null, clock)) {
-      return ETIMEDOUT;
-    }
-  }
-
-  return __pthread_cond_timedwait_relative(cond, mutex, rel_timeout);
-}
-
 int pthread_cond_broadcast(pthread_cond_t* cond_interface) {
   return __pthread_cond_pulse(__get_internal_cond(cond_interface), INT_MAX);
 }
@@ -209,14 +199,14 @@
 
 int pthread_cond_wait(pthread_cond_t* cond_interface, pthread_mutex_t* mutex) {
   pthread_cond_internal_t* cond = __get_internal_cond(cond_interface);
-  return __pthread_cond_timedwait(cond, mutex, NULL, cond->get_clock());
+  return __pthread_cond_timedwait(cond, mutex, false, nullptr);
 }
 
 int pthread_cond_timedwait(pthread_cond_t *cond_interface, pthread_mutex_t * mutex,
                            const timespec *abstime) {
 
   pthread_cond_internal_t* cond = __get_internal_cond(cond_interface);
-  return __pthread_cond_timedwait(cond, mutex, abstime, cond->get_clock());
+  return __pthread_cond_timedwait(cond, mutex, cond->use_realtime_clock(), abstime);
 }
 
 #if !defined(__LP64__)
@@ -225,8 +215,7 @@
                                                 pthread_mutex_t* mutex,
                                                 const timespec* abs_timeout) {
 
-  return __pthread_cond_timedwait(__get_internal_cond(cond_interface), mutex, abs_timeout,
-                                  CLOCK_MONOTONIC);
+  return __pthread_cond_timedwait(__get_internal_cond(cond_interface), mutex, false, abs_timeout);
 }
 
 extern "C" int pthread_cond_timedwait_monotonic_np(pthread_cond_t* cond_interface,
@@ -238,8 +227,13 @@
 extern "C" int pthread_cond_timedwait_relative_np(pthread_cond_t* cond_interface,
                                                   pthread_mutex_t* mutex,
                                                   const timespec* rel_timeout) {
-
-  return __pthread_cond_timedwait_relative(__get_internal_cond(cond_interface), mutex, rel_timeout);
+  timespec ts;
+  timespec* abs_timeout = nullptr;
+  if (rel_timeout != nullptr) {
+    absolute_timespec_from_timespec(ts, *rel_timeout, CLOCK_REALTIME);
+    abs_timeout = &ts;
+  }
+  return __pthread_cond_timedwait(__get_internal_cond(cond_interface), mutex, true, abs_timeout);
 }
 
 extern "C" int pthread_cond_timeout_np(pthread_cond_t* cond_interface,
diff --git a/libc/bionic/pthread_create.cpp b/libc/bionic/pthread_create.cpp
index dbdb180..34826db 100644
--- a/libc/bionic/pthread_create.cpp
+++ b/libc/bionic/pthread_create.cpp
@@ -53,13 +53,6 @@
 
 // This code is used both by each new pthread and the code that initializes the main thread.
 void __init_tls(pthread_internal_t* thread) {
-  if (thread->mmap_size == 0) {
-    // If the TLS area was not allocated by mmap(), it may not have been cleared to zero.
-    // So assume the worst and zero the TLS area.
-    memset(thread->tls, 0, sizeof(thread->tls));
-    memset(thread->key_data, 0, sizeof(thread->key_data));
-  }
-
   // Slot 0 must point to itself. The x86 Linux kernel reads the TLS from %fs:0.
   thread->tls[TLS_SLOT_SELF] = thread->tls;
   thread->tls[TLS_SLOT_THREAD_ID] = thread;
@@ -87,6 +80,7 @@
     // We can only use const static allocated string for mapped region name, as Android kernel
     // uses the string pointer directly when dumping /proc/pid/maps.
     prctl(PR_SET_VMA, PR_SET_VMA_ANON_NAME, ss.ss_sp, ss.ss_size, "thread signal stack");
+    prctl(PR_SET_VMA, PR_SET_VMA_ANON_NAME, stack_base, PAGE_SIZE, "thread signal stack guard page");
   }
 }
 
@@ -140,6 +134,7 @@
     munmap(space, mmap_size);
     return NULL;
   }
+  prctl(PR_SET_VMA, PR_SET_VMA_ANON_NAME, space, stack_guard_size, "thread stack guard page");
 
   return space;
 }
@@ -173,6 +168,11 @@
                 (reinterpret_cast<uintptr_t>(stack_top) - sizeof(pthread_internal_t)) & ~0xf);
 
   pthread_internal_t* thread = reinterpret_cast<pthread_internal_t*>(stack_top);
+  if (mmap_size == 0) {
+    // If thread was not allocated by mmap(), it may not have been cleared to zero.
+    // So assume the worst and zero it.
+    memset(thread, 0, sizeof(pthread_internal_t));
+  }
   attr->stack_size = stack_top - reinterpret_cast<uint8_t*>(attr->stack_base);
 
   thread->mmap_size = mmap_size;
@@ -191,8 +191,7 @@
   // notify gdb about this thread before we start doing anything.
   // This also provides the memory barrier needed to ensure that all memory
   // accesses previously made by the creating thread are visible to us.
-  pthread_mutex_lock(&thread->startup_handshake_mutex);
-  pthread_mutex_destroy(&thread->startup_handshake_mutex);
+  thread->startup_handshake_lock.lock();
 
   __init_alternate_signal_stack(thread);
 
@@ -231,14 +230,14 @@
     return result;
   }
 
-  // Create a mutex for the thread in TLS to wait on once it starts so we can keep
+  // Create a lock for the thread to wait on once it starts so we can keep
   // it from doing anything until after we notify the debugger about it
   //
   // This also provides the memory barrier we need to ensure that all
   // memory accesses previously performed by this thread are visible to
   // the new thread.
-  pthread_mutex_init(&thread->startup_handshake_mutex, NULL);
-  pthread_mutex_lock(&thread->startup_handshake_mutex);
+  thread->startup_handshake_lock.init(false);
+  thread->startup_handshake_lock.lock();
 
   thread->start_routine = start_routine;
   thread->start_routine_arg = arg;
@@ -261,7 +260,7 @@
     // We don't have to unlock the mutex at all because clone(2) failed so there's no child waiting to
     // be unblocked, but we're about to unmap the memory the mutex is stored in, so this serves as a
     // reminder that you can't rewrite this function to use a ScopedPthreadMutexLocker.
-    pthread_mutex_unlock(&thread->startup_handshake_mutex);
+    thread->startup_handshake_lock.unlock();
     if (thread->mmap_size != 0) {
       munmap(thread->attr.stack_base, thread->mmap_size);
     }
@@ -276,13 +275,13 @@
     atomic_store(&thread->join_state, THREAD_DETACHED);
     __pthread_internal_add(thread);
     thread->start_routine = __do_nothing;
-    pthread_mutex_unlock(&thread->startup_handshake_mutex);
+    thread->startup_handshake_lock.unlock();
     return init_errno;
   }
 
   // Publish the pthread_t and unlock the mutex to let the new thread start running.
   *thread_out = __pthread_internal_add(thread);
-  pthread_mutex_unlock(&thread->startup_handshake_mutex);
+  thread->startup_handshake_lock.unlock();
 
   return 0;
 }
diff --git a/libc/bionic/pthread_internal.cpp b/libc/bionic/pthread_internal.cpp
index 1967ccf..8946f79 100644
--- a/libc/bionic/pthread_internal.cpp
+++ b/libc/bionic/pthread_internal.cpp
@@ -81,6 +81,12 @@
 
 pthread_internal_t* __pthread_internal_find(pthread_t thread_id) {
   pthread_internal_t* thread = reinterpret_cast<pthread_internal_t*>(thread_id);
+
+  // check if thread is pthread_self() before acquiring the lock
+  if (thread == __get_thread()) {
+    return thread;
+  }
+
   ScopedPthreadMutexLocker locker(&g_thread_list_lock);
 
   for (pthread_internal_t* t = g_thread_list; t != NULL; t = t->next) {
diff --git a/libc/bionic/pthread_internal.h b/libc/bionic/pthread_internal.h
index 6a39a21..e8be4ae 100644
--- a/libc/bionic/pthread_internal.h
+++ b/libc/bionic/pthread_internal.h
@@ -31,6 +31,7 @@
 #include <pthread.h>
 #include <stdatomic.h>
 
+#include "private/bionic_lock.h"
 #include "private/bionic_tls.h"
 
 /* Has the thread been detached by a pthread_join or pthread_detach call? */
@@ -39,7 +40,8 @@
 /* Has the thread been joined by another thread? */
 #define PTHREAD_ATTR_FLAG_JOINED 0x00000002
 
-struct pthread_key_data_t {
+class pthread_key_data_t {
+ public:
   uintptr_t seq; // Use uintptr_t just for alignment, as we use pointer below.
   void* data;
 };
@@ -51,9 +53,12 @@
   THREAD_DETACHED
 };
 
-struct pthread_internal_t {
-  struct pthread_internal_t* next;
-  struct pthread_internal_t* prev;
+class thread_local_dtor;
+
+class pthread_internal_t {
+ public:
+  class pthread_internal_t* next;
+  class pthread_internal_t* prev;
 
   pid_t tid;
 
@@ -89,10 +94,12 @@
 
   void* alternate_signal_stack;
 
-  pthread_mutex_t startup_handshake_mutex;
+  Lock startup_handshake_lock;
 
   size_t mmap_size;
 
+  thread_local_dtor* thread_local_dtors;
+
   void* tls[BIONIC_TLS_SLOTS];
 
   pthread_key_data_t key_data[BIONIC_PTHREAD_KEY_COUNT];
diff --git a/libc/bionic/pthread_mutex.cpp b/libc/bionic/pthread_mutex.cpp
index 851fc3d..7d8e8a8 100644
--- a/libc/bionic/pthread_mutex.cpp
+++ b/libc/bionic/pthread_mutex.cpp
@@ -166,11 +166,14 @@
 #define  MUTEX_STATE_BITS_LOCKED_UNCONTENDED  MUTEX_STATE_TO_BITS(MUTEX_STATE_LOCKED_UNCONTENDED)
 #define  MUTEX_STATE_BITS_LOCKED_CONTENDED    MUTEX_STATE_TO_BITS(MUTEX_STATE_LOCKED_CONTENDED)
 
-/* return true iff the mutex if locked with no waiters */
-#define  MUTEX_STATE_BITS_IS_LOCKED_UNCONTENDED(v)  (((v) & MUTEX_STATE_MASK) == MUTEX_STATE_BITS_LOCKED_UNCONTENDED)
+// Return true iff the mutex is unlocked.
+#define MUTEX_STATE_BITS_IS_UNLOCKED(v) (((v) & MUTEX_STATE_MASK) == MUTEX_STATE_BITS_UNLOCKED)
 
-/* return true iff the mutex if locked with maybe waiters */
-#define  MUTEX_STATE_BITS_IS_LOCKED_CONTENDED(v)   (((v) & MUTEX_STATE_MASK) == MUTEX_STATE_BITS_LOCKED_CONTENDED)
+// Return true iff the mutex is locked with no waiters.
+#define MUTEX_STATE_BITS_IS_LOCKED_UNCONTENDED(v)  (((v) & MUTEX_STATE_MASK) == MUTEX_STATE_BITS_LOCKED_UNCONTENDED)
+
+// return true iff the mutex is locked with maybe waiters.
+#define MUTEX_STATE_BITS_IS_LOCKED_CONTENDED(v)   (((v) & MUTEX_STATE_MASK) == MUTEX_STATE_BITS_LOCKED_CONTENDED)
 
 /* used to flip from LOCKED_UNCONTENDED to LOCKED_CONTENDED */
 #define  MUTEX_STATE_BITS_FLIP_CONTENTION(v)      ((v) ^ (MUTEX_STATE_BITS_LOCKED_CONTENDED ^ MUTEX_STATE_BITS_LOCKED_UNCONTENDED))
@@ -296,11 +299,15 @@
  */
 static inline __always_inline int __pthread_normal_mutex_lock(pthread_mutex_internal_t* mutex,
                                                               uint16_t shared,
-                                                              const timespec* abs_timeout_or_null,
-                                                              clockid_t clock) {
+                                                              bool use_realtime_clock,
+                                                              const timespec* abs_timeout_or_null) {
     if (__predict_true(__pthread_normal_mutex_trylock(mutex, shared) == 0)) {
         return 0;
     }
+    int result = check_timespec(abs_timeout_or_null, true);
+    if (result != 0) {
+        return result;
+    }
 
     ScopedTrace trace("Contending for pthread mutex");
 
@@ -317,15 +324,8 @@
     // made by other threads visible to the current CPU.
     while (atomic_exchange_explicit(&mutex->state, locked_contended,
                                     memory_order_acquire) != unlocked) {
-        timespec ts;
-        timespec* rel_timeout = NULL;
-        if (abs_timeout_or_null != NULL) {
-            rel_timeout = &ts;
-            if (!timespec_from_absolute_timespec(*rel_timeout, *abs_timeout_or_null, clock)) {
-                return ETIMEDOUT;
-            }
-        }
-        if (__futex_wait_ex(&mutex->state, shared, locked_contended, rel_timeout) == -ETIMEDOUT) {
+        if (__futex_wait_ex(&mutex->state, shared, locked_contended, use_realtime_clock,
+                            abs_timeout_or_null) == -ETIMEDOUT) {
             return ETIMEDOUT;
         }
     }
@@ -396,14 +396,15 @@
                                                       pthread_mutex_internal_t* mutex,
                                                       uint16_t shared,
                                                       uint16_t old_state,
-                                                      const timespec* rel_timeout) {
+                                                      bool use_realtime_clock,
+                                                      const timespec* abs_timeout) {
 // __futex_wait always waits on a 32-bit value. But state is 16-bit. For a normal mutex, the owner_tid
 // field in mutex is not used. On 64-bit devices, the __pad field in mutex is not used.
 // But when a recursive or errorcheck mutex is used on 32-bit devices, we need to add the
 // owner_tid value in the value argument for __futex_wait, otherwise we may always get EAGAIN error.
 
 #if defined(__LP64__)
-  return __futex_wait_ex(&mutex->state, shared, old_state, rel_timeout);
+  return __futex_wait_ex(&mutex->state, shared, old_state, use_realtime_clock, abs_timeout);
 
 #else
   // This implementation works only when the layout of pthread_mutex_internal_t matches below expectation.
@@ -412,19 +413,21 @@
   static_assert(offsetof(pthread_mutex_internal_t, owner_tid) == 2, "");
 
   uint32_t owner_tid = atomic_load_explicit(&mutex->owner_tid, memory_order_relaxed);
-  return __futex_wait_ex(&mutex->state, shared, (owner_tid << 16) | old_state, rel_timeout);
+  return __futex_wait_ex(&mutex->state, shared, (owner_tid << 16) | old_state,
+                         use_realtime_clock, abs_timeout);
 #endif
 }
 
 static int __pthread_mutex_lock_with_timeout(pthread_mutex_internal_t* mutex,
-                                           const timespec* abs_timeout_or_null, clockid_t clock) {
+                                             bool use_realtime_clock,
+                                             const timespec* abs_timeout_or_null) {
     uint16_t old_state = atomic_load_explicit(&mutex->state, memory_order_relaxed);
     uint16_t mtype = (old_state & MUTEX_TYPE_MASK);
     uint16_t shared = (old_state & MUTEX_SHARED_MASK);
 
     // Handle common case first.
     if ( __predict_true(mtype == MUTEX_TYPE_BITS_NORMAL) ) {
-        return __pthread_normal_mutex_lock(mutex, shared, abs_timeout_or_null, clock);
+        return __pthread_normal_mutex_lock(mutex, shared, use_realtime_clock, abs_timeout_or_null);
     }
 
     // Do we already own this recursive or error-check mutex?
@@ -484,16 +487,13 @@
             old_state = new_state;
         }
 
-        // We are in locked_contended state, sleep until someone wakes us up.
-        timespec ts;
-        timespec* rel_timeout = NULL;
-        if (abs_timeout_or_null != NULL) {
-            rel_timeout = &ts;
-            if (!timespec_from_absolute_timespec(*rel_timeout, *abs_timeout_or_null, clock)) {
-                return ETIMEDOUT;
-            }
+        int result = check_timespec(abs_timeout_or_null, true);
+        if (result != 0) {
+            return result;
         }
-        if (__recursive_or_errorcheck_mutex_wait(mutex, shared, old_state, rel_timeout) == -ETIMEDOUT) {
+        // We are in locked_contended state, sleep until someone wakes us up.
+        if (__recursive_or_errorcheck_mutex_wait(mutex, shared, old_state, use_realtime_clock,
+                                                 abs_timeout_or_null) == -ETIMEDOUT) {
             return ETIMEDOUT;
         }
         old_state = atomic_load_explicit(&mutex->state, memory_order_relaxed);
@@ -518,7 +518,7 @@
         return 0;
       }
     }
-    return __pthread_mutex_lock_with_timeout(mutex, NULL, 0);
+    return __pthread_mutex_lock_with_timeout(mutex, false, nullptr);
 }
 
 int pthread_mutex_unlock(pthread_mutex_t* mutex_interface) {
@@ -613,17 +613,12 @@
 
 #if !defined(__LP64__)
 extern "C" int pthread_mutex_lock_timeout_np(pthread_mutex_t* mutex_interface, unsigned ms) {
+    timespec ts;
+    timespec_from_ms(ts, ms);
     timespec abs_timeout;
-    clock_gettime(CLOCK_MONOTONIC, &abs_timeout);
-    abs_timeout.tv_sec  += ms / 1000;
-    abs_timeout.tv_nsec += (ms % 1000) * 1000000;
-    if (abs_timeout.tv_nsec >= NS_PER_S) {
-        abs_timeout.tv_sec++;
-        abs_timeout.tv_nsec -= NS_PER_S;
-    }
-
+    absolute_timespec_from_timespec(abs_timeout, ts, CLOCK_MONOTONIC);
     int error = __pthread_mutex_lock_with_timeout(__get_internal_mutex(mutex_interface),
-                                                  &abs_timeout, CLOCK_MONOTONIC);
+                                                  false, &abs_timeout);
     if (error == ETIMEDOUT) {
         error = EBUSY;
     }
@@ -633,14 +628,18 @@
 
 int pthread_mutex_timedlock(pthread_mutex_t* mutex_interface, const timespec* abs_timeout) {
     return __pthread_mutex_lock_with_timeout(__get_internal_mutex(mutex_interface),
-                                             abs_timeout, CLOCK_REALTIME);
+                                             true, abs_timeout);
 }
 
 int pthread_mutex_destroy(pthread_mutex_t* mutex_interface) {
-    // Use trylock to ensure that the mutex is valid and not already locked.
-    int error = pthread_mutex_trylock(mutex_interface);
-    if (error != 0) {
-        return error;
+    pthread_mutex_internal_t* mutex = __get_internal_mutex(mutex_interface);
+    uint16_t old_state = atomic_load_explicit(&mutex->state, memory_order_relaxed);
+    // Store 0xffff to make the mutex unusable. Although POSIX standard says it is undefined
+    // behavior to destroy a locked mutex, we prefer not to change mutex->state in that situation.
+    if (MUTEX_STATE_BITS_IS_UNLOCKED(old_state) &&
+        atomic_compare_exchange_strong_explicit(&mutex->state, &old_state, 0xffff,
+                                                memory_order_relaxed, memory_order_relaxed)) {
+      return 0;
     }
-    return 0;
+    return EBUSY;
 }
diff --git a/libc/bionic/pthread_once.cpp b/libc/bionic/pthread_once.cpp
index 7688a23..f48eadc 100644
--- a/libc/bionic/pthread_once.cpp
+++ b/libc/bionic/pthread_once.cpp
@@ -79,7 +79,7 @@
     }
 
     // The initialization is underway, wait for its finish.
-    __futex_wait_ex(once_control_ptr, 0, old_value, NULL);
+    __futex_wait_ex(once_control_ptr, 0, old_value, false, nullptr);
     old_value = atomic_load_explicit(once_control_ptr, memory_order_acquire);
   }
 }
diff --git a/libc/bionic/pthread_rwlock.cpp b/libc/bionic/pthread_rwlock.cpp
index 934210e..a065295 100644
--- a/libc/bionic/pthread_rwlock.cpp
+++ b/libc/bionic/pthread_rwlock.cpp
@@ -294,9 +294,13 @@
   }
 
   while (true) {
-    int ret = __pthread_rwlock_tryrdlock(rwlock);
-    if (ret == 0 || ret == EAGAIN) {
-      return ret;
+    int result = __pthread_rwlock_tryrdlock(rwlock);
+    if (result == 0 || result == EAGAIN) {
+      return result;
+    }
+    result = check_timespec(abs_timeout_or_null, true);
+    if (result != 0) {
+      return result;
     }
 
     int old_state = atomic_load_explicit(&rwlock->state, memory_order_relaxed);
@@ -304,16 +308,6 @@
       continue;
     }
 
-    timespec ts;
-    timespec* rel_timeout = NULL;
-
-    if (abs_timeout_or_null != NULL) {
-      rel_timeout = &ts;
-      if (!timespec_from_absolute_timespec(*rel_timeout, *abs_timeout_or_null, CLOCK_REALTIME)) {
-        return ETIMEDOUT;
-      }
-    }
-
     rwlock->pending_lock.lock();
     rwlock->pending_reader_count++;
 
@@ -327,10 +321,10 @@
     int old_serial = rwlock->pending_reader_wakeup_serial;
     rwlock->pending_lock.unlock();
 
-    int futex_ret = 0;
+    int futex_result = 0;
     if (!__can_acquire_read_lock(old_state, rwlock->writer_nonrecursive_preferred)) {
-      futex_ret = __futex_wait_ex(&rwlock->pending_reader_wakeup_serial, rwlock->pshared,
-                                  old_serial, rel_timeout);
+      futex_result = __futex_wait_ex(&rwlock->pending_reader_wakeup_serial, rwlock->pshared,
+                                  old_serial, true, abs_timeout_or_null);
     }
 
     rwlock->pending_lock.lock();
@@ -341,7 +335,7 @@
     }
     rwlock->pending_lock.unlock();
 
-    if (futex_ret == -ETIMEDOUT) {
+    if (futex_result == -ETIMEDOUT) {
       return ETIMEDOUT;
     }
   }
@@ -372,9 +366,13 @@
     return EDEADLK;
   }
   while (true) {
-    int ret = __pthread_rwlock_trywrlock(rwlock);
-    if (ret == 0) {
-      return ret;
+    int result = __pthread_rwlock_trywrlock(rwlock);
+    if (result == 0) {
+      return result;
+    }
+    result = check_timespec(abs_timeout_or_null, true);
+    if (result != 0) {
+      return result;
     }
 
     int old_state = atomic_load_explicit(&rwlock->state, memory_order_relaxed);
@@ -382,16 +380,6 @@
       continue;
     }
 
-    timespec ts;
-    timespec* rel_timeout = NULL;
-
-    if (abs_timeout_or_null != NULL) {
-      rel_timeout = &ts;
-      if (!timespec_from_absolute_timespec(*rel_timeout, *abs_timeout_or_null, CLOCK_REALTIME)) {
-        return ETIMEDOUT;
-      }
-    }
-
     rwlock->pending_lock.lock();
     rwlock->pending_writer_count++;
 
@@ -401,10 +389,10 @@
     int old_serial = rwlock->pending_writer_wakeup_serial;
     rwlock->pending_lock.unlock();
 
-    int futex_ret = 0;
+    int futex_result = 0;
     if (!__can_acquire_write_lock(old_state)) {
-      futex_ret = __futex_wait_ex(&rwlock->pending_writer_wakeup_serial, rwlock->pshared,
-                                  old_serial, rel_timeout);
+      futex_result = __futex_wait_ex(&rwlock->pending_writer_wakeup_serial, rwlock->pshared,
+                                  old_serial, true, abs_timeout_or_null);
     }
 
     rwlock->pending_lock.lock();
@@ -415,7 +403,7 @@
     }
     rwlock->pending_lock.unlock();
 
-    if (futex_ret == -ETIMEDOUT) {
+    if (futex_result == -ETIMEDOUT) {
       return ETIMEDOUT;
     }
   }
@@ -427,7 +415,7 @@
   if (__predict_true(__pthread_rwlock_tryrdlock(rwlock) == 0)) {
     return 0;
   }
-  return __pthread_rwlock_timedrdlock(rwlock, NULL);
+  return __pthread_rwlock_timedrdlock(rwlock, nullptr);
 }
 
 int pthread_rwlock_timedrdlock(pthread_rwlock_t* rwlock_interface, const timespec* abs_timeout) {
@@ -446,7 +434,7 @@
   if (__predict_true(__pthread_rwlock_trywrlock(rwlock) == 0)) {
     return 0;
   }
-  return __pthread_rwlock_timedwrlock(rwlock, NULL);
+  return __pthread_rwlock_timedwrlock(rwlock, nullptr);
 }
 
 int pthread_rwlock_timedwrlock(pthread_rwlock_t* rwlock_interface, const timespec* abs_timeout) {
diff --git a/libc/bionic/pthread_spinlock.cpp b/libc/bionic/pthread_spinlock.cpp
new file mode 100644
index 0000000..f26f283
--- /dev/null
+++ b/libc/bionic/pthread_spinlock.cpp
@@ -0,0 +1,81 @@
+/*
+ * Copyright (C) 2015 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 <pthread.h>
+
+#include "private/bionic_lock.h"
+
+// User-level spinlocks can be hazardous to battery life on Android.
+// We implement a simple compromise that behaves mostly like a spinlock,
+// but prevents excessively long spinning.
+
+struct pthread_spinlock_internal_t {
+  Lock lock;
+};
+
+static_assert(sizeof(pthread_spinlock_t) == sizeof(pthread_spinlock_internal_t),
+              "pthread_spinlock_t should actually be pthread_spinlock_internal_t.");
+
+static_assert(alignof(pthread_spinlock_t) >= 4,
+              "pthread_spinlock_t should fulfill the alignment of pthread_spinlock_internal_t.");
+
+static inline pthread_spinlock_internal_t* __get_internal_spinlock(pthread_spinlock_t* lock) {
+  return reinterpret_cast<pthread_spinlock_internal_t*>(lock);
+}
+
+int pthread_spin_init(pthread_spinlock_t* lock_interface, int pshared) {
+  pthread_spinlock_internal_t* lock = __get_internal_spinlock(lock_interface);
+  lock->lock.init(pshared);
+  return 0;
+}
+
+int pthread_spin_destroy(pthread_spinlock_t* lock_interface) {
+  pthread_spinlock_internal_t* lock = __get_internal_spinlock(lock_interface);
+  return lock->lock.trylock() ? 0 : EBUSY;
+}
+
+int pthread_spin_trylock(pthread_spinlock_t* lock_interface) {
+  pthread_spinlock_internal_t* lock = __get_internal_spinlock(lock_interface);
+  return lock->lock.trylock() ? 0 : EBUSY;
+}
+
+int pthread_spin_lock(pthread_spinlock_t* lock_interface) {
+  pthread_spinlock_internal_t* lock = __get_internal_spinlock(lock_interface);
+  for (int i = 0; i < 10000; ++i) {
+    if (lock->lock.trylock()) {
+      return 0;
+    }
+  }
+  lock->lock.lock();
+  return 0;
+}
+
+int pthread_spin_unlock(pthread_spinlock_t* lock_interface) {
+  pthread_spinlock_internal_t* lock = __get_internal_spinlock(lock_interface);
+  lock->lock.unlock();
+  return 0;
+}
diff --git a/libc/bionic/pty.cpp b/libc/bionic/pty.cpp
index 1a37847..d699ff5 100644
--- a/libc/bionic/pty.cpp
+++ b/libc/bionic/pty.cpp
@@ -151,22 +151,24 @@
   return 0;
 }
 
-int forkpty(int* master, char* name, const termios* t, const winsize* ws) {
+int forkpty(int* amaster, char* name, const termios* t, const winsize* ws) {
+  int master;
   int slave;
-  if (openpty(master, &slave, name, t, ws) == -1) {
+  if (openpty(&master, &slave, name, t, ws) == -1) {
     return -1;
   }
 
   pid_t pid = fork();
   if (pid == -1) {
-    close(*master);
+    close(master);
     close(slave);
     return -1;
   }
 
   if (pid == 0) {
     // Child.
-    close(*master);
+    *amaster = -1;
+    close(master);
     if (login_tty(slave) == -1) {
       _exit(1);
     }
@@ -174,6 +176,7 @@
   }
 
   // Parent.
+  *amaster = master;
   close(slave);
   return pid;
 }
diff --git a/libc/bionic/scandir.cpp b/libc/bionic/scandir.cpp
index ee62fee..e55be42 100644
--- a/libc/bionic/scandir.cpp
+++ b/libc/bionic/scandir.cpp
@@ -16,9 +16,11 @@
 
 #include <dirent.h>
 
+#include <fcntl.h>
 #include <errno.h>
 #include <stdlib.h>
 #include <string.h>
+#include <unistd.h>
 
 #include "private/bionic_macros.h"
 #include "private/ScopedReaddir.h"
@@ -26,7 +28,7 @@
 // A smart pointer to the scandir dirent**.
 class ScandirResult {
  public:
-  ScandirResult() : names_(NULL), size_(0), capacity_(0) {
+  ScandirResult() : names_(nullptr), size_(0), capacity_(0) {
   }
 
   ~ScandirResult() {
@@ -42,7 +44,7 @@
 
   dirent** release() {
     dirent** result = names_;
-    names_ = NULL;
+    names_ = nullptr;
     size_ = capacity_ = 0;
     return result;
   }
@@ -52,7 +54,7 @@
       size_t new_capacity = capacity_ + 32;
       dirent** new_names =
           reinterpret_cast<dirent**>(realloc(names_, new_capacity * sizeof(dirent*)));
-      if (new_names == NULL) {
+      if (new_names == nullptr) {
         return false;
       }
       names_ = new_names;
@@ -60,7 +62,7 @@
     }
 
     dirent* copy = CopyDirent(entry);
-    if (copy == NULL) {
+    if (copy == nullptr) {
       return false;
     }
     names_[size_++] = copy;
@@ -69,7 +71,7 @@
 
   void Sort(int (*comparator)(const dirent**, const dirent**)) {
     // If we have entries and a comparator, sort them.
-    if (size_ > 0 && comparator != NULL) {
+    if (size_ > 0 && comparator != nullptr) {
       qsort(names_, size_, sizeof(dirent*),
             reinterpret_cast<int (*)(const void*, const void*)>(comparator));
     }
@@ -91,19 +93,29 @@
   DISALLOW_COPY_AND_ASSIGN(ScandirResult);
 };
 
-int scandir(const char* dirname, dirent*** name_list,
-            int (*filter)(const dirent*),
-            int (*comparator)(const dirent**, const dirent**)) {
-  ScopedReaddir reader(dirname);
+int scandirat(int parent_fd, const char* dir_name, dirent*** name_list,
+              int (*filter)(const dirent*),
+              int (*comparator)(const dirent**, const dirent**)) {
+  DIR* dir = nullptr;
+  if (parent_fd == AT_FDCWD) {
+    dir = opendir(dir_name);
+  } else {
+    int dir_fd = openat(parent_fd, dir_name, O_CLOEXEC | O_DIRECTORY | O_RDONLY);
+    if (dir_fd != -1) {
+      dir = fdopendir(dir_fd);
+    }
+  }
+
+  ScopedReaddir reader(dir);
   if (reader.IsBad()) {
     return -1;
   }
 
   ScandirResult names;
   dirent* entry;
-  while ((entry = reader.ReadEntry()) != NULL) {
+  while ((entry = reader.ReadEntry()) != nullptr) {
     // If we have a filter, skip names that don't match.
-    if (filter != NULL && !(*filter)(entry)) {
+    if (filter != nullptr && !(*filter)(entry)) {
       continue;
     }
     names.Add(entry);
@@ -115,4 +127,11 @@
   *name_list = names.release();
   return size;
 }
+__strong_alias(scandirat64, scandirat);
+
+int scandir(const char* dir_path, dirent*** name_list,
+            int (*filter)(const dirent*),
+            int (*comparator)(const dirent**, const dirent**)) {
+  return scandirat(AT_FDCWD, dir_path, name_list, filter, comparator);
+}
 __strong_alias(scandir64, scandir);
diff --git a/libc/bionic/semaphore.cpp b/libc/bionic/semaphore.cpp
index 0b04650..1981647 100644
--- a/libc/bionic/semaphore.cpp
+++ b/libc/bionic/semaphore.cpp
@@ -41,6 +41,7 @@
 
 #include "private/bionic_constants.h"
 #include "private/bionic_futex.h"
+#include "private/bionic_sdk_version.h"
 #include "private/bionic_time_conversions.h"
 
 // In this implementation, a semaphore contains a
@@ -80,7 +81,7 @@
 #define SEMCOUNT_ONE              SEMCOUNT_FROM_VALUE(1)
 
 // The value -1 as a sem->count bit-pattern.
-#define SEMCOUNT_MINUS_ONE        SEMCOUNT_FROM_VALUE(-1)
+#define SEMCOUNT_MINUS_ONE        SEMCOUNT_FROM_VALUE(~0U)
 
 #define SEMCOUNT_DECREMENT(sval)    (((sval) - (1U << SEMCOUNT_VALUE_SHIFT)) & SEMCOUNT_VALUE_MASK)
 #define SEMCOUNT_INCREMENT(sval)    (((sval) + (1U << SEMCOUNT_VALUE_SHIFT)) & SEMCOUNT_VALUE_MASK)
@@ -220,7 +221,13 @@
       return 0;
     }
 
-    __futex_wait_ex(sem_count_ptr, shared, shared | SEMCOUNT_MINUS_ONE, NULL);
+    int result = __futex_wait_ex(sem_count_ptr, shared, shared | SEMCOUNT_MINUS_ONE, false, nullptr);
+    if (bionic_get_application_target_sdk_version() > 23) {
+      if (result ==-EINTR) {
+        errno = EINTR;
+        return -1;
+      }
+    }
   }
 }
 
@@ -235,36 +242,29 @@
   }
 
   // Check it as per POSIX.
-  if (abs_timeout == NULL || abs_timeout->tv_sec < 0 || abs_timeout->tv_nsec < 0 || abs_timeout->tv_nsec >= NS_PER_S) {
-    errno = EINVAL;
+  int result = check_timespec(abs_timeout, false);
+  if (result != 0) {
+    errno = result;
     return -1;
   }
 
   unsigned int shared = SEM_GET_SHARED(sem_count_ptr);
 
   while (true) {
-    // POSIX mandates CLOCK_REALTIME here.
-    timespec ts;
-    if (!timespec_from_absolute_timespec(ts, *abs_timeout, CLOCK_REALTIME)) {
-      errno = ETIMEDOUT;
-      return -1;
-    }
-
     // Try to grab the semaphore. If the value was 0, this will also change it to -1.
     if (__sem_dec(sem_count_ptr) > 0) {
-      break;
+      return 0;
     }
 
     // Contention detected. Wait for a wakeup event.
-    int ret = __futex_wait_ex(sem_count_ptr, shared, shared | SEMCOUNT_MINUS_ONE, &ts);
+    int result = __futex_wait_ex(sem_count_ptr, shared, shared | SEMCOUNT_MINUS_ONE, true, abs_timeout);
 
     // Return in case of timeout or interrupt.
-    if (ret == -ETIMEDOUT || ret == -EINTR) {
-      errno = -ret;
+    if (result == -ETIMEDOUT || result == -EINTR) {
+      errno = -result;
       return -1;
     }
   }
-  return 0;
 }
 
 int sem_post(sem_t* sem) {
diff --git a/libc/bionic/setjmp_cookie.cpp b/libc/bionic/setjmp_cookie.cpp
new file mode 100644
index 0000000..3be675a
--- /dev/null
+++ b/libc/bionic/setjmp_cookie.cpp
@@ -0,0 +1,69 @@
+/*
+ * Copyright (C) 2015 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 <assert.h>
+#include <errno.h>
+#include <stddef.h>
+#include <stdlib.h>
+#include <string.h>
+#include <sys/auxv.h>
+#include <sys/cdefs.h>
+
+#include "private/bionic_globals.h"
+#include "private/libc_logging.h"
+#include "private/KernelArgumentBlock.h"
+
+void __libc_init_setjmp_cookie(libc_globals* globals,
+                               KernelArgumentBlock& args) {
+  char* random_data = reinterpret_cast<char*>(args.getauxval(AT_RANDOM));
+  long value = *reinterpret_cast<long*>(random_data + 8);
+
+  // Mask off the last bit to store the signal flag.
+  globals->setjmp_cookie = value & ~1;
+}
+
+extern "C" __LIBC_HIDDEN__ long __bionic_setjmp_cookie_get(long sigflag) {
+  if (sigflag & ~1) {
+    __libc_fatal("unexpected sigflag value: %ld", sigflag);
+  }
+
+  return __libc_globals->setjmp_cookie | sigflag;
+}
+
+// Aborts if cookie doesn't match, returns the signal flag otherwise.
+extern "C" __LIBC_HIDDEN__ long __bionic_setjmp_cookie_check(long cookie) {
+  if (__libc_globals->setjmp_cookie != (cookie & ~1)) {
+    __libc_fatal("setjmp cookie mismatch");
+  }
+
+  return cookie & 1;
+}
+
+extern "C" __LIBC_HIDDEN__ long __bionic_setjmp_checksum_mismatch() {
+  __libc_fatal("setjmp checksum mismatch");
+}
diff --git a/libc/bionic/signal.cpp b/libc/bionic/signal.cpp
index 74a2f65..13d1882 100644
--- a/libc/bionic/signal.cpp
+++ b/libc/bionic/signal.cpp
@@ -28,12 +28,7 @@
 
 #include <signal.h>
 
-#ifdef __LP64__
-static
-#else
-__LIBC_HIDDEN__
-#endif
-sighandler_t _signal(int signum, sighandler_t handler, int flags) {
+__LIBC_HIDDEN__ sighandler_t _signal(int signum, sighandler_t handler, int flags) {
   struct sigaction sa;
   sigemptyset(&sa.sa_mask);
   sa.sa_handler = handler;
diff --git a/libc/upstream-freebsd/android/include/spinlock.h b/libc/bionic/strchrnul.cpp
similarity index 71%
copy from libc/upstream-freebsd/android/include/spinlock.h
copy to libc/bionic/strchrnul.cpp
index f5c3785..55422e0 100644
--- a/libc/upstream-freebsd/android/include/spinlock.h
+++ b/libc/bionic/strchrnul.cpp
@@ -1,5 +1,5 @@
 /*
- * Copyright (C) 2013 The Android Open Source Project
+ * Copyright (C) 2015 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,9 +14,9 @@
  * limitations under the License.
  */
 
-#ifndef _BIONIC_FREEBSD_SPINLOCK_H_included
-#define _BIONIC_FREEBSD_SPINLOCK_H_included
-
-/* TODO: until we have the FreeBSD findfp.c, this is useless. */
-
-#endif
+extern "C" const char* strchrnul(const char* s, int ch) {
+  while (*s && *s != ch) {
+    ++s;
+  }
+  return s;
+}
diff --git a/libc/bionic/stubs.cpp b/libc/bionic/stubs.cpp
index b57aeda..374d015 100644
--- a/libc/bionic/stubs.cpp
+++ b/libc/bionic/stubs.cpp
@@ -39,6 +39,7 @@
 #include <unistd.h>
 
 #include "private/android_filesystem_config.h"
+#include "private/bionic_macros.h"
 #include "private/ErrnoRestorer.h"
 #include "private/libc_logging.h"
 #include "private/ThreadLocalBuffer.h"
@@ -66,11 +67,15 @@
 static ThreadLocalBuffer<group_state_t> g_group_tls_buffer;
 static ThreadLocalBuffer<passwd_state_t> g_passwd_tls_buffer;
 
+static void init_group_state(group_state_t* state) {
+  memset(state, 0, sizeof(group_state_t));
+  state->group_.gr_mem = state->group_members_;
+}
+
 static group_state_t* __group_state() {
   group_state_t* result = g_group_tls_buffer.get();
   if (result != nullptr) {
-    memset(result, 0, sizeof(group_state_t));
-    result->group_.gr_mem = result->group_members_;
+    init_group_state(result);
   }
   return result;
 }
@@ -111,6 +116,7 @@
   snprintf(buf, byte_count, "%s%c%s%c%s", src->pw_name, 0, src->pw_dir, 0, src->pw_shell);
 
   // pw_passwd and pw_gecos are non-POSIX and unused (always NULL) in bionic.
+  // Note: On LP32, we define pw_gecos to pw_passwd since they're both NULL.
   dst->pw_passwd = NULL;
 #if defined(__LP64__)
   dst->pw_gecos = NULL;
@@ -201,7 +207,7 @@
 // u0_a1234 -> 0 * AID_USER + AID_APP + 1234
 // u2_i1000 -> 2 * AID_USER + AID_ISOLATED_START + 1000
 // u1_system -> 1 * AID_USER + android_ids['system']
-// returns 0 and sets errno to ENOENT in case of error
+// returns 0 and sets errno to ENOENT in case of error.
 static id_t app_id_from_name(const char* name, bool is_group) {
   char* end;
   unsigned long userid;
@@ -307,6 +313,54 @@
   }
 }
 
+// Translate an OEM name to the corresponding user/group id.
+// oem_XXX -> AID_OEM_RESERVED_2_START + XXX, iff XXX is within range.
+static id_t oem_id_from_name(const char* name) {
+  unsigned int id;
+  if (sscanf(name, "oem_%u", &id) != 1) {
+    return 0;
+  }
+  // Check OEM id is within range.
+  if (id > (AID_OEM_RESERVED_2_END - AID_OEM_RESERVED_2_START)) {
+    return 0;
+  }
+  return AID_OEM_RESERVED_2_START + static_cast<id_t>(id);
+}
+
+static passwd* oem_id_to_passwd(uid_t uid, passwd_state_t* state) {
+  if (uid < AID_OEM_RESERVED_2_START || uid > AID_OEM_RESERVED_2_END) {
+    return NULL;
+  }
+
+  snprintf(state->name_buffer_, sizeof(state->name_buffer_), "oem_%u",
+           uid - AID_OEM_RESERVED_2_START);
+  snprintf(state->dir_buffer_, sizeof(state->dir_buffer_), "/");
+  snprintf(state->sh_buffer_, sizeof(state->sh_buffer_), "/system/bin/sh");
+
+  passwd* pw = &state->passwd_;
+  pw->pw_name  = state->name_buffer_;
+  pw->pw_dir   = state->dir_buffer_;
+  pw->pw_shell = state->sh_buffer_;
+  pw->pw_uid   = uid;
+  pw->pw_gid   = uid;
+  return pw;
+}
+
+static group* oem_id_to_group(gid_t gid, group_state_t* state) {
+  if (gid < AID_OEM_RESERVED_2_START || gid > AID_OEM_RESERVED_2_END) {
+    return NULL;
+  }
+
+  snprintf(state->group_name_buffer_, sizeof(state->group_name_buffer_),
+           "oem_%u", gid - AID_OEM_RESERVED_2_START);
+
+  group* gr = &state->group_;
+  gr->gr_name   = state->group_name_buffer_;
+  gr->gr_gid    = gid;
+  gr->gr_mem[0] = gr->gr_name;
+  return gr;
+}
+
 // Translate a uid into the corresponding name.
 // 0 to AID_APP-1                   -> "system", "radio", etc.
 // AID_APP to AID_ISOLATED_START-1  -> u0_a1234
@@ -366,6 +420,11 @@
   if (pw != NULL) {
     return pw;
   }
+  // Handle OEM range.
+  pw = oem_id_to_passwd(uid, state);
+  if (pw != NULL) {
+    return pw;
+  }
   return app_id_to_passwd(uid, state);
 }
 
@@ -379,6 +438,11 @@
   if (pw != NULL) {
     return pw;
   }
+  // Handle OEM range.
+  pw = oem_id_to_passwd(oem_id_from_name(login), state);
+  if (pw != NULL) {
+    return pw;
+  }
   return app_id_to_passwd(app_id_from_name(login, false), state);
 }
 
@@ -397,17 +461,38 @@
   return (pw != NULL) ? pw->pw_name : NULL;
 }
 
+static group* getgrgid_internal(gid_t gid, group_state_t* state) {
+  group* grp = android_id_to_group(state, gid);
+  if (grp != NULL) {
+    return grp;
+  }
+  // Handle OEM range.
+  grp = oem_id_to_group(gid, state);
+  if (grp != NULL) {
+    return grp;
+  }
+  return app_id_to_group(gid, state);
+}
+
 group* getgrgid(gid_t gid) { // NOLINT: implementing bad function.
   group_state_t* state = __group_state();
   if (state == NULL) {
     return NULL;
   }
+  return getgrgid_internal(gid, state);
+}
 
-  group* gr = android_id_to_group(state, gid);
-  if (gr != NULL) {
-    return gr;
+static group* getgrnam_internal(const char* name, group_state_t* state) {
+  group* grp = android_name_to_group(state, name);
+  if (grp != NULL) {
+    return grp;
   }
-  return app_id_to_group(gid, state);
+  // Handle OEM range.
+  grp = oem_id_to_group(oem_id_from_name(name), state);
+  if (grp != NULL) {
+    return grp;
+  }
+  return app_id_to_group(app_id_from_name(name, true), state);
 }
 
 group* getgrnam(const char* name) { // NOLINT: implementing bad function.
@@ -415,11 +500,36 @@
   if (state == NULL) {
     return NULL;
   }
+  return getgrnam_internal(name, state);
+}
 
-  if (android_name_to_group(state, name) != 0) {
-    return &state->group_;
+static int getgroup_r(bool by_name, const char* name, gid_t gid, struct group* grp, char* buf,
+                      size_t buflen, struct group** result) {
+  ErrnoRestorer errno_restorer;
+  *result = NULL;
+  char* p = reinterpret_cast<char*>(
+      BIONIC_ALIGN(reinterpret_cast<uintptr_t>(buf), sizeof(uintptr_t)));
+  if (p + sizeof(group_state_t) > buf + buflen) {
+    return ERANGE;
   }
-  return app_id_to_group(app_id_from_name(name, true), state);
+  group_state_t* state = reinterpret_cast<group_state_t*>(p);
+  init_group_state(state);
+  group* retval = (by_name ? getgrnam_internal(name, state) : getgrgid_internal(gid, state));
+  if (retval != NULL) {
+    *grp = *retval;
+    *result = grp;
+    return 0;
+  }
+  return errno;
+}
+
+int getgrgid_r(gid_t gid, struct group* grp, char* buf, size_t buflen, struct group** result) {
+  return getgroup_r(false, NULL, gid, grp, buf, buflen, result);
+}
+
+int getgrnam_r(const char* name, struct group* grp, char* buf, size_t buflen,
+               struct group **result) {
+  return getgroup_r(true, name, 0, grp, buf, buflen, result);
 }
 
 // We don't have an /etc/networks, so all inputs return NULL.
diff --git a/libc/bionic/sysconf.cpp b/libc/bionic/sysconf.cpp
index c301b27..125b3c9 100644
--- a/libc/bionic/sysconf.cpp
+++ b/libc/bionic/sysconf.cpp
@@ -41,16 +41,6 @@
 
 #include "private/bionic_tls.h"
 
-static int __sysconf_monotonic_clock() {
-  timespec t;
-  int rc = clock_getres(CLOCK_MONOTONIC, &t);
-  return (rc == -1) ? -1 : _POSIX_VERSION;
-}
-
-static bool __sysconf_has_clock(clockid_t clock_id) {
-  return clock_getres(clock_id, NULL) == 0;
-}
-
 static long __sysconf_rlimit(int resource) {
   rlimit rl;
   getrlimit(resource, &rl);
@@ -97,8 +87,11 @@
     case _SC_ATEXIT_MAX:        return LONG_MAX;    // Unlimited.
     case _SC_IOV_MAX:           return UIO_MAXIOV;
 
-    case _SC_PAGESIZE:          // Fall through, PAGESIZE and PAGE_SIZE always hold the same value.
-    case _SC_PAGE_SIZE:         return PAGE_SIZE;
+    // _SC_PAGESIZE and _SC_PAGE_SIZE are distinct, but return the same value.
+    case _SC_PAGESIZE:
+    case _SC_PAGE_SIZE:
+      return static_cast<long>(getauxval(AT_PAGESZ));
+
     case _SC_XOPEN_UNIX:        return _XOPEN_UNIX;
     case _SC_AIO_LISTIO_MAX:    return _POSIX_AIO_LISTIO_MAX;     // Minimum requirement.
     case _SC_AIO_MAX:           return _POSIX_AIO_MAX;            // Minimum requirement.
@@ -144,7 +137,7 @@
     case _SC_NPROCESSORS_ONLN:  return get_nprocs();
     case _SC_PHYS_PAGES:        return get_phys_pages();
     case _SC_AVPHYS_PAGES:      return get_avphys_pages();
-    case _SC_MONOTONIC_CLOCK:   return __sysconf_monotonic_clock();
+    case _SC_MONOTONIC_CLOCK:   return _POSIX_VERSION;
 
     case _SC_2_PBS:             return -1;     // Obsolescent in POSIX.1-2008.
     case _SC_2_PBS_ACCOUNTING:  return -1;     // Obsolescent in POSIX.1-2008.
@@ -155,8 +148,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 __sysconf_has_clock(CLOCK_PROCESS_CPUTIME_ID) ?_POSIX_VERSION : -1;
+    case _SC_CPUTIME:           return _POSIX_VERSION;
 
     case _SC_HOST_NAME_MAX:     return _POSIX_HOST_NAME_MAX;    // Minimum requirement.
     case _SC_IPV6:              return _POSIX_IPV6;
@@ -169,8 +161,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 __sysconf_has_clock(CLOCK_THREAD_CPUTIME_ID) ? _POSIX_VERSION : -1;
+    case _SC_THREAD_CPUTIME:    return _POSIX_VERSION;
 
     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/sysinfo.cpp b/libc/bionic/sysinfo.cpp
index 82cb76a..1cb5c79 100644
--- a/libc/bionic/sysinfo.cpp
+++ b/libc/bionic/sysinfo.cpp
@@ -29,10 +29,11 @@
 #include <sys/sysinfo.h>
 
 #include <dirent.h>
-#include <limits.h>
 #include <stdio.h>
 #include <string.h>
+#include <unistd.h>
 
+#include "private/get_cpu_count_from_string.h"
 #include "private/ScopedReaddir.h"
 
 static bool __matches_cpuN(const char* s) {
@@ -61,26 +62,18 @@
 }
 
 int get_nprocs() {
-  FILE* fp = fopen("/proc/stat", "re");
-  if (fp == NULL) {
-    return 1;
-  }
-
-  int result = 0;
-  char buf[256];
-  while (fgets(buf, sizeof(buf), fp) != NULL) {
-    // Extract just the first word from the line.
-    // 'cpu0 7976751 1364388 3116842 469770388 8629405 0 49047 0 0 0'
-    char* p = strchr(buf, ' ');
-    if (p != NULL) {
-      *p = 0;
+  int cpu_count = 1;
+  FILE* fp = fopen("/sys/devices/system/cpu/online", "re");
+  if (fp != nullptr) {
+    char* line = nullptr;
+    size_t len = 0;
+    if (getline(&line, &len, fp) != -1) {
+      cpu_count = GetCpuCountFromString(line);
+      free(line);
     }
-    if (__matches_cpuN(buf)) {
-      ++result;
-    }
+    fclose(fp);
   }
-  fclose(fp);
-  return result;
+  return cpu_count;
 }
 
 static int __get_meminfo_page_count(const char* pattern) {
@@ -94,7 +87,7 @@
   while (fgets(buf, sizeof(buf), fp) != NULL) {
     long total;
     if (sscanf(buf, pattern, &total) == 1) {
-      page_count = static_cast<int>(total / (PAGE_SIZE / 1024));
+      page_count = static_cast<int>(total / (sysconf(_SC_PAGE_SIZE) / 1024));
       break;
     }
   }
diff --git a/libc/bionic/system_properties.cpp b/libc/bionic/system_properties.cpp
index c436a16..9c992da 100644
--- a/libc/bionic/system_properties.cpp
+++ b/libc/bionic/system_properties.cpp
@@ -25,34 +25,38 @@
  * OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF
  * SUCH DAMAGE.
  */
-#include <new>
-#include <stdatomic.h>
-#include <stdio.h>
-#include <stdint.h>
-#include <stdlib.h>
-#include <unistd.h>
-#include <stddef.h>
+#include <ctype.h>
 #include <errno.h>
-#include <poll.h>
 #include <fcntl.h>
+#include <poll.h>
+#include <stdatomic.h>
 #include <stdbool.h>
+#include <stddef.h>
+#include <stdint.h>
+#include <stdio.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/socket.h>
-#include <sys/un.h>
 #include <sys/select.h>
+#include <sys/socket.h>
 #include <sys/stat.h>
 #include <sys/types.h>
-#include <netinet/in.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 "private/bionic_futex.h"
+#include "private/bionic_lock.h"
 #include "private/bionic_macros.h"
+#include "private/libc_logging.h"
 
 static const char property_service_socket[] = "/dev/socket/" PROP_SERVICE_NAME;
 
@@ -112,23 +116,57 @@
     DISALLOW_COPY_AND_ASSIGN(prop_bt);
 };
 
-struct prop_area {
-    uint32_t bytes_used;
-    atomic_uint_least32_t serial;
-    uint32_t magic;
-    uint32_t version;
-    uint32_t reserved[28];
-    char data[0];
+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));
+        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);
+        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, uint8_t namelen, uint_least32_t *const off);
+    prop_info *new_prop_info(const char *name, uint8_t namelen,
+                             const char *value, uint8_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,
+                          uint8_t namelen, bool alloc_if_needed);
+
+    const prop_info *find_property(prop_bt *const trie, const char *name,
+                                   uint8_t namelen, const char *value,
+                                   uint8_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);
 };
 
@@ -158,10 +196,11 @@
     }
 };
 
-static char property_filename[PATH_MAX] = PROP_FILENAME;
+static char property_filename[PROP_FILENAME_MAX] = PROP_FILENAME;
 static bool compat_mode = false;
 static size_t pa_data_size;
 static size_t pa_size;
+static bool initialized = false;
 
 // NOTE: This isn't static because system_properties_compat.c
 // requires it.
@@ -182,13 +221,12 @@
     return atoi(env);
 }
 
-static int map_prop_area_rw()
-{
+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(property_filename,
-                        O_RDWR | O_CREAT | O_NOFOLLOW | O_CLOEXEC | O_EXCL, 0444);
+    const int fd = open(filename, O_RDWR | O_CREAT | O_NOFOLLOW | O_CLOEXEC | O_EXCL, 0444);
 
     if (fd < 0) {
         if (errno == EACCES) {
@@ -197,12 +235,31 @@
              */
             abort();
         }
-        return -1;
+        return nullptr;
+    }
+
+    if (context) {
+        if (fsetxattr(fd, XATTR_NAME_SELINUX, context, strlen(context) + 1, 0) != 0) {
+            __libc_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 -1;
+        return nullptr;
     }
 
     pa_size = PA_SIZE;
@@ -212,29 +269,26 @@
     void *const memory_area = mmap(NULL, pa_size, PROT_READ | PROT_WRITE, MAP_SHARED, fd, 0);
     if (memory_area == MAP_FAILED) {
         close(fd);
-        return -1;
+        return nullptr;
     }
 
     prop_area *pa = new(memory_area) prop_area(PROP_AREA_MAGIC, PROP_AREA_VERSION);
 
-    /* plug into the lib property services */
-    __system_property_area__ = pa;
-
     close(fd);
-    return 0;
+    return pa;
 }
 
-static int map_fd_ro(const int fd) {
+static prop_area* map_fd_ro(const int fd) {
     struct stat fd_stat;
     if (fstat(fd, &fd_stat) < 0) {
-        return -1;
+        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 -1;
+        return nullptr;
     }
 
     pa_size = fd_stat.st_size;
@@ -242,29 +296,28 @@
 
     void* const map_result = mmap(NULL, pa_size, PROT_READ, MAP_SHARED, fd, 0);
     if (map_result == MAP_FAILED) {
-        return -1;
+        return nullptr;
     }
 
     prop_area* pa = reinterpret_cast<prop_area*>(map_result);
-    if ((pa->magic != PROP_AREA_MAGIC) || (pa->version != PROP_AREA_VERSION &&
-                pa->version != PROP_AREA_VERSION_COMPAT)) {
+    if ((pa->magic() != PROP_AREA_MAGIC) ||
+        (pa->version() != PROP_AREA_VERSION &&
+         pa->version() != PROP_AREA_VERSION_COMPAT)) {
         munmap(pa, pa_size);
-        return -1;
+        return nullptr;
     }
 
-    if (pa->version == PROP_AREA_VERSION_COMPAT) {
+    if (pa->version() == PROP_AREA_VERSION_COMPAT) {
         compat_mode = true;
     }
 
-    __system_property_area__ = pa;
-    return 0;
+    return pa;
 }
 
-static int map_prop_area()
-{
-    int fd = open(property_filename, O_CLOEXEC | O_NOFOLLOW | O_RDONLY);
+static prop_area* map_prop_area(const char* filename, bool is_legacy) {
+    int fd = open(filename, O_CLOEXEC | O_NOFOLLOW | O_RDONLY);
     bool close_fd = true;
-    if (fd == -1 && errno == ENOENT) {
+    if (fd == -1 && errno == ENOENT && is_legacy) {
         /*
          * For backwards compatibility, if the file doesn't
          * exist, we use the environment to get the file descriptor.
@@ -273,16 +326,18 @@
          * returns other errors such as ENOMEM or ENFILE, since it
          * might be possible for an external program to trigger this
          * condition.
+         * Only do this for the legacy prop file, secured prop files
+         * do not have a backup
          */
         fd = get_fd_from_env();
         close_fd = false;
     }
 
     if (fd < 0) {
-        return -1;
+        return nullptr;
     }
 
-    const int map_result = map_fd_ro(fd);
+    prop_area* map_result = map_fd_ro(fd);
     if (close_fd) {
         close(fd);
     }
@@ -290,20 +345,19 @@
     return map_result;
 }
 
-static void *allocate_obj(const size_t size, uint_least32_t *const off)
+void *prop_area::allocate_obj(const size_t size, uint_least32_t *const off)
 {
-    prop_area *pa = __system_property_area__;
     const size_t aligned = BIONIC_ALIGN(size, sizeof(uint_least32_t));
-    if (pa->bytes_used + aligned > pa_data_size) {
+    if (bytes_used_ + aligned > pa_data_size) {
         return NULL;
     }
 
-    *off = pa->bytes_used;
-    pa->bytes_used += aligned;
-    return pa->data + *off;
+    *off = bytes_used_;
+    bytes_used_ += aligned;
+    return data_ + *off;
 }
 
-static prop_bt *new_prop_bt(const char *name, uint8_t namelen, uint_least32_t *const off)
+prop_bt *prop_area::new_prop_bt(const char *name, uint8_t namelen, uint_least32_t *const off)
 {
     uint_least32_t new_offset;
     void *const p = allocate_obj(sizeof(prop_bt) + namelen + 1, &new_offset);
@@ -316,7 +370,7 @@
     return NULL;
 }
 
-static prop_info *new_prop_info(const char *name, uint8_t namelen,
+prop_info *prop_area::new_prop_info(const char *name, uint8_t namelen,
         const char *value, uint8_t valuelen, uint_least32_t *const off)
 {
     uint_least32_t new_offset;
@@ -330,27 +384,25 @@
     return NULL;
 }
 
-static void *to_prop_obj(uint_least32_t off)
+void *prop_area::to_prop_obj(uint_least32_t off)
 {
     if (off > pa_data_size)
         return NULL;
-    if (!__system_property_area__)
-        return NULL;
 
-    return (__system_property_area__->data + off);
+    return (data_ + off);
 }
 
-static inline prop_bt *to_prop_bt(atomic_uint_least32_t* off_p) {
+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));
 }
 
-static inline prop_info *to_prop_info(atomic_uint_least32_t* off_p) {
+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));
 }
 
-static inline prop_bt *root_node()
+inline prop_bt *prop_area::root_node()
 {
     return reinterpret_cast<prop_bt*>(to_prop_obj(0));
 }
@@ -366,8 +418,8 @@
         return strncmp(one, two, one_len);
 }
 
-static prop_bt *find_prop_bt(prop_bt *const bt, const char *name,
-                             uint8_t namelen, bool alloc_if_needed)
+prop_bt *prop_area::find_prop_bt(prop_bt *const bt, const char *name,
+                                 uint8_t namelen, bool alloc_if_needed)
 {
 
     prop_bt* current = bt;
@@ -417,7 +469,7 @@
     }
 }
 
-static const prop_info *find_property(prop_bt *const trie, const char *name,
+const prop_info *prop_area::find_property(prop_bt *const trie, const char *name,
         uint8_t namelen, const char *value, uint8_t valuelen,
         bool alloc_if_needed)
 {
@@ -543,44 +595,442 @@
     cookie->count++;
 }
 
-static int foreach_property(prop_bt *const trie,
+bool prop_area::foreach_property(prop_bt *const trie,
         void (*propfn)(const prop_info *pi, void *cookie), void *cookie)
 {
     if (!trie)
-        return -1;
+        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 -1;
+            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 -1;
+            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 -1;
+            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 = __libc_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, false);
+    }
+    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 = __libc_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 = __libc_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, false);
+    }
+    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 = NULL;
+    char *tmp_buf = NULL;
+
+    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() {
+    FILE* file = fopen("/property_contexts", "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 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()
 {
-    return map_prop_area();
+    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, true);
+        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)
@@ -595,7 +1045,24 @@
 
 int __system_property_area_init()
 {
-    return map_prop_area_rw();
+    free_and_unmap_contexts();
+    mkdir(property_filename, S_IRWXU | S_IRGRP | S_IXGRP | S_IROTH | 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;
 }
 
 unsigned int __system_property_area_serial()
@@ -605,15 +1072,26 @@
         return -1;
     }
     // Make sure this read fulfilled before __system_property_serial
-    return atomic_load_explicit(&(pa->serial), memory_order_acquire);
+    return atomic_load_explicit(pa->serial(), memory_order_acquire);
 }
 
 const prop_info *__system_property_find(const char *name)
 {
+    if (!__system_property_area__) {
+        return nullptr;
+    }
+
     if (__predict_false(compat_mode)) {
         return __system_property_find_compat(name);
     }
-    return find_property(root_node(), name, strlen(name), NULL, 0, false);
+
+    prop_area* pa = get_prop_area_for_name(name);
+    if (!pa) {
+        __libc_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,
@@ -688,11 +1166,15 @@
 
 int __system_property_update(prop_info *pi, const char *value, unsigned int len)
 {
-    prop_area *pa = __system_property_area__;
-
     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);
@@ -708,10 +1190,10 @@
     __futex_wake(&pi->serial, INT32_MAX);
 
     atomic_store_explicit(
-        &pa->serial,
-        atomic_load_explicit(&pa->serial, memory_order_relaxed) + 1,
+        pa->serial(),
+        atomic_load_explicit(pa->serial(), memory_order_relaxed) + 1,
         memory_order_release);
-    __futex_wake(&pa->serial, INT32_MAX);
+    __futex_wake(pa->serial(), INT32_MAX);
 
     return 0;
 }
@@ -719,9 +1201,6 @@
 int __system_property_add(const char *name, unsigned int namelen,
             const char *value, unsigned int valuelen)
 {
-    prop_area *pa = __system_property_area__;
-    const prop_info *pi;
-
     if (namelen >= PROP_NAME_MAX)
         return -1;
     if (valuelen >= PROP_VALUE_MAX)
@@ -729,17 +1208,28 @@
     if (namelen < 1)
         return -1;
 
-    pi = find_property(root_node(), name, namelen, value, valuelen, true);
-    if (!pi)
+    if (!__system_property_area__) {
+        return -1;
+    }
+
+    prop_area* pa = get_prop_area_for_name(name);
+
+    if (!pa) {
+        __libc_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(
-        &pa->serial,
-        atomic_load_explicit(&pa->serial, memory_order_relaxed) + 1,
+        __system_property_area__->serial(),
+        atomic_load_explicit(__system_property_area__->serial(), memory_order_relaxed) + 1,
         memory_order_release);
-    __futex_wake(&pa->serial, INT32_MAX);
+    __futex_wake(__system_property_area__->serial(), INT32_MAX);
     return 0;
 }
 
@@ -761,9 +1251,13 @@
     prop_area *pa = __system_property_area__;
     uint32_t my_serial;
 
+    if (!pa) {
+        return 0;
+    }
+
     do {
-        __futex_wait(&pa->serial, serial, NULL);
-        my_serial = atomic_load_explicit(&pa->serial, memory_order_acquire);
+        __futex_wait(pa->serial(), serial, NULL);
+        my_serial = atomic_load_explicit(pa->serial(), memory_order_acquire);
     } while (my_serial == serial);
 
     return my_serial;
@@ -784,9 +1278,18 @@
 int __system_property_foreach(void (*propfn)(const prop_info *pi, void *cookie),
         void *cookie)
 {
+    if (!__system_property_area__) {
+        return -1;
+    }
+
     if (__predict_false(compat_mode)) {
         return __system_property_foreach_compat(propfn, cookie);
     }
 
-    return foreach_property(root_node(), propfn, cookie);
+    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 602d407..dc142a9 100644
--- a/libc/bionic/tmpfile.cpp
+++ b/libc/bionic/tmpfile.cpp
@@ -112,3 +112,4 @@
   }
   return fp;
 }
+__strong_alias(tmpfile64, tmpfile);
diff --git a/libc/bionic/vdso.cpp b/libc/bionic/vdso.cpp
index a240663..029c148 100644
--- a/libc/bionic/vdso.cpp
+++ b/libc/bionic/vdso.cpp
@@ -14,60 +14,49 @@
  * limitations under the License.
  */
 
+#include "private/bionic_globals.h"
+#include "private/bionic_vdso.h"
+
+#if defined(__aarch64__) || defined(__x86_64__) || defined (__i386__)
+
+#include <limits.h>
 #include <link.h>
 #include <string.h>
-#include <sys/auxv.h>
-#include <unistd.h>
-
-// x86 has a vdso, but there's nothing useful to us in it.
-#if defined(__aarch64__) || defined(__x86_64__)
-
-#if defined(__aarch64__)
-#define VDSO_CLOCK_GETTIME_SYMBOL "__kernel_clock_gettime"
-#define VDSO_GETTIMEOFDAY_SYMBOL  "__kernel_gettimeofday"
-#elif defined(__x86_64__)
-#define VDSO_CLOCK_GETTIME_SYMBOL "__vdso_clock_gettime"
-#define VDSO_GETTIMEOFDAY_SYMBOL  "__vdso_gettimeofday"
-#endif
-
+#include <sys/cdefs.h>
+#include <sys/time.h>
 #include <time.h>
-
-extern "C" int __clock_gettime(int, timespec*);
-extern "C" int __gettimeofday(timeval*, struct timezone*);
-
-struct vdso_entry {
-  const char* name;
-  void* fn;
-};
-
-enum {
-  VDSO_CLOCK_GETTIME = 0,
-  VDSO_GETTIMEOFDAY,
-  VDSO_END
-};
-
-static vdso_entry vdso_entries[] = {
-  [VDSO_CLOCK_GETTIME] = { VDSO_CLOCK_GETTIME_SYMBOL, reinterpret_cast<void*>(__clock_gettime) },
-  [VDSO_GETTIMEOFDAY] = { VDSO_GETTIMEOFDAY_SYMBOL, reinterpret_cast<void*>(__gettimeofday) },
-};
+#include <unistd.h>
+#include "private/KernelArgumentBlock.h"
 
 int clock_gettime(int clock_id, timespec* tp) {
-  static int (*vdso_clock_gettime)(int, timespec*) =
-      reinterpret_cast<int (*)(int, timespec*)>(vdso_entries[VDSO_CLOCK_GETTIME].fn);
-  return vdso_clock_gettime(clock_id, tp);
+  auto vdso_clock_gettime = reinterpret_cast<decltype(&clock_gettime)>(
+    __libc_globals->vdso[VDSO_CLOCK_GETTIME].fn);
+  if (__predict_true(vdso_clock_gettime)) {
+    return vdso_clock_gettime(clock_id, tp);
+  }
+  return __clock_gettime(clock_id, tp);
 }
 
 int gettimeofday(timeval* tv, struct timezone* tz) {
-  static int (*vdso_gettimeofday)(timeval*, struct timezone*) =
-      reinterpret_cast<int (*)(timeval*, struct timezone*)>(vdso_entries[VDSO_GETTIMEOFDAY].fn);
-  return vdso_gettimeofday(tv, tz);
+  auto vdso_gettimeofday = reinterpret_cast<decltype(&gettimeofday)>(
+    __libc_globals->vdso[VDSO_GETTIMEOFDAY].fn);
+  if (__predict_true(vdso_gettimeofday)) {
+    return vdso_gettimeofday(tv, tz);
+  }
+  return __gettimeofday(tv, tz);
 }
 
-void __libc_init_vdso() {
+void __libc_init_vdso(libc_globals* globals, KernelArgumentBlock& args) {
+  auto&& vdso = globals->vdso;
+  vdso[VDSO_CLOCK_GETTIME] = { VDSO_CLOCK_GETTIME_SYMBOL,
+                               reinterpret_cast<void*>(__clock_gettime) };
+  vdso[VDSO_GETTIMEOFDAY] = { VDSO_GETTIMEOFDAY_SYMBOL,
+                              reinterpret_cast<void*>(__gettimeofday) };
+
   // Do we have a vdso?
-  uintptr_t vdso_ehdr_addr = getauxval(AT_SYSINFO_EHDR);
+  uintptr_t vdso_ehdr_addr = args.getauxval(AT_SYSINFO_EHDR);
   ElfW(Ehdr)* vdso_ehdr = reinterpret_cast<ElfW(Ehdr)*>(vdso_ehdr_addr);
-  if (vdso_ehdr == NULL) {
+  if (vdso_ehdr == nullptr) {
     return;
   }
 
@@ -85,7 +74,7 @@
 
   // Where's the dynamic table?
   ElfW(Addr) vdso_addr = 0;
-  ElfW(Dyn)* vdso_dyn = NULL;
+  ElfW(Dyn)* vdso_dyn = nullptr;
   ElfW(Phdr)* vdso_phdr = reinterpret_cast<ElfW(Phdr)*>(vdso_ehdr_addr + vdso_ehdr->e_phoff);
   for (size_t i = 0; i < vdso_ehdr->e_phnum; ++i) {
     if (vdso_phdr[i].p_type == PT_DYNAMIC) {
@@ -94,13 +83,13 @@
       vdso_addr = vdso_ehdr_addr + vdso_phdr[i].p_offset - vdso_phdr[i].p_vaddr;
     }
   }
-  if (vdso_addr == 0 || vdso_dyn == NULL) {
+  if (vdso_addr == 0 || vdso_dyn == nullptr) {
     return;
   }
 
   // Where are the string and symbol tables?
-  const char* strtab = NULL;
-  ElfW(Sym)* symtab = NULL;
+  const char* strtab = nullptr;
+  ElfW(Sym)* symtab = nullptr;
   for (ElfW(Dyn)* d = vdso_dyn; d->d_tag != DT_NULL; ++d) {
     if (d->d_tag == DT_STRTAB) {
       strtab = reinterpret_cast<const char*>(vdso_addr + d->d_un.d_ptr);
@@ -108,15 +97,15 @@
       symtab = reinterpret_cast<ElfW(Sym)*>(vdso_addr + d->d_un.d_ptr);
     }
   }
-  if (strtab == NULL || symtab == NULL) {
+  if (strtab == nullptr || symtab == nullptr) {
     return;
   }
 
   // Are there any symbols we want?
   for (size_t i = 0; i < symbol_count; ++i) {
     for (size_t j = 0; j < VDSO_END; ++j) {
-      if (strcmp(vdso_entries[j].name, strtab + symtab[i].st_name) == 0) {
-        vdso_entries[j].fn = reinterpret_cast<void*>(vdso_addr + symtab[i].st_value);
+      if (strcmp(vdso[j].name, strtab + symtab[i].st_name) == 0) {
+        vdso[j].fn = reinterpret_cast<void*>(vdso_addr + symtab[i].st_value);
       }
     }
   }
@@ -124,7 +113,7 @@
 
 #else
 
-void __libc_init_vdso() {
+void __libc_init_vdso(libc_globals*, KernelArgumentBlock&) {
 }
 
 #endif
diff --git a/libc/crt.mk b/libc/crt.mk
index 6365332..7b96bf2 100644
--- a/libc/crt.mk
+++ b/libc/crt.mk
@@ -40,7 +40,7 @@
 	$(hide) $(PRIVATE_CC) $(PRIVATE_CFLAGS) \
 		-MD -MF $(@:%.o=%.d) -o $@ -c $<
 	$(transform-d-to-p)
--include $(GEN:%.o=%.P)
+$(call include-depfile,$(GEN:%.o=%.P),$(GEN))
 
 # crtbegin_so.c -> crtbegin_so1.o
 GEN := $($(my_2nd_arch_prefix)TARGET_OUT_INTERMEDIATE_LIBRARIES)/crtbegin_so1.o
@@ -51,7 +51,7 @@
 	$(hide) $(PRIVATE_CC) $(PRIVATE_CFLAGS) \
 		-MD -MF $(@:%.o=%.d) -o $@ -c $<
 	$(transform-d-to-p)
--include $(GEN:%.o=%.P)
+$(call include-depfile,$(GEN:%.o=%.P),$(GEN))
 
 # crtbegin_so1.o + crtbrand.o -> crtbegin_so.o
 GEN := $($(my_2nd_arch_prefix)TARGET_OUT_INTERMEDIATE_LIBRARIES)/crtbegin_so.o
@@ -71,7 +71,7 @@
 	$(hide) $(PRIVATE_CC) $(PRIVATE_CFLAGS) \
 		-MD -MF $(@:%.o=%.d) -o $@ -c $<
 	$(transform-d-to-p)
--include $(GEN:%.o=%.P)
+$(call include-depfile,$(GEN:%.o=%.P),$(GEN))
 
 # crtbegin_so.o and crtend_so.o are installed to device
 GEN := $($(my_2nd_arch_prefix)TARGET_OUT_SHARED_LIBRARIES)/crtbegin_so.o
@@ -93,7 +93,7 @@
 	$(hide) $(PRIVATE_CC) $(PRIVATE_CFLAGS) \
 		-MD -MF $(@:%.o=%.d) -o $@ -c $<
 	$(transform-d-to-p)
--include $(GEN:%.o=%.P)
+$(call include-depfile,$(GEN:%.o=%.P),$(GEN))
 
 # crtbegin_static1.o + crtbrand.o -> crtbegin_static.o
 GEN := $($(my_2nd_arch_prefix)TARGET_OUT_INTERMEDIATE_LIBRARIES)/crtbegin_static.o
@@ -113,7 +113,7 @@
 	$(hide) $(PRIVATE_CC) $(PRIVATE_CFLAGS) \
 		-MD -MF $(@:%.o=%.d) -o $@ -c $<
 	$(transform-d-to-p)
--include $(GEN:%.o=%.P)
+$(call include-depfile,$(GEN:%.o=%.P),$(GEN))
 
 # crtbegin_dynamic1.o + crtbrand.o -> crtbegin_dynamic.o
 GEN := $($(my_2nd_arch_prefix)TARGET_OUT_INTERMEDIATE_LIBRARIES)/crtbegin_dynamic.o
@@ -135,7 +135,7 @@
 	$(hide) $(PRIVATE_CC) $(PRIVATE_CFLAGS) \
 		-MD -MF $(@:%.o=%.d) -o $@ -c $<
 	$(transform-d-to-p)
--include $(GEN:%.o=%.P)
+$(call include-depfile,$(GEN:%.o=%.P),$(GEN))
 
 # Clear temp vars
 my_libc_crt_target_ldflags :=
diff --git a/libc/dns/include/resolv_netid.h b/libc/dns/include/resolv_netid.h
index d364645..266193a 100644
--- a/libc/dns/include/resolv_netid.h
+++ b/libc/dns/include/resolv_netid.h
@@ -49,6 +49,7 @@
 
 __BEGIN_DECLS
 
+struct __res_params;
 struct addrinfo;
 
 #define __used_in_netd __attribute__((visibility ("default")))
@@ -86,8 +87,8 @@
     const struct android_net_context *, struct addrinfo **) __used_in_netd;
 
 /* set name servers for a network */
-extern void _resolv_set_nameservers_for_net(unsigned netid,
-    const char** servers, int numservers, const char *domains) __used_in_netd;
+extern int _resolv_set_nameservers_for_net(unsigned netid, const char** servers,
+        unsigned numservers, const char *domains, const struct __res_params* params) __used_in_netd;
 
 /* flush the cache associated with a certain network */
 extern void _resolv_flush_cache_for_net(unsigned netid) __used_in_netd;
diff --git a/libc/dns/include/resolv_params.h b/libc/dns/include/resolv_params.h
new file mode 100644
index 0000000..5ee265f
--- /dev/null
+++ b/libc/dns/include/resolv_params.h
@@ -0,0 +1,46 @@
+/*
+ * Copyright (C) 2016 The Android Open Source Project
+ *
+ * Licensed under the Apache License, Version 2.0 (the "License");
+ * you may not use this file except in compliance with the License.
+ * You may obtain a copy of the License at
+ *
+ *      http://www.apache.org/licenses/LICENSE-2.0
+ *
+ * Unless required by applicable law or agreed to in writing, software
+ * distributed under the License is distributed on an "AS IS" BASIS,
+ * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
+ * See the License for the specific language governing permissions and
+ * limitations under the License.
+ */
+
+#ifndef _RESOLV_PARAMS_H
+#define _RESOLV_PARAMS_H
+
+#include <stdint.h>
+
+/* Hard-coded defines */
+#define MAXNS			4	/* max # name servers we'll track */
+#define MAXDNSRCH		6	/* max # domains in search path */
+#define MAXDNSRCHPATH		256	/* max length of domain search paths */
+#define MAXNSSAMPLES		64	/* max # samples to store per server */
+
+/* Defaults used for initializing __res_params */
+#define SUCCESS_THRESHOLD	75	/* if successes * 100 / total_samples is less than
+					 * this value, the server is considered failing
+					 */
+#define NSSAMPLE_VALIDITY	1800	/* Sample validity in seconds.
+					 * Set to -1 to disable skipping failing
+					 * servers.
+					 */
+
+/* per-netid configuration parameters passed from netd to the resolver */
+struct __res_params {
+    uint16_t sample_validity; // sample lifetime in s
+    // threshold of success / total samples below which a server is considered broken
+    uint8_t success_threshold; // 0: disable, value / 100 otherwise
+    uint8_t min_samples; // min # samples needed for statistics to be considered meaningful
+    uint8_t max_samples; // max # samples taken into account for statistics
+} __attribute__((__packed__));
+
+#endif // _RESOLV_PARAMS_H
diff --git a/libc/dns/include/resolv_private.h b/libc/dns/include/resolv_private.h
index 0dab3d8..3ab8ea6 100644
--- a/libc/dns/include/resolv_private.h
+++ b/libc/dns/include/resolv_private.h
@@ -58,7 +58,10 @@
 
 #include <resolv.h>
 #include "resolv_static.h"
+#include "resolv_params.h"
+#include "resolv_stats.h"
 #include <net/if.h>
+#include <time.h>
 
 /* Despite this file's name, it's part of libresolv. On Android, that means it's part of libc :-( */
 #pragma GCC visibility push(default)
@@ -136,9 +139,7 @@
 /*
  * Global defines and variables for resolver stub.
  */
-#define	MAXNS			3	/* max # name servers we'll track */
 #define	MAXDFLSRCH		3	/* # default domain levels to try */
-#define	MAXDNSRCH		6	/* max # domains in search path */
 #define	LOCALDOMAINPARTS	2	/* min levels in name that is "local" */
 
 #define	RES_TIMEOUT		5	/* min. seconds between retries */
@@ -205,6 +206,24 @@
 
 typedef struct __res_state *res_state;
 
+/* Retrieve a local copy of the stats for the given netid. The buffer must have space for
+ * MAXNS __resolver_stats. Returns the revision id of the resolvers used.
+ */
+__LIBC_HIDDEN__
+extern int
+_resolv_cache_get_resolver_stats( unsigned netid, struct __res_params* params,
+        struct __res_stats stats[MAXNS]);
+
+/* Add a sample to the shared struct for the given netid and server, provided that the
+ * revision_id of the stored servers has not changed.
+ */
+__LIBC_HIDDEN__
+extern void
+_resolv_cache_add_resolver_stats_sample( unsigned netid, int revision_id, int ns,
+        const struct __res_sample* sample, int max_samples);
+
+/* End of stats related definitions */
+
 union res_sockaddr_union {
 	struct sockaddr_in	sin;
 #ifdef IN6ADDR_ANY_INIT
@@ -398,7 +417,6 @@
 #define res_nisourserver	__res_nisourserver
 #define res_ownok		__res_ownok
 #define res_queriesmatch	__res_queriesmatch
-#define res_randomid		__res_randomid
 #define sym_ntop		__sym_ntop
 #define sym_ntos		__sym_ntos
 #define sym_ston		__sym_ston
@@ -454,7 +472,6 @@
 const char *	p_option(u_long);
 char *		p_secstodate(u_long);
 int		dn_count_labels(const char *);
-u_int		res_randomid(void);
 int		res_nameinquery(const char *, int, int, const u_char *,
 				     const u_char *);
 int		res_queriesmatch(const u_char *, const u_char *,
@@ -503,7 +520,11 @@
 
 __LIBC_HIDDEN__ void res_setnetid(res_state, unsigned);
 __LIBC_HIDDEN__ void res_setmark(res_state, unsigned);
-u_int  res_randomid(void);
+
+// We use the OpenBSD __res_randomid...
+u_int __res_randomid(void);
+// ...but NetBSD calls it res_randomid.
+#define res_randomid __res_randomid
 
 #ifdef __i386__
 # define __socketcall extern __attribute__((__cdecl__))
diff --git a/libc/dns/include/resolv_stats.h b/libc/dns/include/resolv_stats.h
new file mode 100644
index 0000000..c7901d7
--- /dev/null
+++ b/libc/dns/include/resolv_stats.h
@@ -0,0 +1,84 @@
+/*
+ * Copyright (C) 2016 The Android Open Source Project
+ *
+ * Licensed under the Apache License, Version 2.0 (the "License");
+ * you may not use this file except in compliance with the License.
+ * You may obtain a copy of the License at
+ *
+ *      http://www.apache.org/licenses/LICENSE-2.0
+ *
+ * Unless required by applicable law or agreed to in writing, software
+ * distributed under the License is distributed on an "AS IS" BASIS,
+ * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
+ * See the License for the specific language governing permissions and
+ * limitations under the License.
+ */
+
+#ifndef _RES_STATS_H
+#define _RES_STATS_H
+
+#include <sys/socket.h>
+#include <stdbool.h>
+#include <stdint.h>
+#include <time.h>
+
+#include "resolv_params.h"
+
+#define RCODE_INTERNAL_ERROR    254
+#define RCODE_TIMEOUT           255
+
+/*
+ * Resolver reachability statistics and run-time parameters.
+ */
+
+struct __res_sample {
+    time_t			at;    // time in s at which the sample was recorded
+    uint16_t			rtt;   // round-trip time in ms
+    uint8_t			rcode; // the DNS rcode or RCODE_XXX defined above
+};
+
+struct __res_stats {
+    // Stats of the last <sample_count> queries.
+    struct __res_sample		samples[MAXNSSAMPLES];
+    // The number of samples stored.
+    uint8_t			sample_count;
+    // The next sample to modify.
+    uint8_t			sample_next;
+};
+
+/* Calculate the round-trip-time from start time t0 and end time t1. */
+extern int
+_res_stats_calculate_rtt(const struct timespec* t1, const struct timespec* t0);
+
+/* Initialize a sample for calculating server reachability statistics. */
+extern void
+_res_stats_set_sample(struct __res_sample* sample, time_t now, int rcode, int rtt);
+
+/* Returns true if the server is considered unusable, i.e. if the success rate is not lower than the
+ * threshold for the stored stored samples. If not enough samples are stored, the server is
+ * considered usable.
+ */
+extern bool
+_res_stats_usable_server(const struct __res_params* params, struct __res_stats* stats);
+
+__BEGIN_DECLS
+/* Aggregates the reachability statistics for the given server based on on the stored samples. */
+extern void
+android_net_res_stats_aggregate(struct __res_stats* stats, int* successes, int* errors,
+        int* timeouts, int* internal_errors, int* rtt_avg, time_t* last_sample_time)
+    __attribute__((visibility ("default")));
+
+extern int
+android_net_res_stats_get_info_for_net(unsigned netid, int* nscount,
+        struct sockaddr_storage servers[MAXNS], int* dcount, char domains[MAXDNSRCH][MAXDNSRCHPATH],
+        struct __res_params* params, struct __res_stats stats[MAXNS])
+    __attribute__((visibility ("default")));
+
+/* Returns an array of bools indicating which servers are considered good */
+extern void
+android_net_res_stats_get_usable_servers(const struct __res_params* params,
+        struct __res_stats stats[], int nscount, bool valid_servers[])
+    __attribute__((visibility ("default")));
+__END_DECLS
+
+#endif  // _RES_STATS_H
diff --git a/libc/dns/resolv/res_cache.c b/libc/dns/resolv/res_cache.c
index 5a78450..ad2c5c0 100644
--- a/libc/dns/resolv/res_cache.c
+++ b/libc/dns/resolv/res_cache.c
@@ -27,6 +27,7 @@
  */
 
 #include "resolv_cache.h"
+
 #include <resolv.h>
 #include <stdarg.h>
 #include <stdio.h>
@@ -1232,9 +1233,13 @@
     unsigned                    netid;
     Cache*                      cache;
     struct resolv_cache_info*   next;
-    char*                       nameservers[MAXNS +1];
-    struct addrinfo*            nsaddrinfo[MAXNS + 1];
-    char                        defdname[256];
+    int                         nscount;
+    char*                       nameservers[MAXNS];
+    struct addrinfo*            nsaddrinfo[MAXNS];
+    int                         revision_id; // # times the nameservers have been replaced
+    struct __res_params         params;
+    struct __res_stats          nsstats[MAXNS];
+    char                        defdname[MAXDNSRCHPATH];
     int                         dnsrch_offset[MAXDNSRCH+1];  // offsets into defdname
 };
 
@@ -1361,6 +1366,8 @@
     pthread_mutex_unlock(&_res_cache_list_lock);
 }
 
+static struct resolv_cache_info* _find_cache_info_locked(unsigned netid);
+
 static void
 _cache_flush_locked( Cache*  cache )
 {
@@ -1801,6 +1808,8 @@
  * currently attached to the provided cache_info */
 static int _resolv_is_nameservers_equal_locked(struct resolv_cache_info* cache_info,
         const char** servers, int numservers);
+/* clears the stats samples contained withing the given cache_info */
+static void _res_cache_clear_stats_locked(struct resolv_cache_info* cache_info);
 
 static void
 _res_cache_init(void)
@@ -1854,6 +1863,10 @@
     if (cache) {
         _cache_flush_locked(cache);
     }
+
+    // Also clear the NS statistics.
+    struct resolv_cache_info* cache_info = _find_cache_info_locked(netid);
+    _res_cache_clear_stats_locked(cache_info);
 }
 
 void _resolv_delete_cache_for_net(unsigned netid)
@@ -1928,14 +1941,47 @@
 }
 
 void
-_resolv_set_nameservers_for_net(unsigned netid, const char** servers, int numservers,
-        const char *domains)
+_resolv_set_default_params(struct __res_params* params) {
+    params->sample_validity = NSSAMPLE_VALIDITY;
+    params->success_threshold = SUCCESS_THRESHOLD;
+    params->min_samples = 0;
+    params->max_samples = 0;
+}
+
+int
+_resolv_set_nameservers_for_net(unsigned netid, const char** servers, unsigned numservers,
+        const char *domains, const struct __res_params* params)
 {
-    int i, rt, index;
-    struct addrinfo hints;
     char sbuf[NI_MAXSERV];
     register char *cp;
     int *offset;
+    struct addrinfo* nsaddrinfo[MAXNS];
+
+    if (numservers > MAXNS) {
+        XLOG("%s: numservers=%u, MAXNS=%u", __FUNCTION__, numservers, MAXNS);
+        return E2BIG;
+    }
+
+    // Parse the addresses before actually locking or changing any state, in case there is an error.
+    // As a side effect this also reduces the time the lock is kept.
+    struct addrinfo hints = {
+        .ai_family = AF_UNSPEC,
+        .ai_socktype = SOCK_DGRAM,
+        .ai_flags = AI_NUMERICHOST
+    };
+    snprintf(sbuf, sizeof(sbuf), "%u", NAMESERVER_PORT);
+    for (unsigned i = 0; i < numservers; i++) {
+        // The addrinfo structures allocated here are freed in _free_nameservers_locked().
+        int rt = getaddrinfo(servers[i], sbuf, &hints, &nsaddrinfo[i]);
+        if (rt != 0) {
+            for (unsigned j = 0 ; j < i ; j++) {
+                freeaddrinfo(nsaddrinfo[j]);
+                nsaddrinfo[j] = NULL;
+            }
+            XLOG("%s: getaddrinfo(%s)=%s", __FUNCTION__, servers[i], gai_strerror(rt));
+            return EINVAL;
+        }
+    }
 
     pthread_once(&_res_cache_once, _res_cache_init);
     pthread_mutex_lock(&_res_cache_list_lock);
@@ -1945,33 +1991,52 @@
 
     struct resolv_cache_info* cache_info = _find_cache_info_locked(netid);
 
-    if (cache_info != NULL &&
-            !_resolv_is_nameservers_equal_locked(cache_info, servers, numservers)) {
-        // free current before adding new
-        _free_nameservers_locked(cache_info);
-
-        memset(&hints, 0, sizeof(hints));
-        hints.ai_family = PF_UNSPEC;
-        hints.ai_socktype = SOCK_DGRAM; /*dummy*/
-        hints.ai_flags = AI_NUMERICHOST;
-        snprintf(sbuf, sizeof(sbuf), "%u", NAMESERVER_PORT);
-
-        index = 0;
-        for (i = 0; i < numservers && i < MAXNS; i++) {
-            rt = getaddrinfo(servers[i], sbuf, &hints, &cache_info->nsaddrinfo[index]);
-            if (rt == 0) {
-                cache_info->nameservers[index] = strdup(servers[i]);
-                index++;
-                XLOG("%s: netid = %u, addr = %s\n", __FUNCTION__, netid, servers[i]);
-            } else {
-                cache_info->nsaddrinfo[index] = NULL;
-            }
+    if (cache_info != NULL) {
+        uint8_t old_max_samples = cache_info->params.max_samples;
+        if (params != NULL) {
+            cache_info->params = *params;
+        } else {
+            _resolv_set_default_params(&cache_info->params);
         }
 
+        if (!_resolv_is_nameservers_equal_locked(cache_info, servers, numservers)) {
+            // free current before adding new
+            _free_nameservers_locked(cache_info);
+            unsigned i;
+            for (i = 0; i < numservers; i++) {
+                cache_info->nsaddrinfo[i] = nsaddrinfo[i];
+                cache_info->nameservers[i] = strdup(servers[i]);
+                XLOG("%s: netid = %u, addr = %s\n", __FUNCTION__, netid, servers[i]);
+            }
+            cache_info->nscount = numservers;
+
+            // Flush the cache and reset the stats.
+            _flush_cache_for_net_locked(netid);
+
+            // increment the revision id to ensure that sample state is not written back if the
+            // servers change; in theory it would suffice to do so only if the servers or
+            // max_samples actually change, in practice the overhead of checking is higher than the
+            // cost, and overflows are unlikely
+            ++cache_info->revision_id;
+        } else if (cache_info->params.max_samples != old_max_samples) {
+            // If the maximum number of samples changes, the overhead of keeping the most recent
+            // samples around is not considered worth the effort, so they are cleared instead. All
+            // other parameters do not affect shared state: Changing these parameters does not
+            // invalidate the samples, as they only affect aggregation and the conditions under
+            // which servers are considered usable.
+            _res_cache_clear_stats_locked(cache_info);
+            ++cache_info->revision_id;
+        }
+
+        // Always update the search paths, since determining whether they actually changed is
+        // complex due to the zero-padding, and probably not worth the effort. Cache-flushing
+        // however is not // necessary, since the stored cache entries do contain the domain, not
+        // just the host name.
         // code moved from res_init.c, load_domain_search_list
         strlcpy(cache_info->defdname, domains, sizeof(cache_info->defdname));
         if ((cp = strchr(cache_info->defdname, '\n')) != NULL)
             *cp = '\0';
+
         cp = cache_info->defdname;
         offset = cache_info->dnsrch_offset;
         while (offset < cache_info->dnsrch_offset + MAXDNSRCH) {
@@ -1989,33 +2054,19 @@
             }
         }
         *offset = -1; /* cache_info->dnsrch_offset has MAXDNSRCH+1 items */
-
-        // flush cache since new settings
-        _flush_cache_for_net_locked(netid);
-
     }
 
     pthread_mutex_unlock(&_res_cache_list_lock);
+    return 0;
 }
 
 static int
 _resolv_is_nameservers_equal_locked(struct resolv_cache_info* cache_info,
         const char** servers, int numservers)
 {
-    int i;
-    char** ns;
-    int currentservers;
-    int equal = 1;
-
-    if (numservers > MAXNS) numservers = MAXNS;
-
-    // Find out how many nameservers we had before.
-    currentservers = 0;
-    for (ns = cache_info->nameservers; *ns; ns++)
-        currentservers++;
-
-    if (currentservers != numservers)
+    if (cache_info->nscount != numservers) {
         return 0;
+    }
 
     // Compare each name server against current name servers.
     // TODO: this is incorrect if the list of current or previous nameservers
@@ -2023,33 +2074,37 @@
     // filters out duplicates, but we should probably fix it. It's also
     // insensitive to the order of the nameservers; we should probably fix that
     // too.
-    for (i = 0; i < numservers && equal; i++) {
-        ns = cache_info->nameservers;
-        equal = 0;
-        while(*ns) {
-            if (strcmp(*ns, servers[i]) == 0) {
-                equal = 1;
+    for (int i = 0; i < numservers; i++) {
+        for (int j = 0 ; ; j++) {
+            if (j >= numservers) {
+                return 0;
+            }
+            if (strcmp(cache_info->nameservers[i], servers[j]) == 0) {
                 break;
             }
-            ns++;
         }
     }
 
-    return equal;
+    return 1;
 }
 
 static void
 _free_nameservers_locked(struct resolv_cache_info* cache_info)
 {
     int i;
-    for (i = 0; i <= MAXNS; i++) {
+    for (i = 0; i < cache_info->nscount; i++) {
         free(cache_info->nameservers[i]);
         cache_info->nameservers[i] = NULL;
         if (cache_info->nsaddrinfo[i] != NULL) {
             freeaddrinfo(cache_info->nsaddrinfo[i]);
             cache_info->nsaddrinfo[i] = NULL;
         }
+        cache_info->nsstats[i].sample_count =
+            cache_info->nsstats[i].sample_next = 0;
     }
+    cache_info->nscount = 0;
+    _res_cache_clear_stats_locked(cache_info);
+    ++cache_info->revision_id;
 }
 
 void
@@ -2093,7 +2148,8 @@
         statp->nscount = nserv;
         // now do search domains.  Note that we cache the offsets as this code runs alot
         // but the setting/offset-computer only runs when set/changed
-        strlcpy(statp->defdname, info->defdname, sizeof(statp->defdname));
+        // WARNING: Don't use str*cpy() here, this string contains zeroes.
+        memcpy(statp->defdname, info->defdname, sizeof(statp->defdname));
         register char **pp = statp->dnsrch;
         register int *p = info->dnsrch_offset;
         while (pp < statp->dnsrch + MAXDNSRCH && *p != -1) {
@@ -2102,3 +2158,132 @@
     }
     pthread_mutex_unlock(&_res_cache_list_lock);
 }
+
+/* Resolver reachability statistics. */
+
+static void
+_res_cache_add_stats_sample_locked(struct __res_stats* stats, const struct __res_sample* sample,
+        int max_samples) {
+    // Note: This function expects max_samples > 0, otherwise a (harmless) modification of the
+    // allocated but supposedly unused memory for samples[0] will happen
+    XLOG("%s: adding sample to stats, next = %d, count = %d", __FUNCTION__,
+            stats->sample_next, stats->sample_count);
+    stats->samples[stats->sample_next] = *sample;
+    if (stats->sample_count < max_samples) {
+        ++stats->sample_count;
+    }
+    if (++stats->sample_next >= max_samples) {
+        stats->sample_next = 0;
+    }
+}
+
+static void
+_res_cache_clear_stats_locked(struct resolv_cache_info* cache_info) {
+    if (cache_info) {
+        for (int i = 0 ; i < MAXNS ; ++i) {
+            cache_info->nsstats->sample_count = cache_info->nsstats->sample_next = 0;
+        }
+    }
+}
+
+int
+android_net_res_stats_get_info_for_net(unsigned netid, int* nscount,
+        struct sockaddr_storage servers[MAXNS], int* dcount, char domains[MAXDNSRCH][MAXDNSRCHPATH],
+        struct __res_params* params, struct __res_stats stats[MAXNS]) {
+    int revision_id = -1;
+    pthread_mutex_lock(&_res_cache_list_lock);
+
+    struct resolv_cache_info* info = _find_cache_info_locked(netid);
+    if (info) {
+        if (info->nscount > MAXNS) {
+            pthread_mutex_unlock(&_res_cache_list_lock);
+            XLOG("%s: nscount %d > MAXNS %d", __FUNCTION__, info->nscount, MAXNS);
+            errno = EFAULT;
+            return -1;
+        }
+        int i;
+        for (i = 0; i < info->nscount; i++) {
+            // Verify that the following assumptions are held, failure indicates corruption:
+            //  - getaddrinfo() may never return a sockaddr > sockaddr_storage
+            //  - all addresses are valid
+            //  - there is only one address per addrinfo thanks to numeric resolution
+            int addrlen = info->nsaddrinfo[i]->ai_addrlen;
+            if (addrlen < (int) sizeof(struct sockaddr) ||
+                    addrlen > (int) sizeof(servers[0])) {
+                pthread_mutex_unlock(&_res_cache_list_lock);
+                XLOG("%s: nsaddrinfo[%d].ai_addrlen == %d", __FUNCTION__, i, addrlen);
+                errno = EMSGSIZE;
+                return -1;
+            }
+            if (info->nsaddrinfo[i]->ai_addr == NULL) {
+                pthread_mutex_unlock(&_res_cache_list_lock);
+                XLOG("%s: nsaddrinfo[%d].ai_addr == NULL", __FUNCTION__, i);
+                errno = ENOENT;
+                return -1;
+            }
+            if (info->nsaddrinfo[i]->ai_next != NULL) {
+                pthread_mutex_unlock(&_res_cache_list_lock);
+                XLOG("%s: nsaddrinfo[%d].ai_next != NULL", __FUNCTION__, i);
+                errno = ENOTUNIQ;
+                return -1;
+            }
+        }
+        *nscount = info->nscount;
+        for (i = 0; i < info->nscount; i++) {
+            memcpy(&servers[i], info->nsaddrinfo[i]->ai_addr, info->nsaddrinfo[i]->ai_addrlen);
+            stats[i] = info->nsstats[i];
+        }
+        for (i = 0; i < MAXDNSRCH; i++) {
+            const char* cur_domain = info->defdname + info->dnsrch_offset[i];
+            // dnsrch_offset[i] can either be -1 or point to an empty string to indicate the end
+            // of the search offsets. Checking for < 0 is not strictly necessary, but safer.
+            // TODO: Pass in a search domain array instead of a string to
+            // _resolv_set_nameservers_for_net() and make this double check unnecessary.
+            if (info->dnsrch_offset[i] < 0 ||
+                    ((size_t)info->dnsrch_offset[i]) >= sizeof(info->defdname) || !cur_domain[0]) {
+                break;
+            }
+            strlcpy(domains[i], cur_domain, MAXDNSRCHPATH);
+        }
+        *dcount = i;
+        *params = info->params;
+        revision_id = info->revision_id;
+    }
+
+    pthread_mutex_unlock(&_res_cache_list_lock);
+    return revision_id;
+}
+
+int
+_resolv_cache_get_resolver_stats( unsigned netid, struct __res_params* params,
+        struct __res_stats stats[MAXNS]) {
+    int revision_id = -1;
+    pthread_mutex_lock(&_res_cache_list_lock);
+
+    struct resolv_cache_info* info = _find_cache_info_locked(netid);
+    if (info) {
+        memcpy(stats, info->nsstats, sizeof(info->nsstats));
+        *params = info->params;
+        revision_id = info->revision_id;
+    }
+
+    pthread_mutex_unlock(&_res_cache_list_lock);
+    return revision_id;
+}
+
+void
+_resolv_cache_add_resolver_stats_sample( unsigned netid, int revision_id, int ns,
+       const struct __res_sample* sample, int max_samples) {
+    if (max_samples <= 0) return;
+
+    pthread_mutex_lock(&_res_cache_list_lock);
+
+    struct resolv_cache_info* info = _find_cache_info_locked(netid);
+
+    if (info && info->revision_id == revision_id) {
+        _res_cache_add_stats_sample_locked(&info->nsstats[ns], sample, max_samples);
+    }
+
+    pthread_mutex_unlock(&_res_cache_list_lock);
+}
+
diff --git a/libc/dns/resolv/res_send.c b/libc/dns/resolv/res_send.c
index a8da3ac..1ae675b 100644
--- a/libc/dns/resolv/res_send.c
+++ b/libc/dns/resolv/res_send.c
@@ -81,9 +81,6 @@
 #endif
 #endif /* LIBC_SCCS and not lint */
 
-/* set to 1 to use our small/simple/limited DNS cache */
-#define  USE_RESOLV_CACHE  1
-
 /*
  * Send query to name server and wait for reply.
  */
@@ -116,9 +113,7 @@
 
 #include <isc/eventlib.h>
 
-#if USE_RESOLV_CACHE
-#  include <resolv_cache.h>
-#endif
+#include <resolv_cache.h>
 
 #include "private/libc_logging.h"
 
@@ -133,6 +128,7 @@
 #endif
 #include "res_debug.h"
 #include "res_private.h"
+#include "resolv_stats.h"
 
 #define EXT(res) ((res)->_u._ext)
 #define DBG 0
@@ -144,10 +140,12 @@
 static int		get_salen __P((const struct sockaddr *));
 static struct sockaddr * get_nsaddr __P((res_state, size_t));
 static int		send_vc(res_state, const u_char *, int,
-				u_char *, int, int *, int);
+				u_char *, int, int *, int,
+				time_t *, int *, int *);
 static int		send_dg(res_state, const u_char *, int,
 				u_char *, int, int *, int,
-				int *, int *);
+				int *, int *,
+				time_t *, int *, int *);
 static void		Aerror(const res_state, FILE *, const char *, int,
 			       const struct sockaddr *, int);
 static void		Perror(const res_state, FILE *, const char *, int);
@@ -359,23 +357,13 @@
 	return (1);
 }
 
-
 int
 res_nsend(res_state statp,
 	  const u_char *buf, int buflen, u_char *ans, int anssiz)
 {
 	int gotsomewhere, terrno, try, v_circuit, resplen, ns, n;
 	char abuf[NI_MAXHOST];
-#if USE_RESOLV_CACHE
-        ResolvCacheStatus     cache_status = RESOLV_CACHE_UNSUPPORTED;
-#endif
-
-#if !USE_RESOLV_CACHE
-	if (statp->nscount == 0) {
-		errno = ESRCH;
-		return (-1);
-	}
-#endif
+	ResolvCacheStatus     cache_status = RESOLV_CACHE_UNSUPPORTED;
 
 	if (anssiz < HFIXEDSZ) {
 		errno = EINVAL;
@@ -387,7 +375,6 @@
 	gotsomewhere = 0;
 	terrno = ETIMEDOUT;
 
-#if USE_RESOLV_CACHE
 	int  anslen = 0;
 	cache_status = _resolv_cache_lookup(
 			statp->netid, buf, buflen,
@@ -400,7 +387,6 @@
 		// data so the normal resolve path can do its thing
 		_resolv_populate_res_for_net(statp);
 	}
-
 	if (statp->nscount == 0) {
 		// We have no nameservers configured, so there's no point trying.
 		// Tell the cache the query failed, or any retries and anyone else asking the same
@@ -409,7 +395,6 @@
 		errno = ESRCH;
 		return (-1);
 	}
-#endif
 
 	/*
 	 * If the ns_addr_list in the resolver context has changed, then
@@ -420,9 +405,9 @@
 		struct sockaddr_storage peer;
 		socklen_t peerlen;
 
-		if (EXT(statp).nscount != statp->nscount)
+		if (EXT(statp).nscount != statp->nscount) {
 			needclose++;
-		else
+		} else {
 			for (ns = 0; ns < statp->nscount; ns++) {
 				if (statp->nsaddr_list[ns].sin_family &&
 				    !sock_eq((struct sockaddr *)(void *)&statp->nsaddr_list[ns],
@@ -445,6 +430,7 @@
 					break;
 				}
 			}
+		}
 		if (needclose) {
 			res_nclose(statp);
 			EXT(statp).nscount = 0;
@@ -485,7 +471,7 @@
 		nstime = EXT(statp).nstimes[0];
 		for (ns = 0; ns < lastns; ns++) {
 			if (EXT(statp).ext != NULL)
-                                EXT(statp).ext->nsaddrs[ns] =
+				EXT(statp).ext->nsaddrs[ns] =
 					EXT(statp).ext->nsaddrs[ns + 1];
 			statp->nsaddr_list[ns] = statp->nsaddr_list[ns + 1];
 			EXT(statp).nssocks[ns] = EXT(statp).nssocks[ns + 1];
@@ -502,13 +488,25 @@
 	 * Send request, RETRY times, or until successful.
 	 */
 	for (try = 0; try < statp->retry; try++) {
+	    struct __res_stats stats[MAXNS];
+	    struct __res_params params;
+	    int revision_id = _resolv_cache_get_resolver_stats(statp->netid, &params, stats);
+	    bool usable_servers[MAXNS];
+	    android_net_res_stats_get_usable_servers(&params, stats, statp->nscount,
+		    usable_servers);
+
 	    for (ns = 0; ns < statp->nscount; ns++) {
+		if (!usable_servers[ns]) continue;
 		struct sockaddr *nsap;
 		int nsaplen;
+		time_t now = 0;
+		int rcode = RCODE_INTERNAL_ERROR;
+		int delay = 0;
 		nsap = get_nsaddr(statp, (size_t)ns);
 		nsaplen = get_salen(nsap);
 		statp->_flags &= ~RES_F_LASTMASK;
 		statp->_flags |= (ns << RES_F_LASTSHIFT);
+
  same_ns:
 		if (statp->qhook) {
 			int done = 0, loops = 0;
@@ -552,7 +550,19 @@
 			try = statp->retry;
 
 			n = send_vc(statp, buf, buflen, ans, anssiz, &terrno,
-				    ns);
+				    ns, &now, &rcode, &delay);
+
+			/*
+			 * Only record stats the first time we try a query. This ensures that
+			 * queries that deterministically fail (e.g., a name that always returns
+			 * SERVFAIL or times out) do not unduly affect the stats.
+			 */
+			if (try == 0) {
+				struct __res_sample sample;
+				_res_stats_set_sample(&sample, now, rcode, delay);
+				_resolv_cache_add_resolver_stats_sample(statp->netid, revision_id,
+					ns, &sample, params.max_samples);
+			}
 
 			if (DBG) {
 				__libc_format_log(ANDROID_LOG_DEBUG, "libc",
@@ -571,7 +581,16 @@
 			}
 
 			n = send_dg(statp, buf, buflen, ans, anssiz, &terrno,
-				    ns, &v_circuit, &gotsomewhere);
+				    ns, &v_circuit, &gotsomewhere, &now, &rcode, &delay);
+
+			/* Only record stats the first time we try a query. See above. */
+			if (try == 0) {
+				struct __res_sample sample;
+				_res_stats_set_sample(&sample, now, rcode, delay);
+				_resolv_cache_add_resolver_stats_sample(statp->netid, revision_id,
+					ns, &sample, params.max_samples);
+			}
+
 			if (DBG) {
 				__libc_format_log(ANDROID_LOG_DEBUG, "libc", "used send_dg %d\n",n);
 			}
@@ -582,7 +601,7 @@
 				goto next_ns;
 			if (DBG) {
 				__libc_format_log(ANDROID_LOG_DEBUG, "libc", "time=%ld\n",
-                                                  time(NULL));
+						  time(NULL));
 			}
 			if (v_circuit)
 				goto same_ns;
@@ -599,12 +618,10 @@
 			(stdout, "%s", ""),
 			ans, (resplen > anssiz) ? anssiz : resplen);
 
-#if USE_RESOLV_CACHE
-                if (cache_status == RESOLV_CACHE_NOTFOUND) {
-                    _resolv_cache_add(statp->netid, buf, buflen,
-                                      ans, resplen);
-                }
-#endif
+		if (cache_status == RESOLV_CACHE_NOTFOUND) {
+		    _resolv_cache_add(statp->netid, buf, buflen,
+				      ans, resplen);
+		}
 		/*
 		 * If we have temporarily opened a virtual circuit,
 		 * or if we haven't been asked to keep a socket open,
@@ -656,15 +673,12 @@
 	} else
 		errno = terrno;
 
-#if USE_RESOLV_CACHE
-        _resolv_cache_query_failed(statp->netid, buf, buflen);
-#endif
+	_resolv_cache_query_failed(statp->netid, buf, buflen);
 
 	return (-1);
  fail:
-#if USE_RESOLV_CACHE
+
 	_resolv_cache_query_failed(statp->netid, buf, buflen);
-#endif
 	res_nclose(statp);
 	return (-1);
 }
@@ -735,8 +749,11 @@
 static int
 send_vc(res_state statp,
 	const u_char *buf, int buflen, u_char *ans, int anssiz,
-	int *terrno, int ns)
+	int *terrno, int ns, time_t* at, int* rcode, int* delay)
 {
+	*at = time(NULL);
+	*rcode = RCODE_INTERNAL_ERROR;
+	*delay = 0;
 	const HEADER *hp = (const HEADER *)(const void *)buf;
 	HEADER *anhp = (HEADER *)(void *)ans;
 	struct sockaddr *nsap;
@@ -758,6 +775,8 @@
  same_ns:
 	truncating = 0;
 
+	struct timespec now = evNowTime();
+
 	/* Are we still talking to whom we want to talk to? */
 	if (statp->_vcsock >= 0 && (statp->_flags & RES_F_VC) != 0) {
 		struct sockaddr_storage peer;
@@ -800,7 +819,7 @@
 		}
 		if (statp->_mark != MARK_UNSET) {
 			if (setsockopt(statp->_vcsock, SOL_SOCKET,
-				        SO_MARK, &statp->_mark, sizeof(statp->_mark)) < 0) {
+				    SO_MARK, &statp->_mark, sizeof(statp->_mark)) < 0) {
 				*terrno = errno;
 				Perror(statp, stderr, "setsockopt", errno);
 				return -1;
@@ -820,6 +839,15 @@
 			Aerror(statp, stderr, "connect/vc", errno, nsap,
 			    nsaplen);
 			res_nclose(statp);
+			/*
+			 * The way connect_with_timeout() is implemented prevents us from reliably
+			 * determining whether this was really a timeout or e.g. ECONNREFUSED. Since
+			 * currently both cases are handled in the same way, there is no need to
+			 * change this (yet). If we ever need to reliably distinguish between these
+			 * cases, both connect_with_timeout() and retrying_select() need to be
+			 * modified, though.
+			 */
+			*rcode = RCODE_TIMEOUT;
 			return (0);
 		}
 		statp->_flags |= RES_F_VC;
@@ -900,6 +928,7 @@
 		res_nclose(statp);
 		return (0);
 	}
+
 	if (truncating) {
 		/*
 		 * Flush rest of answer so connection stays in synch.
@@ -936,6 +965,11 @@
 	 * All is well, or the error is fatal.  Signal that the
 	 * next nameserver ought not be tried.
 	 */
+	if (resplen > 0) {
+	    struct timespec done = evNowTime();
+	    *delay = _res_stats_calculate_rtt(&done, &now);
+	    *rcode = anhp->rcode;
+	}
 	return (resplen);
 }
 
@@ -952,8 +986,8 @@
 
 	res = __connect(sock, nsap, salen);
 	if (res < 0 && errno != EINPROGRESS) {
-                res = -1;
-                goto done;
+		res = -1;
+		goto done;
 	}
 	if (res != 0) {
 		now = evNowTime();
@@ -965,7 +999,7 @@
 
 		res = retrying_select(sock, &rset, &wset, &finish);
 		if (res <= 0) {
-                        res = -1;
+			res = -1;
 		}
 	}
 done:
@@ -987,7 +1021,7 @@
 
 retry:
 	if (DBG) {
-		__libc_format_log(ANDROID_LOG_DEBUG, "libc", "  %d retying_select\n", sock);
+		__libc_format_log(ANDROID_LOG_DEBUG, "libc", "  %d retrying_select\n", sock);
 	}
 
 	now = evNowTime();
@@ -1042,17 +1076,20 @@
 	return n;
 }
 
-
 static int
 send_dg(res_state statp,
 	const u_char *buf, int buflen, u_char *ans, int anssiz,
-	int *terrno, int ns, int *v_circuit, int *gotsomewhere)
+	int *terrno, int ns, int *v_circuit, int *gotsomewhere,
+	time_t *at, int *rcode, int* delay)
 {
+	*at = time(NULL);
+	*rcode = RCODE_INTERNAL_ERROR;
+	*delay = 0;
 	const HEADER *hp = (const HEADER *)(const void *)buf;
 	HEADER *anhp = (HEADER *)(void *)ans;
 	const struct sockaddr *nsap;
 	int nsaplen;
-	struct timespec now, timeout, finish;
+	struct timespec now, timeout, finish, done;
 	fd_set dsmask;
 	struct sockaddr_storage from;
 	socklen_t fromlen;
@@ -1145,6 +1182,7 @@
 	n = retrying_select(s, &dsmask, NULL, &finish);
 
 	if (n == 0) {
+		*rcode = RCODE_TIMEOUT;
 		Dprint(statp->options & RES_DEBUG, (stdout, ";; timeout\n"));
 		*gotsomewhere = 1;
 		return (0);
@@ -1239,6 +1277,8 @@
 			ans, (resplen > anssiz) ? anssiz : resplen);
 		goto retry;;
 	}
+	done = evNowTime();
+	*delay = _res_stats_calculate_rtt(&done, &now);
 	if (anhp->rcode == SERVFAIL ||
 	    anhp->rcode == NOTIMP ||
 	    anhp->rcode == REFUSED) {
@@ -1247,8 +1287,10 @@
 			ans, (resplen > anssiz) ? anssiz : resplen);
 		res_nclose(statp);
 		/* don't retry if called from dig */
-		if (!statp->pfcode)
+		if (!statp->pfcode) {
+			*rcode = anhp->rcode;
 			return (0);
+		}
 	}
 	if (!(statp->options & RES_IGNTC) && anhp->tc) {
 		/*
@@ -1265,6 +1307,9 @@
 	 * All is well, or the error is fatal.  Signal that the
 	 * next nameserver ought not be tried.
 	 */
+	if (resplen > 0) {
+		*rcode = anhp->rcode;
+	}
 	return (resplen);
 }
 
diff --git a/libc/dns/resolv/res_state.c b/libc/dns/resolv/res_state.c
index afccd99..0e02a8f 100644
--- a/libc/dns/resolv/res_state.c
+++ b/libc/dns/resolv/res_state.c
@@ -128,7 +128,7 @@
             rt->_pi = (struct prop_info*) __system_property_find("net.change");
             if (rt->_pi == NULL) {
                 /* Still nothing, return current state */
-                D("%s: exiting for tid=%d rt=%d since system property not found",
+                D("%s: exiting for tid=%d rt=%p since system property not found",
                   __FUNCTION__, gettid(), rt);
                 return rt;
             }
diff --git a/libc/dns/resolv/res_stats.c b/libc/dns/resolv/res_stats.c
new file mode 100644
index 0000000..99c79e4
--- /dev/null
+++ b/libc/dns/resolv/res_stats.c
@@ -0,0 +1,184 @@
+/*
+ * Copyright (C) 2016 The Android Open Source Project
+ *
+ * Licensed under the Apache License, Version 2.0 (the "License");
+ * you may not use this file except in compliance with the License.
+ * You may obtain a copy of the License at
+ *
+ *      http://www.apache.org/licenses/LICENSE-2.0
+ *
+ * Unless required by applicable law or agreed to in writing, software
+ * distributed under the License is distributed on an "AS IS" BASIS,
+ * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
+ * See the License for the specific language governing permissions and
+ * limitations under the License.
+ */
+
+#include <stdbool.h>
+#include <arpa/nameser.h>
+#include <string.h>
+
+#include "resolv_stats.h"
+#include "private/libc_logging.h"
+#include "isc/eventlib.h"
+
+#define DBG 0
+
+/* Calculate the round-trip-time from start time t0 and end time t1. */
+int
+_res_stats_calculate_rtt(const struct timespec* t1, const struct timespec* t0) {
+    // Divide ns by one million to get ms, multiply s by thousand to get ms (obvious)
+    long ms0 = t0->tv_sec * 1000 + t0->tv_nsec / 1000000;
+    long ms1 = t1->tv_sec * 1000 + t1->tv_nsec / 1000000;
+    return (int) (ms1 - ms0);
+}
+
+/* Create a sample for calculating server reachability statistics. */
+void
+_res_stats_set_sample(struct __res_sample* sample, time_t now, int rcode, int rtt)
+{
+    if (DBG) {
+        __libc_format_log(ANDROID_LOG_INFO, "libc", "rcode = %d, sec = %d", rcode, rtt);
+    }
+    sample->at = now;
+    sample->rcode = rcode;
+    sample->rtt = rtt;
+}
+
+/* Clears all stored samples for the given server. */
+void
+_res_stats_clear_samples(struct __res_stats* stats)
+{
+    stats->sample_count = stats->sample_next = 0;
+}
+
+/* Aggregates the reachability statistics for the given server based on on the stored samples. */
+void
+android_net_res_stats_aggregate(struct __res_stats* stats, int* successes, int* errors,
+        int* timeouts, int* internal_errors, int* rtt_avg, time_t* last_sample_time)
+{
+    int s = 0;   // successes
+    int e = 0;   // errors
+    int t = 0;   // timouts
+    int ie = 0;  // internal errors
+    long rtt_sum = 0;
+    time_t last = 0;
+    int rtt_count = 0;
+    for (int i = 0 ; i < stats->sample_count ; ++i) {
+        // Treat everything as an error that the code in send_dg() already considers a
+        // rejection by the server, i.e. SERVFAIL, NOTIMP and REFUSED. Assume that NXDOMAIN
+        // and NOTAUTH can actually occur for user queries. NOERROR with empty answer section
+        // is not treated as an error here either. FORMERR seems to sometimes be returned by
+        // some versions of BIND in response to DNSSEC or EDNS0. Whether to treat such responses
+        // as an indication of a broken server is unclear, though. For now treat such responses,
+        // as well as unknown codes as errors.
+        switch (stats->samples[i].rcode) {
+        case NOERROR:
+        case NOTAUTH:
+        case NXDOMAIN:
+            ++s;
+            rtt_sum += stats->samples[i].rtt;
+            ++rtt_count;
+            break;
+        case RCODE_TIMEOUT:
+            ++t;
+            break;
+        case RCODE_INTERNAL_ERROR:
+            ++ie;
+            break;
+        case SERVFAIL:
+        case NOTIMP:
+        case REFUSED:
+        default:
+            ++e;
+            break;
+        }
+    }
+    *successes = s;
+    *errors = e;
+    *timeouts = t;
+    *internal_errors = ie;
+    /* If there was at least one successful sample, calculate average RTT. */
+    if (rtt_count) {
+        *rtt_avg = rtt_sum / rtt_count;
+    } else {
+        *rtt_avg = -1;
+    }
+    /* If we had at least one sample, populate last sample time. */
+    if (stats->sample_count > 0) {
+        if (stats->sample_next > 0) {
+            last = stats->samples[stats->sample_next - 1].at;
+        } else {
+            last = stats->samples[stats->sample_count - 1].at;
+        }
+    }
+    *last_sample_time = last;
+}
+
+bool
+_res_stats_usable_server(const struct __res_params* params, struct __res_stats* stats) {
+    int successes = -1;
+    int errors = -1;
+    int timeouts = -1;
+    int internal_errors = -1;
+    int rtt_avg = -1;
+    time_t last_sample_time = 0;
+    android_net_res_stats_aggregate(stats, &successes, &errors, &timeouts, &internal_errors,
+            &rtt_avg, &last_sample_time);
+    if (successes >= 0 && errors >= 0 && timeouts >= 0) {
+        int total = successes + errors + timeouts;
+        if (DBG) {
+            __libc_format_log(ANDROID_LOG_DEBUG, "libc", "NS stats: S %d + E %d + T %d + I %d "
+                 "= %d, rtt = %d, min_samples = %d\n", successes, errors, timeouts, internal_errors,
+                 total, rtt_avg, params->min_samples);
+        }
+        if (total >= params->min_samples && (errors > 0 || timeouts > 0)) {
+            int success_rate = successes * 100 / total;
+            if (DBG) {
+                __libc_format_log(ANDROID_LOG_DEBUG, "libc", "success rate %d%%\n", success_rate);
+            }
+            if (success_rate < params->success_threshold) {
+                // evNowTime() is used here instead of time() to stay consistent with the rest of
+                // the code base
+                time_t now = evNowTime().tv_sec;
+                if (now - last_sample_time > params->sample_validity) {
+                    // Note: It might be worth considering to expire old servers after their expiry
+                    // date has been reached, however the code for returning the ring buffer to its
+                    // previous non-circular state would induce additional complexity.
+                    if (DBG) {
+                        __libc_format_log(ANDROID_LOG_INFO, "libc",
+                            "samples stale, retrying server\n");
+                    }
+                    _res_stats_clear_samples(stats);
+                } else {
+                    if (DBG) {
+                        __libc_format_log(ANDROID_LOG_INFO, "libc",
+                            "too many resolution errors, ignoring server\n");
+                    }
+                    return 0;
+                }
+            }
+        }
+    }
+    return 1;
+}
+
+void
+android_net_res_stats_get_usable_servers(const struct __res_params* params,
+        struct __res_stats stats[], int nscount, bool usable_servers[]) {
+    unsigned usable_servers_found = 0;
+    for (int ns = 0; ns < nscount; ns++) {
+        bool usable = _res_stats_usable_server(params, &stats[ns]);
+        if (usable) {
+            ++usable_servers_found;
+        }
+        usable_servers[ns] = usable;
+    }
+    // If there are no usable servers, consider all of them usable.
+    // TODO: Explore other possibilities, such as enabling only the best N servers, etc.
+    if (usable_servers_found == 0) {
+        for (int ns = 0; ns < nscount; ns++) {
+            usable_servers[ns] = true;
+        }
+    }
+}
diff --git a/libc/include/android/dlext.h b/libc/include/android/dlext.h
index 40f610f..aa36f1e 100644
--- a/libc/include/android/dlext.h
+++ b/libc/include/android/dlext.h
@@ -1,6 +1,6 @@
 /*
  * Copyright (C) 2014 The Android Open Source Project
-
+ *
  * Licensed under the Apache License, Version 2.0 (the "License");
  * you may not use this file except in compliance with the License.
  * You may obtain a copy of the License at
@@ -80,6 +80,29 @@
    */
   ANDROID_DLEXT_FORCE_FIXED_VADDR = 0x80,
 
+  /* Instructs dlopen to load the library at the address specified by reserved_addr.
+   *
+   * The difference between ANDROID_DLEXT_LOAD_AT_FIXED_ADDRESS and ANDROID_DLEXT_RESERVED_ADDRESS
+   * is that for ANDROID_DLEXT_LOAD_AT_FIXED_ADDRESS the linker reserves memory at reserved_addr
+   * whereas for ANDROID_DLEXT_RESERVED_ADDRESS the linker relies on the caller to reserve the memory.
+   *
+   * This flag can be used with ANDROID_DLEXT_FORCE_FIXED_VADDR; when ANDROID_DLEXT_FORCE_FIXED_VADDR
+   * is set and load_bias is not 0 (load_bias is min(p_vaddr) of PT_LOAD segments) this flag is ignored.
+   * This is implemented this way because the linker has to pick one address over the other and this
+   * way is more convenient for art. Note that ANDROID_DLEXT_FORCE_FIXED_VADDR does not generate
+   * an error when min(p_vaddr) is 0.
+   *
+   * Cannot be used with ANDROID_DLEXT_RESERVED_ADDRESS or ANDROID_DLEXT_RESERVED_ADDRESS_HINT.
+   *
+   * This flag is for ART internal use only.
+   */
+  ANDROID_DLEXT_LOAD_AT_FIXED_ADDRESS = 0x100,
+
+  /* This flag used to load library in a different namespace. The namespace is
+   * specified in library_namespace.
+   */
+  ANDROID_DLEXT_USE_NAMESPACE = 0x200,
+
   /* Mask of valid bits */
   ANDROID_DLEXT_VALID_FLAG_BITS       = ANDROID_DLEXT_RESERVED_ADDRESS |
                                         ANDROID_DLEXT_RESERVED_ADDRESS_HINT |
@@ -88,9 +111,13 @@
                                         ANDROID_DLEXT_USE_LIBRARY_FD |
                                         ANDROID_DLEXT_USE_LIBRARY_FD_OFFSET |
                                         ANDROID_DLEXT_FORCE_LOAD |
-                                        ANDROID_DLEXT_FORCE_FIXED_VADDR,
+                                        ANDROID_DLEXT_FORCE_FIXED_VADDR |
+                                        ANDROID_DLEXT_LOAD_AT_FIXED_ADDRESS |
+                                        ANDROID_DLEXT_USE_NAMESPACE,
 };
 
+struct android_namespace_t;
+
 typedef struct {
   uint64_t flags;
   void*   reserved_addr;
@@ -98,6 +125,7 @@
   int     relro_fd;
   int     library_fd;
   off64_t library_fd_offset;
+  struct android_namespace_t* library_namespace;
 } android_dlextinfo;
 
 extern void* android_dlopen_ext(const char* filename, int flag, const android_dlextinfo* extinfo);
diff --git a/libc/private/bionic_time.h b/libc/include/bits/lockf.h
similarity index 80%
rename from libc/private/bionic_time.h
rename to libc/include/bits/lockf.h
index 030dcfd..d814807 100644
--- a/libc/private/bionic_time.h
+++ b/libc/include/bits/lockf.h
@@ -1,5 +1,5 @@
 /*
- * Copyright (C) 2011 The Android Open Source Project
+ * Copyright (C) 2016 The Android Open Source Project
  * All rights reserved.
  *
  * Redistribution and use in source and binary forms, with or without
@@ -25,17 +25,26 @@
  * OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF
  * SUCH DAMAGE.
  */
-#ifndef _BIONIC_TIME_H
-#define _BIONIC_TIME_H
 
-#include <time.h>
+#ifndef _BITS_LOCKF_H_
+#define _BITS_LOCKF_H_
+
 #include <sys/cdefs.h>
 
+#define F_ULOCK 0
+#define F_LOCK 1
+#define F_TLOCK 2
+#define F_TEST 3
+
 __BEGIN_DECLS
 
-// We can't remove this (and this file) until we fix MtpUtils.cpp.
-time_t mktime_tz(struct tm* const, char const*);
+#if defined(__USE_FILE_OFFSET64)
+int lockf(int, int, off_t) __RENAME(lockf64);
+#else
+int lockf(int, int, off_t);
+#endif
+int lockf64(int, int, off64_t);
 
 __END_DECLS
 
-#endif /* _BIONIC_TIME_H */
+#endif
diff --git a/libc/include/machine/posix_limits.h b/libc/include/bits/posix_limits.h
similarity index 98%
rename from libc/include/machine/posix_limits.h
rename to libc/include/bits/posix_limits.h
index 787af5c..31016a8 100644
--- a/libc/include/machine/posix_limits.h
+++ b/libc/include/bits/posix_limits.h
@@ -26,8 +26,8 @@
  * SUCH DAMAGE.
  */
 
-#ifndef _POSIX_LIMITS_H_
-#define _POSIX_LIMITS_H_
+#ifndef _BITS_POSIX_LIMITS_H_
+#define _BITS_POSIX_LIMITS_H_
 
 
 /* Any constant values here other than -1 or 200809L are explicitly specified by POSIX.1-2008. */
@@ -154,4 +154,4 @@
 #define _XOPEN_SHM                  -1
 #define _XOPEN_UNIX                 1
 
-#endif /* _POSIX_LIMITS_H_ */
+#endif
diff --git a/libc/include/machine/pthread_types.h b/libc/include/bits/pthread_types.h
similarity index 93%
rename from libc/include/machine/pthread_types.h
rename to libc/include/bits/pthread_types.h
index 900541c..6ac1c68 100644
--- a/libc/include/machine/pthread_types.h
+++ b/libc/include/bits/pthread_types.h
@@ -26,8 +26,8 @@
  * SUCH DAMAGE.
  */
 
-#ifndef _MACHINE_PTHREAD_TYPES_H_
-#define _MACHINE_PTHREAD_TYPES_H_
+#ifndef _BITS_PTHREAD_TYPES_H_
+#define _BITS_PTHREAD_TYPES_H_
 
 #include <sys/types.h>
 
@@ -45,4 +45,4 @@
 #endif
 } pthread_attr_t;
 
-#endif /* _MACHINE_PTHREAD_TYPES_H_ */
+#endif
diff --git a/libc/include/machine/timespec.h b/libc/include/bits/timespec.h
similarity index 94%
rename from libc/include/machine/timespec.h
rename to libc/include/bits/timespec.h
index 11779ae..046d898 100644
--- a/libc/include/machine/timespec.h
+++ b/libc/include/bits/timespec.h
@@ -26,8 +26,8 @@
  * SUCH DAMAGE.
  */
 
-#ifndef _MACHINE_TIMESPEC_H_
-#define _MACHINE_TIMESPEC_H_
+#ifndef _BITS_TIMESPEC_H_
+#define _BITS_TIMESPEC_H_
 
 #include <sys/types.h>
 
@@ -43,4 +43,4 @@
 };
 #endif
 
-#endif /* _MACHINE_TIMESPEC_H_ */
+#endif
diff --git a/libc/include/machine/wchar_limits.h b/libc/include/bits/wchar_limits.h
similarity index 93%
rename from libc/include/machine/wchar_limits.h
rename to libc/include/bits/wchar_limits.h
index 94cbd7e..f779c1a 100644
--- a/libc/include/machine/wchar_limits.h
+++ b/libc/include/bits/wchar_limits.h
@@ -26,8 +26,8 @@
  * SUCH DAMAGE.
  */
 
-#ifndef _MACHINE_WCHAR_LIMITS_H_
-#define _MACHINE_WCHAR_LIMITS_H_
+#ifndef _BITS_WCHAR_LIMITS_H_
+#define _BITS_WCHAR_LIMITS_H_
 
 /* Both GCC and clang define __WCHAR_MAX__. */
 #define WCHAR_MAX __WCHAR_MAX__
@@ -39,4 +39,4 @@
 #  define WCHAR_MIN (-(WCHAR_MAX) - 1)
 #endif
 
-#endif /* _MACHINE_WCHAR_LIMITS_H_ */
+#endif
diff --git a/libc/include/byteswap.h b/libc/include/byteswap.h
index 74b0e91..628fb7f 100644
--- a/libc/include/byteswap.h
+++ b/libc/include/byteswap.h
@@ -28,11 +28,10 @@
 #ifndef _BYTESWAP_H_
 #define _BYTESWAP_H_
 
-/* endian.h rather than sys/endian.h so we get the machine-specific file. */
-#include <endian.h>
+#include <sys/endian.h>
 
-#define  bswap_16(x)   swap16(x)
-#define  bswap_32(x)   swap32(x)
-#define  bswap_64(x)   swap64(x)
+#define bswap_16(x) __swap16(x)
+#define bswap_32(x) __swap32(x)
+#define bswap_64(x) __swap64(x)
 
 #endif /* _BYTESWAP_H_ */
diff --git a/libc/include/dirent.h b/libc/include/dirent.h
index 63716a4..3cdfa68 100644
--- a/libc/include/dirent.h
+++ b/libc/include/dirent.h
@@ -81,8 +81,13 @@
 extern int dirfd(DIR*);
 extern int alphasort(const struct dirent**, const struct dirent**);
 extern int alphasort64(const struct dirent64**, const struct dirent64**);
-extern int scandir(const char*, struct dirent***, int (*)(const struct dirent*), int (*)(const struct dirent**, const struct dirent**));
 extern int scandir64(const char*, struct dirent64***, int (*)(const struct dirent64*), int (*)(const struct dirent64**, const struct dirent64**));
+extern int scandir(const char*, struct dirent***, int (*)(const struct dirent*), int (*)(const struct dirent**, const struct dirent**));
+
+#if defined(__USE_GNU)
+int scandirat64(int, const char*, struct dirent64***, int (*)(const struct dirent64*), int (*)(const struct dirent64**, const struct dirent64**));
+int scandirat(int, const char*, struct dirent***, int (*)(const struct dirent*), int (*)(const struct dirent**, const struct dirent**));
+#endif
 
 __END_DECLS
 
diff --git a/libc/include/dlfcn.h b/libc/include/dlfcn.h
index afa7687..c2e8980 100644
--- a/libc/include/dlfcn.h
+++ b/libc/include/dlfcn.h
@@ -43,11 +43,12 @@
                                in dli_sname */
 } Dl_info;
 
-extern void*        dlopen(const char*  filename, int flag);
-extern int          dlclose(void*  handle);
-extern const char*  dlerror(void);
-extern void*        dlsym(void*  handle, const char*  symbol);
-extern int          dladdr(const void* addr, Dl_info *info);
+extern void* dlopen(const char*  filename, int flag);
+extern int dlclose(void*  handle);
+extern const char* dlerror(void);
+extern void* dlsym(void* handle, const char* symbol) __nonnull((2));
+extern void* dlvsym(void* handle, const char* symbol, const char* version) __nonnull((2, 3));
+extern int dladdr(const void* addr, Dl_info *info);
 
 enum {
 #if defined(__LP64__)
diff --git a/libc/include/fcntl.h b/libc/include/fcntl.h
index 0f016d7..6e2ad51 100644
--- a/libc/include/fcntl.h
+++ b/libc/include/fcntl.h
@@ -36,6 +36,10 @@
 #include <linux/stat.h>
 #include <linux/uio.h>
 
+#if defined(__USE_GNU) || defined(__USE_BSD)
+#include <bits/lockf.h>
+#endif
+
 __BEGIN_DECLS
 
 #ifdef __LP64__
diff --git a/libc/private/bionic_time.h b/libc/include/ifaddrs.h
similarity index 70%
copy from libc/private/bionic_time.h
copy to libc/include/ifaddrs.h
index 030dcfd..54a5a2c 100644
--- a/libc/private/bionic_time.h
+++ b/libc/include/ifaddrs.h
@@ -1,5 +1,5 @@
 /*
- * Copyright (C) 2011 The Android Open Source Project
+ * Copyright (C) 2015 The Android Open Source Project
  * All rights reserved.
  *
  * Redistribution and use in source and binary forms, with or without
@@ -25,17 +25,35 @@
  * OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF
  * SUCH DAMAGE.
  */
-#ifndef _BIONIC_TIME_H
-#define _BIONIC_TIME_H
 
-#include <time.h>
+#ifndef _IFADDRS_H_
+#define _IFADDRS_H_
+
 #include <sys/cdefs.h>
+#include <netinet/in.h>
+#include <sys/socket.h>
 
 __BEGIN_DECLS
 
-// We can't remove this (and this file) until we fix MtpUtils.cpp.
-time_t mktime_tz(struct tm* const, char const*);
+struct ifaddrs {
+  struct ifaddrs* ifa_next;
+  char* ifa_name;
+  unsigned int ifa_flags;
+  struct sockaddr* ifa_addr;
+  struct sockaddr* ifa_netmask;
+  union {
+    struct sockaddr* ifu_broadaddr;
+    struct sockaddr* ifu_dstaddr;
+  } ifa_ifu;
+  void* ifa_data;
+};
+
+#define ifa_broadaddr ifa_ifu.ifu_broadaddr
+#define ifa_dstaddr ifa_ifu.ifu_dstaddr
+
+void freeifaddrs(struct ifaddrs*);
+int getifaddrs(struct ifaddrs**);
 
 __END_DECLS
 
-#endif /* _BIONIC_TIME_H */
+#endif
diff --git a/libc/include/libgen.h b/libc/include/libgen.h
index e89328e..4d22d15 100644
--- a/libc/include/libgen.h
+++ b/libc/include/libgen.h
@@ -32,18 +32,19 @@
 #include <sys/cdefs.h>
 #include <sys/types.h>
 
+
 __BEGIN_DECLS
 
-#if !defined(__bionic_using_gnu_basename)
 /*
- * <string.h> gets you the GNU basename.
- * <libgen.h> the POSIX one.
- * Note that our "POSIX" one has the wrong argument cv-qualifiers, but doesn't
- * modify its input and uses thread-local storage for the result if necessary.
+ * Including <string.h> will get you the GNU basename, unless <libgen.h> is
+ * included, either before or after including <string.h>.
+ *
+ * Note that this has the wrong argument cv-qualifiers, but doesn't modify its
+ * input and uses thread-local storage for the result if necessary.
  */
-extern char* basename(const char*);
-#define __bionic_using_posix_basename
-#endif
+extern char* __posix_basename(const char*) __RENAME(basename);
+
+#define basename __posix_basename
 
 /* This has the wrong argument cv-qualifiers, but doesn't modify its input and uses thread-local storage for the result if necessary. */
 extern char* dirname(const char*);
diff --git a/libc/include/limits.h b/libc/include/limits.h
index 6ae629b..342217b 100644
--- a/libc/include/limits.h
+++ b/libc/include/limits.h
@@ -81,21 +81,10 @@
 
 #define MB_LEN_MAX 4
 
-/* New code should use sysconf(_SC_PAGE_SIZE) instead. */
-#ifndef PAGE_SIZE
-#define PAGE_SIZE 4096
-#endif
-#ifndef PAGESIZE
-#define  PAGESIZE  PAGE_SIZE
-#endif
-
-/* glibc's PAGE_MASK is the bitwise negation of BSD's! TODO: remove? */
-#define PAGE_MASK (~(PAGE_SIZE - 1))
-
 #define SEM_VALUE_MAX 0x3fffffff
 
 /* POSIX says these belong in <unistd.h> but BSD has some in <limits.h>. */
-#include <machine/posix_limits.h>
+#include <bits/posix_limits.h>
 
 #define HOST_NAME_MAX _POSIX_HOST_NAME_MAX
 #endif /* !_LIMITS_H_ */
diff --git a/libc/include/malloc.h b/libc/include/malloc.h
index cb1dd3b..87555a9 100644
--- a/libc/include/malloc.h
+++ b/libc/include/malloc.h
@@ -17,11 +17,6 @@
 #ifndef LIBC_INCLUDE_MALLOC_H_
 #define LIBC_INCLUDE_MALLOC_H_
 
-/*
- * Declaration of malloc routines. Bionic uses dlmalloc (see
- * upstream-dlmalloc) but doesn't directly include it here to keep the
- * defined malloc.h interface small.
- */
 #include <sys/cdefs.h>
 #include <stddef.h>
 #include <stdio.h>
diff --git a/libc/include/net/if.h b/libc/include/net/if.h
index 0efbf7f..aa4c19e 100644
--- a/libc/include/net/if.h
+++ b/libc/include/net/if.h
@@ -39,11 +39,15 @@
 
 __BEGIN_DECLS
 
-/*
- * Map an interface name into its corresponding index.
- */
-extern unsigned int if_nametoindex(const char *);
-extern char*        if_indextoname(unsigned ifindex, char *ifname);
+struct if_nameindex {
+  unsigned if_index;
+  char* if_name;
+};
+
+char* if_indextoname(unsigned, char*);
+unsigned if_nametoindex(const char*);
+struct if_nameindex* if_nameindex(void);
+void if_freenameindex(struct if_nameindex*);
 
 __END_DECLS
 
diff --git a/libc/include/netinet/in.h b/libc/include/netinet/in.h
index 44c7fc1..5f3d11f 100644
--- a/libc/include/netinet/in.h
+++ b/libc/include/netinet/in.h
@@ -47,10 +47,10 @@
 typedef uint16_t in_port_t;
 typedef uint32_t in_addr_t;
 
-extern int bindresvport (int sd, struct sockaddr_in *sin);
+int bindresvport(int, struct sockaddr_in*);
 
-static const struct in6_addr in6addr_any = IN6ADDR_ANY_INIT;
-static const struct in6_addr in6addr_loopback = IN6ADDR_LOOPBACK_INIT;
+extern const struct in6_addr in6addr_any;
+extern const struct in6_addr in6addr_loopback;
 
 __END_DECLS
 
diff --git a/libc/include/netinet/in6.h b/libc/include/netinet/in6.h
index 7f3286a..879ac75 100644
--- a/libc/include/netinet/in6.h
+++ b/libc/include/netinet/in6.h
@@ -25,48 +25,47 @@
  * OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF
  * SUCH DAMAGE.
  */
+
 #ifndef _NETINET_IN6_H
 #define _NETINET_IN6_H
 
 #include <linux/in6.h>
 
-#define IN6_IS_ADDR_UNSPECIFIED(a)	\
-	((*(const uint32_t *)(const void *)(&(a)->s6_addr[0]) == 0) &&	\
-	 (*(const uint32_t *)(const void *)(&(a)->s6_addr[4]) == 0) &&	\
-	 (*(const uint32_t *)(const void *)(&(a)->s6_addr[8]) == 0) &&	\
-	 (*(const uint32_t *)(const void *)(&(a)->s6_addr[12]) == 0))
+#define IN6_IS_ADDR_UNSPECIFIED(a) \
+  ((*(const uint32_t*)(&(a)->s6_addr[0]) == 0) && \
+   (*(const uint32_t*)(&(a)->s6_addr[4]) == 0) && \
+   (*(const uint32_t*)(&(a)->s6_addr[8]) == 0) && \
+   (*(const uint32_t*)(&(a)->s6_addr[12]) == 0))
 
-#define IN6_IS_ADDR_LOOPBACK(a)		\
-	((*(const uint32_t *)(const void *)(&(a)->s6_addr[0]) == 0) &&	\
-	 (*(const uint32_t *)(const void *)(&(a)->s6_addr[4]) == 0) &&	\
-	 (*(const uint32_t *)(const void *)(&(a)->s6_addr[8]) == 0) &&	\
-	 (*(const uint32_t *)(const void *)(&(a)->s6_addr[12]) == ntohl(1)))
+#define IN6_IS_ADDR_LOOPBACK(a) \
+  ((*(const uint32_t*)(&(a)->s6_addr[0]) == 0) && \
+   (*(const uint32_t*)(&(a)->s6_addr[4]) == 0) && \
+   (*(const uint32_t*)(&(a)->s6_addr[8]) == 0) && \
+   (*(const uint32_t*)(&(a)->s6_addr[12]) == ntohl(1)))
 
-#define IN6_IS_ADDR_V4COMPAT(a)		\
-	((*(const uint32_t *)(const void *)(&(a)->s6_addr[0]) == 0) &&	\
-	 (*(const uint32_t *)(const void *)(&(a)->s6_addr[4]) == 0) &&	\
-	 (*(const uint32_t *)(const void *)(&(a)->s6_addr[8]) == 0) &&	\
-	 (*(const uint32_t *)(const void *)(&(a)->s6_addr[12]) != 0) &&	\
-	 (*(const uint32_t *)(const void *)(&(a)->s6_addr[12]) != ntohl(1)))
+#define IN6_IS_ADDR_V4COMPAT(a) \
+  ((*(const uint32_t*)(&(a)->s6_addr[0]) == 0) && \
+   (*(const uint32_t*)(&(a)->s6_addr[4]) == 0) && \
+   (*(const uint32_t*)(&(a)->s6_addr[8]) == 0) && \
+   (*(const uint32_t*)(&(a)->s6_addr[12]) != 0) && \
+   (*(const uint32_t*)(&(a)->s6_addr[12]) != ntohl(1)))
 
-#define IN6_IS_ADDR_V4MAPPED(a)		      \
-	((*(const uint32_t *)(const void *)(&(a)->s6_addr[0]) == 0) &&	\
-	 (*(const uint32_t *)(const void *)(&(a)->s6_addr[4]) == 0) &&	\
-	 (*(const uint32_t *)(const void *)(&(a)->s6_addr[8]) == ntohl(0x0000ffff)))
+#define IN6_IS_ADDR_V4MAPPED(a) \
+  ((*(const uint32_t*)(&(a)->s6_addr[0]) == 0) && \
+   (*(const uint32_t*)(&(a)->s6_addr[4]) == 0) && \
+   (*(const uint32_t*)(&(a)->s6_addr[8]) == ntohl(0x0000ffff)))
 
-#define IN6_IS_ADDR_LINKLOCAL(a)	\
-	(((a)->s6_addr[0] == 0xfe) && (((a)->s6_addr[1] & 0xc0) == 0x80))
+#define __bionic_s6_addr(a) ((const uint8_t*)(a))
 
-#define IN6_IS_ADDR_SITELOCAL(a)	\
-	(((a)->s6_addr[0] == 0xfe) && (((a)->s6_addr[1] & 0xc0) == 0xc0))
+#define IN6_IS_ADDR_LINKLOCAL(a) \
+  ((__bionic_s6_addr(a)[0] == 0xfe) && ((__bionic_s6_addr(a)[1] & 0xc0) == 0x80))
 
-/* RFC 4193. */
-#define IN6_IS_ADDR_ULA(a)	\
-	(((a)->s6_addr[0] & 0xfe) == 0xfc)
+#define IN6_IS_ADDR_SITELOCAL(a) \
+  ((__bionic_s6_addr(a)[0] == 0xfe) && ((__bionic_s6_addr(a)[1] & 0xc0) == 0xc0))
 
-#define IN6_IS_ADDR_MULTICAST(a)	\
-	(((__const uint8_t *) (a))[0] == 0xff)
+#define IN6_IS_ADDR_MULTICAST(a) (__bionic_s6_addr(a)[0] == 0xff)
 
+#define IN6_IS_ADDR_ULA(a) ((__bionic_s6_addr(a)[0] & 0xfe) == 0xfc)
 
 #define IPV6_ADDR_SCOPE_NODELOCAL       0x01
 #define IPV6_ADDR_SCOPE_INTFACELOCAL    0x01
@@ -75,27 +74,21 @@
 #define IPV6_ADDR_SCOPE_ORGLOCAL        0x08
 #define IPV6_ADDR_SCOPE_GLOBAL          0x0e
 
-#define IPV6_ADDR_MC_SCOPE(a)	\
-	((a)->s6_addr[1] & 0x0f)
+#define IPV6_ADDR_MC_SCOPE(a) (__bionic_s6_addr(a)[1] & 0x0f)
 
-#define IN6_IS_ADDR_MC_NODELOCAL(a)     \
-	(IN6_IS_ADDR_MULTICAST(a) &&  \
-	 (IPV6_ADDR_MC_SCOPE(a) == IPV6_ADDR_SCOPE_NODELOCAL))
-#define IN6_IS_ADDR_MC_LINKLOCAL(a)	\
-	(IN6_IS_ADDR_MULTICAST(a) &&  \
-	 (IPV6_ADDR_MC_SCOPE(a) == IPV6_ADDR_SCOPE_LINKLOCAL))
-#define IN6_IS_ADDR_MC_SITELOCAL(a)     \
-	(IN6_IS_ADDR_MULTICAST(a) &&  \
-	 (IPV6_ADDR_MC_SCOPE(a) == IPV6_ADDR_SCOPE_SITELOCAL))
-#define IN6_IS_ADDR_MC_ORGLOCAL(a)     \
-	(IN6_IS_ADDR_MULTICAST(a) &&  \
-	 (IPV6_ADDR_MC_SCOPE(a) == IPV6_ADDR_SCOPE_ORGLOCAL))
-#define IN6_IS_ADDR_MC_GLOBAL(a)       \
-	(IN6_IS_ADDR_MULTICAST(a) &&  \
-	 (IPV6_ADDR_MC_SCOPE(a) == IPV6_ADDR_SCOPE_GLOBAL))
+#define IN6_IS_ADDR_MC_NODELOCAL(a) \
+  (IN6_IS_ADDR_MULTICAST(a) && (IPV6_ADDR_MC_SCOPE(a) == IPV6_ADDR_SCOPE_NODELOCAL))
+#define IN6_IS_ADDR_MC_LINKLOCAL(a) \
+  (IN6_IS_ADDR_MULTICAST(a) && (IPV6_ADDR_MC_SCOPE(a) == IPV6_ADDR_SCOPE_LINKLOCAL))
+#define IN6_IS_ADDR_MC_SITELOCAL(a) \
+  (IN6_IS_ADDR_MULTICAST(a) && (IPV6_ADDR_MC_SCOPE(a) == IPV6_ADDR_SCOPE_SITELOCAL))
+#define IN6_IS_ADDR_MC_ORGLOCAL(a) \
+  (IN6_IS_ADDR_MULTICAST(a) && (IPV6_ADDR_MC_SCOPE(a) == IPV6_ADDR_SCOPE_ORGLOCAL))
+#define IN6_IS_ADDR_MC_GLOBAL(a) \
+  (IN6_IS_ADDR_MULTICAST(a) && (IPV6_ADDR_MC_SCOPE(a) == IPV6_ADDR_SCOPE_GLOBAL))
 
-#define IN6_ARE_ADDR_EQUAL(a, b)			\
-    (memcmp(&(a)->s6_addr[0], &(b)->s6_addr[0], sizeof(struct in6_addr)) == 0)
+#define IN6_ARE_ADDR_EQUAL(a, b) \
+  (memcmp(&(a)->s6_addr[0], &(b)->s6_addr[0], sizeof(struct in6_addr)) == 0)
 
 #define INET6_ADDRSTRLEN 46
 
@@ -107,5 +100,4 @@
 
 #define ipv6mr_interface ipv6mr_ifindex
 
-
 #endif /* _NETINET_IN6_H */
diff --git a/libc/include/netinet/udp.h b/libc/include/netinet/udp.h
index 25e0dfc..d4eb368 100644
--- a/libc/include/netinet/udp.h
+++ b/libc/include/netinet/udp.h
@@ -25,31 +25,29 @@
  * OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF
  * SUCH DAMAGE.
  */
+
 #ifndef _NETINET_UDP_H
 #define _NETINET_UDP_H
 
-/*
- * We would include linux/udp.h, but it brings in too much other stuff
- */
+#include <sys/types.h>
 
-#ifdef __FAVOR_BSD
+#include <linux/udp.h>
 
 struct udphdr {
-    u_int16_t uh_sport;	/* source port */
-    u_int16_t uh_dport;	/* destination port */
-    u_int16_t uh_ulen;	/* udp length */
-    u_int16_t uh_sum;	/* udp checksum */
+    __extension__ union {
+        struct /* BSD names */ {
+            u_int16_t uh_sport;
+            u_int16_t uh_dport;
+            u_int16_t uh_ulen;
+            u_int16_t uh_sum;
+        };
+        struct /* Linux names */ {
+            u_int16_t source;
+            u_int16_t dest;
+            u_int16_t len;
+            u_int16_t check;
+        };
+    };
 };
 
-#else
-
-struct udphdr {
-    __u16  source;
-    __u16  dest;
-    __u16  len;
-    __u16  check;
-};
-
-#endif /* __FAVOR_BSD */
-
 #endif /* _NETINET_UDP_H */
diff --git a/libc/include/pthread.h b/libc/include/pthread.h
index 260ae5b..50f2024 100644
--- a/libc/include/pthread.h
+++ b/libc/include/pthread.h
@@ -30,7 +30,7 @@
 #define _PTHREAD_H_
 
 #include <limits.h>
-#include <machine/pthread_types.h>
+#include <bits/pthread_types.h>
 #include <sched.h>
 #include <sys/cdefs.h>
 #include <sys/types.h>
@@ -96,6 +96,26 @@
 
 #define PTHREAD_ONCE_INIT 0
 
+typedef struct {
+#if defined(__LP64__)
+  int64_t __private[4];
+#else
+  int32_t __private[8];
+#endif
+} pthread_barrier_t;
+
+typedef int pthread_barrierattr_t;
+
+#define PTHREAD_BARRIER_SERIAL_THREAD -1
+
+typedef struct {
+#if defined(__LP64__)
+  int64_t __private;
+#else
+  int32_t __private[2];
+#endif
+} pthread_spinlock_t;
+
 #if defined(__LP64__)
 #define PTHREAD_STACK_MIN (4 * PAGE_SIZE)
 #else
@@ -130,7 +150,7 @@
 int pthread_attr_setschedpolicy(pthread_attr_t*, int) __nonnull((1));
 int pthread_attr_setscope(pthread_attr_t*, int) __nonnull((1));
 int pthread_attr_setstack(pthread_attr_t*, void*, size_t) __nonnull((1));
-int pthread_attr_setstacksize(pthread_attr_t*, size_t stack_size) __nonnull((1));
+int pthread_attr_setstacksize(pthread_attr_t*, size_t) __nonnull((1));
 
 int pthread_condattr_destroy(pthread_condattr_t*) __nonnull((1));
 int pthread_condattr_getclock(const pthread_condattr_t*, clockid_t*) __nonnull((1, 2));
@@ -205,9 +225,24 @@
 int pthread_rwlock_timedwrlock(pthread_rwlock_t*, const struct timespec*) __nonnull((1, 2));
 int pthread_rwlock_tryrdlock(pthread_rwlock_t*) __nonnull((1));
 int pthread_rwlock_trywrlock(pthread_rwlock_t*) __nonnull((1));
-int pthread_rwlock_unlock(pthread_rwlock_t *rwlock) __nonnull((1));
+int pthread_rwlock_unlock(pthread_rwlock_t *) __nonnull((1));
 int pthread_rwlock_wrlock(pthread_rwlock_t*) __nonnull((1));
 
+int pthread_barrierattr_init(pthread_barrierattr_t* attr) __nonnull((1));
+int pthread_barrierattr_destroy(pthread_barrierattr_t* attr) __nonnull((1));
+int pthread_barrierattr_getpshared(pthread_barrierattr_t* attr, int* pshared) __nonnull((1, 2));
+int pthread_barrierattr_setpshared(pthread_barrierattr_t* attr, int pshared) __nonnull((1));
+
+int pthread_barrier_init(pthread_barrier_t*, const pthread_barrierattr_t*, unsigned) __nonnull((1));
+int pthread_barrier_destroy(pthread_barrier_t*) __nonnull((1));
+int pthread_barrier_wait(pthread_barrier_t*) __nonnull((1));
+
+int pthread_spin_destroy(pthread_spinlock_t*) __nonnull((1));
+int pthread_spin_init(pthread_spinlock_t*, int) __nonnull((1));
+int pthread_spin_lock(pthread_spinlock_t*) __nonnull((1));
+int pthread_spin_trylock(pthread_spinlock_t*) __nonnull((1));
+int pthread_spin_unlock(pthread_spinlock_t*) __nonnull((1));
+
 pthread_t pthread_self(void) __pure2;
 
 int pthread_setname_np(pthread_t, const char*) __nonnull((2));
diff --git a/libc/include/pwd.h b/libc/include/pwd.h
index 6012b96..905bc75 100644
--- a/libc/include/pwd.h
+++ b/libc/include/pwd.h
@@ -106,6 +106,9 @@
   gid_t pw_gid;
 #ifdef __LP64__
   char* pw_gecos;
+#else
+  // Note: On LP32, we define pw_gecos to pw_passwd since they're both NULL.
+# define pw_gecos pw_passwd
 #endif
   char* pw_dir;
   char* pw_shell;
diff --git a/libc/include/regex.h b/libc/include/regex.h
index aec38e3..b06a515 100644
--- a/libc/include/regex.h
+++ b/libc/include/regex.h
@@ -42,8 +42,9 @@
 #include <sys/cdefs.h>
 #include <sys/types.h>
 
-/* types */
-typedef off_t regoff_t;
+/* POSIX says regoff_t is at least as large as the larger of ptrdiff_t and
+ * ssize_t. BSD uses off_t, but that interacts badly with _FILE_OFFSET_BITS. */
+typedef ssize_t regoff_t;
 
 typedef struct {
 	int re_magic;
diff --git a/libc/include/sched.h b/libc/include/sched.h
index 930dd7c..0b9235b 100644
--- a/libc/include/sched.h
+++ b/libc/include/sched.h
@@ -28,8 +28,8 @@
 #ifndef _SCHED_H_
 #define _SCHED_H_
 
+#include <bits/timespec.h>
 #include <linux/sched.h>
-#include <machine/timespec.h>
 #include <sys/cdefs.h>
 
 __BEGIN_DECLS
diff --git a/libc/include/signal.h b/libc/include/signal.h
index 554e0ac..85c46c0 100644
--- a/libc/include/signal.h
+++ b/libc/include/signal.h
@@ -30,9 +30,9 @@
 #define _SIGNAL_H_
 
 #include <asm/sigcontext.h>
+#include <bits/pthread_types.h>
+#include <bits/timespec.h>
 #include <limits.h>
-#include <machine/pthread_types.h>
-#include <machine/timespec.h>
 #include <sys/cdefs.h>
 #include <sys/types.h>
 
@@ -105,15 +105,15 @@
 
 extern int sigaction(int, const struct sigaction*, struct sigaction*);
 
-_BIONIC_NOT_BEFORE_21(extern sighandler_t signal(int, sighandler_t);)
+extern sighandler_t signal(int, sighandler_t) __INTRODUCED_IN(21);
 
 extern int siginterrupt(int, int);
 
-_BIONIC_NOT_BEFORE_21(extern int sigaddset(sigset_t*, int);)
-_BIONIC_NOT_BEFORE_21(extern int sigdelset(sigset_t*, int);)
-_BIONIC_NOT_BEFORE_21(extern int sigemptyset(sigset_t*);)
-_BIONIC_NOT_BEFORE_21(extern int sigfillset(sigset_t*);)
-_BIONIC_NOT_BEFORE_21(extern int sigismember(const sigset_t*, int);)
+extern int sigaddset(sigset_t*, int) __INTRODUCED_IN(21);
+extern int sigdelset(sigset_t*, int) __INTRODUCED_IN(21);
+extern int sigemptyset(sigset_t*) __INTRODUCED_IN(21);
+extern int sigfillset(sigset_t*) __INTRODUCED_IN(21);
+extern int sigismember(const sigset_t*, int) __INTRODUCED_IN(21);
 
 extern int sigpending(sigset_t*) __nonnull((1));
 extern int sigprocmask(int, const sigset_t*, sigset_t*);
diff --git a/libc/include/stdint.h b/libc/include/stdint.h
index a6f8505..a66e21e 100644
--- a/libc/include/stdint.h
+++ b/libc/include/stdint.h
@@ -29,8 +29,8 @@
 #ifndef _STDINT_H
 #define _STDINT_H
 
+#include <bits/wchar_limits.h>
 #include <stddef.h>
-#include <machine/wchar_limits.h>
 
 typedef __signed char __int8_t;
 typedef unsigned char __uint8_t;
diff --git a/libc/include/stdio.h b/libc/include/stdio.h
index f5ed652..623995b 100644
--- a/libc/include/stdio.h
+++ b/libc/include/stdio.h
@@ -38,14 +38,6 @@
 #ifndef	_STDIO_H_
 #define	_STDIO_H_
 
-/*
- * This file must contain a reference to __gnuc_va_list so that GCC's
- * fixincludes knows that that's what's being used for va_list, and so
- * to leave our <stdio.h> alone. (fixincludes gets in the way of pointing
- * one toolchain at various different sets of platform headers.)
- * If you alter this comment, be sure to keep "__gnuc_va_list" in it!
- */
-
 #include <sys/cdefs.h>
 #include <sys/types.h>
 
@@ -57,96 +49,12 @@
 
 __BEGIN_DECLS
 
-typedef off_t fpos_t;		/* stdio file position type */
+typedef off_t fpos_t;
+typedef off64_t fpos64_t;
 
-/*
- * NB: to fit things in six character monocase externals, the stdio
- * code uses the prefix `__s' for stdio objects, typically followed
- * by a three-character attempt at a mnemonic.
- */
+struct __sFILE;
+typedef struct __sFILE FILE;
 
-/* stdio buffers */
-#if defined(__LP64__)
-struct __sbuf {
-  unsigned char* _base;
-  size_t _size;
-};
-#else
-struct __sbuf {
-	unsigned char *_base;
-	int	_size;
-};
-#endif
-
-/*
- * stdio state variables.
- *
- * The following always hold:
- *
- *	if (_flags&(__SLBF|__SWR)) == (__SLBF|__SWR),
- *		_lbfsize is -_bf._size, else _lbfsize is 0
- *	if _flags&__SRD, _w is 0
- *	if _flags&__SWR, _r is 0
- *
- * This ensures that the getc and putc macros (or inline functions) never
- * try to write or read from a file that is in `read' or `write' mode.
- * (Moreover, they can, and do, automatically switch from read mode to
- * write mode, and back, on "r+" and "w+" files.)
- *
- * _lbfsize is used only to make the inline line-buffered output stream
- * code as compact as possible.
- *
- * _ub, _up, and _ur are used when ungetc() pushes back more characters
- * than fit in the current _bf, or when ungetc() pushes back a character
- * that does not match the previous one in _bf.  When this happens,
- * _ub._base becomes non-nil (i.e., a stream has ungetc() data iff
- * _ub._base!=NULL) and _up and _ur save the current values of _p and _r.
- *
- * NOTE: if you change this structure, you also need to update the
- * std() initializer in findfp.c.
- */
-typedef	struct __sFILE {
-	unsigned char *_p;	/* current position in (some) buffer */
-	int	_r;		/* read space left for getc() */
-	int	_w;		/* write space left for putc() */
-#if defined(__LP64__)
-	int	_flags;		/* flags, below; this FILE is free if 0 */
-	int	_file;		/* fileno, if Unix descriptor, else -1 */
-#else
-	short	_flags;		/* flags, below; this FILE is free if 0 */
-	short	_file;		/* fileno, if Unix descriptor, else -1 */
-#endif
-	struct	__sbuf _bf;	/* the buffer (at least 1 byte, if !NULL) */
-	int	_lbfsize;	/* 0 or -_bf._size, for inline putc */
-
-	/* operations */
-	void	*_cookie;	/* cookie passed to io functions */
-	int	(*_close)(void *);
-	int	(*_read)(void *, char *, int);
-	fpos_t	(*_seek)(void *, fpos_t, int);
-	int	(*_write)(void *, const char *, int);
-
-	/* extension data, to avoid further ABI breakage */
-	struct	__sbuf _ext;
-	/* data for long sequences of ungetc() */
-	unsigned char *_up;	/* saved _p when _p is doing ungetc data */
-	int	_ur;		/* saved _r when _r is counting ungetc data */
-
-	/* tricks to meet minimum requirements even when malloc() fails */
-	unsigned char _ubuf[3];	/* guarantee an ungetc() buffer */
-	unsigned char _nbuf[1];	/* guarantee a getc() buffer */
-
-	/* separate buffer for fgetln() when line crosses buffer boundary */
-	struct	__sbuf _lb;	/* buffer for fgetln() */
-
-	/* Unix stdio files get aligned to block boundaries on fseek() */
-	int	_blksize;	/* stat.st_blksize (may be != _bf._size) */
-	fpos_t	_offset;	/* current lseek offset */
-} FILE;
-
-/* Legacy BSD implementation of stdin/stdout/stderr. */
-extern FILE __sF[];
-/* More obvious implementation. */
 extern FILE* stdin;
 extern FILE* stdout;
 extern FILE* stderr;
@@ -155,24 +63,6 @@
 #define stdout stdout
 #define stderr stderr
 
-#define	__SLBF	0x0001		/* line buffered */
-#define	__SNBF	0x0002		/* unbuffered */
-#define	__SRD	0x0004		/* OK to read */
-#define	__SWR	0x0008		/* OK to write */
-	/* RD and WR are never simultaneously asserted */
-#define	__SRW	0x0010		/* open for reading & writing */
-#define	__SEOF	0x0020		/* found EOF */
-#define	__SERR	0x0040		/* found error */
-#define	__SMBF	0x0080		/* _buf is from malloc */
-#define	__SAPP	0x0100		/* fdopen()ed in append mode */
-#define	__SSTR	0x0200		/* this is an sprintf/snprintf string */
-#define	__SOPT	0x0400		/* do fseek() optimization */
-#define	__SNPT	0x0800		/* do not do fseek() optimization */
-#define	__SOFF	0x1000		/* set iff _offset is in fact correct */
-#define	__SMOD	0x2000		/* true => fgetln modified _p text */
-#define	__SALC	0x4000		/* allocate string space dynamically */
-#define	__SIGN	0x8000		/* ignore this file in _fwalk */
-
 /*
  * The following three definitions are for ANSI C, which took them
  * from System V, which brilliantly took internal interface macros and
@@ -219,18 +109,13 @@
 int	 fflush(FILE *);
 int	 fgetc(FILE *);
 char	*fgets(char * __restrict, int, FILE * __restrict);
-FILE	*fopen(const char * __restrict , const char * __restrict);
 int	 fprintf(FILE * __restrict , const char * __restrict, ...)
 		__printflike(2, 3);
 int	 fputc(int, FILE *);
 int	 fputs(const char * __restrict, FILE * __restrict);
 size_t	 fread(void * __restrict, size_t, size_t, FILE * __restrict);
-FILE	*freopen(const char * __restrict, const char * __restrict,
-	    FILE * __restrict);
 int	 fscanf(FILE * __restrict, const char * __restrict, ...)
 		__scanflike(2, 3);
-int	 fseek(FILE *, long, int);
-long	 ftell(FILE *);
 size_t	 fwrite(const void * __restrict, size_t, size_t, FILE * __restrict);
 int	 getc(FILE *);
 int	 getchar(void);
@@ -252,7 +137,6 @@
 int	 setvbuf(FILE * __restrict, char * __restrict, int, size_t);
 int	 sscanf(const char * __restrict, const char * __restrict, ...)
 		__scanflike(2, 3);
-FILE	*tmpfile(void);
 int	 ungetc(int, FILE *);
 int	 vfprintf(FILE * __restrict, const char * __restrict, __va_list)
 		__printflike(2, 0);
@@ -277,25 +161,55 @@
 #endif
 #endif
 
-extern int rename(const char*, const char*);
-extern int renameat(int, const char*, int, const char*);
+int rename(const char*, const char*);
+int renameat(int, const char*, int, const char*);
+
+int fseek(FILE*, long, int);
+long ftell(FILE*);
 
 #if defined(__USE_FILE_OFFSET64)
-/* Not possible. */
-int	 fgetpos(FILE * __restrict, fpos_t * __restrict)
-	__attribute__((__error__("not available with _FILE_OFFSET_BITS=64")));
-int	 fsetpos(FILE *, const fpos_t *)
-	__attribute__((__error__("not available with _FILE_OFFSET_BITS=64")));
-int	 fseeko(FILE *, off_t, int)
-	__attribute__((__error__("not available with _FILE_OFFSET_BITS=64")));
-off_t	 ftello(FILE *)
-	__attribute__((__error__("not available with _FILE_OFFSET_BITS=64")));
+int fgetpos(FILE*, fpos_t*) __RENAME(fgetpos64);
+int fsetpos(FILE*, const fpos_t*) __RENAME(fsetpos64);
+int fseeko(FILE*, off_t, int) __RENAME(fseeko64);
+off_t ftello(FILE*) __RENAME(ftello64);
+#  if defined(__USE_BSD)
+FILE* funopen(const void*,
+              int (*)(void*, char*, int),
+              int (*)(void*, const char*, int),
+              fpos_t (*)(void*, fpos_t, int),
+              int (*)(void*)) __RENAME(funopen64);
+#  endif
 #else
-int	 fgetpos(FILE * __restrict, fpos_t * __restrict);
-int	 fsetpos(FILE *, const fpos_t *);
-int	 fseeko(FILE *, off_t, int);
-off_t	 ftello(FILE *);
+int fgetpos(FILE*, fpos_t*);
+int fsetpos(FILE*, const fpos_t*);
+int fseeko(FILE*, off_t, int);
+off_t ftello(FILE*);
+#  if defined(__USE_BSD)
+FILE* funopen(const void*,
+              int (*)(void*, char*, int),
+              int (*)(void*, const char*, int),
+              fpos_t (*)(void*, fpos_t, int),
+              int (*)(void*));
+#  endif
 #endif
+int fgetpos64(FILE*, fpos64_t*);
+int fsetpos64(FILE*, const fpos64_t*);
+int fseeko64(FILE*, off64_t, int);
+off64_t ftello64(FILE*);
+#if defined(__USE_BSD)
+FILE* funopen64(const void*,
+                int (*)(void*, char*, int),
+                int (*)(void*, const char*, int),
+                fpos64_t (*)(void*, fpos64_t, int),
+                int (*)(void*));
+#endif
+
+FILE* fopen(const char* __restrict, const char* __restrict);
+FILE* fopen64(const char* __restrict, const char* __restrict);
+FILE* freopen(const char* __restrict, const char* __restrict, FILE* __restrict);
+FILE* freopen64(const char* __restrict, const char* __restrict, FILE* __restrict);
+FILE* tmpfile(void);
+FILE* tmpfile64(void);
 
 #if __ISO_C_VISIBLE >= 1999 || __BSD_VISIBLE
 int	 snprintf(char * __restrict, size_t, const char * __restrict, ...)
@@ -363,18 +277,10 @@
 void clearerr_unlocked(FILE*);
 int feof_unlocked(FILE*);
 int ferror_unlocked(FILE*);
+int fileno_unlocked(FILE*);
 
-/*
- * Stdio function-access interface.
- */
-FILE	*funopen(const void *,
-		int (*)(void *, char *, int),
-		int (*)(void *, const char *, int),
-		fpos_t (*)(void *, fpos_t, int),
-		int (*)(void *));
-
-#define	fropen(cookie, fn) funopen(cookie, fn, 0, 0, 0)
-#define	fwopen(cookie, fn) funopen(cookie, 0, fn, 0, 0)
+#define fropen(cookie, fn) funopen(cookie, fn, 0, 0, 0)
+#define fwopen(cookie, fn) funopen(cookie, 0, fn, 0, 0)
 #endif /* __BSD_VISIBLE */
 
 extern char* __fgets_chk(char*, int, FILE*, size_t);
@@ -382,6 +288,16 @@
 __errordecl(__fgets_too_big_error, "fgets called with size bigger than buffer");
 __errordecl(__fgets_too_small_error, "fgets called with size less than zero");
 
+extern size_t __fread_chk(void * __restrict, size_t, size_t, FILE * __restrict, size_t);
+extern size_t __fread_real(void * __restrict, size_t, size_t, FILE * __restrict) __RENAME(fread);
+__errordecl(__fread_too_big_error, "fread called with size * count bigger than buffer");
+__errordecl(__fread_overflow, "fread called with overflowing size * count");
+
+extern size_t __fwrite_chk(const void * __restrict, size_t, size_t, FILE * __restrict, size_t);
+extern size_t __fwrite_real(const void * __restrict, size_t, size_t, FILE * __restrict) __RENAME(fwrite);
+__errordecl(__fwrite_too_big_error, "fwrite called with size * count bigger than buffer");
+__errordecl(__fwrite_overflow, "fwrite called with overflowing size * count");
+
 #if defined(__BIONIC_FORTIFY)
 
 __BIONIC_FORTIFY_INLINE
@@ -428,6 +344,58 @@
 }
 #endif
 
+__BIONIC_FORTIFY_INLINE
+size_t fread(void * __restrict buf, size_t size, size_t count, FILE * __restrict stream) {
+    size_t bos = __bos0(buf);
+
+#if !defined(__clang__)
+    if (bos == __BIONIC_FORTIFY_UNKNOWN_SIZE) {
+        return __fread_real(buf, size, count, stream);
+    }
+
+    if (__builtin_constant_p(size) && __builtin_constant_p(count)) {
+        size_t total;
+        if (__size_mul_overflow(size, count, &total)) {
+            __fread_overflow();
+        }
+
+        if (total > bos) {
+            __fread_too_big_error();
+        }
+
+        return __fread_real(buf, size, count, stream);
+    }
+#endif
+
+    return __fread_chk(buf, size, count, stream, bos);
+}
+
+__BIONIC_FORTIFY_INLINE
+size_t fwrite(const void * __restrict buf, size_t size, size_t count, FILE * __restrict stream) {
+    size_t bos = __bos0(buf);
+
+#if !defined(__clang__)
+    if (bos == __BIONIC_FORTIFY_UNKNOWN_SIZE) {
+        return __fwrite_real(buf, size, count, stream);
+    }
+
+    if (__builtin_constant_p(size) && __builtin_constant_p(count)) {
+        size_t total;
+        if (__size_mul_overflow(size, count, &total)) {
+            __fwrite_overflow();
+        }
+
+        if (total > bos) {
+            __fwrite_too_big_error();
+        }
+
+        return __fwrite_real(buf, size, count, stream);
+    }
+#endif
+
+    return __fwrite_chk(buf, size, count, stream, bos);
+}
+
 #if !defined(__clang__)
 
 __BIONIC_FORTIFY_INLINE
diff --git a/libc/include/stdlib.h b/libc/include/stdlib.h
index efca577..d9d277a 100644
--- a/libc/include/stdlib.h
+++ b/libc/include/stdlib.h
@@ -76,10 +76,10 @@
 
 extern int posix_memalign(void **memptr, size_t alignment, size_t size);
 
-_BIONIC_NOT_BEFORE_21(extern double atof(const char*);)
+extern double atof(const char*) __INTRODUCED_IN(21);
 
 extern double strtod(const char*, char**) __LIBC_ABI_PUBLIC__;
-_BIONIC_NOT_BEFORE_21(extern float strtof(const char*, char**) __LIBC_ABI_PUBLIC__;)
+extern float strtof(const char*, char**) __LIBC_ABI_PUBLIC__ __INTRODUCED_IN(21);
 extern long double strtold(const char*, char**) __LIBC_ABI_PUBLIC__;
 
 extern long double strtold_l(const char *, char **, locale_t) __LIBC_ABI_PUBLIC__;
@@ -90,9 +90,9 @@
 extern long atol(const char*) __purefunc;
 extern long long atoll(const char*) __purefunc;
 
-_BIONIC_NOT_BEFORE_21(extern int abs(int) __pure2;)
-_BIONIC_NOT_BEFORE_21(extern long labs(long) __pure2;)
-_BIONIC_NOT_BEFORE_21(extern long long llabs(long long) __pure2;)
+extern int abs(int) __pure2 __INTRODUCED_IN(21);
+extern long labs(long) __pure2 __INTRODUCED_IN(21);
+extern long long llabs(long long) __pure2 __INTRODUCED_IN(21);
 
 extern char * realpath(const char *path, char *resolved);
 extern int system(const char *string);
@@ -109,9 +109,9 @@
 
 #define RAND_MAX 0x7fffffff
 
-_BIONIC_NOT_BEFORE_21(int rand(void);)
+int rand(void) __INTRODUCED_IN(21);
 int rand_r(unsigned int*);
-_BIONIC_NOT_BEFORE_21(void srand(unsigned int);)
+void srand(unsigned int) __INTRODUCED_IN(21);
 
 double drand48(void);
 double erand48(unsigned short[3]);
@@ -124,12 +124,12 @@
 void srand48(long);
 
 char* initstate(unsigned int, char*, size_t);
-_BIONIC_NOT_BEFORE_21(long random(void);)
+long random(void) __INTRODUCED_IN(21);
 char* setstate(char*);
-_BIONIC_NOT_BEFORE_21(void srandom(unsigned int);)
+void srandom(unsigned int) __INTRODUCED_IN(21);
 
 int getpt(void);
-_BIONIC_NOT_BEFORE_21(int grantpt(int);)
+int grantpt(int) __INTRODUCED_IN(21);
 int posix_openpt(int);
 char* ptsname(int);
 int ptsname_r(int, char*, size_t);
diff --git a/libc/include/string.h b/libc/include/string.h
index d32c164..32d4a18 100644
--- a/libc/include/string.h
+++ b/libc/include/string.h
@@ -53,6 +53,14 @@
 
 extern char*  strchr(const char *, int) __purefunc;
 extern char* __strchr_chk(const char *, int, size_t);
+#if defined(__USE_GNU)
+#if defined(__cplusplus)
+extern "C++" char* strchrnul(char*, int) __RENAME(strchrnul) __purefunc;
+extern "C++" const char* strchrnul(const char*, int) __RENAME(strchrnul) __purefunc;
+#else
+char* strchrnul(const char*, int) __purefunc;
+#endif
+#endif
 
 extern char*  strrchr(const char *, int) __purefunc;
 extern char* __strrchr_chk(const char *, int, size_t);
@@ -107,18 +115,18 @@
 extern int    strcoll_l(const char *, const char *, locale_t) __purefunc;
 extern size_t strxfrm_l(char* __restrict, const char* __restrict, size_t, locale_t);
 
-#if defined(__USE_GNU) && !defined(__bionic_using_posix_basename)
+#if defined(__USE_GNU) && !defined(basename)
 /*
  * glibc has a basename in <string.h> that's different to the POSIX one in <libgen.h>.
  * It doesn't modify its argument, and in C++ it's const-correct.
  */
+
 #if defined(__cplusplus)
 extern "C++" char* basename(char*) __RENAME(__gnu_basename) __nonnull((1));
 extern "C++" const char* basename(const char*) __RENAME(__gnu_basename) __nonnull((1));
 #else
 extern char* basename(const char*) __RENAME(__gnu_basename) __nonnull((1));
 #endif
-#define __bionic_using_gnu_basename
 #endif
 
 extern void* __memchr_chk(const void*, int, size_t, size_t);
diff --git a/libc/include/sys/_system_properties.h b/libc/include/sys/_system_properties.h
index a0315b5..3b1f7d0 100644
--- a/libc/include/sys/_system_properties.h
+++ b/libc/include/sys/_system_properties.h
@@ -41,6 +41,7 @@
 #define PROP_AREA_VERSION_COMPAT 0x45434f76
 
 #define PROP_SERVICE_NAME "property_service"
+#define PROP_FILENAME_MAX 1024
 #define PROP_FILENAME "/dev/__properties__"
 
 #define PA_SIZE         (128 * 1024)
diff --git a/libc/include/sys/cdefs.h b/libc/include/sys/cdefs.h
index 04613f4..f51942b 100644
--- a/libc/include/sys/cdefs.h
+++ b/libc/include/sys/cdefs.h
@@ -130,30 +130,9 @@
 #define	__volatile
 #endif	/* !__GNUC__ */
 
-/*
- * In non-ANSI C environments, new programs will want ANSI-only C keywords
- * deleted from the program and old programs will want them left alone.
- * Programs using the ANSI C keywords const, inline etc. as normal
- * identifiers should define -DNO_ANSI_KEYWORDS.
- */
-#ifndef	NO_ANSI_KEYWORDS
-#define	const		__const		/* convert ANSI C keywords */
-#define	inline		__inline
-#define	signed		__signed
-#define	volatile	__volatile
-#endif /* !NO_ANSI_KEYWORDS */
 #endif	/* !(__STDC__ || __cplusplus) */
 
 /*
- * Used for internal auditing of the NetBSD source tree.
- */
-#ifdef __AUDIT__
-#define	__aconst	__const
-#else
-#define	__aconst
-#endif
-
-/*
  * The following macro is used to remove const cast-away warnings
  * from gcc -Wcast-qual; it should be used with caution because it
  * can hide valid errors; in particular most valid uses are in
@@ -164,75 +143,19 @@
  */
 #define __UNCONST(a)	((void *)(unsigned long)(const void *)(a))
 
-/*
- * GCC2 provides __extension__ to suppress warnings for various GNU C
- * language extensions under "-ansi -pedantic".
- */
-#if !__GNUC_PREREQ(2, 0)
-#define	__extension__		/* delete __extension__ if non-gcc or gcc1 */
-#endif
-
-/*
- * GCC1 and some versions of GCC2 declare dead (non-returning) and
- * pure (no side effects) functions using "volatile" and "const";
- * unfortunately, these then cause warnings under "-ansi -pedantic".
- * GCC2 uses a new, peculiar __attribute__((attrs)) style.  All of
- * these work for GNU C++ (modulo a slight glitch in the C++ grammar
- * in the distribution version of 2.5.5).
- */
-#if !__GNUC_PREREQ(2, 5)
-#define	__attribute__(x)	/* delete __attribute__ if non-gcc or gcc1 */
-#if defined(__GNUC__) && !defined(__STRICT_ANSI__)
-#define	__dead		__volatile
-#define	__pure		__const
-#endif
-#endif
-
-/* Delete pseudo-keywords wherever they are not available or needed. */
-#ifndef __dead
-#define	__dead
-#define	__pure
-#endif
-
-#if __GNUC_PREREQ(2, 7)
-#define	__unused	__attribute__((__unused__))
-#else
-#define	__unused	/* delete */
-#endif
-
+#define __dead __attribute__((__noreturn__))
+#define __pure __attribute__((__const__))
 #define __pure2 __attribute__((__const__)) /* Android-added: used by FreeBSD libm */
 
-#if __GNUC_PREREQ(3, 1)
-#define	__used		__attribute__((__used__))
-#else
-#define	__used		/* delete */
-#endif
+#define	__unused	__attribute__((__unused__))
 
-#if __GNUC_PREREQ(2, 7)
+#define	__used		__attribute__((__used__))
+
 #define	__packed	__attribute__((__packed__))
 #define	__aligned(x)	__attribute__((__aligned__(x)))
 #define	__section(x)	__attribute__((__section__(x)))
-#elif defined(__lint__)
-#define	__packed	/* delete */
-#define	__aligned(x)	/* delete */
-#define	__section(x)	/* delete */
-#else
-#define	__packed	error: no __packed for this compiler
-#define	__aligned(x)	error: no __aligned for this compiler
-#define	__section(x)	error: no __section for this compiler
-#endif
 
-#if !__GNUC_PREREQ(2, 8)
-#define	__extension__
-#endif
-
-#if __GNUC_PREREQ(2, 8)
 #define __statement(x)	__extension__(x)
-#elif defined(lint)
-#define __statement(x)	(0)
-#else
-#define __statement(x)	(x)
-#endif
 
 #define __nonnull(args) __attribute__((__nonnull__ args))
 
@@ -240,43 +163,20 @@
 #define __scanflike(x, y) __attribute__((__format__(scanf, x, y))) __nonnull((x))
 
 /*
- * C99 defines the restrict type qualifier keyword, which was made available
- * in GCC 2.92.
+ * C99 defines the restrict type qualifier keyword.
  */
 #if defined(__STDC__VERSION__) && __STDC_VERSION__ >= 199901L
 #define	__restrict	restrict
-#else
-#if !__GNUC_PREREQ(2, 92)
-#define	__restrict	/* delete __restrict when not supported */
-#endif
 #endif
 
 /*
- * C99 defines __func__ predefined identifier, which was made available
- * in GCC 2.95.
+ * C99 defines __func__ predefined identifier.
  */
 #if !defined(__STDC_VERSION__) || !(__STDC_VERSION__ >= 199901L)
-#if __GNUC_PREREQ(2, 6)
 #define	__func__	__PRETTY_FUNCTION__
-#elif __GNUC_PREREQ(2, 4)
-#define	__func__	__FUNCTION__
-#else
-#define	__func__	""
-#endif
 #endif /* !(__STDC_VERSION__ >= 199901L) */
 
 /*
- * A barrier to stop the optimizer from moving code or assume live
- * register values. This is gcc specific, the version is more or less
- * arbitrary, might work with older compilers.
- */
-#if __GNUC_PREREQ(2, 95)
-#define	__insn_barrier()	__asm __volatile("":::"memory")
-#else
-#define	__insn_barrier()	/* */
-#endif
-
-/*
  * GNU C version 2.96 adds explicit branch prediction so that
  * the CPU back-end can hint the processor and also so that
  * code blocks can be reordered such that the predicted path
@@ -304,43 +204,19 @@
  *	  basic block reordering that this affects can often generate
  *	  larger code.
  */
-#if __GNUC_PREREQ(2, 96)
 #define	__predict_true(exp)	__builtin_expect((exp) != 0, 1)
 #define	__predict_false(exp)	__builtin_expect((exp) != 0, 0)
-#else
-#define	__predict_true(exp)	(exp)
-#define	__predict_false(exp)	(exp)
-#endif
 
-#if __GNUC_PREREQ(2, 96)
 #define __noreturn    __attribute__((__noreturn__))
 #define __mallocfunc  __attribute__((malloc))
 #define __purefunc    __attribute__((pure))
-#else
-#define __noreturn
-#define __mallocfunc
-#define __purefunc
-#endif
 
-#if __GNUC_PREREQ(3, 1)
 #define __always_inline __attribute__((__always_inline__))
-#else
-#define __always_inline
-#endif
 
-#if __GNUC_PREREQ(3, 4)
 #define __wur __attribute__((__warn_unused_result__))
-#else
-#define __wur
-#endif
 
-#if __GNUC_PREREQ(4, 3)
 #define __errorattr(msg) __attribute__((__error__(msg)))
 #define __warnattr(msg) __attribute__((__warning__(msg)))
-#else
-#define __errorattr(msg)
-#define __warnattr(msg)
-#endif
 
 #define __errordecl(name, msg) extern void name(void) __errorattr(msg)
 
@@ -520,6 +396,11 @@
 #include <android/api-level.h>
 
 /* glibc compatibility. */
+#if __POSIX_VISIBLE >= 200809
+#define __USE_ISOC99 1
+#define __USE_XOPEN2K 1
+#define __USE_XOPEN2K8 1
+#endif
 #if __LP64__
 #define __WORDSIZE 64
 #else
@@ -535,19 +416,14 @@
  * http://gcc.gnu.org/onlinedocs/gcc/Object-Size-Checking.html for details.
  */
 #if defined(_FORTIFY_SOURCE) && _FORTIFY_SOURCE > 0 && defined(__OPTIMIZE__) && __OPTIMIZE__ > 0
-#define __BIONIC_FORTIFY 1
-#if _FORTIFY_SOURCE == 2
-#define __bos(s) __builtin_object_size((s), 1)
-#else
-#define __bos(s) __builtin_object_size((s), 0)
-#endif
-#define __bos0(s) __builtin_object_size((s), 0)
-
-#if __GNUC_PREREQ(4,3) || __has_attribute(__artificial__)
-#define __BIONIC_FORTIFY_INLINE extern __inline__ __always_inline __attribute__((gnu_inline)) __attribute__((__artificial__))
-#else
-#define __BIONIC_FORTIFY_INLINE extern __inline__ __always_inline __attribute__((gnu_inline))
-#endif
+#  define __BIONIC_FORTIFY 1
+#  if _FORTIFY_SOURCE == 2
+#    define __bos(s) __builtin_object_size((s), 1)
+#  else
+#    define __bos(s) __builtin_object_size((s), 0)
+#  endif
+#  define __bos0(s) __builtin_object_size((s), 0)
+#  define __BIONIC_FORTIFY_INLINE extern __inline__ __always_inline __attribute__((gnu_inline)) __attribute__((__artificial__))
 #endif
 #define __BIONIC_FORTIFY_UNKNOWN_SIZE ((size_t) -1)
 
@@ -556,9 +432,9 @@
 
 /* Like __LIBC_HIDDEN__, but preserves binary compatibility for LP32. */
 #ifdef __LP64__
-#define __LIBC64_HIDDEN__ __LIBC_HIDDEN__
+#define __LIBC32_LEGACY_PUBLIC__ __LIBC_HIDDEN__
 #else
-#define __LIBC64_HIDDEN__ __LIBC_ABI_PUBLIC__
+#define __LIBC32_LEGACY_PUBLIC__ __LIBC_ABI_PUBLIC__
 #endif
 
 /* Used to tag non-static symbols that are public and exposed by the shared library. */
@@ -567,10 +443,31 @@
 /* Used to rename functions so that the compiler emits a call to 'x' rather than the function this was applied to. */
 #define __RENAME(x) __asm__(#x)
 
-#if __ANDROID_API__ >= 21
-#define _BIONIC_NOT_BEFORE_21(x) x
+#ifdef __clang__
+#define __AVAILABILITY(...) __attribute__((availability(android,__VA_ARGS__)))
+#define __INTRODUCED_IN(api_level) __AVAILABILITY(introduced=api_level)
+#define __DEPRECATED_IN(api_level) __AVAILABILITY(deprecated=api_level)
+#define __REMOVED_IN(api_level) __AVAILABILITY(obsoleted=api_level)
 #else
-#define _BIONIC_NOT_BEFORE_21(x)
-#endif /* __ANDROID_API__ >= 21 */
+#define __AVAILABILITY(...)
+#define __INTRODUCED_IN(api_level)
+#define __DEPRECATED_IN(api_level)
+#define __REMOVED_IN(api_level)
+#endif // __clang__
+
+#if __has_builtin(__builtin_umul_overflow) || __GNUC__ >= 5
+#if __LP64__
+#define __size_mul_overflow(a, b, result) __builtin_umull_overflow(a, b, result)
+#else
+#define __size_mul_overflow(a, b, result) __builtin_umul_overflow(a, b, result)
+#endif
+#else
+extern __inline__ __always_inline __attribute__((gnu_inline))
+int __size_mul_overflow(__SIZE_TYPE__ a, __SIZE_TYPE__ b, __SIZE_TYPE__ *result) {
+    *result = a * b;
+    static const __SIZE_TYPE__ mul_no_overflow = 1UL << (sizeof(__SIZE_TYPE__) * 4);
+    return (a >= mul_no_overflow || b >= mul_no_overflow) && a > 0 && (__SIZE_TYPE__)-1 / a < b;
+}
+#endif
 
 #endif /* !_SYS_CDEFS_H_ */
diff --git a/libc/include/sys/endian.h b/libc/include/sys/endian.h
index 2fd480d..60cc030 100644
--- a/libc/include/sys/endian.h
+++ b/libc/include/sys/endian.h
@@ -75,10 +75,6 @@
 #define	HTONL(x) (x) = htonl((u_int32_t)(x))
 #define	HTONS(x) (x) = htons((u_int16_t)(x))
 
-#define swap16 __swap16
-#define swap32 __swap32
-#define swap64 __swap64
-
 #define htobe16 __swap16
 #define htobe32 __swap32
 #define htobe64 __swap64
diff --git a/libc/include/sys/fcntl.h b/libc/include/sys/fcntl.h
new file mode 100644
index 0000000..cd30455
--- /dev/null
+++ b/libc/include/sys/fcntl.h
@@ -0,0 +1 @@
+#include <fcntl.h>
diff --git a/libc/include/sys/glibc-syscalls.h b/libc/include/sys/glibc-syscalls.h
index 926209b..26887b1 100644
--- a/libc/include/sys/glibc-syscalls.h
+++ b/libc/include/sys/glibc-syscalls.h
@@ -41,6 +41,7 @@
 #define SYS_eventfd __NR_eventfd
 #define SYS_eventfd2 __NR_eventfd2
 #define SYS_execve __NR_execve
+#define SYS_execveat __NR_execveat
 #define SYS_exit __NR_exit
 #define SYS_exit_group __NR_exit_group
 #define SYS_faccessat __NR_faccessat
@@ -136,6 +137,7 @@
 #define SYS_lstat64 __NR_lstat64
 #define SYS_madvise __NR_madvise
 #define SYS_mbind __NR_mbind
+#define SYS_membarrier __NR_membarrier
 #define SYS_memfd_create __NR_memfd_create
 #define SYS_migrate_pages __NR_migrate_pages
 #define SYS_mincore __NR_mincore
@@ -144,6 +146,7 @@
 #define SYS_mknod __NR_mknod
 #define SYS_mknodat __NR_mknodat
 #define SYS_mlock __NR_mlock
+#define SYS_mlock2 __NR_mlock2
 #define SYS_mlockall __NR_mlockall
 #define SYS_mmap __NR_mmap
 #define SYS_mmap2 __NR_mmap2
@@ -314,6 +317,7 @@
 #define SYS_unlinkat __NR_unlinkat
 #define SYS_unshare __NR_unshare
 #define SYS_uselib __NR_uselib
+#define SYS_userfaultfd __NR_userfaultfd
 #define SYS_ustat __NR_ustat
 #define SYS_utime __NR_utime
 #define SYS_utimensat __NR_utimensat
@@ -367,6 +371,7 @@
 #define SYS_eventfd __NR_eventfd
 #define SYS_eventfd2 __NR_eventfd2
 #define SYS_execve __NR_execve
+#define SYS_execveat __NR_execveat
 #define SYS_exit __NR_exit
 #define SYS_exit_group __NR_exit_group
 #define SYS_faccessat __NR_faccessat
@@ -469,6 +474,7 @@
 #define SYS_lstat64 __NR_lstat64
 #define SYS_madvise __NR_madvise
 #define SYS_mbind __NR_mbind
+#define SYS_membarrier __NR_membarrier
 #define SYS_memfd_create __NR_memfd_create
 #define SYS_mincore __NR_mincore
 #define SYS_mkdir __NR_mkdir
@@ -476,6 +482,7 @@
 #define SYS_mknod __NR_mknod
 #define SYS_mknodat __NR_mknodat
 #define SYS_mlock __NR_mlock
+#define SYS_mlock2 __NR_mlock2
 #define SYS_mlockall __NR_mlockall
 #define SYS_mmap __NR_mmap
 #define SYS_mmap2 __NR_mmap2
@@ -666,6 +673,7 @@
 #define SYS_unlinkat __NR_unlinkat
 #define SYS_unshare __NR_unshare
 #define SYS_uselib __NR_uselib
+#define SYS_userfaultfd __NR_userfaultfd
 #define SYS_ustat __NR_ustat
 #define SYS_utime __NR_utime
 #define SYS_utimensat __NR_utimensat
@@ -722,6 +730,7 @@
 #define SYS_eventfd __NR_eventfd
 #define SYS_eventfd2 __NR_eventfd2
 #define SYS_execve __NR_execve
+#define SYS_execveat __NR_execveat
 #define SYS_exit __NR_exit
 #define SYS_exit_group __NR_exit_group
 #define SYS_faccessat __NR_faccessat
@@ -824,6 +833,7 @@
 #define SYS_lstat64 __NR_lstat64
 #define SYS_madvise __NR_madvise
 #define SYS_mbind __NR_mbind
+#define SYS_membarrier __NR_membarrier
 #define SYS_memfd_create __NR_memfd_create
 #define SYS_migrate_pages __NR_migrate_pages
 #define SYS_mincore __NR_mincore
@@ -832,6 +842,7 @@
 #define SYS_mknod __NR_mknod
 #define SYS_mknodat __NR_mknodat
 #define SYS_mlock __NR_mlock
+#define SYS_mlock2 __NR_mlock2
 #define SYS_mlockall __NR_mlockall
 #define SYS_mmap __NR_mmap
 #define SYS_mmap2 __NR_mmap2
@@ -1033,6 +1044,7 @@
 #define SYS_unused59 __NR_unused59
 #define SYS_unused84 __NR_unused84
 #define SYS_uselib __NR_uselib
+#define SYS_userfaultfd __NR_userfaultfd
 #define SYS_ustat __NR_ustat
 #define SYS_utime __NR_utime
 #define SYS_utimensat __NR_utimensat
@@ -1047,6 +1059,7 @@
 #define SYS_write __NR_write
 #define SYS_writev __NR_writev
 #elif defined(__i386__)
+#define SYS_accept4 __NR_accept4
 #define SYS_access __NR_access
 #define SYS_acct __NR_acct
 #define SYS_add_key __NR_add_key
@@ -1054,6 +1067,7 @@
 #define SYS_afs_syscall __NR_afs_syscall
 #define SYS_alarm __NR_alarm
 #define SYS_bdflush __NR_bdflush
+#define SYS_bind __NR_bind
 #define SYS_bpf __NR_bpf
 #define SYS_break __NR_break
 #define SYS_brk __NR_brk
@@ -1071,6 +1085,7 @@
 #define SYS_clock_settime __NR_clock_settime
 #define SYS_clone __NR_clone
 #define SYS_close __NR_close
+#define SYS_connect __NR_connect
 #define SYS_creat __NR_creat
 #define SYS_create_module __NR_create_module
 #define SYS_delete_module __NR_delete_module
@@ -1085,6 +1100,7 @@
 #define SYS_eventfd __NR_eventfd
 #define SYS_eventfd2 __NR_eventfd2
 #define SYS_execve __NR_execve
+#define SYS_execveat __NR_execveat
 #define SYS_exit __NR_exit
 #define SYS_exit_group __NR_exit_group
 #define SYS_faccessat __NR_faccessat
@@ -1137,6 +1153,7 @@
 #define SYS_getgroups __NR_getgroups
 #define SYS_getgroups32 __NR_getgroups32
 #define SYS_getitimer __NR_getitimer
+#define SYS_getpeername __NR_getpeername
 #define SYS_getpgid __NR_getpgid
 #define SYS_getpgrp __NR_getpgrp
 #define SYS_getpid __NR_getpid
@@ -1151,6 +1168,8 @@
 #define SYS_getrlimit __NR_getrlimit
 #define SYS_getrusage __NR_getrusage
 #define SYS_getsid __NR_getsid
+#define SYS_getsockname __NR_getsockname
+#define SYS_getsockopt __NR_getsockopt
 #define SYS_gettid __NR_gettid
 #define SYS_gettimeofday __NR_gettimeofday
 #define SYS_getuid __NR_getuid
@@ -1183,6 +1202,7 @@
 #define SYS_lgetxattr __NR_lgetxattr
 #define SYS_link __NR_link
 #define SYS_linkat __NR_linkat
+#define SYS_listen __NR_listen
 #define SYS_listxattr __NR_listxattr
 #define SYS_llistxattr __NR_llistxattr
 #define SYS_lock __NR_lock
@@ -1194,6 +1214,7 @@
 #define SYS_lstat64 __NR_lstat64
 #define SYS_madvise __NR_madvise
 #define SYS_mbind __NR_mbind
+#define SYS_membarrier __NR_membarrier
 #define SYS_memfd_create __NR_memfd_create
 #define SYS_migrate_pages __NR_migrate_pages
 #define SYS_mincore __NR_mincore
@@ -1202,6 +1223,7 @@
 #define SYS_mknod __NR_mknod
 #define SYS_mknodat __NR_mknodat
 #define SYS_mlock __NR_mlock
+#define SYS_mlock2 __NR_mlock2
 #define SYS_mlockall __NR_mlockall
 #define SYS_mmap __NR_mmap
 #define SYS_mmap2 __NR_mmap2
@@ -1263,7 +1285,9 @@
 #define SYS_readlinkat __NR_readlinkat
 #define SYS_readv __NR_readv
 #define SYS_reboot __NR_reboot
+#define SYS_recvfrom __NR_recvfrom
 #define SYS_recvmmsg __NR_recvmmsg
+#define SYS_recvmsg __NR_recvmsg
 #define SYS_remap_file_pages __NR_remap_file_pages
 #define SYS_removexattr __NR_removexattr
 #define SYS_rename __NR_rename
@@ -1297,6 +1321,8 @@
 #define SYS_sendfile __NR_sendfile
 #define SYS_sendfile64 __NR_sendfile64
 #define SYS_sendmmsg __NR_sendmmsg
+#define SYS_sendmsg __NR_sendmsg
+#define SYS_sendto __NR_sendto
 #define SYS_set_mempolicy __NR_set_mempolicy
 #define SYS_set_robust_list __NR_set_robust_list
 #define SYS_set_thread_area __NR_set_thread_area
@@ -1325,11 +1351,13 @@
 #define SYS_setreuid32 __NR_setreuid32
 #define SYS_setrlimit __NR_setrlimit
 #define SYS_setsid __NR_setsid
+#define SYS_setsockopt __NR_setsockopt
 #define SYS_settimeofday __NR_settimeofday
 #define SYS_setuid __NR_setuid
 #define SYS_setuid32 __NR_setuid32
 #define SYS_setxattr __NR_setxattr
 #define SYS_sgetmask __NR_sgetmask
+#define SYS_shutdown __NR_shutdown
 #define SYS_sigaction __NR_sigaction
 #define SYS_sigaltstack __NR_sigaltstack
 #define SYS_signal __NR_signal
@@ -1339,7 +1367,9 @@
 #define SYS_sigprocmask __NR_sigprocmask
 #define SYS_sigreturn __NR_sigreturn
 #define SYS_sigsuspend __NR_sigsuspend
+#define SYS_socket __NR_socket
 #define SYS_socketcall __NR_socketcall
+#define SYS_socketpair __NR_socketpair
 #define SYS_splice __NR_splice
 #define SYS_ssetmask __NR_ssetmask
 #define SYS_stat __NR_stat
@@ -1383,6 +1413,7 @@
 #define SYS_unlinkat __NR_unlinkat
 #define SYS_unshare __NR_unshare
 #define SYS_uselib __NR_uselib
+#define SYS_userfaultfd __NR_userfaultfd
 #define SYS_ustat __NR_ustat
 #define SYS_utime __NR_utime
 #define SYS_utimensat __NR_utimensat
@@ -1441,6 +1472,7 @@
 #define SYS_eventfd __NR_eventfd
 #define SYS_eventfd2 __NR_eventfd2
 #define SYS_execve __NR_execve
+#define SYS_execveat __NR_execveat
 #define SYS_exit __NR_exit
 #define SYS_exit_group __NR_exit_group
 #define SYS_faccessat __NR_faccessat
@@ -1534,6 +1566,7 @@
 #define SYS_lstat __NR_lstat
 #define SYS_madvise __NR_madvise
 #define SYS_mbind __NR_mbind
+#define SYS_membarrier __NR_membarrier
 #define SYS_memfd_create __NR_memfd_create
 #define SYS_migrate_pages __NR_migrate_pages
 #define SYS_mincore __NR_mincore
@@ -1542,6 +1575,7 @@
 #define SYS_mknod __NR_mknod
 #define SYS_mknodat __NR_mknodat
 #define SYS_mlock __NR_mlock
+#define SYS_mlock2 __NR_mlock2
 #define SYS_mlockall __NR_mlockall
 #define SYS_mmap __NR_mmap
 #define SYS_modify_ldt __NR_modify_ldt
@@ -1708,6 +1742,7 @@
 #define SYS_unlinkat __NR_unlinkat
 #define SYS_unshare __NR_unshare
 #define SYS_uselib __NR_uselib
+#define SYS_userfaultfd __NR_userfaultfd
 #define SYS_ustat __NR_ustat
 #define SYS_utime __NR_utime
 #define SYS_utimensat __NR_utimensat
diff --git a/libc/include/sys/mman.h b/libc/include/sys/mman.h
index 6857f60..a19ceb5 100644
--- a/libc/include/sys/mman.h
+++ b/libc/include/sys/mman.h
@@ -59,7 +59,7 @@
 extern int munmap(void*, size_t);
 extern int msync(const void*, size_t, int);
 extern int mprotect(const void*, size_t, int);
-extern void* mremap(void*, size_t, size_t, unsigned long);
+extern void* mremap(void*, size_t, size_t, int, ...);
 
 extern int mlockall(int);
 extern int munlockall(void);
diff --git a/libc/include/sys/procfs.h b/libc/include/sys/procfs.h
index b5b1a46..7ef5023 100644
--- a/libc/include/sys/procfs.h
+++ b/libc/include/sys/procfs.h
@@ -39,6 +39,10 @@
 
 typedef fpregset_t elf_fpregset_t;
 
+#if defined(__i386__)
+typedef struct user_fpxregs_struct elf_fpxregset_t;
+#endif
+
 typedef elf_gregset_t prgregset_t;
 typedef elf_fpregset_t prfpregset_t;
 
diff --git a/libc/include/sys/resource.h b/libc/include/sys/resource.h
index 3f8dd45..8209dfb 100644
--- a/libc/include/sys/resource.h
+++ b/libc/include/sys/resource.h
@@ -53,10 +53,7 @@
 
 extern int getrusage(int, struct rusage*);
 
-#if __LP64__
-/* Implementing prlimit for 32-bit isn't worth the effort. */
 extern int prlimit(pid_t, int, const struct rlimit*, struct rlimit*);
-#endif
 extern int prlimit64(pid_t, int, const struct rlimit64*, struct rlimit64*);
 
 __END_DECLS
diff --git a/libc/include/sys/socket.h b/libc/include/sys/socket.h
index 43d1586..c7e9acc 100644
--- a/libc/include/sys/socket.h
+++ b/libc/include/sys/socket.h
@@ -50,19 +50,15 @@
 #ifdef __mips__
 #define SOCK_DGRAM      1
 #define SOCK_STREAM     2
+#else
+#define SOCK_STREAM     1
+#define SOCK_DGRAM      2
+#endif
 #define SOCK_RAW        3
 #define SOCK_RDM        4
 #define SOCK_SEQPACKET  5
 #define SOCK_DCCP       6
 #define SOCK_PACKET     10
-#else
-#define SOCK_STREAM      1
-#define SOCK_DGRAM       2
-#define SOCK_RAW         3
-#define SOCK_RDM         4
-#define SOCK_SEQPACKET   5
-#define SOCK_PACKET      10
-#endif
 
 #define SOCK_CLOEXEC O_CLOEXEC
 #define SOCK_NONBLOCK O_NONBLOCK
@@ -109,7 +105,7 @@
 
 #define CMSG_NXTHDR(mhdr, cmsg) __cmsg_nxthdr((mhdr), (cmsg))
 #define CMSG_ALIGN(len) ( ((len)+sizeof(long)-1) & ~(sizeof(long)-1) )
-#define CMSG_DATA(cmsg) ((void*)((char*)(cmsg) + CMSG_ALIGN(sizeof(struct cmsghdr))))
+#define CMSG_DATA(cmsg) (((unsigned char*)(cmsg) + CMSG_ALIGN(sizeof(struct cmsghdr))))
 #define CMSG_SPACE(len) (CMSG_ALIGN(sizeof(struct cmsghdr)) + CMSG_ALIGN(len))
 #define CMSG_LEN(len) (CMSG_ALIGN(sizeof(struct cmsghdr)) + (len))
 #define CMSG_FIRSTHDR(msg) \
@@ -168,7 +164,9 @@
 #define AF_IEEE802154 36
 #define AF_CAIF 37
 #define AF_ALG 38
-#define AF_MAX 39
+#define AF_NFC 39
+#define AF_VSOCK 40
+#define AF_MAX 41
 
 #define PF_UNSPEC AF_UNSPEC
 #define PF_UNIX AF_UNIX
@@ -209,6 +207,8 @@
 #define PF_IEEE802154 AF_IEEE802154
 #define PF_CAIF AF_CAIF
 #define PF_ALG AF_ALG
+#define PF_NFC AF_NFC
+#define PF_VSOCK AF_VSOCK
 #define PF_MAX AF_MAX
 
 #define SOMAXCONN 128
diff --git a/libc/include/sys/stat.h b/libc/include/sys/stat.h
index c22516f..257ded0 100644
--- a/libc/include/sys/stat.h
+++ b/libc/include/sys/stat.h
@@ -29,8 +29,8 @@
 #ifndef _SYS_STAT_H_
 #define _SYS_STAT_H_
 
+#include <bits/timespec.h>
 #include <linux/stat.h>
-#include <machine/timespec.h>
 #include <sys/cdefs.h>
 #include <sys/types.h>
 
@@ -171,7 +171,7 @@
 }
 #endif /* defined(__BIONIC_FORTIFY) */
 
-_BIONIC_NOT_BEFORE_21(extern int mkfifo(const char*, mode_t);)
+extern int mkfifo(const char*, mode_t) __INTRODUCED_IN(21);
 extern int mkfifoat(int, const char*, mode_t);
 
 extern int fchmodat(int, const char*, mode_t, int);
diff --git a/libc/include/sys/syslog.h b/libc/include/sys/syslog.h
new file mode 100644
index 0000000..7761ece
--- /dev/null
+++ b/libc/include/sys/syslog.h
@@ -0,0 +1 @@
+#include <syslog.h>
diff --git a/libc/include/sys/sysmacros.h b/libc/include/sys/sysmacros.h
index 6f053a8..54e43dd 100644
--- a/libc/include/sys/sysmacros.h
+++ b/libc/include/sys/sysmacros.h
@@ -25,28 +25,20 @@
  * OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF
  * SUCH DAMAGE.
  */
+
 #ifndef _SYS_SYSMACROS_H_
 #define _SYS_SYSMACROS_H_
 
-/* some rogue code includes this file directly :-( */
-#ifndef _SYS_TYPES_H_
-# include <sys/types.h>
-#endif
+#define makedev(__major, __minor) \
+  ( \
+    (((__major) & 0xfffff000ULL) << 32) | (((__major) & 0xfffULL) << 8) | \
+    (((__minor) & 0xffffff00ULL) << 12) | (((__minor) & 0xffULL)) \
+  )
 
-static __inline__ int major(dev_t _dev)
-{
-  return (_dev >> 8) & 0xfff;
-}
+#define major(__dev) \
+  ((unsigned) ((((unsigned long long) (__dev) >> 32) & 0xfffff000) | (((__dev) >> 8) & 0xfff)))
 
-static __inline__ int minor(dev_t _dev)
-{
-  return (_dev & 0xff) | ((_dev >> 12) & 0xfff00);
-}
-
-static __inline__ dev_t makedev(int __ma, int __mi)
-{
-  return ((__ma & 0xfff) << 8) | (__mi & 0xff) | ((__mi & 0xfff00) << 12);
-}
+#define minor(__dev) \
+  ((unsigned) ((((__dev) >> 12) & 0xffffff00) | ((__dev) & 0xff)))
 
 #endif /* _SYS_SYSMACROS_H_ */
-
diff --git a/libc/include/sys/time.h b/libc/include/sys/time.h
index 1f010d4..f60c905 100644
--- a/libc/include/sys/time.h
+++ b/libc/include/sys/time.h
@@ -25,6 +25,7 @@
  * OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF
  * SUCH DAMAGE.
  */
+
 #ifndef _SYS_TIME_H_
 #define _SYS_TIME_H_
 
@@ -32,6 +33,9 @@
 #include <sys/types.h>
 #include <linux/time.h>
 
+/* POSIX says <sys/time.h> gets you most of <sys/select.h> and may get you all of it. */
+#include <sys/select.h>
+
 __BEGIN_DECLS
 
 extern int gettimeofday(struct timeval *, struct timezone *);
@@ -73,6 +77,15 @@
         }                                             \
     } while (0)
 
+#define TIMEVAL_TO_TIMESPEC(tv, ts) {     \
+    (ts)->tv_sec = (tv)->tv_sec;          \
+    (ts)->tv_nsec = (tv)->tv_usec * 1000; \
+}
+#define TIMESPEC_TO_TIMEVAL(tv, ts) {     \
+    (tv)->tv_sec = (ts)->tv_sec;          \
+    (tv)->tv_usec = (ts)->tv_nsec / 1000; \
+}
+
 __END_DECLS
 
 #endif /* _SYS_TIME_H_ */
diff --git a/libc/include/sys/timex.h b/libc/include/sys/timex.h
index 4096e7d..fade5c3 100644
--- a/libc/include/sys/timex.h
+++ b/libc/include/sys/timex.h
@@ -29,6 +29,15 @@
 #ifndef _SYS_TIMEX_H_
 #define _SYS_TIMEX_H_
 
+#include <sys/cdefs.h>
+#include <sys/types.h>
 #include <linux/timex.h>
 
+__BEGIN_DECLS
+
+int adjtimex(struct timex*);
+int clock_adjtime(clockid_t, struct timex*);
+
+__END_DECLS
+
 #endif /* _SYS_TIMEX_H_ */
diff --git a/libc/include/sys/types.h b/libc/include/sys/types.h
index a6b0fd8..217fd60 100644
--- a/libc/include/sys/types.h
+++ b/libc/include/sys/types.h
@@ -139,19 +139,18 @@
 typedef unsigned int        uint_t;
 typedef unsigned int        uint;
 
-/* for some applications */
+#ifdef __BSD_VISIBLE
 #include <sys/sysmacros.h>
 
-#ifdef __BSD_VISIBLE
-typedef	unsigned char	u_char;
-typedef	unsigned short	u_short;
-typedef	unsigned int	u_int;
-typedef	unsigned long	u_long;
+typedef unsigned char  u_char;
+typedef unsigned short u_short;
+typedef unsigned int   u_int;
+typedef unsigned long  u_long;
 
-typedef uint32_t       u_int32_t;
-typedef uint16_t       u_int16_t;
-typedef uint8_t        u_int8_t;
-typedef uint64_t       u_int64_t;
+typedef uint32_t u_int32_t;
+typedef uint16_t u_int16_t;
+typedef uint8_t  u_int8_t;
+typedef uint64_t u_int64_t;
 #endif
 
 #endif
diff --git a/libc/include/sys/ucontext.h b/libc/include/sys/ucontext.h
index 399458e..9e3c653 100644
--- a/libc/include/sys/ucontext.h
+++ b/libc/include/sys/ucontext.h
@@ -82,12 +82,6 @@
 #define NGREG 34 /* x0..x30 + sp + pc + pstate */
 typedef unsigned long greg_t;
 typedef greg_t gregset_t[NGREG];
-
-struct user_fpsimd_struct {
-  long double vregs[32];
-  uint32_t fpsr;
-  uint32_t fpcr;
-};
 typedef struct user_fpsimd_struct fpregset_t;
 
 #include <asm/sigcontext.h>
diff --git a/libc/include/sys/uio.h b/libc/include/sys/uio.h
index 187ec22..72675d1 100644
--- a/libc/include/sys/uio.h
+++ b/libc/include/sys/uio.h
@@ -38,6 +38,18 @@
 int writev(int, const struct iovec*, int);
 
 #if defined(__USE_GNU)
+#if defined(__USE_FILE_OFFSET64)
+ssize_t preadv(int, const struct iovec*, int, off_t) __RENAME(preadv64);
+ssize_t pwritev(int, const struct iovec*, int, off_t) __RENAME(pwritev64);
+#else
+ssize_t preadv(int, const struct iovec*, int, off_t);
+ssize_t pwritev(int, const struct iovec*, int, off_t);
+#endif
+ssize_t preadv64(int, const struct iovec*, int, off64_t);
+ssize_t pwritev64(int, const struct iovec*, int, off64_t);
+#endif
+
+#if defined(__USE_GNU)
 ssize_t process_vm_readv(pid_t, const struct iovec*, unsigned long, const struct iovec*, unsigned long, unsigned long);
 ssize_t process_vm_writev(pid_t, const struct iovec*, unsigned long, const struct iovec*, unsigned long, unsigned long);
 #endif
diff --git a/libc/include/sys/unistd.h b/libc/include/sys/unistd.h
new file mode 100644
index 0000000..1e823fb
--- /dev/null
+++ b/libc/include/sys/unistd.h
@@ -0,0 +1 @@
+#include <unistd.h>
diff --git a/libc/include/sys/user.h b/libc/include/sys/user.h
index b370add..3312981 100644
--- a/libc/include/sys/user.h
+++ b/libc/include/sys/user.h
@@ -30,11 +30,13 @@
 #define _SYS_USER_H_
 
 #include <sys/cdefs.h>
-#include <limits.h> /* For PAGE_SIZE. */
 #include <stddef.h> /* For size_t. */
 
 __BEGIN_DECLS
 
+#define PAGE_SIZE 4096
+#define PAGE_MASK (~(PAGE_SIZE - 1))
+
 #if __i386__
 
 struct user_fpregs_struct {
@@ -47,7 +49,7 @@
   long fos;
   long st_space[20];
 };
-struct user_fxsr_struct {
+struct user_fpxregs_struct {
   unsigned short cwd;
   unsigned short swd;
   unsigned short twd;
@@ -230,7 +232,17 @@
 
 #elif defined(__aarch64__)
 
-// There are no user structures for 64 bit arm.
+struct user_regs_struct {
+  uint64_t regs[31];
+  uint64_t sp;
+  uint64_t pc;
+  uint64_t pstate;
+};
+struct user_fpsimd_struct {
+  __uint128_t vregs[32];
+  uint32_t fpsr;
+  uint32_t fpcr;
+};
 
 #else
 
diff --git a/libc/include/sys/vt.h b/libc/include/sys/vt.h
index b37a869..834abfb 100644
--- a/libc/include/sys/vt.h
+++ b/libc/include/sys/vt.h
@@ -1,28 +1 @@
-/*
- * 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 <linux/vt.h>
diff --git a/libc/include/sys/wait.h b/libc/include/sys/wait.h
index 12b7308..2317b02 100644
--- a/libc/include/sys/wait.h
+++ b/libc/include/sys/wait.h
@@ -44,6 +44,7 @@
 #define WIFEXITED(s)    (WTERMSIG(s) == 0)
 #define WIFSTOPPED(s)   (WTERMSIG(s) == 0x7f)
 #define WIFSIGNALED(s)  (WTERMSIG((s)+1) >= 2)
+#define WIFCONTINUED(s) ((s) == 0xffff)
 
 #define W_EXITCODE(ret, sig)    ((ret) << 8 | (sig))
 #define W_STOPCODE(sig)         ((sig) << 8 | 0x7f)
diff --git a/libc/include/syscall.h b/libc/include/syscall.h
new file mode 100644
index 0000000..4c30578
--- /dev/null
+++ b/libc/include/syscall.h
@@ -0,0 +1 @@
+#include <sys/syscall.h>
diff --git a/libc/include/sysexits.h b/libc/include/sysexits.h
new file mode 100644
index 0000000..e244836
--- /dev/null
+++ b/libc/include/sysexits.h
@@ -0,0 +1,119 @@
+/*	$OpenBSD: sysexits.h,v 1.5 2003/06/02 19:34:12 millert Exp $	*/
+/*	$NetBSD: sysexits.h,v 1.4 1994/10/26 00:56:33 cgd Exp $	*/
+
+/*
+ * Copyright (c) 1987 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.
+ *
+ *	@(#)sysexits.h	4.8 (Berkeley) 4/3/91
+ */
+
+#ifndef	_SYSEXITS_H_
+#define	_SYSEXITS_H_
+
+/*
+ *  SYSEXITS.H -- Exit status codes for system programs.
+ *
+ *	This include file attempts to categorize possible error
+ *	exit statuses for system programs, notably delivermail
+ *	and the Berkeley network.
+ *
+ *	Error numbers begin at EX__BASE to reduce the possibility of
+ *	clashing with other exit statuses that random programs may
+ *	already return.  The meaning of the codes is approximately
+ *	as follows:
+ *
+ *	EX_USAGE -- The command was used incorrectly, e.g., with
+ *		the wrong number of arguments, a bad flag, a bad
+ *		syntax in a parameter, or whatever.
+ *	EX_DATAERR -- The input data was incorrect in some way.
+ *		This should only be used for user's data & not
+ *		system files.
+ *	EX_NOINPUT -- An input file (not a system file) did not
+ *		exist or was not readable.  This could also include
+ *		errors like "No message" to a mailer (if it cared
+ *		to catch it).
+ *	EX_NOUSER -- The user specified did not exist.  This might
+ *		be used for mail addresses or remote logins.
+ *	EX_NOHOST -- The host specified did not exist.  This is used
+ *		in mail addresses or network requests.
+ *	EX_UNAVAILABLE -- A service is unavailable.  This can occur
+ *		if a support program or file does not exist.  This
+ *		can also be used as a catchall message when something
+ *		you wanted to do doesn't work, but you don't know
+ *		why.
+ *	EX_SOFTWARE -- An internal software error has been detected.
+ *		This should be limited to non-operating system related
+ *		errors as possible.
+ *	EX_OSERR -- An operating system error has been detected.
+ *		This is intended to be used for such things as "cannot
+ *		fork", "cannot create pipe", or the like.  It includes
+ *		things like getuid returning a user that does not
+ *		exist in the passwd file.
+ *	EX_OSFILE -- Some system file (e.g., /etc/passwd, /var/run/utmp,
+ *		etc.) does not exist, cannot be opened, or has some
+ *		sort of error (e.g., syntax error).
+ *	EX_CANTCREAT -- A (user specified) output file cannot be
+ *		created.
+ *	EX_IOERR -- An error occurred while doing I/O on some file.
+ *	EX_TEMPFAIL -- temporary failure, indicating something that
+ *		is not really an error.  In sendmail, this means
+ *		that a mailer (e.g.) could not create a connection,
+ *		and the request should be reattempted later.
+ *	EX_PROTOCOL -- the remote system returned something that
+ *		was "not possible" during a protocol exchange.
+ *	EX_NOPERM -- You did not have sufficient permission to
+ *		perform the operation.  This is not intended for
+ *		file system problems, which should use EX_NOINPUT or
+ *		EX_CANTCREAT, but rather for higher level permissions.
+ *	EX_CONFIG -- Something was found in an unconfigured or
+ *		misconfigured state.
+ */
+
+#define EX_OK		0	/* successful termination */
+
+#define EX__BASE	64	/* base value for error messages */
+
+#define EX_USAGE	64	/* command line usage error */
+#define EX_DATAERR	65	/* data format error */
+#define EX_NOINPUT	66	/* cannot open input */
+#define EX_NOUSER	67	/* addressee unknown */
+#define EX_NOHOST	68	/* host name unknown */
+#define EX_UNAVAILABLE	69	/* service unavailable */
+#define EX_SOFTWARE	70	/* internal software error */
+#define EX_OSERR	71	/* system error (e.g., can't fork) */
+#define EX_OSFILE	72	/* critical OS file missing */
+#define EX_CANTCREAT	73	/* can't create (user) output file */
+#define EX_IOERR	74	/* input/output error */
+#define EX_TEMPFAIL	75	/* temp failure; user is invited to retry */
+#define EX_PROTOCOL	76	/* remote error in protocol */
+#define EX_NOPERM	77	/* permission denied */
+#define EX_CONFIG	78	/* configuration error */
+
+#define EX__MAX		78	/* maximum listed value */
+
+#endif /* !_SYSEXITS_H_ */
diff --git a/libc/include/uchar.h b/libc/include/uchar.h
index e1fcb5c..a5e72ea 100644
--- a/libc/include/uchar.h
+++ b/libc/include/uchar.h
@@ -34,6 +34,11 @@
 
 __BEGIN_DECLS
 
+#if __STDC_VERSION__ >= 201112L && !defined(__cplusplus)
+typedef __CHAR16_TYPE__ char16_t;
+typedef __CHAR32_TYPE__ char32_t;
+#endif
+
 #define __STD_UTF_16__ 1
 #define __STD_UTF_32__ 1
 
diff --git a/libc/include/unistd.h b/libc/include/unistd.h
index f0de29e..5045267 100644
--- a/libc/include/unistd.h
+++ b/libc/include/unistd.h
@@ -35,7 +35,8 @@
 #include <sys/select.h>
 #include <sys/sysconf.h>
 
-#include <machine/posix_limits.h>
+#include <bits/lockf.h>
+#include <bits/posix_limits.h>
 
 __BEGIN_DECLS
 
@@ -75,146 +76,168 @@
 
 extern char** environ;
 
-extern __noreturn void _exit(int);
+extern __noreturn void _exit(int __status);
 
 extern pid_t  fork(void);
 extern pid_t  vfork(void);
 extern pid_t  getpid(void);
 extern pid_t  gettid(void) __pure2;
-extern pid_t  getpgid(pid_t);
-extern int    setpgid(pid_t, pid_t);
+extern pid_t  getpgid(pid_t __pid);
+extern int    setpgid(pid_t __pid, pid_t __pgid);
 extern pid_t  getppid(void);
 extern pid_t  getpgrp(void);
 extern int    setpgrp(void);
-extern pid_t  getsid(pid_t);
+extern pid_t  getsid(pid_t __pid) __INTRODUCED_IN(21);
 extern pid_t  setsid(void);
 
-extern int execv(const char *, char * const *);
-extern int execvp(const char *, char * const *);
-extern int execvpe(const char *, char * const *, char * const *);
-extern int execve(const char *, char * const *, char * const *);
-extern int execl(const char *, const char *, ...);
-extern int execlp(const char *, const char *, ...);
-extern int execle(const char *, const char *, ...);
+extern int execv(const char* __path, char* const* __argv);
+extern int execvp(const char* __file, char* const* __argv);
+extern int execvpe(const char* __file, char* const* __argv, char* const* __envp)
+  __INTRODUCED_IN(21);
+extern int execve(const char* __file, char* const* __argv, char* const* __envp);
+extern int execl(const char* __path, const char* __arg0, ...);
+extern int execlp(const char* __file, const char* __arg0, ...);
+extern int execle(const char* __path, const char* __arg0, ...);
 
-extern int nice(int);
+extern int nice(int __incr);
 
-extern int setuid(uid_t);
+extern int setuid(uid_t __uid);
 extern uid_t getuid(void);
-extern int seteuid(uid_t);
+extern int seteuid(uid_t __uid);
 extern uid_t geteuid(void);
-extern int setgid(gid_t);
+extern int setgid(gid_t __gid);
 extern gid_t getgid(void);
-extern int setegid(gid_t);
+extern int setegid(gid_t __gid);
 extern gid_t getegid(void);
-extern int getgroups(int, gid_t *);
-extern int setgroups(size_t, const gid_t *);
-extern int setreuid(uid_t, uid_t);
-extern int setregid(gid_t, gid_t);
-extern int setresuid(uid_t, uid_t, uid_t);
-extern int setresgid(gid_t, gid_t, gid_t);
-extern int getresuid(uid_t *ruid, uid_t *euid, uid_t *suid);
-extern int getresgid(gid_t *rgid, gid_t *egid, gid_t *sgid);
+extern int getgroups(int __size, gid_t* __list);
+extern int setgroups(size_t __size, const gid_t* __list);
+extern int setreuid(uid_t __ruid, uid_t __euid);
+extern int setregid(gid_t __rgid, gid_t __egid);
+extern int setresuid(uid_t __ruid, uid_t __euid, uid_t __suid);
+extern int setresgid(gid_t __rgid, gid_t __egid, gid_t __sgid);
+extern int getresuid(uid_t* __ruid, uid_t* __euid, uid_t* __suid);
+extern int getresgid(gid_t* __rgid, gid_t* __egid, gid_t* __sgid);
 extern char* getlogin(void);
 
-extern long fpathconf(int, int);
-extern long pathconf(const char*, int);
+extern long fpathconf(int __fd, int __name);
+extern long pathconf(const char* __path, int __name);
 
-extern int access(const char*, int);
-extern int faccessat(int, const char*, int, int);
-extern int link(const char*, const char*);
-extern int linkat(int, const char*, int, const char*, int);
-extern int unlink(const char*);
-extern int unlinkat(int, const char*, int);
-extern int chdir(const char *);
-extern int fchdir(int);
-extern int rmdir(const char *);
-extern int pipe(int *);
+extern int access(const char* __path, int __mode);
+extern int faccessat(int __dirfd, const char* __path, int __mode, int __flags)
+  __INTRODUCED_IN(21);
+extern int link(const char* __oldpath, const char* __newpath);
+extern int linkat(int __olddirfd, const char* __oldpath, int __newdirfd,
+                  const char* __newpath, int __flags) __INTRODUCED_IN(21);
+extern int unlink(const char* __path);
+extern int unlinkat(int __dirfd, const char* __path, int __flags);
+extern int chdir(const char* __path);
+extern int fchdir(int __fd);
+extern int rmdir(const char* __path);
+extern int pipe(int* __pipefd);
 #if defined(__USE_GNU)
-extern int pipe2(int *, int);
+extern int pipe2(int* __pipefd, int __flags) __INTRODUCED_IN(9);
 #endif
-extern int chroot(const char *);
-extern int symlink(const char*, const char*);
-extern int symlinkat(const char*, int, const char*);
-extern ssize_t readlink(const char*, char*, size_t);
-extern ssize_t readlinkat(int, const char*, char*, size_t);
-extern int chown(const char *, uid_t, gid_t);
-extern int fchown(int, uid_t, gid_t);
-extern int fchownat(int, const char*, uid_t, gid_t, int);
-extern int lchown(const char *, uid_t, gid_t);
-extern char *getcwd(char *, size_t);
+extern int chroot(const char* __path);
+extern int symlink(const char* __oldpath, const char* __newpath);
+extern int symlinkat(const char* __oldpath, int __newdirfd,
+                     const char* __newpath) __INTRODUCED_IN(21);
+extern ssize_t readlink(const char* __path, char* __buf, size_t __bufsiz);
+extern ssize_t readlinkat(int __dirfd, const char* __path, char* __buf,
+                          size_t __bufsiz) __INTRODUCED_IN(21);
+extern int chown(const char* __path, uid_t __owner, gid_t __group);
+extern int fchown(int __fd, uid_t __owner, gid_t __group);
+extern int fchownat(int __dirfd, const char* __path, uid_t __owner,
+                    gid_t __group, int __flags);
+extern int lchown(const char* __path, uid_t __owner, gid_t __group);
+extern char* getcwd(char* __buf, size_t __size);
 
 extern int sync(void);
 
-extern int close(int);
+extern int close(int __fd);
 
-extern ssize_t read(int, void *, size_t);
-extern ssize_t write(int, const void *, size_t);
+extern ssize_t read(int __fd, void* __buf, size_t __count);
+extern ssize_t write(int __fd, const void* __buf, size_t __count);
 
-extern int dup(int);
-extern int dup2(int, int);
-extern int dup3(int, int, int);
-extern int fcntl(int, int, ...);
-extern int ioctl(int, int, ...);
-extern int fsync(int);
-extern int fdatasync(int);
+extern int dup(int __oldfd);
+extern int dup2(int __oldfd, int __newfd);
+extern int dup3(int __oldfd, int __newfd, int __flags) __INTRODUCED_IN(21);
+extern int fcntl(int __fd, int __cmd, ...);
+extern int ioctl(int __fd, int __request, ...);
+extern int fsync(int __fd);
+extern int fdatasync(int __fd) __INTRODUCED_IN(9);
 
 #if defined(__USE_FILE_OFFSET64)
-extern int truncate(const char *, off_t) __RENAME(truncate64);
-extern off_t lseek(int, off_t, int) __RENAME(lseek64);
-extern ssize_t pread(int, void *, size_t, off_t) __RENAME(pread64);
-extern ssize_t pwrite(int, const void *, size_t, off_t) __RENAME(pwrite64);
-extern int ftruncate(int, off_t) __RENAME(ftruncate64);
+extern off_t lseek(int __fd, off_t __offset, int __whence) __RENAME(lseek64);
 #else
-extern int truncate(const char *, off_t);
-extern off_t lseek(int, off_t, int);
-extern ssize_t pread(int, void *, size_t, off_t);
-extern ssize_t pwrite(int, const void *, size_t, off_t);
-extern int ftruncate(int, off_t);
+extern off_t lseek(int __fd, off_t __offset, int __whence);
 #endif
-extern int truncate64(const char *, off64_t);
-extern off64_t lseek64(int, off64_t, int);
-extern ssize_t pread64(int, void *, size_t, off64_t);
-extern ssize_t pwrite64(int, const void *, size_t, off64_t);
-extern int ftruncate64(int, off64_t);
+
+extern off64_t lseek64(int __fd, off64_t __offset, int __whence);
+
+#if defined(__USE_FILE_OFFSET64) && __ANDROID_API__ >= 21
+extern int truncate(const char* __path, off_t __length) __RENAME(truncate64);
+extern ssize_t pread(int __fd, void* __buf, size_t __count, off_t __offset)
+  __RENAME(pread64);
+extern ssize_t pwrite(int __fd, const void* __buf, size_t __count,
+                      off_t __offset) __RENAME(pwrite64);
+extern int ftruncate(int __fd, off_t __length) __RENAME(ftruncate64);
+#else
+extern int truncate(const char* __path, off_t __length);
+extern ssize_t pread(int __fd, void* __buf, size_t __count, off_t __offset);
+extern ssize_t pwrite(int __fd, const void* __buf, size_t __count,
+                      off_t __offset);
+extern int ftruncate(int __fd, off_t __length);
+#endif
+
+extern int truncate64(const char* __path, off64_t __length) __INTRODUCED_IN(21);
+extern ssize_t pread64(int __fd, void* __buf, size_t __count, off64_t __offset) __INTRODUCED_IN(21);
+extern ssize_t pwrite64(int __fd, const void* __buf, size_t __count,
+                        off64_t __offset) __INTRODUCED_IN(21);
+extern int ftruncate64(int __fd, off64_t __length) __INTRODUCED_IN(21);
 
 extern int pause(void);
-extern unsigned int alarm(unsigned int);
-extern unsigned int sleep(unsigned int);
-extern int usleep(useconds_t);
+extern unsigned int alarm(unsigned int __seconds);
+extern unsigned int sleep(unsigned int __seconds);
+extern int usleep(useconds_t __usec);
 
-int gethostname(char*, size_t);
-int sethostname(const char*, size_t);
+int gethostname(char* __name, size_t __len);
+int sethostname(const char* __name, size_t __len);
 
-extern void *__brk(void *);
-extern int brk(void *);
-extern void *sbrk(ptrdiff_t);
+extern void* __brk(void* __addr);
+extern int brk(void* __addr);
+extern void* sbrk(ptrdiff_t __increment);
 
-extern int getopt(int, char * const *, const char *);
-extern char *optarg;
+extern int getopt(int __argc, char* const* __argv, const char* __argstring);
+extern char* optarg;
 extern int optind, opterr, optopt;
 
-extern int isatty(int);
-extern char* ttyname(int);
-extern int ttyname_r(int, char*, size_t);
+extern int isatty(int __fd);
+extern char* ttyname(int __fd);
+extern int ttyname_r(int __fd, char* __buf, size_t __buflen) __INTRODUCED_IN(8);
 
-extern int  acct(const char*  filepath);
+extern int acct(const char* __filepath);
 
+long sysconf(int __name);
+
+#if __ANDROID_API__ >= 21
 int getpagesize(void);
+#else
+__inline__ int getpagesize(void) {
+  return sysconf(_SC_PAGESIZE);
+}
+#endif
 
-long sysconf(int);
+long syscall(long __number, ...);
 
-long syscall(long number, ...);
-
-extern int daemon(int, int);
+extern int daemon(int __nochdir, int __noclose);
 
 #if defined(__arm__) || (defined(__mips__) && !defined(__LP64__))
-extern int cacheflush(long, long, long);
+extern int cacheflush(long __addr, long __nbytes, long __cache);
     /* __attribute__((deprecated("use __builtin___clear_cache instead"))); */
 #endif
 
-extern pid_t tcgetpgrp(int fd);
-extern int   tcsetpgrp(int fd, pid_t _pid);
+extern pid_t tcgetpgrp(int __fd);
+extern int tcsetpgrp(int __fd, pid_t __pid);
 
 /* Used to retry syscalls that can return EINTR. */
 #define TEMP_FAILURE_RETRY(exp) ({         \
@@ -224,6 +247,11 @@
     } while (_rc == -1 && errno == EINTR); \
     _rc; })
 
+/* TODO(unified-headers): Factor out all the FORTIFY features. */
+extern char* __getcwd_chk(char*, size_t, size_t);
+__errordecl(__getcwd_dest_size_error, "getcwd called with size bigger than destination");
+extern char* __getcwd_real(char*, size_t) __RENAME(getcwd);
+
 extern ssize_t __pread_chk(int, void*, size_t, off_t, size_t);
 __errordecl(__pread_dest_size_error, "pread called with size bigger than destination");
 __errordecl(__pread_count_toobig_error, "pread called with count > SSIZE_MAX");
@@ -234,11 +262,26 @@
 __errordecl(__pread64_count_toobig_error, "pread64 called with count > SSIZE_MAX");
 extern ssize_t __pread64_real(int, void*, size_t, off64_t) __RENAME(pread64);
 
+extern ssize_t __pwrite_chk(int, const void*, size_t, off_t, size_t);
+__errordecl(__pwrite_dest_size_error, "pwrite called with size bigger than destination");
+__errordecl(__pwrite_count_toobig_error, "pwrite called with count > SSIZE_MAX");
+extern ssize_t __pwrite_real(int, const void*, size_t, off_t) __RENAME(pwrite);
+
+extern ssize_t __pwrite64_chk(int, const void*, size_t, off64_t, size_t);
+__errordecl(__pwrite64_dest_size_error, "pwrite64 called with size bigger than destination");
+__errordecl(__pwrite64_count_toobig_error, "pwrite64 called with count > SSIZE_MAX");
+extern ssize_t __pwrite64_real(int, const void*, size_t, off64_t) __RENAME(pwrite64);
+
 extern ssize_t __read_chk(int, void*, size_t, size_t);
 __errordecl(__read_dest_size_error, "read called with size bigger than destination");
 __errordecl(__read_count_toobig_error, "read called with count > SSIZE_MAX");
 extern ssize_t __read_real(int, void*, size_t) __RENAME(read);
 
+extern ssize_t __write_chk(int, const void*, size_t, size_t);
+__errordecl(__write_dest_size_error, "write called with size bigger than destination");
+__errordecl(__write_count_toobig_error, "write called with count > SSIZE_MAX");
+extern ssize_t __write_real(int, const void*, size_t) __RENAME(write);
+
 extern ssize_t __readlink_chk(const char*, char*, size_t, size_t);
 __errordecl(__readlink_dest_size_error, "readlink called with size bigger than destination");
 __errordecl(__readlink_size_toobig_error, "readlink called with size > SSIZE_MAX");
@@ -251,6 +294,37 @@
 
 #if defined(__BIONIC_FORTIFY)
 
+__BIONIC_FORTIFY_INLINE
+char* getcwd(char* buf, size_t size) {
+    size_t bos = __bos(buf);
+
+#if defined(__clang__)
+    /*
+     * Work around LLVM's incorrect __builtin_object_size implementation here
+     * to avoid needing the workaround in the __getcwd_chk ABI forever.
+     *
+     * https://llvm.org/bugs/show_bug.cgi?id=23277
+     */
+    if (buf == NULL) {
+        bos = __BIONIC_FORTIFY_UNKNOWN_SIZE;
+    }
+#else
+    if (bos == __BIONIC_FORTIFY_UNKNOWN_SIZE) {
+        return __getcwd_real(buf, size);
+    }
+
+    if (__builtin_constant_p(size) && (size > bos)) {
+        __getcwd_dest_size_error();
+    }
+
+    if (__builtin_constant_p(size) && (size <= bos)) {
+        return __getcwd_real(buf, size);
+    }
+#endif
+
+    return __getcwd_chk(buf, size, bos);
+}
+
 #if defined(__USE_FILE_OFFSET64)
 #define __PREAD_PREFIX(x) __pread64_ ## x
 #else
@@ -307,6 +381,62 @@
     return __pread64_chk(fd, buf, count, offset, bos);
 }
 
+#if defined(__USE_FILE_OFFSET64)
+#define __PWRITE_PREFIX(x) __pwrite64_ ## x
+#else
+#define __PWRITE_PREFIX(x) __pwrite_ ## x
+#endif
+
+__BIONIC_FORTIFY_INLINE
+ssize_t pwrite(int fd, const void* buf, size_t count, off_t offset) {
+    size_t bos = __bos0(buf);
+
+#if !defined(__clang__)
+    if (__builtin_constant_p(count) && (count > SSIZE_MAX)) {
+        __PWRITE_PREFIX(count_toobig_error)();
+    }
+
+    if (bos == __BIONIC_FORTIFY_UNKNOWN_SIZE) {
+        return __PWRITE_PREFIX(real)(fd, buf, count, offset);
+    }
+
+    if (__builtin_constant_p(count) && (count > bos)) {
+        __PWRITE_PREFIX(dest_size_error)();
+    }
+
+    if (__builtin_constant_p(count) && (count <= bos)) {
+        return __PWRITE_PREFIX(real)(fd, buf, count, offset);
+    }
+#endif
+
+    return __PWRITE_PREFIX(chk)(fd, buf, count, offset, bos);
+}
+
+__BIONIC_FORTIFY_INLINE
+ssize_t pwrite64(int fd, const void* buf, size_t count, off64_t offset) {
+    size_t bos = __bos0(buf);
+
+#if !defined(__clang__)
+    if (__builtin_constant_p(count) && (count > SSIZE_MAX)) {
+        __pwrite64_count_toobig_error();
+    }
+
+    if (bos == __BIONIC_FORTIFY_UNKNOWN_SIZE) {
+        return __pwrite64_real(fd, buf, count, offset);
+    }
+
+    if (__builtin_constant_p(count) && (count > bos)) {
+        __pwrite64_dest_size_error();
+    }
+
+    if (__builtin_constant_p(count) && (count <= bos)) {
+        return __pwrite64_real(fd, buf, count, offset);
+    }
+#endif
+
+    return __pwrite64_chk(fd, buf, count, offset, bos);
+}
+
 __BIONIC_FORTIFY_INLINE
 ssize_t read(int fd, void* buf, size_t count) {
     size_t bos = __bos0(buf);
@@ -333,6 +463,33 @@
 }
 
 __BIONIC_FORTIFY_INLINE
+ssize_t write(int fd, const void* buf, size_t count) {
+    size_t bos = __bos0(buf);
+
+#if !defined(__clang__)
+#if 0 /* work around a false positive due to a missed optimization */
+    if (__builtin_constant_p(count) && (count > SSIZE_MAX)) {
+        __write_count_toobig_error();
+    }
+#endif
+
+    if (bos == __BIONIC_FORTIFY_UNKNOWN_SIZE) {
+        return __write_real(fd, buf, count);
+    }
+
+    if (__builtin_constant_p(count) && (count > bos)) {
+        __write_dest_size_error();
+    }
+
+    if (__builtin_constant_p(count) && (count <= bos)) {
+        return __write_real(fd, buf, count);
+    }
+#endif
+
+    return __write_chk(fd, buf, count, bos);
+}
+
+__BIONIC_FORTIFY_INLINE
 ssize_t readlink(const char* path, char* buf, size_t size) {
     size_t bos = __bos(buf);
 
diff --git a/libc/include/utmp.h b/libc/include/utmp.h
index ebf2372..c6f22a5 100644
--- a/libc/include/utmp.h
+++ b/libc/include/utmp.h
@@ -46,7 +46,16 @@
 #define UT_HOSTSIZE 16
 #endif
 
-#define USER_PROCESS 7
+#define EMPTY         0
+#define RUN_LVL       1
+#define BOOT_TIME     2
+#define NEW_TIME      3
+#define OLD_TIME      4
+#define INIT_PROCESS  5
+#define LOGIN_PROCESS 6
+#define USER_PROCESS  7
+#define DEAD_PROCESS  8
+#define ACCOUNTING    9
 
 struct lastlog
 {
@@ -88,8 +97,9 @@
 __BEGIN_DECLS
 
 int utmpname(const char*);
-void setutent();
-struct utmp* getutent();
+void setutent(void);
+struct utmp* getutent(void);
+void endutent(void);
 
 int login_tty(int);
 
diff --git a/libc/include/wait.h b/libc/include/wait.h
new file mode 100644
index 0000000..d01b811
--- /dev/null
+++ b/libc/include/wait.h
@@ -0,0 +1 @@
+#include <sys/wait.h>
diff --git a/libc/include/wchar.h b/libc/include/wchar.h
index ea6aca0..0a94cee 100644
--- a/libc/include/wchar.h
+++ b/libc/include/wchar.h
@@ -36,7 +36,7 @@
 #include <time.h>
 #include <xlocale.h>
 
-#include <machine/wchar_limits.h>
+#include <bits/wchar_limits.h>
 
 __BEGIN_DECLS
 
diff --git a/libc/kernel/common/scsi/scsi.h b/libc/kernel/common/scsi/scsi.h
new file mode 100644
index 0000000..9e5edd7
--- /dev/null
+++ b/libc/kernel/common/scsi/scsi.h
@@ -0,0 +1,261 @@
+/****************************************************************************
+ ****************************************************************************
+ ***
+ ***   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 _SCSI_SCSI_H
+#define _SCSI_SCSI_H
+#include <linux/types.h>
+#define TEST_UNIT_READY 0x00
+/* WARNING: DO NOT EDIT, AUTO-GENERATED CODE - SEE TOP FOR INSTRUCTIONS */
+#define REZERO_UNIT 0x01
+#define REQUEST_SENSE 0x03
+#define FORMAT_UNIT 0x04
+#define READ_BLOCK_LIMITS 0x05
+/* WARNING: DO NOT EDIT, AUTO-GENERATED CODE - SEE TOP FOR INSTRUCTIONS */
+#define REASSIGN_BLOCKS 0x07
+#define INITIALIZE_ELEMENT_STATUS 0x07
+#define READ_6 0x08
+#define WRITE_6 0x0a
+/* WARNING: DO NOT EDIT, AUTO-GENERATED CODE - SEE TOP FOR INSTRUCTIONS */
+#define SEEK_6 0x0b
+#define READ_REVERSE 0x0f
+#define WRITE_FILEMARKS 0x10
+#define SPACE 0x11
+/* WARNING: DO NOT EDIT, AUTO-GENERATED CODE - SEE TOP FOR INSTRUCTIONS */
+#define INQUIRY 0x12
+#define RECOVER_BUFFERED_DATA 0x14
+#define MODE_SELECT 0x15
+#define RESERVE 0x16
+/* WARNING: DO NOT EDIT, AUTO-GENERATED CODE - SEE TOP FOR INSTRUCTIONS */
+#define RELEASE 0x17
+#define COPY 0x18
+#define ERASE 0x19
+#define MODE_SENSE 0x1a
+/* WARNING: DO NOT EDIT, AUTO-GENERATED CODE - SEE TOP FOR INSTRUCTIONS */
+#define START_STOP 0x1b
+#define RECEIVE_DIAGNOSTIC 0x1c
+#define SEND_DIAGNOSTIC 0x1d
+#define ALLOW_MEDIUM_REMOVAL 0x1e
+/* WARNING: DO NOT EDIT, AUTO-GENERATED CODE - SEE TOP FOR INSTRUCTIONS */
+#define READ_FORMAT_CAPACITIES 0x23
+#define SET_WINDOW 0x24
+#define READ_CAPACITY 0x25
+#define READ_10 0x28
+/* WARNING: DO NOT EDIT, AUTO-GENERATED CODE - SEE TOP FOR INSTRUCTIONS */
+#define WRITE_10 0x2a
+#define SEEK_10 0x2b
+#define POSITION_TO_ELEMENT 0x2b
+#define WRITE_VERIFY 0x2e
+/* WARNING: DO NOT EDIT, AUTO-GENERATED CODE - SEE TOP FOR INSTRUCTIONS */
+#define VERIFY 0x2f
+#define SEARCH_HIGH 0x30
+#define SEARCH_EQUAL 0x31
+#define SEARCH_LOW 0x32
+/* WARNING: DO NOT EDIT, AUTO-GENERATED CODE - SEE TOP FOR INSTRUCTIONS */
+#define SET_LIMITS 0x33
+#define PRE_FETCH 0x34
+#define READ_POSITION 0x34
+#define SYNCHRONIZE_CACHE 0x35
+/* WARNING: DO NOT EDIT, AUTO-GENERATED CODE - SEE TOP FOR INSTRUCTIONS */
+#define LOCK_UNLOCK_CACHE 0x36
+#define READ_DEFECT_DATA 0x37
+#define MEDIUM_SCAN 0x38
+#define COMPARE 0x39
+/* WARNING: DO NOT EDIT, AUTO-GENERATED CODE - SEE TOP FOR INSTRUCTIONS */
+#define COPY_VERIFY 0x3a
+#define WRITE_BUFFER 0x3b
+#define READ_BUFFER 0x3c
+#define UPDATE_BLOCK 0x3d
+/* WARNING: DO NOT EDIT, AUTO-GENERATED CODE - SEE TOP FOR INSTRUCTIONS */
+#define READ_LONG 0x3e
+#define WRITE_LONG 0x3f
+#define CHANGE_DEFINITION 0x40
+#define WRITE_SAME 0x41
+/* WARNING: DO NOT EDIT, AUTO-GENERATED CODE - SEE TOP FOR INSTRUCTIONS */
+#define UNMAP 0x42
+#define READ_TOC 0x43
+#define READ_HEADER 0x44
+#define GET_EVENT_STATUS_NOTIFICATION 0x4a
+/* WARNING: DO NOT EDIT, AUTO-GENERATED CODE - SEE TOP FOR INSTRUCTIONS */
+#define LOG_SELECT 0x4c
+#define LOG_SENSE 0x4d
+#define XDWRITEREAD_10 0x53
+#define MODE_SELECT_10 0x55
+/* WARNING: DO NOT EDIT, AUTO-GENERATED CODE - SEE TOP FOR INSTRUCTIONS */
+#define RESERVE_10 0x56
+#define RELEASE_10 0x57
+#define MODE_SENSE_10 0x5a
+#define PERSISTENT_RESERVE_IN 0x5e
+/* WARNING: DO NOT EDIT, AUTO-GENERATED CODE - SEE TOP FOR INSTRUCTIONS */
+#define PERSISTENT_RESERVE_OUT 0x5f
+#define VARIABLE_LENGTH_CMD 0x7f
+#define REPORT_LUNS 0xa0
+#define SECURITY_PROTOCOL_IN 0xa2
+/* WARNING: DO NOT EDIT, AUTO-GENERATED CODE - SEE TOP FOR INSTRUCTIONS */
+#define MAINTENANCE_IN 0xa3
+#define MAINTENANCE_OUT 0xa4
+#define MOVE_MEDIUM 0xa5
+#define EXCHANGE_MEDIUM 0xa6
+/* WARNING: DO NOT EDIT, AUTO-GENERATED CODE - SEE TOP FOR INSTRUCTIONS */
+#define READ_12 0xa8
+#define WRITE_12 0xaa
+#define READ_MEDIA_SERIAL_NUMBER 0xab
+#define WRITE_VERIFY_12 0xae
+/* WARNING: DO NOT EDIT, AUTO-GENERATED CODE - SEE TOP FOR INSTRUCTIONS */
+#define VERIFY_12 0xaf
+#define SEARCH_HIGH_12 0xb0
+#define SEARCH_EQUAL_12 0xb1
+#define SEARCH_LOW_12 0xb2
+/* WARNING: DO NOT EDIT, AUTO-GENERATED CODE - SEE TOP FOR INSTRUCTIONS */
+#define SECURITY_PROTOCOL_OUT 0xb5
+#define READ_ELEMENT_STATUS 0xb8
+#define SEND_VOLUME_TAG 0xb6
+#define WRITE_LONG_2 0xea
+/* WARNING: DO NOT EDIT, AUTO-GENERATED CODE - SEE TOP FOR INSTRUCTIONS */
+#define EXTENDED_COPY 0x83
+#define RECEIVE_COPY_RESULTS 0x84
+#define ACCESS_CONTROL_IN 0x86
+#define ACCESS_CONTROL_OUT 0x87
+/* WARNING: DO NOT EDIT, AUTO-GENERATED CODE - SEE TOP FOR INSTRUCTIONS */
+#define READ_16 0x88
+#define COMPARE_AND_WRITE 0x89
+#define WRITE_16 0x8a
+#define READ_ATTRIBUTE 0x8c
+/* WARNING: DO NOT EDIT, AUTO-GENERATED CODE - SEE TOP FOR INSTRUCTIONS */
+#define WRITE_ATTRIBUTE 0x8d
+#define VERIFY_16 0x8f
+#define SYNCHRONIZE_CACHE_16 0x91
+#define WRITE_SAME_16 0x93
+/* WARNING: DO NOT EDIT, AUTO-GENERATED CODE - SEE TOP FOR INSTRUCTIONS */
+#define SERVICE_ACTION_IN 0x9e
+#define GOOD 0x00
+#define CHECK_CONDITION 0x01
+#define CONDITION_GOOD 0x02
+/* WARNING: DO NOT EDIT, AUTO-GENERATED CODE - SEE TOP FOR INSTRUCTIONS */
+#define BUSY 0x04
+#define INTERMEDIATE_GOOD 0x08
+#define INTERMEDIATE_C_GOOD 0x0a
+#define RESERVATION_CONFLICT 0x0c
+/* WARNING: DO NOT EDIT, AUTO-GENERATED CODE - SEE TOP FOR INSTRUCTIONS */
+#define COMMAND_TERMINATED 0x11
+#define QUEUE_FULL 0x14
+#define ACA_ACTIVE 0x18
+#define TASK_ABORTED 0x20
+/* WARNING: DO NOT EDIT, AUTO-GENERATED CODE - SEE TOP FOR INSTRUCTIONS */
+#define STATUS_MASK 0xfe
+#define NO_SENSE 0x00
+#define RECOVERED_ERROR 0x01
+#define NOT_READY 0x02
+/* WARNING: DO NOT EDIT, AUTO-GENERATED CODE - SEE TOP FOR INSTRUCTIONS */
+#define MEDIUM_ERROR 0x03
+#define HARDWARE_ERROR 0x04
+#define ILLEGAL_REQUEST 0x05
+#define UNIT_ATTENTION 0x06
+/* WARNING: DO NOT EDIT, AUTO-GENERATED CODE - SEE TOP FOR INSTRUCTIONS */
+#define DATA_PROTECT 0x07
+#define BLANK_CHECK 0x08
+#define COPY_ABORTED 0x0a
+#define ABORTED_COMMAND 0x0b
+/* WARNING: DO NOT EDIT, AUTO-GENERATED CODE - SEE TOP FOR INSTRUCTIONS */
+#define VOLUME_OVERFLOW 0x0d
+#define MISCOMPARE 0x0e
+#define TYPE_DISK 0x00
+#define TYPE_TAPE 0x01
+/* WARNING: DO NOT EDIT, AUTO-GENERATED CODE - SEE TOP FOR INSTRUCTIONS */
+#define TYPE_PRINTER 0x02
+#define TYPE_PROCESSOR 0x03
+#define TYPE_WORM 0x04
+#define TYPE_ROM 0x05
+/* WARNING: DO NOT EDIT, AUTO-GENERATED CODE - SEE TOP FOR INSTRUCTIONS */
+#define TYPE_SCANNER 0x06
+#define TYPE_MOD 0x07
+#define TYPE_MEDIUM_CHANGER 0x08
+#define TYPE_COMM 0x09
+/* WARNING: DO NOT EDIT, AUTO-GENERATED CODE - SEE TOP FOR INSTRUCTIONS */
+#define TYPE_RAID 0x0c
+#define TYPE_ENCLOSURE 0x0d
+#define TYPE_RBC 0x0e
+#define TYPE_OSD 0x11
+/* WARNING: DO NOT EDIT, AUTO-GENERATED CODE - SEE TOP FOR INSTRUCTIONS */
+#define TYPE_ZBC 0x14
+#define TYPE_WLUN 0x1e
+#define TYPE_NO_LUN 0x7f
+struct ccs_modesel_head {
+/* WARNING: DO NOT EDIT, AUTO-GENERATED CODE - SEE TOP FOR INSTRUCTIONS */
+  __u8 _r1;
+  __u8 medium;
+  __u8 _r2;
+  __u8 block_desc_length;
+/* WARNING: DO NOT EDIT, AUTO-GENERATED CODE - SEE TOP FOR INSTRUCTIONS */
+  __u8 density;
+  __u8 number_blocks_hi;
+  __u8 number_blocks_med;
+  __u8 number_blocks_lo;
+/* WARNING: DO NOT EDIT, AUTO-GENERATED CODE - SEE TOP FOR INSTRUCTIONS */
+  __u8 _r3;
+  __u8 block_length_hi;
+  __u8 block_length_med;
+  __u8 block_length_lo;
+/* WARNING: DO NOT EDIT, AUTO-GENERATED CODE - SEE TOP FOR INSTRUCTIONS */
+};
+#define COMMAND_COMPLETE 0x00
+#define EXTENDED_MESSAGE 0x01
+#define EXTENDED_MODIFY_DATA_POINTER 0x00
+/* WARNING: DO NOT EDIT, AUTO-GENERATED CODE - SEE TOP FOR INSTRUCTIONS */
+#define EXTENDED_SDTR 0x01
+#define EXTENDED_EXTENDED_IDENTIFY 0x02
+#define EXTENDED_WDTR 0x03
+#define EXTENDED_PPR 0x04
+/* WARNING: DO NOT EDIT, AUTO-GENERATED CODE - SEE TOP FOR INSTRUCTIONS */
+#define EXTENDED_MODIFY_BIDI_DATA_PTR 0x05
+#define SAVE_POINTERS 0x02
+#define RESTORE_POINTERS 0x03
+#define DISCONNECT 0x04
+/* WARNING: DO NOT EDIT, AUTO-GENERATED CODE - SEE TOP FOR INSTRUCTIONS */
+#define INITIATOR_ERROR 0x05
+#define ABORT_TASK_SET 0x06
+#define MESSAGE_REJECT 0x07
+#define NOP 0x08
+/* WARNING: DO NOT EDIT, AUTO-GENERATED CODE - SEE TOP FOR INSTRUCTIONS */
+#define MSG_PARITY_ERROR 0x09
+#define LINKED_CMD_COMPLETE 0x0a
+#define LINKED_FLG_CMD_COMPLETE 0x0b
+#define TARGET_RESET 0x0c
+/* WARNING: DO NOT EDIT, AUTO-GENERATED CODE - SEE TOP FOR INSTRUCTIONS */
+#define ABORT_TASK 0x0d
+#define CLEAR_TASK_SET 0x0e
+#define INITIATE_RECOVERY 0x0f
+#define RELEASE_RECOVERY 0x10
+/* WARNING: DO NOT EDIT, AUTO-GENERATED CODE - SEE TOP FOR INSTRUCTIONS */
+#define CLEAR_ACA 0x16
+#define LOGICAL_UNIT_RESET 0x17
+#define SIMPLE_QUEUE_TAG 0x20
+#define HEAD_OF_QUEUE_TAG 0x21
+/* WARNING: DO NOT EDIT, AUTO-GENERATED CODE - SEE TOP FOR INSTRUCTIONS */
+#define ORDERED_QUEUE_TAG 0x22
+#define IGNORE_WIDE_RESIDUE 0x23
+#define ACA 0x24
+#define QAS_REQUEST 0x55
+/* WARNING: DO NOT EDIT, AUTO-GENERATED CODE - SEE TOP FOR INSTRUCTIONS */
+#define BUS_DEVICE_RESET TARGET_RESET
+#define ABORT ABORT_TASK_SET
+#define SCSI_IOCTL_GET_IDLUN 0x5382
+#define SCSI_IOCTL_PROBE_HOST 0x5385
+/* WARNING: DO NOT EDIT, AUTO-GENERATED CODE - SEE TOP FOR INSTRUCTIONS */
+#define SCSI_IOCTL_GET_BUS_NUMBER 0x5386
+#define SCSI_IOCTL_GET_PCI 0x5387
+#endif
diff --git a/libc/kernel/common/scsi/scsi_ioctl.h b/libc/kernel/common/scsi/scsi_ioctl.h
new file mode 100644
index 0000000..c2f64a7
--- /dev/null
+++ b/libc/kernel/common/scsi/scsi_ioctl.h
@@ -0,0 +1,34 @@
+/****************************************************************************
+ ****************************************************************************
+ ***
+ ***   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 _SCSI_IOCTL_H
+#define _SCSI_IOCTL_H
+#define SCSI_IOCTL_SEND_COMMAND 1
+#define SCSI_IOCTL_TEST_UNIT_READY 2
+/* WARNING: DO NOT EDIT, AUTO-GENERATED CODE - SEE TOP FOR INSTRUCTIONS */
+#define SCSI_IOCTL_BENCHMARK_COMMAND 3
+#define SCSI_IOCTL_SYNC 4
+#define SCSI_IOCTL_START_UNIT 5
+#define SCSI_IOCTL_STOP_UNIT 6
+/* WARNING: DO NOT EDIT, AUTO-GENERATED CODE - SEE TOP FOR INSTRUCTIONS */
+#define SCSI_IOCTL_DOORLOCK 0x5380
+#define SCSI_IOCTL_DOORUNLOCK 0x5381
+#define SCSI_REMOVAL_PREVENT 1
+#define SCSI_REMOVAL_ALLOW 0
+/* WARNING: DO NOT EDIT, AUTO-GENERATED CODE - SEE TOP FOR INSTRUCTIONS */
+#endif
diff --git a/libc/kernel/common/scsi/sg.h b/libc/kernel/common/scsi/sg.h
new file mode 100644
index 0000000..a38eccb
--- /dev/null
+++ b/libc/kernel/common/scsi/sg.h
@@ -0,0 +1,179 @@
+/****************************************************************************
+ ****************************************************************************
+ ***
+ ***   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 _SCSI_GENERIC_H
+#define _SCSI_GENERIC_H
+#include <linux/compiler.h>
+typedef struct sg_iovec {
+/* WARNING: DO NOT EDIT, AUTO-GENERATED CODE - SEE TOP FOR INSTRUCTIONS */
+  void __user * iov_base;
+  size_t iov_len;
+} sg_iovec_t;
+typedef struct sg_io_hdr {
+/* WARNING: DO NOT EDIT, AUTO-GENERATED CODE - SEE TOP FOR INSTRUCTIONS */
+  int interface_id;
+  int dxfer_direction;
+  unsigned char cmd_len;
+  unsigned char mx_sb_len;
+/* WARNING: DO NOT EDIT, AUTO-GENERATED CODE - SEE TOP FOR INSTRUCTIONS */
+  unsigned short iovec_count;
+  unsigned int dxfer_len;
+  void __user * dxferp;
+  unsigned char __user * cmdp;
+/* WARNING: DO NOT EDIT, AUTO-GENERATED CODE - SEE TOP FOR INSTRUCTIONS */
+  void __user * sbp;
+  unsigned int timeout;
+  unsigned int flags;
+  int pack_id;
+/* WARNING: DO NOT EDIT, AUTO-GENERATED CODE - SEE TOP FOR INSTRUCTIONS */
+  void __user * usr_ptr;
+  unsigned char status;
+  unsigned char masked_status;
+  unsigned char msg_status;
+/* WARNING: DO NOT EDIT, AUTO-GENERATED CODE - SEE TOP FOR INSTRUCTIONS */
+  unsigned char sb_len_wr;
+  unsigned short host_status;
+  unsigned short driver_status;
+  int resid;
+/* WARNING: DO NOT EDIT, AUTO-GENERATED CODE - SEE TOP FOR INSTRUCTIONS */
+  unsigned int duration;
+  unsigned int info;
+} sg_io_hdr_t;
+#define SG_INTERFACE_ID_ORIG 'S'
+/* WARNING: DO NOT EDIT, AUTO-GENERATED CODE - SEE TOP FOR INSTRUCTIONS */
+#define SG_DXFER_NONE (- 1)
+#define SG_DXFER_TO_DEV (- 2)
+#define SG_DXFER_FROM_DEV (- 3)
+#define SG_DXFER_TO_FROM_DEV (- 4)
+/* WARNING: DO NOT EDIT, AUTO-GENERATED CODE - SEE TOP FOR INSTRUCTIONS */
+#define SG_DXFER_UNKNOWN (- 5)
+#define SG_FLAG_DIRECT_IO 1
+#define SG_FLAG_UNUSED_LUN_INHIBIT 2
+#define SG_FLAG_MMAP_IO 4
+/* WARNING: DO NOT EDIT, AUTO-GENERATED CODE - SEE TOP FOR INSTRUCTIONS */
+#define SG_FLAG_NO_DXFER 0x10000
+#define SG_FLAG_Q_AT_TAIL 0x10
+#define SG_FLAG_Q_AT_HEAD 0x20
+#define SG_INFO_OK_MASK 0x1
+/* WARNING: DO NOT EDIT, AUTO-GENERATED CODE - SEE TOP FOR INSTRUCTIONS */
+#define SG_INFO_OK 0x0
+#define SG_INFO_CHECK 0x1
+#define SG_INFO_DIRECT_IO_MASK 0x6
+#define SG_INFO_INDIRECT_IO 0x0
+/* WARNING: DO NOT EDIT, AUTO-GENERATED CODE - SEE TOP FOR INSTRUCTIONS */
+#define SG_INFO_DIRECT_IO 0x2
+#define SG_INFO_MIXED_IO 0x4
+typedef struct sg_scsi_id {
+  int host_no;
+/* WARNING: DO NOT EDIT, AUTO-GENERATED CODE - SEE TOP FOR INSTRUCTIONS */
+  int channel;
+  int scsi_id;
+  int lun;
+  int scsi_type;
+/* WARNING: DO NOT EDIT, AUTO-GENERATED CODE - SEE TOP FOR INSTRUCTIONS */
+  short h_cmd_per_lun;
+  short d_queue_depth;
+  int unused[2];
+} sg_scsi_id_t;
+/* WARNING: DO NOT EDIT, AUTO-GENERATED CODE - SEE TOP FOR INSTRUCTIONS */
+typedef struct sg_req_info {
+  char req_state;
+  char orphan;
+  char sg_io_owned;
+/* WARNING: DO NOT EDIT, AUTO-GENERATED CODE - SEE TOP FOR INSTRUCTIONS */
+  char problem;
+  int pack_id;
+  void __user * usr_ptr;
+  unsigned int duration;
+/* WARNING: DO NOT EDIT, AUTO-GENERATED CODE - SEE TOP FOR INSTRUCTIONS */
+  int unused;
+} sg_req_info_t;
+#define SG_EMULATED_HOST 0x2203
+#define SG_SET_TRANSFORM 0x2204
+/* WARNING: DO NOT EDIT, AUTO-GENERATED CODE - SEE TOP FOR INSTRUCTIONS */
+#define SG_GET_TRANSFORM 0x2205
+#define SG_SET_RESERVED_SIZE 0x2275
+#define SG_GET_RESERVED_SIZE 0x2272
+#define SG_GET_SCSI_ID 0x2276
+/* WARNING: DO NOT EDIT, AUTO-GENERATED CODE - SEE TOP FOR INSTRUCTIONS */
+#define SG_SET_FORCE_LOW_DMA 0x2279
+#define SG_GET_LOW_DMA 0x227a
+#define SG_SET_FORCE_PACK_ID 0x227b
+#define SG_GET_PACK_ID 0x227c
+/* WARNING: DO NOT EDIT, AUTO-GENERATED CODE - SEE TOP FOR INSTRUCTIONS */
+#define SG_GET_NUM_WAITING 0x227d
+#define SG_GET_SG_TABLESIZE 0x227F
+#define SG_GET_VERSION_NUM 0x2282
+#define SG_SCSI_RESET 0x2284
+/* WARNING: DO NOT EDIT, AUTO-GENERATED CODE - SEE TOP FOR INSTRUCTIONS */
+#define SG_SCSI_RESET_NOTHING 0
+#define SG_SCSI_RESET_DEVICE 1
+#define SG_SCSI_RESET_BUS 2
+#define SG_SCSI_RESET_HOST 3
+/* WARNING: DO NOT EDIT, AUTO-GENERATED CODE - SEE TOP FOR INSTRUCTIONS */
+#define SG_SCSI_RESET_TARGET 4
+#define SG_IO 0x2285
+#define SG_GET_REQUEST_TABLE 0x2286
+#define SG_SET_KEEP_ORPHAN 0x2287
+/* WARNING: DO NOT EDIT, AUTO-GENERATED CODE - SEE TOP FOR INSTRUCTIONS */
+#define SG_GET_KEEP_ORPHAN 0x2288
+#define SG_GET_ACCESS_COUNT 0x2289
+#define SG_SCATTER_SZ (8 * 4096)
+#define SG_DEFAULT_RETRIES 0
+/* WARNING: DO NOT EDIT, AUTO-GENERATED CODE - SEE TOP FOR INSTRUCTIONS */
+#define SG_DEF_FORCE_LOW_DMA 0
+#define SG_DEF_FORCE_PACK_ID 0
+#define SG_DEF_KEEP_ORPHAN 0
+#define SG_DEF_RESERVED_SIZE SG_SCATTER_SZ
+/* WARNING: DO NOT EDIT, AUTO-GENERATED CODE - SEE TOP FOR INSTRUCTIONS */
+#define SG_MAX_QUEUE 16
+#define SG_BIG_BUFF SG_DEF_RESERVED_SIZE
+typedef struct sg_io_hdr Sg_io_hdr;
+typedef struct sg_io_vec Sg_io_vec;
+/* WARNING: DO NOT EDIT, AUTO-GENERATED CODE - SEE TOP FOR INSTRUCTIONS */
+typedef struct sg_scsi_id Sg_scsi_id;
+typedef struct sg_req_info Sg_req_info;
+#define SG_MAX_SENSE 16
+struct sg_header {
+/* WARNING: DO NOT EDIT, AUTO-GENERATED CODE - SEE TOP FOR INSTRUCTIONS */
+  int pack_len;
+  int reply_len;
+  int pack_id;
+  int result;
+/* WARNING: DO NOT EDIT, AUTO-GENERATED CODE - SEE TOP FOR INSTRUCTIONS */
+  unsigned int twelve_byte : 1;
+  unsigned int target_status : 5;
+  unsigned int host_status : 8;
+  unsigned int driver_status : 8;
+/* WARNING: DO NOT EDIT, AUTO-GENERATED CODE - SEE TOP FOR INSTRUCTIONS */
+  unsigned int other_flags : 10;
+  unsigned char sense_buffer[SG_MAX_SENSE];
+};
+#define SG_SET_TIMEOUT 0x2201
+/* WARNING: DO NOT EDIT, AUTO-GENERATED CODE - SEE TOP FOR INSTRUCTIONS */
+#define SG_GET_TIMEOUT 0x2202
+#define SG_GET_COMMAND_Q 0x2270
+#define SG_SET_COMMAND_Q 0x2271
+#define SG_SET_DEBUG 0x227e
+/* WARNING: DO NOT EDIT, AUTO-GENERATED CODE - SEE TOP FOR INSTRUCTIONS */
+#define SG_NEXT_CMD_LEN 0x2283
+#define SG_DEFAULT_TIMEOUT (60 * HZ)
+#define SG_DEF_COMMAND_Q 0
+#define SG_DEF_UNDERRUN_FLAG 0
+/* WARNING: DO NOT EDIT, AUTO-GENERATED CODE - SEE TOP FOR INSTRUCTIONS */
+#endif
diff --git a/libc/kernel/tools/clean_header.py b/libc/kernel/tools/clean_header.py
index 0e0ed76..e84bcf9 100755
--- a/libc/kernel/tools/clean_header.py
+++ b/libc/kernel/tools/clean_header.py
@@ -73,90 +73,77 @@
 from defaults import *
 from utils import *
 
-noUpdate = 1
+def print_error(no_update, msg):
+    if no_update:
+        panic(msg)
+    sys.stderr.write("warning: " + msg)
 
-def cleanupFile(path, original_path):
+
+def cleanupFile(dst_dir, src_dir, rel_path, no_update = True):
     """reads an original header and perform the cleanup operation on it
        this functions returns the destination path and the clean header
        as a single string"""
     # check the header path
-    src_path = path
+    full_path = os.path.join(src_dir, rel_path)
 
-    if not os.path.exists(src_path):
-        if noUpdate:
-            panic( "file does not exist: '%s'\n" % path )
-        sys.stderr.write( "warning: file does not exit: %s\n" % path )
+    if not os.path.exists(full_path):
+        print_error(no_update, "file does not exist: '%s'\n" % full_path)
         return None, None
 
-    if not os.path.isfile(src_path):
-        if noUpdate:
-            panic( "path is not a file: '%s'\n" % path )
-        sys.stderr.write( "warning: not a file: %s\n" % path )
+    if not os.path.isfile(full_path):
+        print_error(no_update, "path is not a file: '%s'\n" % full_path)
         return None, None
 
-    if os.path.commonprefix( [ src_path, original_path ] ) != original_path:
-        if noUpdate:
-            panic( "file is not in 'original' directory: %s\n" % path );
-        sys.stderr.write( "warning: file not in 'original' ignored: %s\n" % path )
-        return None, None
-
-    src_path = src_path[len(original_path):]
-    if len(src_path) > 0 and src_path[0] == '/':
-        src_path = src_path[1:]
-
-    if len(src_path) == 0:
-        panic( "oops, internal error, can't extract correct relative path\n" )
-
     # convert into destination path, extracting architecture if needed
     # and the corresponding list of known static functions
     #
     arch = None
     statics = kernel_known_generic_statics
-    m = re.match(r"asm-([\w\d_\+\.\-]+)(/.*)", src_path)
+    m = re.match(r"asm-([\w\d_\+\.\-]+)(/.*)", rel_path)
     if m and m.group(1) != 'generic':
         dst_path = "arch-%s/asm/%s" % m.groups()
-        arch     = m.group(1)
-        statics  = statics.union( kernel_known_statics.get( arch, set() ) )
+        arch = m.group(1)
+        statics  = statics.union(kernel_known_statics.get(arch, set()))
     else:
         # process headers under the uapi directory
         # note the "asm" level has been explicitly added in the original
         # kernel header tree for architectural-dependent uapi headers
-        m_uapi = re.match(r"(uapi)/([\w\d_\+\.\-]+)(/.*)", src_path)
+        m_uapi = re.match(r"(uapi)/([\w\d_\+\.\-]+)(/.*)", rel_path)
         if m_uapi:
-            dst_path = src_path
+            dst_path = rel_path
             m_uapi_arch = re.match(r"asm-([\w\d_\+\.\-]+)", m_uapi.group(2))
             if m_uapi_arch and m_uapi_arch.group(1) != 'generic':
-                arch     = m_uapi_arch.group(1)
-                statics  = statics.union( kernel_known_statics.get( arch, set() ) )
+                arch = m_uapi_arch.group(1)
+                statics = statics.union(kernel_known_statics.get(arch, set()))
         # common headers (ie non-asm and non-uapi)
         else:
-            dst_path = "common/" + src_path
+            dst_path = os.path.join("common", rel_path)
 
-    dst_path = os.path.normpath( kernel_cleaned_path + "/" + dst_path )
+    dst_path = os.path.join(dst_dir, dst_path)
 
     # now, let's parse the file
     #
     parser = cpp.BlockParser()
-    blocks = parser.parseFile(path)
+    blocks = parser.parseFile(full_path)
     if not parser.parsed:
-        sys.stderr.write( "error: can't parse '%s'" % path )
-        sys.exit(1)
+        print_error(no_update, "can't parse '%s'%" % full_path)
+        return None, None
 
     macros = kernel_known_macros.copy()
     if arch and arch in kernel_default_arch_macros:
         macros.update(kernel_default_arch_macros[arch])
 
     if arch and arch in kernel_arch_token_replacements:
-        blocks.replaceTokens( kernel_arch_token_replacements[arch] )
+        blocks.replaceTokens(kernel_arch_token_replacements[arch])
 
-    blocks.optimizeMacros( macros )
+    blocks.optimizeMacros(macros)
     blocks.optimizeIf01()
-    blocks.removeVarsAndFuncs( statics )
-    blocks.replaceTokens( kernel_token_replacements )
-    blocks.removeMacroDefines( kernel_ignored_macros )
+    blocks.removeVarsAndFuncs(statics)
+    blocks.replaceTokens(kernel_token_replacements)
+    blocks.removeMacroDefines(kernel_ignored_macros)
 
     out = StringOutput()
-    out.write( kernel_disclaimer )
+    out.write(kernel_disclaimer)
     blocks.writeWithWarning(out, kernel_warning, 4)
     return dst_path, out.get()
 
@@ -183,28 +170,31 @@
         sys.exit(1)
 
     try:
-        optlist, args = getopt.getopt( sys.argv[1:], 'uvk:d:' )
+        optlist, args = getopt.getopt(sys.argv[1:], 'uvk:d:')
     except:
         # unrecognized option
-        sys.stderr.write( "error: unrecognized option\n" )
+        sys.stderr.write("error: unrecognized option\n")
         usage()
 
+    no_update = True
+    dst_dir = get_kernel_dir()
+    src_dir = get_kernel_headers_original_dir()
     for opt, arg in optlist:
         if opt == '-u':
-            noUpdate = 0
+            no_update = False
         elif opt == '-v':
             logging.basicConfig(level=logging.DEBUG)
         elif opt == '-k':
-            kernel_original_path = arg
+            src_dir = arg
         elif opt == '-d':
-            kernel_cleaned_path = arg
+            dst_dir = arg
 
     if len(args) == 0:
         usage()
 
-    if noUpdate:
+    if no_update:
         for path in args:
-            dst_path, newdata = cleanupFile(path,kernel_original_path)
+            dst_path, newdata = cleanupFile(dst_dir, src_dir, path)
             print newdata
 
         sys.exit(0)
@@ -214,12 +204,12 @@
     b = BatchFileUpdater()
 
     for path in args:
-        dst_path, newdata = cleanupFile(path,kernel_original_path)
+        dst_path, newdata = cleanupFile(dst_dir, src_dir, path, no_update)
         if not dst_path:
             continue
 
-        b.readFile( dst_path )
-        r = b.editFile( dst_path, newdata )
+        b.readFile(dst_path)
+        r = b.editFile(dst_path, newdata)
         if r == 0:
             r = "unchanged"
         elif r == 1:
@@ -227,7 +217,7 @@
         else:
             r = "added"
 
-        print "cleaning: %-*s -> %-*s (%s)" % ( 35, path, 35, dst_path, r )
+        print "cleaning: %-*s -> %-*s (%s)" % (35, path, 35, dst_path, r)
 
 
     b.updateGitFiles()
diff --git a/libc/kernel/tools/defaults.py b/libc/kernel/tools/defaults.py
index 8aba998..773d22f 100644
--- a/libc/kernel/tools/defaults.py
+++ b/libc/kernel/tools/defaults.py
@@ -12,12 +12,6 @@
 # tree. used when looking for sources...
 kernel_dirs = [ "linux", "asm", "asm-generic", "mtd" ]
 
-# path to the directory containing the original kernel headers
-kernel_original_path = os.path.normpath( find_program_dir() + '/../../../../external/kernel-headers/original' )
-
-# path to the default location of the cleaned-up headers
-kernel_cleaned_path = os.path.normpath( find_program_dir() + '/..' )
-
 # a special value that is used to indicate that a given macro is known to be
 # undefined during optimization
 kCppUndefinedMacro = "<<<undefined>>>"
@@ -70,6 +64,8 @@
     # The kernel's SIGRTMIN/SIGRTMAX are absolute limits; userspace steals a few.
     "SIGRTMIN": "__SIGRTMIN",
     "SIGRTMAX": "__SIGRTMAX",
+    # We want to support both BSD and Linux member names in struct udphdr.
+    "udphdr": "__kernel_udphdr",
     }
 
 # this is the set of known static inline functions that we want to keep
diff --git a/libc/kernel/tools/generate_uapi_headers.sh b/libc/kernel/tools/generate_uapi_headers.sh
index 90ba0ed..3c80d9f 100755
--- a/libc/kernel/tools/generate_uapi_headers.sh
+++ b/libc/kernel/tools/generate_uapi_headers.sh
@@ -99,6 +99,35 @@
   done
 }
 
+function check_hdrs () {
+  local src_dir=$1
+  local tgt_dir=$2
+  local kernel_dir=$3
+
+  local search_dirs=()
+
+  # This only works if none of the filenames have spaces.
+  for file in $(ls -d ${src_dir}/* 2> /dev/null); do
+    if [[ -d "${file}" ]]; then
+      search_dirs+=("${file}")
+    elif [[ -f  "${file}" ]] && [[ "${file}" =~ .h$ ]]; then
+      tgt_file=${tgt_dir}/$(basename ${file})
+      if [[ -e ${tgt_file} ]] && ! diff "${file}" "${tgt_file}" > /dev/null; then
+        if [[ ${file} =~ ${kernel_dir}/*(.+) ]]; then
+          echo "New version of ${BASH_REMATCH[1]} found in kernel headers."
+        else
+          echo "New version of ${file} found in kernel headers."
+        fi
+        echo "This file needs to be updated manually."
+      fi
+    fi
+  done
+
+  for dir in "${search_dirs[@]}"; do
+    check_hdrs "${dir}" ${tgt_dir}/$(basename ${dir}) "${kernel_dir}"
+  done
+}
+
 trap cleanup EXIT
 # This automatically triggers a call to cleanup.
 trap "exit 1" HUP INT TERM TSTP
@@ -207,3 +236,8 @@
                  "${KERNEL_DIR}/${src_dir}/arch/${arch}/include/generated/asm" \
                  "${ANDROID_KERNEL_DIR}/uapi/asm-${arch}/asm"
 done
+
+# Verify if modified headers have changed.
+check_hdrs "${KERNEL_DIR}/${src_dir}/include/scsi" \
+           "${ANDROID_KERNEL_DIR}/scsi" \
+           "${KERNEL_DIR}/${src_dir}"
diff --git a/libc/kernel/tools/update_all.py b/libc/kernel/tools/update_all.py
index f45d4e0..7f3657c 100755
--- a/libc/kernel/tools/update_all.py
+++ b/libc/kernel/tools/update_all.py
@@ -6,72 +6,93 @@
 
 def usage():
     print """\
-  usage: %(progname)s [kernel-original-path]
+  usage: %(progname)s [kernel-original-path] [kernel-modified-path]
 
     this program is used to update all the auto-generated clean headers
     used by the Bionic C library. it assumes the following:
 
-      - a set of source kernel headers is located in '../original',
-        relative to the program's directory
+      - a set of source kernel headers is located in
+        'external/kernel-headers/original', relative to the current
+        android tree
 
-      - the clean headers will be placed in '../arch-<arch>/asm',
-        '../common/linux', '../common/asm-generic', etc..
+      - a set of manually modified kernel header files located in
+        'external/kernel-headers/modified', relative to the current
+        android tree
+
+      - the clean headers will be placed in 'bionic/libc/kernel/arch-<arch>/asm',
+        'bionic/libc/kernel/common', etc..
 """ % { "progname" : os.path.basename(sys.argv[0]) }
     sys.exit(0)
 
 try:
-    optlist, args = getopt.getopt( sys.argv[1:], '' )
+    optlist, args = getopt.getopt(sys.argv[1:], '')
 except:
     # unrecognized option
-    sys.stderr.write( "error: unrecognized option\n" )
+    sys.stderr.write("error: unrecognized option\n")
     usage()
 
-if len(optlist) > 0 or len(args) > 1:
+if len(optlist) > 0 or len(args) > 2:
     usage()
 
-progdir = find_program_dir()
-
-if len(args) == 1:
+modified_dir = get_kernel_headers_modified_dir()
+if len(args) == 1 or len(args) == 2:
     original_dir = args[0]
     if not os.path.isdir(original_dir):
-        panic( "Not a directory: %s\n" % original_dir )
+        panic("Not a directory: %s\n" % original_dir)
+
+    if len(args) == 2:
+        modified_dir = args[1]
+        if not os.path.isdir(modified_dir):
+            panic("Not a directory: %s\n" % modified_dir)
 else:
-    original_dir = kernel_original_path
+    original_dir = get_kernel_headers_original_dir()
     if not os.path.isdir(original_dir):
-        panic( "Missing directory, please specify one through command-line: %s\n" % original_dir )
+        panic("Missing directory, please specify one through command-line: %s\n" % original_dir)
 
-skip_ion = False
+if not os.path.isdir(modified_dir):
+    modified_dir = None
 
-# find all source files in 'original'
-#
-sources = []
-warning_ion = []
-for root, dirs, files in os.walk( original_dir ):
+# Find all source files in 'original'.
+sources = dict()
+original_dir = os.path.normpath(original_dir)
+original_dir_len = len(original_dir) + 1
+for root, _, files in os.walk(original_dir):
     for file in files:
-        if skip_ion and (file == "ion.h" or file == "ion_test.h"):
-            warning_ion.append("  Skipped file %s/%s" % (root, file))
-            continue
-        base, ext = os.path.splitext(file)
+        _, ext = os.path.splitext(file)
         if ext == ".h":
-            sources.append( "%s/%s" % (root,file) )
+            rel_path = os.path.normpath(os.path.join(root, file))
+            rel_path = rel_path[original_dir_len:]
+            # Check to see if there is a modified header to use instead.
+            if modified_dir and os.path.exists(os.path.join(modified_dir, rel_path)):
+                sources[rel_path] = False
+            else:
+                sources[rel_path] = True
+
 
 b = BatchFileUpdater()
 
+kernel_dir = get_kernel_dir()
 for arch in kernel_archs:
-    b.readDir( os.path.normpath( progdir + "/../arch-%s" % arch ) )
+    b.readDir(os.path.join(kernel_dir, "arch-%s" % arch))
 
-b.readDir( os.path.normpath( progdir + "/../common" ) )
-
-#print "OLD " + repr(b.old_files)
+b.readDir(os.path.join(kernel_dir, "common"))
 
 oldlen = 120
-for path in sources:
-    dst_path, newdata = clean_header.cleanupFile(path, original_dir)
+android_root_len = len(get_android_root()) + 1
+for rel_path in sorted(sources):
+    if sources[rel_path]:
+        src_dir = original_dir
+        src_str = "<original>/"
+    else:
+        src_dir = modified_dir
+        src_str = "<modified>/"
+    dst_path, newdata = clean_header.cleanupFile(kernel_dir, src_dir, rel_path)
     if not dst_path:
         continue
 
-    b.readFile( dst_path )
-    r = b.editFile( dst_path, newdata )
+    dst_path = os.path.join(kernel_dir, dst_path)
+    b.readFile(dst_path)
+    r = b.editFile(dst_path, newdata)
     if r == 0:
         state = "unchanged"
     elif r == 1:
@@ -79,9 +100,11 @@
     else:
         state = "added"
 
-    str = "cleaning: %-*s -> %-*s (%s)" % ( 35, "<original>" + path[len(original_dir):], 35, dst_path, state )
+    # dst_path is guaranteed to include android root.
+    rel_dst_path = dst_path[android_root_len:]
+    str = "cleaning: %-*s -> %-*s (%s)" % (35, src_str + rel_path, 35, rel_dst_path, state)
     if sys.stdout.isatty():
-        print "%-*s" % (oldlen,str),
+        print "%-*s" % (oldlen, str),
         if (r == 0):
             print "\r",
         else:
@@ -92,11 +115,8 @@
 
     oldlen = len(str)
 
-print "%-*s" % (oldlen,"Done!")
+print "%-*s" % (oldlen, "Done!")
 
 b.updateGitFiles()
 
-if warning_ion:
-    print "NOTE: Due to import into aosp, some files were not processed."
-    print "\n".join(warning_ion)
 sys.exit(0)
diff --git a/libc/kernel/tools/utils.py b/libc/kernel/tools/utils.py
index e5a310e..e2cc9ce 100644
--- a/libc/kernel/tools/utils.py
+++ b/libc/kernel/tools/utils.py
@@ -13,8 +13,26 @@
     sys.exit(1)
 
 
-def find_program_dir():
-    return os.path.dirname(sys.argv[0])
+def get_kernel_headers_dir():
+    return os.path.join(get_android_root(), "external/kernel-headers")
+
+
+def get_kernel_headers_original_dir():
+    return os.path.join(get_kernel_headers_dir(), "original")
+
+
+def get_kernel_headers_modified_dir():
+    return os.path.join(get_kernel_headers_dir(), "modified")
+
+
+def get_kernel_dir():
+    return os.path.join(get_android_root(), "bionic/libc/kernel")
+
+
+def get_android_root():
+    if "ANDROID_BUILD_TOP" in os.environ:
+        return os.environ["ANDROID_BUILD_TOP"]
+    panic("Unable to find root of tree, did you forget to lunch a target?")
 
 
 class StringOutput:
diff --git a/libc/kernel/uapi/asm-arm/asm/kvm.h b/libc/kernel/uapi/asm-arm/asm/kvm.h
index c37d809..aa534ab 100644
--- a/libc/kernel/uapi/asm-arm/asm/kvm.h
+++ b/libc/kernel/uapi/asm-arm/asm/kvm.h
@@ -154,32 +154,36 @@
 #define KVM_DEV_ARM_VGIC_OFFSET_SHIFT 0
 #define KVM_DEV_ARM_VGIC_OFFSET_MASK (0xffffffffULL << KVM_DEV_ARM_VGIC_OFFSET_SHIFT)
 #define KVM_DEV_ARM_VGIC_GRP_NR_IRQS 3
-#define KVM_ARM_IRQ_TYPE_SHIFT 24
+#define KVM_DEV_ARM_VGIC_GRP_CTRL 4
 /* WARNING: DO NOT EDIT, AUTO-GENERATED CODE - SEE TOP FOR INSTRUCTIONS */
+#define KVM_DEV_ARM_VGIC_CTRL_INIT 0
+#define KVM_ARM_IRQ_TYPE_SHIFT 24
 #define KVM_ARM_IRQ_TYPE_MASK 0xff
 #define KVM_ARM_IRQ_VCPU_SHIFT 16
+/* WARNING: DO NOT EDIT, AUTO-GENERATED CODE - SEE TOP FOR INSTRUCTIONS */
 #define KVM_ARM_IRQ_VCPU_MASK 0xff
 #define KVM_ARM_IRQ_NUM_SHIFT 0
-/* WARNING: DO NOT EDIT, AUTO-GENERATED CODE - SEE TOP FOR INSTRUCTIONS */
 #define KVM_ARM_IRQ_NUM_MASK 0xffff
 #define KVM_ARM_IRQ_TYPE_CPU 0
+/* WARNING: DO NOT EDIT, AUTO-GENERATED CODE - SEE TOP FOR INSTRUCTIONS */
 #define KVM_ARM_IRQ_TYPE_SPI 1
 #define KVM_ARM_IRQ_TYPE_PPI 2
-/* WARNING: DO NOT EDIT, AUTO-GENERATED CODE - SEE TOP FOR INSTRUCTIONS */
 #define KVM_ARM_IRQ_CPU_IRQ 0
 #define KVM_ARM_IRQ_CPU_FIQ 1
-#define KVM_ARM_IRQ_GIC_MAX 127
-#define KVM_PSCI_FN_BASE 0x95c1ba5e
 /* WARNING: DO NOT EDIT, AUTO-GENERATED CODE - SEE TOP FOR INSTRUCTIONS */
+#define KVM_ARM_IRQ_GIC_MAX 127
+#define KVM_NR_IRQCHIPS 1
+#define KVM_PSCI_FN_BASE 0x95c1ba5e
 #define KVM_PSCI_FN(n) (KVM_PSCI_FN_BASE + (n))
+/* WARNING: DO NOT EDIT, AUTO-GENERATED CODE - SEE TOP FOR INSTRUCTIONS */
 #define KVM_PSCI_FN_CPU_SUSPEND KVM_PSCI_FN(0)
 #define KVM_PSCI_FN_CPU_OFF KVM_PSCI_FN(1)
 #define KVM_PSCI_FN_CPU_ON KVM_PSCI_FN(2)
-/* WARNING: DO NOT EDIT, AUTO-GENERATED CODE - SEE TOP FOR INSTRUCTIONS */
 #define KVM_PSCI_FN_MIGRATE KVM_PSCI_FN(3)
+/* WARNING: DO NOT EDIT, AUTO-GENERATED CODE - SEE TOP FOR INSTRUCTIONS */
 #define KVM_PSCI_RET_SUCCESS PSCI_RET_SUCCESS
 #define KVM_PSCI_RET_NI PSCI_RET_NOT_SUPPORTED
 #define KVM_PSCI_RET_INVAL PSCI_RET_INVALID_PARAMS
-/* WARNING: DO NOT EDIT, AUTO-GENERATED CODE - SEE TOP FOR INSTRUCTIONS */
 #define KVM_PSCI_RET_DENIED PSCI_RET_DENIED
+/* WARNING: DO NOT EDIT, AUTO-GENERATED CODE - SEE TOP FOR INSTRUCTIONS */
 #endif
diff --git a/libc/kernel/uapi/asm-arm/asm/unistd.h b/libc/kernel/uapi/asm-arm/asm/unistd.h
index 32f6688..468f50a 100644
--- a/libc/kernel/uapi/asm-arm/asm/unistd.h
+++ b/libc/kernel/uapi/asm-arm/asm/unistd.h
@@ -464,6 +464,11 @@
 #define __NR_getrandom (__NR_SYSCALL_BASE + 384)
 #define __NR_memfd_create (__NR_SYSCALL_BASE + 385)
 #define __NR_bpf (__NR_SYSCALL_BASE + 386)
+#define __NR_execveat (__NR_SYSCALL_BASE + 387)
+/* WARNING: DO NOT EDIT, AUTO-GENERATED CODE - SEE TOP FOR INSTRUCTIONS */
+#define __NR_userfaultfd (__NR_SYSCALL_BASE + 388)
+#define __NR_membarrier (__NR_SYSCALL_BASE + 389)
+#define __NR_mlock2 (__NR_SYSCALL_BASE + 390)
 #define __ARM_NR_BASE (__NR_SYSCALL_BASE + 0x0f0000)
 /* WARNING: DO NOT EDIT, AUTO-GENERATED CODE - SEE TOP FOR INSTRUCTIONS */
 #define __ARM_NR_breakpoint (__ARM_NR_BASE + 1)
diff --git a/libc/kernel/uapi/asm-arm64/asm/hwcap.h b/libc/kernel/uapi/asm-arm64/asm/hwcap.h
index ccea53d..5e2b495 100644
--- a/libc/kernel/uapi/asm-arm64/asm/hwcap.h
+++ b/libc/kernel/uapi/asm-arm64/asm/hwcap.h
@@ -28,4 +28,6 @@
 /* WARNING: DO NOT EDIT, AUTO-GENERATED CODE - SEE TOP FOR INSTRUCTIONS */
 #define HWCAP_SHA2 (1 << 6)
 #define HWCAP_CRC32 (1 << 7)
+#define HWCAP_ATOMICS (1 << 8)
 #endif
+/* WARNING: DO NOT EDIT, AUTO-GENERATED CODE - SEE TOP FOR INSTRUCTIONS */
diff --git a/libc/kernel/uapi/asm-arm64/asm/kvm.h b/libc/kernel/uapi/asm-arm64/asm/kvm.h
index 855e084..39b961a 100644
--- a/libc/kernel/uapi/asm-arm64/asm/kvm.h
+++ b/libc/kernel/uapi/asm-arm64/asm/kvm.h
@@ -29,7 +29,7 @@
 #define KVM_NR_SPSR 5
 #ifndef __ASSEMBLY__
 #include <linux/psci.h>
-#include <asm/types.h>
+#include <linux/types.h>
 /* WARNING: DO NOT EDIT, AUTO-GENERATED CODE - SEE TOP FOR INSTRUCTIONS */
 #include <asm/ptrace.h>
 #define __KVM_HAVE_GUEST_DEBUG
@@ -52,86 +52,106 @@
 #define KVM_ARM_TARGET_XGENE_POTENZA 3
 /* WARNING: DO NOT EDIT, AUTO-GENERATED CODE - SEE TOP FOR INSTRUCTIONS */
 #define KVM_ARM_TARGET_CORTEX_A53 4
-#define KVM_ARM_NUM_TARGETS 5
+#define KVM_ARM_TARGET_GENERIC_V8 5
+#define KVM_ARM_NUM_TARGETS 6
 #define KVM_ARM_DEVICE_TYPE_SHIFT 0
-#define KVM_ARM_DEVICE_TYPE_MASK (0xffff << KVM_ARM_DEVICE_TYPE_SHIFT)
 /* WARNING: DO NOT EDIT, AUTO-GENERATED CODE - SEE TOP FOR INSTRUCTIONS */
+#define KVM_ARM_DEVICE_TYPE_MASK (0xffff << KVM_ARM_DEVICE_TYPE_SHIFT)
 #define KVM_ARM_DEVICE_ID_SHIFT 16
 #define KVM_ARM_DEVICE_ID_MASK (0xffff << KVM_ARM_DEVICE_ID_SHIFT)
 #define KVM_ARM_DEVICE_VGIC_V2 0
-#define KVM_VGIC_V2_ADDR_TYPE_DIST 0
 /* WARNING: DO NOT EDIT, AUTO-GENERATED CODE - SEE TOP FOR INSTRUCTIONS */
+#define KVM_VGIC_V2_ADDR_TYPE_DIST 0
 #define KVM_VGIC_V2_ADDR_TYPE_CPU 1
 #define KVM_VGIC_V2_DIST_SIZE 0x1000
 #define KVM_VGIC_V2_CPU_SIZE 0x2000
-#define KVM_ARM_VCPU_POWER_OFF 0
 /* WARNING: DO NOT EDIT, AUTO-GENERATED CODE - SEE TOP FOR INSTRUCTIONS */
+#define KVM_VGIC_V3_ADDR_TYPE_DIST 2
+#define KVM_VGIC_V3_ADDR_TYPE_REDIST 3
+#define KVM_VGIC_V3_DIST_SIZE SZ_64K
+#define KVM_VGIC_V3_REDIST_SIZE (2 * SZ_64K)
+/* WARNING: DO NOT EDIT, AUTO-GENERATED CODE - SEE TOP FOR INSTRUCTIONS */
+#define KVM_ARM_VCPU_POWER_OFF 0
 #define KVM_ARM_VCPU_EL1_32BIT 1
 #define KVM_ARM_VCPU_PSCI_0_2 2
 struct kvm_vcpu_init {
-  __u32 target;
 /* WARNING: DO NOT EDIT, AUTO-GENERATED CODE - SEE TOP FOR INSTRUCTIONS */
+  __u32 target;
   __u32 features[7];
 };
 struct kvm_sregs {
-};
 /* WARNING: DO NOT EDIT, AUTO-GENERATED CODE - SEE TOP FOR INSTRUCTIONS */
+};
 struct kvm_fpu {
 };
-struct kvm_guest_debug_arch {
-};
+#define KVM_ARM_MAX_DBG_REGS 16
 /* WARNING: DO NOT EDIT, AUTO-GENERATED CODE - SEE TOP FOR INSTRUCTIONS */
-struct kvm_debug_exit_arch {
+struct kvm_guest_debug_arch {
+  __u64 dbg_bcr[KVM_ARM_MAX_DBG_REGS];
+  __u64 dbg_bvr[KVM_ARM_MAX_DBG_REGS];
+  __u64 dbg_wcr[KVM_ARM_MAX_DBG_REGS];
+/* WARNING: DO NOT EDIT, AUTO-GENERATED CODE - SEE TOP FOR INSTRUCTIONS */
+  __u64 dbg_wvr[KVM_ARM_MAX_DBG_REGS];
 };
+struct kvm_debug_exit_arch {
+  __u32 hsr;
+/* WARNING: DO NOT EDIT, AUTO-GENERATED CODE - SEE TOP FOR INSTRUCTIONS */
+  __u64 far;
+};
+#define KVM_GUESTDBG_USE_SW_BP (1 << 16)
+#define KVM_GUESTDBG_USE_HW (1 << 17)
+/* WARNING: DO NOT EDIT, AUTO-GENERATED CODE - SEE TOP FOR INSTRUCTIONS */
 struct kvm_sync_regs {
 };
-/* WARNING: DO NOT EDIT, AUTO-GENERATED CODE - SEE TOP FOR INSTRUCTIONS */
 struct kvm_arch_memory_slot {
 };
+/* WARNING: DO NOT EDIT, AUTO-GENERATED CODE - SEE TOP FOR INSTRUCTIONS */
 #define KVM_REG_ARM_COPROC_MASK 0x000000000FFF0000
 #define KVM_REG_ARM_COPROC_SHIFT 16
-/* WARNING: DO NOT EDIT, AUTO-GENERATED CODE - SEE TOP FOR INSTRUCTIONS */
 #define KVM_REG_ARM_CORE (0x0010 << KVM_REG_ARM_COPROC_SHIFT)
 #define KVM_REG_ARM_CORE_REG(name) (offsetof(struct kvm_regs, name) / sizeof(__u32))
+/* WARNING: DO NOT EDIT, AUTO-GENERATED CODE - SEE TOP FOR INSTRUCTIONS */
 #define KVM_REG_ARM_DEMUX (0x0011 << KVM_REG_ARM_COPROC_SHIFT)
 #define KVM_REG_ARM_DEMUX_ID_MASK 0x000000000000FF00
-/* WARNING: DO NOT EDIT, AUTO-GENERATED CODE - SEE TOP FOR INSTRUCTIONS */
 #define KVM_REG_ARM_DEMUX_ID_SHIFT 8
 #define KVM_REG_ARM_DEMUX_ID_CCSIDR (0x00 << KVM_REG_ARM_DEMUX_ID_SHIFT)
+/* WARNING: DO NOT EDIT, AUTO-GENERATED CODE - SEE TOP FOR INSTRUCTIONS */
 #define KVM_REG_ARM_DEMUX_VAL_MASK 0x00000000000000FF
 #define KVM_REG_ARM_DEMUX_VAL_SHIFT 0
-/* WARNING: DO NOT EDIT, AUTO-GENERATED CODE - SEE TOP FOR INSTRUCTIONS */
 #define KVM_REG_ARM64_SYSREG (0x0013 << KVM_REG_ARM_COPROC_SHIFT)
 #define KVM_REG_ARM64_SYSREG_OP0_MASK 0x000000000000c000
+/* WARNING: DO NOT EDIT, AUTO-GENERATED CODE - SEE TOP FOR INSTRUCTIONS */
 #define KVM_REG_ARM64_SYSREG_OP0_SHIFT 14
 #define KVM_REG_ARM64_SYSREG_OP1_MASK 0x0000000000003800
-/* WARNING: DO NOT EDIT, AUTO-GENERATED CODE - SEE TOP FOR INSTRUCTIONS */
 #define KVM_REG_ARM64_SYSREG_OP1_SHIFT 11
 #define KVM_REG_ARM64_SYSREG_CRN_MASK 0x0000000000000780
+/* WARNING: DO NOT EDIT, AUTO-GENERATED CODE - SEE TOP FOR INSTRUCTIONS */
 #define KVM_REG_ARM64_SYSREG_CRN_SHIFT 7
 #define KVM_REG_ARM64_SYSREG_CRM_MASK 0x0000000000000078
-/* WARNING: DO NOT EDIT, AUTO-GENERATED CODE - SEE TOP FOR INSTRUCTIONS */
 #define KVM_REG_ARM64_SYSREG_CRM_SHIFT 3
 #define KVM_REG_ARM64_SYSREG_OP2_MASK 0x0000000000000007
+/* WARNING: DO NOT EDIT, AUTO-GENERATED CODE - SEE TOP FOR INSTRUCTIONS */
 #define KVM_REG_ARM64_SYSREG_OP2_SHIFT 0
 #define ARM64_SYS_REG_SHIFT_MASK(x,n) (((x) << KVM_REG_ARM64_SYSREG_ ##n ##_SHIFT) & KVM_REG_ARM64_SYSREG_ ##n ##_MASK)
-/* WARNING: DO NOT EDIT, AUTO-GENERATED CODE - SEE TOP FOR INSTRUCTIONS */
 #define __ARM64_SYS_REG(op0,op1,crn,crm,op2) (KVM_REG_ARM64 | KVM_REG_ARM64_SYSREG | ARM64_SYS_REG_SHIFT_MASK(op0, OP0) | ARM64_SYS_REG_SHIFT_MASK(op1, OP1) | ARM64_SYS_REG_SHIFT_MASK(crn, CRN) | ARM64_SYS_REG_SHIFT_MASK(crm, CRM) | ARM64_SYS_REG_SHIFT_MASK(op2, OP2))
 #define ARM64_SYS_REG(...) (__ARM64_SYS_REG(__VA_ARGS__) | KVM_REG_SIZE_U64)
+/* WARNING: DO NOT EDIT, AUTO-GENERATED CODE - SEE TOP FOR INSTRUCTIONS */
 #define KVM_REG_ARM_TIMER_CTL ARM64_SYS_REG(3, 3, 14, 3, 1)
 #define KVM_REG_ARM_TIMER_CNT ARM64_SYS_REG(3, 3, 14, 3, 2)
-/* WARNING: DO NOT EDIT, AUTO-GENERATED CODE - SEE TOP FOR INSTRUCTIONS */
 #define KVM_REG_ARM_TIMER_CVAL ARM64_SYS_REG(3, 3, 14, 0, 2)
 #define KVM_DEV_ARM_VGIC_GRP_ADDR 0
+/* WARNING: DO NOT EDIT, AUTO-GENERATED CODE - SEE TOP FOR INSTRUCTIONS */
 #define KVM_DEV_ARM_VGIC_GRP_DIST_REGS 1
 #define KVM_DEV_ARM_VGIC_GRP_CPU_REGS 2
-/* WARNING: DO NOT EDIT, AUTO-GENERATED CODE - SEE TOP FOR INSTRUCTIONS */
 #define KVM_DEV_ARM_VGIC_CPUID_SHIFT 32
 #define KVM_DEV_ARM_VGIC_CPUID_MASK (0xffULL << KVM_DEV_ARM_VGIC_CPUID_SHIFT)
+/* WARNING: DO NOT EDIT, AUTO-GENERATED CODE - SEE TOP FOR INSTRUCTIONS */
 #define KVM_DEV_ARM_VGIC_OFFSET_SHIFT 0
 #define KVM_DEV_ARM_VGIC_OFFSET_MASK (0xffffffffULL << KVM_DEV_ARM_VGIC_OFFSET_SHIFT)
-/* WARNING: DO NOT EDIT, AUTO-GENERATED CODE - SEE TOP FOR INSTRUCTIONS */
 #define KVM_DEV_ARM_VGIC_GRP_NR_IRQS 3
+#define KVM_DEV_ARM_VGIC_GRP_CTRL 4
+/* WARNING: DO NOT EDIT, AUTO-GENERATED CODE - SEE TOP FOR INSTRUCTIONS */
+#define KVM_DEV_ARM_VGIC_CTRL_INIT 0
 #define KVM_ARM_IRQ_TYPE_SHIFT 24
 #define KVM_ARM_IRQ_TYPE_MASK 0xff
 #define KVM_ARM_IRQ_VCPU_SHIFT 16
@@ -147,18 +167,19 @@
 #define KVM_ARM_IRQ_CPU_FIQ 1
 /* WARNING: DO NOT EDIT, AUTO-GENERATED CODE - SEE TOP FOR INSTRUCTIONS */
 #define KVM_ARM_IRQ_GIC_MAX 127
+#define KVM_NR_IRQCHIPS 1
 #define KVM_PSCI_FN_BASE 0x95c1ba5e
 #define KVM_PSCI_FN(n) (KVM_PSCI_FN_BASE + (n))
-#define KVM_PSCI_FN_CPU_SUSPEND KVM_PSCI_FN(0)
 /* WARNING: DO NOT EDIT, AUTO-GENERATED CODE - SEE TOP FOR INSTRUCTIONS */
+#define KVM_PSCI_FN_CPU_SUSPEND KVM_PSCI_FN(0)
 #define KVM_PSCI_FN_CPU_OFF KVM_PSCI_FN(1)
 #define KVM_PSCI_FN_CPU_ON KVM_PSCI_FN(2)
 #define KVM_PSCI_FN_MIGRATE KVM_PSCI_FN(3)
-#define KVM_PSCI_RET_SUCCESS PSCI_RET_SUCCESS
 /* WARNING: DO NOT EDIT, AUTO-GENERATED CODE - SEE TOP FOR INSTRUCTIONS */
+#define KVM_PSCI_RET_SUCCESS PSCI_RET_SUCCESS
 #define KVM_PSCI_RET_NI PSCI_RET_NOT_SUPPORTED
 #define KVM_PSCI_RET_INVAL PSCI_RET_INVALID_PARAMS
 #define KVM_PSCI_RET_DENIED PSCI_RET_DENIED
-#endif
 /* WARNING: DO NOT EDIT, AUTO-GENERATED CODE - SEE TOP FOR INSTRUCTIONS */
 #endif
+#endif
diff --git a/libc/kernel/uapi/asm-arm64/asm/ptrace.h b/libc/kernel/uapi/asm-arm64/asm/ptrace.h
index ec531f9..37148f5 100644
--- a/libc/kernel/uapi/asm-arm64/asm/ptrace.h
+++ b/libc/kernel/uapi/asm-arm64/asm/ptrace.h
@@ -37,43 +37,44 @@
 #define PSR_A_BIT 0x00000100
 /* WARNING: DO NOT EDIT, AUTO-GENERATED CODE - SEE TOP FOR INSTRUCTIONS */
 #define PSR_D_BIT 0x00000200
+#define PSR_PAN_BIT 0x00400000
 #define PSR_Q_BIT 0x08000000
 #define PSR_V_BIT 0x10000000
-#define PSR_C_BIT 0x20000000
 /* WARNING: DO NOT EDIT, AUTO-GENERATED CODE - SEE TOP FOR INSTRUCTIONS */
+#define PSR_C_BIT 0x20000000
 #define PSR_Z_BIT 0x40000000
 #define PSR_N_BIT 0x80000000
 #define PSR_f 0xff000000
-#define PSR_s 0x00ff0000
 /* WARNING: DO NOT EDIT, AUTO-GENERATED CODE - SEE TOP FOR INSTRUCTIONS */
+#define PSR_s 0x00ff0000
 #define PSR_x 0x0000ff00
 #define PSR_c 0x000000ff
 #ifndef __ASSEMBLY__
-struct user_pt_regs {
 /* WARNING: DO NOT EDIT, AUTO-GENERATED CODE - SEE TOP FOR INSTRUCTIONS */
+struct user_pt_regs {
   __u64 regs[31];
   __u64 sp;
   __u64 pc;
-  __u64 pstate;
 /* WARNING: DO NOT EDIT, AUTO-GENERATED CODE - SEE TOP FOR INSTRUCTIONS */
+  __u64 pstate;
 };
 struct user_fpsimd_state {
   __uint128_t vregs[32];
-  __u32 fpsr;
 /* WARNING: DO NOT EDIT, AUTO-GENERATED CODE - SEE TOP FOR INSTRUCTIONS */
+  __u32 fpsr;
   __u32 fpcr;
 };
 struct user_hwdebug_state {
-  __u32 dbg_info;
 /* WARNING: DO NOT EDIT, AUTO-GENERATED CODE - SEE TOP FOR INSTRUCTIONS */
+  __u32 dbg_info;
   __u32 pad;
   struct {
     __u64 addr;
-    __u32 ctrl;
 /* WARNING: DO NOT EDIT, AUTO-GENERATED CODE - SEE TOP FOR INSTRUCTIONS */
+    __u32 ctrl;
     __u32 pad;
   } dbg_regs[16];
 };
-#endif
 /* WARNING: DO NOT EDIT, AUTO-GENERATED CODE - SEE TOP FOR INSTRUCTIONS */
 #endif
+#endif
diff --git a/libc/kernel/uapi/asm-arm64/asm/signal.h b/libc/kernel/uapi/asm-arm64/asm/signal.h
index 39f8c48..0ff3e96 100644
--- a/libc/kernel/uapi/asm-arm64/asm/signal.h
+++ b/libc/kernel/uapi/asm-arm64/asm/signal.h
@@ -19,6 +19,8 @@
 #ifndef __ASM_SIGNAL_H
 #define __ASM_SIGNAL_H
 #define SA_RESTORER 0x04000000
-#include <asm-generic/signal.h>
+#define MINSIGSTKSZ 5120
 /* WARNING: DO NOT EDIT, AUTO-GENERATED CODE - SEE TOP FOR INSTRUCTIONS */
+#define SIGSTKSZ 16384
+#include <asm-generic/signal.h>
 #endif
diff --git a/libc/kernel/uapi/asm-arm64/asm/ucontext.h b/libc/kernel/uapi/asm-arm64/asm/ucontext.h
new file mode 100644
index 0000000..edb9155
--- /dev/null
+++ b/libc/kernel/uapi/asm-arm64/asm/ucontext.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 _UAPI__ASM_UCONTEXT_H
+#define _UAPI__ASM_UCONTEXT_H
+#include <linux/types.h>
+struct ucontext {
+/* WARNING: DO NOT EDIT, AUTO-GENERATED CODE - SEE TOP FOR INSTRUCTIONS */
+  unsigned long uc_flags;
+  struct ucontext * uc_link;
+  stack_t uc_stack;
+  sigset_t uc_sigmask;
+/* WARNING: DO NOT EDIT, AUTO-GENERATED CODE - SEE TOP FOR INSTRUCTIONS */
+  __u8 __linux_unused[1024 / 8 - sizeof(sigset_t)];
+  struct sigcontext uc_mcontext;
+};
+#endif
+/* WARNING: DO NOT EDIT, AUTO-GENERATED CODE - SEE TOP FOR INSTRUCTIONS */
diff --git a/libc/kernel/uapi/asm-generic/mman-common.h b/libc/kernel/uapi/asm-generic/mman-common.h
index 8e6a57f..00075c7 100644
--- a/libc/kernel/uapi/asm-generic/mman-common.h
+++ b/libc/kernel/uapi/asm-generic/mman-common.h
@@ -34,32 +34,33 @@
 #define MAP_FIXED 0x10
 #define MAP_ANONYMOUS 0x20
 #define MAP_UNINITIALIZED 0x0
-#define MS_ASYNC 1
+#define MLOCK_ONFAULT 0x01
 /* WARNING: DO NOT EDIT, AUTO-GENERATED CODE - SEE TOP FOR INSTRUCTIONS */
+#define MS_ASYNC 1
 #define MS_INVALIDATE 2
 #define MS_SYNC 4
 #define MADV_NORMAL 0
-#define MADV_RANDOM 1
 /* WARNING: DO NOT EDIT, AUTO-GENERATED CODE - SEE TOP FOR INSTRUCTIONS */
+#define MADV_RANDOM 1
 #define MADV_SEQUENTIAL 2
 #define MADV_WILLNEED 3
 #define MADV_DONTNEED 4
-#define MADV_REMOVE 9
 /* WARNING: DO NOT EDIT, AUTO-GENERATED CODE - SEE TOP FOR INSTRUCTIONS */
+#define MADV_REMOVE 9
 #define MADV_DONTFORK 10
 #define MADV_DOFORK 11
 #define MADV_HWPOISON 100
-#define MADV_SOFT_OFFLINE 101
 /* WARNING: DO NOT EDIT, AUTO-GENERATED CODE - SEE TOP FOR INSTRUCTIONS */
+#define MADV_SOFT_OFFLINE 101
 #define MADV_MERGEABLE 12
 #define MADV_UNMERGEABLE 13
 #define MADV_HUGEPAGE 14
-#define MADV_NOHUGEPAGE 15
 /* WARNING: DO NOT EDIT, AUTO-GENERATED CODE - SEE TOP FOR INSTRUCTIONS */
+#define MADV_NOHUGEPAGE 15
 #define MADV_DONTDUMP 16
 #define MADV_DODUMP 17
 #define MAP_FILE 0
-#define MAP_HUGE_SHIFT 26
 /* WARNING: DO NOT EDIT, AUTO-GENERATED CODE - SEE TOP FOR INSTRUCTIONS */
+#define MAP_HUGE_SHIFT 26
 #define MAP_HUGE_MASK 0x3f
 #endif
diff --git a/libc/kernel/uapi/asm-generic/mman.h b/libc/kernel/uapi/asm-generic/mman.h
index 5a0242a..5db0e52 100644
--- a/libc/kernel/uapi/asm-generic/mman.h
+++ b/libc/kernel/uapi/asm-generic/mman.h
@@ -33,4 +33,6 @@
 /* WARNING: DO NOT EDIT, AUTO-GENERATED CODE - SEE TOP FOR INSTRUCTIONS */
 #define MCL_CURRENT 1
 #define MCL_FUTURE 2
+#define MCL_ONFAULT 4
 #endif
+/* WARNING: DO NOT EDIT, AUTO-GENERATED CODE - SEE TOP FOR INSTRUCTIONS */
diff --git a/libc/kernel/uapi/asm-generic/siginfo.h b/libc/kernel/uapi/asm-generic/siginfo.h
index 2083fa1..ad54529 100644
--- a/libc/kernel/uapi/asm-generic/siginfo.h
+++ b/libc/kernel/uapi/asm-generic/siginfo.h
@@ -94,6 +94,11 @@
       int _trapno;
 #endif
       short _addr_lsb;
+      struct {
+/* WARNING: DO NOT EDIT, AUTO-GENERATED CODE - SEE TOP FOR INSTRUCTIONS */
+        void __user * _lower;
+        void __user * _upper;
+      } _addr_bnd;
     } _sigfault;
 /* WARNING: DO NOT EDIT, AUTO-GENERATED CODE - SEE TOP FOR INSTRUCTIONS */
     struct {
@@ -132,129 +137,133 @@
 #endif
 /* WARNING: DO NOT EDIT, AUTO-GENERATED CODE - SEE TOP FOR INSTRUCTIONS */
 #define si_addr_lsb _sifields._sigfault._addr_lsb
+#define si_lower _sifields._sigfault._addr_bnd._lower
+#define si_upper _sifields._sigfault._addr_bnd._upper
 #define si_band _sifields._sigpoll._band
+/* WARNING: DO NOT EDIT, AUTO-GENERATED CODE - SEE TOP FOR INSTRUCTIONS */
 #define si_fd _sifields._sigpoll._fd
 #ifdef __ARCH_SIGSYS
-/* WARNING: DO NOT EDIT, AUTO-GENERATED CODE - SEE TOP FOR INSTRUCTIONS */
 #define si_call_addr _sifields._sigsys._call_addr
 #define si_syscall _sifields._sigsys._syscall
+/* WARNING: DO NOT EDIT, AUTO-GENERATED CODE - SEE TOP FOR INSTRUCTIONS */
 #define si_arch _sifields._sigsys._arch
 #endif
-/* WARNING: DO NOT EDIT, AUTO-GENERATED CODE - SEE TOP FOR INSTRUCTIONS */
 #define __SI_KILL 0
 #define __SI_TIMER 0
+/* WARNING: DO NOT EDIT, AUTO-GENERATED CODE - SEE TOP FOR INSTRUCTIONS */
 #define __SI_POLL 0
 #define __SI_FAULT 0
-/* WARNING: DO NOT EDIT, AUTO-GENERATED CODE - SEE TOP FOR INSTRUCTIONS */
 #define __SI_CHLD 0
 #define __SI_RT 0
+/* WARNING: DO NOT EDIT, AUTO-GENERATED CODE - SEE TOP FOR INSTRUCTIONS */
 #define __SI_MESGQ 0
 #define __SI_SYS 0
-/* WARNING: DO NOT EDIT, AUTO-GENERATED CODE - SEE TOP FOR INSTRUCTIONS */
 #define __SI_CODE(T,N) (N)
 #define SI_USER 0
+/* WARNING: DO NOT EDIT, AUTO-GENERATED CODE - SEE TOP FOR INSTRUCTIONS */
 #define SI_KERNEL 0x80
 #define SI_QUEUE - 1
-/* WARNING: DO NOT EDIT, AUTO-GENERATED CODE - SEE TOP FOR INSTRUCTIONS */
 #define SI_TIMER __SI_CODE(__SI_TIMER, - 2)
 #define SI_MESGQ __SI_CODE(__SI_MESGQ, - 3)
+/* WARNING: DO NOT EDIT, AUTO-GENERATED CODE - SEE TOP FOR INSTRUCTIONS */
 #define SI_ASYNCIO - 4
 #define SI_SIGIO - 5
-/* WARNING: DO NOT EDIT, AUTO-GENERATED CODE - SEE TOP FOR INSTRUCTIONS */
 #define SI_TKILL - 6
 #define SI_DETHREAD - 7
+/* WARNING: DO NOT EDIT, AUTO-GENERATED CODE - SEE TOP FOR INSTRUCTIONS */
 #define SI_FROMUSER(siptr) ((siptr)->si_code <= 0)
 #define SI_FROMKERNEL(siptr) ((siptr)->si_code > 0)
-/* WARNING: DO NOT EDIT, AUTO-GENERATED CODE - SEE TOP FOR INSTRUCTIONS */
 #define ILL_ILLOPC (__SI_FAULT | 1)
 #define ILL_ILLOPN (__SI_FAULT | 2)
+/* WARNING: DO NOT EDIT, AUTO-GENERATED CODE - SEE TOP FOR INSTRUCTIONS */
 #define ILL_ILLADR (__SI_FAULT | 3)
 #define ILL_ILLTRP (__SI_FAULT | 4)
-/* WARNING: DO NOT EDIT, AUTO-GENERATED CODE - SEE TOP FOR INSTRUCTIONS */
 #define ILL_PRVOPC (__SI_FAULT | 5)
 #define ILL_PRVREG (__SI_FAULT | 6)
+/* WARNING: DO NOT EDIT, AUTO-GENERATED CODE - SEE TOP FOR INSTRUCTIONS */
 #define ILL_COPROC (__SI_FAULT | 7)
 #define ILL_BADSTK (__SI_FAULT | 8)
-/* WARNING: DO NOT EDIT, AUTO-GENERATED CODE - SEE TOP FOR INSTRUCTIONS */
 #define NSIGILL 8
 #define FPE_INTDIV (__SI_FAULT | 1)
+/* WARNING: DO NOT EDIT, AUTO-GENERATED CODE - SEE TOP FOR INSTRUCTIONS */
 #define FPE_INTOVF (__SI_FAULT | 2)
 #define FPE_FLTDIV (__SI_FAULT | 3)
-/* WARNING: DO NOT EDIT, AUTO-GENERATED CODE - SEE TOP FOR INSTRUCTIONS */
 #define FPE_FLTOVF (__SI_FAULT | 4)
 #define FPE_FLTUND (__SI_FAULT | 5)
+/* WARNING: DO NOT EDIT, AUTO-GENERATED CODE - SEE TOP FOR INSTRUCTIONS */
 #define FPE_FLTRES (__SI_FAULT | 6)
 #define FPE_FLTINV (__SI_FAULT | 7)
-/* WARNING: DO NOT EDIT, AUTO-GENERATED CODE - SEE TOP FOR INSTRUCTIONS */
 #define FPE_FLTSUB (__SI_FAULT | 8)
 #define NSIGFPE 8
+/* WARNING: DO NOT EDIT, AUTO-GENERATED CODE - SEE TOP FOR INSTRUCTIONS */
 #define SEGV_MAPERR (__SI_FAULT | 1)
 #define SEGV_ACCERR (__SI_FAULT | 2)
+#define SEGV_BNDERR (__SI_FAULT | 3)
+#define NSIGSEGV 3
 /* WARNING: DO NOT EDIT, AUTO-GENERATED CODE - SEE TOP FOR INSTRUCTIONS */
-#define NSIGSEGV 2
 #define BUS_ADRALN (__SI_FAULT | 1)
 #define BUS_ADRERR (__SI_FAULT | 2)
 #define BUS_OBJERR (__SI_FAULT | 3)
-/* WARNING: DO NOT EDIT, AUTO-GENERATED CODE - SEE TOP FOR INSTRUCTIONS */
 #define BUS_MCEERR_AR (__SI_FAULT | 4)
+/* WARNING: DO NOT EDIT, AUTO-GENERATED CODE - SEE TOP FOR INSTRUCTIONS */
 #define BUS_MCEERR_AO (__SI_FAULT | 5)
 #define NSIGBUS 5
 #define TRAP_BRKPT (__SI_FAULT | 1)
-/* WARNING: DO NOT EDIT, AUTO-GENERATED CODE - SEE TOP FOR INSTRUCTIONS */
 #define TRAP_TRACE (__SI_FAULT | 2)
+/* WARNING: DO NOT EDIT, AUTO-GENERATED CODE - SEE TOP FOR INSTRUCTIONS */
 #define TRAP_BRANCH (__SI_FAULT | 3)
 #define TRAP_HWBKPT (__SI_FAULT | 4)
 #define NSIGTRAP 4
-/* WARNING: DO NOT EDIT, AUTO-GENERATED CODE - SEE TOP FOR INSTRUCTIONS */
 #define CLD_EXITED (__SI_CHLD | 1)
+/* WARNING: DO NOT EDIT, AUTO-GENERATED CODE - SEE TOP FOR INSTRUCTIONS */
 #define CLD_KILLED (__SI_CHLD | 2)
 #define CLD_DUMPED (__SI_CHLD | 3)
 #define CLD_TRAPPED (__SI_CHLD | 4)
-/* WARNING: DO NOT EDIT, AUTO-GENERATED CODE - SEE TOP FOR INSTRUCTIONS */
 #define CLD_STOPPED (__SI_CHLD | 5)
+/* WARNING: DO NOT EDIT, AUTO-GENERATED CODE - SEE TOP FOR INSTRUCTIONS */
 #define CLD_CONTINUED (__SI_CHLD | 6)
 #define NSIGCHLD 6
 #define POLL_IN (__SI_POLL | 1)
-/* WARNING: DO NOT EDIT, AUTO-GENERATED CODE - SEE TOP FOR INSTRUCTIONS */
 #define POLL_OUT (__SI_POLL | 2)
+/* WARNING: DO NOT EDIT, AUTO-GENERATED CODE - SEE TOP FOR INSTRUCTIONS */
 #define POLL_MSG (__SI_POLL | 3)
 #define POLL_ERR (__SI_POLL | 4)
 #define POLL_PRI (__SI_POLL | 5)
-/* WARNING: DO NOT EDIT, AUTO-GENERATED CODE - SEE TOP FOR INSTRUCTIONS */
 #define POLL_HUP (__SI_POLL | 6)
+/* WARNING: DO NOT EDIT, AUTO-GENERATED CODE - SEE TOP FOR INSTRUCTIONS */
 #define NSIGPOLL 6
 #define SYS_SECCOMP (__SI_SYS | 1)
 #define NSIGSYS 1
-/* WARNING: DO NOT EDIT, AUTO-GENERATED CODE - SEE TOP FOR INSTRUCTIONS */
 #define SIGEV_SIGNAL 0
+/* WARNING: DO NOT EDIT, AUTO-GENERATED CODE - SEE TOP FOR INSTRUCTIONS */
 #define SIGEV_NONE 1
 #define SIGEV_THREAD 2
 #define SIGEV_THREAD_ID 4
-/* WARNING: DO NOT EDIT, AUTO-GENERATED CODE - SEE TOP FOR INSTRUCTIONS */
 #ifndef __ARCH_SIGEV_PREAMBLE_SIZE
+/* WARNING: DO NOT EDIT, AUTO-GENERATED CODE - SEE TOP FOR INSTRUCTIONS */
 #define __ARCH_SIGEV_PREAMBLE_SIZE (sizeof(int) * 2 + sizeof(sigval_t))
 #endif
 #define SIGEV_MAX_SIZE 64
-/* WARNING: DO NOT EDIT, AUTO-GENERATED CODE - SEE TOP FOR INSTRUCTIONS */
 #define SIGEV_PAD_SIZE ((SIGEV_MAX_SIZE - __ARCH_SIGEV_PREAMBLE_SIZE) / sizeof(int))
+/* WARNING: DO NOT EDIT, AUTO-GENERATED CODE - SEE TOP FOR INSTRUCTIONS */
 typedef struct sigevent {
   sigval_t sigev_value;
   int sigev_signo;
-/* WARNING: DO NOT EDIT, AUTO-GENERATED CODE - SEE TOP FOR INSTRUCTIONS */
   int sigev_notify;
+/* WARNING: DO NOT EDIT, AUTO-GENERATED CODE - SEE TOP FOR INSTRUCTIONS */
   union {
     int _pad[SIGEV_PAD_SIZE];
     int _tid;
-/* WARNING: DO NOT EDIT, AUTO-GENERATED CODE - SEE TOP FOR INSTRUCTIONS */
     struct {
+/* WARNING: DO NOT EDIT, AUTO-GENERATED CODE - SEE TOP FOR INSTRUCTIONS */
       void(* _function) (sigval_t);
       void * _attribute;
     } _sigev_thread;
-/* WARNING: DO NOT EDIT, AUTO-GENERATED CODE - SEE TOP FOR INSTRUCTIONS */
   } _sigev_un;
+/* WARNING: DO NOT EDIT, AUTO-GENERATED CODE - SEE TOP FOR INSTRUCTIONS */
 } sigevent_t;
 #define sigev_notify_function _sigev_un._sigev_thread._function
 #define sigev_notify_attributes _sigev_un._sigev_thread._attribute
-/* WARNING: DO NOT EDIT, AUTO-GENERATED CODE - SEE TOP FOR INSTRUCTIONS */
 #define sigev_notify_thread_id _sigev_un._tid
+/* WARNING: DO NOT EDIT, AUTO-GENERATED CODE - SEE TOP FOR INSTRUCTIONS */
 #endif
diff --git a/libc/kernel/uapi/asm-generic/signal.h b/libc/kernel/uapi/asm-generic/signal.h
index 30188cb..d63fd3e 100644
--- a/libc/kernel/uapi/asm-generic/signal.h
+++ b/libc/kernel/uapi/asm-generic/signal.h
@@ -82,35 +82,38 @@
 #define SA_NOMASK SA_NODEFER
 /* WARNING: DO NOT EDIT, AUTO-GENERATED CODE - SEE TOP FOR INSTRUCTIONS */
 #define SA_ONESHOT SA_RESETHAND
+#if !defined(MINSIGSTKSZ) || !defined(SIGSTKSZ)
 #define MINSIGSTKSZ 2048
 #define SIGSTKSZ 8192
-#ifndef __ASSEMBLY__
 /* WARNING: DO NOT EDIT, AUTO-GENERATED CODE - SEE TOP FOR INSTRUCTIONS */
+#endif
+#ifndef __ASSEMBLY__
 typedef struct {
   unsigned long sig[_NSIG_WORDS];
+/* WARNING: DO NOT EDIT, AUTO-GENERATED CODE - SEE TOP FOR INSTRUCTIONS */
 } sigset_t;
 typedef unsigned long old_sigset_t;
-/* WARNING: DO NOT EDIT, AUTO-GENERATED CODE - SEE TOP FOR INSTRUCTIONS */
 #include <asm-generic/signal-defs.h>
 #ifdef SA_RESTORER
+/* WARNING: DO NOT EDIT, AUTO-GENERATED CODE - SEE TOP FOR INSTRUCTIONS */
 #define __ARCH_HAS_SA_RESTORER
 #endif
-/* WARNING: DO NOT EDIT, AUTO-GENERATED CODE - SEE TOP FOR INSTRUCTIONS */
 struct sigaction {
   __sighandler_t sa_handler;
+/* WARNING: DO NOT EDIT, AUTO-GENERATED CODE - SEE TOP FOR INSTRUCTIONS */
   unsigned long sa_flags;
 #ifdef SA_RESTORER
-/* WARNING: DO NOT EDIT, AUTO-GENERATED CODE - SEE TOP FOR INSTRUCTIONS */
   __sigrestore_t sa_restorer;
 #endif
+/* WARNING: DO NOT EDIT, AUTO-GENERATED CODE - SEE TOP FOR INSTRUCTIONS */
   sigset_t sa_mask;
 };
-/* WARNING: DO NOT EDIT, AUTO-GENERATED CODE - SEE TOP FOR INSTRUCTIONS */
 typedef struct sigaltstack {
   void __user * ss_sp;
+/* WARNING: DO NOT EDIT, AUTO-GENERATED CODE - SEE TOP FOR INSTRUCTIONS */
   int ss_flags;
   size_t ss_size;
-/* WARNING: DO NOT EDIT, AUTO-GENERATED CODE - SEE TOP FOR INSTRUCTIONS */
 } stack_t;
 #endif
+/* WARNING: DO NOT EDIT, AUTO-GENERATED CODE - SEE TOP FOR INSTRUCTIONS */
 #endif
diff --git a/libc/kernel/uapi/asm-generic/socket.h b/libc/kernel/uapi/asm-generic/socket.h
index 93daf83..ec38e2c 100644
--- a/libc/kernel/uapi/asm-generic/socket.h
+++ b/libc/kernel/uapi/asm-generic/socket.h
@@ -89,5 +89,8 @@
 #define SO_BUSY_POLL 46
 #define SO_MAX_PACING_RATE 47
 #define SO_BPF_EXTENSIONS 48
-#endif
+#define SO_INCOMING_CPU 49
 /* WARNING: DO NOT EDIT, AUTO-GENERATED CODE - SEE TOP FOR INSTRUCTIONS */
+#define SO_ATTACH_BPF 50
+#define SO_DETACH_BPF SO_DETACH_FILTER
+#endif
diff --git a/libc/kernel/uapi/asm-generic/unistd.h b/libc/kernel/uapi/asm-generic/unistd.h
index d7ac6c2..635a123 100644
--- a/libc/kernel/uapi/asm-generic/unistd.h
+++ b/libc/kernel/uapi/asm-generic/unistd.h
@@ -377,8 +377,13 @@
 #define __NR_memfd_create 279
 /* WARNING: DO NOT EDIT, AUTO-GENERATED CODE - SEE TOP FOR INSTRUCTIONS */
 #define __NR_bpf 280
+#define __NR_execveat 281
+#define __NR_userfaultfd 282
+#define __NR_membarrier 283
+/* WARNING: DO NOT EDIT, AUTO-GENERATED CODE - SEE TOP FOR INSTRUCTIONS */
+#define __NR_mlock2 284
 #undef __NR_syscalls
-#define __NR_syscalls 281
+#define __NR_syscalls 285
 #ifdef __ARCH_WANT_SYSCALL_NO_AT
 /* WARNING: DO NOT EDIT, AUTO-GENERATED CODE - SEE TOP FOR INSTRUCTIONS */
 #define __NR_open 1024
diff --git a/libc/kernel/uapi/asm-mips/asm/break.h b/libc/kernel/uapi/asm-mips/asm/break.h
index 7834e51..d7f3089 100644
--- a/libc/kernel/uapi/asm-mips/asm/break.h
+++ b/libc/kernel/uapi/asm-mips/asm/break.h
@@ -26,9 +26,11 @@
 #define BRK_RANGE 8
 #define BRK_BUG 12
 /* WARNING: DO NOT EDIT, AUTO-GENERATED CODE - SEE TOP FOR INSTRUCTIONS */
+#define BRK_UPROBE 13
+#define BRK_UPROBE_XOL 14
 #define BRK_MEMU 514
 #define BRK_KPROBE_BP 515
+/* WARNING: DO NOT EDIT, AUTO-GENERATED CODE - SEE TOP FOR INSTRUCTIONS */
 #define BRK_KPROBE_SSTEPBP 516
 #define BRK_MULOVF 1023
-/* WARNING: DO NOT EDIT, AUTO-GENERATED CODE - SEE TOP FOR INSTRUCTIONS */
 #endif
diff --git a/libc/kernel/uapi/asm-mips/asm/hwcap.h b/libc/kernel/uapi/asm-mips/asm/hwcap.h
new file mode 100644
index 0000000..cc4c30c
--- /dev/null
+++ b/libc/kernel/uapi/asm-mips/asm/hwcap.h
@@ -0,0 +1,24 @@
+/****************************************************************************
+ ****************************************************************************
+ ***
+ ***   This header was automatically generated from a Linux kernel header
+ ***   of the same name, to make information necessary for userspace to
+ ***   call into the kernel available to libc.  It contains only constants,
+ ***   structures, and macros generated from the original header, and thus,
+ ***   contains no copyrightable information.
+ ***
+ ***   To edit the content of this header, modify the corresponding
+ ***   source file (e.g. under external/kernel-headers/original/) then
+ ***   run bionic/libc/kernel/tools/update_all.py
+ ***
+ ***   Any manual change here will be lost the next time this script will
+ ***   be run. You've been warned!
+ ***
+ ****************************************************************************
+ ****************************************************************************/
+#ifndef _UAPI_ASM_HWCAP_H
+#define _UAPI_ASM_HWCAP_H
+#define HWCAP_MIPS_R6 (1 << 0)
+#define HWCAP_MIPS_MSA (1 << 1)
+/* WARNING: DO NOT EDIT, AUTO-GENERATED CODE - SEE TOP FOR INSTRUCTIONS */
+#endif
diff --git a/libc/kernel/uapi/asm-mips/asm/inst.h b/libc/kernel/uapi/asm-mips/asm/inst.h
index e9b8372..7446223 100644
--- a/libc/kernel/uapi/asm-mips/asm/inst.h
+++ b/libc/kernel/uapi/asm-mips/asm/inst.h
@@ -32,1019 +32,1072 @@
   bgtz_op,
 /* WARNING: DO NOT EDIT, AUTO-GENERATED CODE - SEE TOP FOR INSTRUCTIONS */
   addi_op,
+  cbcond0_op = addi_op,
   addiu_op,
   slti_op,
-  sltiu_op,
 /* WARNING: DO NOT EDIT, AUTO-GENERATED CODE - SEE TOP FOR INSTRUCTIONS */
+  sltiu_op,
   andi_op,
   ori_op,
   xori_op,
-  lui_op,
 /* WARNING: DO NOT EDIT, AUTO-GENERATED CODE - SEE TOP FOR INSTRUCTIONS */
+  lui_op,
   cop0_op,
   cop1_op,
   cop2_op,
-  cop1x_op,
 /* WARNING: DO NOT EDIT, AUTO-GENERATED CODE - SEE TOP FOR INSTRUCTIONS */
+  cop1x_op,
   beql_op,
   bnel_op,
   blezl_op,
-  bgtzl_op,
 /* WARNING: DO NOT EDIT, AUTO-GENERATED CODE - SEE TOP FOR INSTRUCTIONS */
+  bgtzl_op,
   daddi_op,
+  cbcond1_op = daddi_op,
   daddiu_op,
+/* WARNING: DO NOT EDIT, AUTO-GENERATED CODE - SEE TOP FOR INSTRUCTIONS */
   ldl_op,
   ldr_op,
-/* WARNING: DO NOT EDIT, AUTO-GENERATED CODE - SEE TOP FOR INSTRUCTIONS */
   spec2_op,
   jalx_op,
-  mdmx_op,
-  spec3_op,
 /* WARNING: DO NOT EDIT, AUTO-GENERATED CODE - SEE TOP FOR INSTRUCTIONS */
+  mdmx_op,
+  msa_op = mdmx_op,
+  spec3_op,
   lb_op,
+/* WARNING: DO NOT EDIT, AUTO-GENERATED CODE - SEE TOP FOR INSTRUCTIONS */
   lh_op,
   lwl_op,
   lw_op,
-/* WARNING: DO NOT EDIT, AUTO-GENERATED CODE - SEE TOP FOR INSTRUCTIONS */
   lbu_op,
+/* WARNING: DO NOT EDIT, AUTO-GENERATED CODE - SEE TOP FOR INSTRUCTIONS */
   lhu_op,
   lwr_op,
   lwu_op,
-/* WARNING: DO NOT EDIT, AUTO-GENERATED CODE - SEE TOP FOR INSTRUCTIONS */
   sb_op,
+/* WARNING: DO NOT EDIT, AUTO-GENERATED CODE - SEE TOP FOR INSTRUCTIONS */
   sh_op,
   swl_op,
   sw_op,
-/* WARNING: DO NOT EDIT, AUTO-GENERATED CODE - SEE TOP FOR INSTRUCTIONS */
   sdl_op,
+/* WARNING: DO NOT EDIT, AUTO-GENERATED CODE - SEE TOP FOR INSTRUCTIONS */
   sdr_op,
   swr_op,
   cache_op,
-/* WARNING: DO NOT EDIT, AUTO-GENERATED CODE - SEE TOP FOR INSTRUCTIONS */
   ll_op,
+/* WARNING: DO NOT EDIT, AUTO-GENERATED CODE - SEE TOP FOR INSTRUCTIONS */
   lwc1_op,
   lwc2_op,
+  bc6_op = lwc2_op,
   pref_op,
 /* WARNING: DO NOT EDIT, AUTO-GENERATED CODE - SEE TOP FOR INSTRUCTIONS */
   lld_op,
   ldc1_op,
   ldc2_op,
-  ld_op,
+  beqzcjic_op = ldc2_op,
 /* WARNING: DO NOT EDIT, AUTO-GENERATED CODE - SEE TOP FOR INSTRUCTIONS */
+  ld_op,
   sc_op,
   swc1_op,
   swc2_op,
-  major_3b_op,
 /* WARNING: DO NOT EDIT, AUTO-GENERATED CODE - SEE TOP FOR INSTRUCTIONS */
+  balc6_op = swc2_op,
+  major_3b_op,
   scd_op,
   sdc1_op,
-  sdc2_op,
-  sd_op
 /* WARNING: DO NOT EDIT, AUTO-GENERATED CODE - SEE TOP FOR INSTRUCTIONS */
+  sdc2_op,
+  bnezcjialc_op = sdc2_op,
+  sd_op
 };
+/* WARNING: DO NOT EDIT, AUTO-GENERATED CODE - SEE TOP FOR INSTRUCTIONS */
 enum spec_op {
   sll_op,
   movc_op,
-/* WARNING: DO NOT EDIT, AUTO-GENERATED CODE - SEE TOP FOR INSTRUCTIONS */
   srl_op,
+/* WARNING: DO NOT EDIT, AUTO-GENERATED CODE - SEE TOP FOR INSTRUCTIONS */
   sra_op,
   sllv_op,
   pmon_op,
-/* WARNING: DO NOT EDIT, AUTO-GENERATED CODE - SEE TOP FOR INSTRUCTIONS */
   srlv_op,
+/* WARNING: DO NOT EDIT, AUTO-GENERATED CODE - SEE TOP FOR INSTRUCTIONS */
   srav_op,
   jr_op,
   jalr_op,
-/* WARNING: DO NOT EDIT, AUTO-GENERATED CODE - SEE TOP FOR INSTRUCTIONS */
   movz_op,
+/* WARNING: DO NOT EDIT, AUTO-GENERATED CODE - SEE TOP FOR INSTRUCTIONS */
   movn_op,
   syscall_op,
   break_op,
-/* WARNING: DO NOT EDIT, AUTO-GENERATED CODE - SEE TOP FOR INSTRUCTIONS */
   spim_op,
+/* WARNING: DO NOT EDIT, AUTO-GENERATED CODE - SEE TOP FOR INSTRUCTIONS */
   sync_op,
   mfhi_op,
   mthi_op,
-/* WARNING: DO NOT EDIT, AUTO-GENERATED CODE - SEE TOP FOR INSTRUCTIONS */
   mflo_op,
+/* WARNING: DO NOT EDIT, AUTO-GENERATED CODE - SEE TOP FOR INSTRUCTIONS */
   mtlo_op,
   dsllv_op,
   spec2_unused_op,
-/* WARNING: DO NOT EDIT, AUTO-GENERATED CODE - SEE TOP FOR INSTRUCTIONS */
   dsrlv_op,
+/* WARNING: DO NOT EDIT, AUTO-GENERATED CODE - SEE TOP FOR INSTRUCTIONS */
   dsrav_op,
   mult_op,
   multu_op,
-/* WARNING: DO NOT EDIT, AUTO-GENERATED CODE - SEE TOP FOR INSTRUCTIONS */
   div_op,
+/* WARNING: DO NOT EDIT, AUTO-GENERATED CODE - SEE TOP FOR INSTRUCTIONS */
   divu_op,
   dmult_op,
   dmultu_op,
-/* WARNING: DO NOT EDIT, AUTO-GENERATED CODE - SEE TOP FOR INSTRUCTIONS */
   ddiv_op,
+/* WARNING: DO NOT EDIT, AUTO-GENERATED CODE - SEE TOP FOR INSTRUCTIONS */
   ddivu_op,
   add_op,
   addu_op,
-/* WARNING: DO NOT EDIT, AUTO-GENERATED CODE - SEE TOP FOR INSTRUCTIONS */
   sub_op,
+/* WARNING: DO NOT EDIT, AUTO-GENERATED CODE - SEE TOP FOR INSTRUCTIONS */
   subu_op,
   and_op,
   or_op,
-/* WARNING: DO NOT EDIT, AUTO-GENERATED CODE - SEE TOP FOR INSTRUCTIONS */
   xor_op,
+/* WARNING: DO NOT EDIT, AUTO-GENERATED CODE - SEE TOP FOR INSTRUCTIONS */
   nor_op,
   spec3_unused_op,
   spec4_unused_op,
-/* WARNING: DO NOT EDIT, AUTO-GENERATED CODE - SEE TOP FOR INSTRUCTIONS */
   slt_op,
+/* WARNING: DO NOT EDIT, AUTO-GENERATED CODE - SEE TOP FOR INSTRUCTIONS */
   sltu_op,
   dadd_op,
   daddu_op,
-/* WARNING: DO NOT EDIT, AUTO-GENERATED CODE - SEE TOP FOR INSTRUCTIONS */
   dsub_op,
+/* WARNING: DO NOT EDIT, AUTO-GENERATED CODE - SEE TOP FOR INSTRUCTIONS */
   dsubu_op,
   tge_op,
   tgeu_op,
-/* WARNING: DO NOT EDIT, AUTO-GENERATED CODE - SEE TOP FOR INSTRUCTIONS */
   tlt_op,
+/* WARNING: DO NOT EDIT, AUTO-GENERATED CODE - SEE TOP FOR INSTRUCTIONS */
   tltu_op,
   teq_op,
   spec5_unused_op,
-/* WARNING: DO NOT EDIT, AUTO-GENERATED CODE - SEE TOP FOR INSTRUCTIONS */
   tne_op,
+/* WARNING: DO NOT EDIT, AUTO-GENERATED CODE - SEE TOP FOR INSTRUCTIONS */
   spec6_unused_op,
   dsll_op,
   spec7_unused_op,
-/* WARNING: DO NOT EDIT, AUTO-GENERATED CODE - SEE TOP FOR INSTRUCTIONS */
   dsrl_op,
+/* WARNING: DO NOT EDIT, AUTO-GENERATED CODE - SEE TOP FOR INSTRUCTIONS */
   dsra_op,
   dsll32_op,
   spec8_unused_op,
-/* WARNING: DO NOT EDIT, AUTO-GENERATED CODE - SEE TOP FOR INSTRUCTIONS */
   dsrl32_op,
+/* WARNING: DO NOT EDIT, AUTO-GENERATED CODE - SEE TOP FOR INSTRUCTIONS */
   dsra32_op
 };
 enum spec2_op {
-/* WARNING: DO NOT EDIT, AUTO-GENERATED CODE - SEE TOP FOR INSTRUCTIONS */
   madd_op,
+/* WARNING: DO NOT EDIT, AUTO-GENERATED CODE - SEE TOP FOR INSTRUCTIONS */
   maddu_op,
   mul_op,
   spec2_3_unused_op,
-/* WARNING: DO NOT EDIT, AUTO-GENERATED CODE - SEE TOP FOR INSTRUCTIONS */
   msub_op,
+/* WARNING: DO NOT EDIT, AUTO-GENERATED CODE - SEE TOP FOR INSTRUCTIONS */
   msubu_op,
   clz_op = 0x20,
   clo_op,
-/* WARNING: DO NOT EDIT, AUTO-GENERATED CODE - SEE TOP FOR INSTRUCTIONS */
   dclz_op = 0x24,
+/* WARNING: DO NOT EDIT, AUTO-GENERATED CODE - SEE TOP FOR INSTRUCTIONS */
   dclo_op,
   sdbpp_op = 0x3f
 };
-/* WARNING: DO NOT EDIT, AUTO-GENERATED CODE - SEE TOP FOR INSTRUCTIONS */
 enum spec3_op {
+/* WARNING: DO NOT EDIT, AUTO-GENERATED CODE - SEE TOP FOR INSTRUCTIONS */
   ext_op,
   dextm_op,
   dextu_op,
-/* WARNING: DO NOT EDIT, AUTO-GENERATED CODE - SEE TOP FOR INSTRUCTIONS */
   dext_op,
+/* WARNING: DO NOT EDIT, AUTO-GENERATED CODE - SEE TOP FOR INSTRUCTIONS */
   ins_op,
   dinsm_op,
   dinsu_op,
-/* WARNING: DO NOT EDIT, AUTO-GENERATED CODE - SEE TOP FOR INSTRUCTIONS */
   dins_op,
+/* WARNING: DO NOT EDIT, AUTO-GENERATED CODE - SEE TOP FOR INSTRUCTIONS */
   yield_op = 0x09,
   lx_op = 0x0a,
   lwle_op = 0x19,
-/* WARNING: DO NOT EDIT, AUTO-GENERATED CODE - SEE TOP FOR INSTRUCTIONS */
   lwre_op = 0x1a,
+/* WARNING: DO NOT EDIT, AUTO-GENERATED CODE - SEE TOP FOR INSTRUCTIONS */
   cachee_op = 0x1b,
   sbe_op = 0x1c,
   she_op = 0x1d,
-/* WARNING: DO NOT EDIT, AUTO-GENERATED CODE - SEE TOP FOR INSTRUCTIONS */
   sce_op = 0x1e,
+/* WARNING: DO NOT EDIT, AUTO-GENERATED CODE - SEE TOP FOR INSTRUCTIONS */
   swe_op = 0x1f,
   bshfl_op = 0x20,
   swle_op = 0x21,
-/* WARNING: DO NOT EDIT, AUTO-GENERATED CODE - SEE TOP FOR INSTRUCTIONS */
   swre_op = 0x22,
+/* WARNING: DO NOT EDIT, AUTO-GENERATED CODE - SEE TOP FOR INSTRUCTIONS */
   prefe_op = 0x23,
   dbshfl_op = 0x24,
-  lbue_op = 0x28,
+  cache6_op = 0x25,
+  sc6_op = 0x26,
 /* WARNING: DO NOT EDIT, AUTO-GENERATED CODE - SEE TOP FOR INSTRUCTIONS */
+  scd6_op = 0x27,
+  lbue_op = 0x28,
   lhue_op = 0x29,
   lbe_op = 0x2c,
+/* WARNING: DO NOT EDIT, AUTO-GENERATED CODE - SEE TOP FOR INSTRUCTIONS */
   lhe_op = 0x2d,
   lle_op = 0x2e,
-/* WARNING: DO NOT EDIT, AUTO-GENERATED CODE - SEE TOP FOR INSTRUCTIONS */
   lwe_op = 0x2f,
+  pref6_op = 0x35,
+/* WARNING: DO NOT EDIT, AUTO-GENERATED CODE - SEE TOP FOR INSTRUCTIONS */
+  ll6_op = 0x36,
+  lld6_op = 0x37,
   rdhwr_op = 0x3b
 };
-enum rt_op {
 /* WARNING: DO NOT EDIT, AUTO-GENERATED CODE - SEE TOP FOR INSTRUCTIONS */
+enum rt_op {
   bltz_op,
   bgez_op,
   bltzl_op,
-  bgezl_op,
 /* WARNING: DO NOT EDIT, AUTO-GENERATED CODE - SEE TOP FOR INSTRUCTIONS */
+  bgezl_op,
   spimi_op,
   unused_rt_op_0x05,
   unused_rt_op_0x06,
-  unused_rt_op_0x07,
 /* WARNING: DO NOT EDIT, AUTO-GENERATED CODE - SEE TOP FOR INSTRUCTIONS */
+  unused_rt_op_0x07,
   tgei_op,
   tgeiu_op,
   tlti_op,
-  tltiu_op,
 /* WARNING: DO NOT EDIT, AUTO-GENERATED CODE - SEE TOP FOR INSTRUCTIONS */
+  tltiu_op,
   teqi_op,
   unused_0x0d_rt_op,
   tnei_op,
-  unused_0x0f_rt_op,
 /* WARNING: DO NOT EDIT, AUTO-GENERATED CODE - SEE TOP FOR INSTRUCTIONS */
+  unused_0x0f_rt_op,
   bltzal_op,
   bgezal_op,
   bltzall_op,
-  bgezall_op,
 /* WARNING: DO NOT EDIT, AUTO-GENERATED CODE - SEE TOP FOR INSTRUCTIONS */
+  bgezall_op,
   rt_op_0x14,
   rt_op_0x15,
   rt_op_0x16,
-  rt_op_0x17,
 /* WARNING: DO NOT EDIT, AUTO-GENERATED CODE - SEE TOP FOR INSTRUCTIONS */
+  rt_op_0x17,
   rt_op_0x18,
   rt_op_0x19,
   rt_op_0x1a,
-  rt_op_0x1b,
 /* WARNING: DO NOT EDIT, AUTO-GENERATED CODE - SEE TOP FOR INSTRUCTIONS */
+  rt_op_0x1b,
   bposge32_op,
   rt_op_0x1d,
   rt_op_0x1e,
-  rt_op_0x1f
 /* WARNING: DO NOT EDIT, AUTO-GENERATED CODE - SEE TOP FOR INSTRUCTIONS */
+  rt_op_0x1f
 };
 enum cop_op {
   mfc_op = 0x00,
-  dmfc_op = 0x01,
 /* WARNING: DO NOT EDIT, AUTO-GENERATED CODE - SEE TOP FOR INSTRUCTIONS */
+  dmfc_op = 0x01,
   cfc_op = 0x02,
+  mfhc0_op = 0x02,
   mfhc_op = 0x03,
+/* WARNING: DO NOT EDIT, AUTO-GENERATED CODE - SEE TOP FOR INSTRUCTIONS */
   mtc_op = 0x04,
   dmtc_op = 0x05,
-/* WARNING: DO NOT EDIT, AUTO-GENERATED CODE - SEE TOP FOR INSTRUCTIONS */
   ctc_op = 0x06,
+  mthc0_op = 0x06,
+/* WARNING: DO NOT EDIT, AUTO-GENERATED CODE - SEE TOP FOR INSTRUCTIONS */
   mthc_op = 0x07,
   bc_op = 0x08,
-  cop_op = 0x10,
+  bc1eqz_op = 0x09,
+  bc1nez_op = 0x0d,
 /* WARNING: DO NOT EDIT, AUTO-GENERATED CODE - SEE TOP FOR INSTRUCTIONS */
+  cop_op = 0x10,
   copm_op = 0x18
 };
 enum bcop_op {
-  bcf_op,
 /* WARNING: DO NOT EDIT, AUTO-GENERATED CODE - SEE TOP FOR INSTRUCTIONS */
+  bcf_op,
   bct_op,
   bcfl_op,
   bctl_op
-};
 /* WARNING: DO NOT EDIT, AUTO-GENERATED CODE - SEE TOP FOR INSTRUCTIONS */
+};
 enum cop0_coi_func {
   tlbr_op = 0x01,
   tlbwi_op = 0x02,
-  tlbwr_op = 0x06,
 /* WARNING: DO NOT EDIT, AUTO-GENERATED CODE - SEE TOP FOR INSTRUCTIONS */
+  tlbwr_op = 0x06,
   tlbp_op = 0x08,
   rfe_op = 0x10,
   eret_op = 0x18,
-  wait_op = 0x20,
 /* WARNING: DO NOT EDIT, AUTO-GENERATED CODE - SEE TOP FOR INSTRUCTIONS */
+  wait_op = 0x20,
 };
 enum cop0_com_func {
   tlbr1_op = 0x01,
-  tlbw_op = 0x02,
 /* WARNING: DO NOT EDIT, AUTO-GENERATED CODE - SEE TOP FOR INSTRUCTIONS */
+  tlbw_op = 0x02,
   tlbp1_op = 0x08,
   dctr_op = 0x09,
   dctw_op = 0x0a
-};
 /* WARNING: DO NOT EDIT, AUTO-GENERATED CODE - SEE TOP FOR INSTRUCTIONS */
+};
 enum cop1_fmt {
   s_fmt,
   d_fmt,
-  e_fmt,
 /* WARNING: DO NOT EDIT, AUTO-GENERATED CODE - SEE TOP FOR INSTRUCTIONS */
+  e_fmt,
   q_fmt,
   w_fmt,
   l_fmt
-};
 /* WARNING: DO NOT EDIT, AUTO-GENERATED CODE - SEE TOP FOR INSTRUCTIONS */
+};
 enum cop1_sdw_func {
   fadd_op = 0x00,
   fsub_op = 0x01,
-  fmul_op = 0x02,
 /* WARNING: DO NOT EDIT, AUTO-GENERATED CODE - SEE TOP FOR INSTRUCTIONS */
+  fmul_op = 0x02,
   fdiv_op = 0x03,
   fsqrt_op = 0x04,
   fabs_op = 0x05,
-  fmov_op = 0x06,
 /* WARNING: DO NOT EDIT, AUTO-GENERATED CODE - SEE TOP FOR INSTRUCTIONS */
+  fmov_op = 0x06,
   fneg_op = 0x07,
   froundl_op = 0x08,
   ftruncl_op = 0x09,
-  fceill_op = 0x0a,
 /* WARNING: DO NOT EDIT, AUTO-GENERATED CODE - SEE TOP FOR INSTRUCTIONS */
+  fceill_op = 0x0a,
   ffloorl_op = 0x0b,
   fround_op = 0x0c,
   ftrunc_op = 0x0d,
-  fceil_op = 0x0e,
 /* WARNING: DO NOT EDIT, AUTO-GENERATED CODE - SEE TOP FOR INSTRUCTIONS */
+  fceil_op = 0x0e,
   ffloor_op = 0x0f,
   fmovc_op = 0x11,
   fmovz_op = 0x12,
-  fmovn_op = 0x13,
 /* WARNING: DO NOT EDIT, AUTO-GENERATED CODE - SEE TOP FOR INSTRUCTIONS */
+  fmovn_op = 0x13,
+  fseleqz_op = 0x14,
   frecip_op = 0x15,
   frsqrt_op = 0x16,
+/* WARNING: DO NOT EDIT, AUTO-GENERATED CODE - SEE TOP FOR INSTRUCTIONS */
+  fselnez_op = 0x17,
+  fmaddf_op = 0x18,
+  fmsubf_op = 0x19,
+  frint_op = 0x1a,
+/* WARNING: DO NOT EDIT, AUTO-GENERATED CODE - SEE TOP FOR INSTRUCTIONS */
+  fclass_op = 0x1b,
+  fmin_op = 0x1c,
+  fmina_op = 0x1d,
+  fmax_op = 0x1e,
+/* WARNING: DO NOT EDIT, AUTO-GENERATED CODE - SEE TOP FOR INSTRUCTIONS */
+  fmaxa_op = 0x1f,
   fcvts_op = 0x20,
   fcvtd_op = 0x21,
-/* WARNING: DO NOT EDIT, AUTO-GENERATED CODE - SEE TOP FOR INSTRUCTIONS */
   fcvte_op = 0x22,
+/* WARNING: DO NOT EDIT, AUTO-GENERATED CODE - SEE TOP FOR INSTRUCTIONS */
   fcvtw_op = 0x24,
   fcvtl_op = 0x25,
   fcmp_op = 0x30
-/* WARNING: DO NOT EDIT, AUTO-GENERATED CODE - SEE TOP FOR INSTRUCTIONS */
 };
+/* WARNING: DO NOT EDIT, AUTO-GENERATED CODE - SEE TOP FOR INSTRUCTIONS */
 enum cop1x_func {
   lwxc1_op = 0x00,
   ldxc1_op = 0x01,
-/* WARNING: DO NOT EDIT, AUTO-GENERATED CODE - SEE TOP FOR INSTRUCTIONS */
   swxc1_op = 0x08,
+/* WARNING: DO NOT EDIT, AUTO-GENERATED CODE - SEE TOP FOR INSTRUCTIONS */
   sdxc1_op = 0x09,
   pfetch_op = 0x0f,
   madd_s_op = 0x20,
-/* WARNING: DO NOT EDIT, AUTO-GENERATED CODE - SEE TOP FOR INSTRUCTIONS */
   madd_d_op = 0x21,
+/* WARNING: DO NOT EDIT, AUTO-GENERATED CODE - SEE TOP FOR INSTRUCTIONS */
   madd_e_op = 0x22,
   msub_s_op = 0x28,
   msub_d_op = 0x29,
-/* WARNING: DO NOT EDIT, AUTO-GENERATED CODE - SEE TOP FOR INSTRUCTIONS */
   msub_e_op = 0x2a,
+/* WARNING: DO NOT EDIT, AUTO-GENERATED CODE - SEE TOP FOR INSTRUCTIONS */
   nmadd_s_op = 0x30,
   nmadd_d_op = 0x31,
   nmadd_e_op = 0x32,
-/* WARNING: DO NOT EDIT, AUTO-GENERATED CODE - SEE TOP FOR INSTRUCTIONS */
   nmsub_s_op = 0x38,
+/* WARNING: DO NOT EDIT, AUTO-GENERATED CODE - SEE TOP FOR INSTRUCTIONS */
   nmsub_d_op = 0x39,
   nmsub_e_op = 0x3a
 };
-/* WARNING: DO NOT EDIT, AUTO-GENERATED CODE - SEE TOP FOR INSTRUCTIONS */
 enum mad_func {
+/* WARNING: DO NOT EDIT, AUTO-GENERATED CODE - SEE TOP FOR INSTRUCTIONS */
   madd_fp_op = 0x08,
   msub_fp_op = 0x0a,
   nmadd_fp_op = 0x0c,
-/* WARNING: DO NOT EDIT, AUTO-GENERATED CODE - SEE TOP FOR INSTRUCTIONS */
   nmsub_fp_op = 0x0e
+/* WARNING: DO NOT EDIT, AUTO-GENERATED CODE - SEE TOP FOR INSTRUCTIONS */
 };
 enum lx_func {
   lwx_op = 0x00,
-/* WARNING: DO NOT EDIT, AUTO-GENERATED CODE - SEE TOP FOR INSTRUCTIONS */
   lhx_op = 0x04,
+/* WARNING: DO NOT EDIT, AUTO-GENERATED CODE - SEE TOP FOR INSTRUCTIONS */
   lbux_op = 0x06,
   ldx_op = 0x08,
   lwux_op = 0x10,
-/* WARNING: DO NOT EDIT, AUTO-GENERATED CODE - SEE TOP FOR INSTRUCTIONS */
   lhux_op = 0x14,
+/* WARNING: DO NOT EDIT, AUTO-GENERATED CODE - SEE TOP FOR INSTRUCTIONS */
   lbx_op = 0x16,
 };
 enum bshfl_func {
-/* WARNING: DO NOT EDIT, AUTO-GENERATED CODE - SEE TOP FOR INSTRUCTIONS */
   wsbh_op = 0x2,
+/* WARNING: DO NOT EDIT, AUTO-GENERATED CODE - SEE TOP FOR INSTRUCTIONS */
   dshd_op = 0x5,
   seb_op = 0x10,
   seh_op = 0x18,
+};
 /* WARNING: DO NOT EDIT, AUTO-GENERATED CODE - SEE TOP FOR INSTRUCTIONS */
+enum msa_mi10_func {
+  msa_ld_op = 8,
+  msa_st_op = 9,
+};
+/* WARNING: DO NOT EDIT, AUTO-GENERATED CODE - SEE TOP FOR INSTRUCTIONS */
+enum msa_2b_fmt {
+  msa_fmt_b = 0,
+  msa_fmt_h = 1,
+  msa_fmt_w = 2,
+/* WARNING: DO NOT EDIT, AUTO-GENERATED CODE - SEE TOP FOR INSTRUCTIONS */
+  msa_fmt_d = 3,
 };
 enum mm_major_op {
   mm_pool32a_op,
-  mm_pool16a_op,
 /* WARNING: DO NOT EDIT, AUTO-GENERATED CODE - SEE TOP FOR INSTRUCTIONS */
+  mm_pool16a_op,
   mm_lbu16_op,
   mm_move16_op,
   mm_addi32_op,
-  mm_lbu32_op,
 /* WARNING: DO NOT EDIT, AUTO-GENERATED CODE - SEE TOP FOR INSTRUCTIONS */
+  mm_lbu32_op,
   mm_sb32_op,
   mm_lb32_op,
   mm_pool32b_op,
-  mm_pool16b_op,
 /* WARNING: DO NOT EDIT, AUTO-GENERATED CODE - SEE TOP FOR INSTRUCTIONS */
+  mm_pool16b_op,
   mm_lhu16_op,
   mm_andi16_op,
   mm_addiu32_op,
-  mm_lhu32_op,
 /* WARNING: DO NOT EDIT, AUTO-GENERATED CODE - SEE TOP FOR INSTRUCTIONS */
+  mm_lhu32_op,
   mm_sh32_op,
   mm_lh32_op,
   mm_pool32i_op,
-  mm_pool16c_op,
 /* WARNING: DO NOT EDIT, AUTO-GENERATED CODE - SEE TOP FOR INSTRUCTIONS */
+  mm_pool16c_op,
   mm_lwsp16_op,
   mm_pool16d_op,
   mm_ori32_op,
-  mm_pool32f_op,
 /* WARNING: DO NOT EDIT, AUTO-GENERATED CODE - SEE TOP FOR INSTRUCTIONS */
+  mm_pool32f_op,
   mm_reserved1_op,
   mm_reserved2_op,
   mm_pool32c_op,
-  mm_lwgp16_op,
 /* WARNING: DO NOT EDIT, AUTO-GENERATED CODE - SEE TOP FOR INSTRUCTIONS */
+  mm_lwgp16_op,
   mm_lw16_op,
   mm_pool16e_op,
   mm_xori32_op,
-  mm_jals32_op,
 /* WARNING: DO NOT EDIT, AUTO-GENERATED CODE - SEE TOP FOR INSTRUCTIONS */
+  mm_jals32_op,
   mm_addiupc_op,
   mm_reserved3_op,
   mm_reserved4_op,
-  mm_pool16f_op,
 /* WARNING: DO NOT EDIT, AUTO-GENERATED CODE - SEE TOP FOR INSTRUCTIONS */
+  mm_pool16f_op,
   mm_sb16_op,
   mm_beqz16_op,
   mm_slti32_op,
-  mm_beq32_op,
 /* WARNING: DO NOT EDIT, AUTO-GENERATED CODE - SEE TOP FOR INSTRUCTIONS */
+  mm_beq32_op,
   mm_swc132_op,
   mm_lwc132_op,
   mm_reserved5_op,
-  mm_reserved6_op,
 /* WARNING: DO NOT EDIT, AUTO-GENERATED CODE - SEE TOP FOR INSTRUCTIONS */
+  mm_reserved6_op,
   mm_sh16_op,
   mm_bnez16_op,
   mm_sltiu32_op,
-  mm_bne32_op,
 /* WARNING: DO NOT EDIT, AUTO-GENERATED CODE - SEE TOP FOR INSTRUCTIONS */
+  mm_bne32_op,
   mm_sdc132_op,
   mm_ldc132_op,
   mm_reserved7_op,
-  mm_reserved8_op,
 /* WARNING: DO NOT EDIT, AUTO-GENERATED CODE - SEE TOP FOR INSTRUCTIONS */
+  mm_reserved8_op,
   mm_swsp16_op,
   mm_b16_op,
   mm_andi32_op,
-  mm_j32_op,
 /* WARNING: DO NOT EDIT, AUTO-GENERATED CODE - SEE TOP FOR INSTRUCTIONS */
+  mm_j32_op,
   mm_sd32_op,
   mm_ld32_op,
   mm_reserved11_op,
-  mm_reserved12_op,
 /* WARNING: DO NOT EDIT, AUTO-GENERATED CODE - SEE TOP FOR INSTRUCTIONS */
+  mm_reserved12_op,
   mm_sw16_op,
   mm_li16_op,
   mm_jalx32_op,
-  mm_jal32_op,
 /* WARNING: DO NOT EDIT, AUTO-GENERATED CODE - SEE TOP FOR INSTRUCTIONS */
+  mm_jal32_op,
   mm_sw32_op,
   mm_lw32_op,
 };
-enum mm_32i_minor_op {
 /* WARNING: DO NOT EDIT, AUTO-GENERATED CODE - SEE TOP FOR INSTRUCTIONS */
+enum mm_32i_minor_op {
   mm_bltz_op,
   mm_bltzal_op,
   mm_bgez_op,
-  mm_bgezal_op,
 /* WARNING: DO NOT EDIT, AUTO-GENERATED CODE - SEE TOP FOR INSTRUCTIONS */
+  mm_bgezal_op,
   mm_blez_op,
   mm_bnezc_op,
   mm_bgtz_op,
-  mm_beqzc_op,
 /* WARNING: DO NOT EDIT, AUTO-GENERATED CODE - SEE TOP FOR INSTRUCTIONS */
+  mm_beqzc_op,
   mm_tlti_op,
   mm_tgei_op,
   mm_tltiu_op,
-  mm_tgeiu_op,
 /* WARNING: DO NOT EDIT, AUTO-GENERATED CODE - SEE TOP FOR INSTRUCTIONS */
+  mm_tgeiu_op,
   mm_tnei_op,
   mm_lui_op,
   mm_teqi_op,
-  mm_reserved13_op,
 /* WARNING: DO NOT EDIT, AUTO-GENERATED CODE - SEE TOP FOR INSTRUCTIONS */
+  mm_reserved13_op,
   mm_synci_op,
   mm_bltzals_op,
   mm_reserved14_op,
-  mm_bgezals_op,
 /* WARNING: DO NOT EDIT, AUTO-GENERATED CODE - SEE TOP FOR INSTRUCTIONS */
+  mm_bgezals_op,
   mm_bc2f_op,
   mm_bc2t_op,
   mm_reserved15_op,
-  mm_reserved16_op,
 /* WARNING: DO NOT EDIT, AUTO-GENERATED CODE - SEE TOP FOR INSTRUCTIONS */
+  mm_reserved16_op,
   mm_reserved17_op,
   mm_reserved18_op,
   mm_bposge64_op,
-  mm_bposge32_op,
 /* WARNING: DO NOT EDIT, AUTO-GENERATED CODE - SEE TOP FOR INSTRUCTIONS */
+  mm_bposge32_op,
   mm_bc1f_op,
   mm_bc1t_op,
   mm_reserved19_op,
-  mm_reserved20_op,
 /* WARNING: DO NOT EDIT, AUTO-GENERATED CODE - SEE TOP FOR INSTRUCTIONS */
+  mm_reserved20_op,
   mm_bc1any2f_op,
   mm_bc1any2t_op,
   mm_bc1any4f_op,
-  mm_bc1any4t_op,
 /* WARNING: DO NOT EDIT, AUTO-GENERATED CODE - SEE TOP FOR INSTRUCTIONS */
+  mm_bc1any4t_op,
 };
 enum mm_32a_minor_op {
   mm_sll32_op = 0x000,
-  mm_ins_op = 0x00c,
 /* WARNING: DO NOT EDIT, AUTO-GENERATED CODE - SEE TOP FOR INSTRUCTIONS */
+  mm_ins_op = 0x00c,
   mm_sllv32_op = 0x010,
   mm_ext_op = 0x02c,
   mm_pool32axf_op = 0x03c,
-  mm_srl32_op = 0x040,
 /* WARNING: DO NOT EDIT, AUTO-GENERATED CODE - SEE TOP FOR INSTRUCTIONS */
+  mm_srl32_op = 0x040,
   mm_sra_op = 0x080,
   mm_srlv32_op = 0x090,
   mm_rotr_op = 0x0c0,
-  mm_lwxs_op = 0x118,
 /* WARNING: DO NOT EDIT, AUTO-GENERATED CODE - SEE TOP FOR INSTRUCTIONS */
+  mm_lwxs_op = 0x118,
   mm_addu32_op = 0x150,
   mm_subu32_op = 0x1d0,
   mm_wsbh_op = 0x1ec,
-  mm_mul_op = 0x210,
 /* WARNING: DO NOT EDIT, AUTO-GENERATED CODE - SEE TOP FOR INSTRUCTIONS */
+  mm_mul_op = 0x210,
   mm_and_op = 0x250,
   mm_or32_op = 0x290,
   mm_xor32_op = 0x310,
-  mm_slt_op = 0x350,
 /* WARNING: DO NOT EDIT, AUTO-GENERATED CODE - SEE TOP FOR INSTRUCTIONS */
+  mm_slt_op = 0x350,
   mm_sltu_op = 0x390,
 };
 enum mm_32b_func {
-  mm_lwc2_func = 0x0,
 /* WARNING: DO NOT EDIT, AUTO-GENERATED CODE - SEE TOP FOR INSTRUCTIONS */
+  mm_lwc2_func = 0x0,
   mm_lwp_func = 0x1,
   mm_ldc2_func = 0x2,
   mm_ldp_func = 0x4,
-  mm_lwm32_func = 0x5,
 /* WARNING: DO NOT EDIT, AUTO-GENERATED CODE - SEE TOP FOR INSTRUCTIONS */
+  mm_lwm32_func = 0x5,
   mm_cache_func = 0x6,
   mm_ldm_func = 0x7,
   mm_swc2_func = 0x8,
-  mm_swp_func = 0x9,
 /* WARNING: DO NOT EDIT, AUTO-GENERATED CODE - SEE TOP FOR INSTRUCTIONS */
+  mm_swp_func = 0x9,
   mm_sdc2_func = 0xa,
   mm_sdp_func = 0xc,
   mm_swm32_func = 0xd,
-  mm_sdm_func = 0xf,
 /* WARNING: DO NOT EDIT, AUTO-GENERATED CODE - SEE TOP FOR INSTRUCTIONS */
+  mm_sdm_func = 0xf,
 };
 enum mm_32c_func {
   mm_pref_func = 0x2,
-  mm_ll_func = 0x3,
 /* WARNING: DO NOT EDIT, AUTO-GENERATED CODE - SEE TOP FOR INSTRUCTIONS */
+  mm_ll_func = 0x3,
   mm_swr_func = 0x9,
   mm_sc_func = 0xb,
   mm_lwu_func = 0xe,
-};
 /* WARNING: DO NOT EDIT, AUTO-GENERATED CODE - SEE TOP FOR INSTRUCTIONS */
+};
 enum mm_32axf_minor_op {
   mm_mfc0_op = 0x003,
   mm_mtc0_op = 0x00b,
-  mm_tlbp_op = 0x00d,
 /* WARNING: DO NOT EDIT, AUTO-GENERATED CODE - SEE TOP FOR INSTRUCTIONS */
+  mm_tlbp_op = 0x00d,
   mm_mfhi32_op = 0x035,
   mm_jalr_op = 0x03c,
   mm_tlbr_op = 0x04d,
-  mm_mflo32_op = 0x075,
 /* WARNING: DO NOT EDIT, AUTO-GENERATED CODE - SEE TOP FOR INSTRUCTIONS */
+  mm_mflo32_op = 0x075,
   mm_jalrhb_op = 0x07c,
   mm_tlbwi_op = 0x08d,
   mm_tlbwr_op = 0x0cd,
-  mm_jalrs_op = 0x13c,
 /* WARNING: DO NOT EDIT, AUTO-GENERATED CODE - SEE TOP FOR INSTRUCTIONS */
+  mm_jalrs_op = 0x13c,
   mm_jalrshb_op = 0x17c,
   mm_sync_op = 0x1ad,
   mm_syscall_op = 0x22d,
-  mm_wait_op = 0x24d,
 /* WARNING: DO NOT EDIT, AUTO-GENERATED CODE - SEE TOP FOR INSTRUCTIONS */
+  mm_wait_op = 0x24d,
   mm_eret_op = 0x3cd,
   mm_divu_op = 0x5dc,
 };
-enum mm_32f_minor_op {
 /* WARNING: DO NOT EDIT, AUTO-GENERATED CODE - SEE TOP FOR INSTRUCTIONS */
+enum mm_32f_minor_op {
   mm_32f_00_op = 0x00,
   mm_32f_01_op = 0x01,
   mm_32f_02_op = 0x02,
-  mm_32f_10_op = 0x08,
 /* WARNING: DO NOT EDIT, AUTO-GENERATED CODE - SEE TOP FOR INSTRUCTIONS */
+  mm_32f_10_op = 0x08,
   mm_32f_11_op = 0x09,
   mm_32f_12_op = 0x0a,
   mm_32f_20_op = 0x10,
-  mm_32f_30_op = 0x18,
 /* WARNING: DO NOT EDIT, AUTO-GENERATED CODE - SEE TOP FOR INSTRUCTIONS */
+  mm_32f_30_op = 0x18,
   mm_32f_40_op = 0x20,
   mm_32f_41_op = 0x21,
   mm_32f_42_op = 0x22,
-  mm_32f_50_op = 0x28,
 /* WARNING: DO NOT EDIT, AUTO-GENERATED CODE - SEE TOP FOR INSTRUCTIONS */
+  mm_32f_50_op = 0x28,
   mm_32f_51_op = 0x29,
   mm_32f_52_op = 0x2a,
   mm_32f_60_op = 0x30,
-  mm_32f_70_op = 0x38,
 /* WARNING: DO NOT EDIT, AUTO-GENERATED CODE - SEE TOP FOR INSTRUCTIONS */
+  mm_32f_70_op = 0x38,
   mm_32f_73_op = 0x3b,
   mm_32f_74_op = 0x3c,
 };
-enum mm_32f_10_minor_op {
 /* WARNING: DO NOT EDIT, AUTO-GENERATED CODE - SEE TOP FOR INSTRUCTIONS */
+enum mm_32f_10_minor_op {
   mm_lwxc1_op = 0x1,
   mm_swxc1_op,
   mm_ldxc1_op,
-  mm_sdxc1_op,
 /* WARNING: DO NOT EDIT, AUTO-GENERATED CODE - SEE TOP FOR INSTRUCTIONS */
+  mm_sdxc1_op,
   mm_luxc1_op,
   mm_suxc1_op,
 };
-enum mm_32f_func {
 /* WARNING: DO NOT EDIT, AUTO-GENERATED CODE - SEE TOP FOR INSTRUCTIONS */
+enum mm_32f_func {
   mm_lwxc1_func = 0x048,
   mm_swxc1_func = 0x088,
   mm_ldxc1_func = 0x0c8,
-  mm_sdxc1_func = 0x108,
 /* WARNING: DO NOT EDIT, AUTO-GENERATED CODE - SEE TOP FOR INSTRUCTIONS */
+  mm_sdxc1_func = 0x108,
 };
 enum mm_32f_40_minor_op {
   mm_fmovf_op,
-  mm_fmovt_op,
 /* WARNING: DO NOT EDIT, AUTO-GENERATED CODE - SEE TOP FOR INSTRUCTIONS */
+  mm_fmovt_op,
 };
 enum mm_32f_60_minor_op {
   mm_fadd_op,
-  mm_fsub_op,
 /* WARNING: DO NOT EDIT, AUTO-GENERATED CODE - SEE TOP FOR INSTRUCTIONS */
+  mm_fsub_op,
   mm_fmul_op,
   mm_fdiv_op,
 };
-enum mm_32f_70_minor_op {
 /* WARNING: DO NOT EDIT, AUTO-GENERATED CODE - SEE TOP FOR INSTRUCTIONS */
+enum mm_32f_70_minor_op {
   mm_fmovn_op,
   mm_fmovz_op,
 };
-enum mm_32f_73_minor_op {
 /* WARNING: DO NOT EDIT, AUTO-GENERATED CODE - SEE TOP FOR INSTRUCTIONS */
+enum mm_32f_73_minor_op {
   mm_fmov0_op = 0x01,
   mm_fcvtl_op = 0x04,
   mm_movf0_op = 0x05,
-  mm_frsqrt_op = 0x08,
 /* WARNING: DO NOT EDIT, AUTO-GENERATED CODE - SEE TOP FOR INSTRUCTIONS */
+  mm_frsqrt_op = 0x08,
   mm_ffloorl_op = 0x0c,
   mm_fabs0_op = 0x0d,
   mm_fcvtw_op = 0x24,
-  mm_movt0_op = 0x25,
 /* WARNING: DO NOT EDIT, AUTO-GENERATED CODE - SEE TOP FOR INSTRUCTIONS */
+  mm_movt0_op = 0x25,
   mm_fsqrt_op = 0x28,
   mm_ffloorw_op = 0x2c,
   mm_fneg0_op = 0x2d,
-  mm_cfc1_op = 0x40,
 /* WARNING: DO NOT EDIT, AUTO-GENERATED CODE - SEE TOP FOR INSTRUCTIONS */
+  mm_cfc1_op = 0x40,
   mm_frecip_op = 0x48,
   mm_fceill_op = 0x4c,
   mm_fcvtd0_op = 0x4d,
-  mm_ctc1_op = 0x60,
 /* WARNING: DO NOT EDIT, AUTO-GENERATED CODE - SEE TOP FOR INSTRUCTIONS */
+  mm_ctc1_op = 0x60,
   mm_fceilw_op = 0x6c,
   mm_fcvts0_op = 0x6d,
   mm_mfc1_op = 0x80,
-  mm_fmov1_op = 0x81,
 /* WARNING: DO NOT EDIT, AUTO-GENERATED CODE - SEE TOP FOR INSTRUCTIONS */
+  mm_fmov1_op = 0x81,
   mm_movf1_op = 0x85,
   mm_ftruncl_op = 0x8c,
   mm_fabs1_op = 0x8d,
-  mm_mtc1_op = 0xa0,
 /* WARNING: DO NOT EDIT, AUTO-GENERATED CODE - SEE TOP FOR INSTRUCTIONS */
+  mm_mtc1_op = 0xa0,
   mm_movt1_op = 0xa5,
   mm_ftruncw_op = 0xac,
   mm_fneg1_op = 0xad,
-  mm_mfhc1_op = 0xc0,
 /* WARNING: DO NOT EDIT, AUTO-GENERATED CODE - SEE TOP FOR INSTRUCTIONS */
+  mm_mfhc1_op = 0xc0,
   mm_froundl_op = 0xcc,
   mm_fcvtd1_op = 0xcd,
   mm_mthc1_op = 0xe0,
-  mm_froundw_op = 0xec,
 /* WARNING: DO NOT EDIT, AUTO-GENERATED CODE - SEE TOP FOR INSTRUCTIONS */
+  mm_froundw_op = 0xec,
   mm_fcvts1_op = 0xed,
 };
 enum mm_16c_minor_op {
-  mm_lwm16_op = 0x04,
 /* WARNING: DO NOT EDIT, AUTO-GENERATED CODE - SEE TOP FOR INSTRUCTIONS */
+  mm_lwm16_op = 0x04,
   mm_swm16_op = 0x05,
   mm_jr16_op = 0x0c,
   mm_jrc_op = 0x0d,
-  mm_jalr16_op = 0x0e,
 /* WARNING: DO NOT EDIT, AUTO-GENERATED CODE - SEE TOP FOR INSTRUCTIONS */
+  mm_jalr16_op = 0x0e,
   mm_jalrs16_op = 0x0f,
   mm_jraddiusp_op = 0x18,
 };
-enum mm_16d_minor_op {
 /* WARNING: DO NOT EDIT, AUTO-GENERATED CODE - SEE TOP FOR INSTRUCTIONS */
+enum mm_16d_minor_op {
   mm_addius5_func,
   mm_addiusp_func,
 };
-enum MIPS16e_ops {
 /* WARNING: DO NOT EDIT, AUTO-GENERATED CODE - SEE TOP FOR INSTRUCTIONS */
+enum MIPS16e_ops {
   MIPS16e_jal_op = 003,
   MIPS16e_ld_op = 007,
   MIPS16e_i8_op = 014,
-  MIPS16e_sd_op = 017,
 /* WARNING: DO NOT EDIT, AUTO-GENERATED CODE - SEE TOP FOR INSTRUCTIONS */
+  MIPS16e_sd_op = 017,
   MIPS16e_lb_op = 020,
   MIPS16e_lh_op = 021,
   MIPS16e_lwsp_op = 022,
-  MIPS16e_lw_op = 023,
 /* WARNING: DO NOT EDIT, AUTO-GENERATED CODE - SEE TOP FOR INSTRUCTIONS */
+  MIPS16e_lw_op = 023,
   MIPS16e_lbu_op = 024,
   MIPS16e_lhu_op = 025,
   MIPS16e_lwpc_op = 026,
-  MIPS16e_lwu_op = 027,
 /* WARNING: DO NOT EDIT, AUTO-GENERATED CODE - SEE TOP FOR INSTRUCTIONS */
+  MIPS16e_lwu_op = 027,
   MIPS16e_sb_op = 030,
   MIPS16e_sh_op = 031,
   MIPS16e_swsp_op = 032,
-  MIPS16e_sw_op = 033,
 /* WARNING: DO NOT EDIT, AUTO-GENERATED CODE - SEE TOP FOR INSTRUCTIONS */
+  MIPS16e_sw_op = 033,
   MIPS16e_rr_op = 035,
   MIPS16e_extend_op = 036,
   MIPS16e_i64_op = 037,
-};
 /* WARNING: DO NOT EDIT, AUTO-GENERATED CODE - SEE TOP FOR INSTRUCTIONS */
+};
 enum MIPS16e_i64_func {
   MIPS16e_ldsp_func,
   MIPS16e_sdsp_func,
-  MIPS16e_sdrasp_func,
 /* WARNING: DO NOT EDIT, AUTO-GENERATED CODE - SEE TOP FOR INSTRUCTIONS */
+  MIPS16e_sdrasp_func,
   MIPS16e_dadjsp_func,
   MIPS16e_ldpc_func,
 };
-enum MIPS16e_rr_func {
 /* WARNING: DO NOT EDIT, AUTO-GENERATED CODE - SEE TOP FOR INSTRUCTIONS */
+enum MIPS16e_rr_func {
   MIPS16e_jr_func,
 };
 enum MIPS6e_i8_func {
-  MIPS16e_swrasp_func = 02,
 /* WARNING: DO NOT EDIT, AUTO-GENERATED CODE - SEE TOP FOR INSTRUCTIONS */
+  MIPS16e_swrasp_func = 02,
 };
 #define MM_NOP16 0x0c00
 struct j_format {
-  __BITFIELD_FIELD(unsigned int opcode : 6, __BITFIELD_FIELD(unsigned int target : 26,;
 /* WARNING: DO NOT EDIT, AUTO-GENERATED CODE - SEE TOP FOR INSTRUCTIONS */
+  __BITFIELD_FIELD(unsigned int opcode : 6, __BITFIELD_FIELD(unsigned int target : 26,;
  ))
 };
 struct i_format {
-  __BITFIELD_FIELD(unsigned int opcode : 6, __BITFIELD_FIELD(unsigned int rs : 5, __BITFIELD_FIELD(unsigned int rt : 5, __BITFIELD_FIELD(signed int simmediate : 16,;
 /* WARNING: DO NOT EDIT, AUTO-GENERATED CODE - SEE TOP FOR INSTRUCTIONS */
+  __BITFIELD_FIELD(unsigned int opcode : 6, __BITFIELD_FIELD(unsigned int rs : 5, __BITFIELD_FIELD(unsigned int rt : 5, __BITFIELD_FIELD(signed int simmediate : 16,;
  ))))
 };
 struct u_format {
-  __BITFIELD_FIELD(unsigned int opcode : 6, __BITFIELD_FIELD(unsigned int rs : 5, __BITFIELD_FIELD(unsigned int rt : 5, __BITFIELD_FIELD(unsigned int uimmediate : 16,;
 /* WARNING: DO NOT EDIT, AUTO-GENERATED CODE - SEE TOP FOR INSTRUCTIONS */
+  __BITFIELD_FIELD(unsigned int opcode : 6, __BITFIELD_FIELD(unsigned int rs : 5, __BITFIELD_FIELD(unsigned int rt : 5, __BITFIELD_FIELD(unsigned int uimmediate : 16,;
  ))))
 };
 struct c_format {
-  __BITFIELD_FIELD(unsigned int opcode : 6, __BITFIELD_FIELD(unsigned int rs : 5, __BITFIELD_FIELD(unsigned int c_op : 3, __BITFIELD_FIELD(unsigned int cache : 2, __BITFIELD_FIELD(unsigned int simmediate : 16,;
 /* WARNING: DO NOT EDIT, AUTO-GENERATED CODE - SEE TOP FOR INSTRUCTIONS */
+  __BITFIELD_FIELD(unsigned int opcode : 6, __BITFIELD_FIELD(unsigned int rs : 5, __BITFIELD_FIELD(unsigned int c_op : 3, __BITFIELD_FIELD(unsigned int cache : 2, __BITFIELD_FIELD(unsigned int simmediate : 16,;
  )))))
 };
 struct r_format {
-  __BITFIELD_FIELD(unsigned int opcode : 6, __BITFIELD_FIELD(unsigned int rs : 5, __BITFIELD_FIELD(unsigned int rt : 5, __BITFIELD_FIELD(unsigned int rd : 5, __BITFIELD_FIELD(unsigned int re : 5, __BITFIELD_FIELD(unsigned int func : 6,;
 /* WARNING: DO NOT EDIT, AUTO-GENERATED CODE - SEE TOP FOR INSTRUCTIONS */
+  __BITFIELD_FIELD(unsigned int opcode : 6, __BITFIELD_FIELD(unsigned int rs : 5, __BITFIELD_FIELD(unsigned int rt : 5, __BITFIELD_FIELD(unsigned int rd : 5, __BITFIELD_FIELD(unsigned int re : 5, __BITFIELD_FIELD(unsigned int func : 6,;
  ))))))
 };
 struct p_format {
-  __BITFIELD_FIELD(unsigned int opcode : 6, __BITFIELD_FIELD(unsigned int rs : 5, __BITFIELD_FIELD(unsigned int rt : 5, __BITFIELD_FIELD(unsigned int rd : 5, __BITFIELD_FIELD(unsigned int re : 5, __BITFIELD_FIELD(unsigned int func : 6,;
 /* WARNING: DO NOT EDIT, AUTO-GENERATED CODE - SEE TOP FOR INSTRUCTIONS */
+  __BITFIELD_FIELD(unsigned int opcode : 6, __BITFIELD_FIELD(unsigned int rs : 5, __BITFIELD_FIELD(unsigned int rt : 5, __BITFIELD_FIELD(unsigned int rd : 5, __BITFIELD_FIELD(unsigned int re : 5, __BITFIELD_FIELD(unsigned int func : 6,;
  ))))))
 };
 struct f_format {
-  __BITFIELD_FIELD(unsigned int opcode : 6, __BITFIELD_FIELD(unsigned int : 1, __BITFIELD_FIELD(unsigned int fmt : 4, __BITFIELD_FIELD(unsigned int rt : 5, __BITFIELD_FIELD(unsigned int rd : 5, __BITFIELD_FIELD(unsigned int re : 5, __BITFIELD_FIELD(unsigned int func : 6,;
 /* WARNING: DO NOT EDIT, AUTO-GENERATED CODE - SEE TOP FOR INSTRUCTIONS */
+  __BITFIELD_FIELD(unsigned int opcode : 6, __BITFIELD_FIELD(unsigned int : 1, __BITFIELD_FIELD(unsigned int fmt : 4, __BITFIELD_FIELD(unsigned int rt : 5, __BITFIELD_FIELD(unsigned int rd : 5, __BITFIELD_FIELD(unsigned int re : 5, __BITFIELD_FIELD(unsigned int func : 6,;
  )))))))
 };
 struct ma_format {
-  __BITFIELD_FIELD(unsigned int opcode : 6, __BITFIELD_FIELD(unsigned int fr : 5, __BITFIELD_FIELD(unsigned int ft : 5, __BITFIELD_FIELD(unsigned int fs : 5, __BITFIELD_FIELD(unsigned int fd : 5, __BITFIELD_FIELD(unsigned int func : 4, __BITFIELD_FIELD(unsigned int fmt : 2,;
 /* WARNING: DO NOT EDIT, AUTO-GENERATED CODE - SEE TOP FOR INSTRUCTIONS */
+  __BITFIELD_FIELD(unsigned int opcode : 6, __BITFIELD_FIELD(unsigned int fr : 5, __BITFIELD_FIELD(unsigned int ft : 5, __BITFIELD_FIELD(unsigned int fs : 5, __BITFIELD_FIELD(unsigned int fd : 5, __BITFIELD_FIELD(unsigned int func : 4, __BITFIELD_FIELD(unsigned int fmt : 2,;
  )))))))
 };
 struct b_format {
-  __BITFIELD_FIELD(unsigned int opcode : 6, __BITFIELD_FIELD(unsigned int code : 20, __BITFIELD_FIELD(unsigned int func : 6,;
 /* WARNING: DO NOT EDIT, AUTO-GENERATED CODE - SEE TOP FOR INSTRUCTIONS */
+  __BITFIELD_FIELD(unsigned int opcode : 6, __BITFIELD_FIELD(unsigned int code : 20, __BITFIELD_FIELD(unsigned int func : 6,;
  )))
 };
 struct ps_format {
-  __BITFIELD_FIELD(unsigned int opcode : 6, __BITFIELD_FIELD(unsigned int rs : 5, __BITFIELD_FIELD(unsigned int ft : 5, __BITFIELD_FIELD(unsigned int fs : 5, __BITFIELD_FIELD(unsigned int fd : 5, __BITFIELD_FIELD(unsigned int func : 6,;
 /* WARNING: DO NOT EDIT, AUTO-GENERATED CODE - SEE TOP FOR INSTRUCTIONS */
+  __BITFIELD_FIELD(unsigned int opcode : 6, __BITFIELD_FIELD(unsigned int rs : 5, __BITFIELD_FIELD(unsigned int ft : 5, __BITFIELD_FIELD(unsigned int fs : 5, __BITFIELD_FIELD(unsigned int fd : 5, __BITFIELD_FIELD(unsigned int func : 6,;
  ))))))
 };
 struct v_format {
-  __BITFIELD_FIELD(unsigned int opcode : 6, __BITFIELD_FIELD(unsigned int sel : 4, __BITFIELD_FIELD(unsigned int fmt : 1, __BITFIELD_FIELD(unsigned int vt : 5, __BITFIELD_FIELD(unsigned int vs : 5, __BITFIELD_FIELD(unsigned int vd : 5, __BITFIELD_FIELD(unsigned int func : 6,;
 /* WARNING: DO NOT EDIT, AUTO-GENERATED CODE - SEE TOP FOR INSTRUCTIONS */
+  __BITFIELD_FIELD(unsigned int opcode : 6, __BITFIELD_FIELD(unsigned int sel : 4, __BITFIELD_FIELD(unsigned int fmt : 1, __BITFIELD_FIELD(unsigned int vt : 5, __BITFIELD_FIELD(unsigned int vs : 5, __BITFIELD_FIELD(unsigned int vd : 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,;
+struct msa_mi10_format {
 /* WARNING: DO NOT EDIT, AUTO-GENERATED CODE - SEE TOP FOR INSTRUCTIONS */
+  __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 spec3_format {
+/* WARNING: DO NOT EDIT, AUTO-GENERATED CODE - SEE TOP FOR INSTRUCTIONS */
+  __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,;
  )))))
 };
 struct fb_format {
-  __BITFIELD_FIELD(unsigned int opcode : 6, __BITFIELD_FIELD(unsigned int bc : 5, __BITFIELD_FIELD(unsigned int cc : 3, __BITFIELD_FIELD(unsigned int flag : 2, __BITFIELD_FIELD(signed int simmediate : 16,;
 /* WARNING: DO NOT EDIT, AUTO-GENERATED CODE - SEE TOP FOR INSTRUCTIONS */
+  __BITFIELD_FIELD(unsigned int opcode : 6, __BITFIELD_FIELD(unsigned int bc : 5, __BITFIELD_FIELD(unsigned int cc : 3, __BITFIELD_FIELD(unsigned int flag : 2, __BITFIELD_FIELD(signed int simmediate : 16,;
  )))))
 };
 struct fp0_format {
-  __BITFIELD_FIELD(unsigned int opcode : 6, __BITFIELD_FIELD(unsigned int fmt : 5, __BITFIELD_FIELD(unsigned int ft : 5, __BITFIELD_FIELD(unsigned int fs : 5, __BITFIELD_FIELD(unsigned int fd : 5, __BITFIELD_FIELD(unsigned int func : 6,;
 /* WARNING: DO NOT EDIT, AUTO-GENERATED CODE - SEE TOP FOR INSTRUCTIONS */
+  __BITFIELD_FIELD(unsigned int opcode : 6, __BITFIELD_FIELD(unsigned int fmt : 5, __BITFIELD_FIELD(unsigned int ft : 5, __BITFIELD_FIELD(unsigned int fs : 5, __BITFIELD_FIELD(unsigned int fd : 5, __BITFIELD_FIELD(unsigned int func : 6,;
  ))))))
 };
 struct mm_fp0_format {
-  __BITFIELD_FIELD(unsigned int opcode : 6, __BITFIELD_FIELD(unsigned int ft : 5, __BITFIELD_FIELD(unsigned int fs : 5, __BITFIELD_FIELD(unsigned int fd : 5, __BITFIELD_FIELD(unsigned int fmt : 3, __BITFIELD_FIELD(unsigned int op : 2, __BITFIELD_FIELD(unsigned int func : 6,;
 /* WARNING: DO NOT EDIT, AUTO-GENERATED CODE - SEE TOP FOR INSTRUCTIONS */
+  __BITFIELD_FIELD(unsigned int opcode : 6, __BITFIELD_FIELD(unsigned int ft : 5, __BITFIELD_FIELD(unsigned int fs : 5, __BITFIELD_FIELD(unsigned int fd : 5, __BITFIELD_FIELD(unsigned int fmt : 3, __BITFIELD_FIELD(unsigned int op : 2, __BITFIELD_FIELD(unsigned int func : 6,;
  )))))))
 };
 struct fp1_format {
-  __BITFIELD_FIELD(unsigned int opcode : 6, __BITFIELD_FIELD(unsigned int op : 5, __BITFIELD_FIELD(unsigned int rt : 5, __BITFIELD_FIELD(unsigned int fs : 5, __BITFIELD_FIELD(unsigned int fd : 5, __BITFIELD_FIELD(unsigned int func : 6,;
 /* WARNING: DO NOT EDIT, AUTO-GENERATED CODE - SEE TOP FOR INSTRUCTIONS */
+  __BITFIELD_FIELD(unsigned int opcode : 6, __BITFIELD_FIELD(unsigned int op : 5, __BITFIELD_FIELD(unsigned int rt : 5, __BITFIELD_FIELD(unsigned int fs : 5, __BITFIELD_FIELD(unsigned int fd : 5, __BITFIELD_FIELD(unsigned int func : 6,;
  ))))))
 };
 struct mm_fp1_format {
-  __BITFIELD_FIELD(unsigned int opcode : 6, __BITFIELD_FIELD(unsigned int rt : 5, __BITFIELD_FIELD(unsigned int fs : 5, __BITFIELD_FIELD(unsigned int fmt : 2, __BITFIELD_FIELD(unsigned int op : 8, __BITFIELD_FIELD(unsigned int func : 6,;
 /* WARNING: DO NOT EDIT, AUTO-GENERATED CODE - SEE TOP FOR INSTRUCTIONS */
+  __BITFIELD_FIELD(unsigned int opcode : 6, __BITFIELD_FIELD(unsigned int rt : 5, __BITFIELD_FIELD(unsigned int fs : 5, __BITFIELD_FIELD(unsigned int fmt : 2, __BITFIELD_FIELD(unsigned int op : 8, __BITFIELD_FIELD(unsigned int func : 6,;
  ))))))
 };
 struct mm_fp2_format {
-  __BITFIELD_FIELD(unsigned int opcode : 6, __BITFIELD_FIELD(unsigned int fd : 5, __BITFIELD_FIELD(unsigned int fs : 5, __BITFIELD_FIELD(unsigned int cc : 3, __BITFIELD_FIELD(unsigned int zero : 2, __BITFIELD_FIELD(unsigned int fmt : 2, __BITFIELD_FIELD(unsigned int op : 3, __BITFIELD_FIELD(unsigned int func : 6,;
 /* WARNING: DO NOT EDIT, AUTO-GENERATED CODE - SEE TOP FOR INSTRUCTIONS */
+  __BITFIELD_FIELD(unsigned int opcode : 6, __BITFIELD_FIELD(unsigned int fd : 5, __BITFIELD_FIELD(unsigned int fs : 5, __BITFIELD_FIELD(unsigned int cc : 3, __BITFIELD_FIELD(unsigned int zero : 2, __BITFIELD_FIELD(unsigned int fmt : 2, __BITFIELD_FIELD(unsigned int op : 3, __BITFIELD_FIELD(unsigned int func : 6,;
  ))))))))
 };
 struct mm_fp3_format {
-  __BITFIELD_FIELD(unsigned int opcode : 6, __BITFIELD_FIELD(unsigned int rt : 5, __BITFIELD_FIELD(unsigned int fs : 5, __BITFIELD_FIELD(unsigned int fmt : 3, __BITFIELD_FIELD(unsigned int op : 7, __BITFIELD_FIELD(unsigned int func : 6,;
 /* WARNING: DO NOT EDIT, AUTO-GENERATED CODE - SEE TOP FOR INSTRUCTIONS */
+  __BITFIELD_FIELD(unsigned int opcode : 6, __BITFIELD_FIELD(unsigned int rt : 5, __BITFIELD_FIELD(unsigned int fs : 5, __BITFIELD_FIELD(unsigned int fmt : 3, __BITFIELD_FIELD(unsigned int op : 7, __BITFIELD_FIELD(unsigned int func : 6,;
  ))))))
 };
 struct mm_fp4_format {
-  __BITFIELD_FIELD(unsigned int opcode : 6, __BITFIELD_FIELD(unsigned int rt : 5, __BITFIELD_FIELD(unsigned int fs : 5, __BITFIELD_FIELD(unsigned int cc : 3, __BITFIELD_FIELD(unsigned int fmt : 3, __BITFIELD_FIELD(unsigned int cond : 4, __BITFIELD_FIELD(unsigned int func : 6,;
 /* WARNING: DO NOT EDIT, AUTO-GENERATED CODE - SEE TOP FOR INSTRUCTIONS */
+  __BITFIELD_FIELD(unsigned int opcode : 6, __BITFIELD_FIELD(unsigned int rt : 5, __BITFIELD_FIELD(unsigned int fs : 5, __BITFIELD_FIELD(unsigned int cc : 3, __BITFIELD_FIELD(unsigned int fmt : 3, __BITFIELD_FIELD(unsigned int cond : 4, __BITFIELD_FIELD(unsigned int func : 6,;
  )))))))
 };
 struct mm_fp5_format {
-  __BITFIELD_FIELD(unsigned int opcode : 6, __BITFIELD_FIELD(unsigned int index : 5, __BITFIELD_FIELD(unsigned int base : 5, __BITFIELD_FIELD(unsigned int fd : 5, __BITFIELD_FIELD(unsigned int op : 5, __BITFIELD_FIELD(unsigned int func : 6,;
 /* WARNING: DO NOT EDIT, AUTO-GENERATED CODE - SEE TOP FOR INSTRUCTIONS */
+  __BITFIELD_FIELD(unsigned int opcode : 6, __BITFIELD_FIELD(unsigned int index : 5, __BITFIELD_FIELD(unsigned int base : 5, __BITFIELD_FIELD(unsigned int fd : 5, __BITFIELD_FIELD(unsigned int op : 5, __BITFIELD_FIELD(unsigned int func : 6,;
  ))))))
 };
 struct fp6_format {
-  __BITFIELD_FIELD(unsigned int opcode : 6, __BITFIELD_FIELD(unsigned int fr : 5, __BITFIELD_FIELD(unsigned int ft : 5, __BITFIELD_FIELD(unsigned int fs : 5, __BITFIELD_FIELD(unsigned int fd : 5, __BITFIELD_FIELD(unsigned int func : 6,;
 /* WARNING: DO NOT EDIT, AUTO-GENERATED CODE - SEE TOP FOR INSTRUCTIONS */
+  __BITFIELD_FIELD(unsigned int opcode : 6, __BITFIELD_FIELD(unsigned int fr : 5, __BITFIELD_FIELD(unsigned int ft : 5, __BITFIELD_FIELD(unsigned int fs : 5, __BITFIELD_FIELD(unsigned int fd : 5, __BITFIELD_FIELD(unsigned int func : 6,;
  ))))))
 };
 struct mm_fp6_format {
-  __BITFIELD_FIELD(unsigned int opcode : 6, __BITFIELD_FIELD(unsigned int ft : 5, __BITFIELD_FIELD(unsigned int fs : 5, __BITFIELD_FIELD(unsigned int fd : 5, __BITFIELD_FIELD(unsigned int fr : 5, __BITFIELD_FIELD(unsigned int func : 6,;
 /* WARNING: DO NOT EDIT, AUTO-GENERATED CODE - SEE TOP FOR INSTRUCTIONS */
+  __BITFIELD_FIELD(unsigned int opcode : 6, __BITFIELD_FIELD(unsigned int ft : 5, __BITFIELD_FIELD(unsigned int fs : 5, __BITFIELD_FIELD(unsigned int fd : 5, __BITFIELD_FIELD(unsigned int fr : 5, __BITFIELD_FIELD(unsigned int func : 6,;
  ))))))
 };
 struct mm_i_format {
-  __BITFIELD_FIELD(unsigned int opcode : 6, __BITFIELD_FIELD(unsigned int rt : 5, __BITFIELD_FIELD(unsigned int rs : 5, __BITFIELD_FIELD(signed int simmediate : 16,;
 /* WARNING: DO NOT EDIT, AUTO-GENERATED CODE - SEE TOP FOR INSTRUCTIONS */
+  __BITFIELD_FIELD(unsigned int opcode : 6, __BITFIELD_FIELD(unsigned int rt : 5, __BITFIELD_FIELD(unsigned int rs : 5, __BITFIELD_FIELD(signed int simmediate : 16,;
  ))))
 };
 struct mm_m_format {
-  __BITFIELD_FIELD(unsigned int opcode : 6, __BITFIELD_FIELD(unsigned int rd : 5, __BITFIELD_FIELD(unsigned int base : 5, __BITFIELD_FIELD(unsigned int func : 4, __BITFIELD_FIELD(signed int simmediate : 12,;
 /* WARNING: DO NOT EDIT, AUTO-GENERATED CODE - SEE TOP FOR INSTRUCTIONS */
+  __BITFIELD_FIELD(unsigned int opcode : 6, __BITFIELD_FIELD(unsigned int rd : 5, __BITFIELD_FIELD(unsigned int base : 5, __BITFIELD_FIELD(unsigned int func : 4, __BITFIELD_FIELD(signed int simmediate : 12,;
  )))))
 };
 struct mm_x_format {
-  __BITFIELD_FIELD(unsigned int opcode : 6, __BITFIELD_FIELD(unsigned int index : 5, __BITFIELD_FIELD(unsigned int base : 5, __BITFIELD_FIELD(unsigned int rd : 5, __BITFIELD_FIELD(unsigned int func : 11,;
 /* WARNING: DO NOT EDIT, AUTO-GENERATED CODE - SEE TOP FOR INSTRUCTIONS */
+  __BITFIELD_FIELD(unsigned int opcode : 6, __BITFIELD_FIELD(unsigned int index : 5, __BITFIELD_FIELD(unsigned int base : 5, __BITFIELD_FIELD(unsigned int rd : 5, __BITFIELD_FIELD(unsigned int func : 11,;
  )))))
 };
 struct mm_b0_format {
-  __BITFIELD_FIELD(unsigned int opcode : 6, __BITFIELD_FIELD(signed int simmediate : 10, __BITFIELD_FIELD(unsigned int : 16,;
 /* WARNING: DO NOT EDIT, AUTO-GENERATED CODE - SEE TOP FOR INSTRUCTIONS */
+  __BITFIELD_FIELD(unsigned int opcode : 6, __BITFIELD_FIELD(signed int simmediate : 10, __BITFIELD_FIELD(unsigned int : 16,;
  )))
 };
 struct mm_b1_format {
-  __BITFIELD_FIELD(unsigned int opcode : 6, __BITFIELD_FIELD(unsigned int rs : 3, __BITFIELD_FIELD(signed int simmediate : 7, __BITFIELD_FIELD(unsigned int : 16,;
 /* WARNING: DO NOT EDIT, AUTO-GENERATED CODE - SEE TOP FOR INSTRUCTIONS */
+  __BITFIELD_FIELD(unsigned int opcode : 6, __BITFIELD_FIELD(unsigned int rs : 3, __BITFIELD_FIELD(signed int simmediate : 7, __BITFIELD_FIELD(unsigned int : 16,;
  ))))
 };
 struct mm16_m_format {
-  __BITFIELD_FIELD(unsigned int opcode : 6, __BITFIELD_FIELD(unsigned int func : 4, __BITFIELD_FIELD(unsigned int rlist : 2, __BITFIELD_FIELD(unsigned int imm : 4, __BITFIELD_FIELD(unsigned int : 16,;
 /* WARNING: DO NOT EDIT, AUTO-GENERATED CODE - SEE TOP FOR INSTRUCTIONS */
+  __BITFIELD_FIELD(unsigned int opcode : 6, __BITFIELD_FIELD(unsigned int func : 4, __BITFIELD_FIELD(unsigned int rlist : 2, __BITFIELD_FIELD(unsigned int imm : 4, __BITFIELD_FIELD(unsigned int : 16,;
  )))))
 };
 struct mm16_rb_format {
-  __BITFIELD_FIELD(unsigned int opcode : 6, __BITFIELD_FIELD(unsigned int rt : 3, __BITFIELD_FIELD(unsigned int base : 3, __BITFIELD_FIELD(signed int simmediate : 4, __BITFIELD_FIELD(unsigned int : 16,;
 /* WARNING: DO NOT EDIT, AUTO-GENERATED CODE - SEE TOP FOR INSTRUCTIONS */
+  __BITFIELD_FIELD(unsigned int opcode : 6, __BITFIELD_FIELD(unsigned int rt : 3, __BITFIELD_FIELD(unsigned int base : 3, __BITFIELD_FIELD(signed int simmediate : 4, __BITFIELD_FIELD(unsigned int : 16,;
  )))))
 };
 struct mm16_r3_format {
-  __BITFIELD_FIELD(unsigned int opcode : 6, __BITFIELD_FIELD(unsigned int rt : 3, __BITFIELD_FIELD(signed int simmediate : 7, __BITFIELD_FIELD(unsigned int : 16,;
 /* WARNING: DO NOT EDIT, AUTO-GENERATED CODE - SEE TOP FOR INSTRUCTIONS */
+  __BITFIELD_FIELD(unsigned int opcode : 6, __BITFIELD_FIELD(unsigned int rt : 3, __BITFIELD_FIELD(signed int simmediate : 7, __BITFIELD_FIELD(unsigned int : 16,;
  ))))
 };
 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,;
 /* WARNING: DO NOT EDIT, AUTO-GENERATED CODE - SEE TOP FOR INSTRUCTIONS */
+  __BITFIELD_FIELD(unsigned int opcode : 6, __BITFIELD_FIELD(unsigned int rt : 5, __BITFIELD_FIELD(signed int simmediate : 5, __BITFIELD_FIELD(unsigned int : 16,;
  ))))
 };
 struct m16e_rr {
-  __BITFIELD_FIELD(unsigned int opcode : 5, __BITFIELD_FIELD(unsigned int rx : 3, __BITFIELD_FIELD(unsigned int nd : 1, __BITFIELD_FIELD(unsigned int l : 1, __BITFIELD_FIELD(unsigned int ra : 1, __BITFIELD_FIELD(unsigned int func : 5,;
 /* WARNING: DO NOT EDIT, AUTO-GENERATED CODE - SEE TOP FOR INSTRUCTIONS */
+  __BITFIELD_FIELD(unsigned int opcode : 5, __BITFIELD_FIELD(unsigned int rx : 3, __BITFIELD_FIELD(unsigned int nd : 1, __BITFIELD_FIELD(unsigned int l : 1, __BITFIELD_FIELD(unsigned int ra : 1, __BITFIELD_FIELD(unsigned int func : 5,;
  ))))))
 };
 struct m16e_jal {
-  __BITFIELD_FIELD(unsigned int opcode : 5, __BITFIELD_FIELD(unsigned int x : 1, __BITFIELD_FIELD(unsigned int imm20_16 : 5, __BITFIELD_FIELD(signed int imm25_21 : 5,;
 /* WARNING: DO NOT EDIT, AUTO-GENERATED CODE - SEE TOP FOR INSTRUCTIONS */
+  __BITFIELD_FIELD(unsigned int opcode : 5, __BITFIELD_FIELD(unsigned int x : 1, __BITFIELD_FIELD(unsigned int imm20_16 : 5, __BITFIELD_FIELD(signed int imm25_21 : 5,;
  ))))
 };
 struct m16e_i64 {
-  __BITFIELD_FIELD(unsigned int opcode : 5, __BITFIELD_FIELD(unsigned int func : 3, __BITFIELD_FIELD(unsigned int imm : 8,;
 /* WARNING: DO NOT EDIT, AUTO-GENERATED CODE - SEE TOP FOR INSTRUCTIONS */
+  __BITFIELD_FIELD(unsigned int opcode : 5, __BITFIELD_FIELD(unsigned int func : 3, __BITFIELD_FIELD(unsigned int imm : 8,;
  )))
 };
 struct m16e_ri64 {
-  __BITFIELD_FIELD(unsigned int opcode : 5, __BITFIELD_FIELD(unsigned int func : 3, __BITFIELD_FIELD(unsigned int ry : 3, __BITFIELD_FIELD(unsigned int imm : 5,;
 /* WARNING: DO NOT EDIT, AUTO-GENERATED CODE - SEE TOP FOR INSTRUCTIONS */
+  __BITFIELD_FIELD(unsigned int opcode : 5, __BITFIELD_FIELD(unsigned int func : 3, __BITFIELD_FIELD(unsigned int ry : 3, __BITFIELD_FIELD(unsigned int imm : 5,;
  ))))
 };
 struct m16e_ri {
-  __BITFIELD_FIELD(unsigned int opcode : 5, __BITFIELD_FIELD(unsigned int rx : 3, __BITFIELD_FIELD(unsigned int imm : 8,;
 /* WARNING: DO NOT EDIT, AUTO-GENERATED CODE - SEE TOP FOR INSTRUCTIONS */
+  __BITFIELD_FIELD(unsigned int opcode : 5, __BITFIELD_FIELD(unsigned int rx : 3, __BITFIELD_FIELD(unsigned int imm : 8,;
  )))
 };
 struct m16e_rri {
-  __BITFIELD_FIELD(unsigned int opcode : 5, __BITFIELD_FIELD(unsigned int rx : 3, __BITFIELD_FIELD(unsigned int ry : 3, __BITFIELD_FIELD(unsigned int imm : 5,;
 /* WARNING: DO NOT EDIT, AUTO-GENERATED CODE - SEE TOP FOR INSTRUCTIONS */
+  __BITFIELD_FIELD(unsigned int opcode : 5, __BITFIELD_FIELD(unsigned int rx : 3, __BITFIELD_FIELD(unsigned int ry : 3, __BITFIELD_FIELD(unsigned int imm : 5,;
  ))))
 };
 struct m16e_i8 {
-  __BITFIELD_FIELD(unsigned int opcode : 5, __BITFIELD_FIELD(unsigned int func : 3, __BITFIELD_FIELD(unsigned int imm : 8,;
 /* WARNING: DO NOT EDIT, AUTO-GENERATED CODE - SEE TOP FOR INSTRUCTIONS */
+  __BITFIELD_FIELD(unsigned int opcode : 5, __BITFIELD_FIELD(unsigned int func : 3, __BITFIELD_FIELD(unsigned int imm : 8,;
  )))
 };
 union mips_instruction {
-  unsigned int word;
 /* WARNING: DO NOT EDIT, AUTO-GENERATED CODE - SEE TOP FOR INSTRUCTIONS */
+  unsigned int word;
   unsigned short halfword[2];
   unsigned char byte[4];
   struct j_format j_format;
-  struct i_format i_format;
 /* WARNING: DO NOT EDIT, AUTO-GENERATED CODE - SEE TOP FOR INSTRUCTIONS */
+  struct i_format i_format;
   struct u_format u_format;
   struct c_format c_format;
   struct r_format r_format;
-  struct p_format p_format;
 /* WARNING: DO NOT EDIT, AUTO-GENERATED CODE - SEE TOP FOR INSTRUCTIONS */
+  struct p_format p_format;
   struct f_format f_format;
   struct ma_format ma_format;
+  struct msa_mi10_format msa_mi10_format;
+/* WARNING: DO NOT EDIT, AUTO-GENERATED CODE - SEE TOP FOR INSTRUCTIONS */
   struct b_format b_format;
   struct ps_format ps_format;
-/* WARNING: DO NOT EDIT, AUTO-GENERATED CODE - SEE TOP FOR INSTRUCTIONS */
   struct v_format v_format;
   struct spec3_format spec3_format;
+/* WARNING: DO NOT EDIT, AUTO-GENERATED CODE - SEE TOP FOR INSTRUCTIONS */
   struct fb_format fb_format;
   struct fp0_format fp0_format;
-/* WARNING: DO NOT EDIT, AUTO-GENERATED CODE - SEE TOP FOR INSTRUCTIONS */
   struct mm_fp0_format mm_fp0_format;
   struct fp1_format fp1_format;
+/* WARNING: DO NOT EDIT, AUTO-GENERATED CODE - SEE TOP FOR INSTRUCTIONS */
   struct mm_fp1_format mm_fp1_format;
   struct mm_fp2_format mm_fp2_format;
-/* WARNING: DO NOT EDIT, AUTO-GENERATED CODE - SEE TOP FOR INSTRUCTIONS */
   struct mm_fp3_format mm_fp3_format;
   struct mm_fp4_format mm_fp4_format;
+/* WARNING: DO NOT EDIT, AUTO-GENERATED CODE - SEE TOP FOR INSTRUCTIONS */
   struct mm_fp5_format mm_fp5_format;
   struct fp6_format fp6_format;
-/* WARNING: DO NOT EDIT, AUTO-GENERATED CODE - SEE TOP FOR INSTRUCTIONS */
   struct mm_fp6_format mm_fp6_format;
   struct mm_i_format mm_i_format;
+/* WARNING: DO NOT EDIT, AUTO-GENERATED CODE - SEE TOP FOR INSTRUCTIONS */
   struct mm_m_format mm_m_format;
   struct mm_x_format mm_x_format;
-/* WARNING: DO NOT EDIT, AUTO-GENERATED CODE - SEE TOP FOR INSTRUCTIONS */
   struct mm_b0_format mm_b0_format;
   struct mm_b1_format mm_b1_format;
+/* WARNING: DO NOT EDIT, AUTO-GENERATED CODE - SEE TOP FOR INSTRUCTIONS */
   struct mm16_m_format mm16_m_format;
   struct mm16_rb_format mm16_rb_format;
-/* WARNING: DO NOT EDIT, AUTO-GENERATED CODE - SEE TOP FOR INSTRUCTIONS */
   struct mm16_r3_format mm16_r3_format;
   struct mm16_r5_format mm16_r5_format;
+/* WARNING: DO NOT EDIT, AUTO-GENERATED CODE - SEE TOP FOR INSTRUCTIONS */
 };
 union mips16e_instruction {
-/* WARNING: DO NOT EDIT, AUTO-GENERATED CODE - SEE TOP FOR INSTRUCTIONS */
   unsigned int full : 16;
   struct m16e_rr rr;
+/* WARNING: DO NOT EDIT, AUTO-GENERATED CODE - SEE TOP FOR INSTRUCTIONS */
   struct m16e_jal jal;
   struct m16e_i64 i64;
-/* WARNING: DO NOT EDIT, AUTO-GENERATED CODE - SEE TOP FOR INSTRUCTIONS */
   struct m16e_ri64 ri64;
   struct m16e_ri ri;
+/* WARNING: DO NOT EDIT, AUTO-GENERATED CODE - SEE TOP FOR INSTRUCTIONS */
   struct m16e_rri rri;
   struct m16e_i8 i8;
-/* WARNING: DO NOT EDIT, AUTO-GENERATED CODE - SEE TOP FOR INSTRUCTIONS */
 };
 #endif
+/* WARNING: DO NOT EDIT, AUTO-GENERATED CODE - SEE TOP FOR INSTRUCTIONS */
diff --git a/libc/kernel/uapi/asm-mips/asm/kvm.h b/libc/kernel/uapi/asm-mips/asm/kvm.h
index 0206d16..9c01470 100644
--- a/libc/kernel/uapi/asm-mips/asm/kvm.h
+++ b/libc/kernel/uapi/asm-mips/asm/kvm.h
@@ -28,79 +28,88 @@
 /* WARNING: DO NOT EDIT, AUTO-GENERATED CODE - SEE TOP FOR INSTRUCTIONS */
 };
 struct kvm_fpu {
-  __u64 fpr[32];
-  __u32 fir;
-/* WARNING: DO NOT EDIT, AUTO-GENERATED CODE - SEE TOP FOR INSTRUCTIONS */
-  __u32 fccr;
-  __u32 fexr;
-  __u32 fenr;
-  __u32 fcsr;
-/* WARNING: DO NOT EDIT, AUTO-GENERATED CODE - SEE TOP FOR INSTRUCTIONS */
-  __u32 pad;
 };
-#define KVM_REG_MIPS_R0 (KVM_REG_MIPS | KVM_REG_SIZE_U64 | 0)
-#define KVM_REG_MIPS_R1 (KVM_REG_MIPS | KVM_REG_SIZE_U64 | 1)
+#define KVM_REG_MIPS_GP (KVM_REG_MIPS | 0x0000000000000000ULL)
 /* WARNING: DO NOT EDIT, AUTO-GENERATED CODE - SEE TOP FOR INSTRUCTIONS */
-#define KVM_REG_MIPS_R2 (KVM_REG_MIPS | KVM_REG_SIZE_U64 | 2)
-#define KVM_REG_MIPS_R3 (KVM_REG_MIPS | KVM_REG_SIZE_U64 | 3)
-#define KVM_REG_MIPS_R4 (KVM_REG_MIPS | KVM_REG_SIZE_U64 | 4)
-#define KVM_REG_MIPS_R5 (KVM_REG_MIPS | KVM_REG_SIZE_U64 | 5)
+#define KVM_REG_MIPS_CP0 (KVM_REG_MIPS | 0x0000000000010000ULL)
+#define KVM_REG_MIPS_KVM (KVM_REG_MIPS | 0x0000000000020000ULL)
+#define KVM_REG_MIPS_FPU (KVM_REG_MIPS | 0x0000000000030000ULL)
+#define KVM_REG_MIPS_R0 (KVM_REG_MIPS_GP | KVM_REG_SIZE_U64 | 0)
 /* WARNING: DO NOT EDIT, AUTO-GENERATED CODE - SEE TOP FOR INSTRUCTIONS */
-#define KVM_REG_MIPS_R6 (KVM_REG_MIPS | KVM_REG_SIZE_U64 | 6)
-#define KVM_REG_MIPS_R7 (KVM_REG_MIPS | KVM_REG_SIZE_U64 | 7)
-#define KVM_REG_MIPS_R8 (KVM_REG_MIPS | KVM_REG_SIZE_U64 | 8)
-#define KVM_REG_MIPS_R9 (KVM_REG_MIPS | KVM_REG_SIZE_U64 | 9)
+#define KVM_REG_MIPS_R1 (KVM_REG_MIPS_GP | KVM_REG_SIZE_U64 | 1)
+#define KVM_REG_MIPS_R2 (KVM_REG_MIPS_GP | KVM_REG_SIZE_U64 | 2)
+#define KVM_REG_MIPS_R3 (KVM_REG_MIPS_GP | KVM_REG_SIZE_U64 | 3)
+#define KVM_REG_MIPS_R4 (KVM_REG_MIPS_GP | KVM_REG_SIZE_U64 | 4)
 /* WARNING: DO NOT EDIT, AUTO-GENERATED CODE - SEE TOP FOR INSTRUCTIONS */
-#define KVM_REG_MIPS_R10 (KVM_REG_MIPS | KVM_REG_SIZE_U64 | 10)
-#define KVM_REG_MIPS_R11 (KVM_REG_MIPS | KVM_REG_SIZE_U64 | 11)
-#define KVM_REG_MIPS_R12 (KVM_REG_MIPS | KVM_REG_SIZE_U64 | 12)
-#define KVM_REG_MIPS_R13 (KVM_REG_MIPS | KVM_REG_SIZE_U64 | 13)
+#define KVM_REG_MIPS_R5 (KVM_REG_MIPS_GP | KVM_REG_SIZE_U64 | 5)
+#define KVM_REG_MIPS_R6 (KVM_REG_MIPS_GP | KVM_REG_SIZE_U64 | 6)
+#define KVM_REG_MIPS_R7 (KVM_REG_MIPS_GP | KVM_REG_SIZE_U64 | 7)
+#define KVM_REG_MIPS_R8 (KVM_REG_MIPS_GP | KVM_REG_SIZE_U64 | 8)
 /* WARNING: DO NOT EDIT, AUTO-GENERATED CODE - SEE TOP FOR INSTRUCTIONS */
-#define KVM_REG_MIPS_R14 (KVM_REG_MIPS | KVM_REG_SIZE_U64 | 14)
-#define KVM_REG_MIPS_R15 (KVM_REG_MIPS | KVM_REG_SIZE_U64 | 15)
-#define KVM_REG_MIPS_R16 (KVM_REG_MIPS | KVM_REG_SIZE_U64 | 16)
-#define KVM_REG_MIPS_R17 (KVM_REG_MIPS | KVM_REG_SIZE_U64 | 17)
+#define KVM_REG_MIPS_R9 (KVM_REG_MIPS_GP | KVM_REG_SIZE_U64 | 9)
+#define KVM_REG_MIPS_R10 (KVM_REG_MIPS_GP | KVM_REG_SIZE_U64 | 10)
+#define KVM_REG_MIPS_R11 (KVM_REG_MIPS_GP | KVM_REG_SIZE_U64 | 11)
+#define KVM_REG_MIPS_R12 (KVM_REG_MIPS_GP | KVM_REG_SIZE_U64 | 12)
 /* WARNING: DO NOT EDIT, AUTO-GENERATED CODE - SEE TOP FOR INSTRUCTIONS */
-#define KVM_REG_MIPS_R18 (KVM_REG_MIPS | KVM_REG_SIZE_U64 | 18)
-#define KVM_REG_MIPS_R19 (KVM_REG_MIPS | KVM_REG_SIZE_U64 | 19)
-#define KVM_REG_MIPS_R20 (KVM_REG_MIPS | KVM_REG_SIZE_U64 | 20)
-#define KVM_REG_MIPS_R21 (KVM_REG_MIPS | KVM_REG_SIZE_U64 | 21)
+#define KVM_REG_MIPS_R13 (KVM_REG_MIPS_GP | KVM_REG_SIZE_U64 | 13)
+#define KVM_REG_MIPS_R14 (KVM_REG_MIPS_GP | KVM_REG_SIZE_U64 | 14)
+#define KVM_REG_MIPS_R15 (KVM_REG_MIPS_GP | KVM_REG_SIZE_U64 | 15)
+#define KVM_REG_MIPS_R16 (KVM_REG_MIPS_GP | KVM_REG_SIZE_U64 | 16)
 /* WARNING: DO NOT EDIT, AUTO-GENERATED CODE - SEE TOP FOR INSTRUCTIONS */
-#define KVM_REG_MIPS_R22 (KVM_REG_MIPS | KVM_REG_SIZE_U64 | 22)
-#define KVM_REG_MIPS_R23 (KVM_REG_MIPS | KVM_REG_SIZE_U64 | 23)
-#define KVM_REG_MIPS_R24 (KVM_REG_MIPS | KVM_REG_SIZE_U64 | 24)
-#define KVM_REG_MIPS_R25 (KVM_REG_MIPS | KVM_REG_SIZE_U64 | 25)
+#define KVM_REG_MIPS_R17 (KVM_REG_MIPS_GP | KVM_REG_SIZE_U64 | 17)
+#define KVM_REG_MIPS_R18 (KVM_REG_MIPS_GP | KVM_REG_SIZE_U64 | 18)
+#define KVM_REG_MIPS_R19 (KVM_REG_MIPS_GP | KVM_REG_SIZE_U64 | 19)
+#define KVM_REG_MIPS_R20 (KVM_REG_MIPS_GP | KVM_REG_SIZE_U64 | 20)
 /* WARNING: DO NOT EDIT, AUTO-GENERATED CODE - SEE TOP FOR INSTRUCTIONS */
-#define KVM_REG_MIPS_R26 (KVM_REG_MIPS | KVM_REG_SIZE_U64 | 26)
-#define KVM_REG_MIPS_R27 (KVM_REG_MIPS | KVM_REG_SIZE_U64 | 27)
-#define KVM_REG_MIPS_R28 (KVM_REG_MIPS | KVM_REG_SIZE_U64 | 28)
-#define KVM_REG_MIPS_R29 (KVM_REG_MIPS | KVM_REG_SIZE_U64 | 29)
+#define KVM_REG_MIPS_R21 (KVM_REG_MIPS_GP | KVM_REG_SIZE_U64 | 21)
+#define KVM_REG_MIPS_R22 (KVM_REG_MIPS_GP | KVM_REG_SIZE_U64 | 22)
+#define KVM_REG_MIPS_R23 (KVM_REG_MIPS_GP | KVM_REG_SIZE_U64 | 23)
+#define KVM_REG_MIPS_R24 (KVM_REG_MIPS_GP | KVM_REG_SIZE_U64 | 24)
 /* WARNING: DO NOT EDIT, AUTO-GENERATED CODE - SEE TOP FOR INSTRUCTIONS */
-#define KVM_REG_MIPS_R30 (KVM_REG_MIPS | KVM_REG_SIZE_U64 | 30)
-#define KVM_REG_MIPS_R31 (KVM_REG_MIPS | KVM_REG_SIZE_U64 | 31)
-#define KVM_REG_MIPS_HI (KVM_REG_MIPS | KVM_REG_SIZE_U64 | 32)
-#define KVM_REG_MIPS_LO (KVM_REG_MIPS | KVM_REG_SIZE_U64 | 33)
+#define KVM_REG_MIPS_R25 (KVM_REG_MIPS_GP | KVM_REG_SIZE_U64 | 25)
+#define KVM_REG_MIPS_R26 (KVM_REG_MIPS_GP | KVM_REG_SIZE_U64 | 26)
+#define KVM_REG_MIPS_R27 (KVM_REG_MIPS_GP | KVM_REG_SIZE_U64 | 27)
+#define KVM_REG_MIPS_R28 (KVM_REG_MIPS_GP | KVM_REG_SIZE_U64 | 28)
 /* WARNING: DO NOT EDIT, AUTO-GENERATED CODE - SEE TOP FOR INSTRUCTIONS */
-#define KVM_REG_MIPS_PC (KVM_REG_MIPS | KVM_REG_SIZE_U64 | 34)
-#define KVM_REG_MIPS_COUNT_CTL (KVM_REG_MIPS | KVM_REG_SIZE_U64 | 0x20000 | 0)
+#define KVM_REG_MIPS_R29 (KVM_REG_MIPS_GP | KVM_REG_SIZE_U64 | 29)
+#define KVM_REG_MIPS_R30 (KVM_REG_MIPS_GP | KVM_REG_SIZE_U64 | 30)
+#define KVM_REG_MIPS_R31 (KVM_REG_MIPS_GP | KVM_REG_SIZE_U64 | 31)
+#define KVM_REG_MIPS_HI (KVM_REG_MIPS_GP | KVM_REG_SIZE_U64 | 32)
+/* WARNING: DO NOT EDIT, AUTO-GENERATED CODE - SEE TOP FOR INSTRUCTIONS */
+#define KVM_REG_MIPS_LO (KVM_REG_MIPS_GP | KVM_REG_SIZE_U64 | 33)
+#define KVM_REG_MIPS_PC (KVM_REG_MIPS_GP | KVM_REG_SIZE_U64 | 34)
+#define KVM_REG_MIPS_COUNT_CTL (KVM_REG_MIPS_KVM | KVM_REG_SIZE_U64 | 0)
 #define KVM_REG_MIPS_COUNT_CTL_DC 0x00000001
-#define KVM_REG_MIPS_COUNT_RESUME (KVM_REG_MIPS | KVM_REG_SIZE_U64 | 0x20000 | 1)
 /* WARNING: DO NOT EDIT, AUTO-GENERATED CODE - SEE TOP FOR INSTRUCTIONS */
-#define KVM_REG_MIPS_COUNT_HZ (KVM_REG_MIPS | KVM_REG_SIZE_U64 | 0x20000 | 2)
+#define KVM_REG_MIPS_COUNT_RESUME (KVM_REG_MIPS_KVM | KVM_REG_SIZE_U64 | 1)
+#define KVM_REG_MIPS_COUNT_HZ (KVM_REG_MIPS_KVM | KVM_REG_SIZE_U64 | 2)
+#define KVM_REG_MIPS_FPR (KVM_REG_MIPS_FPU | 0x0000000000000000ULL)
+#define KVM_REG_MIPS_FCR (KVM_REG_MIPS_FPU | 0x0000000000000100ULL)
+/* WARNING: DO NOT EDIT, AUTO-GENERATED CODE - SEE TOP FOR INSTRUCTIONS */
+#define KVM_REG_MIPS_MSACR (KVM_REG_MIPS_FPU | 0x0000000000000200ULL)
+#define KVM_REG_MIPS_FPR_32(n) (KVM_REG_MIPS_FPR | KVM_REG_SIZE_U32 | (n))
+#define KVM_REG_MIPS_FPR_64(n) (KVM_REG_MIPS_FPR | KVM_REG_SIZE_U64 | (n))
+#define KVM_REG_MIPS_VEC_128(n) (KVM_REG_MIPS_FPR | KVM_REG_SIZE_U128 | (n))
+/* WARNING: DO NOT EDIT, AUTO-GENERATED CODE - SEE TOP FOR INSTRUCTIONS */
+#define KVM_REG_MIPS_FCR_IR (KVM_REG_MIPS_FCR | KVM_REG_SIZE_U32 | 0)
+#define KVM_REG_MIPS_FCR_CSR (KVM_REG_MIPS_FCR | KVM_REG_SIZE_U32 | 31)
+#define KVM_REG_MIPS_MSA_IR (KVM_REG_MIPS_MSACR | KVM_REG_SIZE_U32 | 0)
+#define KVM_REG_MIPS_MSA_CSR (KVM_REG_MIPS_MSACR | KVM_REG_SIZE_U32 | 1)
+/* WARNING: DO NOT EDIT, AUTO-GENERATED CODE - SEE TOP FOR INSTRUCTIONS */
 struct kvm_debug_exit_arch {
   __u64 epc;
 };
-/* WARNING: DO NOT EDIT, AUTO-GENERATED CODE - SEE TOP FOR INSTRUCTIONS */
 struct kvm_guest_debug_arch {
+/* WARNING: DO NOT EDIT, AUTO-GENERATED CODE - SEE TOP FOR INSTRUCTIONS */
 };
 struct kvm_sync_regs {
 };
-/* WARNING: DO NOT EDIT, AUTO-GENERATED CODE - SEE TOP FOR INSTRUCTIONS */
 struct kvm_sregs {
+/* WARNING: DO NOT EDIT, AUTO-GENERATED CODE - SEE TOP FOR INSTRUCTIONS */
 };
 struct kvm_mips_interrupt {
   __u32 cpu;
-/* WARNING: DO NOT EDIT, AUTO-GENERATED CODE - SEE TOP FOR INSTRUCTIONS */
   __u32 irq;
+/* WARNING: DO NOT EDIT, AUTO-GENERATED CODE - SEE TOP FOR INSTRUCTIONS */
 };
 #endif
diff --git a/libc/kernel/uapi/asm-mips/asm/mman.h b/libc/kernel/uapi/asm-mips/asm/mman.h
index b9a9031..7d7f68d 100644
--- a/libc/kernel/uapi/asm-mips/asm/mman.h
+++ b/libc/kernel/uapi/asm-mips/asm/mman.h
@@ -56,26 +56,29 @@
 #define MCL_CURRENT 1
 #define MCL_FUTURE 2
 /* WARNING: DO NOT EDIT, AUTO-GENERATED CODE - SEE TOP FOR INSTRUCTIONS */
+#define MCL_ONFAULT 4
+#define MLOCK_ONFAULT 0x01
 #define MADV_NORMAL 0
 #define MADV_RANDOM 1
+/* WARNING: DO NOT EDIT, AUTO-GENERATED CODE - SEE TOP FOR INSTRUCTIONS */
 #define MADV_SEQUENTIAL 2
 #define MADV_WILLNEED 3
-/* WARNING: DO NOT EDIT, AUTO-GENERATED CODE - SEE TOP FOR INSTRUCTIONS */
 #define MADV_DONTNEED 4
 #define MADV_REMOVE 9
+/* WARNING: DO NOT EDIT, AUTO-GENERATED CODE - SEE TOP FOR INSTRUCTIONS */
 #define MADV_DONTFORK 10
 #define MADV_DOFORK 11
-/* WARNING: DO NOT EDIT, AUTO-GENERATED CODE - SEE TOP FOR INSTRUCTIONS */
 #define MADV_MERGEABLE 12
 #define MADV_UNMERGEABLE 13
+/* WARNING: DO NOT EDIT, AUTO-GENERATED CODE - SEE TOP FOR INSTRUCTIONS */
 #define MADV_HWPOISON 100
 #define MADV_HUGEPAGE 14
-/* WARNING: DO NOT EDIT, AUTO-GENERATED CODE - SEE TOP FOR INSTRUCTIONS */
 #define MADV_NOHUGEPAGE 15
 #define MADV_DONTDUMP 16
+/* WARNING: DO NOT EDIT, AUTO-GENERATED CODE - SEE TOP FOR INSTRUCTIONS */
 #define MADV_DODUMP 17
 #define MAP_FILE 0
-/* WARNING: DO NOT EDIT, AUTO-GENERATED CODE - SEE TOP FOR INSTRUCTIONS */
 #define MAP_HUGE_SHIFT 26
 #define MAP_HUGE_MASK 0x3f
+/* WARNING: DO NOT EDIT, AUTO-GENERATED CODE - SEE TOP FOR INSTRUCTIONS */
 #endif
diff --git a/libc/kernel/uapi/asm-mips/asm/sigcontext.h b/libc/kernel/uapi/asm-mips/asm/sigcontext.h
index 59870bc..2fc0229 100644
--- a/libc/kernel/uapi/asm-mips/asm/sigcontext.h
+++ b/libc/kernel/uapi/asm-mips/asm/sigcontext.h
@@ -21,6 +21,11 @@
 #include <linux/types.h>
 #include <asm/sgidefs.h>
 /* WARNING: DO NOT EDIT, AUTO-GENERATED CODE - SEE TOP FOR INSTRUCTIONS */
+#define USED_FP (1 << 0)
+#define USED_FR1 (1 << 1)
+#define USED_HYBRID_FPRS (1 << 2)
+#define USED_EXTCONTEXT (1 << 3)
+/* WARNING: DO NOT EDIT, AUTO-GENERATED CODE - SEE TOP FOR INSTRUCTIONS */
 #if _MIPS_SIM == _MIPS_SIM_ABI32
 struct sigcontext {
   unsigned int sc_regmask;
diff --git a/libc/kernel/uapi/asm-mips/asm/siginfo.h b/libc/kernel/uapi/asm-mips/asm/siginfo.h
index 2f95d17..758327c 100644
--- a/libc/kernel/uapi/asm-mips/asm/siginfo.h
+++ b/libc/kernel/uapi/asm-mips/asm/siginfo.h
@@ -22,93 +22,97 @@
 #undef __ARCH_SI_TRAPNO
 /* WARNING: DO NOT EDIT, AUTO-GENERATED CODE - SEE TOP FOR INSTRUCTIONS */
 #define HAVE_ARCH_SIGINFO_T
-#define HAVE_ARCH_COPY_SIGINFO
-struct siginfo;
 #if _MIPS_SZLONG == 32
-/* WARNING: DO NOT EDIT, AUTO-GENERATED CODE - SEE TOP FOR INSTRUCTIONS */
 #define __ARCH_SI_PREAMBLE_SIZE (3 * sizeof(int))
 #elif _MIPS_SZLONG==64
+/* WARNING: DO NOT EDIT, AUTO-GENERATED CODE - SEE TOP FOR INSTRUCTIONS */
 #define __ARCH_SI_PREAMBLE_SIZE (4 * sizeof(int))
 #else
-/* WARNING: DO NOT EDIT, AUTO-GENERATED CODE - SEE TOP FOR INSTRUCTIONS */
 #error _MIPS_SZLONG neither 32 nor 64
 #endif
+/* WARNING: DO NOT EDIT, AUTO-GENERATED CODE - SEE TOP FOR INSTRUCTIONS */
 #define __ARCH_SIGSYS
 #include <asm-generic/siginfo.h>
-/* WARNING: DO NOT EDIT, AUTO-GENERATED CODE - SEE TOP FOR INSTRUCTIONS */
 typedef struct siginfo {
   int si_signo;
+/* WARNING: DO NOT EDIT, AUTO-GENERATED CODE - SEE TOP FOR INSTRUCTIONS */
   int si_code;
   int si_errno;
-/* WARNING: DO NOT EDIT, AUTO-GENERATED CODE - SEE TOP FOR INSTRUCTIONS */
   int __pad0[SI_MAX_SIZE / sizeof(int) - SI_PAD_SIZE - 3];
   union {
+/* WARNING: DO NOT EDIT, AUTO-GENERATED CODE - SEE TOP FOR INSTRUCTIONS */
     int _pad[SI_PAD_SIZE];
     struct {
-/* WARNING: DO NOT EDIT, AUTO-GENERATED CODE - SEE TOP FOR INSTRUCTIONS */
       pid_t _pid;
       __ARCH_SI_UID_T _uid;
+/* WARNING: DO NOT EDIT, AUTO-GENERATED CODE - SEE TOP FOR INSTRUCTIONS */
     } _kill;
     struct {
-/* WARNING: DO NOT EDIT, AUTO-GENERATED CODE - SEE TOP FOR INSTRUCTIONS */
       timer_t _tid;
       int _overrun;
+/* WARNING: DO NOT EDIT, AUTO-GENERATED CODE - SEE TOP FOR INSTRUCTIONS */
       char _pad[sizeof(__ARCH_SI_UID_T) - sizeof(int)];
       sigval_t _sigval;
-/* WARNING: DO NOT EDIT, AUTO-GENERATED CODE - SEE TOP FOR INSTRUCTIONS */
       int _sys_private;
     } _timer;
+/* WARNING: DO NOT EDIT, AUTO-GENERATED CODE - SEE TOP FOR INSTRUCTIONS */
     struct {
       pid_t _pid;
-/* WARNING: DO NOT EDIT, AUTO-GENERATED CODE - SEE TOP FOR INSTRUCTIONS */
       __ARCH_SI_UID_T _uid;
       sigval_t _sigval;
+/* WARNING: DO NOT EDIT, AUTO-GENERATED CODE - SEE TOP FOR INSTRUCTIONS */
     } _rt;
     struct {
-/* WARNING: DO NOT EDIT, AUTO-GENERATED CODE - SEE TOP FOR INSTRUCTIONS */
       pid_t _pid;
       __ARCH_SI_UID_T _uid;
+/* WARNING: DO NOT EDIT, AUTO-GENERATED CODE - SEE TOP FOR INSTRUCTIONS */
       int _status;
       clock_t _utime;
-/* WARNING: DO NOT EDIT, AUTO-GENERATED CODE - SEE TOP FOR INSTRUCTIONS */
       clock_t _stime;
     } _sigchld;
+/* WARNING: DO NOT EDIT, AUTO-GENERATED CODE - SEE TOP FOR INSTRUCTIONS */
     struct {
       pid_t _pid;
-/* WARNING: DO NOT EDIT, AUTO-GENERATED CODE - SEE TOP FOR INSTRUCTIONS */
       clock_t _utime;
       int _status;
+/* WARNING: DO NOT EDIT, AUTO-GENERATED CODE - SEE TOP FOR INSTRUCTIONS */
       clock_t _stime;
     } _irix_sigchld;
-/* WARNING: DO NOT EDIT, AUTO-GENERATED CODE - SEE TOP FOR INSTRUCTIONS */
     struct {
       void __user * _addr;
+/* WARNING: DO NOT EDIT, AUTO-GENERATED CODE - SEE TOP FOR INSTRUCTIONS */
 #ifdef __ARCH_SI_TRAPNO
       int _trapno;
-/* WARNING: DO NOT EDIT, AUTO-GENERATED CODE - SEE TOP FOR INSTRUCTIONS */
 #endif
       short _addr_lsb;
+/* WARNING: DO NOT EDIT, AUTO-GENERATED CODE - SEE TOP FOR INSTRUCTIONS */
+      struct {
+        void __user * _lower;
+        void __user * _upper;
+      } _addr_bnd;
+/* WARNING: DO NOT EDIT, AUTO-GENERATED CODE - SEE TOP FOR INSTRUCTIONS */
     } _sigfault;
     struct {
-/* WARNING: DO NOT EDIT, AUTO-GENERATED CODE - SEE TOP FOR INSTRUCTIONS */
       __ARCH_SI_BAND_T _band;
       int _fd;
+/* WARNING: DO NOT EDIT, AUTO-GENERATED CODE - SEE TOP FOR INSTRUCTIONS */
     } _sigpoll;
     struct {
-/* WARNING: DO NOT EDIT, AUTO-GENERATED CODE - SEE TOP FOR INSTRUCTIONS */
       void __user * _call_addr;
       int _syscall;
+/* WARNING: DO NOT EDIT, AUTO-GENERATED CODE - SEE TOP FOR INSTRUCTIONS */
       unsigned int _arch;
     } _sigsys;
-/* WARNING: DO NOT EDIT, AUTO-GENERATED CODE - SEE TOP FOR INSTRUCTIONS */
   } _sifields;
 } siginfo_t;
+/* WARNING: DO NOT EDIT, AUTO-GENERATED CODE - SEE TOP FOR INSTRUCTIONS */
 #undef SI_ASYNCIO
 #undef SI_TIMER
-/* WARNING: DO NOT EDIT, AUTO-GENERATED CODE - SEE TOP FOR INSTRUCTIONS */
 #undef SI_MESGQ
 #define SI_ASYNCIO - 2
+/* WARNING: DO NOT EDIT, AUTO-GENERATED CODE - SEE TOP FOR INSTRUCTIONS */
 #define SI_TIMER __SI_CODE(__SI_TIMER, - 3)
 #define SI_MESGQ __SI_CODE(__SI_MESGQ, - 4)
-/* WARNING: DO NOT EDIT, AUTO-GENERATED CODE - SEE TOP FOR INSTRUCTIONS */
+#include <asm-generic/siginfo.h>
 #endif
+/* WARNING: DO NOT EDIT, AUTO-GENERATED CODE - SEE TOP FOR INSTRUCTIONS */
diff --git a/libc/kernel/uapi/asm-mips/asm/socket.h b/libc/kernel/uapi/asm-mips/asm/socket.h
index 38e4e63..4405053 100644
--- a/libc/kernel/uapi/asm-mips/asm/socket.h
+++ b/libc/kernel/uapi/asm-mips/asm/socket.h
@@ -88,4 +88,8 @@
 /* WARNING: DO NOT EDIT, AUTO-GENERATED CODE - SEE TOP FOR INSTRUCTIONS */
 #define SO_MAX_PACING_RATE 47
 #define SO_BPF_EXTENSIONS 48
+#define SO_INCOMING_CPU 49
+#define SO_ATTACH_BPF 50
+/* WARNING: DO NOT EDIT, AUTO-GENERATED CODE - SEE TOP FOR INSTRUCTIONS */
+#define SO_DETACH_BPF SO_DETACH_FILTER
 #endif
diff --git a/libc/kernel/uapi/asm-mips/asm/swab.h b/libc/kernel/uapi/asm-mips/asm/swab.h
index 0629d36..d78191d 100644
--- a/libc/kernel/uapi/asm-mips/asm/swab.h
+++ b/libc/kernel/uapi/asm-mips/asm/swab.h
@@ -22,7 +22,7 @@
 #include <linux/types.h>
 /* WARNING: DO NOT EDIT, AUTO-GENERATED CODE - SEE TOP FOR INSTRUCTIONS */
 #define __SWAB_64_THRU_32__
-#if defined(__mips_isa_rev) && __mips_isa_rev >= 2 || defined(_MIPS_ARCH_LOONGSON3A)
+#if !defined(__mips16) && (defined(__mips_isa_rev) && __mips_isa_rev >= 2 || defined(_MIPS_ARCH_LOONGSON3A))
 #define __arch_swab16 __arch_swab16
 #define __arch_swab32 __arch_swab32
 /* WARNING: DO NOT EDIT, AUTO-GENERATED CODE - SEE TOP FOR INSTRUCTIONS */
diff --git a/libc/kernel/uapi/asm-mips/asm/unistd.h b/libc/kernel/uapi/asm-mips/asm/unistd.h
index 04a45bf..d5c3de3 100644
--- a/libc/kernel/uapi/asm-mips/asm/unistd.h
+++ b/libc/kernel/uapi/asm-mips/asm/unistd.h
@@ -466,10 +466,15 @@
 #define __NR_memfd_create (__NR_Linux + 354)
 #define __NR_bpf (__NR_Linux + 355)
 /* WARNING: DO NOT EDIT, AUTO-GENERATED CODE - SEE TOP FOR INSTRUCTIONS */
-#define __NR_Linux_syscalls 355
+#define __NR_execveat (__NR_Linux + 356)
+#define __NR_userfaultfd (__NR_Linux + 357)
+#define __NR_membarrier (__NR_Linux + 358)
+#define __NR_mlock2 (__NR_Linux + 359)
+/* WARNING: DO NOT EDIT, AUTO-GENERATED CODE - SEE TOP FOR INSTRUCTIONS */
+#define __NR_Linux_syscalls 359
 #endif
 #define __NR_O32_Linux 4000
-#define __NR_O32_Linux_syscalls 355
+#define __NR_O32_Linux_syscalls 359
 /* WARNING: DO NOT EDIT, AUTO-GENERATED CODE - SEE TOP FOR INSTRUCTIONS */
 #if _MIPS_SIM == _MIPS_SIM_ABI64
 #define __NR_Linux 5000
@@ -867,11 +872,16 @@
 #define __NR_memfd_create (__NR_Linux + 314)
 /* WARNING: DO NOT EDIT, AUTO-GENERATED CODE - SEE TOP FOR INSTRUCTIONS */
 #define __NR_bpf (__NR_Linux + 315)
-#define __NR_Linux_syscalls 315
+#define __NR_execveat (__NR_Linux + 316)
+#define __NR_userfaultfd (__NR_Linux + 317)
+#define __NR_membarrier (__NR_Linux + 318)
+/* WARNING: DO NOT EDIT, AUTO-GENERATED CODE - SEE TOP FOR INSTRUCTIONS */
+#define __NR_mlock2 (__NR_Linux + 319)
+#define __NR_Linux_syscalls 319
 #endif
 #define __NR_64_Linux 5000
 /* WARNING: DO NOT EDIT, AUTO-GENERATED CODE - SEE TOP FOR INSTRUCTIONS */
-#define __NR_64_Linux_syscalls 315
+#define __NR_64_Linux_syscalls 319
 #if _MIPS_SIM == _MIPS_SIM_NABI32
 #define __NR_Linux 6000
 #define __NR_read (__NR_Linux + 0)
@@ -1273,9 +1283,14 @@
 /* WARNING: DO NOT EDIT, AUTO-GENERATED CODE - SEE TOP FOR INSTRUCTIONS */
 #define __NR_memfd_create (__NR_Linux + 318)
 #define __NR_bpf (__NR_Linux + 319)
-#define __NR_Linux_syscalls 319
+#define __NR_execveat (__NR_Linux + 320)
+#define __NR_userfaultfd (__NR_Linux + 321)
+/* WARNING: DO NOT EDIT, AUTO-GENERATED CODE - SEE TOP FOR INSTRUCTIONS */
+#define __NR_membarrier (__NR_Linux + 322)
+#define __NR_mlock2 (__NR_Linux + 323)
+#define __NR_Linux_syscalls 323
 #endif
 /* WARNING: DO NOT EDIT, AUTO-GENERATED CODE - SEE TOP FOR INSTRUCTIONS */
 #define __NR_N32_Linux 6000
-#define __NR_N32_Linux_syscalls 319
+#define __NR_N32_Linux_syscalls 323
 #endif
diff --git a/libc/kernel/uapi/asm-x86/asm/bitsperlong.h b/libc/kernel/uapi/asm-x86/asm/bitsperlong.h
index 2deae24..0bc255c 100644
--- a/libc/kernel/uapi/asm-x86/asm/bitsperlong.h
+++ b/libc/kernel/uapi/asm-x86/asm/bitsperlong.h
@@ -18,7 +18,7 @@
  ****************************************************************************/
 #ifndef __ASM_X86_BITSPERLONG_H
 #define __ASM_X86_BITSPERLONG_H
-#ifdef __x86_64__
+#if defined(__x86_64__) && !defined(__ILP32__)
 #define __BITS_PER_LONG 64
 /* WARNING: DO NOT EDIT, AUTO-GENERATED CODE - SEE TOP FOR INSTRUCTIONS */
 #else
diff --git a/libc/kernel/uapi/asm-x86/asm/bootparam.h b/libc/kernel/uapi/asm-x86/asm/bootparam.h
index 27201d6..1394829 100644
--- a/libc/kernel/uapi/asm-x86/asm/bootparam.h
+++ b/libc/kernel/uapi/asm-x86/asm/bootparam.h
@@ -29,161 +29,162 @@
 #define RAMDISK_PROMPT_FLAG 0x8000
 #define RAMDISK_LOAD_FLAG 0x4000
 #define LOADED_HIGH (1 << 0)
-#define QUIET_FLAG (1 << 5)
+#define KASLR_FLAG (1 << 1)
 /* WARNING: DO NOT EDIT, AUTO-GENERATED CODE - SEE TOP FOR INSTRUCTIONS */
+#define QUIET_FLAG (1 << 5)
 #define KEEP_SEGMENTS (1 << 6)
 #define CAN_USE_HEAP (1 << 7)
 #define XLF_KERNEL_64 (1 << 0)
-#define XLF_CAN_BE_LOADED_ABOVE_4G (1 << 1)
 /* WARNING: DO NOT EDIT, AUTO-GENERATED CODE - SEE TOP FOR INSTRUCTIONS */
+#define XLF_CAN_BE_LOADED_ABOVE_4G (1 << 1)
 #define XLF_EFI_HANDOVER_32 (1 << 2)
 #define XLF_EFI_HANDOVER_64 (1 << 3)
 #define XLF_EFI_KEXEC (1 << 4)
-#ifndef __ASSEMBLY__
 /* WARNING: DO NOT EDIT, AUTO-GENERATED CODE - SEE TOP FOR INSTRUCTIONS */
+#ifndef __ASSEMBLY__
 #include <linux/types.h>
 #include <linux/screen_info.h>
 #include <linux/apm_bios.h>
-#include <linux/edd.h>
 /* WARNING: DO NOT EDIT, AUTO-GENERATED CODE - SEE TOP FOR INSTRUCTIONS */
+#include <linux/edd.h>
 #include <asm/e820.h>
 #include <asm/ist.h>
 #include <video/edid.h>
-struct setup_data {
 /* WARNING: DO NOT EDIT, AUTO-GENERATED CODE - SEE TOP FOR INSTRUCTIONS */
+struct setup_data {
   __u64 next;
   __u32 type;
   __u32 len;
-  __u8 data[0];
 /* WARNING: DO NOT EDIT, AUTO-GENERATED CODE - SEE TOP FOR INSTRUCTIONS */
+  __u8 data[0];
 };
 struct setup_header {
   __u8 setup_sects;
-  __u16 root_flags;
 /* WARNING: DO NOT EDIT, AUTO-GENERATED CODE - SEE TOP FOR INSTRUCTIONS */
+  __u16 root_flags;
   __u32 syssize;
   __u16 ram_size;
   __u16 vid_mode;
-  __u16 root_dev;
 /* WARNING: DO NOT EDIT, AUTO-GENERATED CODE - SEE TOP FOR INSTRUCTIONS */
+  __u16 root_dev;
   __u16 boot_flag;
   __u16 jump;
   __u32 header;
-  __u16 version;
 /* WARNING: DO NOT EDIT, AUTO-GENERATED CODE - SEE TOP FOR INSTRUCTIONS */
+  __u16 version;
   __u32 realmode_swtch;
   __u16 start_sys;
   __u16 kernel_version;
-  __u8 type_of_loader;
 /* WARNING: DO NOT EDIT, AUTO-GENERATED CODE - SEE TOP FOR INSTRUCTIONS */
+  __u8 type_of_loader;
   __u8 loadflags;
   __u16 setup_move_size;
   __u32 code32_start;
-  __u32 ramdisk_image;
 /* WARNING: DO NOT EDIT, AUTO-GENERATED CODE - SEE TOP FOR INSTRUCTIONS */
+  __u32 ramdisk_image;
   __u32 ramdisk_size;
   __u32 bootsect_kludge;
   __u16 heap_end_ptr;
-  __u8 ext_loader_ver;
 /* WARNING: DO NOT EDIT, AUTO-GENERATED CODE - SEE TOP FOR INSTRUCTIONS */
+  __u8 ext_loader_ver;
   __u8 ext_loader_type;
   __u32 cmd_line_ptr;
   __u32 initrd_addr_max;
-  __u32 kernel_alignment;
 /* WARNING: DO NOT EDIT, AUTO-GENERATED CODE - SEE TOP FOR INSTRUCTIONS */
+  __u32 kernel_alignment;
   __u8 relocatable_kernel;
   __u8 min_alignment;
   __u16 xloadflags;
-  __u32 cmdline_size;
 /* WARNING: DO NOT EDIT, AUTO-GENERATED CODE - SEE TOP FOR INSTRUCTIONS */
+  __u32 cmdline_size;
   __u32 hardware_subarch;
   __u64 hardware_subarch_data;
   __u32 payload_offset;
-  __u32 payload_length;
 /* WARNING: DO NOT EDIT, AUTO-GENERATED CODE - SEE TOP FOR INSTRUCTIONS */
+  __u32 payload_length;
   __u64 setup_data;
   __u64 pref_address;
   __u32 init_size;
-  __u32 handover_offset;
 /* WARNING: DO NOT EDIT, AUTO-GENERATED CODE - SEE TOP FOR INSTRUCTIONS */
+  __u32 handover_offset;
 } __attribute__((packed));
 struct sys_desc_table {
   __u16 length;
-  __u8 table[14];
 /* WARNING: DO NOT EDIT, AUTO-GENERATED CODE - SEE TOP FOR INSTRUCTIONS */
+  __u8 table[14];
 };
 struct olpc_ofw_header {
   __u32 ofw_magic;
-  __u32 ofw_version;
 /* WARNING: DO NOT EDIT, AUTO-GENERATED CODE - SEE TOP FOR INSTRUCTIONS */
+  __u32 ofw_version;
   __u32 cif_handler;
   __u32 irq_desc_table;
 } __attribute__((packed));
-struct efi_info {
 /* WARNING: DO NOT EDIT, AUTO-GENERATED CODE - SEE TOP FOR INSTRUCTIONS */
+struct efi_info {
   __u32 efi_loader_signature;
   __u32 efi_systab;
   __u32 efi_memdesc_size;
-  __u32 efi_memdesc_version;
 /* WARNING: DO NOT EDIT, AUTO-GENERATED CODE - SEE TOP FOR INSTRUCTIONS */
+  __u32 efi_memdesc_version;
   __u32 efi_memmap;
   __u32 efi_memmap_size;
   __u32 efi_systab_hi;
-  __u32 efi_memmap_hi;
 /* WARNING: DO NOT EDIT, AUTO-GENERATED CODE - SEE TOP FOR INSTRUCTIONS */
+  __u32 efi_memmap_hi;
 };
 struct boot_params {
   struct screen_info screen_info;
-  struct apm_bios_info apm_bios_info;
 /* WARNING: DO NOT EDIT, AUTO-GENERATED CODE - SEE TOP FOR INSTRUCTIONS */
+  struct apm_bios_info apm_bios_info;
   __u8 _pad2[4];
   __u64 tboot_addr;
   struct ist_info ist_info;
-  __u8 _pad3[16];
 /* WARNING: DO NOT EDIT, AUTO-GENERATED CODE - SEE TOP FOR INSTRUCTIONS */
+  __u8 _pad3[16];
   __u8 hd0_info[16];
   __u8 hd1_info[16];
   struct sys_desc_table sys_desc_table;
-  struct olpc_ofw_header olpc_ofw_header;
 /* WARNING: DO NOT EDIT, AUTO-GENERATED CODE - SEE TOP FOR INSTRUCTIONS */
+  struct olpc_ofw_header olpc_ofw_header;
   __u32 ext_ramdisk_image;
   __u32 ext_ramdisk_size;
   __u32 ext_cmd_line_ptr;
-  __u8 _pad4[116];
 /* WARNING: DO NOT EDIT, AUTO-GENERATED CODE - SEE TOP FOR INSTRUCTIONS */
+  __u8 _pad4[116];
   struct edid_info edid_info;
   struct efi_info efi_info;
   __u32 alt_mem_k;
-  __u32 scratch;
 /* WARNING: DO NOT EDIT, AUTO-GENERATED CODE - SEE TOP FOR INSTRUCTIONS */
+  __u32 scratch;
   __u8 e820_entries;
   __u8 eddbuf_entries;
   __u8 edd_mbr_sig_buf_entries;
-  __u8 kbd_status;
 /* WARNING: DO NOT EDIT, AUTO-GENERATED CODE - SEE TOP FOR INSTRUCTIONS */
+  __u8 kbd_status;
   __u8 _pad5[3];
   __u8 sentinel;
   __u8 _pad6[1];
-  struct setup_header hdr;
 /* WARNING: DO NOT EDIT, AUTO-GENERATED CODE - SEE TOP FOR INSTRUCTIONS */
+  struct setup_header hdr;
   __u8 _pad7[0x290 - 0x1f1 - sizeof(struct setup_header)];
   __u32 edd_mbr_sig_buffer[EDD_MBR_SIG_MAX];
   struct e820entry e820_map[E820MAX];
-  __u8 _pad8[48];
 /* WARNING: DO NOT EDIT, AUTO-GENERATED CODE - SEE TOP FOR INSTRUCTIONS */
+  __u8 _pad8[48];
   struct edd_info eddbuf[EDDMAXNR];
   __u8 _pad9[276];
 } __attribute__((packed));
-enum {
 /* WARNING: DO NOT EDIT, AUTO-GENERATED CODE - SEE TOP FOR INSTRUCTIONS */
+enum {
   X86_SUBARCH_PC = 0,
   X86_SUBARCH_LGUEST,
   X86_SUBARCH_XEN,
-  X86_SUBARCH_INTEL_MID,
 /* WARNING: DO NOT EDIT, AUTO-GENERATED CODE - SEE TOP FOR INSTRUCTIONS */
+  X86_SUBARCH_INTEL_MID,
   X86_SUBARCH_CE4100,
   X86_NR_SUBARCHS,
 };
-#endif
 /* WARNING: DO NOT EDIT, AUTO-GENERATED CODE - SEE TOP FOR INSTRUCTIONS */
 #endif
+#endif
diff --git a/libc/kernel/uapi/asm-x86/asm/e820.h b/libc/kernel/uapi/asm-x86/asm/e820.h
index d4cb389..10ec6b9 100644
--- a/libc/kernel/uapi/asm-x86/asm/e820.h
+++ b/libc/kernel/uapi/asm-x86/asm/e820.h
@@ -29,28 +29,31 @@
 #define E820_ACPI 3
 #define E820_NVS 4
 #define E820_UNUSABLE 5
-#define E820_RESERVED_KERN 128
+#define E820_PMEM 7
 /* WARNING: DO NOT EDIT, AUTO-GENERATED CODE - SEE TOP FOR INSTRUCTIONS */
+#define E820_PRAM 12
+#define E820_RESERVED_KERN 128
 #ifndef __ASSEMBLY__
 #include <linux/types.h>
+/* WARNING: DO NOT EDIT, AUTO-GENERATED CODE - SEE TOP FOR INSTRUCTIONS */
 struct e820entry {
   __u64 addr;
-/* WARNING: DO NOT EDIT, AUTO-GENERATED CODE - SEE TOP FOR INSTRUCTIONS */
   __u64 size;
   __u32 type;
+/* WARNING: DO NOT EDIT, AUTO-GENERATED CODE - SEE TOP FOR INSTRUCTIONS */
 } __attribute__((packed));
 struct e820map {
-/* WARNING: DO NOT EDIT, AUTO-GENERATED CODE - SEE TOP FOR INSTRUCTIONS */
   __u32 nr_map;
   struct e820entry map[E820_X_MAX];
+/* WARNING: DO NOT EDIT, AUTO-GENERATED CODE - SEE TOP FOR INSTRUCTIONS */
 };
 #define ISA_START_ADDRESS 0xa0000
-/* WARNING: DO NOT EDIT, AUTO-GENERATED CODE - SEE TOP FOR INSTRUCTIONS */
 #define ISA_END_ADDRESS 0x100000
 #define BIOS_BEGIN 0x000a0000
+/* WARNING: DO NOT EDIT, AUTO-GENERATED CODE - SEE TOP FOR INSTRUCTIONS */
 #define BIOS_END 0x00100000
 #define BIOS_ROM_BASE 0xffe00000
-/* WARNING: DO NOT EDIT, AUTO-GENERATED CODE - SEE TOP FOR INSTRUCTIONS */
 #define BIOS_ROM_END 0xffffffff
 #endif
+/* WARNING: DO NOT EDIT, AUTO-GENERATED CODE - SEE TOP FOR INSTRUCTIONS */
 #endif
diff --git a/libc/kernel/uapi/asm-x86/asm/hyperv.h b/libc/kernel/uapi/asm-x86/asm/hyperv.h
index e869504..312726f 100644
--- a/libc/kernel/uapi/asm-x86/asm/hyperv.h
+++ b/libc/kernel/uapi/asm-x86/asm/hyperv.h
@@ -33,52 +33,57 @@
 /* WARNING: DO NOT EDIT, AUTO-GENERATED CODE - SEE TOP FOR INSTRUCTIONS */
 #define HV_X64_MSR_VP_RUNTIME_AVAILABLE (1 << 0)
 #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)
 /* WARNING: DO NOT EDIT, AUTO-GENERATED CODE - SEE TOP FOR INSTRUCTIONS */
+#define HV_X64_MSR_APIC_FREQUENCY_AVAILABLE (1 << 11)
 #define HV_X64_MSR_TSC_FREQUENCY_AVAILABLE (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)
 /* WARNING: DO NOT EDIT, AUTO-GENERATED CODE - SEE TOP FOR INSTRUCTIONS */
+#define HV_X64_MSR_APIC_ACCESS_AVAILABLE (1 << 4)
 #define HV_X64_MSR_HYPERCALL_AVAILABLE (1 << 5)
 #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)
 /* WARNING: DO NOT EDIT, AUTO-GENERATED CODE - SEE TOP FOR INSTRUCTIONS */
+#define HV_X64_MSR_STAT_PAGES_AVAILABLE (1 << 8)
 #define HV_X64_CREATE_PARTITIONS (1 << 0)
 #define HV_X64_ACCESS_PARTITION_ID (1 << 1)
 #define HV_X64_ACCESS_MEMORY_POOL (1 << 2)
-#define HV_X64_ADJUST_MESSAGE_BUFFERS (1 << 3)
 /* WARNING: DO NOT EDIT, AUTO-GENERATED CODE - SEE TOP FOR INSTRUCTIONS */
+#define HV_X64_ADJUST_MESSAGE_BUFFERS (1 << 3)
 #define HV_X64_POST_MESSAGES (1 << 4)
 #define HV_X64_SIGNAL_EVENTS (1 << 5)
 #define HV_X64_CREATE_PORT (1 << 6)
-#define HV_X64_CONNECT_PORT (1 << 7)
 /* WARNING: DO NOT EDIT, AUTO-GENERATED CODE - SEE TOP FOR INSTRUCTIONS */
+#define HV_X64_CONNECT_PORT (1 << 7)
 #define HV_X64_ACCESS_STATS (1 << 8)
 #define HV_X64_DEBUGGING (1 << 11)
 #define HV_X64_CPU_POWER_MANAGEMENT (1 << 12)
-#define HV_X64_CONFIGURE_PROFILER (1 << 13)
 /* WARNING: DO NOT EDIT, AUTO-GENERATED CODE - SEE TOP FOR INSTRUCTIONS */
+#define HV_X64_CONFIGURE_PROFILER (1 << 13)
 #define HV_X64_MWAIT_AVAILABLE (1 << 0)
 #define HV_X64_GUEST_DEBUGGING_AVAILABLE (1 << 1)
 #define HV_X64_PERF_MONITOR_AVAILABLE (1 << 2)
-#define HV_X64_CPU_DYNAMIC_PARTITIONING_AVAILABLE (1 << 3)
 /* WARNING: DO NOT EDIT, AUTO-GENERATED CODE - SEE TOP FOR INSTRUCTIONS */
+#define HV_X64_CPU_DYNAMIC_PARTITIONING_AVAILABLE (1 << 3)
 #define HV_X64_HYPERCALL_PARAMS_XMM_AVAILABLE (1 << 4)
 #define HV_X64_GUEST_IDLE_STATE_AVAILABLE (1 << 5)
+#define HV_X64_GUEST_CRASH_MSR_AVAILABLE (1 << 10)
+/* WARNING: DO NOT EDIT, AUTO-GENERATED CODE - SEE TOP FOR INSTRUCTIONS */
 #define HV_X64_MWAIT_RECOMMENDED (1 << 0)
 #define HV_X64_LOCAL_TLB_FLUSH_RECOMMENDED (1 << 1)
-/* WARNING: DO NOT EDIT, AUTO-GENERATED CODE - SEE TOP FOR INSTRUCTIONS */
 #define HV_X64_REMOTE_TLB_FLUSH_RECOMMENDED (1 << 2)
 #define HV_X64_APIC_ACCESS_RECOMMENDED (1 << 3)
+/* WARNING: DO NOT EDIT, AUTO-GENERATED CODE - SEE TOP FOR INSTRUCTIONS */
 #define HV_X64_SYSTEM_RESET_RECOMMENDED (1 << 4)
 #define HV_X64_RELAXED_TIMING_RECOMMENDED (1 << 5)
-/* WARNING: DO NOT EDIT, AUTO-GENERATED CODE - SEE TOP FOR INSTRUCTIONS */
 #define HV_X64_MSR_GUEST_OS_ID 0x40000000
 #define HV_X64_MSR_HYPERCALL 0x40000001
+/* WARNING: DO NOT EDIT, AUTO-GENERATED CODE - SEE TOP FOR INSTRUCTIONS */
 #define HV_X64_MSR_VP_INDEX 0x40000002
+#define HV_X64_MSR_RESET 0x40000003
+#define HV_X64_MSR_VP_RUNTIME 0x40000010
 #define HV_X64_MSR_TIME_REF_COUNT 0x40000020
 /* WARNING: DO NOT EDIT, AUTO-GENERATED CODE - SEE TOP FOR INSTRUCTIONS */
 #define HV_X64_MSR_TSC_FREQUENCY 0x40000022
@@ -114,6 +119,26 @@
 #define HV_X64_MSR_SINT13 0x4000009D
 #define HV_X64_MSR_SINT14 0x4000009E
 #define HV_X64_MSR_SINT15 0x4000009F
+#define HV_X64_MSR_STIMER0_CONFIG 0x400000B0
+/* WARNING: DO NOT EDIT, AUTO-GENERATED CODE - SEE TOP FOR INSTRUCTIONS */
+#define HV_X64_MSR_STIMER0_COUNT 0x400000B1
+#define HV_X64_MSR_STIMER1_CONFIG 0x400000B2
+#define HV_X64_MSR_STIMER1_COUNT 0x400000B3
+#define HV_X64_MSR_STIMER2_CONFIG 0x400000B4
+/* WARNING: DO NOT EDIT, AUTO-GENERATED CODE - SEE TOP FOR INSTRUCTIONS */
+#define HV_X64_MSR_STIMER2_COUNT 0x400000B5
+#define HV_X64_MSR_STIMER3_CONFIG 0x400000B6
+#define HV_X64_MSR_STIMER3_COUNT 0x400000B7
+#define HV_X64_MSR_CRASH_P0 0x40000100
+/* WARNING: DO NOT EDIT, AUTO-GENERATED CODE - SEE TOP FOR INSTRUCTIONS */
+#define HV_X64_MSR_CRASH_P1 0x40000101
+#define HV_X64_MSR_CRASH_P2 0x40000102
+#define HV_X64_MSR_CRASH_P3 0x40000103
+#define HV_X64_MSR_CRASH_P4 0x40000104
+/* WARNING: DO NOT EDIT, AUTO-GENERATED CODE - SEE TOP FOR INSTRUCTIONS */
+#define HV_X64_MSR_CRASH_CTL 0x40000105
+#define HV_X64_MSR_CRASH_CTL_NOTIFY (1ULL << 63)
+#define HV_X64_MSR_CRASH_PARAMS (1 + (HV_X64_MSR_CRASH_P4 - HV_X64_MSR_CRASH_P0))
 #define HV_X64_MSR_HYPERCALL_ENABLE 0x00000001
 /* WARNING: DO NOT EDIT, AUTO-GENERATED CODE - SEE TOP FOR INSTRUCTIONS */
 #define HV_X64_MSR_HYPERCALL_PAGE_ADDRESS_SHIFT 12
@@ -136,13 +161,25 @@
 #define HV_STATUS_INVALID_HYPERCALL_INPUT 3
 #define HV_STATUS_INVALID_ALIGNMENT 4
 /* WARNING: DO NOT EDIT, AUTO-GENERATED CODE - SEE TOP FOR INSTRUCTIONS */
+#define HV_STATUS_INSUFFICIENT_MEMORY 11
+#define HV_STATUS_INVALID_CONNECTION_ID 18
 #define HV_STATUS_INSUFFICIENT_BUFFERS 19
 typedef struct _HV_REFERENCE_TSC_PAGE {
+/* WARNING: DO NOT EDIT, AUTO-GENERATED CODE - SEE TOP FOR INSTRUCTIONS */
   __u32 tsc_sequence;
   __u32 res1;
-/* WARNING: DO NOT EDIT, AUTO-GENERATED CODE - SEE TOP FOR INSTRUCTIONS */
   __u64 tsc_scale;
   __s64 tsc_offset;
-} HV_REFERENCE_TSC_PAGE, * PHV_REFERENCE_TSC_PAGE;
-#endif
 /* WARNING: DO NOT EDIT, AUTO-GENERATED CODE - SEE TOP FOR INSTRUCTIONS */
+} HV_REFERENCE_TSC_PAGE, * PHV_REFERENCE_TSC_PAGE;
+#define HV_SYNIC_SINT_COUNT (16)
+#define HV_SYNIC_VERSION_1 (0x1)
+#define HV_SYNIC_CONTROL_ENABLE (1ULL << 0)
+/* WARNING: DO NOT EDIT, AUTO-GENERATED CODE - SEE TOP FOR INSTRUCTIONS */
+#define HV_SYNIC_SIMP_ENABLE (1ULL << 0)
+#define HV_SYNIC_SIEFP_ENABLE (1ULL << 0)
+#define HV_SYNIC_SINT_MASKED (1ULL << 16)
+#define HV_SYNIC_SINT_AUTO_EOI (1ULL << 17)
+/* WARNING: DO NOT EDIT, AUTO-GENERATED CODE - SEE TOP FOR INSTRUCTIONS */
+#define HV_SYNIC_SINT_VECTOR_MASK (0xFF)
+#endif
diff --git a/libc/kernel/uapi/asm-x86/asm/kvm.h b/libc/kernel/uapi/asm-x86/asm/kvm.h
index 6b6b6f2..45c8d12 100644
--- a/libc/kernel/uapi/asm-x86/asm/kvm.h
+++ b/libc/kernel/uapi/asm-x86/asm/kvm.h
@@ -129,209 +129,219 @@
 #define KVM_IRQCHIP_PIC_SLAVE 1
 #define KVM_IRQCHIP_IOAPIC 2
 #define KVM_NR_IRQCHIPS 3
-struct kvm_regs {
+#define KVM_RUN_X86_SMM (1 << 0)
 /* WARNING: DO NOT EDIT, AUTO-GENERATED CODE - SEE TOP FOR INSTRUCTIONS */
+struct kvm_regs {
   __u64 rax, rbx, rcx, rdx;
   __u64 rsi, rdi, rsp, rbp;
   __u64 r8, r9, r10, r11;
-  __u64 r12, r13, r14, r15;
 /* WARNING: DO NOT EDIT, AUTO-GENERATED CODE - SEE TOP FOR INSTRUCTIONS */
+  __u64 r12, r13, r14, r15;
   __u64 rip, rflags;
 };
 #define KVM_APIC_REG_SIZE 0x400
-struct kvm_lapic_state {
 /* WARNING: DO NOT EDIT, AUTO-GENERATED CODE - SEE TOP FOR INSTRUCTIONS */
+struct kvm_lapic_state {
   char regs[KVM_APIC_REG_SIZE];
 };
 struct kvm_segment {
-  __u64 base;
 /* WARNING: DO NOT EDIT, AUTO-GENERATED CODE - SEE TOP FOR INSTRUCTIONS */
+  __u64 base;
   __u32 limit;
   __u16 selector;
   __u8 type;
-  __u8 present, dpl, db, s, l, g, avl;
 /* WARNING: DO NOT EDIT, AUTO-GENERATED CODE - SEE TOP FOR INSTRUCTIONS */
+  __u8 present, dpl, db, s, l, g, avl;
   __u8 unusable;
   __u8 padding;
 };
-struct kvm_dtable {
 /* WARNING: DO NOT EDIT, AUTO-GENERATED CODE - SEE TOP FOR INSTRUCTIONS */
+struct kvm_dtable {
   __u64 base;
   __u16 limit;
   __u16 padding[3];
-};
 /* WARNING: DO NOT EDIT, AUTO-GENERATED CODE - SEE TOP FOR INSTRUCTIONS */
+};
 struct kvm_sregs {
   struct kvm_segment cs, ds, es, fs, gs, ss;
   struct kvm_segment tr, ldt;
-  struct kvm_dtable gdt, idt;
 /* WARNING: DO NOT EDIT, AUTO-GENERATED CODE - SEE TOP FOR INSTRUCTIONS */
+  struct kvm_dtable gdt, idt;
   __u64 cr0, cr2, cr3, cr4, cr8;
   __u64 efer;
   __u64 apic_base;
-  __u64 interrupt_bitmap[(KVM_NR_INTERRUPTS + 63) / 64];
 /* WARNING: DO NOT EDIT, AUTO-GENERATED CODE - SEE TOP FOR INSTRUCTIONS */
+  __u64 interrupt_bitmap[(KVM_NR_INTERRUPTS + 63) / 64];
 };
 struct kvm_fpu {
   __u8 fpr[8][16];
-  __u16 fcw;
 /* WARNING: DO NOT EDIT, AUTO-GENERATED CODE - SEE TOP FOR INSTRUCTIONS */
+  __u16 fcw;
   __u16 fsw;
   __u8 ftwx;
   __u8 pad1;
-  __u16 last_opcode;
 /* WARNING: DO NOT EDIT, AUTO-GENERATED CODE - SEE TOP FOR INSTRUCTIONS */
+  __u16 last_opcode;
   __u64 last_ip;
   __u64 last_dp;
   __u8 xmm[16][16];
-  __u32 mxcsr;
 /* WARNING: DO NOT EDIT, AUTO-GENERATED CODE - SEE TOP FOR INSTRUCTIONS */
+  __u32 mxcsr;
   __u32 pad2;
 };
 struct kvm_msr_entry {
-  __u32 index;
 /* WARNING: DO NOT EDIT, AUTO-GENERATED CODE - SEE TOP FOR INSTRUCTIONS */
+  __u32 index;
   __u32 reserved;
   __u64 data;
 };
-struct kvm_msrs {
 /* WARNING: DO NOT EDIT, AUTO-GENERATED CODE - SEE TOP FOR INSTRUCTIONS */
+struct kvm_msrs {
   __u32 nmsrs;
   __u32 pad;
   struct kvm_msr_entry entries[0];
-};
 /* WARNING: DO NOT EDIT, AUTO-GENERATED CODE - SEE TOP FOR INSTRUCTIONS */
+};
 struct kvm_msr_list {
   __u32 nmsrs;
   __u32 indices[0];
-};
 /* WARNING: DO NOT EDIT, AUTO-GENERATED CODE - SEE TOP FOR INSTRUCTIONS */
+};
 struct kvm_cpuid_entry {
   __u32 function;
   __u32 eax;
-  __u32 ebx;
 /* WARNING: DO NOT EDIT, AUTO-GENERATED CODE - SEE TOP FOR INSTRUCTIONS */
+  __u32 ebx;
   __u32 ecx;
   __u32 edx;
   __u32 padding;
-};
 /* WARNING: DO NOT EDIT, AUTO-GENERATED CODE - SEE TOP FOR INSTRUCTIONS */
+};
 struct kvm_cpuid {
   __u32 nent;
   __u32 padding;
-  struct kvm_cpuid_entry entries[0];
 /* WARNING: DO NOT EDIT, AUTO-GENERATED CODE - SEE TOP FOR INSTRUCTIONS */
+  struct kvm_cpuid_entry entries[0];
 };
 struct kvm_cpuid_entry2 {
   __u32 function;
-  __u32 index;
 /* WARNING: DO NOT EDIT, AUTO-GENERATED CODE - SEE TOP FOR INSTRUCTIONS */
+  __u32 index;
   __u32 flags;
   __u32 eax;
   __u32 ebx;
-  __u32 ecx;
 /* WARNING: DO NOT EDIT, AUTO-GENERATED CODE - SEE TOP FOR INSTRUCTIONS */
+  __u32 ecx;
   __u32 edx;
   __u32 padding[3];
 };
-#define KVM_CPUID_FLAG_SIGNIFCANT_INDEX BIT(0)
 /* WARNING: DO NOT EDIT, AUTO-GENERATED CODE - SEE TOP FOR INSTRUCTIONS */
+#define KVM_CPUID_FLAG_SIGNIFCANT_INDEX BIT(0)
 #define KVM_CPUID_FLAG_STATEFUL_FUNC BIT(1)
 #define KVM_CPUID_FLAG_STATE_READ_NEXT BIT(2)
 struct kvm_cpuid2 {
-  __u32 nent;
 /* WARNING: DO NOT EDIT, AUTO-GENERATED CODE - SEE TOP FOR INSTRUCTIONS */
+  __u32 nent;
   __u32 padding;
   struct kvm_cpuid_entry2 entries[0];
 };
-struct kvm_pit_channel_state {
 /* WARNING: DO NOT EDIT, AUTO-GENERATED CODE - SEE TOP FOR INSTRUCTIONS */
+struct kvm_pit_channel_state {
   __u32 count;
   __u16 latched_count;
   __u8 count_latched;
-  __u8 status_latched;
 /* WARNING: DO NOT EDIT, AUTO-GENERATED CODE - SEE TOP FOR INSTRUCTIONS */
+  __u8 status_latched;
   __u8 status;
   __u8 read_state;
   __u8 write_state;
-  __u8 write_latch;
 /* WARNING: DO NOT EDIT, AUTO-GENERATED CODE - SEE TOP FOR INSTRUCTIONS */
+  __u8 write_latch;
   __u8 rw_mode;
   __u8 mode;
   __u8 bcd;
-  __u8 gate;
 /* WARNING: DO NOT EDIT, AUTO-GENERATED CODE - SEE TOP FOR INSTRUCTIONS */
+  __u8 gate;
   __s64 count_load_time;
 };
 struct kvm_debug_exit_arch {
-  __u32 exception;
 /* WARNING: DO NOT EDIT, AUTO-GENERATED CODE - SEE TOP FOR INSTRUCTIONS */
+  __u32 exception;
   __u32 pad;
   __u64 pc;
   __u64 dr6;
-  __u64 dr7;
 /* WARNING: DO NOT EDIT, AUTO-GENERATED CODE - SEE TOP FOR INSTRUCTIONS */
+  __u64 dr7;
 };
 #define KVM_GUESTDBG_USE_SW_BP 0x00010000
 #define KVM_GUESTDBG_USE_HW_BP 0x00020000
-#define KVM_GUESTDBG_INJECT_DB 0x00040000
 /* WARNING: DO NOT EDIT, AUTO-GENERATED CODE - SEE TOP FOR INSTRUCTIONS */
+#define KVM_GUESTDBG_INJECT_DB 0x00040000
 #define KVM_GUESTDBG_INJECT_BP 0x00080000
 struct kvm_guest_debug_arch {
   __u64 debugreg[8];
-};
 /* WARNING: DO NOT EDIT, AUTO-GENERATED CODE - SEE TOP FOR INSTRUCTIONS */
+};
 struct kvm_pit_state {
   struct kvm_pit_channel_state channels[3];
 };
-#define KVM_PIT_FLAGS_HPET_LEGACY 0x00000001
 /* WARNING: DO NOT EDIT, AUTO-GENERATED CODE - SEE TOP FOR INSTRUCTIONS */
+#define KVM_PIT_FLAGS_HPET_LEGACY 0x00000001
 struct kvm_pit_state2 {
   struct kvm_pit_channel_state channels[3];
   __u32 flags;
-  __u32 reserved[9];
 /* WARNING: DO NOT EDIT, AUTO-GENERATED CODE - SEE TOP FOR INSTRUCTIONS */
+  __u32 reserved[9];
 };
 struct kvm_reinject_control {
   __u8 pit_reinject;
-  __u8 reserved[31];
 /* WARNING: DO NOT EDIT, AUTO-GENERATED CODE - SEE TOP FOR INSTRUCTIONS */
+  __u8 reserved[31];
 };
 #define KVM_VCPUEVENT_VALID_NMI_PENDING 0x00000001
 #define KVM_VCPUEVENT_VALID_SIPI_VECTOR 0x00000002
-#define KVM_VCPUEVENT_VALID_SHADOW 0x00000004
 /* WARNING: DO NOT EDIT, AUTO-GENERATED CODE - SEE TOP FOR INSTRUCTIONS */
+#define KVM_VCPUEVENT_VALID_SHADOW 0x00000004
+#define KVM_VCPUEVENT_VALID_SMM 0x00000008
 #define KVM_X86_SHADOW_INT_MOV_SS 0x01
 #define KVM_X86_SHADOW_INT_STI 0x02
+/* WARNING: DO NOT EDIT, AUTO-GENERATED CODE - SEE TOP FOR INSTRUCTIONS */
 struct kvm_vcpu_events {
   struct {
-/* WARNING: DO NOT EDIT, AUTO-GENERATED CODE - SEE TOP FOR INSTRUCTIONS */
     __u8 injected;
     __u8 nr;
+/* WARNING: DO NOT EDIT, AUTO-GENERATED CODE - SEE TOP FOR INSTRUCTIONS */
     __u8 has_error_code;
     __u8 pad;
-/* WARNING: DO NOT EDIT, AUTO-GENERATED CODE - SEE TOP FOR INSTRUCTIONS */
     __u32 error_code;
   } exception;
+/* WARNING: DO NOT EDIT, AUTO-GENERATED CODE - SEE TOP FOR INSTRUCTIONS */
   struct {
     __u8 injected;
-/* WARNING: DO NOT EDIT, AUTO-GENERATED CODE - SEE TOP FOR INSTRUCTIONS */
     __u8 nr;
     __u8 soft;
+/* WARNING: DO NOT EDIT, AUTO-GENERATED CODE - SEE TOP FOR INSTRUCTIONS */
     __u8 shadow;
   } interrupt;
-/* WARNING: DO NOT EDIT, AUTO-GENERATED CODE - SEE TOP FOR INSTRUCTIONS */
   struct {
     __u8 injected;
+/* WARNING: DO NOT EDIT, AUTO-GENERATED CODE - SEE TOP FOR INSTRUCTIONS */
     __u8 pending;
     __u8 masked;
-/* WARNING: DO NOT EDIT, AUTO-GENERATED CODE - SEE TOP FOR INSTRUCTIONS */
     __u8 pad;
   } nmi;
+/* WARNING: DO NOT EDIT, AUTO-GENERATED CODE - SEE TOP FOR INSTRUCTIONS */
   __u32 sipi_vector;
   __u32 flags;
+  struct {
+    __u8 smm;
 /* WARNING: DO NOT EDIT, AUTO-GENERATED CODE - SEE TOP FOR INSTRUCTIONS */
-  __u32 reserved[10];
+    __u8 pending;
+    __u8 smm_inside_nmi;
+    __u8 latched_init;
+  } smi;
+/* WARNING: DO NOT EDIT, AUTO-GENERATED CODE - SEE TOP FOR INSTRUCTIONS */
+  __u32 reserved[9];
 };
 struct kvm_debugregs {
   __u64 db[4];
@@ -363,4 +373,7 @@
 /* WARNING: DO NOT EDIT, AUTO-GENERATED CODE - SEE TOP FOR INSTRUCTIONS */
 struct kvm_sync_regs {
 };
+#define KVM_X86_QUIRK_LINT0_REENABLED (1 << 0)
+#define KVM_X86_QUIRK_CD_NW_CLEARED (1 << 1)
+/* WARNING: DO NOT EDIT, AUTO-GENERATED CODE - SEE TOP FOR INSTRUCTIONS */
 #endif
diff --git a/libc/kernel/uapi/asm-x86/asm/mce.h b/libc/kernel/uapi/asm-x86/asm/mce.h
index dce4194..ca24c44 100644
--- a/libc/kernel/uapi/asm-x86/asm/mce.h
+++ b/libc/kernel/uapi/asm-x86/asm/mce.h
@@ -19,7 +19,7 @@
 #ifndef _UAPI_ASM_X86_MCE_H
 #define _UAPI_ASM_X86_MCE_H
 #include <linux/types.h>
-#include <asm/ioctls.h>
+#include <linux/ioctl.h>
 /* WARNING: DO NOT EDIT, AUTO-GENERATED CODE - SEE TOP FOR INSTRUCTIONS */
 struct mce {
   __u64 status;
@@ -33,22 +33,23 @@
 /* WARNING: DO NOT EDIT, AUTO-GENERATED CODE - SEE TOP FOR INSTRUCTIONS */
   __u8 cpuvendor;
   __u8 inject_flags;
-  __u16 pad;
-  __u32 cpuid;
+  __u8 severity;
+  __u8 usable_addr;
 /* WARNING: DO NOT EDIT, AUTO-GENERATED CODE - SEE TOP FOR INSTRUCTIONS */
+  __u32 cpuid;
   __u8 cs;
   __u8 bank;
   __u8 cpu;
-  __u8 finished;
 /* WARNING: DO NOT EDIT, AUTO-GENERATED CODE - SEE TOP FOR INSTRUCTIONS */
+  __u8 finished;
   __u32 extcpu;
   __u32 socketid;
   __u32 apicid;
-  __u64 mcgcap;
 /* WARNING: DO NOT EDIT, AUTO-GENERATED CODE - SEE TOP FOR INSTRUCTIONS */
+  __u64 mcgcap;
 };
 #define MCE_GET_RECORD_LEN _IOR('M', 1, int)
 #define MCE_GET_LOG_LEN _IOR('M', 2, int)
-#define MCE_GETCLEAR_FLAGS _IOR('M', 3, int)
 /* WARNING: DO NOT EDIT, AUTO-GENERATED CODE - SEE TOP FOR INSTRUCTIONS */
+#define MCE_GETCLEAR_FLAGS _IOR('M', 3, int)
 #endif
diff --git a/libc/kernel/uapi/asm-x86/asm/msr.h b/libc/kernel/uapi/asm-x86/asm/msr.h
index c648410..020bf3a 100644
--- a/libc/kernel/uapi/asm-x86/asm/msr.h
+++ b/libc/kernel/uapi/asm-x86/asm/msr.h
@@ -18,13 +18,12 @@
  ****************************************************************************/
 #ifndef _UAPI_ASM_X86_MSR_H
 #define _UAPI_ASM_X86_MSR_H
-#include <asm/msr-index.h>
 #ifndef __ASSEMBLY__
-/* WARNING: DO NOT EDIT, AUTO-GENERATED CODE - SEE TOP FOR INSTRUCTIONS */
 #include <linux/types.h>
+/* WARNING: DO NOT EDIT, AUTO-GENERATED CODE - SEE TOP FOR INSTRUCTIONS */
 #include <linux/ioctl.h>
 #define X86_IOC_RDMSR_REGS _IOWR('c', 0xA0, __u32[8])
 #define X86_IOC_WRMSR_REGS _IOWR('c', 0xA1, __u32[8])
-/* WARNING: DO NOT EDIT, AUTO-GENERATED CODE - SEE TOP FOR INSTRUCTIONS */
 #endif
+/* WARNING: DO NOT EDIT, AUTO-GENERATED CODE - SEE TOP FOR INSTRUCTIONS */
 #endif
diff --git a/libc/kernel/uapi/asm-x86/asm/mtrr.h b/libc/kernel/uapi/asm-x86/asm/mtrr.h
index 135fa33..b697b7f 100644
--- a/libc/kernel/uapi/asm-x86/asm/mtrr.h
+++ b/libc/kernel/uapi/asm-x86/asm/mtrr.h
@@ -98,4 +98,6 @@
 /* WARNING: DO NOT EDIT, AUTO-GENERATED CODE - SEE TOP FOR INSTRUCTIONS */
 #define MTRR_TYPE_WRBACK 6
 #define MTRR_NUM_TYPES 7
+#define MTRR_TYPE_INVALID 0xff
 #endif
+/* WARNING: DO NOT EDIT, AUTO-GENERATED CODE - SEE TOP FOR INSTRUCTIONS */
diff --git a/libc/kernel/uapi/asm-x86/asm/processor-flags.h b/libc/kernel/uapi/asm-x86/asm/processor-flags.h
index 3c36ddc..74fbff2 100644
--- a/libc/kernel/uapi/asm-x86/asm/processor-flags.h
+++ b/libc/kernel/uapi/asm-x86/asm/processor-flags.h
@@ -57,113 +57,110 @@
 #define X86_EFLAGS_AC_BIT 18
 /* WARNING: DO NOT EDIT, AUTO-GENERATED CODE - SEE TOP FOR INSTRUCTIONS */
 #define X86_EFLAGS_AC _BITUL(X86_EFLAGS_AC_BIT)
-#define X86_EFLAGS_AC_BIT 18
-#define X86_EFLAGS_AC _BITUL(X86_EFLAGS_AC_BIT)
 #define X86_EFLAGS_VIF_BIT 19
-/* WARNING: DO NOT EDIT, AUTO-GENERATED CODE - SEE TOP FOR INSTRUCTIONS */
 #define X86_EFLAGS_VIF _BITUL(X86_EFLAGS_VIF_BIT)
 #define X86_EFLAGS_VIP_BIT 20
+/* WARNING: DO NOT EDIT, AUTO-GENERATED CODE - SEE TOP FOR INSTRUCTIONS */
 #define X86_EFLAGS_VIP _BITUL(X86_EFLAGS_VIP_BIT)
 #define X86_EFLAGS_ID_BIT 21
-/* WARNING: DO NOT EDIT, AUTO-GENERATED CODE - SEE TOP FOR INSTRUCTIONS */
 #define X86_EFLAGS_ID _BITUL(X86_EFLAGS_ID_BIT)
 #define X86_CR0_PE_BIT 0
+/* WARNING: DO NOT EDIT, AUTO-GENERATED CODE - SEE TOP FOR INSTRUCTIONS */
 #define X86_CR0_PE _BITUL(X86_CR0_PE_BIT)
 #define X86_CR0_MP_BIT 1
-/* WARNING: DO NOT EDIT, AUTO-GENERATED CODE - SEE TOP FOR INSTRUCTIONS */
 #define X86_CR0_MP _BITUL(X86_CR0_MP_BIT)
 #define X86_CR0_EM_BIT 2
+/* WARNING: DO NOT EDIT, AUTO-GENERATED CODE - SEE TOP FOR INSTRUCTIONS */
 #define X86_CR0_EM _BITUL(X86_CR0_EM_BIT)
 #define X86_CR0_TS_BIT 3
-/* WARNING: DO NOT EDIT, AUTO-GENERATED CODE - SEE TOP FOR INSTRUCTIONS */
 #define X86_CR0_TS _BITUL(X86_CR0_TS_BIT)
 #define X86_CR0_ET_BIT 4
+/* WARNING: DO NOT EDIT, AUTO-GENERATED CODE - SEE TOP FOR INSTRUCTIONS */
 #define X86_CR0_ET _BITUL(X86_CR0_ET_BIT)
 #define X86_CR0_NE_BIT 5
-/* WARNING: DO NOT EDIT, AUTO-GENERATED CODE - SEE TOP FOR INSTRUCTIONS */
 #define X86_CR0_NE _BITUL(X86_CR0_NE_BIT)
 #define X86_CR0_WP_BIT 16
+/* WARNING: DO NOT EDIT, AUTO-GENERATED CODE - SEE TOP FOR INSTRUCTIONS */
 #define X86_CR0_WP _BITUL(X86_CR0_WP_BIT)
 #define X86_CR0_AM_BIT 18
-/* WARNING: DO NOT EDIT, AUTO-GENERATED CODE - SEE TOP FOR INSTRUCTIONS */
 #define X86_CR0_AM _BITUL(X86_CR0_AM_BIT)
 #define X86_CR0_NW_BIT 29
+/* WARNING: DO NOT EDIT, AUTO-GENERATED CODE - SEE TOP FOR INSTRUCTIONS */
 #define X86_CR0_NW _BITUL(X86_CR0_NW_BIT)
 #define X86_CR0_CD_BIT 30
-/* WARNING: DO NOT EDIT, AUTO-GENERATED CODE - SEE TOP FOR INSTRUCTIONS */
 #define X86_CR0_CD _BITUL(X86_CR0_CD_BIT)
 #define X86_CR0_PG_BIT 31
+/* WARNING: DO NOT EDIT, AUTO-GENERATED CODE - SEE TOP FOR INSTRUCTIONS */
 #define X86_CR0_PG _BITUL(X86_CR0_PG_BIT)
 #define X86_CR3_PWT_BIT 3
-/* WARNING: DO NOT EDIT, AUTO-GENERATED CODE - SEE TOP FOR INSTRUCTIONS */
 #define X86_CR3_PWT _BITUL(X86_CR3_PWT_BIT)
 #define X86_CR3_PCD_BIT 4
+/* WARNING: DO NOT EDIT, AUTO-GENERATED CODE - SEE TOP FOR INSTRUCTIONS */
 #define X86_CR3_PCD _BITUL(X86_CR3_PCD_BIT)
 #define X86_CR3_PCID_MASK _AC(0x00000fff, UL)
-/* WARNING: DO NOT EDIT, AUTO-GENERATED CODE - SEE TOP FOR INSTRUCTIONS */
 #define X86_CR4_VME_BIT 0
 #define X86_CR4_VME _BITUL(X86_CR4_VME_BIT)
+/* WARNING: DO NOT EDIT, AUTO-GENERATED CODE - SEE TOP FOR INSTRUCTIONS */
 #define X86_CR4_PVI_BIT 1
 #define X86_CR4_PVI _BITUL(X86_CR4_PVI_BIT)
-/* WARNING: DO NOT EDIT, AUTO-GENERATED CODE - SEE TOP FOR INSTRUCTIONS */
 #define X86_CR4_TSD_BIT 2
 #define X86_CR4_TSD _BITUL(X86_CR4_TSD_BIT)
+/* WARNING: DO NOT EDIT, AUTO-GENERATED CODE - SEE TOP FOR INSTRUCTIONS */
 #define X86_CR4_DE_BIT 3
 #define X86_CR4_DE _BITUL(X86_CR4_DE_BIT)
-/* WARNING: DO NOT EDIT, AUTO-GENERATED CODE - SEE TOP FOR INSTRUCTIONS */
 #define X86_CR4_PSE_BIT 4
 #define X86_CR4_PSE _BITUL(X86_CR4_PSE_BIT)
+/* WARNING: DO NOT EDIT, AUTO-GENERATED CODE - SEE TOP FOR INSTRUCTIONS */
 #define X86_CR4_PAE_BIT 5
 #define X86_CR4_PAE _BITUL(X86_CR4_PAE_BIT)
-/* WARNING: DO NOT EDIT, AUTO-GENERATED CODE - SEE TOP FOR INSTRUCTIONS */
 #define X86_CR4_MCE_BIT 6
 #define X86_CR4_MCE _BITUL(X86_CR4_MCE_BIT)
+/* WARNING: DO NOT EDIT, AUTO-GENERATED CODE - SEE TOP FOR INSTRUCTIONS */
 #define X86_CR4_PGE_BIT 7
 #define X86_CR4_PGE _BITUL(X86_CR4_PGE_BIT)
-/* WARNING: DO NOT EDIT, AUTO-GENERATED CODE - SEE TOP FOR INSTRUCTIONS */
 #define X86_CR4_PCE_BIT 8
 #define X86_CR4_PCE _BITUL(X86_CR4_PCE_BIT)
+/* WARNING: DO NOT EDIT, AUTO-GENERATED CODE - SEE TOP FOR INSTRUCTIONS */
 #define X86_CR4_OSFXSR_BIT 9
 #define X86_CR4_OSFXSR _BITUL(X86_CR4_OSFXSR_BIT)
-/* WARNING: DO NOT EDIT, AUTO-GENERATED CODE - SEE TOP FOR INSTRUCTIONS */
 #define X86_CR4_OSXMMEXCPT_BIT 10
 #define X86_CR4_OSXMMEXCPT _BITUL(X86_CR4_OSXMMEXCPT_BIT)
+/* WARNING: DO NOT EDIT, AUTO-GENERATED CODE - SEE TOP FOR INSTRUCTIONS */
 #define X86_CR4_VMXE_BIT 13
 #define X86_CR4_VMXE _BITUL(X86_CR4_VMXE_BIT)
-/* WARNING: DO NOT EDIT, AUTO-GENERATED CODE - SEE TOP FOR INSTRUCTIONS */
 #define X86_CR4_SMXE_BIT 14
 #define X86_CR4_SMXE _BITUL(X86_CR4_SMXE_BIT)
+/* WARNING: DO NOT EDIT, AUTO-GENERATED CODE - SEE TOP FOR INSTRUCTIONS */
 #define X86_CR4_FSGSBASE_BIT 16
 #define X86_CR4_FSGSBASE _BITUL(X86_CR4_FSGSBASE_BIT)
-/* WARNING: DO NOT EDIT, AUTO-GENERATED CODE - SEE TOP FOR INSTRUCTIONS */
 #define X86_CR4_PCIDE_BIT 17
 #define X86_CR4_PCIDE _BITUL(X86_CR4_PCIDE_BIT)
+/* WARNING: DO NOT EDIT, AUTO-GENERATED CODE - SEE TOP FOR INSTRUCTIONS */
 #define X86_CR4_OSXSAVE_BIT 18
 #define X86_CR4_OSXSAVE _BITUL(X86_CR4_OSXSAVE_BIT)
-/* WARNING: DO NOT EDIT, AUTO-GENERATED CODE - SEE TOP FOR INSTRUCTIONS */
 #define X86_CR4_SMEP_BIT 20
 #define X86_CR4_SMEP _BITUL(X86_CR4_SMEP_BIT)
+/* WARNING: DO NOT EDIT, AUTO-GENERATED CODE - SEE TOP FOR INSTRUCTIONS */
 #define X86_CR4_SMAP_BIT 21
 #define X86_CR4_SMAP _BITUL(X86_CR4_SMAP_BIT)
-/* WARNING: DO NOT EDIT, AUTO-GENERATED CODE - SEE TOP FOR INSTRUCTIONS */
 #define X86_CR8_TPR _AC(0x0000000f, UL)
 #define CX86_PCR0 0x20
+/* WARNING: DO NOT EDIT, AUTO-GENERATED CODE - SEE TOP FOR INSTRUCTIONS */
 #define CX86_GCR 0xb8
 #define CX86_CCR0 0xc0
-/* WARNING: DO NOT EDIT, AUTO-GENERATED CODE - SEE TOP FOR INSTRUCTIONS */
 #define CX86_CCR1 0xc1
 #define CX86_CCR2 0xc2
+/* WARNING: DO NOT EDIT, AUTO-GENERATED CODE - SEE TOP FOR INSTRUCTIONS */
 #define CX86_CCR3 0xc3
 #define CX86_CCR4 0xe8
-/* WARNING: DO NOT EDIT, AUTO-GENERATED CODE - SEE TOP FOR INSTRUCTIONS */
 #define CX86_CCR5 0xe9
 #define CX86_CCR6 0xea
+/* WARNING: DO NOT EDIT, AUTO-GENERATED CODE - SEE TOP FOR INSTRUCTIONS */
 #define CX86_CCR7 0xeb
 #define CX86_PCR1 0xf0
-/* WARNING: DO NOT EDIT, AUTO-GENERATED CODE - SEE TOP FOR INSTRUCTIONS */
 #define CX86_DIR0 0xfe
 #define CX86_DIR1 0xff
+/* WARNING: DO NOT EDIT, AUTO-GENERATED CODE - SEE TOP FOR INSTRUCTIONS */
 #define CX86_ARR_BASE 0xc4
 #define CX86_RCR_BASE 0xdc
-/* WARNING: DO NOT EDIT, AUTO-GENERATED CODE - SEE TOP FOR INSTRUCTIONS */
 #endif
diff --git a/libc/kernel/uapi/asm-x86/asm/ptrace-abi.h b/libc/kernel/uapi/asm-x86/asm/ptrace-abi.h
index f10a195..b09aedb 100644
--- a/libc/kernel/uapi/asm-x86/asm/ptrace-abi.h
+++ b/libc/kernel/uapi/asm-x86/asm/ptrace-abi.h
@@ -71,31 +71,30 @@
 #define RSP 152
 #define SS 160
 /* WARNING: DO NOT EDIT, AUTO-GENERATED CODE - SEE TOP FOR INSTRUCTIONS */
-#define ARGOFFSET R11
 #endif
 #define FRAME_SIZE 168
 #endif
-/* WARNING: DO NOT EDIT, AUTO-GENERATED CODE - SEE TOP FOR INSTRUCTIONS */
 #define PTRACE_GETREGS 12
+/* WARNING: DO NOT EDIT, AUTO-GENERATED CODE - SEE TOP FOR INSTRUCTIONS */
 #define PTRACE_SETREGS 13
 #define PTRACE_GETFPREGS 14
 #define PTRACE_SETFPREGS 15
-/* WARNING: DO NOT EDIT, AUTO-GENERATED CODE - SEE TOP FOR INSTRUCTIONS */
 #define PTRACE_GETFPXREGS 18
+/* WARNING: DO NOT EDIT, AUTO-GENERATED CODE - SEE TOP FOR INSTRUCTIONS */
 #define PTRACE_SETFPXREGS 19
 #define PTRACE_OLDSETOPTIONS 21
 #define PTRACE_GET_THREAD_AREA 25
-/* WARNING: DO NOT EDIT, AUTO-GENERATED CODE - SEE TOP FOR INSTRUCTIONS */
 #define PTRACE_SET_THREAD_AREA 26
+/* WARNING: DO NOT EDIT, AUTO-GENERATED CODE - SEE TOP FOR INSTRUCTIONS */
 #ifdef __x86_64__
 #define PTRACE_ARCH_PRCTL 30
 #endif
-/* WARNING: DO NOT EDIT, AUTO-GENERATED CODE - SEE TOP FOR INSTRUCTIONS */
 #define PTRACE_SYSEMU 31
+/* WARNING: DO NOT EDIT, AUTO-GENERATED CODE - SEE TOP FOR INSTRUCTIONS */
 #define PTRACE_SYSEMU_SINGLESTEP 32
 #define PTRACE_SINGLEBLOCK 33
 #ifndef __ASSEMBLY__
-/* WARNING: DO NOT EDIT, AUTO-GENERATED CODE - SEE TOP FOR INSTRUCTIONS */
 #include <linux/types.h>
+/* WARNING: DO NOT EDIT, AUTO-GENERATED CODE - SEE TOP FOR INSTRUCTIONS */
 #endif
 #endif
diff --git a/libc/kernel/uapi/asm-x86/asm/sigcontext.h b/libc/kernel/uapi/asm-x86/asm/sigcontext.h
index b925d44..c9dbc50 100644
--- a/libc/kernel/uapi/asm-x86/asm/sigcontext.h
+++ b/libc/kernel/uapi/asm-x86/asm/sigcontext.h
@@ -28,153 +28,88 @@
 /* WARNING: DO NOT EDIT, AUTO-GENERATED CODE - SEE TOP FOR INSTRUCTIONS */
   __u32 magic1;
   __u32 extended_size;
-  __u64 xstate_bv;
+  __u64 xfeatures;
   __u32 xstate_size;
 /* WARNING: DO NOT EDIT, AUTO-GENERATED CODE - SEE TOP FOR INSTRUCTIONS */
   __u32 padding[7];
 };
-#ifdef __i386__
 struct _fpreg {
+  __u16 significand[4];
 /* WARNING: DO NOT EDIT, AUTO-GENERATED CODE - SEE TOP FOR INSTRUCTIONS */
-  unsigned short significand[4];
-  unsigned short exponent;
+  __u16 exponent;
 };
 struct _fpxreg {
+  __u16 significand[4];
 /* WARNING: DO NOT EDIT, AUTO-GENERATED CODE - SEE TOP FOR INSTRUCTIONS */
-  unsigned short significand[4];
-  unsigned short exponent;
-  unsigned short padding[3];
+  __u16 exponent;
+  __u16 padding[3];
 };
-/* WARNING: DO NOT EDIT, AUTO-GENERATED CODE - SEE TOP FOR INSTRUCTIONS */
 struct _xmmreg {
-  unsigned long element[4];
-};
-struct _fpstate {
 /* WARNING: DO NOT EDIT, AUTO-GENERATED CODE - SEE TOP FOR INSTRUCTIONS */
-  unsigned long cw;
-  unsigned long sw;
-  unsigned long tag;
-  unsigned long ipoff;
-/* WARNING: DO NOT EDIT, AUTO-GENERATED CODE - SEE TOP FOR INSTRUCTIONS */
-  unsigned long cssel;
-  unsigned long dataoff;
-  unsigned long datasel;
-  struct _fpreg _st[8];
-/* WARNING: DO NOT EDIT, AUTO-GENERATED CODE - SEE TOP FOR INSTRUCTIONS */
-  unsigned short status;
-  unsigned short magic;
-  unsigned long _fxsr_env[6];
-  unsigned long mxcsr;
-/* WARNING: DO NOT EDIT, AUTO-GENERATED CODE - SEE TOP FOR INSTRUCTIONS */
-  unsigned long reserved;
-  struct _fpxreg _fxsr_st[8];
-  struct _xmmreg _xmm[8];
-  unsigned long padding1[44];
-/* WARNING: DO NOT EDIT, AUTO-GENERATED CODE - SEE TOP FOR INSTRUCTIONS */
-  union {
-    unsigned long padding2[12];
-    struct _fpx_sw_bytes sw_reserved;
-  };
-/* WARNING: DO NOT EDIT, AUTO-GENERATED CODE - SEE TOP FOR INSTRUCTIONS */
+  __u32 element[4];
 };
 #define X86_FXSR_MAGIC 0x0000
-struct sigcontext {
-  unsigned short gs, __gsh;
+struct _fpstate_32 {
 /* WARNING: DO NOT EDIT, AUTO-GENERATED CODE - SEE TOP FOR INSTRUCTIONS */
-  unsigned short fs, __fsh;
-  unsigned short es, __esh;
-  unsigned short ds, __dsh;
-  unsigned long edi;
+  __u32 cw;
+  __u32 sw;
+  __u32 tag;
+  __u32 ipoff;
 /* WARNING: DO NOT EDIT, AUTO-GENERATED CODE - SEE TOP FOR INSTRUCTIONS */
-  unsigned long esi;
-  unsigned long ebp;
-  unsigned long esp;
-  unsigned long ebx;
+  __u32 cssel;
+  __u32 dataoff;
+  __u32 datasel;
+  struct _fpreg _st[8];
 /* WARNING: DO NOT EDIT, AUTO-GENERATED CODE - SEE TOP FOR INSTRUCTIONS */
-  unsigned long edx;
-  unsigned long ecx;
-  unsigned long eax;
-  unsigned long trapno;
+  __u16 status;
+  __u16 magic;
+  __u32 _fxsr_env[6];
+  __u32 mxcsr;
 /* WARNING: DO NOT EDIT, AUTO-GENERATED CODE - SEE TOP FOR INSTRUCTIONS */
-  unsigned long err;
-  unsigned long eip;
-  unsigned short cs, __csh;
-  unsigned long eflags;
+  __u32 reserved;
+  struct _fpxreg _fxsr_st[8];
+  struct _xmmreg _xmm[8];
+  union {
 /* WARNING: DO NOT EDIT, AUTO-GENERATED CODE - SEE TOP FOR INSTRUCTIONS */
-  unsigned long esp_at_signal;
-  unsigned short ss, __ssh;
-  struct _fpstate __user * fpstate;
-  unsigned long oldmask;
+    __u32 padding1[44];
+    __u32 padding[44];
+  };
+  union {
 /* WARNING: DO NOT EDIT, AUTO-GENERATED CODE - SEE TOP FOR INSTRUCTIONS */
-  unsigned long cr2;
+    __u32 padding2[12];
+    struct _fpx_sw_bytes sw_reserved;
+  };
 };
-#else
-struct _fpstate {
 /* WARNING: DO NOT EDIT, AUTO-GENERATED CODE - SEE TOP FOR INSTRUCTIONS */
+struct _fpstate_64 {
   __u16 cwd;
   __u16 swd;
   __u16 twd;
-  __u16 fop;
 /* WARNING: DO NOT EDIT, AUTO-GENERATED CODE - SEE TOP FOR INSTRUCTIONS */
+  __u16 fop;
   __u64 rip;
   __u64 rdp;
   __u32 mxcsr;
-  __u32 mxcsr_mask;
 /* WARNING: DO NOT EDIT, AUTO-GENERATED CODE - SEE TOP FOR INSTRUCTIONS */
+  __u32 mxcsr_mask;
   __u32 st_space[32];
   __u32 xmm_space[64];
   __u32 reserved2[12];
-  union {
 /* WARNING: DO NOT EDIT, AUTO-GENERATED CODE - SEE TOP FOR INSTRUCTIONS */
+  union {
     __u32 reserved3[12];
     struct _fpx_sw_bytes sw_reserved;
   };
-};
-/* WARNING: DO NOT EDIT, AUTO-GENERATED CODE - SEE TOP FOR INSTRUCTIONS */
-struct sigcontext {
-  __u64 r8;
-  __u64 r9;
-  __u64 r10;
-/* WARNING: DO NOT EDIT, AUTO-GENERATED CODE - SEE TOP FOR INSTRUCTIONS */
-  __u64 r11;
-  __u64 r12;
-  __u64 r13;
-  __u64 r14;
-/* WARNING: DO NOT EDIT, AUTO-GENERATED CODE - SEE TOP FOR INSTRUCTIONS */
-  __u64 r15;
-  __u64 rdi;
-  __u64 rsi;
-  __u64 rbp;
-/* WARNING: DO NOT EDIT, AUTO-GENERATED CODE - SEE TOP FOR INSTRUCTIONS */
-  __u64 rbx;
-  __u64 rdx;
-  __u64 rax;
-  __u64 rcx;
-/* WARNING: DO NOT EDIT, AUTO-GENERATED CODE - SEE TOP FOR INSTRUCTIONS */
-  __u64 rsp;
-  __u64 rip;
-  __u64 eflags;
-  __u16 cs;
-/* WARNING: DO NOT EDIT, AUTO-GENERATED CODE - SEE TOP FOR INSTRUCTIONS */
-  __u16 gs;
-  __u16 fs;
-  __u16 __pad0;
-  __u64 err;
-/* WARNING: DO NOT EDIT, AUTO-GENERATED CODE - SEE TOP FOR INSTRUCTIONS */
-  __u64 trapno;
-  __u64 oldmask;
-  __u64 cr2;
-  struct _fpstate __user * fpstate;
-/* WARNING: DO NOT EDIT, AUTO-GENERATED CODE - SEE TOP FOR INSTRUCTIONS */
-#ifdef __ILP32__
-  __u32 __fpstate_pad;
-#endif
-  __u64 reserved1[8];
 /* WARNING: DO NOT EDIT, AUTO-GENERATED CODE - SEE TOP FOR INSTRUCTIONS */
 };
+#ifdef __i386__
+#define _fpstate _fpstate_32
+#else
+/* WARNING: DO NOT EDIT, AUTO-GENERATED CODE - SEE TOP FOR INSTRUCTIONS */
+#define _fpstate _fpstate_64
 #endif
-struct _xsave_hdr {
-  __u64 xstate_bv;
+struct _header {
+  __u64 xfeatures;
 /* WARNING: DO NOT EDIT, AUTO-GENERATED CODE - SEE TOP FOR INSTRUCTIONS */
   __u64 reserved1[2];
   __u64 reserved2[5];
@@ -186,8 +121,153 @@
 struct _xstate {
   struct _fpstate fpstate;
 /* WARNING: DO NOT EDIT, AUTO-GENERATED CODE - SEE TOP FOR INSTRUCTIONS */
-  struct _xsave_hdr xstate_hdr;
+  struct _header xstate_hdr;
   struct _ymmh_state ymmh;
 };
+struct sigcontext_32 {
+/* WARNING: DO NOT EDIT, AUTO-GENERATED CODE - SEE TOP FOR INSTRUCTIONS */
+  __u16 gs, __gsh;
+  __u16 fs, __fsh;
+  __u16 es, __esh;
+  __u16 ds, __dsh;
+/* WARNING: DO NOT EDIT, AUTO-GENERATED CODE - SEE TOP FOR INSTRUCTIONS */
+  __u32 di;
+  __u32 si;
+  __u32 bp;
+  __u32 sp;
+/* WARNING: DO NOT EDIT, AUTO-GENERATED CODE - SEE TOP FOR INSTRUCTIONS */
+  __u32 bx;
+  __u32 dx;
+  __u32 cx;
+  __u32 ax;
+/* WARNING: DO NOT EDIT, AUTO-GENERATED CODE - SEE TOP FOR INSTRUCTIONS */
+  __u32 trapno;
+  __u32 err;
+  __u32 ip;
+  __u16 cs, __csh;
+/* WARNING: DO NOT EDIT, AUTO-GENERATED CODE - SEE TOP FOR INSTRUCTIONS */
+  __u32 flags;
+  __u32 sp_at_signal;
+  __u16 ss, __ssh;
+  __u32 fpstate;
+/* WARNING: DO NOT EDIT, AUTO-GENERATED CODE - SEE TOP FOR INSTRUCTIONS */
+  __u32 oldmask;
+  __u32 cr2;
+};
+struct sigcontext_64 {
+/* WARNING: DO NOT EDIT, AUTO-GENERATED CODE - SEE TOP FOR INSTRUCTIONS */
+  __u64 r8;
+  __u64 r9;
+  __u64 r10;
+  __u64 r11;
+/* WARNING: DO NOT EDIT, AUTO-GENERATED CODE - SEE TOP FOR INSTRUCTIONS */
+  __u64 r12;
+  __u64 r13;
+  __u64 r14;
+  __u64 r15;
+/* WARNING: DO NOT EDIT, AUTO-GENERATED CODE - SEE TOP FOR INSTRUCTIONS */
+  __u64 di;
+  __u64 si;
+  __u64 bp;
+  __u64 bx;
+/* WARNING: DO NOT EDIT, AUTO-GENERATED CODE - SEE TOP FOR INSTRUCTIONS */
+  __u64 dx;
+  __u64 ax;
+  __u64 cx;
+  __u64 sp;
+/* WARNING: DO NOT EDIT, AUTO-GENERATED CODE - SEE TOP FOR INSTRUCTIONS */
+  __u64 ip;
+  __u64 flags;
+  __u16 cs;
+  __u16 gs;
+/* WARNING: DO NOT EDIT, AUTO-GENERATED CODE - SEE TOP FOR INSTRUCTIONS */
+  __u16 fs;
+  __u16 __pad0;
+  __u64 err;
+  __u64 trapno;
+/* WARNING: DO NOT EDIT, AUTO-GENERATED CODE - SEE TOP FOR INSTRUCTIONS */
+  __u64 oldmask;
+  __u64 cr2;
+  __u64 fpstate;
+  __u64 reserved1[8];
+/* WARNING: DO NOT EDIT, AUTO-GENERATED CODE - SEE TOP FOR INSTRUCTIONS */
+};
+#define _fpstate_ia32 _fpstate_32
+#define sigcontext_ia32 sigcontext_32
+#ifdef __i386__
+/* WARNING: DO NOT EDIT, AUTO-GENERATED CODE - SEE TOP FOR INSTRUCTIONS */
+struct sigcontext {
+  __u16 gs, __gsh;
+  __u16 fs, __fsh;
+  __u16 es, __esh;
+/* WARNING: DO NOT EDIT, AUTO-GENERATED CODE - SEE TOP FOR INSTRUCTIONS */
+  __u16 ds, __dsh;
+  __u32 edi;
+  __u32 esi;
+  __u32 ebp;
+/* WARNING: DO NOT EDIT, AUTO-GENERATED CODE - SEE TOP FOR INSTRUCTIONS */
+  __u32 esp;
+  __u32 ebx;
+  __u32 edx;
+  __u32 ecx;
+/* WARNING: DO NOT EDIT, AUTO-GENERATED CODE - SEE TOP FOR INSTRUCTIONS */
+  __u32 eax;
+  __u32 trapno;
+  __u32 err;
+  __u32 eip;
+/* WARNING: DO NOT EDIT, AUTO-GENERATED CODE - SEE TOP FOR INSTRUCTIONS */
+  __u16 cs, __csh;
+  __u32 eflags;
+  __u32 esp_at_signal;
+  __u16 ss, __ssh;
+/* WARNING: DO NOT EDIT, AUTO-GENERATED CODE - SEE TOP FOR INSTRUCTIONS */
+  struct _fpstate __user * fpstate;
+  __u32 oldmask;
+  __u32 cr2;
+};
+/* WARNING: DO NOT EDIT, AUTO-GENERATED CODE - SEE TOP FOR INSTRUCTIONS */
+#else
+struct sigcontext {
+  __u64 r8;
+  __u64 r9;
+/* WARNING: DO NOT EDIT, AUTO-GENERATED CODE - SEE TOP FOR INSTRUCTIONS */
+  __u64 r10;
+  __u64 r11;
+  __u64 r12;
+  __u64 r13;
+/* WARNING: DO NOT EDIT, AUTO-GENERATED CODE - SEE TOP FOR INSTRUCTIONS */
+  __u64 r14;
+  __u64 r15;
+  __u64 rdi;
+  __u64 rsi;
+/* WARNING: DO NOT EDIT, AUTO-GENERATED CODE - SEE TOP FOR INSTRUCTIONS */
+  __u64 rbp;
+  __u64 rbx;
+  __u64 rdx;
+  __u64 rax;
+/* WARNING: DO NOT EDIT, AUTO-GENERATED CODE - SEE TOP FOR INSTRUCTIONS */
+  __u64 rcx;
+  __u64 rsp;
+  __u64 rip;
+  __u64 eflags;
+/* WARNING: DO NOT EDIT, AUTO-GENERATED CODE - SEE TOP FOR INSTRUCTIONS */
+  __u16 cs;
+  __u16 gs;
+  __u16 fs;
+  __u16 __pad0;
+/* WARNING: DO NOT EDIT, AUTO-GENERATED CODE - SEE TOP FOR INSTRUCTIONS */
+  __u64 err;
+  __u64 trapno;
+  __u64 oldmask;
+  __u64 cr2;
+/* WARNING: DO NOT EDIT, AUTO-GENERATED CODE - SEE TOP FOR INSTRUCTIONS */
+  struct _fpstate __user * fpstate;
+#ifdef __ILP32__
+  __u32 __fpstate_pad;
+#endif
+/* WARNING: DO NOT EDIT, AUTO-GENERATED CODE - SEE TOP FOR INSTRUCTIONS */
+  __u64 reserved1[8];
+};
+#endif
 #endif
 /* WARNING: DO NOT EDIT, AUTO-GENERATED CODE - SEE TOP FOR INSTRUCTIONS */
diff --git a/libc/kernel/uapi/asm-x86/asm/sigcontext32.h b/libc/kernel/uapi/asm-x86/asm/sigcontext32.h
index 8f38dfd..9e3b963 100644
--- a/libc/kernel/uapi/asm-x86/asm/sigcontext32.h
+++ b/libc/kernel/uapi/asm-x86/asm/sigcontext32.h
@@ -18,79 +18,6 @@
  ****************************************************************************/
 #ifndef _ASM_X86_SIGCONTEXT32_H
 #define _ASM_X86_SIGCONTEXT32_H
-#include <linux/types.h>
-#define X86_FXSR_MAGIC 0x0000
-/* WARNING: DO NOT EDIT, AUTO-GENERATED CODE - SEE TOP FOR INSTRUCTIONS */
-struct _fpreg {
-  unsigned short significand[4];
-  unsigned short exponent;
-};
-/* WARNING: DO NOT EDIT, AUTO-GENERATED CODE - SEE TOP FOR INSTRUCTIONS */
-struct _fpxreg {
-  unsigned short significand[4];
-  unsigned short exponent;
-  unsigned short padding[3];
-/* WARNING: DO NOT EDIT, AUTO-GENERATED CODE - SEE TOP FOR INSTRUCTIONS */
-};
-struct _xmmreg {
-  __u32 element[4];
-};
-/* WARNING: DO NOT EDIT, AUTO-GENERATED CODE - SEE TOP FOR INSTRUCTIONS */
-struct _fpstate_ia32 {
-  __u32 cw;
-  __u32 sw;
-  __u32 tag;
-/* WARNING: DO NOT EDIT, AUTO-GENERATED CODE - SEE TOP FOR INSTRUCTIONS */
-  __u32 ipoff;
-  __u32 cssel;
-  __u32 dataoff;
-  __u32 datasel;
-/* WARNING: DO NOT EDIT, AUTO-GENERATED CODE - SEE TOP FOR INSTRUCTIONS */
-  struct _fpreg _st[8];
-  unsigned short status;
-  unsigned short magic;
-  __u32 _fxsr_env[6];
-/* WARNING: DO NOT EDIT, AUTO-GENERATED CODE - SEE TOP FOR INSTRUCTIONS */
-  __u32 mxcsr;
-  __u32 reserved;
-  struct _fpxreg _fxsr_st[8];
-  struct _xmmreg _xmm[8];
-/* WARNING: DO NOT EDIT, AUTO-GENERATED CODE - SEE TOP FOR INSTRUCTIONS */
-  __u32 padding[44];
-  union {
-    __u32 padding2[12];
-    struct _fpx_sw_bytes sw_reserved;
-/* WARNING: DO NOT EDIT, AUTO-GENERATED CODE - SEE TOP FOR INSTRUCTIONS */
-  };
-};
-struct sigcontext_ia32 {
-  unsigned short gs, __gsh;
-/* WARNING: DO NOT EDIT, AUTO-GENERATED CODE - SEE TOP FOR INSTRUCTIONS */
-  unsigned short fs, __fsh;
-  unsigned short es, __esh;
-  unsigned short ds, __dsh;
-  unsigned int di;
-/* WARNING: DO NOT EDIT, AUTO-GENERATED CODE - SEE TOP FOR INSTRUCTIONS */
-  unsigned int si;
-  unsigned int bp;
-  unsigned int sp;
-  unsigned int bx;
-/* WARNING: DO NOT EDIT, AUTO-GENERATED CODE - SEE TOP FOR INSTRUCTIONS */
-  unsigned int dx;
-  unsigned int cx;
-  unsigned int ax;
-  unsigned int trapno;
-/* WARNING: DO NOT EDIT, AUTO-GENERATED CODE - SEE TOP FOR INSTRUCTIONS */
-  unsigned int err;
-  unsigned int ip;
-  unsigned short cs, __csh;
-  unsigned int flags;
-/* WARNING: DO NOT EDIT, AUTO-GENERATED CODE - SEE TOP FOR INSTRUCTIONS */
-  unsigned int sp_at_signal;
-  unsigned short ss, __ssh;
-  unsigned int fpstate;
-  unsigned int oldmask;
-/* WARNING: DO NOT EDIT, AUTO-GENERATED CODE - SEE TOP FOR INSTRUCTIONS */
-  unsigned int cr2;
-};
+#include <asm/sigcontext.h>
 #endif
+/* WARNING: DO NOT EDIT, AUTO-GENERATED CODE - SEE TOP FOR INSTRUCTIONS */
diff --git a/libc/kernel/uapi/asm-x86/asm/svm.h b/libc/kernel/uapi/asm-x86/asm/svm.h
index 1ee4fd8..29ead9b 100644
--- a/libc/kernel/uapi/asm-x86/asm/svm.h
+++ b/libc/kernel/uapi/asm-x86/asm/svm.h
@@ -109,6 +109,6 @@
 #define SVM_EXIT_XSETBV 0x08d
 #define SVM_EXIT_NPF 0x400
 #define SVM_EXIT_ERR - 1
-#define SVM_EXIT_REASONS { SVM_EXIT_READ_CR0, "read_cr0" }, { SVM_EXIT_READ_CR3, "read_cr3" }, { SVM_EXIT_READ_CR4, "read_cr4" }, { SVM_EXIT_READ_CR8, "read_cr8" }, { SVM_EXIT_WRITE_CR0, "write_cr0" }, { SVM_EXIT_WRITE_CR3, "write_cr3" }, { SVM_EXIT_WRITE_CR4, "write_cr4" }, { SVM_EXIT_WRITE_CR8, "write_cr8" }, { SVM_EXIT_READ_DR0, "read_dr0" }, { SVM_EXIT_READ_DR1, "read_dr1" }, { SVM_EXIT_READ_DR2, "read_dr2" }, { SVM_EXIT_READ_DR3, "read_dr3" }, { SVM_EXIT_WRITE_DR0, "write_dr0" }, { SVM_EXIT_WRITE_DR1, "write_dr1" }, { SVM_EXIT_WRITE_DR2, "write_dr2" }, { SVM_EXIT_WRITE_DR3, "write_dr3" }, { SVM_EXIT_WRITE_DR5, "write_dr5" }, { SVM_EXIT_WRITE_DR7, "write_dr7" }, { SVM_EXIT_EXCP_BASE + DB_VECTOR, "DB excp" }, { SVM_EXIT_EXCP_BASE + BP_VECTOR, "BP excp" }, { SVM_EXIT_EXCP_BASE + UD_VECTOR, "UD excp" }, { SVM_EXIT_EXCP_BASE + PF_VECTOR, "PF excp" }, { SVM_EXIT_EXCP_BASE + NM_VECTOR, "NM excp" }, { SVM_EXIT_EXCP_BASE + MC_VECTOR, "MC excp" }, { SVM_EXIT_INTR, "interrupt" }, { SVM_EXIT_NMI, "nmi" }, { SVM_EXIT_SMI, "smi" }, { SVM_EXIT_INIT, "init" }, { SVM_EXIT_VINTR, "vintr" }, { SVM_EXIT_CPUID, "cpuid" }, { SVM_EXIT_INVD, "invd" }, { SVM_EXIT_HLT, "hlt" }, { SVM_EXIT_INVLPG, "invlpg" }, { SVM_EXIT_INVLPGA, "invlpga" }, { SVM_EXIT_IOIO, "io" }, { SVM_EXIT_MSR, "msr" }, { SVM_EXIT_TASK_SWITCH, "task_switch" }, { SVM_EXIT_SHUTDOWN, "shutdown" }, { SVM_EXIT_VMRUN, "vmrun" }, { SVM_EXIT_VMMCALL, "hypercall" }, { SVM_EXIT_VMLOAD, "vmload" }, { SVM_EXIT_VMSAVE, "vmsave" }, { SVM_EXIT_STGI, "stgi" }, { SVM_EXIT_CLGI, "clgi" }, { SVM_EXIT_SKINIT, "skinit" }, { SVM_EXIT_WBINVD, "wbinvd" }, { SVM_EXIT_MONITOR, "monitor" }, { SVM_EXIT_MWAIT, "mwait" }, { SVM_EXIT_XSETBV, "xsetbv" }, { SVM_EXIT_NPF, "npf" }
+#define SVM_EXIT_REASONS { SVM_EXIT_READ_CR0, "read_cr0" }, { SVM_EXIT_READ_CR3, "read_cr3" }, { SVM_EXIT_READ_CR4, "read_cr4" }, { SVM_EXIT_READ_CR8, "read_cr8" }, { SVM_EXIT_WRITE_CR0, "write_cr0" }, { SVM_EXIT_WRITE_CR3, "write_cr3" }, { SVM_EXIT_WRITE_CR4, "write_cr4" }, { SVM_EXIT_WRITE_CR8, "write_cr8" }, { SVM_EXIT_READ_DR0, "read_dr0" }, { SVM_EXIT_READ_DR1, "read_dr1" }, { SVM_EXIT_READ_DR2, "read_dr2" }, { SVM_EXIT_READ_DR3, "read_dr3" }, { SVM_EXIT_WRITE_DR0, "write_dr0" }, { SVM_EXIT_WRITE_DR1, "write_dr1" }, { SVM_EXIT_WRITE_DR2, "write_dr2" }, { SVM_EXIT_WRITE_DR3, "write_dr3" }, { SVM_EXIT_WRITE_DR5, "write_dr5" }, { SVM_EXIT_WRITE_DR7, "write_dr7" }, { SVM_EXIT_EXCP_BASE + DB_VECTOR, "DB excp" }, { SVM_EXIT_EXCP_BASE + BP_VECTOR, "BP excp" }, { SVM_EXIT_EXCP_BASE + UD_VECTOR, "UD excp" }, { SVM_EXIT_EXCP_BASE + PF_VECTOR, "PF excp" }, { SVM_EXIT_EXCP_BASE + NM_VECTOR, "NM excp" }, { SVM_EXIT_EXCP_BASE + AC_VECTOR, "AC excp" }, { SVM_EXIT_EXCP_BASE + MC_VECTOR, "MC excp" }, { SVM_EXIT_INTR, "interrupt" }, { SVM_EXIT_NMI, "nmi" }, { SVM_EXIT_SMI, "smi" }, { SVM_EXIT_INIT, "init" }, { SVM_EXIT_VINTR, "vintr" }, { SVM_EXIT_CPUID, "cpuid" }, { SVM_EXIT_INVD, "invd" }, { SVM_EXIT_HLT, "hlt" }, { SVM_EXIT_INVLPG, "invlpg" }, { SVM_EXIT_INVLPGA, "invlpga" }, { SVM_EXIT_IOIO, "io" }, { SVM_EXIT_MSR, "msr" }, { SVM_EXIT_TASK_SWITCH, "task_switch" }, { SVM_EXIT_SHUTDOWN, "shutdown" }, { SVM_EXIT_VMRUN, "vmrun" }, { SVM_EXIT_VMMCALL, "hypercall" }, { SVM_EXIT_VMLOAD, "vmload" }, { SVM_EXIT_VMSAVE, "vmsave" }, { SVM_EXIT_STGI, "stgi" }, { SVM_EXIT_CLGI, "clgi" }, { SVM_EXIT_SKINIT, "skinit" }, { SVM_EXIT_WBINVD, "wbinvd" }, { SVM_EXIT_MONITOR, "monitor" }, { SVM_EXIT_MWAIT, "mwait" }, { SVM_EXIT_XSETBV, "xsetbv" }, { SVM_EXIT_NPF, "npf" }
 /* WARNING: DO NOT EDIT, AUTO-GENERATED CODE - SEE TOP FOR INSTRUCTIONS */
 #endif
diff --git a/libc/kernel/uapi/asm-x86/asm/unistd_32.h b/libc/kernel/uapi/asm-x86/asm/unistd_32.h
index c1a7ef4..6a5a8d4 100644
--- a/libc/kernel/uapi/asm-x86/asm/unistd_32.h
+++ b/libc/kernel/uapi/asm-x86/asm/unistd_32.h
@@ -461,4 +461,28 @@
 #define __NR_memfd_create 356
 #define __NR_bpf 357
 /* WARNING: DO NOT EDIT, AUTO-GENERATED CODE - SEE TOP FOR INSTRUCTIONS */
+#define __NR_execveat 358
+#define __NR_socket 359
+#define __NR_socketpair 360
+#define __NR_bind 361
+/* WARNING: DO NOT EDIT, AUTO-GENERATED CODE - SEE TOP FOR INSTRUCTIONS */
+#define __NR_connect 362
+#define __NR_listen 363
+#define __NR_accept4 364
+#define __NR_getsockopt 365
+/* WARNING: DO NOT EDIT, AUTO-GENERATED CODE - SEE TOP FOR INSTRUCTIONS */
+#define __NR_setsockopt 366
+#define __NR_getsockname 367
+#define __NR_getpeername 368
+#define __NR_sendto 369
+/* WARNING: DO NOT EDIT, AUTO-GENERATED CODE - SEE TOP FOR INSTRUCTIONS */
+#define __NR_sendmsg 370
+#define __NR_recvfrom 371
+#define __NR_recvmsg 372
+#define __NR_shutdown 373
+/* WARNING: DO NOT EDIT, AUTO-GENERATED CODE - SEE TOP FOR INSTRUCTIONS */
+#define __NR_userfaultfd 374
+#define __NR_membarrier 375
+#define __NR_mlock2 376
 #endif
+/* WARNING: DO NOT EDIT, AUTO-GENERATED CODE - SEE TOP FOR INSTRUCTIONS */
diff --git a/libc/kernel/uapi/asm-x86/asm/unistd_64.h b/libc/kernel/uapi/asm-x86/asm/unistd_64.h
index c538b21..2d02d21 100644
--- a/libc/kernel/uapi/asm-x86/asm/unistd_64.h
+++ b/libc/kernel/uapi/asm-x86/asm/unistd_64.h
@@ -421,4 +421,9 @@
 #define __NR_kexec_file_load 320
 #define __NR_bpf 321
 /* WARNING: DO NOT EDIT, AUTO-GENERATED CODE - SEE TOP FOR INSTRUCTIONS */
+#define __NR_execveat 322
+#define __NR_userfaultfd 323
+#define __NR_membarrier 324
+#define __NR_mlock2 325
+/* WARNING: DO NOT EDIT, AUTO-GENERATED CODE - SEE TOP FOR INSTRUCTIONS */
 #endif
diff --git a/libc/kernel/uapi/asm-x86/asm/unistd_x32.h b/libc/kernel/uapi/asm-x86/asm/unistd_x32.h
index d87d074..894615c 100644
--- a/libc/kernel/uapi/asm-x86/asm/unistd_x32.h
+++ b/libc/kernel/uapi/asm-x86/asm/unistd_x32.h
@@ -366,45 +366,50 @@
 #define __NR_kexec_file_load (__X32_SYSCALL_BIT + 320)
 #define __NR_bpf (__X32_SYSCALL_BIT + 321)
 /* WARNING: DO NOT EDIT, AUTO-GENERATED CODE - SEE TOP FOR INSTRUCTIONS */
+#define __NR_userfaultfd (__X32_SYSCALL_BIT + 323)
+#define __NR_membarrier (__X32_SYSCALL_BIT + 324)
+#define __NR_mlock2 (__X32_SYSCALL_BIT + 325)
 #define __NR_rt_sigaction (__X32_SYSCALL_BIT + 512)
+/* WARNING: DO NOT EDIT, AUTO-GENERATED CODE - SEE TOP FOR INSTRUCTIONS */
 #define __NR_rt_sigreturn (__X32_SYSCALL_BIT + 513)
 #define __NR_ioctl (__X32_SYSCALL_BIT + 514)
 #define __NR_readv (__X32_SYSCALL_BIT + 515)
-/* WARNING: DO NOT EDIT, AUTO-GENERATED CODE - SEE TOP FOR INSTRUCTIONS */
 #define __NR_writev (__X32_SYSCALL_BIT + 516)
+/* WARNING: DO NOT EDIT, AUTO-GENERATED CODE - SEE TOP FOR INSTRUCTIONS */
 #define __NR_recvfrom (__X32_SYSCALL_BIT + 517)
 #define __NR_sendmsg (__X32_SYSCALL_BIT + 518)
 #define __NR_recvmsg (__X32_SYSCALL_BIT + 519)
-/* WARNING: DO NOT EDIT, AUTO-GENERATED CODE - SEE TOP FOR INSTRUCTIONS */
 #define __NR_execve (__X32_SYSCALL_BIT + 520)
+/* WARNING: DO NOT EDIT, AUTO-GENERATED CODE - SEE TOP FOR INSTRUCTIONS */
 #define __NR_ptrace (__X32_SYSCALL_BIT + 521)
 #define __NR_rt_sigpending (__X32_SYSCALL_BIT + 522)
 #define __NR_rt_sigtimedwait (__X32_SYSCALL_BIT + 523)
-/* WARNING: DO NOT EDIT, AUTO-GENERATED CODE - SEE TOP FOR INSTRUCTIONS */
 #define __NR_rt_sigqueueinfo (__X32_SYSCALL_BIT + 524)
+/* WARNING: DO NOT EDIT, AUTO-GENERATED CODE - SEE TOP FOR INSTRUCTIONS */
 #define __NR_sigaltstack (__X32_SYSCALL_BIT + 525)
 #define __NR_timer_create (__X32_SYSCALL_BIT + 526)
 #define __NR_mq_notify (__X32_SYSCALL_BIT + 527)
-/* WARNING: DO NOT EDIT, AUTO-GENERATED CODE - SEE TOP FOR INSTRUCTIONS */
 #define __NR_kexec_load (__X32_SYSCALL_BIT + 528)
+/* WARNING: DO NOT EDIT, AUTO-GENERATED CODE - SEE TOP FOR INSTRUCTIONS */
 #define __NR_waitid (__X32_SYSCALL_BIT + 529)
 #define __NR_set_robust_list (__X32_SYSCALL_BIT + 530)
 #define __NR_get_robust_list (__X32_SYSCALL_BIT + 531)
-/* WARNING: DO NOT EDIT, AUTO-GENERATED CODE - SEE TOP FOR INSTRUCTIONS */
 #define __NR_vmsplice (__X32_SYSCALL_BIT + 532)
+/* WARNING: DO NOT EDIT, AUTO-GENERATED CODE - SEE TOP FOR INSTRUCTIONS */
 #define __NR_move_pages (__X32_SYSCALL_BIT + 533)
 #define __NR_preadv (__X32_SYSCALL_BIT + 534)
 #define __NR_pwritev (__X32_SYSCALL_BIT + 535)
-/* WARNING: DO NOT EDIT, AUTO-GENERATED CODE - SEE TOP FOR INSTRUCTIONS */
 #define __NR_rt_tgsigqueueinfo (__X32_SYSCALL_BIT + 536)
+/* WARNING: DO NOT EDIT, AUTO-GENERATED CODE - SEE TOP FOR INSTRUCTIONS */
 #define __NR_recvmmsg (__X32_SYSCALL_BIT + 537)
 #define __NR_sendmmsg (__X32_SYSCALL_BIT + 538)
 #define __NR_process_vm_readv (__X32_SYSCALL_BIT + 539)
-/* WARNING: DO NOT EDIT, AUTO-GENERATED CODE - SEE TOP FOR INSTRUCTIONS */
 #define __NR_process_vm_writev (__X32_SYSCALL_BIT + 540)
+/* WARNING: DO NOT EDIT, AUTO-GENERATED CODE - SEE TOP FOR INSTRUCTIONS */
 #define __NR_setsockopt (__X32_SYSCALL_BIT + 541)
 #define __NR_getsockopt (__X32_SYSCALL_BIT + 542)
 #define __NR_io_setup (__X32_SYSCALL_BIT + 543)
-/* WARNING: DO NOT EDIT, AUTO-GENERATED CODE - SEE TOP FOR INSTRUCTIONS */
 #define __NR_io_submit (__X32_SYSCALL_BIT + 544)
+/* WARNING: DO NOT EDIT, AUTO-GENERATED CODE - SEE TOP FOR INSTRUCTIONS */
+#define __NR_execveat (__X32_SYSCALL_BIT + 545)
 #endif
diff --git a/libc/kernel/uapi/asm-x86/asm/vmx.h b/libc/kernel/uapi/asm-x86/asm/vmx.h
index 6731d3c..d72833d 100644
--- a/libc/kernel/uapi/asm-x86/asm/vmx.h
+++ b/libc/kernel/uapi/asm-x86/asm/vmx.h
@@ -54,26 +54,37 @@
 #define EXIT_REASON_MSR_READ 31
 #define EXIT_REASON_MSR_WRITE 32
 #define EXIT_REASON_INVALID_STATE 33
-#define EXIT_REASON_MWAIT_INSTRUCTION 36
+#define EXIT_REASON_MSR_LOAD_FAIL 34
 /* WARNING: DO NOT EDIT, AUTO-GENERATED CODE - SEE TOP FOR INSTRUCTIONS */
+#define EXIT_REASON_MWAIT_INSTRUCTION 36
+#define EXIT_REASON_MONITOR_TRAP_FLAG 37
 #define EXIT_REASON_MONITOR_INSTRUCTION 39
 #define EXIT_REASON_PAUSE_INSTRUCTION 40
+/* WARNING: DO NOT EDIT, AUTO-GENERATED CODE - SEE TOP FOR INSTRUCTIONS */
 #define EXIT_REASON_MCE_DURING_VMENTRY 41
 #define EXIT_REASON_TPR_BELOW_THRESHOLD 43
-/* WARNING: DO NOT EDIT, AUTO-GENERATED CODE - SEE TOP FOR INSTRUCTIONS */
 #define EXIT_REASON_APIC_ACCESS 44
 #define EXIT_REASON_EOI_INDUCED 45
+/* WARNING: DO NOT EDIT, AUTO-GENERATED CODE - SEE TOP FOR INSTRUCTIONS */
 #define EXIT_REASON_EPT_VIOLATION 48
 #define EXIT_REASON_EPT_MISCONFIG 49
-/* WARNING: DO NOT EDIT, AUTO-GENERATED CODE - SEE TOP FOR INSTRUCTIONS */
 #define EXIT_REASON_INVEPT 50
+#define EXIT_REASON_RDTSCP 51
+/* WARNING: DO NOT EDIT, AUTO-GENERATED CODE - SEE TOP FOR INSTRUCTIONS */
 #define EXIT_REASON_PREEMPTION_TIMER 52
 #define EXIT_REASON_INVVPID 53
 #define EXIT_REASON_WBINVD 54
-/* WARNING: DO NOT EDIT, AUTO-GENERATED CODE - SEE TOP FOR INSTRUCTIONS */
 #define EXIT_REASON_XSETBV 55
+/* WARNING: DO NOT EDIT, AUTO-GENERATED CODE - SEE TOP FOR INSTRUCTIONS */
 #define EXIT_REASON_APIC_WRITE 56
 #define EXIT_REASON_INVPCID 58
-#define VMX_EXIT_REASONS { EXIT_REASON_EXCEPTION_NMI, "EXCEPTION_NMI" }, { EXIT_REASON_EXTERNAL_INTERRUPT, "EXTERNAL_INTERRUPT" }, { EXIT_REASON_TRIPLE_FAULT, "TRIPLE_FAULT" }, { EXIT_REASON_PENDING_INTERRUPT, "PENDING_INTERRUPT" }, { EXIT_REASON_NMI_WINDOW, "NMI_WINDOW" }, { EXIT_REASON_TASK_SWITCH, "TASK_SWITCH" }, { EXIT_REASON_CPUID, "CPUID" }, { EXIT_REASON_HLT, "HLT" }, { EXIT_REASON_INVLPG, "INVLPG" }, { EXIT_REASON_RDPMC, "RDPMC" }, { EXIT_REASON_RDTSC, "RDTSC" }, { EXIT_REASON_VMCALL, "VMCALL" }, { EXIT_REASON_VMCLEAR, "VMCLEAR" }, { EXIT_REASON_VMLAUNCH, "VMLAUNCH" }, { EXIT_REASON_VMPTRLD, "VMPTRLD" }, { EXIT_REASON_VMPTRST, "VMPTRST" }, { EXIT_REASON_VMREAD, "VMREAD" }, { EXIT_REASON_VMRESUME, "VMRESUME" }, { EXIT_REASON_VMWRITE, "VMWRITE" }, { EXIT_REASON_VMOFF, "VMOFF" }, { EXIT_REASON_VMON, "VMON" }, { EXIT_REASON_CR_ACCESS, "CR_ACCESS" }, { EXIT_REASON_DR_ACCESS, "DR_ACCESS" }, { EXIT_REASON_IO_INSTRUCTION, "IO_INSTRUCTION" }, { EXIT_REASON_MSR_READ, "MSR_READ" }, { EXIT_REASON_MSR_WRITE, "MSR_WRITE" }, { EXIT_REASON_MWAIT_INSTRUCTION, "MWAIT_INSTRUCTION" }, { EXIT_REASON_MONITOR_INSTRUCTION, "MONITOR_INSTRUCTION" }, { EXIT_REASON_PAUSE_INSTRUCTION, "PAUSE_INSTRUCTION" }, { EXIT_REASON_MCE_DURING_VMENTRY, "MCE_DURING_VMENTRY" }, { EXIT_REASON_TPR_BELOW_THRESHOLD, "TPR_BELOW_THRESHOLD" }, { EXIT_REASON_APIC_ACCESS, "APIC_ACCESS" }, { EXIT_REASON_EPT_VIOLATION, "EPT_VIOLATION" }, { EXIT_REASON_EPT_MISCONFIG, "EPT_MISCONFIG" }, { EXIT_REASON_INVEPT, "INVEPT" }, { EXIT_REASON_PREEMPTION_TIMER, "PREEMPTION_TIMER" }, { EXIT_REASON_WBINVD, "WBINVD" }, { EXIT_REASON_APIC_WRITE, "APIC_WRITE" }, { EXIT_REASON_EOI_INDUCED, "EOI_INDUCED" }, { EXIT_REASON_INVALID_STATE, "INVALID_STATE" }, { EXIT_REASON_INVD, "INVD" }, { EXIT_REASON_INVVPID, "INVVPID" }, { EXIT_REASON_INVPCID, "INVPCID" }
+#define EXIT_REASON_PML_FULL 62
+#define EXIT_REASON_XSAVES 63
 /* WARNING: DO NOT EDIT, AUTO-GENERATED CODE - SEE TOP FOR INSTRUCTIONS */
+#define EXIT_REASON_XRSTORS 64
+#define EXIT_REASON_PCOMMIT 65
+#define VMX_EXIT_REASONS { EXIT_REASON_EXCEPTION_NMI, "EXCEPTION_NMI" }, { EXIT_REASON_EXTERNAL_INTERRUPT, "EXTERNAL_INTERRUPT" }, { EXIT_REASON_TRIPLE_FAULT, "TRIPLE_FAULT" }, { EXIT_REASON_PENDING_INTERRUPT, "PENDING_INTERRUPT" }, { EXIT_REASON_NMI_WINDOW, "NMI_WINDOW" }, { EXIT_REASON_TASK_SWITCH, "TASK_SWITCH" }, { EXIT_REASON_CPUID, "CPUID" }, { EXIT_REASON_HLT, "HLT" }, { EXIT_REASON_INVLPG, "INVLPG" }, { EXIT_REASON_RDPMC, "RDPMC" }, { EXIT_REASON_RDTSC, "RDTSC" }, { EXIT_REASON_VMCALL, "VMCALL" }, { EXIT_REASON_VMCLEAR, "VMCLEAR" }, { EXIT_REASON_VMLAUNCH, "VMLAUNCH" }, { EXIT_REASON_VMPTRLD, "VMPTRLD" }, { EXIT_REASON_VMPTRST, "VMPTRST" }, { EXIT_REASON_VMREAD, "VMREAD" }, { EXIT_REASON_VMRESUME, "VMRESUME" }, { EXIT_REASON_VMWRITE, "VMWRITE" }, { EXIT_REASON_VMOFF, "VMOFF" }, { EXIT_REASON_VMON, "VMON" }, { EXIT_REASON_CR_ACCESS, "CR_ACCESS" }, { EXIT_REASON_DR_ACCESS, "DR_ACCESS" }, { EXIT_REASON_IO_INSTRUCTION, "IO_INSTRUCTION" }, { EXIT_REASON_MSR_READ, "MSR_READ" }, { EXIT_REASON_MSR_WRITE, "MSR_WRITE" }, { EXIT_REASON_MWAIT_INSTRUCTION, "MWAIT_INSTRUCTION" }, { EXIT_REASON_MONITOR_TRAP_FLAG, "MONITOR_TRAP_FLAG" }, { EXIT_REASON_MONITOR_INSTRUCTION, "MONITOR_INSTRUCTION" }, { EXIT_REASON_PAUSE_INSTRUCTION, "PAUSE_INSTRUCTION" }, { EXIT_REASON_MCE_DURING_VMENTRY, "MCE_DURING_VMENTRY" }, { EXIT_REASON_TPR_BELOW_THRESHOLD, "TPR_BELOW_THRESHOLD" }, { EXIT_REASON_APIC_ACCESS, "APIC_ACCESS" }, { EXIT_REASON_EPT_VIOLATION, "EPT_VIOLATION" }, { EXIT_REASON_EPT_MISCONFIG, "EPT_MISCONFIG" }, { EXIT_REASON_INVEPT, "INVEPT" }, { EXIT_REASON_PREEMPTION_TIMER, "PREEMPTION_TIMER" }, { EXIT_REASON_WBINVD, "WBINVD" }, { EXIT_REASON_APIC_WRITE, "APIC_WRITE" }, { EXIT_REASON_EOI_INDUCED, "EOI_INDUCED" }, { EXIT_REASON_INVALID_STATE, "INVALID_STATE" }, { EXIT_REASON_MSR_LOAD_FAIL, "MSR_LOAD_FAIL" }, { EXIT_REASON_INVD, "INVD" }, { EXIT_REASON_INVVPID, "INVVPID" }, { EXIT_REASON_INVPCID, "INVPCID" }, { EXIT_REASON_XSAVES, "XSAVES" }, { EXIT_REASON_XRSTORS, "XRSTORS" }, { EXIT_REASON_PCOMMIT, "PCOMMIT" }
+#define VMX_ABORT_SAVE_GUEST_MSR_FAIL 1
+/* WARNING: DO NOT EDIT, AUTO-GENERATED CODE - SEE TOP FOR INSTRUCTIONS */
+#define VMX_ABORT_LOAD_HOST_MSR_FAIL 4
 #endif
diff --git a/libc/kernel/uapi/drm/amdgpu_drm.h b/libc/kernel/uapi/drm/amdgpu_drm.h
new file mode 100644
index 0000000..16c127c
--- /dev/null
+++ b/libc/kernel/uapi/drm/amdgpu_drm.h
@@ -0,0 +1,499 @@
+/****************************************************************************
+ ****************************************************************************
+ ***
+ ***   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 __AMDGPU_DRM_H__
+#define __AMDGPU_DRM_H__
+#include "drm.h"
+#define DRM_AMDGPU_GEM_CREATE 0x00
+/* WARNING: DO NOT EDIT, AUTO-GENERATED CODE - SEE TOP FOR INSTRUCTIONS */
+#define DRM_AMDGPU_GEM_MMAP 0x01
+#define DRM_AMDGPU_CTX 0x02
+#define DRM_AMDGPU_BO_LIST 0x03
+#define DRM_AMDGPU_CS 0x04
+/* WARNING: DO NOT EDIT, AUTO-GENERATED CODE - SEE TOP FOR INSTRUCTIONS */
+#define DRM_AMDGPU_INFO 0x05
+#define DRM_AMDGPU_GEM_METADATA 0x06
+#define DRM_AMDGPU_GEM_WAIT_IDLE 0x07
+#define DRM_AMDGPU_GEM_VA 0x08
+/* WARNING: DO NOT EDIT, AUTO-GENERATED CODE - SEE TOP FOR INSTRUCTIONS */
+#define DRM_AMDGPU_WAIT_CS 0x09
+#define DRM_AMDGPU_GEM_OP 0x10
+#define DRM_AMDGPU_GEM_USERPTR 0x11
+#define DRM_IOCTL_AMDGPU_GEM_CREATE DRM_IOWR(DRM_COMMAND_BASE + DRM_AMDGPU_GEM_CREATE, union drm_amdgpu_gem_create)
+/* WARNING: DO NOT EDIT, AUTO-GENERATED CODE - SEE TOP FOR INSTRUCTIONS */
+#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)
+#define DRM_IOCTL_AMDGPU_BO_LIST DRM_IOWR(DRM_COMMAND_BASE + DRM_AMDGPU_BO_LIST, union drm_amdgpu_bo_list)
+#define DRM_IOCTL_AMDGPU_CS DRM_IOWR(DRM_COMMAND_BASE + DRM_AMDGPU_CS, union drm_amdgpu_cs)
+/* WARNING: DO NOT EDIT, AUTO-GENERATED CODE - SEE TOP FOR INSTRUCTIONS */
+#define DRM_IOCTL_AMDGPU_INFO DRM_IOW(DRM_COMMAND_BASE + DRM_AMDGPU_INFO, struct drm_amdgpu_info)
+#define DRM_IOCTL_AMDGPU_GEM_METADATA DRM_IOWR(DRM_COMMAND_BASE + DRM_AMDGPU_GEM_METADATA, struct drm_amdgpu_gem_metadata)
+#define DRM_IOCTL_AMDGPU_GEM_WAIT_IDLE DRM_IOWR(DRM_COMMAND_BASE + DRM_AMDGPU_GEM_WAIT_IDLE, union drm_amdgpu_gem_wait_idle)
+#define DRM_IOCTL_AMDGPU_GEM_VA DRM_IOW(DRM_COMMAND_BASE + DRM_AMDGPU_GEM_VA, struct drm_amdgpu_gem_va)
+/* WARNING: DO NOT EDIT, AUTO-GENERATED CODE - SEE TOP FOR INSTRUCTIONS */
+#define DRM_IOCTL_AMDGPU_WAIT_CS DRM_IOWR(DRM_COMMAND_BASE + DRM_AMDGPU_WAIT_CS, union drm_amdgpu_wait_cs)
+#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 AMDGPU_GEM_DOMAIN_CPU 0x1
+/* WARNING: DO NOT EDIT, AUTO-GENERATED CODE - SEE TOP FOR INSTRUCTIONS */
+#define AMDGPU_GEM_DOMAIN_GTT 0x2
+#define AMDGPU_GEM_DOMAIN_VRAM 0x4
+#define AMDGPU_GEM_DOMAIN_GDS 0x8
+#define AMDGPU_GEM_DOMAIN_GWS 0x10
+/* WARNING: DO NOT EDIT, AUTO-GENERATED CODE - SEE TOP FOR INSTRUCTIONS */
+#define AMDGPU_GEM_DOMAIN_OA 0x20
+#define AMDGPU_GEM_CREATE_CPU_ACCESS_REQUIRED (1 << 0)
+#define AMDGPU_GEM_CREATE_NO_CPU_ACCESS (1 << 1)
+#define AMDGPU_GEM_CREATE_CPU_GTT_USWC (1 << 2)
+/* WARNING: DO NOT EDIT, AUTO-GENERATED CODE - SEE TOP FOR INSTRUCTIONS */
+struct drm_amdgpu_gem_create_in {
+  uint64_t bo_size;
+  uint64_t alignment;
+  uint64_t domains;
+/* WARNING: DO NOT EDIT, AUTO-GENERATED CODE - SEE TOP FOR INSTRUCTIONS */
+  uint64_t domain_flags;
+};
+struct drm_amdgpu_gem_create_out {
+  uint32_t handle;
+/* WARNING: DO NOT EDIT, AUTO-GENERATED CODE - SEE TOP FOR INSTRUCTIONS */
+  uint32_t _pad;
+};
+union drm_amdgpu_gem_create {
+  struct drm_amdgpu_gem_create_in in;
+/* WARNING: DO NOT EDIT, AUTO-GENERATED CODE - SEE TOP FOR INSTRUCTIONS */
+  struct drm_amdgpu_gem_create_out out;
+};
+#define AMDGPU_BO_LIST_OP_CREATE 0
+#define AMDGPU_BO_LIST_OP_DESTROY 1
+/* WARNING: DO NOT EDIT, AUTO-GENERATED CODE - SEE TOP FOR INSTRUCTIONS */
+#define AMDGPU_BO_LIST_OP_UPDATE 2
+struct drm_amdgpu_bo_list_in {
+  uint32_t operation;
+  uint32_t list_handle;
+/* WARNING: DO NOT EDIT, AUTO-GENERATED CODE - SEE TOP FOR INSTRUCTIONS */
+  uint32_t bo_number;
+  uint32_t bo_info_size;
+  uint64_t bo_info_ptr;
+};
+/* WARNING: DO NOT EDIT, AUTO-GENERATED CODE - SEE TOP FOR INSTRUCTIONS */
+struct drm_amdgpu_bo_list_entry {
+  uint32_t bo_handle;
+  uint32_t bo_priority;
+};
+/* WARNING: DO NOT EDIT, AUTO-GENERATED CODE - SEE TOP FOR INSTRUCTIONS */
+struct drm_amdgpu_bo_list_out {
+  uint32_t list_handle;
+  uint32_t _pad;
+};
+/* WARNING: DO NOT EDIT, AUTO-GENERATED CODE - SEE TOP FOR INSTRUCTIONS */
+union drm_amdgpu_bo_list {
+  struct drm_amdgpu_bo_list_in in;
+  struct drm_amdgpu_bo_list_out out;
+};
+/* WARNING: DO NOT EDIT, AUTO-GENERATED CODE - SEE TOP FOR INSTRUCTIONS */
+#define AMDGPU_CTX_OP_ALLOC_CTX 1
+#define AMDGPU_CTX_OP_FREE_CTX 2
+#define AMDGPU_CTX_OP_QUERY_STATE 3
+#define AMDGPU_CTX_NO_RESET 0
+/* WARNING: DO NOT EDIT, AUTO-GENERATED CODE - SEE TOP FOR INSTRUCTIONS */
+#define AMDGPU_CTX_GUILTY_RESET 1
+#define AMDGPU_CTX_INNOCENT_RESET 2
+#define AMDGPU_CTX_UNKNOWN_RESET 3
+struct drm_amdgpu_ctx_in {
+/* WARNING: DO NOT EDIT, AUTO-GENERATED CODE - SEE TOP FOR INSTRUCTIONS */
+  uint32_t op;
+  uint32_t flags;
+  uint32_t ctx_id;
+  uint32_t _pad;
+/* WARNING: DO NOT EDIT, AUTO-GENERATED CODE - SEE TOP FOR INSTRUCTIONS */
+};
+union drm_amdgpu_ctx_out {
+  struct {
+    uint32_t ctx_id;
+/* WARNING: DO NOT EDIT, AUTO-GENERATED CODE - SEE TOP FOR INSTRUCTIONS */
+    uint32_t _pad;
+  } alloc;
+  struct {
+    uint64_t flags;
+/* WARNING: DO NOT EDIT, AUTO-GENERATED CODE - SEE TOP FOR INSTRUCTIONS */
+    uint32_t hangs;
+    uint32_t reset_status;
+  } state;
+};
+/* WARNING: DO NOT EDIT, AUTO-GENERATED CODE - SEE TOP FOR INSTRUCTIONS */
+union drm_amdgpu_ctx {
+  struct drm_amdgpu_ctx_in in;
+  union drm_amdgpu_ctx_out out;
+};
+/* WARNING: DO NOT EDIT, AUTO-GENERATED CODE - SEE TOP FOR INSTRUCTIONS */
+#define AMDGPU_GEM_USERPTR_READONLY (1 << 0)
+#define AMDGPU_GEM_USERPTR_ANONONLY (1 << 1)
+#define AMDGPU_GEM_USERPTR_VALIDATE (1 << 2)
+#define AMDGPU_GEM_USERPTR_REGISTER (1 << 3)
+/* WARNING: DO NOT EDIT, AUTO-GENERATED CODE - SEE TOP FOR INSTRUCTIONS */
+struct drm_amdgpu_gem_userptr {
+  uint64_t addr;
+  uint64_t size;
+  uint32_t flags;
+/* WARNING: DO NOT EDIT, AUTO-GENERATED CODE - SEE TOP FOR INSTRUCTIONS */
+  uint32_t handle;
+};
+#define AMDGPU_TILING_ARRAY_MODE_SHIFT 0
+#define AMDGPU_TILING_ARRAY_MODE_MASK 0xf
+/* WARNING: DO NOT EDIT, AUTO-GENERATED CODE - SEE TOP FOR INSTRUCTIONS */
+#define AMDGPU_TILING_PIPE_CONFIG_SHIFT 4
+#define AMDGPU_TILING_PIPE_CONFIG_MASK 0x1f
+#define AMDGPU_TILING_TILE_SPLIT_SHIFT 9
+#define AMDGPU_TILING_TILE_SPLIT_MASK 0x7
+/* WARNING: DO NOT EDIT, AUTO-GENERATED CODE - SEE TOP FOR INSTRUCTIONS */
+#define AMDGPU_TILING_MICRO_TILE_MODE_SHIFT 12
+#define AMDGPU_TILING_MICRO_TILE_MODE_MASK 0x7
+#define AMDGPU_TILING_BANK_WIDTH_SHIFT 15
+#define AMDGPU_TILING_BANK_WIDTH_MASK 0x3
+/* WARNING: DO NOT EDIT, AUTO-GENERATED CODE - SEE TOP FOR INSTRUCTIONS */
+#define AMDGPU_TILING_BANK_HEIGHT_SHIFT 17
+#define AMDGPU_TILING_BANK_HEIGHT_MASK 0x3
+#define AMDGPU_TILING_MACRO_TILE_ASPECT_SHIFT 19
+#define AMDGPU_TILING_MACRO_TILE_ASPECT_MASK 0x3
+/* WARNING: DO NOT EDIT, AUTO-GENERATED CODE - SEE TOP FOR INSTRUCTIONS */
+#define AMDGPU_TILING_NUM_BANKS_SHIFT 21
+#define AMDGPU_TILING_NUM_BANKS_MASK 0x3
+#define AMDGPU_TILING_SET(field,value) (((value) & AMDGPU_TILING_ ##field ##_MASK) << AMDGPU_TILING_ ##field ##_SHIFT)
+#define AMDGPU_TILING_GET(value,field) (((value) >> AMDGPU_TILING_ ##field ##_SHIFT) & AMDGPU_TILING_ ##field ##_MASK)
+/* WARNING: DO NOT EDIT, AUTO-GENERATED CODE - SEE TOP FOR INSTRUCTIONS */
+#define AMDGPU_GEM_METADATA_OP_SET_METADATA 1
+#define AMDGPU_GEM_METADATA_OP_GET_METADATA 2
+struct drm_amdgpu_gem_metadata {
+  uint32_t handle;
+/* WARNING: DO NOT EDIT, AUTO-GENERATED CODE - SEE TOP FOR INSTRUCTIONS */
+  uint32_t op;
+  struct {
+    uint64_t flags;
+    uint64_t tiling_info;
+/* WARNING: DO NOT EDIT, AUTO-GENERATED CODE - SEE TOP FOR INSTRUCTIONS */
+    uint32_t data_size_bytes;
+    uint32_t data[64];
+  } data;
+};
+/* WARNING: DO NOT EDIT, AUTO-GENERATED CODE - SEE TOP FOR INSTRUCTIONS */
+struct drm_amdgpu_gem_mmap_in {
+  uint32_t handle;
+  uint32_t _pad;
+};
+/* WARNING: DO NOT EDIT, AUTO-GENERATED CODE - SEE TOP FOR INSTRUCTIONS */
+struct drm_amdgpu_gem_mmap_out {
+  uint64_t addr_ptr;
+};
+union drm_amdgpu_gem_mmap {
+/* WARNING: DO NOT EDIT, AUTO-GENERATED CODE - SEE TOP FOR INSTRUCTIONS */
+  struct drm_amdgpu_gem_mmap_in in;
+  struct drm_amdgpu_gem_mmap_out out;
+};
+struct drm_amdgpu_gem_wait_idle_in {
+/* WARNING: DO NOT EDIT, AUTO-GENERATED CODE - SEE TOP FOR INSTRUCTIONS */
+  uint32_t handle;
+  uint32_t flags;
+  uint64_t timeout;
+};
+/* WARNING: DO NOT EDIT, AUTO-GENERATED CODE - SEE TOP FOR INSTRUCTIONS */
+struct drm_amdgpu_gem_wait_idle_out {
+  uint32_t status;
+  uint32_t domain;
+};
+/* WARNING: DO NOT EDIT, AUTO-GENERATED CODE - SEE TOP FOR INSTRUCTIONS */
+union drm_amdgpu_gem_wait_idle {
+  struct drm_amdgpu_gem_wait_idle_in in;
+  struct drm_amdgpu_gem_wait_idle_out out;
+};
+/* WARNING: DO NOT EDIT, AUTO-GENERATED CODE - SEE TOP FOR INSTRUCTIONS */
+struct drm_amdgpu_wait_cs_in {
+  uint64_t handle;
+  uint64_t timeout;
+  uint32_t ip_type;
+/* WARNING: DO NOT EDIT, AUTO-GENERATED CODE - SEE TOP FOR INSTRUCTIONS */
+  uint32_t ip_instance;
+  uint32_t ring;
+  uint32_t ctx_id;
+};
+/* WARNING: DO NOT EDIT, AUTO-GENERATED CODE - SEE TOP FOR INSTRUCTIONS */
+struct drm_amdgpu_wait_cs_out {
+  uint64_t status;
+};
+union drm_amdgpu_wait_cs {
+/* WARNING: DO NOT EDIT, AUTO-GENERATED CODE - SEE TOP FOR INSTRUCTIONS */
+  struct drm_amdgpu_wait_cs_in in;
+  struct drm_amdgpu_wait_cs_out out;
+};
+#define AMDGPU_GEM_OP_GET_GEM_CREATE_INFO 0
+/* WARNING: DO NOT EDIT, AUTO-GENERATED CODE - SEE TOP FOR INSTRUCTIONS */
+#define AMDGPU_GEM_OP_SET_PLACEMENT 1
+struct drm_amdgpu_gem_op {
+  uint32_t handle;
+  uint32_t op;
+/* WARNING: DO NOT EDIT, AUTO-GENERATED CODE - SEE TOP FOR INSTRUCTIONS */
+  uint64_t value;
+};
+#define AMDGPU_VA_OP_MAP 1
+#define AMDGPU_VA_OP_UNMAP 2
+/* WARNING: DO NOT EDIT, AUTO-GENERATED CODE - SEE TOP FOR INSTRUCTIONS */
+#define AMDGPU_VM_DELAY_UPDATE (1 << 0)
+#define AMDGPU_VM_PAGE_READABLE (1 << 1)
+#define AMDGPU_VM_PAGE_WRITEABLE (1 << 2)
+#define AMDGPU_VM_PAGE_EXECUTABLE (1 << 3)
+/* WARNING: DO NOT EDIT, AUTO-GENERATED CODE - SEE TOP FOR INSTRUCTIONS */
+struct drm_amdgpu_gem_va {
+  uint32_t handle;
+  uint32_t _pad;
+  uint32_t operation;
+/* WARNING: DO NOT EDIT, AUTO-GENERATED CODE - SEE TOP FOR INSTRUCTIONS */
+  uint32_t flags;
+  uint64_t va_address;
+  uint64_t offset_in_bo;
+  uint64_t map_size;
+/* WARNING: DO NOT EDIT, AUTO-GENERATED CODE - SEE TOP FOR INSTRUCTIONS */
+};
+#define AMDGPU_HW_IP_GFX 0
+#define AMDGPU_HW_IP_COMPUTE 1
+#define AMDGPU_HW_IP_DMA 2
+/* WARNING: DO NOT EDIT, AUTO-GENERATED CODE - SEE TOP FOR INSTRUCTIONS */
+#define AMDGPU_HW_IP_UVD 3
+#define AMDGPU_HW_IP_VCE 4
+#define AMDGPU_HW_IP_NUM 5
+#define AMDGPU_HW_IP_INSTANCE_MAX_COUNT 1
+/* WARNING: DO NOT EDIT, AUTO-GENERATED CODE - SEE TOP FOR INSTRUCTIONS */
+#define AMDGPU_CHUNK_ID_IB 0x01
+#define AMDGPU_CHUNK_ID_FENCE 0x02
+#define AMDGPU_CHUNK_ID_DEPENDENCIES 0x03
+struct drm_amdgpu_cs_chunk {
+/* WARNING: DO NOT EDIT, AUTO-GENERATED CODE - SEE TOP FOR INSTRUCTIONS */
+  uint32_t chunk_id;
+  uint32_t length_dw;
+  uint64_t chunk_data;
+};
+/* WARNING: DO NOT EDIT, AUTO-GENERATED CODE - SEE TOP FOR INSTRUCTIONS */
+struct drm_amdgpu_cs_in {
+  uint32_t ctx_id;
+  uint32_t bo_list_handle;
+  uint32_t num_chunks;
+/* WARNING: DO NOT EDIT, AUTO-GENERATED CODE - SEE TOP FOR INSTRUCTIONS */
+  uint32_t _pad;
+  uint64_t chunks;
+};
+struct drm_amdgpu_cs_out {
+/* WARNING: DO NOT EDIT, AUTO-GENERATED CODE - SEE TOP FOR INSTRUCTIONS */
+  uint64_t handle;
+};
+union drm_amdgpu_cs {
+  struct drm_amdgpu_cs_in in;
+/* WARNING: DO NOT EDIT, AUTO-GENERATED CODE - SEE TOP FOR INSTRUCTIONS */
+  struct drm_amdgpu_cs_out out;
+};
+#define AMDGPU_IB_FLAG_CE (1 << 0)
+#define AMDGPU_IB_FLAG_PREAMBLE (1 << 1)
+/* WARNING: DO NOT EDIT, AUTO-GENERATED CODE - SEE TOP FOR INSTRUCTIONS */
+struct drm_amdgpu_cs_chunk_ib {
+  uint32_t _pad;
+  uint32_t flags;
+  uint64_t va_start;
+/* WARNING: DO NOT EDIT, AUTO-GENERATED CODE - SEE TOP FOR INSTRUCTIONS */
+  uint32_t ib_bytes;
+  uint32_t ip_type;
+  uint32_t ip_instance;
+  uint32_t ring;
+/* WARNING: DO NOT EDIT, AUTO-GENERATED CODE - SEE TOP FOR INSTRUCTIONS */
+};
+struct drm_amdgpu_cs_chunk_dep {
+  uint32_t ip_type;
+  uint32_t ip_instance;
+/* WARNING: DO NOT EDIT, AUTO-GENERATED CODE - SEE TOP FOR INSTRUCTIONS */
+  uint32_t ring;
+  uint32_t ctx_id;
+  uint64_t handle;
+};
+/* WARNING: DO NOT EDIT, AUTO-GENERATED CODE - SEE TOP FOR INSTRUCTIONS */
+struct drm_amdgpu_cs_chunk_fence {
+  uint32_t handle;
+  uint32_t offset;
+};
+/* WARNING: DO NOT EDIT, AUTO-GENERATED CODE - SEE TOP FOR INSTRUCTIONS */
+struct drm_amdgpu_cs_chunk_data {
+  union {
+    struct drm_amdgpu_cs_chunk_ib ib_data;
+    struct drm_amdgpu_cs_chunk_fence fence_data;
+/* WARNING: DO NOT EDIT, AUTO-GENERATED CODE - SEE TOP FOR INSTRUCTIONS */
+  };
+};
+#define AMDGPU_IDS_FLAGS_FUSION 0x1
+#define AMDGPU_INFO_ACCEL_WORKING 0x00
+/* WARNING: DO NOT EDIT, AUTO-GENERATED CODE - SEE TOP FOR INSTRUCTIONS */
+#define AMDGPU_INFO_CRTC_FROM_ID 0x01
+#define AMDGPU_INFO_HW_IP_INFO 0x02
+#define AMDGPU_INFO_HW_IP_COUNT 0x03
+#define AMDGPU_INFO_TIMESTAMP 0x05
+/* WARNING: DO NOT EDIT, AUTO-GENERATED CODE - SEE TOP FOR INSTRUCTIONS */
+#define AMDGPU_INFO_FW_VERSION 0x0e
+#define AMDGPU_INFO_FW_VCE 0x1
+#define AMDGPU_INFO_FW_UVD 0x2
+#define AMDGPU_INFO_FW_GMC 0x03
+/* WARNING: DO NOT EDIT, AUTO-GENERATED CODE - SEE TOP FOR INSTRUCTIONS */
+#define AMDGPU_INFO_FW_GFX_ME 0x04
+#define AMDGPU_INFO_FW_GFX_PFP 0x05
+#define AMDGPU_INFO_FW_GFX_CE 0x06
+#define AMDGPU_INFO_FW_GFX_RLC 0x07
+/* WARNING: DO NOT EDIT, AUTO-GENERATED CODE - SEE TOP FOR INSTRUCTIONS */
+#define AMDGPU_INFO_FW_GFX_MEC 0x08
+#define AMDGPU_INFO_FW_SMC 0x0a
+#define AMDGPU_INFO_FW_SDMA 0x0b
+#define AMDGPU_INFO_NUM_BYTES_MOVED 0x0f
+/* WARNING: DO NOT EDIT, AUTO-GENERATED CODE - SEE TOP FOR INSTRUCTIONS */
+#define AMDGPU_INFO_VRAM_USAGE 0x10
+#define AMDGPU_INFO_GTT_USAGE 0x11
+#define AMDGPU_INFO_GDS_CONFIG 0x13
+#define AMDGPU_INFO_VRAM_GTT 0x14
+/* WARNING: DO NOT EDIT, AUTO-GENERATED CODE - SEE TOP FOR INSTRUCTIONS */
+#define AMDGPU_INFO_READ_MMR_REG 0x15
+#define AMDGPU_INFO_DEV_INFO 0x16
+#define AMDGPU_INFO_VIS_VRAM_USAGE 0x17
+#define AMDGPU_INFO_MMR_SE_INDEX_SHIFT 0
+/* WARNING: DO NOT EDIT, AUTO-GENERATED CODE - SEE TOP FOR INSTRUCTIONS */
+#define AMDGPU_INFO_MMR_SE_INDEX_MASK 0xff
+#define AMDGPU_INFO_MMR_SH_INDEX_SHIFT 8
+#define AMDGPU_INFO_MMR_SH_INDEX_MASK 0xff
+struct drm_amdgpu_info {
+/* WARNING: DO NOT EDIT, AUTO-GENERATED CODE - SEE TOP FOR INSTRUCTIONS */
+  uint64_t return_pointer;
+  uint32_t return_size;
+  uint32_t query;
+  union {
+/* WARNING: DO NOT EDIT, AUTO-GENERATED CODE - SEE TOP FOR INSTRUCTIONS */
+    struct {
+      uint32_t id;
+      uint32_t _pad;
+    } mode_crtc;
+/* WARNING: DO NOT EDIT, AUTO-GENERATED CODE - SEE TOP FOR INSTRUCTIONS */
+    struct {
+      uint32_t type;
+      uint32_t ip_instance;
+    } query_hw_ip;
+/* WARNING: DO NOT EDIT, AUTO-GENERATED CODE - SEE TOP FOR INSTRUCTIONS */
+    struct {
+      uint32_t dword_offset;
+      uint32_t count;
+      uint32_t instance;
+/* WARNING: DO NOT EDIT, AUTO-GENERATED CODE - SEE TOP FOR INSTRUCTIONS */
+      uint32_t flags;
+    } read_mmr_reg;
+    struct {
+      uint32_t fw_type;
+/* WARNING: DO NOT EDIT, AUTO-GENERATED CODE - SEE TOP FOR INSTRUCTIONS */
+      uint32_t ip_instance;
+      uint32_t index;
+      uint32_t _pad;
+    } query_fw;
+/* WARNING: DO NOT EDIT, AUTO-GENERATED CODE - SEE TOP FOR INSTRUCTIONS */
+  };
+};
+struct drm_amdgpu_info_gds {
+  uint32_t gds_gfx_partition_size;
+/* WARNING: DO NOT EDIT, AUTO-GENERATED CODE - SEE TOP FOR INSTRUCTIONS */
+  uint32_t compute_partition_size;
+  uint32_t gds_total_size;
+  uint32_t gws_per_gfx_partition;
+  uint32_t gws_per_compute_partition;
+/* WARNING: DO NOT EDIT, AUTO-GENERATED CODE - SEE TOP FOR INSTRUCTIONS */
+  uint32_t oa_per_gfx_partition;
+  uint32_t oa_per_compute_partition;
+  uint32_t _pad;
+};
+/* WARNING: DO NOT EDIT, AUTO-GENERATED CODE - SEE TOP FOR INSTRUCTIONS */
+struct drm_amdgpu_info_vram_gtt {
+  uint64_t vram_size;
+  uint64_t vram_cpu_accessible_size;
+  uint64_t gtt_size;
+/* WARNING: DO NOT EDIT, AUTO-GENERATED CODE - SEE TOP FOR INSTRUCTIONS */
+};
+struct drm_amdgpu_info_firmware {
+  uint32_t ver;
+  uint32_t feature;
+/* WARNING: DO NOT EDIT, AUTO-GENERATED CODE - SEE TOP FOR INSTRUCTIONS */
+};
+#define AMDGPU_VRAM_TYPE_UNKNOWN 0
+#define AMDGPU_VRAM_TYPE_GDDR1 1
+#define AMDGPU_VRAM_TYPE_DDR2 2
+/* WARNING: DO NOT EDIT, AUTO-GENERATED CODE - SEE TOP FOR INSTRUCTIONS */
+#define AMDGPU_VRAM_TYPE_GDDR3 3
+#define AMDGPU_VRAM_TYPE_GDDR4 4
+#define AMDGPU_VRAM_TYPE_GDDR5 5
+#define AMDGPU_VRAM_TYPE_HBM 6
+/* WARNING: DO NOT EDIT, AUTO-GENERATED CODE - SEE TOP FOR INSTRUCTIONS */
+#define AMDGPU_VRAM_TYPE_DDR3 7
+struct drm_amdgpu_info_device {
+  uint32_t device_id;
+  uint32_t chip_rev;
+/* WARNING: DO NOT EDIT, AUTO-GENERATED CODE - SEE TOP FOR INSTRUCTIONS */
+  uint32_t external_rev;
+  uint32_t pci_rev;
+  uint32_t family;
+  uint32_t num_shader_engines;
+/* WARNING: DO NOT EDIT, AUTO-GENERATED CODE - SEE TOP FOR INSTRUCTIONS */
+  uint32_t num_shader_arrays_per_engine;
+  uint32_t gpu_counter_freq;
+  uint64_t max_engine_clock;
+  uint64_t max_memory_clock;
+/* WARNING: DO NOT EDIT, AUTO-GENERATED CODE - SEE TOP FOR INSTRUCTIONS */
+  uint32_t cu_active_number;
+  uint32_t cu_ao_mask;
+  uint32_t cu_bitmap[4][4];
+  uint32_t enabled_rb_pipes_mask;
+/* WARNING: DO NOT EDIT, AUTO-GENERATED CODE - SEE TOP FOR INSTRUCTIONS */
+  uint32_t num_rb_pipes;
+  uint32_t num_hw_gfx_contexts;
+  uint32_t _pad;
+  uint64_t ids_flags;
+/* WARNING: DO NOT EDIT, AUTO-GENERATED CODE - SEE TOP FOR INSTRUCTIONS */
+  uint64_t virtual_address_offset;
+  uint64_t virtual_address_max;
+  uint32_t virtual_address_alignment;
+  uint32_t pte_fragment_size;
+/* WARNING: DO NOT EDIT, AUTO-GENERATED CODE - SEE TOP FOR INSTRUCTIONS */
+  uint32_t gart_page_size;
+  uint32_t ce_ram_size;
+  uint32_t vram_type;
+  uint32_t vram_bit_width;
+/* WARNING: DO NOT EDIT, AUTO-GENERATED CODE - SEE TOP FOR INSTRUCTIONS */
+  uint32_t vce_harvest_config;
+};
+struct drm_amdgpu_info_hw_ip {
+  uint32_t hw_ip_version_major;
+/* WARNING: DO NOT EDIT, AUTO-GENERATED CODE - SEE TOP FOR INSTRUCTIONS */
+  uint32_t hw_ip_version_minor;
+  uint64_t capabilities_flags;
+  uint32_t ib_start_alignment;
+  uint32_t ib_size_alignment;
+/* WARNING: DO NOT EDIT, AUTO-GENERATED CODE - SEE TOP FOR INSTRUCTIONS */
+  uint32_t available_rings;
+  uint32_t _pad;
+};
+#define AMDGPU_FAMILY_UNKNOWN 0
+/* WARNING: DO NOT EDIT, AUTO-GENERATED CODE - SEE TOP FOR INSTRUCTIONS */
+#define AMDGPU_FAMILY_CI 120
+#define AMDGPU_FAMILY_KV 125
+#define AMDGPU_FAMILY_VI 130
+#define AMDGPU_FAMILY_CZ 135
+/* WARNING: DO NOT EDIT, AUTO-GENERATED CODE - SEE TOP FOR INSTRUCTIONS */
+#endif
diff --git a/libc/kernel/uapi/drm/drm.h b/libc/kernel/uapi/drm/drm.h
index 8efc7d7..1f32797 100644
--- a/libc/kernel/uapi/drm/drm.h
+++ b/libc/kernel/uapi/drm/drm.h
@@ -434,208 +434,215 @@
 #define DRM_CAP_ASYNC_PAGE_FLIP 0x7
 #define DRM_CAP_CURSOR_WIDTH 0x8
 #define DRM_CAP_CURSOR_HEIGHT 0x9
-struct drm_get_cap {
+#define DRM_CAP_ADDFB2_MODIFIERS 0x10
 /* WARNING: DO NOT EDIT, AUTO-GENERATED CODE - SEE TOP FOR INSTRUCTIONS */
+struct drm_get_cap {
   __u64 capability;
   __u64 value;
 };
-#define DRM_CLIENT_CAP_STEREO_3D 1
 /* WARNING: DO NOT EDIT, AUTO-GENERATED CODE - SEE TOP FOR INSTRUCTIONS */
+#define DRM_CLIENT_CAP_STEREO_3D 1
 #define DRM_CLIENT_CAP_UNIVERSAL_PLANES 2
+#define DRM_CLIENT_CAP_ATOMIC 3
 struct drm_set_client_cap {
+/* WARNING: DO NOT EDIT, AUTO-GENERATED CODE - SEE TOP FOR INSTRUCTIONS */
   __u64 capability;
   __u64 value;
-/* WARNING: DO NOT EDIT, AUTO-GENERATED CODE - SEE TOP FOR INSTRUCTIONS */
 };
 #define DRM_CLOEXEC O_CLOEXEC
+/* WARNING: DO NOT EDIT, AUTO-GENERATED CODE - SEE TOP FOR INSTRUCTIONS */
 struct drm_prime_handle {
   __u32 handle;
-/* WARNING: DO NOT EDIT, AUTO-GENERATED CODE - SEE TOP FOR INSTRUCTIONS */
   __u32 flags;
   __s32 fd;
+/* WARNING: DO NOT EDIT, AUTO-GENERATED CODE - SEE TOP FOR INSTRUCTIONS */
 };
 #include <drm/drm_mode.h>
-/* WARNING: DO NOT EDIT, AUTO-GENERATED CODE - SEE TOP FOR INSTRUCTIONS */
 #define DRM_IOCTL_BASE 'd'
 #define DRM_IO(nr) _IO(DRM_IOCTL_BASE, nr)
+/* WARNING: DO NOT EDIT, AUTO-GENERATED CODE - SEE TOP FOR INSTRUCTIONS */
 #define DRM_IOR(nr,type) _IOR(DRM_IOCTL_BASE, nr, type)
 #define DRM_IOW(nr,type) _IOW(DRM_IOCTL_BASE, nr, type)
-/* WARNING: DO NOT EDIT, AUTO-GENERATED CODE - SEE TOP FOR INSTRUCTIONS */
 #define DRM_IOWR(nr,type) _IOWR(DRM_IOCTL_BASE, nr, type)
 #define DRM_IOCTL_VERSION DRM_IOWR(0x00, struct drm_version)
+/* WARNING: DO NOT EDIT, AUTO-GENERATED CODE - SEE TOP FOR INSTRUCTIONS */
 #define DRM_IOCTL_GET_UNIQUE DRM_IOWR(0x01, struct drm_unique)
 #define DRM_IOCTL_GET_MAGIC DRM_IOR(0x02, struct drm_auth)
-/* WARNING: DO NOT EDIT, AUTO-GENERATED CODE - SEE TOP FOR INSTRUCTIONS */
 #define DRM_IOCTL_IRQ_BUSID DRM_IOWR(0x03, struct drm_irq_busid)
 #define DRM_IOCTL_GET_MAP DRM_IOWR(0x04, struct drm_map)
+/* WARNING: DO NOT EDIT, AUTO-GENERATED CODE - SEE TOP FOR INSTRUCTIONS */
 #define DRM_IOCTL_GET_CLIENT DRM_IOWR(0x05, struct drm_client)
 #define DRM_IOCTL_GET_STATS DRM_IOR(0x06, struct drm_stats)
-/* WARNING: DO NOT EDIT, AUTO-GENERATED CODE - SEE TOP FOR INSTRUCTIONS */
 #define DRM_IOCTL_SET_VERSION DRM_IOWR(0x07, struct drm_set_version)
 #define DRM_IOCTL_MODESET_CTL DRM_IOW(0x08, struct drm_modeset_ctl)
+/* WARNING: DO NOT EDIT, AUTO-GENERATED CODE - SEE TOP FOR INSTRUCTIONS */
 #define DRM_IOCTL_GEM_CLOSE DRM_IOW(0x09, struct drm_gem_close)
 #define DRM_IOCTL_GEM_FLINK DRM_IOWR(0x0a, struct drm_gem_flink)
-/* WARNING: DO NOT EDIT, AUTO-GENERATED CODE - SEE TOP FOR INSTRUCTIONS */
 #define DRM_IOCTL_GEM_OPEN DRM_IOWR(0x0b, struct drm_gem_open)
 #define DRM_IOCTL_GET_CAP DRM_IOWR(0x0c, struct drm_get_cap)
+/* WARNING: DO NOT EDIT, AUTO-GENERATED CODE - SEE TOP FOR INSTRUCTIONS */
 #define DRM_IOCTL_SET_CLIENT_CAP DRM_IOW(0x0d, struct drm_set_client_cap)
 #define DRM_IOCTL_SET_UNIQUE DRM_IOW(0x10, struct drm_unique)
-/* WARNING: DO NOT EDIT, AUTO-GENERATED CODE - SEE TOP FOR INSTRUCTIONS */
 #define DRM_IOCTL_AUTH_MAGIC DRM_IOW(0x11, struct drm_auth)
 #define DRM_IOCTL_BLOCK DRM_IOWR(0x12, struct drm_block)
+/* WARNING: DO NOT EDIT, AUTO-GENERATED CODE - SEE TOP FOR INSTRUCTIONS */
 #define DRM_IOCTL_UNBLOCK DRM_IOWR(0x13, struct drm_block)
 #define DRM_IOCTL_CONTROL DRM_IOW(0x14, struct drm_control)
-/* WARNING: DO NOT EDIT, AUTO-GENERATED CODE - SEE TOP FOR INSTRUCTIONS */
 #define DRM_IOCTL_ADD_MAP DRM_IOWR(0x15, struct drm_map)
 #define DRM_IOCTL_ADD_BUFS DRM_IOWR(0x16, struct drm_buf_desc)
+/* WARNING: DO NOT EDIT, AUTO-GENERATED CODE - SEE TOP FOR INSTRUCTIONS */
 #define DRM_IOCTL_MARK_BUFS DRM_IOW(0x17, struct drm_buf_desc)
 #define DRM_IOCTL_INFO_BUFS DRM_IOWR(0x18, struct drm_buf_info)
-/* WARNING: DO NOT EDIT, AUTO-GENERATED CODE - SEE TOP FOR INSTRUCTIONS */
 #define DRM_IOCTL_MAP_BUFS DRM_IOWR(0x19, struct drm_buf_map)
 #define DRM_IOCTL_FREE_BUFS DRM_IOW(0x1a, struct drm_buf_free)
+/* WARNING: DO NOT EDIT, AUTO-GENERATED CODE - SEE TOP FOR INSTRUCTIONS */
 #define DRM_IOCTL_RM_MAP DRM_IOW(0x1b, struct drm_map)
 #define DRM_IOCTL_SET_SAREA_CTX DRM_IOW(0x1c, struct drm_ctx_priv_map)
-/* WARNING: DO NOT EDIT, AUTO-GENERATED CODE - SEE TOP FOR INSTRUCTIONS */
 #define DRM_IOCTL_GET_SAREA_CTX DRM_IOWR(0x1d, struct drm_ctx_priv_map)
 #define DRM_IOCTL_SET_MASTER DRM_IO(0x1e)
+/* WARNING: DO NOT EDIT, AUTO-GENERATED CODE - SEE TOP FOR INSTRUCTIONS */
 #define DRM_IOCTL_DROP_MASTER DRM_IO(0x1f)
 #define DRM_IOCTL_ADD_CTX DRM_IOWR(0x20, struct drm_ctx)
-/* WARNING: DO NOT EDIT, AUTO-GENERATED CODE - SEE TOP FOR INSTRUCTIONS */
 #define DRM_IOCTL_RM_CTX DRM_IOWR(0x21, struct drm_ctx)
 #define DRM_IOCTL_MOD_CTX DRM_IOW(0x22, struct drm_ctx)
+/* WARNING: DO NOT EDIT, AUTO-GENERATED CODE - SEE TOP FOR INSTRUCTIONS */
 #define DRM_IOCTL_GET_CTX DRM_IOWR(0x23, struct drm_ctx)
 #define DRM_IOCTL_SWITCH_CTX DRM_IOW(0x24, struct drm_ctx)
-/* WARNING: DO NOT EDIT, AUTO-GENERATED CODE - SEE TOP FOR INSTRUCTIONS */
 #define DRM_IOCTL_NEW_CTX DRM_IOW(0x25, struct drm_ctx)
 #define DRM_IOCTL_RES_CTX DRM_IOWR(0x26, struct drm_ctx_res)
+/* WARNING: DO NOT EDIT, AUTO-GENERATED CODE - SEE TOP FOR INSTRUCTIONS */
 #define DRM_IOCTL_ADD_DRAW DRM_IOWR(0x27, struct drm_draw)
 #define DRM_IOCTL_RM_DRAW DRM_IOWR(0x28, struct drm_draw)
-/* WARNING: DO NOT EDIT, AUTO-GENERATED CODE - SEE TOP FOR INSTRUCTIONS */
 #define DRM_IOCTL_DMA DRM_IOWR(0x29, struct drm_dma)
 #define DRM_IOCTL_LOCK DRM_IOW(0x2a, struct drm_lock)
+/* WARNING: DO NOT EDIT, AUTO-GENERATED CODE - SEE TOP FOR INSTRUCTIONS */
 #define DRM_IOCTL_UNLOCK DRM_IOW(0x2b, struct drm_lock)
 #define DRM_IOCTL_FINISH DRM_IOW(0x2c, struct drm_lock)
-/* WARNING: DO NOT EDIT, AUTO-GENERATED CODE - SEE TOP FOR INSTRUCTIONS */
 #define DRM_IOCTL_PRIME_HANDLE_TO_FD DRM_IOWR(0x2d, struct drm_prime_handle)
 #define DRM_IOCTL_PRIME_FD_TO_HANDLE DRM_IOWR(0x2e, struct drm_prime_handle)
+/* WARNING: DO NOT EDIT, AUTO-GENERATED CODE - SEE TOP FOR INSTRUCTIONS */
 #define DRM_IOCTL_AGP_ACQUIRE DRM_IO(0x30)
 #define DRM_IOCTL_AGP_RELEASE DRM_IO(0x31)
-/* WARNING: DO NOT EDIT, AUTO-GENERATED CODE - SEE TOP FOR INSTRUCTIONS */
 #define DRM_IOCTL_AGP_ENABLE DRM_IOW(0x32, struct drm_agp_mode)
 #define DRM_IOCTL_AGP_INFO DRM_IOR(0x33, struct drm_agp_info)
+/* WARNING: DO NOT EDIT, AUTO-GENERATED CODE - SEE TOP FOR INSTRUCTIONS */
 #define DRM_IOCTL_AGP_ALLOC DRM_IOWR(0x34, struct drm_agp_buffer)
 #define DRM_IOCTL_AGP_FREE DRM_IOW(0x35, struct drm_agp_buffer)
-/* WARNING: DO NOT EDIT, AUTO-GENERATED CODE - SEE TOP FOR INSTRUCTIONS */
 #define DRM_IOCTL_AGP_BIND DRM_IOW(0x36, struct drm_agp_binding)
 #define DRM_IOCTL_AGP_UNBIND DRM_IOW(0x37, struct drm_agp_binding)
+/* WARNING: DO NOT EDIT, AUTO-GENERATED CODE - SEE TOP FOR INSTRUCTIONS */
 #define DRM_IOCTL_SG_ALLOC DRM_IOWR(0x38, struct drm_scatter_gather)
 #define DRM_IOCTL_SG_FREE DRM_IOW(0x39, struct drm_scatter_gather)
-/* WARNING: DO NOT EDIT, AUTO-GENERATED CODE - SEE TOP FOR INSTRUCTIONS */
 #define DRM_IOCTL_WAIT_VBLANK DRM_IOWR(0x3a, union drm_wait_vblank)
 #define DRM_IOCTL_UPDATE_DRAW DRM_IOW(0x3f, struct drm_update_draw)
+/* WARNING: DO NOT EDIT, AUTO-GENERATED CODE - SEE TOP FOR INSTRUCTIONS */
 #define DRM_IOCTL_MODE_GETRESOURCES DRM_IOWR(0xA0, struct drm_mode_card_res)
 #define DRM_IOCTL_MODE_GETCRTC DRM_IOWR(0xA1, struct drm_mode_crtc)
-/* WARNING: DO NOT EDIT, AUTO-GENERATED CODE - SEE TOP FOR INSTRUCTIONS */
 #define DRM_IOCTL_MODE_SETCRTC DRM_IOWR(0xA2, struct drm_mode_crtc)
 #define DRM_IOCTL_MODE_CURSOR DRM_IOWR(0xA3, struct drm_mode_cursor)
+/* WARNING: DO NOT EDIT, AUTO-GENERATED CODE - SEE TOP FOR INSTRUCTIONS */
 #define DRM_IOCTL_MODE_GETGAMMA DRM_IOWR(0xA4, struct drm_mode_crtc_lut)
 #define DRM_IOCTL_MODE_SETGAMMA DRM_IOWR(0xA5, struct drm_mode_crtc_lut)
-/* WARNING: DO NOT EDIT, AUTO-GENERATED CODE - SEE TOP FOR INSTRUCTIONS */
 #define DRM_IOCTL_MODE_GETENCODER DRM_IOWR(0xA6, struct drm_mode_get_encoder)
 #define DRM_IOCTL_MODE_GETCONNECTOR DRM_IOWR(0xA7, struct drm_mode_get_connector)
+/* WARNING: DO NOT EDIT, AUTO-GENERATED CODE - SEE TOP FOR INSTRUCTIONS */
 #define DRM_IOCTL_MODE_ATTACHMODE DRM_IOWR(0xA8, struct drm_mode_mode_cmd)
 #define DRM_IOCTL_MODE_DETACHMODE DRM_IOWR(0xA9, struct drm_mode_mode_cmd)
-/* WARNING: DO NOT EDIT, AUTO-GENERATED CODE - SEE TOP FOR INSTRUCTIONS */
 #define DRM_IOCTL_MODE_GETPROPERTY DRM_IOWR(0xAA, struct drm_mode_get_property)
 #define DRM_IOCTL_MODE_SETPROPERTY DRM_IOWR(0xAB, struct drm_mode_connector_set_property)
+/* WARNING: DO NOT EDIT, AUTO-GENERATED CODE - SEE TOP FOR INSTRUCTIONS */
 #define DRM_IOCTL_MODE_GETPROPBLOB DRM_IOWR(0xAC, struct drm_mode_get_blob)
 #define DRM_IOCTL_MODE_GETFB DRM_IOWR(0xAD, struct drm_mode_fb_cmd)
-/* WARNING: DO NOT EDIT, AUTO-GENERATED CODE - SEE TOP FOR INSTRUCTIONS */
 #define DRM_IOCTL_MODE_ADDFB DRM_IOWR(0xAE, struct drm_mode_fb_cmd)
 #define DRM_IOCTL_MODE_RMFB DRM_IOWR(0xAF, unsigned int)
+/* WARNING: DO NOT EDIT, AUTO-GENERATED CODE - SEE TOP FOR INSTRUCTIONS */
 #define DRM_IOCTL_MODE_PAGE_FLIP DRM_IOWR(0xB0, struct drm_mode_crtc_page_flip)
 #define DRM_IOCTL_MODE_DIRTYFB DRM_IOWR(0xB1, struct drm_mode_fb_dirty_cmd)
-/* WARNING: DO NOT EDIT, AUTO-GENERATED CODE - SEE TOP FOR INSTRUCTIONS */
 #define DRM_IOCTL_MODE_CREATE_DUMB DRM_IOWR(0xB2, struct drm_mode_create_dumb)
 #define DRM_IOCTL_MODE_MAP_DUMB DRM_IOWR(0xB3, struct drm_mode_map_dumb)
+/* WARNING: DO NOT EDIT, AUTO-GENERATED CODE - SEE TOP FOR INSTRUCTIONS */
 #define DRM_IOCTL_MODE_DESTROY_DUMB DRM_IOWR(0xB4, struct drm_mode_destroy_dumb)
 #define DRM_IOCTL_MODE_GETPLANERESOURCES DRM_IOWR(0xB5, struct drm_mode_get_plane_res)
-/* WARNING: DO NOT EDIT, AUTO-GENERATED CODE - SEE TOP FOR INSTRUCTIONS */
 #define DRM_IOCTL_MODE_GETPLANE DRM_IOWR(0xB6, struct drm_mode_get_plane)
 #define DRM_IOCTL_MODE_SETPLANE DRM_IOWR(0xB7, struct drm_mode_set_plane)
+/* WARNING: DO NOT EDIT, AUTO-GENERATED CODE - SEE TOP FOR INSTRUCTIONS */
 #define DRM_IOCTL_MODE_ADDFB2 DRM_IOWR(0xB8, struct drm_mode_fb_cmd2)
 #define DRM_IOCTL_MODE_OBJ_GETPROPERTIES DRM_IOWR(0xB9, struct drm_mode_obj_get_properties)
-/* WARNING: DO NOT EDIT, AUTO-GENERATED CODE - SEE TOP FOR INSTRUCTIONS */
 #define DRM_IOCTL_MODE_OBJ_SETPROPERTY DRM_IOWR(0xBA, struct drm_mode_obj_set_property)
 #define DRM_IOCTL_MODE_CURSOR2 DRM_IOWR(0xBB, struct drm_mode_cursor2)
-#define DRM_COMMAND_BASE 0x40
-#define DRM_COMMAND_END 0xA0
 /* WARNING: DO NOT EDIT, AUTO-GENERATED CODE - SEE TOP FOR INSTRUCTIONS */
+#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_COMMAND_BASE 0x40
+/* WARNING: DO NOT EDIT, AUTO-GENERATED CODE - SEE TOP FOR INSTRUCTIONS */
+#define DRM_COMMAND_END 0xA0
 struct drm_event {
   __u32 type;
   __u32 length;
-};
 /* WARNING: DO NOT EDIT, AUTO-GENERATED CODE - SEE TOP FOR INSTRUCTIONS */
+};
 #define DRM_EVENT_VBLANK 0x01
 #define DRM_EVENT_FLIP_COMPLETE 0x02
 struct drm_event_vblank {
-  struct drm_event base;
 /* WARNING: DO NOT EDIT, AUTO-GENERATED CODE - SEE TOP FOR INSTRUCTIONS */
+  struct drm_event base;
   __u64 user_data;
   __u32 tv_sec;
   __u32 tv_usec;
-  __u32 sequence;
 /* WARNING: DO NOT EDIT, AUTO-GENERATED CODE - SEE TOP FOR INSTRUCTIONS */
+  __u32 sequence;
   __u32 reserved;
 };
 typedef struct drm_clip_rect drm_clip_rect_t;
-typedef struct drm_drawable_info drm_drawable_info_t;
 /* WARNING: DO NOT EDIT, AUTO-GENERATED CODE - SEE TOP FOR INSTRUCTIONS */
+typedef struct drm_drawable_info drm_drawable_info_t;
 typedef struct drm_tex_region drm_tex_region_t;
 typedef struct drm_hw_lock drm_hw_lock_t;
 typedef struct drm_version drm_version_t;
-typedef struct drm_unique drm_unique_t;
 /* WARNING: DO NOT EDIT, AUTO-GENERATED CODE - SEE TOP FOR INSTRUCTIONS */
+typedef struct drm_unique drm_unique_t;
 typedef struct drm_list drm_list_t;
 typedef struct drm_block drm_block_t;
 typedef struct drm_control drm_control_t;
-typedef enum drm_map_type drm_map_type_t;
 /* WARNING: DO NOT EDIT, AUTO-GENERATED CODE - SEE TOP FOR INSTRUCTIONS */
+typedef enum drm_map_type drm_map_type_t;
 typedef enum drm_map_flags drm_map_flags_t;
 typedef struct drm_ctx_priv_map drm_ctx_priv_map_t;
 typedef struct drm_map drm_map_t;
-typedef struct drm_client drm_client_t;
 /* WARNING: DO NOT EDIT, AUTO-GENERATED CODE - SEE TOP FOR INSTRUCTIONS */
+typedef struct drm_client drm_client_t;
 typedef enum drm_stat_type drm_stat_type_t;
 typedef struct drm_stats drm_stats_t;
 typedef enum drm_lock_flags drm_lock_flags_t;
-typedef struct drm_lock drm_lock_t;
 /* WARNING: DO NOT EDIT, AUTO-GENERATED CODE - SEE TOP FOR INSTRUCTIONS */
+typedef struct drm_lock drm_lock_t;
 typedef enum drm_dma_flags drm_dma_flags_t;
 typedef struct drm_buf_desc drm_buf_desc_t;
 typedef struct drm_buf_info drm_buf_info_t;
-typedef struct drm_buf_free drm_buf_free_t;
 /* WARNING: DO NOT EDIT, AUTO-GENERATED CODE - SEE TOP FOR INSTRUCTIONS */
+typedef struct drm_buf_free drm_buf_free_t;
 typedef struct drm_buf_pub drm_buf_pub_t;
 typedef struct drm_buf_map drm_buf_map_t;
 typedef struct drm_dma drm_dma_t;
-typedef union drm_wait_vblank drm_wait_vblank_t;
 /* WARNING: DO NOT EDIT, AUTO-GENERATED CODE - SEE TOP FOR INSTRUCTIONS */
+typedef union drm_wait_vblank drm_wait_vblank_t;
 typedef struct drm_agp_mode drm_agp_mode_t;
 typedef enum drm_ctx_flags drm_ctx_flags_t;
 typedef struct drm_ctx drm_ctx_t;
-typedef struct drm_ctx_res drm_ctx_res_t;
 /* WARNING: DO NOT EDIT, AUTO-GENERATED CODE - SEE TOP FOR INSTRUCTIONS */
+typedef struct drm_ctx_res drm_ctx_res_t;
 typedef struct drm_draw drm_draw_t;
 typedef struct drm_update_draw drm_update_draw_t;
 typedef struct drm_auth drm_auth_t;
-typedef struct drm_irq_busid drm_irq_busid_t;
 /* WARNING: DO NOT EDIT, AUTO-GENERATED CODE - SEE TOP FOR INSTRUCTIONS */
+typedef struct drm_irq_busid drm_irq_busid_t;
 typedef enum drm_vblank_seq_type drm_vblank_seq_type_t;
 typedef struct drm_agp_buffer drm_agp_buffer_t;
 typedef struct drm_agp_binding drm_agp_binding_t;
-typedef struct drm_agp_info drm_agp_info_t;
 /* WARNING: DO NOT EDIT, AUTO-GENERATED CODE - SEE TOP FOR INSTRUCTIONS */
+typedef struct drm_agp_info drm_agp_info_t;
 typedef struct drm_scatter_gather drm_scatter_gather_t;
 typedef struct drm_set_version drm_set_version_t;
 #endif
+/* WARNING: DO NOT EDIT, AUTO-GENERATED CODE - SEE TOP FOR INSTRUCTIONS */
diff --git a/libc/kernel/uapi/drm/drm_fourcc.h b/libc/kernel/uapi/drm/drm_fourcc.h
index 47e93dd..ec8a91a 100644
--- a/libc/kernel/uapi/drm/drm_fourcc.h
+++ b/libc/kernel/uapi/drm/drm_fourcc.h
@@ -23,79 +23,96 @@
 /* WARNING: DO NOT EDIT, AUTO-GENERATED CODE - SEE TOP FOR INSTRUCTIONS */
 #define DRM_FORMAT_BIG_ENDIAN (1 << 31)
 #define DRM_FORMAT_C8 fourcc_code('C', '8', ' ', ' ')
+#define DRM_FORMAT_R8 fourcc_code('R', '8', ' ', ' ')
+#define DRM_FORMAT_RG88 fourcc_code('R', 'G', '8', '8')
+/* WARNING: DO NOT EDIT, AUTO-GENERATED CODE - SEE TOP FOR INSTRUCTIONS */
+#define DRM_FORMAT_GR88 fourcc_code('G', 'R', '8', '8')
 #define DRM_FORMAT_RGB332 fourcc_code('R', 'G', 'B', '8')
 #define DRM_FORMAT_BGR233 fourcc_code('B', 'G', 'R', '8')
-/* WARNING: DO NOT EDIT, AUTO-GENERATED CODE - SEE TOP FOR INSTRUCTIONS */
 #define DRM_FORMAT_XRGB4444 fourcc_code('X', 'R', '1', '2')
+/* WARNING: DO NOT EDIT, AUTO-GENERATED CODE - SEE TOP FOR INSTRUCTIONS */
 #define DRM_FORMAT_XBGR4444 fourcc_code('X', 'B', '1', '2')
 #define DRM_FORMAT_RGBX4444 fourcc_code('R', 'X', '1', '2')
 #define DRM_FORMAT_BGRX4444 fourcc_code('B', 'X', '1', '2')
-/* WARNING: DO NOT EDIT, AUTO-GENERATED CODE - SEE TOP FOR INSTRUCTIONS */
 #define DRM_FORMAT_ARGB4444 fourcc_code('A', 'R', '1', '2')
+/* WARNING: DO NOT EDIT, AUTO-GENERATED CODE - SEE TOP FOR INSTRUCTIONS */
 #define DRM_FORMAT_ABGR4444 fourcc_code('A', 'B', '1', '2')
 #define DRM_FORMAT_RGBA4444 fourcc_code('R', 'A', '1', '2')
 #define DRM_FORMAT_BGRA4444 fourcc_code('B', 'A', '1', '2')
-/* WARNING: DO NOT EDIT, AUTO-GENERATED CODE - SEE TOP FOR INSTRUCTIONS */
 #define DRM_FORMAT_XRGB1555 fourcc_code('X', 'R', '1', '5')
+/* WARNING: DO NOT EDIT, AUTO-GENERATED CODE - SEE TOP FOR INSTRUCTIONS */
 #define DRM_FORMAT_XBGR1555 fourcc_code('X', 'B', '1', '5')
 #define DRM_FORMAT_RGBX5551 fourcc_code('R', 'X', '1', '5')
 #define DRM_FORMAT_BGRX5551 fourcc_code('B', 'X', '1', '5')
-/* WARNING: DO NOT EDIT, AUTO-GENERATED CODE - SEE TOP FOR INSTRUCTIONS */
 #define DRM_FORMAT_ARGB1555 fourcc_code('A', 'R', '1', '5')
+/* WARNING: DO NOT EDIT, AUTO-GENERATED CODE - SEE TOP FOR INSTRUCTIONS */
 #define DRM_FORMAT_ABGR1555 fourcc_code('A', 'B', '1', '5')
 #define DRM_FORMAT_RGBA5551 fourcc_code('R', 'A', '1', '5')
 #define DRM_FORMAT_BGRA5551 fourcc_code('B', 'A', '1', '5')
-/* WARNING: DO NOT EDIT, AUTO-GENERATED CODE - SEE TOP FOR INSTRUCTIONS */
 #define DRM_FORMAT_RGB565 fourcc_code('R', 'G', '1', '6')
+/* WARNING: DO NOT EDIT, AUTO-GENERATED CODE - SEE TOP FOR INSTRUCTIONS */
 #define DRM_FORMAT_BGR565 fourcc_code('B', 'G', '1', '6')
 #define DRM_FORMAT_RGB888 fourcc_code('R', 'G', '2', '4')
 #define DRM_FORMAT_BGR888 fourcc_code('B', 'G', '2', '4')
-/* WARNING: DO NOT EDIT, AUTO-GENERATED CODE - SEE TOP FOR INSTRUCTIONS */
 #define DRM_FORMAT_XRGB8888 fourcc_code('X', 'R', '2', '4')
+/* WARNING: DO NOT EDIT, AUTO-GENERATED CODE - SEE TOP FOR INSTRUCTIONS */
 #define DRM_FORMAT_XBGR8888 fourcc_code('X', 'B', '2', '4')
 #define DRM_FORMAT_RGBX8888 fourcc_code('R', 'X', '2', '4')
 #define DRM_FORMAT_BGRX8888 fourcc_code('B', 'X', '2', '4')
-/* WARNING: DO NOT EDIT, AUTO-GENERATED CODE - SEE TOP FOR INSTRUCTIONS */
 #define DRM_FORMAT_ARGB8888 fourcc_code('A', 'R', '2', '4')
+/* WARNING: DO NOT EDIT, AUTO-GENERATED CODE - SEE TOP FOR INSTRUCTIONS */
 #define DRM_FORMAT_ABGR8888 fourcc_code('A', 'B', '2', '4')
 #define DRM_FORMAT_RGBA8888 fourcc_code('R', 'A', '2', '4')
 #define DRM_FORMAT_BGRA8888 fourcc_code('B', 'A', '2', '4')
-/* WARNING: DO NOT EDIT, AUTO-GENERATED CODE - SEE TOP FOR INSTRUCTIONS */
 #define DRM_FORMAT_XRGB2101010 fourcc_code('X', 'R', '3', '0')
+/* WARNING: DO NOT EDIT, AUTO-GENERATED CODE - SEE TOP FOR INSTRUCTIONS */
 #define DRM_FORMAT_XBGR2101010 fourcc_code('X', 'B', '3', '0')
 #define DRM_FORMAT_RGBX1010102 fourcc_code('R', 'X', '3', '0')
 #define DRM_FORMAT_BGRX1010102 fourcc_code('B', 'X', '3', '0')
-/* WARNING: DO NOT EDIT, AUTO-GENERATED CODE - SEE TOP FOR INSTRUCTIONS */
 #define DRM_FORMAT_ARGB2101010 fourcc_code('A', 'R', '3', '0')
+/* WARNING: DO NOT EDIT, AUTO-GENERATED CODE - SEE TOP FOR INSTRUCTIONS */
 #define DRM_FORMAT_ABGR2101010 fourcc_code('A', 'B', '3', '0')
 #define DRM_FORMAT_RGBA1010102 fourcc_code('R', 'A', '3', '0')
 #define DRM_FORMAT_BGRA1010102 fourcc_code('B', 'A', '3', '0')
-/* WARNING: DO NOT EDIT, AUTO-GENERATED CODE - SEE TOP FOR INSTRUCTIONS */
 #define DRM_FORMAT_YUYV fourcc_code('Y', 'U', 'Y', 'V')
+/* WARNING: DO NOT EDIT, AUTO-GENERATED CODE - SEE TOP FOR INSTRUCTIONS */
 #define DRM_FORMAT_YVYU fourcc_code('Y', 'V', 'Y', 'U')
 #define DRM_FORMAT_UYVY fourcc_code('U', 'Y', 'V', 'Y')
 #define DRM_FORMAT_VYUY fourcc_code('V', 'Y', 'U', 'Y')
-/* WARNING: DO NOT EDIT, AUTO-GENERATED CODE - SEE TOP FOR INSTRUCTIONS */
 #define DRM_FORMAT_AYUV fourcc_code('A', 'Y', 'U', 'V')
+/* WARNING: DO NOT EDIT, AUTO-GENERATED CODE - SEE TOP FOR INSTRUCTIONS */
 #define DRM_FORMAT_NV12 fourcc_code('N', 'V', '1', '2')
 #define DRM_FORMAT_NV21 fourcc_code('N', 'V', '2', '1')
 #define DRM_FORMAT_NV16 fourcc_code('N', 'V', '1', '6')
-/* WARNING: DO NOT EDIT, AUTO-GENERATED CODE - SEE TOP FOR INSTRUCTIONS */
 #define DRM_FORMAT_NV61 fourcc_code('N', 'V', '6', '1')
+/* WARNING: DO NOT EDIT, AUTO-GENERATED CODE - SEE TOP FOR INSTRUCTIONS */
 #define DRM_FORMAT_NV24 fourcc_code('N', 'V', '2', '4')
 #define DRM_FORMAT_NV42 fourcc_code('N', 'V', '4', '2')
-#define DRM_FORMAT_NV12MT fourcc_code('T', 'M', '1', '2')
-/* WARNING: DO NOT EDIT, AUTO-GENERATED CODE - SEE TOP FOR INSTRUCTIONS */
 #define DRM_FORMAT_YUV410 fourcc_code('Y', 'U', 'V', '9')
 #define DRM_FORMAT_YVU410 fourcc_code('Y', 'V', 'U', '9')
+/* WARNING: DO NOT EDIT, AUTO-GENERATED CODE - SEE TOP FOR INSTRUCTIONS */
 #define DRM_FORMAT_YUV411 fourcc_code('Y', 'U', '1', '1')
 #define DRM_FORMAT_YVU411 fourcc_code('Y', 'V', '1', '1')
-/* WARNING: DO NOT EDIT, AUTO-GENERATED CODE - SEE TOP FOR INSTRUCTIONS */
 #define DRM_FORMAT_YUV420 fourcc_code('Y', 'U', '1', '2')
 #define DRM_FORMAT_YVU420 fourcc_code('Y', 'V', '1', '2')
+/* WARNING: DO NOT EDIT, AUTO-GENERATED CODE - SEE TOP FOR INSTRUCTIONS */
 #define DRM_FORMAT_YUV422 fourcc_code('Y', 'U', '1', '6')
 #define DRM_FORMAT_YVU422 fourcc_code('Y', 'V', '1', '6')
-/* WARNING: DO NOT EDIT, AUTO-GENERATED CODE - SEE TOP FOR INSTRUCTIONS */
 #define DRM_FORMAT_YUV444 fourcc_code('Y', 'U', '2', '4')
 #define DRM_FORMAT_YVU444 fourcc_code('Y', 'V', '2', '4')
+/* WARNING: DO NOT EDIT, AUTO-GENERATED CODE - SEE TOP FOR INSTRUCTIONS */
+#define DRM_FORMAT_MOD_NONE 0
+#define DRM_FORMAT_MOD_VENDOR_INTEL 0x01
+#define DRM_FORMAT_MOD_VENDOR_AMD 0x02
+#define DRM_FORMAT_MOD_VENDOR_NV 0x03
+/* WARNING: DO NOT EDIT, AUTO-GENERATED CODE - SEE TOP FOR INSTRUCTIONS */
+#define DRM_FORMAT_MOD_VENDOR_SAMSUNG 0x04
+#define DRM_FORMAT_MOD_VENDOR_QCOM 0x05
+#define fourcc_mod_code(vendor,val) ((((__u64) DRM_FORMAT_MOD_VENDOR_ ##vendor) << 56) | (val & 0x00ffffffffffffffULL))
+#define I915_FORMAT_MOD_X_TILED fourcc_mod_code(INTEL, 1)
+/* WARNING: DO NOT EDIT, AUTO-GENERATED CODE - SEE TOP FOR INSTRUCTIONS */
+#define I915_FORMAT_MOD_Y_TILED fourcc_mod_code(INTEL, 2)
+#define I915_FORMAT_MOD_Yf_TILED fourcc_mod_code(INTEL, 3)
+#define DRM_FORMAT_MOD_SAMSUNG_64_32_TILE fourcc_mod_code(SAMSUNG, 1)
 #endif
+/* WARNING: DO NOT EDIT, AUTO-GENERATED CODE - SEE TOP FOR INSTRUCTIONS */
diff --git a/libc/kernel/uapi/drm/drm_mode.h b/libc/kernel/uapi/drm/drm_mode.h
index abd92a1..240a8ae 100644
--- a/libc/kernel/uapi/drm/drm_mode.h
+++ b/libc/kernel/uapi/drm/drm_mode.h
@@ -87,8 +87,18 @@
 struct drm_mode_modeinfo {
 /* WARNING: DO NOT EDIT, AUTO-GENERATED CODE - SEE TOP FOR INSTRUCTIONS */
   __u32 clock;
-  __u16 hdisplay, hsync_start, hsync_end, htotal, hskew;
-  __u16 vdisplay, vsync_start, vsync_end, vtotal, vscan;
+  __u16 hdisplay;
+  __u16 hsync_start;
+  __u16 hsync_end;
+/* WARNING: DO NOT EDIT, AUTO-GENERATED CODE - SEE TOP FOR INSTRUCTIONS */
+  __u16 htotal;
+  __u16 hskew;
+  __u16 vdisplay;
+  __u16 vsync_start;
+/* WARNING: DO NOT EDIT, AUTO-GENERATED CODE - SEE TOP FOR INSTRUCTIONS */
+  __u16 vsync_end;
+  __u16 vtotal;
+  __u16 vscan;
   __u32 vrefresh;
 /* WARNING: DO NOT EDIT, AUTO-GENERATED CODE - SEE TOP FOR INSTRUCTIONS */
   __u32 flags;
@@ -107,121 +117,131 @@
   __u32 count_connectors;
 /* WARNING: DO NOT EDIT, AUTO-GENERATED CODE - SEE TOP FOR INSTRUCTIONS */
   __u32 count_encoders;
-  __u32 min_width, max_width;
-  __u32 min_height, max_height;
-};
+  __u32 min_width;
+  __u32 max_width;
+  __u32 min_height;
 /* WARNING: DO NOT EDIT, AUTO-GENERATED CODE - SEE TOP FOR INSTRUCTIONS */
+  __u32 max_height;
+};
 struct drm_mode_crtc {
   __u64 set_connectors_ptr;
+/* WARNING: DO NOT EDIT, AUTO-GENERATED CODE - SEE TOP FOR INSTRUCTIONS */
   __u32 count_connectors;
   __u32 crtc_id;
-/* WARNING: DO NOT EDIT, AUTO-GENERATED CODE - SEE TOP FOR INSTRUCTIONS */
   __u32 fb_id;
-  __u32 x, y;
+  __u32 x;
+/* WARNING: DO NOT EDIT, AUTO-GENERATED CODE - SEE TOP FOR INSTRUCTIONS */
+  __u32 y;
   __u32 gamma_size;
   __u32 mode_valid;
-/* WARNING: DO NOT EDIT, AUTO-GENERATED CODE - SEE TOP FOR INSTRUCTIONS */
   struct drm_mode_modeinfo mode;
+/* WARNING: DO NOT EDIT, AUTO-GENERATED CODE - SEE TOP FOR INSTRUCTIONS */
 };
 #define DRM_MODE_PRESENT_TOP_FIELD (1 << 0)
 #define DRM_MODE_PRESENT_BOTTOM_FIELD (1 << 1)
-/* WARNING: DO NOT EDIT, AUTO-GENERATED CODE - SEE TOP FOR INSTRUCTIONS */
 struct drm_mode_set_plane {
+/* WARNING: DO NOT EDIT, AUTO-GENERATED CODE - SEE TOP FOR INSTRUCTIONS */
   __u32 plane_id;
   __u32 crtc_id;
   __u32 fb_id;
-/* WARNING: DO NOT EDIT, AUTO-GENERATED CODE - SEE TOP FOR INSTRUCTIONS */
   __u32 flags;
-  __s32 crtc_x, crtc_y;
-  __u32 crtc_w, crtc_h;
-  __u32 src_x, src_y;
 /* WARNING: DO NOT EDIT, AUTO-GENERATED CODE - SEE TOP FOR INSTRUCTIONS */
-  __u32 src_h, src_w;
+  __s32 crtc_x;
+  __s32 crtc_y;
+  __u32 crtc_w;
+  __u32 crtc_h;
+/* WARNING: DO NOT EDIT, AUTO-GENERATED CODE - SEE TOP FOR INSTRUCTIONS */
+  __u32 src_x;
+  __u32 src_y;
+  __u32 src_h;
+  __u32 src_w;
+/* WARNING: DO NOT EDIT, AUTO-GENERATED CODE - SEE TOP FOR INSTRUCTIONS */
 };
 struct drm_mode_get_plane {
   __u32 plane_id;
-/* WARNING: DO NOT EDIT, AUTO-GENERATED CODE - SEE TOP FOR INSTRUCTIONS */
   __u32 crtc_id;
+/* WARNING: DO NOT EDIT, AUTO-GENERATED CODE - SEE TOP FOR INSTRUCTIONS */
   __u32 fb_id;
   __u32 possible_crtcs;
   __u32 gamma_size;
-/* WARNING: DO NOT EDIT, AUTO-GENERATED CODE - SEE TOP FOR INSTRUCTIONS */
   __u32 count_format_types;
+/* WARNING: DO NOT EDIT, AUTO-GENERATED CODE - SEE TOP FOR INSTRUCTIONS */
   __u64 format_type_ptr;
 };
 struct drm_mode_get_plane_res {
-/* WARNING: DO NOT EDIT, AUTO-GENERATED CODE - SEE TOP FOR INSTRUCTIONS */
   __u64 plane_id_ptr;
+/* WARNING: DO NOT EDIT, AUTO-GENERATED CODE - SEE TOP FOR INSTRUCTIONS */
   __u32 count_planes;
 };
 #define DRM_MODE_ENCODER_NONE 0
-/* WARNING: DO NOT EDIT, AUTO-GENERATED CODE - SEE TOP FOR INSTRUCTIONS */
 #define DRM_MODE_ENCODER_DAC 1
+/* WARNING: DO NOT EDIT, AUTO-GENERATED CODE - SEE TOP FOR INSTRUCTIONS */
 #define DRM_MODE_ENCODER_TMDS 2
 #define DRM_MODE_ENCODER_LVDS 3
 #define DRM_MODE_ENCODER_TVDAC 4
-/* WARNING: DO NOT EDIT, AUTO-GENERATED CODE - SEE TOP FOR INSTRUCTIONS */
 #define DRM_MODE_ENCODER_VIRTUAL 5
+/* WARNING: DO NOT EDIT, AUTO-GENERATED CODE - SEE TOP FOR INSTRUCTIONS */
 #define DRM_MODE_ENCODER_DSI 6
 #define DRM_MODE_ENCODER_DPMST 7
 struct drm_mode_get_encoder {
-/* WARNING: DO NOT EDIT, AUTO-GENERATED CODE - SEE TOP FOR INSTRUCTIONS */
   __u32 encoder_id;
+/* WARNING: DO NOT EDIT, AUTO-GENERATED CODE - SEE TOP FOR INSTRUCTIONS */
   __u32 encoder_type;
   __u32 crtc_id;
   __u32 possible_crtcs;
-/* WARNING: DO NOT EDIT, AUTO-GENERATED CODE - SEE TOP FOR INSTRUCTIONS */
   __u32 possible_clones;
+/* WARNING: DO NOT EDIT, AUTO-GENERATED CODE - SEE TOP FOR INSTRUCTIONS */
 };
 #define DRM_MODE_SUBCONNECTOR_Automatic 0
 #define DRM_MODE_SUBCONNECTOR_Unknown 0
-/* WARNING: DO NOT EDIT, AUTO-GENERATED CODE - SEE TOP FOR INSTRUCTIONS */
 #define DRM_MODE_SUBCONNECTOR_DVID 3
+/* WARNING: DO NOT EDIT, AUTO-GENERATED CODE - SEE TOP FOR INSTRUCTIONS */
 #define DRM_MODE_SUBCONNECTOR_DVIA 4
 #define DRM_MODE_SUBCONNECTOR_Composite 5
 #define DRM_MODE_SUBCONNECTOR_SVIDEO 6
-/* WARNING: DO NOT EDIT, AUTO-GENERATED CODE - SEE TOP FOR INSTRUCTIONS */
 #define DRM_MODE_SUBCONNECTOR_Component 8
+/* WARNING: DO NOT EDIT, AUTO-GENERATED CODE - SEE TOP FOR INSTRUCTIONS */
 #define DRM_MODE_SUBCONNECTOR_SCART 9
 #define DRM_MODE_CONNECTOR_Unknown 0
 #define DRM_MODE_CONNECTOR_VGA 1
-/* WARNING: DO NOT EDIT, AUTO-GENERATED CODE - SEE TOP FOR INSTRUCTIONS */
 #define DRM_MODE_CONNECTOR_DVII 2
+/* WARNING: DO NOT EDIT, AUTO-GENERATED CODE - SEE TOP FOR INSTRUCTIONS */
 #define DRM_MODE_CONNECTOR_DVID 3
 #define DRM_MODE_CONNECTOR_DVIA 4
 #define DRM_MODE_CONNECTOR_Composite 5
-/* WARNING: DO NOT EDIT, AUTO-GENERATED CODE - SEE TOP FOR INSTRUCTIONS */
 #define DRM_MODE_CONNECTOR_SVIDEO 6
+/* WARNING: DO NOT EDIT, AUTO-GENERATED CODE - SEE TOP FOR INSTRUCTIONS */
 #define DRM_MODE_CONNECTOR_LVDS 7
 #define DRM_MODE_CONNECTOR_Component 8
 #define DRM_MODE_CONNECTOR_9PinDIN 9
-/* WARNING: DO NOT EDIT, AUTO-GENERATED CODE - SEE TOP FOR INSTRUCTIONS */
 #define DRM_MODE_CONNECTOR_DisplayPort 10
+/* WARNING: DO NOT EDIT, AUTO-GENERATED CODE - SEE TOP FOR INSTRUCTIONS */
 #define DRM_MODE_CONNECTOR_HDMIA 11
 #define DRM_MODE_CONNECTOR_HDMIB 12
 #define DRM_MODE_CONNECTOR_TV 13
-/* WARNING: DO NOT EDIT, AUTO-GENERATED CODE - SEE TOP FOR INSTRUCTIONS */
 #define DRM_MODE_CONNECTOR_eDP 14
+/* WARNING: DO NOT EDIT, AUTO-GENERATED CODE - SEE TOP FOR INSTRUCTIONS */
 #define DRM_MODE_CONNECTOR_VIRTUAL 15
 #define DRM_MODE_CONNECTOR_DSI 16
 struct drm_mode_get_connector {
-/* WARNING: DO NOT EDIT, AUTO-GENERATED CODE - SEE TOP FOR INSTRUCTIONS */
   __u64 encoders_ptr;
+/* WARNING: DO NOT EDIT, AUTO-GENERATED CODE - SEE TOP FOR INSTRUCTIONS */
   __u64 modes_ptr;
   __u64 props_ptr;
   __u64 prop_values_ptr;
-/* WARNING: DO NOT EDIT, AUTO-GENERATED CODE - SEE TOP FOR INSTRUCTIONS */
   __u32 count_modes;
+/* WARNING: DO NOT EDIT, AUTO-GENERATED CODE - SEE TOP FOR INSTRUCTIONS */
   __u32 count_props;
   __u32 count_encoders;
   __u32 encoder_id;
-/* WARNING: DO NOT EDIT, AUTO-GENERATED CODE - SEE TOP FOR INSTRUCTIONS */
   __u32 connector_id;
+/* WARNING: DO NOT EDIT, AUTO-GENERATED CODE - SEE TOP FOR INSTRUCTIONS */
   __u32 connector_type;
   __u32 connector_type_id;
   __u32 connection;
+  __u32 mm_width;
 /* WARNING: DO NOT EDIT, AUTO-GENERATED CODE - SEE TOP FOR INSTRUCTIONS */
-  __u32 mm_width, mm_height;
+  __u32 mm_height;
   __u32 subpixel;
   __u32 pad;
 };
@@ -239,66 +259,71 @@
 #define DRM_MODE_PROP_TYPE(n) ((n) << 6)
 #define DRM_MODE_PROP_OBJECT DRM_MODE_PROP_TYPE(1)
 #define DRM_MODE_PROP_SIGNED_RANGE DRM_MODE_PROP_TYPE(2)
-struct drm_mode_property_enum {
+#define DRM_MODE_PROP_ATOMIC 0x80000000
 /* WARNING: DO NOT EDIT, AUTO-GENERATED CODE - SEE TOP FOR INSTRUCTIONS */
+struct drm_mode_property_enum {
   __u64 value;
   char name[DRM_PROP_NAME_LEN];
 };
-struct drm_mode_get_property {
 /* WARNING: DO NOT EDIT, AUTO-GENERATED CODE - SEE TOP FOR INSTRUCTIONS */
+struct drm_mode_get_property {
   __u64 values_ptr;
   __u64 enum_blob_ptr;
   __u32 prop_id;
-  __u32 flags;
 /* WARNING: DO NOT EDIT, AUTO-GENERATED CODE - SEE TOP FOR INSTRUCTIONS */
+  __u32 flags;
   char name[DRM_PROP_NAME_LEN];
   __u32 count_values;
   __u32 count_enum_blobs;
-};
 /* WARNING: DO NOT EDIT, AUTO-GENERATED CODE - SEE TOP FOR INSTRUCTIONS */
+};
 struct drm_mode_connector_set_property {
   __u64 value;
   __u32 prop_id;
-  __u32 connector_id;
 /* WARNING: DO NOT EDIT, AUTO-GENERATED CODE - SEE TOP FOR INSTRUCTIONS */
+  __u32 connector_id;
 };
 struct drm_mode_obj_get_properties {
   __u64 props_ptr;
-  __u64 prop_values_ptr;
 /* WARNING: DO NOT EDIT, AUTO-GENERATED CODE - SEE TOP FOR INSTRUCTIONS */
+  __u64 prop_values_ptr;
   __u32 count_props;
   __u32 obj_id;
   __u32 obj_type;
-};
 /* WARNING: DO NOT EDIT, AUTO-GENERATED CODE - SEE TOP FOR INSTRUCTIONS */
+};
 struct drm_mode_obj_set_property {
   __u64 value;
   __u32 prop_id;
-  __u32 obj_id;
 /* WARNING: DO NOT EDIT, AUTO-GENERATED CODE - SEE TOP FOR INSTRUCTIONS */
+  __u32 obj_id;
   __u32 obj_type;
 };
 struct drm_mode_get_blob {
-  __u32 blob_id;
 /* WARNING: DO NOT EDIT, AUTO-GENERATED CODE - SEE TOP FOR INSTRUCTIONS */
+  __u32 blob_id;
   __u32 length;
   __u64 data;
 };
-struct drm_mode_fb_cmd {
 /* WARNING: DO NOT EDIT, AUTO-GENERATED CODE - SEE TOP FOR INSTRUCTIONS */
+struct drm_mode_fb_cmd {
   __u32 fb_id;
-  __u32 width, height;
+  __u32 width;
+  __u32 height;
+/* WARNING: DO NOT EDIT, AUTO-GENERATED CODE - SEE TOP FOR INSTRUCTIONS */
   __u32 pitch;
   __u32 bpp;
-/* WARNING: DO NOT EDIT, AUTO-GENERATED CODE - SEE TOP FOR INSTRUCTIONS */
   __u32 depth;
   __u32 handle;
+/* WARNING: DO NOT EDIT, AUTO-GENERATED CODE - SEE TOP FOR INSTRUCTIONS */
 };
 #define DRM_MODE_FB_INTERLACED (1 << 0)
-/* WARNING: DO NOT EDIT, AUTO-GENERATED CODE - SEE TOP FOR INSTRUCTIONS */
+#define DRM_MODE_FB_MODIFIERS (1 << 1)
 struct drm_mode_fb_cmd2 {
+/* WARNING: DO NOT EDIT, AUTO-GENERATED CODE - SEE TOP FOR INSTRUCTIONS */
   __u32 fb_id;
-  __u32 width, height;
+  __u32 width;
+  __u32 height;
   __u32 pixel_format;
 /* WARNING: DO NOT EDIT, AUTO-GENERATED CODE - SEE TOP FOR INSTRUCTIONS */
   __u32 flags;
@@ -306,95 +331,124 @@
   __u32 pitches[4];
   __u32 offsets[4];
 /* WARNING: DO NOT EDIT, AUTO-GENERATED CODE - SEE TOP FOR INSTRUCTIONS */
+  __u64 modifier[4];
 };
 #define DRM_MODE_FB_DIRTY_ANNOTATE_COPY 0x01
 #define DRM_MODE_FB_DIRTY_ANNOTATE_FILL 0x02
-#define DRM_MODE_FB_DIRTY_FLAGS 0x03
 /* WARNING: DO NOT EDIT, AUTO-GENERATED CODE - SEE TOP FOR INSTRUCTIONS */
+#define DRM_MODE_FB_DIRTY_FLAGS 0x03
 #define DRM_MODE_FB_DIRTY_MAX_CLIPS 256
 struct drm_mode_fb_dirty_cmd {
   __u32 fb_id;
-  __u32 flags;
 /* WARNING: DO NOT EDIT, AUTO-GENERATED CODE - SEE TOP FOR INSTRUCTIONS */
+  __u32 flags;
   __u32 color;
   __u32 num_clips;
   __u64 clips_ptr;
-};
 /* WARNING: DO NOT EDIT, AUTO-GENERATED CODE - SEE TOP FOR INSTRUCTIONS */
+};
 struct drm_mode_mode_cmd {
   __u32 connector_id;
   struct drm_mode_modeinfo mode;
-};
 /* WARNING: DO NOT EDIT, AUTO-GENERATED CODE - SEE TOP FOR INSTRUCTIONS */
+};
 #define DRM_MODE_CURSOR_BO 0x01
 #define DRM_MODE_CURSOR_MOVE 0x02
 #define DRM_MODE_CURSOR_FLAGS 0x03
-struct drm_mode_cursor {
 /* WARNING: DO NOT EDIT, AUTO-GENERATED CODE - SEE TOP FOR INSTRUCTIONS */
+struct drm_mode_cursor {
   __u32 flags;
   __u32 crtc_id;
   __s32 x;
-  __s32 y;
 /* WARNING: DO NOT EDIT, AUTO-GENERATED CODE - SEE TOP FOR INSTRUCTIONS */
+  __s32 y;
   __u32 width;
   __u32 height;
   __u32 handle;
-};
 /* WARNING: DO NOT EDIT, AUTO-GENERATED CODE - SEE TOP FOR INSTRUCTIONS */
+};
 struct drm_mode_cursor2 {
   __u32 flags;
   __u32 crtc_id;
-  __s32 x;
 /* WARNING: DO NOT EDIT, AUTO-GENERATED CODE - SEE TOP FOR INSTRUCTIONS */
+  __s32 x;
   __s32 y;
   __u32 width;
   __u32 height;
-  __u32 handle;
 /* WARNING: DO NOT EDIT, AUTO-GENERATED CODE - SEE TOP FOR INSTRUCTIONS */
+  __u32 handle;
   __s32 hot_x;
   __s32 hot_y;
 };
-struct drm_mode_crtc_lut {
 /* WARNING: DO NOT EDIT, AUTO-GENERATED CODE - SEE TOP FOR INSTRUCTIONS */
+struct drm_mode_crtc_lut {
   __u32 crtc_id;
   __u32 gamma_size;
   __u64 red;
-  __u64 green;
 /* WARNING: DO NOT EDIT, AUTO-GENERATED CODE - SEE TOP FOR INSTRUCTIONS */
+  __u64 green;
   __u64 blue;
 };
 #define DRM_MODE_PAGE_FLIP_EVENT 0x01
-#define DRM_MODE_PAGE_FLIP_ASYNC 0x02
 /* WARNING: DO NOT EDIT, AUTO-GENERATED CODE - SEE TOP FOR INSTRUCTIONS */
+#define DRM_MODE_PAGE_FLIP_ASYNC 0x02
 #define DRM_MODE_PAGE_FLIP_FLAGS (DRM_MODE_PAGE_FLIP_EVENT | DRM_MODE_PAGE_FLIP_ASYNC)
 struct drm_mode_crtc_page_flip {
   __u32 crtc_id;
-  __u32 fb_id;
 /* WARNING: DO NOT EDIT, AUTO-GENERATED CODE - SEE TOP FOR INSTRUCTIONS */
+  __u32 fb_id;
   __u32 flags;
   __u32 reserved;
   __u64 user_data;
-};
 /* WARNING: DO NOT EDIT, AUTO-GENERATED CODE - SEE TOP FOR INSTRUCTIONS */
+};
 struct drm_mode_create_dumb {
   uint32_t height;
   uint32_t width;
-  uint32_t bpp;
 /* WARNING: DO NOT EDIT, AUTO-GENERATED CODE - SEE TOP FOR INSTRUCTIONS */
+  uint32_t bpp;
   uint32_t flags;
   uint32_t handle;
   uint32_t pitch;
-  uint64_t size;
 /* WARNING: DO NOT EDIT, AUTO-GENERATED CODE - SEE TOP FOR INSTRUCTIONS */
+  uint64_t size;
 };
 struct drm_mode_map_dumb {
   __u32 handle;
-  __u32 pad;
 /* WARNING: DO NOT EDIT, AUTO-GENERATED CODE - SEE TOP FOR INSTRUCTIONS */
+  __u32 pad;
   __u64 offset;
 };
 struct drm_mode_destroy_dumb {
+/* WARNING: DO NOT EDIT, AUTO-GENERATED CODE - SEE TOP FOR INSTRUCTIONS */
   uint32_t handle;
+};
+#define DRM_MODE_ATOMIC_TEST_ONLY 0x0100
+#define DRM_MODE_ATOMIC_NONBLOCK 0x0200
+/* WARNING: DO NOT EDIT, AUTO-GENERATED CODE - SEE TOP FOR INSTRUCTIONS */
+#define DRM_MODE_ATOMIC_ALLOW_MODESET 0x0400
+#define DRM_MODE_ATOMIC_FLAGS (DRM_MODE_PAGE_FLIP_EVENT | DRM_MODE_PAGE_FLIP_ASYNC | DRM_MODE_ATOMIC_TEST_ONLY | DRM_MODE_ATOMIC_NONBLOCK | DRM_MODE_ATOMIC_ALLOW_MODESET)
+struct drm_mode_atomic {
+  __u32 flags;
+/* WARNING: DO NOT EDIT, AUTO-GENERATED CODE - SEE TOP FOR INSTRUCTIONS */
+  __u32 count_objs;
+  __u64 objs_ptr;
+  __u64 count_props_ptr;
+  __u64 props_ptr;
+/* WARNING: DO NOT EDIT, AUTO-GENERATED CODE - SEE TOP FOR INSTRUCTIONS */
+  __u64 prop_values_ptr;
+  __u64 reserved;
+  __u64 user_data;
+};
+/* WARNING: DO NOT EDIT, AUTO-GENERATED CODE - SEE TOP FOR INSTRUCTIONS */
+struct drm_mode_create_blob {
+  __u64 data;
+  __u32 length;
+  __u32 blob_id;
 /* WARNING: DO NOT EDIT, AUTO-GENERATED CODE - SEE TOP FOR INSTRUCTIONS */
 };
+struct drm_mode_destroy_blob {
+  __u32 blob_id;
+};
+/* WARNING: DO NOT EDIT, AUTO-GENERATED CODE - SEE TOP FOR INSTRUCTIONS */
 #endif
diff --git a/libc/kernel/uapi/drm/i810_drm.h b/libc/kernel/uapi/drm/i810_drm.h
index ebe3332..9292a80 100644
--- a/libc/kernel/uapi/drm/i810_drm.h
+++ b/libc/kernel/uapi/drm/i810_drm.h
@@ -18,244 +18,246 @@
  ****************************************************************************/
 #ifndef _I810_DRM_H_
 #define _I810_DRM_H_
+#include <drm/drm.h>
 #ifndef _I810_DEFINES_
-#define _I810_DEFINES_
 /* WARNING: DO NOT EDIT, AUTO-GENERATED CODE - SEE TOP FOR INSTRUCTIONS */
+#define _I810_DEFINES_
 #define I810_DMA_BUF_ORDER 12
 #define I810_DMA_BUF_SZ (1 << I810_DMA_BUF_ORDER)
 #define I810_DMA_BUF_NR 256
-#define I810_NR_SAREA_CLIPRECTS 8
 /* WARNING: DO NOT EDIT, AUTO-GENERATED CODE - SEE TOP FOR INSTRUCTIONS */
+#define I810_NR_SAREA_CLIPRECTS 8
 #define I810_NR_TEX_REGIONS 64
 #define I810_LOG_MIN_TEX_REGION_SIZE 16
 #endif
-#define I810_UPLOAD_TEX0IMAGE 0x1
 /* WARNING: DO NOT EDIT, AUTO-GENERATED CODE - SEE TOP FOR INSTRUCTIONS */
+#define I810_UPLOAD_TEX0IMAGE 0x1
 #define I810_UPLOAD_TEX1IMAGE 0x2
 #define I810_UPLOAD_CTX 0x4
 #define I810_UPLOAD_BUFFERS 0x8
-#define I810_UPLOAD_TEX0 0x10
 /* WARNING: DO NOT EDIT, AUTO-GENERATED CODE - SEE TOP FOR INSTRUCTIONS */
+#define I810_UPLOAD_TEX0 0x10
 #define I810_UPLOAD_TEX1 0x20
 #define I810_UPLOAD_CLIPRECTS 0x40
 #define I810_DESTREG_DI0 0
-#define I810_DESTREG_DI1 1
 /* WARNING: DO NOT EDIT, AUTO-GENERATED CODE - SEE TOP FOR INSTRUCTIONS */
+#define I810_DESTREG_DI1 1
 #define I810_DESTREG_DV0 2
 #define I810_DESTREG_DV1 3
 #define I810_DESTREG_DR0 4
-#define I810_DESTREG_DR1 5
 /* WARNING: DO NOT EDIT, AUTO-GENERATED CODE - SEE TOP FOR INSTRUCTIONS */
+#define I810_DESTREG_DR1 5
 #define I810_DESTREG_DR2 6
 #define I810_DESTREG_DR3 7
 #define I810_DESTREG_DR4 8
-#define I810_DEST_SETUP_SIZE 10
 /* WARNING: DO NOT EDIT, AUTO-GENERATED CODE - SEE TOP FOR INSTRUCTIONS */
+#define I810_DEST_SETUP_SIZE 10
 #define I810_CTXREG_CF0 0
 #define I810_CTXREG_CF1 1
 #define I810_CTXREG_ST0 2
-#define I810_CTXREG_ST1 3
 /* WARNING: DO NOT EDIT, AUTO-GENERATED CODE - SEE TOP FOR INSTRUCTIONS */
+#define I810_CTXREG_ST1 3
 #define I810_CTXREG_VF 4
 #define I810_CTXREG_MT 5
 #define I810_CTXREG_MC0 6
-#define I810_CTXREG_MC1 7
 /* WARNING: DO NOT EDIT, AUTO-GENERATED CODE - SEE TOP FOR INSTRUCTIONS */
+#define I810_CTXREG_MC1 7
 #define I810_CTXREG_MC2 8
 #define I810_CTXREG_MA0 9
 #define I810_CTXREG_MA1 10
-#define I810_CTXREG_MA2 11
 /* WARNING: DO NOT EDIT, AUTO-GENERATED CODE - SEE TOP FOR INSTRUCTIONS */
+#define I810_CTXREG_MA2 11
 #define I810_CTXREG_SDM 12
 #define I810_CTXREG_FOG 13
 #define I810_CTXREG_B1 14
-#define I810_CTXREG_B2 15
 /* WARNING: DO NOT EDIT, AUTO-GENERATED CODE - SEE TOP FOR INSTRUCTIONS */
+#define I810_CTXREG_B2 15
 #define I810_CTXREG_LCS 16
 #define I810_CTXREG_PV 17
 #define I810_CTXREG_ZA 18
-#define I810_CTXREG_AA 19
 /* WARNING: DO NOT EDIT, AUTO-GENERATED CODE - SEE TOP FOR INSTRUCTIONS */
+#define I810_CTXREG_AA 19
 #define I810_CTX_SETUP_SIZE 20
 #define I810_TEXREG_MI0 0
 #define I810_TEXREG_MI1 1
-#define I810_TEXREG_MI2 2
 /* WARNING: DO NOT EDIT, AUTO-GENERATED CODE - SEE TOP FOR INSTRUCTIONS */
+#define I810_TEXREG_MI2 2
 #define I810_TEXREG_MI3 3
 #define I810_TEXREG_MF 4
 #define I810_TEXREG_MLC 5
-#define I810_TEXREG_MLL 6
 /* WARNING: DO NOT EDIT, AUTO-GENERATED CODE - SEE TOP FOR INSTRUCTIONS */
+#define I810_TEXREG_MLL 6
 #define I810_TEXREG_MCS 7
 #define I810_TEX_SETUP_SIZE 8
 #define I810_FRONT 0x1
-#define I810_BACK 0x2
 /* WARNING: DO NOT EDIT, AUTO-GENERATED CODE - SEE TOP FOR INSTRUCTIONS */
+#define I810_BACK 0x2
 #define I810_DEPTH 0x4
 typedef enum _drm_i810_init_func {
   I810_INIT_DMA = 0x01,
-  I810_CLEANUP_DMA = 0x02,
 /* WARNING: DO NOT EDIT, AUTO-GENERATED CODE - SEE TOP FOR INSTRUCTIONS */
+  I810_CLEANUP_DMA = 0x02,
   I810_INIT_DMA_1_4 = 0x03
 } drm_i810_init_func_t;
 typedef struct _drm_i810_init {
-  drm_i810_init_func_t func;
 /* WARNING: DO NOT EDIT, AUTO-GENERATED CODE - SEE TOP FOR INSTRUCTIONS */
+  drm_i810_init_func_t func;
   unsigned int mmio_offset;
   unsigned int buffers_offset;
   int sarea_priv_offset;
-  unsigned int ring_start;
 /* WARNING: DO NOT EDIT, AUTO-GENERATED CODE - SEE TOP FOR INSTRUCTIONS */
+  unsigned int ring_start;
   unsigned int ring_end;
   unsigned int ring_size;
   unsigned int front_offset;
-  unsigned int back_offset;
 /* WARNING: DO NOT EDIT, AUTO-GENERATED CODE - SEE TOP FOR INSTRUCTIONS */
+  unsigned int back_offset;
   unsigned int depth_offset;
   unsigned int overlay_offset;
   unsigned int overlay_physical;
-  unsigned int w;
 /* WARNING: DO NOT EDIT, AUTO-GENERATED CODE - SEE TOP FOR INSTRUCTIONS */
+  unsigned int w;
   unsigned int h;
   unsigned int pitch;
   unsigned int pitch_bits;
-} drm_i810_init_t;
 /* WARNING: DO NOT EDIT, AUTO-GENERATED CODE - SEE TOP FOR INSTRUCTIONS */
+} drm_i810_init_t;
 typedef struct _drm_i810_pre12_init {
   drm_i810_init_func_t func;
   unsigned int mmio_offset;
-  unsigned int buffers_offset;
 /* WARNING: DO NOT EDIT, AUTO-GENERATED CODE - SEE TOP FOR INSTRUCTIONS */
+  unsigned int buffers_offset;
   int sarea_priv_offset;
   unsigned int ring_start;
   unsigned int ring_end;
-  unsigned int ring_size;
 /* WARNING: DO NOT EDIT, AUTO-GENERATED CODE - SEE TOP FOR INSTRUCTIONS */
+  unsigned int ring_size;
   unsigned int front_offset;
   unsigned int back_offset;
   unsigned int depth_offset;
-  unsigned int w;
 /* WARNING: DO NOT EDIT, AUTO-GENERATED CODE - SEE TOP FOR INSTRUCTIONS */
+  unsigned int w;
   unsigned int h;
   unsigned int pitch;
   unsigned int pitch_bits;
-} drm_i810_pre12_init_t;
 /* WARNING: DO NOT EDIT, AUTO-GENERATED CODE - SEE TOP FOR INSTRUCTIONS */
+} drm_i810_pre12_init_t;
 typedef struct _drm_i810_tex_region {
   unsigned char next, prev;
   unsigned char in_use;
-  int age;
 /* WARNING: DO NOT EDIT, AUTO-GENERATED CODE - SEE TOP FOR INSTRUCTIONS */
+  int age;
 } drm_i810_tex_region_t;
 typedef struct _drm_i810_sarea {
   unsigned int ContextState[I810_CTX_SETUP_SIZE];
-  unsigned int BufferState[I810_DEST_SETUP_SIZE];
 /* WARNING: DO NOT EDIT, AUTO-GENERATED CODE - SEE TOP FOR INSTRUCTIONS */
+  unsigned int BufferState[I810_DEST_SETUP_SIZE];
   unsigned int TexState[2][I810_TEX_SETUP_SIZE];
   unsigned int dirty;
   unsigned int nbox;
-  struct drm_clip_rect boxes[I810_NR_SAREA_CLIPRECTS];
 /* WARNING: DO NOT EDIT, AUTO-GENERATED CODE - SEE TOP FOR INSTRUCTIONS */
+  struct drm_clip_rect boxes[I810_NR_SAREA_CLIPRECTS];
   drm_i810_tex_region_t texList[I810_NR_TEX_REGIONS + 1];
   int texAge;
   int last_enqueue;
-  int last_dispatch;
 /* WARNING: DO NOT EDIT, AUTO-GENERATED CODE - SEE TOP FOR INSTRUCTIONS */
+  int last_dispatch;
   int last_quiescent;
   int ctxOwner;
   int vertex_prim;
-  int pf_enabled;
 /* WARNING: DO NOT EDIT, AUTO-GENERATED CODE - SEE TOP FOR INSTRUCTIONS */
+  int pf_enabled;
   int pf_active;
   int pf_current_page;
 } drm_i810_sarea_t;
-#define DRM_I810_INIT 0x00
 /* WARNING: DO NOT EDIT, AUTO-GENERATED CODE - SEE TOP FOR INSTRUCTIONS */
+#define DRM_I810_INIT 0x00
 #define DRM_I810_VERTEX 0x01
 #define DRM_I810_CLEAR 0x02
 #define DRM_I810_FLUSH 0x03
-#define DRM_I810_GETAGE 0x04
 /* WARNING: DO NOT EDIT, AUTO-GENERATED CODE - SEE TOP FOR INSTRUCTIONS */
+#define DRM_I810_GETAGE 0x04
 #define DRM_I810_GETBUF 0x05
 #define DRM_I810_SWAP 0x06
 #define DRM_I810_COPY 0x07
-#define DRM_I810_DOCOPY 0x08
 /* WARNING: DO NOT EDIT, AUTO-GENERATED CODE - SEE TOP FOR INSTRUCTIONS */
+#define DRM_I810_DOCOPY 0x08
 #define DRM_I810_OV0INFO 0x09
 #define DRM_I810_FSTATUS 0x0a
 #define DRM_I810_OV0FLIP 0x0b
-#define DRM_I810_MC 0x0c
 /* WARNING: DO NOT EDIT, AUTO-GENERATED CODE - SEE TOP FOR INSTRUCTIONS */
+#define DRM_I810_MC 0x0c
 #define DRM_I810_RSTATUS 0x0d
 #define DRM_I810_FLIP 0x0e
 #define DRM_IOCTL_I810_INIT DRM_IOW(DRM_COMMAND_BASE + DRM_I810_INIT, drm_i810_init_t)
-#define DRM_IOCTL_I810_VERTEX DRM_IOW(DRM_COMMAND_BASE + DRM_I810_VERTEX, drm_i810_vertex_t)
 /* WARNING: DO NOT EDIT, AUTO-GENERATED CODE - SEE TOP FOR INSTRUCTIONS */
+#define DRM_IOCTL_I810_VERTEX DRM_IOW(DRM_COMMAND_BASE + DRM_I810_VERTEX, drm_i810_vertex_t)
 #define DRM_IOCTL_I810_CLEAR DRM_IOW(DRM_COMMAND_BASE + DRM_I810_CLEAR, drm_i810_clear_t)
 #define DRM_IOCTL_I810_FLUSH DRM_IO(DRM_COMMAND_BASE + DRM_I810_FLUSH)
 #define DRM_IOCTL_I810_GETAGE DRM_IO(DRM_COMMAND_BASE + DRM_I810_GETAGE)
-#define DRM_IOCTL_I810_GETBUF DRM_IOWR(DRM_COMMAND_BASE + DRM_I810_GETBUF, drm_i810_dma_t)
 /* WARNING: DO NOT EDIT, AUTO-GENERATED CODE - SEE TOP FOR INSTRUCTIONS */
+#define DRM_IOCTL_I810_GETBUF DRM_IOWR(DRM_COMMAND_BASE + DRM_I810_GETBUF, drm_i810_dma_t)
 #define DRM_IOCTL_I810_SWAP DRM_IO(DRM_COMMAND_BASE + DRM_I810_SWAP)
 #define DRM_IOCTL_I810_COPY DRM_IOW(DRM_COMMAND_BASE + DRM_I810_COPY, drm_i810_copy_t)
 #define DRM_IOCTL_I810_DOCOPY DRM_IO(DRM_COMMAND_BASE + DRM_I810_DOCOPY)
-#define DRM_IOCTL_I810_OV0INFO DRM_IOR(DRM_COMMAND_BASE + DRM_I810_OV0INFO, drm_i810_overlay_t)
 /* WARNING: DO NOT EDIT, AUTO-GENERATED CODE - SEE TOP FOR INSTRUCTIONS */
+#define DRM_IOCTL_I810_OV0INFO DRM_IOR(DRM_COMMAND_BASE + DRM_I810_OV0INFO, drm_i810_overlay_t)
 #define DRM_IOCTL_I810_FSTATUS DRM_IO(DRM_COMMAND_BASE + DRM_I810_FSTATUS)
 #define DRM_IOCTL_I810_OV0FLIP DRM_IO(DRM_COMMAND_BASE + DRM_I810_OV0FLIP)
 #define DRM_IOCTL_I810_MC DRM_IOW(DRM_COMMAND_BASE + DRM_I810_MC, drm_i810_mc_t)
-#define DRM_IOCTL_I810_RSTATUS DRM_IO(DRM_COMMAND_BASE + DRM_I810_RSTATUS)
 /* WARNING: DO NOT EDIT, AUTO-GENERATED CODE - SEE TOP FOR INSTRUCTIONS */
+#define DRM_IOCTL_I810_RSTATUS DRM_IO(DRM_COMMAND_BASE + DRM_I810_RSTATUS)
 #define DRM_IOCTL_I810_FLIP DRM_IO(DRM_COMMAND_BASE + DRM_I810_FLIP)
 typedef struct _drm_i810_clear {
   int clear_color;
-  int clear_depth;
 /* WARNING: DO NOT EDIT, AUTO-GENERATED CODE - SEE TOP FOR INSTRUCTIONS */
+  int clear_depth;
   int flags;
 } drm_i810_clear_t;
 typedef struct _drm_i810_vertex {
-  int idx;
 /* WARNING: DO NOT EDIT, AUTO-GENERATED CODE - SEE TOP FOR INSTRUCTIONS */
+  int idx;
   int used;
   int discard;
 } drm_i810_vertex_t;
-typedef struct _drm_i810_copy_t {
 /* WARNING: DO NOT EDIT, AUTO-GENERATED CODE - SEE TOP FOR INSTRUCTIONS */
+typedef struct _drm_i810_copy_t {
   int idx;
   int used;
   void * address;
-} drm_i810_copy_t;
 /* WARNING: DO NOT EDIT, AUTO-GENERATED CODE - SEE TOP FOR INSTRUCTIONS */
+} drm_i810_copy_t;
 #define PR_TRIANGLES (0x0 << 18)
 #define PR_TRISTRIP_0 (0x1 << 18)
 #define PR_TRISTRIP_1 (0x2 << 18)
-#define PR_TRIFAN (0x3 << 18)
 /* WARNING: DO NOT EDIT, AUTO-GENERATED CODE - SEE TOP FOR INSTRUCTIONS */
+#define PR_TRIFAN (0x3 << 18)
 #define PR_POLYGON (0x4 << 18)
 #define PR_LINES (0x5 << 18)
 #define PR_LINESTRIP (0x6 << 18)
-#define PR_RECTS (0x7 << 18)
 /* WARNING: DO NOT EDIT, AUTO-GENERATED CODE - SEE TOP FOR INSTRUCTIONS */
+#define PR_RECTS (0x7 << 18)
 #define PR_MASK (0x7 << 18)
 typedef struct drm_i810_dma {
   void * virtual;
-  int request_idx;
 /* WARNING: DO NOT EDIT, AUTO-GENERATED CODE - SEE TOP FOR INSTRUCTIONS */
+  int request_idx;
   int request_size;
   int granted;
 } drm_i810_dma_t;
-typedef struct _drm_i810_overlay_t {
 /* WARNING: DO NOT EDIT, AUTO-GENERATED CODE - SEE TOP FOR INSTRUCTIONS */
+typedef struct _drm_i810_overlay_t {
   unsigned int offset;
   unsigned int physical;
 } drm_i810_overlay_t;
-typedef struct _drm_i810_mc {
 /* WARNING: DO NOT EDIT, AUTO-GENERATED CODE - SEE TOP FOR INSTRUCTIONS */
+typedef struct _drm_i810_mc {
   int idx;
   int used;
   int num_blocks;
-  int * length;
 /* WARNING: DO NOT EDIT, AUTO-GENERATED CODE - SEE TOP FOR INSTRUCTIONS */
+  int * length;
   unsigned int last_render;
 } drm_i810_mc_t;
 #endif
+/* WARNING: DO NOT EDIT, AUTO-GENERATED CODE - SEE TOP FOR INSTRUCTIONS */
diff --git a/libc/kernel/uapi/drm/i915_drm.h b/libc/kernel/uapi/drm/i915_drm.h
index 3d15fec..da68576 100644
--- a/libc/kernel/uapi/drm/i915_drm.h
+++ b/libc/kernel/uapi/drm/i915_drm.h
@@ -197,68 +197,73 @@
 #define DRM_I915_GET_RESET_STATS 0x32
 /* WARNING: DO NOT EDIT, AUTO-GENERATED CODE - SEE TOP FOR INSTRUCTIONS */
 #define DRM_I915_GEM_USERPTR 0x33
+#define DRM_I915_GEM_CONTEXT_GETPARAM 0x34
+#define DRM_I915_GEM_CONTEXT_SETPARAM 0x35
 #define DRM_IOCTL_I915_INIT DRM_IOW(DRM_COMMAND_BASE + DRM_I915_INIT, drm_i915_init_t)
+/* WARNING: DO NOT EDIT, AUTO-GENERATED CODE - SEE TOP FOR INSTRUCTIONS */
 #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)
-/* WARNING: DO NOT EDIT, AUTO-GENERATED CODE - SEE TOP FOR INSTRUCTIONS */
 #define DRM_IOCTL_I915_BATCHBUFFER DRM_IOW(DRM_COMMAND_BASE + DRM_I915_BATCHBUFFER, drm_i915_batchbuffer_t)
 #define DRM_IOCTL_I915_IRQ_EMIT DRM_IOWR(DRM_COMMAND_BASE + DRM_I915_IRQ_EMIT, drm_i915_irq_emit_t)
+/* WARNING: DO NOT EDIT, AUTO-GENERATED CODE - SEE TOP FOR INSTRUCTIONS */
 #define DRM_IOCTL_I915_IRQ_WAIT DRM_IOW(DRM_COMMAND_BASE + DRM_I915_IRQ_WAIT, drm_i915_irq_wait_t)
 #define DRM_IOCTL_I915_GETPARAM DRM_IOWR(DRM_COMMAND_BASE + DRM_I915_GETPARAM, drm_i915_getparam_t)
-/* WARNING: DO NOT EDIT, AUTO-GENERATED CODE - SEE TOP FOR INSTRUCTIONS */
 #define DRM_IOCTL_I915_SETPARAM DRM_IOW(DRM_COMMAND_BASE + DRM_I915_SETPARAM, drm_i915_setparam_t)
 #define DRM_IOCTL_I915_ALLOC DRM_IOWR(DRM_COMMAND_BASE + DRM_I915_ALLOC, drm_i915_mem_alloc_t)
+/* WARNING: DO NOT EDIT, AUTO-GENERATED CODE - SEE TOP FOR INSTRUCTIONS */
 #define DRM_IOCTL_I915_FREE DRM_IOW(DRM_COMMAND_BASE + DRM_I915_FREE, drm_i915_mem_free_t)
 #define DRM_IOCTL_I915_INIT_HEAP DRM_IOW(DRM_COMMAND_BASE + DRM_I915_INIT_HEAP, drm_i915_mem_init_heap_t)
-/* WARNING: DO NOT EDIT, AUTO-GENERATED CODE - SEE TOP FOR INSTRUCTIONS */
 #define DRM_IOCTL_I915_CMDBUFFER DRM_IOW(DRM_COMMAND_BASE + DRM_I915_CMDBUFFER, drm_i915_cmdbuffer_t)
 #define DRM_IOCTL_I915_DESTROY_HEAP DRM_IOW(DRM_COMMAND_BASE + DRM_I915_DESTROY_HEAP, drm_i915_mem_destroy_heap_t)
+/* WARNING: DO NOT EDIT, AUTO-GENERATED CODE - SEE TOP FOR INSTRUCTIONS */
 #define DRM_IOCTL_I915_SET_VBLANK_PIPE DRM_IOW(DRM_COMMAND_BASE + DRM_I915_SET_VBLANK_PIPE, drm_i915_vblank_pipe_t)
 #define DRM_IOCTL_I915_GET_VBLANK_PIPE DRM_IOR(DRM_COMMAND_BASE + DRM_I915_GET_VBLANK_PIPE, drm_i915_vblank_pipe_t)
-/* WARNING: DO NOT EDIT, AUTO-GENERATED CODE - SEE TOP FOR INSTRUCTIONS */
 #define DRM_IOCTL_I915_VBLANK_SWAP DRM_IOWR(DRM_COMMAND_BASE + DRM_I915_VBLANK_SWAP, drm_i915_vblank_swap_t)
 #define DRM_IOCTL_I915_HWS_ADDR DRM_IOW(DRM_COMMAND_BASE + DRM_I915_HWS_ADDR, struct drm_i915_gem_init)
+/* WARNING: DO NOT EDIT, AUTO-GENERATED CODE - SEE TOP FOR INSTRUCTIONS */
 #define DRM_IOCTL_I915_GEM_INIT DRM_IOW(DRM_COMMAND_BASE + DRM_I915_GEM_INIT, struct drm_i915_gem_init)
 #define DRM_IOCTL_I915_GEM_EXECBUFFER DRM_IOW(DRM_COMMAND_BASE + DRM_I915_GEM_EXECBUFFER, struct drm_i915_gem_execbuffer)
-/* WARNING: DO NOT EDIT, AUTO-GENERATED CODE - SEE TOP FOR INSTRUCTIONS */
 #define DRM_IOCTL_I915_GEM_EXECBUFFER2 DRM_IOW(DRM_COMMAND_BASE + DRM_I915_GEM_EXECBUFFER2, struct drm_i915_gem_execbuffer2)
 #define DRM_IOCTL_I915_GEM_PIN DRM_IOWR(DRM_COMMAND_BASE + DRM_I915_GEM_PIN, struct drm_i915_gem_pin)
+/* WARNING: DO NOT EDIT, AUTO-GENERATED CODE - SEE TOP FOR INSTRUCTIONS */
 #define DRM_IOCTL_I915_GEM_UNPIN DRM_IOW(DRM_COMMAND_BASE + DRM_I915_GEM_UNPIN, struct drm_i915_gem_unpin)
 #define DRM_IOCTL_I915_GEM_BUSY DRM_IOWR(DRM_COMMAND_BASE + DRM_I915_GEM_BUSY, struct drm_i915_gem_busy)
-/* WARNING: DO NOT EDIT, AUTO-GENERATED CODE - SEE TOP FOR INSTRUCTIONS */
 #define DRM_IOCTL_I915_GEM_SET_CACHING DRM_IOW(DRM_COMMAND_BASE + DRM_I915_GEM_SET_CACHING, struct drm_i915_gem_caching)
 #define DRM_IOCTL_I915_GEM_GET_CACHING DRM_IOWR(DRM_COMMAND_BASE + DRM_I915_GEM_GET_CACHING, struct drm_i915_gem_caching)
+/* WARNING: DO NOT EDIT, AUTO-GENERATED CODE - SEE TOP FOR INSTRUCTIONS */
 #define DRM_IOCTL_I915_GEM_THROTTLE DRM_IO(DRM_COMMAND_BASE + DRM_I915_GEM_THROTTLE)
 #define DRM_IOCTL_I915_GEM_ENTERVT DRM_IO(DRM_COMMAND_BASE + DRM_I915_GEM_ENTERVT)
-/* WARNING: DO NOT EDIT, AUTO-GENERATED CODE - SEE TOP FOR INSTRUCTIONS */
 #define DRM_IOCTL_I915_GEM_LEAVEVT DRM_IO(DRM_COMMAND_BASE + DRM_I915_GEM_LEAVEVT)
 #define DRM_IOCTL_I915_GEM_CREATE DRM_IOWR(DRM_COMMAND_BASE + DRM_I915_GEM_CREATE, struct drm_i915_gem_create)
+/* WARNING: DO NOT EDIT, AUTO-GENERATED CODE - SEE TOP FOR INSTRUCTIONS */
 #define DRM_IOCTL_I915_GEM_PREAD DRM_IOW(DRM_COMMAND_BASE + DRM_I915_GEM_PREAD, struct drm_i915_gem_pread)
 #define DRM_IOCTL_I915_GEM_PWRITE DRM_IOW(DRM_COMMAND_BASE + DRM_I915_GEM_PWRITE, struct drm_i915_gem_pwrite)
-/* WARNING: DO NOT EDIT, AUTO-GENERATED CODE - SEE TOP FOR INSTRUCTIONS */
 #define DRM_IOCTL_I915_GEM_MMAP DRM_IOWR(DRM_COMMAND_BASE + DRM_I915_GEM_MMAP, struct drm_i915_gem_mmap)
 #define DRM_IOCTL_I915_GEM_MMAP_GTT DRM_IOWR(DRM_COMMAND_BASE + DRM_I915_GEM_MMAP_GTT, struct drm_i915_gem_mmap_gtt)
+/* WARNING: DO NOT EDIT, AUTO-GENERATED CODE - SEE TOP FOR INSTRUCTIONS */
 #define DRM_IOCTL_I915_GEM_SET_DOMAIN DRM_IOW(DRM_COMMAND_BASE + DRM_I915_GEM_SET_DOMAIN, struct drm_i915_gem_set_domain)
 #define DRM_IOCTL_I915_GEM_SW_FINISH DRM_IOW(DRM_COMMAND_BASE + DRM_I915_GEM_SW_FINISH, struct drm_i915_gem_sw_finish)
-/* WARNING: DO NOT EDIT, AUTO-GENERATED CODE - SEE TOP FOR INSTRUCTIONS */
 #define DRM_IOCTL_I915_GEM_SET_TILING DRM_IOWR(DRM_COMMAND_BASE + DRM_I915_GEM_SET_TILING, struct drm_i915_gem_set_tiling)
 #define DRM_IOCTL_I915_GEM_GET_TILING DRM_IOWR(DRM_COMMAND_BASE + DRM_I915_GEM_GET_TILING, struct drm_i915_gem_get_tiling)
+/* WARNING: DO NOT EDIT, AUTO-GENERATED CODE - SEE TOP FOR INSTRUCTIONS */
 #define DRM_IOCTL_I915_GEM_GET_APERTURE DRM_IOR(DRM_COMMAND_BASE + DRM_I915_GEM_GET_APERTURE, struct drm_i915_gem_get_aperture)
 #define DRM_IOCTL_I915_GET_PIPE_FROM_CRTC_ID DRM_IOWR(DRM_COMMAND_BASE + DRM_I915_GET_PIPE_FROM_CRTC_ID, struct drm_i915_get_pipe_from_crtc_id)
-/* WARNING: DO NOT EDIT, AUTO-GENERATED CODE - SEE TOP FOR INSTRUCTIONS */
 #define DRM_IOCTL_I915_GEM_MADVISE DRM_IOWR(DRM_COMMAND_BASE + DRM_I915_GEM_MADVISE, struct drm_i915_gem_madvise)
 #define DRM_IOCTL_I915_OVERLAY_PUT_IMAGE DRM_IOW(DRM_COMMAND_BASE + DRM_I915_OVERLAY_PUT_IMAGE, struct drm_intel_overlay_put_image)
+/* WARNING: DO NOT EDIT, AUTO-GENERATED CODE - SEE TOP FOR INSTRUCTIONS */
 #define DRM_IOCTL_I915_OVERLAY_ATTRS DRM_IOWR(DRM_COMMAND_BASE + DRM_I915_OVERLAY_ATTRS, struct drm_intel_overlay_attrs)
 #define DRM_IOCTL_I915_SET_SPRITE_COLORKEY DRM_IOWR(DRM_COMMAND_BASE + DRM_I915_SET_SPRITE_COLORKEY, struct drm_intel_sprite_colorkey)
-/* WARNING: DO NOT EDIT, AUTO-GENERATED CODE - SEE TOP FOR INSTRUCTIONS */
-#define DRM_IOCTL_I915_GET_SPRITE_COLORKEY DRM_IOWR(DRM_COMMAND_BASE + DRM_I915_SET_SPRITE_COLORKEY, struct drm_intel_sprite_colorkey)
+#define DRM_IOCTL_I915_GET_SPRITE_COLORKEY DRM_IOWR(DRM_COMMAND_BASE + DRM_I915_GET_SPRITE_COLORKEY, struct drm_intel_sprite_colorkey)
 #define DRM_IOCTL_I915_GEM_WAIT DRM_IOWR(DRM_COMMAND_BASE + DRM_I915_GEM_WAIT, struct drm_i915_gem_wait)
+/* WARNING: DO NOT EDIT, AUTO-GENERATED CODE - SEE TOP FOR INSTRUCTIONS */
 #define DRM_IOCTL_I915_GEM_CONTEXT_CREATE DRM_IOWR(DRM_COMMAND_BASE + DRM_I915_GEM_CONTEXT_CREATE, struct drm_i915_gem_context_create)
 #define DRM_IOCTL_I915_GEM_CONTEXT_DESTROY DRM_IOW(DRM_COMMAND_BASE + DRM_I915_GEM_CONTEXT_DESTROY, struct drm_i915_gem_context_destroy)
-/* WARNING: DO NOT EDIT, AUTO-GENERATED CODE - SEE TOP FOR INSTRUCTIONS */
 #define DRM_IOCTL_I915_REG_READ DRM_IOWR(DRM_COMMAND_BASE + DRM_I915_REG_READ, struct drm_i915_reg_read)
 #define DRM_IOCTL_I915_GET_RESET_STATS DRM_IOWR(DRM_COMMAND_BASE + DRM_I915_GET_RESET_STATS, struct drm_i915_reset_stats)
+/* WARNING: DO NOT EDIT, AUTO-GENERATED CODE - SEE TOP FOR INSTRUCTIONS */
 #define DRM_IOCTL_I915_GEM_USERPTR DRM_IOWR(DRM_COMMAND_BASE + DRM_I915_GEM_USERPTR, struct drm_i915_gem_userptr)
+#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)
 typedef struct drm_i915_batchbuffer {
 /* WARNING: DO NOT EDIT, AUTO-GENERATED CODE - SEE TOP FOR INSTRUCTIONS */
   int start;
@@ -322,8 +327,18 @@
 #define I915_PARAM_HAS_WT 27
 /* WARNING: DO NOT EDIT, AUTO-GENERATED CODE - SEE TOP FOR INSTRUCTIONS */
 #define I915_PARAM_CMD_PARSER_VERSION 28
+#define I915_PARAM_HAS_COHERENT_PHYS_GTT 29
+#define I915_PARAM_MMAP_VERSION 30
+#define I915_PARAM_HAS_BSD2 31
+/* WARNING: DO NOT EDIT, AUTO-GENERATED CODE - SEE TOP FOR INSTRUCTIONS */
+#define I915_PARAM_REVISION 32
+#define I915_PARAM_SUBSLICE_TOTAL 33
+#define I915_PARAM_EU_TOTAL 34
+#define I915_PARAM_HAS_GPU_RESET 35
+/* WARNING: DO NOT EDIT, AUTO-GENERATED CODE - SEE TOP FOR INSTRUCTIONS */
+#define I915_PARAM_HAS_RESOURCE_STREAMER 36
 typedef struct drm_i915_getparam {
-  int param;
+  __s32 param;
   int __user * value;
 /* WARNING: DO NOT EDIT, AUTO-GENERATED CODE - SEE TOP FOR INSTRUCTIONS */
 } drm_i915_getparam_t;
@@ -413,117 +428,127 @@
 /* WARNING: DO NOT EDIT, AUTO-GENERATED CODE - SEE TOP FOR INSTRUCTIONS */
   __u64 size;
   __u64 addr_ptr;
+  __u64 flags;
+#define I915_MMAP_WC 0x1
+/* WARNING: DO NOT EDIT, AUTO-GENERATED CODE - SEE TOP FOR INSTRUCTIONS */
 };
 struct drm_i915_gem_mmap_gtt {
-/* WARNING: DO NOT EDIT, AUTO-GENERATED CODE - SEE TOP FOR INSTRUCTIONS */
   __u32 handle;
   __u32 pad;
+/* WARNING: DO NOT EDIT, AUTO-GENERATED CODE - SEE TOP FOR INSTRUCTIONS */
   __u64 offset;
 };
-/* WARNING: DO NOT EDIT, AUTO-GENERATED CODE - SEE TOP FOR INSTRUCTIONS */
 struct drm_i915_gem_set_domain {
   __u32 handle;
+/* WARNING: DO NOT EDIT, AUTO-GENERATED CODE - SEE TOP FOR INSTRUCTIONS */
   __u32 read_domains;
   __u32 write_domain;
-/* WARNING: DO NOT EDIT, AUTO-GENERATED CODE - SEE TOP FOR INSTRUCTIONS */
 };
 struct drm_i915_gem_sw_finish {
+/* WARNING: DO NOT EDIT, AUTO-GENERATED CODE - SEE TOP FOR INSTRUCTIONS */
   __u32 handle;
 };
-/* WARNING: DO NOT EDIT, AUTO-GENERATED CODE - SEE TOP FOR INSTRUCTIONS */
 struct drm_i915_gem_relocation_entry {
   __u32 target_handle;
+/* WARNING: DO NOT EDIT, AUTO-GENERATED CODE - SEE TOP FOR INSTRUCTIONS */
   __u32 delta;
   __u64 offset;
-/* WARNING: DO NOT EDIT, AUTO-GENERATED CODE - SEE TOP FOR INSTRUCTIONS */
   __u64 presumed_offset;
   __u32 read_domains;
+/* WARNING: DO NOT EDIT, AUTO-GENERATED CODE - SEE TOP FOR INSTRUCTIONS */
   __u32 write_domain;
 };
-/* WARNING: DO NOT EDIT, AUTO-GENERATED CODE - SEE TOP FOR INSTRUCTIONS */
 #define I915_GEM_DOMAIN_CPU 0x00000001
 #define I915_GEM_DOMAIN_RENDER 0x00000002
+/* WARNING: DO NOT EDIT, AUTO-GENERATED CODE - SEE TOP FOR INSTRUCTIONS */
 #define I915_GEM_DOMAIN_SAMPLER 0x00000004
 #define I915_GEM_DOMAIN_COMMAND 0x00000008
-/* WARNING: DO NOT EDIT, AUTO-GENERATED CODE - SEE TOP FOR INSTRUCTIONS */
 #define I915_GEM_DOMAIN_INSTRUCTION 0x00000010
 #define I915_GEM_DOMAIN_VERTEX 0x00000020
+/* WARNING: DO NOT EDIT, AUTO-GENERATED CODE - SEE TOP FOR INSTRUCTIONS */
 #define I915_GEM_DOMAIN_GTT 0x00000040
 struct drm_i915_gem_exec_object {
-/* WARNING: DO NOT EDIT, AUTO-GENERATED CODE - SEE TOP FOR INSTRUCTIONS */
   __u32 handle;
   __u32 relocation_count;
+/* WARNING: DO NOT EDIT, AUTO-GENERATED CODE - SEE TOP FOR INSTRUCTIONS */
   __u64 relocs_ptr;
   __u64 alignment;
-/* WARNING: DO NOT EDIT, AUTO-GENERATED CODE - SEE TOP FOR INSTRUCTIONS */
   __u64 offset;
 };
+/* WARNING: DO NOT EDIT, AUTO-GENERATED CODE - SEE TOP FOR INSTRUCTIONS */
 struct drm_i915_gem_execbuffer {
   __u64 buffers_ptr;
-/* WARNING: DO NOT EDIT, AUTO-GENERATED CODE - SEE TOP FOR INSTRUCTIONS */
   __u32 buffer_count;
   __u32 batch_start_offset;
+/* WARNING: DO NOT EDIT, AUTO-GENERATED CODE - SEE TOP FOR INSTRUCTIONS */
   __u32 batch_len;
   __u32 DR1;
-/* WARNING: DO NOT EDIT, AUTO-GENERATED CODE - SEE TOP FOR INSTRUCTIONS */
   __u32 DR4;
   __u32 num_cliprects;
+/* WARNING: DO NOT EDIT, AUTO-GENERATED CODE - SEE TOP FOR INSTRUCTIONS */
   __u64 cliprects_ptr;
 };
-/* WARNING: DO NOT EDIT, AUTO-GENERATED CODE - SEE TOP FOR INSTRUCTIONS */
 struct drm_i915_gem_exec_object2 {
   __u32 handle;
+/* WARNING: DO NOT EDIT, AUTO-GENERATED CODE - SEE TOP FOR INSTRUCTIONS */
   __u32 relocation_count;
   __u64 relocs_ptr;
-/* WARNING: DO NOT EDIT, AUTO-GENERATED CODE - SEE TOP FOR INSTRUCTIONS */
   __u64 alignment;
   __u64 offset;
+/* WARNING: DO NOT EDIT, AUTO-GENERATED CODE - SEE TOP FOR INSTRUCTIONS */
 #define EXEC_OBJECT_NEEDS_FENCE (1 << 0)
 #define EXEC_OBJECT_NEEDS_GTT (1 << 1)
-/* WARNING: DO NOT EDIT, AUTO-GENERATED CODE - SEE TOP FOR INSTRUCTIONS */
 #define EXEC_OBJECT_WRITE (1 << 2)
-#define __EXEC_OBJECT_UNKNOWN_FLAGS - (EXEC_OBJECT_WRITE << 1)
+#define EXEC_OBJECT_SUPPORTS_48B_ADDRESS (1 << 3)
+/* WARNING: DO NOT EDIT, AUTO-GENERATED CODE - SEE TOP FOR INSTRUCTIONS */
+#define __EXEC_OBJECT_UNKNOWN_FLAGS - (EXEC_OBJECT_SUPPORTS_48B_ADDRESS << 1)
   __u64 flags;
   __u64 rsvd1;
-/* WARNING: DO NOT EDIT, AUTO-GENERATED CODE - SEE TOP FOR INSTRUCTIONS */
   __u64 rsvd2;
+/* WARNING: DO NOT EDIT, AUTO-GENERATED CODE - SEE TOP FOR INSTRUCTIONS */
 };
 struct drm_i915_gem_execbuffer2 {
   __u64 buffers_ptr;
-/* WARNING: DO NOT EDIT, AUTO-GENERATED CODE - SEE TOP FOR INSTRUCTIONS */
   __u32 buffer_count;
+/* WARNING: DO NOT EDIT, AUTO-GENERATED CODE - SEE TOP FOR INSTRUCTIONS */
   __u32 batch_start_offset;
   __u32 batch_len;
   __u32 DR1;
-/* WARNING: DO NOT EDIT, AUTO-GENERATED CODE - SEE TOP FOR INSTRUCTIONS */
   __u32 DR4;
+/* WARNING: DO NOT EDIT, AUTO-GENERATED CODE - SEE TOP FOR INSTRUCTIONS */
   __u32 num_cliprects;
   __u64 cliprects_ptr;
 #define I915_EXEC_RING_MASK (7 << 0)
-/* WARNING: DO NOT EDIT, AUTO-GENERATED CODE - SEE TOP FOR INSTRUCTIONS */
 #define I915_EXEC_DEFAULT (0 << 0)
+/* WARNING: DO NOT EDIT, AUTO-GENERATED CODE - SEE TOP FOR INSTRUCTIONS */
 #define I915_EXEC_RENDER (1 << 0)
 #define I915_EXEC_BSD (2 << 0)
 #define I915_EXEC_BLT (3 << 0)
-/* WARNING: DO NOT EDIT, AUTO-GENERATED CODE - SEE TOP FOR INSTRUCTIONS */
 #define I915_EXEC_VEBOX (4 << 0)
+/* WARNING: DO NOT EDIT, AUTO-GENERATED CODE - SEE TOP FOR INSTRUCTIONS */
 #define I915_EXEC_CONSTANTS_MASK (3 << 6)
 #define I915_EXEC_CONSTANTS_REL_GENERAL (0 << 6)
 #define I915_EXEC_CONSTANTS_ABSOLUTE (1 << 6)
-/* WARNING: DO NOT EDIT, AUTO-GENERATED CODE - SEE TOP FOR INSTRUCTIONS */
 #define I915_EXEC_CONSTANTS_REL_SURFACE (2 << 6)
+/* WARNING: DO NOT EDIT, AUTO-GENERATED CODE - SEE TOP FOR INSTRUCTIONS */
   __u64 flags;
   __u64 rsvd1;
   __u64 rsvd2;
-/* WARNING: DO NOT EDIT, AUTO-GENERATED CODE - SEE TOP FOR INSTRUCTIONS */
 };
+/* WARNING: DO NOT EDIT, AUTO-GENERATED CODE - SEE TOP FOR INSTRUCTIONS */
 #define I915_EXEC_GEN7_SOL_RESET (1 << 8)
 #define I915_EXEC_SECURE (1 << 9)
 #define I915_EXEC_IS_PINNED (1 << 10)
-/* WARNING: DO NOT EDIT, AUTO-GENERATED CODE - SEE TOP FOR INSTRUCTIONS */
 #define I915_EXEC_NO_RELOC (1 << 11)
+/* WARNING: DO NOT EDIT, AUTO-GENERATED CODE - SEE TOP FOR INSTRUCTIONS */
 #define I915_EXEC_HANDLE_LUT (1 << 12)
-#define __I915_EXEC_UNKNOWN_FLAGS - (I915_EXEC_HANDLE_LUT << 1)
+#define I915_EXEC_BSD_MASK (3 << 13)
+#define I915_EXEC_BSD_DEFAULT (0 << 13)
+#define I915_EXEC_BSD_RING1 (1 << 13)
+/* WARNING: DO NOT EDIT, AUTO-GENERATED CODE - SEE TOP FOR INSTRUCTIONS */
+#define I915_EXEC_BSD_RING2 (2 << 13)
+#define I915_EXEC_RESOURCE_STREAMER (1 << 15)
+#define __I915_EXEC_UNKNOWN_FLAGS - (I915_EXEC_RESOURCE_STREAMER << 1)
 #define I915_EXEC_CONTEXT_ID_MASK (0xffffffff)
 /* WARNING: DO NOT EDIT, AUTO-GENERATED CODE - SEE TOP FOR INSTRUCTIONS */
 #define i915_execbuffer2_set_context_id(eb2,context) (eb2).rsvd1 = context & I915_EXEC_CONTEXT_ID_MASK
@@ -581,144 +606,156 @@
   __u32 tiling_mode;
   __u32 swizzle_mode;
 /* WARNING: DO NOT EDIT, AUTO-GENERATED CODE - SEE TOP FOR INSTRUCTIONS */
+  __u32 phys_swizzle_mode;
 };
 struct drm_i915_gem_get_aperture {
   __u64 aper_size;
-  __u64 aper_available_size;
 /* WARNING: DO NOT EDIT, AUTO-GENERATED CODE - SEE TOP FOR INSTRUCTIONS */
+  __u64 aper_available_size;
 };
 struct drm_i915_get_pipe_from_crtc_id {
   __u32 crtc_id;
-  __u32 pipe;
 /* WARNING: DO NOT EDIT, AUTO-GENERATED CODE - SEE TOP FOR INSTRUCTIONS */
+  __u32 pipe;
 };
 #define I915_MADV_WILLNEED 0
 #define I915_MADV_DONTNEED 1
-#define __I915_MADV_PURGED 2
 /* WARNING: DO NOT EDIT, AUTO-GENERATED CODE - SEE TOP FOR INSTRUCTIONS */
+#define __I915_MADV_PURGED 2
 struct drm_i915_gem_madvise {
   __u32 handle;
   __u32 madv;
-  __u32 retained;
 /* WARNING: DO NOT EDIT, AUTO-GENERATED CODE - SEE TOP FOR INSTRUCTIONS */
+  __u32 retained;
 };
 #define I915_OVERLAY_TYPE_MASK 0xff
 #define I915_OVERLAY_YUV_PLANAR 0x01
-#define I915_OVERLAY_YUV_PACKED 0x02
 /* WARNING: DO NOT EDIT, AUTO-GENERATED CODE - SEE TOP FOR INSTRUCTIONS */
+#define I915_OVERLAY_YUV_PACKED 0x02
 #define I915_OVERLAY_RGB 0x03
 #define I915_OVERLAY_DEPTH_MASK 0xff00
 #define I915_OVERLAY_RGB24 0x1000
-#define I915_OVERLAY_RGB16 0x2000
 /* WARNING: DO NOT EDIT, AUTO-GENERATED CODE - SEE TOP FOR INSTRUCTIONS */
+#define I915_OVERLAY_RGB16 0x2000
 #define I915_OVERLAY_RGB15 0x3000
 #define I915_OVERLAY_YUV422 0x0100
 #define I915_OVERLAY_YUV411 0x0200
-#define I915_OVERLAY_YUV420 0x0300
 /* WARNING: DO NOT EDIT, AUTO-GENERATED CODE - SEE TOP FOR INSTRUCTIONS */
+#define I915_OVERLAY_YUV420 0x0300
 #define I915_OVERLAY_YUV410 0x0400
 #define I915_OVERLAY_SWAP_MASK 0xff0000
 #define I915_OVERLAY_NO_SWAP 0x000000
-#define I915_OVERLAY_UV_SWAP 0x010000
 /* WARNING: DO NOT EDIT, AUTO-GENERATED CODE - SEE TOP FOR INSTRUCTIONS */
+#define I915_OVERLAY_UV_SWAP 0x010000
 #define I915_OVERLAY_Y_SWAP 0x020000
 #define I915_OVERLAY_Y_AND_UV_SWAP 0x030000
 #define I915_OVERLAY_FLAGS_MASK 0xff000000
-#define I915_OVERLAY_ENABLE 0x01000000
 /* WARNING: DO NOT EDIT, AUTO-GENERATED CODE - SEE TOP FOR INSTRUCTIONS */
+#define I915_OVERLAY_ENABLE 0x01000000
 struct drm_intel_overlay_put_image {
   __u32 flags;
   __u32 bo_handle;
-  __u16 stride_Y;
 /* WARNING: DO NOT EDIT, AUTO-GENERATED CODE - SEE TOP FOR INSTRUCTIONS */
+  __u16 stride_Y;
   __u16 stride_UV;
   __u32 offset_Y;
   __u32 offset_U;
-  __u32 offset_V;
 /* WARNING: DO NOT EDIT, AUTO-GENERATED CODE - SEE TOP FOR INSTRUCTIONS */
+  __u32 offset_V;
   __u16 src_width;
   __u16 src_height;
   __u16 src_scan_width;
-  __u16 src_scan_height;
 /* WARNING: DO NOT EDIT, AUTO-GENERATED CODE - SEE TOP FOR INSTRUCTIONS */
+  __u16 src_scan_height;
   __u32 crtc_id;
   __u16 dst_x;
   __u16 dst_y;
-  __u16 dst_width;
 /* WARNING: DO NOT EDIT, AUTO-GENERATED CODE - SEE TOP FOR INSTRUCTIONS */
+  __u16 dst_width;
   __u16 dst_height;
 };
 #define I915_OVERLAY_UPDATE_ATTRS (1 << 0)
-#define I915_OVERLAY_UPDATE_GAMMA (1 << 1)
 /* WARNING: DO NOT EDIT, AUTO-GENERATED CODE - SEE TOP FOR INSTRUCTIONS */
+#define I915_OVERLAY_UPDATE_GAMMA (1 << 1)
+#define I915_OVERLAY_DISABLE_DEST_COLORKEY (1 << 2)
 struct drm_intel_overlay_attrs {
   __u32 flags;
+/* WARNING: DO NOT EDIT, AUTO-GENERATED CODE - SEE TOP FOR INSTRUCTIONS */
   __u32 color_key;
   __s32 brightness;
-/* WARNING: DO NOT EDIT, AUTO-GENERATED CODE - SEE TOP FOR INSTRUCTIONS */
   __u32 contrast;
   __u32 saturation;
+/* WARNING: DO NOT EDIT, AUTO-GENERATED CODE - SEE TOP FOR INSTRUCTIONS */
   __u32 gamma0;
   __u32 gamma1;
-/* WARNING: DO NOT EDIT, AUTO-GENERATED CODE - SEE TOP FOR INSTRUCTIONS */
   __u32 gamma2;
   __u32 gamma3;
+/* WARNING: DO NOT EDIT, AUTO-GENERATED CODE - SEE TOP FOR INSTRUCTIONS */
   __u32 gamma4;
   __u32 gamma5;
-/* WARNING: DO NOT EDIT, AUTO-GENERATED CODE - SEE TOP FOR INSTRUCTIONS */
 };
 #define I915_SET_COLORKEY_NONE (1 << 0)
+/* WARNING: DO NOT EDIT, AUTO-GENERATED CODE - SEE TOP FOR INSTRUCTIONS */
 #define I915_SET_COLORKEY_DESTINATION (1 << 1)
 #define I915_SET_COLORKEY_SOURCE (1 << 2)
-/* WARNING: DO NOT EDIT, AUTO-GENERATED CODE - SEE TOP FOR INSTRUCTIONS */
 struct drm_intel_sprite_colorkey {
   __u32 plane_id;
+/* WARNING: DO NOT EDIT, AUTO-GENERATED CODE - SEE TOP FOR INSTRUCTIONS */
   __u32 min_value;
   __u32 channel_mask;
-/* WARNING: DO NOT EDIT, AUTO-GENERATED CODE - SEE TOP FOR INSTRUCTIONS */
   __u32 max_value;
   __u32 flags;
+/* WARNING: DO NOT EDIT, AUTO-GENERATED CODE - SEE TOP FOR INSTRUCTIONS */
 };
 struct drm_i915_gem_wait {
-/* WARNING: DO NOT EDIT, AUTO-GENERATED CODE - SEE TOP FOR INSTRUCTIONS */
   __u32 bo_handle;
   __u32 flags;
+/* WARNING: DO NOT EDIT, AUTO-GENERATED CODE - SEE TOP FOR INSTRUCTIONS */
   __s64 timeout_ns;
 };
-/* WARNING: DO NOT EDIT, AUTO-GENERATED CODE - SEE TOP FOR INSTRUCTIONS */
 struct drm_i915_gem_context_create {
   __u32 ctx_id;
+/* WARNING: DO NOT EDIT, AUTO-GENERATED CODE - SEE TOP FOR INSTRUCTIONS */
   __u32 pad;
 };
-/* WARNING: DO NOT EDIT, AUTO-GENERATED CODE - SEE TOP FOR INSTRUCTIONS */
 struct drm_i915_gem_context_destroy {
   __u32 ctx_id;
+/* WARNING: DO NOT EDIT, AUTO-GENERATED CODE - SEE TOP FOR INSTRUCTIONS */
   __u32 pad;
 };
-/* WARNING: DO NOT EDIT, AUTO-GENERATED CODE - SEE TOP FOR INSTRUCTIONS */
 struct drm_i915_reg_read {
   __u64 offset;
+/* WARNING: DO NOT EDIT, AUTO-GENERATED CODE - SEE TOP FOR INSTRUCTIONS */
   __u64 val;
 };
-/* WARNING: DO NOT EDIT, AUTO-GENERATED CODE - SEE TOP FOR INSTRUCTIONS */
 struct drm_i915_reset_stats {
   __u32 ctx_id;
+/* WARNING: DO NOT EDIT, AUTO-GENERATED CODE - SEE TOP FOR INSTRUCTIONS */
   __u32 flags;
   __u32 reset_count;
-/* WARNING: DO NOT EDIT, AUTO-GENERATED CODE - SEE TOP FOR INSTRUCTIONS */
   __u32 batch_active;
   __u32 batch_pending;
+/* WARNING: DO NOT EDIT, AUTO-GENERATED CODE - SEE TOP FOR INSTRUCTIONS */
   __u32 pad;
 };
-/* WARNING: DO NOT EDIT, AUTO-GENERATED CODE - SEE TOP FOR INSTRUCTIONS */
 struct drm_i915_gem_userptr {
   __u64 user_ptr;
+/* WARNING: DO NOT EDIT, AUTO-GENERATED CODE - SEE TOP FOR INSTRUCTIONS */
   __u64 user_size;
   __u32 flags;
-/* WARNING: DO NOT EDIT, AUTO-GENERATED CODE - SEE TOP FOR INSTRUCTIONS */
 #define I915_USERPTR_READ_ONLY 0x1
 #define I915_USERPTR_UNSYNCHRONIZED 0x80000000
+/* WARNING: DO NOT EDIT, AUTO-GENERATED CODE - SEE TOP FOR INSTRUCTIONS */
   __u32 handle;
 };
+struct drm_i915_gem_context_param {
+  __u32 ctx_id;
 /* WARNING: DO NOT EDIT, AUTO-GENERATED CODE - SEE TOP FOR INSTRUCTIONS */
+  __u32 size;
+  __u64 param;
+#define I915_CONTEXT_PARAM_BAN_PERIOD 0x1
+#define I915_CONTEXT_PARAM_NO_ZEROMAP 0x2
+/* WARNING: DO NOT EDIT, AUTO-GENERATED CODE - SEE TOP FOR INSTRUCTIONS */
+  __u64 value;
+};
 #endif
diff --git a/libc/kernel/uapi/drm/msm_drm.h b/libc/kernel/uapi/drm/msm_drm.h
index 8db4b0d..069fd01 100644
--- a/libc/kernel/uapi/drm/msm_drm.h
+++ b/libc/kernel/uapi/drm/msm_drm.h
@@ -27,8 +27,8 @@
 #define MSM_PIPE_3D0 0x10
 /* WARNING: DO NOT EDIT, AUTO-GENERATED CODE - SEE TOP FOR INSTRUCTIONS */
 struct drm_msm_timespec {
-  int64_t tv_sec;
-  int64_t tv_nsec;
+  __s64 tv_sec;
+  __s64 tv_nsec;
 };
 /* WARNING: DO NOT EDIT, AUTO-GENERATED CODE - SEE TOP FOR INSTRUCTIONS */
 #define MSM_PARAM_GPU_ID 0x01
@@ -36,9 +36,9 @@
 #define MSM_PARAM_CHIP_ID 0x03
 struct drm_msm_param {
 /* WARNING: DO NOT EDIT, AUTO-GENERATED CODE - SEE TOP FOR INSTRUCTIONS */
-  uint32_t pipe;
-  uint32_t param;
-  uint64_t value;
+  __u32 pipe;
+  __u32 param;
+  __u64 value;
 };
 /* WARNING: DO NOT EDIT, AUTO-GENERATED CODE - SEE TOP FOR INSTRUCTIONS */
 #define MSM_BO_SCANOUT 0x00000001
@@ -51,15 +51,15 @@
 #define MSM_BO_FLAGS (MSM_BO_SCANOUT | MSM_BO_GPU_READONLY | MSM_BO_CACHED | MSM_BO_WC | MSM_BO_UNCACHED)
 struct drm_msm_gem_new {
 /* WARNING: DO NOT EDIT, AUTO-GENERATED CODE - SEE TOP FOR INSTRUCTIONS */
-  uint64_t size;
-  uint32_t flags;
-  uint32_t handle;
+  __u64 size;
+  __u32 flags;
+  __u32 handle;
 };
 /* WARNING: DO NOT EDIT, AUTO-GENERATED CODE - SEE TOP FOR INSTRUCTIONS */
 struct drm_msm_gem_info {
-  uint32_t handle;
-  uint32_t pad;
-  uint64_t offset;
+  __u32 handle;
+  __u32 pad;
+  __u64 offset;
 /* WARNING: DO NOT EDIT, AUTO-GENERATED CODE - SEE TOP FOR INSTRUCTIONS */
 };
 #define MSM_PREP_READ 0x01
@@ -68,22 +68,22 @@
 /* WARNING: DO NOT EDIT, AUTO-GENERATED CODE - SEE TOP FOR INSTRUCTIONS */
 #define MSM_PREP_FLAGS (MSM_PREP_READ | MSM_PREP_WRITE | MSM_PREP_NOSYNC)
 struct drm_msm_gem_cpu_prep {
-  uint32_t handle;
-  uint32_t op;
+  __u32 handle;
+  __u32 op;
 /* WARNING: DO NOT EDIT, AUTO-GENERATED CODE - SEE TOP FOR INSTRUCTIONS */
   struct drm_msm_timespec timeout;
 };
 struct drm_msm_gem_cpu_fini {
-  uint32_t handle;
+  __u32 handle;
 /* WARNING: DO NOT EDIT, AUTO-GENERATED CODE - SEE TOP FOR INSTRUCTIONS */
 };
 struct drm_msm_gem_submit_reloc {
-  uint32_t submit_offset;
-  uint32_t or;
+  __u32 submit_offset;
+  __u32 or;
 /* WARNING: DO NOT EDIT, AUTO-GENERATED CODE - SEE TOP FOR INSTRUCTIONS */
-  int32_t shift;
-  uint32_t reloc_idx;
-  uint64_t reloc_offset;
+  __s32 shift;
+  __u32 reloc_idx;
+  __u64 reloc_offset;
 };
 /* WARNING: DO NOT EDIT, AUTO-GENERATED CODE - SEE TOP FOR INSTRUCTIONS */
 #define MSM_SUBMIT_CMD_BUF 0x0001
@@ -91,14 +91,14 @@
 #define MSM_SUBMIT_CMD_CTX_RESTORE_BUF 0x0003
 struct drm_msm_gem_submit_cmd {
 /* WARNING: DO NOT EDIT, AUTO-GENERATED CODE - SEE TOP FOR INSTRUCTIONS */
-  uint32_t type;
-  uint32_t submit_idx;
-  uint32_t submit_offset;
-  uint32_t size;
+  __u32 type;
+  __u32 submit_idx;
+  __u32 submit_offset;
+  __u32 size;
 /* WARNING: DO NOT EDIT, AUTO-GENERATED CODE - SEE TOP FOR INSTRUCTIONS */
-  uint32_t pad;
-  uint32_t nr_relocs;
-  uint64_t __user relocs;
+  __u32 pad;
+  __u32 nr_relocs;
+  __u64 __user relocs;
 };
 /* WARNING: DO NOT EDIT, AUTO-GENERATED CODE - SEE TOP FOR INSTRUCTIONS */
 #define MSM_SUBMIT_BO_READ 0x0001
@@ -106,24 +106,24 @@
 #define MSM_SUBMIT_BO_FLAGS (MSM_SUBMIT_BO_READ | MSM_SUBMIT_BO_WRITE)
 struct drm_msm_gem_submit_bo {
 /* WARNING: DO NOT EDIT, AUTO-GENERATED CODE - SEE TOP FOR INSTRUCTIONS */
-  uint32_t flags;
-  uint32_t handle;
-  uint64_t presumed;
+  __u32 flags;
+  __u32 handle;
+  __u64 presumed;
 };
 /* WARNING: DO NOT EDIT, AUTO-GENERATED CODE - SEE TOP FOR INSTRUCTIONS */
 struct drm_msm_gem_submit {
-  uint32_t pipe;
-  uint32_t fence;
-  uint32_t nr_bos;
+  __u32 pipe;
+  __u32 fence;
+  __u32 nr_bos;
 /* WARNING: DO NOT EDIT, AUTO-GENERATED CODE - SEE TOP FOR INSTRUCTIONS */
-  uint32_t nr_cmds;
-  uint64_t __user bos;
-  uint64_t __user cmds;
+  __u32 nr_cmds;
+  __u64 __user bos;
+  __u64 __user cmds;
 };
 /* WARNING: DO NOT EDIT, AUTO-GENERATED CODE - SEE TOP FOR INSTRUCTIONS */
 struct drm_msm_wait_fence {
-  uint32_t fence;
-  uint32_t pad;
+  __u32 fence;
+  __u32 pad;
   struct drm_msm_timespec timeout;
 /* WARNING: DO NOT EDIT, AUTO-GENERATED CODE - SEE TOP FOR INSTRUCTIONS */
 };
diff --git a/libc/kernel/uapi/drm/nouveau_drm.h b/libc/kernel/uapi/drm/nouveau_drm.h
index 29248a0..38ee589 100644
--- a/libc/kernel/uapi/drm/nouveau_drm.h
+++ b/libc/kernel/uapi/drm/nouveau_drm.h
@@ -19,131 +19,128 @@
 #ifndef __NOUVEAU_DRM_H__
 #define __NOUVEAU_DRM_H__
 #define DRM_NOUVEAU_EVENT_NVIF 0x80000000
-#define NOUVEAU_ABI16_CLIENT 0xffffffff
-/* WARNING: DO NOT EDIT, AUTO-GENERATED CODE - SEE TOP FOR INSTRUCTIONS */
-#define NOUVEAU_ABI16_DEVICE 0xdddddddd
-#define NOUVEAU_ABI16_CHAN(n) (0xcccc0000 | (n))
 #define NOUVEAU_GEM_DOMAIN_CPU (1 << 0)
-#define NOUVEAU_GEM_DOMAIN_VRAM (1 << 1)
 /* WARNING: DO NOT EDIT, AUTO-GENERATED CODE - SEE TOP FOR INSTRUCTIONS */
+#define NOUVEAU_GEM_DOMAIN_VRAM (1 << 1)
 #define NOUVEAU_GEM_DOMAIN_GART (1 << 2)
 #define NOUVEAU_GEM_DOMAIN_MAPPABLE (1 << 3)
+#define NOUVEAU_GEM_DOMAIN_COHERENT (1 << 4)
+/* WARNING: DO NOT EDIT, AUTO-GENERATED CODE - SEE TOP FOR INSTRUCTIONS */
 #define NOUVEAU_GEM_TILE_COMP 0x00030000
 #define NOUVEAU_GEM_TILE_LAYOUT_MASK 0x0000ff00
-/* WARNING: DO NOT EDIT, AUTO-GENERATED CODE - SEE TOP FOR INSTRUCTIONS */
 #define NOUVEAU_GEM_TILE_16BPP 0x00000001
 #define NOUVEAU_GEM_TILE_32BPP 0x00000002
+/* WARNING: DO NOT EDIT, AUTO-GENERATED CODE - SEE TOP FOR INSTRUCTIONS */
 #define NOUVEAU_GEM_TILE_ZETA 0x00000004
 #define NOUVEAU_GEM_TILE_NONCONTIG 0x00000008
-/* WARNING: DO NOT EDIT, AUTO-GENERATED CODE - SEE TOP FOR INSTRUCTIONS */
 struct drm_nouveau_gem_info {
   uint32_t handle;
+/* WARNING: DO NOT EDIT, AUTO-GENERATED CODE - SEE TOP FOR INSTRUCTIONS */
   uint32_t domain;
   uint64_t size;
-/* WARNING: DO NOT EDIT, AUTO-GENERATED CODE - SEE TOP FOR INSTRUCTIONS */
   uint64_t offset;
   uint64_t map_handle;
+/* WARNING: DO NOT EDIT, AUTO-GENERATED CODE - SEE TOP FOR INSTRUCTIONS */
   uint32_t tile_mode;
   uint32_t tile_flags;
-/* WARNING: DO NOT EDIT, AUTO-GENERATED CODE - SEE TOP FOR INSTRUCTIONS */
 };
 struct drm_nouveau_gem_new {
+/* WARNING: DO NOT EDIT, AUTO-GENERATED CODE - SEE TOP FOR INSTRUCTIONS */
   struct drm_nouveau_gem_info info;
   uint32_t channel_hint;
-/* WARNING: DO NOT EDIT, AUTO-GENERATED CODE - SEE TOP FOR INSTRUCTIONS */
   uint32_t align;
 };
+/* WARNING: DO NOT EDIT, AUTO-GENERATED CODE - SEE TOP FOR INSTRUCTIONS */
 #define NOUVEAU_GEM_MAX_BUFFERS 1024
 struct drm_nouveau_gem_pushbuf_bo_presumed {
-/* WARNING: DO NOT EDIT, AUTO-GENERATED CODE - SEE TOP FOR INSTRUCTIONS */
   uint32_t valid;
   uint32_t domain;
+/* WARNING: DO NOT EDIT, AUTO-GENERATED CODE - SEE TOP FOR INSTRUCTIONS */
   uint64_t offset;
 };
-/* WARNING: DO NOT EDIT, AUTO-GENERATED CODE - SEE TOP FOR INSTRUCTIONS */
 struct drm_nouveau_gem_pushbuf_bo {
   uint64_t user_priv;
+/* WARNING: DO NOT EDIT, AUTO-GENERATED CODE - SEE TOP FOR INSTRUCTIONS */
   uint32_t handle;
   uint32_t read_domains;
-/* WARNING: DO NOT EDIT, AUTO-GENERATED CODE - SEE TOP FOR INSTRUCTIONS */
   uint32_t write_domains;
   uint32_t valid_domains;
+/* WARNING: DO NOT EDIT, AUTO-GENERATED CODE - SEE TOP FOR INSTRUCTIONS */
   struct drm_nouveau_gem_pushbuf_bo_presumed presumed;
 };
-/* WARNING: DO NOT EDIT, AUTO-GENERATED CODE - SEE TOP FOR INSTRUCTIONS */
 #define NOUVEAU_GEM_RELOC_LOW (1 << 0)
 #define NOUVEAU_GEM_RELOC_HIGH (1 << 1)
+/* WARNING: DO NOT EDIT, AUTO-GENERATED CODE - SEE TOP FOR INSTRUCTIONS */
 #define NOUVEAU_GEM_RELOC_OR (1 << 2)
 #define NOUVEAU_GEM_MAX_RELOCS 1024
-/* WARNING: DO NOT EDIT, AUTO-GENERATED CODE - SEE TOP FOR INSTRUCTIONS */
 struct drm_nouveau_gem_pushbuf_reloc {
   uint32_t reloc_bo_index;
+/* WARNING: DO NOT EDIT, AUTO-GENERATED CODE - SEE TOP FOR INSTRUCTIONS */
   uint32_t reloc_bo_offset;
   uint32_t bo_index;
-/* WARNING: DO NOT EDIT, AUTO-GENERATED CODE - SEE TOP FOR INSTRUCTIONS */
   uint32_t flags;
   uint32_t data;
+/* WARNING: DO NOT EDIT, AUTO-GENERATED CODE - SEE TOP FOR INSTRUCTIONS */
   uint32_t vor;
   uint32_t tor;
-/* WARNING: DO NOT EDIT, AUTO-GENERATED CODE - SEE TOP FOR INSTRUCTIONS */
 };
 #define NOUVEAU_GEM_MAX_PUSH 512
+/* WARNING: DO NOT EDIT, AUTO-GENERATED CODE - SEE TOP FOR INSTRUCTIONS */
 struct drm_nouveau_gem_pushbuf_push {
   uint32_t bo_index;
-/* WARNING: DO NOT EDIT, AUTO-GENERATED CODE - SEE TOP FOR INSTRUCTIONS */
   uint32_t pad;
   uint64_t offset;
+/* WARNING: DO NOT EDIT, AUTO-GENERATED CODE - SEE TOP FOR INSTRUCTIONS */
   uint64_t length;
 };
-/* WARNING: DO NOT EDIT, AUTO-GENERATED CODE - SEE TOP FOR INSTRUCTIONS */
 struct drm_nouveau_gem_pushbuf {
   uint32_t channel;
+/* WARNING: DO NOT EDIT, AUTO-GENERATED CODE - SEE TOP FOR INSTRUCTIONS */
   uint32_t nr_buffers;
   uint64_t buffers;
-/* WARNING: DO NOT EDIT, AUTO-GENERATED CODE - SEE TOP FOR INSTRUCTIONS */
   uint32_t nr_relocs;
   uint32_t nr_push;
+/* WARNING: DO NOT EDIT, AUTO-GENERATED CODE - SEE TOP FOR INSTRUCTIONS */
   uint64_t relocs;
   uint64_t push;
-/* WARNING: DO NOT EDIT, AUTO-GENERATED CODE - SEE TOP FOR INSTRUCTIONS */
   uint32_t suffix0;
   uint32_t suffix1;
+/* WARNING: DO NOT EDIT, AUTO-GENERATED CODE - SEE TOP FOR INSTRUCTIONS */
   uint64_t vram_available;
   uint64_t gart_available;
-/* WARNING: DO NOT EDIT, AUTO-GENERATED CODE - SEE TOP FOR INSTRUCTIONS */
 };
 #define NOUVEAU_GEM_CPU_PREP_NOWAIT 0x00000001
+/* WARNING: DO NOT EDIT, AUTO-GENERATED CODE - SEE TOP FOR INSTRUCTIONS */
 #define NOUVEAU_GEM_CPU_PREP_WRITE 0x00000004
 struct drm_nouveau_gem_cpu_prep {
-/* WARNING: DO NOT EDIT, AUTO-GENERATED CODE - SEE TOP FOR INSTRUCTIONS */
   uint32_t handle;
   uint32_t flags;
+/* WARNING: DO NOT EDIT, AUTO-GENERATED CODE - SEE TOP FOR INSTRUCTIONS */
 };
 struct drm_nouveau_gem_cpu_fini {
-/* WARNING: DO NOT EDIT, AUTO-GENERATED CODE - SEE TOP FOR INSTRUCTIONS */
   uint32_t handle;
 };
+/* WARNING: DO NOT EDIT, AUTO-GENERATED CODE - SEE TOP FOR INSTRUCTIONS */
 #define DRM_NOUVEAU_GETPARAM 0x00
 #define DRM_NOUVEAU_SETPARAM 0x01
-/* WARNING: DO NOT EDIT, AUTO-GENERATED CODE - SEE TOP FOR INSTRUCTIONS */
 #define DRM_NOUVEAU_CHANNEL_ALLOC 0x02
 #define DRM_NOUVEAU_CHANNEL_FREE 0x03
+/* WARNING: DO NOT EDIT, AUTO-GENERATED CODE - SEE TOP FOR INSTRUCTIONS */
 #define DRM_NOUVEAU_GROBJ_ALLOC 0x04
 #define DRM_NOUVEAU_NOTIFIEROBJ_ALLOC 0x05
-/* WARNING: DO NOT EDIT, AUTO-GENERATED CODE - SEE TOP FOR INSTRUCTIONS */
 #define DRM_NOUVEAU_GPUOBJ_FREE 0x06
 #define DRM_NOUVEAU_NVIF 0x07
+/* WARNING: DO NOT EDIT, AUTO-GENERATED CODE - SEE TOP FOR INSTRUCTIONS */
 #define DRM_NOUVEAU_GEM_NEW 0x40
 #define DRM_NOUVEAU_GEM_PUSHBUF 0x41
-/* WARNING: DO NOT EDIT, AUTO-GENERATED CODE - SEE TOP FOR INSTRUCTIONS */
 #define DRM_NOUVEAU_GEM_CPU_PREP 0x42
 #define DRM_NOUVEAU_GEM_CPU_FINI 0x43
+/* WARNING: DO NOT EDIT, AUTO-GENERATED CODE - SEE TOP FOR INSTRUCTIONS */
 #define DRM_NOUVEAU_GEM_INFO 0x44
 #define DRM_IOCTL_NOUVEAU_GEM_NEW DRM_IOWR(DRM_COMMAND_BASE + DRM_NOUVEAU_GEM_NEW, struct drm_nouveau_gem_new)
-/* WARNING: DO NOT EDIT, AUTO-GENERATED CODE - SEE TOP FOR INSTRUCTIONS */
 #define DRM_IOCTL_NOUVEAU_GEM_PUSHBUF DRM_IOWR(DRM_COMMAND_BASE + DRM_NOUVEAU_GEM_PUSHBUF, struct drm_nouveau_gem_pushbuf)
 #define DRM_IOCTL_NOUVEAU_GEM_CPU_PREP DRM_IOW(DRM_COMMAND_BASE + DRM_NOUVEAU_GEM_CPU_PREP, struct drm_nouveau_gem_cpu_prep)
+/* WARNING: DO NOT EDIT, AUTO-GENERATED CODE - SEE TOP FOR INSTRUCTIONS */
 #define DRM_IOCTL_NOUVEAU_GEM_CPU_FINI DRM_IOW(DRM_COMMAND_BASE + DRM_NOUVEAU_GEM_CPU_FINI, struct drm_nouveau_gem_cpu_fini)
 #define DRM_IOCTL_NOUVEAU_GEM_INFO DRM_IOWR(DRM_COMMAND_BASE + DRM_NOUVEAU_GEM_INFO, struct drm_nouveau_gem_info)
-/* WARNING: DO NOT EDIT, AUTO-GENERATED CODE - SEE TOP FOR INSTRUCTIONS */
 #endif
diff --git a/libc/kernel/uapi/drm/r128_drm.h b/libc/kernel/uapi/drm/r128_drm.h
index 4e68381..de30d62 100644
--- a/libc/kernel/uapi/drm/r128_drm.h
+++ b/libc/kernel/uapi/drm/r128_drm.h
@@ -18,263 +18,264 @@
  ****************************************************************************/
 #ifndef __R128_DRM_H__
 #define __R128_DRM_H__
+#include <drm/drm.h>
 #ifndef __R128_SAREA_DEFINES__
-#define __R128_SAREA_DEFINES__
 /* WARNING: DO NOT EDIT, AUTO-GENERATED CODE - SEE TOP FOR INSTRUCTIONS */
+#define __R128_SAREA_DEFINES__
 #define R128_UPLOAD_CONTEXT 0x001
 #define R128_UPLOAD_SETUP 0x002
 #define R128_UPLOAD_TEX0 0x004
-#define R128_UPLOAD_TEX1 0x008
 /* WARNING: DO NOT EDIT, AUTO-GENERATED CODE - SEE TOP FOR INSTRUCTIONS */
+#define R128_UPLOAD_TEX1 0x008
 #define R128_UPLOAD_TEX0IMAGES 0x010
 #define R128_UPLOAD_TEX1IMAGES 0x020
 #define R128_UPLOAD_CORE 0x040
-#define R128_UPLOAD_MASKS 0x080
 /* WARNING: DO NOT EDIT, AUTO-GENERATED CODE - SEE TOP FOR INSTRUCTIONS */
+#define R128_UPLOAD_MASKS 0x080
 #define R128_UPLOAD_WINDOW 0x100
 #define R128_UPLOAD_CLIPRECTS 0x200
 #define R128_REQUIRE_QUIESCENCE 0x400
-#define R128_UPLOAD_ALL 0x7ff
 /* WARNING: DO NOT EDIT, AUTO-GENERATED CODE - SEE TOP FOR INSTRUCTIONS */
+#define R128_UPLOAD_ALL 0x7ff
 #define R128_FRONT 0x1
 #define R128_BACK 0x2
 #define R128_DEPTH 0x4
-#define R128_POINTS 0x1
 /* WARNING: DO NOT EDIT, AUTO-GENERATED CODE - SEE TOP FOR INSTRUCTIONS */
+#define R128_POINTS 0x1
 #define R128_LINES 0x2
 #define R128_LINE_STRIP 0x3
 #define R128_TRIANGLES 0x4
-#define R128_TRIANGLE_FAN 0x5
 /* WARNING: DO NOT EDIT, AUTO-GENERATED CODE - SEE TOP FOR INSTRUCTIONS */
+#define R128_TRIANGLE_FAN 0x5
 #define R128_TRIANGLE_STRIP 0x6
 #define R128_BUFFER_SIZE 16384
 #define R128_INDEX_PRIM_OFFSET 20
-#define R128_HOSTDATA_BLIT_OFFSET 32
 /* WARNING: DO NOT EDIT, AUTO-GENERATED CODE - SEE TOP FOR INSTRUCTIONS */
+#define R128_HOSTDATA_BLIT_OFFSET 32
 #define R128_NR_SAREA_CLIPRECTS 12
 #define R128_LOCAL_TEX_HEAP 0
 #define R128_AGP_TEX_HEAP 1
-#define R128_NR_TEX_HEAPS 2
 /* WARNING: DO NOT EDIT, AUTO-GENERATED CODE - SEE TOP FOR INSTRUCTIONS */
+#define R128_NR_TEX_HEAPS 2
 #define R128_NR_TEX_REGIONS 64
 #define R128_LOG_TEX_GRANULARITY 16
 #define R128_NR_CONTEXT_REGS 12
-#define R128_MAX_TEXTURE_LEVELS 11
 /* WARNING: DO NOT EDIT, AUTO-GENERATED CODE - SEE TOP FOR INSTRUCTIONS */
+#define R128_MAX_TEXTURE_LEVELS 11
 #define R128_MAX_TEXTURE_UNITS 2
 #endif
 typedef struct {
-  unsigned int dst_pitch_offset_c;
 /* WARNING: DO NOT EDIT, AUTO-GENERATED CODE - SEE TOP FOR INSTRUCTIONS */
+  unsigned int dst_pitch_offset_c;
   unsigned int dp_gui_master_cntl_c;
   unsigned int sc_top_left_c;
   unsigned int sc_bottom_right_c;
-  unsigned int z_offset_c;
 /* WARNING: DO NOT EDIT, AUTO-GENERATED CODE - SEE TOP FOR INSTRUCTIONS */
+  unsigned int z_offset_c;
   unsigned int z_pitch_c;
   unsigned int z_sten_cntl_c;
   unsigned int tex_cntl_c;
-  unsigned int misc_3d_state_cntl_reg;
 /* WARNING: DO NOT EDIT, AUTO-GENERATED CODE - SEE TOP FOR INSTRUCTIONS */
+  unsigned int misc_3d_state_cntl_reg;
   unsigned int texture_clr_cmp_clr_c;
   unsigned int texture_clr_cmp_msk_c;
   unsigned int fog_color_c;
-  unsigned int tex_size_pitch_c;
 /* WARNING: DO NOT EDIT, AUTO-GENERATED CODE - SEE TOP FOR INSTRUCTIONS */
+  unsigned int tex_size_pitch_c;
   unsigned int constant_color_c;
   unsigned int pm4_vc_fpu_setup;
   unsigned int setup_cntl;
-  unsigned int dp_write_mask;
 /* WARNING: DO NOT EDIT, AUTO-GENERATED CODE - SEE TOP FOR INSTRUCTIONS */
+  unsigned int dp_write_mask;
   unsigned int sten_ref_mask_c;
   unsigned int plane_3d_mask_c;
   unsigned int window_xy_offset;
-  unsigned int scale_3d_cntl;
 /* WARNING: DO NOT EDIT, AUTO-GENERATED CODE - SEE TOP FOR INSTRUCTIONS */
+  unsigned int scale_3d_cntl;
 } drm_r128_context_regs_t;
 typedef struct {
   unsigned int tex_cntl;
-  unsigned int tex_combine_cntl;
 /* WARNING: DO NOT EDIT, AUTO-GENERATED CODE - SEE TOP FOR INSTRUCTIONS */
+  unsigned int tex_combine_cntl;
   unsigned int tex_size_pitch;
   unsigned int tex_offset[R128_MAX_TEXTURE_LEVELS];
   unsigned int tex_border_color;
-} drm_r128_texture_regs_t;
 /* WARNING: DO NOT EDIT, AUTO-GENERATED CODE - SEE TOP FOR INSTRUCTIONS */
+} drm_r128_texture_regs_t;
 typedef struct drm_r128_sarea {
   drm_r128_context_regs_t context_state;
   drm_r128_texture_regs_t tex_state[R128_MAX_TEXTURE_UNITS];
-  unsigned int dirty;
 /* WARNING: DO NOT EDIT, AUTO-GENERATED CODE - SEE TOP FOR INSTRUCTIONS */
+  unsigned int dirty;
   unsigned int vertsize;
   unsigned int vc_format;
   struct drm_clip_rect boxes[R128_NR_SAREA_CLIPRECTS];
-  unsigned int nbox;
 /* WARNING: DO NOT EDIT, AUTO-GENERATED CODE - SEE TOP FOR INSTRUCTIONS */
+  unsigned int nbox;
   unsigned int last_frame;
   unsigned int last_dispatch;
   struct drm_tex_region tex_list[R128_NR_TEX_HEAPS][R128_NR_TEX_REGIONS + 1];
-  unsigned int tex_age[R128_NR_TEX_HEAPS];
 /* WARNING: DO NOT EDIT, AUTO-GENERATED CODE - SEE TOP FOR INSTRUCTIONS */
+  unsigned int tex_age[R128_NR_TEX_HEAPS];
   int ctx_owner;
   int pfAllowPageFlip;
   int pfCurrentPage;
-} drm_r128_sarea_t;
 /* WARNING: DO NOT EDIT, AUTO-GENERATED CODE - SEE TOP FOR INSTRUCTIONS */
+} drm_r128_sarea_t;
 #define DRM_R128_INIT 0x00
 #define DRM_R128_CCE_START 0x01
 #define DRM_R128_CCE_STOP 0x02
-#define DRM_R128_CCE_RESET 0x03
 /* WARNING: DO NOT EDIT, AUTO-GENERATED CODE - SEE TOP FOR INSTRUCTIONS */
+#define DRM_R128_CCE_RESET 0x03
 #define DRM_R128_CCE_IDLE 0x04
 #define DRM_R128_RESET 0x06
 #define DRM_R128_SWAP 0x07
-#define DRM_R128_CLEAR 0x08
 /* WARNING: DO NOT EDIT, AUTO-GENERATED CODE - SEE TOP FOR INSTRUCTIONS */
+#define DRM_R128_CLEAR 0x08
 #define DRM_R128_VERTEX 0x09
 #define DRM_R128_INDICES 0x0a
 #define DRM_R128_BLIT 0x0b
-#define DRM_R128_DEPTH 0x0c
 /* WARNING: DO NOT EDIT, AUTO-GENERATED CODE - SEE TOP FOR INSTRUCTIONS */
+#define DRM_R128_DEPTH 0x0c
 #define DRM_R128_STIPPLE 0x0d
 #define DRM_R128_INDIRECT 0x0f
 #define DRM_R128_FULLSCREEN 0x10
-#define DRM_R128_CLEAR2 0x11
 /* WARNING: DO NOT EDIT, AUTO-GENERATED CODE - SEE TOP FOR INSTRUCTIONS */
+#define DRM_R128_CLEAR2 0x11
 #define DRM_R128_GETPARAM 0x12
 #define DRM_R128_FLIP 0x13
 #define DRM_IOCTL_R128_INIT DRM_IOW(DRM_COMMAND_BASE + DRM_R128_INIT, drm_r128_init_t)
-#define DRM_IOCTL_R128_CCE_START DRM_IO(DRM_COMMAND_BASE + DRM_R128_CCE_START)
 /* WARNING: DO NOT EDIT, AUTO-GENERATED CODE - SEE TOP FOR INSTRUCTIONS */
+#define DRM_IOCTL_R128_CCE_START DRM_IO(DRM_COMMAND_BASE + DRM_R128_CCE_START)
 #define DRM_IOCTL_R128_CCE_STOP DRM_IOW(DRM_COMMAND_BASE + DRM_R128_CCE_STOP, drm_r128_cce_stop_t)
 #define DRM_IOCTL_R128_CCE_RESET DRM_IO(DRM_COMMAND_BASE + DRM_R128_CCE_RESET)
 #define DRM_IOCTL_R128_CCE_IDLE DRM_IO(DRM_COMMAND_BASE + DRM_R128_CCE_IDLE)
-#define DRM_IOCTL_R128_RESET DRM_IO(DRM_COMMAND_BASE + DRM_R128_RESET)
 /* WARNING: DO NOT EDIT, AUTO-GENERATED CODE - SEE TOP FOR INSTRUCTIONS */
+#define DRM_IOCTL_R128_RESET DRM_IO(DRM_COMMAND_BASE + DRM_R128_RESET)
 #define DRM_IOCTL_R128_SWAP DRM_IO(DRM_COMMAND_BASE + DRM_R128_SWAP)
 #define DRM_IOCTL_R128_CLEAR DRM_IOW(DRM_COMMAND_BASE + DRM_R128_CLEAR, drm_r128_clear_t)
 #define DRM_IOCTL_R128_VERTEX DRM_IOW(DRM_COMMAND_BASE + DRM_R128_VERTEX, drm_r128_vertex_t)
-#define DRM_IOCTL_R128_INDICES DRM_IOW(DRM_COMMAND_BASE + DRM_R128_INDICES, drm_r128_indices_t)
 /* WARNING: DO NOT EDIT, AUTO-GENERATED CODE - SEE TOP FOR INSTRUCTIONS */
+#define DRM_IOCTL_R128_INDICES DRM_IOW(DRM_COMMAND_BASE + DRM_R128_INDICES, drm_r128_indices_t)
 #define DRM_IOCTL_R128_BLIT DRM_IOW(DRM_COMMAND_BASE + DRM_R128_BLIT, drm_r128_blit_t)
 #define DRM_IOCTL_R128_DEPTH DRM_IOW(DRM_COMMAND_BASE + DRM_R128_DEPTH, drm_r128_depth_t)
 #define DRM_IOCTL_R128_STIPPLE DRM_IOW(DRM_COMMAND_BASE + DRM_R128_STIPPLE, drm_r128_stipple_t)
-#define DRM_IOCTL_R128_INDIRECT DRM_IOWR(DRM_COMMAND_BASE + DRM_R128_INDIRECT, drm_r128_indirect_t)
 /* WARNING: DO NOT EDIT, AUTO-GENERATED CODE - SEE TOP FOR INSTRUCTIONS */
+#define DRM_IOCTL_R128_INDIRECT DRM_IOWR(DRM_COMMAND_BASE + DRM_R128_INDIRECT, drm_r128_indirect_t)
 #define DRM_IOCTL_R128_FULLSCREEN DRM_IOW(DRM_COMMAND_BASE + DRM_R128_FULLSCREEN, drm_r128_fullscreen_t)
 #define DRM_IOCTL_R128_CLEAR2 DRM_IOW(DRM_COMMAND_BASE + DRM_R128_CLEAR2, drm_r128_clear2_t)
 #define DRM_IOCTL_R128_GETPARAM DRM_IOWR(DRM_COMMAND_BASE + DRM_R128_GETPARAM, drm_r128_getparam_t)
-#define DRM_IOCTL_R128_FLIP DRM_IO(DRM_COMMAND_BASE + DRM_R128_FLIP)
 /* WARNING: DO NOT EDIT, AUTO-GENERATED CODE - SEE TOP FOR INSTRUCTIONS */
+#define DRM_IOCTL_R128_FLIP DRM_IO(DRM_COMMAND_BASE + DRM_R128_FLIP)
 typedef struct drm_r128_init {
   enum {
     R128_INIT_CCE = 0x01,
-    R128_CLEANUP_CCE = 0x02
 /* WARNING: DO NOT EDIT, AUTO-GENERATED CODE - SEE TOP FOR INSTRUCTIONS */
+    R128_CLEANUP_CCE = 0x02
   } func;
   unsigned long sarea_priv_offset;
   int is_pci;
-  int cce_mode;
 /* WARNING: DO NOT EDIT, AUTO-GENERATED CODE - SEE TOP FOR INSTRUCTIONS */
+  int cce_mode;
   int cce_secure;
   int ring_size;
   int usec_timeout;
-  unsigned int fb_bpp;
 /* WARNING: DO NOT EDIT, AUTO-GENERATED CODE - SEE TOP FOR INSTRUCTIONS */
+  unsigned int fb_bpp;
   unsigned int front_offset, front_pitch;
   unsigned int back_offset, back_pitch;
   unsigned int depth_bpp;
-  unsigned int depth_offset, depth_pitch;
 /* WARNING: DO NOT EDIT, AUTO-GENERATED CODE - SEE TOP FOR INSTRUCTIONS */
+  unsigned int depth_offset, depth_pitch;
   unsigned int span_offset;
   unsigned long fb_offset;
   unsigned long mmio_offset;
-  unsigned long ring_offset;
 /* WARNING: DO NOT EDIT, AUTO-GENERATED CODE - SEE TOP FOR INSTRUCTIONS */
+  unsigned long ring_offset;
   unsigned long ring_rptr_offset;
   unsigned long buffers_offset;
   unsigned long agp_textures_offset;
-} drm_r128_init_t;
 /* WARNING: DO NOT EDIT, AUTO-GENERATED CODE - SEE TOP FOR INSTRUCTIONS */
+} drm_r128_init_t;
 typedef struct drm_r128_cce_stop {
   int flush;
   int idle;
-} drm_r128_cce_stop_t;
 /* WARNING: DO NOT EDIT, AUTO-GENERATED CODE - SEE TOP FOR INSTRUCTIONS */
+} drm_r128_cce_stop_t;
 typedef struct drm_r128_clear {
   unsigned int flags;
   unsigned int clear_color;
-  unsigned int clear_depth;
 /* WARNING: DO NOT EDIT, AUTO-GENERATED CODE - SEE TOP FOR INSTRUCTIONS */
+  unsigned int clear_depth;
   unsigned int color_mask;
   unsigned int depth_mask;
 } drm_r128_clear_t;
-typedef struct drm_r128_vertex {
 /* WARNING: DO NOT EDIT, AUTO-GENERATED CODE - SEE TOP FOR INSTRUCTIONS */
+typedef struct drm_r128_vertex {
   int prim;
   int idx;
   int count;
-  int discard;
 /* WARNING: DO NOT EDIT, AUTO-GENERATED CODE - SEE TOP FOR INSTRUCTIONS */
+  int discard;
 } drm_r128_vertex_t;
 typedef struct drm_r128_indices {
   int prim;
-  int idx;
 /* WARNING: DO NOT EDIT, AUTO-GENERATED CODE - SEE TOP FOR INSTRUCTIONS */
+  int idx;
   int start;
   int end;
   int discard;
-} drm_r128_indices_t;
 /* WARNING: DO NOT EDIT, AUTO-GENERATED CODE - SEE TOP FOR INSTRUCTIONS */
+} drm_r128_indices_t;
 typedef struct drm_r128_blit {
   int idx;
   int pitch;
-  int offset;
 /* WARNING: DO NOT EDIT, AUTO-GENERATED CODE - SEE TOP FOR INSTRUCTIONS */
+  int offset;
   int format;
   unsigned short x, y;
   unsigned short width, height;
-} drm_r128_blit_t;
 /* WARNING: DO NOT EDIT, AUTO-GENERATED CODE - SEE TOP FOR INSTRUCTIONS */
+} drm_r128_blit_t;
 typedef struct drm_r128_depth {
   enum {
     R128_WRITE_SPAN = 0x01,
-    R128_WRITE_PIXELS = 0x02,
 /* WARNING: DO NOT EDIT, AUTO-GENERATED CODE - SEE TOP FOR INSTRUCTIONS */
+    R128_WRITE_PIXELS = 0x02,
     R128_READ_SPAN = 0x03,
     R128_READ_PIXELS = 0x04
   } func;
-  int n;
 /* WARNING: DO NOT EDIT, AUTO-GENERATED CODE - SEE TOP FOR INSTRUCTIONS */
+  int n;
   int __user * x;
   int __user * y;
   unsigned int __user * buffer;
-  unsigned char __user * mask;
 /* WARNING: DO NOT EDIT, AUTO-GENERATED CODE - SEE TOP FOR INSTRUCTIONS */
+  unsigned char __user * mask;
 } drm_r128_depth_t;
 typedef struct drm_r128_stipple {
   unsigned int __user * mask;
-} drm_r128_stipple_t;
 /* WARNING: DO NOT EDIT, AUTO-GENERATED CODE - SEE TOP FOR INSTRUCTIONS */
+} drm_r128_stipple_t;
 typedef struct drm_r128_indirect {
   int idx;
   int start;
-  int end;
 /* WARNING: DO NOT EDIT, AUTO-GENERATED CODE - SEE TOP FOR INSTRUCTIONS */
+  int end;
   int discard;
 } drm_r128_indirect_t;
 typedef struct drm_r128_fullscreen {
-  enum {
 /* WARNING: DO NOT EDIT, AUTO-GENERATED CODE - SEE TOP FOR INSTRUCTIONS */
+  enum {
     R128_INIT_FULLSCREEN = 0x01,
     R128_CLEANUP_FULLSCREEN = 0x02
   } func;
-} drm_r128_fullscreen_t;
 /* WARNING: DO NOT EDIT, AUTO-GENERATED CODE - SEE TOP FOR INSTRUCTIONS */
+} drm_r128_fullscreen_t;
 #define R128_PARAM_IRQ_NR 1
 typedef struct drm_r128_getparam {
   int param;
-  void __user * value;
 /* WARNING: DO NOT EDIT, AUTO-GENERATED CODE - SEE TOP FOR INSTRUCTIONS */
+  void __user * value;
 } drm_r128_getparam_t;
 #endif
diff --git a/libc/kernel/uapi/drm/radeon_drm.h b/libc/kernel/uapi/drm/radeon_drm.h
index 6fb86f1..d85309f 100644
--- a/libc/kernel/uapi/drm/radeon_drm.h
+++ b/libc/kernel/uapi/drm/radeon_drm.h
@@ -18,7 +18,7 @@
  ****************************************************************************/
 #ifndef __RADEON_DRM_H__
 #define __RADEON_DRM_H__
-#include <drm/drm.h>
+#include "drm.h"
 #ifndef __RADEON_SAREA_DEFINES__
 /* WARNING: DO NOT EDIT, AUTO-GENERATED CODE - SEE TOP FOR INSTRUCTIONS */
 #define __RADEON_SAREA_DEFINES__
@@ -961,29 +961,36 @@
 #define RADEON_INFO_GTT_USAGE 0x1f
 #define RADEON_INFO_ACTIVE_CU_COUNT 0x20
 /* WARNING: DO NOT EDIT, AUTO-GENERATED CODE - SEE TOP FOR INSTRUCTIONS */
+#define RADEON_INFO_CURRENT_GPU_TEMP 0x21
+#define RADEON_INFO_CURRENT_GPU_SCLK 0x22
+#define RADEON_INFO_CURRENT_GPU_MCLK 0x23
+#define RADEON_INFO_READ_REG 0x24
+/* WARNING: DO NOT EDIT, AUTO-GENERATED CODE - SEE TOP FOR INSTRUCTIONS */
+#define RADEON_INFO_VA_UNMAP_WORKING 0x25
+#define RADEON_INFO_GPU_RESET_COUNTER 0x26
 struct drm_radeon_info {
   uint32_t request;
+/* WARNING: DO NOT EDIT, AUTO-GENERATED CODE - SEE TOP FOR INSTRUCTIONS */
   uint32_t pad;
   uint64_t value;
-/* WARNING: DO NOT EDIT, AUTO-GENERATED CODE - SEE TOP FOR INSTRUCTIONS */
 };
 #define SI_TILE_MODE_COLOR_LINEAR_ALIGNED 8
+/* WARNING: DO NOT EDIT, AUTO-GENERATED CODE - SEE TOP FOR INSTRUCTIONS */
 #define SI_TILE_MODE_COLOR_1D 13
 #define SI_TILE_MODE_COLOR_1D_SCANOUT 9
-/* WARNING: DO NOT EDIT, AUTO-GENERATED CODE - SEE TOP FOR INSTRUCTIONS */
 #define SI_TILE_MODE_COLOR_2D_8BPP 14
 #define SI_TILE_MODE_COLOR_2D_16BPP 15
+/* WARNING: DO NOT EDIT, AUTO-GENERATED CODE - SEE TOP FOR INSTRUCTIONS */
 #define SI_TILE_MODE_COLOR_2D_32BPP 16
 #define SI_TILE_MODE_COLOR_2D_64BPP 17
-/* WARNING: DO NOT EDIT, AUTO-GENERATED CODE - SEE TOP FOR INSTRUCTIONS */
 #define SI_TILE_MODE_COLOR_2D_SCANOUT_16BPP 11
 #define SI_TILE_MODE_COLOR_2D_SCANOUT_32BPP 12
+/* WARNING: DO NOT EDIT, AUTO-GENERATED CODE - SEE TOP FOR INSTRUCTIONS */
 #define SI_TILE_MODE_DEPTH_STENCIL_1D 4
 #define SI_TILE_MODE_DEPTH_STENCIL_2D 0
-/* WARNING: DO NOT EDIT, AUTO-GENERATED CODE - SEE TOP FOR INSTRUCTIONS */
 #define SI_TILE_MODE_DEPTH_STENCIL_2D_2AA 3
 #define SI_TILE_MODE_DEPTH_STENCIL_2D_4AA 3
+/* WARNING: DO NOT EDIT, AUTO-GENERATED CODE - SEE TOP FOR INSTRUCTIONS */
 #define SI_TILE_MODE_DEPTH_STENCIL_2D_8AA 2
 #define CIK_TILE_MODE_DEPTH_STENCIL_1D 5
-/* WARNING: DO NOT EDIT, AUTO-GENERATED CODE - SEE TOP FOR INSTRUCTIONS */
 #endif
diff --git a/libc/kernel/uapi/drm/savage_drm.h b/libc/kernel/uapi/drm/savage_drm.h
index db873b6..eba99a3 100644
--- a/libc/kernel/uapi/drm/savage_drm.h
+++ b/libc/kernel/uapi/drm/savage_drm.h
@@ -18,166 +18,167 @@
  ****************************************************************************/
 #ifndef __SAVAGE_DRM_H__
 #define __SAVAGE_DRM_H__
+#include <drm/drm.h>
 #ifndef __SAVAGE_SAREA_DEFINES__
-#define __SAVAGE_SAREA_DEFINES__
 /* WARNING: DO NOT EDIT, AUTO-GENERATED CODE - SEE TOP FOR INSTRUCTIONS */
+#define __SAVAGE_SAREA_DEFINES__
 #define SAVAGE_CARD_HEAP 0
 #define SAVAGE_AGP_HEAP 1
 #define SAVAGE_NR_TEX_HEAPS 2
-#define SAVAGE_NR_TEX_REGIONS 16
 /* WARNING: DO NOT EDIT, AUTO-GENERATED CODE - SEE TOP FOR INSTRUCTIONS */
+#define SAVAGE_NR_TEX_REGIONS 16
 #define SAVAGE_LOG_MIN_TEX_REGION_SIZE 16
 #endif
 typedef struct _drm_savage_sarea {
-  struct drm_tex_region texList[SAVAGE_NR_TEX_HEAPS][SAVAGE_NR_TEX_REGIONS + 1];
 /* WARNING: DO NOT EDIT, AUTO-GENERATED CODE - SEE TOP FOR INSTRUCTIONS */
+  struct drm_tex_region texList[SAVAGE_NR_TEX_HEAPS][SAVAGE_NR_TEX_REGIONS + 1];
   unsigned int texAge[SAVAGE_NR_TEX_HEAPS];
   int ctxOwner;
 } drm_savage_sarea_t, * drm_savage_sarea_ptr;
-#define DRM_SAVAGE_BCI_INIT 0x00
 /* WARNING: DO NOT EDIT, AUTO-GENERATED CODE - SEE TOP FOR INSTRUCTIONS */
+#define DRM_SAVAGE_BCI_INIT 0x00
 #define DRM_SAVAGE_BCI_CMDBUF 0x01
 #define DRM_SAVAGE_BCI_EVENT_EMIT 0x02
 #define DRM_SAVAGE_BCI_EVENT_WAIT 0x03
-#define DRM_IOCTL_SAVAGE_BCI_INIT DRM_IOW(DRM_COMMAND_BASE + DRM_SAVAGE_BCI_INIT, drm_savage_init_t)
 /* WARNING: DO NOT EDIT, AUTO-GENERATED CODE - SEE TOP FOR INSTRUCTIONS */
+#define DRM_IOCTL_SAVAGE_BCI_INIT DRM_IOW(DRM_COMMAND_BASE + DRM_SAVAGE_BCI_INIT, drm_savage_init_t)
 #define DRM_IOCTL_SAVAGE_BCI_CMDBUF DRM_IOW(DRM_COMMAND_BASE + DRM_SAVAGE_BCI_CMDBUF, drm_savage_cmdbuf_t)
 #define DRM_IOCTL_SAVAGE_BCI_EVENT_EMIT DRM_IOWR(DRM_COMMAND_BASE + DRM_SAVAGE_BCI_EVENT_EMIT, drm_savage_event_emit_t)
 #define DRM_IOCTL_SAVAGE_BCI_EVENT_WAIT DRM_IOW(DRM_COMMAND_BASE + DRM_SAVAGE_BCI_EVENT_WAIT, drm_savage_event_wait_t)
-#define SAVAGE_DMA_PCI 1
 /* WARNING: DO NOT EDIT, AUTO-GENERATED CODE - SEE TOP FOR INSTRUCTIONS */
+#define SAVAGE_DMA_PCI 1
 #define SAVAGE_DMA_AGP 3
 typedef struct drm_savage_init {
   enum {
-    SAVAGE_INIT_BCI = 1,
 /* WARNING: DO NOT EDIT, AUTO-GENERATED CODE - SEE TOP FOR INSTRUCTIONS */
+    SAVAGE_INIT_BCI = 1,
     SAVAGE_CLEANUP_BCI = 2
   } func;
   unsigned int sarea_priv_offset;
-  unsigned int cob_size;
 /* WARNING: DO NOT EDIT, AUTO-GENERATED CODE - SEE TOP FOR INSTRUCTIONS */
+  unsigned int cob_size;
   unsigned int bci_threshold_lo, bci_threshold_hi;
   unsigned int dma_type;
   unsigned int fb_bpp;
-  unsigned int front_offset, front_pitch;
 /* WARNING: DO NOT EDIT, AUTO-GENERATED CODE - SEE TOP FOR INSTRUCTIONS */
+  unsigned int front_offset, front_pitch;
   unsigned int back_offset, back_pitch;
   unsigned int depth_bpp;
   unsigned int depth_offset, depth_pitch;
-  unsigned int texture_offset;
 /* WARNING: DO NOT EDIT, AUTO-GENERATED CODE - SEE TOP FOR INSTRUCTIONS */
+  unsigned int texture_offset;
   unsigned int texture_size;
   unsigned long status_offset;
   unsigned long buffers_offset;
-  unsigned long agp_textures_offset;
 /* WARNING: DO NOT EDIT, AUTO-GENERATED CODE - SEE TOP FOR INSTRUCTIONS */
+  unsigned long agp_textures_offset;
   unsigned long cmd_dma_offset;
 } drm_savage_init_t;
 typedef union drm_savage_cmd_header drm_savage_cmd_header_t;
-typedef struct drm_savage_cmdbuf {
 /* WARNING: DO NOT EDIT, AUTO-GENERATED CODE - SEE TOP FOR INSTRUCTIONS */
+typedef struct drm_savage_cmdbuf {
   drm_savage_cmd_header_t __user * cmd_addr;
   unsigned int size;
   unsigned int dma_idx;
-  int discard;
 /* WARNING: DO NOT EDIT, AUTO-GENERATED CODE - SEE TOP FOR INSTRUCTIONS */
+  int discard;
   unsigned int __user * vb_addr;
   unsigned int vb_size;
   unsigned int vb_stride;
-  struct drm_clip_rect __user * box_addr;
 /* WARNING: DO NOT EDIT, AUTO-GENERATED CODE - SEE TOP FOR INSTRUCTIONS */
+  struct drm_clip_rect __user * box_addr;
   unsigned int nbox;
 } drm_savage_cmdbuf_t;
 #define SAVAGE_WAIT_2D 0x1
-#define SAVAGE_WAIT_3D 0x2
 /* WARNING: DO NOT EDIT, AUTO-GENERATED CODE - SEE TOP FOR INSTRUCTIONS */
+#define SAVAGE_WAIT_3D 0x2
 #define SAVAGE_WAIT_IRQ 0x4
 typedef struct drm_savage_event {
   unsigned int count;
-  unsigned int flags;
 /* WARNING: DO NOT EDIT, AUTO-GENERATED CODE - SEE TOP FOR INSTRUCTIONS */
+  unsigned int flags;
 } drm_savage_event_emit_t, drm_savage_event_wait_t;
 #define SAVAGE_CMD_STATE 0
 #define SAVAGE_CMD_DMA_PRIM 1
-#define SAVAGE_CMD_VB_PRIM 2
 /* WARNING: DO NOT EDIT, AUTO-GENERATED CODE - SEE TOP FOR INSTRUCTIONS */
+#define SAVAGE_CMD_VB_PRIM 2
 #define SAVAGE_CMD_DMA_IDX 3
 #define SAVAGE_CMD_VB_IDX 4
 #define SAVAGE_CMD_CLEAR 5
-#define SAVAGE_CMD_SWAP 6
 /* WARNING: DO NOT EDIT, AUTO-GENERATED CODE - SEE TOP FOR INSTRUCTIONS */
+#define SAVAGE_CMD_SWAP 6
 #define SAVAGE_PRIM_TRILIST 0
 #define SAVAGE_PRIM_TRISTRIP 1
 #define SAVAGE_PRIM_TRIFAN 2
-#define SAVAGE_PRIM_TRILIST_201 3
 /* WARNING: DO NOT EDIT, AUTO-GENERATED CODE - SEE TOP FOR INSTRUCTIONS */
+#define SAVAGE_PRIM_TRILIST_201 3
 #define SAVAGE_SKIP_Z 0x01
 #define SAVAGE_SKIP_W 0x02
 #define SAVAGE_SKIP_C0 0x04
-#define SAVAGE_SKIP_C1 0x08
 /* WARNING: DO NOT EDIT, AUTO-GENERATED CODE - SEE TOP FOR INSTRUCTIONS */
+#define SAVAGE_SKIP_C1 0x08
 #define SAVAGE_SKIP_S0 0x10
 #define SAVAGE_SKIP_T0 0x20
 #define SAVAGE_SKIP_ST0 0x30
-#define SAVAGE_SKIP_S1 0x40
 /* WARNING: DO NOT EDIT, AUTO-GENERATED CODE - SEE TOP FOR INSTRUCTIONS */
+#define SAVAGE_SKIP_S1 0x40
 #define SAVAGE_SKIP_T1 0x80
 #define SAVAGE_SKIP_ST1 0xc0
 #define SAVAGE_SKIP_ALL_S3D 0x3f
-#define SAVAGE_SKIP_ALL_S4 0xff
 /* WARNING: DO NOT EDIT, AUTO-GENERATED CODE - SEE TOP FOR INSTRUCTIONS */
+#define SAVAGE_SKIP_ALL_S4 0xff
 #define SAVAGE_FRONT 0x1
 #define SAVAGE_BACK 0x2
 #define SAVAGE_DEPTH 0x4
-union drm_savage_cmd_header {
 /* WARNING: DO NOT EDIT, AUTO-GENERATED CODE - SEE TOP FOR INSTRUCTIONS */
+union drm_savage_cmd_header {
   struct {
     unsigned char cmd;
     unsigned char pad0;
-    unsigned short pad1;
 /* WARNING: DO NOT EDIT, AUTO-GENERATED CODE - SEE TOP FOR INSTRUCTIONS */
+    unsigned short pad1;
     unsigned short pad2;
     unsigned short pad3;
   } cmd;
-  struct {
 /* WARNING: DO NOT EDIT, AUTO-GENERATED CODE - SEE TOP FOR INSTRUCTIONS */
+  struct {
     unsigned char cmd;
     unsigned char global;
     unsigned short count;
-    unsigned short start;
 /* WARNING: DO NOT EDIT, AUTO-GENERATED CODE - SEE TOP FOR INSTRUCTIONS */
+    unsigned short start;
     unsigned short pad3;
   } state;
   struct {
-    unsigned char cmd;
 /* WARNING: DO NOT EDIT, AUTO-GENERATED CODE - SEE TOP FOR INSTRUCTIONS */
+    unsigned char cmd;
     unsigned char prim;
     unsigned short skip;
     unsigned short count;
-    unsigned short start;
 /* WARNING: DO NOT EDIT, AUTO-GENERATED CODE - SEE TOP FOR INSTRUCTIONS */
+    unsigned short start;
   } prim;
   struct {
     unsigned char cmd;
-    unsigned char prim;
 /* WARNING: DO NOT EDIT, AUTO-GENERATED CODE - SEE TOP FOR INSTRUCTIONS */
+    unsigned char prim;
     unsigned short skip;
     unsigned short count;
     unsigned short pad3;
-  } idx;
 /* WARNING: DO NOT EDIT, AUTO-GENERATED CODE - SEE TOP FOR INSTRUCTIONS */
+  } idx;
   struct {
     unsigned char cmd;
     unsigned char pad0;
-    unsigned short pad1;
 /* WARNING: DO NOT EDIT, AUTO-GENERATED CODE - SEE TOP FOR INSTRUCTIONS */
+    unsigned short pad1;
     unsigned int flags;
   } clear0;
   struct {
-    unsigned int mask;
 /* WARNING: DO NOT EDIT, AUTO-GENERATED CODE - SEE TOP FOR INSTRUCTIONS */
+    unsigned int mask;
     unsigned int value;
   } clear1;
 };
-#endif
 /* WARNING: DO NOT EDIT, AUTO-GENERATED CODE - SEE TOP FOR INSTRUCTIONS */
+#endif
diff --git a/libc/kernel/uapi/drm/sis_drm.h b/libc/kernel/uapi/drm/sis_drm.h
index 5a9e868..52054c4 100644
--- a/libc/kernel/uapi/drm/sis_drm.h
+++ b/libc/kernel/uapi/drm/sis_drm.h
@@ -51,8 +51,4 @@
   unsigned long offset, size;
 } drm_sis_fb_t;
 /* WARNING: DO NOT EDIT, AUTO-GENERATED CODE - SEE TOP FOR INSTRUCTIONS */
-struct sis_file_private {
-  struct list_head obj_list;
-};
 #endif
-/* WARNING: DO NOT EDIT, AUTO-GENERATED CODE - SEE TOP FOR INSTRUCTIONS */
diff --git a/libc/kernel/uapi/drm/tegra_drm.h b/libc/kernel/uapi/drm/tegra_drm.h
index e207c0c..e5d8b67 100644
--- a/libc/kernel/uapi/drm/tegra_drm.h
+++ b/libc/kernel/uapi/drm/tegra_drm.h
@@ -31,168 +31,169 @@
 struct drm_tegra_gem_mmap {
   __u32 handle;
 /* WARNING: DO NOT EDIT, AUTO-GENERATED CODE - SEE TOP FOR INSTRUCTIONS */
-  __u32 offset;
+  __u32 pad;
+  __u64 offset;
 };
 struct drm_tegra_syncpt_read {
-  __u32 id;
 /* WARNING: DO NOT EDIT, AUTO-GENERATED CODE - SEE TOP FOR INSTRUCTIONS */
+  __u32 id;
   __u32 value;
 };
 struct drm_tegra_syncpt_incr {
-  __u32 id;
 /* WARNING: DO NOT EDIT, AUTO-GENERATED CODE - SEE TOP FOR INSTRUCTIONS */
+  __u32 id;
   __u32 pad;
 };
 struct drm_tegra_syncpt_wait {
-  __u32 id;
 /* WARNING: DO NOT EDIT, AUTO-GENERATED CODE - SEE TOP FOR INSTRUCTIONS */
+  __u32 id;
   __u32 thresh;
   __u32 timeout;
   __u32 value;
-};
 /* WARNING: DO NOT EDIT, AUTO-GENERATED CODE - SEE TOP FOR INSTRUCTIONS */
+};
 #define DRM_TEGRA_NO_TIMEOUT (0xffffffff)
 struct drm_tegra_open_channel {
   __u32 client;
-  __u32 pad;
 /* WARNING: DO NOT EDIT, AUTO-GENERATED CODE - SEE TOP FOR INSTRUCTIONS */
+  __u32 pad;
   __u64 context;
 };
 struct drm_tegra_close_channel {
-  __u64 context;
 /* WARNING: DO NOT EDIT, AUTO-GENERATED CODE - SEE TOP FOR INSTRUCTIONS */
+  __u64 context;
 };
 struct drm_tegra_get_syncpt {
   __u64 context;
-  __u32 index;
 /* WARNING: DO NOT EDIT, AUTO-GENERATED CODE - SEE TOP FOR INSTRUCTIONS */
+  __u32 index;
   __u32 id;
 };
 struct drm_tegra_get_syncpt_base {
-  __u64 context;
 /* WARNING: DO NOT EDIT, AUTO-GENERATED CODE - SEE TOP FOR INSTRUCTIONS */
+  __u64 context;
   __u32 syncpt;
   __u32 id;
 };
-struct drm_tegra_syncpt {
 /* WARNING: DO NOT EDIT, AUTO-GENERATED CODE - SEE TOP FOR INSTRUCTIONS */
+struct drm_tegra_syncpt {
   __u32 id;
   __u32 incrs;
 };
-struct drm_tegra_cmdbuf {
 /* WARNING: DO NOT EDIT, AUTO-GENERATED CODE - SEE TOP FOR INSTRUCTIONS */
+struct drm_tegra_cmdbuf {
   __u32 handle;
   __u32 offset;
   __u32 words;
-  __u32 pad;
 /* WARNING: DO NOT EDIT, AUTO-GENERATED CODE - SEE TOP FOR INSTRUCTIONS */
+  __u32 pad;
 };
 struct drm_tegra_reloc {
   struct {
-    __u32 handle;
 /* WARNING: DO NOT EDIT, AUTO-GENERATED CODE - SEE TOP FOR INSTRUCTIONS */
+    __u32 handle;
     __u32 offset;
   } cmdbuf;
   struct {
-    __u32 handle;
 /* WARNING: DO NOT EDIT, AUTO-GENERATED CODE - SEE TOP FOR INSTRUCTIONS */
+    __u32 handle;
     __u32 offset;
   } target;
   __u32 shift;
-  __u32 pad;
 /* WARNING: DO NOT EDIT, AUTO-GENERATED CODE - SEE TOP FOR INSTRUCTIONS */
+  __u32 pad;
 };
 struct drm_tegra_waitchk {
   __u32 handle;
-  __u32 offset;
 /* WARNING: DO NOT EDIT, AUTO-GENERATED CODE - SEE TOP FOR INSTRUCTIONS */
+  __u32 offset;
   __u32 syncpt;
   __u32 thresh;
 };
-struct drm_tegra_submit {
 /* WARNING: DO NOT EDIT, AUTO-GENERATED CODE - SEE TOP FOR INSTRUCTIONS */
+struct drm_tegra_submit {
   __u64 context;
   __u32 num_syncpts;
   __u32 num_cmdbufs;
-  __u32 num_relocs;
 /* WARNING: DO NOT EDIT, AUTO-GENERATED CODE - SEE TOP FOR INSTRUCTIONS */
+  __u32 num_relocs;
   __u32 num_waitchks;
   __u32 waitchk_mask;
   __u32 timeout;
-  __u64 syncpts;
 /* WARNING: DO NOT EDIT, AUTO-GENERATED CODE - SEE TOP FOR INSTRUCTIONS */
+  __u64 syncpts;
   __u64 cmdbufs;
   __u64 relocs;
   __u64 waitchks;
-  __u32 fence;
 /* WARNING: DO NOT EDIT, AUTO-GENERATED CODE - SEE TOP FOR INSTRUCTIONS */
+  __u32 fence;
   __u32 reserved[5];
 };
 #define DRM_TEGRA_GEM_TILING_MODE_PITCH 0
-#define DRM_TEGRA_GEM_TILING_MODE_TILED 1
 /* WARNING: DO NOT EDIT, AUTO-GENERATED CODE - SEE TOP FOR INSTRUCTIONS */
+#define DRM_TEGRA_GEM_TILING_MODE_TILED 1
 #define DRM_TEGRA_GEM_TILING_MODE_BLOCK 2
 struct drm_tegra_gem_set_tiling {
   __u32 handle;
-  __u32 mode;
 /* WARNING: DO NOT EDIT, AUTO-GENERATED CODE - SEE TOP FOR INSTRUCTIONS */
+  __u32 mode;
   __u32 value;
   __u32 pad;
 };
-struct drm_tegra_gem_get_tiling {
 /* WARNING: DO NOT EDIT, AUTO-GENERATED CODE - SEE TOP FOR INSTRUCTIONS */
+struct drm_tegra_gem_get_tiling {
   __u32 handle;
   __u32 mode;
   __u32 value;
-  __u32 pad;
 /* WARNING: DO NOT EDIT, AUTO-GENERATED CODE - SEE TOP FOR INSTRUCTIONS */
+  __u32 pad;
 };
 #define DRM_TEGRA_GEM_BOTTOM_UP (1 << 0)
 #define DRM_TEGRA_GEM_FLAGS (DRM_TEGRA_GEM_BOTTOM_UP)
+/* WARNING: DO NOT EDIT, AUTO-GENERATED CODE - SEE TOP FOR INSTRUCTIONS */
 struct drm_tegra_gem_set_flags {
-/* WARNING: DO NOT EDIT, AUTO-GENERATED CODE - SEE TOP FOR INSTRUCTIONS */
   __u32 handle;
   __u32 flags;
 };
+/* WARNING: DO NOT EDIT, AUTO-GENERATED CODE - SEE TOP FOR INSTRUCTIONS */
 struct drm_tegra_gem_get_flags {
-/* WARNING: DO NOT EDIT, AUTO-GENERATED CODE - SEE TOP FOR INSTRUCTIONS */
   __u32 handle;
   __u32 flags;
 };
-#define DRM_TEGRA_GEM_CREATE 0x00
 /* WARNING: DO NOT EDIT, AUTO-GENERATED CODE - SEE TOP FOR INSTRUCTIONS */
+#define DRM_TEGRA_GEM_CREATE 0x00
 #define DRM_TEGRA_GEM_MMAP 0x01
 #define DRM_TEGRA_SYNCPT_READ 0x02
 #define DRM_TEGRA_SYNCPT_INCR 0x03
-#define DRM_TEGRA_SYNCPT_WAIT 0x04
 /* WARNING: DO NOT EDIT, AUTO-GENERATED CODE - SEE TOP FOR INSTRUCTIONS */
+#define DRM_TEGRA_SYNCPT_WAIT 0x04
 #define DRM_TEGRA_OPEN_CHANNEL 0x05
 #define DRM_TEGRA_CLOSE_CHANNEL 0x06
 #define DRM_TEGRA_GET_SYNCPT 0x07
-#define DRM_TEGRA_SUBMIT 0x08
 /* WARNING: DO NOT EDIT, AUTO-GENERATED CODE - SEE TOP FOR INSTRUCTIONS */
+#define DRM_TEGRA_SUBMIT 0x08
 #define DRM_TEGRA_GET_SYNCPT_BASE 0x09
 #define DRM_TEGRA_GEM_SET_TILING 0x0a
 #define DRM_TEGRA_GEM_GET_TILING 0x0b
-#define DRM_TEGRA_GEM_SET_FLAGS 0x0c
 /* WARNING: DO NOT EDIT, AUTO-GENERATED CODE - SEE TOP FOR INSTRUCTIONS */
+#define DRM_TEGRA_GEM_SET_FLAGS 0x0c
 #define DRM_TEGRA_GEM_GET_FLAGS 0x0d
 #define DRM_IOCTL_TEGRA_GEM_CREATE DRM_IOWR(DRM_COMMAND_BASE + DRM_TEGRA_GEM_CREATE, struct drm_tegra_gem_create)
 #define DRM_IOCTL_TEGRA_GEM_MMAP DRM_IOWR(DRM_COMMAND_BASE + DRM_TEGRA_GEM_MMAP, struct drm_tegra_gem_mmap)
-#define DRM_IOCTL_TEGRA_SYNCPT_READ DRM_IOWR(DRM_COMMAND_BASE + DRM_TEGRA_SYNCPT_READ, struct drm_tegra_syncpt_read)
 /* WARNING: DO NOT EDIT, AUTO-GENERATED CODE - SEE TOP FOR INSTRUCTIONS */
+#define DRM_IOCTL_TEGRA_SYNCPT_READ DRM_IOWR(DRM_COMMAND_BASE + DRM_TEGRA_SYNCPT_READ, struct drm_tegra_syncpt_read)
 #define DRM_IOCTL_TEGRA_SYNCPT_INCR DRM_IOWR(DRM_COMMAND_BASE + DRM_TEGRA_SYNCPT_INCR, struct drm_tegra_syncpt_incr)
 #define DRM_IOCTL_TEGRA_SYNCPT_WAIT DRM_IOWR(DRM_COMMAND_BASE + DRM_TEGRA_SYNCPT_WAIT, struct drm_tegra_syncpt_wait)
 #define DRM_IOCTL_TEGRA_OPEN_CHANNEL DRM_IOWR(DRM_COMMAND_BASE + DRM_TEGRA_OPEN_CHANNEL, struct drm_tegra_open_channel)
-#define DRM_IOCTL_TEGRA_CLOSE_CHANNEL DRM_IOWR(DRM_COMMAND_BASE + DRM_TEGRA_CLOSE_CHANNEL, struct drm_tegra_open_channel)
 /* WARNING: DO NOT EDIT, AUTO-GENERATED CODE - SEE TOP FOR INSTRUCTIONS */
+#define DRM_IOCTL_TEGRA_CLOSE_CHANNEL DRM_IOWR(DRM_COMMAND_BASE + DRM_TEGRA_CLOSE_CHANNEL, struct drm_tegra_open_channel)
 #define DRM_IOCTL_TEGRA_GET_SYNCPT DRM_IOWR(DRM_COMMAND_BASE + DRM_TEGRA_GET_SYNCPT, struct drm_tegra_get_syncpt)
 #define DRM_IOCTL_TEGRA_SUBMIT DRM_IOWR(DRM_COMMAND_BASE + DRM_TEGRA_SUBMIT, struct drm_tegra_submit)
 #define DRM_IOCTL_TEGRA_GET_SYNCPT_BASE DRM_IOWR(DRM_COMMAND_BASE + DRM_TEGRA_GET_SYNCPT_BASE, struct drm_tegra_get_syncpt_base)
-#define DRM_IOCTL_TEGRA_GEM_SET_TILING DRM_IOWR(DRM_COMMAND_BASE + DRM_TEGRA_GEM_SET_TILING, struct drm_tegra_gem_set_tiling)
 /* WARNING: DO NOT EDIT, AUTO-GENERATED CODE - SEE TOP FOR INSTRUCTIONS */
+#define DRM_IOCTL_TEGRA_GEM_SET_TILING DRM_IOWR(DRM_COMMAND_BASE + DRM_TEGRA_GEM_SET_TILING, struct drm_tegra_gem_set_tiling)
 #define DRM_IOCTL_TEGRA_GEM_GET_TILING DRM_IOWR(DRM_COMMAND_BASE + DRM_TEGRA_GEM_GET_TILING, struct drm_tegra_gem_get_tiling)
 #define DRM_IOCTL_TEGRA_GEM_SET_FLAGS DRM_IOWR(DRM_COMMAND_BASE + DRM_TEGRA_GEM_SET_FLAGS, struct drm_tegra_gem_set_flags)
 #define DRM_IOCTL_TEGRA_GEM_GET_FLAGS DRM_IOWR(DRM_COMMAND_BASE + DRM_TEGRA_GEM_GET_FLAGS, struct drm_tegra_gem_get_flags)
-#endif
 /* WARNING: DO NOT EDIT, AUTO-GENERATED CODE - SEE TOP FOR INSTRUCTIONS */
+#endif
diff --git a/libc/kernel/uapi/drm/via_drm.h b/libc/kernel/uapi/drm/via_drm.h
index 8be086c..18ac0b6 100644
--- a/libc/kernel/uapi/drm/via_drm.h
+++ b/libc/kernel/uapi/drm/via_drm.h
@@ -238,8 +238,4 @@
 /* WARNING: DO NOT EDIT, AUTO-GENERATED CODE - SEE TOP FOR INSTRUCTIONS */
   drm_via_blitsync_t sync;
 } drm_via_dmablit_t;
-struct via_file_private {
-  struct list_head obj_list;
-/* WARNING: DO NOT EDIT, AUTO-GENERATED CODE - SEE TOP FOR INSTRUCTIONS */
-};
 #endif
diff --git a/libc/kernel/uapi/drm/virtgpu_drm.h b/libc/kernel/uapi/drm/virtgpu_drm.h
new file mode 100644
index 0000000..94a82d1
--- /dev/null
+++ b/libc/kernel/uapi/drm/virtgpu_drm.h
@@ -0,0 +1,136 @@
+/****************************************************************************
+ ****************************************************************************
+ ***
+ ***   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 VIRTGPU_DRM_H
+#define VIRTGPU_DRM_H
+#include <stddef.h>
+#include "drm/drm.h"
+/* WARNING: DO NOT EDIT, AUTO-GENERATED CODE - SEE TOP FOR INSTRUCTIONS */
+#define DRM_VIRTGPU_MAP 0x01
+#define DRM_VIRTGPU_EXECBUFFER 0x02
+#define DRM_VIRTGPU_GETPARAM 0x03
+#define DRM_VIRTGPU_RESOURCE_CREATE 0x04
+/* WARNING: DO NOT EDIT, AUTO-GENERATED CODE - SEE TOP FOR INSTRUCTIONS */
+#define DRM_VIRTGPU_RESOURCE_INFO 0x05
+#define DRM_VIRTGPU_TRANSFER_FROM_HOST 0x06
+#define DRM_VIRTGPU_TRANSFER_TO_HOST 0x07
+#define DRM_VIRTGPU_WAIT 0x08
+/* WARNING: DO NOT EDIT, AUTO-GENERATED CODE - SEE TOP FOR INSTRUCTIONS */
+#define DRM_VIRTGPU_GET_CAPS 0x09
+struct drm_virtgpu_map {
+  uint64_t offset;
+  uint32_t handle;
+/* WARNING: DO NOT EDIT, AUTO-GENERATED CODE - SEE TOP FOR INSTRUCTIONS */
+  uint32_t pad;
+};
+struct drm_virtgpu_execbuffer {
+  uint32_t flags;
+/* WARNING: DO NOT EDIT, AUTO-GENERATED CODE - SEE TOP FOR INSTRUCTIONS */
+  uint32_t size;
+  uint64_t command;
+  uint64_t bo_handles;
+  uint32_t num_bo_handles;
+/* WARNING: DO NOT EDIT, AUTO-GENERATED CODE - SEE TOP FOR INSTRUCTIONS */
+  uint32_t pad;
+};
+#define VIRTGPU_PARAM_3D_FEATURES 1
+struct drm_virtgpu_getparam {
+/* WARNING: DO NOT EDIT, AUTO-GENERATED CODE - SEE TOP FOR INSTRUCTIONS */
+  uint64_t param;
+  uint64_t value;
+};
+struct drm_virtgpu_resource_create {
+/* WARNING: DO NOT EDIT, AUTO-GENERATED CODE - SEE TOP FOR INSTRUCTIONS */
+  uint32_t target;
+  uint32_t format;
+  uint32_t bind;
+  uint32_t width;
+/* WARNING: DO NOT EDIT, AUTO-GENERATED CODE - SEE TOP FOR INSTRUCTIONS */
+  uint32_t height;
+  uint32_t depth;
+  uint32_t array_size;
+  uint32_t last_level;
+/* WARNING: DO NOT EDIT, AUTO-GENERATED CODE - SEE TOP FOR INSTRUCTIONS */
+  uint32_t nr_samples;
+  uint32_t flags;
+  uint32_t bo_handle;
+  uint32_t res_handle;
+/* WARNING: DO NOT EDIT, AUTO-GENERATED CODE - SEE TOP FOR INSTRUCTIONS */
+  uint32_t size;
+  uint32_t stride;
+};
+struct drm_virtgpu_resource_info {
+/* WARNING: DO NOT EDIT, AUTO-GENERATED CODE - SEE TOP FOR INSTRUCTIONS */
+  uint32_t bo_handle;
+  uint32_t res_handle;
+  uint32_t size;
+  uint32_t stride;
+/* WARNING: DO NOT EDIT, AUTO-GENERATED CODE - SEE TOP FOR INSTRUCTIONS */
+};
+struct drm_virtgpu_3d_box {
+  uint32_t x;
+  uint32_t y;
+/* WARNING: DO NOT EDIT, AUTO-GENERATED CODE - SEE TOP FOR INSTRUCTIONS */
+  uint32_t z;
+  uint32_t w;
+  uint32_t h;
+  uint32_t d;
+/* WARNING: DO NOT EDIT, AUTO-GENERATED CODE - SEE TOP FOR INSTRUCTIONS */
+};
+struct drm_virtgpu_3d_transfer_to_host {
+  uint32_t bo_handle;
+  struct drm_virtgpu_3d_box box;
+/* WARNING: DO NOT EDIT, AUTO-GENERATED CODE - SEE TOP FOR INSTRUCTIONS */
+  uint32_t level;
+  uint32_t offset;
+};
+struct drm_virtgpu_3d_transfer_from_host {
+/* WARNING: DO NOT EDIT, AUTO-GENERATED CODE - SEE TOP FOR INSTRUCTIONS */
+  uint32_t bo_handle;
+  struct drm_virtgpu_3d_box box;
+  uint32_t level;
+  uint32_t offset;
+/* WARNING: DO NOT EDIT, AUTO-GENERATED CODE - SEE TOP FOR INSTRUCTIONS */
+};
+#define VIRTGPU_WAIT_NOWAIT 1
+struct drm_virtgpu_3d_wait {
+  uint32_t handle;
+/* WARNING: DO NOT EDIT, AUTO-GENERATED CODE - SEE TOP FOR INSTRUCTIONS */
+  uint32_t flags;
+};
+struct drm_virtgpu_get_caps {
+  uint32_t cap_set_id;
+/* WARNING: DO NOT EDIT, AUTO-GENERATED CODE - SEE TOP FOR INSTRUCTIONS */
+  uint32_t cap_set_ver;
+  uint64_t addr;
+  uint32_t size;
+  uint32_t pad;
+/* WARNING: DO NOT EDIT, AUTO-GENERATED CODE - SEE TOP FOR INSTRUCTIONS */
+};
+#define DRM_IOCTL_VIRTGPU_MAP DRM_IOWR(DRM_COMMAND_BASE + DRM_VIRTGPU_MAP, struct drm_virtgpu_map)
+#define DRM_IOCTL_VIRTGPU_EXECBUFFER DRM_IOW(DRM_COMMAND_BASE + DRM_VIRTGPU_EXECBUFFER, struct drm_virtgpu_execbuffer)
+#define DRM_IOCTL_VIRTGPU_GETPARAM DRM_IOWR(DRM_COMMAND_BASE + DRM_VIRTGPU_GETPARAM, struct drm_virtgpu_getparam)
+/* WARNING: DO NOT EDIT, AUTO-GENERATED CODE - SEE TOP FOR INSTRUCTIONS */
+#define DRM_IOCTL_VIRTGPU_RESOURCE_CREATE DRM_IOWR(DRM_COMMAND_BASE + DRM_VIRTGPU_RESOURCE_CREATE, struct drm_virtgpu_resource_create)
+#define DRM_IOCTL_VIRTGPU_RESOURCE_INFO DRM_IOWR(DRM_COMMAND_BASE + DRM_VIRTGPU_RESOURCE_INFO, struct drm_virtgpu_resource_info)
+#define DRM_IOCTL_VIRTGPU_TRANSFER_FROM_HOST DRM_IOWR(DRM_COMMAND_BASE + DRM_VIRTGPU_TRANSFER_FROM_HOST, struct drm_virtgpu_3d_transfer_from_host)
+#define DRM_IOCTL_VIRTGPU_TRANSFER_TO_HOST DRM_IOWR(DRM_COMMAND_BASE + DRM_VIRTGPU_TRANSFER_TO_HOST, struct drm_virtgpu_3d_transfer_to_host)
+/* WARNING: DO NOT EDIT, AUTO-GENERATED CODE - SEE TOP FOR INSTRUCTIONS */
+#define DRM_IOCTL_VIRTGPU_WAIT DRM_IOWR(DRM_COMMAND_BASE + DRM_VIRTGPU_WAIT, struct drm_virtgpu_3d_wait)
+#define DRM_IOCTL_VIRTGPU_GET_CAPS DRM_IOWR(DRM_COMMAND_BASE + DRM_VIRTGPU_GET_CAPS, struct drm_virtgpu_get_caps)
+#endif
diff --git a/libc/kernel/uapi/drm/vmwgfx_drm.h b/libc/kernel/uapi/drm/vmwgfx_drm.h
index c12cdd1..26762ab 100644
--- a/libc/kernel/uapi/drm/vmwgfx_drm.h
+++ b/libc/kernel/uapi/drm/vmwgfx_drm.h
@@ -54,244 +54,249 @@
 #define DRM_VMW_GB_SURFACE_CREATE 23
 #define DRM_VMW_GB_SURFACE_REF 24
 #define DRM_VMW_SYNCCPU 25
-#define DRM_VMW_PARAM_NUM_STREAMS 0
+#define DRM_VMW_CREATE_EXTENDED_CONTEXT 26
 /* WARNING: DO NOT EDIT, AUTO-GENERATED CODE - SEE TOP FOR INSTRUCTIONS */
+#define DRM_VMW_PARAM_NUM_STREAMS 0
 #define DRM_VMW_PARAM_NUM_FREE_STREAMS 1
 #define DRM_VMW_PARAM_3D 2
 #define DRM_VMW_PARAM_HW_CAPS 3
-#define DRM_VMW_PARAM_FIFO_CAPS 4
 /* WARNING: DO NOT EDIT, AUTO-GENERATED CODE - SEE TOP FOR INSTRUCTIONS */
+#define DRM_VMW_PARAM_FIFO_CAPS 4
 #define DRM_VMW_PARAM_MAX_FB_SIZE 5
 #define DRM_VMW_PARAM_FIFO_HW_VERSION 6
 #define DRM_VMW_PARAM_MAX_SURF_MEMORY 7
-#define DRM_VMW_PARAM_3D_CAPS_SIZE 8
 /* WARNING: DO NOT EDIT, AUTO-GENERATED CODE - SEE TOP FOR INSTRUCTIONS */
+#define DRM_VMW_PARAM_3D_CAPS_SIZE 8
 #define DRM_VMW_PARAM_MAX_MOB_MEMORY 9
 #define DRM_VMW_PARAM_MAX_MOB_SIZE 10
+#define DRM_VMW_PARAM_SCREEN_TARGET 11
+/* WARNING: DO NOT EDIT, AUTO-GENERATED CODE - SEE TOP FOR INSTRUCTIONS */
+#define DRM_VMW_PARAM_DX 12
 enum drm_vmw_handle_type {
   DRM_VMW_HANDLE_LEGACY = 0,
-/* WARNING: DO NOT EDIT, AUTO-GENERATED CODE - SEE TOP FOR INSTRUCTIONS */
   DRM_VMW_HANDLE_PRIME = 1
+/* WARNING: DO NOT EDIT, AUTO-GENERATED CODE - SEE TOP FOR INSTRUCTIONS */
 };
 struct drm_vmw_getparam_arg {
   uint64_t value;
-/* WARNING: DO NOT EDIT, AUTO-GENERATED CODE - SEE TOP FOR INSTRUCTIONS */
   uint32_t param;
+/* WARNING: DO NOT EDIT, AUTO-GENERATED CODE - SEE TOP FOR INSTRUCTIONS */
   uint32_t pad64;
 };
 struct drm_vmw_context_arg {
-/* WARNING: DO NOT EDIT, AUTO-GENERATED CODE - SEE TOP FOR INSTRUCTIONS */
   int32_t cid;
+/* WARNING: DO NOT EDIT, AUTO-GENERATED CODE - SEE TOP FOR INSTRUCTIONS */
   uint32_t pad64;
 };
 struct drm_vmw_surface_create_req {
-/* WARNING: DO NOT EDIT, AUTO-GENERATED CODE - SEE TOP FOR INSTRUCTIONS */
   uint32_t flags;
+/* WARNING: DO NOT EDIT, AUTO-GENERATED CODE - SEE TOP FOR INSTRUCTIONS */
   uint32_t format;
   uint32_t mip_levels[DRM_VMW_MAX_SURFACE_FACES];
   uint64_t size_addr;
-/* WARNING: DO NOT EDIT, AUTO-GENERATED CODE - SEE TOP FOR INSTRUCTIONS */
   int32_t shareable;
+/* WARNING: DO NOT EDIT, AUTO-GENERATED CODE - SEE TOP FOR INSTRUCTIONS */
   int32_t scanout;
 };
 struct drm_vmw_surface_arg {
-/* WARNING: DO NOT EDIT, AUTO-GENERATED CODE - SEE TOP FOR INSTRUCTIONS */
   int32_t sid;
+/* WARNING: DO NOT EDIT, AUTO-GENERATED CODE - SEE TOP FOR INSTRUCTIONS */
   enum drm_vmw_handle_type handle_type;
 };
 struct drm_vmw_size {
-/* WARNING: DO NOT EDIT, AUTO-GENERATED CODE - SEE TOP FOR INSTRUCTIONS */
   uint32_t width;
+/* WARNING: DO NOT EDIT, AUTO-GENERATED CODE - SEE TOP FOR INSTRUCTIONS */
   uint32_t height;
   uint32_t depth;
   uint32_t pad64;
-/* WARNING: DO NOT EDIT, AUTO-GENERATED CODE - SEE TOP FOR INSTRUCTIONS */
 };
+/* WARNING: DO NOT EDIT, AUTO-GENERATED CODE - SEE TOP FOR INSTRUCTIONS */
 union drm_vmw_surface_create_arg {
   struct drm_vmw_surface_arg rep;
   struct drm_vmw_surface_create_req req;
-/* WARNING: DO NOT EDIT, AUTO-GENERATED CODE - SEE TOP FOR INSTRUCTIONS */
 };
+/* WARNING: DO NOT EDIT, AUTO-GENERATED CODE - SEE TOP FOR INSTRUCTIONS */
 union drm_vmw_surface_reference_arg {
   struct drm_vmw_surface_create_req rep;
   struct drm_vmw_surface_arg req;
-/* WARNING: DO NOT EDIT, AUTO-GENERATED CODE - SEE TOP FOR INSTRUCTIONS */
 };
-#define DRM_VMW_EXECBUF_VERSION 1
+/* WARNING: DO NOT EDIT, AUTO-GENERATED CODE - SEE TOP FOR INSTRUCTIONS */
+#define DRM_VMW_EXECBUF_VERSION 2
 struct drm_vmw_execbuf_arg {
   uint64_t commands;
-/* WARNING: DO NOT EDIT, AUTO-GENERATED CODE - SEE TOP FOR INSTRUCTIONS */
   uint32_t command_size;
+/* WARNING: DO NOT EDIT, AUTO-GENERATED CODE - SEE TOP FOR INSTRUCTIONS */
   uint32_t throttle_us;
   uint64_t fence_rep;
   uint32_t version;
-/* WARNING: DO NOT EDIT, AUTO-GENERATED CODE - SEE TOP FOR INSTRUCTIONS */
   uint32_t flags;
+/* WARNING: DO NOT EDIT, AUTO-GENERATED CODE - SEE TOP FOR INSTRUCTIONS */
+  uint32_t context_handle;
+  uint32_t pad64;
 };
 struct drm_vmw_fence_rep {
-  uint32_t handle;
 /* WARNING: DO NOT EDIT, AUTO-GENERATED CODE - SEE TOP FOR INSTRUCTIONS */
+  uint32_t handle;
   uint32_t mask;
   uint32_t seqno;
   uint32_t passed_seqno;
-  uint32_t pad64;
 /* WARNING: DO NOT EDIT, AUTO-GENERATED CODE - SEE TOP FOR INSTRUCTIONS */
+  uint32_t pad64;
   int32_t error;
 };
 struct drm_vmw_alloc_dmabuf_req {
-  uint32_t size;
 /* WARNING: DO NOT EDIT, AUTO-GENERATED CODE - SEE TOP FOR INSTRUCTIONS */
+  uint32_t size;
   uint32_t pad64;
 };
 struct drm_vmw_dmabuf_rep {
-  uint64_t map_handle;
 /* WARNING: DO NOT EDIT, AUTO-GENERATED CODE - SEE TOP FOR INSTRUCTIONS */
+  uint64_t map_handle;
   uint32_t handle;
   uint32_t cur_gmr_id;
   uint32_t cur_gmr_offset;
-  uint32_t pad64;
 /* WARNING: DO NOT EDIT, AUTO-GENERATED CODE - SEE TOP FOR INSTRUCTIONS */
+  uint32_t pad64;
 };
 union drm_vmw_alloc_dmabuf_arg {
   struct drm_vmw_alloc_dmabuf_req req;
-  struct drm_vmw_dmabuf_rep rep;
 /* WARNING: DO NOT EDIT, AUTO-GENERATED CODE - SEE TOP FOR INSTRUCTIONS */
+  struct drm_vmw_dmabuf_rep rep;
 };
 struct drm_vmw_unref_dmabuf_arg {
   uint32_t handle;
-  uint32_t pad64;
 /* WARNING: DO NOT EDIT, AUTO-GENERATED CODE - SEE TOP FOR INSTRUCTIONS */
+  uint32_t pad64;
 };
 struct drm_vmw_rect {
   int32_t x;
-  int32_t y;
 /* WARNING: DO NOT EDIT, AUTO-GENERATED CODE - SEE TOP FOR INSTRUCTIONS */
+  int32_t y;
   uint32_t w;
   uint32_t h;
 };
-struct drm_vmw_control_stream_arg {
 /* WARNING: DO NOT EDIT, AUTO-GENERATED CODE - SEE TOP FOR INSTRUCTIONS */
+struct drm_vmw_control_stream_arg {
   uint32_t stream_id;
   uint32_t enabled;
   uint32_t flags;
-  uint32_t color_key;
 /* WARNING: DO NOT EDIT, AUTO-GENERATED CODE - SEE TOP FOR INSTRUCTIONS */
+  uint32_t color_key;
   uint32_t handle;
   uint32_t offset;
   int32_t format;
-  uint32_t size;
 /* WARNING: DO NOT EDIT, AUTO-GENERATED CODE - SEE TOP FOR INSTRUCTIONS */
+  uint32_t size;
   uint32_t width;
   uint32_t height;
   uint32_t pitch[3];
-  uint32_t pad64;
 /* WARNING: DO NOT EDIT, AUTO-GENERATED CODE - SEE TOP FOR INSTRUCTIONS */
+  uint32_t pad64;
   struct drm_vmw_rect src;
   struct drm_vmw_rect dst;
 };
-#define DRM_VMW_CURSOR_BYPASS_ALL (1 << 0)
 /* WARNING: DO NOT EDIT, AUTO-GENERATED CODE - SEE TOP FOR INSTRUCTIONS */
+#define DRM_VMW_CURSOR_BYPASS_ALL (1 << 0)
 #define DRM_VMW_CURSOR_BYPASS_FLAGS (1)
 struct drm_vmw_cursor_bypass_arg {
   uint32_t flags;
-  uint32_t crtc_id;
 /* WARNING: DO NOT EDIT, AUTO-GENERATED CODE - SEE TOP FOR INSTRUCTIONS */
+  uint32_t crtc_id;
   int32_t xpos;
   int32_t ypos;
   int32_t xhot;
-  int32_t yhot;
 /* WARNING: DO NOT EDIT, AUTO-GENERATED CODE - SEE TOP FOR INSTRUCTIONS */
+  int32_t yhot;
 };
 struct drm_vmw_stream_arg {
   uint32_t stream_id;
-  uint32_t pad64;
 /* WARNING: DO NOT EDIT, AUTO-GENERATED CODE - SEE TOP FOR INSTRUCTIONS */
+  uint32_t pad64;
 };
 struct drm_vmw_get_3d_cap_arg {
   uint64_t buffer;
-  uint32_t max_size;
 /* WARNING: DO NOT EDIT, AUTO-GENERATED CODE - SEE TOP FOR INSTRUCTIONS */
+  uint32_t max_size;
   uint32_t pad64;
 };
 #define DRM_VMW_FENCE_FLAG_EXEC (1 << 0)
-#define DRM_VMW_FENCE_FLAG_QUERY (1 << 1)
 /* WARNING: DO NOT EDIT, AUTO-GENERATED CODE - SEE TOP FOR INSTRUCTIONS */
+#define DRM_VMW_FENCE_FLAG_QUERY (1 << 1)
 #define DRM_VMW_WAIT_OPTION_UNREF (1 << 0)
 struct drm_vmw_fence_wait_arg {
   uint32_t handle;
-  int32_t cookie_valid;
 /* WARNING: DO NOT EDIT, AUTO-GENERATED CODE - SEE TOP FOR INSTRUCTIONS */
+  int32_t cookie_valid;
   uint64_t kernel_cookie;
   uint64_t timeout_us;
   int32_t lazy;
-  int32_t flags;
 /* WARNING: DO NOT EDIT, AUTO-GENERATED CODE - SEE TOP FOR INSTRUCTIONS */
+  int32_t flags;
   int32_t wait_options;
   int32_t pad64;
 };
-struct drm_vmw_fence_signaled_arg {
 /* WARNING: DO NOT EDIT, AUTO-GENERATED CODE - SEE TOP FOR INSTRUCTIONS */
+struct drm_vmw_fence_signaled_arg {
   uint32_t handle;
   uint32_t flags;
   int32_t signaled;
-  uint32_t passed_seqno;
 /* WARNING: DO NOT EDIT, AUTO-GENERATED CODE - SEE TOP FOR INSTRUCTIONS */
+  uint32_t passed_seqno;
   uint32_t signaled_flags;
   uint32_t pad64;
 };
-struct drm_vmw_fence_arg {
 /* WARNING: DO NOT EDIT, AUTO-GENERATED CODE - SEE TOP FOR INSTRUCTIONS */
+struct drm_vmw_fence_arg {
   uint32_t handle;
   uint32_t pad64;
 };
-#define DRM_VMW_EVENT_FENCE_SIGNALED 0x80000000
 /* WARNING: DO NOT EDIT, AUTO-GENERATED CODE - SEE TOP FOR INSTRUCTIONS */
+#define DRM_VMW_EVENT_FENCE_SIGNALED 0x80000000
 struct drm_vmw_event_fence {
   struct drm_event base;
   uint64_t user_data;
-  uint32_t tv_sec;
 /* WARNING: DO NOT EDIT, AUTO-GENERATED CODE - SEE TOP FOR INSTRUCTIONS */
+  uint32_t tv_sec;
   uint32_t tv_usec;
 };
 #define DRM_VMW_FE_FLAG_REQ_TIME (1 << 0)
-struct drm_vmw_fence_event_arg {
 /* WARNING: DO NOT EDIT, AUTO-GENERATED CODE - SEE TOP FOR INSTRUCTIONS */
+struct drm_vmw_fence_event_arg {
   uint64_t fence_rep;
   uint64_t user_data;
   uint32_t handle;
-  uint32_t flags;
 /* WARNING: DO NOT EDIT, AUTO-GENERATED CODE - SEE TOP FOR INSTRUCTIONS */
+  uint32_t flags;
 };
 struct drm_vmw_present_arg {
   uint32_t fb_id;
-  uint32_t sid;
 /* WARNING: DO NOT EDIT, AUTO-GENERATED CODE - SEE TOP FOR INSTRUCTIONS */
+  uint32_t sid;
   int32_t dest_x;
   int32_t dest_y;
   uint64_t clips_ptr;
-  uint32_t num_clips;
 /* WARNING: DO NOT EDIT, AUTO-GENERATED CODE - SEE TOP FOR INSTRUCTIONS */
+  uint32_t num_clips;
   uint32_t pad64;
 };
 struct drm_vmw_present_readback_arg {
-  uint32_t fb_id;
 /* WARNING: DO NOT EDIT, AUTO-GENERATED CODE - SEE TOP FOR INSTRUCTIONS */
+  uint32_t fb_id;
   uint32_t num_clips;
   uint64_t clips_ptr;
   uint64_t fence_rep;
-};
 /* WARNING: DO NOT EDIT, AUTO-GENERATED CODE - SEE TOP FOR INSTRUCTIONS */
+};
 struct drm_vmw_update_layout_arg {
   uint32_t num_outputs;
   uint32_t pad64;
-  uint64_t rects;
 /* WARNING: DO NOT EDIT, AUTO-GENERATED CODE - SEE TOP FOR INSTRUCTIONS */
+  uint64_t rects;
 };
 enum drm_vmw_shader_type {
   drm_vmw_shader_type_vs = 0,
-  drm_vmw_shader_type_ps,
 /* WARNING: DO NOT EDIT, AUTO-GENERATED CODE - SEE TOP FOR INSTRUCTIONS */
-  drm_vmw_shader_type_gs
+  drm_vmw_shader_type_ps,
 };
 struct drm_vmw_shader_create_arg {
   enum drm_vmw_shader_type shader_type;
@@ -323,7 +328,7 @@
 /* WARNING: DO NOT EDIT, AUTO-GENERATED CODE - SEE TOP FOR INSTRUCTIONS */
   uint32_t autogen_filter;
   uint32_t buffer_handle;
-  uint32_t pad64;
+  uint32_t array_size;
   struct drm_vmw_size base_size;
 /* WARNING: DO NOT EDIT, AUTO-GENERATED CODE - SEE TOP FOR INSTRUCTIONS */
 };
@@ -371,4 +376,14 @@
   uint32_t pad64;
 };
 /* WARNING: DO NOT EDIT, AUTO-GENERATED CODE - SEE TOP FOR INSTRUCTIONS */
+enum drm_vmw_extended_context {
+  drm_vmw_context_legacy,
+  drm_vmw_context_dx
+};
+/* WARNING: DO NOT EDIT, AUTO-GENERATED CODE - SEE TOP FOR INSTRUCTIONS */
+union drm_vmw_extended_context_arg {
+  enum drm_vmw_extended_context req;
+  struct drm_vmw_context_arg rep;
+};
+/* WARNING: DO NOT EDIT, AUTO-GENERATED CODE - SEE TOP FOR INSTRUCTIONS */
 #endif
diff --git a/libc/kernel/uapi/linux/am437x-vpfe.h b/libc/kernel/uapi/linux/am437x-vpfe.h
new file mode 100644
index 0000000..6a71994
--- /dev/null
+++ b/libc/kernel/uapi/linux/am437x-vpfe.h
@@ -0,0 +1,95 @@
+/****************************************************************************
+ ****************************************************************************
+ ***
+ ***   This header was automatically generated from a Linux kernel header
+ ***   of the same name, to make information necessary for userspace to
+ ***   call into the kernel available to libc.  It contains only constants,
+ ***   structures, and macros generated from the original header, and thus,
+ ***   contains no copyrightable information.
+ ***
+ ***   To edit the content of this header, modify the corresponding
+ ***   source file (e.g. under external/kernel-headers/original/) then
+ ***   run bionic/libc/kernel/tools/update_all.py
+ ***
+ ***   Any manual change here will be lost the next time this script will
+ ***   be run. You've been warned!
+ ***
+ ****************************************************************************
+ ****************************************************************************/
+#ifndef AM437X_VPFE_USER_H
+#define AM437X_VPFE_USER_H
+#include <linux/videodev2.h>
+enum vpfe_ccdc_data_size {
+/* WARNING: DO NOT EDIT, AUTO-GENERATED CODE - SEE TOP FOR INSTRUCTIONS */
+  VPFE_CCDC_DATA_16BITS = 0,
+  VPFE_CCDC_DATA_15BITS,
+  VPFE_CCDC_DATA_14BITS,
+  VPFE_CCDC_DATA_13BITS,
+/* WARNING: DO NOT EDIT, AUTO-GENERATED CODE - SEE TOP FOR INSTRUCTIONS */
+  VPFE_CCDC_DATA_12BITS,
+  VPFE_CCDC_DATA_11BITS,
+  VPFE_CCDC_DATA_10BITS,
+  VPFE_CCDC_DATA_8BITS,
+/* WARNING: DO NOT EDIT, AUTO-GENERATED CODE - SEE TOP FOR INSTRUCTIONS */
+};
+enum vpfe_ccdc_sample_length {
+  VPFE_CCDC_SAMPLE_1PIXELS = 0,
+  VPFE_CCDC_SAMPLE_2PIXELS,
+/* WARNING: DO NOT EDIT, AUTO-GENERATED CODE - SEE TOP FOR INSTRUCTIONS */
+  VPFE_CCDC_SAMPLE_4PIXELS,
+  VPFE_CCDC_SAMPLE_8PIXELS,
+  VPFE_CCDC_SAMPLE_16PIXELS,
+};
+/* WARNING: DO NOT EDIT, AUTO-GENERATED CODE - SEE TOP FOR INSTRUCTIONS */
+enum vpfe_ccdc_sample_line {
+  VPFE_CCDC_SAMPLE_1LINES = 0,
+  VPFE_CCDC_SAMPLE_2LINES,
+  VPFE_CCDC_SAMPLE_4LINES,
+/* WARNING: DO NOT EDIT, AUTO-GENERATED CODE - SEE TOP FOR INSTRUCTIONS */
+  VPFE_CCDC_SAMPLE_8LINES,
+  VPFE_CCDC_SAMPLE_16LINES,
+};
+enum vpfe_ccdc_gamma_width {
+/* WARNING: DO NOT EDIT, AUTO-GENERATED CODE - SEE TOP FOR INSTRUCTIONS */
+  VPFE_CCDC_GAMMA_BITS_15_6 = 0,
+  VPFE_CCDC_GAMMA_BITS_14_5,
+  VPFE_CCDC_GAMMA_BITS_13_4,
+  VPFE_CCDC_GAMMA_BITS_12_3,
+/* WARNING: DO NOT EDIT, AUTO-GENERATED CODE - SEE TOP FOR INSTRUCTIONS */
+  VPFE_CCDC_GAMMA_BITS_11_2,
+  VPFE_CCDC_GAMMA_BITS_10_1,
+  VPFE_CCDC_GAMMA_BITS_09_0,
+};
+/* WARNING: DO NOT EDIT, AUTO-GENERATED CODE - SEE TOP FOR INSTRUCTIONS */
+struct vpfe_ccdc_a_law {
+  unsigned char enable;
+  enum vpfe_ccdc_gamma_width gamma_wd;
+};
+/* WARNING: DO NOT EDIT, AUTO-GENERATED CODE - SEE TOP FOR INSTRUCTIONS */
+struct vpfe_ccdc_black_clamp {
+  unsigned char enable;
+  enum vpfe_ccdc_sample_length sample_pixel;
+  enum vpfe_ccdc_sample_line sample_ln;
+/* WARNING: DO NOT EDIT, AUTO-GENERATED CODE - SEE TOP FOR INSTRUCTIONS */
+  unsigned short start_pixel;
+  unsigned short sgain;
+  unsigned short dc_sub;
+};
+/* WARNING: DO NOT EDIT, AUTO-GENERATED CODE - SEE TOP FOR INSTRUCTIONS */
+struct vpfe_ccdc_black_compensation {
+  char r;
+  char gr;
+  char b;
+/* WARNING: DO NOT EDIT, AUTO-GENERATED CODE - SEE TOP FOR INSTRUCTIONS */
+  char gb;
+};
+struct vpfe_ccdc_config_params_raw {
+  enum vpfe_ccdc_data_size data_sz;
+/* WARNING: DO NOT EDIT, AUTO-GENERATED CODE - SEE TOP FOR INSTRUCTIONS */
+  struct vpfe_ccdc_a_law alaw;
+  struct vpfe_ccdc_black_clamp blk_clamp;
+  struct vpfe_ccdc_black_compensation blk_comp;
+};
+/* WARNING: DO NOT EDIT, AUTO-GENERATED CODE - SEE TOP FOR INSTRUCTIONS */
+#define VIDIOC_AM437X_CCDC_CFG _IOW('V', BASE_VIDIOC_PRIVATE + 1, void *)
+#endif
diff --git a/libc/kernel/uapi/linux/android/binder.h b/libc/kernel/uapi/linux/android/binder.h
new file mode 100644
index 0000000..6d465ae
--- /dev/null
+++ b/libc/kernel/uapi/linux/android/binder.h
@@ -0,0 +1,191 @@
+/****************************************************************************
+ ****************************************************************************
+ ***
+ ***   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_BINDER_H
+#define _UAPI_LINUX_BINDER_H
+#include <linux/types.h>
+#include <linux/ioctl.h>
+/* WARNING: DO NOT EDIT, AUTO-GENERATED CODE - SEE TOP FOR INSTRUCTIONS */
+#define B_PACK_CHARS(c1,c2,c3,c4) ((((c1) << 24)) | (((c2) << 16)) | (((c3) << 8)) | (c4))
+#define B_TYPE_LARGE 0x85
+enum {
+  BINDER_TYPE_BINDER = B_PACK_CHARS('s', 'b', '*', B_TYPE_LARGE),
+/* WARNING: DO NOT EDIT, AUTO-GENERATED CODE - SEE TOP FOR INSTRUCTIONS */
+  BINDER_TYPE_WEAK_BINDER = B_PACK_CHARS('w', 'b', '*', B_TYPE_LARGE),
+  BINDER_TYPE_HANDLE = B_PACK_CHARS('s', 'h', '*', B_TYPE_LARGE),
+  BINDER_TYPE_WEAK_HANDLE = B_PACK_CHARS('w', 'h', '*', B_TYPE_LARGE),
+  BINDER_TYPE_FD = B_PACK_CHARS('f', 'd', '*', B_TYPE_LARGE),
+/* WARNING: DO NOT EDIT, AUTO-GENERATED CODE - SEE TOP FOR INSTRUCTIONS */
+};
+enum {
+  FLAT_BINDER_FLAG_PRIORITY_MASK = 0xff,
+  FLAT_BINDER_FLAG_ACCEPTS_FDS = 0x100,
+/* WARNING: DO NOT EDIT, AUTO-GENERATED CODE - SEE TOP FOR INSTRUCTIONS */
+};
+#ifdef BINDER_IPC_32BIT
+typedef __u32 binder_size_t;
+typedef __u32 binder_uintptr_t;
+/* WARNING: DO NOT EDIT, AUTO-GENERATED CODE - SEE TOP FOR INSTRUCTIONS */
+#else
+typedef __u64 binder_size_t;
+typedef __u64 binder_uintptr_t;
+#endif
+/* WARNING: DO NOT EDIT, AUTO-GENERATED CODE - SEE TOP FOR INSTRUCTIONS */
+struct flat_binder_object {
+  __u32 type;
+  __u32 flags;
+  union {
+/* WARNING: DO NOT EDIT, AUTO-GENERATED CODE - SEE TOP FOR INSTRUCTIONS */
+    binder_uintptr_t binder;
+    __u32 handle;
+  };
+  binder_uintptr_t cookie;
+/* WARNING: DO NOT EDIT, AUTO-GENERATED CODE - SEE TOP FOR INSTRUCTIONS */
+};
+struct binder_write_read {
+  binder_size_t write_size;
+  binder_size_t write_consumed;
+/* WARNING: DO NOT EDIT, AUTO-GENERATED CODE - SEE TOP FOR INSTRUCTIONS */
+  binder_uintptr_t write_buffer;
+  binder_size_t read_size;
+  binder_size_t read_consumed;
+  binder_uintptr_t read_buffer;
+/* WARNING: DO NOT EDIT, AUTO-GENERATED CODE - SEE TOP FOR INSTRUCTIONS */
+};
+struct binder_version {
+  __s32 protocol_version;
+};
+/* WARNING: DO NOT EDIT, AUTO-GENERATED CODE - SEE TOP FOR INSTRUCTIONS */
+#ifdef BINDER_IPC_32BIT
+#define BINDER_CURRENT_PROTOCOL_VERSION 7
+#else
+#define BINDER_CURRENT_PROTOCOL_VERSION 8
+/* WARNING: DO NOT EDIT, AUTO-GENERATED CODE - SEE TOP FOR INSTRUCTIONS */
+#endif
+#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)
+/* WARNING: DO NOT EDIT, AUTO-GENERATED CODE - SEE TOP FOR INSTRUCTIONS */
+#define BINDER_SET_IDLE_PRIORITY _IOW('b', 6, __s32)
+#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)
+/* WARNING: DO NOT EDIT, AUTO-GENERATED CODE - SEE TOP FOR INSTRUCTIONS */
+enum transaction_flags {
+  TF_ONE_WAY = 0x01,
+  TF_ROOT_OBJECT = 0x04,
+  TF_STATUS_CODE = 0x08,
+/* WARNING: DO NOT EDIT, AUTO-GENERATED CODE - SEE TOP FOR INSTRUCTIONS */
+  TF_ACCEPT_FDS = 0x10,
+};
+struct binder_transaction_data {
+  union {
+/* WARNING: DO NOT EDIT, AUTO-GENERATED CODE - SEE TOP FOR INSTRUCTIONS */
+    __u32 handle;
+    binder_uintptr_t ptr;
+  } target;
+  binder_uintptr_t cookie;
+/* WARNING: DO NOT EDIT, AUTO-GENERATED CODE - SEE TOP FOR INSTRUCTIONS */
+  __u32 code;
+  __u32 flags;
+  pid_t sender_pid;
+  uid_t sender_euid;
+/* WARNING: DO NOT EDIT, AUTO-GENERATED CODE - SEE TOP FOR INSTRUCTIONS */
+  binder_size_t data_size;
+  binder_size_t offsets_size;
+  union {
+    struct {
+/* WARNING: DO NOT EDIT, AUTO-GENERATED CODE - SEE TOP FOR INSTRUCTIONS */
+      binder_uintptr_t buffer;
+      binder_uintptr_t offsets;
+    } ptr;
+    __u8 buf[8];
+/* WARNING: DO NOT EDIT, AUTO-GENERATED CODE - SEE TOP FOR INSTRUCTIONS */
+  } data;
+};
+struct binder_ptr_cookie {
+  binder_uintptr_t ptr;
+/* WARNING: DO NOT EDIT, AUTO-GENERATED CODE - SEE TOP FOR INSTRUCTIONS */
+  binder_uintptr_t cookie;
+};
+struct binder_handle_cookie {
+  __u32 handle;
+/* WARNING: DO NOT EDIT, AUTO-GENERATED CODE - SEE TOP FOR INSTRUCTIONS */
+  binder_uintptr_t cookie;
+} __packed;
+struct binder_pri_desc {
+  __s32 priority;
+/* WARNING: DO NOT EDIT, AUTO-GENERATED CODE - SEE TOP FOR INSTRUCTIONS */
+  __u32 desc;
+};
+struct binder_pri_ptr_cookie {
+  __s32 priority;
+/* WARNING: DO NOT EDIT, AUTO-GENERATED CODE - SEE TOP FOR INSTRUCTIONS */
+  binder_uintptr_t ptr;
+  binder_uintptr_t cookie;
+};
+enum binder_driver_return_protocol {
+/* WARNING: DO NOT EDIT, AUTO-GENERATED CODE - SEE TOP FOR INSTRUCTIONS */
+  BR_ERROR = _IOR('r', 0, __s32),
+  BR_OK = _IO('r', 1),
+  BR_TRANSACTION = _IOR('r', 2, struct binder_transaction_data),
+  BR_REPLY = _IOR('r', 3, struct binder_transaction_data),
+/* WARNING: DO NOT EDIT, AUTO-GENERATED CODE - SEE TOP FOR INSTRUCTIONS */
+  BR_ACQUIRE_RESULT = _IOR('r', 4, __s32),
+  BR_DEAD_REPLY = _IO('r', 5),
+  BR_TRANSACTION_COMPLETE = _IO('r', 6),
+  BR_INCREFS = _IOR('r', 7, struct binder_ptr_cookie),
+/* WARNING: DO NOT EDIT, AUTO-GENERATED CODE - SEE TOP FOR INSTRUCTIONS */
+  BR_ACQUIRE = _IOR('r', 8, struct binder_ptr_cookie),
+  BR_RELEASE = _IOR('r', 9, struct binder_ptr_cookie),
+  BR_DECREFS = _IOR('r', 10, struct binder_ptr_cookie),
+  BR_ATTEMPT_ACQUIRE = _IOR('r', 11, struct binder_pri_ptr_cookie),
+/* WARNING: DO NOT EDIT, AUTO-GENERATED CODE - SEE TOP FOR INSTRUCTIONS */
+  BR_NOOP = _IO('r', 12),
+  BR_SPAWN_LOOPER = _IO('r', 13),
+  BR_FINISHED = _IO('r', 14),
+  BR_DEAD_BINDER = _IOR('r', 15, binder_uintptr_t),
+/* WARNING: DO NOT EDIT, AUTO-GENERATED CODE - SEE TOP FOR INSTRUCTIONS */
+  BR_CLEAR_DEATH_NOTIFICATION_DONE = _IOR('r', 16, binder_uintptr_t),
+  BR_FAILED_REPLY = _IO('r', 17),
+};
+enum binder_driver_command_protocol {
+/* WARNING: DO NOT EDIT, AUTO-GENERATED CODE - SEE TOP FOR INSTRUCTIONS */
+  BC_TRANSACTION = _IOW('c', 0, struct binder_transaction_data),
+  BC_REPLY = _IOW('c', 1, struct binder_transaction_data),
+  BC_ACQUIRE_RESULT = _IOW('c', 2, __s32),
+  BC_FREE_BUFFER = _IOW('c', 3, binder_uintptr_t),
+/* WARNING: DO NOT EDIT, AUTO-GENERATED CODE - SEE TOP FOR INSTRUCTIONS */
+  BC_INCREFS = _IOW('c', 4, __u32),
+  BC_ACQUIRE = _IOW('c', 5, __u32),
+  BC_RELEASE = _IOW('c', 6, __u32),
+  BC_DECREFS = _IOW('c', 7, __u32),
+/* WARNING: DO NOT EDIT, AUTO-GENERATED CODE - SEE TOP FOR INSTRUCTIONS */
+  BC_INCREFS_DONE = _IOW('c', 8, struct binder_ptr_cookie),
+  BC_ACQUIRE_DONE = _IOW('c', 9, struct binder_ptr_cookie),
+  BC_ATTEMPT_ACQUIRE = _IOW('c', 10, struct binder_pri_desc),
+  BC_REGISTER_LOOPER = _IO('c', 11),
+/* WARNING: DO NOT EDIT, AUTO-GENERATED CODE - SEE TOP FOR INSTRUCTIONS */
+  BC_ENTER_LOOPER = _IO('c', 12),
+  BC_EXIT_LOOPER = _IO('c', 13),
+  BC_REQUEST_DEATH_NOTIFICATION = _IOW('c', 14, struct binder_handle_cookie),
+  BC_CLEAR_DEATH_NOTIFICATION = _IOW('c', 15, struct binder_handle_cookie),
+/* WARNING: DO NOT EDIT, AUTO-GENERATED CODE - SEE TOP FOR INSTRUCTIONS */
+  BC_DEAD_BINDER_DONE = _IOW('c', 16, binder_uintptr_t),
+};
+#endif
diff --git a/libc/kernel/uapi/linux/atm_zatm.h b/libc/kernel/uapi/linux/atm_zatm.h
index 34755bb..7f44195 100644
--- a/libc/kernel/uapi/linux/atm_zatm.h
+++ b/libc/kernel/uapi/linux/atm_zatm.h
@@ -38,11 +38,6 @@
 /* WARNING: DO NOT EDIT, AUTO-GENERATED CODE - SEE TOP FOR INSTRUCTIONS */
   struct zatm_pool_info info;
 };
-struct zatm_t_hist {
-  struct timeval real;
-/* WARNING: DO NOT EDIT, AUTO-GENERATED CODE - SEE TOP FOR INSTRUCTIONS */
-  struct timeval expected;
-};
 #define ZATM_OAM_POOL 0
 #define ZATM_AAL0_POOL 1
 /* WARNING: DO NOT EDIT, AUTO-GENERATED CODE - SEE TOP FOR INSTRUCTIONS */
diff --git a/libc/kernel/uapi/linux/audit.h b/libc/kernel/uapi/linux/audit.h
index da6c746..5c4389d 100644
--- a/libc/kernel/uapi/linux/audit.h
+++ b/libc/kernel/uapi/linux/audit.h
@@ -242,97 +242,107 @@
 #define AUDIT_OBJ_GID 110
 /* WARNING: DO NOT EDIT, AUTO-GENERATED CODE - SEE TOP FOR INSTRUCTIONS */
 #define AUDIT_FIELD_COMPARE 111
+#define AUDIT_EXE 112
 #define AUDIT_ARG0 200
 #define AUDIT_ARG1 (AUDIT_ARG0 + 1)
-#define AUDIT_ARG2 (AUDIT_ARG0 + 2)
 /* WARNING: DO NOT EDIT, AUTO-GENERATED CODE - SEE TOP FOR INSTRUCTIONS */
+#define AUDIT_ARG2 (AUDIT_ARG0 + 2)
 #define AUDIT_ARG3 (AUDIT_ARG0 + 3)
 #define AUDIT_FILTERKEY 210
 #define AUDIT_NEGATE 0x80000000
-#define AUDIT_BIT_MASK 0x08000000
 /* WARNING: DO NOT EDIT, AUTO-GENERATED CODE - SEE TOP FOR INSTRUCTIONS */
+#define AUDIT_BIT_MASK 0x08000000
 #define AUDIT_LESS_THAN 0x10000000
 #define AUDIT_GREATER_THAN 0x20000000
 #define AUDIT_NOT_EQUAL 0x30000000
-#define AUDIT_EQUAL 0x40000000
 /* WARNING: DO NOT EDIT, AUTO-GENERATED CODE - SEE TOP FOR INSTRUCTIONS */
+#define AUDIT_EQUAL 0x40000000
 #define AUDIT_BIT_TEST (AUDIT_BIT_MASK | AUDIT_EQUAL)
 #define AUDIT_LESS_THAN_OR_EQUAL (AUDIT_LESS_THAN | AUDIT_EQUAL)
 #define AUDIT_GREATER_THAN_OR_EQUAL (AUDIT_GREATER_THAN | AUDIT_EQUAL)
-#define AUDIT_OPERATORS (AUDIT_EQUAL | AUDIT_NOT_EQUAL | AUDIT_BIT_MASK)
 /* WARNING: DO NOT EDIT, AUTO-GENERATED CODE - SEE TOP FOR INSTRUCTIONS */
+#define AUDIT_OPERATORS (AUDIT_EQUAL | AUDIT_NOT_EQUAL | AUDIT_BIT_MASK)
 enum {
   Audit_equal,
   Audit_not_equal,
-  Audit_bitmask,
 /* WARNING: DO NOT EDIT, AUTO-GENERATED CODE - SEE TOP FOR INSTRUCTIONS */
+  Audit_bitmask,
   Audit_bittest,
   Audit_lt,
   Audit_gt,
-  Audit_le,
 /* WARNING: DO NOT EDIT, AUTO-GENERATED CODE - SEE TOP FOR INSTRUCTIONS */
+  Audit_le,
   Audit_ge,
   Audit_bad
 };
-#define AUDIT_STATUS_ENABLED 0x0001
 /* WARNING: DO NOT EDIT, AUTO-GENERATED CODE - SEE TOP FOR INSTRUCTIONS */
+#define AUDIT_STATUS_ENABLED 0x0001
 #define AUDIT_STATUS_FAILURE 0x0002
 #define AUDIT_STATUS_PID 0x0004
 #define AUDIT_STATUS_RATE_LIMIT 0x0008
+/* WARNING: DO NOT EDIT, AUTO-GENERATED CODE - SEE TOP FOR INSTRUCTIONS */
 #define AUDIT_STATUS_BACKLOG_LIMIT 0x0010
-/* WARNING: DO NOT EDIT, AUTO-GENERATED CODE - SEE TOP FOR INSTRUCTIONS */
 #define AUDIT_STATUS_BACKLOG_WAIT_TIME 0x0020
-#define AUDIT_VERSION_BACKLOG_LIMIT 1
-#define AUDIT_VERSION_BACKLOG_WAIT_TIME 2
-#define AUDIT_VERSION_LATEST AUDIT_VERSION_BACKLOG_WAIT_TIME
+#define AUDIT_FEATURE_BITMAP_BACKLOG_LIMIT 0x00000001
+#define AUDIT_FEATURE_BITMAP_BACKLOG_WAIT_TIME 0x00000002
 /* WARNING: DO NOT EDIT, AUTO-GENERATED CODE - SEE TOP FOR INSTRUCTIONS */
+#define AUDIT_FEATURE_BITMAP_EXECUTABLE_PATH 0x00000004
+#define AUDIT_FEATURE_BITMAP_ALL (AUDIT_FEATURE_BITMAP_BACKLOG_LIMIT | AUDIT_FEATURE_BITMAP_BACKLOG_WAIT_TIME | AUDIT_FEATURE_BITMAP_EXECUTABLE_PATH)
+#define AUDIT_VERSION_LATEST AUDIT_FEATURE_BITMAP_ALL
+#define AUDIT_VERSION_BACKLOG_LIMIT AUDIT_FEATURE_BITMAP_BACKLOG_LIMIT
+/* WARNING: DO NOT EDIT, AUTO-GENERATED CODE - SEE TOP FOR INSTRUCTIONS */
+#define AUDIT_VERSION_BACKLOG_WAIT_TIME AUDIT_FEATURE_BITMAP_BACKLOG_WAIT_TIME
 #define AUDIT_FAIL_SILENT 0
 #define AUDIT_FAIL_PRINTK 1
 #define AUDIT_FAIL_PANIC 2
-#define __AUDIT_ARCH_CONVENTION_MASK 0x30000000
 /* WARNING: DO NOT EDIT, AUTO-GENERATED CODE - SEE TOP FOR INSTRUCTIONS */
+#define __AUDIT_ARCH_CONVENTION_MASK 0x30000000
 #define __AUDIT_ARCH_CONVENTION_MIPS64_N32 0x20000000
 #define __AUDIT_ARCH_64BIT 0x80000000
 #define __AUDIT_ARCH_LE 0x40000000
-#define AUDIT_ARCH_AARCH64 (EM_AARCH64 | __AUDIT_ARCH_64BIT | __AUDIT_ARCH_LE)
 /* WARNING: DO NOT EDIT, AUTO-GENERATED CODE - SEE TOP FOR INSTRUCTIONS */
+#define AUDIT_ARCH_AARCH64 (EM_AARCH64 | __AUDIT_ARCH_64BIT | __AUDIT_ARCH_LE)
 #define AUDIT_ARCH_ALPHA (EM_ALPHA | __AUDIT_ARCH_64BIT | __AUDIT_ARCH_LE)
 #define AUDIT_ARCH_ARM (EM_ARM | __AUDIT_ARCH_LE)
 #define AUDIT_ARCH_ARMEB (EM_ARM)
-#define AUDIT_ARCH_CRIS (EM_CRIS | __AUDIT_ARCH_LE)
 /* WARNING: DO NOT EDIT, AUTO-GENERATED CODE - SEE TOP FOR INSTRUCTIONS */
+#define AUDIT_ARCH_CRIS (EM_CRIS | __AUDIT_ARCH_LE)
 #define AUDIT_ARCH_FRV (EM_FRV)
 #define AUDIT_ARCH_I386 (EM_386 | __AUDIT_ARCH_LE)
 #define AUDIT_ARCH_IA64 (EM_IA_64 | __AUDIT_ARCH_64BIT | __AUDIT_ARCH_LE)
-#define AUDIT_ARCH_M32R (EM_M32R)
 /* WARNING: DO NOT EDIT, AUTO-GENERATED CODE - SEE TOP FOR INSTRUCTIONS */
+#define AUDIT_ARCH_M32R (EM_M32R)
 #define AUDIT_ARCH_M68K (EM_68K)
 #define AUDIT_ARCH_MICROBLAZE (EM_MICROBLAZE)
 #define AUDIT_ARCH_MIPS (EM_MIPS)
-#define AUDIT_ARCH_MIPSEL (EM_MIPS | __AUDIT_ARCH_LE)
 /* WARNING: DO NOT EDIT, AUTO-GENERATED CODE - SEE TOP FOR INSTRUCTIONS */
+#define AUDIT_ARCH_MIPSEL (EM_MIPS | __AUDIT_ARCH_LE)
 #define AUDIT_ARCH_MIPS64 (EM_MIPS | __AUDIT_ARCH_64BIT)
 #define AUDIT_ARCH_MIPS64N32 (EM_MIPS | __AUDIT_ARCH_64BIT | __AUDIT_ARCH_CONVENTION_MIPS64_N32)
 #define AUDIT_ARCH_MIPSEL64 (EM_MIPS | __AUDIT_ARCH_64BIT | __AUDIT_ARCH_LE)
-#define AUDIT_ARCH_MIPSEL64N32 (EM_MIPS | __AUDIT_ARCH_64BIT | __AUDIT_ARCH_LE | __AUDIT_ARCH_CONVENTION_MIPS64_N32)
 /* WARNING: DO NOT EDIT, AUTO-GENERATED CODE - SEE TOP FOR INSTRUCTIONS */
+#define AUDIT_ARCH_MIPSEL64N32 (EM_MIPS | __AUDIT_ARCH_64BIT | __AUDIT_ARCH_LE | __AUDIT_ARCH_CONVENTION_MIPS64_N32)
 #define AUDIT_ARCH_OPENRISC (EM_OPENRISC)
 #define AUDIT_ARCH_PARISC (EM_PARISC)
 #define AUDIT_ARCH_PARISC64 (EM_PARISC | __AUDIT_ARCH_64BIT)
-#define AUDIT_ARCH_PPC (EM_PPC)
 /* WARNING: DO NOT EDIT, AUTO-GENERATED CODE - SEE TOP FOR INSTRUCTIONS */
+#define AUDIT_ARCH_PPC (EM_PPC)
 #define AUDIT_ARCH_PPC64 (EM_PPC64 | __AUDIT_ARCH_64BIT)
 #define AUDIT_ARCH_PPC64LE (EM_PPC64 | __AUDIT_ARCH_64BIT | __AUDIT_ARCH_LE)
 #define AUDIT_ARCH_S390 (EM_S390)
-#define AUDIT_ARCH_S390X (EM_S390 | __AUDIT_ARCH_64BIT)
 /* WARNING: DO NOT EDIT, AUTO-GENERATED CODE - SEE TOP FOR INSTRUCTIONS */
+#define AUDIT_ARCH_S390X (EM_S390 | __AUDIT_ARCH_64BIT)
 #define AUDIT_ARCH_SH (EM_SH)
 #define AUDIT_ARCH_SHEL (EM_SH | __AUDIT_ARCH_LE)
 #define AUDIT_ARCH_SH64 (EM_SH | __AUDIT_ARCH_64BIT)
-#define AUDIT_ARCH_SHEL64 (EM_SH | __AUDIT_ARCH_64BIT | __AUDIT_ARCH_LE)
 /* WARNING: DO NOT EDIT, AUTO-GENERATED CODE - SEE TOP FOR INSTRUCTIONS */
+#define AUDIT_ARCH_SHEL64 (EM_SH | __AUDIT_ARCH_64BIT | __AUDIT_ARCH_LE)
 #define AUDIT_ARCH_SPARC (EM_SPARC)
 #define AUDIT_ARCH_SPARC64 (EM_SPARCV9 | __AUDIT_ARCH_64BIT)
+#define AUDIT_ARCH_TILEGX (EM_TILEGX | __AUDIT_ARCH_64BIT | __AUDIT_ARCH_LE)
+/* WARNING: DO NOT EDIT, AUTO-GENERATED CODE - SEE TOP FOR INSTRUCTIONS */
+#define AUDIT_ARCH_TILEGX32 (EM_TILEGX | __AUDIT_ARCH_LE)
+#define AUDIT_ARCH_TILEPRO (EM_TILEPRO | __AUDIT_ARCH_LE)
 #define AUDIT_ARCH_X86_64 (EM_X86_64 | __AUDIT_ARCH_64BIT | __AUDIT_ARCH_LE)
 #define AUDIT_PERM_EXEC 1
 /* WARNING: DO NOT EDIT, AUTO-GENERATED CODE - SEE TOP FOR INSTRUCTIONS */
@@ -359,43 +369,47 @@
   __u32 backlog_limit;
   __u32 lost;
   __u32 backlog;
-  __u32 version;
+  union {
 /* WARNING: DO NOT EDIT, AUTO-GENERATED CODE - SEE TOP FOR INSTRUCTIONS */
+    __u32 version;
+    __u32 feature_bitmap;
+  };
   __u32 backlog_wait_time;
+/* WARNING: DO NOT EDIT, AUTO-GENERATED CODE - SEE TOP FOR INSTRUCTIONS */
 };
 struct audit_features {
 #define AUDIT_FEATURE_VERSION 1
-/* WARNING: DO NOT EDIT, AUTO-GENERATED CODE - SEE TOP FOR INSTRUCTIONS */
   __u32 vers;
+/* WARNING: DO NOT EDIT, AUTO-GENERATED CODE - SEE TOP FOR INSTRUCTIONS */
   __u32 mask;
   __u32 features;
   __u32 lock;
-/* WARNING: DO NOT EDIT, AUTO-GENERATED CODE - SEE TOP FOR INSTRUCTIONS */
 };
+/* WARNING: DO NOT EDIT, AUTO-GENERATED CODE - SEE TOP FOR INSTRUCTIONS */
 #define AUDIT_FEATURE_ONLY_UNSET_LOGINUID 0
 #define AUDIT_FEATURE_LOGINUID_IMMUTABLE 1
 #define AUDIT_LAST_FEATURE AUDIT_FEATURE_LOGINUID_IMMUTABLE
-/* WARNING: DO NOT EDIT, AUTO-GENERATED CODE - SEE TOP FOR INSTRUCTIONS */
 #define audit_feature_valid(x) ((x) >= 0 && (x) <= AUDIT_LAST_FEATURE)
+/* WARNING: DO NOT EDIT, AUTO-GENERATED CODE - SEE TOP FOR INSTRUCTIONS */
 #define AUDIT_FEATURE_TO_MASK(x) (1 << ((x) & 31))
 struct audit_tty_status {
   __u32 enabled;
-/* WARNING: DO NOT EDIT, AUTO-GENERATED CODE - SEE TOP FOR INSTRUCTIONS */
   __u32 log_passwd;
+/* WARNING: DO NOT EDIT, AUTO-GENERATED CODE - SEE TOP FOR INSTRUCTIONS */
 };
 #define AUDIT_UID_UNSET (unsigned int) - 1
 struct audit_rule_data {
-/* WARNING: DO NOT EDIT, AUTO-GENERATED CODE - SEE TOP FOR INSTRUCTIONS */
   __u32 flags;
+/* WARNING: DO NOT EDIT, AUTO-GENERATED CODE - SEE TOP FOR INSTRUCTIONS */
   __u32 action;
   __u32 field_count;
   __u32 mask[AUDIT_BITMASK_SIZE];
-/* WARNING: DO NOT EDIT, AUTO-GENERATED CODE - SEE TOP FOR INSTRUCTIONS */
   __u32 fields[AUDIT_MAX_FIELDS];
+/* WARNING: DO NOT EDIT, AUTO-GENERATED CODE - SEE TOP FOR INSTRUCTIONS */
   __u32 values[AUDIT_MAX_FIELDS];
   __u32 fieldflags[AUDIT_MAX_FIELDS];
   __u32 buflen;
-/* WARNING: DO NOT EDIT, AUTO-GENERATED CODE - SEE TOP FOR INSTRUCTIONS */
   char buf[0];
+/* WARNING: DO NOT EDIT, AUTO-GENERATED CODE - SEE TOP FOR INSTRUCTIONS */
 };
 #endif
diff --git a/libc/kernel/uapi/linux/blkpg.h b/libc/kernel/uapi/linux/blkpg.h
index 35b9730..97cb38d 100644
--- a/libc/kernel/uapi/linux/blkpg.h
+++ b/libc/kernel/uapi/linux/blkpg.h
@@ -16,8 +16,8 @@
  ***
  ****************************************************************************
  ****************************************************************************/
-#ifndef _LINUX_BLKPG_H
-#define _LINUX_BLKPG_H
+#ifndef _UAPI__LINUX_BLKPG_H
+#define _UAPI__LINUX_BLKPG_H
 #include <linux/compiler.h>
 #include <linux/ioctl.h>
 /* WARNING: DO NOT EDIT, AUTO-GENERATED CODE - SEE TOP FOR INSTRUCTIONS */
diff --git a/libc/kernel/uapi/linux/bpf.h b/libc/kernel/uapi/linux/bpf.h
index cc9f6d6..8a21996 100644
--- a/libc/kernel/uapi/linux/bpf.h
+++ b/libc/kernel/uapi/linux/bpf.h
@@ -76,49 +76,131 @@
   BPF_MAP_GET_NEXT_KEY,
   BPF_PROG_LOAD,
 /* WARNING: DO NOT EDIT, AUTO-GENERATED CODE - SEE TOP FOR INSTRUCTIONS */
+  BPF_OBJ_PIN,
+  BPF_OBJ_GET,
 };
 enum bpf_map_type {
-  BPF_MAP_TYPE_UNSPEC,
-};
 /* WARNING: DO NOT EDIT, AUTO-GENERATED CODE - SEE TOP FOR INSTRUCTIONS */
+  BPF_MAP_TYPE_UNSPEC,
+  BPF_MAP_TYPE_HASH,
+  BPF_MAP_TYPE_ARRAY,
+  BPF_MAP_TYPE_PROG_ARRAY,
+/* WARNING: DO NOT EDIT, AUTO-GENERATED CODE - SEE TOP FOR INSTRUCTIONS */
+  BPF_MAP_TYPE_PERF_EVENT_ARRAY,
+};
 enum bpf_prog_type {
   BPF_PROG_TYPE_UNSPEC,
-};
-union bpf_attr {
 /* WARNING: DO NOT EDIT, AUTO-GENERATED CODE - SEE TOP FOR INSTRUCTIONS */
+  BPF_PROG_TYPE_SOCKET_FILTER,
+  BPF_PROG_TYPE_KPROBE,
+  BPF_PROG_TYPE_SCHED_CLS,
+  BPF_PROG_TYPE_SCHED_ACT,
+/* WARNING: DO NOT EDIT, AUTO-GENERATED CODE - SEE TOP FOR INSTRUCTIONS */
+};
+#define BPF_PSEUDO_MAP_FD 1
+#define BPF_ANY 0
+#define BPF_NOEXIST 1
+/* WARNING: DO NOT EDIT, AUTO-GENERATED CODE - SEE TOP FOR INSTRUCTIONS */
+#define BPF_EXIST 2
+union bpf_attr {
   struct {
     __u32 map_type;
+/* WARNING: DO NOT EDIT, AUTO-GENERATED CODE - SEE TOP FOR INSTRUCTIONS */
     __u32 key_size;
     __u32 value_size;
-/* WARNING: DO NOT EDIT, AUTO-GENERATED CODE - SEE TOP FOR INSTRUCTIONS */
     __u32 max_entries;
   };
+/* WARNING: DO NOT EDIT, AUTO-GENERATED CODE - SEE TOP FOR INSTRUCTIONS */
   struct {
     __u32 map_fd;
-/* WARNING: DO NOT EDIT, AUTO-GENERATED CODE - SEE TOP FOR INSTRUCTIONS */
     __aligned_u64 key;
     union {
+/* WARNING: DO NOT EDIT, AUTO-GENERATED CODE - SEE TOP FOR INSTRUCTIONS */
       __aligned_u64 value;
       __aligned_u64 next_key;
-/* WARNING: DO NOT EDIT, AUTO-GENERATED CODE - SEE TOP FOR INSTRUCTIONS */
     };
+    __u64 flags;
+/* WARNING: DO NOT EDIT, AUTO-GENERATED CODE - SEE TOP FOR INSTRUCTIONS */
   };
   struct {
     __u32 prog_type;
-/* WARNING: DO NOT EDIT, AUTO-GENERATED CODE - SEE TOP FOR INSTRUCTIONS */
     __u32 insn_cnt;
+/* WARNING: DO NOT EDIT, AUTO-GENERATED CODE - SEE TOP FOR INSTRUCTIONS */
     __aligned_u64 insns;
     __aligned_u64 license;
     __u32 log_level;
-/* WARNING: DO NOT EDIT, AUTO-GENERATED CODE - SEE TOP FOR INSTRUCTIONS */
     __u32 log_size;
+/* WARNING: DO NOT EDIT, AUTO-GENERATED CODE - SEE TOP FOR INSTRUCTIONS */
     __aligned_u64 log_buf;
+    __u32 kern_version;
+  };
+  struct {
+/* WARNING: DO NOT EDIT, AUTO-GENERATED CODE - SEE TOP FOR INSTRUCTIONS */
+    __aligned_u64 pathname;
+    __u32 bpf_fd;
   };
 } __attribute__((aligned(8)));
 /* WARNING: DO NOT EDIT, AUTO-GENERATED CODE - SEE TOP FOR INSTRUCTIONS */
 enum bpf_func_id {
   BPF_FUNC_unspec,
-  __BPF_FUNC_MAX_ID,
-};
+  BPF_FUNC_map_lookup_elem,
+  BPF_FUNC_map_update_elem,
 /* WARNING: DO NOT EDIT, AUTO-GENERATED CODE - SEE TOP FOR INSTRUCTIONS */
+  BPF_FUNC_map_delete_elem,
+  BPF_FUNC_probe_read,
+  BPF_FUNC_ktime_get_ns,
+  BPF_FUNC_trace_printk,
+/* WARNING: DO NOT EDIT, AUTO-GENERATED CODE - SEE TOP FOR INSTRUCTIONS */
+  BPF_FUNC_get_prandom_u32,
+  BPF_FUNC_get_smp_processor_id,
+  BPF_FUNC_skb_store_bytes,
+  BPF_FUNC_l3_csum_replace,
+/* WARNING: DO NOT EDIT, AUTO-GENERATED CODE - SEE TOP FOR INSTRUCTIONS */
+  BPF_FUNC_l4_csum_replace,
+  BPF_FUNC_tail_call,
+  BPF_FUNC_clone_redirect,
+  BPF_FUNC_get_current_pid_tgid,
+/* WARNING: DO NOT EDIT, AUTO-GENERATED CODE - SEE TOP FOR INSTRUCTIONS */
+  BPF_FUNC_get_current_uid_gid,
+  BPF_FUNC_get_current_comm,
+  BPF_FUNC_get_cgroup_classid,
+  BPF_FUNC_skb_vlan_push,
+/* WARNING: DO NOT EDIT, AUTO-GENERATED CODE - SEE TOP FOR INSTRUCTIONS */
+  BPF_FUNC_skb_vlan_pop,
+  BPF_FUNC_skb_get_tunnel_key,
+  BPF_FUNC_skb_set_tunnel_key,
+  BPF_FUNC_perf_event_read,
+/* WARNING: DO NOT EDIT, AUTO-GENERATED CODE - SEE TOP FOR INSTRUCTIONS */
+  BPF_FUNC_redirect,
+  BPF_FUNC_get_route_realm,
+  BPF_FUNC_perf_event_output,
+  __BPF_FUNC_MAX_ID,
+/* WARNING: DO NOT EDIT, AUTO-GENERATED CODE - SEE TOP FOR INSTRUCTIONS */
+};
+struct __sk_buff {
+  __u32 len;
+  __u32 pkt_type;
+/* WARNING: DO NOT EDIT, AUTO-GENERATED CODE - SEE TOP FOR INSTRUCTIONS */
+  __u32 mark;
+  __u32 queue_mapping;
+  __u32 protocol;
+  __u32 vlan_present;
+/* WARNING: DO NOT EDIT, AUTO-GENERATED CODE - SEE TOP FOR INSTRUCTIONS */
+  __u32 vlan_tci;
+  __u32 vlan_proto;
+  __u32 priority;
+  __u32 ingress_ifindex;
+/* WARNING: DO NOT EDIT, AUTO-GENERATED CODE - SEE TOP FOR INSTRUCTIONS */
+  __u32 ifindex;
+  __u32 tc_index;
+  __u32 cb[5];
+  __u32 hash;
+/* WARNING: DO NOT EDIT, AUTO-GENERATED CODE - SEE TOP FOR INSTRUCTIONS */
+  __u32 tc_classid;
+};
+struct bpf_tunnel_key {
+  __u32 tunnel_id;
+/* WARNING: DO NOT EDIT, AUTO-GENERATED CODE - SEE TOP FOR INSTRUCTIONS */
+  __u32 remote_ipv4;
+};
 #endif
diff --git a/libc/kernel/uapi/linux/btrfs.h b/libc/kernel/uapi/linux/btrfs.h
index 8047f6a..98dacee 100644
--- a/libc/kernel/uapi/linux/btrfs.h
+++ b/libc/kernel/uapi/linux/btrfs.h
@@ -147,358 +147,375 @@
 #define BTRFS_IOCTL_DEV_REPLACE_RESULT_NOT_STARTED 1
 /* WARNING: DO NOT EDIT, AUTO-GENERATED CODE - SEE TOP FOR INSTRUCTIONS */
 #define BTRFS_IOCTL_DEV_REPLACE_RESULT_ALREADY_STARTED 2
+#define BTRFS_IOCTL_DEV_REPLACE_RESULT_SCRUB_INPROGRESS 3
 struct btrfs_ioctl_dev_replace_args {
   __u64 cmd;
-  __u64 result;
 /* WARNING: DO NOT EDIT, AUTO-GENERATED CODE - SEE TOP FOR INSTRUCTIONS */
+  __u64 result;
   union {
     struct btrfs_ioctl_dev_replace_start_params start;
     struct btrfs_ioctl_dev_replace_status_params status;
-  };
 /* WARNING: DO NOT EDIT, AUTO-GENERATED CODE - SEE TOP FOR INSTRUCTIONS */
+  };
   __u64 spare[64];
 };
 struct btrfs_ioctl_dev_info_args {
-  __u64 devid;
 /* WARNING: DO NOT EDIT, AUTO-GENERATED CODE - SEE TOP FOR INSTRUCTIONS */
+  __u64 devid;
   __u8 uuid[BTRFS_UUID_SIZE];
   __u64 bytes_used;
   __u64 total_bytes;
-  __u64 unused[379];
 /* WARNING: DO NOT EDIT, AUTO-GENERATED CODE - SEE TOP FOR INSTRUCTIONS */
+  __u64 unused[379];
   __u8 path[BTRFS_DEVICE_PATH_NAME_MAX];
 };
 struct btrfs_ioctl_fs_info_args {
-  __u64 max_id;
 /* WARNING: DO NOT EDIT, AUTO-GENERATED CODE - SEE TOP FOR INSTRUCTIONS */
+  __u64 max_id;
   __u64 num_devices;
   __u8 fsid[BTRFS_FSID_SIZE];
   __u32 nodesize;
-  __u32 sectorsize;
 /* WARNING: DO NOT EDIT, AUTO-GENERATED CODE - SEE TOP FOR INSTRUCTIONS */
+  __u32 sectorsize;
   __u32 clone_alignment;
   __u32 reserved32;
   __u64 reserved[122];
-};
 /* WARNING: DO NOT EDIT, AUTO-GENERATED CODE - SEE TOP FOR INSTRUCTIONS */
+};
 struct btrfs_ioctl_feature_flags {
   __u64 compat_flags;
   __u64 compat_ro_flags;
-  __u64 incompat_flags;
 /* WARNING: DO NOT EDIT, AUTO-GENERATED CODE - SEE TOP FOR INSTRUCTIONS */
+  __u64 incompat_flags;
 };
 #define BTRFS_BALANCE_CTL_PAUSE 1
 #define BTRFS_BALANCE_CTL_CANCEL 2
-struct btrfs_balance_args {
 /* WARNING: DO NOT EDIT, AUTO-GENERATED CODE - SEE TOP FOR INSTRUCTIONS */
+struct btrfs_balance_args {
   __u64 profiles;
-  __u64 usage;
+  union {
+    __le64 usage;
+/* WARNING: DO NOT EDIT, AUTO-GENERATED CODE - SEE TOP FOR INSTRUCTIONS */
+    struct {
+      __le32 usage_min;
+      __le32 usage_max;
+    };
+/* WARNING: DO NOT EDIT, AUTO-GENERATED CODE - SEE TOP FOR INSTRUCTIONS */
+  };
   __u64 devid;
   __u64 pstart;
-/* WARNING: DO NOT EDIT, AUTO-GENERATED CODE - SEE TOP FOR INSTRUCTIONS */
   __u64 pend;
+/* WARNING: DO NOT EDIT, AUTO-GENERATED CODE - SEE TOP FOR INSTRUCTIONS */
   __u64 vstart;
   __u64 vend;
   __u64 target;
-/* WARNING: DO NOT EDIT, AUTO-GENERATED CODE - SEE TOP FOR INSTRUCTIONS */
   __u64 flags;
-  __u64 limit;
-  __u64 unused[7];
-} __attribute__((__packed__));
 /* WARNING: DO NOT EDIT, AUTO-GENERATED CODE - SEE TOP FOR INSTRUCTIONS */
+  union {
+    __u64 limit;
+    struct {
+      __u32 limit_min;
+/* WARNING: DO NOT EDIT, AUTO-GENERATED CODE - SEE TOP FOR INSTRUCTIONS */
+      __u32 limit_max;
+    };
+  };
+  __le32 stripes_min;
+/* WARNING: DO NOT EDIT, AUTO-GENERATED CODE - SEE TOP FOR INSTRUCTIONS */
+  __le32 stripes_max;
+  __u64 unused[6];
+} __attribute__((__packed__));
 struct btrfs_balance_progress {
+/* WARNING: DO NOT EDIT, AUTO-GENERATED CODE - SEE TOP FOR INSTRUCTIONS */
   __u64 expected;
   __u64 considered;
   __u64 completed;
-/* WARNING: DO NOT EDIT, AUTO-GENERATED CODE - SEE TOP FOR INSTRUCTIONS */
 };
+/* WARNING: DO NOT EDIT, AUTO-GENERATED CODE - SEE TOP FOR INSTRUCTIONS */
 #define BTRFS_BALANCE_STATE_RUNNING (1ULL << 0)
 #define BTRFS_BALANCE_STATE_PAUSE_REQ (1ULL << 1)
 #define BTRFS_BALANCE_STATE_CANCEL_REQ (1ULL << 2)
-/* WARNING: DO NOT EDIT, AUTO-GENERATED CODE - SEE TOP FOR INSTRUCTIONS */
 struct btrfs_ioctl_balance_args {
+/* WARNING: DO NOT EDIT, AUTO-GENERATED CODE - SEE TOP FOR INSTRUCTIONS */
   __u64 flags;
   __u64 state;
   struct btrfs_balance_args data;
-/* WARNING: DO NOT EDIT, AUTO-GENERATED CODE - SEE TOP FOR INSTRUCTIONS */
   struct btrfs_balance_args meta;
+/* WARNING: DO NOT EDIT, AUTO-GENERATED CODE - SEE TOP FOR INSTRUCTIONS */
   struct btrfs_balance_args sys;
   struct btrfs_balance_progress stat;
   __u64 unused[72];
-/* WARNING: DO NOT EDIT, AUTO-GENERATED CODE - SEE TOP FOR INSTRUCTIONS */
 };
+/* WARNING: DO NOT EDIT, AUTO-GENERATED CODE - SEE TOP FOR INSTRUCTIONS */
 #define BTRFS_INO_LOOKUP_PATH_MAX 4080
 struct btrfs_ioctl_ino_lookup_args {
   __u64 treeid;
-/* WARNING: DO NOT EDIT, AUTO-GENERATED CODE - SEE TOP FOR INSTRUCTIONS */
   __u64 objectid;
+/* WARNING: DO NOT EDIT, AUTO-GENERATED CODE - SEE TOP FOR INSTRUCTIONS */
   char name[BTRFS_INO_LOOKUP_PATH_MAX];
 };
 struct btrfs_ioctl_search_key {
-/* WARNING: DO NOT EDIT, AUTO-GENERATED CODE - SEE TOP FOR INSTRUCTIONS */
   __u64 tree_id;
+/* WARNING: DO NOT EDIT, AUTO-GENERATED CODE - SEE TOP FOR INSTRUCTIONS */
   __u64 min_objectid;
   __u64 max_objectid;
   __u64 min_offset;
-/* WARNING: DO NOT EDIT, AUTO-GENERATED CODE - SEE TOP FOR INSTRUCTIONS */
   __u64 max_offset;
+/* WARNING: DO NOT EDIT, AUTO-GENERATED CODE - SEE TOP FOR INSTRUCTIONS */
   __u64 min_transid;
   __u64 max_transid;
   __u32 min_type;
-/* WARNING: DO NOT EDIT, AUTO-GENERATED CODE - SEE TOP FOR INSTRUCTIONS */
   __u32 max_type;
+/* WARNING: DO NOT EDIT, AUTO-GENERATED CODE - SEE TOP FOR INSTRUCTIONS */
   __u32 nr_items;
   __u32 unused;
   __u64 unused1;
-/* WARNING: DO NOT EDIT, AUTO-GENERATED CODE - SEE TOP FOR INSTRUCTIONS */
   __u64 unused2;
+/* WARNING: DO NOT EDIT, AUTO-GENERATED CODE - SEE TOP FOR INSTRUCTIONS */
   __u64 unused3;
   __u64 unused4;
 };
-/* WARNING: DO NOT EDIT, AUTO-GENERATED CODE - SEE TOP FOR INSTRUCTIONS */
 struct btrfs_ioctl_search_header {
+/* WARNING: DO NOT EDIT, AUTO-GENERATED CODE - SEE TOP FOR INSTRUCTIONS */
   __u64 transid;
   __u64 objectid;
   __u64 offset;
-/* WARNING: DO NOT EDIT, AUTO-GENERATED CODE - SEE TOP FOR INSTRUCTIONS */
   __u32 type;
+/* WARNING: DO NOT EDIT, AUTO-GENERATED CODE - SEE TOP FOR INSTRUCTIONS */
   __u32 len;
 };
 #define BTRFS_SEARCH_ARGS_BUFSIZE (4096 - sizeof(struct btrfs_ioctl_search_key))
-/* WARNING: DO NOT EDIT, AUTO-GENERATED CODE - SEE TOP FOR INSTRUCTIONS */
 struct btrfs_ioctl_search_args {
+/* WARNING: DO NOT EDIT, AUTO-GENERATED CODE - SEE TOP FOR INSTRUCTIONS */
   struct btrfs_ioctl_search_key key;
   char buf[BTRFS_SEARCH_ARGS_BUFSIZE];
 };
-/* WARNING: DO NOT EDIT, AUTO-GENERATED CODE - SEE TOP FOR INSTRUCTIONS */
 struct btrfs_ioctl_search_args_v2 {
+/* WARNING: DO NOT EDIT, AUTO-GENERATED CODE - SEE TOP FOR INSTRUCTIONS */
   struct btrfs_ioctl_search_key key;
   __u64 buf_size;
   __u64 buf[0];
-/* WARNING: DO NOT EDIT, AUTO-GENERATED CODE - SEE TOP FOR INSTRUCTIONS */
 };
+/* WARNING: DO NOT EDIT, AUTO-GENERATED CODE - SEE TOP FOR INSTRUCTIONS */
 struct btrfs_ioctl_clone_range_args {
   __s64 src_fd;
   __u64 src_offset, src_length;
-/* WARNING: DO NOT EDIT, AUTO-GENERATED CODE - SEE TOP FOR INSTRUCTIONS */
   __u64 dest_offset;
+/* WARNING: DO NOT EDIT, AUTO-GENERATED CODE - SEE TOP FOR INSTRUCTIONS */
 };
 #define BTRFS_DEFRAG_RANGE_COMPRESS 1
 #define BTRFS_DEFRAG_RANGE_START_IO 2
-/* WARNING: DO NOT EDIT, AUTO-GENERATED CODE - SEE TOP FOR INSTRUCTIONS */
 #define BTRFS_SAME_DATA_DIFFERS 1
+/* WARNING: DO NOT EDIT, AUTO-GENERATED CODE - SEE TOP FOR INSTRUCTIONS */
 struct btrfs_ioctl_same_extent_info {
   __s64 fd;
   __u64 logical_offset;
-/* WARNING: DO NOT EDIT, AUTO-GENERATED CODE - SEE TOP FOR INSTRUCTIONS */
   __u64 bytes_deduped;
+/* WARNING: DO NOT EDIT, AUTO-GENERATED CODE - SEE TOP FOR INSTRUCTIONS */
   __s32 status;
   __u32 reserved;
 };
-/* WARNING: DO NOT EDIT, AUTO-GENERATED CODE - SEE TOP FOR INSTRUCTIONS */
 struct btrfs_ioctl_same_args {
+/* WARNING: DO NOT EDIT, AUTO-GENERATED CODE - SEE TOP FOR INSTRUCTIONS */
   __u64 logical_offset;
   __u64 length;
   __u16 dest_count;
-/* WARNING: DO NOT EDIT, AUTO-GENERATED CODE - SEE TOP FOR INSTRUCTIONS */
   __u16 reserved1;
+/* WARNING: DO NOT EDIT, AUTO-GENERATED CODE - SEE TOP FOR INSTRUCTIONS */
   __u32 reserved2;
   struct btrfs_ioctl_same_extent_info info[0];
 };
-/* WARNING: DO NOT EDIT, AUTO-GENERATED CODE - SEE TOP FOR INSTRUCTIONS */
 struct btrfs_ioctl_space_info {
+/* WARNING: DO NOT EDIT, AUTO-GENERATED CODE - SEE TOP FOR INSTRUCTIONS */
   __u64 flags;
   __u64 total_bytes;
   __u64 used_bytes;
-/* WARNING: DO NOT EDIT, AUTO-GENERATED CODE - SEE TOP FOR INSTRUCTIONS */
 };
+/* WARNING: DO NOT EDIT, AUTO-GENERATED CODE - SEE TOP FOR INSTRUCTIONS */
 struct btrfs_ioctl_space_args {
   __u64 space_slots;
   __u64 total_spaces;
-/* WARNING: DO NOT EDIT, AUTO-GENERATED CODE - SEE TOP FOR INSTRUCTIONS */
   struct btrfs_ioctl_space_info spaces[0];
+/* WARNING: DO NOT EDIT, AUTO-GENERATED CODE - SEE TOP FOR INSTRUCTIONS */
 };
 struct btrfs_data_container {
   __u32 bytes_left;
-/* WARNING: DO NOT EDIT, AUTO-GENERATED CODE - SEE TOP FOR INSTRUCTIONS */
   __u32 bytes_missing;
+/* WARNING: DO NOT EDIT, AUTO-GENERATED CODE - SEE TOP FOR INSTRUCTIONS */
   __u32 elem_cnt;
   __u32 elem_missed;
   __u64 val[0];
-/* WARNING: DO NOT EDIT, AUTO-GENERATED CODE - SEE TOP FOR INSTRUCTIONS */
 };
+/* WARNING: DO NOT EDIT, AUTO-GENERATED CODE - SEE TOP FOR INSTRUCTIONS */
 struct btrfs_ioctl_ino_path_args {
   __u64 inum;
   __u64 size;
-/* WARNING: DO NOT EDIT, AUTO-GENERATED CODE - SEE TOP FOR INSTRUCTIONS */
   __u64 reserved[4];
+/* WARNING: DO NOT EDIT, AUTO-GENERATED CODE - SEE TOP FOR INSTRUCTIONS */
   __u64 fspath;
 };
 struct btrfs_ioctl_logical_ino_args {
-/* WARNING: DO NOT EDIT, AUTO-GENERATED CODE - SEE TOP FOR INSTRUCTIONS */
   __u64 logical;
+/* WARNING: DO NOT EDIT, AUTO-GENERATED CODE - SEE TOP FOR INSTRUCTIONS */
   __u64 size;
   __u64 reserved[4];
   __u64 inodes;
-/* WARNING: DO NOT EDIT, AUTO-GENERATED CODE - SEE TOP FOR INSTRUCTIONS */
 };
+/* WARNING: DO NOT EDIT, AUTO-GENERATED CODE - SEE TOP FOR INSTRUCTIONS */
 enum btrfs_dev_stat_values {
   BTRFS_DEV_STAT_WRITE_ERRS,
   BTRFS_DEV_STAT_READ_ERRS,
-/* WARNING: DO NOT EDIT, AUTO-GENERATED CODE - SEE TOP FOR INSTRUCTIONS */
   BTRFS_DEV_STAT_FLUSH_ERRS,
+/* WARNING: DO NOT EDIT, AUTO-GENERATED CODE - SEE TOP FOR INSTRUCTIONS */
   BTRFS_DEV_STAT_CORRUPTION_ERRS,
   BTRFS_DEV_STAT_GENERATION_ERRS,
   BTRFS_DEV_STAT_VALUES_MAX
-/* WARNING: DO NOT EDIT, AUTO-GENERATED CODE - SEE TOP FOR INSTRUCTIONS */
 };
+/* WARNING: DO NOT EDIT, AUTO-GENERATED CODE - SEE TOP FOR INSTRUCTIONS */
 #define BTRFS_DEV_STATS_RESET (1ULL << 0)
 struct btrfs_ioctl_get_dev_stats {
   __u64 devid;
-/* WARNING: DO NOT EDIT, AUTO-GENERATED CODE - SEE TOP FOR INSTRUCTIONS */
   __u64 nr_items;
+/* WARNING: DO NOT EDIT, AUTO-GENERATED CODE - SEE TOP FOR INSTRUCTIONS */
   __u64 flags;
   __u64 values[BTRFS_DEV_STAT_VALUES_MAX];
   __u64 unused[128 - 2 - BTRFS_DEV_STAT_VALUES_MAX];
-/* WARNING: DO NOT EDIT, AUTO-GENERATED CODE - SEE TOP FOR INSTRUCTIONS */
 };
+/* WARNING: DO NOT EDIT, AUTO-GENERATED CODE - SEE TOP FOR INSTRUCTIONS */
 #define BTRFS_QUOTA_CTL_ENABLE 1
 #define BTRFS_QUOTA_CTL_DISABLE 2
 #define BTRFS_QUOTA_CTL_RESCAN__NOTUSED 3
-/* WARNING: DO NOT EDIT, AUTO-GENERATED CODE - SEE TOP FOR INSTRUCTIONS */
 struct btrfs_ioctl_quota_ctl_args {
+/* WARNING: DO NOT EDIT, AUTO-GENERATED CODE - SEE TOP FOR INSTRUCTIONS */
   __u64 cmd;
   __u64 status;
 };
-/* WARNING: DO NOT EDIT, AUTO-GENERATED CODE - SEE TOP FOR INSTRUCTIONS */
 struct btrfs_ioctl_quota_rescan_args {
+/* WARNING: DO NOT EDIT, AUTO-GENERATED CODE - SEE TOP FOR INSTRUCTIONS */
   __u64 flags;
   __u64 progress;
   __u64 reserved[6];
-/* WARNING: DO NOT EDIT, AUTO-GENERATED CODE - SEE TOP FOR INSTRUCTIONS */
 };
+/* WARNING: DO NOT EDIT, AUTO-GENERATED CODE - SEE TOP FOR INSTRUCTIONS */
 struct btrfs_ioctl_qgroup_assign_args {
   __u64 assign;
   __u64 src;
-/* WARNING: DO NOT EDIT, AUTO-GENERATED CODE - SEE TOP FOR INSTRUCTIONS */
   __u64 dst;
+/* WARNING: DO NOT EDIT, AUTO-GENERATED CODE - SEE TOP FOR INSTRUCTIONS */
 };
 struct btrfs_ioctl_qgroup_create_args {
   __u64 create;
-/* WARNING: DO NOT EDIT, AUTO-GENERATED CODE - SEE TOP FOR INSTRUCTIONS */
   __u64 qgroupid;
+/* WARNING: DO NOT EDIT, AUTO-GENERATED CODE - SEE TOP FOR INSTRUCTIONS */
 };
 struct btrfs_ioctl_timespec {
   __u64 sec;
-/* WARNING: DO NOT EDIT, AUTO-GENERATED CODE - SEE TOP FOR INSTRUCTIONS */
   __u32 nsec;
+/* WARNING: DO NOT EDIT, AUTO-GENERATED CODE - SEE TOP FOR INSTRUCTIONS */
 };
 struct btrfs_ioctl_received_subvol_args {
   char uuid[BTRFS_UUID_SIZE];
-/* WARNING: DO NOT EDIT, AUTO-GENERATED CODE - SEE TOP FOR INSTRUCTIONS */
   __u64 stransid;
+/* WARNING: DO NOT EDIT, AUTO-GENERATED CODE - SEE TOP FOR INSTRUCTIONS */
   __u64 rtransid;
   struct btrfs_ioctl_timespec stime;
   struct btrfs_ioctl_timespec rtime;
-/* WARNING: DO NOT EDIT, AUTO-GENERATED CODE - SEE TOP FOR INSTRUCTIONS */
   __u64 flags;
+/* WARNING: DO NOT EDIT, AUTO-GENERATED CODE - SEE TOP FOR INSTRUCTIONS */
   __u64 reserved[16];
 };
 #define BTRFS_SEND_FLAG_NO_FILE_DATA 0x1
-/* WARNING: DO NOT EDIT, AUTO-GENERATED CODE - SEE TOP FOR INSTRUCTIONS */
 #define BTRFS_SEND_FLAG_OMIT_STREAM_HEADER 0x2
+/* WARNING: DO NOT EDIT, AUTO-GENERATED CODE - SEE TOP FOR INSTRUCTIONS */
 #define BTRFS_SEND_FLAG_OMIT_END_CMD 0x4
 #define BTRFS_SEND_FLAG_MASK (BTRFS_SEND_FLAG_NO_FILE_DATA | BTRFS_SEND_FLAG_OMIT_STREAM_HEADER | BTRFS_SEND_FLAG_OMIT_END_CMD)
 struct btrfs_ioctl_send_args {
-/* WARNING: DO NOT EDIT, AUTO-GENERATED CODE - SEE TOP FOR INSTRUCTIONS */
   __s64 send_fd;
+/* WARNING: DO NOT EDIT, AUTO-GENERATED CODE - SEE TOP FOR INSTRUCTIONS */
   __u64 clone_sources_count;
   __u64 __user * clone_sources;
   __u64 parent_root;
-/* WARNING: DO NOT EDIT, AUTO-GENERATED CODE - SEE TOP FOR INSTRUCTIONS */
   __u64 flags;
+/* WARNING: DO NOT EDIT, AUTO-GENERATED CODE - SEE TOP FOR INSTRUCTIONS */
   __u64 reserved[4];
 };
 enum btrfs_err_code {
+  BTRFS_ERROR_DEV_RAID1_MIN_NOT_MET = 1,
 /* WARNING: DO NOT EDIT, AUTO-GENERATED CODE - SEE TOP FOR INSTRUCTIONS */
-  notused,
-  BTRFS_ERROR_DEV_RAID1_MIN_NOT_MET,
   BTRFS_ERROR_DEV_RAID10_MIN_NOT_MET,
   BTRFS_ERROR_DEV_RAID5_MIN_NOT_MET,
-/* WARNING: DO NOT EDIT, AUTO-GENERATED CODE - SEE TOP FOR INSTRUCTIONS */
   BTRFS_ERROR_DEV_RAID6_MIN_NOT_MET,
   BTRFS_ERROR_DEV_TGT_REPLACE,
+/* WARNING: DO NOT EDIT, AUTO-GENERATED CODE - SEE TOP FOR INSTRUCTIONS */
   BTRFS_ERROR_DEV_MISSING_NOT_FOUND,
   BTRFS_ERROR_DEV_ONLY_WRITABLE,
-/* WARNING: DO NOT EDIT, AUTO-GENERATED CODE - SEE TOP FOR INSTRUCTIONS */
   BTRFS_ERROR_DEV_EXCL_RUN_IN_PROGRESS
 };
+/* WARNING: DO NOT EDIT, AUTO-GENERATED CODE - SEE TOP FOR INSTRUCTIONS */
 #define BTRFS_IOC_SNAP_CREATE _IOW(BTRFS_IOCTL_MAGIC, 1, struct btrfs_ioctl_vol_args)
 #define BTRFS_IOC_DEFRAG _IOW(BTRFS_IOCTL_MAGIC, 2, struct btrfs_ioctl_vol_args)
-/* WARNING: DO NOT EDIT, AUTO-GENERATED CODE - SEE TOP FOR INSTRUCTIONS */
 #define BTRFS_IOC_RESIZE _IOW(BTRFS_IOCTL_MAGIC, 3, struct btrfs_ioctl_vol_args)
 #define BTRFS_IOC_SCAN_DEV _IOW(BTRFS_IOCTL_MAGIC, 4, struct btrfs_ioctl_vol_args)
+/* WARNING: DO NOT EDIT, AUTO-GENERATED CODE - SEE TOP FOR INSTRUCTIONS */
 #define BTRFS_IOC_TRANS_START _IO(BTRFS_IOCTL_MAGIC, 6)
 #define BTRFS_IOC_TRANS_END _IO(BTRFS_IOCTL_MAGIC, 7)
-/* WARNING: DO NOT EDIT, AUTO-GENERATED CODE - SEE TOP FOR INSTRUCTIONS */
 #define BTRFS_IOC_SYNC _IO(BTRFS_IOCTL_MAGIC, 8)
 #define BTRFS_IOC_CLONE _IOW(BTRFS_IOCTL_MAGIC, 9, int)
+/* WARNING: DO NOT EDIT, AUTO-GENERATED CODE - SEE TOP FOR INSTRUCTIONS */
 #define BTRFS_IOC_ADD_DEV _IOW(BTRFS_IOCTL_MAGIC, 10, struct btrfs_ioctl_vol_args)
 #define BTRFS_IOC_RM_DEV _IOW(BTRFS_IOCTL_MAGIC, 11, struct btrfs_ioctl_vol_args)
-/* WARNING: DO NOT EDIT, AUTO-GENERATED CODE - SEE TOP FOR INSTRUCTIONS */
 #define BTRFS_IOC_BALANCE _IOW(BTRFS_IOCTL_MAGIC, 12, struct btrfs_ioctl_vol_args)
 #define BTRFS_IOC_CLONE_RANGE _IOW(BTRFS_IOCTL_MAGIC, 13, struct btrfs_ioctl_clone_range_args)
+/* WARNING: DO NOT EDIT, AUTO-GENERATED CODE - SEE TOP FOR INSTRUCTIONS */
 #define BTRFS_IOC_SUBVOL_CREATE _IOW(BTRFS_IOCTL_MAGIC, 14, struct btrfs_ioctl_vol_args)
 #define BTRFS_IOC_SNAP_DESTROY _IOW(BTRFS_IOCTL_MAGIC, 15, struct btrfs_ioctl_vol_args)
-/* WARNING: DO NOT EDIT, AUTO-GENERATED CODE - SEE TOP FOR INSTRUCTIONS */
 #define BTRFS_IOC_DEFRAG_RANGE _IOW(BTRFS_IOCTL_MAGIC, 16, struct btrfs_ioctl_defrag_range_args)
 #define BTRFS_IOC_TREE_SEARCH _IOWR(BTRFS_IOCTL_MAGIC, 17, struct btrfs_ioctl_search_args)
+/* WARNING: DO NOT EDIT, AUTO-GENERATED CODE - SEE TOP FOR INSTRUCTIONS */
 #define BTRFS_IOC_TREE_SEARCH_V2 _IOWR(BTRFS_IOCTL_MAGIC, 17, struct btrfs_ioctl_search_args_v2)
 #define BTRFS_IOC_INO_LOOKUP _IOWR(BTRFS_IOCTL_MAGIC, 18, struct btrfs_ioctl_ino_lookup_args)
-/* WARNING: DO NOT EDIT, AUTO-GENERATED CODE - SEE TOP FOR INSTRUCTIONS */
 #define BTRFS_IOC_DEFAULT_SUBVOL _IOW(BTRFS_IOCTL_MAGIC, 19, __u64)
 #define BTRFS_IOC_SPACE_INFO _IOWR(BTRFS_IOCTL_MAGIC, 20, struct btrfs_ioctl_space_args)
+/* WARNING: DO NOT EDIT, AUTO-GENERATED CODE - SEE TOP FOR INSTRUCTIONS */
 #define BTRFS_IOC_START_SYNC _IOR(BTRFS_IOCTL_MAGIC, 24, __u64)
 #define BTRFS_IOC_WAIT_SYNC _IOW(BTRFS_IOCTL_MAGIC, 22, __u64)
-/* WARNING: DO NOT EDIT, AUTO-GENERATED CODE - SEE TOP FOR INSTRUCTIONS */
 #define BTRFS_IOC_SNAP_CREATE_V2 _IOW(BTRFS_IOCTL_MAGIC, 23, struct btrfs_ioctl_vol_args_v2)
 #define BTRFS_IOC_SUBVOL_CREATE_V2 _IOW(BTRFS_IOCTL_MAGIC, 24, struct btrfs_ioctl_vol_args_v2)
+/* WARNING: DO NOT EDIT, AUTO-GENERATED CODE - SEE TOP FOR INSTRUCTIONS */
 #define BTRFS_IOC_SUBVOL_GETFLAGS _IOR(BTRFS_IOCTL_MAGIC, 25, __u64)
 #define BTRFS_IOC_SUBVOL_SETFLAGS _IOW(BTRFS_IOCTL_MAGIC, 26, __u64)
-/* WARNING: DO NOT EDIT, AUTO-GENERATED CODE - SEE TOP FOR INSTRUCTIONS */
 #define BTRFS_IOC_SCRUB _IOWR(BTRFS_IOCTL_MAGIC, 27, struct btrfs_ioctl_scrub_args)
 #define BTRFS_IOC_SCRUB_CANCEL _IO(BTRFS_IOCTL_MAGIC, 28)
+/* WARNING: DO NOT EDIT, AUTO-GENERATED CODE - SEE TOP FOR INSTRUCTIONS */
 #define BTRFS_IOC_SCRUB_PROGRESS _IOWR(BTRFS_IOCTL_MAGIC, 29, struct btrfs_ioctl_scrub_args)
 #define BTRFS_IOC_DEV_INFO _IOWR(BTRFS_IOCTL_MAGIC, 30, struct btrfs_ioctl_dev_info_args)
-/* WARNING: DO NOT EDIT, AUTO-GENERATED CODE - SEE TOP FOR INSTRUCTIONS */
 #define BTRFS_IOC_FS_INFO _IOR(BTRFS_IOCTL_MAGIC, 31, struct btrfs_ioctl_fs_info_args)
 #define BTRFS_IOC_BALANCE_V2 _IOWR(BTRFS_IOCTL_MAGIC, 32, struct btrfs_ioctl_balance_args)
+/* WARNING: DO NOT EDIT, AUTO-GENERATED CODE - SEE TOP FOR INSTRUCTIONS */
 #define BTRFS_IOC_BALANCE_CTL _IOW(BTRFS_IOCTL_MAGIC, 33, int)
 #define BTRFS_IOC_BALANCE_PROGRESS _IOR(BTRFS_IOCTL_MAGIC, 34, struct btrfs_ioctl_balance_args)
-/* WARNING: DO NOT EDIT, AUTO-GENERATED CODE - SEE TOP FOR INSTRUCTIONS */
 #define BTRFS_IOC_INO_PATHS _IOWR(BTRFS_IOCTL_MAGIC, 35, struct btrfs_ioctl_ino_path_args)
 #define BTRFS_IOC_LOGICAL_INO _IOWR(BTRFS_IOCTL_MAGIC, 36, struct btrfs_ioctl_ino_path_args)
+/* WARNING: DO NOT EDIT, AUTO-GENERATED CODE - SEE TOP FOR INSTRUCTIONS */
 #define BTRFS_IOC_SET_RECEIVED_SUBVOL _IOWR(BTRFS_IOCTL_MAGIC, 37, struct btrfs_ioctl_received_subvol_args)
 #define BTRFS_IOC_SEND _IOW(BTRFS_IOCTL_MAGIC, 38, struct btrfs_ioctl_send_args)
-/* WARNING: DO NOT EDIT, AUTO-GENERATED CODE - SEE TOP FOR INSTRUCTIONS */
 #define BTRFS_IOC_DEVICES_READY _IOR(BTRFS_IOCTL_MAGIC, 39, struct btrfs_ioctl_vol_args)
 #define BTRFS_IOC_QUOTA_CTL _IOWR(BTRFS_IOCTL_MAGIC, 40, struct btrfs_ioctl_quota_ctl_args)
+/* WARNING: DO NOT EDIT, AUTO-GENERATED CODE - SEE TOP FOR INSTRUCTIONS */
 #define BTRFS_IOC_QGROUP_ASSIGN _IOW(BTRFS_IOCTL_MAGIC, 41, struct btrfs_ioctl_qgroup_assign_args)
 #define BTRFS_IOC_QGROUP_CREATE _IOW(BTRFS_IOCTL_MAGIC, 42, struct btrfs_ioctl_qgroup_create_args)
-/* WARNING: DO NOT EDIT, AUTO-GENERATED CODE - SEE TOP FOR INSTRUCTIONS */
 #define BTRFS_IOC_QGROUP_LIMIT _IOR(BTRFS_IOCTL_MAGIC, 43, struct btrfs_ioctl_qgroup_limit_args)
 #define BTRFS_IOC_QUOTA_RESCAN _IOW(BTRFS_IOCTL_MAGIC, 44, struct btrfs_ioctl_quota_rescan_args)
+/* WARNING: DO NOT EDIT, AUTO-GENERATED CODE - SEE TOP FOR INSTRUCTIONS */
 #define BTRFS_IOC_QUOTA_RESCAN_STATUS _IOR(BTRFS_IOCTL_MAGIC, 45, struct btrfs_ioctl_quota_rescan_args)
 #define BTRFS_IOC_QUOTA_RESCAN_WAIT _IO(BTRFS_IOCTL_MAGIC, 46)
-/* WARNING: DO NOT EDIT, AUTO-GENERATED CODE - SEE TOP FOR INSTRUCTIONS */
 #define BTRFS_IOC_GET_FSLABEL _IOR(BTRFS_IOCTL_MAGIC, 49, char[BTRFS_LABEL_SIZE])
 #define BTRFS_IOC_SET_FSLABEL _IOW(BTRFS_IOCTL_MAGIC, 50, char[BTRFS_LABEL_SIZE])
+/* WARNING: DO NOT EDIT, AUTO-GENERATED CODE - SEE TOP FOR INSTRUCTIONS */
 #define BTRFS_IOC_GET_DEV_STATS _IOWR(BTRFS_IOCTL_MAGIC, 52, struct btrfs_ioctl_get_dev_stats)
 #define BTRFS_IOC_DEV_REPLACE _IOWR(BTRFS_IOCTL_MAGIC, 53, struct btrfs_ioctl_dev_replace_args)
-/* WARNING: DO NOT EDIT, AUTO-GENERATED CODE - SEE TOP FOR INSTRUCTIONS */
 #define BTRFS_IOC_FILE_EXTENT_SAME _IOWR(BTRFS_IOCTL_MAGIC, 54, struct btrfs_ioctl_same_args)
 #define BTRFS_IOC_GET_FEATURES _IOR(BTRFS_IOCTL_MAGIC, 57, struct btrfs_ioctl_feature_flags)
+/* WARNING: DO NOT EDIT, AUTO-GENERATED CODE - SEE TOP FOR INSTRUCTIONS */
 #define BTRFS_IOC_SET_FEATURES _IOW(BTRFS_IOCTL_MAGIC, 57, struct btrfs_ioctl_feature_flags[2])
 #define BTRFS_IOC_GET_SUPPORTED_FEATURES _IOR(BTRFS_IOCTL_MAGIC, 57, struct btrfs_ioctl_feature_flags[3])
-/* WARNING: DO NOT EDIT, AUTO-GENERATED CODE - SEE TOP FOR INSTRUCTIONS */
 #endif
diff --git a/libc/kernel/uapi/linux/can.h b/libc/kernel/uapi/linux/can.h
index 4c4f2c6..fc2c230 100644
--- a/libc/kernel/uapi/linux/can.h
+++ b/libc/kernel/uapi/linux/can.h
@@ -42,49 +42,53 @@
   canid_t can_id;
 /* WARNING: DO NOT EDIT, AUTO-GENERATED CODE - SEE TOP FOR INSTRUCTIONS */
   __u8 can_dlc;
+  __u8 __pad;
+  __u8 __res0;
+  __u8 __res1;
+/* WARNING: DO NOT EDIT, AUTO-GENERATED CODE - SEE TOP FOR INSTRUCTIONS */
   __u8 data[CAN_MAX_DLEN] __attribute__((aligned(8)));
 };
 #define CANFD_BRS 0x01
-/* WARNING: DO NOT EDIT, AUTO-GENERATED CODE - SEE TOP FOR INSTRUCTIONS */
 #define CANFD_ESI 0x02
+/* WARNING: DO NOT EDIT, AUTO-GENERATED CODE - SEE TOP FOR INSTRUCTIONS */
 struct canfd_frame {
   canid_t can_id;
   __u8 len;
-/* WARNING: DO NOT EDIT, AUTO-GENERATED CODE - SEE TOP FOR INSTRUCTIONS */
   __u8 flags;
+/* WARNING: DO NOT EDIT, AUTO-GENERATED CODE - SEE TOP FOR INSTRUCTIONS */
   __u8 __res0;
   __u8 __res1;
   __u8 data[CANFD_MAX_DLEN] __attribute__((aligned(8)));
-/* WARNING: DO NOT EDIT, AUTO-GENERATED CODE - SEE TOP FOR INSTRUCTIONS */
 };
+/* WARNING: DO NOT EDIT, AUTO-GENERATED CODE - SEE TOP FOR INSTRUCTIONS */
 #define CAN_MTU (sizeof(struct can_frame))
 #define CANFD_MTU (sizeof(struct canfd_frame))
 #define CAN_RAW 1
-/* WARNING: DO NOT EDIT, AUTO-GENERATED CODE - SEE TOP FOR INSTRUCTIONS */
 #define CAN_BCM 2
+/* WARNING: DO NOT EDIT, AUTO-GENERATED CODE - SEE TOP FOR INSTRUCTIONS */
 #define CAN_TP16 3
 #define CAN_TP20 4
 #define CAN_MCNET 5
-/* WARNING: DO NOT EDIT, AUTO-GENERATED CODE - SEE TOP FOR INSTRUCTIONS */
 #define CAN_ISOTP 6
+/* WARNING: DO NOT EDIT, AUTO-GENERATED CODE - SEE TOP FOR INSTRUCTIONS */
 #define CAN_NPROTO 7
 #define SOL_CAN_BASE 100
 struct sockaddr_can {
-/* WARNING: DO NOT EDIT, AUTO-GENERATED CODE - SEE TOP FOR INSTRUCTIONS */
   __kernel_sa_family_t can_family;
+/* WARNING: DO NOT EDIT, AUTO-GENERATED CODE - SEE TOP FOR INSTRUCTIONS */
   int can_ifindex;
   union {
     struct {
-/* WARNING: DO NOT EDIT, AUTO-GENERATED CODE - SEE TOP FOR INSTRUCTIONS */
       canid_t rx_id, tx_id;
+/* WARNING: DO NOT EDIT, AUTO-GENERATED CODE - SEE TOP FOR INSTRUCTIONS */
     } tp;
   } can_addr;
 };
-/* WARNING: DO NOT EDIT, AUTO-GENERATED CODE - SEE TOP FOR INSTRUCTIONS */
 struct can_filter {
+/* WARNING: DO NOT EDIT, AUTO-GENERATED CODE - SEE TOP FOR INSTRUCTIONS */
   canid_t can_id;
   canid_t can_mask;
 };
-/* WARNING: DO NOT EDIT, AUTO-GENERATED CODE - SEE TOP FOR INSTRUCTIONS */
 #define CAN_INV_FILTER 0x20000000U
+/* WARNING: DO NOT EDIT, AUTO-GENERATED CODE - SEE TOP FOR INSTRUCTIONS */
 #endif
diff --git a/libc/kernel/uapi/linux/can/bcm.h b/libc/kernel/uapi/linux/can/bcm.h
index 25d71e8..0a86166 100644
--- a/libc/kernel/uapi/linux/can/bcm.h
+++ b/libc/kernel/uapi/linux/can/bcm.h
@@ -21,12 +21,17 @@
 #include <linux/types.h>
 #include <linux/can.h>
 /* WARNING: DO NOT EDIT, AUTO-GENERATED CODE - SEE TOP FOR INSTRUCTIONS */
+struct bcm_timeval {
+  long tv_sec;
+  long tv_usec;
+};
+/* WARNING: DO NOT EDIT, AUTO-GENERATED CODE - SEE TOP FOR INSTRUCTIONS */
 struct bcm_msg_head {
   __u32 opcode;
   __u32 flags;
   __u32 count;
 /* WARNING: DO NOT EDIT, AUTO-GENERATED CODE - SEE TOP FOR INSTRUCTIONS */
-  struct timeval ival1, ival2;
+  struct bcm_timeval ival1, ival2;
   canid_t can_id;
   __u32 nframes;
   struct can_frame frames[0];
diff --git a/libc/kernel/uapi/linux/can/error.h b/libc/kernel/uapi/linux/can/error.h
index 46af758..59f1285 100644
--- a/libc/kernel/uapi/linux/can/error.h
+++ b/libc/kernel/uapi/linux/can/error.h
@@ -41,53 +41,54 @@
 #define CAN_ERR_CRTL_RX_PASSIVE 0x10
 #define CAN_ERR_CRTL_TX_PASSIVE 0x20
 /* WARNING: DO NOT EDIT, AUTO-GENERATED CODE - SEE TOP FOR INSTRUCTIONS */
+#define CAN_ERR_CRTL_ACTIVE 0x40
 #define CAN_ERR_PROT_UNSPEC 0x00
 #define CAN_ERR_PROT_BIT 0x01
 #define CAN_ERR_PROT_FORM 0x02
-#define CAN_ERR_PROT_STUFF 0x04
 /* WARNING: DO NOT EDIT, AUTO-GENERATED CODE - SEE TOP FOR INSTRUCTIONS */
+#define CAN_ERR_PROT_STUFF 0x04
 #define CAN_ERR_PROT_BIT0 0x08
 #define CAN_ERR_PROT_BIT1 0x10
 #define CAN_ERR_PROT_OVERLOAD 0x20
-#define CAN_ERR_PROT_ACTIVE 0x40
 /* WARNING: DO NOT EDIT, AUTO-GENERATED CODE - SEE TOP FOR INSTRUCTIONS */
+#define CAN_ERR_PROT_ACTIVE 0x40
 #define CAN_ERR_PROT_TX 0x80
 #define CAN_ERR_PROT_LOC_UNSPEC 0x00
 #define CAN_ERR_PROT_LOC_SOF 0x03
-#define CAN_ERR_PROT_LOC_ID28_21 0x02
 /* WARNING: DO NOT EDIT, AUTO-GENERATED CODE - SEE TOP FOR INSTRUCTIONS */
+#define CAN_ERR_PROT_LOC_ID28_21 0x02
 #define CAN_ERR_PROT_LOC_ID20_18 0x06
 #define CAN_ERR_PROT_LOC_SRTR 0x04
 #define CAN_ERR_PROT_LOC_IDE 0x05
-#define CAN_ERR_PROT_LOC_ID17_13 0x07
 /* WARNING: DO NOT EDIT, AUTO-GENERATED CODE - SEE TOP FOR INSTRUCTIONS */
+#define CAN_ERR_PROT_LOC_ID17_13 0x07
 #define CAN_ERR_PROT_LOC_ID12_05 0x0F
 #define CAN_ERR_PROT_LOC_ID04_00 0x0E
 #define CAN_ERR_PROT_LOC_RTR 0x0C
-#define CAN_ERR_PROT_LOC_RES1 0x0D
 /* WARNING: DO NOT EDIT, AUTO-GENERATED CODE - SEE TOP FOR INSTRUCTIONS */
+#define CAN_ERR_PROT_LOC_RES1 0x0D
 #define CAN_ERR_PROT_LOC_RES0 0x09
 #define CAN_ERR_PROT_LOC_DLC 0x0B
 #define CAN_ERR_PROT_LOC_DATA 0x0A
-#define CAN_ERR_PROT_LOC_CRC_SEQ 0x08
 /* WARNING: DO NOT EDIT, AUTO-GENERATED CODE - SEE TOP FOR INSTRUCTIONS */
+#define CAN_ERR_PROT_LOC_CRC_SEQ 0x08
 #define CAN_ERR_PROT_LOC_CRC_DEL 0x18
 #define CAN_ERR_PROT_LOC_ACK 0x19
 #define CAN_ERR_PROT_LOC_ACK_DEL 0x1B
-#define CAN_ERR_PROT_LOC_EOF 0x1A
 /* WARNING: DO NOT EDIT, AUTO-GENERATED CODE - SEE TOP FOR INSTRUCTIONS */
+#define CAN_ERR_PROT_LOC_EOF 0x1A
 #define CAN_ERR_PROT_LOC_INTERM 0x12
 #define CAN_ERR_TRX_UNSPEC 0x00
 #define CAN_ERR_TRX_CANH_NO_WIRE 0x04
-#define CAN_ERR_TRX_CANH_SHORT_TO_BAT 0x05
 /* WARNING: DO NOT EDIT, AUTO-GENERATED CODE - SEE TOP FOR INSTRUCTIONS */
+#define CAN_ERR_TRX_CANH_SHORT_TO_BAT 0x05
 #define CAN_ERR_TRX_CANH_SHORT_TO_VCC 0x06
 #define CAN_ERR_TRX_CANH_SHORT_TO_GND 0x07
 #define CAN_ERR_TRX_CANL_NO_WIRE 0x40
-#define CAN_ERR_TRX_CANL_SHORT_TO_BAT 0x50
 /* WARNING: DO NOT EDIT, AUTO-GENERATED CODE - SEE TOP FOR INSTRUCTIONS */
+#define CAN_ERR_TRX_CANL_SHORT_TO_BAT 0x50
 #define CAN_ERR_TRX_CANL_SHORT_TO_VCC 0x60
 #define CAN_ERR_TRX_CANL_SHORT_TO_GND 0x70
 #define CAN_ERR_TRX_CANL_SHORT_TO_CANH 0x80
-#endif
 /* WARNING: DO NOT EDIT, AUTO-GENERATED CODE - SEE TOP FOR INSTRUCTIONS */
+#endif
diff --git a/libc/kernel/uapi/linux/can/gw.h b/libc/kernel/uapi/linux/can/gw.h
index 37703fe..a9fd293 100644
--- a/libc/kernel/uapi/linux/can/gw.h
+++ b/libc/kernel/uapi/linux/can/gw.h
@@ -53,58 +53,59 @@
 /* WARNING: DO NOT EDIT, AUTO-GENERATED CODE - SEE TOP FOR INSTRUCTIONS */
   CGW_DELETED,
   CGW_LIM_HOPS,
+  CGW_MOD_UID,
   __CGW_MAX
-};
 /* WARNING: DO NOT EDIT, AUTO-GENERATED CODE - SEE TOP FOR INSTRUCTIONS */
+};
 #define CGW_MAX (__CGW_MAX - 1)
 #define CGW_FLAGS_CAN_ECHO 0x01
 #define CGW_FLAGS_CAN_SRC_TSTAMP 0x02
-#define CGW_FLAGS_CAN_IIF_TX_OK 0x04
 /* WARNING: DO NOT EDIT, AUTO-GENERATED CODE - SEE TOP FOR INSTRUCTIONS */
+#define CGW_FLAGS_CAN_IIF_TX_OK 0x04
 #define CGW_MOD_FUNCS 4
 #define CGW_MOD_ID 0x01
 #define CGW_MOD_DLC 0x02
-#define CGW_MOD_DATA 0x04
 /* WARNING: DO NOT EDIT, AUTO-GENERATED CODE - SEE TOP FOR INSTRUCTIONS */
+#define CGW_MOD_DATA 0x04
 #define CGW_FRAME_MODS 3
 #define MAX_MODFUNCTIONS (CGW_MOD_FUNCS * CGW_FRAME_MODS)
 struct cgw_frame_mod {
-  struct can_frame cf;
 /* WARNING: DO NOT EDIT, AUTO-GENERATED CODE - SEE TOP FOR INSTRUCTIONS */
+  struct can_frame cf;
   __u8 modtype;
 } __attribute__((packed));
 #define CGW_MODATTR_LEN sizeof(struct cgw_frame_mod)
-struct cgw_csum_xor {
 /* WARNING: DO NOT EDIT, AUTO-GENERATED CODE - SEE TOP FOR INSTRUCTIONS */
+struct cgw_csum_xor {
   __s8 from_idx;
   __s8 to_idx;
   __s8 result_idx;
-  __u8 init_xor_val;
 /* WARNING: DO NOT EDIT, AUTO-GENERATED CODE - SEE TOP FOR INSTRUCTIONS */
+  __u8 init_xor_val;
 } __attribute__((packed));
 struct cgw_csum_crc8 {
   __s8 from_idx;
-  __s8 to_idx;
 /* WARNING: DO NOT EDIT, AUTO-GENERATED CODE - SEE TOP FOR INSTRUCTIONS */
+  __s8 to_idx;
   __s8 result_idx;
   __u8 init_crc_val;
   __u8 final_xor_val;
-  __u8 crctab[256];
 /* WARNING: DO NOT EDIT, AUTO-GENERATED CODE - SEE TOP FOR INSTRUCTIONS */
+  __u8 crctab[256];
   __u8 profile;
   __u8 profile_data[20];
 } __attribute__((packed));
-#define CGW_CS_XOR_LEN sizeof(struct cgw_csum_xor)
 /* WARNING: DO NOT EDIT, AUTO-GENERATED CODE - SEE TOP FOR INSTRUCTIONS */
+#define CGW_CS_XOR_LEN sizeof(struct cgw_csum_xor)
 #define CGW_CS_CRC8_LEN sizeof(struct cgw_csum_crc8)
 enum {
   CGW_CRC8PRF_UNSPEC,
-  CGW_CRC8PRF_1U8,
 /* WARNING: DO NOT EDIT, AUTO-GENERATED CODE - SEE TOP FOR INSTRUCTIONS */
+  CGW_CRC8PRF_1U8,
   CGW_CRC8PRF_16U8,
   CGW_CRC8PRF_SFFID_XOR,
   __CGW_CRC8PRF_MAX
-};
 /* WARNING: DO NOT EDIT, AUTO-GENERATED CODE - SEE TOP FOR INSTRUCTIONS */
+};
 #define CGW_CRC8PRF_MAX (__CGW_CRC8PRF_MAX - 1)
 #endif
diff --git a/libc/kernel/uapi/linux/can/raw.h b/libc/kernel/uapi/linux/can/raw.h
index a70d881..0a19352 100644
--- a/libc/kernel/uapi/linux/can/raw.h
+++ b/libc/kernel/uapi/linux/can/raw.h
@@ -28,6 +28,7 @@
 /* WARNING: DO NOT EDIT, AUTO-GENERATED CODE - SEE TOP FOR INSTRUCTIONS */
   CAN_RAW_RECV_OWN_MSGS,
   CAN_RAW_FD_FRAMES,
+  CAN_RAW_JOIN_FILTERS,
 };
-#endif
 /* WARNING: DO NOT EDIT, AUTO-GENERATED CODE - SEE TOP FOR INSTRUCTIONS */
+#endif
diff --git a/libc/kernel/uapi/linux/cryptouser.h b/libc/kernel/uapi/linux/cryptouser.h
new file mode 100644
index 0000000..2a7bc39
--- /dev/null
+++ b/libc/kernel/uapi/linux/cryptouser.h
@@ -0,0 +1,111 @@
+/****************************************************************************
+ ****************************************************************************
+ ***
+ ***   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!
+ ***
+ ****************************************************************************
+ ****************************************************************************/
+enum {
+  CRYPTO_MSG_BASE = 0x10,
+  CRYPTO_MSG_NEWALG = 0x10,
+  CRYPTO_MSG_DELALG,
+/* WARNING: DO NOT EDIT, AUTO-GENERATED CODE - SEE TOP FOR INSTRUCTIONS */
+  CRYPTO_MSG_UPDATEALG,
+  CRYPTO_MSG_GETALG,
+  CRYPTO_MSG_DELRNG,
+  __CRYPTO_MSG_MAX
+/* WARNING: DO NOT EDIT, AUTO-GENERATED CODE - SEE TOP FOR INSTRUCTIONS */
+};
+#define CRYPTO_MSG_MAX (__CRYPTO_MSG_MAX - 1)
+#define CRYPTO_NR_MSGTYPES (CRYPTO_MSG_MAX + 1 - CRYPTO_MSG_BASE)
+#define CRYPTO_MAX_NAME CRYPTO_MAX_ALG_NAME
+/* WARNING: DO NOT EDIT, AUTO-GENERATED CODE - SEE TOP FOR INSTRUCTIONS */
+enum crypto_attr_type_t {
+  CRYPTOCFGA_UNSPEC,
+  CRYPTOCFGA_PRIORITY_VAL,
+  CRYPTOCFGA_REPORT_LARVAL,
+/* WARNING: DO NOT EDIT, AUTO-GENERATED CODE - SEE TOP FOR INSTRUCTIONS */
+  CRYPTOCFGA_REPORT_HASH,
+  CRYPTOCFGA_REPORT_BLKCIPHER,
+  CRYPTOCFGA_REPORT_AEAD,
+  CRYPTOCFGA_REPORT_COMPRESS,
+/* WARNING: DO NOT EDIT, AUTO-GENERATED CODE - SEE TOP FOR INSTRUCTIONS */
+  CRYPTOCFGA_REPORT_RNG,
+  CRYPTOCFGA_REPORT_CIPHER,
+  CRYPTOCFGA_REPORT_AKCIPHER,
+  __CRYPTOCFGA_MAX
+/* WARNING: DO NOT EDIT, AUTO-GENERATED CODE - SEE TOP FOR INSTRUCTIONS */
+#define CRYPTOCFGA_MAX (__CRYPTOCFGA_MAX - 1)
+};
+struct crypto_user_alg {
+  char cru_name[CRYPTO_MAX_ALG_NAME];
+/* WARNING: DO NOT EDIT, AUTO-GENERATED CODE - SEE TOP FOR INSTRUCTIONS */
+  char cru_driver_name[CRYPTO_MAX_ALG_NAME];
+  char cru_module_name[CRYPTO_MAX_ALG_NAME];
+  __u32 cru_type;
+  __u32 cru_mask;
+/* WARNING: DO NOT EDIT, AUTO-GENERATED CODE - SEE TOP FOR INSTRUCTIONS */
+  __u32 cru_refcnt;
+  __u32 cru_flags;
+};
+struct crypto_report_larval {
+/* WARNING: DO NOT EDIT, AUTO-GENERATED CODE - SEE TOP FOR INSTRUCTIONS */
+  char type[CRYPTO_MAX_NAME];
+};
+struct crypto_report_hash {
+  char type[CRYPTO_MAX_NAME];
+/* WARNING: DO NOT EDIT, AUTO-GENERATED CODE - SEE TOP FOR INSTRUCTIONS */
+  unsigned int blocksize;
+  unsigned int digestsize;
+};
+struct crypto_report_cipher {
+/* WARNING: DO NOT EDIT, AUTO-GENERATED CODE - SEE TOP FOR INSTRUCTIONS */
+  char type[CRYPTO_MAX_ALG_NAME];
+  unsigned int blocksize;
+  unsigned int min_keysize;
+  unsigned int max_keysize;
+/* WARNING: DO NOT EDIT, AUTO-GENERATED CODE - SEE TOP FOR INSTRUCTIONS */
+};
+struct crypto_report_blkcipher {
+  char type[CRYPTO_MAX_NAME];
+  char geniv[CRYPTO_MAX_NAME];
+/* WARNING: DO NOT EDIT, AUTO-GENERATED CODE - SEE TOP FOR INSTRUCTIONS */
+  unsigned int blocksize;
+  unsigned int min_keysize;
+  unsigned int max_keysize;
+  unsigned int ivsize;
+/* WARNING: DO NOT EDIT, AUTO-GENERATED CODE - SEE TOP FOR INSTRUCTIONS */
+};
+struct crypto_report_aead {
+  char type[CRYPTO_MAX_NAME];
+  char geniv[CRYPTO_MAX_NAME];
+/* WARNING: DO NOT EDIT, AUTO-GENERATED CODE - SEE TOP FOR INSTRUCTIONS */
+  unsigned int blocksize;
+  unsigned int maxauthsize;
+  unsigned int ivsize;
+};
+/* WARNING: DO NOT EDIT, AUTO-GENERATED CODE - SEE TOP FOR INSTRUCTIONS */
+struct crypto_report_comp {
+  char type[CRYPTO_MAX_NAME];
+};
+struct crypto_report_rng {
+/* WARNING: DO NOT EDIT, AUTO-GENERATED CODE - SEE TOP FOR INSTRUCTIONS */
+  char type[CRYPTO_MAX_NAME];
+  unsigned int seedsize;
+};
+struct crypto_report_akcipher {
+/* WARNING: DO NOT EDIT, AUTO-GENERATED CODE - SEE TOP FOR INSTRUCTIONS */
+  char type[CRYPTO_MAX_NAME];
+};
+#define CRYPTO_REPORT_MAXSIZE (sizeof(struct crypto_user_alg) + sizeof(struct crypto_report_blkcipher))
diff --git a/libc/kernel/uapi/linux/dcbnl.h b/libc/kernel/uapi/linux/dcbnl.h
index 2623b8e..e111f4b 100644
--- a/libc/kernel/uapi/linux/dcbnl.h
+++ b/libc/kernel/uapi/linux/dcbnl.h
@@ -44,6 +44,36 @@
 struct ieee_maxrate {
   __u64 tc_maxrate[IEEE_8021QAZ_MAX_TCS];
 };
+enum dcbnl_cndd_states {
+/* WARNING: DO NOT EDIT, AUTO-GENERATED CODE - SEE TOP FOR INSTRUCTIONS */
+  DCB_CNDD_RESET = 0,
+  DCB_CNDD_EDGE,
+  DCB_CNDD_INTERIOR,
+  DCB_CNDD_INTERIOR_READY,
+/* WARNING: DO NOT EDIT, AUTO-GENERATED CODE - SEE TOP FOR INSTRUCTIONS */
+};
+struct ieee_qcn {
+  __u8 rpg_enable[IEEE_8021QAZ_MAX_TCS];
+  __u32 rppp_max_rps[IEEE_8021QAZ_MAX_TCS];
+/* WARNING: DO NOT EDIT, AUTO-GENERATED CODE - SEE TOP FOR INSTRUCTIONS */
+  __u32 rpg_time_reset[IEEE_8021QAZ_MAX_TCS];
+  __u32 rpg_byte_reset[IEEE_8021QAZ_MAX_TCS];
+  __u32 rpg_threshold[IEEE_8021QAZ_MAX_TCS];
+  __u32 rpg_max_rate[IEEE_8021QAZ_MAX_TCS];
+/* WARNING: DO NOT EDIT, AUTO-GENERATED CODE - SEE TOP FOR INSTRUCTIONS */
+  __u32 rpg_ai_rate[IEEE_8021QAZ_MAX_TCS];
+  __u32 rpg_hai_rate[IEEE_8021QAZ_MAX_TCS];
+  __u32 rpg_gd[IEEE_8021QAZ_MAX_TCS];
+  __u32 rpg_min_dec_fac[IEEE_8021QAZ_MAX_TCS];
+/* WARNING: DO NOT EDIT, AUTO-GENERATED CODE - SEE TOP FOR INSTRUCTIONS */
+  __u32 rpg_min_rate[IEEE_8021QAZ_MAX_TCS];
+  __u32 cndd_state_machine[IEEE_8021QAZ_MAX_TCS];
+};
+struct ieee_qcn_stats {
+/* WARNING: DO NOT EDIT, AUTO-GENERATED CODE - SEE TOP FOR INSTRUCTIONS */
+  __u64 rppp_rp_centiseconds[IEEE_8021QAZ_MAX_TCS];
+  __u32 rppp_created_rps[IEEE_8021QAZ_MAX_TCS];
+};
 struct ieee_pfc {
 /* WARNING: DO NOT EDIT, AUTO-GENERATED CODE - SEE TOP FOR INSTRUCTIONS */
   __u8 pfc_cap;
@@ -174,213 +204,216 @@
   DCB_ATTR_IEEE_PEER_PFC,
   DCB_ATTR_IEEE_PEER_APP,
   DCB_ATTR_IEEE_MAXRATE,
-  __DCB_ATTR_IEEE_MAX
+  DCB_ATTR_IEEE_QCN,
 /* WARNING: DO NOT EDIT, AUTO-GENERATED CODE - SEE TOP FOR INSTRUCTIONS */
+  DCB_ATTR_IEEE_QCN_STATS,
+  __DCB_ATTR_IEEE_MAX
 };
 #define DCB_ATTR_IEEE_MAX (__DCB_ATTR_IEEE_MAX - 1)
+/* WARNING: DO NOT EDIT, AUTO-GENERATED CODE - SEE TOP FOR INSTRUCTIONS */
 enum ieee_attrs_app {
   DCB_ATTR_IEEE_APP_UNSPEC,
-/* WARNING: DO NOT EDIT, AUTO-GENERATED CODE - SEE TOP FOR INSTRUCTIONS */
   DCB_ATTR_IEEE_APP,
   __DCB_ATTR_IEEE_APP_MAX
+/* WARNING: DO NOT EDIT, AUTO-GENERATED CODE - SEE TOP FOR INSTRUCTIONS */
 };
 #define DCB_ATTR_IEEE_APP_MAX (__DCB_ATTR_IEEE_APP_MAX - 1)
-/* WARNING: DO NOT EDIT, AUTO-GENERATED CODE - SEE TOP FOR INSTRUCTIONS */
 enum cee_attrs {
   DCB_ATTR_CEE_UNSPEC,
+/* WARNING: DO NOT EDIT, AUTO-GENERATED CODE - SEE TOP FOR INSTRUCTIONS */
   DCB_ATTR_CEE_PEER_PG,
   DCB_ATTR_CEE_PEER_PFC,
-/* WARNING: DO NOT EDIT, AUTO-GENERATED CODE - SEE TOP FOR INSTRUCTIONS */
   DCB_ATTR_CEE_PEER_APP_TABLE,
   DCB_ATTR_CEE_TX_PG,
+/* WARNING: DO NOT EDIT, AUTO-GENERATED CODE - SEE TOP FOR INSTRUCTIONS */
   DCB_ATTR_CEE_RX_PG,
   DCB_ATTR_CEE_PFC,
-/* WARNING: DO NOT EDIT, AUTO-GENERATED CODE - SEE TOP FOR INSTRUCTIONS */
   DCB_ATTR_CEE_APP_TABLE,
   DCB_ATTR_CEE_FEAT,
+/* WARNING: DO NOT EDIT, AUTO-GENERATED CODE - SEE TOP FOR INSTRUCTIONS */
   __DCB_ATTR_CEE_MAX
 };
-/* WARNING: DO NOT EDIT, AUTO-GENERATED CODE - SEE TOP FOR INSTRUCTIONS */
 #define DCB_ATTR_CEE_MAX (__DCB_ATTR_CEE_MAX - 1)
 enum peer_app_attr {
+/* WARNING: DO NOT EDIT, AUTO-GENERATED CODE - SEE TOP FOR INSTRUCTIONS */
   DCB_ATTR_CEE_PEER_APP_UNSPEC,
   DCB_ATTR_CEE_PEER_APP_INFO,
-/* WARNING: DO NOT EDIT, AUTO-GENERATED CODE - SEE TOP FOR INSTRUCTIONS */
   DCB_ATTR_CEE_PEER_APP,
   __DCB_ATTR_CEE_PEER_APP_MAX
+/* WARNING: DO NOT EDIT, AUTO-GENERATED CODE - SEE TOP FOR INSTRUCTIONS */
 };
 #define DCB_ATTR_CEE_PEER_APP_MAX (__DCB_ATTR_CEE_PEER_APP_MAX - 1)
-/* WARNING: DO NOT EDIT, AUTO-GENERATED CODE - SEE TOP FOR INSTRUCTIONS */
 enum cee_attrs_app {
   DCB_ATTR_CEE_APP_UNSPEC,
+/* WARNING: DO NOT EDIT, AUTO-GENERATED CODE - SEE TOP FOR INSTRUCTIONS */
   DCB_ATTR_CEE_APP,
   __DCB_ATTR_CEE_APP_MAX
-/* WARNING: DO NOT EDIT, AUTO-GENERATED CODE - SEE TOP FOR INSTRUCTIONS */
 };
 #define DCB_ATTR_CEE_APP_MAX (__DCB_ATTR_CEE_APP_MAX - 1)
+/* WARNING: DO NOT EDIT, AUTO-GENERATED CODE - SEE TOP FOR INSTRUCTIONS */
 enum dcbnl_pfc_up_attrs {
   DCB_PFC_UP_ATTR_UNDEFINED,
-/* WARNING: DO NOT EDIT, AUTO-GENERATED CODE - SEE TOP FOR INSTRUCTIONS */
   DCB_PFC_UP_ATTR_0,
   DCB_PFC_UP_ATTR_1,
+/* WARNING: DO NOT EDIT, AUTO-GENERATED CODE - SEE TOP FOR INSTRUCTIONS */
   DCB_PFC_UP_ATTR_2,
   DCB_PFC_UP_ATTR_3,
-/* WARNING: DO NOT EDIT, AUTO-GENERATED CODE - SEE TOP FOR INSTRUCTIONS */
   DCB_PFC_UP_ATTR_4,
   DCB_PFC_UP_ATTR_5,
+/* WARNING: DO NOT EDIT, AUTO-GENERATED CODE - SEE TOP FOR INSTRUCTIONS */
   DCB_PFC_UP_ATTR_6,
   DCB_PFC_UP_ATTR_7,
-/* WARNING: DO NOT EDIT, AUTO-GENERATED CODE - SEE TOP FOR INSTRUCTIONS */
   DCB_PFC_UP_ATTR_ALL,
   __DCB_PFC_UP_ATTR_ENUM_MAX,
+/* WARNING: DO NOT EDIT, AUTO-GENERATED CODE - SEE TOP FOR INSTRUCTIONS */
   DCB_PFC_UP_ATTR_MAX = __DCB_PFC_UP_ATTR_ENUM_MAX - 1,
 };
-/* WARNING: DO NOT EDIT, AUTO-GENERATED CODE - SEE TOP FOR INSTRUCTIONS */
 enum dcbnl_pg_attrs {
   DCB_PG_ATTR_UNDEFINED,
+/* WARNING: DO NOT EDIT, AUTO-GENERATED CODE - SEE TOP FOR INSTRUCTIONS */
   DCB_PG_ATTR_TC_0,
   DCB_PG_ATTR_TC_1,
-/* WARNING: DO NOT EDIT, AUTO-GENERATED CODE - SEE TOP FOR INSTRUCTIONS */
   DCB_PG_ATTR_TC_2,
   DCB_PG_ATTR_TC_3,
+/* WARNING: DO NOT EDIT, AUTO-GENERATED CODE - SEE TOP FOR INSTRUCTIONS */
   DCB_PG_ATTR_TC_4,
   DCB_PG_ATTR_TC_5,
-/* WARNING: DO NOT EDIT, AUTO-GENERATED CODE - SEE TOP FOR INSTRUCTIONS */
   DCB_PG_ATTR_TC_6,
   DCB_PG_ATTR_TC_7,
+/* WARNING: DO NOT EDIT, AUTO-GENERATED CODE - SEE TOP FOR INSTRUCTIONS */
   DCB_PG_ATTR_TC_MAX,
   DCB_PG_ATTR_TC_ALL,
-/* WARNING: DO NOT EDIT, AUTO-GENERATED CODE - SEE TOP FOR INSTRUCTIONS */
   DCB_PG_ATTR_BW_ID_0,
   DCB_PG_ATTR_BW_ID_1,
+/* WARNING: DO NOT EDIT, AUTO-GENERATED CODE - SEE TOP FOR INSTRUCTIONS */
   DCB_PG_ATTR_BW_ID_2,
   DCB_PG_ATTR_BW_ID_3,
-/* WARNING: DO NOT EDIT, AUTO-GENERATED CODE - SEE TOP FOR INSTRUCTIONS */
   DCB_PG_ATTR_BW_ID_4,
   DCB_PG_ATTR_BW_ID_5,
+/* WARNING: DO NOT EDIT, AUTO-GENERATED CODE - SEE TOP FOR INSTRUCTIONS */
   DCB_PG_ATTR_BW_ID_6,
   DCB_PG_ATTR_BW_ID_7,
-/* WARNING: DO NOT EDIT, AUTO-GENERATED CODE - SEE TOP FOR INSTRUCTIONS */
   DCB_PG_ATTR_BW_ID_MAX,
   DCB_PG_ATTR_BW_ID_ALL,
+/* WARNING: DO NOT EDIT, AUTO-GENERATED CODE - SEE TOP FOR INSTRUCTIONS */
   __DCB_PG_ATTR_ENUM_MAX,
   DCB_PG_ATTR_MAX = __DCB_PG_ATTR_ENUM_MAX - 1,
-/* WARNING: DO NOT EDIT, AUTO-GENERATED CODE - SEE TOP FOR INSTRUCTIONS */
 };
 enum dcbnl_tc_attrs {
+/* WARNING: DO NOT EDIT, AUTO-GENERATED CODE - SEE TOP FOR INSTRUCTIONS */
   DCB_TC_ATTR_PARAM_UNDEFINED,
   DCB_TC_ATTR_PARAM_PGID,
-/* WARNING: DO NOT EDIT, AUTO-GENERATED CODE - SEE TOP FOR INSTRUCTIONS */
   DCB_TC_ATTR_PARAM_UP_MAPPING,
   DCB_TC_ATTR_PARAM_STRICT_PRIO,
+/* WARNING: DO NOT EDIT, AUTO-GENERATED CODE - SEE TOP FOR INSTRUCTIONS */
   DCB_TC_ATTR_PARAM_BW_PCT,
   DCB_TC_ATTR_PARAM_ALL,
-/* WARNING: DO NOT EDIT, AUTO-GENERATED CODE - SEE TOP FOR INSTRUCTIONS */
   __DCB_TC_ATTR_PARAM_ENUM_MAX,
   DCB_TC_ATTR_PARAM_MAX = __DCB_TC_ATTR_PARAM_ENUM_MAX - 1,
+/* WARNING: DO NOT EDIT, AUTO-GENERATED CODE - SEE TOP FOR INSTRUCTIONS */
 };
 enum dcbnl_cap_attrs {
-/* WARNING: DO NOT EDIT, AUTO-GENERATED CODE - SEE TOP FOR INSTRUCTIONS */
   DCB_CAP_ATTR_UNDEFINED,
   DCB_CAP_ATTR_ALL,
+/* WARNING: DO NOT EDIT, AUTO-GENERATED CODE - SEE TOP FOR INSTRUCTIONS */
   DCB_CAP_ATTR_PG,
   DCB_CAP_ATTR_PFC,
-/* WARNING: DO NOT EDIT, AUTO-GENERATED CODE - SEE TOP FOR INSTRUCTIONS */
   DCB_CAP_ATTR_UP2TC,
   DCB_CAP_ATTR_PG_TCS,
+/* WARNING: DO NOT EDIT, AUTO-GENERATED CODE - SEE TOP FOR INSTRUCTIONS */
   DCB_CAP_ATTR_PFC_TCS,
   DCB_CAP_ATTR_GSP,
-/* WARNING: DO NOT EDIT, AUTO-GENERATED CODE - SEE TOP FOR INSTRUCTIONS */
   DCB_CAP_ATTR_BCN,
   DCB_CAP_ATTR_DCBX,
+/* WARNING: DO NOT EDIT, AUTO-GENERATED CODE - SEE TOP FOR INSTRUCTIONS */
   __DCB_CAP_ATTR_ENUM_MAX,
   DCB_CAP_ATTR_MAX = __DCB_CAP_ATTR_ENUM_MAX - 1,
-/* WARNING: DO NOT EDIT, AUTO-GENERATED CODE - SEE TOP FOR INSTRUCTIONS */
 };
 #define DCB_CAP_DCBX_HOST 0x01
+/* WARNING: DO NOT EDIT, AUTO-GENERATED CODE - SEE TOP FOR INSTRUCTIONS */
 #define DCB_CAP_DCBX_LLD_MANAGED 0x02
 #define DCB_CAP_DCBX_VER_CEE 0x04
-/* WARNING: DO NOT EDIT, AUTO-GENERATED CODE - SEE TOP FOR INSTRUCTIONS */
 #define DCB_CAP_DCBX_VER_IEEE 0x08
 #define DCB_CAP_DCBX_STATIC 0x10
+/* WARNING: DO NOT EDIT, AUTO-GENERATED CODE - SEE TOP FOR INSTRUCTIONS */
 enum dcbnl_numtcs_attrs {
   DCB_NUMTCS_ATTR_UNDEFINED,
-/* WARNING: DO NOT EDIT, AUTO-GENERATED CODE - SEE TOP FOR INSTRUCTIONS */
   DCB_NUMTCS_ATTR_ALL,
   DCB_NUMTCS_ATTR_PG,
+/* WARNING: DO NOT EDIT, AUTO-GENERATED CODE - SEE TOP FOR INSTRUCTIONS */
   DCB_NUMTCS_ATTR_PFC,
   __DCB_NUMTCS_ATTR_ENUM_MAX,
-/* WARNING: DO NOT EDIT, AUTO-GENERATED CODE - SEE TOP FOR INSTRUCTIONS */
   DCB_NUMTCS_ATTR_MAX = __DCB_NUMTCS_ATTR_ENUM_MAX - 1,
 };
+/* WARNING: DO NOT EDIT, AUTO-GENERATED CODE - SEE TOP FOR INSTRUCTIONS */
 enum dcbnl_bcn_attrs {
   DCB_BCN_ATTR_UNDEFINED = 0,
-/* WARNING: DO NOT EDIT, AUTO-GENERATED CODE - SEE TOP FOR INSTRUCTIONS */
   DCB_BCN_ATTR_RP_0,
   DCB_BCN_ATTR_RP_1,
+/* WARNING: DO NOT EDIT, AUTO-GENERATED CODE - SEE TOP FOR INSTRUCTIONS */
   DCB_BCN_ATTR_RP_2,
   DCB_BCN_ATTR_RP_3,
-/* WARNING: DO NOT EDIT, AUTO-GENERATED CODE - SEE TOP FOR INSTRUCTIONS */
   DCB_BCN_ATTR_RP_4,
   DCB_BCN_ATTR_RP_5,
+/* WARNING: DO NOT EDIT, AUTO-GENERATED CODE - SEE TOP FOR INSTRUCTIONS */
   DCB_BCN_ATTR_RP_6,
   DCB_BCN_ATTR_RP_7,
-/* WARNING: DO NOT EDIT, AUTO-GENERATED CODE - SEE TOP FOR INSTRUCTIONS */
   DCB_BCN_ATTR_RP_ALL,
   DCB_BCN_ATTR_BCNA_0,
+/* WARNING: DO NOT EDIT, AUTO-GENERATED CODE - SEE TOP FOR INSTRUCTIONS */
   DCB_BCN_ATTR_BCNA_1,
   DCB_BCN_ATTR_ALPHA,
-/* WARNING: DO NOT EDIT, AUTO-GENERATED CODE - SEE TOP FOR INSTRUCTIONS */
   DCB_BCN_ATTR_BETA,
   DCB_BCN_ATTR_GD,
+/* WARNING: DO NOT EDIT, AUTO-GENERATED CODE - SEE TOP FOR INSTRUCTIONS */
   DCB_BCN_ATTR_GI,
   DCB_BCN_ATTR_TMAX,
-/* WARNING: DO NOT EDIT, AUTO-GENERATED CODE - SEE TOP FOR INSTRUCTIONS */
   DCB_BCN_ATTR_TD,
   DCB_BCN_ATTR_RMIN,
+/* WARNING: DO NOT EDIT, AUTO-GENERATED CODE - SEE TOP FOR INSTRUCTIONS */
   DCB_BCN_ATTR_W,
   DCB_BCN_ATTR_RD,
-/* WARNING: DO NOT EDIT, AUTO-GENERATED CODE - SEE TOP FOR INSTRUCTIONS */
   DCB_BCN_ATTR_RU,
   DCB_BCN_ATTR_WRTT,
+/* WARNING: DO NOT EDIT, AUTO-GENERATED CODE - SEE TOP FOR INSTRUCTIONS */
   DCB_BCN_ATTR_RI,
   DCB_BCN_ATTR_C,
-/* WARNING: DO NOT EDIT, AUTO-GENERATED CODE - SEE TOP FOR INSTRUCTIONS */
   DCB_BCN_ATTR_ALL,
   __DCB_BCN_ATTR_ENUM_MAX,
+/* WARNING: DO NOT EDIT, AUTO-GENERATED CODE - SEE TOP FOR INSTRUCTIONS */
   DCB_BCN_ATTR_MAX = __DCB_BCN_ATTR_ENUM_MAX - 1,
 };
-/* WARNING: DO NOT EDIT, AUTO-GENERATED CODE - SEE TOP FOR INSTRUCTIONS */
 enum dcb_general_attr_values {
   DCB_ATTR_VALUE_UNDEFINED = 0xff
+/* WARNING: DO NOT EDIT, AUTO-GENERATED CODE - SEE TOP FOR INSTRUCTIONS */
 };
 #define DCB_APP_IDTYPE_ETHTYPE 0x00
-/* WARNING: DO NOT EDIT, AUTO-GENERATED CODE - SEE TOP FOR INSTRUCTIONS */
 #define DCB_APP_IDTYPE_PORTNUM 0x01
 enum dcbnl_app_attrs {
+/* WARNING: DO NOT EDIT, AUTO-GENERATED CODE - SEE TOP FOR INSTRUCTIONS */
   DCB_APP_ATTR_UNDEFINED,
   DCB_APP_ATTR_IDTYPE,
-/* WARNING: DO NOT EDIT, AUTO-GENERATED CODE - SEE TOP FOR INSTRUCTIONS */
   DCB_APP_ATTR_ID,
   DCB_APP_ATTR_PRIORITY,
+/* WARNING: DO NOT EDIT, AUTO-GENERATED CODE - SEE TOP FOR INSTRUCTIONS */
   __DCB_APP_ATTR_ENUM_MAX,
   DCB_APP_ATTR_MAX = __DCB_APP_ATTR_ENUM_MAX - 1,
-/* WARNING: DO NOT EDIT, AUTO-GENERATED CODE - SEE TOP FOR INSTRUCTIONS */
 };
 #define DCB_FEATCFG_ERROR 0x01
+/* WARNING: DO NOT EDIT, AUTO-GENERATED CODE - SEE TOP FOR INSTRUCTIONS */
 #define DCB_FEATCFG_ENABLE 0x02
 #define DCB_FEATCFG_WILLING 0x04
-/* WARNING: DO NOT EDIT, AUTO-GENERATED CODE - SEE TOP FOR INSTRUCTIONS */
 #define DCB_FEATCFG_ADVERTISE 0x08
 enum dcbnl_featcfg_attrs {
+/* WARNING: DO NOT EDIT, AUTO-GENERATED CODE - SEE TOP FOR INSTRUCTIONS */
   DCB_FEATCFG_ATTR_UNDEFINED,
   DCB_FEATCFG_ATTR_ALL,
-/* WARNING: DO NOT EDIT, AUTO-GENERATED CODE - SEE TOP FOR INSTRUCTIONS */
   DCB_FEATCFG_ATTR_PG,
   DCB_FEATCFG_ATTR_PFC,
+/* WARNING: DO NOT EDIT, AUTO-GENERATED CODE - SEE TOP FOR INSTRUCTIONS */
   DCB_FEATCFG_ATTR_APP,
   __DCB_FEATCFG_ATTR_ENUM_MAX,
-/* WARNING: DO NOT EDIT, AUTO-GENERATED CODE - SEE TOP FOR INSTRUCTIONS */
   DCB_FEATCFG_ATTR_MAX = __DCB_FEATCFG_ATTR_ENUM_MAX - 1,
 };
+/* WARNING: DO NOT EDIT, AUTO-GENERATED CODE - SEE TOP FOR INSTRUCTIONS */
 #endif
diff --git a/libc/kernel/uapi/linux/dlm_device.h b/libc/kernel/uapi/linux/dlm_device.h
index c496d8d..3bc43f4 100644
--- a/libc/kernel/uapi/linux/dlm_device.h
+++ b/libc/kernel/uapi/linux/dlm_device.h
@@ -24,7 +24,7 @@
 #define DLM_USER_LVB_LEN 32
 #define DLM_DEVICE_VERSION_MAJOR 6
 #define DLM_DEVICE_VERSION_MINOR 0
-#define DLM_DEVICE_VERSION_PATCH 1
+#define DLM_DEVICE_VERSION_PATCH 2
 /* WARNING: DO NOT EDIT, AUTO-GENERATED CODE - SEE TOP FOR INSTRUCTIONS */
 struct dlm_lock_params {
   __u8 mode;
diff --git a/libc/kernel/uapi/linux/dm-ioctl.h b/libc/kernel/uapi/linux/dm-ioctl.h
index 91dccc1..9d42701 100644
--- a/libc/kernel/uapi/linux/dm-ioctl.h
+++ b/libc/kernel/uapi/linux/dm-ioctl.h
@@ -121,9 +121,9 @@
 #define DM_DEV_SET_GEOMETRY _IOWR(DM_IOCTL, DM_DEV_SET_GEOMETRY_CMD, struct dm_ioctl)
 #define DM_VERSION_MAJOR 4
 /* WARNING: DO NOT EDIT, AUTO-GENERATED CODE - SEE TOP FOR INSTRUCTIONS */
-#define DM_VERSION_MINOR 28
+#define DM_VERSION_MINOR 34
 #define DM_VERSION_PATCHLEVEL 0
-#define DM_VERSION_EXTRA "-ioctl(2014-09-17)"
+#define DM_VERSION_EXTRA "-ioctl(2015-10-28)"
 #define DM_READONLY_FLAG (1 << 0)
 /* WARNING: DO NOT EDIT, AUTO-GENERATED CODE - SEE TOP FOR INSTRUCTIONS */
 #define DM_SUSPEND_FLAG (1 << 1)
@@ -144,5 +144,6 @@
 #define DM_SECURE_DATA_FLAG (1 << 15)
 #define DM_DATA_OUT_FLAG (1 << 16)
 #define DM_DEFERRED_REMOVE (1 << 17)
-#endif
+#define DM_INTERNAL_SUSPEND_FLAG (1 << 18)
 /* WARNING: DO NOT EDIT, AUTO-GENERATED CODE - SEE TOP FOR INSTRUCTIONS */
+#endif
diff --git a/libc/kernel/uapi/linux/dvb/dmx.h b/libc/kernel/uapi/linux/dvb/dmx.h
index 8e1d718..99da210 100644
--- a/libc/kernel/uapi/linux/dvb/dmx.h
+++ b/libc/kernel/uapi/linux/dvb/dmx.h
@@ -22,117 +22,118 @@
 #include <time.h>
 /* WARNING: DO NOT EDIT, AUTO-GENERATED CODE - SEE TOP FOR INSTRUCTIONS */
 #define DMX_FILTER_SIZE 16
-typedef enum {
+enum dmx_output {
   DMX_OUT_DECODER,
   DMX_OUT_TAP,
 /* WARNING: DO NOT EDIT, AUTO-GENERATED CODE - SEE TOP FOR INSTRUCTIONS */
   DMX_OUT_TS_TAP,
   DMX_OUT_TSDEMUX_TAP
-} dmx_output_t;
-typedef enum {
+};
+typedef enum dmx_output dmx_output_t;
 /* WARNING: DO NOT EDIT, AUTO-GENERATED CODE - SEE TOP FOR INSTRUCTIONS */
+typedef enum dmx_input {
   DMX_IN_FRONTEND,
   DMX_IN_DVR
 } dmx_input_t;
-typedef enum dmx_ts_pes {
 /* WARNING: DO NOT EDIT, AUTO-GENERATED CODE - SEE TOP FOR INSTRUCTIONS */
+typedef enum dmx_ts_pes {
   DMX_PES_AUDIO0,
   DMX_PES_VIDEO0,
   DMX_PES_TELETEXT0,
-  DMX_PES_SUBTITLE0,
 /* WARNING: DO NOT EDIT, AUTO-GENERATED CODE - SEE TOP FOR INSTRUCTIONS */
+  DMX_PES_SUBTITLE0,
   DMX_PES_PCR0,
   DMX_PES_AUDIO1,
   DMX_PES_VIDEO1,
-  DMX_PES_TELETEXT1,
 /* WARNING: DO NOT EDIT, AUTO-GENERATED CODE - SEE TOP FOR INSTRUCTIONS */
+  DMX_PES_TELETEXT1,
   DMX_PES_SUBTITLE1,
   DMX_PES_PCR1,
   DMX_PES_AUDIO2,
-  DMX_PES_VIDEO2,
 /* WARNING: DO NOT EDIT, AUTO-GENERATED CODE - SEE TOP FOR INSTRUCTIONS */
+  DMX_PES_VIDEO2,
   DMX_PES_TELETEXT2,
   DMX_PES_SUBTITLE2,
   DMX_PES_PCR2,
-  DMX_PES_AUDIO3,
 /* WARNING: DO NOT EDIT, AUTO-GENERATED CODE - SEE TOP FOR INSTRUCTIONS */
+  DMX_PES_AUDIO3,
   DMX_PES_VIDEO3,
   DMX_PES_TELETEXT3,
   DMX_PES_SUBTITLE3,
-  DMX_PES_PCR3,
 /* WARNING: DO NOT EDIT, AUTO-GENERATED CODE - SEE TOP FOR INSTRUCTIONS */
+  DMX_PES_PCR3,
   DMX_PES_OTHER
 } dmx_pes_type_t;
 #define DMX_PES_AUDIO DMX_PES_AUDIO0
-#define DMX_PES_VIDEO DMX_PES_VIDEO0
 /* WARNING: DO NOT EDIT, AUTO-GENERATED CODE - SEE TOP FOR INSTRUCTIONS */
+#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 {
 /* WARNING: DO NOT EDIT, AUTO-GENERATED CODE - SEE TOP FOR INSTRUCTIONS */
+typedef struct dmx_filter {
   __u8 filter[DMX_FILTER_SIZE];
   __u8 mask[DMX_FILTER_SIZE];
   __u8 mode[DMX_FILTER_SIZE];
-} dmx_filter_t;
 /* WARNING: DO NOT EDIT, AUTO-GENERATED CODE - SEE TOP FOR INSTRUCTIONS */
+} dmx_filter_t;
 struct dmx_sct_filter_params {
   __u16 pid;
   dmx_filter_t filter;
-  __u32 timeout;
 /* WARNING: DO NOT EDIT, AUTO-GENERATED CODE - SEE TOP FOR INSTRUCTIONS */
+  __u32 timeout;
   __u32 flags;
 #define DMX_CHECK_CRC 1
 #define DMX_ONESHOT 2
-#define DMX_IMMEDIATE_START 4
 /* WARNING: DO NOT EDIT, AUTO-GENERATED CODE - SEE TOP FOR INSTRUCTIONS */
+#define DMX_IMMEDIATE_START 4
 #define DMX_KERNEL_CLIENT 0x8000
 };
 struct dmx_pes_filter_params {
-  __u16 pid;
 /* WARNING: DO NOT EDIT, AUTO-GENERATED CODE - SEE TOP FOR INSTRUCTIONS */
+  __u16 pid;
   dmx_input_t input;
   dmx_output_t output;
   dmx_pes_type_t pes_type;
-  __u32 flags;
 /* WARNING: DO NOT EDIT, AUTO-GENERATED CODE - SEE TOP FOR INSTRUCTIONS */
+  __u32 flags;
 };
 typedef struct dmx_caps {
   __u32 caps;
+/* WARNING: DO NOT EDIT, AUTO-GENERATED CODE - SEE TOP FOR INSTRUCTIONS */
   int num_decoders;
-/* WARNING: DO NOT EDIT, AUTO-GENERATED CODE - SEE TOP FOR INSTRUCTIONS */
 } dmx_caps_t;
-typedef enum {
+typedef enum dmx_source {
   DMX_SOURCE_FRONT0 = 0,
-  DMX_SOURCE_FRONT1,
 /* WARNING: DO NOT EDIT, AUTO-GENERATED CODE - SEE TOP FOR INSTRUCTIONS */
+  DMX_SOURCE_FRONT1,
   DMX_SOURCE_FRONT2,
   DMX_SOURCE_FRONT3,
   DMX_SOURCE_DVR0 = 16,
-  DMX_SOURCE_DVR1,
 /* WARNING: DO NOT EDIT, AUTO-GENERATED CODE - SEE TOP FOR INSTRUCTIONS */
+  DMX_SOURCE_DVR1,
   DMX_SOURCE_DVR2,
   DMX_SOURCE_DVR3
 } dmx_source_t;
-struct dmx_stc {
 /* WARNING: DO NOT EDIT, AUTO-GENERATED CODE - SEE TOP FOR INSTRUCTIONS */
+struct dmx_stc {
   unsigned int num;
   unsigned int base;
   __u64 stc;
-};
 /* WARNING: DO NOT EDIT, AUTO-GENERATED CODE - SEE TOP FOR INSTRUCTIONS */
+};
 #define DMX_START _IO('o', 41)
 #define DMX_STOP _IO('o', 42)
 #define DMX_SET_FILTER _IOW('o', 43, struct dmx_sct_filter_params)
-#define DMX_SET_PES_FILTER _IOW('o', 44, struct dmx_pes_filter_params)
 /* WARNING: DO NOT EDIT, AUTO-GENERATED CODE - SEE TOP FOR INSTRUCTIONS */
+#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)
 /* WARNING: DO NOT EDIT, AUTO-GENERATED CODE - SEE TOP FOR INSTRUCTIONS */
+#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)
-#endif
 /* WARNING: DO NOT EDIT, AUTO-GENERATED CODE - SEE TOP FOR INSTRUCTIONS */
+#endif
diff --git a/libc/kernel/uapi/linux/dvb/frontend.h b/libc/kernel/uapi/linux/dvb/frontend.h
index a97d5e7..3a833cf 100644
--- a/libc/kernel/uapi/linux/dvb/frontend.h
+++ b/libc/kernel/uapi/linux/dvb/frontend.h
@@ -19,15 +19,15 @@
 #ifndef _DVBFRONTEND_H_
 #define _DVBFRONTEND_H_
 #include <linux/types.h>
-typedef enum fe_type {
+enum fe_type {
 /* WARNING: DO NOT EDIT, AUTO-GENERATED CODE - SEE TOP FOR INSTRUCTIONS */
   FE_QPSK,
   FE_QAM,
   FE_OFDM,
   FE_ATSC
 /* WARNING: DO NOT EDIT, AUTO-GENERATED CODE - SEE TOP FOR INSTRUCTIONS */
-} fe_type_t;
-typedef enum fe_caps {
+};
+enum fe_caps {
   FE_IS_STUPID = 0,
   FE_CAN_INVERSION_AUTO = 0x1,
 /* WARNING: DO NOT EDIT, AUTO-GENERATED CODE - SEE TOP FOR INSTRUCTIONS */
@@ -67,11 +67,11 @@
   FE_CAN_RECOVER = 0x40000000,
 /* WARNING: DO NOT EDIT, AUTO-GENERATED CODE - SEE TOP FOR INSTRUCTIONS */
   FE_CAN_MUTE_TS = 0x80000000
-} fe_caps_t;
+};
 struct dvb_frontend_info {
   char name[128];
 /* WARNING: DO NOT EDIT, AUTO-GENERATED CODE - SEE TOP FOR INSTRUCTIONS */
-  fe_type_t type;
+  enum fe_type type;
   __u32 frequency_min;
   __u32 frequency_max;
   __u32 frequency_stepsize;
@@ -82,7 +82,7 @@
   __u32 symbol_rate_tolerance;
 /* WARNING: DO NOT EDIT, AUTO-GENERATED CODE - SEE TOP FOR INSTRUCTIONS */
   __u32 notifier_delay;
-  fe_caps_t caps;
+  enum fe_caps caps;
 };
 struct dvb_diseqc_master_cmd {
 /* WARNING: DO NOT EDIT, AUTO-GENERATED CODE - SEE TOP FOR INSTRUCTIONS */
@@ -96,23 +96,23 @@
   int timeout;
 };
 /* WARNING: DO NOT EDIT, AUTO-GENERATED CODE - SEE TOP FOR INSTRUCTIONS */
-typedef enum fe_sec_voltage {
+enum fe_sec_voltage {
   SEC_VOLTAGE_13,
   SEC_VOLTAGE_18,
   SEC_VOLTAGE_OFF
 /* WARNING: DO NOT EDIT, AUTO-GENERATED CODE - SEE TOP FOR INSTRUCTIONS */
-} fe_sec_voltage_t;
-typedef enum fe_sec_tone_mode {
+};
+enum fe_sec_tone_mode {
   SEC_TONE_ON,
   SEC_TONE_OFF
 /* WARNING: DO NOT EDIT, AUTO-GENERATED CODE - SEE TOP FOR INSTRUCTIONS */
-} fe_sec_tone_mode_t;
-typedef enum fe_sec_mini_cmd {
+};
+enum fe_sec_mini_cmd {
   SEC_MINI_A,
   SEC_MINI_B
 /* WARNING: DO NOT EDIT, AUTO-GENERATED CODE - SEE TOP FOR INSTRUCTIONS */
-} fe_sec_mini_cmd_t;
-typedef enum fe_status {
+};
+enum fe_status {
   FE_HAS_SIGNAL = 0x01,
   FE_HAS_CARRIER = 0x02,
 /* WARNING: DO NOT EDIT, AUTO-GENERATED CODE - SEE TOP FOR INSTRUCTIONS */
@@ -122,14 +122,14 @@
   FE_TIMEDOUT = 0x20,
 /* WARNING: DO NOT EDIT, AUTO-GENERATED CODE - SEE TOP FOR INSTRUCTIONS */
   FE_REINIT = 0x40,
-} fe_status_t;
-typedef enum fe_spectral_inversion {
+};
+enum fe_spectral_inversion {
   INVERSION_OFF,
 /* WARNING: DO NOT EDIT, AUTO-GENERATED CODE - SEE TOP FOR INSTRUCTIONS */
   INVERSION_ON,
   INVERSION_AUTO
-} fe_spectral_inversion_t;
-typedef enum fe_code_rate {
+};
+enum fe_code_rate {
 /* WARNING: DO NOT EDIT, AUTO-GENERATED CODE - SEE TOP FOR INSTRUCTIONS */
   FEC_NONE = 0,
   FEC_1_2,
@@ -147,8 +147,8 @@
   FEC_9_10,
 /* WARNING: DO NOT EDIT, AUTO-GENERATED CODE - SEE TOP FOR INSTRUCTIONS */
   FEC_2_5,
-} fe_code_rate_t;
-typedef enum fe_modulation {
+};
+enum fe_modulation {
   QPSK,
 /* WARNING: DO NOT EDIT, AUTO-GENERATED CODE - SEE TOP FOR INSTRUCTIONS */
   QAM_16,
@@ -167,8 +167,8 @@
   DQPSK,
 /* WARNING: DO NOT EDIT, AUTO-GENERATED CODE - SEE TOP FOR INSTRUCTIONS */
   QAM_4_NR,
-} fe_modulation_t;
-typedef enum fe_transmit_mode {
+};
+enum fe_transmit_mode {
   TRANSMISSION_MODE_2K,
 /* WARNING: DO NOT EDIT, AUTO-GENERATED CODE - SEE TOP FOR INSTRUCTIONS */
   TRANSMISSION_MODE_8K,
@@ -181,94 +181,39 @@
   TRANSMISSION_MODE_C1,
   TRANSMISSION_MODE_C3780,
 /* WARNING: DO NOT EDIT, AUTO-GENERATED CODE - SEE TOP FOR INSTRUCTIONS */
-} fe_transmit_mode_t;
-typedef enum fe_bandwidth {
-  BANDWIDTH_8_MHZ,
-  BANDWIDTH_7_MHZ,
-/* WARNING: DO NOT EDIT, AUTO-GENERATED CODE - SEE TOP FOR INSTRUCTIONS */
-  BANDWIDTH_6_MHZ,
-  BANDWIDTH_AUTO,
-  BANDWIDTH_5_MHZ,
-  BANDWIDTH_10_MHZ,
-/* WARNING: DO NOT EDIT, AUTO-GENERATED CODE - SEE TOP FOR INSTRUCTIONS */
-  BANDWIDTH_1_712_MHZ,
-} fe_bandwidth_t;
-typedef enum fe_guard_interval {
+};
+enum fe_guard_interval {
   GUARD_INTERVAL_1_32,
-/* WARNING: DO NOT EDIT, AUTO-GENERATED CODE - SEE TOP FOR INSTRUCTIONS */
   GUARD_INTERVAL_1_16,
+/* WARNING: DO NOT EDIT, AUTO-GENERATED CODE - SEE TOP FOR INSTRUCTIONS */
   GUARD_INTERVAL_1_8,
   GUARD_INTERVAL_1_4,
   GUARD_INTERVAL_AUTO,
-/* WARNING: DO NOT EDIT, AUTO-GENERATED CODE - SEE TOP FOR INSTRUCTIONS */
   GUARD_INTERVAL_1_128,
+/* WARNING: DO NOT EDIT, AUTO-GENERATED CODE - SEE TOP FOR INSTRUCTIONS */
   GUARD_INTERVAL_19_128,
   GUARD_INTERVAL_19_256,
   GUARD_INTERVAL_PN420,
-/* WARNING: DO NOT EDIT, AUTO-GENERATED CODE - SEE TOP FOR INSTRUCTIONS */
   GUARD_INTERVAL_PN595,
-  GUARD_INTERVAL_PN945,
-} fe_guard_interval_t;
-typedef enum fe_hierarchy {
 /* WARNING: DO NOT EDIT, AUTO-GENERATED CODE - SEE TOP FOR INSTRUCTIONS */
+  GUARD_INTERVAL_PN945,
+};
+enum fe_hierarchy {
   HIERARCHY_NONE,
+/* WARNING: DO NOT EDIT, AUTO-GENERATED CODE - SEE TOP FOR INSTRUCTIONS */
   HIERARCHY_1,
   HIERARCHY_2,
   HIERARCHY_4,
-/* WARNING: DO NOT EDIT, AUTO-GENERATED CODE - SEE TOP FOR INSTRUCTIONS */
   HIERARCHY_AUTO
-} fe_hierarchy_t;
+/* WARNING: DO NOT EDIT, AUTO-GENERATED CODE - SEE TOP FOR INSTRUCTIONS */
+};
 enum fe_interleaving {
   INTERLEAVING_NONE,
-/* WARNING: DO NOT EDIT, AUTO-GENERATED CODE - SEE TOP FOR INSTRUCTIONS */
   INTERLEAVING_AUTO,
+/* WARNING: DO NOT EDIT, AUTO-GENERATED CODE - SEE TOP FOR INSTRUCTIONS */
   INTERLEAVING_240,
   INTERLEAVING_720,
 };
-/* WARNING: DO NOT EDIT, AUTO-GENERATED CODE - SEE TOP FOR INSTRUCTIONS */
-struct dvb_qpsk_parameters {
-  __u32 symbol_rate;
-  fe_code_rate_t fec_inner;
-};
-/* WARNING: DO NOT EDIT, AUTO-GENERATED CODE - SEE TOP FOR INSTRUCTIONS */
-struct dvb_qam_parameters {
-  __u32 symbol_rate;
-  fe_code_rate_t fec_inner;
-  fe_modulation_t modulation;
-/* WARNING: DO NOT EDIT, AUTO-GENERATED CODE - SEE TOP FOR INSTRUCTIONS */
-};
-struct dvb_vsb_parameters {
-  fe_modulation_t modulation;
-};
-/* WARNING: DO NOT EDIT, AUTO-GENERATED CODE - SEE TOP FOR INSTRUCTIONS */
-struct dvb_ofdm_parameters {
-  fe_bandwidth_t bandwidth;
-  fe_code_rate_t code_rate_HP;
-  fe_code_rate_t code_rate_LP;
-/* WARNING: DO NOT EDIT, AUTO-GENERATED CODE - SEE TOP FOR INSTRUCTIONS */
-  fe_modulation_t constellation;
-  fe_transmit_mode_t transmission_mode;
-  fe_guard_interval_t guard_interval;
-  fe_hierarchy_t hierarchy_information;
-/* WARNING: DO NOT EDIT, AUTO-GENERATED CODE - SEE TOP FOR INSTRUCTIONS */
-};
-struct dvb_frontend_parameters {
-  __u32 frequency;
-  fe_spectral_inversion_t inversion;
-/* WARNING: DO NOT EDIT, AUTO-GENERATED CODE - SEE TOP FOR INSTRUCTIONS */
-  union {
-    struct dvb_qpsk_parameters qpsk;
-    struct dvb_qam_parameters qam;
-    struct dvb_ofdm_parameters ofdm;
-/* WARNING: DO NOT EDIT, AUTO-GENERATED CODE - SEE TOP FOR INSTRUCTIONS */
-    struct dvb_vsb_parameters vsb;
-  } u;
-};
-struct dvb_frontend_event {
-/* WARNING: DO NOT EDIT, AUTO-GENERATED CODE - SEE TOP FOR INSTRUCTIONS */
-  fe_status_t status;
-  struct dvb_frontend_parameters parameters;
-};
 #define DTV_UNDEFINED 0
 /* WARNING: DO NOT EDIT, AUTO-GENERATED CODE - SEE TOP FOR INSTRUCTIONS */
 #define DTV_TUNE 1
@@ -359,21 +304,21 @@
 #define DTV_STAT_ERROR_BLOCK_COUNT 68
 #define DTV_STAT_TOTAL_BLOCK_COUNT 69
 #define DTV_MAX_COMMAND DTV_STAT_TOTAL_BLOCK_COUNT
-typedef enum fe_pilot {
+enum fe_pilot {
 /* WARNING: DO NOT EDIT, AUTO-GENERATED CODE - SEE TOP FOR INSTRUCTIONS */
   PILOT_ON,
   PILOT_OFF,
   PILOT_AUTO,
-} fe_pilot_t;
+};
 /* WARNING: DO NOT EDIT, AUTO-GENERATED CODE - SEE TOP FOR INSTRUCTIONS */
-typedef enum fe_rolloff {
+enum fe_rolloff {
   ROLLOFF_35,
   ROLLOFF_20,
   ROLLOFF_25,
 /* WARNING: DO NOT EDIT, AUTO-GENERATED CODE - SEE TOP FOR INSTRUCTIONS */
   ROLLOFF_AUTO,
-} fe_rolloff_t;
-typedef enum fe_delivery_system {
+};
+enum fe_delivery_system {
   SYS_UNDEFINED,
 /* WARNING: DO NOT EDIT, AUTO-GENERATED CODE - SEE TOP FOR INSTRUCTIONS */
   SYS_DVBC_ANNEX_A,
@@ -398,7 +343,7 @@
 /* WARNING: DO NOT EDIT, AUTO-GENERATED CODE - SEE TOP FOR INSTRUCTIONS */
   SYS_TURBO,
   SYS_DVBC_ANNEX_C,
-} fe_delivery_system_t;
+};
 #define SYS_DVBC_ANNEX_AC SYS_DVBC_ANNEX_A
 /* WARNING: DO NOT EDIT, AUTO-GENERATED CODE - SEE TOP FOR INSTRUCTIONS */
 #define SYS_DMBTH SYS_DTMB
@@ -492,6 +437,81 @@
   struct dtv_property * props;
 /* WARNING: DO NOT EDIT, AUTO-GENERATED CODE - SEE TOP FOR INSTRUCTIONS */
 };
+enum fe_bandwidth {
+  BANDWIDTH_8_MHZ,
+  BANDWIDTH_7_MHZ,
+/* WARNING: DO NOT EDIT, AUTO-GENERATED CODE - SEE TOP FOR INSTRUCTIONS */
+  BANDWIDTH_6_MHZ,
+  BANDWIDTH_AUTO,
+  BANDWIDTH_5_MHZ,
+  BANDWIDTH_10_MHZ,
+/* WARNING: DO NOT EDIT, AUTO-GENERATED CODE - SEE TOP FOR INSTRUCTIONS */
+  BANDWIDTH_1_712_MHZ,
+};
+typedef enum fe_sec_voltage fe_sec_voltage_t;
+typedef enum fe_caps fe_caps_t;
+/* WARNING: DO NOT EDIT, AUTO-GENERATED CODE - SEE TOP FOR INSTRUCTIONS */
+typedef enum fe_type fe_type_t;
+typedef enum fe_sec_tone_mode fe_sec_tone_mode_t;
+typedef enum fe_sec_mini_cmd fe_sec_mini_cmd_t;
+typedef enum fe_status fe_status_t;
+/* WARNING: DO NOT EDIT, AUTO-GENERATED CODE - SEE TOP FOR INSTRUCTIONS */
+typedef enum fe_spectral_inversion fe_spectral_inversion_t;
+typedef enum fe_code_rate fe_code_rate_t;
+typedef enum fe_modulation fe_modulation_t;
+typedef enum fe_transmit_mode fe_transmit_mode_t;
+/* WARNING: DO NOT EDIT, AUTO-GENERATED CODE - SEE TOP FOR INSTRUCTIONS */
+typedef enum fe_bandwidth fe_bandwidth_t;
+typedef enum fe_guard_interval fe_guard_interval_t;
+typedef enum fe_hierarchy fe_hierarchy_t;
+typedef enum fe_pilot fe_pilot_t;
+/* WARNING: DO NOT EDIT, AUTO-GENERATED CODE - SEE TOP FOR INSTRUCTIONS */
+typedef enum fe_rolloff fe_rolloff_t;
+typedef enum fe_delivery_system fe_delivery_system_t;
+struct dvb_qpsk_parameters {
+  __u32 symbol_rate;
+/* WARNING: DO NOT EDIT, AUTO-GENERATED CODE - SEE TOP FOR INSTRUCTIONS */
+  fe_code_rate_t fec_inner;
+};
+struct dvb_qam_parameters {
+  __u32 symbol_rate;
+/* WARNING: DO NOT EDIT, AUTO-GENERATED CODE - SEE TOP FOR INSTRUCTIONS */
+  fe_code_rate_t fec_inner;
+  fe_modulation_t modulation;
+};
+struct dvb_vsb_parameters {
+/* WARNING: DO NOT EDIT, AUTO-GENERATED CODE - SEE TOP FOR INSTRUCTIONS */
+  fe_modulation_t modulation;
+};
+struct dvb_ofdm_parameters {
+  fe_bandwidth_t bandwidth;
+/* WARNING: DO NOT EDIT, AUTO-GENERATED CODE - SEE TOP FOR INSTRUCTIONS */
+  fe_code_rate_t code_rate_HP;
+  fe_code_rate_t code_rate_LP;
+  fe_modulation_t constellation;
+  fe_transmit_mode_t transmission_mode;
+/* WARNING: DO NOT EDIT, AUTO-GENERATED CODE - SEE TOP FOR INSTRUCTIONS */
+  fe_guard_interval_t guard_interval;
+  fe_hierarchy_t hierarchy_information;
+};
+struct dvb_frontend_parameters {
+/* WARNING: DO NOT EDIT, AUTO-GENERATED CODE - SEE TOP FOR INSTRUCTIONS */
+  __u32 frequency;
+  fe_spectral_inversion_t inversion;
+  union {
+    struct dvb_qpsk_parameters qpsk;
+/* WARNING: DO NOT EDIT, AUTO-GENERATED CODE - SEE TOP FOR INSTRUCTIONS */
+    struct dvb_qam_parameters qam;
+    struct dvb_ofdm_parameters ofdm;
+    struct dvb_vsb_parameters vsb;
+  } u;
+/* WARNING: DO NOT EDIT, AUTO-GENERATED CODE - SEE TOP FOR INSTRUCTIONS */
+};
+struct dvb_frontend_event {
+  fe_status_t status;
+  struct dvb_frontend_parameters parameters;
+/* WARNING: DO NOT EDIT, AUTO-GENERATED CODE - SEE TOP FOR INSTRUCTIONS */
+};
 #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
diff --git a/libc/kernel/uapi/linux/elf-em.h b/libc/kernel/uapi/linux/elf-em.h
index 8fe939a..1e372fa 100644
--- a/libc/kernel/uapi/linux/elf-em.h
+++ b/libc/kernel/uapi/linux/elf-em.h
@@ -42,27 +42,33 @@
 #define EM_SH 42
 /* WARNING: DO NOT EDIT, AUTO-GENERATED CODE - SEE TOP FOR INSTRUCTIONS */
 #define EM_SPARCV9 43
+#define EM_H8_300 46
 #define EM_IA_64 50
 #define EM_X86_64 62
-#define EM_S390 22
 /* WARNING: DO NOT EDIT, AUTO-GENERATED CODE - SEE TOP FOR INSTRUCTIONS */
+#define EM_S390 22
 #define EM_CRIS 76
 #define EM_V850 87
 #define EM_M32R 88
-#define EM_MN10300 89
 /* WARNING: DO NOT EDIT, AUTO-GENERATED CODE - SEE TOP FOR INSTRUCTIONS */
+#define EM_MN10300 89
 #define EM_OPENRISC 92
 #define EM_BLACKFIN 106
+#define EM_ALTERA_NIOS2 113
+/* WARNING: DO NOT EDIT, AUTO-GENERATED CODE - SEE TOP FOR INSTRUCTIONS */
 #define EM_TI_C6000 140
 #define EM_AARCH64 183
+#define EM_TILEPRO 188
+#define EM_MICROBLAZE 189
 /* WARNING: DO NOT EDIT, AUTO-GENERATED CODE - SEE TOP FOR INSTRUCTIONS */
+#define EM_TILEGX 191
 #define EM_FRV 0x5441
 #define EM_AVR32 0x18ad
 #define EM_ALPHA 0x9026
-#define EM_CYGNUS_V850 0x9080
 /* WARNING: DO NOT EDIT, AUTO-GENERATED CODE - SEE TOP FOR INSTRUCTIONS */
+#define EM_CYGNUS_V850 0x9080
 #define EM_CYGNUS_M32R 0x9041
 #define EM_S390_OLD 0xA390
 #define EM_CYGNUS_MN10300 0xbeef
-#endif
 /* WARNING: DO NOT EDIT, AUTO-GENERATED CODE - SEE TOP FOR INSTRUCTIONS */
+#endif
diff --git a/libc/kernel/uapi/linux/elf.h b/libc/kernel/uapi/linux/elf.h
index 4e42758..27a2f84 100644
--- a/libc/kernel/uapi/linux/elf.h
+++ b/libc/kernel/uapi/linux/elf.h
@@ -412,20 +412,22 @@
 #define NT_ARM_HW_BREAK 0x402
 /* WARNING: DO NOT EDIT, AUTO-GENERATED CODE - SEE TOP FOR INSTRUCTIONS */
 #define NT_ARM_HW_WATCH 0x403
+#define NT_ARM_SYSTEM_CALL 0x404
 #define NT_METAG_CBUF 0x500
 #define NT_METAG_RPIPE 0x501
-#define NT_METAG_TLS 0x502
 /* WARNING: DO NOT EDIT, AUTO-GENERATED CODE - SEE TOP FOR INSTRUCTIONS */
+#define NT_METAG_TLS 0x502
 typedef struct elf32_note {
   Elf32_Word n_namesz;
   Elf32_Word n_descsz;
-  Elf32_Word n_type;
 /* WARNING: DO NOT EDIT, AUTO-GENERATED CODE - SEE TOP FOR INSTRUCTIONS */
+  Elf32_Word n_type;
 } Elf32_Nhdr;
 typedef struct elf64_note {
   Elf64_Word n_namesz;
-  Elf64_Word n_descsz;
 /* WARNING: DO NOT EDIT, AUTO-GENERATED CODE - SEE TOP FOR INSTRUCTIONS */
+  Elf64_Word n_descsz;
   Elf64_Word n_type;
 } Elf64_Nhdr;
 #endif
+/* WARNING: DO NOT EDIT, AUTO-GENERATED CODE - SEE TOP FOR INSTRUCTIONS */
diff --git a/libc/kernel/uapi/linux/ethtool.h b/libc/kernel/uapi/linux/ethtool.h
index 1a00c7f..a2a2da7 100644
--- a/libc/kernel/uapi/linux/ethtool.h
+++ b/libc/kernel/uapi/linux/ethtool.h
@@ -49,180 +49,185 @@
 #define ETH_MDIO_SUPPORTS_C45 2
 #define ETHTOOL_FWVERS_LEN 32
 #define ETHTOOL_BUSINFO_LEN 32
-struct ethtool_drvinfo {
+#define ETHTOOL_EROMVERS_LEN 32
 /* WARNING: DO NOT EDIT, AUTO-GENERATED CODE - SEE TOP FOR INSTRUCTIONS */
+struct ethtool_drvinfo {
   __u32 cmd;
   char driver[32];
   char version[32];
+/* WARNING: DO NOT EDIT, AUTO-GENERATED CODE - SEE TOP FOR INSTRUCTIONS */
   char fw_version[ETHTOOL_FWVERS_LEN];
-/* WARNING: DO NOT EDIT, AUTO-GENERATED CODE - SEE TOP FOR INSTRUCTIONS */
   char bus_info[ETHTOOL_BUSINFO_LEN];
-  char reserved1[32];
+  char erom_version[ETHTOOL_EROMVERS_LEN];
   char reserved2[12];
-  __u32 n_priv_flags;
 /* WARNING: DO NOT EDIT, AUTO-GENERATED CODE - SEE TOP FOR INSTRUCTIONS */
+  __u32 n_priv_flags;
   __u32 n_stats;
   __u32 testinfo_len;
   __u32 eedump_len;
-  __u32 regdump_len;
 /* WARNING: DO NOT EDIT, AUTO-GENERATED CODE - SEE TOP FOR INSTRUCTIONS */
+  __u32 regdump_len;
 };
 #define SOPASS_MAX 6
 struct ethtool_wolinfo {
-  __u32 cmd;
 /* WARNING: DO NOT EDIT, AUTO-GENERATED CODE - SEE TOP FOR INSTRUCTIONS */
+  __u32 cmd;
   __u32 supported;
   __u32 wolopts;
   __u8 sopass[SOPASS_MAX];
-};
 /* WARNING: DO NOT EDIT, AUTO-GENERATED CODE - SEE TOP FOR INSTRUCTIONS */
+};
 struct ethtool_value {
   __u32 cmd;
   __u32 data;
-};
 /* WARNING: DO NOT EDIT, AUTO-GENERATED CODE - SEE TOP FOR INSTRUCTIONS */
+};
 enum tunable_id {
   ETHTOOL_ID_UNSPEC,
   ETHTOOL_RX_COPYBREAK,
-  ETHTOOL_TX_COPYBREAK,
 /* WARNING: DO NOT EDIT, AUTO-GENERATED CODE - SEE TOP FOR INSTRUCTIONS */
+  ETHTOOL_TX_COPYBREAK,
+  __ETHTOOL_TUNABLE_COUNT,
 };
 enum tunable_type_id {
+/* WARNING: DO NOT EDIT, AUTO-GENERATED CODE - SEE TOP FOR INSTRUCTIONS */
   ETHTOOL_TUNABLE_UNSPEC,
   ETHTOOL_TUNABLE_U8,
-/* WARNING: DO NOT EDIT, AUTO-GENERATED CODE - SEE TOP FOR INSTRUCTIONS */
   ETHTOOL_TUNABLE_U16,
   ETHTOOL_TUNABLE_U32,
+/* WARNING: DO NOT EDIT, AUTO-GENERATED CODE - SEE TOP FOR INSTRUCTIONS */
   ETHTOOL_TUNABLE_U64,
   ETHTOOL_TUNABLE_STRING,
-/* WARNING: DO NOT EDIT, AUTO-GENERATED CODE - SEE TOP FOR INSTRUCTIONS */
   ETHTOOL_TUNABLE_S8,
   ETHTOOL_TUNABLE_S16,
+/* WARNING: DO NOT EDIT, AUTO-GENERATED CODE - SEE TOP FOR INSTRUCTIONS */
   ETHTOOL_TUNABLE_S32,
   ETHTOOL_TUNABLE_S64,
-/* WARNING: DO NOT EDIT, AUTO-GENERATED CODE - SEE TOP FOR INSTRUCTIONS */
 };
 struct ethtool_tunable {
+/* WARNING: DO NOT EDIT, AUTO-GENERATED CODE - SEE TOP FOR INSTRUCTIONS */
   __u32 cmd;
   __u32 id;
-/* WARNING: DO NOT EDIT, AUTO-GENERATED CODE - SEE TOP FOR INSTRUCTIONS */
   __u32 type_id;
   __u32 len;
+/* WARNING: DO NOT EDIT, AUTO-GENERATED CODE - SEE TOP FOR INSTRUCTIONS */
   void * data[0];
 };
-/* WARNING: DO NOT EDIT, AUTO-GENERATED CODE - SEE TOP FOR INSTRUCTIONS */
 struct ethtool_regs {
   __u32 cmd;
+/* WARNING: DO NOT EDIT, AUTO-GENERATED CODE - SEE TOP FOR INSTRUCTIONS */
   __u32 version;
   __u32 len;
-/* WARNING: DO NOT EDIT, AUTO-GENERATED CODE - SEE TOP FOR INSTRUCTIONS */
   __u8 data[0];
 };
+/* WARNING: DO NOT EDIT, AUTO-GENERATED CODE - SEE TOP FOR INSTRUCTIONS */
 struct ethtool_eeprom {
   __u32 cmd;
-/* WARNING: DO NOT EDIT, AUTO-GENERATED CODE - SEE TOP FOR INSTRUCTIONS */
   __u32 magic;
   __u32 offset;
+/* WARNING: DO NOT EDIT, AUTO-GENERATED CODE - SEE TOP FOR INSTRUCTIONS */
   __u32 len;
   __u8 data[0];
-/* WARNING: DO NOT EDIT, AUTO-GENERATED CODE - SEE TOP FOR INSTRUCTIONS */
 };
 struct ethtool_eee {
+/* WARNING: DO NOT EDIT, AUTO-GENERATED CODE - SEE TOP FOR INSTRUCTIONS */
   __u32 cmd;
   __u32 supported;
-/* WARNING: DO NOT EDIT, AUTO-GENERATED CODE - SEE TOP FOR INSTRUCTIONS */
   __u32 advertised;
   __u32 lp_advertised;
+/* WARNING: DO NOT EDIT, AUTO-GENERATED CODE - SEE TOP FOR INSTRUCTIONS */
   __u32 eee_active;
   __u32 eee_enabled;
-/* WARNING: DO NOT EDIT, AUTO-GENERATED CODE - SEE TOP FOR INSTRUCTIONS */
   __u32 tx_lpi_enabled;
   __u32 tx_lpi_timer;
+/* WARNING: DO NOT EDIT, AUTO-GENERATED CODE - SEE TOP FOR INSTRUCTIONS */
   __u32 reserved[2];
 };
-/* WARNING: DO NOT EDIT, AUTO-GENERATED CODE - SEE TOP FOR INSTRUCTIONS */
 struct ethtool_modinfo {
   __u32 cmd;
+/* WARNING: DO NOT EDIT, AUTO-GENERATED CODE - SEE TOP FOR INSTRUCTIONS */
   __u32 type;
   __u32 eeprom_len;
-/* WARNING: DO NOT EDIT, AUTO-GENERATED CODE - SEE TOP FOR INSTRUCTIONS */
   __u32 reserved[8];
 };
+/* WARNING: DO NOT EDIT, AUTO-GENERATED CODE - SEE TOP FOR INSTRUCTIONS */
 struct ethtool_coalesce {
   __u32 cmd;
-/* WARNING: DO NOT EDIT, AUTO-GENERATED CODE - SEE TOP FOR INSTRUCTIONS */
   __u32 rx_coalesce_usecs;
   __u32 rx_max_coalesced_frames;
+/* WARNING: DO NOT EDIT, AUTO-GENERATED CODE - SEE TOP FOR INSTRUCTIONS */
   __u32 rx_coalesce_usecs_irq;
   __u32 rx_max_coalesced_frames_irq;
-/* WARNING: DO NOT EDIT, AUTO-GENERATED CODE - SEE TOP FOR INSTRUCTIONS */
   __u32 tx_coalesce_usecs;
   __u32 tx_max_coalesced_frames;
+/* WARNING: DO NOT EDIT, AUTO-GENERATED CODE - SEE TOP FOR INSTRUCTIONS */
   __u32 tx_coalesce_usecs_irq;
   __u32 tx_max_coalesced_frames_irq;
-/* WARNING: DO NOT EDIT, AUTO-GENERATED CODE - SEE TOP FOR INSTRUCTIONS */
   __u32 stats_block_coalesce_usecs;
   __u32 use_adaptive_rx_coalesce;
+/* WARNING: DO NOT EDIT, AUTO-GENERATED CODE - SEE TOP FOR INSTRUCTIONS */
   __u32 use_adaptive_tx_coalesce;
   __u32 pkt_rate_low;
-/* WARNING: DO NOT EDIT, AUTO-GENERATED CODE - SEE TOP FOR INSTRUCTIONS */
   __u32 rx_coalesce_usecs_low;
   __u32 rx_max_coalesced_frames_low;
+/* WARNING: DO NOT EDIT, AUTO-GENERATED CODE - SEE TOP FOR INSTRUCTIONS */
   __u32 tx_coalesce_usecs_low;
   __u32 tx_max_coalesced_frames_low;
-/* WARNING: DO NOT EDIT, AUTO-GENERATED CODE - SEE TOP FOR INSTRUCTIONS */
   __u32 pkt_rate_high;
   __u32 rx_coalesce_usecs_high;
+/* WARNING: DO NOT EDIT, AUTO-GENERATED CODE - SEE TOP FOR INSTRUCTIONS */
   __u32 rx_max_coalesced_frames_high;
   __u32 tx_coalesce_usecs_high;
-/* WARNING: DO NOT EDIT, AUTO-GENERATED CODE - SEE TOP FOR INSTRUCTIONS */
   __u32 tx_max_coalesced_frames_high;
   __u32 rate_sample_interval;
+/* WARNING: DO NOT EDIT, AUTO-GENERATED CODE - SEE TOP FOR INSTRUCTIONS */
 };
 struct ethtool_ringparam {
-/* WARNING: DO NOT EDIT, AUTO-GENERATED CODE - SEE TOP FOR INSTRUCTIONS */
   __u32 cmd;
   __u32 rx_max_pending;
+/* WARNING: DO NOT EDIT, AUTO-GENERATED CODE - SEE TOP FOR INSTRUCTIONS */
   __u32 rx_mini_max_pending;
   __u32 rx_jumbo_max_pending;
-/* WARNING: DO NOT EDIT, AUTO-GENERATED CODE - SEE TOP FOR INSTRUCTIONS */
   __u32 tx_max_pending;
   __u32 rx_pending;
+/* WARNING: DO NOT EDIT, AUTO-GENERATED CODE - SEE TOP FOR INSTRUCTIONS */
   __u32 rx_mini_pending;
   __u32 rx_jumbo_pending;
-/* WARNING: DO NOT EDIT, AUTO-GENERATED CODE - SEE TOP FOR INSTRUCTIONS */
   __u32 tx_pending;
 };
+/* WARNING: DO NOT EDIT, AUTO-GENERATED CODE - SEE TOP FOR INSTRUCTIONS */
 struct ethtool_channels {
   __u32 cmd;
-/* WARNING: DO NOT EDIT, AUTO-GENERATED CODE - SEE TOP FOR INSTRUCTIONS */
   __u32 max_rx;
   __u32 max_tx;
+/* WARNING: DO NOT EDIT, AUTO-GENERATED CODE - SEE TOP FOR INSTRUCTIONS */
   __u32 max_other;
   __u32 max_combined;
-/* WARNING: DO NOT EDIT, AUTO-GENERATED CODE - SEE TOP FOR INSTRUCTIONS */
   __u32 rx_count;
   __u32 tx_count;
+/* WARNING: DO NOT EDIT, AUTO-GENERATED CODE - SEE TOP FOR INSTRUCTIONS */
   __u32 other_count;
   __u32 combined_count;
-/* WARNING: DO NOT EDIT, AUTO-GENERATED CODE - SEE TOP FOR INSTRUCTIONS */
 };
 struct ethtool_pauseparam {
+/* WARNING: DO NOT EDIT, AUTO-GENERATED CODE - SEE TOP FOR INSTRUCTIONS */
   __u32 cmd;
   __u32 autoneg;
-/* WARNING: DO NOT EDIT, AUTO-GENERATED CODE - SEE TOP FOR INSTRUCTIONS */
   __u32 rx_pause;
   __u32 tx_pause;
+/* WARNING: DO NOT EDIT, AUTO-GENERATED CODE - SEE TOP FOR INSTRUCTIONS */
 };
 #define ETH_GSTRING_LEN 32
-/* WARNING: DO NOT EDIT, AUTO-GENERATED CODE - SEE TOP FOR INSTRUCTIONS */
 enum ethtool_stringset {
   ETH_SS_TEST = 0,
+/* WARNING: DO NOT EDIT, AUTO-GENERATED CODE - SEE TOP FOR INSTRUCTIONS */
   ETH_SS_STATS,
   ETH_SS_PRIV_FLAGS,
-/* WARNING: DO NOT EDIT, AUTO-GENERATED CODE - SEE TOP FOR INSTRUCTIONS */
   ETH_SS_NTUPLE_FILTERS,
   ETH_SS_FEATURES,
+/* WARNING: DO NOT EDIT, AUTO-GENERATED CODE - SEE TOP FOR INSTRUCTIONS */
+  ETH_SS_RSS_HASH_FUNCS,
+  ETH_SS_TUNABLES,
 };
 struct ethtool_gstrings {
 /* WARNING: DO NOT EDIT, AUTO-GENERATED CODE - SEE TOP FOR INSTRUCTIONS */
@@ -337,297 +342,312 @@
   __u32 location;
 /* WARNING: DO NOT EDIT, AUTO-GENERATED CODE - SEE TOP FOR INSTRUCTIONS */
 };
-struct ethtool_rxnfc {
-  __u32 cmd;
-  __u32 flow_type;
+#define ETHTOOL_RX_FLOW_SPEC_RING 0x00000000FFFFFFFFLL
+#define ETHTOOL_RX_FLOW_SPEC_RING_VF 0x000000FF00000000LL
+#define ETHTOOL_RX_FLOW_SPEC_RING_VF_OFF 32
 /* WARNING: DO NOT EDIT, AUTO-GENERATED CODE - SEE TOP FOR INSTRUCTIONS */
-  __u64 data;
-  struct ethtool_rx_flow_spec fs;
-  __u32 rule_cnt;
-  __u32 rule_locs[0];
-/* WARNING: DO NOT EDIT, AUTO-GENERATED CODE - SEE TOP FOR INSTRUCTIONS */
-};
 struct ethtool_rxfh_indir {
   __u32 cmd;
   __u32 size;
-/* WARNING: DO NOT EDIT, AUTO-GENERATED CODE - SEE TOP FOR INSTRUCTIONS */
   __u32 ring_index[0];
+/* WARNING: DO NOT EDIT, AUTO-GENERATED CODE - SEE TOP FOR INSTRUCTIONS */
 };
 struct ethtool_rxfh {
   __u32 cmd;
-/* WARNING: DO NOT EDIT, AUTO-GENERATED CODE - SEE TOP FOR INSTRUCTIONS */
   __u32 rss_context;
+/* WARNING: DO NOT EDIT, AUTO-GENERATED CODE - SEE TOP FOR INSTRUCTIONS */
   __u32 indir_size;
   __u32 key_size;
-  __u32 rsvd[2];
+  __u8 hfunc;
+  __u8 rsvd8[3];
 /* WARNING: DO NOT EDIT, AUTO-GENERATED CODE - SEE TOP FOR INSTRUCTIONS */
+  __u32 rsvd32;
   __u32 rss_config[0];
 };
 #define ETH_RXFH_INDIR_NO_CHANGE 0xffffffff
-struct ethtool_rx_ntuple_flow_spec {
 /* WARNING: DO NOT EDIT, AUTO-GENERATED CODE - SEE TOP FOR INSTRUCTIONS */
+struct ethtool_rx_ntuple_flow_spec {
   __u32 flow_type;
   union {
     struct ethtool_tcpip4_spec tcp_ip4_spec;
-    struct ethtool_tcpip4_spec udp_ip4_spec;
 /* WARNING: DO NOT EDIT, AUTO-GENERATED CODE - SEE TOP FOR INSTRUCTIONS */
+    struct ethtool_tcpip4_spec udp_ip4_spec;
     struct ethtool_tcpip4_spec sctp_ip4_spec;
     struct ethtool_ah_espip4_spec ah_ip4_spec;
     struct ethtool_ah_espip4_spec esp_ip4_spec;
-    struct ethtool_usrip4_spec usr_ip4_spec;
 /* WARNING: DO NOT EDIT, AUTO-GENERATED CODE - SEE TOP FOR INSTRUCTIONS */
+    struct ethtool_usrip4_spec usr_ip4_spec;
     struct ethhdr ether_spec;
     __u8 hdata[72];
   } h_u, m_u;
-  __u16 vlan_tag;
 /* WARNING: DO NOT EDIT, AUTO-GENERATED CODE - SEE TOP FOR INSTRUCTIONS */
+  __u16 vlan_tag;
   __u16 vlan_tag_mask;
   __u64 data;
   __u64 data_mask;
-  __s32 action;
 /* WARNING: DO NOT EDIT, AUTO-GENERATED CODE - SEE TOP FOR INSTRUCTIONS */
+  __s32 action;
 #define ETHTOOL_RXNTUPLE_ACTION_DROP (- 1)
 #define ETHTOOL_RXNTUPLE_ACTION_CLEAR (- 2)
 };
-struct ethtool_rx_ntuple {
 /* WARNING: DO NOT EDIT, AUTO-GENERATED CODE - SEE TOP FOR INSTRUCTIONS */
+struct ethtool_rx_ntuple {
   __u32 cmd;
   struct ethtool_rx_ntuple_flow_spec fs;
 };
-#define ETHTOOL_FLASH_MAX_FILENAME 128
 /* WARNING: DO NOT EDIT, AUTO-GENERATED CODE - SEE TOP FOR INSTRUCTIONS */
+#define ETHTOOL_FLASH_MAX_FILENAME 128
 enum ethtool_flash_op_type {
   ETHTOOL_FLASH_ALL_REGIONS = 0,
 };
-struct ethtool_flash {
 /* WARNING: DO NOT EDIT, AUTO-GENERATED CODE - SEE TOP FOR INSTRUCTIONS */
+struct ethtool_flash {
   __u32 cmd;
   __u32 region;
   char data[ETHTOOL_FLASH_MAX_FILENAME];
-};
 /* WARNING: DO NOT EDIT, AUTO-GENERATED CODE - SEE TOP FOR INSTRUCTIONS */
+};
 struct ethtool_dump {
   __u32 cmd;
   __u32 version;
-  __u32 flag;
 /* WARNING: DO NOT EDIT, AUTO-GENERATED CODE - SEE TOP FOR INSTRUCTIONS */
+  __u32 flag;
   __u32 len;
   __u8 data[0];
 };
-#define ETH_FW_DUMP_DISABLE 0
 /* WARNING: DO NOT EDIT, AUTO-GENERATED CODE - SEE TOP FOR INSTRUCTIONS */
+#define ETH_FW_DUMP_DISABLE 0
 struct ethtool_get_features_block {
   __u32 available;
   __u32 requested;
-  __u32 active;
 /* WARNING: DO NOT EDIT, AUTO-GENERATED CODE - SEE TOP FOR INSTRUCTIONS */
+  __u32 active;
   __u32 never_changed;
 };
 struct ethtool_gfeatures {
-  __u32 cmd;
 /* WARNING: DO NOT EDIT, AUTO-GENERATED CODE - SEE TOP FOR INSTRUCTIONS */
+  __u32 cmd;
   __u32 size;
   struct ethtool_get_features_block features[0];
 };
-struct ethtool_set_features_block {
 /* WARNING: DO NOT EDIT, AUTO-GENERATED CODE - SEE TOP FOR INSTRUCTIONS */
+struct ethtool_set_features_block {
   __u32 valid;
   __u32 requested;
 };
-struct ethtool_sfeatures {
 /* WARNING: DO NOT EDIT, AUTO-GENERATED CODE - SEE TOP FOR INSTRUCTIONS */
+struct ethtool_sfeatures {
   __u32 cmd;
   __u32 size;
   struct ethtool_set_features_block features[0];
-};
 /* WARNING: DO NOT EDIT, AUTO-GENERATED CODE - SEE TOP FOR INSTRUCTIONS */
+};
 struct ethtool_ts_info {
   __u32 cmd;
   __u32 so_timestamping;
-  __s32 phc_index;
 /* WARNING: DO NOT EDIT, AUTO-GENERATED CODE - SEE TOP FOR INSTRUCTIONS */
+  __s32 phc_index;
   __u32 tx_types;
   __u32 tx_reserved[3];
   __u32 rx_filters;
-  __u32 rx_reserved[3];
 /* WARNING: DO NOT EDIT, AUTO-GENERATED CODE - SEE TOP FOR INSTRUCTIONS */
+  __u32 rx_reserved[3];
 };
 enum ethtool_sfeatures_retval_bits {
   ETHTOOL_F_UNSUPPORTED__BIT,
-  ETHTOOL_F_WISH__BIT,
 /* WARNING: DO NOT EDIT, AUTO-GENERATED CODE - SEE TOP FOR INSTRUCTIONS */
+  ETHTOOL_F_WISH__BIT,
   ETHTOOL_F_COMPAT__BIT,
 };
 #define ETHTOOL_F_UNSUPPORTED (1 << ETHTOOL_F_UNSUPPORTED__BIT)
-#define ETHTOOL_F_WISH (1 << ETHTOOL_F_WISH__BIT)
 /* WARNING: DO NOT EDIT, AUTO-GENERATED CODE - SEE TOP FOR INSTRUCTIONS */
+#define ETHTOOL_F_WISH (1 << ETHTOOL_F_WISH__BIT)
 #define ETHTOOL_F_COMPAT (1 << ETHTOOL_F_COMPAT__BIT)
 #define ETHTOOL_GSET 0x00000001
 #define ETHTOOL_SSET 0x00000002
-#define ETHTOOL_GDRVINFO 0x00000003
 /* WARNING: DO NOT EDIT, AUTO-GENERATED CODE - SEE TOP FOR INSTRUCTIONS */
+#define ETHTOOL_GDRVINFO 0x00000003
 #define ETHTOOL_GREGS 0x00000004
 #define ETHTOOL_GWOL 0x00000005
 #define ETHTOOL_SWOL 0x00000006
-#define ETHTOOL_GMSGLVL 0x00000007
 /* WARNING: DO NOT EDIT, AUTO-GENERATED CODE - SEE TOP FOR INSTRUCTIONS */
+#define ETHTOOL_GMSGLVL 0x00000007
 #define ETHTOOL_SMSGLVL 0x00000008
 #define ETHTOOL_NWAY_RST 0x00000009
 #define ETHTOOL_GLINK 0x0000000a
-#define ETHTOOL_GEEPROM 0x0000000b
 /* WARNING: DO NOT EDIT, AUTO-GENERATED CODE - SEE TOP FOR INSTRUCTIONS */
+#define ETHTOOL_GEEPROM 0x0000000b
 #define ETHTOOL_SEEPROM 0x0000000c
 #define ETHTOOL_GCOALESCE 0x0000000e
 #define ETHTOOL_SCOALESCE 0x0000000f
-#define ETHTOOL_GRINGPARAM 0x00000010
 /* WARNING: DO NOT EDIT, AUTO-GENERATED CODE - SEE TOP FOR INSTRUCTIONS */
+#define ETHTOOL_GRINGPARAM 0x00000010
 #define ETHTOOL_SRINGPARAM 0x00000011
 #define ETHTOOL_GPAUSEPARAM 0x00000012
 #define ETHTOOL_SPAUSEPARAM 0x00000013
-#define ETHTOOL_GRXCSUM 0x00000014
 /* WARNING: DO NOT EDIT, AUTO-GENERATED CODE - SEE TOP FOR INSTRUCTIONS */
+#define ETHTOOL_GRXCSUM 0x00000014
 #define ETHTOOL_SRXCSUM 0x00000015
 #define ETHTOOL_GTXCSUM 0x00000016
 #define ETHTOOL_STXCSUM 0x00000017
-#define ETHTOOL_GSG 0x00000018
 /* WARNING: DO NOT EDIT, AUTO-GENERATED CODE - SEE TOP FOR INSTRUCTIONS */
+#define ETHTOOL_GSG 0x00000018
 #define ETHTOOL_SSG 0x00000019
 #define ETHTOOL_TEST 0x0000001a
 #define ETHTOOL_GSTRINGS 0x0000001b
-#define ETHTOOL_PHYS_ID 0x0000001c
 /* WARNING: DO NOT EDIT, AUTO-GENERATED CODE - SEE TOP FOR INSTRUCTIONS */
+#define ETHTOOL_PHYS_ID 0x0000001c
 #define ETHTOOL_GSTATS 0x0000001d
 #define ETHTOOL_GTSO 0x0000001e
 #define ETHTOOL_STSO 0x0000001f
-#define ETHTOOL_GPERMADDR 0x00000020
 /* WARNING: DO NOT EDIT, AUTO-GENERATED CODE - SEE TOP FOR INSTRUCTIONS */
+#define ETHTOOL_GPERMADDR 0x00000020
 #define ETHTOOL_GUFO 0x00000021
 #define ETHTOOL_SUFO 0x00000022
 #define ETHTOOL_GGSO 0x00000023
-#define ETHTOOL_SGSO 0x00000024
 /* WARNING: DO NOT EDIT, AUTO-GENERATED CODE - SEE TOP FOR INSTRUCTIONS */
+#define ETHTOOL_SGSO 0x00000024
 #define ETHTOOL_GFLAGS 0x00000025
 #define ETHTOOL_SFLAGS 0x00000026
 #define ETHTOOL_GPFLAGS 0x00000027
-#define ETHTOOL_SPFLAGS 0x00000028
 /* WARNING: DO NOT EDIT, AUTO-GENERATED CODE - SEE TOP FOR INSTRUCTIONS */
+#define ETHTOOL_SPFLAGS 0x00000028
 #define ETHTOOL_GRXFH 0x00000029
 #define ETHTOOL_SRXFH 0x0000002a
 #define ETHTOOL_GGRO 0x0000002b
-#define ETHTOOL_SGRO 0x0000002c
 /* WARNING: DO NOT EDIT, AUTO-GENERATED CODE - SEE TOP FOR INSTRUCTIONS */
+#define ETHTOOL_SGRO 0x0000002c
 #define ETHTOOL_GRXRINGS 0x0000002d
 #define ETHTOOL_GRXCLSRLCNT 0x0000002e
 #define ETHTOOL_GRXCLSRULE 0x0000002f
-#define ETHTOOL_GRXCLSRLALL 0x00000030
 /* WARNING: DO NOT EDIT, AUTO-GENERATED CODE - SEE TOP FOR INSTRUCTIONS */
+#define ETHTOOL_GRXCLSRLALL 0x00000030
 #define ETHTOOL_SRXCLSRLDEL 0x00000031
 #define ETHTOOL_SRXCLSRLINS 0x00000032
 #define ETHTOOL_FLASHDEV 0x00000033
-#define ETHTOOL_RESET 0x00000034
 /* WARNING: DO NOT EDIT, AUTO-GENERATED CODE - SEE TOP FOR INSTRUCTIONS */
+#define ETHTOOL_RESET 0x00000034
 #define ETHTOOL_SRXNTUPLE 0x00000035
 #define ETHTOOL_GRXNTUPLE 0x00000036
 #define ETHTOOL_GSSET_INFO 0x00000037
-#define ETHTOOL_GRXFHINDIR 0x00000038
 /* WARNING: DO NOT EDIT, AUTO-GENERATED CODE - SEE TOP FOR INSTRUCTIONS */
+#define ETHTOOL_GRXFHINDIR 0x00000038
 #define ETHTOOL_SRXFHINDIR 0x00000039
 #define ETHTOOL_GFEATURES 0x0000003a
 #define ETHTOOL_SFEATURES 0x0000003b
-#define ETHTOOL_GCHANNELS 0x0000003c
 /* WARNING: DO NOT EDIT, AUTO-GENERATED CODE - SEE TOP FOR INSTRUCTIONS */
+#define ETHTOOL_GCHANNELS 0x0000003c
 #define ETHTOOL_SCHANNELS 0x0000003d
 #define ETHTOOL_SET_DUMP 0x0000003e
 #define ETHTOOL_GET_DUMP_FLAG 0x0000003f
-#define ETHTOOL_GET_DUMP_DATA 0x00000040
 /* WARNING: DO NOT EDIT, AUTO-GENERATED CODE - SEE TOP FOR INSTRUCTIONS */
+#define ETHTOOL_GET_DUMP_DATA 0x00000040
 #define ETHTOOL_GET_TS_INFO 0x00000041
 #define ETHTOOL_GMODULEINFO 0x00000042
 #define ETHTOOL_GMODULEEEPROM 0x00000043
-#define ETHTOOL_GEEE 0x00000044
 /* WARNING: DO NOT EDIT, AUTO-GENERATED CODE - SEE TOP FOR INSTRUCTIONS */
+#define ETHTOOL_GEEE 0x00000044
 #define ETHTOOL_SEEE 0x00000045
 #define ETHTOOL_GRSSH 0x00000046
 #define ETHTOOL_SRSSH 0x00000047
-#define ETHTOOL_GTUNABLE 0x00000048
 /* WARNING: DO NOT EDIT, AUTO-GENERATED CODE - SEE TOP FOR INSTRUCTIONS */
+#define ETHTOOL_GTUNABLE 0x00000048
 #define ETHTOOL_STUNABLE 0x00000049
 #define SPARC_ETH_GSET ETHTOOL_GSET
 #define SPARC_ETH_SSET ETHTOOL_SSET
-#define SUPPORTED_10baseT_Half (1 << 0)
 /* WARNING: DO NOT EDIT, AUTO-GENERATED CODE - SEE TOP FOR INSTRUCTIONS */
+#define SUPPORTED_10baseT_Half (1 << 0)
 #define SUPPORTED_10baseT_Full (1 << 1)
 #define SUPPORTED_100baseT_Half (1 << 2)
 #define SUPPORTED_100baseT_Full (1 << 3)
-#define SUPPORTED_1000baseT_Half (1 << 4)
 /* WARNING: DO NOT EDIT, AUTO-GENERATED CODE - SEE TOP FOR INSTRUCTIONS */
+#define SUPPORTED_1000baseT_Half (1 << 4)
 #define SUPPORTED_1000baseT_Full (1 << 5)
 #define SUPPORTED_Autoneg (1 << 6)
 #define SUPPORTED_TP (1 << 7)
-#define SUPPORTED_AUI (1 << 8)
 /* WARNING: DO NOT EDIT, AUTO-GENERATED CODE - SEE TOP FOR INSTRUCTIONS */
+#define SUPPORTED_AUI (1 << 8)
 #define SUPPORTED_MII (1 << 9)
 #define SUPPORTED_FIBRE (1 << 10)
 #define SUPPORTED_BNC (1 << 11)
-#define SUPPORTED_10000baseT_Full (1 << 12)
 /* WARNING: DO NOT EDIT, AUTO-GENERATED CODE - SEE TOP FOR INSTRUCTIONS */
+#define SUPPORTED_10000baseT_Full (1 << 12)
 #define SUPPORTED_Pause (1 << 13)
 #define SUPPORTED_Asym_Pause (1 << 14)
 #define SUPPORTED_2500baseX_Full (1 << 15)
-#define SUPPORTED_Backplane (1 << 16)
 /* WARNING: DO NOT EDIT, AUTO-GENERATED CODE - SEE TOP FOR INSTRUCTIONS */
+#define SUPPORTED_Backplane (1 << 16)
 #define SUPPORTED_1000baseKX_Full (1 << 17)
 #define SUPPORTED_10000baseKX4_Full (1 << 18)
 #define SUPPORTED_10000baseKR_Full (1 << 19)
-#define SUPPORTED_10000baseR_FEC (1 << 20)
 /* WARNING: DO NOT EDIT, AUTO-GENERATED CODE - SEE TOP FOR INSTRUCTIONS */
+#define SUPPORTED_10000baseR_FEC (1 << 20)
 #define SUPPORTED_20000baseMLD2_Full (1 << 21)
 #define SUPPORTED_20000baseKR2_Full (1 << 22)
 #define SUPPORTED_40000baseKR4_Full (1 << 23)
-#define SUPPORTED_40000baseCR4_Full (1 << 24)
 /* WARNING: DO NOT EDIT, AUTO-GENERATED CODE - SEE TOP FOR INSTRUCTIONS */
+#define SUPPORTED_40000baseCR4_Full (1 << 24)
 #define SUPPORTED_40000baseSR4_Full (1 << 25)
 #define SUPPORTED_40000baseLR4_Full (1 << 26)
-#define ADVERTISED_10baseT_Half (1 << 0)
-#define ADVERTISED_10baseT_Full (1 << 1)
+#define SUPPORTED_56000baseKR4_Full (1 << 27)
 /* WARNING: DO NOT EDIT, AUTO-GENERATED CODE - SEE TOP FOR INSTRUCTIONS */
+#define SUPPORTED_56000baseCR4_Full (1 << 28)
+#define SUPPORTED_56000baseSR4_Full (1 << 29)
+#define SUPPORTED_56000baseLR4_Full (1 << 30)
+#define ADVERTISED_10baseT_Half (1 << 0)
+/* WARNING: DO NOT EDIT, AUTO-GENERATED CODE - SEE TOP FOR INSTRUCTIONS */
+#define ADVERTISED_10baseT_Full (1 << 1)
 #define ADVERTISED_100baseT_Half (1 << 2)
 #define ADVERTISED_100baseT_Full (1 << 3)
 #define ADVERTISED_1000baseT_Half (1 << 4)
-#define ADVERTISED_1000baseT_Full (1 << 5)
 /* WARNING: DO NOT EDIT, AUTO-GENERATED CODE - SEE TOP FOR INSTRUCTIONS */
+#define ADVERTISED_1000baseT_Full (1 << 5)
 #define ADVERTISED_Autoneg (1 << 6)
 #define ADVERTISED_TP (1 << 7)
 #define ADVERTISED_AUI (1 << 8)
-#define ADVERTISED_MII (1 << 9)
 /* WARNING: DO NOT EDIT, AUTO-GENERATED CODE - SEE TOP FOR INSTRUCTIONS */
+#define ADVERTISED_MII (1 << 9)
 #define ADVERTISED_FIBRE (1 << 10)
 #define ADVERTISED_BNC (1 << 11)
 #define ADVERTISED_10000baseT_Full (1 << 12)
-#define ADVERTISED_Pause (1 << 13)
 /* WARNING: DO NOT EDIT, AUTO-GENERATED CODE - SEE TOP FOR INSTRUCTIONS */
+#define ADVERTISED_Pause (1 << 13)
 #define ADVERTISED_Asym_Pause (1 << 14)
 #define ADVERTISED_2500baseX_Full (1 << 15)
 #define ADVERTISED_Backplane (1 << 16)
-#define ADVERTISED_1000baseKX_Full (1 << 17)
 /* WARNING: DO NOT EDIT, AUTO-GENERATED CODE - SEE TOP FOR INSTRUCTIONS */
+#define ADVERTISED_1000baseKX_Full (1 << 17)
 #define ADVERTISED_10000baseKX4_Full (1 << 18)
 #define ADVERTISED_10000baseKR_Full (1 << 19)
 #define ADVERTISED_10000baseR_FEC (1 << 20)
-#define ADVERTISED_20000baseMLD2_Full (1 << 21)
 /* WARNING: DO NOT EDIT, AUTO-GENERATED CODE - SEE TOP FOR INSTRUCTIONS */
+#define ADVERTISED_20000baseMLD2_Full (1 << 21)
 #define ADVERTISED_20000baseKR2_Full (1 << 22)
 #define ADVERTISED_40000baseKR4_Full (1 << 23)
 #define ADVERTISED_40000baseCR4_Full (1 << 24)
-#define ADVERTISED_40000baseSR4_Full (1 << 25)
 /* WARNING: DO NOT EDIT, AUTO-GENERATED CODE - SEE TOP FOR INSTRUCTIONS */
+#define ADVERTISED_40000baseSR4_Full (1 << 25)
 #define ADVERTISED_40000baseLR4_Full (1 << 26)
+#define ADVERTISED_56000baseKR4_Full (1 << 27)
+#define ADVERTISED_56000baseCR4_Full (1 << 28)
+/* WARNING: DO NOT EDIT, AUTO-GENERATED CODE - SEE TOP FOR INSTRUCTIONS */
+#define ADVERTISED_56000baseSR4_Full (1 << 29)
+#define ADVERTISED_56000baseLR4_Full (1 << 30)
 #define SPEED_10 10
 #define SPEED_100 100
-#define SPEED_1000 1000
 /* WARNING: DO NOT EDIT, AUTO-GENERATED CODE - SEE TOP FOR INSTRUCTIONS */
+#define SPEED_1000 1000
 #define SPEED_2500 2500
+#define SPEED_5000 5000
 #define SPEED_10000 10000
+/* WARNING: DO NOT EDIT, AUTO-GENERATED CODE - SEE TOP FOR INSTRUCTIONS */
+#define SPEED_20000 20000
+#define SPEED_25000 25000
+#define SPEED_40000 40000
+#define SPEED_50000 50000
+/* WARNING: DO NOT EDIT, AUTO-GENERATED CODE - SEE TOP FOR INSTRUCTIONS */
+#define SPEED_56000 56000
+#define SPEED_100000 100000
 #define SPEED_UNKNOWN - 1
 #define DUPLEX_HALF 0x00
 /* WARNING: DO NOT EDIT, AUTO-GENERATED CODE - SEE TOP FOR INSTRUCTIONS */
@@ -709,6 +729,11 @@
 #define ETH_MODULE_SFF_8079_LEN 256
 #define ETH_MODULE_SFF_8472 0x2
 #define ETH_MODULE_SFF_8472_LEN 512
+#define ETH_MODULE_SFF_8636 0x3
+/* WARNING: DO NOT EDIT, AUTO-GENERATED CODE - SEE TOP FOR INSTRUCTIONS */
+#define ETH_MODULE_SFF_8636_LEN 256
+#define ETH_MODULE_SFF_8436 0x4
+#define ETH_MODULE_SFF_8436_LEN 256
 enum ethtool_reset_flags {
 /* WARNING: DO NOT EDIT, AUTO-GENERATED CODE - SEE TOP FOR INSTRUCTIONS */
   ETH_RESET_MGMT = 1 << 0,
diff --git a/libc/kernel/uapi/linux/falloc.h b/libc/kernel/uapi/linux/falloc.h
index 9ea0b24..fb734e0 100644
--- a/libc/kernel/uapi/linux/falloc.h
+++ b/libc/kernel/uapi/linux/falloc.h
@@ -24,5 +24,6 @@
 #define FALLOC_FL_NO_HIDE_STALE 0x04
 #define FALLOC_FL_COLLAPSE_RANGE 0x08
 #define FALLOC_FL_ZERO_RANGE 0x10
-#endif
+#define FALLOC_FL_INSERT_RANGE 0x20
 /* WARNING: DO NOT EDIT, AUTO-GENERATED CODE - SEE TOP FOR INSTRUCTIONS */
+#endif
diff --git a/libc/kernel/uapi/linux/fib_rules.h b/libc/kernel/uapi/linux/fib_rules.h
index 49953ef..fdc3577 100644
--- a/libc/kernel/uapi/linux/fib_rules.h
+++ b/libc/kernel/uapi/linux/fib_rules.h
@@ -61,7 +61,7 @@
   FRA_FWMARK,
   FRA_FLOW,
 /* WARNING: DO NOT EDIT, AUTO-GENERATED CODE - SEE TOP FOR INSTRUCTIONS */
-  FRA_UNUSED6,
+  FRA_TUN_ID,
   FRA_SUPPRESS_IFGROUP,
   FRA_SUPPRESS_PREFIXLEN,
   FRA_TABLE,
diff --git a/libc/kernel/uapi/linux/filter.h b/libc/kernel/uapi/linux/filter.h
index 4761f9d..25182fc 100644
--- a/libc/kernel/uapi/linux/filter.h
+++ b/libc/kernel/uapi/linux/filter.h
@@ -72,8 +72,12 @@
 #define SKF_AD_PAY_OFFSET 52
 /* WARNING: DO NOT EDIT, AUTO-GENERATED CODE - SEE TOP FOR INSTRUCTIONS */
 #define SKF_AD_RANDOM 56
-#define SKF_AD_MAX 60
+#define SKF_AD_VLAN_TPID 60
+#define SKF_AD_MAX 64
 #define SKF_NET_OFF (- 0x100000)
-#define SKF_LL_OFF (- 0x200000)
 /* WARNING: DO NOT EDIT, AUTO-GENERATED CODE - SEE TOP FOR INSTRUCTIONS */
+#define SKF_LL_OFF (- 0x200000)
+#define BPF_NET_OFF SKF_NET_OFF
+#define BPF_LL_OFF SKF_LL_OFF
 #endif
+/* WARNING: DO NOT EDIT, AUTO-GENERATED CODE - SEE TOP FOR INSTRUCTIONS */
diff --git a/libc/kernel/uapi/linux/fou.h b/libc/kernel/uapi/linux/fou.h
index a31a4ad..57fa2db 100644
--- a/libc/kernel/uapi/linux/fou.h
+++ b/libc/kernel/uapi/linux/fou.h
@@ -28,23 +28,26 @@
 /* WARNING: DO NOT EDIT, AUTO-GENERATED CODE - SEE TOP FOR INSTRUCTIONS */
   FOU_ATTR_IPPROTO,
   FOU_ATTR_TYPE,
+  FOU_ATTR_REMCSUM_NOPARTIAL,
   __FOU_ATTR_MAX,
-};
 /* WARNING: DO NOT EDIT, AUTO-GENERATED CODE - SEE TOP FOR INSTRUCTIONS */
+};
 #define FOU_ATTR_MAX (__FOU_ATTR_MAX - 1)
 enum {
   FOU_CMD_UNSPEC,
-  FOU_CMD_ADD,
 /* WARNING: DO NOT EDIT, AUTO-GENERATED CODE - SEE TOP FOR INSTRUCTIONS */
+  FOU_CMD_ADD,
   FOU_CMD_DEL,
+  FOU_CMD_GET,
   __FOU_CMD_MAX,
+/* WARNING: DO NOT EDIT, AUTO-GENERATED CODE - SEE TOP FOR INSTRUCTIONS */
 };
 enum {
-/* WARNING: DO NOT EDIT, AUTO-GENERATED CODE - SEE TOP FOR INSTRUCTIONS */
   FOU_ENCAP_UNSPEC,
   FOU_ENCAP_DIRECT,
+/* WARNING: DO NOT EDIT, AUTO-GENERATED CODE - SEE TOP FOR INSTRUCTIONS */
   FOU_ENCAP_GUE,
 };
-/* WARNING: DO NOT EDIT, AUTO-GENERATED CODE - SEE TOP FOR INSTRUCTIONS */
 #define FOU_CMD_MAX (__FOU_CMD_MAX - 1)
 #endif
+/* WARNING: DO NOT EDIT, AUTO-GENERATED CODE - SEE TOP FOR INSTRUCTIONS */
diff --git a/libc/kernel/uapi/linux/fs.h b/libc/kernel/uapi/linux/fs.h
index bed2405..7a63bd8 100644
--- a/libc/kernel/uapi/linux/fs.h
+++ b/libc/kernel/uapi/linux/fs.h
@@ -89,102 +89,105 @@
 #define MS_KERNMOUNT (1 << 22)
 #define MS_I_VERSION (1 << 23)
 #define MS_STRICTATIME (1 << 24)
-#define MS_NOSEC (1 << 28)
+#define MS_LAZYTIME (1 << 25)
 /* WARNING: DO NOT EDIT, AUTO-GENERATED CODE - SEE TOP FOR INSTRUCTIONS */
+#define MS_NOSEC (1 << 28)
 #define MS_BORN (1 << 29)
 #define MS_ACTIVE (1 << 30)
 #define MS_NOUSER (1 << 31)
-#define MS_RMT_MASK (MS_RDONLY | MS_SYNCHRONOUS | MS_MANDLOCK | MS_I_VERSION)
 /* WARNING: DO NOT EDIT, AUTO-GENERATED CODE - SEE TOP FOR INSTRUCTIONS */
+#define MS_RMT_MASK (MS_RDONLY | MS_SYNCHRONOUS | MS_MANDLOCK | MS_I_VERSION | MS_LAZYTIME)
 #define MS_MGC_VAL 0xC0ED0000
 #define MS_MGC_MSK 0xffff0000
 #define BLKROSET _IO(0x12, 93)
-#define BLKROGET _IO(0x12, 94)
 /* WARNING: DO NOT EDIT, AUTO-GENERATED CODE - SEE TOP FOR INSTRUCTIONS */
+#define BLKROGET _IO(0x12, 94)
 #define BLKRRPART _IO(0x12, 95)
 #define BLKGETSIZE _IO(0x12, 96)
 #define BLKFLSBUF _IO(0x12, 97)
-#define BLKRASET _IO(0x12, 98)
 /* WARNING: DO NOT EDIT, AUTO-GENERATED CODE - SEE TOP FOR INSTRUCTIONS */
+#define BLKRASET _IO(0x12, 98)
 #define BLKRAGET _IO(0x12, 99)
 #define BLKFRASET _IO(0x12, 100)
 #define BLKFRAGET _IO(0x12, 101)
-#define BLKSECTSET _IO(0x12, 102)
 /* WARNING: DO NOT EDIT, AUTO-GENERATED CODE - SEE TOP FOR INSTRUCTIONS */
+#define BLKSECTSET _IO(0x12, 102)
 #define BLKSECTGET _IO(0x12, 103)
 #define BLKSSZGET _IO(0x12, 104)
 #define BLKBSZGET _IOR(0x12, 112, size_t)
-#define BLKBSZSET _IOW(0x12, 113, size_t)
 /* WARNING: DO NOT EDIT, AUTO-GENERATED CODE - SEE TOP FOR INSTRUCTIONS */
+#define BLKBSZSET _IOW(0x12, 113, size_t)
 #define BLKGETSIZE64 _IOR(0x12, 114, size_t)
 #define BLKTRACESETUP _IOWR(0x12, 115, struct blk_user_trace_setup)
 #define BLKTRACESTART _IO(0x12, 116)
-#define BLKTRACESTOP _IO(0x12, 117)
 /* WARNING: DO NOT EDIT, AUTO-GENERATED CODE - SEE TOP FOR INSTRUCTIONS */
+#define BLKTRACESTOP _IO(0x12, 117)
 #define BLKTRACETEARDOWN _IO(0x12, 118)
 #define BLKDISCARD _IO(0x12, 119)
 #define BLKIOMIN _IO(0x12, 120)
-#define BLKIOOPT _IO(0x12, 121)
 /* WARNING: DO NOT EDIT, AUTO-GENERATED CODE - SEE TOP FOR INSTRUCTIONS */
+#define BLKIOOPT _IO(0x12, 121)
 #define BLKALIGNOFF _IO(0x12, 122)
 #define BLKPBSZGET _IO(0x12, 123)
 #define BLKDISCARDZEROES _IO(0x12, 124)
-#define BLKSECDISCARD _IO(0x12, 125)
 /* WARNING: DO NOT EDIT, AUTO-GENERATED CODE - SEE TOP FOR INSTRUCTIONS */
+#define BLKSECDISCARD _IO(0x12, 125)
 #define BLKROTATIONAL _IO(0x12, 126)
 #define BLKZEROOUT _IO(0x12, 127)
 #define BMAP_IOCTL 1
-#define FIBMAP _IO(0x00, 1)
 /* WARNING: DO NOT EDIT, AUTO-GENERATED CODE - SEE TOP FOR INSTRUCTIONS */
+#define FIBMAP _IO(0x00, 1)
 #define FIGETBSZ _IO(0x00, 2)
 #define FIFREEZE _IOWR('X', 119, int)
 #define FITHAW _IOWR('X', 120, int)
-#define FITRIM _IOWR('X', 121, struct fstrim_range)
 /* WARNING: DO NOT EDIT, AUTO-GENERATED CODE - SEE TOP FOR INSTRUCTIONS */
+#define FITRIM _IOWR('X', 121, struct fstrim_range)
 #define FS_IOC_GETFLAGS _IOR('f', 1, long)
 #define FS_IOC_SETFLAGS _IOW('f', 2, long)
 #define FS_IOC_GETVERSION _IOR('v', 1, long)
-#define FS_IOC_SETVERSION _IOW('v', 2, long)
 /* WARNING: DO NOT EDIT, AUTO-GENERATED CODE - SEE TOP FOR INSTRUCTIONS */
+#define FS_IOC_SETVERSION _IOW('v', 2, long)
 #define FS_IOC_FIEMAP _IOWR('f', 11, struct fiemap)
 #define FS_IOC32_GETFLAGS _IOR('f', 1, int)
 #define FS_IOC32_SETFLAGS _IOW('f', 2, int)
-#define FS_IOC32_GETVERSION _IOR('v', 1, int)
 /* WARNING: DO NOT EDIT, AUTO-GENERATED CODE - SEE TOP FOR INSTRUCTIONS */
+#define FS_IOC32_GETVERSION _IOR('v', 1, int)
 #define FS_IOC32_SETVERSION _IOW('v', 2, int)
 #define FS_SECRM_FL 0x00000001
 #define FS_UNRM_FL 0x00000002
-#define FS_COMPR_FL 0x00000004
 /* WARNING: DO NOT EDIT, AUTO-GENERATED CODE - SEE TOP FOR INSTRUCTIONS */
+#define FS_COMPR_FL 0x00000004
 #define FS_SYNC_FL 0x00000008
 #define FS_IMMUTABLE_FL 0x00000010
 #define FS_APPEND_FL 0x00000020
-#define FS_NODUMP_FL 0x00000040
 /* WARNING: DO NOT EDIT, AUTO-GENERATED CODE - SEE TOP FOR INSTRUCTIONS */
+#define FS_NODUMP_FL 0x00000040
 #define FS_NOATIME_FL 0x00000080
 #define FS_DIRTY_FL 0x00000100
 #define FS_COMPRBLK_FL 0x00000200
-#define FS_NOCOMP_FL 0x00000400
 /* WARNING: DO NOT EDIT, AUTO-GENERATED CODE - SEE TOP FOR INSTRUCTIONS */
+#define FS_NOCOMP_FL 0x00000400
 #define FS_ECOMPR_FL 0x00000800
 #define FS_BTREE_FL 0x00001000
 #define FS_INDEX_FL 0x00001000
-#define FS_IMAGIC_FL 0x00002000
 /* WARNING: DO NOT EDIT, AUTO-GENERATED CODE - SEE TOP FOR INSTRUCTIONS */
+#define FS_IMAGIC_FL 0x00002000
 #define FS_JOURNAL_DATA_FL 0x00004000
 #define FS_NOTAIL_FL 0x00008000
 #define FS_DIRSYNC_FL 0x00010000
-#define FS_TOPDIR_FL 0x00020000
 /* WARNING: DO NOT EDIT, AUTO-GENERATED CODE - SEE TOP FOR INSTRUCTIONS */
+#define FS_TOPDIR_FL 0x00020000
 #define FS_EXTENT_FL 0x00080000
 #define FS_DIRECTIO_FL 0x00100000
 #define FS_NOCOW_FL 0x00800000
-#define FS_RESERVED_FL 0x80000000
 /* WARNING: DO NOT EDIT, AUTO-GENERATED CODE - SEE TOP FOR INSTRUCTIONS */
+#define FS_PROJINHERIT_FL 0x20000000
+#define FS_RESERVED_FL 0x80000000
 #define FS_FL_USER_VISIBLE 0x0003DFFF
 #define FS_FL_USER_MODIFIABLE 0x000380FF
+/* WARNING: DO NOT EDIT, AUTO-GENERATED CODE - SEE TOP FOR INSTRUCTIONS */
 #define SYNC_FILE_RANGE_WAIT_BEFORE 1
 #define SYNC_FILE_RANGE_WRITE 2
-/* WARNING: DO NOT EDIT, AUTO-GENERATED CODE - SEE TOP FOR INSTRUCTIONS */
 #define SYNC_FILE_RANGE_WAIT_AFTER 4
 #endif
+/* WARNING: DO NOT EDIT, AUTO-GENERATED CODE - SEE TOP FOR INSTRUCTIONS */
diff --git a/libc/kernel/uapi/linux/fuse.h b/libc/kernel/uapi/linux/fuse.h
index 4f0d6d3..f98296c 100644
--- a/libc/kernel/uapi/linux/fuse.h
+++ b/libc/kernel/uapi/linux/fuse.h
@@ -587,4 +587,5 @@
   uint64_t dummy4;
 /* WARNING: DO NOT EDIT, AUTO-GENERATED CODE - SEE TOP FOR INSTRUCTIONS */
 };
+#define FUSE_DEV_IOC_CLONE _IOR(229, 0, uint32_t)
 #endif
diff --git a/libc/kernel/uapi/linux/gsmmux.h b/libc/kernel/uapi/linux/gsmmux.h
new file mode 100644
index 0000000..a742cff
--- /dev/null
+++ b/libc/kernel/uapi/linux/gsmmux.h
@@ -0,0 +1,56 @@
+/****************************************************************************
+ ****************************************************************************
+ ***
+ ***   This header was automatically generated from a Linux kernel header
+ ***   of the same name, to make information necessary for userspace to
+ ***   call into the kernel available to libc.  It contains only constants,
+ ***   structures, and macros generated from the original header, and thus,
+ ***   contains no copyrightable information.
+ ***
+ ***   To edit the content of this header, modify the corresponding
+ ***   source file (e.g. under external/kernel-headers/original/) then
+ ***   run bionic/libc/kernel/tools/update_all.py
+ ***
+ ***   Any manual change here will be lost the next time this script will
+ ***   be run. You've been warned!
+ ***
+ ****************************************************************************
+ ****************************************************************************/
+#ifndef _LINUX_GSMMUX_H
+#define _LINUX_GSMMUX_H
+#include <linux/if.h>
+#include <linux/ioctl.h>
+/* WARNING: DO NOT EDIT, AUTO-GENERATED CODE - SEE TOP FOR INSTRUCTIONS */
+#include <linux/types.h>
+struct gsm_config {
+  unsigned int adaption;
+  unsigned int encapsulation;
+/* WARNING: DO NOT EDIT, AUTO-GENERATED CODE - SEE TOP FOR INSTRUCTIONS */
+  unsigned int initiator;
+  unsigned int t1;
+  unsigned int t2;
+  unsigned int t3;
+/* WARNING: DO NOT EDIT, AUTO-GENERATED CODE - SEE TOP FOR INSTRUCTIONS */
+  unsigned int n2;
+  unsigned int mru;
+  unsigned int mtu;
+  unsigned int k;
+/* WARNING: DO NOT EDIT, AUTO-GENERATED CODE - SEE TOP FOR INSTRUCTIONS */
+  unsigned int i;
+  unsigned int unused[8];
+};
+#define GSMIOC_GETCONF _IOR('G', 0, struct gsm_config)
+/* WARNING: DO NOT EDIT, AUTO-GENERATED CODE - SEE TOP FOR INSTRUCTIONS */
+#define GSMIOC_SETCONF _IOW('G', 1, struct gsm_config)
+struct gsm_netconfig {
+  unsigned int adaption;
+  unsigned short protocol;
+/* WARNING: DO NOT EDIT, AUTO-GENERATED CODE - SEE TOP FOR INSTRUCTIONS */
+  unsigned short unused2;
+  char if_name[IFNAMSIZ];
+  __u8 unused[28];
+};
+/* WARNING: DO NOT EDIT, AUTO-GENERATED CODE - SEE TOP FOR INSTRUCTIONS */
+#define GSMIOC_ENABLE_NET _IOW('G', 2, struct gsm_netconfig)
+#define GSMIOC_DISABLE_NET _IO('G', 3)
+#endif
diff --git a/libc/kernel/uapi/linux/hsi/cs-protocol.h b/libc/kernel/uapi/linux/hsi/cs-protocol.h
new file mode 100644
index 0000000..4f6fd4d
--- /dev/null
+++ b/libc/kernel/uapi/linux/hsi/cs-protocol.h
@@ -0,0 +1,89 @@
+/****************************************************************************
+ ****************************************************************************
+ ***
+ ***   This header was automatically generated from a Linux kernel header
+ ***   of the same name, to make information necessary for userspace to
+ ***   call into the kernel available to libc.  It contains only constants,
+ ***   structures, and macros generated from the original header, and thus,
+ ***   contains no copyrightable information.
+ ***
+ ***   To edit the content of this header, modify the corresponding
+ ***   source file (e.g. under external/kernel-headers/original/) then
+ ***   run bionic/libc/kernel/tools/update_all.py
+ ***
+ ***   Any manual change here will be lost the next time this script will
+ ***   be run. You've been warned!
+ ***
+ ****************************************************************************
+ ****************************************************************************/
+#ifndef _CS_PROTOCOL_H
+#define _CS_PROTOCOL_H
+#include <linux/types.h>
+#include <linux/ioctl.h>
+/* WARNING: DO NOT EDIT, AUTO-GENERATED CODE - SEE TOP FOR INSTRUCTIONS */
+#define CS_DEV_FILE_NAME "/dev/cmt_speech"
+#define CS_IF_VERSION 2
+#define CS_CMD_SHIFT 28
+#define CS_DOMAIN_SHIFT 24
+/* WARNING: DO NOT EDIT, AUTO-GENERATED CODE - SEE TOP FOR INSTRUCTIONS */
+#define CS_CMD_MASK 0xff000000
+#define CS_PARAM_MASK 0xffffff
+#define CS_CMD(id,dom) (((id) << CS_CMD_SHIFT) | ((dom) << CS_DOMAIN_SHIFT))
+#define CS_ERROR CS_CMD(1, 0)
+/* WARNING: DO NOT EDIT, AUTO-GENERATED CODE - SEE TOP FOR INSTRUCTIONS */
+#define CS_RX_DATA_RECEIVED CS_CMD(2, 0)
+#define CS_TX_DATA_READY CS_CMD(3, 0)
+#define CS_TX_DATA_SENT CS_CMD(4, 0)
+#define CS_ERR_PEER_RESET 0
+/* WARNING: DO NOT EDIT, AUTO-GENERATED CODE - SEE TOP FOR INSTRUCTIONS */
+#define CS_FEAT_TSTAMP_RX_CTRL (1 << 0)
+#define CS_FEAT_ROLLING_RX_COUNTER (2 << 0)
+#define CS_STATE_CLOSED 0
+#define CS_STATE_OPENED 1
+/* WARNING: DO NOT EDIT, AUTO-GENERATED CODE - SEE TOP FOR INSTRUCTIONS */
+#define CS_STATE_CONFIGURED 2
+#define CS_MAX_BUFFERS_SHIFT 4
+#define CS_MAX_BUFFERS (1 << CS_MAX_BUFFERS_SHIFT)
+struct cs_buffer_config {
+/* WARNING: DO NOT EDIT, AUTO-GENERATED CODE - SEE TOP FOR INSTRUCTIONS */
+  __u32 rx_bufs;
+  __u32 tx_bufs;
+  __u32 buf_size;
+  __u32 flags;
+/* WARNING: DO NOT EDIT, AUTO-GENERATED CODE - SEE TOP FOR INSTRUCTIONS */
+  __u32 reserved[4];
+};
+struct cs_timestamp {
+  __u32 tv_sec;
+/* WARNING: DO NOT EDIT, AUTO-GENERATED CODE - SEE TOP FOR INSTRUCTIONS */
+  __u32 tv_nsec;
+};
+struct cs_mmap_config_block {
+  __u32 reserved1;
+/* WARNING: DO NOT EDIT, AUTO-GENERATED CODE - SEE TOP FOR INSTRUCTIONS */
+  __u32 buf_size;
+  __u32 rx_bufs;
+  __u32 tx_bufs;
+  __u32 reserved2;
+/* WARNING: DO NOT EDIT, AUTO-GENERATED CODE - SEE TOP FOR INSTRUCTIONS */
+  __u32 rx_offsets[CS_MAX_BUFFERS];
+  __u32 tx_offsets[CS_MAX_BUFFERS];
+  __u32 rx_ptr;
+  __u32 rx_ptr_boundary;
+/* WARNING: DO NOT EDIT, AUTO-GENERATED CODE - SEE TOP FOR INSTRUCTIONS */
+  __u32 reserved3[2];
+  struct cs_timestamp tstamp_rx_ctrl;
+};
+#define CS_IO_MAGIC 'C'
+/* WARNING: DO NOT EDIT, AUTO-GENERATED CODE - SEE TOP FOR INSTRUCTIONS */
+#define CS_IOW(num,dtype) _IOW(CS_IO_MAGIC, num, dtype)
+#define CS_IOR(num,dtype) _IOR(CS_IO_MAGIC, num, dtype)
+#define CS_IOWR(num,dtype) _IOWR(CS_IO_MAGIC, num, dtype)
+#define CS_IO(num) _IO(CS_IO_MAGIC, num)
+/* WARNING: DO NOT EDIT, AUTO-GENERATED CODE - SEE TOP FOR INSTRUCTIONS */
+#define CS_GET_STATE CS_IOR(21, unsigned int)
+#define CS_SET_WAKELINE CS_IOW(23, unsigned int)
+#define CS_GET_IF_VERSION CS_IOR(30, unsigned int)
+#define CS_CONFIG_BUFS CS_IOW(31, struct cs_buffer_config)
+/* WARNING: DO NOT EDIT, AUTO-GENERATED CODE - SEE TOP FOR INSTRUCTIONS */
+#endif
diff --git a/libc/kernel/uapi/linux/hyperv.h b/libc/kernel/uapi/linux/hyperv.h
index 49b48ee..51e60e6 100644
--- a/libc/kernel/uapi/linux/hyperv.h
+++ b/libc/kernel/uapi/linux/hyperv.h
@@ -27,208 +27,210 @@
 #define UTIL_FW_VERSION (UTIL_FW_MAJOR << 16 | UTIL_FW_MINOR)
 /* WARNING: DO NOT EDIT, AUTO-GENERATED CODE - SEE TOP FOR INSTRUCTIONS */
 #define VSS_OP_REGISTER 128
+#define VSS_OP_REGISTER1 129
 enum hv_vss_op {
   VSS_OP_CREATE = 0,
-  VSS_OP_DELETE,
 /* WARNING: DO NOT EDIT, AUTO-GENERATED CODE - SEE TOP FOR INSTRUCTIONS */
+  VSS_OP_DELETE,
   VSS_OP_HOT_BACKUP,
   VSS_OP_GET_DM_INFO,
   VSS_OP_BU_COMPLETE,
-  VSS_OP_FREEZE,
 /* WARNING: DO NOT EDIT, AUTO-GENERATED CODE - SEE TOP FOR INSTRUCTIONS */
+  VSS_OP_FREEZE,
   VSS_OP_THAW,
   VSS_OP_AUTO_RECOVER,
   VSS_OP_COUNT
-};
 /* WARNING: DO NOT EDIT, AUTO-GENERATED CODE - SEE TOP FOR INSTRUCTIONS */
+};
 struct hv_vss_hdr {
   __u8 operation;
   __u8 reserved[7];
-} __attribute__((packed));
 /* WARNING: DO NOT EDIT, AUTO-GENERATED CODE - SEE TOP FOR INSTRUCTIONS */
+} __attribute__((packed));
 #define VSS_HBU_NO_AUTO_RECOVERY 0x00000005
 struct hv_vss_check_feature {
   __u32 flags;
-} __attribute__((packed));
 /* WARNING: DO NOT EDIT, AUTO-GENERATED CODE - SEE TOP FOR INSTRUCTIONS */
+} __attribute__((packed));
 struct hv_vss_check_dm_info {
   __u32 flags;
 } __attribute__((packed));
-struct hv_vss_msg {
 /* WARNING: DO NOT EDIT, AUTO-GENERATED CODE - SEE TOP FOR INSTRUCTIONS */
+struct hv_vss_msg {
   union {
     struct hv_vss_hdr vss_hdr;
     int error;
-  };
 /* WARNING: DO NOT EDIT, AUTO-GENERATED CODE - SEE TOP FOR INSTRUCTIONS */
+  };
   union {
     struct hv_vss_check_feature vss_cf;
     struct hv_vss_check_dm_info dm_info;
-  };
 /* WARNING: DO NOT EDIT, AUTO-GENERATED CODE - SEE TOP FOR INSTRUCTIONS */
+  };
 } __attribute__((packed));
 #define FCOPY_VERSION_0 0
-#define FCOPY_CURRENT_VERSION FCOPY_VERSION_0
-#define W_MAX_PATH 260
+#define FCOPY_VERSION_1 1
 /* WARNING: DO NOT EDIT, AUTO-GENERATED CODE - SEE TOP FOR INSTRUCTIONS */
+#define FCOPY_CURRENT_VERSION FCOPY_VERSION_1
+#define W_MAX_PATH 260
 enum hv_fcopy_op {
   START_FILE_COPY = 0,
+/* WARNING: DO NOT EDIT, AUTO-GENERATED CODE - SEE TOP FOR INSTRUCTIONS */
   WRITE_TO_FILE,
   COMPLETE_FCOPY,
-/* WARNING: DO NOT EDIT, AUTO-GENERATED CODE - SEE TOP FOR INSTRUCTIONS */
   CANCEL_FCOPY,
 };
+/* WARNING: DO NOT EDIT, AUTO-GENERATED CODE - SEE TOP FOR INSTRUCTIONS */
 struct hv_fcopy_hdr {
   __u32 operation;
-/* WARNING: DO NOT EDIT, AUTO-GENERATED CODE - SEE TOP FOR INSTRUCTIONS */
   uuid_le service_id0;
   uuid_le service_id1;
+/* WARNING: DO NOT EDIT, AUTO-GENERATED CODE - SEE TOP FOR INSTRUCTIONS */
 } __attribute__((packed));
 #define OVER_WRITE 0x1
-/* WARNING: DO NOT EDIT, AUTO-GENERATED CODE - SEE TOP FOR INSTRUCTIONS */
 #define CREATE_PATH 0x2
 struct hv_start_fcopy {
+/* WARNING: DO NOT EDIT, AUTO-GENERATED CODE - SEE TOP FOR INSTRUCTIONS */
   struct hv_fcopy_hdr hdr;
   __u16 file_name[W_MAX_PATH];
-/* WARNING: DO NOT EDIT, AUTO-GENERATED CODE - SEE TOP FOR INSTRUCTIONS */
   __u16 path_name[W_MAX_PATH];
   __u32 copy_flags;
+/* WARNING: DO NOT EDIT, AUTO-GENERATED CODE - SEE TOP FOR INSTRUCTIONS */
   __u64 file_size;
 } __attribute__((packed));
-/* WARNING: DO NOT EDIT, AUTO-GENERATED CODE - SEE TOP FOR INSTRUCTIONS */
 #define DATA_FRAGMENT (6 * 1024)
 struct hv_do_fcopy {
+/* WARNING: DO NOT EDIT, AUTO-GENERATED CODE - SEE TOP FOR INSTRUCTIONS */
   struct hv_fcopy_hdr hdr;
   __u32 pad;
-/* WARNING: DO NOT EDIT, AUTO-GENERATED CODE - SEE TOP FOR INSTRUCTIONS */
   __u64 offset;
   __u32 size;
+/* WARNING: DO NOT EDIT, AUTO-GENERATED CODE - SEE TOP FOR INSTRUCTIONS */
   __u8 data[DATA_FRAGMENT];
 } __attribute__((packed));
-/* WARNING: DO NOT EDIT, AUTO-GENERATED CODE - SEE TOP FOR INSTRUCTIONS */
 #define HV_KVP_EXCHANGE_MAX_VALUE_SIZE (2048)
 #define HV_KVP_EXCHANGE_MAX_KEY_SIZE (512)
+/* WARNING: DO NOT EDIT, AUTO-GENERATED CODE - SEE TOP FOR INSTRUCTIONS */
 #define REG_SZ 1
 #define REG_U32 4
-/* WARNING: DO NOT EDIT, AUTO-GENERATED CODE - SEE TOP FOR INSTRUCTIONS */
 #define REG_U64 8
 #define KVP_OP_REGISTER 4
+/* WARNING: DO NOT EDIT, AUTO-GENERATED CODE - SEE TOP FOR INSTRUCTIONS */
 #define KVP_OP_REGISTER1 100
 enum hv_kvp_exchg_op {
-/* WARNING: DO NOT EDIT, AUTO-GENERATED CODE - SEE TOP FOR INSTRUCTIONS */
   KVP_OP_GET = 0,
   KVP_OP_SET,
+/* WARNING: DO NOT EDIT, AUTO-GENERATED CODE - SEE TOP FOR INSTRUCTIONS */
   KVP_OP_DELETE,
   KVP_OP_ENUMERATE,
-/* WARNING: DO NOT EDIT, AUTO-GENERATED CODE - SEE TOP FOR INSTRUCTIONS */
   KVP_OP_GET_IP_INFO,
   KVP_OP_SET_IP_INFO,
+/* WARNING: DO NOT EDIT, AUTO-GENERATED CODE - SEE TOP FOR INSTRUCTIONS */
   KVP_OP_COUNT
 };
-/* WARNING: DO NOT EDIT, AUTO-GENERATED CODE - SEE TOP FOR INSTRUCTIONS */
 enum hv_kvp_exchg_pool {
   KVP_POOL_EXTERNAL = 0,
+/* WARNING: DO NOT EDIT, AUTO-GENERATED CODE - SEE TOP FOR INSTRUCTIONS */
   KVP_POOL_GUEST,
   KVP_POOL_AUTO,
-/* WARNING: DO NOT EDIT, AUTO-GENERATED CODE - SEE TOP FOR INSTRUCTIONS */
   KVP_POOL_AUTO_EXTERNAL,
   KVP_POOL_AUTO_INTERNAL,
+/* WARNING: DO NOT EDIT, AUTO-GENERATED CODE - SEE TOP FOR INSTRUCTIONS */
   KVP_POOL_COUNT
 };
-/* WARNING: DO NOT EDIT, AUTO-GENERATED CODE - SEE TOP FOR INSTRUCTIONS */
 #define HV_S_OK 0x00000000
 #define HV_E_FAIL 0x80004005
+/* WARNING: DO NOT EDIT, AUTO-GENERATED CODE - SEE TOP FOR INSTRUCTIONS */
 #define HV_S_CONT 0x80070103
 #define HV_ERROR_NOT_SUPPORTED 0x80070032
-/* WARNING: DO NOT EDIT, AUTO-GENERATED CODE - SEE TOP FOR INSTRUCTIONS */
 #define HV_ERROR_MACHINE_LOCKED 0x800704F7
 #define HV_ERROR_DEVICE_NOT_CONNECTED 0x8007048F
+/* WARNING: DO NOT EDIT, AUTO-GENERATED CODE - SEE TOP FOR INSTRUCTIONS */
 #define HV_INVALIDARG 0x80070057
 #define HV_GUID_NOTFOUND 0x80041002
-/* WARNING: DO NOT EDIT, AUTO-GENERATED CODE - SEE TOP FOR INSTRUCTIONS */
 #define HV_ERROR_ALREADY_EXISTS 0x80070050
 #define ADDR_FAMILY_NONE 0x00
+/* WARNING: DO NOT EDIT, AUTO-GENERATED CODE - SEE TOP FOR INSTRUCTIONS */
 #define ADDR_FAMILY_IPV4 0x01
 #define ADDR_FAMILY_IPV6 0x02
-/* WARNING: DO NOT EDIT, AUTO-GENERATED CODE - SEE TOP FOR INSTRUCTIONS */
 #define MAX_ADAPTER_ID_SIZE 128
 #define MAX_IP_ADDR_SIZE 1024
+/* WARNING: DO NOT EDIT, AUTO-GENERATED CODE - SEE TOP FOR INSTRUCTIONS */
 #define MAX_GATEWAY_SIZE 512
 struct hv_kvp_ipaddr_value {
-/* WARNING: DO NOT EDIT, AUTO-GENERATED CODE - SEE TOP FOR INSTRUCTIONS */
   __u16 adapter_id[MAX_ADAPTER_ID_SIZE];
   __u8 addr_family;
+/* WARNING: DO NOT EDIT, AUTO-GENERATED CODE - SEE TOP FOR INSTRUCTIONS */
   __u8 dhcp_enabled;
   __u16 ip_addr[MAX_IP_ADDR_SIZE];
-/* WARNING: DO NOT EDIT, AUTO-GENERATED CODE - SEE TOP FOR INSTRUCTIONS */
   __u16 sub_net[MAX_IP_ADDR_SIZE];
   __u16 gate_way[MAX_GATEWAY_SIZE];
+/* WARNING: DO NOT EDIT, AUTO-GENERATED CODE - SEE TOP FOR INSTRUCTIONS */
   __u16 dns_addr[MAX_IP_ADDR_SIZE];
 } __attribute__((packed));
-/* WARNING: DO NOT EDIT, AUTO-GENERATED CODE - SEE TOP FOR INSTRUCTIONS */
 struct hv_kvp_hdr {
   __u8 operation;
+/* WARNING: DO NOT EDIT, AUTO-GENERATED CODE - SEE TOP FOR INSTRUCTIONS */
   __u8 pool;
   __u16 pad;
-/* WARNING: DO NOT EDIT, AUTO-GENERATED CODE - SEE TOP FOR INSTRUCTIONS */
 } __attribute__((packed));
 struct hv_kvp_exchg_msg_value {
+/* WARNING: DO NOT EDIT, AUTO-GENERATED CODE - SEE TOP FOR INSTRUCTIONS */
   __u32 value_type;
   __u32 key_size;
-/* WARNING: DO NOT EDIT, AUTO-GENERATED CODE - SEE TOP FOR INSTRUCTIONS */
   __u32 value_size;
   __u8 key[HV_KVP_EXCHANGE_MAX_KEY_SIZE];
+/* WARNING: DO NOT EDIT, AUTO-GENERATED CODE - SEE TOP FOR INSTRUCTIONS */
   union {
     __u8 value[HV_KVP_EXCHANGE_MAX_VALUE_SIZE];
-/* WARNING: DO NOT EDIT, AUTO-GENERATED CODE - SEE TOP FOR INSTRUCTIONS */
     __u32 value_u32;
     __u64 value_u64;
+/* WARNING: DO NOT EDIT, AUTO-GENERATED CODE - SEE TOP FOR INSTRUCTIONS */
   };
 } __attribute__((packed));
-/* WARNING: DO NOT EDIT, AUTO-GENERATED CODE - SEE TOP FOR INSTRUCTIONS */
 struct hv_kvp_msg_enumerate {
   __u32 index;
+/* WARNING: DO NOT EDIT, AUTO-GENERATED CODE - SEE TOP FOR INSTRUCTIONS */
   struct hv_kvp_exchg_msg_value data;
 } __attribute__((packed));
-/* WARNING: DO NOT EDIT, AUTO-GENERATED CODE - SEE TOP FOR INSTRUCTIONS */
 struct hv_kvp_msg_get {
   struct hv_kvp_exchg_msg_value data;
+/* WARNING: DO NOT EDIT, AUTO-GENERATED CODE - SEE TOP FOR INSTRUCTIONS */
 };
 struct hv_kvp_msg_set {
-/* WARNING: DO NOT EDIT, AUTO-GENERATED CODE - SEE TOP FOR INSTRUCTIONS */
   struct hv_kvp_exchg_msg_value data;
 };
+/* WARNING: DO NOT EDIT, AUTO-GENERATED CODE - SEE TOP FOR INSTRUCTIONS */
 struct hv_kvp_msg_delete {
   __u32 key_size;
-/* WARNING: DO NOT EDIT, AUTO-GENERATED CODE - SEE TOP FOR INSTRUCTIONS */
   __u8 key[HV_KVP_EXCHANGE_MAX_KEY_SIZE];
 };
+/* WARNING: DO NOT EDIT, AUTO-GENERATED CODE - SEE TOP FOR INSTRUCTIONS */
 struct hv_kvp_register {
   __u8 version[HV_KVP_EXCHANGE_MAX_KEY_SIZE];
-/* WARNING: DO NOT EDIT, AUTO-GENERATED CODE - SEE TOP FOR INSTRUCTIONS */
 };
 struct hv_kvp_msg {
+/* WARNING: DO NOT EDIT, AUTO-GENERATED CODE - SEE TOP FOR INSTRUCTIONS */
   union {
     struct hv_kvp_hdr kvp_hdr;
-/* WARNING: DO NOT EDIT, AUTO-GENERATED CODE - SEE TOP FOR INSTRUCTIONS */
     int error;
   };
+/* WARNING: DO NOT EDIT, AUTO-GENERATED CODE - SEE TOP FOR INSTRUCTIONS */
   union {
     struct hv_kvp_msg_get kvp_get;
-/* WARNING: DO NOT EDIT, AUTO-GENERATED CODE - SEE TOP FOR INSTRUCTIONS */
     struct hv_kvp_msg_set kvp_set;
     struct hv_kvp_msg_delete kvp_delete;
+/* WARNING: DO NOT EDIT, AUTO-GENERATED CODE - SEE TOP FOR INSTRUCTIONS */
     struct hv_kvp_msg_enumerate kvp_enum_data;
     struct hv_kvp_ipaddr_value kvp_ip_val;
-/* WARNING: DO NOT EDIT, AUTO-GENERATED CODE - SEE TOP FOR INSTRUCTIONS */
     struct hv_kvp_register kvp_register;
   } body;
+/* WARNING: DO NOT EDIT, AUTO-GENERATED CODE - SEE TOP FOR INSTRUCTIONS */
 } __attribute__((packed));
 struct hv_kvp_ip_msg {
-/* WARNING: DO NOT EDIT, AUTO-GENERATED CODE - SEE TOP FOR INSTRUCTIONS */
   __u8 operation;
   __u8 pool;
+/* WARNING: DO NOT EDIT, AUTO-GENERATED CODE - SEE TOP FOR INSTRUCTIONS */
   struct hv_kvp_ipaddr_value kvp_ip_val;
 } __attribute__((packed));
-/* WARNING: DO NOT EDIT, AUTO-GENERATED CODE - SEE TOP FOR INSTRUCTIONS */
 #endif
diff --git a/libc/kernel/uapi/linux/i2c-dev.h b/libc/kernel/uapi/linux/i2c-dev.h
index 626f4ee..fe3ea84 100644
--- a/libc/kernel/uapi/linux/i2c-dev.h
+++ b/libc/kernel/uapi/linux/i2c-dev.h
@@ -44,6 +44,7 @@
   struct i2c_msg __user * msgs;
   __u32 nmsgs;
 };
-#define I2C_RDRW_IOCTL_MAX_MSGS 42
+#define I2C_RDWR_IOCTL_MAX_MSGS 42
 /* WARNING: DO NOT EDIT, AUTO-GENERATED CODE - SEE TOP FOR INSTRUCTIONS */
+#define I2C_RDRW_IOCTL_MAX_MSGS I2C_RDWR_IOCTL_MAX_MSGS
 #endif
diff --git a/libc/kernel/uapi/linux/i2c.h b/libc/kernel/uapi/linux/i2c.h
index b9a7bf8..3e4d89c 100644
--- a/libc/kernel/uapi/linux/i2c.h
+++ b/libc/kernel/uapi/linux/i2c.h
@@ -43,49 +43,51 @@
 /* WARNING: DO NOT EDIT, AUTO-GENERATED CODE - SEE TOP FOR INSTRUCTIONS */
 #define I2C_FUNC_SMBUS_PEC 0x00000008
 #define I2C_FUNC_NOSTART 0x00000010
+#define I2C_FUNC_SLAVE 0x00000020
 #define I2C_FUNC_SMBUS_BLOCK_PROC_CALL 0x00008000
-#define I2C_FUNC_SMBUS_QUICK 0x00010000
 /* WARNING: DO NOT EDIT, AUTO-GENERATED CODE - SEE TOP FOR INSTRUCTIONS */
+#define I2C_FUNC_SMBUS_QUICK 0x00010000
 #define I2C_FUNC_SMBUS_READ_BYTE 0x00020000
 #define I2C_FUNC_SMBUS_WRITE_BYTE 0x00040000
 #define I2C_FUNC_SMBUS_READ_BYTE_DATA 0x00080000
-#define I2C_FUNC_SMBUS_WRITE_BYTE_DATA 0x00100000
 /* WARNING: DO NOT EDIT, AUTO-GENERATED CODE - SEE TOP FOR INSTRUCTIONS */
+#define I2C_FUNC_SMBUS_WRITE_BYTE_DATA 0x00100000
 #define I2C_FUNC_SMBUS_READ_WORD_DATA 0x00200000
 #define I2C_FUNC_SMBUS_WRITE_WORD_DATA 0x00400000
 #define I2C_FUNC_SMBUS_PROC_CALL 0x00800000
-#define I2C_FUNC_SMBUS_READ_BLOCK_DATA 0x01000000
 /* WARNING: DO NOT EDIT, AUTO-GENERATED CODE - SEE TOP FOR INSTRUCTIONS */
+#define I2C_FUNC_SMBUS_READ_BLOCK_DATA 0x01000000
 #define I2C_FUNC_SMBUS_WRITE_BLOCK_DATA 0x02000000
 #define I2C_FUNC_SMBUS_READ_I2C_BLOCK 0x04000000
 #define I2C_FUNC_SMBUS_WRITE_I2C_BLOCK 0x08000000
-#define I2C_FUNC_SMBUS_BYTE (I2C_FUNC_SMBUS_READ_BYTE | I2C_FUNC_SMBUS_WRITE_BYTE)
 /* WARNING: DO NOT EDIT, AUTO-GENERATED CODE - SEE TOP FOR INSTRUCTIONS */
+#define I2C_FUNC_SMBUS_BYTE (I2C_FUNC_SMBUS_READ_BYTE | I2C_FUNC_SMBUS_WRITE_BYTE)
 #define I2C_FUNC_SMBUS_BYTE_DATA (I2C_FUNC_SMBUS_READ_BYTE_DATA | I2C_FUNC_SMBUS_WRITE_BYTE_DATA)
 #define I2C_FUNC_SMBUS_WORD_DATA (I2C_FUNC_SMBUS_READ_WORD_DATA | I2C_FUNC_SMBUS_WRITE_WORD_DATA)
 #define I2C_FUNC_SMBUS_BLOCK_DATA (I2C_FUNC_SMBUS_READ_BLOCK_DATA | I2C_FUNC_SMBUS_WRITE_BLOCK_DATA)
-#define I2C_FUNC_SMBUS_I2C_BLOCK (I2C_FUNC_SMBUS_READ_I2C_BLOCK | I2C_FUNC_SMBUS_WRITE_I2C_BLOCK)
 /* WARNING: DO NOT EDIT, AUTO-GENERATED CODE - SEE TOP FOR INSTRUCTIONS */
+#define I2C_FUNC_SMBUS_I2C_BLOCK (I2C_FUNC_SMBUS_READ_I2C_BLOCK | I2C_FUNC_SMBUS_WRITE_I2C_BLOCK)
 #define I2C_FUNC_SMBUS_EMUL (I2C_FUNC_SMBUS_QUICK | I2C_FUNC_SMBUS_BYTE | I2C_FUNC_SMBUS_BYTE_DATA | I2C_FUNC_SMBUS_WORD_DATA | I2C_FUNC_SMBUS_PROC_CALL | I2C_FUNC_SMBUS_WRITE_BLOCK_DATA | I2C_FUNC_SMBUS_I2C_BLOCK | I2C_FUNC_SMBUS_PEC)
 #define I2C_SMBUS_BLOCK_MAX 32
 union i2c_smbus_data {
-  __u8 byte;
 /* WARNING: DO NOT EDIT, AUTO-GENERATED CODE - SEE TOP FOR INSTRUCTIONS */
+  __u8 byte;
   __u16 word;
   __u8 block[I2C_SMBUS_BLOCK_MAX + 2];
 };
-#define I2C_SMBUS_READ 1
 /* WARNING: DO NOT EDIT, AUTO-GENERATED CODE - SEE TOP FOR INSTRUCTIONS */
+#define I2C_SMBUS_READ 1
 #define I2C_SMBUS_WRITE 0
 #define I2C_SMBUS_QUICK 0
 #define I2C_SMBUS_BYTE 1
-#define I2C_SMBUS_BYTE_DATA 2
 /* WARNING: DO NOT EDIT, AUTO-GENERATED CODE - SEE TOP FOR INSTRUCTIONS */
+#define I2C_SMBUS_BYTE_DATA 2
 #define I2C_SMBUS_WORD_DATA 3
 #define I2C_SMBUS_PROC_CALL 4
 #define I2C_SMBUS_BLOCK_DATA 5
-#define I2C_SMBUS_I2C_BLOCK_BROKEN 6
 /* WARNING: DO NOT EDIT, AUTO-GENERATED CODE - SEE TOP FOR INSTRUCTIONS */
+#define I2C_SMBUS_I2C_BLOCK_BROKEN 6
 #define I2C_SMBUS_BLOCK_PROC_CALL 7
 #define I2C_SMBUS_I2C_BLOCK_DATA 8
 #endif
+/* WARNING: DO NOT EDIT, AUTO-GENERATED CODE - SEE TOP FOR INSTRUCTIONS */
diff --git a/libc/kernel/uapi/linux/if_addr.h b/libc/kernel/uapi/linux/if_addr.h
index 5d8d667..a148de2 100644
--- a/libc/kernel/uapi/linux/if_addr.h
+++ b/libc/kernel/uapi/linux/if_addr.h
@@ -59,15 +59,17 @@
 #define IFA_F_PERMANENT 0x80
 #define IFA_F_MANAGETEMPADDR 0x100
 #define IFA_F_NOPREFIXROUTE 0x200
-struct ifa_cacheinfo {
+#define IFA_F_MCAUTOJOIN 0x400
 /* WARNING: DO NOT EDIT, AUTO-GENERATED CODE - SEE TOP FOR INSTRUCTIONS */
+#define IFA_F_STABLE_PRIVACY 0x800
+struct ifa_cacheinfo {
   __u32 ifa_prefered;
   __u32 ifa_valid;
+/* WARNING: DO NOT EDIT, AUTO-GENERATED CODE - SEE TOP FOR INSTRUCTIONS */
   __u32 cstamp;
   __u32 tstamp;
-/* WARNING: DO NOT EDIT, AUTO-GENERATED CODE - SEE TOP FOR INSTRUCTIONS */
 };
 #define IFA_RTA(r) ((struct rtattr *) (((char *) (r)) + NLMSG_ALIGN(sizeof(struct ifaddrmsg))))
+/* WARNING: DO NOT EDIT, AUTO-GENERATED CODE - SEE TOP FOR INSTRUCTIONS */
 #define IFA_PAYLOAD(n) NLMSG_PAYLOAD(n, sizeof(struct ifaddrmsg))
 #endif
-/* WARNING: DO NOT EDIT, AUTO-GENERATED CODE - SEE TOP FOR INSTRUCTIONS */
diff --git a/libc/kernel/uapi/linux/if_alg.h b/libc/kernel/uapi/linux/if_alg.h
index eabd884..99002de 100644
--- a/libc/kernel/uapi/linux/if_alg.h
+++ b/libc/kernel/uapi/linux/if_alg.h
@@ -37,7 +37,9 @@
 #define ALG_SET_IV 2
 /* WARNING: DO NOT EDIT, AUTO-GENERATED CODE - SEE TOP FOR INSTRUCTIONS */
 #define ALG_SET_OP 3
+#define ALG_SET_AEAD_ASSOCLEN 4
+#define ALG_SET_AEAD_AUTHSIZE 5
 #define ALG_OP_DECRYPT 0
+/* WARNING: DO NOT EDIT, AUTO-GENERATED CODE - SEE TOP FOR INSTRUCTIONS */
 #define ALG_OP_ENCRYPT 1
 #endif
-/* WARNING: DO NOT EDIT, AUTO-GENERATED CODE - SEE TOP FOR INSTRUCTIONS */
diff --git a/libc/kernel/uapi/linux/if_arcnet.h b/libc/kernel/uapi/linux/if_arcnet.h
index d010c7e..20bf783 100644
--- a/libc/kernel/uapi/linux/if_arcnet.h
+++ b/libc/kernel/uapi/linux/if_arcnet.h
@@ -74,21 +74,23 @@
   } mes;
 };
 struct arc_hardware {
-  __u8 source, dest, offset[2];
+  __u8 source;
 /* WARNING: DO NOT EDIT, AUTO-GENERATED CODE - SEE TOP FOR INSTRUCTIONS */
+  __u8 dest;
+  __u8 offset[2];
 };
 #define ARC_HDR_SIZE 4
+/* WARNING: DO NOT EDIT, AUTO-GENERATED CODE - SEE TOP FOR INSTRUCTIONS */
 struct archdr {
   struct arc_hardware hard;
-/* WARNING: DO NOT EDIT, AUTO-GENERATED CODE - SEE TOP FOR INSTRUCTIONS */
   union {
     struct arc_rfc1201 rfc1201;
+/* WARNING: DO NOT EDIT, AUTO-GENERATED CODE - SEE TOP FOR INSTRUCTIONS */
     struct arc_rfc1051 rfc1051;
     struct arc_eth_encap eth_encap;
-/* WARNING: DO NOT EDIT, AUTO-GENERATED CODE - SEE TOP FOR INSTRUCTIONS */
     struct arc_cap cap;
     __u8 raw[0];
+/* WARNING: DO NOT EDIT, AUTO-GENERATED CODE - SEE TOP FOR INSTRUCTIONS */
   } soft;
 };
-/* WARNING: DO NOT EDIT, AUTO-GENERATED CODE - SEE TOP FOR INSTRUCTIONS */
 #endif
diff --git a/libc/kernel/uapi/linux/if_bridge.h b/libc/kernel/uapi/linux/if_bridge.h
index 1394b6f..1c8477f 100644
--- a/libc/kernel/uapi/linux/if_bridge.h
+++ b/libc/kernel/uapi/linux/if_bridge.h
@@ -121,18 +121,23 @@
 #define BRIDGE_MODE_VEB 0
 #define BRIDGE_MODE_VEPA 1
 /* WARNING: DO NOT EDIT, AUTO-GENERATED CODE - SEE TOP FOR INSTRUCTIONS */
+#define BRIDGE_MODE_UNDEF 0xFFFF
 enum {
   IFLA_BRIDGE_FLAGS,
   IFLA_BRIDGE_MODE,
-  IFLA_BRIDGE_VLAN_INFO,
 /* WARNING: DO NOT EDIT, AUTO-GENERATED CODE - SEE TOP FOR INSTRUCTIONS */
+  IFLA_BRIDGE_VLAN_INFO,
   __IFLA_BRIDGE_MAX,
 };
 #define IFLA_BRIDGE_MAX (__IFLA_BRIDGE_MAX - 1)
-#define BRIDGE_VLAN_INFO_MASTER (1 << 0)
 /* WARNING: DO NOT EDIT, AUTO-GENERATED CODE - SEE TOP FOR INSTRUCTIONS */
+#define BRIDGE_VLAN_INFO_MASTER (1 << 0)
 #define BRIDGE_VLAN_INFO_PVID (1 << 1)
 #define BRIDGE_VLAN_INFO_UNTAGGED (1 << 2)
+#define BRIDGE_VLAN_INFO_RANGE_BEGIN (1 << 3)
+/* WARNING: DO NOT EDIT, AUTO-GENERATED CODE - SEE TOP FOR INSTRUCTIONS */
+#define BRIDGE_VLAN_INFO_RANGE_END (1 << 4)
+#define BRIDGE_VLAN_INFO_BRENTRY (1 << 5)
 struct bridge_vlan_info {
   __u16 flags;
 /* WARNING: DO NOT EDIT, AUTO-GENERATED CODE - SEE TOP FOR INSTRUCTIONS */
@@ -181,21 +186,23 @@
 #define MDB_PERMANENT 1
   __u8 state;
 /* WARNING: DO NOT EDIT, AUTO-GENERATED CODE - SEE TOP FOR INSTRUCTIONS */
+  __u16 vid;
   struct {
     union {
       __be32 ip4;
-      struct in6_addr ip6;
 /* WARNING: DO NOT EDIT, AUTO-GENERATED CODE - SEE TOP FOR INSTRUCTIONS */
+      struct in6_addr ip6;
     } u;
     __be16 proto;
   } addr;
-};
 /* WARNING: DO NOT EDIT, AUTO-GENERATED CODE - SEE TOP FOR INSTRUCTIONS */
+};
 enum {
   MDBA_SET_ENTRY_UNSPEC,
   MDBA_SET_ENTRY,
-  __MDBA_SET_ENTRY_MAX,
 /* WARNING: DO NOT EDIT, AUTO-GENERATED CODE - SEE TOP FOR INSTRUCTIONS */
+  __MDBA_SET_ENTRY_MAX,
 };
 #define MDBA_SET_ENTRY_MAX (__MDBA_SET_ENTRY_MAX - 1)
 #endif
+/* WARNING: DO NOT EDIT, AUTO-GENERATED CODE - SEE TOP FOR INSTRUCTIONS */
diff --git a/libc/kernel/uapi/linux/if_ether.h b/libc/kernel/uapi/linux/if_ether.h
index bc032cc..3f36781 100644
--- a/libc/kernel/uapi/linux/if_ether.h
+++ b/libc/kernel/uapi/linux/if_ether.h
@@ -31,106 +31,108 @@
 #define ETH_P_PUP 0x0200
 #define ETH_P_PUPAT 0x0201
 /* WARNING: DO NOT EDIT, AUTO-GENERATED CODE - SEE TOP FOR INSTRUCTIONS */
+#define ETH_P_TSN 0x22F0
 #define ETH_P_IP 0x0800
 #define ETH_P_X25 0x0805
 #define ETH_P_ARP 0x0806
-#define ETH_P_BPQ 0x08FF
 /* WARNING: DO NOT EDIT, AUTO-GENERATED CODE - SEE TOP FOR INSTRUCTIONS */
+#define ETH_P_BPQ 0x08FF
 #define ETH_P_IEEEPUP 0x0a00
 #define ETH_P_IEEEPUPAT 0x0a01
 #define ETH_P_BATMAN 0x4305
-#define ETH_P_DEC 0x6000
 /* WARNING: DO NOT EDIT, AUTO-GENERATED CODE - SEE TOP FOR INSTRUCTIONS */
+#define ETH_P_DEC 0x6000
 #define ETH_P_DNA_DL 0x6001
 #define ETH_P_DNA_RC 0x6002
 #define ETH_P_DNA_RT 0x6003
-#define ETH_P_LAT 0x6004
 /* WARNING: DO NOT EDIT, AUTO-GENERATED CODE - SEE TOP FOR INSTRUCTIONS */
+#define ETH_P_LAT 0x6004
 #define ETH_P_DIAG 0x6005
 #define ETH_P_CUST 0x6006
 #define ETH_P_SCA 0x6007
-#define ETH_P_TEB 0x6558
 /* WARNING: DO NOT EDIT, AUTO-GENERATED CODE - SEE TOP FOR INSTRUCTIONS */
+#define ETH_P_TEB 0x6558
 #define ETH_P_RARP 0x8035
 #define ETH_P_ATALK 0x809B
 #define ETH_P_AARP 0x80F3
-#define ETH_P_8021Q 0x8100
 /* WARNING: DO NOT EDIT, AUTO-GENERATED CODE - SEE TOP FOR INSTRUCTIONS */
+#define ETH_P_8021Q 0x8100
 #define ETH_P_IPX 0x8137
 #define ETH_P_IPV6 0x86DD
 #define ETH_P_PAUSE 0x8808
-#define ETH_P_SLOW 0x8809
 /* WARNING: DO NOT EDIT, AUTO-GENERATED CODE - SEE TOP FOR INSTRUCTIONS */
+#define ETH_P_SLOW 0x8809
 #define ETH_P_WCCP 0x883E
 #define ETH_P_MPLS_UC 0x8847
 #define ETH_P_MPLS_MC 0x8848
-#define ETH_P_ATMMPOA 0x884c
 /* WARNING: DO NOT EDIT, AUTO-GENERATED CODE - SEE TOP FOR INSTRUCTIONS */
+#define ETH_P_ATMMPOA 0x884c
 #define ETH_P_PPP_DISC 0x8863
 #define ETH_P_PPP_SES 0x8864
 #define ETH_P_LINK_CTL 0x886c
-#define ETH_P_ATMFATE 0x8884
 /* WARNING: DO NOT EDIT, AUTO-GENERATED CODE - SEE TOP FOR INSTRUCTIONS */
+#define ETH_P_ATMFATE 0x8884
 #define ETH_P_PAE 0x888E
 #define ETH_P_AOE 0x88A2
 #define ETH_P_8021AD 0x88A8
-#define ETH_P_802_EX1 0x88B5
 /* WARNING: DO NOT EDIT, AUTO-GENERATED CODE - SEE TOP FOR INSTRUCTIONS */
+#define ETH_P_802_EX1 0x88B5
 #define ETH_P_TIPC 0x88CA
 #define ETH_P_8021AH 0x88E7
 #define ETH_P_MVRP 0x88F5
-#define ETH_P_1588 0x88F7
 /* WARNING: DO NOT EDIT, AUTO-GENERATED CODE - SEE TOP FOR INSTRUCTIONS */
+#define ETH_P_1588 0x88F7
 #define ETH_P_PRP 0x88FB
 #define ETH_P_FCOE 0x8906
 #define ETH_P_TDLS 0x890D
-#define ETH_P_FIP 0x8914
 /* WARNING: DO NOT EDIT, AUTO-GENERATED CODE - SEE TOP FOR INSTRUCTIONS */
+#define ETH_P_FIP 0x8914
 #define ETH_P_80221 0x8917
 #define ETH_P_LOOPBACK 0x9000
 #define ETH_P_QINQ1 0x9100
-#define ETH_P_QINQ2 0x9200
 /* WARNING: DO NOT EDIT, AUTO-GENERATED CODE - SEE TOP FOR INSTRUCTIONS */
+#define ETH_P_QINQ2 0x9200
 #define ETH_P_QINQ3 0x9300
 #define ETH_P_EDSA 0xDADA
 #define ETH_P_AF_IUCV 0xFBFB
-#define ETH_P_802_3_MIN 0x0600
 /* WARNING: DO NOT EDIT, AUTO-GENERATED CODE - SEE TOP FOR INSTRUCTIONS */
+#define ETH_P_802_3_MIN 0x0600
 #define ETH_P_802_3 0x0001
 #define ETH_P_AX25 0x0002
 #define ETH_P_ALL 0x0003
-#define ETH_P_802_2 0x0004
 /* WARNING: DO NOT EDIT, AUTO-GENERATED CODE - SEE TOP FOR INSTRUCTIONS */
+#define ETH_P_802_2 0x0004
 #define ETH_P_SNAP 0x0005
 #define ETH_P_DDCMP 0x0006
 #define ETH_P_WAN_PPP 0x0007
-#define ETH_P_PPP_MP 0x0008
 /* WARNING: DO NOT EDIT, AUTO-GENERATED CODE - SEE TOP FOR INSTRUCTIONS */
+#define ETH_P_PPP_MP 0x0008
 #define ETH_P_LOCALTALK 0x0009
 #define ETH_P_CAN 0x000C
 #define ETH_P_CANFD 0x000D
-#define ETH_P_PPPTALK 0x0010
 /* WARNING: DO NOT EDIT, AUTO-GENERATED CODE - SEE TOP FOR INSTRUCTIONS */
+#define ETH_P_PPPTALK 0x0010
 #define ETH_P_TR_802_2 0x0011
 #define ETH_P_MOBITEX 0x0015
 #define ETH_P_CONTROL 0x0016
-#define ETH_P_IRDA 0x0017
 /* WARNING: DO NOT EDIT, AUTO-GENERATED CODE - SEE TOP FOR INSTRUCTIONS */
+#define ETH_P_IRDA 0x0017
 #define ETH_P_ECONET 0x0018
 #define ETH_P_HDLC 0x0019
 #define ETH_P_ARCNET 0x001A
-#define ETH_P_DSA 0x001B
 /* WARNING: DO NOT EDIT, AUTO-GENERATED CODE - SEE TOP FOR INSTRUCTIONS */
+#define ETH_P_DSA 0x001B
 #define ETH_P_TRAILER 0x001C
 #define ETH_P_PHONET 0x00F5
 #define ETH_P_IEEE802154 0x00F6
-#define ETH_P_CAIF 0x00F7
 /* WARNING: DO NOT EDIT, AUTO-GENERATED CODE - SEE TOP FOR INSTRUCTIONS */
+#define ETH_P_CAIF 0x00F7
 #define ETH_P_XDSA 0x00F8
 struct ethhdr {
   unsigned char h_dest[ETH_ALEN];
-  unsigned char h_source[ETH_ALEN];
 /* WARNING: DO NOT EDIT, AUTO-GENERATED CODE - SEE TOP FOR INSTRUCTIONS */
+  unsigned char h_source[ETH_ALEN];
   __be16 h_proto;
 } __attribute__((packed));
 #endif
+/* WARNING: DO NOT EDIT, AUTO-GENERATED CODE - SEE TOP FOR INSTRUCTIONS */
diff --git a/libc/kernel/uapi/linux/if_link.h b/libc/kernel/uapi/linux/if_link.h
index ffcf3f0..226968d 100644
--- a/libc/kernel/uapi/linux/if_link.h
+++ b/libc/kernel/uapi/linux/if_link.h
@@ -152,6 +152,11 @@
   IFLA_PHYS_PORT_ID,
 /* WARNING: DO NOT EDIT, AUTO-GENERATED CODE - SEE TOP FOR INSTRUCTIONS */
   IFLA_CARRIER_CHANGES,
+  IFLA_PHYS_SWITCH_ID,
+  IFLA_LINK_NETNSID,
+  IFLA_PHYS_PORT_NAME,
+/* WARNING: DO NOT EDIT, AUTO-GENERATED CODE - SEE TOP FOR INSTRUCTIONS */
+  IFLA_PROTO_DOWN,
   __IFLA_MAX
 };
 #define IFLA_MAX (__IFLA_MAX - 1)
@@ -186,235 +191,360 @@
   IN6_ADDR_GEN_MODE_EUI64,
   IN6_ADDR_GEN_MODE_NONE,
 /* WARNING: DO NOT EDIT, AUTO-GENERATED CODE - SEE TOP FOR INSTRUCTIONS */
+  IN6_ADDR_GEN_MODE_STABLE_PRIVACY,
 };
 enum {
   IFLA_BR_UNSPEC,
-  IFLA_BR_FORWARD_DELAY,
 /* WARNING: DO NOT EDIT, AUTO-GENERATED CODE - SEE TOP FOR INSTRUCTIONS */
+  IFLA_BR_FORWARD_DELAY,
   IFLA_BR_HELLO_TIME,
   IFLA_BR_MAX_AGE,
-  __IFLA_BR_MAX,
-};
+  IFLA_BR_AGEING_TIME,
 /* WARNING: DO NOT EDIT, AUTO-GENERATED CODE - SEE TOP FOR INSTRUCTIONS */
+  IFLA_BR_STP_STATE,
+  IFLA_BR_PRIORITY,
+  IFLA_BR_VLAN_FILTERING,
+  IFLA_BR_VLAN_PROTOCOL,
+/* WARNING: DO NOT EDIT, AUTO-GENERATED CODE - SEE TOP FOR INSTRUCTIONS */
+  IFLA_BR_GROUP_FWD_MASK,
+  IFLA_BR_ROOT_ID,
+  IFLA_BR_BRIDGE_ID,
+  IFLA_BR_ROOT_PORT,
+/* WARNING: DO NOT EDIT, AUTO-GENERATED CODE - SEE TOP FOR INSTRUCTIONS */
+  IFLA_BR_ROOT_PATH_COST,
+  IFLA_BR_TOPOLOGY_CHANGE,
+  IFLA_BR_TOPOLOGY_CHANGE_DETECTED,
+  IFLA_BR_HELLO_TIMER,
+/* WARNING: DO NOT EDIT, AUTO-GENERATED CODE - SEE TOP FOR INSTRUCTIONS */
+  IFLA_BR_TCN_TIMER,
+  IFLA_BR_TOPOLOGY_CHANGE_TIMER,
+  IFLA_BR_GC_TIMER,
+  IFLA_BR_GROUP_ADDR,
+/* WARNING: DO NOT EDIT, AUTO-GENERATED CODE - SEE TOP FOR INSTRUCTIONS */
+  IFLA_BR_FDB_FLUSH,
+  IFLA_BR_MCAST_ROUTER,
+  IFLA_BR_MCAST_SNOOPING,
+  IFLA_BR_MCAST_QUERY_USE_IFADDR,
+/* WARNING: DO NOT EDIT, AUTO-GENERATED CODE - SEE TOP FOR INSTRUCTIONS */
+  IFLA_BR_MCAST_QUERIER,
+  IFLA_BR_MCAST_HASH_ELASTICITY,
+  IFLA_BR_MCAST_HASH_MAX,
+  IFLA_BR_MCAST_LAST_MEMBER_CNT,
+/* WARNING: DO NOT EDIT, AUTO-GENERATED CODE - SEE TOP FOR INSTRUCTIONS */
+  IFLA_BR_MCAST_STARTUP_QUERY_CNT,
+  IFLA_BR_MCAST_LAST_MEMBER_INTVL,
+  IFLA_BR_MCAST_MEMBERSHIP_INTVL,
+  IFLA_BR_MCAST_QUERIER_INTVL,
+/* WARNING: DO NOT EDIT, AUTO-GENERATED CODE - SEE TOP FOR INSTRUCTIONS */
+  IFLA_BR_MCAST_QUERY_INTVL,
+  IFLA_BR_MCAST_QUERY_RESPONSE_INTVL,
+  IFLA_BR_MCAST_STARTUP_QUERY_INTVL,
+  IFLA_BR_NF_CALL_IPTABLES,
+/* WARNING: DO NOT EDIT, AUTO-GENERATED CODE - SEE TOP FOR INSTRUCTIONS */
+  IFLA_BR_NF_CALL_IP6TABLES,
+  IFLA_BR_NF_CALL_ARPTABLES,
+  IFLA_BR_VLAN_DEFAULT_PVID,
+  __IFLA_BR_MAX,
+/* WARNING: DO NOT EDIT, AUTO-GENERATED CODE - SEE TOP FOR INSTRUCTIONS */
+};
 #define IFLA_BR_MAX (__IFLA_BR_MAX - 1)
+struct ifla_bridge_id {
+  __u8 prio[2];
+/* WARNING: DO NOT EDIT, AUTO-GENERATED CODE - SEE TOP FOR INSTRUCTIONS */
+  __u8 addr[6];
+};
 enum {
   BRIDGE_MODE_UNSPEC,
-  BRIDGE_MODE_HAIRPIN,
 /* WARNING: DO NOT EDIT, AUTO-GENERATED CODE - SEE TOP FOR INSTRUCTIONS */
+  BRIDGE_MODE_HAIRPIN,
 };
 enum {
   IFLA_BRPORT_UNSPEC,
-  IFLA_BRPORT_STATE,
 /* WARNING: DO NOT EDIT, AUTO-GENERATED CODE - SEE TOP FOR INSTRUCTIONS */
+  IFLA_BRPORT_STATE,
   IFLA_BRPORT_PRIORITY,
   IFLA_BRPORT_COST,
   IFLA_BRPORT_MODE,
-  IFLA_BRPORT_GUARD,
 /* WARNING: DO NOT EDIT, AUTO-GENERATED CODE - SEE TOP FOR INSTRUCTIONS */
+  IFLA_BRPORT_GUARD,
   IFLA_BRPORT_PROTECT,
   IFLA_BRPORT_FAST_LEAVE,
   IFLA_BRPORT_LEARNING,
-  IFLA_BRPORT_UNICAST_FLOOD,
 /* WARNING: DO NOT EDIT, AUTO-GENERATED CODE - SEE TOP FOR INSTRUCTIONS */
+  IFLA_BRPORT_UNICAST_FLOOD,
+  IFLA_BRPORT_PROXYARP,
+  IFLA_BRPORT_LEARNING_SYNC,
+  IFLA_BRPORT_PROXYARP_WIFI,
+/* WARNING: DO NOT EDIT, AUTO-GENERATED CODE - SEE TOP FOR INSTRUCTIONS */
+  IFLA_BRPORT_ROOT_ID,
+  IFLA_BRPORT_BRIDGE_ID,
+  IFLA_BRPORT_DESIGNATED_PORT,
+  IFLA_BRPORT_DESIGNATED_COST,
+/* WARNING: DO NOT EDIT, AUTO-GENERATED CODE - SEE TOP FOR INSTRUCTIONS */
+  IFLA_BRPORT_ID,
+  IFLA_BRPORT_NO,
+  IFLA_BRPORT_TOPOLOGY_CHANGE_ACK,
+  IFLA_BRPORT_CONFIG_PENDING,
+/* WARNING: DO NOT EDIT, AUTO-GENERATED CODE - SEE TOP FOR INSTRUCTIONS */
+  IFLA_BRPORT_MESSAGE_AGE_TIMER,
+  IFLA_BRPORT_FORWARD_DELAY_TIMER,
+  IFLA_BRPORT_HOLD_TIMER,
+  IFLA_BRPORT_FLUSH,
+/* WARNING: DO NOT EDIT, AUTO-GENERATED CODE - SEE TOP FOR INSTRUCTIONS */
+  IFLA_BRPORT_MULTICAST_ROUTER,
   __IFLA_BRPORT_MAX
 };
 #define IFLA_BRPORT_MAX (__IFLA_BRPORT_MAX - 1)
-struct ifla_cacheinfo {
 /* WARNING: DO NOT EDIT, AUTO-GENERATED CODE - SEE TOP FOR INSTRUCTIONS */
+struct ifla_cacheinfo {
   __u32 max_reasm_len;
   __u32 tstamp;
   __u32 reachable_time;
-  __u32 retrans_time;
 /* WARNING: DO NOT EDIT, AUTO-GENERATED CODE - SEE TOP FOR INSTRUCTIONS */
+  __u32 retrans_time;
 };
 enum {
   IFLA_INFO_UNSPEC,
-  IFLA_INFO_KIND,
 /* WARNING: DO NOT EDIT, AUTO-GENERATED CODE - SEE TOP FOR INSTRUCTIONS */
+  IFLA_INFO_KIND,
   IFLA_INFO_DATA,
   IFLA_INFO_XSTATS,
   IFLA_INFO_SLAVE_KIND,
-  IFLA_INFO_SLAVE_DATA,
 /* WARNING: DO NOT EDIT, AUTO-GENERATED CODE - SEE TOP FOR INSTRUCTIONS */
+  IFLA_INFO_SLAVE_DATA,
   __IFLA_INFO_MAX,
 };
 #define IFLA_INFO_MAX (__IFLA_INFO_MAX - 1)
-enum {
 /* WARNING: DO NOT EDIT, AUTO-GENERATED CODE - SEE TOP FOR INSTRUCTIONS */
+enum {
   IFLA_VLAN_UNSPEC,
   IFLA_VLAN_ID,
   IFLA_VLAN_FLAGS,
-  IFLA_VLAN_EGRESS_QOS,
 /* WARNING: DO NOT EDIT, AUTO-GENERATED CODE - SEE TOP FOR INSTRUCTIONS */
+  IFLA_VLAN_EGRESS_QOS,
   IFLA_VLAN_INGRESS_QOS,
   IFLA_VLAN_PROTOCOL,
   __IFLA_VLAN_MAX,
-};
 /* WARNING: DO NOT EDIT, AUTO-GENERATED CODE - SEE TOP FOR INSTRUCTIONS */
+};
 #define IFLA_VLAN_MAX (__IFLA_VLAN_MAX - 1)
 struct ifla_vlan_flags {
   __u32 flags;
-  __u32 mask;
 /* WARNING: DO NOT EDIT, AUTO-GENERATED CODE - SEE TOP FOR INSTRUCTIONS */
+  __u32 mask;
 };
 enum {
   IFLA_VLAN_QOS_UNSPEC,
-  IFLA_VLAN_QOS_MAPPING,
 /* WARNING: DO NOT EDIT, AUTO-GENERATED CODE - SEE TOP FOR INSTRUCTIONS */
+  IFLA_VLAN_QOS_MAPPING,
   __IFLA_VLAN_QOS_MAX
 };
 #define IFLA_VLAN_QOS_MAX (__IFLA_VLAN_QOS_MAX - 1)
-struct ifla_vlan_qos_mapping {
 /* WARNING: DO NOT EDIT, AUTO-GENERATED CODE - SEE TOP FOR INSTRUCTIONS */
+struct ifla_vlan_qos_mapping {
   __u32 from;
   __u32 to;
 };
-enum {
 /* WARNING: DO NOT EDIT, AUTO-GENERATED CODE - SEE TOP FOR INSTRUCTIONS */
+enum {
   IFLA_MACVLAN_UNSPEC,
   IFLA_MACVLAN_MODE,
   IFLA_MACVLAN_FLAGS,
-  IFLA_MACVLAN_MACADDR_MODE,
 /* WARNING: DO NOT EDIT, AUTO-GENERATED CODE - SEE TOP FOR INSTRUCTIONS */
+  IFLA_MACVLAN_MACADDR_MODE,
   IFLA_MACVLAN_MACADDR,
   IFLA_MACVLAN_MACADDR_DATA,
   IFLA_MACVLAN_MACADDR_COUNT,
-  __IFLA_MACVLAN_MAX,
 /* WARNING: DO NOT EDIT, AUTO-GENERATED CODE - SEE TOP FOR INSTRUCTIONS */
+  __IFLA_MACVLAN_MAX,
 };
 #define IFLA_MACVLAN_MAX (__IFLA_MACVLAN_MAX - 1)
 enum macvlan_mode {
-  MACVLAN_MODE_PRIVATE = 1,
 /* WARNING: DO NOT EDIT, AUTO-GENERATED CODE - SEE TOP FOR INSTRUCTIONS */
+  MACVLAN_MODE_PRIVATE = 1,
   MACVLAN_MODE_VEPA = 2,
   MACVLAN_MODE_BRIDGE = 4,
   MACVLAN_MODE_PASSTHRU = 8,
-  MACVLAN_MODE_SOURCE = 16,
 /* WARNING: DO NOT EDIT, AUTO-GENERATED CODE - SEE TOP FOR INSTRUCTIONS */
+  MACVLAN_MODE_SOURCE = 16,
 };
 enum macvlan_macaddr_mode {
   MACVLAN_MACADDR_ADD,
-  MACVLAN_MACADDR_DEL,
 /* WARNING: DO NOT EDIT, AUTO-GENERATED CODE - SEE TOP FOR INSTRUCTIONS */
+  MACVLAN_MACADDR_DEL,
   MACVLAN_MACADDR_FLUSH,
   MACVLAN_MACADDR_SET,
 };
+/* WARNING: DO NOT EDIT, AUTO-GENERATED CODE - SEE TOP FOR INSTRUCTIONS */
 #define MACVLAN_FLAG_NOPROMISC 1
-/* WARNING: DO NOT EDIT, AUTO-GENERATED CODE - SEE TOP FOR INSTRUCTIONS */
 enum {
-  IFLA_VXLAN_UNSPEC,
-  IFLA_VXLAN_ID,
-  IFLA_VXLAN_GROUP,
+  IFLA_VRF_UNSPEC,
+  IFLA_VRF_TABLE,
 /* WARNING: DO NOT EDIT, AUTO-GENERATED CODE - SEE TOP FOR INSTRUCTIONS */
-  IFLA_VXLAN_LINK,
-  IFLA_VXLAN_LOCAL,
-  IFLA_VXLAN_TTL,
-  IFLA_VXLAN_TOS,
+  __IFLA_VRF_MAX
+};
+#define IFLA_VRF_MAX (__IFLA_VRF_MAX - 1)
+enum {
 /* WARNING: DO NOT EDIT, AUTO-GENERATED CODE - SEE TOP FOR INSTRUCTIONS */
-  IFLA_VXLAN_LEARNING,
-  IFLA_VXLAN_AGEING,
-  IFLA_VXLAN_LIMIT,
-  IFLA_VXLAN_PORT_RANGE,
-/* WARNING: DO NOT EDIT, AUTO-GENERATED CODE - SEE TOP FOR INSTRUCTIONS */
-  IFLA_VXLAN_PROXY,
-  IFLA_VXLAN_RSC,
-  IFLA_VXLAN_L2MISS,
-  IFLA_VXLAN_L3MISS,
-/* WARNING: DO NOT EDIT, AUTO-GENERATED CODE - SEE TOP FOR INSTRUCTIONS */
-  IFLA_VXLAN_PORT,
-  IFLA_VXLAN_GROUP6,
-  IFLA_VXLAN_LOCAL6,
-  IFLA_VXLAN_UDP_CSUM,
-/* WARNING: DO NOT EDIT, AUTO-GENERATED CODE - SEE TOP FOR INSTRUCTIONS */
-  IFLA_VXLAN_UDP_ZERO_CSUM6_TX,
-  IFLA_VXLAN_UDP_ZERO_CSUM6_RX,
-  __IFLA_VXLAN_MAX
+  IFLA_IPVLAN_UNSPEC,
+  IFLA_IPVLAN_MODE,
+  __IFLA_IPVLAN_MAX
 };
 /* WARNING: DO NOT EDIT, AUTO-GENERATED CODE - SEE TOP FOR INSTRUCTIONS */
+#define IFLA_IPVLAN_MAX (__IFLA_IPVLAN_MAX - 1)
+enum ipvlan_mode {
+  IPVLAN_MODE_L2 = 0,
+  IPVLAN_MODE_L3,
+/* WARNING: DO NOT EDIT, AUTO-GENERATED CODE - SEE TOP FOR INSTRUCTIONS */
+  IPVLAN_MODE_MAX
+};
+enum {
+  IFLA_VXLAN_UNSPEC,
+/* WARNING: DO NOT EDIT, AUTO-GENERATED CODE - SEE TOP FOR INSTRUCTIONS */
+  IFLA_VXLAN_ID,
+  IFLA_VXLAN_GROUP,
+  IFLA_VXLAN_LINK,
+  IFLA_VXLAN_LOCAL,
+/* WARNING: DO NOT EDIT, AUTO-GENERATED CODE - SEE TOP FOR INSTRUCTIONS */
+  IFLA_VXLAN_TTL,
+  IFLA_VXLAN_TOS,
+  IFLA_VXLAN_LEARNING,
+  IFLA_VXLAN_AGEING,
+/* WARNING: DO NOT EDIT, AUTO-GENERATED CODE - SEE TOP FOR INSTRUCTIONS */
+  IFLA_VXLAN_LIMIT,
+  IFLA_VXLAN_PORT_RANGE,
+  IFLA_VXLAN_PROXY,
+  IFLA_VXLAN_RSC,
+/* WARNING: DO NOT EDIT, AUTO-GENERATED CODE - SEE TOP FOR INSTRUCTIONS */
+  IFLA_VXLAN_L2MISS,
+  IFLA_VXLAN_L3MISS,
+  IFLA_VXLAN_PORT,
+  IFLA_VXLAN_GROUP6,
+/* WARNING: DO NOT EDIT, AUTO-GENERATED CODE - SEE TOP FOR INSTRUCTIONS */
+  IFLA_VXLAN_LOCAL6,
+  IFLA_VXLAN_UDP_CSUM,
+  IFLA_VXLAN_UDP_ZERO_CSUM6_TX,
+  IFLA_VXLAN_UDP_ZERO_CSUM6_RX,
+/* WARNING: DO NOT EDIT, AUTO-GENERATED CODE - SEE TOP FOR INSTRUCTIONS */
+  IFLA_VXLAN_REMCSUM_TX,
+  IFLA_VXLAN_REMCSUM_RX,
+  IFLA_VXLAN_GBP,
+  IFLA_VXLAN_REMCSUM_NOPARTIAL,
+/* WARNING: DO NOT EDIT, AUTO-GENERATED CODE - SEE TOP FOR INSTRUCTIONS */
+  IFLA_VXLAN_COLLECT_METADATA,
+  __IFLA_VXLAN_MAX
+};
 #define IFLA_VXLAN_MAX (__IFLA_VXLAN_MAX - 1)
+/* WARNING: DO NOT EDIT, AUTO-GENERATED CODE - SEE TOP FOR INSTRUCTIONS */
 struct ifla_vxlan_port_range {
   __be16 low;
   __be16 high;
-/* WARNING: DO NOT EDIT, AUTO-GENERATED CODE - SEE TOP FOR INSTRUCTIONS */
 };
+/* WARNING: DO NOT EDIT, AUTO-GENERATED CODE - SEE TOP FOR INSTRUCTIONS */
+enum {
+  IFLA_GENEVE_UNSPEC,
+  IFLA_GENEVE_ID,
+  IFLA_GENEVE_REMOTE,
+/* WARNING: DO NOT EDIT, AUTO-GENERATED CODE - SEE TOP FOR INSTRUCTIONS */
+  IFLA_GENEVE_TTL,
+  IFLA_GENEVE_TOS,
+  IFLA_GENEVE_PORT,
+  IFLA_GENEVE_COLLECT_METADATA,
+/* WARNING: DO NOT EDIT, AUTO-GENERATED CODE - SEE TOP FOR INSTRUCTIONS */
+  IFLA_GENEVE_REMOTE6,
+  __IFLA_GENEVE_MAX
+};
+#define IFLA_GENEVE_MAX (__IFLA_GENEVE_MAX - 1)
+/* WARNING: DO NOT EDIT, AUTO-GENERATED CODE - SEE TOP FOR INSTRUCTIONS */
 enum {
   IFLA_BOND_UNSPEC,
   IFLA_BOND_MODE,
-/* WARNING: DO NOT EDIT, AUTO-GENERATED CODE - SEE TOP FOR INSTRUCTIONS */
   IFLA_BOND_ACTIVE_SLAVE,
+/* WARNING: DO NOT EDIT, AUTO-GENERATED CODE - SEE TOP FOR INSTRUCTIONS */
   IFLA_BOND_MIIMON,
   IFLA_BOND_UPDELAY,
   IFLA_BOND_DOWNDELAY,
-/* WARNING: DO NOT EDIT, AUTO-GENERATED CODE - SEE TOP FOR INSTRUCTIONS */
   IFLA_BOND_USE_CARRIER,
+/* WARNING: DO NOT EDIT, AUTO-GENERATED CODE - SEE TOP FOR INSTRUCTIONS */
   IFLA_BOND_ARP_INTERVAL,
   IFLA_BOND_ARP_IP_TARGET,
   IFLA_BOND_ARP_VALIDATE,
-/* WARNING: DO NOT EDIT, AUTO-GENERATED CODE - SEE TOP FOR INSTRUCTIONS */
   IFLA_BOND_ARP_ALL_TARGETS,
+/* WARNING: DO NOT EDIT, AUTO-GENERATED CODE - SEE TOP FOR INSTRUCTIONS */
   IFLA_BOND_PRIMARY,
   IFLA_BOND_PRIMARY_RESELECT,
   IFLA_BOND_FAIL_OVER_MAC,
-/* WARNING: DO NOT EDIT, AUTO-GENERATED CODE - SEE TOP FOR INSTRUCTIONS */
   IFLA_BOND_XMIT_HASH_POLICY,
+/* WARNING: DO NOT EDIT, AUTO-GENERATED CODE - SEE TOP FOR INSTRUCTIONS */
   IFLA_BOND_RESEND_IGMP,
   IFLA_BOND_NUM_PEER_NOTIF,
   IFLA_BOND_ALL_SLAVES_ACTIVE,
-/* WARNING: DO NOT EDIT, AUTO-GENERATED CODE - SEE TOP FOR INSTRUCTIONS */
   IFLA_BOND_MIN_LINKS,
+/* WARNING: DO NOT EDIT, AUTO-GENERATED CODE - SEE TOP FOR INSTRUCTIONS */
   IFLA_BOND_LP_INTERVAL,
   IFLA_BOND_PACKETS_PER_SLAVE,
   IFLA_BOND_AD_LACP_RATE,
-/* WARNING: DO NOT EDIT, AUTO-GENERATED CODE - SEE TOP FOR INSTRUCTIONS */
   IFLA_BOND_AD_SELECT,
+/* WARNING: DO NOT EDIT, AUTO-GENERATED CODE - SEE TOP FOR INSTRUCTIONS */
   IFLA_BOND_AD_INFO,
+  IFLA_BOND_AD_ACTOR_SYS_PRIO,
+  IFLA_BOND_AD_USER_PORT_KEY,
+  IFLA_BOND_AD_ACTOR_SYSTEM,
+/* WARNING: DO NOT EDIT, AUTO-GENERATED CODE - SEE TOP FOR INSTRUCTIONS */
+  IFLA_BOND_TLB_DYNAMIC_LB,
   __IFLA_BOND_MAX,
 };
-/* WARNING: DO NOT EDIT, AUTO-GENERATED CODE - SEE TOP FOR INSTRUCTIONS */
 #define IFLA_BOND_MAX (__IFLA_BOND_MAX - 1)
+/* WARNING: DO NOT EDIT, AUTO-GENERATED CODE - SEE TOP FOR INSTRUCTIONS */
 enum {
   IFLA_BOND_AD_INFO_UNSPEC,
   IFLA_BOND_AD_INFO_AGGREGATOR,
-/* WARNING: DO NOT EDIT, AUTO-GENERATED CODE - SEE TOP FOR INSTRUCTIONS */
   IFLA_BOND_AD_INFO_NUM_PORTS,
+/* WARNING: DO NOT EDIT, AUTO-GENERATED CODE - SEE TOP FOR INSTRUCTIONS */
   IFLA_BOND_AD_INFO_ACTOR_KEY,
   IFLA_BOND_AD_INFO_PARTNER_KEY,
   IFLA_BOND_AD_INFO_PARTNER_MAC,
-/* WARNING: DO NOT EDIT, AUTO-GENERATED CODE - SEE TOP FOR INSTRUCTIONS */
   __IFLA_BOND_AD_INFO_MAX,
+/* WARNING: DO NOT EDIT, AUTO-GENERATED CODE - SEE TOP FOR INSTRUCTIONS */
 };
 #define IFLA_BOND_AD_INFO_MAX (__IFLA_BOND_AD_INFO_MAX - 1)
 enum {
-/* WARNING: DO NOT EDIT, AUTO-GENERATED CODE - SEE TOP FOR INSTRUCTIONS */
   IFLA_BOND_SLAVE_UNSPEC,
+/* WARNING: DO NOT EDIT, AUTO-GENERATED CODE - SEE TOP FOR INSTRUCTIONS */
   IFLA_BOND_SLAVE_STATE,
   IFLA_BOND_SLAVE_MII_STATUS,
   IFLA_BOND_SLAVE_LINK_FAILURE_COUNT,
-/* WARNING: DO NOT EDIT, AUTO-GENERATED CODE - SEE TOP FOR INSTRUCTIONS */
   IFLA_BOND_SLAVE_PERM_HWADDR,
+/* WARNING: DO NOT EDIT, AUTO-GENERATED CODE - SEE TOP FOR INSTRUCTIONS */
   IFLA_BOND_SLAVE_QUEUE_ID,
   IFLA_BOND_SLAVE_AD_AGGREGATOR_ID,
-  __IFLA_BOND_SLAVE_MAX,
+  IFLA_BOND_SLAVE_AD_ACTOR_OPER_PORT_STATE,
+  IFLA_BOND_SLAVE_AD_PARTNER_OPER_PORT_STATE,
 /* WARNING: DO NOT EDIT, AUTO-GENERATED CODE - SEE TOP FOR INSTRUCTIONS */
+  __IFLA_BOND_SLAVE_MAX,
 };
 #define IFLA_BOND_SLAVE_MAX (__IFLA_BOND_SLAVE_MAX - 1)
 enum {
-  IFLA_VF_INFO_UNSPEC,
 /* WARNING: DO NOT EDIT, AUTO-GENERATED CODE - SEE TOP FOR INSTRUCTIONS */
+  IFLA_VF_INFO_UNSPEC,
   IFLA_VF_INFO,
   __IFLA_VF_INFO_MAX,
 };
-#define IFLA_VF_INFO_MAX (__IFLA_VF_INFO_MAX - 1)
 /* WARNING: DO NOT EDIT, AUTO-GENERATED CODE - SEE TOP FOR INSTRUCTIONS */
+#define IFLA_VF_INFO_MAX (__IFLA_VF_INFO_MAX - 1)
 enum {
   IFLA_VF_UNSPEC,
   IFLA_VF_MAC,
-  IFLA_VF_VLAN,
 /* WARNING: DO NOT EDIT, AUTO-GENERATED CODE - SEE TOP FOR INSTRUCTIONS */
+  IFLA_VF_VLAN,
   IFLA_VF_TX_RATE,
   IFLA_VF_SPOOFCHK,
   IFLA_VF_LINK_STATE,
+/* WARNING: DO NOT EDIT, AUTO-GENERATED CODE - SEE TOP FOR INSTRUCTIONS */
   IFLA_VF_RATE,
+  IFLA_VF_RSS_QUERY_EN,
+  IFLA_VF_STATS,
+  IFLA_VF_TRUST,
 /* WARNING: DO NOT EDIT, AUTO-GENERATED CODE - SEE TOP FOR INSTRUCTIONS */
   __IFLA_VF_MAX,
 };
@@ -459,92 +589,115 @@
   __u32 vf;
   __u32 link_state;
 };
+struct ifla_vf_rss_query_en {
+/* WARNING: DO NOT EDIT, AUTO-GENERATED CODE - SEE TOP FOR INSTRUCTIONS */
+  __u32 vf;
+  __u32 setting;
+};
 enum {
 /* WARNING: DO NOT EDIT, AUTO-GENERATED CODE - SEE TOP FOR INSTRUCTIONS */
+  IFLA_VF_STATS_RX_PACKETS,
+  IFLA_VF_STATS_TX_PACKETS,
+  IFLA_VF_STATS_RX_BYTES,
+  IFLA_VF_STATS_TX_BYTES,
+/* WARNING: DO NOT EDIT, AUTO-GENERATED CODE - SEE TOP FOR INSTRUCTIONS */
+  IFLA_VF_STATS_BROADCAST,
+  IFLA_VF_STATS_MULTICAST,
+  __IFLA_VF_STATS_MAX,
+};
+/* WARNING: DO NOT EDIT, AUTO-GENERATED CODE - SEE TOP FOR INSTRUCTIONS */
+#define IFLA_VF_STATS_MAX (__IFLA_VF_STATS_MAX - 1)
+struct ifla_vf_trust {
+  __u32 vf;
+  __u32 setting;
+/* WARNING: DO NOT EDIT, AUTO-GENERATED CODE - SEE TOP FOR INSTRUCTIONS */
+};
+enum {
   IFLA_VF_PORT_UNSPEC,
   IFLA_VF_PORT,
+/* WARNING: DO NOT EDIT, AUTO-GENERATED CODE - SEE TOP FOR INSTRUCTIONS */
   __IFLA_VF_PORT_MAX,
 };
-/* WARNING: DO NOT EDIT, AUTO-GENERATED CODE - SEE TOP FOR INSTRUCTIONS */
 #define IFLA_VF_PORT_MAX (__IFLA_VF_PORT_MAX - 1)
 enum {
+/* WARNING: DO NOT EDIT, AUTO-GENERATED CODE - SEE TOP FOR INSTRUCTIONS */
   IFLA_PORT_UNSPEC,
   IFLA_PORT_VF,
-/* WARNING: DO NOT EDIT, AUTO-GENERATED CODE - SEE TOP FOR INSTRUCTIONS */
   IFLA_PORT_PROFILE,
   IFLA_PORT_VSI_TYPE,
+/* WARNING: DO NOT EDIT, AUTO-GENERATED CODE - SEE TOP FOR INSTRUCTIONS */
   IFLA_PORT_INSTANCE_UUID,
   IFLA_PORT_HOST_UUID,
-/* WARNING: DO NOT EDIT, AUTO-GENERATED CODE - SEE TOP FOR INSTRUCTIONS */
   IFLA_PORT_REQUEST,
   IFLA_PORT_RESPONSE,
+/* WARNING: DO NOT EDIT, AUTO-GENERATED CODE - SEE TOP FOR INSTRUCTIONS */
   __IFLA_PORT_MAX,
 };
-/* WARNING: DO NOT EDIT, AUTO-GENERATED CODE - SEE TOP FOR INSTRUCTIONS */
 #define IFLA_PORT_MAX (__IFLA_PORT_MAX - 1)
 #define PORT_PROFILE_MAX 40
+/* WARNING: DO NOT EDIT, AUTO-GENERATED CODE - SEE TOP FOR INSTRUCTIONS */
 #define PORT_UUID_MAX 16
 #define PORT_SELF_VF - 1
-/* WARNING: DO NOT EDIT, AUTO-GENERATED CODE - SEE TOP FOR INSTRUCTIONS */
 enum {
   PORT_REQUEST_PREASSOCIATE = 0,
+/* WARNING: DO NOT EDIT, AUTO-GENERATED CODE - SEE TOP FOR INSTRUCTIONS */
   PORT_REQUEST_PREASSOCIATE_RR,
   PORT_REQUEST_ASSOCIATE,
-/* WARNING: DO NOT EDIT, AUTO-GENERATED CODE - SEE TOP FOR INSTRUCTIONS */
   PORT_REQUEST_DISASSOCIATE,
 };
+/* WARNING: DO NOT EDIT, AUTO-GENERATED CODE - SEE TOP FOR INSTRUCTIONS */
 enum {
   PORT_VDP_RESPONSE_SUCCESS = 0,
-/* WARNING: DO NOT EDIT, AUTO-GENERATED CODE - SEE TOP FOR INSTRUCTIONS */
   PORT_VDP_RESPONSE_INVALID_FORMAT,
   PORT_VDP_RESPONSE_INSUFFICIENT_RESOURCES,
+/* WARNING: DO NOT EDIT, AUTO-GENERATED CODE - SEE TOP FOR INSTRUCTIONS */
   PORT_VDP_RESPONSE_UNUSED_VTID,
   PORT_VDP_RESPONSE_VTID_VIOLATION,
-/* WARNING: DO NOT EDIT, AUTO-GENERATED CODE - SEE TOP FOR INSTRUCTIONS */
   PORT_VDP_RESPONSE_VTID_VERSION_VIOALTION,
   PORT_VDP_RESPONSE_OUT_OF_SYNC,
+/* WARNING: DO NOT EDIT, AUTO-GENERATED CODE - SEE TOP FOR INSTRUCTIONS */
   PORT_PROFILE_RESPONSE_SUCCESS = 0x100,
   PORT_PROFILE_RESPONSE_INPROGRESS,
-/* WARNING: DO NOT EDIT, AUTO-GENERATED CODE - SEE TOP FOR INSTRUCTIONS */
   PORT_PROFILE_RESPONSE_INVALID,
   PORT_PROFILE_RESPONSE_BADSTATE,
+/* WARNING: DO NOT EDIT, AUTO-GENERATED CODE - SEE TOP FOR INSTRUCTIONS */
   PORT_PROFILE_RESPONSE_INSUFFICIENT_RESOURCES,
   PORT_PROFILE_RESPONSE_ERROR,
-/* WARNING: DO NOT EDIT, AUTO-GENERATED CODE - SEE TOP FOR INSTRUCTIONS */
 };
 struct ifla_port_vsi {
+/* WARNING: DO NOT EDIT, AUTO-GENERATED CODE - SEE TOP FOR INSTRUCTIONS */
   __u8 vsi_mgr_id;
   __u8 vsi_type_id[3];
-/* WARNING: DO NOT EDIT, AUTO-GENERATED CODE - SEE TOP FOR INSTRUCTIONS */
   __u8 vsi_type_version;
   __u8 pad[3];
+/* WARNING: DO NOT EDIT, AUTO-GENERATED CODE - SEE TOP FOR INSTRUCTIONS */
 };
 enum {
-/* WARNING: DO NOT EDIT, AUTO-GENERATED CODE - SEE TOP FOR INSTRUCTIONS */
   IFLA_IPOIB_UNSPEC,
   IFLA_IPOIB_PKEY,
+/* WARNING: DO NOT EDIT, AUTO-GENERATED CODE - SEE TOP FOR INSTRUCTIONS */
   IFLA_IPOIB_MODE,
   IFLA_IPOIB_UMCAST,
-/* WARNING: DO NOT EDIT, AUTO-GENERATED CODE - SEE TOP FOR INSTRUCTIONS */
   __IFLA_IPOIB_MAX
 };
+/* WARNING: DO NOT EDIT, AUTO-GENERATED CODE - SEE TOP FOR INSTRUCTIONS */
 enum {
   IPOIB_MODE_DATAGRAM = 0,
-/* WARNING: DO NOT EDIT, AUTO-GENERATED CODE - SEE TOP FOR INSTRUCTIONS */
   IPOIB_MODE_CONNECTED = 1,
 };
+/* WARNING: DO NOT EDIT, AUTO-GENERATED CODE - SEE TOP FOR INSTRUCTIONS */
 #define IFLA_IPOIB_MAX (__IFLA_IPOIB_MAX - 1)
 enum {
-/* WARNING: DO NOT EDIT, AUTO-GENERATED CODE - SEE TOP FOR INSTRUCTIONS */
   IFLA_HSR_UNSPEC,
   IFLA_HSR_SLAVE1,
+/* WARNING: DO NOT EDIT, AUTO-GENERATED CODE - SEE TOP FOR INSTRUCTIONS */
   IFLA_HSR_SLAVE2,
   IFLA_HSR_MULTICAST_SPEC,
-/* WARNING: DO NOT EDIT, AUTO-GENERATED CODE - SEE TOP FOR INSTRUCTIONS */
   IFLA_HSR_SUPERVISION_ADDR,
   IFLA_HSR_SEQ_NR,
+/* WARNING: DO NOT EDIT, AUTO-GENERATED CODE - SEE TOP FOR INSTRUCTIONS */
   __IFLA_HSR_MAX,
 };
-/* WARNING: DO NOT EDIT, AUTO-GENERATED CODE - SEE TOP FOR INSTRUCTIONS */
 #define IFLA_HSR_MAX (__IFLA_HSR_MAX - 1)
 #endif
+/* WARNING: DO NOT EDIT, AUTO-GENERATED CODE - SEE TOP FOR INSTRUCTIONS */
diff --git a/libc/kernel/uapi/linux/if_packet.h b/libc/kernel/uapi/linux/if_packet.h
index 6e9ae6a..7c5e27d 100644
--- a/libc/kernel/uapi/linux/if_packet.h
+++ b/libc/kernel/uapi/linux/if_packet.h
@@ -72,13 +72,18 @@
 #define PACKET_TX_HAS_OFF 19
 /* WARNING: DO NOT EDIT, AUTO-GENERATED CODE - SEE TOP FOR INSTRUCTIONS */
 #define PACKET_QDISC_BYPASS 20
+#define PACKET_ROLLOVER_STATS 21
+#define PACKET_FANOUT_DATA 22
 #define PACKET_FANOUT_HASH 0
+/* WARNING: DO NOT EDIT, AUTO-GENERATED CODE - SEE TOP FOR INSTRUCTIONS */
 #define PACKET_FANOUT_LB 1
 #define PACKET_FANOUT_CPU 2
-/* WARNING: DO NOT EDIT, AUTO-GENERATED CODE - SEE TOP FOR INSTRUCTIONS */
 #define PACKET_FANOUT_ROLLOVER 3
 #define PACKET_FANOUT_RND 4
+/* WARNING: DO NOT EDIT, AUTO-GENERATED CODE - SEE TOP FOR INSTRUCTIONS */
 #define PACKET_FANOUT_QM 5
+#define PACKET_FANOUT_CBPF 6
+#define PACKET_FANOUT_EBPF 7
 #define PACKET_FANOUT_FLAG_ROLLOVER 0x1000
 /* WARNING: DO NOT EDIT, AUTO-GENERATED CODE - SEE TOP FOR INSTRUCTIONS */
 #define PACKET_FANOUT_FLAG_DEFRAG 0x8000
@@ -93,169 +98,177 @@
 /* WARNING: DO NOT EDIT, AUTO-GENERATED CODE - SEE TOP FOR INSTRUCTIONS */
   unsigned int tp_freeze_q_cnt;
 };
-union tpacket_stats_u {
-  struct tpacket_stats stats1;
+struct tpacket_rollover_stats {
+  __aligned_u64 tp_all;
 /* WARNING: DO NOT EDIT, AUTO-GENERATED CODE - SEE TOP FOR INSTRUCTIONS */
+  __aligned_u64 tp_huge;
+  __aligned_u64 tp_failed;
+};
+union tpacket_stats_u {
+/* WARNING: DO NOT EDIT, AUTO-GENERATED CODE - SEE TOP FOR INSTRUCTIONS */
+  struct tpacket_stats stats1;
   struct tpacket_stats_v3 stats3;
 };
 struct tpacket_auxdata {
-  __u32 tp_status;
 /* WARNING: DO NOT EDIT, AUTO-GENERATED CODE - SEE TOP FOR INSTRUCTIONS */
+  __u32 tp_status;
   __u32 tp_len;
   __u32 tp_snaplen;
   __u16 tp_mac;
-  __u16 tp_net;
 /* WARNING: DO NOT EDIT, AUTO-GENERATED CODE - SEE TOP FOR INSTRUCTIONS */
+  __u16 tp_net;
   __u16 tp_vlan_tci;
   __u16 tp_vlan_tpid;
 };
-#define TP_STATUS_KERNEL 0
 /* WARNING: DO NOT EDIT, AUTO-GENERATED CODE - SEE TOP FOR INSTRUCTIONS */
+#define TP_STATUS_KERNEL 0
 #define TP_STATUS_USER (1 << 0)
 #define TP_STATUS_COPY (1 << 1)
 #define TP_STATUS_LOSING (1 << 2)
-#define TP_STATUS_CSUMNOTREADY (1 << 3)
 /* WARNING: DO NOT EDIT, AUTO-GENERATED CODE - SEE TOP FOR INSTRUCTIONS */
+#define TP_STATUS_CSUMNOTREADY (1 << 3)
 #define TP_STATUS_VLAN_VALID (1 << 4)
 #define TP_STATUS_BLK_TMO (1 << 5)
 #define TP_STATUS_VLAN_TPID_VALID (1 << 6)
-#define TP_STATUS_AVAILABLE 0
 /* WARNING: DO NOT EDIT, AUTO-GENERATED CODE - SEE TOP FOR INSTRUCTIONS */
+#define TP_STATUS_CSUM_VALID (1 << 7)
+#define TP_STATUS_AVAILABLE 0
 #define TP_STATUS_SEND_REQUEST (1 << 0)
 #define TP_STATUS_SENDING (1 << 1)
+/* WARNING: DO NOT EDIT, AUTO-GENERATED CODE - SEE TOP FOR INSTRUCTIONS */
 #define TP_STATUS_WRONG_FORMAT (1 << 2)
 #define TP_STATUS_TS_SOFTWARE (1 << 29)
-/* WARNING: DO NOT EDIT, AUTO-GENERATED CODE - SEE TOP FOR INSTRUCTIONS */
 #define TP_STATUS_TS_SYS_HARDWARE (1 << 30)
 #define TP_STATUS_TS_RAW_HARDWARE (1 << 31)
+/* WARNING: DO NOT EDIT, AUTO-GENERATED CODE - SEE TOP FOR INSTRUCTIONS */
 #define TP_FT_REQ_FILL_RXHASH 0x1
 struct tpacket_hdr {
-/* WARNING: DO NOT EDIT, AUTO-GENERATED CODE - SEE TOP FOR INSTRUCTIONS */
   unsigned long tp_status;
   unsigned int tp_len;
+/* WARNING: DO NOT EDIT, AUTO-GENERATED CODE - SEE TOP FOR INSTRUCTIONS */
   unsigned int tp_snaplen;
   unsigned short tp_mac;
-/* WARNING: DO NOT EDIT, AUTO-GENERATED CODE - SEE TOP FOR INSTRUCTIONS */
   unsigned short tp_net;
   unsigned int tp_sec;
+/* WARNING: DO NOT EDIT, AUTO-GENERATED CODE - SEE TOP FOR INSTRUCTIONS */
   unsigned int tp_usec;
 };
-/* WARNING: DO NOT EDIT, AUTO-GENERATED CODE - SEE TOP FOR INSTRUCTIONS */
 #define TPACKET_ALIGNMENT 16
 #define TPACKET_ALIGN(x) (((x) + TPACKET_ALIGNMENT - 1) & ~(TPACKET_ALIGNMENT - 1))
+/* WARNING: DO NOT EDIT, AUTO-GENERATED CODE - SEE TOP FOR INSTRUCTIONS */
 #define TPACKET_HDRLEN (TPACKET_ALIGN(sizeof(struct tpacket_hdr)) + sizeof(struct sockaddr_ll))
 struct tpacket2_hdr {
-/* WARNING: DO NOT EDIT, AUTO-GENERATED CODE - SEE TOP FOR INSTRUCTIONS */
   __u32 tp_status;
   __u32 tp_len;
+/* WARNING: DO NOT EDIT, AUTO-GENERATED CODE - SEE TOP FOR INSTRUCTIONS */
   __u32 tp_snaplen;
   __u16 tp_mac;
-/* WARNING: DO NOT EDIT, AUTO-GENERATED CODE - SEE TOP FOR INSTRUCTIONS */
   __u16 tp_net;
   __u32 tp_sec;
+/* WARNING: DO NOT EDIT, AUTO-GENERATED CODE - SEE TOP FOR INSTRUCTIONS */
   __u32 tp_nsec;
   __u16 tp_vlan_tci;
-/* WARNING: DO NOT EDIT, AUTO-GENERATED CODE - SEE TOP FOR INSTRUCTIONS */
   __u16 tp_vlan_tpid;
   __u8 tp_padding[4];
+/* WARNING: DO NOT EDIT, AUTO-GENERATED CODE - SEE TOP FOR INSTRUCTIONS */
 };
 struct tpacket_hdr_variant1 {
-/* WARNING: DO NOT EDIT, AUTO-GENERATED CODE - SEE TOP FOR INSTRUCTIONS */
   __u32 tp_rxhash;
   __u32 tp_vlan_tci;
+/* WARNING: DO NOT EDIT, AUTO-GENERATED CODE - SEE TOP FOR INSTRUCTIONS */
   __u16 tp_vlan_tpid;
   __u16 tp_padding;
-/* WARNING: DO NOT EDIT, AUTO-GENERATED CODE - SEE TOP FOR INSTRUCTIONS */
 };
 struct tpacket3_hdr {
+/* WARNING: DO NOT EDIT, AUTO-GENERATED CODE - SEE TOP FOR INSTRUCTIONS */
   __u32 tp_next_offset;
   __u32 tp_sec;
-/* WARNING: DO NOT EDIT, AUTO-GENERATED CODE - SEE TOP FOR INSTRUCTIONS */
   __u32 tp_nsec;
   __u32 tp_snaplen;
+/* WARNING: DO NOT EDIT, AUTO-GENERATED CODE - SEE TOP FOR INSTRUCTIONS */
   __u32 tp_len;
   __u32 tp_status;
-/* WARNING: DO NOT EDIT, AUTO-GENERATED CODE - SEE TOP FOR INSTRUCTIONS */
   __u16 tp_mac;
   __u16 tp_net;
+/* WARNING: DO NOT EDIT, AUTO-GENERATED CODE - SEE TOP FOR INSTRUCTIONS */
   union {
     struct tpacket_hdr_variant1 hv1;
-/* WARNING: DO NOT EDIT, AUTO-GENERATED CODE - SEE TOP FOR INSTRUCTIONS */
   };
   __u8 tp_padding[8];
+/* WARNING: DO NOT EDIT, AUTO-GENERATED CODE - SEE TOP FOR INSTRUCTIONS */
 };
 struct tpacket_bd_ts {
-/* WARNING: DO NOT EDIT, AUTO-GENERATED CODE - SEE TOP FOR INSTRUCTIONS */
   unsigned int ts_sec;
   union {
+/* WARNING: DO NOT EDIT, AUTO-GENERATED CODE - SEE TOP FOR INSTRUCTIONS */
     unsigned int ts_usec;
     unsigned int ts_nsec;
-/* WARNING: DO NOT EDIT, AUTO-GENERATED CODE - SEE TOP FOR INSTRUCTIONS */
   };
 };
+/* WARNING: DO NOT EDIT, AUTO-GENERATED CODE - SEE TOP FOR INSTRUCTIONS */
 struct tpacket_hdr_v1 {
   __u32 block_status;
-/* WARNING: DO NOT EDIT, AUTO-GENERATED CODE - SEE TOP FOR INSTRUCTIONS */
   __u32 num_pkts;
   __u32 offset_to_first_pkt;
+/* WARNING: DO NOT EDIT, AUTO-GENERATED CODE - SEE TOP FOR INSTRUCTIONS */
   __u32 blk_len;
   __aligned_u64 seq_num;
-/* WARNING: DO NOT EDIT, AUTO-GENERATED CODE - SEE TOP FOR INSTRUCTIONS */
   struct tpacket_bd_ts ts_first_pkt, ts_last_pkt;
 };
+/* WARNING: DO NOT EDIT, AUTO-GENERATED CODE - SEE TOP FOR INSTRUCTIONS */
 union tpacket_bd_header_u {
   struct tpacket_hdr_v1 bh1;
-/* WARNING: DO NOT EDIT, AUTO-GENERATED CODE - SEE TOP FOR INSTRUCTIONS */
 };
 struct tpacket_block_desc {
+/* WARNING: DO NOT EDIT, AUTO-GENERATED CODE - SEE TOP FOR INSTRUCTIONS */
   __u32 version;
   __u32 offset_to_priv;
-/* WARNING: DO NOT EDIT, AUTO-GENERATED CODE - SEE TOP FOR INSTRUCTIONS */
   union tpacket_bd_header_u hdr;
 };
+/* WARNING: DO NOT EDIT, AUTO-GENERATED CODE - SEE TOP FOR INSTRUCTIONS */
 #define TPACKET2_HDRLEN (TPACKET_ALIGN(sizeof(struct tpacket2_hdr)) + sizeof(struct sockaddr_ll))
 #define TPACKET3_HDRLEN (TPACKET_ALIGN(sizeof(struct tpacket3_hdr)) + sizeof(struct sockaddr_ll))
-/* WARNING: DO NOT EDIT, AUTO-GENERATED CODE - SEE TOP FOR INSTRUCTIONS */
 enum tpacket_versions {
   TPACKET_V1,
+/* WARNING: DO NOT EDIT, AUTO-GENERATED CODE - SEE TOP FOR INSTRUCTIONS */
   TPACKET_V2,
   TPACKET_V3
-/* WARNING: DO NOT EDIT, AUTO-GENERATED CODE - SEE TOP FOR INSTRUCTIONS */
 };
 struct tpacket_req {
+/* WARNING: DO NOT EDIT, AUTO-GENERATED CODE - SEE TOP FOR INSTRUCTIONS */
   unsigned int tp_block_size;
   unsigned int tp_block_nr;
-/* WARNING: DO NOT EDIT, AUTO-GENERATED CODE - SEE TOP FOR INSTRUCTIONS */
   unsigned int tp_frame_size;
   unsigned int tp_frame_nr;
+/* WARNING: DO NOT EDIT, AUTO-GENERATED CODE - SEE TOP FOR INSTRUCTIONS */
 };
 struct tpacket_req3 {
-/* WARNING: DO NOT EDIT, AUTO-GENERATED CODE - SEE TOP FOR INSTRUCTIONS */
   unsigned int tp_block_size;
   unsigned int tp_block_nr;
+/* WARNING: DO NOT EDIT, AUTO-GENERATED CODE - SEE TOP FOR INSTRUCTIONS */
   unsigned int tp_frame_size;
   unsigned int tp_frame_nr;
-/* WARNING: DO NOT EDIT, AUTO-GENERATED CODE - SEE TOP FOR INSTRUCTIONS */
   unsigned int tp_retire_blk_tov;
   unsigned int tp_sizeof_priv;
+/* WARNING: DO NOT EDIT, AUTO-GENERATED CODE - SEE TOP FOR INSTRUCTIONS */
   unsigned int tp_feature_req_word;
 };
-/* WARNING: DO NOT EDIT, AUTO-GENERATED CODE - SEE TOP FOR INSTRUCTIONS */
 union tpacket_req_u {
   struct tpacket_req req;
+/* WARNING: DO NOT EDIT, AUTO-GENERATED CODE - SEE TOP FOR INSTRUCTIONS */
   struct tpacket_req3 req3;
 };
-/* WARNING: DO NOT EDIT, AUTO-GENERATED CODE - SEE TOP FOR INSTRUCTIONS */
 struct packet_mreq {
   int mr_ifindex;
+/* WARNING: DO NOT EDIT, AUTO-GENERATED CODE - SEE TOP FOR INSTRUCTIONS */
   unsigned short mr_type;
   unsigned short mr_alen;
-/* WARNING: DO NOT EDIT, AUTO-GENERATED CODE - SEE TOP FOR INSTRUCTIONS */
   unsigned char mr_address[8];
 };
+/* WARNING: DO NOT EDIT, AUTO-GENERATED CODE - SEE TOP FOR INSTRUCTIONS */
 #define PACKET_MR_MULTICAST 0
 #define PACKET_MR_PROMISC 1
-/* WARNING: DO NOT EDIT, AUTO-GENERATED CODE - SEE TOP FOR INSTRUCTIONS */
 #define PACKET_MR_ALLMULTI 2
 #define PACKET_MR_UNICAST 3
+/* WARNING: DO NOT EDIT, AUTO-GENERATED CODE - SEE TOP FOR INSTRUCTIONS */
 #endif
diff --git a/libc/kernel/uapi/linux/if_tun.h b/libc/kernel/uapi/linux/if_tun.h
index dd2dc2a..c5c1c27 100644
--- a/libc/kernel/uapi/linux/if_tun.h
+++ b/libc/kernel/uapi/linux/if_tun.h
@@ -23,77 +23,73 @@
 /* WARNING: DO NOT EDIT, AUTO-GENERATED CODE - SEE TOP FOR INSTRUCTIONS */
 #include <linux/filter.h>
 #define TUN_READQ_SIZE 500
-#define TUN_TUN_DEV 0x0001
-#define TUN_TAP_DEV 0x0002
+#define TUN_TUN_DEV IFF_TUN
+#define TUN_TAP_DEV IFF_TAP
 /* WARNING: DO NOT EDIT, AUTO-GENERATED CODE - SEE TOP FOR INSTRUCTIONS */
 #define TUN_TYPE_MASK 0x000f
-#define TUN_FASYNC 0x0010
-#define TUN_NOCHECKSUM 0x0020
-#define TUN_NO_PI 0x0040
-/* WARNING: DO NOT EDIT, AUTO-GENERATED CODE - SEE TOP FOR INSTRUCTIONS */
-#define TUN_ONE_QUEUE 0x0080
-#define TUN_PERSIST 0x0100
-#define TUN_VNET_HDR 0x0200
-#define TUN_TAP_MQ 0x0400
-/* WARNING: DO NOT EDIT, AUTO-GENERATED CODE - SEE TOP FOR INSTRUCTIONS */
 #define TUNSETNOCSUM _IOW('T', 200, int)
 #define TUNSETDEBUG _IOW('T', 201, int)
 #define TUNSETIFF _IOW('T', 202, int)
-#define TUNSETPERSIST _IOW('T', 203, int)
 /* WARNING: DO NOT EDIT, AUTO-GENERATED CODE - SEE TOP FOR INSTRUCTIONS */
+#define TUNSETPERSIST _IOW('T', 203, int)
 #define TUNSETOWNER _IOW('T', 204, int)
 #define TUNSETLINK _IOW('T', 205, int)
 #define TUNSETGROUP _IOW('T', 206, int)
-#define TUNGETFEATURES _IOR('T', 207, unsigned int)
 /* WARNING: DO NOT EDIT, AUTO-GENERATED CODE - SEE TOP FOR INSTRUCTIONS */
+#define TUNGETFEATURES _IOR('T', 207, unsigned int)
 #define TUNSETOFFLOAD _IOW('T', 208, unsigned int)
 #define TUNSETTXFILTER _IOW('T', 209, unsigned int)
 #define TUNGETIFF _IOR('T', 210, unsigned int)
-#define TUNGETSNDBUF _IOR('T', 211, int)
 /* WARNING: DO NOT EDIT, AUTO-GENERATED CODE - SEE TOP FOR INSTRUCTIONS */
+#define TUNGETSNDBUF _IOR('T', 211, int)
 #define TUNSETSNDBUF _IOW('T', 212, int)
 #define TUNATTACHFILTER _IOW('T', 213, struct sock_fprog)
 #define TUNDETACHFILTER _IOW('T', 214, struct sock_fprog)
-#define TUNGETVNETHDRSZ _IOR('T', 215, int)
 /* WARNING: DO NOT EDIT, AUTO-GENERATED CODE - SEE TOP FOR INSTRUCTIONS */
+#define TUNGETVNETHDRSZ _IOR('T', 215, int)
 #define TUNSETVNETHDRSZ _IOW('T', 216, int)
 #define TUNSETQUEUE _IOW('T', 217, int)
 #define TUNSETIFINDEX _IOW('T', 218, unsigned int)
-#define TUNGETFILTER _IOR('T', 219, struct sock_fprog)
 /* WARNING: DO NOT EDIT, AUTO-GENERATED CODE - SEE TOP FOR INSTRUCTIONS */
+#define TUNGETFILTER _IOR('T', 219, struct sock_fprog)
+#define TUNSETVNETLE _IOW('T', 220, int)
+#define TUNGETVNETLE _IOR('T', 221, int)
+#define TUNSETVNETBE _IOW('T', 222, int)
+/* WARNING: DO NOT EDIT, AUTO-GENERATED CODE - SEE TOP FOR INSTRUCTIONS */
+#define TUNGETVNETBE _IOR('T', 223, int)
 #define IFF_TUN 0x0001
 #define IFF_TAP 0x0002
 #define IFF_NO_PI 0x1000
-#define IFF_ONE_QUEUE 0x2000
 /* WARNING: DO NOT EDIT, AUTO-GENERATED CODE - SEE TOP FOR INSTRUCTIONS */
+#define IFF_ONE_QUEUE 0x2000
 #define IFF_VNET_HDR 0x4000
 #define IFF_TUN_EXCL 0x8000
 #define IFF_MULTI_QUEUE 0x0100
-#define IFF_ATTACH_QUEUE 0x0200
 /* WARNING: DO NOT EDIT, AUTO-GENERATED CODE - SEE TOP FOR INSTRUCTIONS */
+#define IFF_ATTACH_QUEUE 0x0200
 #define IFF_DETACH_QUEUE 0x0400
 #define IFF_PERSIST 0x0800
 #define IFF_NOFILTER 0x1000
-#define TUN_TX_TIMESTAMP 1
 /* WARNING: DO NOT EDIT, AUTO-GENERATED CODE - SEE TOP FOR INSTRUCTIONS */
+#define TUN_TX_TIMESTAMP 1
 #define TUN_F_CSUM 0x01
 #define TUN_F_TSO4 0x02
 #define TUN_F_TSO6 0x04
-#define TUN_F_TSO_ECN 0x08
 /* WARNING: DO NOT EDIT, AUTO-GENERATED CODE - SEE TOP FOR INSTRUCTIONS */
+#define TUN_F_TSO_ECN 0x08
 #define TUN_F_UFO 0x10
 #define TUN_PKT_STRIP 0x0001
 struct tun_pi {
-  __u16 flags;
 /* WARNING: DO NOT EDIT, AUTO-GENERATED CODE - SEE TOP FOR INSTRUCTIONS */
+  __u16 flags;
   __be16 proto;
 };
 #define TUN_FLT_ALLMULTI 0x0001
-struct tun_filter {
 /* WARNING: DO NOT EDIT, AUTO-GENERATED CODE - SEE TOP FOR INSTRUCTIONS */
+struct tun_filter {
   __u16 flags;
   __u16 count;
   __u8 addr[0][ETH_ALEN];
-};
 /* WARNING: DO NOT EDIT, AUTO-GENERATED CODE - SEE TOP FOR INSTRUCTIONS */
+};
 #endif
diff --git a/libc/kernel/uapi/linux/if_tunnel.h b/libc/kernel/uapi/linux/if_tunnel.h
index fea3428..2855e24 100644
--- a/libc/kernel/uapi/linux/if_tunnel.h
+++ b/libc/kernel/uapi/linux/if_tunnel.h
@@ -94,65 +94,67 @@
 };
 #define TUNNEL_ENCAP_FLAG_CSUM (1 << 0)
 #define TUNNEL_ENCAP_FLAG_CSUM6 (1 << 1)
-#define SIT_ISATAP 0x0001
+#define TUNNEL_ENCAP_FLAG_REMCSUM (1 << 2)
 /* WARNING: DO NOT EDIT, AUTO-GENERATED CODE - SEE TOP FOR INSTRUCTIONS */
+#define SIT_ISATAP 0x0001
 struct ip_tunnel_prl {
   __be32 addr;
   __u16 flags;
-  __u16 __reserved;
 /* WARNING: DO NOT EDIT, AUTO-GENERATED CODE - SEE TOP FOR INSTRUCTIONS */
+  __u16 __reserved;
   __u32 datalen;
   __u32 __reserved2;
 };
-#define PRL_DEFAULT 0x0001
 /* WARNING: DO NOT EDIT, AUTO-GENERATED CODE - SEE TOP FOR INSTRUCTIONS */
+#define PRL_DEFAULT 0x0001
 struct ip_tunnel_6rd {
   struct in6_addr prefix;
   __be32 relay_prefix;
-  __u16 prefixlen;
 /* WARNING: DO NOT EDIT, AUTO-GENERATED CODE - SEE TOP FOR INSTRUCTIONS */
+  __u16 prefixlen;
   __u16 relay_prefixlen;
 };
 enum {
-  IFLA_GRE_UNSPEC,
 /* WARNING: DO NOT EDIT, AUTO-GENERATED CODE - SEE TOP FOR INSTRUCTIONS */
+  IFLA_GRE_UNSPEC,
   IFLA_GRE_LINK,
   IFLA_GRE_IFLAGS,
   IFLA_GRE_OFLAGS,
-  IFLA_GRE_IKEY,
 /* WARNING: DO NOT EDIT, AUTO-GENERATED CODE - SEE TOP FOR INSTRUCTIONS */
+  IFLA_GRE_IKEY,
   IFLA_GRE_OKEY,
   IFLA_GRE_LOCAL,
   IFLA_GRE_REMOTE,
-  IFLA_GRE_TTL,
 /* WARNING: DO NOT EDIT, AUTO-GENERATED CODE - SEE TOP FOR INSTRUCTIONS */
+  IFLA_GRE_TTL,
   IFLA_GRE_TOS,
   IFLA_GRE_PMTUDISC,
   IFLA_GRE_ENCAP_LIMIT,
-  IFLA_GRE_FLOWINFO,
 /* WARNING: DO NOT EDIT, AUTO-GENERATED CODE - SEE TOP FOR INSTRUCTIONS */
+  IFLA_GRE_FLOWINFO,
   IFLA_GRE_FLAGS,
   IFLA_GRE_ENCAP_TYPE,
   IFLA_GRE_ENCAP_FLAGS,
-  IFLA_GRE_ENCAP_SPORT,
 /* WARNING: DO NOT EDIT, AUTO-GENERATED CODE - SEE TOP FOR INSTRUCTIONS */
+  IFLA_GRE_ENCAP_SPORT,
   IFLA_GRE_ENCAP_DPORT,
+  IFLA_GRE_COLLECT_METADATA,
   __IFLA_GRE_MAX,
+/* WARNING: DO NOT EDIT, AUTO-GENERATED CODE - SEE TOP FOR INSTRUCTIONS */
 };
 #define IFLA_GRE_MAX (__IFLA_GRE_MAX - 1)
-/* WARNING: DO NOT EDIT, AUTO-GENERATED CODE - SEE TOP FOR INSTRUCTIONS */
 #define VTI_ISVTI ((__force __be16) 0x0001)
 enum {
+/* WARNING: DO NOT EDIT, AUTO-GENERATED CODE - SEE TOP FOR INSTRUCTIONS */
   IFLA_VTI_UNSPEC,
   IFLA_VTI_LINK,
-/* WARNING: DO NOT EDIT, AUTO-GENERATED CODE - SEE TOP FOR INSTRUCTIONS */
   IFLA_VTI_IKEY,
   IFLA_VTI_OKEY,
+/* WARNING: DO NOT EDIT, AUTO-GENERATED CODE - SEE TOP FOR INSTRUCTIONS */
   IFLA_VTI_LOCAL,
   IFLA_VTI_REMOTE,
-/* WARNING: DO NOT EDIT, AUTO-GENERATED CODE - SEE TOP FOR INSTRUCTIONS */
   __IFLA_VTI_MAX,
 };
+/* WARNING: DO NOT EDIT, AUTO-GENERATED CODE - SEE TOP FOR INSTRUCTIONS */
 #define IFLA_VTI_MAX (__IFLA_VTI_MAX - 1)
 #endif
-/* WARNING: DO NOT EDIT, AUTO-GENERATED CODE - SEE TOP FOR INSTRUCTIONS */
diff --git a/libc/kernel/uapi/linux/iio/events.h b/libc/kernel/uapi/linux/iio/events.h
new file mode 100644
index 0000000..67ecbb2
--- /dev/null
+++ b/libc/kernel/uapi/linux/iio/events.h
@@ -0,0 +1,39 @@
+/****************************************************************************
+ ****************************************************************************
+ ***
+ ***   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_IIO_EVENTS_H_
+#define _UAPI_IIO_EVENTS_H_
+#include <linux/ioctl.h>
+#include <linux/types.h>
+/* WARNING: DO NOT EDIT, AUTO-GENERATED CODE - SEE TOP FOR INSTRUCTIONS */
+struct iio_event_data {
+  __u64 id;
+  __s64 timestamp;
+};
+/* WARNING: DO NOT EDIT, AUTO-GENERATED CODE - SEE TOP FOR INSTRUCTIONS */
+#define IIO_GET_EVENT_FD_IOCTL _IOR('i', 0x90, int)
+#define IIO_EVENT_CODE_EXTRACT_TYPE(mask) ((mask >> 56) & 0xFF)
+#define IIO_EVENT_CODE_EXTRACT_DIR(mask) ((mask >> 48) & 0x7F)
+#define IIO_EVENT_CODE_EXTRACT_CHAN_TYPE(mask) ((mask >> 32) & 0xFF)
+/* WARNING: DO NOT EDIT, AUTO-GENERATED CODE - SEE TOP FOR INSTRUCTIONS */
+#define IIO_EVENT_CODE_EXTRACT_CHAN(mask) ((__s16) (mask & 0xFFFF))
+#define IIO_EVENT_CODE_EXTRACT_CHAN2(mask) ((__s16) (((mask) >> 16) & 0xFFFF))
+#define IIO_EVENT_CODE_EXTRACT_MODIFIER(mask) ((mask >> 40) & 0xFF)
+#define IIO_EVENT_CODE_EXTRACT_DIFF(mask) (((mask) >> 55) & 0x1)
+/* WARNING: DO NOT EDIT, AUTO-GENERATED CODE - SEE TOP FOR INSTRUCTIONS */
+#endif
diff --git a/libc/kernel/uapi/linux/iio/types.h b/libc/kernel/uapi/linux/iio/types.h
new file mode 100644
index 0000000..7520dbf
--- /dev/null
+++ b/libc/kernel/uapi/linux/iio/types.h
@@ -0,0 +1,121 @@
+/****************************************************************************
+ ****************************************************************************
+ ***
+ ***   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_IIO_TYPES_H_
+#define _UAPI_IIO_TYPES_H_
+enum iio_chan_type {
+  IIO_VOLTAGE,
+/* WARNING: DO NOT EDIT, AUTO-GENERATED CODE - SEE TOP FOR INSTRUCTIONS */
+  IIO_CURRENT,
+  IIO_POWER,
+  IIO_ACCEL,
+  IIO_ANGL_VEL,
+/* WARNING: DO NOT EDIT, AUTO-GENERATED CODE - SEE TOP FOR INSTRUCTIONS */
+  IIO_MAGN,
+  IIO_LIGHT,
+  IIO_INTENSITY,
+  IIO_PROXIMITY,
+/* WARNING: DO NOT EDIT, AUTO-GENERATED CODE - SEE TOP FOR INSTRUCTIONS */
+  IIO_TEMP,
+  IIO_INCLI,
+  IIO_ROT,
+  IIO_ANGL,
+/* WARNING: DO NOT EDIT, AUTO-GENERATED CODE - SEE TOP FOR INSTRUCTIONS */
+  IIO_TIMESTAMP,
+  IIO_CAPACITANCE,
+  IIO_ALTVOLTAGE,
+  IIO_CCT,
+/* WARNING: DO NOT EDIT, AUTO-GENERATED CODE - SEE TOP FOR INSTRUCTIONS */
+  IIO_PRESSURE,
+  IIO_HUMIDITYRELATIVE,
+  IIO_ACTIVITY,
+  IIO_STEPS,
+/* WARNING: DO NOT EDIT, AUTO-GENERATED CODE - SEE TOP FOR INSTRUCTIONS */
+  IIO_ENERGY,
+  IIO_DISTANCE,
+  IIO_VELOCITY,
+  IIO_CONCENTRATION,
+/* WARNING: DO NOT EDIT, AUTO-GENERATED CODE - SEE TOP FOR INSTRUCTIONS */
+  IIO_RESISTANCE,
+};
+enum iio_modifier {
+  IIO_NO_MOD,
+/* WARNING: DO NOT EDIT, AUTO-GENERATED CODE - SEE TOP FOR INSTRUCTIONS */
+  IIO_MOD_X,
+  IIO_MOD_Y,
+  IIO_MOD_Z,
+  IIO_MOD_X_AND_Y,
+/* WARNING: DO NOT EDIT, AUTO-GENERATED CODE - SEE TOP FOR INSTRUCTIONS */
+  IIO_MOD_X_AND_Z,
+  IIO_MOD_Y_AND_Z,
+  IIO_MOD_X_AND_Y_AND_Z,
+  IIO_MOD_X_OR_Y,
+/* WARNING: DO NOT EDIT, AUTO-GENERATED CODE - SEE TOP FOR INSTRUCTIONS */
+  IIO_MOD_X_OR_Z,
+  IIO_MOD_Y_OR_Z,
+  IIO_MOD_X_OR_Y_OR_Z,
+  IIO_MOD_LIGHT_BOTH,
+/* WARNING: DO NOT EDIT, AUTO-GENERATED CODE - SEE TOP FOR INSTRUCTIONS */
+  IIO_MOD_LIGHT_IR,
+  IIO_MOD_ROOT_SUM_SQUARED_X_Y,
+  IIO_MOD_SUM_SQUARED_X_Y_Z,
+  IIO_MOD_LIGHT_CLEAR,
+/* WARNING: DO NOT EDIT, AUTO-GENERATED CODE - SEE TOP FOR INSTRUCTIONS */
+  IIO_MOD_LIGHT_RED,
+  IIO_MOD_LIGHT_GREEN,
+  IIO_MOD_LIGHT_BLUE,
+  IIO_MOD_QUATERNION,
+/* WARNING: DO NOT EDIT, AUTO-GENERATED CODE - SEE TOP FOR INSTRUCTIONS */
+  IIO_MOD_TEMP_AMBIENT,
+  IIO_MOD_TEMP_OBJECT,
+  IIO_MOD_NORTH_MAGN,
+  IIO_MOD_NORTH_TRUE,
+/* WARNING: DO NOT EDIT, AUTO-GENERATED CODE - SEE TOP FOR INSTRUCTIONS */
+  IIO_MOD_NORTH_MAGN_TILT_COMP,
+  IIO_MOD_NORTH_TRUE_TILT_COMP,
+  IIO_MOD_RUNNING,
+  IIO_MOD_JOGGING,
+/* WARNING: DO NOT EDIT, AUTO-GENERATED CODE - SEE TOP FOR INSTRUCTIONS */
+  IIO_MOD_WALKING,
+  IIO_MOD_STILL,
+  IIO_MOD_ROOT_SUM_SQUARED_X_Y_Z,
+  IIO_MOD_I,
+/* WARNING: DO NOT EDIT, AUTO-GENERATED CODE - SEE TOP FOR INSTRUCTIONS */
+  IIO_MOD_Q,
+  IIO_MOD_CO2,
+  IIO_MOD_VOC,
+};
+/* WARNING: DO NOT EDIT, AUTO-GENERATED CODE - SEE TOP FOR INSTRUCTIONS */
+enum iio_event_type {
+  IIO_EV_TYPE_THRESH,
+  IIO_EV_TYPE_MAG,
+  IIO_EV_TYPE_ROC,
+/* WARNING: DO NOT EDIT, AUTO-GENERATED CODE - SEE TOP FOR INSTRUCTIONS */
+  IIO_EV_TYPE_THRESH_ADAPTIVE,
+  IIO_EV_TYPE_MAG_ADAPTIVE,
+  IIO_EV_TYPE_CHANGE,
+};
+/* WARNING: DO NOT EDIT, AUTO-GENERATED CODE - SEE TOP FOR INSTRUCTIONS */
+enum iio_event_direction {
+  IIO_EV_DIR_EITHER,
+  IIO_EV_DIR_RISING,
+  IIO_EV_DIR_FALLING,
+/* WARNING: DO NOT EDIT, AUTO-GENERATED CODE - SEE TOP FOR INSTRUCTIONS */
+  IIO_EV_DIR_NONE,
+};
+#endif
diff --git a/libc/kernel/uapi/linux/ila.h b/libc/kernel/uapi/linux/ila.h
new file mode 100644
index 0000000..dc036d7
--- /dev/null
+++ b/libc/kernel/uapi/linux/ila.h
@@ -0,0 +1,29 @@
+/****************************************************************************
+ ****************************************************************************
+ ***
+ ***   This header was automatically generated from a Linux kernel header
+ ***   of the same name, to make information necessary for userspace to
+ ***   call into the kernel available to libc.  It contains only constants,
+ ***   structures, and macros generated from the original header, and thus,
+ ***   contains no copyrightable information.
+ ***
+ ***   To edit the content of this header, modify the corresponding
+ ***   source file (e.g. under external/kernel-headers/original/) then
+ ***   run bionic/libc/kernel/tools/update_all.py
+ ***
+ ***   Any manual change here will be lost the next time this script will
+ ***   be run. You've been warned!
+ ***
+ ****************************************************************************
+ ****************************************************************************/
+#ifndef _UAPI_LINUX_ILA_H
+#define _UAPI_LINUX_ILA_H
+enum {
+  ILA_ATTR_UNSPEC,
+/* WARNING: DO NOT EDIT, AUTO-GENERATED CODE - SEE TOP FOR INSTRUCTIONS */
+  ILA_ATTR_LOCATOR,
+  __ILA_ATTR_MAX,
+};
+#define ILA_ATTR_MAX (__ILA_ATTR_MAX - 1)
+/* WARNING: DO NOT EDIT, AUTO-GENERATED CODE - SEE TOP FOR INSTRUCTIONS */
+#endif
diff --git a/libc/kernel/uapi/linux/in.h b/libc/kernel/uapi/linux/in.h
index 6a6d16e..03fdf99 100644
--- a/libc/kernel/uapi/linux/in.h
+++ b/libc/kernel/uapi/linux/in.h
@@ -19,206 +19,226 @@
 #ifndef _UAPI_LINUX_IN_H
 #define _UAPI_LINUX_IN_H
 #include <linux/types.h>
-#include <linux/socket.h>
+#include <linux/libc-compat.h>
 /* WARNING: DO NOT EDIT, AUTO-GENERATED CODE - SEE TOP FOR INSTRUCTIONS */
+#include <linux/socket.h>
+#if __UAPI_DEF_IN_IPPROTO
 enum {
   IPPROTO_IP = 0,
+/* WARNING: DO NOT EDIT, AUTO-GENERATED CODE - SEE TOP FOR INSTRUCTIONS */
 #define IPPROTO_IP IPPROTO_IP
   IPPROTO_ICMP = 1,
-/* WARNING: DO NOT EDIT, AUTO-GENERATED CODE - SEE TOP FOR INSTRUCTIONS */
 #define IPPROTO_ICMP IPPROTO_ICMP
   IPPROTO_IGMP = 2,
+/* WARNING: DO NOT EDIT, AUTO-GENERATED CODE - SEE TOP FOR INSTRUCTIONS */
 #define IPPROTO_IGMP IPPROTO_IGMP
   IPPROTO_IPIP = 4,
-/* WARNING: DO NOT EDIT, AUTO-GENERATED CODE - SEE TOP FOR INSTRUCTIONS */
 #define IPPROTO_IPIP IPPROTO_IPIP
   IPPROTO_TCP = 6,
+/* WARNING: DO NOT EDIT, AUTO-GENERATED CODE - SEE TOP FOR INSTRUCTIONS */
 #define IPPROTO_TCP IPPROTO_TCP
   IPPROTO_EGP = 8,
-/* WARNING: DO NOT EDIT, AUTO-GENERATED CODE - SEE TOP FOR INSTRUCTIONS */
 #define IPPROTO_EGP IPPROTO_EGP
   IPPROTO_PUP = 12,
+/* WARNING: DO NOT EDIT, AUTO-GENERATED CODE - SEE TOP FOR INSTRUCTIONS */
 #define IPPROTO_PUP IPPROTO_PUP
   IPPROTO_UDP = 17,
-/* WARNING: DO NOT EDIT, AUTO-GENERATED CODE - SEE TOP FOR INSTRUCTIONS */
 #define IPPROTO_UDP IPPROTO_UDP
   IPPROTO_IDP = 22,
+/* WARNING: DO NOT EDIT, AUTO-GENERATED CODE - SEE TOP FOR INSTRUCTIONS */
 #define IPPROTO_IDP IPPROTO_IDP
   IPPROTO_TP = 29,
-/* WARNING: DO NOT EDIT, AUTO-GENERATED CODE - SEE TOP FOR INSTRUCTIONS */
 #define IPPROTO_TP IPPROTO_TP
   IPPROTO_DCCP = 33,
+/* WARNING: DO NOT EDIT, AUTO-GENERATED CODE - SEE TOP FOR INSTRUCTIONS */
 #define IPPROTO_DCCP IPPROTO_DCCP
   IPPROTO_IPV6 = 41,
-/* WARNING: DO NOT EDIT, AUTO-GENERATED CODE - SEE TOP FOR INSTRUCTIONS */
 #define IPPROTO_IPV6 IPPROTO_IPV6
   IPPROTO_RSVP = 46,
+/* WARNING: DO NOT EDIT, AUTO-GENERATED CODE - SEE TOP FOR INSTRUCTIONS */
 #define IPPROTO_RSVP IPPROTO_RSVP
   IPPROTO_GRE = 47,
-/* WARNING: DO NOT EDIT, AUTO-GENERATED CODE - SEE TOP FOR INSTRUCTIONS */
 #define IPPROTO_GRE IPPROTO_GRE
   IPPROTO_ESP = 50,
+/* WARNING: DO NOT EDIT, AUTO-GENERATED CODE - SEE TOP FOR INSTRUCTIONS */
 #define IPPROTO_ESP IPPROTO_ESP
   IPPROTO_AH = 51,
-/* WARNING: DO NOT EDIT, AUTO-GENERATED CODE - SEE TOP FOR INSTRUCTIONS */
 #define IPPROTO_AH IPPROTO_AH
   IPPROTO_MTP = 92,
+/* WARNING: DO NOT EDIT, AUTO-GENERATED CODE - SEE TOP FOR INSTRUCTIONS */
 #define IPPROTO_MTP IPPROTO_MTP
   IPPROTO_BEETPH = 94,
-/* WARNING: DO NOT EDIT, AUTO-GENERATED CODE - SEE TOP FOR INSTRUCTIONS */
 #define IPPROTO_BEETPH IPPROTO_BEETPH
   IPPROTO_ENCAP = 98,
+/* WARNING: DO NOT EDIT, AUTO-GENERATED CODE - SEE TOP FOR INSTRUCTIONS */
 #define IPPROTO_ENCAP IPPROTO_ENCAP
   IPPROTO_PIM = 103,
-/* WARNING: DO NOT EDIT, AUTO-GENERATED CODE - SEE TOP FOR INSTRUCTIONS */
 #define IPPROTO_PIM IPPROTO_PIM
   IPPROTO_COMP = 108,
+/* WARNING: DO NOT EDIT, AUTO-GENERATED CODE - SEE TOP FOR INSTRUCTIONS */
 #define IPPROTO_COMP IPPROTO_COMP
   IPPROTO_SCTP = 132,
-/* WARNING: DO NOT EDIT, AUTO-GENERATED CODE - SEE TOP FOR INSTRUCTIONS */
 #define IPPROTO_SCTP IPPROTO_SCTP
   IPPROTO_UDPLITE = 136,
+/* WARNING: DO NOT EDIT, AUTO-GENERATED CODE - SEE TOP FOR INSTRUCTIONS */
 #define IPPROTO_UDPLITE IPPROTO_UDPLITE
+  IPPROTO_MPLS = 137,
+#define IPPROTO_MPLS IPPROTO_MPLS
   IPPROTO_RAW = 255,
 /* WARNING: DO NOT EDIT, AUTO-GENERATED CODE - SEE TOP FOR INSTRUCTIONS */
 #define IPPROTO_RAW IPPROTO_RAW
   IPPROTO_MAX
 };
-struct in_addr {
+#endif
 /* WARNING: DO NOT EDIT, AUTO-GENERATED CODE - SEE TOP FOR INSTRUCTIONS */
+#if __UAPI_DEF_IN_ADDR
+struct in_addr {
   __be32 s_addr;
 };
+/* WARNING: DO NOT EDIT, AUTO-GENERATED CODE - SEE TOP FOR INSTRUCTIONS */
+#endif
 #define IP_TOS 1
 #define IP_TTL 2
-/* WARNING: DO NOT EDIT, AUTO-GENERATED CODE - SEE TOP FOR INSTRUCTIONS */
 #define IP_HDRINCL 3
+/* WARNING: DO NOT EDIT, AUTO-GENERATED CODE - SEE TOP FOR INSTRUCTIONS */
 #define IP_OPTIONS 4
 #define IP_ROUTER_ALERT 5
 #define IP_RECVOPTS 6
-/* WARNING: DO NOT EDIT, AUTO-GENERATED CODE - SEE TOP FOR INSTRUCTIONS */
 #define IP_RETOPTS 7
+/* WARNING: DO NOT EDIT, AUTO-GENERATED CODE - SEE TOP FOR INSTRUCTIONS */
 #define IP_PKTINFO 8
 #define IP_PKTOPTIONS 9
 #define IP_MTU_DISCOVER 10
-/* WARNING: DO NOT EDIT, AUTO-GENERATED CODE - SEE TOP FOR INSTRUCTIONS */
 #define IP_RECVERR 11
+/* WARNING: DO NOT EDIT, AUTO-GENERATED CODE - SEE TOP FOR INSTRUCTIONS */
 #define IP_RECVTTL 12
 #define IP_RECVTOS 13
 #define IP_MTU 14
-/* WARNING: DO NOT EDIT, AUTO-GENERATED CODE - SEE TOP FOR INSTRUCTIONS */
 #define IP_FREEBIND 15
+/* WARNING: DO NOT EDIT, AUTO-GENERATED CODE - SEE TOP FOR INSTRUCTIONS */
 #define IP_IPSEC_POLICY 16
 #define IP_XFRM_POLICY 17
 #define IP_PASSSEC 18
-/* WARNING: DO NOT EDIT, AUTO-GENERATED CODE - SEE TOP FOR INSTRUCTIONS */
 #define IP_TRANSPARENT 19
+/* WARNING: DO NOT EDIT, AUTO-GENERATED CODE - SEE TOP FOR INSTRUCTIONS */
 #define IP_RECVRETOPTS IP_RETOPTS
 #define IP_ORIGDSTADDR 20
 #define IP_RECVORIGDSTADDR IP_ORIGDSTADDR
-/* WARNING: DO NOT EDIT, AUTO-GENERATED CODE - SEE TOP FOR INSTRUCTIONS */
 #define IP_MINTTL 21
-#define IP_NODEFRAG 22
-#define IP_PMTUDISC_DONT 0
-#define IP_PMTUDISC_WANT 1
 /* WARNING: DO NOT EDIT, AUTO-GENERATED CODE - SEE TOP FOR INSTRUCTIONS */
+#define IP_NODEFRAG 22
+#define IP_CHECKSUM 23
+#define IP_BIND_ADDRESS_NO_PORT 24
+#define IP_PMTUDISC_DONT 0
+/* WARNING: DO NOT EDIT, AUTO-GENERATED CODE - SEE TOP FOR INSTRUCTIONS */
+#define IP_PMTUDISC_WANT 1
 #define IP_PMTUDISC_DO 2
 #define IP_PMTUDISC_PROBE 3
 #define IP_PMTUDISC_INTERFACE 4
-#define IP_PMTUDISC_OMIT 5
 /* WARNING: DO NOT EDIT, AUTO-GENERATED CODE - SEE TOP FOR INSTRUCTIONS */
+#define IP_PMTUDISC_OMIT 5
 #define IP_MULTICAST_IF 32
 #define IP_MULTICAST_TTL 33
 #define IP_MULTICAST_LOOP 34
-#define IP_ADD_MEMBERSHIP 35
 /* WARNING: DO NOT EDIT, AUTO-GENERATED CODE - SEE TOP FOR INSTRUCTIONS */
+#define IP_ADD_MEMBERSHIP 35
 #define IP_DROP_MEMBERSHIP 36
 #define IP_UNBLOCK_SOURCE 37
 #define IP_BLOCK_SOURCE 38
-#define IP_ADD_SOURCE_MEMBERSHIP 39
 /* WARNING: DO NOT EDIT, AUTO-GENERATED CODE - SEE TOP FOR INSTRUCTIONS */
+#define IP_ADD_SOURCE_MEMBERSHIP 39
 #define IP_DROP_SOURCE_MEMBERSHIP 40
 #define IP_MSFILTER 41
 #define MCAST_JOIN_GROUP 42
-#define MCAST_BLOCK_SOURCE 43
 /* WARNING: DO NOT EDIT, AUTO-GENERATED CODE - SEE TOP FOR INSTRUCTIONS */
+#define MCAST_BLOCK_SOURCE 43
 #define MCAST_UNBLOCK_SOURCE 44
 #define MCAST_LEAVE_GROUP 45
 #define MCAST_JOIN_SOURCE_GROUP 46
-#define MCAST_LEAVE_SOURCE_GROUP 47
 /* WARNING: DO NOT EDIT, AUTO-GENERATED CODE - SEE TOP FOR INSTRUCTIONS */
+#define MCAST_LEAVE_SOURCE_GROUP 47
 #define MCAST_MSFILTER 48
 #define IP_MULTICAST_ALL 49
 #define IP_UNICAST_IF 50
-#define MCAST_EXCLUDE 0
 /* WARNING: DO NOT EDIT, AUTO-GENERATED CODE - SEE TOP FOR INSTRUCTIONS */
+#define MCAST_EXCLUDE 0
 #define MCAST_INCLUDE 1
 #define IP_DEFAULT_MULTICAST_TTL 1
 #define IP_DEFAULT_MULTICAST_LOOP 1
-struct ip_mreq {
 /* WARNING: DO NOT EDIT, AUTO-GENERATED CODE - SEE TOP FOR INSTRUCTIONS */
+#if __UAPI_DEF_IP_MREQ
+struct ip_mreq {
   struct in_addr imr_multiaddr;
   struct in_addr imr_interface;
+/* WARNING: DO NOT EDIT, AUTO-GENERATED CODE - SEE TOP FOR INSTRUCTIONS */
 };
 struct ip_mreqn {
-/* WARNING: DO NOT EDIT, AUTO-GENERATED CODE - SEE TOP FOR INSTRUCTIONS */
   struct in_addr imr_multiaddr;
   struct in_addr imr_address;
+/* WARNING: DO NOT EDIT, AUTO-GENERATED CODE - SEE TOP FOR INSTRUCTIONS */
   int imr_ifindex;
 };
-/* WARNING: DO NOT EDIT, AUTO-GENERATED CODE - SEE TOP FOR INSTRUCTIONS */
 struct ip_mreq_source {
   __be32 imr_multiaddr;
+/* WARNING: DO NOT EDIT, AUTO-GENERATED CODE - SEE TOP FOR INSTRUCTIONS */
   __be32 imr_interface;
   __be32 imr_sourceaddr;
-/* WARNING: DO NOT EDIT, AUTO-GENERATED CODE - SEE TOP FOR INSTRUCTIONS */
 };
 struct ip_msfilter {
+/* WARNING: DO NOT EDIT, AUTO-GENERATED CODE - SEE TOP FOR INSTRUCTIONS */
   __be32 imsf_multiaddr;
   __be32 imsf_interface;
-/* WARNING: DO NOT EDIT, AUTO-GENERATED CODE - SEE TOP FOR INSTRUCTIONS */
   __u32 imsf_fmode;
   __u32 imsf_numsrc;
+/* WARNING: DO NOT EDIT, AUTO-GENERATED CODE - SEE TOP FOR INSTRUCTIONS */
   __be32 imsf_slist[1];
 };
-/* WARNING: DO NOT EDIT, AUTO-GENERATED CODE - SEE TOP FOR INSTRUCTIONS */
 #define IP_MSFILTER_SIZE(numsrc) (sizeof(struct ip_msfilter) - sizeof(__u32) + (numsrc) * sizeof(__u32))
 struct group_req {
+/* WARNING: DO NOT EDIT, AUTO-GENERATED CODE - SEE TOP FOR INSTRUCTIONS */
   __u32 gr_interface;
   struct __kernel_sockaddr_storage gr_group;
-/* WARNING: DO NOT EDIT, AUTO-GENERATED CODE - SEE TOP FOR INSTRUCTIONS */
 };
 struct group_source_req {
+/* WARNING: DO NOT EDIT, AUTO-GENERATED CODE - SEE TOP FOR INSTRUCTIONS */
   __u32 gsr_interface;
   struct __kernel_sockaddr_storage gsr_group;
-/* WARNING: DO NOT EDIT, AUTO-GENERATED CODE - SEE TOP FOR INSTRUCTIONS */
   struct __kernel_sockaddr_storage gsr_source;
 };
+/* WARNING: DO NOT EDIT, AUTO-GENERATED CODE - SEE TOP FOR INSTRUCTIONS */
 struct group_filter {
   __u32 gf_interface;
-/* WARNING: DO NOT EDIT, AUTO-GENERATED CODE - SEE TOP FOR INSTRUCTIONS */
   struct __kernel_sockaddr_storage gf_group;
   __u32 gf_fmode;
+/* WARNING: DO NOT EDIT, AUTO-GENERATED CODE - SEE TOP FOR INSTRUCTIONS */
   __u32 gf_numsrc;
   struct __kernel_sockaddr_storage gf_slist[1];
-/* WARNING: DO NOT EDIT, AUTO-GENERATED CODE - SEE TOP FOR INSTRUCTIONS */
 };
 #define GROUP_FILTER_SIZE(numsrc) (sizeof(struct group_filter) - sizeof(struct __kernel_sockaddr_storage) + (numsrc) * sizeof(struct __kernel_sockaddr_storage))
+/* WARNING: DO NOT EDIT, AUTO-GENERATED CODE - SEE TOP FOR INSTRUCTIONS */
+#endif
+#if __UAPI_DEF_IN_PKTINFO
 struct in_pktinfo {
   int ipi_ifindex;
 /* WARNING: DO NOT EDIT, AUTO-GENERATED CODE - SEE TOP FOR INSTRUCTIONS */
   struct in_addr ipi_spec_dst;
   struct in_addr ipi_addr;
 };
-#define __SOCK_SIZE__ 16
+#endif
 /* WARNING: DO NOT EDIT, AUTO-GENERATED CODE - SEE TOP FOR INSTRUCTIONS */
+#if __UAPI_DEF_SOCKADDR_IN
+#define __SOCK_SIZE__ 16
 struct sockaddr_in {
   __kernel_sa_family_t sin_family;
+/* WARNING: DO NOT EDIT, AUTO-GENERATED CODE - SEE TOP FOR INSTRUCTIONS */
   __be16 sin_port;
   struct in_addr sin_addr;
-/* WARNING: DO NOT EDIT, AUTO-GENERATED CODE - SEE TOP FOR INSTRUCTIONS */
   unsigned char __pad[__SOCK_SIZE__ - sizeof(short int) - sizeof(unsigned short int) - sizeof(struct in_addr)];
 };
+/* WARNING: DO NOT EDIT, AUTO-GENERATED CODE - SEE TOP FOR INSTRUCTIONS */
 #define sin_zero __pad
+#endif
+#if __UAPI_DEF_IN_CLASS
 #define IN_CLASSA(a) ((((long int) (a)) & 0x80000000) == 0)
 /* WARNING: DO NOT EDIT, AUTO-GENERATED CODE - SEE TOP FOR INSTRUCTIONS */
 #define IN_CLASSA_NET 0xff000000
@@ -256,5 +276,6 @@
 #define INADDR_ALLRTRS_GROUP 0xe0000002U
 #define INADDR_MAX_LOCAL_GROUP 0xe00000ffU
 /* WARNING: DO NOT EDIT, AUTO-GENERATED CODE - SEE TOP FOR INSTRUCTIONS */
+#endif
 #include <asm/byteorder.h>
 #endif
diff --git a/libc/kernel/uapi/linux/inet_diag.h b/libc/kernel/uapi/linux/inet_diag.h
index 447d928..d904418 100644
--- a/libc/kernel/uapi/linux/inet_diag.h
+++ b/libc/kernel/uapi/linux/inet_diag.h
@@ -118,31 +118,38 @@
 /* WARNING: DO NOT EDIT, AUTO-GENERATED CODE - SEE TOP FOR INSTRUCTIONS */
   INET_DIAG_SHUTDOWN,
   INET_DIAG_DCTCPINFO,
-};
-#define INET_DIAG_MAX INET_DIAG_DCTCPINFO
+  INET_DIAG_PROTOCOL,
+  INET_DIAG_SKV6ONLY,
 /* WARNING: DO NOT EDIT, AUTO-GENERATED CODE - SEE TOP FOR INSTRUCTIONS */
+};
+#define INET_DIAG_MAX INET_DIAG_SKV6ONLY
 struct inet_diag_meminfo {
   __u32 idiag_rmem;
+/* WARNING: DO NOT EDIT, AUTO-GENERATED CODE - SEE TOP FOR INSTRUCTIONS */
   __u32 idiag_wmem;
   __u32 idiag_fmem;
-/* WARNING: DO NOT EDIT, AUTO-GENERATED CODE - SEE TOP FOR INSTRUCTIONS */
   __u32 idiag_tmem;
 };
+/* WARNING: DO NOT EDIT, AUTO-GENERATED CODE - SEE TOP FOR INSTRUCTIONS */
 struct tcpvegas_info {
   __u32 tcpv_enabled;
-/* WARNING: DO NOT EDIT, AUTO-GENERATED CODE - SEE TOP FOR INSTRUCTIONS */
   __u32 tcpv_rttcnt;
   __u32 tcpv_rtt;
+/* WARNING: DO NOT EDIT, AUTO-GENERATED CODE - SEE TOP FOR INSTRUCTIONS */
   __u32 tcpv_minrtt;
 };
-/* WARNING: DO NOT EDIT, AUTO-GENERATED CODE - SEE TOP FOR INSTRUCTIONS */
 struct tcp_dctcp_info {
   __u16 dctcp_enabled;
+/* WARNING: DO NOT EDIT, AUTO-GENERATED CODE - SEE TOP FOR INSTRUCTIONS */
   __u16 dctcp_ce_state;
   __u32 dctcp_alpha;
-/* WARNING: DO NOT EDIT, AUTO-GENERATED CODE - SEE TOP FOR INSTRUCTIONS */
   __u32 dctcp_ab_ecn;
   __u32 dctcp_ab_tot;
+/* WARNING: DO NOT EDIT, AUTO-GENERATED CODE - SEE TOP FOR INSTRUCTIONS */
+};
+union tcp_cc_info {
+  struct tcpvegas_info vegas;
+  struct tcp_dctcp_info dctcp;
+/* WARNING: DO NOT EDIT, AUTO-GENERATED CODE - SEE TOP FOR INSTRUCTIONS */
 };
 #endif
-/* WARNING: DO NOT EDIT, AUTO-GENERATED CODE - SEE TOP FOR INSTRUCTIONS */
diff --git a/libc/kernel/uapi/linux/input-event-codes.h b/libc/kernel/uapi/linux/input-event-codes.h
new file mode 100644
index 0000000..3bf47e9
--- /dev/null
+++ b/libc/kernel/uapi/linux/input-event-codes.h
@@ -0,0 +1,865 @@
+/****************************************************************************
+ ****************************************************************************
+ ***
+ ***   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_INPUT_EVENT_CODES_H
+#define _UAPI_INPUT_EVENT_CODES_H
+#define INPUT_PROP_POINTER 0x00
+#define INPUT_PROP_DIRECT 0x01
+/* WARNING: DO NOT EDIT, AUTO-GENERATED CODE - SEE TOP FOR INSTRUCTIONS */
+#define INPUT_PROP_BUTTONPAD 0x02
+#define INPUT_PROP_SEMI_MT 0x03
+#define INPUT_PROP_TOPBUTTONPAD 0x04
+#define INPUT_PROP_POINTING_STICK 0x05
+/* WARNING: DO NOT EDIT, AUTO-GENERATED CODE - SEE TOP FOR INSTRUCTIONS */
+#define INPUT_PROP_ACCELEROMETER 0x06
+#define INPUT_PROP_MAX 0x1f
+#define INPUT_PROP_CNT (INPUT_PROP_MAX + 1)
+#define EV_SYN 0x00
+/* WARNING: DO NOT EDIT, AUTO-GENERATED CODE - SEE TOP FOR INSTRUCTIONS */
+#define EV_KEY 0x01
+#define EV_REL 0x02
+#define EV_ABS 0x03
+#define EV_MSC 0x04
+/* WARNING: DO NOT EDIT, AUTO-GENERATED CODE - SEE TOP FOR INSTRUCTIONS */
+#define EV_SW 0x05
+#define EV_LED 0x11
+#define EV_SND 0x12
+#define EV_REP 0x14
+/* WARNING: DO NOT EDIT, AUTO-GENERATED CODE - SEE TOP FOR INSTRUCTIONS */
+#define EV_FF 0x15
+#define EV_PWR 0x16
+#define EV_FF_STATUS 0x17
+#define EV_MAX 0x1f
+/* WARNING: DO NOT EDIT, AUTO-GENERATED CODE - SEE TOP FOR INSTRUCTIONS */
+#define EV_CNT (EV_MAX + 1)
+#define SYN_REPORT 0
+#define SYN_CONFIG 1
+#define SYN_MT_REPORT 2
+/* WARNING: DO NOT EDIT, AUTO-GENERATED CODE - SEE TOP FOR INSTRUCTIONS */
+#define SYN_DROPPED 3
+#define SYN_MAX 0xf
+#define SYN_CNT (SYN_MAX + 1)
+#define KEY_RESERVED 0
+/* WARNING: DO NOT EDIT, AUTO-GENERATED CODE - SEE TOP FOR INSTRUCTIONS */
+#define KEY_ESC 1
+#define KEY_1 2
+#define KEY_2 3
+#define KEY_3 4
+/* WARNING: DO NOT EDIT, AUTO-GENERATED CODE - SEE TOP FOR INSTRUCTIONS */
+#define KEY_4 5
+#define KEY_5 6
+#define KEY_6 7
+#define KEY_7 8
+/* WARNING: DO NOT EDIT, AUTO-GENERATED CODE - SEE TOP FOR INSTRUCTIONS */
+#define KEY_8 9
+#define KEY_9 10
+#define KEY_0 11
+#define KEY_MINUS 12
+/* WARNING: DO NOT EDIT, AUTO-GENERATED CODE - SEE TOP FOR INSTRUCTIONS */
+#define KEY_EQUAL 13
+#define KEY_BACKSPACE 14
+#define KEY_TAB 15
+#define KEY_Q 16
+/* WARNING: DO NOT EDIT, AUTO-GENERATED CODE - SEE TOP FOR INSTRUCTIONS */
+#define KEY_W 17
+#define KEY_E 18
+#define KEY_R 19
+#define KEY_T 20
+/* WARNING: DO NOT EDIT, AUTO-GENERATED CODE - SEE TOP FOR INSTRUCTIONS */
+#define KEY_Y 21
+#define KEY_U 22
+#define KEY_I 23
+#define KEY_O 24
+/* WARNING: DO NOT EDIT, AUTO-GENERATED CODE - SEE TOP FOR INSTRUCTIONS */
+#define KEY_P 25
+#define KEY_LEFTBRACE 26
+#define KEY_RIGHTBRACE 27
+#define KEY_ENTER 28
+/* WARNING: DO NOT EDIT, AUTO-GENERATED CODE - SEE TOP FOR INSTRUCTIONS */
+#define KEY_LEFTCTRL 29
+#define KEY_A 30
+#define KEY_S 31
+#define KEY_D 32
+/* WARNING: DO NOT EDIT, AUTO-GENERATED CODE - SEE TOP FOR INSTRUCTIONS */
+#define KEY_F 33
+#define KEY_G 34
+#define KEY_H 35
+#define KEY_J 36
+/* WARNING: DO NOT EDIT, AUTO-GENERATED CODE - SEE TOP FOR INSTRUCTIONS */
+#define KEY_K 37
+#define KEY_L 38
+#define KEY_SEMICOLON 39
+#define KEY_APOSTROPHE 40
+/* WARNING: DO NOT EDIT, AUTO-GENERATED CODE - SEE TOP FOR INSTRUCTIONS */
+#define KEY_GRAVE 41
+#define KEY_LEFTSHIFT 42
+#define KEY_BACKSLASH 43
+#define KEY_Z 44
+/* WARNING: DO NOT EDIT, AUTO-GENERATED CODE - SEE TOP FOR INSTRUCTIONS */
+#define KEY_X 45
+#define KEY_C 46
+#define KEY_V 47
+#define KEY_B 48
+/* WARNING: DO NOT EDIT, AUTO-GENERATED CODE - SEE TOP FOR INSTRUCTIONS */
+#define KEY_N 49
+#define KEY_M 50
+#define KEY_COMMA 51
+#define KEY_DOT 52
+/* WARNING: DO NOT EDIT, AUTO-GENERATED CODE - SEE TOP FOR INSTRUCTIONS */
+#define KEY_SLASH 53
+#define KEY_RIGHTSHIFT 54
+#define KEY_KPASTERISK 55
+#define KEY_LEFTALT 56
+/* WARNING: DO NOT EDIT, AUTO-GENERATED CODE - SEE TOP FOR INSTRUCTIONS */
+#define KEY_SPACE 57
+#define KEY_CAPSLOCK 58
+#define KEY_F1 59
+#define KEY_F2 60
+/* WARNING: DO NOT EDIT, AUTO-GENERATED CODE - SEE TOP FOR INSTRUCTIONS */
+#define KEY_F3 61
+#define KEY_F4 62
+#define KEY_F5 63
+#define KEY_F6 64
+/* WARNING: DO NOT EDIT, AUTO-GENERATED CODE - SEE TOP FOR INSTRUCTIONS */
+#define KEY_F7 65
+#define KEY_F8 66
+#define KEY_F9 67
+#define KEY_F10 68
+/* WARNING: DO NOT EDIT, AUTO-GENERATED CODE - SEE TOP FOR INSTRUCTIONS */
+#define KEY_NUMLOCK 69
+#define KEY_SCROLLLOCK 70
+#define KEY_KP7 71
+#define KEY_KP8 72
+/* WARNING: DO NOT EDIT, AUTO-GENERATED CODE - SEE TOP FOR INSTRUCTIONS */
+#define KEY_KP9 73
+#define KEY_KPMINUS 74
+#define KEY_KP4 75
+#define KEY_KP5 76
+/* WARNING: DO NOT EDIT, AUTO-GENERATED CODE - SEE TOP FOR INSTRUCTIONS */
+#define KEY_KP6 77
+#define KEY_KPPLUS 78
+#define KEY_KP1 79
+#define KEY_KP2 80
+/* WARNING: DO NOT EDIT, AUTO-GENERATED CODE - SEE TOP FOR INSTRUCTIONS */
+#define KEY_KP3 81
+#define KEY_KP0 82
+#define KEY_KPDOT 83
+#define KEY_ZENKAKUHANKAKU 85
+/* WARNING: DO NOT EDIT, AUTO-GENERATED CODE - SEE TOP FOR INSTRUCTIONS */
+#define KEY_102ND 86
+#define KEY_F11 87
+#define KEY_F12 88
+#define KEY_RO 89
+/* WARNING: DO NOT EDIT, AUTO-GENERATED CODE - SEE TOP FOR INSTRUCTIONS */
+#define KEY_KATAKANA 90
+#define KEY_HIRAGANA 91
+#define KEY_HENKAN 92
+#define KEY_KATAKANAHIRAGANA 93
+/* WARNING: DO NOT EDIT, AUTO-GENERATED CODE - SEE TOP FOR INSTRUCTIONS */
+#define KEY_MUHENKAN 94
+#define KEY_KPJPCOMMA 95
+#define KEY_KPENTER 96
+#define KEY_RIGHTCTRL 97
+/* WARNING: DO NOT EDIT, AUTO-GENERATED CODE - SEE TOP FOR INSTRUCTIONS */
+#define KEY_KPSLASH 98
+#define KEY_SYSRQ 99
+#define KEY_RIGHTALT 100
+#define KEY_LINEFEED 101
+/* WARNING: DO NOT EDIT, AUTO-GENERATED CODE - SEE TOP FOR INSTRUCTIONS */
+#define KEY_HOME 102
+#define KEY_UP 103
+#define KEY_PAGEUP 104
+#define KEY_LEFT 105
+/* WARNING: DO NOT EDIT, AUTO-GENERATED CODE - SEE TOP FOR INSTRUCTIONS */
+#define KEY_RIGHT 106
+#define KEY_END 107
+#define KEY_DOWN 108
+#define KEY_PAGEDOWN 109
+/* WARNING: DO NOT EDIT, AUTO-GENERATED CODE - SEE TOP FOR INSTRUCTIONS */
+#define KEY_INSERT 110
+#define KEY_DELETE 111
+#define KEY_MACRO 112
+#define KEY_MUTE 113
+/* WARNING: DO NOT EDIT, AUTO-GENERATED CODE - SEE TOP FOR INSTRUCTIONS */
+#define KEY_VOLUMEDOWN 114
+#define KEY_VOLUMEUP 115
+#define KEY_POWER 116
+#define KEY_KPEQUAL 117
+/* WARNING: DO NOT EDIT, AUTO-GENERATED CODE - SEE TOP FOR INSTRUCTIONS */
+#define KEY_KPPLUSMINUS 118
+#define KEY_PAUSE 119
+#define KEY_SCALE 120
+#define KEY_KPCOMMA 121
+/* WARNING: DO NOT EDIT, AUTO-GENERATED CODE - SEE TOP FOR INSTRUCTIONS */
+#define KEY_HANGEUL 122
+#define KEY_HANGUEL KEY_HANGEUL
+#define KEY_HANJA 123
+#define KEY_YEN 124
+/* WARNING: DO NOT EDIT, AUTO-GENERATED CODE - SEE TOP FOR INSTRUCTIONS */
+#define KEY_LEFTMETA 125
+#define KEY_RIGHTMETA 126
+#define KEY_COMPOSE 127
+#define KEY_STOP 128
+/* WARNING: DO NOT EDIT, AUTO-GENERATED CODE - SEE TOP FOR INSTRUCTIONS */
+#define KEY_AGAIN 129
+#define KEY_PROPS 130
+#define KEY_UNDO 131
+#define KEY_FRONT 132
+/* WARNING: DO NOT EDIT, AUTO-GENERATED CODE - SEE TOP FOR INSTRUCTIONS */
+#define KEY_COPY 133
+#define KEY_OPEN 134
+#define KEY_PASTE 135
+#define KEY_FIND 136
+/* WARNING: DO NOT EDIT, AUTO-GENERATED CODE - SEE TOP FOR INSTRUCTIONS */
+#define KEY_CUT 137
+#define KEY_HELP 138
+#define KEY_MENU 139
+#define KEY_CALC 140
+/* WARNING: DO NOT EDIT, AUTO-GENERATED CODE - SEE TOP FOR INSTRUCTIONS */
+#define KEY_SETUP 141
+#define KEY_SLEEP 142
+#define KEY_WAKEUP 143
+#define KEY_FILE 144
+/* WARNING: DO NOT EDIT, AUTO-GENERATED CODE - SEE TOP FOR INSTRUCTIONS */
+#define KEY_SENDFILE 145
+#define KEY_DELETEFILE 146
+#define KEY_XFER 147
+#define KEY_PROG1 148
+/* WARNING: DO NOT EDIT, AUTO-GENERATED CODE - SEE TOP FOR INSTRUCTIONS */
+#define KEY_PROG2 149
+#define KEY_WWW 150
+#define KEY_MSDOS 151
+#define KEY_COFFEE 152
+/* WARNING: DO NOT EDIT, AUTO-GENERATED CODE - SEE TOP FOR INSTRUCTIONS */
+#define KEY_SCREENLOCK KEY_COFFEE
+#define KEY_ROTATE_DISPLAY 153
+#define KEY_DIRECTION KEY_ROTATE_DISPLAY
+#define KEY_CYCLEWINDOWS 154
+/* WARNING: DO NOT EDIT, AUTO-GENERATED CODE - SEE TOP FOR INSTRUCTIONS */
+#define KEY_MAIL 155
+#define KEY_BOOKMARKS 156
+#define KEY_COMPUTER 157
+#define KEY_BACK 158
+/* WARNING: DO NOT EDIT, AUTO-GENERATED CODE - SEE TOP FOR INSTRUCTIONS */
+#define KEY_FORWARD 159
+#define KEY_CLOSECD 160
+#define KEY_EJECTCD 161
+#define KEY_EJECTCLOSECD 162
+/* WARNING: DO NOT EDIT, AUTO-GENERATED CODE - SEE TOP FOR INSTRUCTIONS */
+#define KEY_NEXTSONG 163
+#define KEY_PLAYPAUSE 164
+#define KEY_PREVIOUSSONG 165
+#define KEY_STOPCD 166
+/* WARNING: DO NOT EDIT, AUTO-GENERATED CODE - SEE TOP FOR INSTRUCTIONS */
+#define KEY_RECORD 167
+#define KEY_REWIND 168
+#define KEY_PHONE 169
+#define KEY_ISO 170
+/* WARNING: DO NOT EDIT, AUTO-GENERATED CODE - SEE TOP FOR INSTRUCTIONS */
+#define KEY_CONFIG 171
+#define KEY_HOMEPAGE 172
+#define KEY_REFRESH 173
+#define KEY_EXIT 174
+/* WARNING: DO NOT EDIT, AUTO-GENERATED CODE - SEE TOP FOR INSTRUCTIONS */
+#define KEY_MOVE 175
+#define KEY_EDIT 176
+#define KEY_SCROLLUP 177
+#define KEY_SCROLLDOWN 178
+/* WARNING: DO NOT EDIT, AUTO-GENERATED CODE - SEE TOP FOR INSTRUCTIONS */
+#define KEY_KPLEFTPAREN 179
+#define KEY_KPRIGHTPAREN 180
+#define KEY_NEW 181
+#define KEY_REDO 182
+/* WARNING: DO NOT EDIT, AUTO-GENERATED CODE - SEE TOP FOR INSTRUCTIONS */
+#define KEY_F13 183
+#define KEY_F14 184
+#define KEY_F15 185
+#define KEY_F16 186
+/* WARNING: DO NOT EDIT, AUTO-GENERATED CODE - SEE TOP FOR INSTRUCTIONS */
+#define KEY_F17 187
+#define KEY_F18 188
+#define KEY_F19 189
+#define KEY_F20 190
+/* WARNING: DO NOT EDIT, AUTO-GENERATED CODE - SEE TOP FOR INSTRUCTIONS */
+#define KEY_F21 191
+#define KEY_F22 192
+#define KEY_F23 193
+#define KEY_F24 194
+/* WARNING: DO NOT EDIT, AUTO-GENERATED CODE - SEE TOP FOR INSTRUCTIONS */
+#define KEY_PLAYCD 200
+#define KEY_PAUSECD 201
+#define KEY_PROG3 202
+#define KEY_PROG4 203
+/* WARNING: DO NOT EDIT, AUTO-GENERATED CODE - SEE TOP FOR INSTRUCTIONS */
+#define KEY_DASHBOARD 204
+#define KEY_SUSPEND 205
+#define KEY_CLOSE 206
+#define KEY_PLAY 207
+/* WARNING: DO NOT EDIT, AUTO-GENERATED CODE - SEE TOP FOR INSTRUCTIONS */
+#define KEY_FASTFORWARD 208
+#define KEY_BASSBOOST 209
+#define KEY_PRINT 210
+#define KEY_HP 211
+/* WARNING: DO NOT EDIT, AUTO-GENERATED CODE - SEE TOP FOR INSTRUCTIONS */
+#define KEY_CAMERA 212
+#define KEY_SOUND 213
+#define KEY_QUESTION 214
+#define KEY_EMAIL 215
+/* WARNING: DO NOT EDIT, AUTO-GENERATED CODE - SEE TOP FOR INSTRUCTIONS */
+#define KEY_CHAT 216
+#define KEY_SEARCH 217
+#define KEY_CONNECT 218
+#define KEY_FINANCE 219
+/* WARNING: DO NOT EDIT, AUTO-GENERATED CODE - SEE TOP FOR INSTRUCTIONS */
+#define KEY_SPORT 220
+#define KEY_SHOP 221
+#define KEY_ALTERASE 222
+#define KEY_CANCEL 223
+/* WARNING: DO NOT EDIT, AUTO-GENERATED CODE - SEE TOP FOR INSTRUCTIONS */
+#define KEY_BRIGHTNESSDOWN 224
+#define KEY_BRIGHTNESSUP 225
+#define KEY_MEDIA 226
+#define KEY_SWITCHVIDEOMODE 227
+/* WARNING: DO NOT EDIT, AUTO-GENERATED CODE - SEE TOP FOR INSTRUCTIONS */
+#define KEY_KBDILLUMTOGGLE 228
+#define KEY_KBDILLUMDOWN 229
+#define KEY_KBDILLUMUP 230
+#define KEY_SEND 231
+/* WARNING: DO NOT EDIT, AUTO-GENERATED CODE - SEE TOP FOR INSTRUCTIONS */
+#define KEY_REPLY 232
+#define KEY_FORWARDMAIL 233
+#define KEY_SAVE 234
+#define KEY_DOCUMENTS 235
+/* WARNING: DO NOT EDIT, AUTO-GENERATED CODE - SEE TOP FOR INSTRUCTIONS */
+#define KEY_BATTERY 236
+#define KEY_BLUETOOTH 237
+#define KEY_WLAN 238
+#define KEY_UWB 239
+/* WARNING: DO NOT EDIT, AUTO-GENERATED CODE - SEE TOP FOR INSTRUCTIONS */
+#define KEY_UNKNOWN 240
+#define KEY_VIDEO_NEXT 241
+#define KEY_VIDEO_PREV 242
+#define KEY_BRIGHTNESS_CYCLE 243
+/* WARNING: DO NOT EDIT, AUTO-GENERATED CODE - SEE TOP FOR INSTRUCTIONS */
+#define KEY_BRIGHTNESS_AUTO 244
+#define KEY_BRIGHTNESS_ZERO KEY_BRIGHTNESS_AUTO
+#define KEY_DISPLAY_OFF 245
+#define KEY_WWAN 246
+/* WARNING: DO NOT EDIT, AUTO-GENERATED CODE - SEE TOP FOR INSTRUCTIONS */
+#define KEY_WIMAX KEY_WWAN
+#define KEY_RFKILL 247
+#define KEY_MICMUTE 248
+#define BTN_MISC 0x100
+/* WARNING: DO NOT EDIT, AUTO-GENERATED CODE - SEE TOP FOR INSTRUCTIONS */
+#define BTN_0 0x100
+#define BTN_1 0x101
+#define BTN_2 0x102
+#define BTN_3 0x103
+/* WARNING: DO NOT EDIT, AUTO-GENERATED CODE - SEE TOP FOR INSTRUCTIONS */
+#define BTN_4 0x104
+#define BTN_5 0x105
+#define BTN_6 0x106
+#define BTN_7 0x107
+/* WARNING: DO NOT EDIT, AUTO-GENERATED CODE - SEE TOP FOR INSTRUCTIONS */
+#define BTN_8 0x108
+#define BTN_9 0x109
+#define BTN_MOUSE 0x110
+#define BTN_LEFT 0x110
+/* WARNING: DO NOT EDIT, AUTO-GENERATED CODE - SEE TOP FOR INSTRUCTIONS */
+#define BTN_RIGHT 0x111
+#define BTN_MIDDLE 0x112
+#define BTN_SIDE 0x113
+#define BTN_EXTRA 0x114
+/* WARNING: DO NOT EDIT, AUTO-GENERATED CODE - SEE TOP FOR INSTRUCTIONS */
+#define BTN_FORWARD 0x115
+#define BTN_BACK 0x116
+#define BTN_TASK 0x117
+#define BTN_JOYSTICK 0x120
+/* WARNING: DO NOT EDIT, AUTO-GENERATED CODE - SEE TOP FOR INSTRUCTIONS */
+#define BTN_TRIGGER 0x120
+#define BTN_THUMB 0x121
+#define BTN_THUMB2 0x122
+#define BTN_TOP 0x123
+/* WARNING: DO NOT EDIT, AUTO-GENERATED CODE - SEE TOP FOR INSTRUCTIONS */
+#define BTN_TOP2 0x124
+#define BTN_PINKIE 0x125
+#define BTN_BASE 0x126
+#define BTN_BASE2 0x127
+/* WARNING: DO NOT EDIT, AUTO-GENERATED CODE - SEE TOP FOR INSTRUCTIONS */
+#define BTN_BASE3 0x128
+#define BTN_BASE4 0x129
+#define BTN_BASE5 0x12a
+#define BTN_BASE6 0x12b
+/* WARNING: DO NOT EDIT, AUTO-GENERATED CODE - SEE TOP FOR INSTRUCTIONS */
+#define BTN_DEAD 0x12f
+#define BTN_GAMEPAD 0x130
+#define BTN_SOUTH 0x130
+#define BTN_A BTN_SOUTH
+/* WARNING: DO NOT EDIT, AUTO-GENERATED CODE - SEE TOP FOR INSTRUCTIONS */
+#define BTN_EAST 0x131
+#define BTN_B BTN_EAST
+#define BTN_C 0x132
+#define BTN_NORTH 0x133
+/* WARNING: DO NOT EDIT, AUTO-GENERATED CODE - SEE TOP FOR INSTRUCTIONS */
+#define BTN_X BTN_NORTH
+#define BTN_WEST 0x134
+#define BTN_Y BTN_WEST
+#define BTN_Z 0x135
+/* WARNING: DO NOT EDIT, AUTO-GENERATED CODE - SEE TOP FOR INSTRUCTIONS */
+#define BTN_TL 0x136
+#define BTN_TR 0x137
+#define BTN_TL2 0x138
+#define BTN_TR2 0x139
+/* WARNING: DO NOT EDIT, AUTO-GENERATED CODE - SEE TOP FOR INSTRUCTIONS */
+#define BTN_SELECT 0x13a
+#define BTN_START 0x13b
+#define BTN_MODE 0x13c
+#define BTN_THUMBL 0x13d
+/* WARNING: DO NOT EDIT, AUTO-GENERATED CODE - SEE TOP FOR INSTRUCTIONS */
+#define BTN_THUMBR 0x13e
+#define BTN_DIGI 0x140
+#define BTN_TOOL_PEN 0x140
+#define BTN_TOOL_RUBBER 0x141
+/* WARNING: DO NOT EDIT, AUTO-GENERATED CODE - SEE TOP FOR INSTRUCTIONS */
+#define BTN_TOOL_BRUSH 0x142
+#define BTN_TOOL_PENCIL 0x143
+#define BTN_TOOL_AIRBRUSH 0x144
+#define BTN_TOOL_FINGER 0x145
+/* WARNING: DO NOT EDIT, AUTO-GENERATED CODE - SEE TOP FOR INSTRUCTIONS */
+#define BTN_TOOL_MOUSE 0x146
+#define BTN_TOOL_LENS 0x147
+#define BTN_TOOL_QUINTTAP 0x148
+#define BTN_TOUCH 0x14a
+/* WARNING: DO NOT EDIT, AUTO-GENERATED CODE - SEE TOP FOR INSTRUCTIONS */
+#define BTN_STYLUS 0x14b
+#define BTN_STYLUS2 0x14c
+#define BTN_TOOL_DOUBLETAP 0x14d
+#define BTN_TOOL_TRIPLETAP 0x14e
+/* WARNING: DO NOT EDIT, AUTO-GENERATED CODE - SEE TOP FOR INSTRUCTIONS */
+#define BTN_TOOL_QUADTAP 0x14f
+#define BTN_WHEEL 0x150
+#define BTN_GEAR_DOWN 0x150
+#define BTN_GEAR_UP 0x151
+/* WARNING: DO NOT EDIT, AUTO-GENERATED CODE - SEE TOP FOR INSTRUCTIONS */
+#define KEY_OK 0x160
+#define KEY_SELECT 0x161
+#define KEY_GOTO 0x162
+#define KEY_CLEAR 0x163
+/* WARNING: DO NOT EDIT, AUTO-GENERATED CODE - SEE TOP FOR INSTRUCTIONS */
+#define KEY_POWER2 0x164
+#define KEY_OPTION 0x165
+#define KEY_INFO 0x166
+#define KEY_TIME 0x167
+/* WARNING: DO NOT EDIT, AUTO-GENERATED CODE - SEE TOP FOR INSTRUCTIONS */
+#define KEY_VENDOR 0x168
+#define KEY_ARCHIVE 0x169
+#define KEY_PROGRAM 0x16a
+#define KEY_CHANNEL 0x16b
+/* WARNING: DO NOT EDIT, AUTO-GENERATED CODE - SEE TOP FOR INSTRUCTIONS */
+#define KEY_FAVORITES 0x16c
+#define KEY_EPG 0x16d
+#define KEY_PVR 0x16e
+#define KEY_MHP 0x16f
+/* WARNING: DO NOT EDIT, AUTO-GENERATED CODE - SEE TOP FOR INSTRUCTIONS */
+#define KEY_LANGUAGE 0x170
+#define KEY_TITLE 0x171
+#define KEY_SUBTITLE 0x172
+#define KEY_ANGLE 0x173
+/* WARNING: DO NOT EDIT, AUTO-GENERATED CODE - SEE TOP FOR INSTRUCTIONS */
+#define KEY_ZOOM 0x174
+#define KEY_MODE 0x175
+#define KEY_KEYBOARD 0x176
+#define KEY_SCREEN 0x177
+/* WARNING: DO NOT EDIT, AUTO-GENERATED CODE - SEE TOP FOR INSTRUCTIONS */
+#define KEY_PC 0x178
+#define KEY_TV 0x179
+#define KEY_TV2 0x17a
+#define KEY_VCR 0x17b
+/* WARNING: DO NOT EDIT, AUTO-GENERATED CODE - SEE TOP FOR INSTRUCTIONS */
+#define KEY_VCR2 0x17c
+#define KEY_SAT 0x17d
+#define KEY_SAT2 0x17e
+#define KEY_CD 0x17f
+/* WARNING: DO NOT EDIT, AUTO-GENERATED CODE - SEE TOP FOR INSTRUCTIONS */
+#define KEY_TAPE 0x180
+#define KEY_RADIO 0x181
+#define KEY_TUNER 0x182
+#define KEY_PLAYER 0x183
+/* WARNING: DO NOT EDIT, AUTO-GENERATED CODE - SEE TOP FOR INSTRUCTIONS */
+#define KEY_TEXT 0x184
+#define KEY_DVD 0x185
+#define KEY_AUX 0x186
+#define KEY_MP3 0x187
+/* WARNING: DO NOT EDIT, AUTO-GENERATED CODE - SEE TOP FOR INSTRUCTIONS */
+#define KEY_AUDIO 0x188
+#define KEY_VIDEO 0x189
+#define KEY_DIRECTORY 0x18a
+#define KEY_LIST 0x18b
+/* WARNING: DO NOT EDIT, AUTO-GENERATED CODE - SEE TOP FOR INSTRUCTIONS */
+#define KEY_MEMO 0x18c
+#define KEY_CALENDAR 0x18d
+#define KEY_RED 0x18e
+#define KEY_GREEN 0x18f
+/* WARNING: DO NOT EDIT, AUTO-GENERATED CODE - SEE TOP FOR INSTRUCTIONS */
+#define KEY_YELLOW 0x190
+#define KEY_BLUE 0x191
+#define KEY_CHANNELUP 0x192
+#define KEY_CHANNELDOWN 0x193
+/* WARNING: DO NOT EDIT, AUTO-GENERATED CODE - SEE TOP FOR INSTRUCTIONS */
+#define KEY_FIRST 0x194
+#define KEY_LAST 0x195
+#define KEY_AB 0x196
+#define KEY_NEXT 0x197
+/* WARNING: DO NOT EDIT, AUTO-GENERATED CODE - SEE TOP FOR INSTRUCTIONS */
+#define KEY_RESTART 0x198
+#define KEY_SLOW 0x199
+#define KEY_SHUFFLE 0x19a
+#define KEY_BREAK 0x19b
+/* WARNING: DO NOT EDIT, AUTO-GENERATED CODE - SEE TOP FOR INSTRUCTIONS */
+#define KEY_PREVIOUS 0x19c
+#define KEY_DIGITS 0x19d
+#define KEY_TEEN 0x19e
+#define KEY_TWEN 0x19f
+/* WARNING: DO NOT EDIT, AUTO-GENERATED CODE - SEE TOP FOR INSTRUCTIONS */
+#define KEY_VIDEOPHONE 0x1a0
+#define KEY_GAMES 0x1a1
+#define KEY_ZOOMIN 0x1a2
+#define KEY_ZOOMOUT 0x1a3
+/* WARNING: DO NOT EDIT, AUTO-GENERATED CODE - SEE TOP FOR INSTRUCTIONS */
+#define KEY_ZOOMRESET 0x1a4
+#define KEY_WORDPROCESSOR 0x1a5
+#define KEY_EDITOR 0x1a6
+#define KEY_SPREADSHEET 0x1a7
+/* WARNING: DO NOT EDIT, AUTO-GENERATED CODE - SEE TOP FOR INSTRUCTIONS */
+#define KEY_GRAPHICSEDITOR 0x1a8
+#define KEY_PRESENTATION 0x1a9
+#define KEY_DATABASE 0x1aa
+#define KEY_NEWS 0x1ab
+/* WARNING: DO NOT EDIT, AUTO-GENERATED CODE - SEE TOP FOR INSTRUCTIONS */
+#define KEY_VOICEMAIL 0x1ac
+#define KEY_ADDRESSBOOK 0x1ad
+#define KEY_MESSENGER 0x1ae
+#define KEY_DISPLAYTOGGLE 0x1af
+/* WARNING: DO NOT EDIT, AUTO-GENERATED CODE - SEE TOP FOR INSTRUCTIONS */
+#define KEY_BRIGHTNESS_TOGGLE KEY_DISPLAYTOGGLE
+#define KEY_SPELLCHECK 0x1b0
+#define KEY_LOGOFF 0x1b1
+#define KEY_DOLLAR 0x1b2
+/* WARNING: DO NOT EDIT, AUTO-GENERATED CODE - SEE TOP FOR INSTRUCTIONS */
+#define KEY_EURO 0x1b3
+#define KEY_FRAMEBACK 0x1b4
+#define KEY_FRAMEFORWARD 0x1b5
+#define KEY_CONTEXT_MENU 0x1b6
+/* WARNING: DO NOT EDIT, AUTO-GENERATED CODE - SEE TOP FOR INSTRUCTIONS */
+#define KEY_MEDIA_REPEAT 0x1b7
+#define KEY_10CHANNELSUP 0x1b8
+#define KEY_10CHANNELSDOWN 0x1b9
+#define KEY_IMAGES 0x1ba
+/* WARNING: DO NOT EDIT, AUTO-GENERATED CODE - SEE TOP FOR INSTRUCTIONS */
+#define KEY_DEL_EOL 0x1c0
+#define KEY_DEL_EOS 0x1c1
+#define KEY_INS_LINE 0x1c2
+#define KEY_DEL_LINE 0x1c3
+/* WARNING: DO NOT EDIT, AUTO-GENERATED CODE - SEE TOP FOR INSTRUCTIONS */
+#define KEY_FN 0x1d0
+#define KEY_FN_ESC 0x1d1
+#define KEY_FN_F1 0x1d2
+#define KEY_FN_F2 0x1d3
+/* WARNING: DO NOT EDIT, AUTO-GENERATED CODE - SEE TOP FOR INSTRUCTIONS */
+#define KEY_FN_F3 0x1d4
+#define KEY_FN_F4 0x1d5
+#define KEY_FN_F5 0x1d6
+#define KEY_FN_F6 0x1d7
+/* WARNING: DO NOT EDIT, AUTO-GENERATED CODE - SEE TOP FOR INSTRUCTIONS */
+#define KEY_FN_F7 0x1d8
+#define KEY_FN_F8 0x1d9
+#define KEY_FN_F9 0x1da
+#define KEY_FN_F10 0x1db
+/* WARNING: DO NOT EDIT, AUTO-GENERATED CODE - SEE TOP FOR INSTRUCTIONS */
+#define KEY_FN_F11 0x1dc
+#define KEY_FN_F12 0x1dd
+#define KEY_FN_1 0x1de
+#define KEY_FN_2 0x1df
+/* WARNING: DO NOT EDIT, AUTO-GENERATED CODE - SEE TOP FOR INSTRUCTIONS */
+#define KEY_FN_D 0x1e0
+#define KEY_FN_E 0x1e1
+#define KEY_FN_F 0x1e2
+#define KEY_FN_S 0x1e3
+/* WARNING: DO NOT EDIT, AUTO-GENERATED CODE - SEE TOP FOR INSTRUCTIONS */
+#define KEY_FN_B 0x1e4
+#define KEY_BRL_DOT1 0x1f1
+#define KEY_BRL_DOT2 0x1f2
+#define KEY_BRL_DOT3 0x1f3
+/* WARNING: DO NOT EDIT, AUTO-GENERATED CODE - SEE TOP FOR INSTRUCTIONS */
+#define KEY_BRL_DOT4 0x1f4
+#define KEY_BRL_DOT5 0x1f5
+#define KEY_BRL_DOT6 0x1f6
+#define KEY_BRL_DOT7 0x1f7
+/* WARNING: DO NOT EDIT, AUTO-GENERATED CODE - SEE TOP FOR INSTRUCTIONS */
+#define KEY_BRL_DOT8 0x1f8
+#define KEY_BRL_DOT9 0x1f9
+#define KEY_BRL_DOT10 0x1fa
+#define KEY_NUMERIC_0 0x200
+/* WARNING: DO NOT EDIT, AUTO-GENERATED CODE - SEE TOP FOR INSTRUCTIONS */
+#define KEY_NUMERIC_1 0x201
+#define KEY_NUMERIC_2 0x202
+#define KEY_NUMERIC_3 0x203
+#define KEY_NUMERIC_4 0x204
+/* WARNING: DO NOT EDIT, AUTO-GENERATED CODE - SEE TOP FOR INSTRUCTIONS */
+#define KEY_NUMERIC_5 0x205
+#define KEY_NUMERIC_6 0x206
+#define KEY_NUMERIC_7 0x207
+#define KEY_NUMERIC_8 0x208
+/* WARNING: DO NOT EDIT, AUTO-GENERATED CODE - SEE TOP FOR INSTRUCTIONS */
+#define KEY_NUMERIC_9 0x209
+#define KEY_NUMERIC_STAR 0x20a
+#define KEY_NUMERIC_POUND 0x20b
+#define KEY_NUMERIC_A 0x20c
+/* WARNING: DO NOT EDIT, AUTO-GENERATED CODE - SEE TOP FOR INSTRUCTIONS */
+#define KEY_NUMERIC_B 0x20d
+#define KEY_NUMERIC_C 0x20e
+#define KEY_NUMERIC_D 0x20f
+#define KEY_CAMERA_FOCUS 0x210
+/* WARNING: DO NOT EDIT, AUTO-GENERATED CODE - SEE TOP FOR INSTRUCTIONS */
+#define KEY_WPS_BUTTON 0x211
+#define KEY_TOUCHPAD_TOGGLE 0x212
+#define KEY_TOUCHPAD_ON 0x213
+#define KEY_TOUCHPAD_OFF 0x214
+/* WARNING: DO NOT EDIT, AUTO-GENERATED CODE - SEE TOP FOR INSTRUCTIONS */
+#define KEY_CAMERA_ZOOMIN 0x215
+#define KEY_CAMERA_ZOOMOUT 0x216
+#define KEY_CAMERA_UP 0x217
+#define KEY_CAMERA_DOWN 0x218
+/* WARNING: DO NOT EDIT, AUTO-GENERATED CODE - SEE TOP FOR INSTRUCTIONS */
+#define KEY_CAMERA_LEFT 0x219
+#define KEY_CAMERA_RIGHT 0x21a
+#define KEY_ATTENDANT_ON 0x21b
+#define KEY_ATTENDANT_OFF 0x21c
+/* WARNING: DO NOT EDIT, AUTO-GENERATED CODE - SEE TOP FOR INSTRUCTIONS */
+#define KEY_ATTENDANT_TOGGLE 0x21d
+#define KEY_LIGHTS_TOGGLE 0x21e
+#define BTN_DPAD_UP 0x220
+#define BTN_DPAD_DOWN 0x221
+/* WARNING: DO NOT EDIT, AUTO-GENERATED CODE - SEE TOP FOR INSTRUCTIONS */
+#define BTN_DPAD_LEFT 0x222
+#define BTN_DPAD_RIGHT 0x223
+#define KEY_ALS_TOGGLE 0x230
+#define KEY_BUTTONCONFIG 0x240
+/* WARNING: DO NOT EDIT, AUTO-GENERATED CODE - SEE TOP FOR INSTRUCTIONS */
+#define KEY_TASKMANAGER 0x241
+#define KEY_JOURNAL 0x242
+#define KEY_CONTROLPANEL 0x243
+#define KEY_APPSELECT 0x244
+/* WARNING: DO NOT EDIT, AUTO-GENERATED CODE - SEE TOP FOR INSTRUCTIONS */
+#define KEY_SCREENSAVER 0x245
+#define KEY_VOICECOMMAND 0x246
+#define KEY_BRIGHTNESS_MIN 0x250
+#define KEY_BRIGHTNESS_MAX 0x251
+/* WARNING: DO NOT EDIT, AUTO-GENERATED CODE - SEE TOP FOR INSTRUCTIONS */
+#define KEY_KBDINPUTASSIST_PREV 0x260
+#define KEY_KBDINPUTASSIST_NEXT 0x261
+#define KEY_KBDINPUTASSIST_PREVGROUP 0x262
+#define KEY_KBDINPUTASSIST_NEXTGROUP 0x263
+/* WARNING: DO NOT EDIT, AUTO-GENERATED CODE - SEE TOP FOR INSTRUCTIONS */
+#define KEY_KBDINPUTASSIST_ACCEPT 0x264
+#define KEY_KBDINPUTASSIST_CANCEL 0x265
+#define BTN_TRIGGER_HAPPY 0x2c0
+#define BTN_TRIGGER_HAPPY1 0x2c0
+/* WARNING: DO NOT EDIT, AUTO-GENERATED CODE - SEE TOP FOR INSTRUCTIONS */
+#define BTN_TRIGGER_HAPPY2 0x2c1
+#define BTN_TRIGGER_HAPPY3 0x2c2
+#define BTN_TRIGGER_HAPPY4 0x2c3
+#define BTN_TRIGGER_HAPPY5 0x2c4
+/* WARNING: DO NOT EDIT, AUTO-GENERATED CODE - SEE TOP FOR INSTRUCTIONS */
+#define BTN_TRIGGER_HAPPY6 0x2c5
+#define BTN_TRIGGER_HAPPY7 0x2c6
+#define BTN_TRIGGER_HAPPY8 0x2c7
+#define BTN_TRIGGER_HAPPY9 0x2c8
+/* WARNING: DO NOT EDIT, AUTO-GENERATED CODE - SEE TOP FOR INSTRUCTIONS */
+#define BTN_TRIGGER_HAPPY10 0x2c9
+#define BTN_TRIGGER_HAPPY11 0x2ca
+#define BTN_TRIGGER_HAPPY12 0x2cb
+#define BTN_TRIGGER_HAPPY13 0x2cc
+/* WARNING: DO NOT EDIT, AUTO-GENERATED CODE - SEE TOP FOR INSTRUCTIONS */
+#define BTN_TRIGGER_HAPPY14 0x2cd
+#define BTN_TRIGGER_HAPPY15 0x2ce
+#define BTN_TRIGGER_HAPPY16 0x2cf
+#define BTN_TRIGGER_HAPPY17 0x2d0
+/* WARNING: DO NOT EDIT, AUTO-GENERATED CODE - SEE TOP FOR INSTRUCTIONS */
+#define BTN_TRIGGER_HAPPY18 0x2d1
+#define BTN_TRIGGER_HAPPY19 0x2d2
+#define BTN_TRIGGER_HAPPY20 0x2d3
+#define BTN_TRIGGER_HAPPY21 0x2d4
+/* WARNING: DO NOT EDIT, AUTO-GENERATED CODE - SEE TOP FOR INSTRUCTIONS */
+#define BTN_TRIGGER_HAPPY22 0x2d5
+#define BTN_TRIGGER_HAPPY23 0x2d6
+#define BTN_TRIGGER_HAPPY24 0x2d7
+#define BTN_TRIGGER_HAPPY25 0x2d8
+/* WARNING: DO NOT EDIT, AUTO-GENERATED CODE - SEE TOP FOR INSTRUCTIONS */
+#define BTN_TRIGGER_HAPPY26 0x2d9
+#define BTN_TRIGGER_HAPPY27 0x2da
+#define BTN_TRIGGER_HAPPY28 0x2db
+#define BTN_TRIGGER_HAPPY29 0x2dc
+/* WARNING: DO NOT EDIT, AUTO-GENERATED CODE - SEE TOP FOR INSTRUCTIONS */
+#define BTN_TRIGGER_HAPPY30 0x2dd
+#define BTN_TRIGGER_HAPPY31 0x2de
+#define BTN_TRIGGER_HAPPY32 0x2df
+#define BTN_TRIGGER_HAPPY33 0x2e0
+/* WARNING: DO NOT EDIT, AUTO-GENERATED CODE - SEE TOP FOR INSTRUCTIONS */
+#define BTN_TRIGGER_HAPPY34 0x2e1
+#define BTN_TRIGGER_HAPPY35 0x2e2
+#define BTN_TRIGGER_HAPPY36 0x2e3
+#define BTN_TRIGGER_HAPPY37 0x2e4
+/* WARNING: DO NOT EDIT, AUTO-GENERATED CODE - SEE TOP FOR INSTRUCTIONS */
+#define BTN_TRIGGER_HAPPY38 0x2e5
+#define BTN_TRIGGER_HAPPY39 0x2e6
+#define BTN_TRIGGER_HAPPY40 0x2e7
+#define KEY_MIN_INTERESTING KEY_MUTE
+/* WARNING: DO NOT EDIT, AUTO-GENERATED CODE - SEE TOP FOR INSTRUCTIONS */
+#define KEY_MAX 0x2ff
+#define KEY_CNT (KEY_MAX + 1)
+#define REL_X 0x00
+#define REL_Y 0x01
+/* WARNING: DO NOT EDIT, AUTO-GENERATED CODE - SEE TOP FOR INSTRUCTIONS */
+#define REL_Z 0x02
+#define REL_RX 0x03
+#define REL_RY 0x04
+#define REL_RZ 0x05
+/* WARNING: DO NOT EDIT, AUTO-GENERATED CODE - SEE TOP FOR INSTRUCTIONS */
+#define REL_HWHEEL 0x06
+#define REL_DIAL 0x07
+#define REL_WHEEL 0x08
+#define REL_MISC 0x09
+/* WARNING: DO NOT EDIT, AUTO-GENERATED CODE - SEE TOP FOR INSTRUCTIONS */
+#define REL_MAX 0x0f
+#define REL_CNT (REL_MAX + 1)
+#define ABS_X 0x00
+#define ABS_Y 0x01
+/* WARNING: DO NOT EDIT, AUTO-GENERATED CODE - SEE TOP FOR INSTRUCTIONS */
+#define ABS_Z 0x02
+#define ABS_RX 0x03
+#define ABS_RY 0x04
+#define ABS_RZ 0x05
+/* WARNING: DO NOT EDIT, AUTO-GENERATED CODE - SEE TOP FOR INSTRUCTIONS */
+#define ABS_THROTTLE 0x06
+#define ABS_RUDDER 0x07
+#define ABS_WHEEL 0x08
+#define ABS_GAS 0x09
+/* WARNING: DO NOT EDIT, AUTO-GENERATED CODE - SEE TOP FOR INSTRUCTIONS */
+#define ABS_BRAKE 0x0a
+#define ABS_HAT0X 0x10
+#define ABS_HAT0Y 0x11
+#define ABS_HAT1X 0x12
+/* WARNING: DO NOT EDIT, AUTO-GENERATED CODE - SEE TOP FOR INSTRUCTIONS */
+#define ABS_HAT1Y 0x13
+#define ABS_HAT2X 0x14
+#define ABS_HAT2Y 0x15
+#define ABS_HAT3X 0x16
+/* WARNING: DO NOT EDIT, AUTO-GENERATED CODE - SEE TOP FOR INSTRUCTIONS */
+#define ABS_HAT3Y 0x17
+#define ABS_PRESSURE 0x18
+#define ABS_DISTANCE 0x19
+#define ABS_TILT_X 0x1a
+/* WARNING: DO NOT EDIT, AUTO-GENERATED CODE - SEE TOP FOR INSTRUCTIONS */
+#define ABS_TILT_Y 0x1b
+#define ABS_TOOL_WIDTH 0x1c
+#define ABS_VOLUME 0x20
+#define ABS_MISC 0x28
+/* WARNING: DO NOT EDIT, AUTO-GENERATED CODE - SEE TOP FOR INSTRUCTIONS */
+#define ABS_MT_SLOT 0x2f
+#define ABS_MT_TOUCH_MAJOR 0x30
+#define ABS_MT_TOUCH_MINOR 0x31
+#define ABS_MT_WIDTH_MAJOR 0x32
+/* WARNING: DO NOT EDIT, AUTO-GENERATED CODE - SEE TOP FOR INSTRUCTIONS */
+#define ABS_MT_WIDTH_MINOR 0x33
+#define ABS_MT_ORIENTATION 0x34
+#define ABS_MT_POSITION_X 0x35
+#define ABS_MT_POSITION_Y 0x36
+/* WARNING: DO NOT EDIT, AUTO-GENERATED CODE - SEE TOP FOR INSTRUCTIONS */
+#define ABS_MT_TOOL_TYPE 0x37
+#define ABS_MT_BLOB_ID 0x38
+#define ABS_MT_TRACKING_ID 0x39
+#define ABS_MT_PRESSURE 0x3a
+/* WARNING: DO NOT EDIT, AUTO-GENERATED CODE - SEE TOP FOR INSTRUCTIONS */
+#define ABS_MT_DISTANCE 0x3b
+#define ABS_MT_TOOL_X 0x3c
+#define ABS_MT_TOOL_Y 0x3d
+#define ABS_MAX 0x3f
+/* WARNING: DO NOT EDIT, AUTO-GENERATED CODE - SEE TOP FOR INSTRUCTIONS */
+#define ABS_CNT (ABS_MAX + 1)
+#define SW_LID 0x00
+#define SW_TABLET_MODE 0x01
+#define SW_HEADPHONE_INSERT 0x02
+/* WARNING: DO NOT EDIT, AUTO-GENERATED CODE - SEE TOP FOR INSTRUCTIONS */
+#define SW_RFKILL_ALL 0x03
+#define SW_RADIO SW_RFKILL_ALL
+#define SW_MICROPHONE_INSERT 0x04
+#define SW_DOCK 0x05
+/* WARNING: DO NOT EDIT, AUTO-GENERATED CODE - SEE TOP FOR INSTRUCTIONS */
+#define SW_LINEOUT_INSERT 0x06
+#define SW_JACK_PHYSICAL_INSERT 0x07
+#define SW_VIDEOOUT_INSERT 0x08
+#define SW_CAMERA_LENS_COVER 0x09
+/* WARNING: DO NOT EDIT, AUTO-GENERATED CODE - SEE TOP FOR INSTRUCTIONS */
+#define SW_KEYPAD_SLIDE 0x0a
+#define SW_FRONT_PROXIMITY 0x0b
+#define SW_ROTATE_LOCK 0x0c
+#define SW_LINEIN_INSERT 0x0d
+/* WARNING: DO NOT EDIT, AUTO-GENERATED CODE - SEE TOP FOR INSTRUCTIONS */
+#define SW_MUTE_DEVICE 0x0e
+#define SW_MAX 0x0f
+#define SW_CNT (SW_MAX + 1)
+#define MSC_SERIAL 0x00
+/* WARNING: DO NOT EDIT, AUTO-GENERATED CODE - SEE TOP FOR INSTRUCTIONS */
+#define MSC_PULSELED 0x01
+#define MSC_GESTURE 0x02
+#define MSC_RAW 0x03
+#define MSC_SCAN 0x04
+/* WARNING: DO NOT EDIT, AUTO-GENERATED CODE - SEE TOP FOR INSTRUCTIONS */
+#define MSC_TIMESTAMP 0x05
+#define MSC_MAX 0x07
+#define MSC_CNT (MSC_MAX + 1)
+#define LED_NUML 0x00
+/* WARNING: DO NOT EDIT, AUTO-GENERATED CODE - SEE TOP FOR INSTRUCTIONS */
+#define LED_CAPSL 0x01
+#define LED_SCROLLL 0x02
+#define LED_COMPOSE 0x03
+#define LED_KANA 0x04
+/* WARNING: DO NOT EDIT, AUTO-GENERATED CODE - SEE TOP FOR INSTRUCTIONS */
+#define LED_SLEEP 0x05
+#define LED_SUSPEND 0x06
+#define LED_MUTE 0x07
+#define LED_MISC 0x08
+/* WARNING: DO NOT EDIT, AUTO-GENERATED CODE - SEE TOP FOR INSTRUCTIONS */
+#define LED_MAIL 0x09
+#define LED_CHARGING 0x0a
+#define LED_MAX 0x0f
+#define LED_CNT (LED_MAX + 1)
+/* WARNING: DO NOT EDIT, AUTO-GENERATED CODE - SEE TOP FOR INSTRUCTIONS */
+#define REP_DELAY 0x00
+#define REP_PERIOD 0x01
+#define REP_MAX 0x01
+#define REP_CNT (REP_MAX + 1)
+/* WARNING: DO NOT EDIT, AUTO-GENERATED CODE - SEE TOP FOR INSTRUCTIONS */
+#define SND_CLICK 0x00
+#define SND_BELL 0x01
+#define SND_TONE 0x02
+#define SND_MAX 0x07
+/* WARNING: DO NOT EDIT, AUTO-GENERATED CODE - SEE TOP FOR INSTRUCTIONS */
+#define SND_CNT (SND_MAX + 1)
+#endif
diff --git a/libc/kernel/uapi/linux/input.h b/libc/kernel/uapi/linux/input.h
index 88a1f0e..9fbebb6 100644
--- a/libc/kernel/uapi/linux/input.h
+++ b/libc/kernel/uapi/linux/input.h
@@ -23,943 +23,118 @@
 /* WARNING: DO NOT EDIT, AUTO-GENERATED CODE - SEE TOP FOR INSTRUCTIONS */
 #include <sys/types.h>
 #include <linux/types.h>
+#include "input-event-codes.h"
 struct input_event {
-  struct timeval time;
 /* WARNING: DO NOT EDIT, AUTO-GENERATED CODE - SEE TOP FOR INSTRUCTIONS */
+  struct timeval time;
   __u16 type;
   __u16 code;
   __s32 value;
-};
 /* WARNING: DO NOT EDIT, AUTO-GENERATED CODE - SEE TOP FOR INSTRUCTIONS */
+};
 #define EV_VERSION 0x010001
 struct input_id {
   __u16 bustype;
-  __u16 vendor;
 /* WARNING: DO NOT EDIT, AUTO-GENERATED CODE - SEE TOP FOR INSTRUCTIONS */
+  __u16 vendor;
   __u16 product;
   __u16 version;
 };
-struct input_absinfo {
 /* WARNING: DO NOT EDIT, AUTO-GENERATED CODE - SEE TOP FOR INSTRUCTIONS */
+struct input_absinfo {
   __s32 value;
   __s32 minimum;
   __s32 maximum;
-  __s32 fuzz;
 /* WARNING: DO NOT EDIT, AUTO-GENERATED CODE - SEE TOP FOR INSTRUCTIONS */
+  __s32 fuzz;
   __s32 flat;
   __s32 resolution;
 };
-struct input_keymap_entry {
 /* WARNING: DO NOT EDIT, AUTO-GENERATED CODE - SEE TOP FOR INSTRUCTIONS */
+struct input_keymap_entry {
 #define INPUT_KEYMAP_BY_INDEX (1 << 0)
   __u8 flags;
   __u8 len;
-  __u16 index;
 /* WARNING: DO NOT EDIT, AUTO-GENERATED CODE - SEE TOP FOR INSTRUCTIONS */
+  __u16 index;
   __u32 keycode;
   __u8 scancode[32];
 };
-#define EVIOCGVERSION _IOR('E', 0x01, int)
 /* WARNING: DO NOT EDIT, AUTO-GENERATED CODE - SEE TOP FOR INSTRUCTIONS */
+struct input_mask {
+  __u32 type;
+  __u32 codes_size;
+  __u64 codes_ptr;
+/* WARNING: DO NOT EDIT, AUTO-GENERATED CODE - SEE TOP FOR INSTRUCTIONS */
+};
+#define EVIOCGVERSION _IOR('E', 0x01, int)
 #define EVIOCGID _IOR('E', 0x02, struct input_id)
 #define EVIOCGREP _IOR('E', 0x03, unsigned int[2])
+/* WARNING: DO NOT EDIT, AUTO-GENERATED CODE - SEE TOP FOR INSTRUCTIONS */
 #define EVIOCSREP _IOW('E', 0x03, unsigned int[2])
 #define EVIOCGKEYCODE _IOR('E', 0x04, unsigned int[2])
-/* WARNING: DO NOT EDIT, AUTO-GENERATED CODE - SEE TOP FOR INSTRUCTIONS */
 #define EVIOCGKEYCODE_V2 _IOR('E', 0x04, struct input_keymap_entry)
 #define EVIOCSKEYCODE _IOW('E', 0x04, unsigned int[2])
+/* WARNING: DO NOT EDIT, AUTO-GENERATED CODE - SEE TOP FOR INSTRUCTIONS */
 #define EVIOCSKEYCODE_V2 _IOW('E', 0x04, struct input_keymap_entry)
 #define EVIOCGNAME(len) _IOC(_IOC_READ, 'E', 0x06, len)
-/* WARNING: DO NOT EDIT, AUTO-GENERATED CODE - SEE TOP FOR INSTRUCTIONS */
 #define EVIOCGPHYS(len) _IOC(_IOC_READ, 'E', 0x07, len)
 #define EVIOCGUNIQ(len) _IOC(_IOC_READ, 'E', 0x08, len)
+/* WARNING: DO NOT EDIT, AUTO-GENERATED CODE - SEE TOP FOR INSTRUCTIONS */
 #define EVIOCGPROP(len) _IOC(_IOC_READ, 'E', 0x09, len)
 #define EVIOCGMTSLOTS(len) _IOC(_IOC_READ, 'E', 0x0a, len)
-/* WARNING: DO NOT EDIT, AUTO-GENERATED CODE - SEE TOP FOR INSTRUCTIONS */
 #define EVIOCGKEY(len) _IOC(_IOC_READ, 'E', 0x18, len)
 #define EVIOCGLED(len) _IOC(_IOC_READ, 'E', 0x19, len)
+/* WARNING: DO NOT EDIT, AUTO-GENERATED CODE - SEE TOP FOR INSTRUCTIONS */
 #define EVIOCGSND(len) _IOC(_IOC_READ, 'E', 0x1a, len)
 #define EVIOCGSW(len) _IOC(_IOC_READ, 'E', 0x1b, len)
-/* WARNING: DO NOT EDIT, AUTO-GENERATED CODE - SEE TOP FOR INSTRUCTIONS */
 #define EVIOCGBIT(ev,len) _IOC(_IOC_READ, 'E', 0x20 + (ev), len)
 #define EVIOCGABS(abs) _IOR('E', 0x40 + (abs), struct input_absinfo)
-#define EVIOCSABS(abs) _IOW('E', 0xc0 + (abs), struct input_absinfo)
-#define EVIOCSFF _IOC(_IOC_WRITE, 'E', 0x80, sizeof(struct ff_effect))
 /* WARNING: DO NOT EDIT, AUTO-GENERATED CODE - SEE TOP FOR INSTRUCTIONS */
+#define EVIOCSABS(abs) _IOW('E', 0xc0 + (abs), struct input_absinfo)
+#define EVIOCSFF _IOW('E', 0x80, struct ff_effect)
 #define EVIOCRMFF _IOW('E', 0x81, int)
 #define EVIOCGEFFECTS _IOR('E', 0x84, int)
+/* WARNING: DO NOT EDIT, AUTO-GENERATED CODE - SEE TOP FOR INSTRUCTIONS */
 #define EVIOCGRAB _IOW('E', 0x90, int)
 #define EVIOCREVOKE _IOW('E', 0x91, int)
+#define EVIOCGMASK _IOR('E', 0x92, struct input_mask)
+#define EVIOCSMASK _IOW('E', 0x93, struct input_mask)
 /* WARNING: DO NOT EDIT, AUTO-GENERATED CODE - SEE TOP FOR INSTRUCTIONS */
 #define EVIOCSCLOCKID _IOW('E', 0xa0, int)
-#define INPUT_PROP_POINTER 0x00
-#define INPUT_PROP_DIRECT 0x01
-#define INPUT_PROP_BUTTONPAD 0x02
-/* WARNING: DO NOT EDIT, AUTO-GENERATED CODE - SEE TOP FOR INSTRUCTIONS */
-#define INPUT_PROP_SEMI_MT 0x03
-#define INPUT_PROP_TOPBUTTONPAD 0x04
-#define INPUT_PROP_POINTING_STICK 0x05
-#define INPUT_PROP_MAX 0x1f
-/* WARNING: DO NOT EDIT, AUTO-GENERATED CODE - SEE TOP FOR INSTRUCTIONS */
-#define INPUT_PROP_CNT (INPUT_PROP_MAX + 1)
-#define EV_SYN 0x00
-#define EV_KEY 0x01
-#define EV_REL 0x02
-/* WARNING: DO NOT EDIT, AUTO-GENERATED CODE - SEE TOP FOR INSTRUCTIONS */
-#define EV_ABS 0x03
-#define EV_MSC 0x04
-#define EV_SW 0x05
-#define EV_LED 0x11
-/* WARNING: DO NOT EDIT, AUTO-GENERATED CODE - SEE TOP FOR INSTRUCTIONS */
-#define EV_SND 0x12
-#define EV_REP 0x14
-#define EV_FF 0x15
-#define EV_PWR 0x16
-/* WARNING: DO NOT EDIT, AUTO-GENERATED CODE - SEE TOP FOR INSTRUCTIONS */
-#define EV_FF_STATUS 0x17
-#define EV_MAX 0x1f
-#define EV_CNT (EV_MAX + 1)
-#define SYN_REPORT 0
-/* WARNING: DO NOT EDIT, AUTO-GENERATED CODE - SEE TOP FOR INSTRUCTIONS */
-#define SYN_CONFIG 1
-#define SYN_MT_REPORT 2
-#define SYN_DROPPED 3
-#define SYN_MAX 0xf
-/* WARNING: DO NOT EDIT, AUTO-GENERATED CODE - SEE TOP FOR INSTRUCTIONS */
-#define SYN_CNT (SYN_MAX + 1)
-#define KEY_RESERVED 0
-#define KEY_ESC 1
-#define KEY_1 2
-/* WARNING: DO NOT EDIT, AUTO-GENERATED CODE - SEE TOP FOR INSTRUCTIONS */
-#define KEY_2 3
-#define KEY_3 4
-#define KEY_4 5
-#define KEY_5 6
-/* WARNING: DO NOT EDIT, AUTO-GENERATED CODE - SEE TOP FOR INSTRUCTIONS */
-#define KEY_6 7
-#define KEY_7 8
-#define KEY_8 9
-#define KEY_9 10
-/* WARNING: DO NOT EDIT, AUTO-GENERATED CODE - SEE TOP FOR INSTRUCTIONS */
-#define KEY_0 11
-#define KEY_MINUS 12
-#define KEY_EQUAL 13
-#define KEY_BACKSPACE 14
-/* WARNING: DO NOT EDIT, AUTO-GENERATED CODE - SEE TOP FOR INSTRUCTIONS */
-#define KEY_TAB 15
-#define KEY_Q 16
-#define KEY_W 17
-#define KEY_E 18
-/* WARNING: DO NOT EDIT, AUTO-GENERATED CODE - SEE TOP FOR INSTRUCTIONS */
-#define KEY_R 19
-#define KEY_T 20
-#define KEY_Y 21
-#define KEY_U 22
-/* WARNING: DO NOT EDIT, AUTO-GENERATED CODE - SEE TOP FOR INSTRUCTIONS */
-#define KEY_I 23
-#define KEY_O 24
-#define KEY_P 25
-#define KEY_LEFTBRACE 26
-/* WARNING: DO NOT EDIT, AUTO-GENERATED CODE - SEE TOP FOR INSTRUCTIONS */
-#define KEY_RIGHTBRACE 27
-#define KEY_ENTER 28
-#define KEY_LEFTCTRL 29
-#define KEY_A 30
-/* WARNING: DO NOT EDIT, AUTO-GENERATED CODE - SEE TOP FOR INSTRUCTIONS */
-#define KEY_S 31
-#define KEY_D 32
-#define KEY_F 33
-#define KEY_G 34
-/* WARNING: DO NOT EDIT, AUTO-GENERATED CODE - SEE TOP FOR INSTRUCTIONS */
-#define KEY_H 35
-#define KEY_J 36
-#define KEY_K 37
-#define KEY_L 38
-/* WARNING: DO NOT EDIT, AUTO-GENERATED CODE - SEE TOP FOR INSTRUCTIONS */
-#define KEY_SEMICOLON 39
-#define KEY_APOSTROPHE 40
-#define KEY_GRAVE 41
-#define KEY_LEFTSHIFT 42
-/* WARNING: DO NOT EDIT, AUTO-GENERATED CODE - SEE TOP FOR INSTRUCTIONS */
-#define KEY_BACKSLASH 43
-#define KEY_Z 44
-#define KEY_X 45
-#define KEY_C 46
-/* WARNING: DO NOT EDIT, AUTO-GENERATED CODE - SEE TOP FOR INSTRUCTIONS */
-#define KEY_V 47
-#define KEY_B 48
-#define KEY_N 49
-#define KEY_M 50
-/* WARNING: DO NOT EDIT, AUTO-GENERATED CODE - SEE TOP FOR INSTRUCTIONS */
-#define KEY_COMMA 51
-#define KEY_DOT 52
-#define KEY_SLASH 53
-#define KEY_RIGHTSHIFT 54
-/* WARNING: DO NOT EDIT, AUTO-GENERATED CODE - SEE TOP FOR INSTRUCTIONS */
-#define KEY_KPASTERISK 55
-#define KEY_LEFTALT 56
-#define KEY_SPACE 57
-#define KEY_CAPSLOCK 58
-/* WARNING: DO NOT EDIT, AUTO-GENERATED CODE - SEE TOP FOR INSTRUCTIONS */
-#define KEY_F1 59
-#define KEY_F2 60
-#define KEY_F3 61
-#define KEY_F4 62
-/* WARNING: DO NOT EDIT, AUTO-GENERATED CODE - SEE TOP FOR INSTRUCTIONS */
-#define KEY_F5 63
-#define KEY_F6 64
-#define KEY_F7 65
-#define KEY_F8 66
-/* WARNING: DO NOT EDIT, AUTO-GENERATED CODE - SEE TOP FOR INSTRUCTIONS */
-#define KEY_F9 67
-#define KEY_F10 68
-#define KEY_NUMLOCK 69
-#define KEY_SCROLLLOCK 70
-/* WARNING: DO NOT EDIT, AUTO-GENERATED CODE - SEE TOP FOR INSTRUCTIONS */
-#define KEY_KP7 71
-#define KEY_KP8 72
-#define KEY_KP9 73
-#define KEY_KPMINUS 74
-/* WARNING: DO NOT EDIT, AUTO-GENERATED CODE - SEE TOP FOR INSTRUCTIONS */
-#define KEY_KP4 75
-#define KEY_KP5 76
-#define KEY_KP6 77
-#define KEY_KPPLUS 78
-/* WARNING: DO NOT EDIT, AUTO-GENERATED CODE - SEE TOP FOR INSTRUCTIONS */
-#define KEY_KP1 79
-#define KEY_KP2 80
-#define KEY_KP3 81
-#define KEY_KP0 82
-/* WARNING: DO NOT EDIT, AUTO-GENERATED CODE - SEE TOP FOR INSTRUCTIONS */
-#define KEY_KPDOT 83
-#define KEY_ZENKAKUHANKAKU 85
-#define KEY_102ND 86
-#define KEY_F11 87
-/* WARNING: DO NOT EDIT, AUTO-GENERATED CODE - SEE TOP FOR INSTRUCTIONS */
-#define KEY_F12 88
-#define KEY_RO 89
-#define KEY_KATAKANA 90
-#define KEY_HIRAGANA 91
-/* WARNING: DO NOT EDIT, AUTO-GENERATED CODE - SEE TOP FOR INSTRUCTIONS */
-#define KEY_HENKAN 92
-#define KEY_KATAKANAHIRAGANA 93
-#define KEY_MUHENKAN 94
-#define KEY_KPJPCOMMA 95
-/* WARNING: DO NOT EDIT, AUTO-GENERATED CODE - SEE TOP FOR INSTRUCTIONS */
-#define KEY_KPENTER 96
-#define KEY_RIGHTCTRL 97
-#define KEY_KPSLASH 98
-#define KEY_SYSRQ 99
-/* WARNING: DO NOT EDIT, AUTO-GENERATED CODE - SEE TOP FOR INSTRUCTIONS */
-#define KEY_RIGHTALT 100
-#define KEY_LINEFEED 101
-#define KEY_HOME 102
-#define KEY_UP 103
-/* WARNING: DO NOT EDIT, AUTO-GENERATED CODE - SEE TOP FOR INSTRUCTIONS */
-#define KEY_PAGEUP 104
-#define KEY_LEFT 105
-#define KEY_RIGHT 106
-#define KEY_END 107
-/* WARNING: DO NOT EDIT, AUTO-GENERATED CODE - SEE TOP FOR INSTRUCTIONS */
-#define KEY_DOWN 108
-#define KEY_PAGEDOWN 109
-#define KEY_INSERT 110
-#define KEY_DELETE 111
-/* WARNING: DO NOT EDIT, AUTO-GENERATED CODE - SEE TOP FOR INSTRUCTIONS */
-#define KEY_MACRO 112
-#define KEY_MUTE 113
-#define KEY_VOLUMEDOWN 114
-#define KEY_VOLUMEUP 115
-/* WARNING: DO NOT EDIT, AUTO-GENERATED CODE - SEE TOP FOR INSTRUCTIONS */
-#define KEY_POWER 116
-#define KEY_KPEQUAL 117
-#define KEY_KPPLUSMINUS 118
-#define KEY_PAUSE 119
-/* WARNING: DO NOT EDIT, AUTO-GENERATED CODE - SEE TOP FOR INSTRUCTIONS */
-#define KEY_SCALE 120
-#define KEY_KPCOMMA 121
-#define KEY_HANGEUL 122
-#define KEY_HANGUEL KEY_HANGEUL
-/* WARNING: DO NOT EDIT, AUTO-GENERATED CODE - SEE TOP FOR INSTRUCTIONS */
-#define KEY_HANJA 123
-#define KEY_YEN 124
-#define KEY_LEFTMETA 125
-#define KEY_RIGHTMETA 126
-/* WARNING: DO NOT EDIT, AUTO-GENERATED CODE - SEE TOP FOR INSTRUCTIONS */
-#define KEY_COMPOSE 127
-#define KEY_STOP 128
-#define KEY_AGAIN 129
-#define KEY_PROPS 130
-/* WARNING: DO NOT EDIT, AUTO-GENERATED CODE - SEE TOP FOR INSTRUCTIONS */
-#define KEY_UNDO 131
-#define KEY_FRONT 132
-#define KEY_COPY 133
-#define KEY_OPEN 134
-/* WARNING: DO NOT EDIT, AUTO-GENERATED CODE - SEE TOP FOR INSTRUCTIONS */
-#define KEY_PASTE 135
-#define KEY_FIND 136
-#define KEY_CUT 137
-#define KEY_HELP 138
-/* WARNING: DO NOT EDIT, AUTO-GENERATED CODE - SEE TOP FOR INSTRUCTIONS */
-#define KEY_MENU 139
-#define KEY_CALC 140
-#define KEY_SETUP 141
-#define KEY_SLEEP 142
-/* WARNING: DO NOT EDIT, AUTO-GENERATED CODE - SEE TOP FOR INSTRUCTIONS */
-#define KEY_WAKEUP 143
-#define KEY_FILE 144
-#define KEY_SENDFILE 145
-#define KEY_DELETEFILE 146
-/* WARNING: DO NOT EDIT, AUTO-GENERATED CODE - SEE TOP FOR INSTRUCTIONS */
-#define KEY_XFER 147
-#define KEY_PROG1 148
-#define KEY_PROG2 149
-#define KEY_WWW 150
-/* WARNING: DO NOT EDIT, AUTO-GENERATED CODE - SEE TOP FOR INSTRUCTIONS */
-#define KEY_MSDOS 151
-#define KEY_COFFEE 152
-#define KEY_SCREENLOCK KEY_COFFEE
-#define KEY_DIRECTION 153
-/* WARNING: DO NOT EDIT, AUTO-GENERATED CODE - SEE TOP FOR INSTRUCTIONS */
-#define KEY_CYCLEWINDOWS 154
-#define KEY_MAIL 155
-#define KEY_BOOKMARKS 156
-#define KEY_COMPUTER 157
-/* WARNING: DO NOT EDIT, AUTO-GENERATED CODE - SEE TOP FOR INSTRUCTIONS */
-#define KEY_BACK 158
-#define KEY_FORWARD 159
-#define KEY_CLOSECD 160
-#define KEY_EJECTCD 161
-/* WARNING: DO NOT EDIT, AUTO-GENERATED CODE - SEE TOP FOR INSTRUCTIONS */
-#define KEY_EJECTCLOSECD 162
-#define KEY_NEXTSONG 163
-#define KEY_PLAYPAUSE 164
-#define KEY_PREVIOUSSONG 165
-/* WARNING: DO NOT EDIT, AUTO-GENERATED CODE - SEE TOP FOR INSTRUCTIONS */
-#define KEY_STOPCD 166
-#define KEY_RECORD 167
-#define KEY_REWIND 168
-#define KEY_PHONE 169
-/* WARNING: DO NOT EDIT, AUTO-GENERATED CODE - SEE TOP FOR INSTRUCTIONS */
-#define KEY_ISO 170
-#define KEY_CONFIG 171
-#define KEY_HOMEPAGE 172
-#define KEY_REFRESH 173
-/* WARNING: DO NOT EDIT, AUTO-GENERATED CODE - SEE TOP FOR INSTRUCTIONS */
-#define KEY_EXIT 174
-#define KEY_MOVE 175
-#define KEY_EDIT 176
-#define KEY_SCROLLUP 177
-/* WARNING: DO NOT EDIT, AUTO-GENERATED CODE - SEE TOP FOR INSTRUCTIONS */
-#define KEY_SCROLLDOWN 178
-#define KEY_KPLEFTPAREN 179
-#define KEY_KPRIGHTPAREN 180
-#define KEY_NEW 181
-/* WARNING: DO NOT EDIT, AUTO-GENERATED CODE - SEE TOP FOR INSTRUCTIONS */
-#define KEY_REDO 182
-#define KEY_F13 183
-#define KEY_F14 184
-#define KEY_F15 185
-/* WARNING: DO NOT EDIT, AUTO-GENERATED CODE - SEE TOP FOR INSTRUCTIONS */
-#define KEY_F16 186
-#define KEY_F17 187
-#define KEY_F18 188
-#define KEY_F19 189
-/* WARNING: DO NOT EDIT, AUTO-GENERATED CODE - SEE TOP FOR INSTRUCTIONS */
-#define KEY_F20 190
-#define KEY_F21 191
-#define KEY_F22 192
-#define KEY_F23 193
-/* WARNING: DO NOT EDIT, AUTO-GENERATED CODE - SEE TOP FOR INSTRUCTIONS */
-#define KEY_F24 194
-#define KEY_PLAYCD 200
-#define KEY_PAUSECD 201
-#define KEY_PROG3 202
-/* WARNING: DO NOT EDIT, AUTO-GENERATED CODE - SEE TOP FOR INSTRUCTIONS */
-#define KEY_PROG4 203
-#define KEY_DASHBOARD 204
-#define KEY_SUSPEND 205
-#define KEY_CLOSE 206
-/* WARNING: DO NOT EDIT, AUTO-GENERATED CODE - SEE TOP FOR INSTRUCTIONS */
-#define KEY_PLAY 207
-#define KEY_FASTFORWARD 208
-#define KEY_BASSBOOST 209
-#define KEY_PRINT 210
-/* WARNING: DO NOT EDIT, AUTO-GENERATED CODE - SEE TOP FOR INSTRUCTIONS */
-#define KEY_HP 211
-#define KEY_CAMERA 212
-#define KEY_SOUND 213
-#define KEY_QUESTION 214
-/* WARNING: DO NOT EDIT, AUTO-GENERATED CODE - SEE TOP FOR INSTRUCTIONS */
-#define KEY_EMAIL 215
-#define KEY_CHAT 216
-#define KEY_SEARCH 217
-#define KEY_CONNECT 218
-/* WARNING: DO NOT EDIT, AUTO-GENERATED CODE - SEE TOP FOR INSTRUCTIONS */
-#define KEY_FINANCE 219
-#define KEY_SPORT 220
-#define KEY_SHOP 221
-#define KEY_ALTERASE 222
-/* WARNING: DO NOT EDIT, AUTO-GENERATED CODE - SEE TOP FOR INSTRUCTIONS */
-#define KEY_CANCEL 223
-#define KEY_BRIGHTNESSDOWN 224
-#define KEY_BRIGHTNESSUP 225
-#define KEY_MEDIA 226
-/* WARNING: DO NOT EDIT, AUTO-GENERATED CODE - SEE TOP FOR INSTRUCTIONS */
-#define KEY_SWITCHVIDEOMODE 227
-#define KEY_KBDILLUMTOGGLE 228
-#define KEY_KBDILLUMDOWN 229
-#define KEY_KBDILLUMUP 230
-/* WARNING: DO NOT EDIT, AUTO-GENERATED CODE - SEE TOP FOR INSTRUCTIONS */
-#define KEY_SEND 231
-#define KEY_REPLY 232
-#define KEY_FORWARDMAIL 233
-#define KEY_SAVE 234
-/* WARNING: DO NOT EDIT, AUTO-GENERATED CODE - SEE TOP FOR INSTRUCTIONS */
-#define KEY_DOCUMENTS 235
-#define KEY_BATTERY 236
-#define KEY_BLUETOOTH 237
-#define KEY_WLAN 238
-/* WARNING: DO NOT EDIT, AUTO-GENERATED CODE - SEE TOP FOR INSTRUCTIONS */
-#define KEY_UWB 239
-#define KEY_UNKNOWN 240
-#define KEY_VIDEO_NEXT 241
-#define KEY_VIDEO_PREV 242
-/* WARNING: DO NOT EDIT, AUTO-GENERATED CODE - SEE TOP FOR INSTRUCTIONS */
-#define KEY_BRIGHTNESS_CYCLE 243
-#define KEY_BRIGHTNESS_AUTO 244
-#define KEY_BRIGHTNESS_ZERO KEY_BRIGHTNESS_AUTO
-#define KEY_DISPLAY_OFF 245
-/* WARNING: DO NOT EDIT, AUTO-GENERATED CODE - SEE TOP FOR INSTRUCTIONS */
-#define KEY_WWAN 246
-#define KEY_WIMAX KEY_WWAN
-#define KEY_RFKILL 247
-#define KEY_MICMUTE 248
-/* WARNING: DO NOT EDIT, AUTO-GENERATED CODE - SEE TOP FOR INSTRUCTIONS */
-#define BTN_MISC 0x100
-#define BTN_0 0x100
-#define BTN_1 0x101
-#define BTN_2 0x102
-/* WARNING: DO NOT EDIT, AUTO-GENERATED CODE - SEE TOP FOR INSTRUCTIONS */
-#define BTN_3 0x103
-#define BTN_4 0x104
-#define BTN_5 0x105
-#define BTN_6 0x106
-/* WARNING: DO NOT EDIT, AUTO-GENERATED CODE - SEE TOP FOR INSTRUCTIONS */
-#define BTN_7 0x107
-#define BTN_8 0x108
-#define BTN_9 0x109
-#define BTN_MOUSE 0x110
-/* WARNING: DO NOT EDIT, AUTO-GENERATED CODE - SEE TOP FOR INSTRUCTIONS */
-#define BTN_LEFT 0x110
-#define BTN_RIGHT 0x111
-#define BTN_MIDDLE 0x112
-#define BTN_SIDE 0x113
-/* WARNING: DO NOT EDIT, AUTO-GENERATED CODE - SEE TOP FOR INSTRUCTIONS */
-#define BTN_EXTRA 0x114
-#define BTN_FORWARD 0x115
-#define BTN_BACK 0x116
-#define BTN_TASK 0x117
-/* WARNING: DO NOT EDIT, AUTO-GENERATED CODE - SEE TOP FOR INSTRUCTIONS */
-#define BTN_JOYSTICK 0x120
-#define BTN_TRIGGER 0x120
-#define BTN_THUMB 0x121
-#define BTN_THUMB2 0x122
-/* WARNING: DO NOT EDIT, AUTO-GENERATED CODE - SEE TOP FOR INSTRUCTIONS */
-#define BTN_TOP 0x123
-#define BTN_TOP2 0x124
-#define BTN_PINKIE 0x125
-#define BTN_BASE 0x126
-/* WARNING: DO NOT EDIT, AUTO-GENERATED CODE - SEE TOP FOR INSTRUCTIONS */
-#define BTN_BASE2 0x127
-#define BTN_BASE3 0x128
-#define BTN_BASE4 0x129
-#define BTN_BASE5 0x12a
-/* WARNING: DO NOT EDIT, AUTO-GENERATED CODE - SEE TOP FOR INSTRUCTIONS */
-#define BTN_BASE6 0x12b
-#define BTN_DEAD 0x12f
-#define BTN_GAMEPAD 0x130
-#define BTN_SOUTH 0x130
-/* WARNING: DO NOT EDIT, AUTO-GENERATED CODE - SEE TOP FOR INSTRUCTIONS */
-#define BTN_A BTN_SOUTH
-#define BTN_EAST 0x131
-#define BTN_B BTN_EAST
-#define BTN_C 0x132
-/* WARNING: DO NOT EDIT, AUTO-GENERATED CODE - SEE TOP FOR INSTRUCTIONS */
-#define BTN_NORTH 0x133
-#define BTN_X BTN_NORTH
-#define BTN_WEST 0x134
-#define BTN_Y BTN_WEST
-/* WARNING: DO NOT EDIT, AUTO-GENERATED CODE - SEE TOP FOR INSTRUCTIONS */
-#define BTN_Z 0x135
-#define BTN_TL 0x136
-#define BTN_TR 0x137
-#define BTN_TL2 0x138
-/* WARNING: DO NOT EDIT, AUTO-GENERATED CODE - SEE TOP FOR INSTRUCTIONS */
-#define BTN_TR2 0x139
-#define BTN_SELECT 0x13a
-#define BTN_START 0x13b
-#define BTN_MODE 0x13c
-/* WARNING: DO NOT EDIT, AUTO-GENERATED CODE - SEE TOP FOR INSTRUCTIONS */
-#define BTN_THUMBL 0x13d
-#define BTN_THUMBR 0x13e
-#define BTN_DIGI 0x140
-#define BTN_TOOL_PEN 0x140
-/* WARNING: DO NOT EDIT, AUTO-GENERATED CODE - SEE TOP FOR INSTRUCTIONS */
-#define BTN_TOOL_RUBBER 0x141
-#define BTN_TOOL_BRUSH 0x142
-#define BTN_TOOL_PENCIL 0x143
-#define BTN_TOOL_AIRBRUSH 0x144
-/* WARNING: DO NOT EDIT, AUTO-GENERATED CODE - SEE TOP FOR INSTRUCTIONS */
-#define BTN_TOOL_FINGER 0x145
-#define BTN_TOOL_MOUSE 0x146
-#define BTN_TOOL_LENS 0x147
-#define BTN_TOOL_QUINTTAP 0x148
-/* WARNING: DO NOT EDIT, AUTO-GENERATED CODE - SEE TOP FOR INSTRUCTIONS */
-#define BTN_TOUCH 0x14a
-#define BTN_STYLUS 0x14b
-#define BTN_STYLUS2 0x14c
-#define BTN_TOOL_DOUBLETAP 0x14d
-/* WARNING: DO NOT EDIT, AUTO-GENERATED CODE - SEE TOP FOR INSTRUCTIONS */
-#define BTN_TOOL_TRIPLETAP 0x14e
-#define BTN_TOOL_QUADTAP 0x14f
-#define BTN_WHEEL 0x150
-#define BTN_GEAR_DOWN 0x150
-/* WARNING: DO NOT EDIT, AUTO-GENERATED CODE - SEE TOP FOR INSTRUCTIONS */
-#define BTN_GEAR_UP 0x151
-#define KEY_OK 0x160
-#define KEY_SELECT 0x161
-#define KEY_GOTO 0x162
-/* WARNING: DO NOT EDIT, AUTO-GENERATED CODE - SEE TOP FOR INSTRUCTIONS */
-#define KEY_CLEAR 0x163
-#define KEY_POWER2 0x164
-#define KEY_OPTION 0x165
-#define KEY_INFO 0x166
-/* WARNING: DO NOT EDIT, AUTO-GENERATED CODE - SEE TOP FOR INSTRUCTIONS */
-#define KEY_TIME 0x167
-#define KEY_VENDOR 0x168
-#define KEY_ARCHIVE 0x169
-#define KEY_PROGRAM 0x16a
-/* WARNING: DO NOT EDIT, AUTO-GENERATED CODE - SEE TOP FOR INSTRUCTIONS */
-#define KEY_CHANNEL 0x16b
-#define KEY_FAVORITES 0x16c
-#define KEY_EPG 0x16d
-#define KEY_PVR 0x16e
-/* WARNING: DO NOT EDIT, AUTO-GENERATED CODE - SEE TOP FOR INSTRUCTIONS */
-#define KEY_MHP 0x16f
-#define KEY_LANGUAGE 0x170
-#define KEY_TITLE 0x171
-#define KEY_SUBTITLE 0x172
-/* WARNING: DO NOT EDIT, AUTO-GENERATED CODE - SEE TOP FOR INSTRUCTIONS */
-#define KEY_ANGLE 0x173
-#define KEY_ZOOM 0x174
-#define KEY_MODE 0x175
-#define KEY_KEYBOARD 0x176
-/* WARNING: DO NOT EDIT, AUTO-GENERATED CODE - SEE TOP FOR INSTRUCTIONS */
-#define KEY_SCREEN 0x177
-#define KEY_PC 0x178
-#define KEY_TV 0x179
-#define KEY_TV2 0x17a
-/* WARNING: DO NOT EDIT, AUTO-GENERATED CODE - SEE TOP FOR INSTRUCTIONS */
-#define KEY_VCR 0x17b
-#define KEY_VCR2 0x17c
-#define KEY_SAT 0x17d
-#define KEY_SAT2 0x17e
-/* WARNING: DO NOT EDIT, AUTO-GENERATED CODE - SEE TOP FOR INSTRUCTIONS */
-#define KEY_CD 0x17f
-#define KEY_TAPE 0x180
-#define KEY_RADIO 0x181
-#define KEY_TUNER 0x182
-/* WARNING: DO NOT EDIT, AUTO-GENERATED CODE - SEE TOP FOR INSTRUCTIONS */
-#define KEY_PLAYER 0x183
-#define KEY_TEXT 0x184
-#define KEY_DVD 0x185
-#define KEY_AUX 0x186
-/* WARNING: DO NOT EDIT, AUTO-GENERATED CODE - SEE TOP FOR INSTRUCTIONS */
-#define KEY_MP3 0x187
-#define KEY_AUDIO 0x188
-#define KEY_VIDEO 0x189
-#define KEY_DIRECTORY 0x18a
-/* WARNING: DO NOT EDIT, AUTO-GENERATED CODE - SEE TOP FOR INSTRUCTIONS */
-#define KEY_LIST 0x18b
-#define KEY_MEMO 0x18c
-#define KEY_CALENDAR 0x18d
-#define KEY_RED 0x18e
-/* WARNING: DO NOT EDIT, AUTO-GENERATED CODE - SEE TOP FOR INSTRUCTIONS */
-#define KEY_GREEN 0x18f
-#define KEY_YELLOW 0x190
-#define KEY_BLUE 0x191
-#define KEY_CHANNELUP 0x192
-/* WARNING: DO NOT EDIT, AUTO-GENERATED CODE - SEE TOP FOR INSTRUCTIONS */
-#define KEY_CHANNELDOWN 0x193
-#define KEY_FIRST 0x194
-#define KEY_LAST 0x195
-#define KEY_AB 0x196
-/* WARNING: DO NOT EDIT, AUTO-GENERATED CODE - SEE TOP FOR INSTRUCTIONS */
-#define KEY_NEXT 0x197
-#define KEY_RESTART 0x198
-#define KEY_SLOW 0x199
-#define KEY_SHUFFLE 0x19a
-/* WARNING: DO NOT EDIT, AUTO-GENERATED CODE - SEE TOP FOR INSTRUCTIONS */
-#define KEY_BREAK 0x19b
-#define KEY_PREVIOUS 0x19c
-#define KEY_DIGITS 0x19d
-#define KEY_TEEN 0x19e
-/* WARNING: DO NOT EDIT, AUTO-GENERATED CODE - SEE TOP FOR INSTRUCTIONS */
-#define KEY_TWEN 0x19f
-#define KEY_VIDEOPHONE 0x1a0
-#define KEY_GAMES 0x1a1
-#define KEY_ZOOMIN 0x1a2
-/* WARNING: DO NOT EDIT, AUTO-GENERATED CODE - SEE TOP FOR INSTRUCTIONS */
-#define KEY_ZOOMOUT 0x1a3
-#define KEY_ZOOMRESET 0x1a4
-#define KEY_WORDPROCESSOR 0x1a5
-#define KEY_EDITOR 0x1a6
-/* WARNING: DO NOT EDIT, AUTO-GENERATED CODE - SEE TOP FOR INSTRUCTIONS */
-#define KEY_SPREADSHEET 0x1a7
-#define KEY_GRAPHICSEDITOR 0x1a8
-#define KEY_PRESENTATION 0x1a9
-#define KEY_DATABASE 0x1aa
-/* WARNING: DO NOT EDIT, AUTO-GENERATED CODE - SEE TOP FOR INSTRUCTIONS */
-#define KEY_NEWS 0x1ab
-#define KEY_VOICEMAIL 0x1ac
-#define KEY_ADDRESSBOOK 0x1ad
-#define KEY_MESSENGER 0x1ae
-/* WARNING: DO NOT EDIT, AUTO-GENERATED CODE - SEE TOP FOR INSTRUCTIONS */
-#define KEY_DISPLAYTOGGLE 0x1af
-#define KEY_BRIGHTNESS_TOGGLE KEY_DISPLAYTOGGLE
-#define KEY_SPELLCHECK 0x1b0
-#define KEY_LOGOFF 0x1b1
-/* WARNING: DO NOT EDIT, AUTO-GENERATED CODE - SEE TOP FOR INSTRUCTIONS */
-#define KEY_DOLLAR 0x1b2
-#define KEY_EURO 0x1b3
-#define KEY_FRAMEBACK 0x1b4
-#define KEY_FRAMEFORWARD 0x1b5
-/* WARNING: DO NOT EDIT, AUTO-GENERATED CODE - SEE TOP FOR INSTRUCTIONS */
-#define KEY_CONTEXT_MENU 0x1b6
-#define KEY_MEDIA_REPEAT 0x1b7
-#define KEY_10CHANNELSUP 0x1b8
-#define KEY_10CHANNELSDOWN 0x1b9
-/* WARNING: DO NOT EDIT, AUTO-GENERATED CODE - SEE TOP FOR INSTRUCTIONS */
-#define KEY_IMAGES 0x1ba
-#define KEY_DEL_EOL 0x1c0
-#define KEY_DEL_EOS 0x1c1
-#define KEY_INS_LINE 0x1c2
-/* WARNING: DO NOT EDIT, AUTO-GENERATED CODE - SEE TOP FOR INSTRUCTIONS */
-#define KEY_DEL_LINE 0x1c3
-#define KEY_FN 0x1d0
-#define KEY_FN_ESC 0x1d1
-#define KEY_FN_F1 0x1d2
-/* WARNING: DO NOT EDIT, AUTO-GENERATED CODE - SEE TOP FOR INSTRUCTIONS */
-#define KEY_FN_F2 0x1d3
-#define KEY_FN_F3 0x1d4
-#define KEY_FN_F4 0x1d5
-#define KEY_FN_F5 0x1d6
-/* WARNING: DO NOT EDIT, AUTO-GENERATED CODE - SEE TOP FOR INSTRUCTIONS */
-#define KEY_FN_F6 0x1d7
-#define KEY_FN_F7 0x1d8
-#define KEY_FN_F8 0x1d9
-#define KEY_FN_F9 0x1da
-/* WARNING: DO NOT EDIT, AUTO-GENERATED CODE - SEE TOP FOR INSTRUCTIONS */
-#define KEY_FN_F10 0x1db
-#define KEY_FN_F11 0x1dc
-#define KEY_FN_F12 0x1dd
-#define KEY_FN_1 0x1de
-/* WARNING: DO NOT EDIT, AUTO-GENERATED CODE - SEE TOP FOR INSTRUCTIONS */
-#define KEY_FN_2 0x1df
-#define KEY_FN_D 0x1e0
-#define KEY_FN_E 0x1e1
-#define KEY_FN_F 0x1e2
-/* WARNING: DO NOT EDIT, AUTO-GENERATED CODE - SEE TOP FOR INSTRUCTIONS */
-#define KEY_FN_S 0x1e3
-#define KEY_FN_B 0x1e4
-#define KEY_BRL_DOT1 0x1f1
-#define KEY_BRL_DOT2 0x1f2
-/* WARNING: DO NOT EDIT, AUTO-GENERATED CODE - SEE TOP FOR INSTRUCTIONS */
-#define KEY_BRL_DOT3 0x1f3
-#define KEY_BRL_DOT4 0x1f4
-#define KEY_BRL_DOT5 0x1f5
-#define KEY_BRL_DOT6 0x1f6
-/* WARNING: DO NOT EDIT, AUTO-GENERATED CODE - SEE TOP FOR INSTRUCTIONS */
-#define KEY_BRL_DOT7 0x1f7
-#define KEY_BRL_DOT8 0x1f8
-#define KEY_BRL_DOT9 0x1f9
-#define KEY_BRL_DOT10 0x1fa
-/* WARNING: DO NOT EDIT, AUTO-GENERATED CODE - SEE TOP FOR INSTRUCTIONS */
-#define KEY_NUMERIC_0 0x200
-#define KEY_NUMERIC_1 0x201
-#define KEY_NUMERIC_2 0x202
-#define KEY_NUMERIC_3 0x203
-/* WARNING: DO NOT EDIT, AUTO-GENERATED CODE - SEE TOP FOR INSTRUCTIONS */
-#define KEY_NUMERIC_4 0x204
-#define KEY_NUMERIC_5 0x205
-#define KEY_NUMERIC_6 0x206
-#define KEY_NUMERIC_7 0x207
-/* WARNING: DO NOT EDIT, AUTO-GENERATED CODE - SEE TOP FOR INSTRUCTIONS */
-#define KEY_NUMERIC_8 0x208
-#define KEY_NUMERIC_9 0x209
-#define KEY_NUMERIC_STAR 0x20a
-#define KEY_NUMERIC_POUND 0x20b
-/* WARNING: DO NOT EDIT, AUTO-GENERATED CODE - SEE TOP FOR INSTRUCTIONS */
-#define KEY_CAMERA_FOCUS 0x210
-#define KEY_WPS_BUTTON 0x211
-#define KEY_TOUCHPAD_TOGGLE 0x212
-#define KEY_TOUCHPAD_ON 0x213
-/* WARNING: DO NOT EDIT, AUTO-GENERATED CODE - SEE TOP FOR INSTRUCTIONS */
-#define KEY_TOUCHPAD_OFF 0x214
-#define KEY_CAMERA_ZOOMIN 0x215
-#define KEY_CAMERA_ZOOMOUT 0x216
-#define KEY_CAMERA_UP 0x217
-/* WARNING: DO NOT EDIT, AUTO-GENERATED CODE - SEE TOP FOR INSTRUCTIONS */
-#define KEY_CAMERA_DOWN 0x218
-#define KEY_CAMERA_LEFT 0x219
-#define KEY_CAMERA_RIGHT 0x21a
-#define KEY_ATTENDANT_ON 0x21b
-/* WARNING: DO NOT EDIT, AUTO-GENERATED CODE - SEE TOP FOR INSTRUCTIONS */
-#define KEY_ATTENDANT_OFF 0x21c
-#define KEY_ATTENDANT_TOGGLE 0x21d
-#define KEY_LIGHTS_TOGGLE 0x21e
-#define BTN_DPAD_UP 0x220
-/* WARNING: DO NOT EDIT, AUTO-GENERATED CODE - SEE TOP FOR INSTRUCTIONS */
-#define BTN_DPAD_DOWN 0x221
-#define BTN_DPAD_LEFT 0x222
-#define BTN_DPAD_RIGHT 0x223
-#define KEY_ALS_TOGGLE 0x230
-/* WARNING: DO NOT EDIT, AUTO-GENERATED CODE - SEE TOP FOR INSTRUCTIONS */
-#define KEY_BUTTONCONFIG 0x240
-#define KEY_TASKMANAGER 0x241
-#define KEY_JOURNAL 0x242
-#define KEY_CONTROLPANEL 0x243
-/* WARNING: DO NOT EDIT, AUTO-GENERATED CODE - SEE TOP FOR INSTRUCTIONS */
-#define KEY_APPSELECT 0x244
-#define KEY_SCREENSAVER 0x245
-#define KEY_VOICECOMMAND 0x246
-#define KEY_BRIGHTNESS_MIN 0x250
-/* WARNING: DO NOT EDIT, AUTO-GENERATED CODE - SEE TOP FOR INSTRUCTIONS */
-#define KEY_BRIGHTNESS_MAX 0x251
-#define KEY_KBDINPUTASSIST_PREV 0x260
-#define KEY_KBDINPUTASSIST_NEXT 0x261
-#define KEY_KBDINPUTASSIST_PREVGROUP 0x262
-/* WARNING: DO NOT EDIT, AUTO-GENERATED CODE - SEE TOP FOR INSTRUCTIONS */
-#define KEY_KBDINPUTASSIST_NEXTGROUP 0x263
-#define KEY_KBDINPUTASSIST_ACCEPT 0x264
-#define KEY_KBDINPUTASSIST_CANCEL 0x265
-#define BTN_TRIGGER_HAPPY 0x2c0
-/* WARNING: DO NOT EDIT, AUTO-GENERATED CODE - SEE TOP FOR INSTRUCTIONS */
-#define BTN_TRIGGER_HAPPY1 0x2c0
-#define BTN_TRIGGER_HAPPY2 0x2c1
-#define BTN_TRIGGER_HAPPY3 0x2c2
-#define BTN_TRIGGER_HAPPY4 0x2c3
-/* WARNING: DO NOT EDIT, AUTO-GENERATED CODE - SEE TOP FOR INSTRUCTIONS */
-#define BTN_TRIGGER_HAPPY5 0x2c4
-#define BTN_TRIGGER_HAPPY6 0x2c5
-#define BTN_TRIGGER_HAPPY7 0x2c6
-#define BTN_TRIGGER_HAPPY8 0x2c7
-/* WARNING: DO NOT EDIT, AUTO-GENERATED CODE - SEE TOP FOR INSTRUCTIONS */
-#define BTN_TRIGGER_HAPPY9 0x2c8
-#define BTN_TRIGGER_HAPPY10 0x2c9
-#define BTN_TRIGGER_HAPPY11 0x2ca
-#define BTN_TRIGGER_HAPPY12 0x2cb
-/* WARNING: DO NOT EDIT, AUTO-GENERATED CODE - SEE TOP FOR INSTRUCTIONS */
-#define BTN_TRIGGER_HAPPY13 0x2cc
-#define BTN_TRIGGER_HAPPY14 0x2cd
-#define BTN_TRIGGER_HAPPY15 0x2ce
-#define BTN_TRIGGER_HAPPY16 0x2cf
-/* WARNING: DO NOT EDIT, AUTO-GENERATED CODE - SEE TOP FOR INSTRUCTIONS */
-#define BTN_TRIGGER_HAPPY17 0x2d0
-#define BTN_TRIGGER_HAPPY18 0x2d1
-#define BTN_TRIGGER_HAPPY19 0x2d2
-#define BTN_TRIGGER_HAPPY20 0x2d3
-/* WARNING: DO NOT EDIT, AUTO-GENERATED CODE - SEE TOP FOR INSTRUCTIONS */
-#define BTN_TRIGGER_HAPPY21 0x2d4
-#define BTN_TRIGGER_HAPPY22 0x2d5
-#define BTN_TRIGGER_HAPPY23 0x2d6
-#define BTN_TRIGGER_HAPPY24 0x2d7
-/* WARNING: DO NOT EDIT, AUTO-GENERATED CODE - SEE TOP FOR INSTRUCTIONS */
-#define BTN_TRIGGER_HAPPY25 0x2d8
-#define BTN_TRIGGER_HAPPY26 0x2d9
-#define BTN_TRIGGER_HAPPY27 0x2da
-#define BTN_TRIGGER_HAPPY28 0x2db
-/* WARNING: DO NOT EDIT, AUTO-GENERATED CODE - SEE TOP FOR INSTRUCTIONS */
-#define BTN_TRIGGER_HAPPY29 0x2dc
-#define BTN_TRIGGER_HAPPY30 0x2dd
-#define BTN_TRIGGER_HAPPY31 0x2de
-#define BTN_TRIGGER_HAPPY32 0x2df
-/* WARNING: DO NOT EDIT, AUTO-GENERATED CODE - SEE TOP FOR INSTRUCTIONS */
-#define BTN_TRIGGER_HAPPY33 0x2e0
-#define BTN_TRIGGER_HAPPY34 0x2e1
-#define BTN_TRIGGER_HAPPY35 0x2e2
-#define BTN_TRIGGER_HAPPY36 0x2e3
-/* WARNING: DO NOT EDIT, AUTO-GENERATED CODE - SEE TOP FOR INSTRUCTIONS */
-#define BTN_TRIGGER_HAPPY37 0x2e4
-#define BTN_TRIGGER_HAPPY38 0x2e5
-#define BTN_TRIGGER_HAPPY39 0x2e6
-#define BTN_TRIGGER_HAPPY40 0x2e7
-/* WARNING: DO NOT EDIT, AUTO-GENERATED CODE - SEE TOP FOR INSTRUCTIONS */
-#define KEY_MIN_INTERESTING KEY_MUTE
-#define KEY_MAX 0x2ff
-#define KEY_CNT (KEY_MAX + 1)
-#define REL_X 0x00
-/* WARNING: DO NOT EDIT, AUTO-GENERATED CODE - SEE TOP FOR INSTRUCTIONS */
-#define REL_Y 0x01
-#define REL_Z 0x02
-#define REL_RX 0x03
-#define REL_RY 0x04
-/* WARNING: DO NOT EDIT, AUTO-GENERATED CODE - SEE TOP FOR INSTRUCTIONS */
-#define REL_RZ 0x05
-#define REL_HWHEEL 0x06
-#define REL_DIAL 0x07
-#define REL_WHEEL 0x08
-/* WARNING: DO NOT EDIT, AUTO-GENERATED CODE - SEE TOP FOR INSTRUCTIONS */
-#define REL_MISC 0x09
-#define REL_MAX 0x0f
-#define REL_CNT (REL_MAX + 1)
-#define ABS_X 0x00
-/* WARNING: DO NOT EDIT, AUTO-GENERATED CODE - SEE TOP FOR INSTRUCTIONS */
-#define ABS_Y 0x01
-#define ABS_Z 0x02
-#define ABS_RX 0x03
-#define ABS_RY 0x04
-/* WARNING: DO NOT EDIT, AUTO-GENERATED CODE - SEE TOP FOR INSTRUCTIONS */
-#define ABS_RZ 0x05
-#define ABS_THROTTLE 0x06
-#define ABS_RUDDER 0x07
-#define ABS_WHEEL 0x08
-/* WARNING: DO NOT EDIT, AUTO-GENERATED CODE - SEE TOP FOR INSTRUCTIONS */
-#define ABS_GAS 0x09
-#define ABS_BRAKE 0x0a
-#define ABS_HAT0X 0x10
-#define ABS_HAT0Y 0x11
-/* WARNING: DO NOT EDIT, AUTO-GENERATED CODE - SEE TOP FOR INSTRUCTIONS */
-#define ABS_HAT1X 0x12
-#define ABS_HAT1Y 0x13
-#define ABS_HAT2X 0x14
-#define ABS_HAT2Y 0x15
-/* WARNING: DO NOT EDIT, AUTO-GENERATED CODE - SEE TOP FOR INSTRUCTIONS */
-#define ABS_HAT3X 0x16
-#define ABS_HAT3Y 0x17
-#define ABS_PRESSURE 0x18
-#define ABS_DISTANCE 0x19
-/* WARNING: DO NOT EDIT, AUTO-GENERATED CODE - SEE TOP FOR INSTRUCTIONS */
-#define ABS_TILT_X 0x1a
-#define ABS_TILT_Y 0x1b
-#define ABS_TOOL_WIDTH 0x1c
-#define ABS_VOLUME 0x20
-/* WARNING: DO NOT EDIT, AUTO-GENERATED CODE - SEE TOP FOR INSTRUCTIONS */
-#define ABS_MISC 0x28
-#define ABS_MT_SLOT 0x2f
-#define ABS_MT_TOUCH_MAJOR 0x30
-#define ABS_MT_TOUCH_MINOR 0x31
-/* WARNING: DO NOT EDIT, AUTO-GENERATED CODE - SEE TOP FOR INSTRUCTIONS */
-#define ABS_MT_WIDTH_MAJOR 0x32
-#define ABS_MT_WIDTH_MINOR 0x33
-#define ABS_MT_ORIENTATION 0x34
-#define ABS_MT_POSITION_X 0x35
-/* WARNING: DO NOT EDIT, AUTO-GENERATED CODE - SEE TOP FOR INSTRUCTIONS */
-#define ABS_MT_POSITION_Y 0x36
-#define ABS_MT_TOOL_TYPE 0x37
-#define ABS_MT_BLOB_ID 0x38
-#define ABS_MT_TRACKING_ID 0x39
-/* WARNING: DO NOT EDIT, AUTO-GENERATED CODE - SEE TOP FOR INSTRUCTIONS */
-#define ABS_MT_PRESSURE 0x3a
-#define ABS_MT_DISTANCE 0x3b
-#define ABS_MT_TOOL_X 0x3c
-#define ABS_MT_TOOL_Y 0x3d
-/* WARNING: DO NOT EDIT, AUTO-GENERATED CODE - SEE TOP FOR INSTRUCTIONS */
-#define ABS_MAX 0x3f
-#define ABS_CNT (ABS_MAX + 1)
-#define SW_LID 0x00
-#define SW_TABLET_MODE 0x01
-/* WARNING: DO NOT EDIT, AUTO-GENERATED CODE - SEE TOP FOR INSTRUCTIONS */
-#define SW_HEADPHONE_INSERT 0x02
-#define SW_RFKILL_ALL 0x03
-#define SW_RADIO SW_RFKILL_ALL
-#define SW_MICROPHONE_INSERT 0x04
-/* WARNING: DO NOT EDIT, AUTO-GENERATED CODE - SEE TOP FOR INSTRUCTIONS */
-#define SW_DOCK 0x05
-#define SW_LINEOUT_INSERT 0x06
-#define SW_JACK_PHYSICAL_INSERT 0x07
-#define SW_VIDEOOUT_INSERT 0x08
-/* WARNING: DO NOT EDIT, AUTO-GENERATED CODE - SEE TOP FOR INSTRUCTIONS */
-#define SW_CAMERA_LENS_COVER 0x09
-#define SW_KEYPAD_SLIDE 0x0a
-#define SW_FRONT_PROXIMITY 0x0b
-#define SW_ROTATE_LOCK 0x0c
-/* WARNING: DO NOT EDIT, AUTO-GENERATED CODE - SEE TOP FOR INSTRUCTIONS */
-#define SW_LINEIN_INSERT 0x0d
-#define SW_MUTE_DEVICE 0x0e
-#define SW_MAX 0x0f
-#define SW_CNT (SW_MAX + 1)
-/* WARNING: DO NOT EDIT, AUTO-GENERATED CODE - SEE TOP FOR INSTRUCTIONS */
-#define MSC_SERIAL 0x00
-#define MSC_PULSELED 0x01
-#define MSC_GESTURE 0x02
-#define MSC_RAW 0x03
-/* WARNING: DO NOT EDIT, AUTO-GENERATED CODE - SEE TOP FOR INSTRUCTIONS */
-#define MSC_SCAN 0x04
-#define MSC_TIMESTAMP 0x05
-#define MSC_MAX 0x07
-#define MSC_CNT (MSC_MAX + 1)
-/* WARNING: DO NOT EDIT, AUTO-GENERATED CODE - SEE TOP FOR INSTRUCTIONS */
-#define LED_NUML 0x00
-#define LED_CAPSL 0x01
-#define LED_SCROLLL 0x02
-#define LED_COMPOSE 0x03
-/* WARNING: DO NOT EDIT, AUTO-GENERATED CODE - SEE TOP FOR INSTRUCTIONS */
-#define LED_KANA 0x04
-#define LED_SLEEP 0x05
-#define LED_SUSPEND 0x06
-#define LED_MUTE 0x07
-/* WARNING: DO NOT EDIT, AUTO-GENERATED CODE - SEE TOP FOR INSTRUCTIONS */
-#define LED_MISC 0x08
-#define LED_MAIL 0x09
-#define LED_CHARGING 0x0a
-#define LED_MAX 0x0f
-/* WARNING: DO NOT EDIT, AUTO-GENERATED CODE - SEE TOP FOR INSTRUCTIONS */
-#define LED_CNT (LED_MAX + 1)
-#define REP_DELAY 0x00
-#define REP_PERIOD 0x01
-#define REP_MAX 0x01
-/* WARNING: DO NOT EDIT, AUTO-GENERATED CODE - SEE TOP FOR INSTRUCTIONS */
-#define REP_CNT (REP_MAX + 1)
-#define SND_CLICK 0x00
-#define SND_BELL 0x01
-#define SND_TONE 0x02
-/* WARNING: DO NOT EDIT, AUTO-GENERATED CODE - SEE TOP FOR INSTRUCTIONS */
-#define SND_MAX 0x07
-#define SND_CNT (SND_MAX + 1)
 #define ID_BUS 0
 #define ID_VENDOR 1
-/* WARNING: DO NOT EDIT, AUTO-GENERATED CODE - SEE TOP FOR INSTRUCTIONS */
 #define ID_PRODUCT 2
+/* WARNING: DO NOT EDIT, AUTO-GENERATED CODE - SEE TOP FOR INSTRUCTIONS */
 #define ID_VERSION 3
 #define BUS_PCI 0x01
 #define BUS_ISAPNP 0x02
-/* WARNING: DO NOT EDIT, AUTO-GENERATED CODE - SEE TOP FOR INSTRUCTIONS */
 #define BUS_USB 0x03
+/* WARNING: DO NOT EDIT, AUTO-GENERATED CODE - SEE TOP FOR INSTRUCTIONS */
 #define BUS_HIL 0x04
 #define BUS_BLUETOOTH 0x05
 #define BUS_VIRTUAL 0x06
-/* WARNING: DO NOT EDIT, AUTO-GENERATED CODE - SEE TOP FOR INSTRUCTIONS */
 #define BUS_ISA 0x10
+/* WARNING: DO NOT EDIT, AUTO-GENERATED CODE - SEE TOP FOR INSTRUCTIONS */
 #define BUS_I8042 0x11
 #define BUS_XTKBD 0x12
 #define BUS_RS232 0x13
-/* WARNING: DO NOT EDIT, AUTO-GENERATED CODE - SEE TOP FOR INSTRUCTIONS */
 #define BUS_GAMEPORT 0x14
+/* WARNING: DO NOT EDIT, AUTO-GENERATED CODE - SEE TOP FOR INSTRUCTIONS */
 #define BUS_PARPORT 0x15
 #define BUS_AMIGA 0x16
 #define BUS_ADB 0x17
-/* WARNING: DO NOT EDIT, AUTO-GENERATED CODE - SEE TOP FOR INSTRUCTIONS */
 #define BUS_I2C 0x18
+/* WARNING: DO NOT EDIT, AUTO-GENERATED CODE - SEE TOP FOR INSTRUCTIONS */
 #define BUS_HOST 0x19
 #define BUS_GSC 0x1A
 #define BUS_ATARI 0x1B
-/* WARNING: DO NOT EDIT, AUTO-GENERATED CODE - SEE TOP FOR INSTRUCTIONS */
 #define BUS_SPI 0x1C
+/* WARNING: DO NOT EDIT, AUTO-GENERATED CODE - SEE TOP FOR INSTRUCTIONS */
 #define MT_TOOL_FINGER 0
 #define MT_TOOL_PEN 1
-#define MT_TOOL_MAX 1
+#define MT_TOOL_PALM 2
+#define MT_TOOL_MAX 2
 /* WARNING: DO NOT EDIT, AUTO-GENERATED CODE - SEE TOP FOR INSTRUCTIONS */
 #define FF_STATUS_STOPPED 0x00
 #define FF_STATUS_PLAYING 0x01
@@ -1063,7 +238,8 @@
 /* WARNING: DO NOT EDIT, AUTO-GENERATED CODE - SEE TOP FOR INSTRUCTIONS */
 #define FF_GAIN 0x60
 #define FF_AUTOCENTER 0x61
+#define FF_MAX_EFFECTS FF_GAIN
 #define FF_MAX 0x7f
-#define FF_CNT (FF_MAX + 1)
 /* WARNING: DO NOT EDIT, AUTO-GENERATED CODE - SEE TOP FOR INSTRUCTIONS */
+#define FF_CNT (FF_MAX + 1)
 #endif
diff --git a/libc/kernel/uapi/linux/ip.h b/libc/kernel/uapi/linux/ip.h
index 8567d24..a56f1d6 100644
--- a/libc/kernel/uapi/linux/ip.h
+++ b/libc/kernel/uapi/linux/ip.h
@@ -173,8 +173,9 @@
 /* WARNING: DO NOT EDIT, AUTO-GENERATED CODE - SEE TOP FOR INSTRUCTIONS */
   IPV4_DEVCONF_IGMPV2_UNSOLICITED_REPORT_INTERVAL,
   IPV4_DEVCONF_IGMPV3_UNSOLICITED_REPORT_INTERVAL,
+  IPV4_DEVCONF_IGNORE_ROUTES_WITH_LINKDOWN,
   __IPV4_DEVCONF_MAX
-};
 /* WARNING: DO NOT EDIT, AUTO-GENERATED CODE - SEE TOP FOR INSTRUCTIONS */
+};
 #define IPV4_DEVCONF_MAX (__IPV4_DEVCONF_MAX - 1)
 #endif
diff --git a/libc/kernel/uapi/linux/ip_vs.h b/libc/kernel/uapi/linux/ip_vs.h
index 2274c4d..2971861 100644
--- a/libc/kernel/uapi/linux/ip_vs.h
+++ b/libc/kernel/uapi/linux/ip_vs.h
@@ -268,66 +268,74 @@
 /* WARNING: DO NOT EDIT, AUTO-GENERATED CODE - SEE TOP FOR INSTRUCTIONS */
   IPVS_SVC_ATTR_STATS,
   IPVS_SVC_ATTR_PE_NAME,
+  IPVS_SVC_ATTR_STATS64,
   __IPVS_SVC_ATTR_MAX,
-};
 /* WARNING: DO NOT EDIT, AUTO-GENERATED CODE - SEE TOP FOR INSTRUCTIONS */
+};
 #define IPVS_SVC_ATTR_MAX (__IPVS_SVC_ATTR_MAX - 1)
 enum {
   IPVS_DEST_ATTR_UNSPEC = 0,
-  IPVS_DEST_ATTR_ADDR,
 /* WARNING: DO NOT EDIT, AUTO-GENERATED CODE - SEE TOP FOR INSTRUCTIONS */
+  IPVS_DEST_ATTR_ADDR,
   IPVS_DEST_ATTR_PORT,
   IPVS_DEST_ATTR_FWD_METHOD,
   IPVS_DEST_ATTR_WEIGHT,
-  IPVS_DEST_ATTR_U_THRESH,
 /* WARNING: DO NOT EDIT, AUTO-GENERATED CODE - SEE TOP FOR INSTRUCTIONS */
+  IPVS_DEST_ATTR_U_THRESH,
   IPVS_DEST_ATTR_L_THRESH,
   IPVS_DEST_ATTR_ACTIVE_CONNS,
   IPVS_DEST_ATTR_INACT_CONNS,
-  IPVS_DEST_ATTR_PERSIST_CONNS,
 /* WARNING: DO NOT EDIT, AUTO-GENERATED CODE - SEE TOP FOR INSTRUCTIONS */
+  IPVS_DEST_ATTR_PERSIST_CONNS,
   IPVS_DEST_ATTR_STATS,
   IPVS_DEST_ATTR_ADDR_FAMILY,
+  IPVS_DEST_ATTR_STATS64,
+/* WARNING: DO NOT EDIT, AUTO-GENERATED CODE - SEE TOP FOR INSTRUCTIONS */
   __IPVS_DEST_ATTR_MAX,
 };
-/* WARNING: DO NOT EDIT, AUTO-GENERATED CODE - SEE TOP FOR INSTRUCTIONS */
 #define IPVS_DEST_ATTR_MAX (__IPVS_DEST_ATTR_MAX - 1)
 enum {
+/* WARNING: DO NOT EDIT, AUTO-GENERATED CODE - SEE TOP FOR INSTRUCTIONS */
   IPVS_DAEMON_ATTR_UNSPEC = 0,
   IPVS_DAEMON_ATTR_STATE,
-/* WARNING: DO NOT EDIT, AUTO-GENERATED CODE - SEE TOP FOR INSTRUCTIONS */
   IPVS_DAEMON_ATTR_MCAST_IFN,
   IPVS_DAEMON_ATTR_SYNC_ID,
+/* WARNING: DO NOT EDIT, AUTO-GENERATED CODE - SEE TOP FOR INSTRUCTIONS */
+  IPVS_DAEMON_ATTR_SYNC_MAXLEN,
+  IPVS_DAEMON_ATTR_MCAST_GROUP,
+  IPVS_DAEMON_ATTR_MCAST_GROUP6,
+  IPVS_DAEMON_ATTR_MCAST_PORT,
+/* WARNING: DO NOT EDIT, AUTO-GENERATED CODE - SEE TOP FOR INSTRUCTIONS */
+  IPVS_DAEMON_ATTR_MCAST_TTL,
   __IPVS_DAEMON_ATTR_MAX,
 };
-/* WARNING: DO NOT EDIT, AUTO-GENERATED CODE - SEE TOP FOR INSTRUCTIONS */
 #define IPVS_DAEMON_ATTR_MAX (__IPVS_DAEMON_ATTR_MAX - 1)
+/* WARNING: DO NOT EDIT, AUTO-GENERATED CODE - SEE TOP FOR INSTRUCTIONS */
 enum {
   IPVS_STATS_ATTR_UNSPEC = 0,
   IPVS_STATS_ATTR_CONNS,
-/* WARNING: DO NOT EDIT, AUTO-GENERATED CODE - SEE TOP FOR INSTRUCTIONS */
   IPVS_STATS_ATTR_INPKTS,
+/* WARNING: DO NOT EDIT, AUTO-GENERATED CODE - SEE TOP FOR INSTRUCTIONS */
   IPVS_STATS_ATTR_OUTPKTS,
   IPVS_STATS_ATTR_INBYTES,
   IPVS_STATS_ATTR_OUTBYTES,
-/* WARNING: DO NOT EDIT, AUTO-GENERATED CODE - SEE TOP FOR INSTRUCTIONS */
   IPVS_STATS_ATTR_CPS,
+/* WARNING: DO NOT EDIT, AUTO-GENERATED CODE - SEE TOP FOR INSTRUCTIONS */
   IPVS_STATS_ATTR_INPPS,
   IPVS_STATS_ATTR_OUTPPS,
   IPVS_STATS_ATTR_INBPS,
-/* WARNING: DO NOT EDIT, AUTO-GENERATED CODE - SEE TOP FOR INSTRUCTIONS */
   IPVS_STATS_ATTR_OUTBPS,
+/* WARNING: DO NOT EDIT, AUTO-GENERATED CODE - SEE TOP FOR INSTRUCTIONS */
   __IPVS_STATS_ATTR_MAX,
 };
 #define IPVS_STATS_ATTR_MAX (__IPVS_STATS_ATTR_MAX - 1)
-/* WARNING: DO NOT EDIT, AUTO-GENERATED CODE - SEE TOP FOR INSTRUCTIONS */
 enum {
+/* WARNING: DO NOT EDIT, AUTO-GENERATED CODE - SEE TOP FOR INSTRUCTIONS */
   IPVS_INFO_ATTR_UNSPEC = 0,
   IPVS_INFO_ATTR_VERSION,
   IPVS_INFO_ATTR_CONN_TAB_SIZE,
-/* WARNING: DO NOT EDIT, AUTO-GENERATED CODE - SEE TOP FOR INSTRUCTIONS */
   __IPVS_INFO_ATTR_MAX,
+/* WARNING: DO NOT EDIT, AUTO-GENERATED CODE - SEE TOP FOR INSTRUCTIONS */
 };
 #define IPVS_INFO_ATTR_MAX (__IPVS_INFO_ATTR_MAX - 1)
 #endif
-/* WARNING: DO NOT EDIT, AUTO-GENERATED CODE - SEE TOP FOR INSTRUCTIONS */
diff --git a/libc/kernel/uapi/linux/ipv6.h b/libc/kernel/uapi/linux/ipv6.h
index 3425f5a..24d5743 100644
--- a/libc/kernel/uapi/linux/ipv6.h
+++ b/libc/kernel/uapi/linux/ipv6.h
@@ -18,132 +18,146 @@
  ****************************************************************************/
 #ifndef _UAPI_IPV6_H
 #define _UAPI_IPV6_H
+#include <linux/libc-compat.h>
 #include <linux/types.h>
-#include <linux/in6.h>
 /* WARNING: DO NOT EDIT, AUTO-GENERATED CODE - SEE TOP FOR INSTRUCTIONS */
+#include <linux/in6.h>
 #include <asm/byteorder.h>
 #define IPV6_MIN_MTU 1280
+#if __UAPI_DEF_IN6_PKTINFO
+/* WARNING: DO NOT EDIT, AUTO-GENERATED CODE - SEE TOP FOR INSTRUCTIONS */
 struct in6_pktinfo {
   struct in6_addr ipi6_addr;
-/* WARNING: DO NOT EDIT, AUTO-GENERATED CODE - SEE TOP FOR INSTRUCTIONS */
   int ipi6_ifindex;
 };
+/* WARNING: DO NOT EDIT, AUTO-GENERATED CODE - SEE TOP FOR INSTRUCTIONS */
+#endif
+#if __UAPI_DEF_IP6_MTUINFO
 struct ip6_mtuinfo {
   struct sockaddr_in6 ip6m_addr;
 /* WARNING: DO NOT EDIT, AUTO-GENERATED CODE - SEE TOP FOR INSTRUCTIONS */
   __u32 ip6m_mtu;
 };
+#endif
 struct in6_ifreq {
-  struct in6_addr ifr6_addr;
 /* WARNING: DO NOT EDIT, AUTO-GENERATED CODE - SEE TOP FOR INSTRUCTIONS */
+  struct in6_addr ifr6_addr;
   __u32 ifr6_prefixlen;
   int ifr6_ifindex;
 };
-#define IPV6_SRCRT_STRICT 0x01
 /* WARNING: DO NOT EDIT, AUTO-GENERATED CODE - SEE TOP FOR INSTRUCTIONS */
+#define IPV6_SRCRT_STRICT 0x01
 #define IPV6_SRCRT_TYPE_0 0
 #define IPV6_SRCRT_TYPE_2 2
 struct ipv6_rt_hdr {
-  __u8 nexthdr;
 /* WARNING: DO NOT EDIT, AUTO-GENERATED CODE - SEE TOP FOR INSTRUCTIONS */
+  __u8 nexthdr;
   __u8 hdrlen;
   __u8 type;
   __u8 segments_left;
-};
 /* WARNING: DO NOT EDIT, AUTO-GENERATED CODE - SEE TOP FOR INSTRUCTIONS */
+};
 struct ipv6_opt_hdr {
   __u8 nexthdr;
   __u8 hdrlen;
-} __attribute__((packed));
 /* WARNING: DO NOT EDIT, AUTO-GENERATED CODE - SEE TOP FOR INSTRUCTIONS */
+} __attribute__((packed));
 #define ipv6_destopt_hdr ipv6_opt_hdr
 #define ipv6_hopopt_hdr ipv6_opt_hdr
 #define IPV6_OPT_ROUTERALERT_MLD 0x0000
-struct rt0_hdr {
 /* WARNING: DO NOT EDIT, AUTO-GENERATED CODE - SEE TOP FOR INSTRUCTIONS */
+struct rt0_hdr {
   struct ipv6_rt_hdr rt_hdr;
   __u32 reserved;
   struct in6_addr addr[0];
-#define rt0_type rt_hdr.type
 /* WARNING: DO NOT EDIT, AUTO-GENERATED CODE - SEE TOP FOR INSTRUCTIONS */
+#define rt0_type rt_hdr.type
 };
 struct rt2_hdr {
   struct ipv6_rt_hdr rt_hdr;
-  __u32 reserved;
 /* WARNING: DO NOT EDIT, AUTO-GENERATED CODE - SEE TOP FOR INSTRUCTIONS */
+  __u32 reserved;
   struct in6_addr addr;
 #define rt2_type rt_hdr.type
 };
-struct ipv6_destopt_hao {
 /* WARNING: DO NOT EDIT, AUTO-GENERATED CODE - SEE TOP FOR INSTRUCTIONS */
+struct ipv6_destopt_hao {
   __u8 type;
   __u8 length;
   struct in6_addr addr;
-} __attribute__((packed));
 /* WARNING: DO NOT EDIT, AUTO-GENERATED CODE - SEE TOP FOR INSTRUCTIONS */
+} __attribute__((packed));
 struct ipv6hdr {
 #ifdef __LITTLE_ENDIAN_BITFIELD
   __u8 priority : 4, version : 4;
-#elif defined(__BIG_ENDIAN_BITFIELD)
 /* WARNING: DO NOT EDIT, AUTO-GENERATED CODE - SEE TOP FOR INSTRUCTIONS */
+#elif defined(__BIG_ENDIAN_BITFIELD)
   __u8 version : 4, priority : 4;
 #else
 #error "Please fix <asm/byteorder.h>"
-#endif
 /* WARNING: DO NOT EDIT, AUTO-GENERATED CODE - SEE TOP FOR INSTRUCTIONS */
+#endif
   __u8 flow_lbl[3];
   __be16 payload_len;
   __u8 nexthdr;
-  __u8 hop_limit;
 /* WARNING: DO NOT EDIT, AUTO-GENERATED CODE - SEE TOP FOR INSTRUCTIONS */
+  __u8 hop_limit;
   struct in6_addr saddr;
   struct in6_addr daddr;
 };
-enum {
 /* WARNING: DO NOT EDIT, AUTO-GENERATED CODE - SEE TOP FOR INSTRUCTIONS */
+enum {
   DEVCONF_FORWARDING = 0,
   DEVCONF_HOPLIMIT,
   DEVCONF_MTU6,
-  DEVCONF_ACCEPT_RA,
 /* WARNING: DO NOT EDIT, AUTO-GENERATED CODE - SEE TOP FOR INSTRUCTIONS */
+  DEVCONF_ACCEPT_RA,
   DEVCONF_ACCEPT_REDIRECTS,
   DEVCONF_AUTOCONF,
   DEVCONF_DAD_TRANSMITS,
-  DEVCONF_RTR_SOLICITS,
 /* WARNING: DO NOT EDIT, AUTO-GENERATED CODE - SEE TOP FOR INSTRUCTIONS */
+  DEVCONF_RTR_SOLICITS,
   DEVCONF_RTR_SOLICIT_INTERVAL,
   DEVCONF_RTR_SOLICIT_DELAY,
   DEVCONF_USE_TEMPADDR,
-  DEVCONF_TEMP_VALID_LFT,
 /* WARNING: DO NOT EDIT, AUTO-GENERATED CODE - SEE TOP FOR INSTRUCTIONS */
+  DEVCONF_TEMP_VALID_LFT,
   DEVCONF_TEMP_PREFERED_LFT,
   DEVCONF_REGEN_MAX_RETRY,
   DEVCONF_MAX_DESYNC_FACTOR,
-  DEVCONF_MAX_ADDRESSES,
 /* WARNING: DO NOT EDIT, AUTO-GENERATED CODE - SEE TOP FOR INSTRUCTIONS */
+  DEVCONF_MAX_ADDRESSES,
   DEVCONF_FORCE_MLD_VERSION,
   DEVCONF_ACCEPT_RA_DEFRTR,
   DEVCONF_ACCEPT_RA_PINFO,
-  DEVCONF_ACCEPT_RA_RTR_PREF,
 /* WARNING: DO NOT EDIT, AUTO-GENERATED CODE - SEE TOP FOR INSTRUCTIONS */
+  DEVCONF_ACCEPT_RA_RTR_PREF,
   DEVCONF_RTR_PROBE_INTERVAL,
   DEVCONF_ACCEPT_RA_RT_INFO_MAX_PLEN,
   DEVCONF_PROXY_NDP,
-  DEVCONF_OPTIMISTIC_DAD,
 /* WARNING: DO NOT EDIT, AUTO-GENERATED CODE - SEE TOP FOR INSTRUCTIONS */
+  DEVCONF_OPTIMISTIC_DAD,
   DEVCONF_ACCEPT_SOURCE_ROUTE,
   DEVCONF_MC_FORWARDING,
   DEVCONF_DISABLE_IPV6,
-  DEVCONF_ACCEPT_DAD,
 /* WARNING: DO NOT EDIT, AUTO-GENERATED CODE - SEE TOP FOR INSTRUCTIONS */
+  DEVCONF_ACCEPT_DAD,
   DEVCONF_FORCE_TLLAO,
   DEVCONF_NDISC_NOTIFY,
   DEVCONF_MLDV1_UNSOLICITED_REPORT_INTERVAL,
-  DEVCONF_MLDV2_UNSOLICITED_REPORT_INTERVAL,
 /* WARNING: DO NOT EDIT, AUTO-GENERATED CODE - SEE TOP FOR INSTRUCTIONS */
+  DEVCONF_MLDV2_UNSOLICITED_REPORT_INTERVAL,
   DEVCONF_SUPPRESS_FRAG_NDISC,
   DEVCONF_ACCEPT_RA_FROM_LOCAL,
+  DEVCONF_USE_OPTIMISTIC,
+/* WARNING: DO NOT EDIT, AUTO-GENERATED CODE - SEE TOP FOR INSTRUCTIONS */
+  DEVCONF_ACCEPT_RA_MTU,
+  DEVCONF_STABLE_SECRET,
+  DEVCONF_USE_OIF_ADDRS_ONLY,
+  DEVCONF_ACCEPT_RA_MIN_HOP_LIMIT,
+/* WARNING: DO NOT EDIT, AUTO-GENERATED CODE - SEE TOP FOR INSTRUCTIONS */
+  DEVCONF_IGNORE_ROUTES_WITH_LINKDOWN,
   DEVCONF_MAX
 };
-/* WARNING: DO NOT EDIT, AUTO-GENERATED CODE - SEE TOP FOR INSTRUCTIONS */
 #endif
+/* WARNING: DO NOT EDIT, AUTO-GENERATED CODE - SEE TOP FOR INSTRUCTIONS */
diff --git a/libc/kernel/uapi/linux/ipv6_route.h b/libc/kernel/uapi/linux/ipv6_route.h
index ff74986..776ad72 100644
--- a/libc/kernel/uapi/linux/ipv6_route.h
+++ b/libc/kernel/uapi/linux/ipv6_route.h
@@ -36,28 +36,29 @@
 #define RTF_PREF(pref) ((pref) << 27)
 #define RTF_PREF_MASK 0x18000000
 /* WARNING: DO NOT EDIT, AUTO-GENERATED CODE - SEE TOP FOR INSTRUCTIONS */
+#define RTF_PCPU 0x40000000
 #define RTF_LOCAL 0x80000000
 struct in6_rtmsg {
   struct in6_addr rtmsg_dst;
-  struct in6_addr rtmsg_src;
 /* WARNING: DO NOT EDIT, AUTO-GENERATED CODE - SEE TOP FOR INSTRUCTIONS */
+  struct in6_addr rtmsg_src;
   struct in6_addr rtmsg_gateway;
   __u32 rtmsg_type;
   __u16 rtmsg_dst_len;
-  __u16 rtmsg_src_len;
 /* WARNING: DO NOT EDIT, AUTO-GENERATED CODE - SEE TOP FOR INSTRUCTIONS */
+  __u16 rtmsg_src_len;
   __u32 rtmsg_metric;
   unsigned long rtmsg_info;
   __u32 rtmsg_flags;
-  int rtmsg_ifindex;
 /* WARNING: DO NOT EDIT, AUTO-GENERATED CODE - SEE TOP FOR INSTRUCTIONS */
+  int rtmsg_ifindex;
 };
 #define RTMSG_NEWDEVICE 0x11
 #define RTMSG_DELDEVICE 0x12
-#define RTMSG_NEWROUTE 0x21
 /* WARNING: DO NOT EDIT, AUTO-GENERATED CODE - SEE TOP FOR INSTRUCTIONS */
+#define RTMSG_NEWROUTE 0x21
 #define RTMSG_DELROUTE 0x22
 #define IP6_RT_PRIO_USER 1024
 #define IP6_RT_PRIO_ADDRCONF 256
-#endif
 /* WARNING: DO NOT EDIT, AUTO-GENERATED CODE - SEE TOP FOR INSTRUCTIONS */
+#endif
diff --git a/libc/kernel/uapi/linux/kcmp.h b/libc/kernel/uapi/linux/kcmp.h
new file mode 100644
index 0000000..5937056
--- /dev/null
+++ b/libc/kernel/uapi/linux/kcmp.h
@@ -0,0 +1,34 @@
+/****************************************************************************
+ ****************************************************************************
+ ***
+ ***   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_KCMP_H
+#define _UAPI_LINUX_KCMP_H
+enum kcmp_type {
+  KCMP_FILE,
+/* WARNING: DO NOT EDIT, AUTO-GENERATED CODE - SEE TOP FOR INSTRUCTIONS */
+  KCMP_VM,
+  KCMP_FILES,
+  KCMP_FS,
+  KCMP_SIGHAND,
+/* WARNING: DO NOT EDIT, AUTO-GENERATED CODE - SEE TOP FOR INSTRUCTIONS */
+  KCMP_IO,
+  KCMP_SYSVSEM,
+  KCMP_TYPES,
+};
+/* WARNING: DO NOT EDIT, AUTO-GENERATED CODE - SEE TOP FOR INSTRUCTIONS */
+#endif
diff --git a/libc/kernel/uapi/linux/kernel-page-flags.h b/libc/kernel/uapi/linux/kernel-page-flags.h
index ce30be7..7e34fe4 100644
--- a/libc/kernel/uapi/linux/kernel-page-flags.h
+++ b/libc/kernel/uapi/linux/kernel-page-flags.h
@@ -48,4 +48,7 @@
 /* WARNING: DO NOT EDIT, AUTO-GENERATED CODE - SEE TOP FOR INSTRUCTIONS */
 #define KPF_THP 22
 #define KPF_BALLOON 23
+#define KPF_ZERO_PAGE 24
+#define KPF_IDLE 25
+/* WARNING: DO NOT EDIT, AUTO-GENERATED CODE - SEE TOP FOR INSTRUCTIONS */
 #endif
diff --git a/libc/kernel/uapi/linux/kfd_ioctl.h b/libc/kernel/uapi/linux/kfd_ioctl.h
new file mode 100644
index 0000000..f0d8a3d
--- /dev/null
+++ b/libc/kernel/uapi/linux/kfd_ioctl.h
@@ -0,0 +1,245 @@
+/****************************************************************************
+ ****************************************************************************
+ ***
+ ***   This header was automatically generated from a Linux kernel header
+ ***   of the same name, to make information necessary for userspace to
+ ***   call into the kernel available to libc.  It contains only constants,
+ ***   structures, and macros generated from the original header, and thus,
+ ***   contains no copyrightable information.
+ ***
+ ***   To edit the content of this header, modify the corresponding
+ ***   source file (e.g. under external/kernel-headers/original/) then
+ ***   run bionic/libc/kernel/tools/update_all.py
+ ***
+ ***   Any manual change here will be lost the next time this script will
+ ***   be run. You've been warned!
+ ***
+ ****************************************************************************
+ ****************************************************************************/
+#ifndef KFD_IOCTL_H_INCLUDED
+#define KFD_IOCTL_H_INCLUDED
+#include <linux/types.h>
+#include <linux/ioctl.h>
+/* WARNING: DO NOT EDIT, AUTO-GENERATED CODE - SEE TOP FOR INSTRUCTIONS */
+#define KFD_IOCTL_MAJOR_VERSION 1
+#define KFD_IOCTL_MINOR_VERSION 1
+struct kfd_ioctl_get_version_args {
+  uint32_t major_version;
+/* WARNING: DO NOT EDIT, AUTO-GENERATED CODE - SEE TOP FOR INSTRUCTIONS */
+  uint32_t minor_version;
+};
+#define KFD_IOC_QUEUE_TYPE_COMPUTE 0
+#define KFD_IOC_QUEUE_TYPE_SDMA 1
+/* WARNING: DO NOT EDIT, AUTO-GENERATED CODE - SEE TOP FOR INSTRUCTIONS */
+#define KFD_IOC_QUEUE_TYPE_COMPUTE_AQL 2
+#define KFD_MAX_QUEUE_PERCENTAGE 100
+#define KFD_MAX_QUEUE_PRIORITY 15
+struct kfd_ioctl_create_queue_args {
+/* WARNING: DO NOT EDIT, AUTO-GENERATED CODE - SEE TOP FOR INSTRUCTIONS */
+  uint64_t ring_base_address;
+  uint64_t write_pointer_address;
+  uint64_t read_pointer_address;
+  uint64_t doorbell_offset;
+/* WARNING: DO NOT EDIT, AUTO-GENERATED CODE - SEE TOP FOR INSTRUCTIONS */
+  uint32_t ring_size;
+  uint32_t gpu_id;
+  uint32_t queue_type;
+  uint32_t queue_percentage;
+/* WARNING: DO NOT EDIT, AUTO-GENERATED CODE - SEE TOP FOR INSTRUCTIONS */
+  uint32_t queue_priority;
+  uint32_t queue_id;
+  uint64_t eop_buffer_address;
+  uint64_t eop_buffer_size;
+/* WARNING: DO NOT EDIT, AUTO-GENERATED CODE - SEE TOP FOR INSTRUCTIONS */
+  uint64_t ctx_save_restore_address;
+  uint64_t ctx_save_restore_size;
+};
+struct kfd_ioctl_destroy_queue_args {
+/* WARNING: DO NOT EDIT, AUTO-GENERATED CODE - SEE TOP FOR INSTRUCTIONS */
+  uint32_t queue_id;
+  uint32_t pad;
+};
+struct kfd_ioctl_update_queue_args {
+/* WARNING: DO NOT EDIT, AUTO-GENERATED CODE - SEE TOP FOR INSTRUCTIONS */
+  uint64_t ring_base_address;
+  uint32_t queue_id;
+  uint32_t ring_size;
+  uint32_t queue_percentage;
+/* WARNING: DO NOT EDIT, AUTO-GENERATED CODE - SEE TOP FOR INSTRUCTIONS */
+  uint32_t queue_priority;
+};
+#define KFD_IOC_CACHE_POLICY_COHERENT 0
+#define KFD_IOC_CACHE_POLICY_NONCOHERENT 1
+/* WARNING: DO NOT EDIT, AUTO-GENERATED CODE - SEE TOP FOR INSTRUCTIONS */
+struct kfd_ioctl_set_memory_policy_args {
+  uint64_t alternate_aperture_base;
+  uint64_t alternate_aperture_size;
+  uint32_t gpu_id;
+/* WARNING: DO NOT EDIT, AUTO-GENERATED CODE - SEE TOP FOR INSTRUCTIONS */
+  uint32_t default_policy;
+  uint32_t alternate_policy;
+  uint32_t pad;
+};
+/* WARNING: DO NOT EDIT, AUTO-GENERATED CODE - SEE TOP FOR INSTRUCTIONS */
+struct kfd_ioctl_get_clock_counters_args {
+  uint64_t gpu_clock_counter;
+  uint64_t cpu_clock_counter;
+  uint64_t system_clock_counter;
+/* WARNING: DO NOT EDIT, AUTO-GENERATED CODE - SEE TOP FOR INSTRUCTIONS */
+  uint64_t system_clock_freq;
+  uint32_t gpu_id;
+  uint32_t pad;
+};
+/* WARNING: DO NOT EDIT, AUTO-GENERATED CODE - SEE TOP FOR INSTRUCTIONS */
+#define NUM_OF_SUPPORTED_GPUS 7
+struct kfd_process_device_apertures {
+  uint64_t lds_base;
+  uint64_t lds_limit;
+/* WARNING: DO NOT EDIT, AUTO-GENERATED CODE - SEE TOP FOR INSTRUCTIONS */
+  uint64_t scratch_base;
+  uint64_t scratch_limit;
+  uint64_t gpuvm_base;
+  uint64_t gpuvm_limit;
+/* WARNING: DO NOT EDIT, AUTO-GENERATED CODE - SEE TOP FOR INSTRUCTIONS */
+  uint32_t gpu_id;
+  uint32_t pad;
+};
+struct kfd_ioctl_get_process_apertures_args {
+/* WARNING: DO NOT EDIT, AUTO-GENERATED CODE - SEE TOP FOR INSTRUCTIONS */
+  struct kfd_process_device_apertures process_apertures[NUM_OF_SUPPORTED_GPUS];
+  uint32_t num_of_nodes;
+  uint32_t pad;
+};
+/* WARNING: DO NOT EDIT, AUTO-GENERATED CODE - SEE TOP FOR INSTRUCTIONS */
+#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 {
+/* WARNING: DO NOT EDIT, AUTO-GENERATED CODE - SEE TOP FOR INSTRUCTIONS */
+  uint32_t gpu_id;
+  uint32_t pad;
+};
+struct kfd_ioctl_dbg_unregister_args {
+/* WARNING: DO NOT EDIT, AUTO-GENERATED CODE - SEE TOP FOR INSTRUCTIONS */
+  uint32_t gpu_id;
+  uint32_t pad;
+};
+struct kfd_ioctl_dbg_address_watch_args {
+/* WARNING: DO NOT EDIT, AUTO-GENERATED CODE - SEE TOP FOR INSTRUCTIONS */
+  uint64_t content_ptr;
+  uint32_t gpu_id;
+  uint32_t buf_size_in_bytes;
+};
+/* WARNING: DO NOT EDIT, AUTO-GENERATED CODE - SEE TOP FOR INSTRUCTIONS */
+struct kfd_ioctl_dbg_wave_control_args {
+  uint64_t content_ptr;
+  uint32_t gpu_id;
+  uint32_t buf_size_in_bytes;
+/* WARNING: DO NOT EDIT, AUTO-GENERATED CODE - SEE TOP FOR INSTRUCTIONS */
+};
+#define KFD_IOC_EVENT_SIGNAL 0
+#define KFD_IOC_EVENT_NODECHANGE 1
+#define KFD_IOC_EVENT_DEVICESTATECHANGE 2
+/* WARNING: DO NOT EDIT, AUTO-GENERATED CODE - SEE TOP FOR INSTRUCTIONS */
+#define KFD_IOC_EVENT_HW_EXCEPTION 3
+#define KFD_IOC_EVENT_SYSTEM_EVENT 4
+#define KFD_IOC_EVENT_DEBUG_EVENT 5
+#define KFD_IOC_EVENT_PROFILE_EVENT 6
+/* WARNING: DO NOT EDIT, AUTO-GENERATED CODE - SEE TOP FOR INSTRUCTIONS */
+#define KFD_IOC_EVENT_QUEUE_EVENT 7
+#define KFD_IOC_EVENT_MEMORY 8
+#define KFD_IOC_WAIT_RESULT_COMPLETE 0
+#define KFD_IOC_WAIT_RESULT_TIMEOUT 1
+/* WARNING: DO NOT EDIT, AUTO-GENERATED CODE - SEE TOP FOR INSTRUCTIONS */
+#define KFD_IOC_WAIT_RESULT_FAIL 2
+#define KFD_SIGNAL_EVENT_LIMIT 256
+struct kfd_ioctl_create_event_args {
+  uint64_t event_page_offset;
+/* WARNING: DO NOT EDIT, AUTO-GENERATED CODE - SEE TOP FOR INSTRUCTIONS */
+  uint32_t event_trigger_data;
+  uint32_t event_type;
+  uint32_t auto_reset;
+  uint32_t node_id;
+/* WARNING: DO NOT EDIT, AUTO-GENERATED CODE - SEE TOP FOR INSTRUCTIONS */
+  uint32_t event_id;
+  uint32_t event_slot_index;
+};
+struct kfd_ioctl_destroy_event_args {
+/* WARNING: DO NOT EDIT, AUTO-GENERATED CODE - SEE TOP FOR INSTRUCTIONS */
+  uint32_t event_id;
+  uint32_t pad;
+};
+struct kfd_ioctl_set_event_args {
+/* WARNING: DO NOT EDIT, AUTO-GENERATED CODE - SEE TOP FOR INSTRUCTIONS */
+  uint32_t event_id;
+  uint32_t pad;
+};
+struct kfd_ioctl_reset_event_args {
+/* WARNING: DO NOT EDIT, AUTO-GENERATED CODE - SEE TOP FOR INSTRUCTIONS */
+  uint32_t event_id;
+  uint32_t pad;
+};
+struct kfd_memory_exception_failure {
+/* WARNING: DO NOT EDIT, AUTO-GENERATED CODE - SEE TOP FOR INSTRUCTIONS */
+  uint32_t NotPresent;
+  uint32_t ReadOnly;
+  uint32_t NoExecute;
+  uint32_t pad;
+/* WARNING: DO NOT EDIT, AUTO-GENERATED CODE - SEE TOP FOR INSTRUCTIONS */
+};
+struct kfd_hsa_memory_exception_data {
+  struct kfd_memory_exception_failure failure;
+  uint64_t va;
+/* WARNING: DO NOT EDIT, AUTO-GENERATED CODE - SEE TOP FOR INSTRUCTIONS */
+  uint32_t gpu_id;
+  uint32_t pad;
+};
+struct kfd_event_data {
+/* WARNING: DO NOT EDIT, AUTO-GENERATED CODE - SEE TOP FOR INSTRUCTIONS */
+  union {
+    struct kfd_hsa_memory_exception_data memory_exception_data;
+  };
+  uint64_t kfd_event_data_ext;
+/* WARNING: DO NOT EDIT, AUTO-GENERATED CODE - SEE TOP FOR INSTRUCTIONS */
+  uint32_t event_id;
+  uint32_t pad;
+};
+struct kfd_ioctl_wait_events_args {
+/* WARNING: DO NOT EDIT, AUTO-GENERATED CODE - SEE TOP FOR INSTRUCTIONS */
+  uint64_t events_ptr;
+  uint32_t num_events;
+  uint32_t wait_for_all;
+  uint32_t timeout;
+/* WARNING: DO NOT EDIT, AUTO-GENERATED CODE - SEE TOP FOR INSTRUCTIONS */
+  uint32_t wait_result;
+};
+#define AMDKFD_IOCTL_BASE 'K'
+#define AMDKFD_IO(nr) _IO(AMDKFD_IOCTL_BASE, nr)
+/* WARNING: DO NOT EDIT, AUTO-GENERATED CODE - SEE TOP FOR INSTRUCTIONS */
+#define AMDKFD_IOR(nr,type) _IOR(AMDKFD_IOCTL_BASE, nr, type)
+#define AMDKFD_IOW(nr,type) _IOW(AMDKFD_IOCTL_BASE, nr, type)
+#define AMDKFD_IOWR(nr,type) _IOWR(AMDKFD_IOCTL_BASE, nr, type)
+#define AMDKFD_IOC_GET_VERSION AMDKFD_IOR(0x01, struct kfd_ioctl_get_version_args)
+/* WARNING: DO NOT EDIT, AUTO-GENERATED CODE - SEE TOP FOR INSTRUCTIONS */
+#define AMDKFD_IOC_CREATE_QUEUE AMDKFD_IOWR(0x02, struct kfd_ioctl_create_queue_args)
+#define AMDKFD_IOC_DESTROY_QUEUE AMDKFD_IOWR(0x03, struct kfd_ioctl_destroy_queue_args)
+#define AMDKFD_IOC_SET_MEMORY_POLICY AMDKFD_IOW(0x04, struct kfd_ioctl_set_memory_policy_args)
+#define AMDKFD_IOC_GET_CLOCK_COUNTERS AMDKFD_IOWR(0x05, struct kfd_ioctl_get_clock_counters_args)
+/* WARNING: DO NOT EDIT, AUTO-GENERATED CODE - SEE TOP FOR INSTRUCTIONS */
+#define AMDKFD_IOC_GET_PROCESS_APERTURES AMDKFD_IOR(0x06, struct kfd_ioctl_get_process_apertures_args)
+#define AMDKFD_IOC_UPDATE_QUEUE AMDKFD_IOW(0x07, struct kfd_ioctl_update_queue_args)
+#define AMDKFD_IOC_CREATE_EVENT AMDKFD_IOWR(0x08, struct kfd_ioctl_create_event_args)
+#define AMDKFD_IOC_DESTROY_EVENT AMDKFD_IOW(0x09, struct kfd_ioctl_destroy_event_args)
+/* WARNING: DO NOT EDIT, AUTO-GENERATED CODE - SEE TOP FOR INSTRUCTIONS */
+#define AMDKFD_IOC_SET_EVENT AMDKFD_IOW(0x0A, struct kfd_ioctl_set_event_args)
+#define AMDKFD_IOC_RESET_EVENT AMDKFD_IOW(0x0B, struct kfd_ioctl_reset_event_args)
+#define AMDKFD_IOC_WAIT_EVENTS AMDKFD_IOWR(0x0C, struct kfd_ioctl_wait_events_args)
+#define AMDKFD_IOC_DBG_REGISTER AMDKFD_IOW(0x0D, struct kfd_ioctl_dbg_register_args)
+/* WARNING: DO NOT EDIT, AUTO-GENERATED CODE - SEE TOP FOR INSTRUCTIONS */
+#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_COMMAND_START 0x01
+/* WARNING: DO NOT EDIT, AUTO-GENERATED CODE - SEE TOP FOR INSTRUCTIONS */
+#define AMDKFD_COMMAND_END 0x11
+#endif
diff --git a/libc/kernel/uapi/linux/kvm.h b/libc/kernel/uapi/linux/kvm.h
index 870fa66..c227904 100644
--- a/libc/kernel/uapi/linux/kvm.h
+++ b/libc/kernel/uapi/linux/kvm.h
@@ -141,212 +141,257 @@
 };
 #define KVM_PIT_SPEAKER_DUMMY 1
 /* WARNING: DO NOT EDIT, AUTO-GENERATED CODE - SEE TOP FOR INSTRUCTIONS */
+struct kvm_s390_skeys {
+  __u64 start_gfn;
+  __u64 count;
+  __u64 skeydata_addr;
+/* WARNING: DO NOT EDIT, AUTO-GENERATED CODE - SEE TOP FOR INSTRUCTIONS */
+  __u32 flags;
+  __u32 reserved[9];
+};
+#define KVM_S390_GET_SKEYS_NONE 1
+/* WARNING: DO NOT EDIT, AUTO-GENERATED CODE - SEE TOP FOR INSTRUCTIONS */
+#define KVM_S390_SKEYS_MAX 1048576
 #define KVM_EXIT_UNKNOWN 0
 #define KVM_EXIT_EXCEPTION 1
 #define KVM_EXIT_IO 2
-#define KVM_EXIT_HYPERCALL 3
 /* WARNING: DO NOT EDIT, AUTO-GENERATED CODE - SEE TOP FOR INSTRUCTIONS */
+#define KVM_EXIT_HYPERCALL 3
 #define KVM_EXIT_DEBUG 4
 #define KVM_EXIT_HLT 5
 #define KVM_EXIT_MMIO 6
-#define KVM_EXIT_IRQ_WINDOW_OPEN 7
 /* WARNING: DO NOT EDIT, AUTO-GENERATED CODE - SEE TOP FOR INSTRUCTIONS */
+#define KVM_EXIT_IRQ_WINDOW_OPEN 7
 #define KVM_EXIT_SHUTDOWN 8
 #define KVM_EXIT_FAIL_ENTRY 9
 #define KVM_EXIT_INTR 10
-#define KVM_EXIT_SET_TPR 11
 /* WARNING: DO NOT EDIT, AUTO-GENERATED CODE - SEE TOP FOR INSTRUCTIONS */
+#define KVM_EXIT_SET_TPR 11
 #define KVM_EXIT_TPR_ACCESS 12
 #define KVM_EXIT_S390_SIEIC 13
 #define KVM_EXIT_S390_RESET 14
-#define KVM_EXIT_DCR 15
 /* WARNING: DO NOT EDIT, AUTO-GENERATED CODE - SEE TOP FOR INSTRUCTIONS */
+#define KVM_EXIT_DCR 15
 #define KVM_EXIT_NMI 16
 #define KVM_EXIT_INTERNAL_ERROR 17
 #define KVM_EXIT_OSI 18
-#define KVM_EXIT_PAPR_HCALL 19
 /* WARNING: DO NOT EDIT, AUTO-GENERATED CODE - SEE TOP FOR INSTRUCTIONS */
+#define KVM_EXIT_PAPR_HCALL 19
 #define KVM_EXIT_S390_UCONTROL 20
 #define KVM_EXIT_WATCHDOG 21
 #define KVM_EXIT_S390_TSCH 22
-#define KVM_EXIT_EPR 23
 /* WARNING: DO NOT EDIT, AUTO-GENERATED CODE - SEE TOP FOR INSTRUCTIONS */
+#define KVM_EXIT_EPR 23
 #define KVM_EXIT_SYSTEM_EVENT 24
+#define KVM_EXIT_S390_STSI 25
+#define KVM_EXIT_IOAPIC_EOI 26
+/* WARNING: DO NOT EDIT, AUTO-GENERATED CODE - SEE TOP FOR INSTRUCTIONS */
 #define KVM_INTERNAL_ERROR_EMULATION 1
 #define KVM_INTERNAL_ERROR_SIMUL_EX 2
 #define KVM_INTERNAL_ERROR_DELIVERY_EV 3
-/* WARNING: DO NOT EDIT, AUTO-GENERATED CODE - SEE TOP FOR INSTRUCTIONS */
 struct kvm_run {
+/* WARNING: DO NOT EDIT, AUTO-GENERATED CODE - SEE TOP FOR INSTRUCTIONS */
   __u8 request_interrupt_window;
   __u8 padding1[7];
   __u32 exit_reason;
-/* WARNING: DO NOT EDIT, AUTO-GENERATED CODE - SEE TOP FOR INSTRUCTIONS */
   __u8 ready_for_interrupt_injection;
-  __u8 if_flag;
-  __u8 padding2[2];
-  __u64 cr8;
 /* WARNING: DO NOT EDIT, AUTO-GENERATED CODE - SEE TOP FOR INSTRUCTIONS */
+  __u8 if_flag;
+  __u16 flags;
+  __u64 cr8;
   __u64 apic_base;
+/* WARNING: DO NOT EDIT, AUTO-GENERATED CODE - SEE TOP FOR INSTRUCTIONS */
 #ifdef __KVM_S390
   __u64 psw_mask;
   __u64 psw_addr;
-/* WARNING: DO NOT EDIT, AUTO-GENERATED CODE - SEE TOP FOR INSTRUCTIONS */
 #endif
+/* WARNING: DO NOT EDIT, AUTO-GENERATED CODE - SEE TOP FOR INSTRUCTIONS */
   union {
     struct {
       __u64 hardware_exit_reason;
-/* WARNING: DO NOT EDIT, AUTO-GENERATED CODE - SEE TOP FOR INSTRUCTIONS */
     } hw;
+/* WARNING: DO NOT EDIT, AUTO-GENERATED CODE - SEE TOP FOR INSTRUCTIONS */
     struct {
       __u64 hardware_entry_failure_reason;
     } fail_entry;
-/* WARNING: DO NOT EDIT, AUTO-GENERATED CODE - SEE TOP FOR INSTRUCTIONS */
     struct {
+/* WARNING: DO NOT EDIT, AUTO-GENERATED CODE - SEE TOP FOR INSTRUCTIONS */
       __u32 exception;
       __u32 error_code;
     } ex;
-/* WARNING: DO NOT EDIT, AUTO-GENERATED CODE - SEE TOP FOR INSTRUCTIONS */
     struct {
+/* WARNING: DO NOT EDIT, AUTO-GENERATED CODE - SEE TOP FOR INSTRUCTIONS */
 #define KVM_EXIT_IO_IN 0
 #define KVM_EXIT_IO_OUT 1
       __u8 direction;
-/* WARNING: DO NOT EDIT, AUTO-GENERATED CODE - SEE TOP FOR INSTRUCTIONS */
       __u8 size;
+/* WARNING: DO NOT EDIT, AUTO-GENERATED CODE - SEE TOP FOR INSTRUCTIONS */
       __u16 port;
       __u32 count;
       __u64 data_offset;
-/* WARNING: DO NOT EDIT, AUTO-GENERATED CODE - SEE TOP FOR INSTRUCTIONS */
     } io;
+/* WARNING: DO NOT EDIT, AUTO-GENERATED CODE - SEE TOP FOR INSTRUCTIONS */
     struct {
       struct kvm_debug_exit_arch arch;
     } debug;
-/* WARNING: DO NOT EDIT, AUTO-GENERATED CODE - SEE TOP FOR INSTRUCTIONS */
     struct {
+/* WARNING: DO NOT EDIT, AUTO-GENERATED CODE - SEE TOP FOR INSTRUCTIONS */
       __u64 phys_addr;
       __u8 data[8];
       __u32 len;
-/* WARNING: DO NOT EDIT, AUTO-GENERATED CODE - SEE TOP FOR INSTRUCTIONS */
       __u8 is_write;
+/* WARNING: DO NOT EDIT, AUTO-GENERATED CODE - SEE TOP FOR INSTRUCTIONS */
     } mmio;
     struct {
       __u64 nr;
-/* WARNING: DO NOT EDIT, AUTO-GENERATED CODE - SEE TOP FOR INSTRUCTIONS */
       __u64 args[6];
+/* WARNING: DO NOT EDIT, AUTO-GENERATED CODE - SEE TOP FOR INSTRUCTIONS */
       __u64 ret;
       __u32 longmode;
       __u32 pad;
-/* WARNING: DO NOT EDIT, AUTO-GENERATED CODE - SEE TOP FOR INSTRUCTIONS */
     } hypercall;
+/* WARNING: DO NOT EDIT, AUTO-GENERATED CODE - SEE TOP FOR INSTRUCTIONS */
     struct {
       __u64 rip;
       __u32 is_write;
-/* WARNING: DO NOT EDIT, AUTO-GENERATED CODE - SEE TOP FOR INSTRUCTIONS */
       __u32 pad;
+/* WARNING: DO NOT EDIT, AUTO-GENERATED CODE - SEE TOP FOR INSTRUCTIONS */
     } tpr_access;
     struct {
       __u8 icptcode;
-/* WARNING: DO NOT EDIT, AUTO-GENERATED CODE - SEE TOP FOR INSTRUCTIONS */
       __u16 ipa;
+/* WARNING: DO NOT EDIT, AUTO-GENERATED CODE - SEE TOP FOR INSTRUCTIONS */
       __u32 ipb;
     } s390_sieic;
 #define KVM_S390_RESET_POR 1
-/* WARNING: DO NOT EDIT, AUTO-GENERATED CODE - SEE TOP FOR INSTRUCTIONS */
 #define KVM_S390_RESET_CLEAR 2
+/* WARNING: DO NOT EDIT, AUTO-GENERATED CODE - SEE TOP FOR INSTRUCTIONS */
 #define KVM_S390_RESET_SUBSYSTEM 4
 #define KVM_S390_RESET_CPU_INIT 8
 #define KVM_S390_RESET_IPL 16
-/* WARNING: DO NOT EDIT, AUTO-GENERATED CODE - SEE TOP FOR INSTRUCTIONS */
     __u64 s390_reset_flags;
+/* WARNING: DO NOT EDIT, AUTO-GENERATED CODE - SEE TOP FOR INSTRUCTIONS */
     struct {
       __u64 trans_exc_code;
       __u32 pgm_code;
-/* WARNING: DO NOT EDIT, AUTO-GENERATED CODE - SEE TOP FOR INSTRUCTIONS */
     } s390_ucontrol;
+/* WARNING: DO NOT EDIT, AUTO-GENERATED CODE - SEE TOP FOR INSTRUCTIONS */
     struct {
       __u32 dcrn;
       __u32 data;
-/* WARNING: DO NOT EDIT, AUTO-GENERATED CODE - SEE TOP FOR INSTRUCTIONS */
       __u8 is_write;
+/* WARNING: DO NOT EDIT, AUTO-GENERATED CODE - SEE TOP FOR INSTRUCTIONS */
     } dcr;
     struct {
       __u32 suberror;
-/* WARNING: DO NOT EDIT, AUTO-GENERATED CODE - SEE TOP FOR INSTRUCTIONS */
       __u32 ndata;
+/* WARNING: DO NOT EDIT, AUTO-GENERATED CODE - SEE TOP FOR INSTRUCTIONS */
       __u64 data[16];
     } internal;
     struct {
-/* WARNING: DO NOT EDIT, AUTO-GENERATED CODE - SEE TOP FOR INSTRUCTIONS */
       __u64 gprs[32];
+/* WARNING: DO NOT EDIT, AUTO-GENERATED CODE - SEE TOP FOR INSTRUCTIONS */
     } osi;
     struct {
       __u64 nr;
-/* WARNING: DO NOT EDIT, AUTO-GENERATED CODE - SEE TOP FOR INSTRUCTIONS */
       __u64 ret;
+/* WARNING: DO NOT EDIT, AUTO-GENERATED CODE - SEE TOP FOR INSTRUCTIONS */
       __u64 args[9];
     } papr_hcall;
     struct {
-/* WARNING: DO NOT EDIT, AUTO-GENERATED CODE - SEE TOP FOR INSTRUCTIONS */
       __u16 subchannel_id;
+/* WARNING: DO NOT EDIT, AUTO-GENERATED CODE - SEE TOP FOR INSTRUCTIONS */
       __u16 subchannel_nr;
       __u32 io_int_parm;
       __u32 io_int_word;
-/* WARNING: DO NOT EDIT, AUTO-GENERATED CODE - SEE TOP FOR INSTRUCTIONS */
       __u32 ipb;
+/* WARNING: DO NOT EDIT, AUTO-GENERATED CODE - SEE TOP FOR INSTRUCTIONS */
       __u8 dequeued;
     } s390_tsch;
     struct {
-/* WARNING: DO NOT EDIT, AUTO-GENERATED CODE - SEE TOP FOR INSTRUCTIONS */
       __u32 epr;
+/* WARNING: DO NOT EDIT, AUTO-GENERATED CODE - SEE TOP FOR INSTRUCTIONS */
     } epr;
     struct {
 #define KVM_SYSTEM_EVENT_SHUTDOWN 1
-/* WARNING: DO NOT EDIT, AUTO-GENERATED CODE - SEE TOP FOR INSTRUCTIONS */
 #define KVM_SYSTEM_EVENT_RESET 2
+/* WARNING: DO NOT EDIT, AUTO-GENERATED CODE - SEE TOP FOR INSTRUCTIONS */
+#define KVM_SYSTEM_EVENT_CRASH 3
       __u32 type;
       __u64 flags;
     } system_event;
 /* WARNING: DO NOT EDIT, AUTO-GENERATED CODE - SEE TOP FOR INSTRUCTIONS */
+    struct {
+      __u64 addr;
+      __u8 ar;
+      __u8 reserved;
+/* WARNING: DO NOT EDIT, AUTO-GENERATED CODE - SEE TOP FOR INSTRUCTIONS */
+      __u8 fc;
+      __u8 sel1;
+      __u16 sel2;
+    } s390_stsi;
+/* WARNING: DO NOT EDIT, AUTO-GENERATED CODE - SEE TOP FOR INSTRUCTIONS */
+    struct {
+      __u8 vector;
+    } eoi;
     char padding[256];
+/* WARNING: DO NOT EDIT, AUTO-GENERATED CODE - SEE TOP FOR INSTRUCTIONS */
   };
   __u64 kvm_valid_regs;
   __u64 kvm_dirty_regs;
-/* WARNING: DO NOT EDIT, AUTO-GENERATED CODE - SEE TOP FOR INSTRUCTIONS */
   union {
-    struct kvm_sync_regs regs;
-    char padding[1024];
-  } s;
 /* WARNING: DO NOT EDIT, AUTO-GENERATED CODE - SEE TOP FOR INSTRUCTIONS */
+    struct kvm_sync_regs regs;
+    char padding[2048];
+  } s;
 };
+/* WARNING: DO NOT EDIT, AUTO-GENERATED CODE - SEE TOP FOR INSTRUCTIONS */
 struct kvm_coalesced_mmio_zone {
   __u64 addr;
   __u32 size;
-/* WARNING: DO NOT EDIT, AUTO-GENERATED CODE - SEE TOP FOR INSTRUCTIONS */
   __u32 pad;
+/* WARNING: DO NOT EDIT, AUTO-GENERATED CODE - SEE TOP FOR INSTRUCTIONS */
 };
 struct kvm_coalesced_mmio {
   __u64 phys_addr;
-/* WARNING: DO NOT EDIT, AUTO-GENERATED CODE - SEE TOP FOR INSTRUCTIONS */
   __u32 len;
+/* WARNING: DO NOT EDIT, AUTO-GENERATED CODE - SEE TOP FOR INSTRUCTIONS */
   __u32 pad;
   __u8 data[8];
 };
-/* WARNING: DO NOT EDIT, AUTO-GENERATED CODE - SEE TOP FOR INSTRUCTIONS */
 struct kvm_coalesced_mmio_ring {
+/* WARNING: DO NOT EDIT, AUTO-GENERATED CODE - SEE TOP FOR INSTRUCTIONS */
   __u32 first, last;
   struct kvm_coalesced_mmio coalesced_mmio[0];
 };
-/* WARNING: DO NOT EDIT, AUTO-GENERATED CODE - SEE TOP FOR INSTRUCTIONS */
 #define KVM_COALESCED_MMIO_MAX ((PAGE_SIZE - sizeof(struct kvm_coalesced_mmio_ring)) / sizeof(struct kvm_coalesced_mmio))
+/* WARNING: DO NOT EDIT, AUTO-GENERATED CODE - SEE TOP FOR INSTRUCTIONS */
 struct kvm_translation {
   __u64 linear_address;
   __u64 physical_address;
-/* WARNING: DO NOT EDIT, AUTO-GENERATED CODE - SEE TOP FOR INSTRUCTIONS */
   __u8 valid;
+/* WARNING: DO NOT EDIT, AUTO-GENERATED CODE - SEE TOP FOR INSTRUCTIONS */
   __u8 writeable;
   __u8 usermode;
   __u8 pad[5];
+};
+/* WARNING: DO NOT EDIT, AUTO-GENERATED CODE - SEE TOP FOR INSTRUCTIONS */
+struct kvm_s390_mem_op {
+  __u64 gaddr;
+  __u64 flags;
+  __u32 size;
+/* WARNING: DO NOT EDIT, AUTO-GENERATED CODE - SEE TOP FOR INSTRUCTIONS */
+  __u32 op;
+  __u64 buf;
+  __u8 ar;
+  __u8 reserved[31];
 /* WARNING: DO NOT EDIT, AUTO-GENERATED CODE - SEE TOP FOR INSTRUCTIONS */
 };
+#define KVM_S390_MEMOP_LOGICAL_READ 0
+#define KVM_S390_MEMOP_LOGICAL_WRITE 1
+#define KVM_S390_MEMOP_F_CHECK_ONLY (1ULL << 0)
+/* WARNING: DO NOT EDIT, AUTO-GENERATED CODE - SEE TOP FOR INSTRUCTIONS */
+#define KVM_S390_MEMOP_F_INJECT_EXCEPTION (1ULL << 1)
 struct kvm_interrupt {
   __u32 irq;
 };
@@ -416,80 +461,95 @@
 #define KVM_S390_INT_IO_MIN 0x00000000u
 #define KVM_S390_INT_IO_MAX 0xfffdffffu
 /* WARNING: DO NOT EDIT, AUTO-GENERATED CODE - SEE TOP FOR INSTRUCTIONS */
+#define KVM_S390_INT_IO_AI_MASK 0x04000000u
 struct kvm_s390_interrupt {
   __u32 type;
   __u32 parm;
-  __u64 parm64;
 /* WARNING: DO NOT EDIT, AUTO-GENERATED CODE - SEE TOP FOR INSTRUCTIONS */
+  __u64 parm64;
 };
 struct kvm_s390_io_info {
   __u16 subchannel_id;
-  __u16 subchannel_nr;
 /* WARNING: DO NOT EDIT, AUTO-GENERATED CODE - SEE TOP FOR INSTRUCTIONS */
+  __u16 subchannel_nr;
   __u32 io_int_parm;
   __u32 io_int_word;
 };
-struct kvm_s390_ext_info {
 /* WARNING: DO NOT EDIT, AUTO-GENERATED CODE - SEE TOP FOR INSTRUCTIONS */
+struct kvm_s390_ext_info {
   __u32 ext_params;
   __u32 pad;
   __u64 ext_params2;
-};
 /* WARNING: DO NOT EDIT, AUTO-GENERATED CODE - SEE TOP FOR INSTRUCTIONS */
+};
 struct kvm_s390_pgm_info {
   __u64 trans_exc_code;
   __u64 mon_code;
-  __u64 per_address;
 /* WARNING: DO NOT EDIT, AUTO-GENERATED CODE - SEE TOP FOR INSTRUCTIONS */
+  __u64 per_address;
   __u32 data_exc_code;
   __u16 code;
   __u16 mon_class_nr;
-  __u8 per_code;
 /* WARNING: DO NOT EDIT, AUTO-GENERATED CODE - SEE TOP FOR INSTRUCTIONS */
+  __u8 per_code;
   __u8 per_atmid;
   __u8 exc_access_id;
   __u8 per_access_id;
-  __u8 op_access_id;
 /* WARNING: DO NOT EDIT, AUTO-GENERATED CODE - SEE TOP FOR INSTRUCTIONS */
+  __u8 op_access_id;
   __u8 pad[3];
 };
 struct kvm_s390_prefix_info {
-  __u32 address;
 /* WARNING: DO NOT EDIT, AUTO-GENERATED CODE - SEE TOP FOR INSTRUCTIONS */
+  __u32 address;
 };
 struct kvm_s390_extcall_info {
   __u16 code;
-};
 /* WARNING: DO NOT EDIT, AUTO-GENERATED CODE - SEE TOP FOR INSTRUCTIONS */
+};
 struct kvm_s390_emerg_info {
   __u16 code;
 };
-struct kvm_s390_mchk_info {
 /* WARNING: DO NOT EDIT, AUTO-GENERATED CODE - SEE TOP FOR INSTRUCTIONS */
+#define KVM_S390_STOP_FLAG_STORE_STATUS 0x01
+struct kvm_s390_stop_info {
+  __u32 flags;
+};
+/* WARNING: DO NOT EDIT, AUTO-GENERATED CODE - SEE TOP FOR INSTRUCTIONS */
+struct kvm_s390_mchk_info {
   __u64 cr14;
   __u64 mcic;
   __u64 failing_storage_address;
-  __u32 ext_damage_code;
 /* WARNING: DO NOT EDIT, AUTO-GENERATED CODE - SEE TOP FOR INSTRUCTIONS */
+  __u32 ext_damage_code;
   __u32 pad;
   __u8 fixed_logout[16];
 };
-struct kvm_s390_irq {
 /* WARNING: DO NOT EDIT, AUTO-GENERATED CODE - SEE TOP FOR INSTRUCTIONS */
+struct kvm_s390_irq {
   __u64 type;
   union {
     struct kvm_s390_io_info io;
-    struct kvm_s390_ext_info ext;
 /* WARNING: DO NOT EDIT, AUTO-GENERATED CODE - SEE TOP FOR INSTRUCTIONS */
+    struct kvm_s390_ext_info ext;
     struct kvm_s390_pgm_info pgm;
     struct kvm_s390_emerg_info emerg;
     struct kvm_s390_extcall_info extcall;
-    struct kvm_s390_prefix_info prefix;
 /* WARNING: DO NOT EDIT, AUTO-GENERATED CODE - SEE TOP FOR INSTRUCTIONS */
+    struct kvm_s390_prefix_info prefix;
+    struct kvm_s390_stop_info stop;
     struct kvm_s390_mchk_info mchk;
     char reserved[64];
+/* WARNING: DO NOT EDIT, AUTO-GENERATED CODE - SEE TOP FOR INSTRUCTIONS */
   } u;
 };
+struct kvm_s390_irq_state {
+  __u64 buf;
+/* WARNING: DO NOT EDIT, AUTO-GENERATED CODE - SEE TOP FOR INSTRUCTIONS */
+  __u32 flags;
+  __u32 len;
+  __u32 reserved[4];
+};
 /* WARNING: DO NOT EDIT, AUTO-GENERATED CODE - SEE TOP FOR INSTRUCTIONS */
 #define KVM_GUESTDBG_ENABLE 0x00000001
 #define KVM_GUESTDBG_SINGLESTEP 0x00000002
@@ -603,12 +663,7 @@
 /* WARNING: DO NOT EDIT, AUTO-GENERATED CODE - SEE TOP FOR INSTRUCTIONS */
 #define KVM_CAP_COALESCED_MMIO 15
 #define KVM_CAP_SYNC_MMU 16
-#define KVM_CAP_DEVICE_ASSIGNMENT 17
 #define KVM_CAP_IOMMU 18
-/* WARNING: DO NOT EDIT, AUTO-GENERATED CODE - SEE TOP FOR INSTRUCTIONS */
-#ifdef __KVM_HAVE_MSI
-#define KVM_CAP_DEVICE_MSI 20
-#endif
 #define KVM_CAP_DESTROY_MEMORY_REGION_WORKS 21
 /* WARNING: DO NOT EDIT, AUTO-GENERATED CODE - SEE TOP FOR INSTRUCTIONS */
 #define KVM_CAP_USER_NMI 22
@@ -622,11 +677,6 @@
 #define KVM_CAP_IRQ_ROUTING 25
 /* WARNING: DO NOT EDIT, AUTO-GENERATED CODE - SEE TOP FOR INSTRUCTIONS */
 #define KVM_CAP_IRQ_INJECT_STATUS 26
-#define KVM_CAP_DEVICE_DEASSIGNMENT 27
-#ifdef __KVM_HAVE_MSIX
-#define KVM_CAP_DEVICE_MSIX 28
-/* WARNING: DO NOT EDIT, AUTO-GENERATED CODE - SEE TOP FOR INSTRUCTIONS */
-#endif
 #define KVM_CAP_ASSIGN_DEV_IRQ 29
 #define KVM_CAP_JOIN_MEMORY_REGIONS_WORKS 30
 #ifdef __KVM_HAVE_MCE
@@ -743,340 +793,370 @@
 /* WARNING: DO NOT EDIT, AUTO-GENERATED CODE - SEE TOP FOR INSTRUCTIONS */
 #define KVM_CAP_PPC_ENABLE_HCALL 104
 #define KVM_CAP_CHECK_EXTENSION_VM 105
-#ifdef KVM_CAP_IRQ_ROUTING
-struct kvm_irq_routing_irqchip {
+#define KVM_CAP_S390_USER_SIGP 106
+#define KVM_CAP_S390_VECTOR_REGISTERS 107
 /* WARNING: DO NOT EDIT, AUTO-GENERATED CODE - SEE TOP FOR INSTRUCTIONS */
+#define KVM_CAP_S390_MEM_OP 108
+#define KVM_CAP_S390_USER_STSI 109
+#define KVM_CAP_S390_SKEYS 110
+#define KVM_CAP_MIPS_FPU 111
+/* WARNING: DO NOT EDIT, AUTO-GENERATED CODE - SEE TOP FOR INSTRUCTIONS */
+#define KVM_CAP_MIPS_MSA 112
+#define KVM_CAP_S390_INJECT_IRQ 113
+#define KVM_CAP_S390_IRQ_STATE 114
+#define KVM_CAP_PPC_HWRNG 115
+/* WARNING: DO NOT EDIT, AUTO-GENERATED CODE - SEE TOP FOR INSTRUCTIONS */
+#define KVM_CAP_DISABLE_QUIRKS 116
+#define KVM_CAP_X86_SMM 117
+#define KVM_CAP_MULTI_ADDRESS_SPACE 118
+#define KVM_CAP_GUEST_DEBUG_HW_BPS 119
+/* WARNING: DO NOT EDIT, AUTO-GENERATED CODE - SEE TOP FOR INSTRUCTIONS */
+#define KVM_CAP_GUEST_DEBUG_HW_WPS 120
+#define KVM_CAP_SPLIT_IRQCHIP 121
+#define KVM_CAP_IOEVENTFD_ANY_LENGTH 122
+#ifdef KVM_CAP_IRQ_ROUTING
+/* WARNING: DO NOT EDIT, AUTO-GENERATED CODE - SEE TOP FOR INSTRUCTIONS */
+struct kvm_irq_routing_irqchip {
   __u32 irqchip;
   __u32 pin;
 };
-struct kvm_irq_routing_msi {
 /* WARNING: DO NOT EDIT, AUTO-GENERATED CODE - SEE TOP FOR INSTRUCTIONS */
+struct kvm_irq_routing_msi {
   __u32 address_lo;
   __u32 address_hi;
   __u32 data;
-  __u32 pad;
 /* WARNING: DO NOT EDIT, AUTO-GENERATED CODE - SEE TOP FOR INSTRUCTIONS */
+  __u32 pad;
 };
 struct kvm_irq_routing_s390_adapter {
   __u64 ind_addr;
-  __u64 summary_addr;
 /* WARNING: DO NOT EDIT, AUTO-GENERATED CODE - SEE TOP FOR INSTRUCTIONS */
+  __u64 summary_addr;
   __u64 ind_offset;
   __u32 summary_offset;
   __u32 adapter_id;
-};
 /* WARNING: DO NOT EDIT, AUTO-GENERATED CODE - SEE TOP FOR INSTRUCTIONS */
+};
 #define KVM_IRQ_ROUTING_IRQCHIP 1
 #define KVM_IRQ_ROUTING_MSI 2
 #define KVM_IRQ_ROUTING_S390_ADAPTER 3
-struct kvm_irq_routing_entry {
 /* WARNING: DO NOT EDIT, AUTO-GENERATED CODE - SEE TOP FOR INSTRUCTIONS */
+struct kvm_irq_routing_entry {
   __u32 gsi;
   __u32 type;
   __u32 flags;
-  __u32 pad;
 /* WARNING: DO NOT EDIT, AUTO-GENERATED CODE - SEE TOP FOR INSTRUCTIONS */
+  __u32 pad;
   union {
     struct kvm_irq_routing_irqchip irqchip;
     struct kvm_irq_routing_msi msi;
-    struct kvm_irq_routing_s390_adapter adapter;
 /* WARNING: DO NOT EDIT, AUTO-GENERATED CODE - SEE TOP FOR INSTRUCTIONS */
+    struct kvm_irq_routing_s390_adapter adapter;
     __u32 pad[8];
   } u;
 };
-struct kvm_irq_routing {
 /* WARNING: DO NOT EDIT, AUTO-GENERATED CODE - SEE TOP FOR INSTRUCTIONS */
+struct kvm_irq_routing {
   __u32 nr;
   __u32 flags;
   struct kvm_irq_routing_entry entries[0];
-};
 /* WARNING: DO NOT EDIT, AUTO-GENERATED CODE - SEE TOP FOR INSTRUCTIONS */
+};
 #endif
 #ifdef KVM_CAP_MCE
 struct kvm_x86_mce {
-  __u64 status;
 /* WARNING: DO NOT EDIT, AUTO-GENERATED CODE - SEE TOP FOR INSTRUCTIONS */
+  __u64 status;
   __u64 addr;
   __u64 misc;
   __u64 mcg_status;
-  __u8 bank;
 /* WARNING: DO NOT EDIT, AUTO-GENERATED CODE - SEE TOP FOR INSTRUCTIONS */
+  __u8 bank;
   __u8 pad1[7];
   __u64 pad2[3];
 };
-#endif
 /* WARNING: DO NOT EDIT, AUTO-GENERATED CODE - SEE TOP FOR INSTRUCTIONS */
+#endif
 #ifdef KVM_CAP_XEN_HVM
 struct kvm_xen_hvm_config {
   __u32 flags;
-  __u32 msr;
 /* WARNING: DO NOT EDIT, AUTO-GENERATED CODE - SEE TOP FOR INSTRUCTIONS */
+  __u32 msr;
   __u64 blob_addr_32;
   __u64 blob_addr_64;
   __u8 blob_size_32;
-  __u8 blob_size_64;
 /* WARNING: DO NOT EDIT, AUTO-GENERATED CODE - SEE TOP FOR INSTRUCTIONS */
+  __u8 blob_size_64;
   __u8 pad2[30];
 };
 #endif
-#define KVM_IRQFD_FLAG_DEASSIGN (1 << 0)
 /* WARNING: DO NOT EDIT, AUTO-GENERATED CODE - SEE TOP FOR INSTRUCTIONS */
+#define KVM_IRQFD_FLAG_DEASSIGN (1 << 0)
 #define KVM_IRQFD_FLAG_RESAMPLE (1 << 1)
 struct kvm_irqfd {
   __u32 fd;
-  __u32 gsi;
 /* WARNING: DO NOT EDIT, AUTO-GENERATED CODE - SEE TOP FOR INSTRUCTIONS */
+  __u32 gsi;
   __u32 flags;
   __u32 resamplefd;
   __u8 pad[16];
-};
 /* WARNING: DO NOT EDIT, AUTO-GENERATED CODE - SEE TOP FOR INSTRUCTIONS */
+};
 struct kvm_clock_data {
   __u64 clock;
   __u32 flags;
-  __u32 pad[9];
 /* WARNING: DO NOT EDIT, AUTO-GENERATED CODE - SEE TOP FOR INSTRUCTIONS */
+  __u32 pad[9];
 };
 #define KVM_MMU_FSL_BOOKE_NOHV 0
 #define KVM_MMU_FSL_BOOKE_HV 1
-struct kvm_config_tlb {
 /* WARNING: DO NOT EDIT, AUTO-GENERATED CODE - SEE TOP FOR INSTRUCTIONS */
+struct kvm_config_tlb {
   __u64 params;
   __u64 array;
   __u32 mmu_type;
-  __u32 array_len;
 /* WARNING: DO NOT EDIT, AUTO-GENERATED CODE - SEE TOP FOR INSTRUCTIONS */
+  __u32 array_len;
 };
 struct kvm_dirty_tlb {
   __u64 bitmap;
-  __u32 num_dirty;
 /* WARNING: DO NOT EDIT, AUTO-GENERATED CODE - SEE TOP FOR INSTRUCTIONS */
+  __u32 num_dirty;
 };
 #define KVM_REG_ARCH_MASK 0xff00000000000000ULL
 #define KVM_REG_GENERIC 0x0000000000000000ULL
-#define KVM_REG_PPC 0x1000000000000000ULL
 /* WARNING: DO NOT EDIT, AUTO-GENERATED CODE - SEE TOP FOR INSTRUCTIONS */
+#define KVM_REG_PPC 0x1000000000000000ULL
 #define KVM_REG_X86 0x2000000000000000ULL
 #define KVM_REG_IA64 0x3000000000000000ULL
 #define KVM_REG_ARM 0x4000000000000000ULL
-#define KVM_REG_S390 0x5000000000000000ULL
 /* WARNING: DO NOT EDIT, AUTO-GENERATED CODE - SEE TOP FOR INSTRUCTIONS */
+#define KVM_REG_S390 0x5000000000000000ULL
 #define KVM_REG_ARM64 0x6000000000000000ULL
 #define KVM_REG_MIPS 0x7000000000000000ULL
 #define KVM_REG_SIZE_SHIFT 52
-#define KVM_REG_SIZE_MASK 0x00f0000000000000ULL
 /* WARNING: DO NOT EDIT, AUTO-GENERATED CODE - SEE TOP FOR INSTRUCTIONS */
+#define KVM_REG_SIZE_MASK 0x00f0000000000000ULL
 #define KVM_REG_SIZE_U8 0x0000000000000000ULL
 #define KVM_REG_SIZE_U16 0x0010000000000000ULL
 #define KVM_REG_SIZE_U32 0x0020000000000000ULL
-#define KVM_REG_SIZE_U64 0x0030000000000000ULL
 /* WARNING: DO NOT EDIT, AUTO-GENERATED CODE - SEE TOP FOR INSTRUCTIONS */
+#define KVM_REG_SIZE_U64 0x0030000000000000ULL
 #define KVM_REG_SIZE_U128 0x0040000000000000ULL
 #define KVM_REG_SIZE_U256 0x0050000000000000ULL
 #define KVM_REG_SIZE_U512 0x0060000000000000ULL
-#define KVM_REG_SIZE_U1024 0x0070000000000000ULL
 /* WARNING: DO NOT EDIT, AUTO-GENERATED CODE - SEE TOP FOR INSTRUCTIONS */
+#define KVM_REG_SIZE_U1024 0x0070000000000000ULL
 struct kvm_reg_list {
   __u64 n;
   __u64 reg[0];
-};
 /* WARNING: DO NOT EDIT, AUTO-GENERATED CODE - SEE TOP FOR INSTRUCTIONS */
+};
 struct kvm_one_reg {
   __u64 id;
   __u64 addr;
-};
 /* WARNING: DO NOT EDIT, AUTO-GENERATED CODE - SEE TOP FOR INSTRUCTIONS */
+};
 struct kvm_msi {
   __u32 address_lo;
   __u32 address_hi;
-  __u32 data;
 /* WARNING: DO NOT EDIT, AUTO-GENERATED CODE - SEE TOP FOR INSTRUCTIONS */
+  __u32 data;
   __u32 flags;
   __u8 pad[16];
 };
-struct kvm_arm_device_addr {
 /* WARNING: DO NOT EDIT, AUTO-GENERATED CODE - SEE TOP FOR INSTRUCTIONS */
+struct kvm_arm_device_addr {
   __u64 id;
   __u64 addr;
 };
-#define KVM_CREATE_DEVICE_TEST 1
 /* WARNING: DO NOT EDIT, AUTO-GENERATED CODE - SEE TOP FOR INSTRUCTIONS */
+#define KVM_CREATE_DEVICE_TEST 1
 struct kvm_create_device {
   __u32 type;
   __u32 fd;
-  __u32 flags;
 /* WARNING: DO NOT EDIT, AUTO-GENERATED CODE - SEE TOP FOR INSTRUCTIONS */
+  __u32 flags;
 };
 struct kvm_device_attr {
   __u32 flags;
-  __u32 group;
 /* WARNING: DO NOT EDIT, AUTO-GENERATED CODE - SEE TOP FOR INSTRUCTIONS */
+  __u32 group;
   __u64 attr;
   __u64 addr;
 };
-#define KVM_DEV_VFIO_GROUP 1
 /* WARNING: DO NOT EDIT, AUTO-GENERATED CODE - SEE TOP FOR INSTRUCTIONS */
+#define KVM_DEV_VFIO_GROUP 1
 #define KVM_DEV_VFIO_GROUP_ADD 1
 #define KVM_DEV_VFIO_GROUP_DEL 2
 enum kvm_device_type {
-  KVM_DEV_TYPE_FSL_MPIC_20 = 1,
 /* WARNING: DO NOT EDIT, AUTO-GENERATED CODE - SEE TOP FOR INSTRUCTIONS */
+  KVM_DEV_TYPE_FSL_MPIC_20 = 1,
 #define KVM_DEV_TYPE_FSL_MPIC_20 KVM_DEV_TYPE_FSL_MPIC_20
   KVM_DEV_TYPE_FSL_MPIC_42,
 #define KVM_DEV_TYPE_FSL_MPIC_42 KVM_DEV_TYPE_FSL_MPIC_42
-  KVM_DEV_TYPE_XICS,
 /* WARNING: DO NOT EDIT, AUTO-GENERATED CODE - SEE TOP FOR INSTRUCTIONS */
+  KVM_DEV_TYPE_XICS,
 #define KVM_DEV_TYPE_XICS KVM_DEV_TYPE_XICS
   KVM_DEV_TYPE_VFIO,
 #define KVM_DEV_TYPE_VFIO KVM_DEV_TYPE_VFIO
-  KVM_DEV_TYPE_ARM_VGIC_V2,
 /* WARNING: DO NOT EDIT, AUTO-GENERATED CODE - SEE TOP FOR INSTRUCTIONS */
+  KVM_DEV_TYPE_ARM_VGIC_V2,
 #define KVM_DEV_TYPE_ARM_VGIC_V2 KVM_DEV_TYPE_ARM_VGIC_V2
   KVM_DEV_TYPE_FLIC,
 #define KVM_DEV_TYPE_FLIC KVM_DEV_TYPE_FLIC
-  KVM_DEV_TYPE_MAX,
 /* WARNING: DO NOT EDIT, AUTO-GENERATED CODE - SEE TOP FOR INSTRUCTIONS */
+  KVM_DEV_TYPE_ARM_VGIC_V3,
+#define KVM_DEV_TYPE_ARM_VGIC_V3 KVM_DEV_TYPE_ARM_VGIC_V3
+  KVM_DEV_TYPE_MAX,
 };
+/* WARNING: DO NOT EDIT, AUTO-GENERATED CODE - SEE TOP FOR INSTRUCTIONS */
 #define KVM_SET_MEMORY_REGION _IOW(KVMIO, 0x40, struct kvm_memory_region)
 #define KVM_CREATE_VCPU _IO(KVMIO, 0x41)
 #define KVM_GET_DIRTY_LOG _IOW(KVMIO, 0x42, struct kvm_dirty_log)
-/* WARNING: DO NOT EDIT, AUTO-GENERATED CODE - SEE TOP FOR INSTRUCTIONS */
 #define KVM_SET_MEMORY_ALIAS _IOW(KVMIO, 0x43, struct kvm_memory_alias)
+/* WARNING: DO NOT EDIT, AUTO-GENERATED CODE - SEE TOP FOR INSTRUCTIONS */
 #define KVM_SET_NR_MMU_PAGES _IO(KVMIO, 0x44)
 #define KVM_GET_NR_MMU_PAGES _IO(KVMIO, 0x45)
 #define KVM_SET_USER_MEMORY_REGION _IOW(KVMIO, 0x46, struct kvm_userspace_memory_region)
-/* WARNING: DO NOT EDIT, AUTO-GENERATED CODE - SEE TOP FOR INSTRUCTIONS */
 #define KVM_SET_TSS_ADDR _IO(KVMIO, 0x47)
+/* WARNING: DO NOT EDIT, AUTO-GENERATED CODE - SEE TOP FOR INSTRUCTIONS */
 #define KVM_SET_IDENTITY_MAP_ADDR _IOW(KVMIO, 0x48, __u64)
 struct kvm_s390_ucas_mapping {
   __u64 user_addr;
-/* WARNING: DO NOT EDIT, AUTO-GENERATED CODE - SEE TOP FOR INSTRUCTIONS */
   __u64 vcpu_addr;
+/* WARNING: DO NOT EDIT, AUTO-GENERATED CODE - SEE TOP FOR INSTRUCTIONS */
   __u64 length;
 };
 #define KVM_S390_UCAS_MAP _IOW(KVMIO, 0x50, struct kvm_s390_ucas_mapping)
-/* WARNING: DO NOT EDIT, AUTO-GENERATED CODE - SEE TOP FOR INSTRUCTIONS */
 #define KVM_S390_UCAS_UNMAP _IOW(KVMIO, 0x51, struct kvm_s390_ucas_mapping)
+/* WARNING: DO NOT EDIT, AUTO-GENERATED CODE - SEE TOP FOR INSTRUCTIONS */
 #define KVM_S390_VCPU_FAULT _IOW(KVMIO, 0x52, unsigned long)
 #define KVM_CREATE_IRQCHIP _IO(KVMIO, 0x60)
 #define KVM_IRQ_LINE _IOW(KVMIO, 0x61, struct kvm_irq_level)
-/* WARNING: DO NOT EDIT, AUTO-GENERATED CODE - SEE TOP FOR INSTRUCTIONS */
 #define KVM_GET_IRQCHIP _IOWR(KVMIO, 0x62, struct kvm_irqchip)
+/* WARNING: DO NOT EDIT, AUTO-GENERATED CODE - SEE TOP FOR INSTRUCTIONS */
 #define KVM_SET_IRQCHIP _IOR(KVMIO, 0x63, struct kvm_irqchip)
 #define KVM_CREATE_PIT _IO(KVMIO, 0x64)
 #define KVM_GET_PIT _IOWR(KVMIO, 0x65, struct kvm_pit_state)
-/* WARNING: DO NOT EDIT, AUTO-GENERATED CODE - SEE TOP FOR INSTRUCTIONS */
 #define KVM_SET_PIT _IOR(KVMIO, 0x66, struct kvm_pit_state)
+/* WARNING: DO NOT EDIT, AUTO-GENERATED CODE - SEE TOP FOR INSTRUCTIONS */
 #define KVM_IRQ_LINE_STATUS _IOWR(KVMIO, 0x67, struct kvm_irq_level)
 #define KVM_REGISTER_COALESCED_MMIO _IOW(KVMIO, 0x67, struct kvm_coalesced_mmio_zone)
 #define KVM_UNREGISTER_COALESCED_MMIO _IOW(KVMIO, 0x68, struct kvm_coalesced_mmio_zone)
-/* WARNING: DO NOT EDIT, AUTO-GENERATED CODE - SEE TOP FOR INSTRUCTIONS */
 #define KVM_ASSIGN_PCI_DEVICE _IOR(KVMIO, 0x69, struct kvm_assigned_pci_dev)
+/* WARNING: DO NOT EDIT, AUTO-GENERATED CODE - SEE TOP FOR INSTRUCTIONS */
 #define KVM_SET_GSI_ROUTING _IOW(KVMIO, 0x6a, struct kvm_irq_routing)
 #define KVM_ASSIGN_IRQ __KVM_DEPRECATED_VM_R_0x70
 #define KVM_ASSIGN_DEV_IRQ _IOW(KVMIO, 0x70, struct kvm_assigned_irq)
-/* WARNING: DO NOT EDIT, AUTO-GENERATED CODE - SEE TOP FOR INSTRUCTIONS */
 #define KVM_REINJECT_CONTROL _IO(KVMIO, 0x71)
+/* WARNING: DO NOT EDIT, AUTO-GENERATED CODE - SEE TOP FOR INSTRUCTIONS */
 #define KVM_DEASSIGN_PCI_DEVICE _IOW(KVMIO, 0x72, struct kvm_assigned_pci_dev)
 #define KVM_ASSIGN_SET_MSIX_NR _IOW(KVMIO, 0x73, struct kvm_assigned_msix_nr)
 #define KVM_ASSIGN_SET_MSIX_ENTRY _IOW(KVMIO, 0x74, struct kvm_assigned_msix_entry)
-/* WARNING: DO NOT EDIT, AUTO-GENERATED CODE - SEE TOP FOR INSTRUCTIONS */
 #define KVM_DEASSIGN_DEV_IRQ _IOW(KVMIO, 0x75, struct kvm_assigned_irq)
+/* WARNING: DO NOT EDIT, AUTO-GENERATED CODE - SEE TOP FOR INSTRUCTIONS */
 #define KVM_IRQFD _IOW(KVMIO, 0x76, struct kvm_irqfd)
 #define KVM_CREATE_PIT2 _IOW(KVMIO, 0x77, struct kvm_pit_config)
 #define KVM_SET_BOOT_CPU_ID _IO(KVMIO, 0x78)
-/* WARNING: DO NOT EDIT, AUTO-GENERATED CODE - SEE TOP FOR INSTRUCTIONS */
 #define KVM_IOEVENTFD _IOW(KVMIO, 0x79, struct kvm_ioeventfd)
+/* WARNING: DO NOT EDIT, AUTO-GENERATED CODE - SEE TOP FOR INSTRUCTIONS */
 #define KVM_XEN_HVM_CONFIG _IOW(KVMIO, 0x7a, struct kvm_xen_hvm_config)
 #define KVM_SET_CLOCK _IOW(KVMIO, 0x7b, struct kvm_clock_data)
 #define KVM_GET_CLOCK _IOR(KVMIO, 0x7c, struct kvm_clock_data)
-/* WARNING: DO NOT EDIT, AUTO-GENERATED CODE - SEE TOP FOR INSTRUCTIONS */
 #define KVM_GET_PIT2 _IOR(KVMIO, 0x9f, struct kvm_pit_state2)
+/* WARNING: DO NOT EDIT, AUTO-GENERATED CODE - SEE TOP FOR INSTRUCTIONS */
 #define KVM_SET_PIT2 _IOW(KVMIO, 0xa0, struct kvm_pit_state2)
 #define KVM_PPC_GET_PVINFO _IOW(KVMIO, 0xa1, struct kvm_ppc_pvinfo)
 #define KVM_SET_TSC_KHZ _IO(KVMIO, 0xa2)
-/* WARNING: DO NOT EDIT, AUTO-GENERATED CODE - SEE TOP FOR INSTRUCTIONS */
 #define KVM_GET_TSC_KHZ _IO(KVMIO, 0xa3)
+/* WARNING: DO NOT EDIT, AUTO-GENERATED CODE - SEE TOP FOR INSTRUCTIONS */
 #define KVM_ASSIGN_SET_INTX_MASK _IOW(KVMIO, 0xa4, struct kvm_assigned_pci_dev)
 #define KVM_SIGNAL_MSI _IOW(KVMIO, 0xa5, struct kvm_msi)
 #define KVM_PPC_GET_SMMU_INFO _IOR(KVMIO, 0xa6, struct kvm_ppc_smmu_info)
-/* WARNING: DO NOT EDIT, AUTO-GENERATED CODE - SEE TOP FOR INSTRUCTIONS */
 #define KVM_PPC_ALLOCATE_HTAB _IOWR(KVMIO, 0xa7, __u32)
+/* WARNING: DO NOT EDIT, AUTO-GENERATED CODE - SEE TOP FOR INSTRUCTIONS */
 #define KVM_CREATE_SPAPR_TCE _IOW(KVMIO, 0xa8, struct kvm_create_spapr_tce)
 #define KVM_ALLOCATE_RMA _IOR(KVMIO, 0xa9, struct kvm_allocate_rma)
 #define KVM_PPC_GET_HTAB_FD _IOW(KVMIO, 0xaa, struct kvm_get_htab_fd)
-/* WARNING: DO NOT EDIT, AUTO-GENERATED CODE - SEE TOP FOR INSTRUCTIONS */
 #define KVM_ARM_SET_DEVICE_ADDR _IOW(KVMIO, 0xab, struct kvm_arm_device_addr)
+/* WARNING: DO NOT EDIT, AUTO-GENERATED CODE - SEE TOP FOR INSTRUCTIONS */
 #define KVM_PPC_RTAS_DEFINE_TOKEN _IOW(KVMIO, 0xac, struct kvm_rtas_token_args)
 #define KVM_CREATE_DEVICE _IOWR(KVMIO, 0xe0, struct kvm_create_device)
 #define KVM_SET_DEVICE_ATTR _IOW(KVMIO, 0xe1, struct kvm_device_attr)
-/* WARNING: DO NOT EDIT, AUTO-GENERATED CODE - SEE TOP FOR INSTRUCTIONS */
 #define KVM_GET_DEVICE_ATTR _IOW(KVMIO, 0xe2, struct kvm_device_attr)
+/* WARNING: DO NOT EDIT, AUTO-GENERATED CODE - SEE TOP FOR INSTRUCTIONS */
 #define KVM_HAS_DEVICE_ATTR _IOW(KVMIO, 0xe3, struct kvm_device_attr)
 #define KVM_RUN _IO(KVMIO, 0x80)
 #define KVM_GET_REGS _IOR(KVMIO, 0x81, struct kvm_regs)
-/* WARNING: DO NOT EDIT, AUTO-GENERATED CODE - SEE TOP FOR INSTRUCTIONS */
 #define KVM_SET_REGS _IOW(KVMIO, 0x82, struct kvm_regs)
+/* WARNING: DO NOT EDIT, AUTO-GENERATED CODE - SEE TOP FOR INSTRUCTIONS */
 #define KVM_GET_SREGS _IOR(KVMIO, 0x83, struct kvm_sregs)
 #define KVM_SET_SREGS _IOW(KVMIO, 0x84, struct kvm_sregs)
 #define KVM_TRANSLATE _IOWR(KVMIO, 0x85, struct kvm_translation)
-/* WARNING: DO NOT EDIT, AUTO-GENERATED CODE - SEE TOP FOR INSTRUCTIONS */
 #define KVM_INTERRUPT _IOW(KVMIO, 0x86, struct kvm_interrupt)
+/* WARNING: DO NOT EDIT, AUTO-GENERATED CODE - SEE TOP FOR INSTRUCTIONS */
 #define KVM_DEBUG_GUEST __KVM_DEPRECATED_VCPU_W_0x87
 #define KVM_GET_MSRS _IOWR(KVMIO, 0x88, struct kvm_msrs)
 #define KVM_SET_MSRS _IOW(KVMIO, 0x89, struct kvm_msrs)
-/* WARNING: DO NOT EDIT, AUTO-GENERATED CODE - SEE TOP FOR INSTRUCTIONS */
 #define KVM_SET_CPUID _IOW(KVMIO, 0x8a, struct kvm_cpuid)
+/* WARNING: DO NOT EDIT, AUTO-GENERATED CODE - SEE TOP FOR INSTRUCTIONS */
 #define KVM_SET_SIGNAL_MASK _IOW(KVMIO, 0x8b, struct kvm_signal_mask)
 #define KVM_GET_FPU _IOR(KVMIO, 0x8c, struct kvm_fpu)
 #define KVM_SET_FPU _IOW(KVMIO, 0x8d, struct kvm_fpu)
-/* WARNING: DO NOT EDIT, AUTO-GENERATED CODE - SEE TOP FOR INSTRUCTIONS */
 #define KVM_GET_LAPIC _IOR(KVMIO, 0x8e, struct kvm_lapic_state)
+/* WARNING: DO NOT EDIT, AUTO-GENERATED CODE - SEE TOP FOR INSTRUCTIONS */
 #define KVM_SET_LAPIC _IOW(KVMIO, 0x8f, struct kvm_lapic_state)
 #define KVM_SET_CPUID2 _IOW(KVMIO, 0x90, struct kvm_cpuid2)
 #define KVM_GET_CPUID2 _IOWR(KVMIO, 0x91, struct kvm_cpuid2)
-/* WARNING: DO NOT EDIT, AUTO-GENERATED CODE - SEE TOP FOR INSTRUCTIONS */
 #define KVM_TPR_ACCESS_REPORTING _IOWR(KVMIO, 0x92, struct kvm_tpr_access_ctl)
+/* WARNING: DO NOT EDIT, AUTO-GENERATED CODE - SEE TOP FOR INSTRUCTIONS */
 #define KVM_SET_VAPIC_ADDR _IOW(KVMIO, 0x93, struct kvm_vapic_addr)
 #define KVM_S390_INTERRUPT _IOW(KVMIO, 0x94, struct kvm_s390_interrupt)
 #define KVM_S390_STORE_STATUS_NOADDR (- 1ul)
-/* WARNING: DO NOT EDIT, AUTO-GENERATED CODE - SEE TOP FOR INSTRUCTIONS */
 #define KVM_S390_STORE_STATUS_PREFIXED (- 2ul)
+/* WARNING: DO NOT EDIT, AUTO-GENERATED CODE - SEE TOP FOR INSTRUCTIONS */
 #define KVM_S390_STORE_STATUS _IOW(KVMIO, 0x95, unsigned long)
 #define KVM_S390_SET_INITIAL_PSW _IOW(KVMIO, 0x96, struct kvm_s390_psw)
 #define KVM_S390_INITIAL_RESET _IO(KVMIO, 0x97)
-/* WARNING: DO NOT EDIT, AUTO-GENERATED CODE - SEE TOP FOR INSTRUCTIONS */
 #define KVM_GET_MP_STATE _IOR(KVMIO, 0x98, struct kvm_mp_state)
+/* WARNING: DO NOT EDIT, AUTO-GENERATED CODE - SEE TOP FOR INSTRUCTIONS */
 #define KVM_SET_MP_STATE _IOW(KVMIO, 0x99, struct kvm_mp_state)
 #define KVM_NMI _IO(KVMIO, 0x9a)
 #define KVM_SET_GUEST_DEBUG _IOW(KVMIO, 0x9b, struct kvm_guest_debug)
-/* WARNING: DO NOT EDIT, AUTO-GENERATED CODE - SEE TOP FOR INSTRUCTIONS */
 #define KVM_X86_SETUP_MCE _IOW(KVMIO, 0x9c, __u64)
+/* WARNING: DO NOT EDIT, AUTO-GENERATED CODE - SEE TOP FOR INSTRUCTIONS */
 #define KVM_X86_GET_MCE_CAP_SUPPORTED _IOR(KVMIO, 0x9d, __u64)
 #define KVM_X86_SET_MCE _IOW(KVMIO, 0x9e, struct kvm_x86_mce)
-#define KVM_IA64_VCPU_GET_STACK _IOR(KVMIO, 0x9a, void *)
-/* WARNING: DO NOT EDIT, AUTO-GENERATED CODE - SEE TOP FOR INSTRUCTIONS */
-#define KVM_IA64_VCPU_SET_STACK _IOW(KVMIO, 0x9b, void *)
 #define KVM_GET_VCPU_EVENTS _IOR(KVMIO, 0x9f, struct kvm_vcpu_events)
 #define KVM_SET_VCPU_EVENTS _IOW(KVMIO, 0xa0, struct kvm_vcpu_events)
-#define KVM_GET_DEBUGREGS _IOR(KVMIO, 0xa1, struct kvm_debugregs)
 /* WARNING: DO NOT EDIT, AUTO-GENERATED CODE - SEE TOP FOR INSTRUCTIONS */
+#define KVM_GET_DEBUGREGS _IOR(KVMIO, 0xa1, struct kvm_debugregs)
 #define KVM_SET_DEBUGREGS _IOW(KVMIO, 0xa2, struct kvm_debugregs)
 #define KVM_ENABLE_CAP _IOW(KVMIO, 0xa3, struct kvm_enable_cap)
 #define KVM_GET_XSAVE _IOR(KVMIO, 0xa4, struct kvm_xsave)
-#define KVM_SET_XSAVE _IOW(KVMIO, 0xa5, struct kvm_xsave)
 /* WARNING: DO NOT EDIT, AUTO-GENERATED CODE - SEE TOP FOR INSTRUCTIONS */
+#define KVM_SET_XSAVE _IOW(KVMIO, 0xa5, struct kvm_xsave)
 #define KVM_GET_XCRS _IOR(KVMIO, 0xa6, struct kvm_xcrs)
 #define KVM_SET_XCRS _IOW(KVMIO, 0xa7, struct kvm_xcrs)
 #define KVM_DIRTY_TLB _IOW(KVMIO, 0xaa, struct kvm_dirty_tlb)
-#define KVM_GET_ONE_REG _IOW(KVMIO, 0xab, struct kvm_one_reg)
 /* WARNING: DO NOT EDIT, AUTO-GENERATED CODE - SEE TOP FOR INSTRUCTIONS */
+#define KVM_GET_ONE_REG _IOW(KVMIO, 0xab, struct kvm_one_reg)
 #define KVM_SET_ONE_REG _IOW(KVMIO, 0xac, struct kvm_one_reg)
 #define KVM_KVMCLOCK_CTRL _IO(KVMIO, 0xad)
 #define KVM_ARM_VCPU_INIT _IOW(KVMIO, 0xae, struct kvm_vcpu_init)
-#define KVM_ARM_PREFERRED_TARGET _IOR(KVMIO, 0xaf, struct kvm_vcpu_init)
 /* WARNING: DO NOT EDIT, AUTO-GENERATED CODE - SEE TOP FOR INSTRUCTIONS */
+#define KVM_ARM_PREFERRED_TARGET _IOR(KVMIO, 0xaf, struct kvm_vcpu_init)
 #define KVM_GET_REG_LIST _IOWR(KVMIO, 0xb0, struct kvm_reg_list)
+#define KVM_S390_MEM_OP _IOW(KVMIO, 0xb1, struct kvm_s390_mem_op)
+#define KVM_S390_GET_SKEYS _IOW(KVMIO, 0xb2, struct kvm_s390_skeys)
+/* WARNING: DO NOT EDIT, AUTO-GENERATED CODE - SEE TOP FOR INSTRUCTIONS */
+#define KVM_S390_SET_SKEYS _IOW(KVMIO, 0xb3, struct kvm_s390_skeys)
+#define KVM_S390_IRQ _IOW(KVMIO, 0xb4, struct kvm_s390_irq)
+#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)
+/* WARNING: DO NOT EDIT, AUTO-GENERATED CODE - SEE TOP FOR INSTRUCTIONS */
+#define KVM_SMI _IO(KVMIO, 0xb7)
 #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/l2tp.h b/libc/kernel/uapi/linux/l2tp.h
index 4eaf7ad..cb1504b 100644
--- a/libc/kernel/uapi/linux/l2tp.h
+++ b/libc/kernel/uapi/linux/l2tp.h
@@ -154,5 +154,6 @@
 };
 #define L2TP_GENL_NAME "l2tp"
 #define L2TP_GENL_VERSION 0x1
-#endif
+#define L2TP_GENL_MCGROUP "l2tp"
 /* WARNING: DO NOT EDIT, AUTO-GENERATED CODE - SEE TOP FOR INSTRUCTIONS */
+#endif
diff --git a/libc/kernel/uapi/linux/libc-compat.h b/libc/kernel/uapi/linux/libc-compat.h
index b66ebe2..c91df87 100644
--- a/libc/kernel/uapi/linux/libc-compat.h
+++ b/libc/kernel/uapi/linux/libc-compat.h
@@ -21,27 +21,47 @@
 #ifdef __GLIBC__
 #ifdef _NETINET_IN_H
 /* WARNING: DO NOT EDIT, AUTO-GENERATED CODE - SEE TOP FOR INSTRUCTIONS */
+#define __UAPI_DEF_IN_ADDR 0
+#define __UAPI_DEF_IN_IPPROTO 0
+#define __UAPI_DEF_IN_PKTINFO 0
+#define __UAPI_DEF_IP_MREQ 0
+/* WARNING: DO NOT EDIT, AUTO-GENERATED CODE - SEE TOP FOR INSTRUCTIONS */
+#define __UAPI_DEF_SOCKADDR_IN 0
+#define __UAPI_DEF_IN_CLASS 0
 #define __UAPI_DEF_IN6_ADDR 0
 #if defined(__USE_MISC) || defined(__USE_GNU)
+/* WARNING: DO NOT EDIT, AUTO-GENERATED CODE - SEE TOP FOR INSTRUCTIONS */
 #define __UAPI_DEF_IN6_ADDR_ALT 0
 #else
-/* WARNING: DO NOT EDIT, AUTO-GENERATED CODE - SEE TOP FOR INSTRUCTIONS */
 #define __UAPI_DEF_IN6_ADDR_ALT 1
 #endif
+/* WARNING: DO NOT EDIT, AUTO-GENERATED CODE - SEE TOP FOR INSTRUCTIONS */
 #define __UAPI_DEF_SOCKADDR_IN6 0
 #define __UAPI_DEF_IPV6_MREQ 0
-/* WARNING: DO NOT EDIT, AUTO-GENERATED CODE - SEE TOP FOR INSTRUCTIONS */
 #define __UAPI_DEF_IPPROTO_V6 0
 #define __UAPI_DEF_IPV6_OPTIONS 0
-#else
-#define __UAPI_DEF_IN6_ADDR 1
 /* WARNING: DO NOT EDIT, AUTO-GENERATED CODE - SEE TOP FOR INSTRUCTIONS */
+#define __UAPI_DEF_IN6_PKTINFO 0
+#define __UAPI_DEF_IP6_MTUINFO 0
+#else
+#define __UAPI_DEF_IN_ADDR 1
+/* WARNING: DO NOT EDIT, AUTO-GENERATED CODE - SEE TOP FOR INSTRUCTIONS */
+#define __UAPI_DEF_IN_IPPROTO 1
+#define __UAPI_DEF_IN_PKTINFO 1
+#define __UAPI_DEF_IP_MREQ 1
+#define __UAPI_DEF_SOCKADDR_IN 1
+/* WARNING: DO NOT EDIT, AUTO-GENERATED CODE - SEE TOP FOR INSTRUCTIONS */
+#define __UAPI_DEF_IN_CLASS 1
+#define __UAPI_DEF_IN6_ADDR 1
 #define __UAPI_DEF_IN6_ADDR_ALT 1
 #define __UAPI_DEF_SOCKADDR_IN6 1
+/* WARNING: DO NOT EDIT, AUTO-GENERATED CODE - SEE TOP FOR INSTRUCTIONS */
 #define __UAPI_DEF_IPV6_MREQ 1
 #define __UAPI_DEF_IPPROTO_V6 1
-/* WARNING: DO NOT EDIT, AUTO-GENERATED CODE - SEE TOP FOR INSTRUCTIONS */
 #define __UAPI_DEF_IPV6_OPTIONS 1
+#define __UAPI_DEF_IN6_PKTINFO 1
+/* WARNING: DO NOT EDIT, AUTO-GENERATED CODE - SEE TOP FOR INSTRUCTIONS */
+#define __UAPI_DEF_IP6_MTUINFO 1
 #endif
 #ifdef _SYS_XATTR_H
 #define __UAPI_DEF_XATTR 0
@@ -51,13 +71,23 @@
 #endif
 #else
 /* WARNING: DO NOT EDIT, AUTO-GENERATED CODE - SEE TOP FOR INSTRUCTIONS */
+#define __UAPI_DEF_IN_ADDR 1
+#define __UAPI_DEF_IN_IPPROTO 1
+#define __UAPI_DEF_IN_PKTINFO 1
+#define __UAPI_DEF_IP_MREQ 1
+/* WARNING: DO NOT EDIT, AUTO-GENERATED CODE - SEE TOP FOR INSTRUCTIONS */
+#define __UAPI_DEF_SOCKADDR_IN 1
+#define __UAPI_DEF_IN_CLASS 1
 #define __UAPI_DEF_IN6_ADDR 1
 #define __UAPI_DEF_IN6_ADDR_ALT 1
+/* WARNING: DO NOT EDIT, AUTO-GENERATED CODE - SEE TOP FOR INSTRUCTIONS */
 #define __UAPI_DEF_SOCKADDR_IN6 1
 #define __UAPI_DEF_IPV6_MREQ 1
-/* WARNING: DO NOT EDIT, AUTO-GENERATED CODE - SEE TOP FOR INSTRUCTIONS */
 #define __UAPI_DEF_IPPROTO_V6 1
 #define __UAPI_DEF_IPV6_OPTIONS 1
+/* WARNING: DO NOT EDIT, AUTO-GENERATED CODE - SEE TOP FOR INSTRUCTIONS */
+#define __UAPI_DEF_IN6_PKTINFO 1
+#define __UAPI_DEF_IP6_MTUINFO 1
 #define __UAPI_DEF_XATTR 1
 #endif
 /* WARNING: DO NOT EDIT, AUTO-GENERATED CODE - SEE TOP FOR INSTRUCTIONS */
diff --git a/libc/kernel/uapi/linux/lightnvm.h b/libc/kernel/uapi/linux/lightnvm.h
new file mode 100644
index 0000000..a3430f3
--- /dev/null
+++ b/libc/kernel/uapi/linux/lightnvm.h
@@ -0,0 +1,113 @@
+/****************************************************************************
+ ****************************************************************************
+ ***
+ ***   This header was automatically generated from a Linux kernel header
+ ***   of the same name, to make information necessary for userspace to
+ ***   call into the kernel available to libc.  It contains only constants,
+ ***   structures, and macros generated from the original header, and thus,
+ ***   contains no copyrightable information.
+ ***
+ ***   To edit the content of this header, modify the corresponding
+ ***   source file (e.g. under external/kernel-headers/original/) then
+ ***   run bionic/libc/kernel/tools/update_all.py
+ ***
+ ***   Any manual change here will be lost the next time this script will
+ ***   be run. You've been warned!
+ ***
+ ****************************************************************************
+ ****************************************************************************/
+#ifndef _UAPI_LINUX_LIGHTNVM_H
+#define _UAPI_LINUX_LIGHTNVM_H
+#include <stdio.h>
+#include <sys/ioctl.h>
+/* WARNING: DO NOT EDIT, AUTO-GENERATED CODE - SEE TOP FOR INSTRUCTIONS */
+#define DISK_NAME_LEN 32
+#include <linux/types.h>
+#include <linux/ioctl.h>
+#define NVM_TTYPE_NAME_MAX 48
+/* WARNING: DO NOT EDIT, AUTO-GENERATED CODE - SEE TOP FOR INSTRUCTIONS */
+#define NVM_TTYPE_MAX 63
+#define NVM_CTRL_FILE "/dev/lightnvm/control"
+struct nvm_ioctl_info_tgt {
+  __u32 version[3];
+/* WARNING: DO NOT EDIT, AUTO-GENERATED CODE - SEE TOP FOR INSTRUCTIONS */
+  __u32 reserved;
+  char tgtname[NVM_TTYPE_NAME_MAX];
+};
+struct nvm_ioctl_info {
+/* WARNING: DO NOT EDIT, AUTO-GENERATED CODE - SEE TOP FOR INSTRUCTIONS */
+  __u32 version[3];
+  __u16 tgtsize;
+  __u16 reserved16;
+  __u32 reserved[12];
+/* WARNING: DO NOT EDIT, AUTO-GENERATED CODE - SEE TOP FOR INSTRUCTIONS */
+  struct nvm_ioctl_info_tgt tgts[NVM_TTYPE_MAX];
+};
+enum {
+  NVM_DEVICE_ACTIVE = 1 << 0,
+/* WARNING: DO NOT EDIT, AUTO-GENERATED CODE - SEE TOP FOR INSTRUCTIONS */
+};
+struct nvm_ioctl_device_info {
+  char devname[DISK_NAME_LEN];
+  char bmname[NVM_TTYPE_NAME_MAX];
+/* WARNING: DO NOT EDIT, AUTO-GENERATED CODE - SEE TOP FOR INSTRUCTIONS */
+  __u32 bmversion[3];
+  __u32 flags;
+  __u32 reserved[8];
+};
+/* WARNING: DO NOT EDIT, AUTO-GENERATED CODE - SEE TOP FOR INSTRUCTIONS */
+struct nvm_ioctl_get_devices {
+  __u32 nr_devices;
+  __u32 reserved[31];
+  struct nvm_ioctl_device_info info[31];
+/* WARNING: DO NOT EDIT, AUTO-GENERATED CODE - SEE TOP FOR INSTRUCTIONS */
+};
+struct nvm_ioctl_create_simple {
+  __u32 lun_begin;
+  __u32 lun_end;
+/* WARNING: DO NOT EDIT, AUTO-GENERATED CODE - SEE TOP FOR INSTRUCTIONS */
+};
+enum {
+  NVM_CONFIG_TYPE_SIMPLE = 0,
+};
+/* WARNING: DO NOT EDIT, AUTO-GENERATED CODE - SEE TOP FOR INSTRUCTIONS */
+struct nvm_ioctl_create_conf {
+  __u32 type;
+  union {
+    struct nvm_ioctl_create_simple s;
+/* WARNING: DO NOT EDIT, AUTO-GENERATED CODE - SEE TOP FOR INSTRUCTIONS */
+  };
+};
+struct nvm_ioctl_create {
+  char dev[DISK_NAME_LEN];
+/* WARNING: DO NOT EDIT, AUTO-GENERATED CODE - SEE TOP FOR INSTRUCTIONS */
+  char tgttype[NVM_TTYPE_NAME_MAX];
+  char tgtname[DISK_NAME_LEN];
+  __u32 flags;
+  struct nvm_ioctl_create_conf conf;
+/* WARNING: DO NOT EDIT, AUTO-GENERATED CODE - SEE TOP FOR INSTRUCTIONS */
+};
+struct nvm_ioctl_remove {
+  char tgtname[DISK_NAME_LEN];
+  __u32 flags;
+/* WARNING: DO NOT EDIT, AUTO-GENERATED CODE - SEE TOP FOR INSTRUCTIONS */
+};
+enum {
+  NVM_INFO_CMD = 0x20,
+  NVM_GET_DEVICES_CMD,
+/* WARNING: DO NOT EDIT, AUTO-GENERATED CODE - SEE TOP FOR INSTRUCTIONS */
+  NVM_DEV_CREATE_CMD,
+  NVM_DEV_REMOVE_CMD,
+};
+#define NVM_IOCTL 'L'
+/* WARNING: DO NOT EDIT, AUTO-GENERATED CODE - SEE TOP FOR INSTRUCTIONS */
+#define NVM_INFO _IOWR(NVM_IOCTL, NVM_INFO_CMD, struct nvm_ioctl_info)
+#define NVM_GET_DEVICES _IOR(NVM_IOCTL, NVM_GET_DEVICES_CMD, struct nvm_ioctl_get_devices)
+#define NVM_DEV_CREATE _IOW(NVM_IOCTL, NVM_DEV_CREATE_CMD, struct nvm_ioctl_create)
+#define NVM_DEV_REMOVE _IOW(NVM_IOCTL, NVM_DEV_REMOVE_CMD, struct nvm_ioctl_remove)
+/* WARNING: DO NOT EDIT, AUTO-GENERATED CODE - SEE TOP FOR INSTRUCTIONS */
+#define NVM_VERSION_MAJOR 1
+#define NVM_VERSION_MINOR 0
+#define NVM_VERSION_PATCHLEVEL 0
+#endif
+/* WARNING: DO NOT EDIT, AUTO-GENERATED CODE - SEE TOP FOR INSTRUCTIONS */
diff --git a/libc/kernel/uapi/linux/loop.h b/libc/kernel/uapi/linux/loop.h
index c0881f4..bc15421 100644
--- a/libc/kernel/uapi/linux/loop.h
+++ b/libc/kernel/uapi/linux/loop.h
@@ -26,71 +26,74 @@
   LO_FLAGS_AUTOCLEAR = 4,
   LO_FLAGS_PARTSCAN = 8,
 /* WARNING: DO NOT EDIT, AUTO-GENERATED CODE - SEE TOP FOR INSTRUCTIONS */
+  LO_FLAGS_DIRECT_IO = 16,
 };
 #include <asm/posix_types.h>
 #include <linux/types.h>
-struct loop_info {
 /* WARNING: DO NOT EDIT, AUTO-GENERATED CODE - SEE TOP FOR INSTRUCTIONS */
+struct loop_info {
   int lo_number;
   __kernel_old_dev_t lo_device;
   unsigned long lo_inode;
-  __kernel_old_dev_t lo_rdevice;
 /* WARNING: DO NOT EDIT, AUTO-GENERATED CODE - SEE TOP FOR INSTRUCTIONS */
+  __kernel_old_dev_t lo_rdevice;
   int lo_offset;
   int lo_encrypt_type;
   int lo_encrypt_key_size;
-  int lo_flags;
 /* WARNING: DO NOT EDIT, AUTO-GENERATED CODE - SEE TOP FOR INSTRUCTIONS */
+  int lo_flags;
   char lo_name[LO_NAME_SIZE];
   unsigned char lo_encrypt_key[LO_KEY_SIZE];
   unsigned long lo_init[2];
-  char reserved[4];
 /* WARNING: DO NOT EDIT, AUTO-GENERATED CODE - SEE TOP FOR INSTRUCTIONS */
+  char reserved[4];
 };
 struct loop_info64 {
   __u64 lo_device;
-  __u64 lo_inode;
 /* WARNING: DO NOT EDIT, AUTO-GENERATED CODE - SEE TOP FOR INSTRUCTIONS */
+  __u64 lo_inode;
   __u64 lo_rdevice;
   __u64 lo_offset;
   __u64 lo_sizelimit;
-  __u32 lo_number;
 /* WARNING: DO NOT EDIT, AUTO-GENERATED CODE - SEE TOP FOR INSTRUCTIONS */
+  __u32 lo_number;
   __u32 lo_encrypt_type;
   __u32 lo_encrypt_key_size;
   __u32 lo_flags;
-  __u8 lo_file_name[LO_NAME_SIZE];
 /* WARNING: DO NOT EDIT, AUTO-GENERATED CODE - SEE TOP FOR INSTRUCTIONS */
+  __u8 lo_file_name[LO_NAME_SIZE];
   __u8 lo_crypt_name[LO_NAME_SIZE];
   __u8 lo_encrypt_key[LO_KEY_SIZE];
   __u64 lo_init[2];
-};
 /* WARNING: DO NOT EDIT, AUTO-GENERATED CODE - SEE TOP FOR INSTRUCTIONS */
+};
 #define LO_CRYPT_NONE 0
 #define LO_CRYPT_XOR 1
 #define LO_CRYPT_DES 2
-#define LO_CRYPT_FISH2 3
 /* WARNING: DO NOT EDIT, AUTO-GENERATED CODE - SEE TOP FOR INSTRUCTIONS */
+#define LO_CRYPT_FISH2 3
 #define LO_CRYPT_BLOW 4
 #define LO_CRYPT_CAST128 5
 #define LO_CRYPT_IDEA 6
-#define LO_CRYPT_DUMMY 9
 /* WARNING: DO NOT EDIT, AUTO-GENERATED CODE - SEE TOP FOR INSTRUCTIONS */
+#define LO_CRYPT_DUMMY 9
 #define LO_CRYPT_SKIPJACK 10
 #define LO_CRYPT_CRYPTOAPI 18
 #define MAX_LO_CRYPT 20
-#define LOOP_SET_FD 0x4C00
 /* WARNING: DO NOT EDIT, AUTO-GENERATED CODE - SEE TOP FOR INSTRUCTIONS */
+#define LOOP_SET_FD 0x4C00
 #define LOOP_CLR_FD 0x4C01
 #define LOOP_SET_STATUS 0x4C02
 #define LOOP_GET_STATUS 0x4C03
-#define LOOP_SET_STATUS64 0x4C04
 /* WARNING: DO NOT EDIT, AUTO-GENERATED CODE - SEE TOP FOR INSTRUCTIONS */
+#define LOOP_SET_STATUS64 0x4C04
 #define LOOP_GET_STATUS64 0x4C05
 #define LOOP_CHANGE_FD 0x4C06
 #define LOOP_SET_CAPACITY 0x4C07
-#define LOOP_CTL_ADD 0x4C80
 /* WARNING: DO NOT EDIT, AUTO-GENERATED CODE - SEE TOP FOR INSTRUCTIONS */
+#define LOOP_SET_DIRECT_IO 0x4C08
+#define LOOP_CTL_ADD 0x4C80
 #define LOOP_CTL_REMOVE 0x4C81
 #define LOOP_CTL_GET_FREE 0x4C82
+/* WARNING: DO NOT EDIT, AUTO-GENERATED CODE - SEE TOP FOR INSTRUCTIONS */
 #endif
diff --git a/libc/kernel/uapi/linux/lwtunnel.h b/libc/kernel/uapi/linux/lwtunnel.h
new file mode 100644
index 0000000..9bd438f
--- /dev/null
+++ b/libc/kernel/uapi/linux/lwtunnel.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 _UAPI_LWTUNNEL_H_
+#define _UAPI_LWTUNNEL_H_
+#include <linux/types.h>
+enum lwtunnel_encap_types {
+/* WARNING: DO NOT EDIT, AUTO-GENERATED CODE - SEE TOP FOR INSTRUCTIONS */
+  LWTUNNEL_ENCAP_NONE,
+  LWTUNNEL_ENCAP_MPLS,
+  LWTUNNEL_ENCAP_IP,
+  LWTUNNEL_ENCAP_ILA,
+/* WARNING: DO NOT EDIT, AUTO-GENERATED CODE - SEE TOP FOR INSTRUCTIONS */
+  LWTUNNEL_ENCAP_IP6,
+  __LWTUNNEL_ENCAP_MAX,
+};
+#define LWTUNNEL_ENCAP_MAX (__LWTUNNEL_ENCAP_MAX - 1)
+/* WARNING: DO NOT EDIT, AUTO-GENERATED CODE - SEE TOP FOR INSTRUCTIONS */
+enum lwtunnel_ip_t {
+  LWTUNNEL_IP_UNSPEC,
+  LWTUNNEL_IP_ID,
+  LWTUNNEL_IP_DST,
+/* WARNING: DO NOT EDIT, AUTO-GENERATED CODE - SEE TOP FOR INSTRUCTIONS */
+  LWTUNNEL_IP_SRC,
+  LWTUNNEL_IP_TTL,
+  LWTUNNEL_IP_TOS,
+  LWTUNNEL_IP_FLAGS,
+/* WARNING: DO NOT EDIT, AUTO-GENERATED CODE - SEE TOP FOR INSTRUCTIONS */
+  __LWTUNNEL_IP_MAX,
+};
+#define LWTUNNEL_IP_MAX (__LWTUNNEL_IP_MAX - 1)
+enum lwtunnel_ip6_t {
+/* WARNING: DO NOT EDIT, AUTO-GENERATED CODE - SEE TOP FOR INSTRUCTIONS */
+  LWTUNNEL_IP6_UNSPEC,
+  LWTUNNEL_IP6_ID,
+  LWTUNNEL_IP6_DST,
+  LWTUNNEL_IP6_SRC,
+/* WARNING: DO NOT EDIT, AUTO-GENERATED CODE - SEE TOP FOR INSTRUCTIONS */
+  LWTUNNEL_IP6_HOPLIMIT,
+  LWTUNNEL_IP6_TC,
+  LWTUNNEL_IP6_FLAGS,
+  __LWTUNNEL_IP6_MAX,
+/* WARNING: DO NOT EDIT, AUTO-GENERATED CODE - SEE TOP FOR INSTRUCTIONS */
+};
+#define LWTUNNEL_IP6_MAX (__LWTUNNEL_IP6_MAX - 1)
+#endif
diff --git a/libc/kernel/uapi/linux/magic.h b/libc/kernel/uapi/linux/magic.h
index 7c7c6c3..16b9752 100644
--- a/libc/kernel/uapi/linux/magic.h
+++ b/libc/kernel/uapi/linux/magic.h
@@ -78,21 +78,24 @@
 /* WARNING: DO NOT EDIT, AUTO-GENERATED CODE - SEE TOP FOR INSTRUCTIONS */
 #define CGROUP_SUPER_MAGIC 0x27e0eb
 #define STACK_END_MAGIC 0x57AC6E9D
+#define TRACEFS_MAGIC 0x74726163
 #define V9FS_MAGIC 0x01021997
-#define BDEVFS_MAGIC 0x62646576
 /* WARNING: DO NOT EDIT, AUTO-GENERATED CODE - SEE TOP FOR INSTRUCTIONS */
+#define BDEVFS_MAGIC 0x62646576
 #define BINFMTFS_MAGIC 0x42494e4d
 #define DEVPTS_SUPER_MAGIC 0x1cd1
 #define FUTEXFS_SUPER_MAGIC 0xBAD1DEA
-#define PIPEFS_MAGIC 0x50495045
 /* WARNING: DO NOT EDIT, AUTO-GENERATED CODE - SEE TOP FOR INSTRUCTIONS */
+#define PIPEFS_MAGIC 0x50495045
 #define PROC_SUPER_MAGIC 0x9fa0
 #define SOCKFS_MAGIC 0x534F434B
 #define SYSFS_MAGIC 0x62656572
-#define USBDEVICE_SUPER_MAGIC 0x9fa2
 /* WARNING: DO NOT EDIT, AUTO-GENERATED CODE - SEE TOP FOR INSTRUCTIONS */
+#define USBDEVICE_SUPER_MAGIC 0x9fa2
 #define MTD_INODE_FS_MAGIC 0x11307854
 #define ANON_INODE_FS_MAGIC 0x09041934
 #define BTRFS_TEST_MAGIC 0x73727279
-#endif
 /* WARNING: DO NOT EDIT, AUTO-GENERATED CODE - SEE TOP FOR INSTRUCTIONS */
+#define NSFS_MAGIC 0x6e736673
+#define BPF_FS_MAGIC 0xcafe4a11
+#endif
diff --git a/libc/kernel/uapi/linux/media-bus-format.h b/libc/kernel/uapi/linux/media-bus-format.h
new file mode 100644
index 0000000..01f8593
--- /dev/null
+++ b/libc/kernel/uapi/linux/media-bus-format.h
@@ -0,0 +1,131 @@
+/****************************************************************************
+ ****************************************************************************
+ ***
+ ***   This header was automatically generated from a Linux kernel header
+ ***   of the same name, to make information necessary for userspace to
+ ***   call into the kernel available to libc.  It contains only constants,
+ ***   structures, and macros generated from the original header, and thus,
+ ***   contains no copyrightable information.
+ ***
+ ***   To edit the content of this header, modify the corresponding
+ ***   source file (e.g. under external/kernel-headers/original/) then
+ ***   run bionic/libc/kernel/tools/update_all.py
+ ***
+ ***   Any manual change here will be lost the next time this script will
+ ***   be run. You've been warned!
+ ***
+ ****************************************************************************
+ ****************************************************************************/
+#ifndef __LINUX_MEDIA_BUS_FORMAT_H
+#define __LINUX_MEDIA_BUS_FORMAT_H
+#define MEDIA_BUS_FMT_FIXED 0x0001
+#define MEDIA_BUS_FMT_RGB444_1X12 0x1016
+/* WARNING: DO NOT EDIT, AUTO-GENERATED CODE - SEE TOP FOR INSTRUCTIONS */
+#define MEDIA_BUS_FMT_RGB444_2X8_PADHI_BE 0x1001
+#define MEDIA_BUS_FMT_RGB444_2X8_PADHI_LE 0x1002
+#define MEDIA_BUS_FMT_RGB555_2X8_PADHI_BE 0x1003
+#define MEDIA_BUS_FMT_RGB555_2X8_PADHI_LE 0x1004
+/* WARNING: DO NOT EDIT, AUTO-GENERATED CODE - SEE TOP FOR INSTRUCTIONS */
+#define MEDIA_BUS_FMT_RGB565_1X16 0x1017
+#define MEDIA_BUS_FMT_BGR565_2X8_BE 0x1005
+#define MEDIA_BUS_FMT_BGR565_2X8_LE 0x1006
+#define MEDIA_BUS_FMT_RGB565_2X8_BE 0x1007
+/* WARNING: DO NOT EDIT, AUTO-GENERATED CODE - SEE TOP FOR INSTRUCTIONS */
+#define MEDIA_BUS_FMT_RGB565_2X8_LE 0x1008
+#define MEDIA_BUS_FMT_RGB666_1X18 0x1009
+#define MEDIA_BUS_FMT_RBG888_1X24 0x100e
+#define MEDIA_BUS_FMT_RGB666_1X24_CPADHI 0x1015
+/* WARNING: DO NOT EDIT, AUTO-GENERATED CODE - SEE TOP FOR INSTRUCTIONS */
+#define MEDIA_BUS_FMT_RGB666_1X7X3_SPWG 0x1010
+#define MEDIA_BUS_FMT_BGR888_1X24 0x1013
+#define MEDIA_BUS_FMT_GBR888_1X24 0x1014
+#define MEDIA_BUS_FMT_RGB888_1X24 0x100a
+/* WARNING: DO NOT EDIT, AUTO-GENERATED CODE - SEE TOP FOR INSTRUCTIONS */
+#define MEDIA_BUS_FMT_RGB888_2X12_BE 0x100b
+#define MEDIA_BUS_FMT_RGB888_2X12_LE 0x100c
+#define MEDIA_BUS_FMT_RGB888_1X7X4_SPWG 0x1011
+#define MEDIA_BUS_FMT_RGB888_1X7X4_JEIDA 0x1012
+/* WARNING: DO NOT EDIT, AUTO-GENERATED CODE - SEE TOP FOR INSTRUCTIONS */
+#define MEDIA_BUS_FMT_ARGB8888_1X32 0x100d
+#define MEDIA_BUS_FMT_RGB888_1X32_PADHI 0x100f
+#define MEDIA_BUS_FMT_Y8_1X8 0x2001
+#define MEDIA_BUS_FMT_UV8_1X8 0x2015
+/* WARNING: DO NOT EDIT, AUTO-GENERATED CODE - SEE TOP FOR INSTRUCTIONS */
+#define MEDIA_BUS_FMT_UYVY8_1_5X8 0x2002
+#define MEDIA_BUS_FMT_VYUY8_1_5X8 0x2003
+#define MEDIA_BUS_FMT_YUYV8_1_5X8 0x2004
+#define MEDIA_BUS_FMT_YVYU8_1_5X8 0x2005
+/* WARNING: DO NOT EDIT, AUTO-GENERATED CODE - SEE TOP FOR INSTRUCTIONS */
+#define MEDIA_BUS_FMT_UYVY8_2X8 0x2006
+#define MEDIA_BUS_FMT_VYUY8_2X8 0x2007
+#define MEDIA_BUS_FMT_YUYV8_2X8 0x2008
+#define MEDIA_BUS_FMT_YVYU8_2X8 0x2009
+/* WARNING: DO NOT EDIT, AUTO-GENERATED CODE - SEE TOP FOR INSTRUCTIONS */
+#define MEDIA_BUS_FMT_Y10_1X10 0x200a
+#define MEDIA_BUS_FMT_UYVY10_2X10 0x2018
+#define MEDIA_BUS_FMT_VYUY10_2X10 0x2019
+#define MEDIA_BUS_FMT_YUYV10_2X10 0x200b
+/* WARNING: DO NOT EDIT, AUTO-GENERATED CODE - SEE TOP FOR INSTRUCTIONS */
+#define MEDIA_BUS_FMT_YVYU10_2X10 0x200c
+#define MEDIA_BUS_FMT_Y12_1X12 0x2013
+#define MEDIA_BUS_FMT_UYVY12_2X12 0x201c
+#define MEDIA_BUS_FMT_VYUY12_2X12 0x201d
+/* WARNING: DO NOT EDIT, AUTO-GENERATED CODE - SEE TOP FOR INSTRUCTIONS */
+#define MEDIA_BUS_FMT_YUYV12_2X12 0x201e
+#define MEDIA_BUS_FMT_YVYU12_2X12 0x201f
+#define MEDIA_BUS_FMT_UYVY8_1X16 0x200f
+#define MEDIA_BUS_FMT_VYUY8_1X16 0x2010
+/* WARNING: DO NOT EDIT, AUTO-GENERATED CODE - SEE TOP FOR INSTRUCTIONS */
+#define MEDIA_BUS_FMT_YUYV8_1X16 0x2011
+#define MEDIA_BUS_FMT_YVYU8_1X16 0x2012
+#define MEDIA_BUS_FMT_YDYUYDYV8_1X16 0x2014
+#define MEDIA_BUS_FMT_UYVY10_1X20 0x201a
+/* WARNING: DO NOT EDIT, AUTO-GENERATED CODE - SEE TOP FOR INSTRUCTIONS */
+#define MEDIA_BUS_FMT_VYUY10_1X20 0x201b
+#define MEDIA_BUS_FMT_YUYV10_1X20 0x200d
+#define MEDIA_BUS_FMT_YVYU10_1X20 0x200e
+#define MEDIA_BUS_FMT_VUY8_1X24 0x2024
+/* WARNING: DO NOT EDIT, AUTO-GENERATED CODE - SEE TOP FOR INSTRUCTIONS */
+#define MEDIA_BUS_FMT_YUV8_1X24 0x2025
+#define MEDIA_BUS_FMT_UYVY12_1X24 0x2020
+#define MEDIA_BUS_FMT_VYUY12_1X24 0x2021
+#define MEDIA_BUS_FMT_YUYV12_1X24 0x2022
+/* WARNING: DO NOT EDIT, AUTO-GENERATED CODE - SEE TOP FOR INSTRUCTIONS */
+#define MEDIA_BUS_FMT_YVYU12_1X24 0x2023
+#define MEDIA_BUS_FMT_YUV10_1X30 0x2016
+#define MEDIA_BUS_FMT_AYUV8_1X32 0x2017
+#define MEDIA_BUS_FMT_SBGGR8_1X8 0x3001
+/* WARNING: DO NOT EDIT, AUTO-GENERATED CODE - SEE TOP FOR INSTRUCTIONS */
+#define MEDIA_BUS_FMT_SGBRG8_1X8 0x3013
+#define MEDIA_BUS_FMT_SGRBG8_1X8 0x3002
+#define MEDIA_BUS_FMT_SRGGB8_1X8 0x3014
+#define MEDIA_BUS_FMT_SBGGR10_ALAW8_1X8 0x3015
+/* WARNING: DO NOT EDIT, AUTO-GENERATED CODE - SEE TOP FOR INSTRUCTIONS */
+#define MEDIA_BUS_FMT_SGBRG10_ALAW8_1X8 0x3016
+#define MEDIA_BUS_FMT_SGRBG10_ALAW8_1X8 0x3017
+#define MEDIA_BUS_FMT_SRGGB10_ALAW8_1X8 0x3018
+#define MEDIA_BUS_FMT_SBGGR10_DPCM8_1X8 0x300b
+/* WARNING: DO NOT EDIT, AUTO-GENERATED CODE - SEE TOP FOR INSTRUCTIONS */
+#define MEDIA_BUS_FMT_SGBRG10_DPCM8_1X8 0x300c
+#define MEDIA_BUS_FMT_SGRBG10_DPCM8_1X8 0x3009
+#define MEDIA_BUS_FMT_SRGGB10_DPCM8_1X8 0x300d
+#define MEDIA_BUS_FMT_SBGGR10_2X8_PADHI_BE 0x3003
+/* WARNING: DO NOT EDIT, AUTO-GENERATED CODE - SEE TOP FOR INSTRUCTIONS */
+#define MEDIA_BUS_FMT_SBGGR10_2X8_PADHI_LE 0x3004
+#define MEDIA_BUS_FMT_SBGGR10_2X8_PADLO_BE 0x3005
+#define MEDIA_BUS_FMT_SBGGR10_2X8_PADLO_LE 0x3006
+#define MEDIA_BUS_FMT_SBGGR10_1X10 0x3007
+/* WARNING: DO NOT EDIT, AUTO-GENERATED CODE - SEE TOP FOR INSTRUCTIONS */
+#define MEDIA_BUS_FMT_SGBRG10_1X10 0x300e
+#define MEDIA_BUS_FMT_SGRBG10_1X10 0x300a
+#define MEDIA_BUS_FMT_SRGGB10_1X10 0x300f
+#define MEDIA_BUS_FMT_SBGGR12_1X12 0x3008
+/* WARNING: DO NOT EDIT, AUTO-GENERATED CODE - SEE TOP FOR INSTRUCTIONS */
+#define MEDIA_BUS_FMT_SGBRG12_1X12 0x3010
+#define MEDIA_BUS_FMT_SGRBG12_1X12 0x3011
+#define MEDIA_BUS_FMT_SRGGB12_1X12 0x3012
+#define MEDIA_BUS_FMT_JPEG_1X8 0x4001
+/* WARNING: DO NOT EDIT, AUTO-GENERATED CODE - SEE TOP FOR INSTRUCTIONS */
+#define MEDIA_BUS_FMT_S5C_UYVY_JPEG_1X8 0x5001
+#define MEDIA_BUS_FMT_AHSV8888_1X32 0x6001
+#endif
diff --git a/libc/kernel/uapi/linux/media.h b/libc/kernel/uapi/linux/media.h
index 5ad1330..9b9f465 100644
--- a/libc/kernel/uapi/linux/media.h
+++ b/libc/kernel/uapi/linux/media.h
@@ -46,83 +46,95 @@
 #define MEDIA_ENT_T_DEVNODE_FB (MEDIA_ENT_T_DEVNODE + 2)
 #define MEDIA_ENT_T_DEVNODE_ALSA (MEDIA_ENT_T_DEVNODE + 3)
 /* WARNING: DO NOT EDIT, AUTO-GENERATED CODE - SEE TOP FOR INSTRUCTIONS */
-#define MEDIA_ENT_T_DEVNODE_DVB (MEDIA_ENT_T_DEVNODE + 4)
+#define MEDIA_ENT_T_DEVNODE_DVB_FE (MEDIA_ENT_T_DEVNODE + 4)
+#define MEDIA_ENT_T_DEVNODE_DVB_DEMUX (MEDIA_ENT_T_DEVNODE + 5)
+#define MEDIA_ENT_T_DEVNODE_DVB_DVR (MEDIA_ENT_T_DEVNODE + 6)
+#define MEDIA_ENT_T_DEVNODE_DVB_CA (MEDIA_ENT_T_DEVNODE + 7)
+/* WARNING: DO NOT EDIT, AUTO-GENERATED CODE - SEE TOP FOR INSTRUCTIONS */
+#define MEDIA_ENT_T_DEVNODE_DVB_NET (MEDIA_ENT_T_DEVNODE + 8)
+#define MEDIA_ENT_T_DEVNODE_DVB MEDIA_ENT_T_DEVNODE_DVB_FE
 #define MEDIA_ENT_T_V4L2_SUBDEV (2 << MEDIA_ENT_TYPE_SHIFT)
 #define MEDIA_ENT_T_V4L2_SUBDEV_SENSOR (MEDIA_ENT_T_V4L2_SUBDEV + 1)
-#define MEDIA_ENT_T_V4L2_SUBDEV_FLASH (MEDIA_ENT_T_V4L2_SUBDEV + 2)
 /* WARNING: DO NOT EDIT, AUTO-GENERATED CODE - SEE TOP FOR INSTRUCTIONS */
+#define MEDIA_ENT_T_V4L2_SUBDEV_FLASH (MEDIA_ENT_T_V4L2_SUBDEV + 2)
 #define MEDIA_ENT_T_V4L2_SUBDEV_LENS (MEDIA_ENT_T_V4L2_SUBDEV + 3)
 #define MEDIA_ENT_T_V4L2_SUBDEV_DECODER (MEDIA_ENT_T_V4L2_SUBDEV + 4)
+#define MEDIA_ENT_T_V4L2_SUBDEV_TUNER (MEDIA_ENT_T_V4L2_SUBDEV + 5)
+/* WARNING: DO NOT EDIT, AUTO-GENERATED CODE - SEE TOP FOR INSTRUCTIONS */
 #define MEDIA_ENT_FL_DEFAULT (1 << 0)
 struct media_entity_desc {
-/* WARNING: DO NOT EDIT, AUTO-GENERATED CODE - SEE TOP FOR INSTRUCTIONS */
   __u32 id;
   char name[32];
+/* WARNING: DO NOT EDIT, AUTO-GENERATED CODE - SEE TOP FOR INSTRUCTIONS */
   __u32 type;
   __u32 revision;
-/* WARNING: DO NOT EDIT, AUTO-GENERATED CODE - SEE TOP FOR INSTRUCTIONS */
   __u32 flags;
   __u32 group_id;
+/* WARNING: DO NOT EDIT, AUTO-GENERATED CODE - SEE TOP FOR INSTRUCTIONS */
   __u16 pads;
   __u16 links;
-/* WARNING: DO NOT EDIT, AUTO-GENERATED CODE - SEE TOP FOR INSTRUCTIONS */
   __u32 reserved[4];
   union {
+/* WARNING: DO NOT EDIT, AUTO-GENERATED CODE - SEE TOP FOR INSTRUCTIONS */
     struct {
       __u32 major;
-/* WARNING: DO NOT EDIT, AUTO-GENERATED CODE - SEE TOP FOR INSTRUCTIONS */
       __u32 minor;
+    } dev;
+/* WARNING: DO NOT EDIT, AUTO-GENERATED CODE - SEE TOP FOR INSTRUCTIONS */
+    struct {
+      __u32 card;
+      __u32 device;
+      __u32 subdevice;
+/* WARNING: DO NOT EDIT, AUTO-GENERATED CODE - SEE TOP FOR INSTRUCTIONS */
+    } alsa;
+    struct {
+      __u32 major;
+      __u32 minor;
+/* WARNING: DO NOT EDIT, AUTO-GENERATED CODE - SEE TOP FOR INSTRUCTIONS */
     } v4l;
     struct {
       __u32 major;
-/* WARNING: DO NOT EDIT, AUTO-GENERATED CODE - SEE TOP FOR INSTRUCTIONS */
       __u32 minor;
+/* WARNING: DO NOT EDIT, AUTO-GENERATED CODE - SEE TOP FOR INSTRUCTIONS */
     } fb;
-    struct {
-      __u32 card;
-/* WARNING: DO NOT EDIT, AUTO-GENERATED CODE - SEE TOP FOR INSTRUCTIONS */
-      __u32 device;
-      __u32 subdevice;
-    } alsa;
     int dvb;
-/* WARNING: DO NOT EDIT, AUTO-GENERATED CODE - SEE TOP FOR INSTRUCTIONS */
     __u8 raw[184];
   };
+/* WARNING: DO NOT EDIT, AUTO-GENERATED CODE - SEE TOP FOR INSTRUCTIONS */
 };
 #define MEDIA_PAD_FL_SINK (1 << 0)
-/* WARNING: DO NOT EDIT, AUTO-GENERATED CODE - SEE TOP FOR INSTRUCTIONS */
 #define MEDIA_PAD_FL_SOURCE (1 << 1)
 #define MEDIA_PAD_FL_MUST_CONNECT (1 << 2)
+/* WARNING: DO NOT EDIT, AUTO-GENERATED CODE - SEE TOP FOR INSTRUCTIONS */
 struct media_pad_desc {
   __u32 entity;
-/* WARNING: DO NOT EDIT, AUTO-GENERATED CODE - SEE TOP FOR INSTRUCTIONS */
   __u16 index;
   __u32 flags;
+/* WARNING: DO NOT EDIT, AUTO-GENERATED CODE - SEE TOP FOR INSTRUCTIONS */
   __u32 reserved[2];
 };
-/* WARNING: DO NOT EDIT, AUTO-GENERATED CODE - SEE TOP FOR INSTRUCTIONS */
 #define MEDIA_LNK_FL_ENABLED (1 << 0)
 #define MEDIA_LNK_FL_IMMUTABLE (1 << 1)
+/* WARNING: DO NOT EDIT, AUTO-GENERATED CODE - SEE TOP FOR INSTRUCTIONS */
 #define MEDIA_LNK_FL_DYNAMIC (1 << 2)
 struct media_link_desc {
-/* WARNING: DO NOT EDIT, AUTO-GENERATED CODE - SEE TOP FOR INSTRUCTIONS */
   struct media_pad_desc source;
   struct media_pad_desc sink;
+/* WARNING: DO NOT EDIT, AUTO-GENERATED CODE - SEE TOP FOR INSTRUCTIONS */
   __u32 flags;
   __u32 reserved[2];
-/* WARNING: DO NOT EDIT, AUTO-GENERATED CODE - SEE TOP FOR INSTRUCTIONS */
 };
 struct media_links_enum {
+/* WARNING: DO NOT EDIT, AUTO-GENERATED CODE - SEE TOP FOR INSTRUCTIONS */
   __u32 entity;
   struct media_pad_desc __user * pads;
-/* WARNING: DO NOT EDIT, AUTO-GENERATED CODE - SEE TOP FOR INSTRUCTIONS */
   struct media_link_desc __user * links;
   __u32 reserved[4];
+/* WARNING: DO NOT EDIT, AUTO-GENERATED CODE - SEE TOP FOR INSTRUCTIONS */
 };
 #define MEDIA_IOC_DEVICE_INFO _IOWR('|', 0x00, struct media_device_info)
-/* WARNING: DO NOT EDIT, AUTO-GENERATED CODE - SEE TOP FOR INSTRUCTIONS */
 #define MEDIA_IOC_ENUM_ENTITIES _IOWR('|', 0x01, struct media_entity_desc)
 #define MEDIA_IOC_ENUM_LINKS _IOWR('|', 0x02, struct media_links_enum)
+/* WARNING: DO NOT EDIT, AUTO-GENERATED CODE - SEE TOP FOR INSTRUCTIONS */
 #define MEDIA_IOC_SETUP_LINK _IOWR('|', 0x03, struct media_link_desc)
 #endif
-/* WARNING: DO NOT EDIT, AUTO-GENERATED CODE - SEE TOP FOR INSTRUCTIONS */
diff --git a/libc/kernel/uapi/linux/mei.h b/libc/kernel/uapi/linux/mei.h
index ac8031f..4d3aec6 100644
--- a/libc/kernel/uapi/linux/mei.h
+++ b/libc/kernel/uapi/linux/mei.h
@@ -34,5 +34,7 @@
     struct mei_client out_client_properties;
   };
 };
-#endif
+#define IOCTL_MEI_NOTIFY_SET _IOW('H', 0x02, __u32)
 /* WARNING: DO NOT EDIT, AUTO-GENERATED CODE - SEE TOP FOR INSTRUCTIONS */
+#define IOCTL_MEI_NOTIFY_GET _IOR('H', 0x03, __u32)
+#endif
diff --git a/libc/kernel/uapi/linux/membarrier.h b/libc/kernel/uapi/linux/membarrier.h
new file mode 100644
index 0000000..bdab8fb
--- /dev/null
+++ b/libc/kernel/uapi/linux/membarrier.h
@@ -0,0 +1,26 @@
+/****************************************************************************
+ ****************************************************************************
+ ***
+ ***   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_MEMBARRIER_H
+#define _UAPI_LINUX_MEMBARRIER_H
+enum membarrier_cmd {
+  MEMBARRIER_CMD_QUERY = 0,
+/* WARNING: DO NOT EDIT, AUTO-GENERATED CODE - SEE TOP FOR INSTRUCTIONS */
+  MEMBARRIER_CMD_SHARED = (1 << 0),
+};
+#endif
diff --git a/libc/kernel/uapi/linux/mic_common.h b/libc/kernel/uapi/linux/mic_common.h
index 5a1735c..8715590 100644
--- a/libc/kernel/uapi/linux/mic_common.h
+++ b/libc/kernel/uapi/linux/mic_common.h
@@ -46,69 +46,70 @@
 struct mic_bootparam {
   __le32 magic;
 /* WARNING: DO NOT EDIT, AUTO-GENERATED CODE - SEE TOP FOR INSTRUCTIONS */
-  __s8 c2h_shutdown_db;
-  __s8 h2c_shutdown_db;
   __s8 h2c_config_db;
-  __u8 shutdown_status;
+  __u8 node_id;
+  __u8 h2c_scif_db;
+  __u8 c2h_scif_db;
 /* WARNING: DO NOT EDIT, AUTO-GENERATED CODE - SEE TOP FOR INSTRUCTIONS */
-  __u8 shutdown_card;
+  __u64 scif_host_dma_addr;
+  __u64 scif_card_dma_addr;
 } __attribute__((aligned(8)));
 struct mic_device_page {
-  struct mic_bootparam bootparam;
 /* WARNING: DO NOT EDIT, AUTO-GENERATED CODE - SEE TOP FOR INSTRUCTIONS */
+  struct mic_bootparam bootparam;
   struct mic_device_desc desc[0];
 };
 struct mic_vqconfig {
-  __le64 address;
 /* WARNING: DO NOT EDIT, AUTO-GENERATED CODE - SEE TOP FOR INSTRUCTIONS */
+  __le64 address;
   __le64 used_address;
   __le16 num;
 } __attribute__((aligned(8)));
-#define MIC_VIRTIO_RING_ALIGN 4096
 /* WARNING: DO NOT EDIT, AUTO-GENERATED CODE - SEE TOP FOR INSTRUCTIONS */
+#define MIC_VIRTIO_RING_ALIGN 4096
 #define MIC_MAX_VRINGS 4
 #define MIC_VRING_ENTRIES 128
 #define MIC_MAX_VRING_ENTRIES 128
-#define MIC_MAX_DESC_BLK_SIZE 256
 /* WARNING: DO NOT EDIT, AUTO-GENERATED CODE - SEE TOP FOR INSTRUCTIONS */
+#define MIC_MAX_DESC_BLK_SIZE 256
 struct _mic_vring_info {
   __u16 avail_idx;
   __le32 magic;
-};
 /* WARNING: DO NOT EDIT, AUTO-GENERATED CODE - SEE TOP FOR INSTRUCTIONS */
+};
 struct mic_vring {
   struct vring vr;
   struct _mic_vring_info * info;
-  void * va;
 /* WARNING: DO NOT EDIT, AUTO-GENERATED CODE - SEE TOP FOR INSTRUCTIONS */
+  void * va;
   int len;
 };
 #define mic_aligned_desc_size(d) __mic_align(mic_desc_size(d), 8)
-#ifndef INTEL_MIC_CARD
 /* WARNING: DO NOT EDIT, AUTO-GENERATED CODE - SEE TOP FOR INSTRUCTIONS */
+#ifndef INTEL_MIC_CARD
 #endif
 #define MIC_DP_SIZE 4096
 #define MIC_MAGIC 0xc0ffee00
+/* WARNING: DO NOT EDIT, AUTO-GENERATED CODE - SEE TOP FOR INSTRUCTIONS */
 enum mic_states {
-/* WARNING: DO NOT EDIT, AUTO-GENERATED CODE - SEE TOP FOR INSTRUCTIONS */
-  MIC_OFFLINE = 0,
+  MIC_READY = 0,
+  MIC_BOOTING,
   MIC_ONLINE,
+/* WARNING: DO NOT EDIT, AUTO-GENERATED CODE - SEE TOP FOR INSTRUCTIONS */
   MIC_SHUTTING_DOWN,
+  MIC_RESETTING,
   MIC_RESET_FAILED,
-/* WARNING: DO NOT EDIT, AUTO-GENERATED CODE - SEE TOP FOR INSTRUCTIONS */
-  MIC_SUSPENDING,
-  MIC_SUSPENDED,
   MIC_LAST
-};
 /* WARNING: DO NOT EDIT, AUTO-GENERATED CODE - SEE TOP FOR INSTRUCTIONS */
+};
 enum mic_status {
   MIC_NOP = 0,
   MIC_CRASHED,
-  MIC_HALTED,
 /* WARNING: DO NOT EDIT, AUTO-GENERATED CODE - SEE TOP FOR INSTRUCTIONS */
+  MIC_HALTED,
   MIC_POWER_OFF,
   MIC_RESTART,
   MIC_STATUS_LAST
-};
 /* WARNING: DO NOT EDIT, AUTO-GENERATED CODE - SEE TOP FOR INSTRUCTIONS */
+};
 #endif
diff --git a/libc/kernel/uapi/linux/mmc/ioctl.h b/libc/kernel/uapi/linux/mmc/ioctl.h
index 761f1d7..cd09b3e 100644
--- a/libc/kernel/uapi/linux/mmc/ioctl.h
+++ b/libc/kernel/uapi/linux/mmc/ioctl.h
@@ -41,6 +41,14 @@
 };
 #define mmc_ioc_cmd_set_data(ic,ptr) ic.data_ptr = (__u64) (unsigned long) ptr
 /* WARNING: DO NOT EDIT, AUTO-GENERATED CODE - SEE TOP FOR INSTRUCTIONS */
+struct mmc_ioc_multi_cmd {
+  __u64 num_of_cmds;
+  struct mmc_ioc_cmd cmds[0];
+};
+/* WARNING: DO NOT EDIT, AUTO-GENERATED CODE - SEE TOP FOR INSTRUCTIONS */
 #define MMC_IOC_CMD _IOWR(MMC_BLOCK_MAJOR, 0, struct mmc_ioc_cmd)
+#define MMC_IOC_MULTI_CMD _IOWR(MMC_BLOCK_MAJOR, 1, struct mmc_ioc_multi_cmd)
 #define MMC_IOC_MAX_BYTES (512L * 256)
+#define MMC_IOC_MAX_CMDS 255
+/* WARNING: DO NOT EDIT, AUTO-GENERATED CODE - SEE TOP FOR INSTRUCTIONS */
 #endif
diff --git a/libc/kernel/uapi/linux/mpls.h b/libc/kernel/uapi/linux/mpls.h
index 64b4279..1a95a30 100644
--- a/libc/kernel/uapi/linux/mpls.h
+++ b/libc/kernel/uapi/linux/mpls.h
@@ -34,5 +34,16 @@
 #define MPLS_LS_S_SHIFT 8
 #define MPLS_LS_TTL_MASK 0x000000FF
 #define MPLS_LS_TTL_SHIFT 0
-#endif
+#define MPLS_LABEL_IPV4NULL 0
 /* WARNING: DO NOT EDIT, AUTO-GENERATED CODE - SEE TOP FOR INSTRUCTIONS */
+#define MPLS_LABEL_RTALERT 1
+#define MPLS_LABEL_IPV6NULL 2
+#define MPLS_LABEL_IMPLNULL 3
+#define MPLS_LABEL_ENTROPY 7
+/* WARNING: DO NOT EDIT, AUTO-GENERATED CODE - SEE TOP FOR INSTRUCTIONS */
+#define MPLS_LABEL_GAL 13
+#define MPLS_LABEL_OAMALERT 14
+#define MPLS_LABEL_EXTENSION 15
+#define MPLS_LABEL_FIRST_UNRESERVED 16
+/* WARNING: DO NOT EDIT, AUTO-GENERATED CODE - SEE TOP FOR INSTRUCTIONS */
+#endif
diff --git a/libc/kernel/uapi/linux/mpls_iptunnel.h b/libc/kernel/uapi/linux/mpls_iptunnel.h
new file mode 100644
index 0000000..865253c
--- /dev/null
+++ b/libc/kernel/uapi/linux/mpls_iptunnel.h
@@ -0,0 +1,29 @@
+/****************************************************************************
+ ****************************************************************************
+ ***
+ ***   This header was automatically generated from a Linux kernel header
+ ***   of the same name, to make information necessary for userspace to
+ ***   call into the kernel available to libc.  It contains only constants,
+ ***   structures, and macros generated from the original header, and thus,
+ ***   contains no copyrightable information.
+ ***
+ ***   To edit the content of this header, modify the corresponding
+ ***   source file (e.g. under external/kernel-headers/original/) then
+ ***   run bionic/libc/kernel/tools/update_all.py
+ ***
+ ***   Any manual change here will be lost the next time this script will
+ ***   be run. You've been warned!
+ ***
+ ****************************************************************************
+ ****************************************************************************/
+#ifndef _UAPI_LINUX_MPLS_IPTUNNEL_H
+#define _UAPI_LINUX_MPLS_IPTUNNEL_H
+enum {
+  MPLS_IPTUNNEL_UNSPEC,
+/* WARNING: DO NOT EDIT, AUTO-GENERATED CODE - SEE TOP FOR INSTRUCTIONS */
+  MPLS_IPTUNNEL_DST,
+  __MPLS_IPTUNNEL_MAX,
+};
+#define MPLS_IPTUNNEL_MAX (__MPLS_IPTUNNEL_MAX - 1)
+/* WARNING: DO NOT EDIT, AUTO-GENERATED CODE - SEE TOP FOR INSTRUCTIONS */
+#endif
diff --git a/libc/kernel/uapi/linux/msg.h b/libc/kernel/uapi/linux/msg.h
index ab94ef6..b455f0c 100644
--- a/libc/kernel/uapi/linux/msg.h
+++ b/libc/kernel/uapi/linux/msg.h
@@ -63,17 +63,16 @@
 /* WARNING: DO NOT EDIT, AUTO-GENERATED CODE - SEE TOP FOR INSTRUCTIONS */
   unsigned short msgseg;
 };
-#define MSG_MEM_SCALE 32
-#define MSGMNI 16
-/* WARNING: DO NOT EDIT, AUTO-GENERATED CODE - SEE TOP FOR INSTRUCTIONS */
+#define MSGMNI 32000
 #define MSGMAX 8192
+/* WARNING: DO NOT EDIT, AUTO-GENERATED CODE - SEE TOP FOR INSTRUCTIONS */
 #define MSGMNB 16384
 #define MSGPOOL (MSGMNI * MSGMNB / 1024)
 #define MSGTQL MSGMNB
-/* WARNING: DO NOT EDIT, AUTO-GENERATED CODE - SEE TOP FOR INSTRUCTIONS */
 #define MSGMAP MSGMNB
+/* WARNING: DO NOT EDIT, AUTO-GENERATED CODE - SEE TOP FOR INSTRUCTIONS */
 #define MSGSSZ 16
 #define __MSGSEG ((MSGPOOL * 1024) / MSGSSZ)
 #define MSGSEG (__MSGSEG <= 0xffff ? __MSGSEG : 0xffff)
-/* WARNING: DO NOT EDIT, AUTO-GENERATED CODE - SEE TOP FOR INSTRUCTIONS */
 #endif
+/* WARNING: DO NOT EDIT, AUTO-GENERATED CODE - SEE TOP FOR INSTRUCTIONS */
diff --git a/libc/kernel/uapi/linux/nbd.h b/libc/kernel/uapi/linux/nbd.h
index 588fbd8..e24920b 100644
--- a/libc/kernel/uapi/linux/nbd.h
+++ b/libc/kernel/uapi/linux/nbd.h
@@ -47,23 +47,22 @@
 #define NBD_FLAG_SEND_FLUSH (1 << 2)
 /* WARNING: DO NOT EDIT, AUTO-GENERATED CODE - SEE TOP FOR INSTRUCTIONS */
 #define NBD_FLAG_SEND_TRIM (1 << 5)
-#define nbd_cmd(req) ((req)->cmd[0])
 #define NBD_REQUEST_MAGIC 0x25609513
 #define NBD_REPLY_MAGIC 0x67446698
-/* WARNING: DO NOT EDIT, AUTO-GENERATED CODE - SEE TOP FOR INSTRUCTIONS */
 struct nbd_request {
+/* WARNING: DO NOT EDIT, AUTO-GENERATED CODE - SEE TOP FOR INSTRUCTIONS */
   __be32 magic;
   __be32 type;
   char handle[8];
-/* WARNING: DO NOT EDIT, AUTO-GENERATED CODE - SEE TOP FOR INSTRUCTIONS */
   __be64 from;
+/* WARNING: DO NOT EDIT, AUTO-GENERATED CODE - SEE TOP FOR INSTRUCTIONS */
   __be32 len;
 } __attribute__((packed));
 struct nbd_reply {
-/* WARNING: DO NOT EDIT, AUTO-GENERATED CODE - SEE TOP FOR INSTRUCTIONS */
   __be32 magic;
+/* WARNING: DO NOT EDIT, AUTO-GENERATED CODE - SEE TOP FOR INSTRUCTIONS */
   __be32 error;
   char handle[8];
 };
-/* WARNING: DO NOT EDIT, AUTO-GENERATED CODE - SEE TOP FOR INSTRUCTIONS */
 #endif
+/* WARNING: DO NOT EDIT, AUTO-GENERATED CODE - SEE TOP FOR INSTRUCTIONS */
diff --git a/libc/kernel/uapi/linux/ndctl.h b/libc/kernel/uapi/linux/ndctl.h
new file mode 100644
index 0000000..6626e24
--- /dev/null
+++ b/libc/kernel/uapi/linux/ndctl.h
@@ -0,0 +1,168 @@
+/****************************************************************************
+ ****************************************************************************
+ ***
+ ***   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 __NDCTL_H__
+#define __NDCTL_H__
+#include <linux/types.h>
+struct nd_cmd_smart {
+/* WARNING: DO NOT EDIT, AUTO-GENERATED CODE - SEE TOP FOR INSTRUCTIONS */
+  __u32 status;
+  __u8 data[128];
+} __packed;
+struct nd_cmd_smart_threshold {
+/* WARNING: DO NOT EDIT, AUTO-GENERATED CODE - SEE TOP FOR INSTRUCTIONS */
+  __u32 status;
+  __u8 data[8];
+} __packed;
+struct nd_cmd_dimm_flags {
+/* WARNING: DO NOT EDIT, AUTO-GENERATED CODE - SEE TOP FOR INSTRUCTIONS */
+  __u32 status;
+  __u32 flags;
+} __packed;
+struct nd_cmd_get_config_size {
+/* WARNING: DO NOT EDIT, AUTO-GENERATED CODE - SEE TOP FOR INSTRUCTIONS */
+  __u32 status;
+  __u32 config_size;
+  __u32 max_xfer;
+} __packed;
+/* WARNING: DO NOT EDIT, AUTO-GENERATED CODE - SEE TOP FOR INSTRUCTIONS */
+struct nd_cmd_get_config_data_hdr {
+  __u32 in_offset;
+  __u32 in_length;
+  __u32 status;
+/* WARNING: DO NOT EDIT, AUTO-GENERATED CODE - SEE TOP FOR INSTRUCTIONS */
+  __u8 out_buf[0];
+} __packed;
+struct nd_cmd_set_config_hdr {
+  __u32 in_offset;
+/* WARNING: DO NOT EDIT, AUTO-GENERATED CODE - SEE TOP FOR INSTRUCTIONS */
+  __u32 in_length;
+  __u8 in_buf[0];
+} __packed;
+struct nd_cmd_vendor_hdr {
+/* WARNING: DO NOT EDIT, AUTO-GENERATED CODE - SEE TOP FOR INSTRUCTIONS */
+  __u32 opcode;
+  __u32 in_length;
+  __u8 in_buf[0];
+} __packed;
+/* WARNING: DO NOT EDIT, AUTO-GENERATED CODE - SEE TOP FOR INSTRUCTIONS */
+struct nd_cmd_vendor_tail {
+  __u32 status;
+  __u32 out_length;
+  __u8 out_buf[0];
+/* WARNING: DO NOT EDIT, AUTO-GENERATED CODE - SEE TOP FOR INSTRUCTIONS */
+} __packed;
+struct nd_cmd_ars_cap {
+  __u64 address;
+  __u64 length;
+/* WARNING: DO NOT EDIT, AUTO-GENERATED CODE - SEE TOP FOR INSTRUCTIONS */
+  __u32 status;
+  __u32 max_ars_out;
+} __packed;
+struct nd_cmd_ars_start {
+/* WARNING: DO NOT EDIT, AUTO-GENERATED CODE - SEE TOP FOR INSTRUCTIONS */
+  __u64 address;
+  __u64 length;
+  __u16 type;
+  __u8 reserved[6];
+/* WARNING: DO NOT EDIT, AUTO-GENERATED CODE - SEE TOP FOR INSTRUCTIONS */
+  __u32 status;
+} __packed;
+struct nd_cmd_ars_status {
+  __u32 status;
+/* WARNING: DO NOT EDIT, AUTO-GENERATED CODE - SEE TOP FOR INSTRUCTIONS */
+  __u32 out_length;
+  __u64 address;
+  __u64 length;
+  __u16 type;
+/* WARNING: DO NOT EDIT, AUTO-GENERATED CODE - SEE TOP FOR INSTRUCTIONS */
+  __u32 num_records;
+  struct nd_ars_record {
+    __u32 handle;
+    __u32 flags;
+/* WARNING: DO NOT EDIT, AUTO-GENERATED CODE - SEE TOP FOR INSTRUCTIONS */
+    __u64 err_address;
+    __u64 length;
+  } __packed records[0];
+} __packed;
+/* WARNING: DO NOT EDIT, AUTO-GENERATED CODE - SEE TOP FOR INSTRUCTIONS */
+enum {
+  ND_CMD_IMPLEMENTED = 0,
+  ND_CMD_ARS_CAP = 1,
+  ND_CMD_ARS_START = 2,
+/* WARNING: DO NOT EDIT, AUTO-GENERATED CODE - SEE TOP FOR INSTRUCTIONS */
+  ND_CMD_ARS_STATUS = 3,
+  ND_CMD_SMART = 1,
+  ND_CMD_SMART_THRESHOLD = 2,
+  ND_CMD_DIMM_FLAGS = 3,
+/* WARNING: DO NOT EDIT, AUTO-GENERATED CODE - SEE TOP FOR INSTRUCTIONS */
+  ND_CMD_GET_CONFIG_SIZE = 4,
+  ND_CMD_GET_CONFIG_DATA = 5,
+  ND_CMD_SET_CONFIG_DATA = 6,
+  ND_CMD_VENDOR_EFFECT_LOG_SIZE = 7,
+/* WARNING: DO NOT EDIT, AUTO-GENERATED CODE - SEE TOP FOR INSTRUCTIONS */
+  ND_CMD_VENDOR_EFFECT_LOG = 8,
+  ND_CMD_VENDOR = 9,
+};
+enum {
+/* WARNING: DO NOT EDIT, AUTO-GENERATED CODE - SEE TOP FOR INSTRUCTIONS */
+  ND_ARS_VOLATILE = 1,
+  ND_ARS_PERSISTENT = 2,
+};
+#define ND_IOCTL 'N'
+/* WARNING: DO NOT EDIT, AUTO-GENERATED CODE - SEE TOP FOR INSTRUCTIONS */
+#define ND_IOCTL_SMART _IOWR(ND_IOCTL, ND_CMD_SMART, struct nd_cmd_smart)
+#define ND_IOCTL_SMART_THRESHOLD _IOWR(ND_IOCTL, ND_CMD_SMART_THRESHOLD, struct nd_cmd_smart_threshold)
+#define ND_IOCTL_DIMM_FLAGS _IOWR(ND_IOCTL, ND_CMD_DIMM_FLAGS, struct nd_cmd_dimm_flags)
+#define ND_IOCTL_GET_CONFIG_SIZE _IOWR(ND_IOCTL, ND_CMD_GET_CONFIG_SIZE, struct nd_cmd_get_config_size)
+/* WARNING: DO NOT EDIT, AUTO-GENERATED CODE - SEE TOP FOR INSTRUCTIONS */
+#define ND_IOCTL_GET_CONFIG_DATA _IOWR(ND_IOCTL, ND_CMD_GET_CONFIG_DATA, struct nd_cmd_get_config_data_hdr)
+#define ND_IOCTL_SET_CONFIG_DATA _IOWR(ND_IOCTL, ND_CMD_SET_CONFIG_DATA, struct nd_cmd_set_config_hdr)
+#define ND_IOCTL_VENDOR _IOWR(ND_IOCTL, ND_CMD_VENDOR, struct nd_cmd_vendor_hdr)
+#define ND_IOCTL_ARS_CAP _IOWR(ND_IOCTL, ND_CMD_ARS_CAP, struct nd_cmd_ars_cap)
+/* WARNING: DO NOT EDIT, AUTO-GENERATED CODE - SEE TOP FOR INSTRUCTIONS */
+#define ND_IOCTL_ARS_START _IOWR(ND_IOCTL, ND_CMD_ARS_START, struct nd_cmd_ars_start)
+#define ND_IOCTL_ARS_STATUS _IOWR(ND_IOCTL, ND_CMD_ARS_STATUS, struct nd_cmd_ars_status)
+#define ND_DEVICE_DIMM 1
+#define ND_DEVICE_REGION_PMEM 2
+/* WARNING: DO NOT EDIT, AUTO-GENERATED CODE - SEE TOP FOR INSTRUCTIONS */
+#define ND_DEVICE_REGION_BLK 3
+#define ND_DEVICE_NAMESPACE_IO 4
+#define ND_DEVICE_NAMESPACE_PMEM 5
+#define ND_DEVICE_NAMESPACE_BLK 6
+/* WARNING: DO NOT EDIT, AUTO-GENERATED CODE - SEE TOP FOR INSTRUCTIONS */
+enum nd_driver_flags {
+  ND_DRIVER_DIMM = 1 << ND_DEVICE_DIMM,
+  ND_DRIVER_REGION_PMEM = 1 << ND_DEVICE_REGION_PMEM,
+  ND_DRIVER_REGION_BLK = 1 << ND_DEVICE_REGION_BLK,
+/* WARNING: DO NOT EDIT, AUTO-GENERATED CODE - SEE TOP FOR INSTRUCTIONS */
+  ND_DRIVER_NAMESPACE_IO = 1 << ND_DEVICE_NAMESPACE_IO,
+  ND_DRIVER_NAMESPACE_PMEM = 1 << ND_DEVICE_NAMESPACE_PMEM,
+  ND_DRIVER_NAMESPACE_BLK = 1 << ND_DEVICE_NAMESPACE_BLK,
+};
+/* WARNING: DO NOT EDIT, AUTO-GENERATED CODE - SEE TOP FOR INSTRUCTIONS */
+enum {
+  ND_MIN_NAMESPACE_SIZE = 0x00400000,
+};
+enum ars_masks {
+/* WARNING: DO NOT EDIT, AUTO-GENERATED CODE - SEE TOP FOR INSTRUCTIONS */
+  ARS_STATUS_MASK = 0x0000FFFF,
+  ARS_EXT_STATUS_SHIFT = 16,
+};
+#endif
+/* WARNING: DO NOT EDIT, AUTO-GENERATED CODE - SEE TOP FOR INSTRUCTIONS */
diff --git a/libc/kernel/uapi/linux/neighbour.h b/libc/kernel/uapi/linux/neighbour.h
index c73c7f4..7af454a 100644
--- a/libc/kernel/uapi/linux/neighbour.h
+++ b/libc/kernel/uapi/linux/neighbour.h
@@ -46,72 +46,77 @@
   NDA_IFINDEX,
   NDA_MASTER,
 /* WARNING: DO NOT EDIT, AUTO-GENERATED CODE - SEE TOP FOR INSTRUCTIONS */
+  NDA_LINK_NETNSID,
   __NDA_MAX
 };
 #define NDA_MAX (__NDA_MAX - 1)
-#define NTF_USE 0x01
 /* WARNING: DO NOT EDIT, AUTO-GENERATED CODE - SEE TOP FOR INSTRUCTIONS */
-#define NTF_PROXY 0x08
-#define NTF_ROUTER 0x80
+#define NTF_USE 0x01
 #define NTF_SELF 0x02
 #define NTF_MASTER 0x04
+#define NTF_PROXY 0x08
 /* WARNING: DO NOT EDIT, AUTO-GENERATED CODE - SEE TOP FOR INSTRUCTIONS */
+#define NTF_EXT_LEARNED 0x10
+#define NTF_ROUTER 0x80
 #define NUD_INCOMPLETE 0x01
 #define NUD_REACHABLE 0x02
+/* WARNING: DO NOT EDIT, AUTO-GENERATED CODE - SEE TOP FOR INSTRUCTIONS */
 #define NUD_STALE 0x04
 #define NUD_DELAY 0x08
-/* WARNING: DO NOT EDIT, AUTO-GENERATED CODE - SEE TOP FOR INSTRUCTIONS */
 #define NUD_PROBE 0x10
 #define NUD_FAILED 0x20
+/* WARNING: DO NOT EDIT, AUTO-GENERATED CODE - SEE TOP FOR INSTRUCTIONS */
 #define NUD_NOARP 0x40
 #define NUD_PERMANENT 0x80
-/* WARNING: DO NOT EDIT, AUTO-GENERATED CODE - SEE TOP FOR INSTRUCTIONS */
 #define NUD_NONE 0x00
 struct nda_cacheinfo {
+/* WARNING: DO NOT EDIT, AUTO-GENERATED CODE - SEE TOP FOR INSTRUCTIONS */
   __u32 ndm_confirmed;
   __u32 ndm_used;
-/* WARNING: DO NOT EDIT, AUTO-GENERATED CODE - SEE TOP FOR INSTRUCTIONS */
   __u32 ndm_updated;
   __u32 ndm_refcnt;
+/* WARNING: DO NOT EDIT, AUTO-GENERATED CODE - SEE TOP FOR INSTRUCTIONS */
 };
 struct ndt_stats {
-/* WARNING: DO NOT EDIT, AUTO-GENERATED CODE - SEE TOP FOR INSTRUCTIONS */
   __u64 ndts_allocs;
   __u64 ndts_destroys;
+/* WARNING: DO NOT EDIT, AUTO-GENERATED CODE - SEE TOP FOR INSTRUCTIONS */
   __u64 ndts_hash_grows;
   __u64 ndts_res_failed;
-/* WARNING: DO NOT EDIT, AUTO-GENERATED CODE - SEE TOP FOR INSTRUCTIONS */
   __u64 ndts_lookups;
   __u64 ndts_hits;
+/* WARNING: DO NOT EDIT, AUTO-GENERATED CODE - SEE TOP FOR INSTRUCTIONS */
   __u64 ndts_rcv_probes_mcast;
   __u64 ndts_rcv_probes_ucast;
-/* WARNING: DO NOT EDIT, AUTO-GENERATED CODE - SEE TOP FOR INSTRUCTIONS */
   __u64 ndts_periodic_gc_runs;
   __u64 ndts_forced_gc_runs;
+/* WARNING: DO NOT EDIT, AUTO-GENERATED CODE - SEE TOP FOR INSTRUCTIONS */
+  __u64 ndts_table_fulls;
 };
 enum {
-/* WARNING: DO NOT EDIT, AUTO-GENERATED CODE - SEE TOP FOR INSTRUCTIONS */
   NDTPA_UNSPEC,
+/* WARNING: DO NOT EDIT, AUTO-GENERATED CODE - SEE TOP FOR INSTRUCTIONS */
   NDTPA_IFINDEX,
   NDTPA_REFCNT,
   NDTPA_REACHABLE_TIME,
-/* WARNING: DO NOT EDIT, AUTO-GENERATED CODE - SEE TOP FOR INSTRUCTIONS */
   NDTPA_BASE_REACHABLE_TIME,
+/* WARNING: DO NOT EDIT, AUTO-GENERATED CODE - SEE TOP FOR INSTRUCTIONS */
   NDTPA_RETRANS_TIME,
   NDTPA_GC_STALETIME,
   NDTPA_DELAY_PROBE_TIME,
-/* WARNING: DO NOT EDIT, AUTO-GENERATED CODE - SEE TOP FOR INSTRUCTIONS */
   NDTPA_QUEUE_LEN,
+/* WARNING: DO NOT EDIT, AUTO-GENERATED CODE - SEE TOP FOR INSTRUCTIONS */
   NDTPA_APP_PROBES,
   NDTPA_UCAST_PROBES,
   NDTPA_MCAST_PROBES,
-/* WARNING: DO NOT EDIT, AUTO-GENERATED CODE - SEE TOP FOR INSTRUCTIONS */
   NDTPA_ANYCAST_DELAY,
+/* WARNING: DO NOT EDIT, AUTO-GENERATED CODE - SEE TOP FOR INSTRUCTIONS */
   NDTPA_PROXY_DELAY,
   NDTPA_PROXY_QLEN,
   NDTPA_LOCKTIME,
-/* WARNING: DO NOT EDIT, AUTO-GENERATED CODE - SEE TOP FOR INSTRUCTIONS */
   NDTPA_QUEUE_LENBYTES,
+/* WARNING: DO NOT EDIT, AUTO-GENERATED CODE - SEE TOP FOR INSTRUCTIONS */
+  NDTPA_MCAST_REPROBES,
   __NDTPA_MAX
 };
 #define NDTPA_MAX (__NDTPA_MAX - 1)
diff --git a/libc/kernel/uapi/linux/net_namespace.h b/libc/kernel/uapi/linux/net_namespace.h
new file mode 100644
index 0000000..c9fdd79
--- /dev/null
+++ b/libc/kernel/uapi/linux/net_namespace.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 _UAPI_LINUX_NET_NAMESPACE_H_
+#define _UAPI_LINUX_NET_NAMESPACE_H_
+enum {
+  NETNSA_NONE,
+/* WARNING: DO NOT EDIT, AUTO-GENERATED CODE - SEE TOP FOR INSTRUCTIONS */
+#define NETNSA_NSID_NOT_ASSIGNED - 1
+  NETNSA_NSID,
+  NETNSA_PID,
+  NETNSA_FD,
+/* WARNING: DO NOT EDIT, AUTO-GENERATED CODE - SEE TOP FOR INSTRUCTIONS */
+  __NETNSA_MAX,
+};
+#define NETNSA_MAX (__NETNSA_MAX - 1)
+#endif
+/* WARNING: DO NOT EDIT, AUTO-GENERATED CODE - SEE TOP FOR INSTRUCTIONS */
diff --git a/libc/kernel/uapi/linux/net_tstamp.h b/libc/kernel/uapi/linux/net_tstamp.h
index 5dfd2ac..045201c 100644
--- a/libc/kernel/uapi/linux/net_tstamp.h
+++ b/libc/kernel/uapi/linux/net_tstamp.h
@@ -33,42 +33,44 @@
 /* WARNING: DO NOT EDIT, AUTO-GENERATED CODE - SEE TOP FOR INSTRUCTIONS */
   SOF_TIMESTAMPING_TX_SCHED = (1 << 8),
   SOF_TIMESTAMPING_TX_ACK = (1 << 9),
-  SOF_TIMESTAMPING_LAST = SOF_TIMESTAMPING_TX_ACK,
-  SOF_TIMESTAMPING_MASK = (SOF_TIMESTAMPING_LAST - 1) | SOF_TIMESTAMPING_LAST
+  SOF_TIMESTAMPING_OPT_CMSG = (1 << 10),
+  SOF_TIMESTAMPING_OPT_TSONLY = (1 << 11),
 /* WARNING: DO NOT EDIT, AUTO-GENERATED CODE - SEE TOP FOR INSTRUCTIONS */
+  SOF_TIMESTAMPING_LAST = SOF_TIMESTAMPING_OPT_TSONLY,
+  SOF_TIMESTAMPING_MASK = (SOF_TIMESTAMPING_LAST - 1) | SOF_TIMESTAMPING_LAST
 };
 struct hwtstamp_config {
+/* WARNING: DO NOT EDIT, AUTO-GENERATED CODE - SEE TOP FOR INSTRUCTIONS */
   int flags;
   int tx_type;
-/* WARNING: DO NOT EDIT, AUTO-GENERATED CODE - SEE TOP FOR INSTRUCTIONS */
   int rx_filter;
 };
+/* WARNING: DO NOT EDIT, AUTO-GENERATED CODE - SEE TOP FOR INSTRUCTIONS */
 enum hwtstamp_tx_types {
   HWTSTAMP_TX_OFF,
-/* WARNING: DO NOT EDIT, AUTO-GENERATED CODE - SEE TOP FOR INSTRUCTIONS */
   HWTSTAMP_TX_ON,
   HWTSTAMP_TX_ONESTEP_SYNC,
+/* WARNING: DO NOT EDIT, AUTO-GENERATED CODE - SEE TOP FOR INSTRUCTIONS */
 };
 enum hwtstamp_rx_filters {
-/* WARNING: DO NOT EDIT, AUTO-GENERATED CODE - SEE TOP FOR INSTRUCTIONS */
   HWTSTAMP_FILTER_NONE,
   HWTSTAMP_FILTER_ALL,
+/* WARNING: DO NOT EDIT, AUTO-GENERATED CODE - SEE TOP FOR INSTRUCTIONS */
   HWTSTAMP_FILTER_SOME,
   HWTSTAMP_FILTER_PTP_V1_L4_EVENT,
-/* WARNING: DO NOT EDIT, AUTO-GENERATED CODE - SEE TOP FOR INSTRUCTIONS */
   HWTSTAMP_FILTER_PTP_V1_L4_SYNC,
   HWTSTAMP_FILTER_PTP_V1_L4_DELAY_REQ,
+/* WARNING: DO NOT EDIT, AUTO-GENERATED CODE - SEE TOP FOR INSTRUCTIONS */
   HWTSTAMP_FILTER_PTP_V2_L4_EVENT,
   HWTSTAMP_FILTER_PTP_V2_L4_SYNC,
-/* WARNING: DO NOT EDIT, AUTO-GENERATED CODE - SEE TOP FOR INSTRUCTIONS */
   HWTSTAMP_FILTER_PTP_V2_L4_DELAY_REQ,
   HWTSTAMP_FILTER_PTP_V2_L2_EVENT,
+/* WARNING: DO NOT EDIT, AUTO-GENERATED CODE - SEE TOP FOR INSTRUCTIONS */
   HWTSTAMP_FILTER_PTP_V2_L2_SYNC,
   HWTSTAMP_FILTER_PTP_V2_L2_DELAY_REQ,
-/* WARNING: DO NOT EDIT, AUTO-GENERATED CODE - SEE TOP FOR INSTRUCTIONS */
   HWTSTAMP_FILTER_PTP_V2_EVENT,
   HWTSTAMP_FILTER_PTP_V2_SYNC,
+/* WARNING: DO NOT EDIT, AUTO-GENERATED CODE - SEE TOP FOR INSTRUCTIONS */
   HWTSTAMP_FILTER_PTP_V2_DELAY_REQ,
 };
-/* WARNING: DO NOT EDIT, AUTO-GENERATED CODE - SEE TOP FOR INSTRUCTIONS */
 #endif
diff --git a/libc/kernel/uapi/linux/netconf.h b/libc/kernel/uapi/linux/netconf.h
index a9bf216..556ecaf 100644
--- a/libc/kernel/uapi/linux/netconf.h
+++ b/libc/kernel/uapi/linux/netconf.h
@@ -33,11 +33,12 @@
 /* WARNING: DO NOT EDIT, AUTO-GENERATED CODE - SEE TOP FOR INSTRUCTIONS */
   NETCONFA_MC_FORWARDING,
   NETCONFA_PROXY_NEIGH,
+  NETCONFA_IGNORE_ROUTES_WITH_LINKDOWN,
   __NETCONFA_MAX
-};
 /* WARNING: DO NOT EDIT, AUTO-GENERATED CODE - SEE TOP FOR INSTRUCTIONS */
+};
 #define NETCONFA_MAX (__NETCONFA_MAX - 1)
 #define NETCONFA_IFINDEX_ALL - 1
 #define NETCONFA_IFINDEX_DEFAULT - 2
-#endif
 /* WARNING: DO NOT EDIT, AUTO-GENERATED CODE - SEE TOP FOR INSTRUCTIONS */
+#endif
diff --git a/libc/kernel/uapi/linux/netfilter.h b/libc/kernel/uapi/linux/netfilter.h
index b04daa4..2d85c02 100644
--- a/libc/kernel/uapi/linux/netfilter.h
+++ b/libc/kernel/uapi/linux/netfilter.h
@@ -22,55 +22,64 @@
 #include <linux/compiler.h>
 /* WARNING: DO NOT EDIT, AUTO-GENERATED CODE - SEE TOP FOR INSTRUCTIONS */
 #include <linux/sysctl.h>
+#include <linux/in.h>
+#include <linux/in6.h>
 #define NF_DROP 0
+/* WARNING: DO NOT EDIT, AUTO-GENERATED CODE - SEE TOP FOR INSTRUCTIONS */
 #define NF_ACCEPT 1
 #define NF_STOLEN 2
-/* WARNING: DO NOT EDIT, AUTO-GENERATED CODE - SEE TOP FOR INSTRUCTIONS */
 #define NF_QUEUE 3
 #define NF_REPEAT 4
+/* WARNING: DO NOT EDIT, AUTO-GENERATED CODE - SEE TOP FOR INSTRUCTIONS */
 #define NF_STOP 5
 #define NF_MAX_VERDICT NF_STOP
-/* WARNING: DO NOT EDIT, AUTO-GENERATED CODE - SEE TOP FOR INSTRUCTIONS */
 #define NF_VERDICT_MASK 0x000000ff
 #define NF_VERDICT_FLAG_QUEUE_BYPASS 0x00008000
+/* WARNING: DO NOT EDIT, AUTO-GENERATED CODE - SEE TOP FOR INSTRUCTIONS */
 #define NF_VERDICT_QMASK 0xffff0000
 #define NF_VERDICT_QBITS 16
-/* WARNING: DO NOT EDIT, AUTO-GENERATED CODE - SEE TOP FOR INSTRUCTIONS */
 #define NF_QUEUE_NR(x) ((((x) << 16) & NF_VERDICT_QMASK) | NF_QUEUE)
 #define NF_DROP_ERR(x) (((- x) << 16) | NF_DROP)
+/* WARNING: DO NOT EDIT, AUTO-GENERATED CODE - SEE TOP FOR INSTRUCTIONS */
 #define NFC_UNKNOWN 0x4000
 #define NFC_ALTERED 0x8000
-/* WARNING: DO NOT EDIT, AUTO-GENERATED CODE - SEE TOP FOR INSTRUCTIONS */
 #define NF_VERDICT_BITS 16
 enum nf_inet_hooks {
+/* WARNING: DO NOT EDIT, AUTO-GENERATED CODE - SEE TOP FOR INSTRUCTIONS */
   NF_INET_PRE_ROUTING,
   NF_INET_LOCAL_IN,
-/* WARNING: DO NOT EDIT, AUTO-GENERATED CODE - SEE TOP FOR INSTRUCTIONS */
   NF_INET_FORWARD,
   NF_INET_LOCAL_OUT,
+/* WARNING: DO NOT EDIT, AUTO-GENERATED CODE - SEE TOP FOR INSTRUCTIONS */
   NF_INET_POST_ROUTING,
   NF_INET_NUMHOOKS
+};
+enum nf_dev_hooks {
 /* WARNING: DO NOT EDIT, AUTO-GENERATED CODE - SEE TOP FOR INSTRUCTIONS */
+  NF_NETDEV_INGRESS,
+  NF_NETDEV_NUMHOOKS
 };
 enum {
+/* WARNING: DO NOT EDIT, AUTO-GENERATED CODE - SEE TOP FOR INSTRUCTIONS */
   NFPROTO_UNSPEC = 0,
   NFPROTO_INET = 1,
-/* WARNING: DO NOT EDIT, AUTO-GENERATED CODE - SEE TOP FOR INSTRUCTIONS */
   NFPROTO_IPV4 = 2,
   NFPROTO_ARP = 3,
+/* WARNING: DO NOT EDIT, AUTO-GENERATED CODE - SEE TOP FOR INSTRUCTIONS */
+  NFPROTO_NETDEV = 5,
   NFPROTO_BRIDGE = 7,
   NFPROTO_IPV6 = 10,
-/* WARNING: DO NOT EDIT, AUTO-GENERATED CODE - SEE TOP FOR INSTRUCTIONS */
   NFPROTO_DECNET = 12,
+/* WARNING: DO NOT EDIT, AUTO-GENERATED CODE - SEE TOP FOR INSTRUCTIONS */
   NFPROTO_NUMPROTO,
 };
 union nf_inet_addr {
-/* WARNING: DO NOT EDIT, AUTO-GENERATED CODE - SEE TOP FOR INSTRUCTIONS */
   __u32 all[4];
+/* WARNING: DO NOT EDIT, AUTO-GENERATED CODE - SEE TOP FOR INSTRUCTIONS */
   __be32 ip;
   __be32 ip6[4];
   struct in_addr in;
-/* WARNING: DO NOT EDIT, AUTO-GENERATED CODE - SEE TOP FOR INSTRUCTIONS */
   struct in6_addr in6;
+/* WARNING: DO NOT EDIT, AUTO-GENERATED CODE - SEE TOP FOR INSTRUCTIONS */
 };
 #endif
diff --git a/libc/kernel/uapi/linux/netfilter/ipset/ip_set.h b/libc/kernel/uapi/linux/netfilter/ipset/ip_set.h
index 8210a74..7459cb4 100644
--- a/libc/kernel/uapi/linux/netfilter/ipset/ip_set.h
+++ b/libc/kernel/uapi/linux/netfilter/ipset/ip_set.h
@@ -21,8 +21,8 @@
 #include <linux/types.h>
 #define IPSET_PROTOCOL 6
 /* WARNING: DO NOT EDIT, AUTO-GENERATED CODE - SEE TOP FOR INSTRUCTIONS */
-#define IPSET_MAX_COMMENT_SIZE 255
 #define IPSET_MAXNAMELEN 32
+#define IPSET_MAX_COMMENT_SIZE 255
 enum ipset_cmd {
   IPSET_CMD_NONE,
 /* WARNING: DO NOT EDIT, AUTO-GENERATED CODE - SEE TOP FOR INSTRUCTIONS */
@@ -261,11 +261,16 @@
   IPSET_COUNTER_GT,
 };
 /* WARNING: DO NOT EDIT, AUTO-GENERATED CODE - SEE TOP FOR INSTRUCTIONS */
-struct ip_set_counter_match {
+struct ip_set_counter_match0 {
   __u8 op;
   __u64 value;
 };
 /* WARNING: DO NOT EDIT, AUTO-GENERATED CODE - SEE TOP FOR INSTRUCTIONS */
+struct ip_set_counter_match {
+  __aligned_u64 value;
+  __u8 op;
+};
+/* WARNING: DO NOT EDIT, AUTO-GENERATED CODE - SEE TOP FOR INSTRUCTIONS */
 #define SO_IP_SET 83
 union ip_set_name_index {
   char name[IPSET_MAXNAMELEN];
diff --git a/libc/kernel/uapi/linux/netfilter/nf_conntrack_sctp.h b/libc/kernel/uapi/linux/netfilter/nf_conntrack_sctp.h
index f30c58e..dd7525a 100644
--- a/libc/kernel/uapi/linux/netfilter/nf_conntrack_sctp.h
+++ b/libc/kernel/uapi/linux/netfilter/nf_conntrack_sctp.h
@@ -31,11 +31,14 @@
   SCTP_CONNTRACK_SHUTDOWN_RECD,
   SCTP_CONNTRACK_SHUTDOWN_ACK_SENT,
 /* WARNING: DO NOT EDIT, AUTO-GENERATED CODE - SEE TOP FOR INSTRUCTIONS */
+  SCTP_CONNTRACK_HEARTBEAT_SENT,
+  SCTP_CONNTRACK_HEARTBEAT_ACKED,
   SCTP_CONNTRACK_MAX
 };
+/* WARNING: DO NOT EDIT, AUTO-GENERATED CODE - SEE TOP FOR INSTRUCTIONS */
 struct ip_ct_sctp {
   enum sctp_conntrack state;
-/* WARNING: DO NOT EDIT, AUTO-GENERATED CODE - SEE TOP FOR INSTRUCTIONS */
   __be32 vtag[IP_CT_DIR_MAX];
 };
+/* WARNING: DO NOT EDIT, AUTO-GENERATED CODE - SEE TOP FOR INSTRUCTIONS */
 #endif
diff --git a/libc/kernel/uapi/linux/netfilter/nf_conntrack_tcp.h b/libc/kernel/uapi/linux/netfilter/nf_conntrack_tcp.h
index 1af00d1..8ed4c29 100644
--- a/libc/kernel/uapi/linux/netfilter/nf_conntrack_tcp.h
+++ b/libc/kernel/uapi/linux/netfilter/nf_conntrack_tcp.h
@@ -49,10 +49,11 @@
 #define IP_CT_TCP_FLAG_BE_LIBERAL 0x08
 #define IP_CT_TCP_FLAG_DATA_UNACKNOWLEDGED 0x10
 #define IP_CT_TCP_FLAG_MAXACK_SET 0x20
-struct nf_ct_tcp_flags {
+#define IP_CT_EXP_CHALLENGE_ACK 0x40
 /* WARNING: DO NOT EDIT, AUTO-GENERATED CODE - SEE TOP FOR INSTRUCTIONS */
+struct nf_ct_tcp_flags {
   __u8 flags;
   __u8 mask;
 };
-#endif
 /* WARNING: DO NOT EDIT, AUTO-GENERATED CODE - SEE TOP FOR INSTRUCTIONS */
+#endif
diff --git a/libc/kernel/uapi/linux/netfilter/nf_tables.h b/libc/kernel/uapi/linux/netfilter/nf_tables.h
index 58984af..7284549 100644
--- a/libc/kernel/uapi/linux/netfilter/nf_tables.h
+++ b/libc/kernel/uapi/linux/netfilter/nf_tables.h
@@ -18,66 +18,91 @@
  ****************************************************************************/
 #ifndef _LINUX_NF_TABLES_H
 #define _LINUX_NF_TABLES_H
+#define NFT_TABLE_MAXNAMELEN 32
 #define NFT_CHAIN_MAXNAMELEN 32
-#define NFT_USERDATA_MAXLEN 256
 /* WARNING: DO NOT EDIT, AUTO-GENERATED CODE - SEE TOP FOR INSTRUCTIONS */
+#define NFT_USERDATA_MAXLEN 256
 enum nft_registers {
   NFT_REG_VERDICT,
   NFT_REG_1,
-  NFT_REG_2,
 /* WARNING: DO NOT EDIT, AUTO-GENERATED CODE - SEE TOP FOR INSTRUCTIONS */
+  NFT_REG_2,
   NFT_REG_3,
   NFT_REG_4,
-  __NFT_REG_MAX
-};
+  __NFT_REG_MAX,
 /* WARNING: DO NOT EDIT, AUTO-GENERATED CODE - SEE TOP FOR INSTRUCTIONS */
+  NFT_REG32_00 = 8,
+  MFT_REG32_01,
+  NFT_REG32_02,
+  NFT_REG32_03,
+/* WARNING: DO NOT EDIT, AUTO-GENERATED CODE - SEE TOP FOR INSTRUCTIONS */
+  NFT_REG32_04,
+  NFT_REG32_05,
+  NFT_REG32_06,
+  NFT_REG32_07,
+/* WARNING: DO NOT EDIT, AUTO-GENERATED CODE - SEE TOP FOR INSTRUCTIONS */
+  NFT_REG32_08,
+  NFT_REG32_09,
+  NFT_REG32_10,
+  NFT_REG32_11,
+/* WARNING: DO NOT EDIT, AUTO-GENERATED CODE - SEE TOP FOR INSTRUCTIONS */
+  NFT_REG32_12,
+  NFT_REG32_13,
+  NFT_REG32_14,
+  NFT_REG32_15,
+/* WARNING: DO NOT EDIT, AUTO-GENERATED CODE - SEE TOP FOR INSTRUCTIONS */
+};
 #define NFT_REG_MAX (__NFT_REG_MAX - 1)
+#define NFT_REG_SIZE 16
+#define NFT_REG32_SIZE 4
+/* WARNING: DO NOT EDIT, AUTO-GENERATED CODE - SEE TOP FOR INSTRUCTIONS */
 enum nft_verdicts {
   NFT_CONTINUE = - 1,
   NFT_BREAK = - 2,
-/* WARNING: DO NOT EDIT, AUTO-GENERATED CODE - SEE TOP FOR INSTRUCTIONS */
   NFT_JUMP = - 3,
+/* WARNING: DO NOT EDIT, AUTO-GENERATED CODE - SEE TOP FOR INSTRUCTIONS */
   NFT_GOTO = - 4,
   NFT_RETURN = - 5,
 };
-/* WARNING: DO NOT EDIT, AUTO-GENERATED CODE - SEE TOP FOR INSTRUCTIONS */
 enum nf_tables_msg_types {
+/* WARNING: DO NOT EDIT, AUTO-GENERATED CODE - SEE TOP FOR INSTRUCTIONS */
   NFT_MSG_NEWTABLE,
   NFT_MSG_GETTABLE,
   NFT_MSG_DELTABLE,
-/* WARNING: DO NOT EDIT, AUTO-GENERATED CODE - SEE TOP FOR INSTRUCTIONS */
   NFT_MSG_NEWCHAIN,
+/* WARNING: DO NOT EDIT, AUTO-GENERATED CODE - SEE TOP FOR INSTRUCTIONS */
   NFT_MSG_GETCHAIN,
   NFT_MSG_DELCHAIN,
   NFT_MSG_NEWRULE,
-/* WARNING: DO NOT EDIT, AUTO-GENERATED CODE - SEE TOP FOR INSTRUCTIONS */
   NFT_MSG_GETRULE,
+/* WARNING: DO NOT EDIT, AUTO-GENERATED CODE - SEE TOP FOR INSTRUCTIONS */
   NFT_MSG_DELRULE,
   NFT_MSG_NEWSET,
   NFT_MSG_GETSET,
-/* WARNING: DO NOT EDIT, AUTO-GENERATED CODE - SEE TOP FOR INSTRUCTIONS */
   NFT_MSG_DELSET,
+/* WARNING: DO NOT EDIT, AUTO-GENERATED CODE - SEE TOP FOR INSTRUCTIONS */
   NFT_MSG_NEWSETELEM,
   NFT_MSG_GETSETELEM,
   NFT_MSG_DELSETELEM,
-/* WARNING: DO NOT EDIT, AUTO-GENERATED CODE - SEE TOP FOR INSTRUCTIONS */
   NFT_MSG_NEWGEN,
+/* WARNING: DO NOT EDIT, AUTO-GENERATED CODE - SEE TOP FOR INSTRUCTIONS */
   NFT_MSG_GETGEN,
   NFT_MSG_MAX,
 };
-/* WARNING: DO NOT EDIT, AUTO-GENERATED CODE - SEE TOP FOR INSTRUCTIONS */
 enum nft_list_attributes {
+/* WARNING: DO NOT EDIT, AUTO-GENERATED CODE - SEE TOP FOR INSTRUCTIONS */
   NFTA_LIST_UNPEC,
   NFTA_LIST_ELEM,
   __NFTA_LIST_MAX
-/* WARNING: DO NOT EDIT, AUTO-GENERATED CODE - SEE TOP FOR INSTRUCTIONS */
 };
+/* WARNING: DO NOT EDIT, AUTO-GENERATED CODE - SEE TOP FOR INSTRUCTIONS */
 #define NFTA_LIST_MAX (__NFTA_LIST_MAX - 1)
 enum nft_hook_attributes {
   NFTA_HOOK_UNSPEC,
-/* WARNING: DO NOT EDIT, AUTO-GENERATED CODE - SEE TOP FOR INSTRUCTIONS */
   NFTA_HOOK_HOOKNUM,
+/* WARNING: DO NOT EDIT, AUTO-GENERATED CODE - SEE TOP FOR INSTRUCTIONS */
   NFTA_HOOK_PRIORITY,
+  NFTA_HOOK_DEV,
   __NFTA_HOOK_MAX
 };
 /* WARNING: DO NOT EDIT, AUTO-GENERATED CODE - SEE TOP FOR INSTRUCTIONS */
@@ -147,34 +172,39 @@
   NFT_SET_INTERVAL = 0x4,
 /* WARNING: DO NOT EDIT, AUTO-GENERATED CODE - SEE TOP FOR INSTRUCTIONS */
   NFT_SET_MAP = 0x8,
+  NFT_SET_TIMEOUT = 0x10,
+  NFT_SET_EVAL = 0x20,
 };
+/* WARNING: DO NOT EDIT, AUTO-GENERATED CODE - SEE TOP FOR INSTRUCTIONS */
 enum nft_set_policies {
   NFT_SET_POL_PERFORMANCE,
-/* WARNING: DO NOT EDIT, AUTO-GENERATED CODE - SEE TOP FOR INSTRUCTIONS */
   NFT_SET_POL_MEMORY,
 };
+/* WARNING: DO NOT EDIT, AUTO-GENERATED CODE - SEE TOP FOR INSTRUCTIONS */
 enum nft_set_desc_attributes {
   NFTA_SET_DESC_UNSPEC,
-/* WARNING: DO NOT EDIT, AUTO-GENERATED CODE - SEE TOP FOR INSTRUCTIONS */
   NFTA_SET_DESC_SIZE,
   __NFTA_SET_DESC_MAX
+/* WARNING: DO NOT EDIT, AUTO-GENERATED CODE - SEE TOP FOR INSTRUCTIONS */
 };
 #define NFTA_SET_DESC_MAX (__NFTA_SET_DESC_MAX - 1)
-/* WARNING: DO NOT EDIT, AUTO-GENERATED CODE - SEE TOP FOR INSTRUCTIONS */
 enum nft_set_attributes {
   NFTA_SET_UNSPEC,
+/* WARNING: DO NOT EDIT, AUTO-GENERATED CODE - SEE TOP FOR INSTRUCTIONS */
   NFTA_SET_TABLE,
   NFTA_SET_NAME,
-/* WARNING: DO NOT EDIT, AUTO-GENERATED CODE - SEE TOP FOR INSTRUCTIONS */
   NFTA_SET_FLAGS,
   NFTA_SET_KEY_TYPE,
+/* WARNING: DO NOT EDIT, AUTO-GENERATED CODE - SEE TOP FOR INSTRUCTIONS */
   NFTA_SET_KEY_LEN,
   NFTA_SET_DATA_TYPE,
-/* WARNING: DO NOT EDIT, AUTO-GENERATED CODE - SEE TOP FOR INSTRUCTIONS */
   NFTA_SET_DATA_LEN,
   NFTA_SET_POLICY,
+/* WARNING: DO NOT EDIT, AUTO-GENERATED CODE - SEE TOP FOR INSTRUCTIONS */
   NFTA_SET_DESC,
   NFTA_SET_ID,
+  NFTA_SET_TIMEOUT,
+  NFTA_SET_GC_INTERVAL,
 /* WARNING: DO NOT EDIT, AUTO-GENERATED CODE - SEE TOP FOR INSTRUCTIONS */
   __NFTA_SET_MAX
 };
@@ -189,6 +219,11 @@
   NFTA_SET_ELEM_KEY,
   NFTA_SET_ELEM_DATA,
   NFTA_SET_ELEM_FLAGS,
+  NFTA_SET_ELEM_TIMEOUT,
+/* WARNING: DO NOT EDIT, AUTO-GENERATED CODE - SEE TOP FOR INSTRUCTIONS */
+  NFTA_SET_ELEM_EXPIRATION,
+  NFTA_SET_ELEM_USERDATA,
+  NFTA_SET_ELEM_EXPR,
   __NFTA_SET_ELEM_MAX
 /* WARNING: DO NOT EDIT, AUTO-GENERATED CODE - SEE TOP FOR INSTRUCTIONS */
 };
@@ -219,200 +254,230 @@
   __NFTA_DATA_MAX
 };
 #define NFTA_DATA_MAX (__NFTA_DATA_MAX - 1)
-enum nft_verdict_attributes {
+#define NFT_DATA_VALUE_MAXLEN 64
 /* WARNING: DO NOT EDIT, AUTO-GENERATED CODE - SEE TOP FOR INSTRUCTIONS */
+enum nft_verdict_attributes {
   NFTA_VERDICT_UNSPEC,
   NFTA_VERDICT_CODE,
   NFTA_VERDICT_CHAIN,
-  __NFTA_VERDICT_MAX
 /* WARNING: DO NOT EDIT, AUTO-GENERATED CODE - SEE TOP FOR INSTRUCTIONS */
+  __NFTA_VERDICT_MAX
 };
 #define NFTA_VERDICT_MAX (__NFTA_VERDICT_MAX - 1)
 enum nft_expr_attributes {
-  NFTA_EXPR_UNSPEC,
 /* WARNING: DO NOT EDIT, AUTO-GENERATED CODE - SEE TOP FOR INSTRUCTIONS */
+  NFTA_EXPR_UNSPEC,
   NFTA_EXPR_NAME,
   NFTA_EXPR_DATA,
   __NFTA_EXPR_MAX
-};
 /* WARNING: DO NOT EDIT, AUTO-GENERATED CODE - SEE TOP FOR INSTRUCTIONS */
+};
 #define NFTA_EXPR_MAX (__NFTA_EXPR_MAX - 1)
 enum nft_immediate_attributes {
   NFTA_IMMEDIATE_UNSPEC,
-  NFTA_IMMEDIATE_DREG,
 /* WARNING: DO NOT EDIT, AUTO-GENERATED CODE - SEE TOP FOR INSTRUCTIONS */
+  NFTA_IMMEDIATE_DREG,
   NFTA_IMMEDIATE_DATA,
   __NFTA_IMMEDIATE_MAX
 };
-#define NFTA_IMMEDIATE_MAX (__NFTA_IMMEDIATE_MAX - 1)
 /* WARNING: DO NOT EDIT, AUTO-GENERATED CODE - SEE TOP FOR INSTRUCTIONS */
+#define NFTA_IMMEDIATE_MAX (__NFTA_IMMEDIATE_MAX - 1)
 enum nft_bitwise_attributes {
   NFTA_BITWISE_UNSPEC,
   NFTA_BITWISE_SREG,
-  NFTA_BITWISE_DREG,
 /* WARNING: DO NOT EDIT, AUTO-GENERATED CODE - SEE TOP FOR INSTRUCTIONS */
+  NFTA_BITWISE_DREG,
   NFTA_BITWISE_LEN,
   NFTA_BITWISE_MASK,
   NFTA_BITWISE_XOR,
-  __NFTA_BITWISE_MAX
 /* WARNING: DO NOT EDIT, AUTO-GENERATED CODE - SEE TOP FOR INSTRUCTIONS */
+  __NFTA_BITWISE_MAX
 };
 #define NFTA_BITWISE_MAX (__NFTA_BITWISE_MAX - 1)
 enum nft_byteorder_ops {
-  NFT_BYTEORDER_NTOH,
 /* WARNING: DO NOT EDIT, AUTO-GENERATED CODE - SEE TOP FOR INSTRUCTIONS */
+  NFT_BYTEORDER_NTOH,
   NFT_BYTEORDER_HTON,
 };
 enum nft_byteorder_attributes {
-  NFTA_BYTEORDER_UNSPEC,
 /* WARNING: DO NOT EDIT, AUTO-GENERATED CODE - SEE TOP FOR INSTRUCTIONS */
+  NFTA_BYTEORDER_UNSPEC,
   NFTA_BYTEORDER_SREG,
   NFTA_BYTEORDER_DREG,
   NFTA_BYTEORDER_OP,
-  NFTA_BYTEORDER_LEN,
 /* WARNING: DO NOT EDIT, AUTO-GENERATED CODE - SEE TOP FOR INSTRUCTIONS */
+  NFTA_BYTEORDER_LEN,
   NFTA_BYTEORDER_SIZE,
   __NFTA_BYTEORDER_MAX
 };
-#define NFTA_BYTEORDER_MAX (__NFTA_BYTEORDER_MAX - 1)
 /* WARNING: DO NOT EDIT, AUTO-GENERATED CODE - SEE TOP FOR INSTRUCTIONS */
+#define NFTA_BYTEORDER_MAX (__NFTA_BYTEORDER_MAX - 1)
 enum nft_cmp_ops {
   NFT_CMP_EQ,
   NFT_CMP_NEQ,
-  NFT_CMP_LT,
 /* WARNING: DO NOT EDIT, AUTO-GENERATED CODE - SEE TOP FOR INSTRUCTIONS */
+  NFT_CMP_LT,
   NFT_CMP_LTE,
   NFT_CMP_GT,
   NFT_CMP_GTE,
-};
 /* WARNING: DO NOT EDIT, AUTO-GENERATED CODE - SEE TOP FOR INSTRUCTIONS */
+};
 enum nft_cmp_attributes {
   NFTA_CMP_UNSPEC,
   NFTA_CMP_SREG,
-  NFTA_CMP_OP,
 /* WARNING: DO NOT EDIT, AUTO-GENERATED CODE - SEE TOP FOR INSTRUCTIONS */
+  NFTA_CMP_OP,
   NFTA_CMP_DATA,
   __NFTA_CMP_MAX
 };
-#define NFTA_CMP_MAX (__NFTA_CMP_MAX - 1)
 /* WARNING: DO NOT EDIT, AUTO-GENERATED CODE - SEE TOP FOR INSTRUCTIONS */
+#define NFTA_CMP_MAX (__NFTA_CMP_MAX - 1)
 enum nft_lookup_attributes {
   NFTA_LOOKUP_UNSPEC,
   NFTA_LOOKUP_SET,
-  NFTA_LOOKUP_SREG,
 /* WARNING: DO NOT EDIT, AUTO-GENERATED CODE - SEE TOP FOR INSTRUCTIONS */
+  NFTA_LOOKUP_SREG,
   NFTA_LOOKUP_DREG,
   NFTA_LOOKUP_SET_ID,
   __NFTA_LOOKUP_MAX
-};
 /* WARNING: DO NOT EDIT, AUTO-GENERATED CODE - SEE TOP FOR INSTRUCTIONS */
+};
 #define NFTA_LOOKUP_MAX (__NFTA_LOOKUP_MAX - 1)
+enum nft_dynset_ops {
+  NFT_DYNSET_OP_ADD,
+/* WARNING: DO NOT EDIT, AUTO-GENERATED CODE - SEE TOP FOR INSTRUCTIONS */
+  NFT_DYNSET_OP_UPDATE,
+};
+enum nft_dynset_attributes {
+  NFTA_DYNSET_UNSPEC,
+/* WARNING: DO NOT EDIT, AUTO-GENERATED CODE - SEE TOP FOR INSTRUCTIONS */
+  NFTA_DYNSET_SET_NAME,
+  NFTA_DYNSET_SET_ID,
+  NFTA_DYNSET_OP,
+  NFTA_DYNSET_SREG_KEY,
+/* WARNING: DO NOT EDIT, AUTO-GENERATED CODE - SEE TOP FOR INSTRUCTIONS */
+  NFTA_DYNSET_SREG_DATA,
+  NFTA_DYNSET_TIMEOUT,
+  NFTA_DYNSET_EXPR,
+  __NFTA_DYNSET_MAX,
+/* WARNING: DO NOT EDIT, AUTO-GENERATED CODE - SEE TOP FOR INSTRUCTIONS */
+};
+#define NFTA_DYNSET_MAX (__NFTA_DYNSET_MAX - 1)
 enum nft_payload_bases {
   NFT_PAYLOAD_LL_HEADER,
-  NFT_PAYLOAD_NETWORK_HEADER,
 /* WARNING: DO NOT EDIT, AUTO-GENERATED CODE - SEE TOP FOR INSTRUCTIONS */
+  NFT_PAYLOAD_NETWORK_HEADER,
   NFT_PAYLOAD_TRANSPORT_HEADER,
 };
 enum nft_payload_attributes {
-  NFTA_PAYLOAD_UNSPEC,
 /* WARNING: DO NOT EDIT, AUTO-GENERATED CODE - SEE TOP FOR INSTRUCTIONS */
+  NFTA_PAYLOAD_UNSPEC,
   NFTA_PAYLOAD_DREG,
   NFTA_PAYLOAD_BASE,
   NFTA_PAYLOAD_OFFSET,
-  NFTA_PAYLOAD_LEN,
 /* WARNING: DO NOT EDIT, AUTO-GENERATED CODE - SEE TOP FOR INSTRUCTIONS */
+  NFTA_PAYLOAD_LEN,
   __NFTA_PAYLOAD_MAX
 };
 #define NFTA_PAYLOAD_MAX (__NFTA_PAYLOAD_MAX - 1)
-enum nft_exthdr_attributes {
 /* WARNING: DO NOT EDIT, AUTO-GENERATED CODE - SEE TOP FOR INSTRUCTIONS */
+enum nft_exthdr_attributes {
   NFTA_EXTHDR_UNSPEC,
   NFTA_EXTHDR_DREG,
   NFTA_EXTHDR_TYPE,
-  NFTA_EXTHDR_OFFSET,
 /* WARNING: DO NOT EDIT, AUTO-GENERATED CODE - SEE TOP FOR INSTRUCTIONS */
+  NFTA_EXTHDR_OFFSET,
   NFTA_EXTHDR_LEN,
   __NFTA_EXTHDR_MAX
 };
-#define NFTA_EXTHDR_MAX (__NFTA_EXTHDR_MAX - 1)
 /* WARNING: DO NOT EDIT, AUTO-GENERATED CODE - SEE TOP FOR INSTRUCTIONS */
+#define NFTA_EXTHDR_MAX (__NFTA_EXTHDR_MAX - 1)
 enum nft_meta_keys {
   NFT_META_LEN,
   NFT_META_PROTOCOL,
-  NFT_META_PRIORITY,
 /* WARNING: DO NOT EDIT, AUTO-GENERATED CODE - SEE TOP FOR INSTRUCTIONS */
+  NFT_META_PRIORITY,
   NFT_META_MARK,
   NFT_META_IIF,
   NFT_META_OIF,
-  NFT_META_IIFNAME,
 /* WARNING: DO NOT EDIT, AUTO-GENERATED CODE - SEE TOP FOR INSTRUCTIONS */
+  NFT_META_IIFNAME,
   NFT_META_OIFNAME,
   NFT_META_IIFTYPE,
   NFT_META_OIFTYPE,
-  NFT_META_SKUID,
 /* WARNING: DO NOT EDIT, AUTO-GENERATED CODE - SEE TOP FOR INSTRUCTIONS */
+  NFT_META_SKUID,
   NFT_META_SKGID,
   NFT_META_NFTRACE,
   NFT_META_RTCLASSID,
-  NFT_META_SECMARK,
 /* WARNING: DO NOT EDIT, AUTO-GENERATED CODE - SEE TOP FOR INSTRUCTIONS */
+  NFT_META_SECMARK,
   NFT_META_NFPROTO,
   NFT_META_L4PROTO,
   NFT_META_BRI_IIFNAME,
-  NFT_META_BRI_OIFNAME,
 /* WARNING: DO NOT EDIT, AUTO-GENERATED CODE - SEE TOP FOR INSTRUCTIONS */
+  NFT_META_BRI_OIFNAME,
   NFT_META_PKTTYPE,
   NFT_META_CPU,
   NFT_META_IIFGROUP,
-  NFT_META_OIFGROUP,
 /* WARNING: DO NOT EDIT, AUTO-GENERATED CODE - SEE TOP FOR INSTRUCTIONS */
+  NFT_META_OIFGROUP,
+  NFT_META_CGROUP,
 };
 enum nft_meta_attributes {
+/* WARNING: DO NOT EDIT, AUTO-GENERATED CODE - SEE TOP FOR INSTRUCTIONS */
   NFTA_META_UNSPEC,
   NFTA_META_DREG,
-/* WARNING: DO NOT EDIT, AUTO-GENERATED CODE - SEE TOP FOR INSTRUCTIONS */
   NFTA_META_KEY,
   NFTA_META_SREG,
+/* WARNING: DO NOT EDIT, AUTO-GENERATED CODE - SEE TOP FOR INSTRUCTIONS */
   __NFTA_META_MAX
 };
-/* WARNING: DO NOT EDIT, AUTO-GENERATED CODE - SEE TOP FOR INSTRUCTIONS */
 #define NFTA_META_MAX (__NFTA_META_MAX - 1)
 enum nft_ct_keys {
+/* WARNING: DO NOT EDIT, AUTO-GENERATED CODE - SEE TOP FOR INSTRUCTIONS */
   NFT_CT_STATE,
   NFT_CT_DIRECTION,
-/* WARNING: DO NOT EDIT, AUTO-GENERATED CODE - SEE TOP FOR INSTRUCTIONS */
   NFT_CT_STATUS,
   NFT_CT_MARK,
+/* WARNING: DO NOT EDIT, AUTO-GENERATED CODE - SEE TOP FOR INSTRUCTIONS */
   NFT_CT_SECMARK,
   NFT_CT_EXPIRATION,
-/* WARNING: DO NOT EDIT, AUTO-GENERATED CODE - SEE TOP FOR INSTRUCTIONS */
   NFT_CT_HELPER,
   NFT_CT_L3PROTOCOL,
+/* WARNING: DO NOT EDIT, AUTO-GENERATED CODE - SEE TOP FOR INSTRUCTIONS */
   NFT_CT_SRC,
   NFT_CT_DST,
-/* WARNING: DO NOT EDIT, AUTO-GENERATED CODE - SEE TOP FOR INSTRUCTIONS */
   NFT_CT_PROTOCOL,
   NFT_CT_PROTO_SRC,
+/* WARNING: DO NOT EDIT, AUTO-GENERATED CODE - SEE TOP FOR INSTRUCTIONS */
   NFT_CT_PROTO_DST,
   NFT_CT_LABELS,
-/* WARNING: DO NOT EDIT, AUTO-GENERATED CODE - SEE TOP FOR INSTRUCTIONS */
 };
 enum nft_ct_attributes {
+/* WARNING: DO NOT EDIT, AUTO-GENERATED CODE - SEE TOP FOR INSTRUCTIONS */
   NFTA_CT_UNSPEC,
   NFTA_CT_DREG,
-/* WARNING: DO NOT EDIT, AUTO-GENERATED CODE - SEE TOP FOR INSTRUCTIONS */
   NFTA_CT_KEY,
   NFTA_CT_DIRECTION,
+/* WARNING: DO NOT EDIT, AUTO-GENERATED CODE - SEE TOP FOR INSTRUCTIONS */
   NFTA_CT_SREG,
   __NFTA_CT_MAX
-/* WARNING: DO NOT EDIT, AUTO-GENERATED CODE - SEE TOP FOR INSTRUCTIONS */
 };
 #define NFTA_CT_MAX (__NFTA_CT_MAX - 1)
+/* WARNING: DO NOT EDIT, AUTO-GENERATED CODE - SEE TOP FOR INSTRUCTIONS */
+enum nft_limit_type {
+  NFT_LIMIT_PKTS,
+  NFT_LIMIT_PKT_BYTES
+};
+/* WARNING: DO NOT EDIT, AUTO-GENERATED CODE - SEE TOP FOR INSTRUCTIONS */
 enum nft_limit_attributes {
   NFTA_LIMIT_UNSPEC,
-/* WARNING: DO NOT EDIT, AUTO-GENERATED CODE - SEE TOP FOR INSTRUCTIONS */
   NFTA_LIMIT_RATE,
   NFTA_LIMIT_UNIT,
+/* WARNING: DO NOT EDIT, AUTO-GENERATED CODE - SEE TOP FOR INSTRUCTIONS */
+  NFTA_LIMIT_BURST,
+  NFTA_LIMIT_TYPE,
   __NFTA_LIMIT_MAX
 };
 /* WARNING: DO NOT EDIT, AUTO-GENERATED CODE - SEE TOP FOR INSTRUCTIONS */
@@ -506,11 +571,30 @@
 };
 #define NFTA_MASQ_MAX (__NFTA_MASQ_MAX - 1)
 /* WARNING: DO NOT EDIT, AUTO-GENERATED CODE - SEE TOP FOR INSTRUCTIONS */
+enum nft_redir_attributes {
+  NFTA_REDIR_UNSPEC,
+  NFTA_REDIR_REG_PROTO_MIN,
+  NFTA_REDIR_REG_PROTO_MAX,
+/* WARNING: DO NOT EDIT, AUTO-GENERATED CODE - SEE TOP FOR INSTRUCTIONS */
+  NFTA_REDIR_FLAGS,
+  __NFTA_REDIR_MAX
+};
+#define NFTA_REDIR_MAX (__NFTA_REDIR_MAX - 1)
+/* WARNING: DO NOT EDIT, AUTO-GENERATED CODE - SEE TOP FOR INSTRUCTIONS */
+enum nft_dup_attributes {
+  NFTA_DUP_UNSPEC,
+  NFTA_DUP_SREG_ADDR,
+  NFTA_DUP_SREG_DEV,
+/* WARNING: DO NOT EDIT, AUTO-GENERATED CODE - SEE TOP FOR INSTRUCTIONS */
+  __NFTA_DUP_MAX
+};
+#define NFTA_DUP_MAX (__NFTA_DUP_MAX - 1)
 enum nft_gen_attributes {
+/* WARNING: DO NOT EDIT, AUTO-GENERATED CODE - SEE TOP FOR INSTRUCTIONS */
   NFTA_GEN_UNSPEC,
   NFTA_GEN_ID,
   __NFTA_GEN_MAX
-/* WARNING: DO NOT EDIT, AUTO-GENERATED CODE - SEE TOP FOR INSTRUCTIONS */
 };
+/* WARNING: DO NOT EDIT, AUTO-GENERATED CODE - SEE TOP FOR INSTRUCTIONS */
 #define NFTA_GEN_MAX (__NFTA_GEN_MAX - 1)
 #endif
diff --git a/libc/kernel/uapi/linux/netfilter/nfnetlink_conntrack.h b/libc/kernel/uapi/linux/netfilter/nfnetlink_conntrack.h
index 88e404b..cde3340 100644
--- a/libc/kernel/uapi/linux/netfilter/nfnetlink_conntrack.h
+++ b/libc/kernel/uapi/linux/netfilter/nfnetlink_conntrack.h
@@ -86,228 +86,229 @@
   CTA_TUPLE_IP,
   CTA_TUPLE_PROTO,
 /* WARNING: DO NOT EDIT, AUTO-GENERATED CODE - SEE TOP FOR INSTRUCTIONS */
+  CTA_TUPLE_ZONE,
   __CTA_TUPLE_MAX
 };
 #define CTA_TUPLE_MAX (__CTA_TUPLE_MAX - 1)
-enum ctattr_ip {
 /* WARNING: DO NOT EDIT, AUTO-GENERATED CODE - SEE TOP FOR INSTRUCTIONS */
+enum ctattr_ip {
   CTA_IP_UNSPEC,
   CTA_IP_V4_SRC,
   CTA_IP_V4_DST,
-  CTA_IP_V6_SRC,
 /* WARNING: DO NOT EDIT, AUTO-GENERATED CODE - SEE TOP FOR INSTRUCTIONS */
+  CTA_IP_V6_SRC,
   CTA_IP_V6_DST,
   __CTA_IP_MAX
 };
-#define CTA_IP_MAX (__CTA_IP_MAX - 1)
 /* WARNING: DO NOT EDIT, AUTO-GENERATED CODE - SEE TOP FOR INSTRUCTIONS */
+#define CTA_IP_MAX (__CTA_IP_MAX - 1)
 enum ctattr_l4proto {
   CTA_PROTO_UNSPEC,
   CTA_PROTO_NUM,
-  CTA_PROTO_SRC_PORT,
 /* WARNING: DO NOT EDIT, AUTO-GENERATED CODE - SEE TOP FOR INSTRUCTIONS */
+  CTA_PROTO_SRC_PORT,
   CTA_PROTO_DST_PORT,
   CTA_PROTO_ICMP_ID,
   CTA_PROTO_ICMP_TYPE,
-  CTA_PROTO_ICMP_CODE,
 /* WARNING: DO NOT EDIT, AUTO-GENERATED CODE - SEE TOP FOR INSTRUCTIONS */
+  CTA_PROTO_ICMP_CODE,
   CTA_PROTO_ICMPV6_ID,
   CTA_PROTO_ICMPV6_TYPE,
   CTA_PROTO_ICMPV6_CODE,
-  __CTA_PROTO_MAX
 /* WARNING: DO NOT EDIT, AUTO-GENERATED CODE - SEE TOP FOR INSTRUCTIONS */
+  __CTA_PROTO_MAX
 };
 #define CTA_PROTO_MAX (__CTA_PROTO_MAX - 1)
 enum ctattr_protoinfo {
-  CTA_PROTOINFO_UNSPEC,
 /* WARNING: DO NOT EDIT, AUTO-GENERATED CODE - SEE TOP FOR INSTRUCTIONS */
+  CTA_PROTOINFO_UNSPEC,
   CTA_PROTOINFO_TCP,
   CTA_PROTOINFO_DCCP,
   CTA_PROTOINFO_SCTP,
-  __CTA_PROTOINFO_MAX
 /* WARNING: DO NOT EDIT, AUTO-GENERATED CODE - SEE TOP FOR INSTRUCTIONS */
+  __CTA_PROTOINFO_MAX
 };
 #define CTA_PROTOINFO_MAX (__CTA_PROTOINFO_MAX - 1)
 enum ctattr_protoinfo_tcp {
-  CTA_PROTOINFO_TCP_UNSPEC,
 /* WARNING: DO NOT EDIT, AUTO-GENERATED CODE - SEE TOP FOR INSTRUCTIONS */
+  CTA_PROTOINFO_TCP_UNSPEC,
   CTA_PROTOINFO_TCP_STATE,
   CTA_PROTOINFO_TCP_WSCALE_ORIGINAL,
   CTA_PROTOINFO_TCP_WSCALE_REPLY,
-  CTA_PROTOINFO_TCP_FLAGS_ORIGINAL,
 /* WARNING: DO NOT EDIT, AUTO-GENERATED CODE - SEE TOP FOR INSTRUCTIONS */
+  CTA_PROTOINFO_TCP_FLAGS_ORIGINAL,
   CTA_PROTOINFO_TCP_FLAGS_REPLY,
   __CTA_PROTOINFO_TCP_MAX
 };
-#define CTA_PROTOINFO_TCP_MAX (__CTA_PROTOINFO_TCP_MAX - 1)
 /* WARNING: DO NOT EDIT, AUTO-GENERATED CODE - SEE TOP FOR INSTRUCTIONS */
+#define CTA_PROTOINFO_TCP_MAX (__CTA_PROTOINFO_TCP_MAX - 1)
 enum ctattr_protoinfo_dccp {
   CTA_PROTOINFO_DCCP_UNSPEC,
   CTA_PROTOINFO_DCCP_STATE,
-  CTA_PROTOINFO_DCCP_ROLE,
 /* WARNING: DO NOT EDIT, AUTO-GENERATED CODE - SEE TOP FOR INSTRUCTIONS */
+  CTA_PROTOINFO_DCCP_ROLE,
   CTA_PROTOINFO_DCCP_HANDSHAKE_SEQ,
   __CTA_PROTOINFO_DCCP_MAX,
 };
-#define CTA_PROTOINFO_DCCP_MAX (__CTA_PROTOINFO_DCCP_MAX - 1)
 /* WARNING: DO NOT EDIT, AUTO-GENERATED CODE - SEE TOP FOR INSTRUCTIONS */
+#define CTA_PROTOINFO_DCCP_MAX (__CTA_PROTOINFO_DCCP_MAX - 1)
 enum ctattr_protoinfo_sctp {
   CTA_PROTOINFO_SCTP_UNSPEC,
   CTA_PROTOINFO_SCTP_STATE,
-  CTA_PROTOINFO_SCTP_VTAG_ORIGINAL,
 /* WARNING: DO NOT EDIT, AUTO-GENERATED CODE - SEE TOP FOR INSTRUCTIONS */
+  CTA_PROTOINFO_SCTP_VTAG_ORIGINAL,
   CTA_PROTOINFO_SCTP_VTAG_REPLY,
   __CTA_PROTOINFO_SCTP_MAX
 };
-#define CTA_PROTOINFO_SCTP_MAX (__CTA_PROTOINFO_SCTP_MAX - 1)
 /* WARNING: DO NOT EDIT, AUTO-GENERATED CODE - SEE TOP FOR INSTRUCTIONS */
+#define CTA_PROTOINFO_SCTP_MAX (__CTA_PROTOINFO_SCTP_MAX - 1)
 enum ctattr_counters {
   CTA_COUNTERS_UNSPEC,
   CTA_COUNTERS_PACKETS,
-  CTA_COUNTERS_BYTES,
 /* WARNING: DO NOT EDIT, AUTO-GENERATED CODE - SEE TOP FOR INSTRUCTIONS */
+  CTA_COUNTERS_BYTES,
   CTA_COUNTERS32_PACKETS,
   CTA_COUNTERS32_BYTES,
   __CTA_COUNTERS_MAX
-};
 /* WARNING: DO NOT EDIT, AUTO-GENERATED CODE - SEE TOP FOR INSTRUCTIONS */
+};
 #define CTA_COUNTERS_MAX (__CTA_COUNTERS_MAX - 1)
 enum ctattr_tstamp {
   CTA_TIMESTAMP_UNSPEC,
-  CTA_TIMESTAMP_START,
 /* WARNING: DO NOT EDIT, AUTO-GENERATED CODE - SEE TOP FOR INSTRUCTIONS */
+  CTA_TIMESTAMP_START,
   CTA_TIMESTAMP_STOP,
   __CTA_TIMESTAMP_MAX
 };
-#define CTA_TIMESTAMP_MAX (__CTA_TIMESTAMP_MAX - 1)
 /* WARNING: DO NOT EDIT, AUTO-GENERATED CODE - SEE TOP FOR INSTRUCTIONS */
+#define CTA_TIMESTAMP_MAX (__CTA_TIMESTAMP_MAX - 1)
 enum ctattr_nat {
   CTA_NAT_UNSPEC,
   CTA_NAT_V4_MINIP,
-#define CTA_NAT_MINIP CTA_NAT_V4_MINIP
 /* WARNING: DO NOT EDIT, AUTO-GENERATED CODE - SEE TOP FOR INSTRUCTIONS */
+#define CTA_NAT_MINIP CTA_NAT_V4_MINIP
   CTA_NAT_V4_MAXIP,
 #define CTA_NAT_MAXIP CTA_NAT_V4_MAXIP
   CTA_NAT_PROTO,
-  CTA_NAT_V6_MINIP,
 /* WARNING: DO NOT EDIT, AUTO-GENERATED CODE - SEE TOP FOR INSTRUCTIONS */
+  CTA_NAT_V6_MINIP,
   CTA_NAT_V6_MAXIP,
   __CTA_NAT_MAX
 };
-#define CTA_NAT_MAX (__CTA_NAT_MAX - 1)
 /* WARNING: DO NOT EDIT, AUTO-GENERATED CODE - SEE TOP FOR INSTRUCTIONS */
+#define CTA_NAT_MAX (__CTA_NAT_MAX - 1)
 enum ctattr_protonat {
   CTA_PROTONAT_UNSPEC,
   CTA_PROTONAT_PORT_MIN,
-  CTA_PROTONAT_PORT_MAX,
 /* WARNING: DO NOT EDIT, AUTO-GENERATED CODE - SEE TOP FOR INSTRUCTIONS */
+  CTA_PROTONAT_PORT_MAX,
   __CTA_PROTONAT_MAX
 };
 #define CTA_PROTONAT_MAX (__CTA_PROTONAT_MAX - 1)
-enum ctattr_seqadj {
 /* WARNING: DO NOT EDIT, AUTO-GENERATED CODE - SEE TOP FOR INSTRUCTIONS */
+enum ctattr_seqadj {
   CTA_SEQADJ_UNSPEC,
   CTA_SEQADJ_CORRECTION_POS,
   CTA_SEQADJ_OFFSET_BEFORE,
-  CTA_SEQADJ_OFFSET_AFTER,
 /* WARNING: DO NOT EDIT, AUTO-GENERATED CODE - SEE TOP FOR INSTRUCTIONS */
+  CTA_SEQADJ_OFFSET_AFTER,
   __CTA_SEQADJ_MAX
 };
 #define CTA_SEQADJ_MAX (__CTA_SEQADJ_MAX - 1)
-enum ctattr_natseq {
 /* WARNING: DO NOT EDIT, AUTO-GENERATED CODE - SEE TOP FOR INSTRUCTIONS */
+enum ctattr_natseq {
   CTA_NAT_SEQ_UNSPEC,
   CTA_NAT_SEQ_CORRECTION_POS,
   CTA_NAT_SEQ_OFFSET_BEFORE,
-  CTA_NAT_SEQ_OFFSET_AFTER,
 /* WARNING: DO NOT EDIT, AUTO-GENERATED CODE - SEE TOP FOR INSTRUCTIONS */
+  CTA_NAT_SEQ_OFFSET_AFTER,
   __CTA_NAT_SEQ_MAX
 };
 #define CTA_NAT_SEQ_MAX (__CTA_NAT_SEQ_MAX - 1)
-enum ctattr_expect {
 /* WARNING: DO NOT EDIT, AUTO-GENERATED CODE - SEE TOP FOR INSTRUCTIONS */
+enum ctattr_expect {
   CTA_EXPECT_UNSPEC,
   CTA_EXPECT_MASTER,
   CTA_EXPECT_TUPLE,
-  CTA_EXPECT_MASK,
 /* WARNING: DO NOT EDIT, AUTO-GENERATED CODE - SEE TOP FOR INSTRUCTIONS */
+  CTA_EXPECT_MASK,
   CTA_EXPECT_TIMEOUT,
   CTA_EXPECT_ID,
   CTA_EXPECT_HELP_NAME,
-  CTA_EXPECT_ZONE,
 /* WARNING: DO NOT EDIT, AUTO-GENERATED CODE - SEE TOP FOR INSTRUCTIONS */
+  CTA_EXPECT_ZONE,
   CTA_EXPECT_FLAGS,
   CTA_EXPECT_CLASS,
   CTA_EXPECT_NAT,
-  CTA_EXPECT_FN,
 /* WARNING: DO NOT EDIT, AUTO-GENERATED CODE - SEE TOP FOR INSTRUCTIONS */
+  CTA_EXPECT_FN,
   __CTA_EXPECT_MAX
 };
 #define CTA_EXPECT_MAX (__CTA_EXPECT_MAX - 1)
-enum ctattr_expect_nat {
 /* WARNING: DO NOT EDIT, AUTO-GENERATED CODE - SEE TOP FOR INSTRUCTIONS */
+enum ctattr_expect_nat {
   CTA_EXPECT_NAT_UNSPEC,
   CTA_EXPECT_NAT_DIR,
   CTA_EXPECT_NAT_TUPLE,
-  __CTA_EXPECT_NAT_MAX
 /* WARNING: DO NOT EDIT, AUTO-GENERATED CODE - SEE TOP FOR INSTRUCTIONS */
+  __CTA_EXPECT_NAT_MAX
 };
 #define CTA_EXPECT_NAT_MAX (__CTA_EXPECT_NAT_MAX - 1)
 enum ctattr_help {
-  CTA_HELP_UNSPEC,
 /* WARNING: DO NOT EDIT, AUTO-GENERATED CODE - SEE TOP FOR INSTRUCTIONS */
+  CTA_HELP_UNSPEC,
   CTA_HELP_NAME,
   CTA_HELP_INFO,
   __CTA_HELP_MAX
-};
 /* WARNING: DO NOT EDIT, AUTO-GENERATED CODE - SEE TOP FOR INSTRUCTIONS */
+};
 #define CTA_HELP_MAX (__CTA_HELP_MAX - 1)
 enum ctattr_secctx {
   CTA_SECCTX_UNSPEC,
-  CTA_SECCTX_NAME,
 /* WARNING: DO NOT EDIT, AUTO-GENERATED CODE - SEE TOP FOR INSTRUCTIONS */
+  CTA_SECCTX_NAME,
   __CTA_SECCTX_MAX
 };
 #define CTA_SECCTX_MAX (__CTA_SECCTX_MAX - 1)
-enum ctattr_stats_cpu {
 /* WARNING: DO NOT EDIT, AUTO-GENERATED CODE - SEE TOP FOR INSTRUCTIONS */
+enum ctattr_stats_cpu {
   CTA_STATS_UNSPEC,
   CTA_STATS_SEARCHED,
   CTA_STATS_FOUND,
-  CTA_STATS_NEW,
 /* WARNING: DO NOT EDIT, AUTO-GENERATED CODE - SEE TOP FOR INSTRUCTIONS */
+  CTA_STATS_NEW,
   CTA_STATS_INVALID,
   CTA_STATS_IGNORE,
   CTA_STATS_DELETE,
-  CTA_STATS_DELETE_LIST,
 /* WARNING: DO NOT EDIT, AUTO-GENERATED CODE - SEE TOP FOR INSTRUCTIONS */
+  CTA_STATS_DELETE_LIST,
   CTA_STATS_INSERT,
   CTA_STATS_INSERT_FAILED,
   CTA_STATS_DROP,
-  CTA_STATS_EARLY_DROP,
 /* WARNING: DO NOT EDIT, AUTO-GENERATED CODE - SEE TOP FOR INSTRUCTIONS */
+  CTA_STATS_EARLY_DROP,
   CTA_STATS_ERROR,
   CTA_STATS_SEARCH_RESTART,
   __CTA_STATS_MAX,
-};
 /* WARNING: DO NOT EDIT, AUTO-GENERATED CODE - SEE TOP FOR INSTRUCTIONS */
+};
 #define CTA_STATS_MAX (__CTA_STATS_MAX - 1)
 enum ctattr_stats_global {
   CTA_STATS_GLOBAL_UNSPEC,
-  CTA_STATS_GLOBAL_ENTRIES,
 /* WARNING: DO NOT EDIT, AUTO-GENERATED CODE - SEE TOP FOR INSTRUCTIONS */
+  CTA_STATS_GLOBAL_ENTRIES,
   __CTA_STATS_GLOBAL_MAX,
 };
 #define CTA_STATS_GLOBAL_MAX (__CTA_STATS_GLOBAL_MAX - 1)
-enum ctattr_expect_stats {
 /* WARNING: DO NOT EDIT, AUTO-GENERATED CODE - SEE TOP FOR INSTRUCTIONS */
+enum ctattr_expect_stats {
   CTA_STATS_EXP_UNSPEC,
   CTA_STATS_EXP_NEW,
   CTA_STATS_EXP_CREATE,
-  CTA_STATS_EXP_DELETE,
 /* WARNING: DO NOT EDIT, AUTO-GENERATED CODE - SEE TOP FOR INSTRUCTIONS */
+  CTA_STATS_EXP_DELETE,
   __CTA_STATS_EXP_MAX,
 };
 #define CTA_STATS_EXP_MAX (__CTA_STATS_EXP_MAX - 1)
-#endif
 /* WARNING: DO NOT EDIT, AUTO-GENERATED CODE - SEE TOP FOR INSTRUCTIONS */
+#endif
diff --git a/libc/kernel/uapi/linux/netfilter/nfnetlink_cttimeout.h b/libc/kernel/uapi/linux/netfilter/nfnetlink_cttimeout.h
index 4c35ce0..74558ce 100644
--- a/libc/kernel/uapi/linux/netfilter/nfnetlink_cttimeout.h
+++ b/libc/kernel/uapi/linux/netfilter/nfnetlink_cttimeout.h
@@ -121,25 +121,28 @@
   CTA_TIMEOUT_SCTP_SHUTDOWN_RECD,
   CTA_TIMEOUT_SCTP_SHUTDOWN_ACK_SENT,
 /* WARNING: DO NOT EDIT, AUTO-GENERATED CODE - SEE TOP FOR INSTRUCTIONS */
+  CTA_TIMEOUT_SCTP_HEARTBEAT_SENT,
+  CTA_TIMEOUT_SCTP_HEARTBEAT_ACKED,
   __CTA_TIMEOUT_SCTP_MAX
 };
+/* WARNING: DO NOT EDIT, AUTO-GENERATED CODE - SEE TOP FOR INSTRUCTIONS */
 #define CTA_TIMEOUT_SCTP_MAX (__CTA_TIMEOUT_SCTP_MAX - 1)
 enum ctattr_timeout_icmpv6 {
-/* WARNING: DO NOT EDIT, AUTO-GENERATED CODE - SEE TOP FOR INSTRUCTIONS */
   CTA_TIMEOUT_ICMPV6_UNSPEC,
   CTA_TIMEOUT_ICMPV6_TIMEOUT,
+/* WARNING: DO NOT EDIT, AUTO-GENERATED CODE - SEE TOP FOR INSTRUCTIONS */
   __CTA_TIMEOUT_ICMPV6_MAX
 };
-/* WARNING: DO NOT EDIT, AUTO-GENERATED CODE - SEE TOP FOR INSTRUCTIONS */
 #define CTA_TIMEOUT_ICMPV6_MAX (__CTA_TIMEOUT_ICMPV6_MAX - 1)
 enum ctattr_timeout_gre {
+/* WARNING: DO NOT EDIT, AUTO-GENERATED CODE - SEE TOP FOR INSTRUCTIONS */
   CTA_TIMEOUT_GRE_UNSPEC,
   CTA_TIMEOUT_GRE_UNREPLIED,
-/* WARNING: DO NOT EDIT, AUTO-GENERATED CODE - SEE TOP FOR INSTRUCTIONS */
   CTA_TIMEOUT_GRE_REPLIED,
   __CTA_TIMEOUT_GRE_MAX
+/* WARNING: DO NOT EDIT, AUTO-GENERATED CODE - SEE TOP FOR INSTRUCTIONS */
 };
 #define CTA_TIMEOUT_GRE_MAX (__CTA_TIMEOUT_GRE_MAX - 1)
-/* WARNING: DO NOT EDIT, AUTO-GENERATED CODE - SEE TOP FOR INSTRUCTIONS */
 #define CTNL_TIMEOUT_NAME_MAX 32
 #endif
+/* WARNING: DO NOT EDIT, AUTO-GENERATED CODE - SEE TOP FOR INSTRUCTIONS */
diff --git a/libc/kernel/uapi/linux/netfilter/nfnetlink_log.h b/libc/kernel/uapi/linux/netfilter/nfnetlink_log.h
index c5345fd..016414c 100644
--- a/libc/kernel/uapi/linux/netfilter/nfnetlink_log.h
+++ b/libc/kernel/uapi/linux/netfilter/nfnetlink_log.h
@@ -68,47 +68,51 @@
 /* WARNING: DO NOT EDIT, AUTO-GENERATED CODE - SEE TOP FOR INSTRUCTIONS */
   NFULA_HWHEADER,
   NFULA_HWLEN,
+  NFULA_CT,
+  NFULA_CT_INFO,
+/* WARNING: DO NOT EDIT, AUTO-GENERATED CODE - SEE TOP FOR INSTRUCTIONS */
   __NFULA_MAX
 };
-/* WARNING: DO NOT EDIT, AUTO-GENERATED CODE - SEE TOP FOR INSTRUCTIONS */
 #define NFULA_MAX (__NFULA_MAX - 1)
 enum nfulnl_msg_config_cmds {
+/* WARNING: DO NOT EDIT, AUTO-GENERATED CODE - SEE TOP FOR INSTRUCTIONS */
   NFULNL_CFG_CMD_NONE,
   NFULNL_CFG_CMD_BIND,
-/* WARNING: DO NOT EDIT, AUTO-GENERATED CODE - SEE TOP FOR INSTRUCTIONS */
   NFULNL_CFG_CMD_UNBIND,
   NFULNL_CFG_CMD_PF_BIND,
+/* WARNING: DO NOT EDIT, AUTO-GENERATED CODE - SEE TOP FOR INSTRUCTIONS */
   NFULNL_CFG_CMD_PF_UNBIND,
 };
-/* WARNING: DO NOT EDIT, AUTO-GENERATED CODE - SEE TOP FOR INSTRUCTIONS */
 struct nfulnl_msg_config_cmd {
   __u8 command;
+/* WARNING: DO NOT EDIT, AUTO-GENERATED CODE - SEE TOP FOR INSTRUCTIONS */
 } __attribute__((packed));
 struct nfulnl_msg_config_mode {
-/* WARNING: DO NOT EDIT, AUTO-GENERATED CODE - SEE TOP FOR INSTRUCTIONS */
   __be32 copy_range;
   __u8 copy_mode;
+/* WARNING: DO NOT EDIT, AUTO-GENERATED CODE - SEE TOP FOR INSTRUCTIONS */
   __u8 _pad;
 } __attribute__((packed));
-/* WARNING: DO NOT EDIT, AUTO-GENERATED CODE - SEE TOP FOR INSTRUCTIONS */
 enum nfulnl_attr_config {
   NFULA_CFG_UNSPEC,
+/* WARNING: DO NOT EDIT, AUTO-GENERATED CODE - SEE TOP FOR INSTRUCTIONS */
   NFULA_CFG_CMD,
   NFULA_CFG_MODE,
-/* WARNING: DO NOT EDIT, AUTO-GENERATED CODE - SEE TOP FOR INSTRUCTIONS */
   NFULA_CFG_NLBUFSIZ,
   NFULA_CFG_TIMEOUT,
+/* WARNING: DO NOT EDIT, AUTO-GENERATED CODE - SEE TOP FOR INSTRUCTIONS */
   NFULA_CFG_QTHRESH,
   NFULA_CFG_FLAGS,
-/* WARNING: DO NOT EDIT, AUTO-GENERATED CODE - SEE TOP FOR INSTRUCTIONS */
   __NFULA_CFG_MAX
 };
+/* WARNING: DO NOT EDIT, AUTO-GENERATED CODE - SEE TOP FOR INSTRUCTIONS */
 #define NFULA_CFG_MAX (__NFULA_CFG_MAX - 1)
 #define NFULNL_COPY_NONE 0x00
-/* WARNING: DO NOT EDIT, AUTO-GENERATED CODE - SEE TOP FOR INSTRUCTIONS */
 #define NFULNL_COPY_META 0x01
 #define NFULNL_COPY_PACKET 0x02
+/* WARNING: DO NOT EDIT, AUTO-GENERATED CODE - SEE TOP FOR INSTRUCTIONS */
 #define NFULNL_CFG_F_SEQ 0x0001
 #define NFULNL_CFG_F_SEQ_GLOBAL 0x0002
-/* WARNING: DO NOT EDIT, AUTO-GENERATED CODE - SEE TOP FOR INSTRUCTIONS */
+#define NFULNL_CFG_F_CONNTRACK 0x0004
 #endif
+/* WARNING: DO NOT EDIT, AUTO-GENERATED CODE - SEE TOP FOR INSTRUCTIONS */
diff --git a/libc/kernel/uapi/linux/netfilter/nfnetlink_queue.h b/libc/kernel/uapi/linux/netfilter/nfnetlink_queue.h
index 694636b..8a09ef2 100644
--- a/libc/kernel/uapi/linux/netfilter/nfnetlink_queue.h
+++ b/libc/kernel/uapi/linux/netfilter/nfnetlink_queue.h
@@ -71,61 +71,64 @@
   NFQA_UID,
   NFQA_GID,
 /* WARNING: DO NOT EDIT, AUTO-GENERATED CODE - SEE TOP FOR INSTRUCTIONS */
+  NFQA_SECCTX,
   __NFQA_MAX
 };
 #define NFQA_MAX (__NFQA_MAX - 1)
-struct nfqnl_msg_verdict_hdr {
 /* WARNING: DO NOT EDIT, AUTO-GENERATED CODE - SEE TOP FOR INSTRUCTIONS */
+struct nfqnl_msg_verdict_hdr {
   __be32 verdict;
   __be32 id;
 };
-enum nfqnl_msg_config_cmds {
 /* WARNING: DO NOT EDIT, AUTO-GENERATED CODE - SEE TOP FOR INSTRUCTIONS */
+enum nfqnl_msg_config_cmds {
   NFQNL_CFG_CMD_NONE,
   NFQNL_CFG_CMD_BIND,
   NFQNL_CFG_CMD_UNBIND,
-  NFQNL_CFG_CMD_PF_BIND,
 /* WARNING: DO NOT EDIT, AUTO-GENERATED CODE - SEE TOP FOR INSTRUCTIONS */
+  NFQNL_CFG_CMD_PF_BIND,
   NFQNL_CFG_CMD_PF_UNBIND,
 };
 struct nfqnl_msg_config_cmd {
-  __u8 command;
 /* WARNING: DO NOT EDIT, AUTO-GENERATED CODE - SEE TOP FOR INSTRUCTIONS */
+  __u8 command;
   __u8 _pad;
   __be16 pf;
 };
-enum nfqnl_config_mode {
 /* WARNING: DO NOT EDIT, AUTO-GENERATED CODE - SEE TOP FOR INSTRUCTIONS */
+enum nfqnl_config_mode {
   NFQNL_COPY_NONE,
   NFQNL_COPY_META,
   NFQNL_COPY_PACKET,
-};
 /* WARNING: DO NOT EDIT, AUTO-GENERATED CODE - SEE TOP FOR INSTRUCTIONS */
+};
 struct nfqnl_msg_config_params {
   __be32 copy_range;
   __u8 copy_mode;
-} __attribute__((packed));
 /* WARNING: DO NOT EDIT, AUTO-GENERATED CODE - SEE TOP FOR INSTRUCTIONS */
+} __attribute__((packed));
 enum nfqnl_attr_config {
   NFQA_CFG_UNSPEC,
   NFQA_CFG_CMD,
-  NFQA_CFG_PARAMS,
 /* WARNING: DO NOT EDIT, AUTO-GENERATED CODE - SEE TOP FOR INSTRUCTIONS */
+  NFQA_CFG_PARAMS,
   NFQA_CFG_QUEUE_MAXLEN,
   NFQA_CFG_MASK,
   NFQA_CFG_FLAGS,
-  __NFQA_CFG_MAX
 /* WARNING: DO NOT EDIT, AUTO-GENERATED CODE - SEE TOP FOR INSTRUCTIONS */
+  __NFQA_CFG_MAX
 };
 #define NFQA_CFG_MAX (__NFQA_CFG_MAX - 1)
 #define NFQA_CFG_F_FAIL_OPEN (1 << 0)
-#define NFQA_CFG_F_CONNTRACK (1 << 1)
 /* WARNING: DO NOT EDIT, AUTO-GENERATED CODE - SEE TOP FOR INSTRUCTIONS */
+#define NFQA_CFG_F_CONNTRACK (1 << 1)
 #define NFQA_CFG_F_GSO (1 << 2)
 #define NFQA_CFG_F_UID_GID (1 << 3)
-#define NFQA_CFG_F_MAX (1 << 4)
-#define NFQA_SKB_CSUMNOTREADY (1 << 0)
+#define NFQA_CFG_F_SECCTX (1 << 4)
 /* WARNING: DO NOT EDIT, AUTO-GENERATED CODE - SEE TOP FOR INSTRUCTIONS */
+#define NFQA_CFG_F_MAX (1 << 5)
+#define NFQA_SKB_CSUMNOTREADY (1 << 0)
 #define NFQA_SKB_GSO (1 << 1)
 #define NFQA_SKB_CSUM_NOTVERIFIED (1 << 2)
+/* WARNING: DO NOT EDIT, AUTO-GENERATED CODE - SEE TOP FOR INSTRUCTIONS */
 #endif
diff --git a/libc/kernel/uapi/linux/netfilter/xt_CT.h b/libc/kernel/uapi/linux/netfilter/xt_CT.h
index 03d2093..26ee668 100644
--- a/libc/kernel/uapi/linux/netfilter/xt_CT.h
+++ b/libc/kernel/uapi/linux/netfilter/xt_CT.h
@@ -23,28 +23,32 @@
 /* WARNING: DO NOT EDIT, AUTO-GENERATED CODE - SEE TOP FOR INSTRUCTIONS */
   XT_CT_NOTRACK = 1 << 0,
   XT_CT_NOTRACK_ALIAS = 1 << 1,
-  XT_CT_MASK = XT_CT_NOTRACK | XT_CT_NOTRACK_ALIAS,
-};
+  XT_CT_ZONE_DIR_ORIG = 1 << 2,
+  XT_CT_ZONE_DIR_REPL = 1 << 3,
 /* WARNING: DO NOT EDIT, AUTO-GENERATED CODE - SEE TOP FOR INSTRUCTIONS */
+  XT_CT_ZONE_MARK = 1 << 4,
+  XT_CT_MASK = XT_CT_NOTRACK | XT_CT_NOTRACK_ALIAS | XT_CT_ZONE_DIR_ORIG | XT_CT_ZONE_DIR_REPL | XT_CT_ZONE_MARK,
+};
 struct xt_ct_target_info {
+/* WARNING: DO NOT EDIT, AUTO-GENERATED CODE - SEE TOP FOR INSTRUCTIONS */
   __u16 flags;
   __u16 zone;
   __u32 ct_events;
-/* WARNING: DO NOT EDIT, AUTO-GENERATED CODE - SEE TOP FOR INSTRUCTIONS */
   __u32 exp_events;
+/* WARNING: DO NOT EDIT, AUTO-GENERATED CODE - SEE TOP FOR INSTRUCTIONS */
   char helper[16];
   struct nf_conn * ct __attribute__((aligned(8)));
 };
-/* WARNING: DO NOT EDIT, AUTO-GENERATED CODE - SEE TOP FOR INSTRUCTIONS */
 struct xt_ct_target_info_v1 {
+/* WARNING: DO NOT EDIT, AUTO-GENERATED CODE - SEE TOP FOR INSTRUCTIONS */
   __u16 flags;
   __u16 zone;
   __u32 ct_events;
-/* WARNING: DO NOT EDIT, AUTO-GENERATED CODE - SEE TOP FOR INSTRUCTIONS */
   __u32 exp_events;
+/* WARNING: DO NOT EDIT, AUTO-GENERATED CODE - SEE TOP FOR INSTRUCTIONS */
   char helper[16];
   char timeout[32];
   struct nf_conn * ct __attribute__((aligned(8)));
-/* WARNING: DO NOT EDIT, AUTO-GENERATED CODE - SEE TOP FOR INSTRUCTIONS */
 };
+/* WARNING: DO NOT EDIT, AUTO-GENERATED CODE - SEE TOP FOR INSTRUCTIONS */
 #endif
diff --git a/libc/kernel/uapi/linux/netfilter/xt_set.h b/libc/kernel/uapi/linux/netfilter/xt_set.h
index 5a2fe01..5ae39ec 100644
--- a/libc/kernel/uapi/linux/netfilter/xt_set.h
+++ b/libc/kernel/uapi/linux/netfilter/xt_set.h
@@ -72,8 +72,8 @@
 struct xt_set_info_match_v3 {
 /* WARNING: DO NOT EDIT, AUTO-GENERATED CODE - SEE TOP FOR INSTRUCTIONS */
   struct xt_set_info match_set;
-  struct ip_set_counter_match packets;
-  struct ip_set_counter_match bytes;
+  struct ip_set_counter_match0 packets;
+  struct ip_set_counter_match0 bytes;
   __u32 flags;
 /* WARNING: DO NOT EDIT, AUTO-GENERATED CODE - SEE TOP FOR INSTRUCTIONS */
 };
@@ -86,4 +86,11 @@
   __u32 timeout;
 };
 /* WARNING: DO NOT EDIT, AUTO-GENERATED CODE - SEE TOP FOR INSTRUCTIONS */
+struct xt_set_info_match_v4 {
+  struct xt_set_info match_set;
+  struct ip_set_counter_match packets;
+  struct ip_set_counter_match bytes;
+/* WARNING: DO NOT EDIT, AUTO-GENERATED CODE - SEE TOP FOR INSTRUCTIONS */
+  __u32 flags;
+};
 #endif
diff --git a/libc/kernel/uapi/linux/netfilter/xt_socket.h b/libc/kernel/uapi/linux/netfilter/xt_socket.h
index ff57d20..06c834a 100644
--- a/libc/kernel/uapi/linux/netfilter/xt_socket.h
+++ b/libc/kernel/uapi/linux/netfilter/xt_socket.h
@@ -23,16 +23,22 @@
 /* WARNING: DO NOT EDIT, AUTO-GENERATED CODE - SEE TOP FOR INSTRUCTIONS */
   XT_SOCKET_TRANSPARENT = 1 << 0,
   XT_SOCKET_NOWILDCARD = 1 << 1,
+  XT_SOCKET_RESTORESKMARK = 1 << 2,
 };
-struct xt_socket_mtinfo1 {
 /* WARNING: DO NOT EDIT, AUTO-GENERATED CODE - SEE TOP FOR INSTRUCTIONS */
+struct xt_socket_mtinfo1 {
   __u8 flags;
 };
 #define XT_SOCKET_FLAGS_V1 XT_SOCKET_TRANSPARENT
-struct xt_socket_mtinfo2 {
 /* WARNING: DO NOT EDIT, AUTO-GENERATED CODE - SEE TOP FOR INSTRUCTIONS */
+struct xt_socket_mtinfo2 {
   __u8 flags;
 };
 #define XT_SOCKET_FLAGS_V2 (XT_SOCKET_TRANSPARENT | XT_SOCKET_NOWILDCARD)
-#endif
 /* WARNING: DO NOT EDIT, AUTO-GENERATED CODE - SEE TOP FOR INSTRUCTIONS */
+struct xt_socket_mtinfo3 {
+  __u8 flags;
+};
+#define XT_SOCKET_FLAGS_V3 (XT_SOCKET_TRANSPARENT | XT_SOCKET_NOWILDCARD | XT_SOCKET_RESTORESKMARK)
+/* WARNING: DO NOT EDIT, AUTO-GENERATED CODE - SEE TOP FOR INSTRUCTIONS */
+#endif
diff --git a/libc/kernel/uapi/linux/netfilter_bridge/ebtables.h b/libc/kernel/uapi/linux/netfilter_bridge/ebtables.h
index 6b201a3..aab8490 100644
--- a/libc/kernel/uapi/linux/netfilter_bridge/ebtables.h
+++ b/libc/kernel/uapi/linux/netfilter_bridge/ebtables.h
@@ -18,158 +18,155 @@
  ****************************************************************************/
 #ifndef _UAPI__LINUX_BRIDGE_EFF_H
 #define _UAPI__LINUX_BRIDGE_EFF_H
-#include <linux/if.h>
 #include <linux/netfilter_bridge.h>
-/* WARNING: DO NOT EDIT, AUTO-GENERATED CODE - SEE TOP FOR INSTRUCTIONS */
-#include <linux/if_ether.h>
 #define EBT_TABLE_MAXNAMELEN 32
+/* WARNING: DO NOT EDIT, AUTO-GENERATED CODE - SEE TOP FOR INSTRUCTIONS */
 #define EBT_CHAIN_MAXNAMELEN EBT_TABLE_MAXNAMELEN
 #define EBT_FUNCTION_MAXNAMELEN EBT_TABLE_MAXNAMELEN
-/* WARNING: DO NOT EDIT, AUTO-GENERATED CODE - SEE TOP FOR INSTRUCTIONS */
 #define EBT_ACCEPT - 1
 #define EBT_DROP - 2
+/* WARNING: DO NOT EDIT, AUTO-GENERATED CODE - SEE TOP FOR INSTRUCTIONS */
 #define EBT_CONTINUE - 3
 #define EBT_RETURN - 4
-/* WARNING: DO NOT EDIT, AUTO-GENERATED CODE - SEE TOP FOR INSTRUCTIONS */
 #define NUM_STANDARD_TARGETS 4
 #define EBT_VERDICT_BITS 0x0000000F
+/* WARNING: DO NOT EDIT, AUTO-GENERATED CODE - SEE TOP FOR INSTRUCTIONS */
 struct xt_match;
 struct xt_target;
-/* WARNING: DO NOT EDIT, AUTO-GENERATED CODE - SEE TOP FOR INSTRUCTIONS */
 struct ebt_counter {
   uint64_t pcnt;
+/* WARNING: DO NOT EDIT, AUTO-GENERATED CODE - SEE TOP FOR INSTRUCTIONS */
   uint64_t bcnt;
 };
-/* WARNING: DO NOT EDIT, AUTO-GENERATED CODE - SEE TOP FOR INSTRUCTIONS */
 struct ebt_replace {
   char name[EBT_TABLE_MAXNAMELEN];
+/* WARNING: DO NOT EDIT, AUTO-GENERATED CODE - SEE TOP FOR INSTRUCTIONS */
   unsigned int valid_hooks;
   unsigned int nentries;
-/* WARNING: DO NOT EDIT, AUTO-GENERATED CODE - SEE TOP FOR INSTRUCTIONS */
   unsigned int entries_size;
   struct ebt_entries __user * hook_entry[NF_BR_NUMHOOKS];
+/* WARNING: DO NOT EDIT, AUTO-GENERATED CODE - SEE TOP FOR INSTRUCTIONS */
   unsigned int num_counters;
   struct ebt_counter __user * counters;
-/* WARNING: DO NOT EDIT, AUTO-GENERATED CODE - SEE TOP FOR INSTRUCTIONS */
   char __user * entries;
 };
+/* WARNING: DO NOT EDIT, AUTO-GENERATED CODE - SEE TOP FOR INSTRUCTIONS */
 struct ebt_replace_kernel {
   char name[EBT_TABLE_MAXNAMELEN];
-/* WARNING: DO NOT EDIT, AUTO-GENERATED CODE - SEE TOP FOR INSTRUCTIONS */
   unsigned int valid_hooks;
   unsigned int nentries;
+/* WARNING: DO NOT EDIT, AUTO-GENERATED CODE - SEE TOP FOR INSTRUCTIONS */
   unsigned int entries_size;
   struct ebt_entries * hook_entry[NF_BR_NUMHOOKS];
-/* WARNING: DO NOT EDIT, AUTO-GENERATED CODE - SEE TOP FOR INSTRUCTIONS */
   unsigned int num_counters;
   struct ebt_counter * counters;
+/* WARNING: DO NOT EDIT, AUTO-GENERATED CODE - SEE TOP FOR INSTRUCTIONS */
   char * entries;
 };
-/* WARNING: DO NOT EDIT, AUTO-GENERATED CODE - SEE TOP FOR INSTRUCTIONS */
 struct ebt_entries {
   unsigned int distinguisher;
+/* WARNING: DO NOT EDIT, AUTO-GENERATED CODE - SEE TOP FOR INSTRUCTIONS */
   char name[EBT_CHAIN_MAXNAMELEN];
   unsigned int counter_offset;
-/* WARNING: DO NOT EDIT, AUTO-GENERATED CODE - SEE TOP FOR INSTRUCTIONS */
   int policy;
   unsigned int nentries;
+/* WARNING: DO NOT EDIT, AUTO-GENERATED CODE - SEE TOP FOR INSTRUCTIONS */
   char data[0] __attribute__((aligned(__alignof__(struct ebt_replace))));
 };
-/* WARNING: DO NOT EDIT, AUTO-GENERATED CODE - SEE TOP FOR INSTRUCTIONS */
 #define EBT_ENTRY_OR_ENTRIES 0x01
 #define EBT_NOPROTO 0x02
+/* WARNING: DO NOT EDIT, AUTO-GENERATED CODE - SEE TOP FOR INSTRUCTIONS */
 #define EBT_802_3 0x04
 #define EBT_SOURCEMAC 0x08
-/* WARNING: DO NOT EDIT, AUTO-GENERATED CODE - SEE TOP FOR INSTRUCTIONS */
 #define EBT_DESTMAC 0x10
 #define EBT_F_MASK (EBT_NOPROTO | EBT_802_3 | EBT_SOURCEMAC | EBT_DESTMAC | EBT_ENTRY_OR_ENTRIES)
+/* WARNING: DO NOT EDIT, AUTO-GENERATED CODE - SEE TOP FOR INSTRUCTIONS */
 #define EBT_IPROTO 0x01
 #define EBT_IIN 0x02
-/* WARNING: DO NOT EDIT, AUTO-GENERATED CODE - SEE TOP FOR INSTRUCTIONS */
 #define EBT_IOUT 0x04
 #define EBT_ISOURCE 0x8
+/* WARNING: DO NOT EDIT, AUTO-GENERATED CODE - SEE TOP FOR INSTRUCTIONS */
 #define EBT_IDEST 0x10
 #define EBT_ILOGICALIN 0x20
-/* WARNING: DO NOT EDIT, AUTO-GENERATED CODE - SEE TOP FOR INSTRUCTIONS */
 #define EBT_ILOGICALOUT 0x40
 #define EBT_INV_MASK (EBT_IPROTO | EBT_IIN | EBT_IOUT | EBT_ILOGICALIN | EBT_ILOGICALOUT | EBT_ISOURCE | EBT_IDEST)
+/* WARNING: DO NOT EDIT, AUTO-GENERATED CODE - SEE TOP FOR INSTRUCTIONS */
 struct ebt_entry_match {
   union {
-/* WARNING: DO NOT EDIT, AUTO-GENERATED CODE - SEE TOP FOR INSTRUCTIONS */
     char name[EBT_FUNCTION_MAXNAMELEN];
     struct xt_match * match;
+/* WARNING: DO NOT EDIT, AUTO-GENERATED CODE - SEE TOP FOR INSTRUCTIONS */
   } u;
   unsigned int match_size;
-/* WARNING: DO NOT EDIT, AUTO-GENERATED CODE - SEE TOP FOR INSTRUCTIONS */
   unsigned char data[0] __attribute__((aligned(__alignof__(struct ebt_replace))));
 };
+/* WARNING: DO NOT EDIT, AUTO-GENERATED CODE - SEE TOP FOR INSTRUCTIONS */
 struct ebt_entry_watcher {
   union {
-/* WARNING: DO NOT EDIT, AUTO-GENERATED CODE - SEE TOP FOR INSTRUCTIONS */
     char name[EBT_FUNCTION_MAXNAMELEN];
     struct xt_target * watcher;
+/* WARNING: DO NOT EDIT, AUTO-GENERATED CODE - SEE TOP FOR INSTRUCTIONS */
   } u;
   unsigned int watcher_size;
-/* WARNING: DO NOT EDIT, AUTO-GENERATED CODE - SEE TOP FOR INSTRUCTIONS */
   unsigned char data[0] __attribute__((aligned(__alignof__(struct ebt_replace))));
 };
+/* WARNING: DO NOT EDIT, AUTO-GENERATED CODE - SEE TOP FOR INSTRUCTIONS */
 struct ebt_entry_target {
   union {
-/* WARNING: DO NOT EDIT, AUTO-GENERATED CODE - SEE TOP FOR INSTRUCTIONS */
     char name[EBT_FUNCTION_MAXNAMELEN];
     struct xt_target * target;
+/* WARNING: DO NOT EDIT, AUTO-GENERATED CODE - SEE TOP FOR INSTRUCTIONS */
   } u;
   unsigned int target_size;
-/* WARNING: DO NOT EDIT, AUTO-GENERATED CODE - SEE TOP FOR INSTRUCTIONS */
   unsigned char data[0] __attribute__((aligned(__alignof__(struct ebt_replace))));
 };
+/* WARNING: DO NOT EDIT, AUTO-GENERATED CODE - SEE TOP FOR INSTRUCTIONS */
 #define EBT_STANDARD_TARGET "standard"
 struct ebt_standard_target {
-/* WARNING: DO NOT EDIT, AUTO-GENERATED CODE - SEE TOP FOR INSTRUCTIONS */
   struct ebt_entry_target target;
   int verdict;
+/* WARNING: DO NOT EDIT, AUTO-GENERATED CODE - SEE TOP FOR INSTRUCTIONS */
 };
 struct ebt_entry {
-/* WARNING: DO NOT EDIT, AUTO-GENERATED CODE - SEE TOP FOR INSTRUCTIONS */
   unsigned int bitmask;
   unsigned int invflags;
+/* WARNING: DO NOT EDIT, AUTO-GENERATED CODE - SEE TOP FOR INSTRUCTIONS */
   __be16 ethproto;
   char in[IFNAMSIZ];
-/* WARNING: DO NOT EDIT, AUTO-GENERATED CODE - SEE TOP FOR INSTRUCTIONS */
   char logical_in[IFNAMSIZ];
   char out[IFNAMSIZ];
+/* WARNING: DO NOT EDIT, AUTO-GENERATED CODE - SEE TOP FOR INSTRUCTIONS */
   char logical_out[IFNAMSIZ];
   unsigned char sourcemac[ETH_ALEN];
-/* WARNING: DO NOT EDIT, AUTO-GENERATED CODE - SEE TOP FOR INSTRUCTIONS */
   unsigned char sourcemsk[ETH_ALEN];
   unsigned char destmac[ETH_ALEN];
+/* WARNING: DO NOT EDIT, AUTO-GENERATED CODE - SEE TOP FOR INSTRUCTIONS */
   unsigned char destmsk[ETH_ALEN];
   unsigned int watchers_offset;
-/* WARNING: DO NOT EDIT, AUTO-GENERATED CODE - SEE TOP FOR INSTRUCTIONS */
   unsigned int target_offset;
   unsigned int next_offset;
+/* WARNING: DO NOT EDIT, AUTO-GENERATED CODE - SEE TOP FOR INSTRUCTIONS */
   unsigned char elems[0] __attribute__((aligned(__alignof__(struct ebt_replace))));
 };
-/* WARNING: DO NOT EDIT, AUTO-GENERATED CODE - SEE TOP FOR INSTRUCTIONS */
 #define EBT_BASE_CTL 128
 #define EBT_SO_SET_ENTRIES (EBT_BASE_CTL)
+/* WARNING: DO NOT EDIT, AUTO-GENERATED CODE - SEE TOP FOR INSTRUCTIONS */
 #define EBT_SO_SET_COUNTERS (EBT_SO_SET_ENTRIES + 1)
 #define EBT_SO_SET_MAX (EBT_SO_SET_COUNTERS + 1)
-/* WARNING: DO NOT EDIT, AUTO-GENERATED CODE - SEE TOP FOR INSTRUCTIONS */
 #define EBT_SO_GET_INFO (EBT_BASE_CTL)
 #define EBT_SO_GET_ENTRIES (EBT_SO_GET_INFO + 1)
+/* WARNING: DO NOT EDIT, AUTO-GENERATED CODE - SEE TOP FOR INSTRUCTIONS */
 #define EBT_SO_GET_INIT_INFO (EBT_SO_GET_ENTRIES + 1)
 #define EBT_SO_GET_INIT_ENTRIES (EBT_SO_GET_INIT_INFO + 1)
-/* WARNING: DO NOT EDIT, AUTO-GENERATED CODE - SEE TOP FOR INSTRUCTIONS */
 #define EBT_SO_GET_MAX (EBT_SO_GET_INIT_ENTRIES + 1)
 #define EBT_MATCH_ITERATE(e,fn,args...) \
 ({ unsigned int __i; int __ret = 0; struct ebt_entry_match * __match; for(__i = sizeof(struct ebt_entry); __i < (e)->watchers_offset; __i += __match->match_size + sizeof(struct ebt_entry_match)) { __match = (void *) (e) + __i; __ret = fn(__match, ##args); if(__ret != 0) break; } if(__ret == 0) { if(__i != (e)->watchers_offset) __ret = - EINVAL; } __ret; \
 })
+/* WARNING: DO NOT EDIT, AUTO-GENERATED CODE - SEE TOP FOR INSTRUCTIONS */
 #define EBT_WATCHER_ITERATE(e,fn,args...) \
 ({ unsigned int __i; int __ret = 0; struct ebt_entry_watcher * __watcher; for(__i = e->watchers_offset; __i < (e)->target_offset; __i += __watcher->watcher_size + sizeof(struct ebt_entry_watcher)) { __watcher = (void *) (e) + __i; __ret = fn(__watcher, ##args); if(__ret != 0) break; } if(__ret == 0) { if(__i != (e)->target_offset) __ret = - EINVAL; } __ret; \
 })
 #define EBT_ENTRY_ITERATE(entries,size,fn,args...) \
 ({ unsigned int __i; int __ret = 0; struct ebt_entry * __entry; for(__i = 0; __i < (size);) { __entry = (void *) (entries) + __i; __ret = fn(__entry, ##args); if(__ret != 0) break; if(__entry->bitmask != 0) __i += __entry->next_offset; else __i += sizeof(struct ebt_entries); } if(__ret == 0) { if(__i != (size)) __ret = - EINVAL; } __ret; \
 })
-/* WARNING: DO NOT EDIT, AUTO-GENERATED CODE - SEE TOP FOR INSTRUCTIONS */
 #endif
diff --git a/libc/kernel/uapi/linux/netfilter_ipv6/ip6t_REJECT.h b/libc/kernel/uapi/linux/netfilter_ipv6/ip6t_REJECT.h
index afe5cd5..cf342dc 100644
--- a/libc/kernel/uapi/linux/netfilter_ipv6/ip6t_REJECT.h
+++ b/libc/kernel/uapi/linux/netfilter_ipv6/ip6t_REJECT.h
@@ -28,11 +28,13 @@
 /* WARNING: DO NOT EDIT, AUTO-GENERATED CODE - SEE TOP FOR INSTRUCTIONS */
   IP6T_ICMP6_PORT_UNREACH,
   IP6T_ICMP6_ECHOREPLY,
-  IP6T_TCP_RESET
-};
+  IP6T_TCP_RESET,
+  IP6T_ICMP6_POLICY_FAIL,
 /* WARNING: DO NOT EDIT, AUTO-GENERATED CODE - SEE TOP FOR INSTRUCTIONS */
+  IP6T_ICMP6_REJECT_ROUTE
+};
 struct ip6t_reject_info {
   __u32 with;
+/* WARNING: DO NOT EDIT, AUTO-GENERATED CODE - SEE TOP FOR INSTRUCTIONS */
 };
 #endif
-/* WARNING: DO NOT EDIT, AUTO-GENERATED CODE - SEE TOP FOR INSTRUCTIONS */
diff --git a/libc/kernel/uapi/linux/netlink.h b/libc/kernel/uapi/linux/netlink.h
index bcaf020..bcdac47 100644
--- a/libc/kernel/uapi/linux/netlink.h
+++ b/libc/kernel/uapi/linux/netlink.h
@@ -73,47 +73,52 @@
 /* WARNING: DO NOT EDIT, AUTO-GENERATED CODE - SEE TOP FOR INSTRUCTIONS */
 #define NLM_F_ECHO 8
 #define NLM_F_DUMP_INTR 16
+#define NLM_F_DUMP_FILTERED 32
 #define NLM_F_ROOT 0x100
-#define NLM_F_MATCH 0x200
 /* WARNING: DO NOT EDIT, AUTO-GENERATED CODE - SEE TOP FOR INSTRUCTIONS */
+#define NLM_F_MATCH 0x200
 #define NLM_F_ATOMIC 0x400
 #define NLM_F_DUMP (NLM_F_ROOT | NLM_F_MATCH)
 #define NLM_F_REPLACE 0x100
-#define NLM_F_EXCL 0x200
 /* WARNING: DO NOT EDIT, AUTO-GENERATED CODE - SEE TOP FOR INSTRUCTIONS */
+#define NLM_F_EXCL 0x200
 #define NLM_F_CREATE 0x400
 #define NLM_F_APPEND 0x800
 #define NLMSG_ALIGNTO 4U
-#define NLMSG_ALIGN(len) (((len) + NLMSG_ALIGNTO - 1) & ~(NLMSG_ALIGNTO - 1))
 /* WARNING: DO NOT EDIT, AUTO-GENERATED CODE - SEE TOP FOR INSTRUCTIONS */
+#define NLMSG_ALIGN(len) (((len) + NLMSG_ALIGNTO - 1) & ~(NLMSG_ALIGNTO - 1))
 #define NLMSG_HDRLEN ((int) NLMSG_ALIGN(sizeof(struct nlmsghdr)))
 #define NLMSG_LENGTH(len) ((len) + NLMSG_HDRLEN)
 #define NLMSG_SPACE(len) NLMSG_ALIGN(NLMSG_LENGTH(len))
-#define NLMSG_DATA(nlh) ((void *) (((char *) nlh) + NLMSG_LENGTH(0)))
 /* WARNING: DO NOT EDIT, AUTO-GENERATED CODE - SEE TOP FOR INSTRUCTIONS */
+#define NLMSG_DATA(nlh) ((void *) (((char *) nlh) + NLMSG_LENGTH(0)))
 #define NLMSG_NEXT(nlh,len) ((len) -= NLMSG_ALIGN((nlh)->nlmsg_len), (struct nlmsghdr *) (((char *) (nlh)) + NLMSG_ALIGN((nlh)->nlmsg_len)))
 #define NLMSG_OK(nlh,len) ((len) >= (int) sizeof(struct nlmsghdr) && (nlh)->nlmsg_len >= sizeof(struct nlmsghdr) && (nlh)->nlmsg_len <= (len))
 #define NLMSG_PAYLOAD(nlh,len) ((nlh)->nlmsg_len - NLMSG_SPACE((len)))
-#define NLMSG_NOOP 0x1
 /* WARNING: DO NOT EDIT, AUTO-GENERATED CODE - SEE TOP FOR INSTRUCTIONS */
+#define NLMSG_NOOP 0x1
 #define NLMSG_ERROR 0x2
 #define NLMSG_DONE 0x3
 #define NLMSG_OVERRUN 0x4
-#define NLMSG_MIN_TYPE 0x10
 /* WARNING: DO NOT EDIT, AUTO-GENERATED CODE - SEE TOP FOR INSTRUCTIONS */
+#define NLMSG_MIN_TYPE 0x10
 struct nlmsgerr {
   int error;
   struct nlmsghdr msg;
-};
 /* WARNING: DO NOT EDIT, AUTO-GENERATED CODE - SEE TOP FOR INSTRUCTIONS */
+};
 #define NETLINK_ADD_MEMBERSHIP 1
 #define NETLINK_DROP_MEMBERSHIP 2
 #define NETLINK_PKTINFO 3
-#define NETLINK_BROADCAST_ERROR 4
 /* WARNING: DO NOT EDIT, AUTO-GENERATED CODE - SEE TOP FOR INSTRUCTIONS */
+#define NETLINK_BROADCAST_ERROR 4
 #define NETLINK_NO_ENOBUFS 5
 #define NETLINK_RX_RING 6
 #define NETLINK_TX_RING 7
+/* WARNING: DO NOT EDIT, AUTO-GENERATED CODE - SEE TOP FOR INSTRUCTIONS */
+#define NETLINK_LISTEN_ALL_NSID 8
+#define NETLINK_LIST_MEMBERSHIPS 9
+#define NETLINK_CAP_ACK 10
 struct nl_pktinfo {
 /* WARNING: DO NOT EDIT, AUTO-GENERATED CODE - SEE TOP FOR INSTRUCTIONS */
   __u32 group;
diff --git a/libc/kernel/uapi/linux/nfc.h b/libc/kernel/uapi/linux/nfc.h
index 7a83ac7..1894e92 100644
--- a/libc/kernel/uapi/linux/nfc.h
+++ b/libc/kernel/uapi/linux/nfc.h
@@ -61,141 +61,154 @@
   NFC_CMD_GET_SE,
   NFC_CMD_SE_IO,
 /* WARNING: DO NOT EDIT, AUTO-GENERATED CODE - SEE TOP FOR INSTRUCTIONS */
+  NFC_CMD_ACTIVATE_TARGET,
+  NFC_CMD_VENDOR,
   __NFC_CMD_AFTER_LAST
 };
+/* WARNING: DO NOT EDIT, AUTO-GENERATED CODE - SEE TOP FOR INSTRUCTIONS */
 #define NFC_CMD_MAX (__NFC_CMD_AFTER_LAST - 1)
 enum nfc_attrs {
-/* WARNING: DO NOT EDIT, AUTO-GENERATED CODE - SEE TOP FOR INSTRUCTIONS */
   NFC_ATTR_UNSPEC,
   NFC_ATTR_DEVICE_INDEX,
+/* WARNING: DO NOT EDIT, AUTO-GENERATED CODE - SEE TOP FOR INSTRUCTIONS */
   NFC_ATTR_DEVICE_NAME,
   NFC_ATTR_PROTOCOLS,
-/* WARNING: DO NOT EDIT, AUTO-GENERATED CODE - SEE TOP FOR INSTRUCTIONS */
   NFC_ATTR_TARGET_INDEX,
   NFC_ATTR_TARGET_SENS_RES,
+/* WARNING: DO NOT EDIT, AUTO-GENERATED CODE - SEE TOP FOR INSTRUCTIONS */
   NFC_ATTR_TARGET_SEL_RES,
   NFC_ATTR_TARGET_NFCID1,
-/* WARNING: DO NOT EDIT, AUTO-GENERATED CODE - SEE TOP FOR INSTRUCTIONS */
   NFC_ATTR_TARGET_SENSB_RES,
   NFC_ATTR_TARGET_SENSF_RES,
+/* WARNING: DO NOT EDIT, AUTO-GENERATED CODE - SEE TOP FOR INSTRUCTIONS */
   NFC_ATTR_COMM_MODE,
   NFC_ATTR_RF_MODE,
-/* WARNING: DO NOT EDIT, AUTO-GENERATED CODE - SEE TOP FOR INSTRUCTIONS */
   NFC_ATTR_DEVICE_POWERED,
   NFC_ATTR_IM_PROTOCOLS,
+/* WARNING: DO NOT EDIT, AUTO-GENERATED CODE - SEE TOP FOR INSTRUCTIONS */
   NFC_ATTR_TM_PROTOCOLS,
   NFC_ATTR_LLC_PARAM_LTO,
-/* WARNING: DO NOT EDIT, AUTO-GENERATED CODE - SEE TOP FOR INSTRUCTIONS */
   NFC_ATTR_LLC_PARAM_RW,
   NFC_ATTR_LLC_PARAM_MIUX,
+/* WARNING: DO NOT EDIT, AUTO-GENERATED CODE - SEE TOP FOR INSTRUCTIONS */
   NFC_ATTR_SE,
   NFC_ATTR_LLC_SDP,
-/* WARNING: DO NOT EDIT, AUTO-GENERATED CODE - SEE TOP FOR INSTRUCTIONS */
   NFC_ATTR_FIRMWARE_NAME,
   NFC_ATTR_SE_INDEX,
+/* WARNING: DO NOT EDIT, AUTO-GENERATED CODE - SEE TOP FOR INSTRUCTIONS */
   NFC_ATTR_SE_TYPE,
   NFC_ATTR_SE_AID,
-/* WARNING: DO NOT EDIT, AUTO-GENERATED CODE - SEE TOP FOR INSTRUCTIONS */
   NFC_ATTR_FIRMWARE_DOWNLOAD_STATUS,
   NFC_ATTR_SE_APDU,
+/* WARNING: DO NOT EDIT, AUTO-GENERATED CODE - SEE TOP FOR INSTRUCTIONS */
   NFC_ATTR_TARGET_ISO15693_DSFID,
   NFC_ATTR_TARGET_ISO15693_UID,
+  NFC_ATTR_SE_PARAMS,
+  NFC_ATTR_VENDOR_ID,
 /* WARNING: DO NOT EDIT, AUTO-GENERATED CODE - SEE TOP FOR INSTRUCTIONS */
+  NFC_ATTR_VENDOR_SUBCMD,
+  NFC_ATTR_VENDOR_DATA,
   __NFC_ATTR_AFTER_LAST
 };
+/* WARNING: DO NOT EDIT, AUTO-GENERATED CODE - SEE TOP FOR INSTRUCTIONS */
 #define NFC_ATTR_MAX (__NFC_ATTR_AFTER_LAST - 1)
 enum nfc_sdp_attr {
-/* WARNING: DO NOT EDIT, AUTO-GENERATED CODE - SEE TOP FOR INSTRUCTIONS */
   NFC_SDP_ATTR_UNSPEC,
   NFC_SDP_ATTR_URI,
+/* WARNING: DO NOT EDIT, AUTO-GENERATED CODE - SEE TOP FOR INSTRUCTIONS */
   NFC_SDP_ATTR_SAP,
   __NFC_SDP_ATTR_AFTER_LAST
-/* WARNING: DO NOT EDIT, AUTO-GENERATED CODE - SEE TOP FOR INSTRUCTIONS */
 };
 #define NFC_SDP_ATTR_MAX (__NFC_SDP_ATTR_AFTER_LAST - 1)
+/* WARNING: DO NOT EDIT, AUTO-GENERATED CODE - SEE TOP FOR INSTRUCTIONS */
 #define NFC_DEVICE_NAME_MAXSIZE 8
 #define NFC_NFCID1_MAXSIZE 10
-/* WARNING: DO NOT EDIT, AUTO-GENERATED CODE - SEE TOP FOR INSTRUCTIONS */
 #define NFC_NFCID2_MAXSIZE 8
 #define NFC_NFCID3_MAXSIZE 10
+/* WARNING: DO NOT EDIT, AUTO-GENERATED CODE - SEE TOP FOR INSTRUCTIONS */
 #define NFC_SENSB_RES_MAXSIZE 12
 #define NFC_SENSF_RES_MAXSIZE 18
+#define NFC_ATR_REQ_MAXSIZE 64
+#define NFC_ATR_RES_MAXSIZE 64
 /* WARNING: DO NOT EDIT, AUTO-GENERATED CODE - SEE TOP FOR INSTRUCTIONS */
+#define NFC_ATR_REQ_GB_MAXSIZE 48
+#define NFC_ATR_RES_GB_MAXSIZE 47
 #define NFC_GB_MAXSIZE 48
 #define NFC_FIRMWARE_NAME_MAXSIZE 32
+/* WARNING: DO NOT EDIT, AUTO-GENERATED CODE - SEE TOP FOR INSTRUCTIONS */
 #define NFC_ISO15693_UID_MAXSIZE 8
 #define NFC_PROTO_JEWEL 1
-/* WARNING: DO NOT EDIT, AUTO-GENERATED CODE - SEE TOP FOR INSTRUCTIONS */
 #define NFC_PROTO_MIFARE 2
 #define NFC_PROTO_FELICA 3
+/* WARNING: DO NOT EDIT, AUTO-GENERATED CODE - SEE TOP FOR INSTRUCTIONS */
 #define NFC_PROTO_ISO14443 4
 #define NFC_PROTO_NFC_DEP 5
-/* WARNING: DO NOT EDIT, AUTO-GENERATED CODE - SEE TOP FOR INSTRUCTIONS */
 #define NFC_PROTO_ISO14443_B 6
 #define NFC_PROTO_ISO15693 7
+/* WARNING: DO NOT EDIT, AUTO-GENERATED CODE - SEE TOP FOR INSTRUCTIONS */
 #define NFC_PROTO_MAX 8
 #define NFC_COMM_ACTIVE 0
-/* WARNING: DO NOT EDIT, AUTO-GENERATED CODE - SEE TOP FOR INSTRUCTIONS */
 #define NFC_COMM_PASSIVE 1
 #define NFC_RF_INITIATOR 0
+/* WARNING: DO NOT EDIT, AUTO-GENERATED CODE - SEE TOP FOR INSTRUCTIONS */
 #define NFC_RF_TARGET 1
 #define NFC_RF_NONE 2
-/* WARNING: DO NOT EDIT, AUTO-GENERATED CODE - SEE TOP FOR INSTRUCTIONS */
 #define NFC_PROTO_JEWEL_MASK (1 << NFC_PROTO_JEWEL)
 #define NFC_PROTO_MIFARE_MASK (1 << NFC_PROTO_MIFARE)
+/* WARNING: DO NOT EDIT, AUTO-GENERATED CODE - SEE TOP FOR INSTRUCTIONS */
 #define NFC_PROTO_FELICA_MASK (1 << NFC_PROTO_FELICA)
 #define NFC_PROTO_ISO14443_MASK (1 << NFC_PROTO_ISO14443)
-/* WARNING: DO NOT EDIT, AUTO-GENERATED CODE - SEE TOP FOR INSTRUCTIONS */
 #define NFC_PROTO_NFC_DEP_MASK (1 << NFC_PROTO_NFC_DEP)
 #define NFC_PROTO_ISO14443_B_MASK (1 << NFC_PROTO_ISO14443_B)
+/* WARNING: DO NOT EDIT, AUTO-GENERATED CODE - SEE TOP FOR INSTRUCTIONS */
 #define NFC_PROTO_ISO15693_MASK (1 << NFC_PROTO_ISO15693)
 #define NFC_SE_UICC 0x1
-/* WARNING: DO NOT EDIT, AUTO-GENERATED CODE - SEE TOP FOR INSTRUCTIONS */
 #define NFC_SE_EMBEDDED 0x2
 #define NFC_SE_DISABLED 0x0
+/* WARNING: DO NOT EDIT, AUTO-GENERATED CODE - SEE TOP FOR INSTRUCTIONS */
 #define NFC_SE_ENABLED 0x1
 struct sockaddr_nfc {
-/* WARNING: DO NOT EDIT, AUTO-GENERATED CODE - SEE TOP FOR INSTRUCTIONS */
   sa_family_t sa_family;
   __u32 dev_idx;
+/* WARNING: DO NOT EDIT, AUTO-GENERATED CODE - SEE TOP FOR INSTRUCTIONS */
   __u32 target_idx;
   __u32 nfc_protocol;
-/* WARNING: DO NOT EDIT, AUTO-GENERATED CODE - SEE TOP FOR INSTRUCTIONS */
 };
 #define NFC_LLCP_MAX_SERVICE_NAME 63
+/* WARNING: DO NOT EDIT, AUTO-GENERATED CODE - SEE TOP FOR INSTRUCTIONS */
 struct sockaddr_nfc_llcp {
   sa_family_t sa_family;
-/* WARNING: DO NOT EDIT, AUTO-GENERATED CODE - SEE TOP FOR INSTRUCTIONS */
   __u32 dev_idx;
   __u32 target_idx;
+/* WARNING: DO NOT EDIT, AUTO-GENERATED CODE - SEE TOP FOR INSTRUCTIONS */
   __u32 nfc_protocol;
   __u8 dsap;
-/* WARNING: DO NOT EDIT, AUTO-GENERATED CODE - SEE TOP FOR INSTRUCTIONS */
   __u8 ssap;
   char service_name[NFC_LLCP_MAX_SERVICE_NAME];
+/* WARNING: DO NOT EDIT, AUTO-GENERATED CODE - SEE TOP FOR INSTRUCTIONS */
 ;
   size_t service_name_len;
-/* WARNING: DO NOT EDIT, AUTO-GENERATED CODE - SEE TOP FOR INSTRUCTIONS */
 };
 #define NFC_SOCKPROTO_RAW 0
+/* WARNING: DO NOT EDIT, AUTO-GENERATED CODE - SEE TOP FOR INSTRUCTIONS */
 #define NFC_SOCKPROTO_LLCP 1
 #define NFC_SOCKPROTO_MAX 2
-/* WARNING: DO NOT EDIT, AUTO-GENERATED CODE - SEE TOP FOR INSTRUCTIONS */
 #define NFC_HEADER_SIZE 1
 #define NFC_RAW_HEADER_SIZE 2
+/* WARNING: DO NOT EDIT, AUTO-GENERATED CODE - SEE TOP FOR INSTRUCTIONS */
 #define NFC_DIRECTION_RX 0x00
 #define NFC_DIRECTION_TX 0x01
-/* WARNING: DO NOT EDIT, AUTO-GENERATED CODE - SEE TOP FOR INSTRUCTIONS */
 #define RAW_PAYLOAD_LLCP 0
 #define RAW_PAYLOAD_NCI 1
+/* WARNING: DO NOT EDIT, AUTO-GENERATED CODE - SEE TOP FOR INSTRUCTIONS */
 #define RAW_PAYLOAD_HCI 2
 #define RAW_PAYLOAD_DIGITAL 3
-/* WARNING: DO NOT EDIT, AUTO-GENERATED CODE - SEE TOP FOR INSTRUCTIONS */
 #define RAW_PAYLOAD_PROPRIETARY 4
 #define NFC_LLCP_RW 0
+/* WARNING: DO NOT EDIT, AUTO-GENERATED CODE - SEE TOP FOR INSTRUCTIONS */
 #define NFC_LLCP_MIUX 1
 #define NFC_LLCP_REMOTE_MIU 2
-/* WARNING: DO NOT EDIT, AUTO-GENERATED CODE - SEE TOP FOR INSTRUCTIONS */
 #define NFC_LLCP_REMOTE_LTO 3
 #define NFC_LLCP_REMOTE_RW 4
+/* WARNING: DO NOT EDIT, AUTO-GENERATED CODE - SEE TOP FOR INSTRUCTIONS */
 #endif
diff --git a/libc/kernel/uapi/linux/nfs.h b/libc/kernel/uapi/linux/nfs.h
index 27083a2..0d546e1 100644
--- a/libc/kernel/uapi/linux/nfs.h
+++ b/libc/kernel/uapi/linux/nfs.h
@@ -18,137 +18,138 @@
  ****************************************************************************/
 #ifndef _UAPI_LINUX_NFS_H
 #define _UAPI_LINUX_NFS_H
+#include <linux/types.h>
 #define NFS_PROGRAM 100003
-#define NFS_PORT 2049
 /* WARNING: DO NOT EDIT, AUTO-GENERATED CODE - SEE TOP FOR INSTRUCTIONS */
+#define NFS_PORT 2049
 #define NFS_MAXDATA 8192
 #define NFS_MAXPATHLEN 1024
 #define NFS_MAXNAMLEN 255
-#define NFS_MAXGROUPS 16
 /* WARNING: DO NOT EDIT, AUTO-GENERATED CODE - SEE TOP FOR INSTRUCTIONS */
+#define NFS_MAXGROUPS 16
 #define NFS_FHSIZE 32
 #define NFS_COOKIESIZE 4
 #define NFS_FIFO_DEV (- 1)
-#define NFSMODE_FMT 0170000
 /* WARNING: DO NOT EDIT, AUTO-GENERATED CODE - SEE TOP FOR INSTRUCTIONS */
+#define NFSMODE_FMT 0170000
 #define NFSMODE_DIR 0040000
 #define NFSMODE_CHR 0020000
 #define NFSMODE_BLK 0060000
-#define NFSMODE_REG 0100000
 /* WARNING: DO NOT EDIT, AUTO-GENERATED CODE - SEE TOP FOR INSTRUCTIONS */
+#define NFSMODE_REG 0100000
 #define NFSMODE_LNK 0120000
 #define NFSMODE_SOCK 0140000
 #define NFSMODE_FIFO 0010000
-#define NFS_MNT_PROGRAM 100005
 /* WARNING: DO NOT EDIT, AUTO-GENERATED CODE - SEE TOP FOR INSTRUCTIONS */
+#define NFS_MNT_PROGRAM 100005
 #define NFS_MNT_VERSION 1
 #define NFS_MNT3_VERSION 3
 #define NFS_PIPE_DIRNAME "nfs"
-enum nfs_stat {
 /* WARNING: DO NOT EDIT, AUTO-GENERATED CODE - SEE TOP FOR INSTRUCTIONS */
+enum nfs_stat {
   NFS_OK = 0,
   NFSERR_PERM = 1,
   NFSERR_NOENT = 2,
-  NFSERR_IO = 5,
 /* WARNING: DO NOT EDIT, AUTO-GENERATED CODE - SEE TOP FOR INSTRUCTIONS */
+  NFSERR_IO = 5,
   NFSERR_NXIO = 6,
   NFSERR_EAGAIN = 11,
   NFSERR_ACCES = 13,
-  NFSERR_EXIST = 17,
 /* WARNING: DO NOT EDIT, AUTO-GENERATED CODE - SEE TOP FOR INSTRUCTIONS */
+  NFSERR_EXIST = 17,
   NFSERR_XDEV = 18,
   NFSERR_NODEV = 19,
   NFSERR_NOTDIR = 20,
-  NFSERR_ISDIR = 21,
 /* WARNING: DO NOT EDIT, AUTO-GENERATED CODE - SEE TOP FOR INSTRUCTIONS */
+  NFSERR_ISDIR = 21,
   NFSERR_INVAL = 22,
   NFSERR_FBIG = 27,
   NFSERR_NOSPC = 28,
-  NFSERR_ROFS = 30,
 /* WARNING: DO NOT EDIT, AUTO-GENERATED CODE - SEE TOP FOR INSTRUCTIONS */
+  NFSERR_ROFS = 30,
   NFSERR_MLINK = 31,
   NFSERR_OPNOTSUPP = 45,
   NFSERR_NAMETOOLONG = 63,
-  NFSERR_NOTEMPTY = 66,
 /* WARNING: DO NOT EDIT, AUTO-GENERATED CODE - SEE TOP FOR INSTRUCTIONS */
+  NFSERR_NOTEMPTY = 66,
   NFSERR_DQUOT = 69,
   NFSERR_STALE = 70,
   NFSERR_REMOTE = 71,
-  NFSERR_WFLUSH = 99,
 /* WARNING: DO NOT EDIT, AUTO-GENERATED CODE - SEE TOP FOR INSTRUCTIONS */
+  NFSERR_WFLUSH = 99,
   NFSERR_BADHANDLE = 10001,
   NFSERR_NOT_SYNC = 10002,
   NFSERR_BAD_COOKIE = 10003,
-  NFSERR_NOTSUPP = 10004,
 /* WARNING: DO NOT EDIT, AUTO-GENERATED CODE - SEE TOP FOR INSTRUCTIONS */
+  NFSERR_NOTSUPP = 10004,
   NFSERR_TOOSMALL = 10005,
   NFSERR_SERVERFAULT = 10006,
   NFSERR_BADTYPE = 10007,
-  NFSERR_JUKEBOX = 10008,
 /* WARNING: DO NOT EDIT, AUTO-GENERATED CODE - SEE TOP FOR INSTRUCTIONS */
+  NFSERR_JUKEBOX = 10008,
   NFSERR_SAME = 10009,
   NFSERR_DENIED = 10010,
   NFSERR_EXPIRED = 10011,
-  NFSERR_LOCKED = 10012,
 /* WARNING: DO NOT EDIT, AUTO-GENERATED CODE - SEE TOP FOR INSTRUCTIONS */
+  NFSERR_LOCKED = 10012,
   NFSERR_GRACE = 10013,
   NFSERR_FHEXPIRED = 10014,
   NFSERR_SHARE_DENIED = 10015,
-  NFSERR_WRONGSEC = 10016,
 /* WARNING: DO NOT EDIT, AUTO-GENERATED CODE - SEE TOP FOR INSTRUCTIONS */
+  NFSERR_WRONGSEC = 10016,
   NFSERR_CLID_INUSE = 10017,
   NFSERR_RESOURCE = 10018,
   NFSERR_MOVED = 10019,
-  NFSERR_NOFILEHANDLE = 10020,
 /* WARNING: DO NOT EDIT, AUTO-GENERATED CODE - SEE TOP FOR INSTRUCTIONS */
+  NFSERR_NOFILEHANDLE = 10020,
   NFSERR_MINOR_VERS_MISMATCH = 10021,
   NFSERR_STALE_CLIENTID = 10022,
   NFSERR_STALE_STATEID = 10023,
-  NFSERR_OLD_STATEID = 10024,
 /* WARNING: DO NOT EDIT, AUTO-GENERATED CODE - SEE TOP FOR INSTRUCTIONS */
+  NFSERR_OLD_STATEID = 10024,
   NFSERR_BAD_STATEID = 10025,
   NFSERR_BAD_SEQID = 10026,
   NFSERR_NOT_SAME = 10027,
-  NFSERR_LOCK_RANGE = 10028,
 /* WARNING: DO NOT EDIT, AUTO-GENERATED CODE - SEE TOP FOR INSTRUCTIONS */
+  NFSERR_LOCK_RANGE = 10028,
   NFSERR_SYMLINK = 10029,
   NFSERR_RESTOREFH = 10030,
   NFSERR_LEASE_MOVED = 10031,
-  NFSERR_ATTRNOTSUPP = 10032,
 /* WARNING: DO NOT EDIT, AUTO-GENERATED CODE - SEE TOP FOR INSTRUCTIONS */
+  NFSERR_ATTRNOTSUPP = 10032,
   NFSERR_NO_GRACE = 10033,
   NFSERR_RECLAIM_BAD = 10034,
   NFSERR_RECLAIM_CONFLICT = 10035,
-  NFSERR_BAD_XDR = 10036,
 /* WARNING: DO NOT EDIT, AUTO-GENERATED CODE - SEE TOP FOR INSTRUCTIONS */
+  NFSERR_BAD_XDR = 10036,
   NFSERR_LOCKS_HELD = 10037,
   NFSERR_OPENMODE = 10038,
   NFSERR_BADOWNER = 10039,
-  NFSERR_BADCHAR = 10040,
 /* WARNING: DO NOT EDIT, AUTO-GENERATED CODE - SEE TOP FOR INSTRUCTIONS */
+  NFSERR_BADCHAR = 10040,
   NFSERR_BADNAME = 10041,
   NFSERR_BAD_RANGE = 10042,
   NFSERR_LOCK_NOTSUPP = 10043,
-  NFSERR_OP_ILLEGAL = 10044,
 /* WARNING: DO NOT EDIT, AUTO-GENERATED CODE - SEE TOP FOR INSTRUCTIONS */
+  NFSERR_OP_ILLEGAL = 10044,
   NFSERR_DEADLOCK = 10045,
   NFSERR_FILE_OPEN = 10046,
   NFSERR_ADMIN_REVOKED = 10047,
-  NFSERR_CB_PATH_DOWN = 10048,
 /* WARNING: DO NOT EDIT, AUTO-GENERATED CODE - SEE TOP FOR INSTRUCTIONS */
+  NFSERR_CB_PATH_DOWN = 10048,
 };
 enum nfs_ftype {
   NFNON = 0,
-  NFREG = 1,
 /* WARNING: DO NOT EDIT, AUTO-GENERATED CODE - SEE TOP FOR INSTRUCTIONS */
+  NFREG = 1,
   NFDIR = 2,
   NFBLK = 3,
   NFCHR = 4,
-  NFLNK = 5,
 /* WARNING: DO NOT EDIT, AUTO-GENERATED CODE - SEE TOP FOR INSTRUCTIONS */
+  NFLNK = 5,
   NFSOCK = 6,
   NFBAD = 7,
   NFFIFO = 8
-};
 /* WARNING: DO NOT EDIT, AUTO-GENERATED CODE - SEE TOP FOR INSTRUCTIONS */
+};
 #endif
diff --git a/libc/kernel/uapi/linux/nfs4.h b/libc/kernel/uapi/linux/nfs4.h
index b0dd925..884141a 100644
--- a/libc/kernel/uapi/linux/nfs4.h
+++ b/libc/kernel/uapi/linux/nfs4.h
@@ -19,7 +19,7 @@
 #ifndef _UAPI_LINUX_NFS4_H
 #define _UAPI_LINUX_NFS4_H
 #include <linux/types.h>
-#define NFS4_BITMAP_SIZE 2
+#define NFS4_BITMAP_SIZE 3
 /* WARNING: DO NOT EDIT, AUTO-GENERATED CODE - SEE TOP FOR INSTRUCTIONS */
 #define NFS4_VERIFIER_SIZE 8
 #define NFS4_STATEID_SEQID_SIZE 4
@@ -92,14 +92,19 @@
 #define ACL4_SUPPORT_AUDIT_ACL 0x04
 /* WARNING: DO NOT EDIT, AUTO-GENERATED CODE - SEE TOP FOR INSTRUCTIONS */
 #define ACL4_SUPPORT_ALARM_ACL 0x08
+#define NFS4_ACL_AUTO_INHERIT 0x00000001
+#define NFS4_ACL_PROTECTED 0x00000002
+#define NFS4_ACL_DEFAULTED 0x00000004
+/* WARNING: DO NOT EDIT, AUTO-GENERATED CODE - SEE TOP FOR INSTRUCTIONS */
 #define NFS4_ACE_FILE_INHERIT_ACE 0x00000001
 #define NFS4_ACE_DIRECTORY_INHERIT_ACE 0x00000002
 #define NFS4_ACE_NO_PROPAGATE_INHERIT_ACE 0x00000004
-/* WARNING: DO NOT EDIT, AUTO-GENERATED CODE - SEE TOP FOR INSTRUCTIONS */
 #define NFS4_ACE_INHERIT_ONLY_ACE 0x00000008
+/* WARNING: DO NOT EDIT, AUTO-GENERATED CODE - SEE TOP FOR INSTRUCTIONS */
 #define NFS4_ACE_SUCCESSFUL_ACCESS_ACE_FLAG 0x00000010
 #define NFS4_ACE_FAILED_ACCESS_ACE_FLAG 0x00000020
 #define NFS4_ACE_IDENTIFIER_GROUP 0x00000040
+#define NFS4_ACE_INHERITED_ACE 0x00000080
 /* WARNING: DO NOT EDIT, AUTO-GENERATED CODE - SEE TOP FOR INSTRUCTIONS */
 #define NFS4_ACE_READ_DATA 0x00000001
 #define NFS4_ACE_LIST_DIRECTORY 0x00000001
@@ -116,56 +121,51 @@
 #define NFS4_ACE_READ_ATTRIBUTES 0x00000080
 #define NFS4_ACE_WRITE_ATTRIBUTES 0x00000100
 /* WARNING: DO NOT EDIT, AUTO-GENERATED CODE - SEE TOP FOR INSTRUCTIONS */
+#define NFS4_ACE_WRITE_RETENTION 0x00000200
+#define NFS4_ACE_WRITE_RETENTION_HOLD 0x00000400
 #define NFS4_ACE_DELETE 0x00010000
 #define NFS4_ACE_READ_ACL 0x00020000
+/* WARNING: DO NOT EDIT, AUTO-GENERATED CODE - SEE TOP FOR INSTRUCTIONS */
 #define NFS4_ACE_WRITE_ACL 0x00040000
 #define NFS4_ACE_WRITE_OWNER 0x00080000
-/* WARNING: DO NOT EDIT, AUTO-GENERATED CODE - SEE TOP FOR INSTRUCTIONS */
 #define NFS4_ACE_SYNCHRONIZE 0x00100000
 #define NFS4_ACE_GENERIC_READ 0x00120081
+/* WARNING: DO NOT EDIT, AUTO-GENERATED CODE - SEE TOP FOR INSTRUCTIONS */
 #define NFS4_ACE_GENERIC_WRITE 0x00160106
 #define NFS4_ACE_GENERIC_EXECUTE 0x001200A0
-/* WARNING: DO NOT EDIT, AUTO-GENERATED CODE - SEE TOP FOR INSTRUCTIONS */
 #define NFS4_ACE_MASK_ALL 0x001F01FF
 #define EXCHGID4_FLAG_SUPP_MOVED_REFER 0x00000001
+/* WARNING: DO NOT EDIT, AUTO-GENERATED CODE - SEE TOP FOR INSTRUCTIONS */
 #define EXCHGID4_FLAG_SUPP_MOVED_MIGR 0x00000002
 #define EXCHGID4_FLAG_BIND_PRINC_STATEID 0x00000100
-/* WARNING: DO NOT EDIT, AUTO-GENERATED CODE - SEE TOP FOR INSTRUCTIONS */
 #define EXCHGID4_FLAG_USE_NON_PNFS 0x00010000
 #define EXCHGID4_FLAG_USE_PNFS_MDS 0x00020000
+/* WARNING: DO NOT EDIT, AUTO-GENERATED CODE - SEE TOP FOR INSTRUCTIONS */
 #define EXCHGID4_FLAG_USE_PNFS_DS 0x00040000
 #define EXCHGID4_FLAG_MASK_PNFS 0x00070000
-/* WARNING: DO NOT EDIT, AUTO-GENERATED CODE - SEE TOP FOR INSTRUCTIONS */
 #define EXCHGID4_FLAG_UPD_CONFIRMED_REC_A 0x40000000
 #define EXCHGID4_FLAG_CONFIRMED_R 0x80000000
+/* WARNING: DO NOT EDIT, AUTO-GENERATED CODE - SEE TOP FOR INSTRUCTIONS */
 #define EXCHGID4_FLAG_MASK_A 0x40070103
 #define EXCHGID4_FLAG_MASK_R 0x80070103
-/* WARNING: DO NOT EDIT, AUTO-GENERATED CODE - SEE TOP FOR INSTRUCTIONS */
 #define SEQ4_STATUS_CB_PATH_DOWN 0x00000001
 #define SEQ4_STATUS_CB_GSS_CONTEXTS_EXPIRING 0x00000002
+/* WARNING: DO NOT EDIT, AUTO-GENERATED CODE - SEE TOP FOR INSTRUCTIONS */
 #define SEQ4_STATUS_CB_GSS_CONTEXTS_EXPIRED 0x00000004
 #define SEQ4_STATUS_EXPIRED_ALL_STATE_REVOKED 0x00000008
-/* WARNING: DO NOT EDIT, AUTO-GENERATED CODE - SEE TOP FOR INSTRUCTIONS */
 #define SEQ4_STATUS_EXPIRED_SOME_STATE_REVOKED 0x00000010
 #define SEQ4_STATUS_ADMIN_STATE_REVOKED 0x00000020
+/* WARNING: DO NOT EDIT, AUTO-GENERATED CODE - SEE TOP FOR INSTRUCTIONS */
 #define SEQ4_STATUS_RECALLABLE_STATE_REVOKED 0x00000040
 #define SEQ4_STATUS_LEASE_MOVED 0x00000080
-/* WARNING: DO NOT EDIT, AUTO-GENERATED CODE - SEE TOP FOR INSTRUCTIONS */
 #define SEQ4_STATUS_RESTART_RECLAIM_NEEDED 0x00000100
 #define SEQ4_STATUS_CB_PATH_DOWN_SESSION 0x00000200
+/* WARNING: DO NOT EDIT, AUTO-GENERATED CODE - SEE TOP FOR INSTRUCTIONS */
 #define SEQ4_STATUS_BACKCHANNEL_FAULT 0x00000400
 #define NFS4_SECINFO_STYLE4_CURRENT_FH 0
-/* WARNING: DO NOT EDIT, AUTO-GENERATED CODE - SEE TOP FOR INSTRUCTIONS */
 #define NFS4_SECINFO_STYLE4_PARENT 1
 #define NFS4_MAX_UINT64 (~(__u64) 0)
+/* WARNING: DO NOT EDIT, AUTO-GENERATED CODE - SEE TOP FOR INSTRUCTIONS */
 #define NFS4_MAX_OPS 8
 #define NFS4_MAX_BACK_CHANNEL_OPS 2
-/* WARNING: DO NOT EDIT, AUTO-GENERATED CODE - SEE TOP FOR INSTRUCTIONS */
-enum nfs4_acl_whotype {
-  NFS4_ACL_WHO_NAMED = 0,
-  NFS4_ACL_WHO_OWNER,
-  NFS4_ACL_WHO_GROUP,
-/* WARNING: DO NOT EDIT, AUTO-GENERATED CODE - SEE TOP FOR INSTRUCTIONS */
-  NFS4_ACL_WHO_EVERYONE,
-};
 #endif
diff --git a/libc/kernel/uapi/linux/nfsacl.h b/libc/kernel/uapi/linux/nfsacl.h
index a38d32b..3964cf2 100644
--- a/libc/kernel/uapi/linux/nfsacl.h
+++ b/libc/kernel/uapi/linux/nfsacl.h
@@ -32,5 +32,7 @@
 #define NFS_DFACL 0x0004
 /* WARNING: DO NOT EDIT, AUTO-GENERATED CODE - SEE TOP FOR INSTRUCTIONS */
 #define NFS_DFACLCNT 0x0008
+#define NFS_ACL_MASK 0x000f
 #define NFS_ACL_DEFAULT 0x1000
 #endif
+/* WARNING: DO NOT EDIT, AUTO-GENERATED CODE - SEE TOP FOR INSTRUCTIONS */
diff --git a/libc/kernel/uapi/linux/nfsd/debug.h b/libc/kernel/uapi/linux/nfsd/debug.h
index c6a2b4d..3182121 100644
--- a/libc/kernel/uapi/linux/nfsd/debug.h
+++ b/libc/kernel/uapi/linux/nfsd/debug.h
@@ -19,23 +19,21 @@
 #ifndef _UAPILINUX_NFSD_DEBUG_H
 #define _UAPILINUX_NFSD_DEBUG_H
 #include <linux/sunrpc/debug.h>
-#ifdef RPC_DEBUG
-/* WARNING: DO NOT EDIT, AUTO-GENERATED CODE - SEE TOP FOR INSTRUCTIONS */
-#define NFSD_DEBUG 1
-#endif
 #define NFSDDBG_SOCK 0x0001
-#define NFSDDBG_FH 0x0002
 /* WARNING: DO NOT EDIT, AUTO-GENERATED CODE - SEE TOP FOR INSTRUCTIONS */
+#define NFSDDBG_FH 0x0002
 #define NFSDDBG_EXPORT 0x0004
 #define NFSDDBG_SVC 0x0008
 #define NFSDDBG_PROC 0x0010
-#define NFSDDBG_FILEOP 0x0020
 /* WARNING: DO NOT EDIT, AUTO-GENERATED CODE - SEE TOP FOR INSTRUCTIONS */
+#define NFSDDBG_FILEOP 0x0020
 #define NFSDDBG_AUTH 0x0040
 #define NFSDDBG_REPCACHE 0x0080
 #define NFSDDBG_XDR 0x0100
-#define NFSDDBG_LOCKD 0x0200
 /* WARNING: DO NOT EDIT, AUTO-GENERATED CODE - SEE TOP FOR INSTRUCTIONS */
+#define NFSDDBG_LOCKD 0x0200
+#define NFSDDBG_PNFS 0x0400
 #define NFSDDBG_ALL 0x7FFF
 #define NFSDDBG_NOCHANGE 0xFFFF
+/* WARNING: DO NOT EDIT, AUTO-GENERATED CODE - SEE TOP FOR INSTRUCTIONS */
 #endif
diff --git a/libc/kernel/uapi/linux/nfsd/export.h b/libc/kernel/uapi/linux/nfsd/export.h
index 4d7bfad..c5342e9 100644
--- a/libc/kernel/uapi/linux/nfsd/export.h
+++ b/libc/kernel/uapi/linux/nfsd/export.h
@@ -42,7 +42,8 @@
 #define NFSEXP_NOACL 0x8000
 /* WARNING: DO NOT EDIT, AUTO-GENERATED CODE - SEE TOP FOR INSTRUCTIONS */
 #define NFSEXP_V4ROOT 0x10000
-#define NFSEXP_ALLFLAGS 0x1FE7F
+#define NFSEXP_PNFS 0x20000
+#define NFSEXP_ALLFLAGS 0x3FE7F
 #define NFSEXP_SECINFO_FLAGS (NFSEXP_READONLY | NFSEXP_ROOTSQUASH | NFSEXP_ALLSQUASH | NFSEXP_INSECURE_PORT)
-#endif
 /* WARNING: DO NOT EDIT, AUTO-GENERATED CODE - SEE TOP FOR INSTRUCTIONS */
+#endif
diff --git a/libc/kernel/uapi/linux/nl80211.h b/libc/kernel/uapi/linux/nl80211.h
index ae6d6d8..5453971 100644
--- a/libc/kernel/uapi/linux/nl80211.h
+++ b/libc/kernel/uapi/linux/nl80211.h
@@ -21,498 +21,533 @@
 #include <linux/types.h>
 #define NL80211_GENL_NAME "nl80211"
 /* WARNING: DO NOT EDIT, AUTO-GENERATED CODE - SEE TOP FOR INSTRUCTIONS */
+#define NL80211_MULTICAST_GROUP_CONFIG "config"
+#define NL80211_MULTICAST_GROUP_SCAN "scan"
+#define NL80211_MULTICAST_GROUP_REG "regulatory"
+#define NL80211_MULTICAST_GROUP_MLME "mlme"
+/* WARNING: DO NOT EDIT, AUTO-GENERATED CODE - SEE TOP FOR INSTRUCTIONS */
+#define NL80211_MULTICAST_GROUP_VENDOR "vendor"
+#define NL80211_MULTICAST_GROUP_TESTMODE "testmode"
 enum nl80211_commands {
   NL80211_CMD_UNSPEC,
+/* WARNING: DO NOT EDIT, AUTO-GENERATED CODE - SEE TOP FOR INSTRUCTIONS */
   NL80211_CMD_GET_WIPHY,
   NL80211_CMD_SET_WIPHY,
-/* WARNING: DO NOT EDIT, AUTO-GENERATED CODE - SEE TOP FOR INSTRUCTIONS */
   NL80211_CMD_NEW_WIPHY,
   NL80211_CMD_DEL_WIPHY,
+/* WARNING: DO NOT EDIT, AUTO-GENERATED CODE - SEE TOP FOR INSTRUCTIONS */
   NL80211_CMD_GET_INTERFACE,
   NL80211_CMD_SET_INTERFACE,
-/* WARNING: DO NOT EDIT, AUTO-GENERATED CODE - SEE TOP FOR INSTRUCTIONS */
   NL80211_CMD_NEW_INTERFACE,
   NL80211_CMD_DEL_INTERFACE,
+/* WARNING: DO NOT EDIT, AUTO-GENERATED CODE - SEE TOP FOR INSTRUCTIONS */
   NL80211_CMD_GET_KEY,
   NL80211_CMD_SET_KEY,
-/* WARNING: DO NOT EDIT, AUTO-GENERATED CODE - SEE TOP FOR INSTRUCTIONS */
   NL80211_CMD_NEW_KEY,
   NL80211_CMD_DEL_KEY,
+/* WARNING: DO NOT EDIT, AUTO-GENERATED CODE - SEE TOP FOR INSTRUCTIONS */
   NL80211_CMD_GET_BEACON,
   NL80211_CMD_SET_BEACON,
-/* WARNING: DO NOT EDIT, AUTO-GENERATED CODE - SEE TOP FOR INSTRUCTIONS */
   NL80211_CMD_START_AP,
   NL80211_CMD_NEW_BEACON = NL80211_CMD_START_AP,
+/* WARNING: DO NOT EDIT, AUTO-GENERATED CODE - SEE TOP FOR INSTRUCTIONS */
   NL80211_CMD_STOP_AP,
   NL80211_CMD_DEL_BEACON = NL80211_CMD_STOP_AP,
-/* WARNING: DO NOT EDIT, AUTO-GENERATED CODE - SEE TOP FOR INSTRUCTIONS */
   NL80211_CMD_GET_STATION,
   NL80211_CMD_SET_STATION,
+/* WARNING: DO NOT EDIT, AUTO-GENERATED CODE - SEE TOP FOR INSTRUCTIONS */
   NL80211_CMD_NEW_STATION,
   NL80211_CMD_DEL_STATION,
-/* WARNING: DO NOT EDIT, AUTO-GENERATED CODE - SEE TOP FOR INSTRUCTIONS */
   NL80211_CMD_GET_MPATH,
   NL80211_CMD_SET_MPATH,
+/* WARNING: DO NOT EDIT, AUTO-GENERATED CODE - SEE TOP FOR INSTRUCTIONS */
   NL80211_CMD_NEW_MPATH,
   NL80211_CMD_DEL_MPATH,
-/* WARNING: DO NOT EDIT, AUTO-GENERATED CODE - SEE TOP FOR INSTRUCTIONS */
   NL80211_CMD_SET_BSS,
   NL80211_CMD_SET_REG,
+/* WARNING: DO NOT EDIT, AUTO-GENERATED CODE - SEE TOP FOR INSTRUCTIONS */
   NL80211_CMD_REQ_SET_REG,
   NL80211_CMD_GET_MESH_CONFIG,
-/* WARNING: DO NOT EDIT, AUTO-GENERATED CODE - SEE TOP FOR INSTRUCTIONS */
   NL80211_CMD_SET_MESH_CONFIG,
   NL80211_CMD_SET_MGMT_EXTRA_IE,
+/* WARNING: DO NOT EDIT, AUTO-GENERATED CODE - SEE TOP FOR INSTRUCTIONS */
   NL80211_CMD_GET_REG,
   NL80211_CMD_GET_SCAN,
-/* WARNING: DO NOT EDIT, AUTO-GENERATED CODE - SEE TOP FOR INSTRUCTIONS */
   NL80211_CMD_TRIGGER_SCAN,
   NL80211_CMD_NEW_SCAN_RESULTS,
+/* WARNING: DO NOT EDIT, AUTO-GENERATED CODE - SEE TOP FOR INSTRUCTIONS */
   NL80211_CMD_SCAN_ABORTED,
   NL80211_CMD_REG_CHANGE,
-/* WARNING: DO NOT EDIT, AUTO-GENERATED CODE - SEE TOP FOR INSTRUCTIONS */
   NL80211_CMD_AUTHENTICATE,
   NL80211_CMD_ASSOCIATE,
+/* WARNING: DO NOT EDIT, AUTO-GENERATED CODE - SEE TOP FOR INSTRUCTIONS */
   NL80211_CMD_DEAUTHENTICATE,
   NL80211_CMD_DISASSOCIATE,
-/* WARNING: DO NOT EDIT, AUTO-GENERATED CODE - SEE TOP FOR INSTRUCTIONS */
   NL80211_CMD_MICHAEL_MIC_FAILURE,
   NL80211_CMD_REG_BEACON_HINT,
+/* WARNING: DO NOT EDIT, AUTO-GENERATED CODE - SEE TOP FOR INSTRUCTIONS */
   NL80211_CMD_JOIN_IBSS,
   NL80211_CMD_LEAVE_IBSS,
-/* WARNING: DO NOT EDIT, AUTO-GENERATED CODE - SEE TOP FOR INSTRUCTIONS */
   NL80211_CMD_TESTMODE,
   NL80211_CMD_CONNECT,
+/* WARNING: DO NOT EDIT, AUTO-GENERATED CODE - SEE TOP FOR INSTRUCTIONS */
   NL80211_CMD_ROAM,
   NL80211_CMD_DISCONNECT,
-/* WARNING: DO NOT EDIT, AUTO-GENERATED CODE - SEE TOP FOR INSTRUCTIONS */
   NL80211_CMD_SET_WIPHY_NETNS,
   NL80211_CMD_GET_SURVEY,
+/* WARNING: DO NOT EDIT, AUTO-GENERATED CODE - SEE TOP FOR INSTRUCTIONS */
   NL80211_CMD_NEW_SURVEY_RESULTS,
   NL80211_CMD_SET_PMKSA,
-/* WARNING: DO NOT EDIT, AUTO-GENERATED CODE - SEE TOP FOR INSTRUCTIONS */
   NL80211_CMD_DEL_PMKSA,
   NL80211_CMD_FLUSH_PMKSA,
+/* WARNING: DO NOT EDIT, AUTO-GENERATED CODE - SEE TOP FOR INSTRUCTIONS */
   NL80211_CMD_REMAIN_ON_CHANNEL,
   NL80211_CMD_CANCEL_REMAIN_ON_CHANNEL,
-/* WARNING: DO NOT EDIT, AUTO-GENERATED CODE - SEE TOP FOR INSTRUCTIONS */
   NL80211_CMD_SET_TX_BITRATE_MASK,
   NL80211_CMD_REGISTER_FRAME,
+/* WARNING: DO NOT EDIT, AUTO-GENERATED CODE - SEE TOP FOR INSTRUCTIONS */
   NL80211_CMD_REGISTER_ACTION = NL80211_CMD_REGISTER_FRAME,
   NL80211_CMD_FRAME,
-/* WARNING: DO NOT EDIT, AUTO-GENERATED CODE - SEE TOP FOR INSTRUCTIONS */
   NL80211_CMD_ACTION = NL80211_CMD_FRAME,
   NL80211_CMD_FRAME_TX_STATUS,
+/* WARNING: DO NOT EDIT, AUTO-GENERATED CODE - SEE TOP FOR INSTRUCTIONS */
   NL80211_CMD_ACTION_TX_STATUS = NL80211_CMD_FRAME_TX_STATUS,
   NL80211_CMD_SET_POWER_SAVE,
-/* WARNING: DO NOT EDIT, AUTO-GENERATED CODE - SEE TOP FOR INSTRUCTIONS */
   NL80211_CMD_GET_POWER_SAVE,
   NL80211_CMD_SET_CQM,
+/* WARNING: DO NOT EDIT, AUTO-GENERATED CODE - SEE TOP FOR INSTRUCTIONS */
   NL80211_CMD_NOTIFY_CQM,
   NL80211_CMD_SET_CHANNEL,
-/* WARNING: DO NOT EDIT, AUTO-GENERATED CODE - SEE TOP FOR INSTRUCTIONS */
   NL80211_CMD_SET_WDS_PEER,
   NL80211_CMD_FRAME_WAIT_CANCEL,
+/* WARNING: DO NOT EDIT, AUTO-GENERATED CODE - SEE TOP FOR INSTRUCTIONS */
   NL80211_CMD_JOIN_MESH,
   NL80211_CMD_LEAVE_MESH,
-/* WARNING: DO NOT EDIT, AUTO-GENERATED CODE - SEE TOP FOR INSTRUCTIONS */
   NL80211_CMD_UNPROT_DEAUTHENTICATE,
   NL80211_CMD_UNPROT_DISASSOCIATE,
+/* WARNING: DO NOT EDIT, AUTO-GENERATED CODE - SEE TOP FOR INSTRUCTIONS */
   NL80211_CMD_NEW_PEER_CANDIDATE,
   NL80211_CMD_GET_WOWLAN,
-/* WARNING: DO NOT EDIT, AUTO-GENERATED CODE - SEE TOP FOR INSTRUCTIONS */
   NL80211_CMD_SET_WOWLAN,
   NL80211_CMD_START_SCHED_SCAN,
+/* WARNING: DO NOT EDIT, AUTO-GENERATED CODE - SEE TOP FOR INSTRUCTIONS */
   NL80211_CMD_STOP_SCHED_SCAN,
   NL80211_CMD_SCHED_SCAN_RESULTS,
-/* WARNING: DO NOT EDIT, AUTO-GENERATED CODE - SEE TOP FOR INSTRUCTIONS */
   NL80211_CMD_SCHED_SCAN_STOPPED,
   NL80211_CMD_SET_REKEY_OFFLOAD,
+/* WARNING: DO NOT EDIT, AUTO-GENERATED CODE - SEE TOP FOR INSTRUCTIONS */
   NL80211_CMD_PMKSA_CANDIDATE,
   NL80211_CMD_TDLS_OPER,
-/* WARNING: DO NOT EDIT, AUTO-GENERATED CODE - SEE TOP FOR INSTRUCTIONS */
   NL80211_CMD_TDLS_MGMT,
   NL80211_CMD_UNEXPECTED_FRAME,
+/* WARNING: DO NOT EDIT, AUTO-GENERATED CODE - SEE TOP FOR INSTRUCTIONS */
   NL80211_CMD_PROBE_CLIENT,
   NL80211_CMD_REGISTER_BEACONS,
-/* WARNING: DO NOT EDIT, AUTO-GENERATED CODE - SEE TOP FOR INSTRUCTIONS */
   NL80211_CMD_UNEXPECTED_4ADDR_FRAME,
   NL80211_CMD_SET_NOACK_MAP,
+/* WARNING: DO NOT EDIT, AUTO-GENERATED CODE - SEE TOP FOR INSTRUCTIONS */
   NL80211_CMD_CH_SWITCH_NOTIFY,
   NL80211_CMD_START_P2P_DEVICE,
-/* WARNING: DO NOT EDIT, AUTO-GENERATED CODE - SEE TOP FOR INSTRUCTIONS */
   NL80211_CMD_STOP_P2P_DEVICE,
   NL80211_CMD_CONN_FAILED,
+/* WARNING: DO NOT EDIT, AUTO-GENERATED CODE - SEE TOP FOR INSTRUCTIONS */
   NL80211_CMD_SET_MCAST_RATE,
   NL80211_CMD_SET_MAC_ACL,
-/* WARNING: DO NOT EDIT, AUTO-GENERATED CODE - SEE TOP FOR INSTRUCTIONS */
   NL80211_CMD_RADAR_DETECT,
   NL80211_CMD_GET_PROTOCOL_FEATURES,
+/* WARNING: DO NOT EDIT, AUTO-GENERATED CODE - SEE TOP FOR INSTRUCTIONS */
   NL80211_CMD_UPDATE_FT_IES,
   NL80211_CMD_FT_EVENT,
-/* WARNING: DO NOT EDIT, AUTO-GENERATED CODE - SEE TOP FOR INSTRUCTIONS */
   NL80211_CMD_CRIT_PROTOCOL_START,
   NL80211_CMD_CRIT_PROTOCOL_STOP,
+/* WARNING: DO NOT EDIT, AUTO-GENERATED CODE - SEE TOP FOR INSTRUCTIONS */
   NL80211_CMD_GET_COALESCE,
   NL80211_CMD_SET_COALESCE,
-/* WARNING: DO NOT EDIT, AUTO-GENERATED CODE - SEE TOP FOR INSTRUCTIONS */
   NL80211_CMD_CHANNEL_SWITCH,
   NL80211_CMD_VENDOR,
+/* WARNING: DO NOT EDIT, AUTO-GENERATED CODE - SEE TOP FOR INSTRUCTIONS */
   NL80211_CMD_SET_QOS_MAP,
   NL80211_CMD_ADD_TX_TS,
-/* WARNING: DO NOT EDIT, AUTO-GENERATED CODE - SEE TOP FOR INSTRUCTIONS */
   NL80211_CMD_DEL_TX_TS,
+  NL80211_CMD_GET_MPP,
+/* WARNING: DO NOT EDIT, AUTO-GENERATED CODE - SEE TOP FOR INSTRUCTIONS */
+  NL80211_CMD_JOIN_OCB,
+  NL80211_CMD_LEAVE_OCB,
+  NL80211_CMD_CH_SWITCH_STARTED_NOTIFY,
+  NL80211_CMD_TDLS_CHANNEL_SWITCH,
+/* WARNING: DO NOT EDIT, AUTO-GENERATED CODE - SEE TOP FOR INSTRUCTIONS */
+  NL80211_CMD_TDLS_CANCEL_CHANNEL_SWITCH,
+  NL80211_CMD_WIPHY_REG_CHANGE,
   __NL80211_CMD_AFTER_LAST,
   NL80211_CMD_MAX = __NL80211_CMD_AFTER_LAST - 1
-};
 /* WARNING: DO NOT EDIT, AUTO-GENERATED CODE - SEE TOP FOR INSTRUCTIONS */
+};
 #define NL80211_CMD_SET_BSS NL80211_CMD_SET_BSS
 #define NL80211_CMD_SET_MGMT_EXTRA_IE NL80211_CMD_SET_MGMT_EXTRA_IE
 #define NL80211_CMD_REG_CHANGE NL80211_CMD_REG_CHANGE
-#define NL80211_CMD_AUTHENTICATE NL80211_CMD_AUTHENTICATE
 /* WARNING: DO NOT EDIT, AUTO-GENERATED CODE - SEE TOP FOR INSTRUCTIONS */
+#define NL80211_CMD_AUTHENTICATE NL80211_CMD_AUTHENTICATE
 #define NL80211_CMD_ASSOCIATE NL80211_CMD_ASSOCIATE
 #define NL80211_CMD_DEAUTHENTICATE NL80211_CMD_DEAUTHENTICATE
 #define NL80211_CMD_DISASSOCIATE NL80211_CMD_DISASSOCIATE
-#define NL80211_CMD_REG_BEACON_HINT NL80211_CMD_REG_BEACON_HINT
 /* WARNING: DO NOT EDIT, AUTO-GENERATED CODE - SEE TOP FOR INSTRUCTIONS */
+#define NL80211_CMD_REG_BEACON_HINT NL80211_CMD_REG_BEACON_HINT
 #define NL80211_ATTR_FEATURE_FLAGS NL80211_ATTR_FEATURE_FLAGS
 #define NL80211_CMD_GET_MESH_PARAMS NL80211_CMD_GET_MESH_CONFIG
 #define NL80211_CMD_SET_MESH_PARAMS NL80211_CMD_SET_MESH_CONFIG
-#define NL80211_MESH_SETUP_VENDOR_PATH_SEL_IE NL80211_MESH_SETUP_IE
 /* WARNING: DO NOT EDIT, AUTO-GENERATED CODE - SEE TOP FOR INSTRUCTIONS */
+#define NL80211_MESH_SETUP_VENDOR_PATH_SEL_IE NL80211_MESH_SETUP_IE
 enum nl80211_attrs {
   NL80211_ATTR_UNSPEC,
   NL80211_ATTR_WIPHY,
-  NL80211_ATTR_WIPHY_NAME,
 /* WARNING: DO NOT EDIT, AUTO-GENERATED CODE - SEE TOP FOR INSTRUCTIONS */
+  NL80211_ATTR_WIPHY_NAME,
   NL80211_ATTR_IFINDEX,
   NL80211_ATTR_IFNAME,
   NL80211_ATTR_IFTYPE,
-  NL80211_ATTR_MAC,
 /* WARNING: DO NOT EDIT, AUTO-GENERATED CODE - SEE TOP FOR INSTRUCTIONS */
+  NL80211_ATTR_MAC,
   NL80211_ATTR_KEY_DATA,
   NL80211_ATTR_KEY_IDX,
   NL80211_ATTR_KEY_CIPHER,
-  NL80211_ATTR_KEY_SEQ,
 /* WARNING: DO NOT EDIT, AUTO-GENERATED CODE - SEE TOP FOR INSTRUCTIONS */
+  NL80211_ATTR_KEY_SEQ,
   NL80211_ATTR_KEY_DEFAULT,
   NL80211_ATTR_BEACON_INTERVAL,
   NL80211_ATTR_DTIM_PERIOD,
-  NL80211_ATTR_BEACON_HEAD,
 /* WARNING: DO NOT EDIT, AUTO-GENERATED CODE - SEE TOP FOR INSTRUCTIONS */
+  NL80211_ATTR_BEACON_HEAD,
   NL80211_ATTR_BEACON_TAIL,
   NL80211_ATTR_STA_AID,
   NL80211_ATTR_STA_FLAGS,
-  NL80211_ATTR_STA_LISTEN_INTERVAL,
 /* WARNING: DO NOT EDIT, AUTO-GENERATED CODE - SEE TOP FOR INSTRUCTIONS */
+  NL80211_ATTR_STA_LISTEN_INTERVAL,
   NL80211_ATTR_STA_SUPPORTED_RATES,
   NL80211_ATTR_STA_VLAN,
   NL80211_ATTR_STA_INFO,
-  NL80211_ATTR_WIPHY_BANDS,
 /* WARNING: DO NOT EDIT, AUTO-GENERATED CODE - SEE TOP FOR INSTRUCTIONS */
+  NL80211_ATTR_WIPHY_BANDS,
   NL80211_ATTR_MNTR_FLAGS,
   NL80211_ATTR_MESH_ID,
   NL80211_ATTR_STA_PLINK_ACTION,
-  NL80211_ATTR_MPATH_NEXT_HOP,
 /* WARNING: DO NOT EDIT, AUTO-GENERATED CODE - SEE TOP FOR INSTRUCTIONS */
+  NL80211_ATTR_MPATH_NEXT_HOP,
   NL80211_ATTR_MPATH_INFO,
   NL80211_ATTR_BSS_CTS_PROT,
   NL80211_ATTR_BSS_SHORT_PREAMBLE,
-  NL80211_ATTR_BSS_SHORT_SLOT_TIME,
 /* WARNING: DO NOT EDIT, AUTO-GENERATED CODE - SEE TOP FOR INSTRUCTIONS */
+  NL80211_ATTR_BSS_SHORT_SLOT_TIME,
   NL80211_ATTR_HT_CAPABILITY,
   NL80211_ATTR_SUPPORTED_IFTYPES,
   NL80211_ATTR_REG_ALPHA2,
-  NL80211_ATTR_REG_RULES,
 /* WARNING: DO NOT EDIT, AUTO-GENERATED CODE - SEE TOP FOR INSTRUCTIONS */
+  NL80211_ATTR_REG_RULES,
   NL80211_ATTR_MESH_CONFIG,
   NL80211_ATTR_BSS_BASIC_RATES,
   NL80211_ATTR_WIPHY_TXQ_PARAMS,
-  NL80211_ATTR_WIPHY_FREQ,
 /* WARNING: DO NOT EDIT, AUTO-GENERATED CODE - SEE TOP FOR INSTRUCTIONS */
+  NL80211_ATTR_WIPHY_FREQ,
   NL80211_ATTR_WIPHY_CHANNEL_TYPE,
   NL80211_ATTR_KEY_DEFAULT_MGMT,
   NL80211_ATTR_MGMT_SUBTYPE,
-  NL80211_ATTR_IE,
 /* WARNING: DO NOT EDIT, AUTO-GENERATED CODE - SEE TOP FOR INSTRUCTIONS */
+  NL80211_ATTR_IE,
   NL80211_ATTR_MAX_NUM_SCAN_SSIDS,
   NL80211_ATTR_SCAN_FREQUENCIES,
   NL80211_ATTR_SCAN_SSIDS,
-  NL80211_ATTR_GENERATION,
 /* WARNING: DO NOT EDIT, AUTO-GENERATED CODE - SEE TOP FOR INSTRUCTIONS */
+  NL80211_ATTR_GENERATION,
   NL80211_ATTR_BSS,
   NL80211_ATTR_REG_INITIATOR,
   NL80211_ATTR_REG_TYPE,
-  NL80211_ATTR_SUPPORTED_COMMANDS,
 /* WARNING: DO NOT EDIT, AUTO-GENERATED CODE - SEE TOP FOR INSTRUCTIONS */
+  NL80211_ATTR_SUPPORTED_COMMANDS,
   NL80211_ATTR_FRAME,
   NL80211_ATTR_SSID,
   NL80211_ATTR_AUTH_TYPE,
-  NL80211_ATTR_REASON_CODE,
 /* WARNING: DO NOT EDIT, AUTO-GENERATED CODE - SEE TOP FOR INSTRUCTIONS */
+  NL80211_ATTR_REASON_CODE,
   NL80211_ATTR_KEY_TYPE,
   NL80211_ATTR_MAX_SCAN_IE_LEN,
   NL80211_ATTR_CIPHER_SUITES,
-  NL80211_ATTR_FREQ_BEFORE,
 /* WARNING: DO NOT EDIT, AUTO-GENERATED CODE - SEE TOP FOR INSTRUCTIONS */
+  NL80211_ATTR_FREQ_BEFORE,
   NL80211_ATTR_FREQ_AFTER,
   NL80211_ATTR_FREQ_FIXED,
   NL80211_ATTR_WIPHY_RETRY_SHORT,
-  NL80211_ATTR_WIPHY_RETRY_LONG,
 /* WARNING: DO NOT EDIT, AUTO-GENERATED CODE - SEE TOP FOR INSTRUCTIONS */
+  NL80211_ATTR_WIPHY_RETRY_LONG,
   NL80211_ATTR_WIPHY_FRAG_THRESHOLD,
   NL80211_ATTR_WIPHY_RTS_THRESHOLD,
   NL80211_ATTR_TIMED_OUT,
-  NL80211_ATTR_USE_MFP,
 /* WARNING: DO NOT EDIT, AUTO-GENERATED CODE - SEE TOP FOR INSTRUCTIONS */
+  NL80211_ATTR_USE_MFP,
   NL80211_ATTR_STA_FLAGS2,
   NL80211_ATTR_CONTROL_PORT,
   NL80211_ATTR_TESTDATA,
-  NL80211_ATTR_PRIVACY,
 /* WARNING: DO NOT EDIT, AUTO-GENERATED CODE - SEE TOP FOR INSTRUCTIONS */
+  NL80211_ATTR_PRIVACY,
   NL80211_ATTR_DISCONNECTED_BY_AP,
   NL80211_ATTR_STATUS_CODE,
   NL80211_ATTR_CIPHER_SUITES_PAIRWISE,
-  NL80211_ATTR_CIPHER_SUITE_GROUP,
 /* WARNING: DO NOT EDIT, AUTO-GENERATED CODE - SEE TOP FOR INSTRUCTIONS */
+  NL80211_ATTR_CIPHER_SUITE_GROUP,
   NL80211_ATTR_WPA_VERSIONS,
   NL80211_ATTR_AKM_SUITES,
   NL80211_ATTR_REQ_IE,
-  NL80211_ATTR_RESP_IE,
 /* WARNING: DO NOT EDIT, AUTO-GENERATED CODE - SEE TOP FOR INSTRUCTIONS */
+  NL80211_ATTR_RESP_IE,
   NL80211_ATTR_PREV_BSSID,
   NL80211_ATTR_KEY,
   NL80211_ATTR_KEYS,
-  NL80211_ATTR_PID,
 /* WARNING: DO NOT EDIT, AUTO-GENERATED CODE - SEE TOP FOR INSTRUCTIONS */
+  NL80211_ATTR_PID,
   NL80211_ATTR_4ADDR,
   NL80211_ATTR_SURVEY_INFO,
   NL80211_ATTR_PMKID,
-  NL80211_ATTR_MAX_NUM_PMKIDS,
 /* WARNING: DO NOT EDIT, AUTO-GENERATED CODE - SEE TOP FOR INSTRUCTIONS */
+  NL80211_ATTR_MAX_NUM_PMKIDS,
   NL80211_ATTR_DURATION,
   NL80211_ATTR_COOKIE,
   NL80211_ATTR_WIPHY_COVERAGE_CLASS,
-  NL80211_ATTR_TX_RATES,
 /* WARNING: DO NOT EDIT, AUTO-GENERATED CODE - SEE TOP FOR INSTRUCTIONS */
+  NL80211_ATTR_TX_RATES,
   NL80211_ATTR_FRAME_MATCH,
   NL80211_ATTR_ACK,
   NL80211_ATTR_PS_STATE,
-  NL80211_ATTR_CQM,
 /* WARNING: DO NOT EDIT, AUTO-GENERATED CODE - SEE TOP FOR INSTRUCTIONS */
+  NL80211_ATTR_CQM,
   NL80211_ATTR_LOCAL_STATE_CHANGE,
   NL80211_ATTR_AP_ISOLATE,
   NL80211_ATTR_WIPHY_TX_POWER_SETTING,
-  NL80211_ATTR_WIPHY_TX_POWER_LEVEL,
 /* WARNING: DO NOT EDIT, AUTO-GENERATED CODE - SEE TOP FOR INSTRUCTIONS */
+  NL80211_ATTR_WIPHY_TX_POWER_LEVEL,
   NL80211_ATTR_TX_FRAME_TYPES,
   NL80211_ATTR_RX_FRAME_TYPES,
   NL80211_ATTR_FRAME_TYPE,
-  NL80211_ATTR_CONTROL_PORT_ETHERTYPE,
 /* WARNING: DO NOT EDIT, AUTO-GENERATED CODE - SEE TOP FOR INSTRUCTIONS */
+  NL80211_ATTR_CONTROL_PORT_ETHERTYPE,
   NL80211_ATTR_CONTROL_PORT_NO_ENCRYPT,
   NL80211_ATTR_SUPPORT_IBSS_RSN,
   NL80211_ATTR_WIPHY_ANTENNA_TX,
-  NL80211_ATTR_WIPHY_ANTENNA_RX,
 /* WARNING: DO NOT EDIT, AUTO-GENERATED CODE - SEE TOP FOR INSTRUCTIONS */
+  NL80211_ATTR_WIPHY_ANTENNA_RX,
   NL80211_ATTR_MCAST_RATE,
   NL80211_ATTR_OFFCHANNEL_TX_OK,
   NL80211_ATTR_BSS_HT_OPMODE,
-  NL80211_ATTR_KEY_DEFAULT_TYPES,
 /* WARNING: DO NOT EDIT, AUTO-GENERATED CODE - SEE TOP FOR INSTRUCTIONS */
+  NL80211_ATTR_KEY_DEFAULT_TYPES,
   NL80211_ATTR_MAX_REMAIN_ON_CHANNEL_DURATION,
   NL80211_ATTR_MESH_SETUP,
   NL80211_ATTR_WIPHY_ANTENNA_AVAIL_TX,
-  NL80211_ATTR_WIPHY_ANTENNA_AVAIL_RX,
 /* WARNING: DO NOT EDIT, AUTO-GENERATED CODE - SEE TOP FOR INSTRUCTIONS */
+  NL80211_ATTR_WIPHY_ANTENNA_AVAIL_RX,
   NL80211_ATTR_SUPPORT_MESH_AUTH,
   NL80211_ATTR_STA_PLINK_STATE,
   NL80211_ATTR_WOWLAN_TRIGGERS,
-  NL80211_ATTR_WOWLAN_TRIGGERS_SUPPORTED,
 /* WARNING: DO NOT EDIT, AUTO-GENERATED CODE - SEE TOP FOR INSTRUCTIONS */
+  NL80211_ATTR_WOWLAN_TRIGGERS_SUPPORTED,
   NL80211_ATTR_SCHED_SCAN_INTERVAL,
   NL80211_ATTR_INTERFACE_COMBINATIONS,
   NL80211_ATTR_SOFTWARE_IFTYPES,
-  NL80211_ATTR_REKEY_DATA,
 /* WARNING: DO NOT EDIT, AUTO-GENERATED CODE - SEE TOP FOR INSTRUCTIONS */
+  NL80211_ATTR_REKEY_DATA,
   NL80211_ATTR_MAX_NUM_SCHED_SCAN_SSIDS,
   NL80211_ATTR_MAX_SCHED_SCAN_IE_LEN,
   NL80211_ATTR_SCAN_SUPP_RATES,
-  NL80211_ATTR_HIDDEN_SSID,
 /* WARNING: DO NOT EDIT, AUTO-GENERATED CODE - SEE TOP FOR INSTRUCTIONS */
+  NL80211_ATTR_HIDDEN_SSID,
   NL80211_ATTR_IE_PROBE_RESP,
   NL80211_ATTR_IE_ASSOC_RESP,
   NL80211_ATTR_STA_WME,
-  NL80211_ATTR_SUPPORT_AP_UAPSD,
 /* WARNING: DO NOT EDIT, AUTO-GENERATED CODE - SEE TOP FOR INSTRUCTIONS */
+  NL80211_ATTR_SUPPORT_AP_UAPSD,
   NL80211_ATTR_ROAM_SUPPORT,
   NL80211_ATTR_SCHED_SCAN_MATCH,
   NL80211_ATTR_MAX_MATCH_SETS,
-  NL80211_ATTR_PMKSA_CANDIDATE,
 /* WARNING: DO NOT EDIT, AUTO-GENERATED CODE - SEE TOP FOR INSTRUCTIONS */
+  NL80211_ATTR_PMKSA_CANDIDATE,
   NL80211_ATTR_TX_NO_CCK_RATE,
   NL80211_ATTR_TDLS_ACTION,
   NL80211_ATTR_TDLS_DIALOG_TOKEN,
-  NL80211_ATTR_TDLS_OPERATION,
 /* WARNING: DO NOT EDIT, AUTO-GENERATED CODE - SEE TOP FOR INSTRUCTIONS */
+  NL80211_ATTR_TDLS_OPERATION,
   NL80211_ATTR_TDLS_SUPPORT,
   NL80211_ATTR_TDLS_EXTERNAL_SETUP,
   NL80211_ATTR_DEVICE_AP_SME,
-  NL80211_ATTR_DONT_WAIT_FOR_ACK,
 /* WARNING: DO NOT EDIT, AUTO-GENERATED CODE - SEE TOP FOR INSTRUCTIONS */
+  NL80211_ATTR_DONT_WAIT_FOR_ACK,
   NL80211_ATTR_FEATURE_FLAGS,
   NL80211_ATTR_PROBE_RESP_OFFLOAD,
   NL80211_ATTR_PROBE_RESP,
-  NL80211_ATTR_DFS_REGION,
 /* WARNING: DO NOT EDIT, AUTO-GENERATED CODE - SEE TOP FOR INSTRUCTIONS */
+  NL80211_ATTR_DFS_REGION,
   NL80211_ATTR_DISABLE_HT,
   NL80211_ATTR_HT_CAPABILITY_MASK,
   NL80211_ATTR_NOACK_MAP,
-  NL80211_ATTR_INACTIVITY_TIMEOUT,
 /* WARNING: DO NOT EDIT, AUTO-GENERATED CODE - SEE TOP FOR INSTRUCTIONS */
+  NL80211_ATTR_INACTIVITY_TIMEOUT,
   NL80211_ATTR_RX_SIGNAL_DBM,
   NL80211_ATTR_BG_SCAN_PERIOD,
   NL80211_ATTR_WDEV,
-  NL80211_ATTR_USER_REG_HINT_TYPE,
 /* WARNING: DO NOT EDIT, AUTO-GENERATED CODE - SEE TOP FOR INSTRUCTIONS */
+  NL80211_ATTR_USER_REG_HINT_TYPE,
   NL80211_ATTR_CONN_FAILED_REASON,
   NL80211_ATTR_SAE_DATA,
   NL80211_ATTR_VHT_CAPABILITY,
-  NL80211_ATTR_SCAN_FLAGS,
 /* WARNING: DO NOT EDIT, AUTO-GENERATED CODE - SEE TOP FOR INSTRUCTIONS */
+  NL80211_ATTR_SCAN_FLAGS,
   NL80211_ATTR_CHANNEL_WIDTH,
   NL80211_ATTR_CENTER_FREQ1,
   NL80211_ATTR_CENTER_FREQ2,
-  NL80211_ATTR_P2P_CTWINDOW,
 /* WARNING: DO NOT EDIT, AUTO-GENERATED CODE - SEE TOP FOR INSTRUCTIONS */
+  NL80211_ATTR_P2P_CTWINDOW,
   NL80211_ATTR_P2P_OPPPS,
   NL80211_ATTR_LOCAL_MESH_POWER_MODE,
   NL80211_ATTR_ACL_POLICY,
-  NL80211_ATTR_MAC_ADDRS,
 /* WARNING: DO NOT EDIT, AUTO-GENERATED CODE - SEE TOP FOR INSTRUCTIONS */
+  NL80211_ATTR_MAC_ADDRS,
   NL80211_ATTR_MAC_ACL_MAX,
   NL80211_ATTR_RADAR_EVENT,
   NL80211_ATTR_EXT_CAPA,
-  NL80211_ATTR_EXT_CAPA_MASK,
 /* WARNING: DO NOT EDIT, AUTO-GENERATED CODE - SEE TOP FOR INSTRUCTIONS */
+  NL80211_ATTR_EXT_CAPA_MASK,
   NL80211_ATTR_STA_CAPABILITY,
   NL80211_ATTR_STA_EXT_CAPABILITY,
   NL80211_ATTR_PROTOCOL_FEATURES,
-  NL80211_ATTR_SPLIT_WIPHY_DUMP,
 /* WARNING: DO NOT EDIT, AUTO-GENERATED CODE - SEE TOP FOR INSTRUCTIONS */
+  NL80211_ATTR_SPLIT_WIPHY_DUMP,
   NL80211_ATTR_DISABLE_VHT,
   NL80211_ATTR_VHT_CAPABILITY_MASK,
   NL80211_ATTR_MDID,
-  NL80211_ATTR_IE_RIC,
 /* WARNING: DO NOT EDIT, AUTO-GENERATED CODE - SEE TOP FOR INSTRUCTIONS */
+  NL80211_ATTR_IE_RIC,
   NL80211_ATTR_CRIT_PROT_ID,
   NL80211_ATTR_MAX_CRIT_PROT_DURATION,
   NL80211_ATTR_PEER_AID,
-  NL80211_ATTR_COALESCE_RULE,
 /* WARNING: DO NOT EDIT, AUTO-GENERATED CODE - SEE TOP FOR INSTRUCTIONS */
+  NL80211_ATTR_COALESCE_RULE,
   NL80211_ATTR_CH_SWITCH_COUNT,
   NL80211_ATTR_CH_SWITCH_BLOCK_TX,
   NL80211_ATTR_CSA_IES,
-  NL80211_ATTR_CSA_C_OFF_BEACON,
 /* WARNING: DO NOT EDIT, AUTO-GENERATED CODE - SEE TOP FOR INSTRUCTIONS */
+  NL80211_ATTR_CSA_C_OFF_BEACON,
   NL80211_ATTR_CSA_C_OFF_PRESP,
   NL80211_ATTR_RXMGMT_FLAGS,
   NL80211_ATTR_STA_SUPPORTED_CHANNELS,
-  NL80211_ATTR_STA_SUPPORTED_OPER_CLASSES,
 /* WARNING: DO NOT EDIT, AUTO-GENERATED CODE - SEE TOP FOR INSTRUCTIONS */
+  NL80211_ATTR_STA_SUPPORTED_OPER_CLASSES,
   NL80211_ATTR_HANDLE_DFS,
   NL80211_ATTR_SUPPORT_5_MHZ,
   NL80211_ATTR_SUPPORT_10_MHZ,
-  NL80211_ATTR_OPMODE_NOTIF,
 /* WARNING: DO NOT EDIT, AUTO-GENERATED CODE - SEE TOP FOR INSTRUCTIONS */
+  NL80211_ATTR_OPMODE_NOTIF,
   NL80211_ATTR_VENDOR_ID,
   NL80211_ATTR_VENDOR_SUBCMD,
   NL80211_ATTR_VENDOR_DATA,
-  NL80211_ATTR_VENDOR_EVENTS,
 /* WARNING: DO NOT EDIT, AUTO-GENERATED CODE - SEE TOP FOR INSTRUCTIONS */
+  NL80211_ATTR_VENDOR_EVENTS,
   NL80211_ATTR_QOS_MAP,
   NL80211_ATTR_MAC_HINT,
   NL80211_ATTR_WIPHY_FREQ_HINT,
+/* WARNING: DO NOT EDIT, AUTO-GENERATED CODE - SEE TOP FOR INSTRUCTIONS */
   NL80211_ATTR_MAX_AP_ASSOC_STA,
-/* WARNING: DO NOT EDIT, AUTO-GENERATED CODE - SEE TOP FOR INSTRUCTIONS */
   NL80211_ATTR_TDLS_PEER_CAPABILITY,
-  NL80211_ATTR_IFACE_SOCKET_OWNER,
+  NL80211_ATTR_SOCKET_OWNER,
   NL80211_ATTR_CSA_C_OFFSETS_TX,
-  NL80211_ATTR_MAX_CSA_COUNTERS,
 /* WARNING: DO NOT EDIT, AUTO-GENERATED CODE - SEE TOP FOR INSTRUCTIONS */
+  NL80211_ATTR_MAX_CSA_COUNTERS,
   NL80211_ATTR_TDLS_INITIATOR,
   NL80211_ATTR_USE_RRM,
   NL80211_ATTR_WIPHY_DYN_ACK,
-  NL80211_ATTR_TSID,
 /* WARNING: DO NOT EDIT, AUTO-GENERATED CODE - SEE TOP FOR INSTRUCTIONS */
+  NL80211_ATTR_TSID,
   NL80211_ATTR_USER_PRIO,
   NL80211_ATTR_ADMITTED_TIME,
   NL80211_ATTR_SMPS_MODE,
-  __NL80211_ATTR_AFTER_LAST,
 /* WARNING: DO NOT EDIT, AUTO-GENERATED CODE - SEE TOP FOR INSTRUCTIONS */
+  NL80211_ATTR_OPER_CLASS,
+  NL80211_ATTR_MAC_MASK,
+  NL80211_ATTR_WIPHY_SELF_MANAGED_REG,
+  NL80211_ATTR_EXT_FEATURES,
+/* WARNING: DO NOT EDIT, AUTO-GENERATED CODE - SEE TOP FOR INSTRUCTIONS */
+  NL80211_ATTR_SURVEY_RADIO_STATS,
+  NL80211_ATTR_NETNS_FD,
+  NL80211_ATTR_SCHED_SCAN_DELAY,
+  NL80211_ATTR_REG_INDOOR,
+/* WARNING: DO NOT EDIT, AUTO-GENERATED CODE - SEE TOP FOR INSTRUCTIONS */
+  NL80211_ATTR_MAX_NUM_SCHED_SCAN_PLANS,
+  NL80211_ATTR_MAX_SCAN_PLAN_INTERVAL,
+  NL80211_ATTR_MAX_SCAN_PLAN_ITERATIONS,
+  NL80211_ATTR_SCHED_SCAN_PLANS,
+/* WARNING: DO NOT EDIT, AUTO-GENERATED CODE - SEE TOP FOR INSTRUCTIONS */
+  __NL80211_ATTR_AFTER_LAST,
+  NUM_NL80211_ATTR = __NL80211_ATTR_AFTER_LAST,
   NL80211_ATTR_MAX = __NL80211_ATTR_AFTER_LAST - 1
 };
+/* WARNING: DO NOT EDIT, AUTO-GENERATED CODE - SEE TOP FOR INSTRUCTIONS */
 #define NL80211_ATTR_SCAN_GENERATION NL80211_ATTR_GENERATION
 #define NL80211_ATTR_MESH_PARAMS NL80211_ATTR_MESH_CONFIG
-/* WARNING: DO NOT EDIT, AUTO-GENERATED CODE - SEE TOP FOR INSTRUCTIONS */
+#define NL80211_ATTR_IFACE_SOCKET_OWNER NL80211_ATTR_SOCKET_OWNER
 #define NL80211_CMD_CONNECT NL80211_CMD_CONNECT
+/* WARNING: DO NOT EDIT, AUTO-GENERATED CODE - SEE TOP FOR INSTRUCTIONS */
 #define NL80211_ATTR_HT_CAPABILITY NL80211_ATTR_HT_CAPABILITY
 #define NL80211_ATTR_BSS_BASIC_RATES NL80211_ATTR_BSS_BASIC_RATES
 #define NL80211_ATTR_WIPHY_TXQ_PARAMS NL80211_ATTR_WIPHY_TXQ_PARAMS
-/* WARNING: DO NOT EDIT, AUTO-GENERATED CODE - SEE TOP FOR INSTRUCTIONS */
 #define NL80211_ATTR_WIPHY_FREQ NL80211_ATTR_WIPHY_FREQ
+/* WARNING: DO NOT EDIT, AUTO-GENERATED CODE - SEE TOP FOR INSTRUCTIONS */
 #define NL80211_ATTR_WIPHY_CHANNEL_TYPE NL80211_ATTR_WIPHY_CHANNEL_TYPE
 #define NL80211_ATTR_MGMT_SUBTYPE NL80211_ATTR_MGMT_SUBTYPE
 #define NL80211_ATTR_IE NL80211_ATTR_IE
-/* WARNING: DO NOT EDIT, AUTO-GENERATED CODE - SEE TOP FOR INSTRUCTIONS */
 #define NL80211_ATTR_REG_INITIATOR NL80211_ATTR_REG_INITIATOR
+/* WARNING: DO NOT EDIT, AUTO-GENERATED CODE - SEE TOP FOR INSTRUCTIONS */
 #define NL80211_ATTR_REG_TYPE NL80211_ATTR_REG_TYPE
 #define NL80211_ATTR_FRAME NL80211_ATTR_FRAME
 #define NL80211_ATTR_SSID NL80211_ATTR_SSID
-/* WARNING: DO NOT EDIT, AUTO-GENERATED CODE - SEE TOP FOR INSTRUCTIONS */
 #define NL80211_ATTR_AUTH_TYPE NL80211_ATTR_AUTH_TYPE
+/* WARNING: DO NOT EDIT, AUTO-GENERATED CODE - SEE TOP FOR INSTRUCTIONS */
 #define NL80211_ATTR_REASON_CODE NL80211_ATTR_REASON_CODE
 #define NL80211_ATTR_CIPHER_SUITES_PAIRWISE NL80211_ATTR_CIPHER_SUITES_PAIRWISE
 #define NL80211_ATTR_CIPHER_SUITE_GROUP NL80211_ATTR_CIPHER_SUITE_GROUP
-/* WARNING: DO NOT EDIT, AUTO-GENERATED CODE - SEE TOP FOR INSTRUCTIONS */
 #define NL80211_ATTR_WPA_VERSIONS NL80211_ATTR_WPA_VERSIONS
+/* WARNING: DO NOT EDIT, AUTO-GENERATED CODE - SEE TOP FOR INSTRUCTIONS */
 #define NL80211_ATTR_AKM_SUITES NL80211_ATTR_AKM_SUITES
 #define NL80211_ATTR_KEY NL80211_ATTR_KEY
 #define NL80211_ATTR_KEYS NL80211_ATTR_KEYS
-/* WARNING: DO NOT EDIT, AUTO-GENERATED CODE - SEE TOP FOR INSTRUCTIONS */
 #define NL80211_ATTR_FEATURE_FLAGS NL80211_ATTR_FEATURE_FLAGS
+/* WARNING: DO NOT EDIT, AUTO-GENERATED CODE - SEE TOP FOR INSTRUCTIONS */
 #define NL80211_MAX_SUPP_RATES 32
 #define NL80211_MAX_SUPP_HT_RATES 77
-#define NL80211_MAX_SUPP_REG_RULES 32
-/* WARNING: DO NOT EDIT, AUTO-GENERATED CODE - SEE TOP FOR INSTRUCTIONS */
+#define NL80211_MAX_SUPP_REG_RULES 64
 #define NL80211_TKIP_DATA_OFFSET_ENCR_KEY 0
+/* WARNING: DO NOT EDIT, AUTO-GENERATED CODE - SEE TOP FOR INSTRUCTIONS */
 #define NL80211_TKIP_DATA_OFFSET_TX_MIC_KEY 16
 #define NL80211_TKIP_DATA_OFFSET_RX_MIC_KEY 24
 #define NL80211_HT_CAPABILITY_LEN 26
-/* WARNING: DO NOT EDIT, AUTO-GENERATED CODE - SEE TOP FOR INSTRUCTIONS */
 #define NL80211_VHT_CAPABILITY_LEN 12
+/* WARNING: DO NOT EDIT, AUTO-GENERATED CODE - SEE TOP FOR INSTRUCTIONS */
 #define NL80211_MAX_NR_CIPHER_SUITES 5
 #define NL80211_MAX_NR_AKM_SUITES 2
 #define NL80211_MIN_REMAIN_ON_CHANNEL_TIME 10
-/* WARNING: DO NOT EDIT, AUTO-GENERATED CODE - SEE TOP FOR INSTRUCTIONS */
 #define NL80211_SCAN_RSSI_THOLD_OFF - 300
+/* WARNING: DO NOT EDIT, AUTO-GENERATED CODE - SEE TOP FOR INSTRUCTIONS */
 #define NL80211_CQM_TXE_MAX_INTVL 1800
 enum nl80211_iftype {
   NL80211_IFTYPE_UNSPECIFIED,
-/* WARNING: DO NOT EDIT, AUTO-GENERATED CODE - SEE TOP FOR INSTRUCTIONS */
   NL80211_IFTYPE_ADHOC,
+/* WARNING: DO NOT EDIT, AUTO-GENERATED CODE - SEE TOP FOR INSTRUCTIONS */
   NL80211_IFTYPE_STATION,
   NL80211_IFTYPE_AP,
   NL80211_IFTYPE_AP_VLAN,
-/* WARNING: DO NOT EDIT, AUTO-GENERATED CODE - SEE TOP FOR INSTRUCTIONS */
   NL80211_IFTYPE_WDS,
+/* WARNING: DO NOT EDIT, AUTO-GENERATED CODE - SEE TOP FOR INSTRUCTIONS */
   NL80211_IFTYPE_MONITOR,
   NL80211_IFTYPE_MESH_POINT,
   NL80211_IFTYPE_P2P_CLIENT,
-/* WARNING: DO NOT EDIT, AUTO-GENERATED CODE - SEE TOP FOR INSTRUCTIONS */
   NL80211_IFTYPE_P2P_GO,
+/* WARNING: DO NOT EDIT, AUTO-GENERATED CODE - SEE TOP FOR INSTRUCTIONS */
   NL80211_IFTYPE_P2P_DEVICE,
+  NL80211_IFTYPE_OCB,
   NUM_NL80211_IFTYPES,
   NL80211_IFTYPE_MAX = NUM_NL80211_IFTYPES - 1
 /* WARNING: DO NOT EDIT, AUTO-GENERATED CODE - SEE TOP FOR INSTRUCTIONS */
@@ -553,136 +588,156 @@
 /* WARNING: DO NOT EDIT, AUTO-GENERATED CODE - SEE TOP FOR INSTRUCTIONS */
   NL80211_RATE_INFO_80P80_MHZ_WIDTH,
   NL80211_RATE_INFO_160_MHZ_WIDTH,
+  NL80211_RATE_INFO_10_MHZ_WIDTH,
+  NL80211_RATE_INFO_5_MHZ_WIDTH,
+/* WARNING: DO NOT EDIT, AUTO-GENERATED CODE - SEE TOP FOR INSTRUCTIONS */
   __NL80211_RATE_INFO_AFTER_LAST,
   NL80211_RATE_INFO_MAX = __NL80211_RATE_INFO_AFTER_LAST - 1
-/* WARNING: DO NOT EDIT, AUTO-GENERATED CODE - SEE TOP FOR INSTRUCTIONS */
 };
 enum nl80211_sta_bss_param {
+/* WARNING: DO NOT EDIT, AUTO-GENERATED CODE - SEE TOP FOR INSTRUCTIONS */
   __NL80211_STA_BSS_PARAM_INVALID,
   NL80211_STA_BSS_PARAM_CTS_PROT,
-/* WARNING: DO NOT EDIT, AUTO-GENERATED CODE - SEE TOP FOR INSTRUCTIONS */
   NL80211_STA_BSS_PARAM_SHORT_PREAMBLE,
   NL80211_STA_BSS_PARAM_SHORT_SLOT_TIME,
+/* WARNING: DO NOT EDIT, AUTO-GENERATED CODE - SEE TOP FOR INSTRUCTIONS */
   NL80211_STA_BSS_PARAM_DTIM_PERIOD,
   NL80211_STA_BSS_PARAM_BEACON_INTERVAL,
-/* WARNING: DO NOT EDIT, AUTO-GENERATED CODE - SEE TOP FOR INSTRUCTIONS */
   __NL80211_STA_BSS_PARAM_AFTER_LAST,
   NL80211_STA_BSS_PARAM_MAX = __NL80211_STA_BSS_PARAM_AFTER_LAST - 1
+/* WARNING: DO NOT EDIT, AUTO-GENERATED CODE - SEE TOP FOR INSTRUCTIONS */
 };
 enum nl80211_sta_info {
-/* WARNING: DO NOT EDIT, AUTO-GENERATED CODE - SEE TOP FOR INSTRUCTIONS */
   __NL80211_STA_INFO_INVALID,
   NL80211_STA_INFO_INACTIVE_TIME,
+/* WARNING: DO NOT EDIT, AUTO-GENERATED CODE - SEE TOP FOR INSTRUCTIONS */
   NL80211_STA_INFO_RX_BYTES,
   NL80211_STA_INFO_TX_BYTES,
-/* WARNING: DO NOT EDIT, AUTO-GENERATED CODE - SEE TOP FOR INSTRUCTIONS */
   NL80211_STA_INFO_LLID,
   NL80211_STA_INFO_PLID,
+/* WARNING: DO NOT EDIT, AUTO-GENERATED CODE - SEE TOP FOR INSTRUCTIONS */
   NL80211_STA_INFO_PLINK_STATE,
   NL80211_STA_INFO_SIGNAL,
-/* WARNING: DO NOT EDIT, AUTO-GENERATED CODE - SEE TOP FOR INSTRUCTIONS */
   NL80211_STA_INFO_TX_BITRATE,
   NL80211_STA_INFO_RX_PACKETS,
+/* WARNING: DO NOT EDIT, AUTO-GENERATED CODE - SEE TOP FOR INSTRUCTIONS */
   NL80211_STA_INFO_TX_PACKETS,
   NL80211_STA_INFO_TX_RETRIES,
-/* WARNING: DO NOT EDIT, AUTO-GENERATED CODE - SEE TOP FOR INSTRUCTIONS */
   NL80211_STA_INFO_TX_FAILED,
   NL80211_STA_INFO_SIGNAL_AVG,
+/* WARNING: DO NOT EDIT, AUTO-GENERATED CODE - SEE TOP FOR INSTRUCTIONS */
   NL80211_STA_INFO_RX_BITRATE,
   NL80211_STA_INFO_BSS_PARAM,
-/* WARNING: DO NOT EDIT, AUTO-GENERATED CODE - SEE TOP FOR INSTRUCTIONS */
   NL80211_STA_INFO_CONNECTED_TIME,
   NL80211_STA_INFO_STA_FLAGS,
+/* WARNING: DO NOT EDIT, AUTO-GENERATED CODE - SEE TOP FOR INSTRUCTIONS */
   NL80211_STA_INFO_BEACON_LOSS,
   NL80211_STA_INFO_T_OFFSET,
-/* WARNING: DO NOT EDIT, AUTO-GENERATED CODE - SEE TOP FOR INSTRUCTIONS */
   NL80211_STA_INFO_LOCAL_PM,
   NL80211_STA_INFO_PEER_PM,
+/* WARNING: DO NOT EDIT, AUTO-GENERATED CODE - SEE TOP FOR INSTRUCTIONS */
   NL80211_STA_INFO_NONPEER_PM,
   NL80211_STA_INFO_RX_BYTES64,
-/* WARNING: DO NOT EDIT, AUTO-GENERATED CODE - SEE TOP FOR INSTRUCTIONS */
   NL80211_STA_INFO_TX_BYTES64,
   NL80211_STA_INFO_CHAIN_SIGNAL,
+/* WARNING: DO NOT EDIT, AUTO-GENERATED CODE - SEE TOP FOR INSTRUCTIONS */
   NL80211_STA_INFO_CHAIN_SIGNAL_AVG,
   NL80211_STA_INFO_EXPECTED_THROUGHPUT,
+  NL80211_STA_INFO_RX_DROP_MISC,
+  NL80211_STA_INFO_BEACON_RX,
 /* WARNING: DO NOT EDIT, AUTO-GENERATED CODE - SEE TOP FOR INSTRUCTIONS */
+  NL80211_STA_INFO_BEACON_SIGNAL_AVG,
+  NL80211_STA_INFO_TID_STATS,
   __NL80211_STA_INFO_AFTER_LAST,
   NL80211_STA_INFO_MAX = __NL80211_STA_INFO_AFTER_LAST - 1
+/* WARNING: DO NOT EDIT, AUTO-GENERATED CODE - SEE TOP FOR INSTRUCTIONS */
+};
+enum nl80211_tid_stats {
+  __NL80211_TID_STATS_INVALID,
+  NL80211_TID_STATS_RX_MSDU,
+/* WARNING: DO NOT EDIT, AUTO-GENERATED CODE - SEE TOP FOR INSTRUCTIONS */
+  NL80211_TID_STATS_TX_MSDU,
+  NL80211_TID_STATS_TX_MSDU_RETRIES,
+  NL80211_TID_STATS_TX_MSDU_FAILED,
+  NUM_NL80211_TID_STATS,
+/* WARNING: DO NOT EDIT, AUTO-GENERATED CODE - SEE TOP FOR INSTRUCTIONS */
+  NL80211_TID_STATS_MAX = NUM_NL80211_TID_STATS - 1
 };
 enum nl80211_mpath_flags {
-/* WARNING: DO NOT EDIT, AUTO-GENERATED CODE - SEE TOP FOR INSTRUCTIONS */
   NL80211_MPATH_FLAG_ACTIVE = 1 << 0,
+/* WARNING: DO NOT EDIT, AUTO-GENERATED CODE - SEE TOP FOR INSTRUCTIONS */
   NL80211_MPATH_FLAG_RESOLVING = 1 << 1,
   NL80211_MPATH_FLAG_SN_VALID = 1 << 2,
   NL80211_MPATH_FLAG_FIXED = 1 << 3,
-/* WARNING: DO NOT EDIT, AUTO-GENERATED CODE - SEE TOP FOR INSTRUCTIONS */
   NL80211_MPATH_FLAG_RESOLVED = 1 << 4,
+/* WARNING: DO NOT EDIT, AUTO-GENERATED CODE - SEE TOP FOR INSTRUCTIONS */
 };
 enum nl80211_mpath_info {
   __NL80211_MPATH_INFO_INVALID,
-/* WARNING: DO NOT EDIT, AUTO-GENERATED CODE - SEE TOP FOR INSTRUCTIONS */
   NL80211_MPATH_INFO_FRAME_QLEN,
+/* WARNING: DO NOT EDIT, AUTO-GENERATED CODE - SEE TOP FOR INSTRUCTIONS */
   NL80211_MPATH_INFO_SN,
   NL80211_MPATH_INFO_METRIC,
   NL80211_MPATH_INFO_EXPTIME,
-/* WARNING: DO NOT EDIT, AUTO-GENERATED CODE - SEE TOP FOR INSTRUCTIONS */
   NL80211_MPATH_INFO_FLAGS,
+/* WARNING: DO NOT EDIT, AUTO-GENERATED CODE - SEE TOP FOR INSTRUCTIONS */
   NL80211_MPATH_INFO_DISCOVERY_TIMEOUT,
   NL80211_MPATH_INFO_DISCOVERY_RETRIES,
   __NL80211_MPATH_INFO_AFTER_LAST,
-/* WARNING: DO NOT EDIT, AUTO-GENERATED CODE - SEE TOP FOR INSTRUCTIONS */
   NL80211_MPATH_INFO_MAX = __NL80211_MPATH_INFO_AFTER_LAST - 1
+/* WARNING: DO NOT EDIT, AUTO-GENERATED CODE - SEE TOP FOR INSTRUCTIONS */
 };
 enum nl80211_band_attr {
   __NL80211_BAND_ATTR_INVALID,
-/* WARNING: DO NOT EDIT, AUTO-GENERATED CODE - SEE TOP FOR INSTRUCTIONS */
   NL80211_BAND_ATTR_FREQS,
+/* WARNING: DO NOT EDIT, AUTO-GENERATED CODE - SEE TOP FOR INSTRUCTIONS */
   NL80211_BAND_ATTR_RATES,
   NL80211_BAND_ATTR_HT_MCS_SET,
   NL80211_BAND_ATTR_HT_CAPA,
-/* WARNING: DO NOT EDIT, AUTO-GENERATED CODE - SEE TOP FOR INSTRUCTIONS */
   NL80211_BAND_ATTR_HT_AMPDU_FACTOR,
+/* WARNING: DO NOT EDIT, AUTO-GENERATED CODE - SEE TOP FOR INSTRUCTIONS */
   NL80211_BAND_ATTR_HT_AMPDU_DENSITY,
   NL80211_BAND_ATTR_VHT_MCS_SET,
   NL80211_BAND_ATTR_VHT_CAPA,
-/* WARNING: DO NOT EDIT, AUTO-GENERATED CODE - SEE TOP FOR INSTRUCTIONS */
   __NL80211_BAND_ATTR_AFTER_LAST,
+/* WARNING: DO NOT EDIT, AUTO-GENERATED CODE - SEE TOP FOR INSTRUCTIONS */
   NL80211_BAND_ATTR_MAX = __NL80211_BAND_ATTR_AFTER_LAST - 1
 };
 #define NL80211_BAND_ATTR_HT_CAPA NL80211_BAND_ATTR_HT_CAPA
-/* WARNING: DO NOT EDIT, AUTO-GENERATED CODE - SEE TOP FOR INSTRUCTIONS */
 enum nl80211_frequency_attr {
+/* WARNING: DO NOT EDIT, AUTO-GENERATED CODE - SEE TOP FOR INSTRUCTIONS */
   __NL80211_FREQUENCY_ATTR_INVALID,
   NL80211_FREQUENCY_ATTR_FREQ,
   NL80211_FREQUENCY_ATTR_DISABLED,
-/* WARNING: DO NOT EDIT, AUTO-GENERATED CODE - SEE TOP FOR INSTRUCTIONS */
   NL80211_FREQUENCY_ATTR_NO_IR,
+/* WARNING: DO NOT EDIT, AUTO-GENERATED CODE - SEE TOP FOR INSTRUCTIONS */
   __NL80211_FREQUENCY_ATTR_NO_IBSS,
   NL80211_FREQUENCY_ATTR_RADAR,
   NL80211_FREQUENCY_ATTR_MAX_TX_POWER,
-/* WARNING: DO NOT EDIT, AUTO-GENERATED CODE - SEE TOP FOR INSTRUCTIONS */
   NL80211_FREQUENCY_ATTR_DFS_STATE,
+/* WARNING: DO NOT EDIT, AUTO-GENERATED CODE - SEE TOP FOR INSTRUCTIONS */
   NL80211_FREQUENCY_ATTR_DFS_TIME,
   NL80211_FREQUENCY_ATTR_NO_HT40_MINUS,
   NL80211_FREQUENCY_ATTR_NO_HT40_PLUS,
-/* WARNING: DO NOT EDIT, AUTO-GENERATED CODE - SEE TOP FOR INSTRUCTIONS */
   NL80211_FREQUENCY_ATTR_NO_80MHZ,
+/* WARNING: DO NOT EDIT, AUTO-GENERATED CODE - SEE TOP FOR INSTRUCTIONS */
   NL80211_FREQUENCY_ATTR_NO_160MHZ,
   NL80211_FREQUENCY_ATTR_DFS_CAC_TIME,
   NL80211_FREQUENCY_ATTR_INDOOR_ONLY,
+  NL80211_FREQUENCY_ATTR_IR_CONCURRENT,
 /* WARNING: DO NOT EDIT, AUTO-GENERATED CODE - SEE TOP FOR INSTRUCTIONS */
-  NL80211_FREQUENCY_ATTR_GO_CONCURRENT,
   NL80211_FREQUENCY_ATTR_NO_20MHZ,
   NL80211_FREQUENCY_ATTR_NO_10MHZ,
   __NL80211_FREQUENCY_ATTR_AFTER_LAST,
-/* WARNING: DO NOT EDIT, AUTO-GENERATED CODE - SEE TOP FOR INSTRUCTIONS */
   NL80211_FREQUENCY_ATTR_MAX = __NL80211_FREQUENCY_ATTR_AFTER_LAST - 1
+/* WARNING: DO NOT EDIT, AUTO-GENERATED CODE - SEE TOP FOR INSTRUCTIONS */
 };
 #define NL80211_FREQUENCY_ATTR_MAX_TX_POWER NL80211_FREQUENCY_ATTR_MAX_TX_POWER
 #define NL80211_FREQUENCY_ATTR_PASSIVE_SCAN NL80211_FREQUENCY_ATTR_NO_IR
-/* WARNING: DO NOT EDIT, AUTO-GENERATED CODE - SEE TOP FOR INSTRUCTIONS */
 #define NL80211_FREQUENCY_ATTR_NO_IBSS NL80211_FREQUENCY_ATTR_NO_IR
+/* WARNING: DO NOT EDIT, AUTO-GENERATED CODE - SEE TOP FOR INSTRUCTIONS */
 #define NL80211_FREQUENCY_ATTR_NO_IR NL80211_FREQUENCY_ATTR_NO_IR
+#define NL80211_FREQUENCY_ATTR_GO_CONCURRENT NL80211_FREQUENCY_ATTR_IR_CONCURRENT
 enum nl80211_bitrate_attr {
   __NL80211_BITRATE_ATTR_INVALID,
 /* WARNING: DO NOT EDIT, AUTO-GENERATED CODE - SEE TOP FOR INSTRUCTIONS */
@@ -746,554 +801,589 @@
   __NL80211_RRF_NO_IBSS = 1 << 8,
   NL80211_RRF_AUTO_BW = 1 << 11,
 /* WARNING: DO NOT EDIT, AUTO-GENERATED CODE - SEE TOP FOR INSTRUCTIONS */
+  NL80211_RRF_IR_CONCURRENT = 1 << 12,
+  NL80211_RRF_NO_HT40MINUS = 1 << 13,
+  NL80211_RRF_NO_HT40PLUS = 1 << 14,
+  NL80211_RRF_NO_80MHZ = 1 << 15,
+/* WARNING: DO NOT EDIT, AUTO-GENERATED CODE - SEE TOP FOR INSTRUCTIONS */
+  NL80211_RRF_NO_160MHZ = 1 << 16,
 };
 #define NL80211_RRF_PASSIVE_SCAN NL80211_RRF_NO_IR
 #define NL80211_RRF_NO_IBSS NL80211_RRF_NO_IR
-#define NL80211_RRF_NO_IR NL80211_RRF_NO_IR
 /* WARNING: DO NOT EDIT, AUTO-GENERATED CODE - SEE TOP FOR INSTRUCTIONS */
+#define NL80211_RRF_NO_IR NL80211_RRF_NO_IR
+#define NL80211_RRF_NO_HT40 (NL80211_RRF_NO_HT40MINUS | NL80211_RRF_NO_HT40PLUS)
+#define NL80211_RRF_GO_CONCURRENT NL80211_RRF_IR_CONCURRENT
 #define NL80211_RRF_NO_IR_ALL (NL80211_RRF_NO_IR | __NL80211_RRF_NO_IBSS)
+/* WARNING: DO NOT EDIT, AUTO-GENERATED CODE - SEE TOP FOR INSTRUCTIONS */
 enum nl80211_dfs_regions {
   NL80211_DFS_UNSET = 0,
   NL80211_DFS_FCC = 1,
-/* WARNING: DO NOT EDIT, AUTO-GENERATED CODE - SEE TOP FOR INSTRUCTIONS */
   NL80211_DFS_ETSI = 2,
+/* WARNING: DO NOT EDIT, AUTO-GENERATED CODE - SEE TOP FOR INSTRUCTIONS */
   NL80211_DFS_JP = 3,
 };
 enum nl80211_user_reg_hint_type {
-/* WARNING: DO NOT EDIT, AUTO-GENERATED CODE - SEE TOP FOR INSTRUCTIONS */
   NL80211_USER_REG_HINT_USER = 0,
+/* WARNING: DO NOT EDIT, AUTO-GENERATED CODE - SEE TOP FOR INSTRUCTIONS */
   NL80211_USER_REG_HINT_CELL_BASE = 1,
   NL80211_USER_REG_HINT_INDOOR = 2,
 };
-/* WARNING: DO NOT EDIT, AUTO-GENERATED CODE - SEE TOP FOR INSTRUCTIONS */
 enum nl80211_survey_info {
+/* WARNING: DO NOT EDIT, AUTO-GENERATED CODE - SEE TOP FOR INSTRUCTIONS */
   __NL80211_SURVEY_INFO_INVALID,
   NL80211_SURVEY_INFO_FREQUENCY,
   NL80211_SURVEY_INFO_NOISE,
-/* WARNING: DO NOT EDIT, AUTO-GENERATED CODE - SEE TOP FOR INSTRUCTIONS */
   NL80211_SURVEY_INFO_IN_USE,
-  NL80211_SURVEY_INFO_CHANNEL_TIME,
-  NL80211_SURVEY_INFO_CHANNEL_TIME_BUSY,
-  NL80211_SURVEY_INFO_CHANNEL_TIME_EXT_BUSY,
 /* WARNING: DO NOT EDIT, AUTO-GENERATED CODE - SEE TOP FOR INSTRUCTIONS */
-  NL80211_SURVEY_INFO_CHANNEL_TIME_RX,
-  NL80211_SURVEY_INFO_CHANNEL_TIME_TX,
+  NL80211_SURVEY_INFO_TIME,
+  NL80211_SURVEY_INFO_TIME_BUSY,
+  NL80211_SURVEY_INFO_TIME_EXT_BUSY,
+  NL80211_SURVEY_INFO_TIME_RX,
+/* WARNING: DO NOT EDIT, AUTO-GENERATED CODE - SEE TOP FOR INSTRUCTIONS */
+  NL80211_SURVEY_INFO_TIME_TX,
+  NL80211_SURVEY_INFO_TIME_SCAN,
   __NL80211_SURVEY_INFO_AFTER_LAST,
   NL80211_SURVEY_INFO_MAX = __NL80211_SURVEY_INFO_AFTER_LAST - 1
 /* WARNING: DO NOT EDIT, AUTO-GENERATED CODE - SEE TOP FOR INSTRUCTIONS */
 };
+#define NL80211_SURVEY_INFO_CHANNEL_TIME NL80211_SURVEY_INFO_TIME
+#define NL80211_SURVEY_INFO_CHANNEL_TIME_BUSY NL80211_SURVEY_INFO_TIME_BUSY
+#define NL80211_SURVEY_INFO_CHANNEL_TIME_EXT_BUSY NL80211_SURVEY_INFO_TIME_EXT_BUSY
+/* WARNING: DO NOT EDIT, AUTO-GENERATED CODE - SEE TOP FOR INSTRUCTIONS */
+#define NL80211_SURVEY_INFO_CHANNEL_TIME_RX NL80211_SURVEY_INFO_TIME_RX
+#define NL80211_SURVEY_INFO_CHANNEL_TIME_TX NL80211_SURVEY_INFO_TIME_TX
 enum nl80211_mntr_flags {
   __NL80211_MNTR_FLAG_INVALID,
-  NL80211_MNTR_FLAG_FCSFAIL,
 /* WARNING: DO NOT EDIT, AUTO-GENERATED CODE - SEE TOP FOR INSTRUCTIONS */
+  NL80211_MNTR_FLAG_FCSFAIL,
   NL80211_MNTR_FLAG_PLCPFAIL,
   NL80211_MNTR_FLAG_CONTROL,
   NL80211_MNTR_FLAG_OTHER_BSS,
-  NL80211_MNTR_FLAG_COOK_FRAMES,
 /* WARNING: DO NOT EDIT, AUTO-GENERATED CODE - SEE TOP FOR INSTRUCTIONS */
+  NL80211_MNTR_FLAG_COOK_FRAMES,
   NL80211_MNTR_FLAG_ACTIVE,
   __NL80211_MNTR_FLAG_AFTER_LAST,
   NL80211_MNTR_FLAG_MAX = __NL80211_MNTR_FLAG_AFTER_LAST - 1
-};
 /* WARNING: DO NOT EDIT, AUTO-GENERATED CODE - SEE TOP FOR INSTRUCTIONS */
+};
 enum nl80211_mesh_power_mode {
   NL80211_MESH_POWER_UNKNOWN,
   NL80211_MESH_POWER_ACTIVE,
-  NL80211_MESH_POWER_LIGHT_SLEEP,
 /* WARNING: DO NOT EDIT, AUTO-GENERATED CODE - SEE TOP FOR INSTRUCTIONS */
+  NL80211_MESH_POWER_LIGHT_SLEEP,
   NL80211_MESH_POWER_DEEP_SLEEP,
   __NL80211_MESH_POWER_AFTER_LAST,
   NL80211_MESH_POWER_MAX = __NL80211_MESH_POWER_AFTER_LAST - 1
-};
 /* WARNING: DO NOT EDIT, AUTO-GENERATED CODE - SEE TOP FOR INSTRUCTIONS */
+};
 enum nl80211_meshconf_params {
   __NL80211_MESHCONF_INVALID,
   NL80211_MESHCONF_RETRY_TIMEOUT,
-  NL80211_MESHCONF_CONFIRM_TIMEOUT,
 /* WARNING: DO NOT EDIT, AUTO-GENERATED CODE - SEE TOP FOR INSTRUCTIONS */
+  NL80211_MESHCONF_CONFIRM_TIMEOUT,
   NL80211_MESHCONF_HOLDING_TIMEOUT,
   NL80211_MESHCONF_MAX_PEER_LINKS,
   NL80211_MESHCONF_MAX_RETRIES,
-  NL80211_MESHCONF_TTL,
 /* WARNING: DO NOT EDIT, AUTO-GENERATED CODE - SEE TOP FOR INSTRUCTIONS */
+  NL80211_MESHCONF_TTL,
   NL80211_MESHCONF_AUTO_OPEN_PLINKS,
   NL80211_MESHCONF_HWMP_MAX_PREQ_RETRIES,
   NL80211_MESHCONF_PATH_REFRESH_TIME,
-  NL80211_MESHCONF_MIN_DISCOVERY_TIMEOUT,
 /* WARNING: DO NOT EDIT, AUTO-GENERATED CODE - SEE TOP FOR INSTRUCTIONS */
+  NL80211_MESHCONF_MIN_DISCOVERY_TIMEOUT,
   NL80211_MESHCONF_HWMP_ACTIVE_PATH_TIMEOUT,
   NL80211_MESHCONF_HWMP_PREQ_MIN_INTERVAL,
   NL80211_MESHCONF_HWMP_NET_DIAM_TRVS_TIME,
-  NL80211_MESHCONF_HWMP_ROOTMODE,
 /* WARNING: DO NOT EDIT, AUTO-GENERATED CODE - SEE TOP FOR INSTRUCTIONS */
+  NL80211_MESHCONF_HWMP_ROOTMODE,
   NL80211_MESHCONF_ELEMENT_TTL,
   NL80211_MESHCONF_HWMP_RANN_INTERVAL,
   NL80211_MESHCONF_GATE_ANNOUNCEMENTS,
-  NL80211_MESHCONF_HWMP_PERR_MIN_INTERVAL,
 /* WARNING: DO NOT EDIT, AUTO-GENERATED CODE - SEE TOP FOR INSTRUCTIONS */
+  NL80211_MESHCONF_HWMP_PERR_MIN_INTERVAL,
   NL80211_MESHCONF_FORWARDING,
   NL80211_MESHCONF_RSSI_THRESHOLD,
   NL80211_MESHCONF_SYNC_OFFSET_MAX_NEIGHBOR,
-  NL80211_MESHCONF_HT_OPMODE,
 /* WARNING: DO NOT EDIT, AUTO-GENERATED CODE - SEE TOP FOR INSTRUCTIONS */
+  NL80211_MESHCONF_HT_OPMODE,
   NL80211_MESHCONF_HWMP_PATH_TO_ROOT_TIMEOUT,
   NL80211_MESHCONF_HWMP_ROOT_INTERVAL,
   NL80211_MESHCONF_HWMP_CONFIRMATION_INTERVAL,
-  NL80211_MESHCONF_POWER_MODE,
 /* WARNING: DO NOT EDIT, AUTO-GENERATED CODE - SEE TOP FOR INSTRUCTIONS */
+  NL80211_MESHCONF_POWER_MODE,
   NL80211_MESHCONF_AWAKE_WINDOW,
   NL80211_MESHCONF_PLINK_TIMEOUT,
   __NL80211_MESHCONF_ATTR_AFTER_LAST,
-  NL80211_MESHCONF_ATTR_MAX = __NL80211_MESHCONF_ATTR_AFTER_LAST - 1
 /* WARNING: DO NOT EDIT, AUTO-GENERATED CODE - SEE TOP FOR INSTRUCTIONS */
+  NL80211_MESHCONF_ATTR_MAX = __NL80211_MESHCONF_ATTR_AFTER_LAST - 1
 };
 enum nl80211_mesh_setup_params {
   __NL80211_MESH_SETUP_INVALID,
-  NL80211_MESH_SETUP_ENABLE_VENDOR_PATH_SEL,
 /* WARNING: DO NOT EDIT, AUTO-GENERATED CODE - SEE TOP FOR INSTRUCTIONS */
+  NL80211_MESH_SETUP_ENABLE_VENDOR_PATH_SEL,
   NL80211_MESH_SETUP_ENABLE_VENDOR_METRIC,
   NL80211_MESH_SETUP_IE,
   NL80211_MESH_SETUP_USERSPACE_AUTH,
-  NL80211_MESH_SETUP_USERSPACE_AMPE,
 /* WARNING: DO NOT EDIT, AUTO-GENERATED CODE - SEE TOP FOR INSTRUCTIONS */
+  NL80211_MESH_SETUP_USERSPACE_AMPE,
   NL80211_MESH_SETUP_ENABLE_VENDOR_SYNC,
   NL80211_MESH_SETUP_USERSPACE_MPM,
   NL80211_MESH_SETUP_AUTH_PROTOCOL,
-  __NL80211_MESH_SETUP_ATTR_AFTER_LAST,
 /* WARNING: DO NOT EDIT, AUTO-GENERATED CODE - SEE TOP FOR INSTRUCTIONS */
+  __NL80211_MESH_SETUP_ATTR_AFTER_LAST,
   NL80211_MESH_SETUP_ATTR_MAX = __NL80211_MESH_SETUP_ATTR_AFTER_LAST - 1
 };
 enum nl80211_txq_attr {
-  __NL80211_TXQ_ATTR_INVALID,
 /* WARNING: DO NOT EDIT, AUTO-GENERATED CODE - SEE TOP FOR INSTRUCTIONS */
+  __NL80211_TXQ_ATTR_INVALID,
   NL80211_TXQ_ATTR_AC,
   NL80211_TXQ_ATTR_TXOP,
   NL80211_TXQ_ATTR_CWMIN,
-  NL80211_TXQ_ATTR_CWMAX,
 /* WARNING: DO NOT EDIT, AUTO-GENERATED CODE - SEE TOP FOR INSTRUCTIONS */
+  NL80211_TXQ_ATTR_CWMAX,
   NL80211_TXQ_ATTR_AIFS,
   __NL80211_TXQ_ATTR_AFTER_LAST,
   NL80211_TXQ_ATTR_MAX = __NL80211_TXQ_ATTR_AFTER_LAST - 1
-};
 /* WARNING: DO NOT EDIT, AUTO-GENERATED CODE - SEE TOP FOR INSTRUCTIONS */
+};
 enum nl80211_ac {
   NL80211_AC_VO,
   NL80211_AC_VI,
-  NL80211_AC_BE,
 /* WARNING: DO NOT EDIT, AUTO-GENERATED CODE - SEE TOP FOR INSTRUCTIONS */
+  NL80211_AC_BE,
   NL80211_AC_BK,
   NL80211_NUM_ACS
 };
-#define NL80211_TXQ_ATTR_QUEUE NL80211_TXQ_ATTR_AC
 /* WARNING: DO NOT EDIT, AUTO-GENERATED CODE - SEE TOP FOR INSTRUCTIONS */
+#define NL80211_TXQ_ATTR_QUEUE NL80211_TXQ_ATTR_AC
 #define NL80211_TXQ_Q_VO NL80211_AC_VO
 #define NL80211_TXQ_Q_VI NL80211_AC_VI
 #define NL80211_TXQ_Q_BE NL80211_AC_BE
-#define NL80211_TXQ_Q_BK NL80211_AC_BK
 /* WARNING: DO NOT EDIT, AUTO-GENERATED CODE - SEE TOP FOR INSTRUCTIONS */
+#define NL80211_TXQ_Q_BK NL80211_AC_BK
 enum nl80211_channel_type {
   NL80211_CHAN_NO_HT,
   NL80211_CHAN_HT20,
-  NL80211_CHAN_HT40MINUS,
 /* WARNING: DO NOT EDIT, AUTO-GENERATED CODE - SEE TOP FOR INSTRUCTIONS */
+  NL80211_CHAN_HT40MINUS,
   NL80211_CHAN_HT40PLUS
 };
 enum nl80211_chan_width {
-  NL80211_CHAN_WIDTH_20_NOHT,
 /* WARNING: DO NOT EDIT, AUTO-GENERATED CODE - SEE TOP FOR INSTRUCTIONS */
+  NL80211_CHAN_WIDTH_20_NOHT,
   NL80211_CHAN_WIDTH_20,
   NL80211_CHAN_WIDTH_40,
   NL80211_CHAN_WIDTH_80,
-  NL80211_CHAN_WIDTH_80P80,
 /* WARNING: DO NOT EDIT, AUTO-GENERATED CODE - SEE TOP FOR INSTRUCTIONS */
+  NL80211_CHAN_WIDTH_80P80,
   NL80211_CHAN_WIDTH_160,
   NL80211_CHAN_WIDTH_5,
   NL80211_CHAN_WIDTH_10,
-};
 /* WARNING: DO NOT EDIT, AUTO-GENERATED CODE - SEE TOP FOR INSTRUCTIONS */
+};
 enum nl80211_bss_scan_width {
   NL80211_BSS_CHAN_WIDTH_20,
   NL80211_BSS_CHAN_WIDTH_10,
-  NL80211_BSS_CHAN_WIDTH_5,
 /* WARNING: DO NOT EDIT, AUTO-GENERATED CODE - SEE TOP FOR INSTRUCTIONS */
+  NL80211_BSS_CHAN_WIDTH_5,
 };
 enum nl80211_bss {
   __NL80211_BSS_INVALID,
-  NL80211_BSS_BSSID,
 /* WARNING: DO NOT EDIT, AUTO-GENERATED CODE - SEE TOP FOR INSTRUCTIONS */
+  NL80211_BSS_BSSID,
   NL80211_BSS_FREQUENCY,
   NL80211_BSS_TSF,
   NL80211_BSS_BEACON_INTERVAL,
-  NL80211_BSS_CAPABILITY,
 /* WARNING: DO NOT EDIT, AUTO-GENERATED CODE - SEE TOP FOR INSTRUCTIONS */
+  NL80211_BSS_CAPABILITY,
   NL80211_BSS_INFORMATION_ELEMENTS,
   NL80211_BSS_SIGNAL_MBM,
   NL80211_BSS_SIGNAL_UNSPEC,
-  NL80211_BSS_STATUS,
 /* WARNING: DO NOT EDIT, AUTO-GENERATED CODE - SEE TOP FOR INSTRUCTIONS */
+  NL80211_BSS_STATUS,
   NL80211_BSS_SEEN_MS_AGO,
   NL80211_BSS_BEACON_IES,
   NL80211_BSS_CHAN_WIDTH,
-  NL80211_BSS_BEACON_TSF,
 /* WARNING: DO NOT EDIT, AUTO-GENERATED CODE - SEE TOP FOR INSTRUCTIONS */
+  NL80211_BSS_BEACON_TSF,
   NL80211_BSS_PRESP_DATA,
+  NL80211_BSS_LAST_SEEN_BOOTTIME,
   __NL80211_BSS_AFTER_LAST,
+/* WARNING: DO NOT EDIT, AUTO-GENERATED CODE - SEE TOP FOR INSTRUCTIONS */
   NL80211_BSS_MAX = __NL80211_BSS_AFTER_LAST - 1
 };
-/* WARNING: DO NOT EDIT, AUTO-GENERATED CODE - SEE TOP FOR INSTRUCTIONS */
 enum nl80211_bss_status {
   NL80211_BSS_STATUS_AUTHENTICATED,
+/* WARNING: DO NOT EDIT, AUTO-GENERATED CODE - SEE TOP FOR INSTRUCTIONS */
   NL80211_BSS_STATUS_ASSOCIATED,
   NL80211_BSS_STATUS_IBSS_JOINED,
-/* WARNING: DO NOT EDIT, AUTO-GENERATED CODE - SEE TOP FOR INSTRUCTIONS */
 };
 enum nl80211_auth_type {
+/* WARNING: DO NOT EDIT, AUTO-GENERATED CODE - SEE TOP FOR INSTRUCTIONS */
   NL80211_AUTHTYPE_OPEN_SYSTEM,
   NL80211_AUTHTYPE_SHARED_KEY,
-/* WARNING: DO NOT EDIT, AUTO-GENERATED CODE - SEE TOP FOR INSTRUCTIONS */
   NL80211_AUTHTYPE_FT,
   NL80211_AUTHTYPE_NETWORK_EAP,
+/* WARNING: DO NOT EDIT, AUTO-GENERATED CODE - SEE TOP FOR INSTRUCTIONS */
   NL80211_AUTHTYPE_SAE,
   __NL80211_AUTHTYPE_NUM,
-/* WARNING: DO NOT EDIT, AUTO-GENERATED CODE - SEE TOP FOR INSTRUCTIONS */
   NL80211_AUTHTYPE_MAX = __NL80211_AUTHTYPE_NUM - 1,
   NL80211_AUTHTYPE_AUTOMATIC
+/* WARNING: DO NOT EDIT, AUTO-GENERATED CODE - SEE TOP FOR INSTRUCTIONS */
 };
 enum nl80211_key_type {
-/* WARNING: DO NOT EDIT, AUTO-GENERATED CODE - SEE TOP FOR INSTRUCTIONS */
   NL80211_KEYTYPE_GROUP,
   NL80211_KEYTYPE_PAIRWISE,
+/* WARNING: DO NOT EDIT, AUTO-GENERATED CODE - SEE TOP FOR INSTRUCTIONS */
   NL80211_KEYTYPE_PEERKEY,
   NUM_NL80211_KEYTYPES
-/* WARNING: DO NOT EDIT, AUTO-GENERATED CODE - SEE TOP FOR INSTRUCTIONS */
 };
 enum nl80211_mfp {
+/* WARNING: DO NOT EDIT, AUTO-GENERATED CODE - SEE TOP FOR INSTRUCTIONS */
   NL80211_MFP_NO,
   NL80211_MFP_REQUIRED,
-/* WARNING: DO NOT EDIT, AUTO-GENERATED CODE - SEE TOP FOR INSTRUCTIONS */
 };
 enum nl80211_wpa_versions {
+/* WARNING: DO NOT EDIT, AUTO-GENERATED CODE - SEE TOP FOR INSTRUCTIONS */
   NL80211_WPA_VERSION_1 = 1 << 0,
   NL80211_WPA_VERSION_2 = 1 << 1,
-/* WARNING: DO NOT EDIT, AUTO-GENERATED CODE - SEE TOP FOR INSTRUCTIONS */
 };
 enum nl80211_key_default_types {
+/* WARNING: DO NOT EDIT, AUTO-GENERATED CODE - SEE TOP FOR INSTRUCTIONS */
   __NL80211_KEY_DEFAULT_TYPE_INVALID,
   NL80211_KEY_DEFAULT_TYPE_UNICAST,
-/* WARNING: DO NOT EDIT, AUTO-GENERATED CODE - SEE TOP FOR INSTRUCTIONS */
   NL80211_KEY_DEFAULT_TYPE_MULTICAST,
   NUM_NL80211_KEY_DEFAULT_TYPES
+/* WARNING: DO NOT EDIT, AUTO-GENERATED CODE - SEE TOP FOR INSTRUCTIONS */
 };
 enum nl80211_key_attributes {
-/* WARNING: DO NOT EDIT, AUTO-GENERATED CODE - SEE TOP FOR INSTRUCTIONS */
   __NL80211_KEY_INVALID,
   NL80211_KEY_DATA,
+/* WARNING: DO NOT EDIT, AUTO-GENERATED CODE - SEE TOP FOR INSTRUCTIONS */
   NL80211_KEY_IDX,
   NL80211_KEY_CIPHER,
-/* WARNING: DO NOT EDIT, AUTO-GENERATED CODE - SEE TOP FOR INSTRUCTIONS */
   NL80211_KEY_SEQ,
   NL80211_KEY_DEFAULT,
+/* WARNING: DO NOT EDIT, AUTO-GENERATED CODE - SEE TOP FOR INSTRUCTIONS */
   NL80211_KEY_DEFAULT_MGMT,
   NL80211_KEY_TYPE,
-/* WARNING: DO NOT EDIT, AUTO-GENERATED CODE - SEE TOP FOR INSTRUCTIONS */
   NL80211_KEY_DEFAULT_TYPES,
   __NL80211_KEY_AFTER_LAST,
+/* WARNING: DO NOT EDIT, AUTO-GENERATED CODE - SEE TOP FOR INSTRUCTIONS */
   NL80211_KEY_MAX = __NL80211_KEY_AFTER_LAST - 1
 };
-/* WARNING: DO NOT EDIT, AUTO-GENERATED CODE - SEE TOP FOR INSTRUCTIONS */
 enum nl80211_tx_rate_attributes {
   __NL80211_TXRATE_INVALID,
+/* WARNING: DO NOT EDIT, AUTO-GENERATED CODE - SEE TOP FOR INSTRUCTIONS */
   NL80211_TXRATE_LEGACY,
   NL80211_TXRATE_HT,
-/* WARNING: DO NOT EDIT, AUTO-GENERATED CODE - SEE TOP FOR INSTRUCTIONS */
   NL80211_TXRATE_VHT,
   NL80211_TXRATE_GI,
+/* WARNING: DO NOT EDIT, AUTO-GENERATED CODE - SEE TOP FOR INSTRUCTIONS */
   __NL80211_TXRATE_AFTER_LAST,
   NL80211_TXRATE_MAX = __NL80211_TXRATE_AFTER_LAST - 1
-/* WARNING: DO NOT EDIT, AUTO-GENERATED CODE - SEE TOP FOR INSTRUCTIONS */
 };
 #define NL80211_TXRATE_MCS NL80211_TXRATE_HT
+/* WARNING: DO NOT EDIT, AUTO-GENERATED CODE - SEE TOP FOR INSTRUCTIONS */
 #define NL80211_VHT_NSS_MAX 8
 struct nl80211_txrate_vht {
-/* WARNING: DO NOT EDIT, AUTO-GENERATED CODE - SEE TOP FOR INSTRUCTIONS */
   __u16 mcs[NL80211_VHT_NSS_MAX];
 };
+/* WARNING: DO NOT EDIT, AUTO-GENERATED CODE - SEE TOP FOR INSTRUCTIONS */
 enum nl80211_txrate_gi {
   NL80211_TXRATE_DEFAULT_GI,
-/* WARNING: DO NOT EDIT, AUTO-GENERATED CODE - SEE TOP FOR INSTRUCTIONS */
   NL80211_TXRATE_FORCE_SGI,
   NL80211_TXRATE_FORCE_LGI,
+/* WARNING: DO NOT EDIT, AUTO-GENERATED CODE - SEE TOP FOR INSTRUCTIONS */
 };
 enum nl80211_band {
-/* WARNING: DO NOT EDIT, AUTO-GENERATED CODE - SEE TOP FOR INSTRUCTIONS */
   NL80211_BAND_2GHZ,
   NL80211_BAND_5GHZ,
+/* WARNING: DO NOT EDIT, AUTO-GENERATED CODE - SEE TOP FOR INSTRUCTIONS */
   NL80211_BAND_60GHZ,
 };
-/* WARNING: DO NOT EDIT, AUTO-GENERATED CODE - SEE TOP FOR INSTRUCTIONS */
 enum nl80211_ps_state {
   NL80211_PS_DISABLED,
+/* WARNING: DO NOT EDIT, AUTO-GENERATED CODE - SEE TOP FOR INSTRUCTIONS */
   NL80211_PS_ENABLED,
 };
-/* WARNING: DO NOT EDIT, AUTO-GENERATED CODE - SEE TOP FOR INSTRUCTIONS */
 enum nl80211_attr_cqm {
   __NL80211_ATTR_CQM_INVALID,
+/* WARNING: DO NOT EDIT, AUTO-GENERATED CODE - SEE TOP FOR INSTRUCTIONS */
   NL80211_ATTR_CQM_RSSI_THOLD,
   NL80211_ATTR_CQM_RSSI_HYST,
-/* WARNING: DO NOT EDIT, AUTO-GENERATED CODE - SEE TOP FOR INSTRUCTIONS */
   NL80211_ATTR_CQM_RSSI_THRESHOLD_EVENT,
   NL80211_ATTR_CQM_PKT_LOSS_EVENT,
+/* WARNING: DO NOT EDIT, AUTO-GENERATED CODE - SEE TOP FOR INSTRUCTIONS */
   NL80211_ATTR_CQM_TXE_RATE,
   NL80211_ATTR_CQM_TXE_PKTS,
-/* WARNING: DO NOT EDIT, AUTO-GENERATED CODE - SEE TOP FOR INSTRUCTIONS */
   NL80211_ATTR_CQM_TXE_INTVL,
+  NL80211_ATTR_CQM_BEACON_LOSS_EVENT,
+/* WARNING: DO NOT EDIT, AUTO-GENERATED CODE - SEE TOP FOR INSTRUCTIONS */
   __NL80211_ATTR_CQM_AFTER_LAST,
   NL80211_ATTR_CQM_MAX = __NL80211_ATTR_CQM_AFTER_LAST - 1
 };
-/* WARNING: DO NOT EDIT, AUTO-GENERATED CODE - SEE TOP FOR INSTRUCTIONS */
 enum nl80211_cqm_rssi_threshold_event {
+/* WARNING: DO NOT EDIT, AUTO-GENERATED CODE - SEE TOP FOR INSTRUCTIONS */
   NL80211_CQM_RSSI_THRESHOLD_EVENT_LOW,
   NL80211_CQM_RSSI_THRESHOLD_EVENT_HIGH,
   NL80211_CQM_RSSI_BEACON_LOSS_EVENT,
-/* WARNING: DO NOT EDIT, AUTO-GENERATED CODE - SEE TOP FOR INSTRUCTIONS */
 };
+/* WARNING: DO NOT EDIT, AUTO-GENERATED CODE - SEE TOP FOR INSTRUCTIONS */
 enum nl80211_tx_power_setting {
   NL80211_TX_POWER_AUTOMATIC,
   NL80211_TX_POWER_LIMITED,
-/* WARNING: DO NOT EDIT, AUTO-GENERATED CODE - SEE TOP FOR INSTRUCTIONS */
   NL80211_TX_POWER_FIXED,
+/* WARNING: DO NOT EDIT, AUTO-GENERATED CODE - SEE TOP FOR INSTRUCTIONS */
 };
 enum nl80211_packet_pattern_attr {
   __NL80211_PKTPAT_INVALID,
-/* WARNING: DO NOT EDIT, AUTO-GENERATED CODE - SEE TOP FOR INSTRUCTIONS */
   NL80211_PKTPAT_MASK,
+/* WARNING: DO NOT EDIT, AUTO-GENERATED CODE - SEE TOP FOR INSTRUCTIONS */
   NL80211_PKTPAT_PATTERN,
   NL80211_PKTPAT_OFFSET,
   NUM_NL80211_PKTPAT,
-/* WARNING: DO NOT EDIT, AUTO-GENERATED CODE - SEE TOP FOR INSTRUCTIONS */
   MAX_NL80211_PKTPAT = NUM_NL80211_PKTPAT - 1,
+/* WARNING: DO NOT EDIT, AUTO-GENERATED CODE - SEE TOP FOR INSTRUCTIONS */
 };
 struct nl80211_pattern_support {
   __u32 max_patterns;
-/* WARNING: DO NOT EDIT, AUTO-GENERATED CODE - SEE TOP FOR INSTRUCTIONS */
   __u32 min_pattern_len;
+/* WARNING: DO NOT EDIT, AUTO-GENERATED CODE - SEE TOP FOR INSTRUCTIONS */
   __u32 max_pattern_len;
   __u32 max_pkt_offset;
 } __attribute__((packed));
-/* WARNING: DO NOT EDIT, AUTO-GENERATED CODE - SEE TOP FOR INSTRUCTIONS */
 #define __NL80211_WOWLAN_PKTPAT_INVALID __NL80211_PKTPAT_INVALID
+/* WARNING: DO NOT EDIT, AUTO-GENERATED CODE - SEE TOP FOR INSTRUCTIONS */
 #define NL80211_WOWLAN_PKTPAT_MASK NL80211_PKTPAT_MASK
 #define NL80211_WOWLAN_PKTPAT_PATTERN NL80211_PKTPAT_PATTERN
 #define NL80211_WOWLAN_PKTPAT_OFFSET NL80211_PKTPAT_OFFSET
-/* WARNING: DO NOT EDIT, AUTO-GENERATED CODE - SEE TOP FOR INSTRUCTIONS */
 #define NUM_NL80211_WOWLAN_PKTPAT NUM_NL80211_PKTPAT
+/* WARNING: DO NOT EDIT, AUTO-GENERATED CODE - SEE TOP FOR INSTRUCTIONS */
 #define MAX_NL80211_WOWLAN_PKTPAT MAX_NL80211_PKTPAT
 #define nl80211_wowlan_pattern_support nl80211_pattern_support
 enum nl80211_wowlan_triggers {
-/* WARNING: DO NOT EDIT, AUTO-GENERATED CODE - SEE TOP FOR INSTRUCTIONS */
   __NL80211_WOWLAN_TRIG_INVALID,
+/* WARNING: DO NOT EDIT, AUTO-GENERATED CODE - SEE TOP FOR INSTRUCTIONS */
   NL80211_WOWLAN_TRIG_ANY,
   NL80211_WOWLAN_TRIG_DISCONNECT,
   NL80211_WOWLAN_TRIG_MAGIC_PKT,
-/* WARNING: DO NOT EDIT, AUTO-GENERATED CODE - SEE TOP FOR INSTRUCTIONS */
   NL80211_WOWLAN_TRIG_PKT_PATTERN,
+/* WARNING: DO NOT EDIT, AUTO-GENERATED CODE - SEE TOP FOR INSTRUCTIONS */
   NL80211_WOWLAN_TRIG_GTK_REKEY_SUPPORTED,
   NL80211_WOWLAN_TRIG_GTK_REKEY_FAILURE,
   NL80211_WOWLAN_TRIG_EAP_IDENT_REQUEST,
-/* WARNING: DO NOT EDIT, AUTO-GENERATED CODE - SEE TOP FOR INSTRUCTIONS */
   NL80211_WOWLAN_TRIG_4WAY_HANDSHAKE,
+/* WARNING: DO NOT EDIT, AUTO-GENERATED CODE - SEE TOP FOR INSTRUCTIONS */
   NL80211_WOWLAN_TRIG_RFKILL_RELEASE,
   NL80211_WOWLAN_TRIG_WAKEUP_PKT_80211,
   NL80211_WOWLAN_TRIG_WAKEUP_PKT_80211_LEN,
-/* WARNING: DO NOT EDIT, AUTO-GENERATED CODE - SEE TOP FOR INSTRUCTIONS */
   NL80211_WOWLAN_TRIG_WAKEUP_PKT_8023,
+/* WARNING: DO NOT EDIT, AUTO-GENERATED CODE - SEE TOP FOR INSTRUCTIONS */
   NL80211_WOWLAN_TRIG_WAKEUP_PKT_8023_LEN,
   NL80211_WOWLAN_TRIG_TCP_CONNECTION,
   NL80211_WOWLAN_TRIG_WAKEUP_TCP_MATCH,
-/* WARNING: DO NOT EDIT, AUTO-GENERATED CODE - SEE TOP FOR INSTRUCTIONS */
   NL80211_WOWLAN_TRIG_WAKEUP_TCP_CONNLOST,
-  NL80211_WOWLAN_TRIG_WAKEUP_TCP_NOMORETOKENS,
-  NUM_NL80211_WOWLAN_TRIG,
-  MAX_NL80211_WOWLAN_TRIG = NUM_NL80211_WOWLAN_TRIG - 1
 /* WARNING: DO NOT EDIT, AUTO-GENERATED CODE - SEE TOP FOR INSTRUCTIONS */
+  NL80211_WOWLAN_TRIG_WAKEUP_TCP_NOMORETOKENS,
+  NL80211_WOWLAN_TRIG_NET_DETECT,
+  NL80211_WOWLAN_TRIG_NET_DETECT_RESULTS,
+  NUM_NL80211_WOWLAN_TRIG,
+/* WARNING: DO NOT EDIT, AUTO-GENERATED CODE - SEE TOP FOR INSTRUCTIONS */
+  MAX_NL80211_WOWLAN_TRIG = NUM_NL80211_WOWLAN_TRIG - 1
 };
 struct nl80211_wowlan_tcp_data_seq {
   __u32 start, offset, len;
-};
 /* WARNING: DO NOT EDIT, AUTO-GENERATED CODE - SEE TOP FOR INSTRUCTIONS */
+};
 struct nl80211_wowlan_tcp_data_token {
   __u32 offset, len;
   __u8 token_stream[];
-};
 /* WARNING: DO NOT EDIT, AUTO-GENERATED CODE - SEE TOP FOR INSTRUCTIONS */
+};
 struct nl80211_wowlan_tcp_data_token_feature {
   __u32 min_len, max_len, bufsize;
 };
-enum nl80211_wowlan_tcp_attrs {
 /* WARNING: DO NOT EDIT, AUTO-GENERATED CODE - SEE TOP FOR INSTRUCTIONS */
+enum nl80211_wowlan_tcp_attrs {
   __NL80211_WOWLAN_TCP_INVALID,
   NL80211_WOWLAN_TCP_SRC_IPV4,
   NL80211_WOWLAN_TCP_DST_IPV4,
-  NL80211_WOWLAN_TCP_DST_MAC,
 /* WARNING: DO NOT EDIT, AUTO-GENERATED CODE - SEE TOP FOR INSTRUCTIONS */
+  NL80211_WOWLAN_TCP_DST_MAC,
   NL80211_WOWLAN_TCP_SRC_PORT,
   NL80211_WOWLAN_TCP_DST_PORT,
   NL80211_WOWLAN_TCP_DATA_PAYLOAD,
-  NL80211_WOWLAN_TCP_DATA_PAYLOAD_SEQ,
 /* WARNING: DO NOT EDIT, AUTO-GENERATED CODE - SEE TOP FOR INSTRUCTIONS */
+  NL80211_WOWLAN_TCP_DATA_PAYLOAD_SEQ,
   NL80211_WOWLAN_TCP_DATA_PAYLOAD_TOKEN,
   NL80211_WOWLAN_TCP_DATA_INTERVAL,
   NL80211_WOWLAN_TCP_WAKE_PAYLOAD,
-  NL80211_WOWLAN_TCP_WAKE_MASK,
 /* WARNING: DO NOT EDIT, AUTO-GENERATED CODE - SEE TOP FOR INSTRUCTIONS */
+  NL80211_WOWLAN_TCP_WAKE_MASK,
   NUM_NL80211_WOWLAN_TCP,
   MAX_NL80211_WOWLAN_TCP = NUM_NL80211_WOWLAN_TCP - 1
 };
-struct nl80211_coalesce_rule_support {
 /* WARNING: DO NOT EDIT, AUTO-GENERATED CODE - SEE TOP FOR INSTRUCTIONS */
+struct nl80211_coalesce_rule_support {
   __u32 max_rules;
   struct nl80211_pattern_support pat;
   __u32 max_delay;
-} __attribute__((packed));
 /* WARNING: DO NOT EDIT, AUTO-GENERATED CODE - SEE TOP FOR INSTRUCTIONS */
+} __attribute__((packed));
 enum nl80211_attr_coalesce_rule {
   __NL80211_COALESCE_RULE_INVALID,
   NL80211_ATTR_COALESCE_RULE_DELAY,
-  NL80211_ATTR_COALESCE_RULE_CONDITION,
 /* WARNING: DO NOT EDIT, AUTO-GENERATED CODE - SEE TOP FOR INSTRUCTIONS */
+  NL80211_ATTR_COALESCE_RULE_CONDITION,
   NL80211_ATTR_COALESCE_RULE_PKT_PATTERN,
   NUM_NL80211_ATTR_COALESCE_RULE,
   NL80211_ATTR_COALESCE_RULE_MAX = NUM_NL80211_ATTR_COALESCE_RULE - 1
-};
 /* WARNING: DO NOT EDIT, AUTO-GENERATED CODE - SEE TOP FOR INSTRUCTIONS */
+};
 enum nl80211_coalesce_condition {
   NL80211_COALESCE_CONDITION_MATCH,
   NL80211_COALESCE_CONDITION_NO_MATCH
-};
 /* WARNING: DO NOT EDIT, AUTO-GENERATED CODE - SEE TOP FOR INSTRUCTIONS */
+};
 enum nl80211_iface_limit_attrs {
   NL80211_IFACE_LIMIT_UNSPEC,
   NL80211_IFACE_LIMIT_MAX,
-  NL80211_IFACE_LIMIT_TYPES,
 /* WARNING: DO NOT EDIT, AUTO-GENERATED CODE - SEE TOP FOR INSTRUCTIONS */
+  NL80211_IFACE_LIMIT_TYPES,
   NUM_NL80211_IFACE_LIMIT,
   MAX_NL80211_IFACE_LIMIT = NUM_NL80211_IFACE_LIMIT - 1
 };
-enum nl80211_if_combination_attrs {
 /* WARNING: DO NOT EDIT, AUTO-GENERATED CODE - SEE TOP FOR INSTRUCTIONS */
+enum nl80211_if_combination_attrs {
   NL80211_IFACE_COMB_UNSPEC,
   NL80211_IFACE_COMB_LIMITS,
   NL80211_IFACE_COMB_MAXNUM,
-  NL80211_IFACE_COMB_STA_AP_BI_MATCH,
 /* WARNING: DO NOT EDIT, AUTO-GENERATED CODE - SEE TOP FOR INSTRUCTIONS */
+  NL80211_IFACE_COMB_STA_AP_BI_MATCH,
   NL80211_IFACE_COMB_NUM_CHANNELS,
   NL80211_IFACE_COMB_RADAR_DETECT_WIDTHS,
   NL80211_IFACE_COMB_RADAR_DETECT_REGIONS,
-  NUM_NL80211_IFACE_COMB,
 /* WARNING: DO NOT EDIT, AUTO-GENERATED CODE - SEE TOP FOR INSTRUCTIONS */
+  NUM_NL80211_IFACE_COMB,
   MAX_NL80211_IFACE_COMB = NUM_NL80211_IFACE_COMB - 1
 };
 enum nl80211_plink_state {
-  NL80211_PLINK_LISTEN,
 /* WARNING: DO NOT EDIT, AUTO-GENERATED CODE - SEE TOP FOR INSTRUCTIONS */
+  NL80211_PLINK_LISTEN,
   NL80211_PLINK_OPN_SNT,
   NL80211_PLINK_OPN_RCVD,
   NL80211_PLINK_CNF_RCVD,
-  NL80211_PLINK_ESTAB,
 /* WARNING: DO NOT EDIT, AUTO-GENERATED CODE - SEE TOP FOR INSTRUCTIONS */
+  NL80211_PLINK_ESTAB,
   NL80211_PLINK_HOLDING,
   NL80211_PLINK_BLOCKED,
   NUM_NL80211_PLINK_STATES,
-  MAX_NL80211_PLINK_STATES = NUM_NL80211_PLINK_STATES - 1
 /* WARNING: DO NOT EDIT, AUTO-GENERATED CODE - SEE TOP FOR INSTRUCTIONS */
+  MAX_NL80211_PLINK_STATES = NUM_NL80211_PLINK_STATES - 1
 };
 enum plink_actions {
   NL80211_PLINK_ACTION_NO_ACTION,
-  NL80211_PLINK_ACTION_OPEN,
 /* WARNING: DO NOT EDIT, AUTO-GENERATED CODE - SEE TOP FOR INSTRUCTIONS */
+  NL80211_PLINK_ACTION_OPEN,
   NL80211_PLINK_ACTION_BLOCK,
   NUM_NL80211_PLINK_ACTIONS,
 };
-#define NL80211_KCK_LEN 16
 /* WARNING: DO NOT EDIT, AUTO-GENERATED CODE - SEE TOP FOR INSTRUCTIONS */
+#define NL80211_KCK_LEN 16
 #define NL80211_KEK_LEN 16
 #define NL80211_REPLAY_CTR_LEN 8
 enum nl80211_rekey_data {
-  __NL80211_REKEY_DATA_INVALID,
 /* WARNING: DO NOT EDIT, AUTO-GENERATED CODE - SEE TOP FOR INSTRUCTIONS */
+  __NL80211_REKEY_DATA_INVALID,
   NL80211_REKEY_DATA_KEK,
   NL80211_REKEY_DATA_KCK,
   NL80211_REKEY_DATA_REPLAY_CTR,
-  NUM_NL80211_REKEY_DATA,
 /* WARNING: DO NOT EDIT, AUTO-GENERATED CODE - SEE TOP FOR INSTRUCTIONS */
+  NUM_NL80211_REKEY_DATA,
   MAX_NL80211_REKEY_DATA = NUM_NL80211_REKEY_DATA - 1
 };
 enum nl80211_hidden_ssid {
-  NL80211_HIDDEN_SSID_NOT_IN_USE,
 /* WARNING: DO NOT EDIT, AUTO-GENERATED CODE - SEE TOP FOR INSTRUCTIONS */
+  NL80211_HIDDEN_SSID_NOT_IN_USE,
   NL80211_HIDDEN_SSID_ZERO_LEN,
   NL80211_HIDDEN_SSID_ZERO_CONTENTS
 };
-enum nl80211_sta_wme_attr {
 /* WARNING: DO NOT EDIT, AUTO-GENERATED CODE - SEE TOP FOR INSTRUCTIONS */
+enum nl80211_sta_wme_attr {
   __NL80211_STA_WME_INVALID,
   NL80211_STA_WME_UAPSD_QUEUES,
   NL80211_STA_WME_MAX_SP,
-  __NL80211_STA_WME_AFTER_LAST,
 /* WARNING: DO NOT EDIT, AUTO-GENERATED CODE - SEE TOP FOR INSTRUCTIONS */
+  __NL80211_STA_WME_AFTER_LAST,
   NL80211_STA_WME_MAX = __NL80211_STA_WME_AFTER_LAST - 1
 };
 enum nl80211_pmksa_candidate_attr {
-  __NL80211_PMKSA_CANDIDATE_INVALID,
 /* WARNING: DO NOT EDIT, AUTO-GENERATED CODE - SEE TOP FOR INSTRUCTIONS */
+  __NL80211_PMKSA_CANDIDATE_INVALID,
   NL80211_PMKSA_CANDIDATE_INDEX,
   NL80211_PMKSA_CANDIDATE_BSSID,
   NL80211_PMKSA_CANDIDATE_PREAUTH,
-  NUM_NL80211_PMKSA_CANDIDATE,
 /* WARNING: DO NOT EDIT, AUTO-GENERATED CODE - SEE TOP FOR INSTRUCTIONS */
+  NUM_NL80211_PMKSA_CANDIDATE,
   MAX_NL80211_PMKSA_CANDIDATE = NUM_NL80211_PMKSA_CANDIDATE - 1
 };
 enum nl80211_tdls_operation {
-  NL80211_TDLS_DISCOVERY_REQ,
 /* WARNING: DO NOT EDIT, AUTO-GENERATED CODE - SEE TOP FOR INSTRUCTIONS */
+  NL80211_TDLS_DISCOVERY_REQ,
   NL80211_TDLS_SETUP,
   NL80211_TDLS_TEARDOWN,
   NL80211_TDLS_ENABLE_LINK,
-  NL80211_TDLS_DISABLE_LINK,
 /* WARNING: DO NOT EDIT, AUTO-GENERATED CODE - SEE TOP FOR INSTRUCTIONS */
+  NL80211_TDLS_DISABLE_LINK,
 };
 enum nl80211_feature_flags {
   NL80211_FEATURE_SK_TX_STATUS = 1 << 0,
-  NL80211_FEATURE_HT_IBSS = 1 << 1,
 /* WARNING: DO NOT EDIT, AUTO-GENERATED CODE - SEE TOP FOR INSTRUCTIONS */
+  NL80211_FEATURE_HT_IBSS = 1 << 1,
   NL80211_FEATURE_INACTIVITY_TIMER = 1 << 2,
   NL80211_FEATURE_CELL_BASE_REG_HINTS = 1 << 3,
   NL80211_FEATURE_P2P_DEVICE_NEEDS_CHANNEL = 1 << 4,
-  NL80211_FEATURE_SAE = 1 << 5,
 /* WARNING: DO NOT EDIT, AUTO-GENERATED CODE - SEE TOP FOR INSTRUCTIONS */
+  NL80211_FEATURE_SAE = 1 << 5,
   NL80211_FEATURE_LOW_PRIORITY_SCAN = 1 << 6,
   NL80211_FEATURE_SCAN_FLUSH = 1 << 7,
   NL80211_FEATURE_AP_SCAN = 1 << 8,
-  NL80211_FEATURE_VIF_TXPOWER = 1 << 9,
 /* WARNING: DO NOT EDIT, AUTO-GENERATED CODE - SEE TOP FOR INSTRUCTIONS */
+  NL80211_FEATURE_VIF_TXPOWER = 1 << 9,
   NL80211_FEATURE_NEED_OBSS_SCAN = 1 << 10,
   NL80211_FEATURE_P2P_GO_CTWIN = 1 << 11,
   NL80211_FEATURE_P2P_GO_OPPPS = 1 << 12,
-  NL80211_FEATURE_ADVERTISE_CHAN_LIMITS = 1 << 14,
 /* WARNING: DO NOT EDIT, AUTO-GENERATED CODE - SEE TOP FOR INSTRUCTIONS */
+  NL80211_FEATURE_ADVERTISE_CHAN_LIMITS = 1 << 14,
   NL80211_FEATURE_FULL_AP_CLIENT_STATE = 1 << 15,
   NL80211_FEATURE_USERSPACE_MPM = 1 << 16,
   NL80211_FEATURE_ACTIVE_MONITOR = 1 << 17,
-  NL80211_FEATURE_AP_MODE_CHAN_WIDTH_CHANGE = 1 << 18,
 /* WARNING: DO NOT EDIT, AUTO-GENERATED CODE - SEE TOP FOR INSTRUCTIONS */
+  NL80211_FEATURE_AP_MODE_CHAN_WIDTH_CHANGE = 1 << 18,
   NL80211_FEATURE_DS_PARAM_SET_IE_IN_PROBES = 1 << 19,
   NL80211_FEATURE_WFA_TPC_IE_IN_PROBES = 1 << 20,
   NL80211_FEATURE_QUIET = 1 << 21,
-  NL80211_FEATURE_TX_POWER_INSERTION = 1 << 22,
 /* WARNING: DO NOT EDIT, AUTO-GENERATED CODE - SEE TOP FOR INSTRUCTIONS */
+  NL80211_FEATURE_TX_POWER_INSERTION = 1 << 22,
   NL80211_FEATURE_ACKTO_ESTIMATION = 1 << 23,
   NL80211_FEATURE_STATIC_SMPS = 1 << 24,
   NL80211_FEATURE_DYNAMIC_SMPS = 1 << 25,
+/* WARNING: DO NOT EDIT, AUTO-GENERATED CODE - SEE TOP FOR INSTRUCTIONS */
+  NL80211_FEATURE_SUPPORTS_WMM_ADMISSION = 1 << 26,
+  NL80211_FEATURE_MAC_ON_CREATE = 1 << 27,
+  NL80211_FEATURE_TDLS_CHANNEL_SWITCH = 1 << 28,
+  NL80211_FEATURE_SCAN_RANDOM_MAC_ADDR = 1 << 29,
+/* WARNING: DO NOT EDIT, AUTO-GENERATED CODE - SEE TOP FOR INSTRUCTIONS */
+  NL80211_FEATURE_SCHED_SCAN_RANDOM_MAC_ADDR = 1 << 30,
+  NL80211_FEATURE_ND_RANDOM_MAC_ADDR = 1 << 31,
+};
+enum nl80211_ext_feature_index {
+/* WARNING: DO NOT EDIT, AUTO-GENERATED CODE - SEE TOP FOR INSTRUCTIONS */
+  NL80211_EXT_FEATURE_VHT_IBSS,
+  NUM_NL80211_EXT_FEATURES,
+  MAX_NL80211_EXT_FEATURES = NUM_NL80211_EXT_FEATURES - 1
 };
 /* WARNING: DO NOT EDIT, AUTO-GENERATED CODE - SEE TOP FOR INSTRUCTIONS */
 enum nl80211_probe_resp_offload_support_attr {
@@ -1313,63 +1403,73 @@
 /* WARNING: DO NOT EDIT, AUTO-GENERATED CODE - SEE TOP FOR INSTRUCTIONS */
   NL80211_SCAN_FLAG_FLUSH = 1 << 1,
   NL80211_SCAN_FLAG_AP = 1 << 2,
+  NL80211_SCAN_FLAG_RANDOM_ADDR = 1 << 3,
 };
-enum nl80211_acl_policy {
 /* WARNING: DO NOT EDIT, AUTO-GENERATED CODE - SEE TOP FOR INSTRUCTIONS */
+enum nl80211_acl_policy {
   NL80211_ACL_POLICY_ACCEPT_UNLESS_LISTED,
   NL80211_ACL_POLICY_DENY_UNLESS_LISTED,
 };
-enum nl80211_smps_mode {
 /* WARNING: DO NOT EDIT, AUTO-GENERATED CODE - SEE TOP FOR INSTRUCTIONS */
+enum nl80211_smps_mode {
   NL80211_SMPS_OFF,
   NL80211_SMPS_STATIC,
   NL80211_SMPS_DYNAMIC,
-  __NL80211_SMPS_AFTER_LAST,
 /* WARNING: DO NOT EDIT, AUTO-GENERATED CODE - SEE TOP FOR INSTRUCTIONS */
+  __NL80211_SMPS_AFTER_LAST,
   NL80211_SMPS_MAX = __NL80211_SMPS_AFTER_LAST - 1
 };
 enum nl80211_radar_event {
-  NL80211_RADAR_DETECTED,
 /* WARNING: DO NOT EDIT, AUTO-GENERATED CODE - SEE TOP FOR INSTRUCTIONS */
+  NL80211_RADAR_DETECTED,
   NL80211_RADAR_CAC_FINISHED,
   NL80211_RADAR_CAC_ABORTED,
   NL80211_RADAR_NOP_FINISHED,
-};
 /* WARNING: DO NOT EDIT, AUTO-GENERATED CODE - SEE TOP FOR INSTRUCTIONS */
+};
 enum nl80211_dfs_state {
   NL80211_DFS_USABLE,
   NL80211_DFS_UNAVAILABLE,
-  NL80211_DFS_AVAILABLE,
 /* WARNING: DO NOT EDIT, AUTO-GENERATED CODE - SEE TOP FOR INSTRUCTIONS */
+  NL80211_DFS_AVAILABLE,
 };
 enum nl80211_protocol_features {
   NL80211_PROTOCOL_FEATURE_SPLIT_WIPHY_DUMP = 1 << 0,
-};
 /* WARNING: DO NOT EDIT, AUTO-GENERATED CODE - SEE TOP FOR INSTRUCTIONS */
+};
 enum nl80211_crit_proto_id {
   NL80211_CRIT_PROTO_UNSPEC,
   NL80211_CRIT_PROTO_DHCP,
-  NL80211_CRIT_PROTO_EAPOL,
 /* WARNING: DO NOT EDIT, AUTO-GENERATED CODE - SEE TOP FOR INSTRUCTIONS */
+  NL80211_CRIT_PROTO_EAPOL,
   NL80211_CRIT_PROTO_APIPA,
   NUM_NL80211_CRIT_PROTO
 };
-#define NL80211_CRIT_PROTO_MAX_DURATION 5000
 /* WARNING: DO NOT EDIT, AUTO-GENERATED CODE - SEE TOP FOR INSTRUCTIONS */
+#define NL80211_CRIT_PROTO_MAX_DURATION 5000
 enum nl80211_rxmgmt_flags {
   NL80211_RXMGMT_FLAG_ANSWERED = 1 << 0,
 };
-#define NL80211_VENDOR_ID_IS_LINUX 0x80000000
 /* WARNING: DO NOT EDIT, AUTO-GENERATED CODE - SEE TOP FOR INSTRUCTIONS */
+#define NL80211_VENDOR_ID_IS_LINUX 0x80000000
 struct nl80211_vendor_cmd_info {
   __u32 vendor_id;
   __u32 subcmd;
-};
 /* WARNING: DO NOT EDIT, AUTO-GENERATED CODE - SEE TOP FOR INSTRUCTIONS */
+};
 enum nl80211_tdls_peer_capability {
   NL80211_TDLS_PEER_HT = 1 << 0,
   NL80211_TDLS_PEER_VHT = 1 << 1,
+/* WARNING: DO NOT EDIT, AUTO-GENERATED CODE - SEE TOP FOR INSTRUCTIONS */
   NL80211_TDLS_PEER_WMM = 1 << 2,
+};
+enum nl80211_sched_scan_plan {
+  __NL80211_SCHED_SCAN_PLAN_INVALID,
+/* WARNING: DO NOT EDIT, AUTO-GENERATED CODE - SEE TOP FOR INSTRUCTIONS */
+  NL80211_SCHED_SCAN_PLAN_INTERVAL,
+  NL80211_SCHED_SCAN_PLAN_ITERATIONS,
+  __NL80211_SCHED_SCAN_PLAN_AFTER_LAST,
+  NL80211_SCHED_SCAN_PLAN_MAX = __NL80211_SCHED_SCAN_PLAN_AFTER_LAST - 1
 /* WARNING: DO NOT EDIT, AUTO-GENERATED CODE - SEE TOP FOR INSTRUCTIONS */
 };
 #endif
diff --git a/libc/kernel/uapi/linux/nvme_ioctl.h b/libc/kernel/uapi/linux/nvme_ioctl.h
new file mode 100644
index 0000000..d643767
--- /dev/null
+++ b/libc/kernel/uapi/linux/nvme_ioctl.h
@@ -0,0 +1,74 @@
+/****************************************************************************
+ ****************************************************************************
+ ***
+ ***   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_NVME_IOCTL_H
+#define _UAPI_LINUX_NVME_IOCTL_H
+#include <linux/types.h>
+struct nvme_user_io {
+/* WARNING: DO NOT EDIT, AUTO-GENERATED CODE - SEE TOP FOR INSTRUCTIONS */
+  __u8 opcode;
+  __u8 flags;
+  __u16 control;
+  __u16 nblocks;
+/* WARNING: DO NOT EDIT, AUTO-GENERATED CODE - SEE TOP FOR INSTRUCTIONS */
+  __u16 rsvd;
+  __u64 metadata;
+  __u64 addr;
+  __u64 slba;
+/* WARNING: DO NOT EDIT, AUTO-GENERATED CODE - SEE TOP FOR INSTRUCTIONS */
+  __u32 dsmgmt;
+  __u32 reftag;
+  __u16 apptag;
+  __u16 appmask;
+/* WARNING: DO NOT EDIT, AUTO-GENERATED CODE - SEE TOP FOR INSTRUCTIONS */
+};
+struct nvme_passthru_cmd {
+  __u8 opcode;
+  __u8 flags;
+/* WARNING: DO NOT EDIT, AUTO-GENERATED CODE - SEE TOP FOR INSTRUCTIONS */
+  __u16 rsvd1;
+  __u32 nsid;
+  __u32 cdw2;
+  __u32 cdw3;
+/* WARNING: DO NOT EDIT, AUTO-GENERATED CODE - SEE TOP FOR INSTRUCTIONS */
+  __u64 metadata;
+  __u64 addr;
+  __u32 metadata_len;
+  __u32 data_len;
+/* WARNING: DO NOT EDIT, AUTO-GENERATED CODE - SEE TOP FOR INSTRUCTIONS */
+  __u32 cdw10;
+  __u32 cdw11;
+  __u32 cdw12;
+  __u32 cdw13;
+/* WARNING: DO NOT EDIT, AUTO-GENERATED CODE - SEE TOP FOR INSTRUCTIONS */
+  __u32 cdw14;
+  __u32 cdw15;
+  __u32 timeout_ms;
+  __u32 result;
+/* WARNING: DO NOT EDIT, AUTO-GENERATED CODE - SEE TOP FOR INSTRUCTIONS */
+};
+#define nvme_admin_cmd nvme_passthru_cmd
+#define NVME_IOCTL_ID _IO('N', 0x40)
+#define NVME_IOCTL_ADMIN_CMD _IOWR('N', 0x41, struct nvme_admin_cmd)
+/* WARNING: DO NOT EDIT, AUTO-GENERATED CODE - SEE TOP FOR INSTRUCTIONS */
+#define NVME_IOCTL_SUBMIT_IO _IOW('N', 0x42, struct nvme_user_io)
+#define NVME_IOCTL_IO_CMD _IOWR('N', 0x43, struct nvme_passthru_cmd)
+#define NVME_IOCTL_RESET _IO('N', 0x44)
+#define NVME_IOCTL_SUBSYS_RESET _IO('N', 0x45)
+/* WARNING: DO NOT EDIT, AUTO-GENERATED CODE - SEE TOP FOR INSTRUCTIONS */
+#endif
diff --git a/libc/kernel/uapi/linux/openvswitch.h b/libc/kernel/uapi/linux/openvswitch.h
index 663e37f..61923cc 100644
--- a/libc/kernel/uapi/linux/openvswitch.h
+++ b/libc/kernel/uapi/linux/openvswitch.h
@@ -101,52 +101,67 @@
   OVS_PACKET_ATTR_ACTIONS,
   OVS_PACKET_ATTR_USERDATA,
 /* WARNING: DO NOT EDIT, AUTO-GENERATED CODE - SEE TOP FOR INSTRUCTIONS */
+  OVS_PACKET_ATTR_EGRESS_TUN_KEY,
+  OVS_PACKET_ATTR_UNUSED1,
+  OVS_PACKET_ATTR_UNUSED2,
+  OVS_PACKET_ATTR_PROBE,
+/* WARNING: DO NOT EDIT, AUTO-GENERATED CODE - SEE TOP FOR INSTRUCTIONS */
+  OVS_PACKET_ATTR_MRU,
   __OVS_PACKET_ATTR_MAX
 };
 #define OVS_PACKET_ATTR_MAX (__OVS_PACKET_ATTR_MAX - 1)
-#define OVS_VPORT_FAMILY "ovs_vport"
 /* WARNING: DO NOT EDIT, AUTO-GENERATED CODE - SEE TOP FOR INSTRUCTIONS */
+#define OVS_VPORT_FAMILY "ovs_vport"
 #define OVS_VPORT_MCGROUP "ovs_vport"
 #define OVS_VPORT_VERSION 0x1
 enum ovs_vport_cmd {
-  OVS_VPORT_CMD_UNSPEC,
 /* WARNING: DO NOT EDIT, AUTO-GENERATED CODE - SEE TOP FOR INSTRUCTIONS */
+  OVS_VPORT_CMD_UNSPEC,
   OVS_VPORT_CMD_NEW,
   OVS_VPORT_CMD_DEL,
   OVS_VPORT_CMD_GET,
-  OVS_VPORT_CMD_SET
 /* WARNING: DO NOT EDIT, AUTO-GENERATED CODE - SEE TOP FOR INSTRUCTIONS */
+  OVS_VPORT_CMD_SET
 };
 enum ovs_vport_type {
   OVS_VPORT_TYPE_UNSPEC,
-  OVS_VPORT_TYPE_NETDEV,
 /* WARNING: DO NOT EDIT, AUTO-GENERATED CODE - SEE TOP FOR INSTRUCTIONS */
+  OVS_VPORT_TYPE_NETDEV,
   OVS_VPORT_TYPE_INTERNAL,
   OVS_VPORT_TYPE_GRE,
   OVS_VPORT_TYPE_VXLAN,
-  OVS_VPORT_TYPE_GENEVE,
 /* WARNING: DO NOT EDIT, AUTO-GENERATED CODE - SEE TOP FOR INSTRUCTIONS */
+  OVS_VPORT_TYPE_GENEVE,
   __OVS_VPORT_TYPE_MAX
 };
 #define OVS_VPORT_TYPE_MAX (__OVS_VPORT_TYPE_MAX - 1)
-enum ovs_vport_attr {
 /* WARNING: DO NOT EDIT, AUTO-GENERATED CODE - SEE TOP FOR INSTRUCTIONS */
+enum ovs_vport_attr {
   OVS_VPORT_ATTR_UNSPEC,
   OVS_VPORT_ATTR_PORT_NO,
   OVS_VPORT_ATTR_TYPE,
-  OVS_VPORT_ATTR_NAME,
 /* WARNING: DO NOT EDIT, AUTO-GENERATED CODE - SEE TOP FOR INSTRUCTIONS */
+  OVS_VPORT_ATTR_NAME,
   OVS_VPORT_ATTR_OPTIONS,
   OVS_VPORT_ATTR_UPCALL_PID,
   OVS_VPORT_ATTR_STATS,
-  __OVS_VPORT_ATTR_MAX
 /* WARNING: DO NOT EDIT, AUTO-GENERATED CODE - SEE TOP FOR INSTRUCTIONS */
+  __OVS_VPORT_ATTR_MAX
 };
 #define OVS_VPORT_ATTR_MAX (__OVS_VPORT_ATTR_MAX - 1)
 enum {
-  OVS_TUNNEL_ATTR_UNSPEC,
 /* WARNING: DO NOT EDIT, AUTO-GENERATED CODE - SEE TOP FOR INSTRUCTIONS */
+  OVS_VXLAN_EXT_UNSPEC,
+  OVS_VXLAN_EXT_GBP,
+  __OVS_VXLAN_EXT_MAX,
+};
+/* WARNING: DO NOT EDIT, AUTO-GENERATED CODE - SEE TOP FOR INSTRUCTIONS */
+#define OVS_VXLAN_EXT_MAX (__OVS_VXLAN_EXT_MAX - 1)
+enum {
+  OVS_TUNNEL_ATTR_UNSPEC,
   OVS_TUNNEL_ATTR_DST_PORT,
+/* WARNING: DO NOT EDIT, AUTO-GENERATED CODE - SEE TOP FOR INSTRUCTIONS */
+  OVS_TUNNEL_ATTR_EXTENSION,
   __OVS_TUNNEL_ATTR_MAX
 };
 #define OVS_TUNNEL_ATTR_MAX (__OVS_TUNNEL_ATTR_MAX - 1)
@@ -196,161 +211,223 @@
   OVS_KEY_ATTR_DP_HASH,
   OVS_KEY_ATTR_RECIRC_ID,
 /* WARNING: DO NOT EDIT, AUTO-GENERATED CODE - SEE TOP FOR INSTRUCTIONS */
+  OVS_KEY_ATTR_MPLS,
+  OVS_KEY_ATTR_CT_STATE,
+  OVS_KEY_ATTR_CT_ZONE,
+  OVS_KEY_ATTR_CT_MARK,
+/* WARNING: DO NOT EDIT, AUTO-GENERATED CODE - SEE TOP FOR INSTRUCTIONS */
+  OVS_KEY_ATTR_CT_LABELS,
   __OVS_KEY_ATTR_MAX
 };
 #define OVS_KEY_ATTR_MAX (__OVS_KEY_ATTR_MAX - 1)
-enum ovs_tunnel_key_attr {
 /* WARNING: DO NOT EDIT, AUTO-GENERATED CODE - SEE TOP FOR INSTRUCTIONS */
+enum ovs_tunnel_key_attr {
   OVS_TUNNEL_KEY_ATTR_ID,
   OVS_TUNNEL_KEY_ATTR_IPV4_SRC,
   OVS_TUNNEL_KEY_ATTR_IPV4_DST,
-  OVS_TUNNEL_KEY_ATTR_TOS,
 /* WARNING: DO NOT EDIT, AUTO-GENERATED CODE - SEE TOP FOR INSTRUCTIONS */
+  OVS_TUNNEL_KEY_ATTR_TOS,
   OVS_TUNNEL_KEY_ATTR_TTL,
   OVS_TUNNEL_KEY_ATTR_DONT_FRAGMENT,
   OVS_TUNNEL_KEY_ATTR_CSUM,
-  OVS_TUNNEL_KEY_ATTR_OAM,
 /* WARNING: DO NOT EDIT, AUTO-GENERATED CODE - SEE TOP FOR INSTRUCTIONS */
+  OVS_TUNNEL_KEY_ATTR_OAM,
   OVS_TUNNEL_KEY_ATTR_GENEVE_OPTS,
+  OVS_TUNNEL_KEY_ATTR_TP_SRC,
+  OVS_TUNNEL_KEY_ATTR_TP_DST,
+/* WARNING: DO NOT EDIT, AUTO-GENERATED CODE - SEE TOP FOR INSTRUCTIONS */
+  OVS_TUNNEL_KEY_ATTR_VXLAN_OPTS,
+  OVS_TUNNEL_KEY_ATTR_IPV6_SRC,
+  OVS_TUNNEL_KEY_ATTR_IPV6_DST,
   __OVS_TUNNEL_KEY_ATTR_MAX
+/* WARNING: DO NOT EDIT, AUTO-GENERATED CODE - SEE TOP FOR INSTRUCTIONS */
 };
 #define OVS_TUNNEL_KEY_ATTR_MAX (__OVS_TUNNEL_KEY_ATTR_MAX - 1)
-/* WARNING: DO NOT EDIT, AUTO-GENERATED CODE - SEE TOP FOR INSTRUCTIONS */
 enum ovs_frag_type {
   OVS_FRAG_TYPE_NONE,
+/* WARNING: DO NOT EDIT, AUTO-GENERATED CODE - SEE TOP FOR INSTRUCTIONS */
   OVS_FRAG_TYPE_FIRST,
   OVS_FRAG_TYPE_LATER,
-/* WARNING: DO NOT EDIT, AUTO-GENERATED CODE - SEE TOP FOR INSTRUCTIONS */
   __OVS_FRAG_TYPE_MAX
 };
+/* WARNING: DO NOT EDIT, AUTO-GENERATED CODE - SEE TOP FOR INSTRUCTIONS */
 #define OVS_FRAG_TYPE_MAX (__OVS_FRAG_TYPE_MAX - 1)
 struct ovs_key_ethernet {
-/* WARNING: DO NOT EDIT, AUTO-GENERATED CODE - SEE TOP FOR INSTRUCTIONS */
   __u8 eth_src[ETH_ALEN];
   __u8 eth_dst[ETH_ALEN];
-};
-struct ovs_key_ipv4 {
 /* WARNING: DO NOT EDIT, AUTO-GENERATED CODE - SEE TOP FOR INSTRUCTIONS */
+};
+struct ovs_key_mpls {
+  __be32 mpls_lse;
+};
+/* WARNING: DO NOT EDIT, AUTO-GENERATED CODE - SEE TOP FOR INSTRUCTIONS */
+struct ovs_key_ipv4 {
   __be32 ipv4_src;
   __be32 ipv4_dst;
   __u8 ipv4_proto;
-  __u8 ipv4_tos;
 /* WARNING: DO NOT EDIT, AUTO-GENERATED CODE - SEE TOP FOR INSTRUCTIONS */
+  __u8 ipv4_tos;
   __u8 ipv4_ttl;
   __u8 ipv4_frag;
 };
-struct ovs_key_ipv6 {
 /* WARNING: DO NOT EDIT, AUTO-GENERATED CODE - SEE TOP FOR INSTRUCTIONS */
+struct ovs_key_ipv6 {
   __be32 ipv6_src[4];
   __be32 ipv6_dst[4];
   __be32 ipv6_label;
-  __u8 ipv6_proto;
 /* WARNING: DO NOT EDIT, AUTO-GENERATED CODE - SEE TOP FOR INSTRUCTIONS */
+  __u8 ipv6_proto;
   __u8 ipv6_tclass;
   __u8 ipv6_hlimit;
   __u8 ipv6_frag;
-};
 /* WARNING: DO NOT EDIT, AUTO-GENERATED CODE - SEE TOP FOR INSTRUCTIONS */
+};
 struct ovs_key_tcp {
   __be16 tcp_src;
   __be16 tcp_dst;
-};
 /* WARNING: DO NOT EDIT, AUTO-GENERATED CODE - SEE TOP FOR INSTRUCTIONS */
+};
 struct ovs_key_udp {
   __be16 udp_src;
   __be16 udp_dst;
-};
 /* WARNING: DO NOT EDIT, AUTO-GENERATED CODE - SEE TOP FOR INSTRUCTIONS */
+};
 struct ovs_key_sctp {
   __be16 sctp_src;
   __be16 sctp_dst;
-};
 /* WARNING: DO NOT EDIT, AUTO-GENERATED CODE - SEE TOP FOR INSTRUCTIONS */
+};
 struct ovs_key_icmp {
   __u8 icmp_type;
   __u8 icmp_code;
-};
 /* WARNING: DO NOT EDIT, AUTO-GENERATED CODE - SEE TOP FOR INSTRUCTIONS */
+};
 struct ovs_key_icmpv6 {
   __u8 icmpv6_type;
   __u8 icmpv6_code;
-};
 /* WARNING: DO NOT EDIT, AUTO-GENERATED CODE - SEE TOP FOR INSTRUCTIONS */
+};
 struct ovs_key_arp {
   __be32 arp_sip;
   __be32 arp_tip;
-  __be16 arp_op;
 /* WARNING: DO NOT EDIT, AUTO-GENERATED CODE - SEE TOP FOR INSTRUCTIONS */
+  __be16 arp_op;
   __u8 arp_sha[ETH_ALEN];
   __u8 arp_tha[ETH_ALEN];
 };
-struct ovs_key_nd {
 /* WARNING: DO NOT EDIT, AUTO-GENERATED CODE - SEE TOP FOR INSTRUCTIONS */
-  __u32 nd_target[4];
+struct ovs_key_nd {
+  __be32 nd_target[4];
   __u8 nd_sll[ETH_ALEN];
   __u8 nd_tll[ETH_ALEN];
-};
 /* WARNING: DO NOT EDIT, AUTO-GENERATED CODE - SEE TOP FOR INSTRUCTIONS */
+};
+#define OVS_CT_LABELS_LEN 16
+struct ovs_key_ct_labels {
+  __u8 ct_labels[OVS_CT_LABELS_LEN];
+/* WARNING: DO NOT EDIT, AUTO-GENERATED CODE - SEE TOP FOR INSTRUCTIONS */
+};
+#define OVS_CS_F_NEW 0x01
+#define OVS_CS_F_ESTABLISHED 0x02
+#define OVS_CS_F_RELATED 0x04
+/* WARNING: DO NOT EDIT, AUTO-GENERATED CODE - SEE TOP FOR INSTRUCTIONS */
+#define OVS_CS_F_REPLY_DIR 0x08
+#define OVS_CS_F_INVALID 0x10
+#define OVS_CS_F_TRACKED 0x20
 enum ovs_flow_attr {
+/* WARNING: DO NOT EDIT, AUTO-GENERATED CODE - SEE TOP FOR INSTRUCTIONS */
   OVS_FLOW_ATTR_UNSPEC,
   OVS_FLOW_ATTR_KEY,
   OVS_FLOW_ATTR_ACTIONS,
-/* WARNING: DO NOT EDIT, AUTO-GENERATED CODE - SEE TOP FOR INSTRUCTIONS */
   OVS_FLOW_ATTR_STATS,
+/* WARNING: DO NOT EDIT, AUTO-GENERATED CODE - SEE TOP FOR INSTRUCTIONS */
   OVS_FLOW_ATTR_TCP_FLAGS,
   OVS_FLOW_ATTR_USED,
   OVS_FLOW_ATTR_CLEAR,
-/* WARNING: DO NOT EDIT, AUTO-GENERATED CODE - SEE TOP FOR INSTRUCTIONS */
   OVS_FLOW_ATTR_MASK,
+/* WARNING: DO NOT EDIT, AUTO-GENERATED CODE - SEE TOP FOR INSTRUCTIONS */
+  OVS_FLOW_ATTR_PROBE,
+  OVS_FLOW_ATTR_UFID,
+  OVS_FLOW_ATTR_UFID_FLAGS,
   __OVS_FLOW_ATTR_MAX
+/* WARNING: DO NOT EDIT, AUTO-GENERATED CODE - SEE TOP FOR INSTRUCTIONS */
 };
 #define OVS_FLOW_ATTR_MAX (__OVS_FLOW_ATTR_MAX - 1)
+#define OVS_UFID_F_OMIT_KEY (1 << 0)
+#define OVS_UFID_F_OMIT_MASK (1 << 1)
 /* WARNING: DO NOT EDIT, AUTO-GENERATED CODE - SEE TOP FOR INSTRUCTIONS */
+#define OVS_UFID_F_OMIT_ACTIONS (1 << 2)
 enum ovs_sample_attr {
   OVS_SAMPLE_ATTR_UNSPEC,
   OVS_SAMPLE_ATTR_PROBABILITY,
-  OVS_SAMPLE_ATTR_ACTIONS,
 /* WARNING: DO NOT EDIT, AUTO-GENERATED CODE - SEE TOP FOR INSTRUCTIONS */
+  OVS_SAMPLE_ATTR_ACTIONS,
   __OVS_SAMPLE_ATTR_MAX,
 };
 #define OVS_SAMPLE_ATTR_MAX (__OVS_SAMPLE_ATTR_MAX - 1)
-enum ovs_userspace_attr {
 /* WARNING: DO NOT EDIT, AUTO-GENERATED CODE - SEE TOP FOR INSTRUCTIONS */
+enum ovs_userspace_attr {
   OVS_USERSPACE_ATTR_UNSPEC,
   OVS_USERSPACE_ATTR_PID,
   OVS_USERSPACE_ATTR_USERDATA,
+/* WARNING: DO NOT EDIT, AUTO-GENERATED CODE - SEE TOP FOR INSTRUCTIONS */
+  OVS_USERSPACE_ATTR_EGRESS_TUN_PORT,
+  OVS_USERSPACE_ATTR_ACTIONS,
   __OVS_USERSPACE_ATTR_MAX
+};
+/* WARNING: DO NOT EDIT, AUTO-GENERATED CODE - SEE TOP FOR INSTRUCTIONS */
+#define OVS_USERSPACE_ATTR_MAX (__OVS_USERSPACE_ATTR_MAX - 1)
+struct ovs_action_push_mpls {
+  __be32 mpls_lse;
+  __be16 mpls_ethertype;
 /* WARNING: DO NOT EDIT, AUTO-GENERATED CODE - SEE TOP FOR INSTRUCTIONS */
 };
-#define OVS_USERSPACE_ATTR_MAX (__OVS_USERSPACE_ATTR_MAX - 1)
 struct ovs_action_push_vlan {
   __be16 vlan_tpid;
-/* WARNING: DO NOT EDIT, AUTO-GENERATED CODE - SEE TOP FOR INSTRUCTIONS */
   __be16 vlan_tci;
+/* WARNING: DO NOT EDIT, AUTO-GENERATED CODE - SEE TOP FOR INSTRUCTIONS */
 };
 enum ovs_hash_alg {
   OVS_HASH_ALG_L4,
-/* WARNING: DO NOT EDIT, AUTO-GENERATED CODE - SEE TOP FOR INSTRUCTIONS */
 };
+/* WARNING: DO NOT EDIT, AUTO-GENERATED CODE - SEE TOP FOR INSTRUCTIONS */
 struct ovs_action_hash {
   uint32_t hash_alg;
   uint32_t hash_basis;
+};
+/* WARNING: DO NOT EDIT, AUTO-GENERATED CODE - SEE TOP FOR INSTRUCTIONS */
+enum ovs_ct_attr {
+  OVS_CT_ATTR_UNSPEC,
+  OVS_CT_ATTR_COMMIT,
+  OVS_CT_ATTR_ZONE,
+/* WARNING: DO NOT EDIT, AUTO-GENERATED CODE - SEE TOP FOR INSTRUCTIONS */
+  OVS_CT_ATTR_MARK,
+  OVS_CT_ATTR_LABELS,
+  OVS_CT_ATTR_HELPER,
+  __OVS_CT_ATTR_MAX
 /* WARNING: DO NOT EDIT, AUTO-GENERATED CODE - SEE TOP FOR INSTRUCTIONS */
 };
+#define OVS_CT_ATTR_MAX (__OVS_CT_ATTR_MAX - 1)
 enum ovs_action_attr {
   OVS_ACTION_ATTR_UNSPEC,
-  OVS_ACTION_ATTR_OUTPUT,
 /* WARNING: DO NOT EDIT, AUTO-GENERATED CODE - SEE TOP FOR INSTRUCTIONS */
+  OVS_ACTION_ATTR_OUTPUT,
   OVS_ACTION_ATTR_USERSPACE,
   OVS_ACTION_ATTR_SET,
   OVS_ACTION_ATTR_PUSH_VLAN,
-  OVS_ACTION_ATTR_POP_VLAN,
 /* WARNING: DO NOT EDIT, AUTO-GENERATED CODE - SEE TOP FOR INSTRUCTIONS */
+  OVS_ACTION_ATTR_POP_VLAN,
   OVS_ACTION_ATTR_SAMPLE,
   OVS_ACTION_ATTR_RECIRC,
   OVS_ACTION_ATTR_HASH,
-  __OVS_ACTION_ATTR_MAX
 /* WARNING: DO NOT EDIT, AUTO-GENERATED CODE - SEE TOP FOR INSTRUCTIONS */
+  OVS_ACTION_ATTR_PUSH_MPLS,
+  OVS_ACTION_ATTR_POP_MPLS,
+  OVS_ACTION_ATTR_SET_MASKED,
+  OVS_ACTION_ATTR_CT,
+/* WARNING: DO NOT EDIT, AUTO-GENERATED CODE - SEE TOP FOR INSTRUCTIONS */
+  __OVS_ACTION_ATTR_MAX,
 };
 #define OVS_ACTION_ATTR_MAX (__OVS_ACTION_ATTR_MAX - 1)
 #endif
+/* WARNING: DO NOT EDIT, AUTO-GENERATED CODE - SEE TOP FOR INSTRUCTIONS */
diff --git a/libc/kernel/uapi/linux/pci_regs.h b/libc/kernel/uapi/linux/pci_regs.h
index d191821..9e5bfac 100644
--- a/libc/kernel/uapi/linux/pci_regs.h
+++ b/libc/kernel/uapi/linux/pci_regs.h
@@ -218,734 +218,783 @@
 /* WARNING: DO NOT EDIT, AUTO-GENERATED CODE - SEE TOP FOR INSTRUCTIONS */
 #define PCI_CAP_ID_SATA 0x12
 #define PCI_CAP_ID_AF 0x13
-#define PCI_CAP_ID_MAX PCI_CAP_ID_AF
-#define PCI_CAP_LIST_NEXT 1
+#define PCI_CAP_ID_EA 0x14
+#define PCI_CAP_ID_MAX PCI_CAP_ID_EA
 /* WARNING: DO NOT EDIT, AUTO-GENERATED CODE - SEE TOP FOR INSTRUCTIONS */
+#define PCI_CAP_LIST_NEXT 1
 #define PCI_CAP_FLAGS 2
 #define PCI_CAP_SIZEOF 4
 #define PCI_PM_PMC 2
-#define PCI_PM_CAP_VER_MASK 0x0007
 /* WARNING: DO NOT EDIT, AUTO-GENERATED CODE - SEE TOP FOR INSTRUCTIONS */
+#define PCI_PM_CAP_VER_MASK 0x0007
 #define PCI_PM_CAP_PME_CLOCK 0x0008
 #define PCI_PM_CAP_RESERVED 0x0010
 #define PCI_PM_CAP_DSI 0x0020
-#define PCI_PM_CAP_AUX_POWER 0x01C0
 /* WARNING: DO NOT EDIT, AUTO-GENERATED CODE - SEE TOP FOR INSTRUCTIONS */
+#define PCI_PM_CAP_AUX_POWER 0x01C0
 #define PCI_PM_CAP_D1 0x0200
 #define PCI_PM_CAP_D2 0x0400
 #define PCI_PM_CAP_PME 0x0800
-#define PCI_PM_CAP_PME_MASK 0xF800
 /* WARNING: DO NOT EDIT, AUTO-GENERATED CODE - SEE TOP FOR INSTRUCTIONS */
+#define PCI_PM_CAP_PME_MASK 0xF800
 #define PCI_PM_CAP_PME_D0 0x0800
 #define PCI_PM_CAP_PME_D1 0x1000
 #define PCI_PM_CAP_PME_D2 0x2000
-#define PCI_PM_CAP_PME_D3 0x4000
 /* WARNING: DO NOT EDIT, AUTO-GENERATED CODE - SEE TOP FOR INSTRUCTIONS */
+#define PCI_PM_CAP_PME_D3 0x4000
 #define PCI_PM_CAP_PME_D3cold 0x8000
 #define PCI_PM_CAP_PME_SHIFT 11
 #define PCI_PM_CTRL 4
-#define PCI_PM_CTRL_STATE_MASK 0x0003
 /* WARNING: DO NOT EDIT, AUTO-GENERATED CODE - SEE TOP FOR INSTRUCTIONS */
+#define PCI_PM_CTRL_STATE_MASK 0x0003
 #define PCI_PM_CTRL_NO_SOFT_RESET 0x0008
 #define PCI_PM_CTRL_PME_ENABLE 0x0100
 #define PCI_PM_CTRL_DATA_SEL_MASK 0x1e00
-#define PCI_PM_CTRL_DATA_SCALE_MASK 0x6000
 /* WARNING: DO NOT EDIT, AUTO-GENERATED CODE - SEE TOP FOR INSTRUCTIONS */
+#define PCI_PM_CTRL_DATA_SCALE_MASK 0x6000
 #define PCI_PM_CTRL_PME_STATUS 0x8000
 #define PCI_PM_PPB_EXTENSIONS 6
 #define PCI_PM_PPB_B2_B3 0x40
-#define PCI_PM_BPCC_ENABLE 0x80
 /* WARNING: DO NOT EDIT, AUTO-GENERATED CODE - SEE TOP FOR INSTRUCTIONS */
+#define PCI_PM_BPCC_ENABLE 0x80
 #define PCI_PM_DATA_REGISTER 7
 #define PCI_PM_SIZEOF 8
 #define PCI_AGP_VERSION 2
-#define PCI_AGP_RFU 3
 /* WARNING: DO NOT EDIT, AUTO-GENERATED CODE - SEE TOP FOR INSTRUCTIONS */
+#define PCI_AGP_RFU 3
 #define PCI_AGP_STATUS 4
 #define PCI_AGP_STATUS_RQ_MASK 0xff000000
 #define PCI_AGP_STATUS_SBA 0x0200
-#define PCI_AGP_STATUS_64BIT 0x0020
 /* WARNING: DO NOT EDIT, AUTO-GENERATED CODE - SEE TOP FOR INSTRUCTIONS */
+#define PCI_AGP_STATUS_64BIT 0x0020
 #define PCI_AGP_STATUS_FW 0x0010
 #define PCI_AGP_STATUS_RATE4 0x0004
 #define PCI_AGP_STATUS_RATE2 0x0002
-#define PCI_AGP_STATUS_RATE1 0x0001
 /* WARNING: DO NOT EDIT, AUTO-GENERATED CODE - SEE TOP FOR INSTRUCTIONS */
+#define PCI_AGP_STATUS_RATE1 0x0001
 #define PCI_AGP_COMMAND 8
 #define PCI_AGP_COMMAND_RQ_MASK 0xff000000
 #define PCI_AGP_COMMAND_SBA 0x0200
-#define PCI_AGP_COMMAND_AGP 0x0100
 /* WARNING: DO NOT EDIT, AUTO-GENERATED CODE - SEE TOP FOR INSTRUCTIONS */
+#define PCI_AGP_COMMAND_AGP 0x0100
 #define PCI_AGP_COMMAND_64BIT 0x0020
 #define PCI_AGP_COMMAND_FW 0x0010
 #define PCI_AGP_COMMAND_RATE4 0x0004
-#define PCI_AGP_COMMAND_RATE2 0x0002
 /* WARNING: DO NOT EDIT, AUTO-GENERATED CODE - SEE TOP FOR INSTRUCTIONS */
+#define PCI_AGP_COMMAND_RATE2 0x0002
 #define PCI_AGP_COMMAND_RATE1 0x0001
 #define PCI_AGP_SIZEOF 12
 #define PCI_VPD_ADDR 2
-#define PCI_VPD_ADDR_MASK 0x7fff
 /* WARNING: DO NOT EDIT, AUTO-GENERATED CODE - SEE TOP FOR INSTRUCTIONS */
+#define PCI_VPD_ADDR_MASK 0x7fff
 #define PCI_VPD_ADDR_F 0x8000
 #define PCI_VPD_DATA 4
 #define PCI_CAP_VPD_SIZEOF 8
-#define PCI_SID_ESR 2
 /* WARNING: DO NOT EDIT, AUTO-GENERATED CODE - SEE TOP FOR INSTRUCTIONS */
+#define PCI_SID_ESR 2
 #define PCI_SID_ESR_NSLOTS 0x1f
 #define PCI_SID_ESR_FIC 0x20
 #define PCI_SID_CHASSIS_NR 3
-#define PCI_MSI_FLAGS 2
 /* WARNING: DO NOT EDIT, AUTO-GENERATED CODE - SEE TOP FOR INSTRUCTIONS */
+#define PCI_MSI_FLAGS 2
 #define PCI_MSI_FLAGS_ENABLE 0x0001
 #define PCI_MSI_FLAGS_QMASK 0x000e
 #define PCI_MSI_FLAGS_QSIZE 0x0070
-#define PCI_MSI_FLAGS_64BIT 0x0080
 /* WARNING: DO NOT EDIT, AUTO-GENERATED CODE - SEE TOP FOR INSTRUCTIONS */
+#define PCI_MSI_FLAGS_64BIT 0x0080
 #define PCI_MSI_FLAGS_MASKBIT 0x0100
 #define PCI_MSI_RFU 3
 #define PCI_MSI_ADDRESS_LO 4
-#define PCI_MSI_ADDRESS_HI 8
 /* WARNING: DO NOT EDIT, AUTO-GENERATED CODE - SEE TOP FOR INSTRUCTIONS */
+#define PCI_MSI_ADDRESS_HI 8
 #define PCI_MSI_DATA_32 8
 #define PCI_MSI_MASK_32 12
 #define PCI_MSI_PENDING_32 16
-#define PCI_MSI_DATA_64 12
 /* WARNING: DO NOT EDIT, AUTO-GENERATED CODE - SEE TOP FOR INSTRUCTIONS */
+#define PCI_MSI_DATA_64 12
 #define PCI_MSI_MASK_64 16
 #define PCI_MSI_PENDING_64 20
 #define PCI_MSIX_FLAGS 2
-#define PCI_MSIX_FLAGS_QSIZE 0x07FF
 /* WARNING: DO NOT EDIT, AUTO-GENERATED CODE - SEE TOP FOR INSTRUCTIONS */
+#define PCI_MSIX_FLAGS_QSIZE 0x07FF
 #define PCI_MSIX_FLAGS_MASKALL 0x4000
 #define PCI_MSIX_FLAGS_ENABLE 0x8000
 #define PCI_MSIX_TABLE 4
-#define PCI_MSIX_TABLE_BIR 0x00000007
 /* WARNING: DO NOT EDIT, AUTO-GENERATED CODE - SEE TOP FOR INSTRUCTIONS */
+#define PCI_MSIX_TABLE_BIR 0x00000007
 #define PCI_MSIX_TABLE_OFFSET 0xfffffff8
 #define PCI_MSIX_PBA 8
 #define PCI_MSIX_PBA_BIR 0x00000007
-#define PCI_MSIX_PBA_OFFSET 0xfffffff8
 /* WARNING: DO NOT EDIT, AUTO-GENERATED CODE - SEE TOP FOR INSTRUCTIONS */
+#define PCI_MSIX_PBA_OFFSET 0xfffffff8
+#define PCI_MSIX_FLAGS_BIRMASK PCI_MSIX_PBA_BIR
 #define PCI_CAP_MSIX_SIZEOF 12
 #define PCI_MSIX_ENTRY_SIZE 16
+/* WARNING: DO NOT EDIT, AUTO-GENERATED CODE - SEE TOP FOR INSTRUCTIONS */
 #define PCI_MSIX_ENTRY_LOWER_ADDR 0
 #define PCI_MSIX_ENTRY_UPPER_ADDR 4
-/* WARNING: DO NOT EDIT, AUTO-GENERATED CODE - SEE TOP FOR INSTRUCTIONS */
 #define PCI_MSIX_ENTRY_DATA 8
 #define PCI_MSIX_ENTRY_VECTOR_CTRL 12
+/* WARNING: DO NOT EDIT, AUTO-GENERATED CODE - SEE TOP FOR INSTRUCTIONS */
 #define PCI_MSIX_ENTRY_CTRL_MASKBIT 1
 #define PCI_CHSWP_CSR 2
-/* WARNING: DO NOT EDIT, AUTO-GENERATED CODE - SEE TOP FOR INSTRUCTIONS */
 #define PCI_CHSWP_DHA 0x01
 #define PCI_CHSWP_EIM 0x02
+/* WARNING: DO NOT EDIT, AUTO-GENERATED CODE - SEE TOP FOR INSTRUCTIONS */
 #define PCI_CHSWP_PIE 0x04
 #define PCI_CHSWP_LOO 0x08
-/* WARNING: DO NOT EDIT, AUTO-GENERATED CODE - SEE TOP FOR INSTRUCTIONS */
 #define PCI_CHSWP_PI 0x30
 #define PCI_CHSWP_EXT 0x40
+/* WARNING: DO NOT EDIT, AUTO-GENERATED CODE - SEE TOP FOR INSTRUCTIONS */
 #define PCI_CHSWP_INS 0x80
 #define PCI_AF_LENGTH 2
-/* WARNING: DO NOT EDIT, AUTO-GENERATED CODE - SEE TOP FOR INSTRUCTIONS */
 #define PCI_AF_CAP 3
 #define PCI_AF_CAP_TP 0x01
+/* WARNING: DO NOT EDIT, AUTO-GENERATED CODE - SEE TOP FOR INSTRUCTIONS */
 #define PCI_AF_CAP_FLR 0x02
 #define PCI_AF_CTRL 4
-/* WARNING: DO NOT EDIT, AUTO-GENERATED CODE - SEE TOP FOR INSTRUCTIONS */
 #define PCI_AF_CTRL_FLR 0x01
 #define PCI_AF_STATUS 5
+/* WARNING: DO NOT EDIT, AUTO-GENERATED CODE - SEE TOP FOR INSTRUCTIONS */
 #define PCI_AF_STATUS_TP 0x01
 #define PCI_CAP_AF_SIZEOF 6
+#define PCI_EA_NUM_ENT 2
+#define PCI_EA_NUM_ENT_MASK 0x3f
 /* WARNING: DO NOT EDIT, AUTO-GENERATED CODE - SEE TOP FOR INSTRUCTIONS */
+#define PCI_EA_FIRST_ENT 4
+#define PCI_EA_FIRST_ENT_BRIDGE 8
+#define PCI_EA_ES 0x00000007
+#define PCI_EA_BEI 0x000000f0
+/* WARNING: DO NOT EDIT, AUTO-GENERATED CODE - SEE TOP FOR INSTRUCTIONS */
+#define PCI_EA_BEI_BAR0 0
+#define PCI_EA_BEI_BAR5 5
+#define PCI_EA_BEI_BRIDGE 6
+#define PCI_EA_BEI_ENI 7
+/* WARNING: DO NOT EDIT, AUTO-GENERATED CODE - SEE TOP FOR INSTRUCTIONS */
+#define PCI_EA_BEI_ROM 8
+#define PCI_EA_BEI_VF_BAR0 9
+#define PCI_EA_BEI_VF_BAR5 14
+#define PCI_EA_BEI_RESERVED 15
+/* WARNING: DO NOT EDIT, AUTO-GENERATED CODE - SEE TOP FOR INSTRUCTIONS */
+#define PCI_EA_PP 0x0000ff00
+#define PCI_EA_SP 0x00ff0000
+#define PCI_EA_P_MEM 0x00
+#define PCI_EA_P_MEM_PREFETCH 0x01
+/* WARNING: DO NOT EDIT, AUTO-GENERATED CODE - SEE TOP FOR INSTRUCTIONS */
+#define PCI_EA_P_IO 0x02
+#define PCI_EA_P_VF_MEM_PREFETCH 0x03
+#define PCI_EA_P_VF_MEM 0x04
+#define PCI_EA_P_BRIDGE_MEM 0x05
+/* WARNING: DO NOT EDIT, AUTO-GENERATED CODE - SEE TOP FOR INSTRUCTIONS */
+#define PCI_EA_P_BRIDGE_MEM_PREFETCH 0x06
+#define PCI_EA_P_BRIDGE_IO 0x07
+#define PCI_EA_P_MEM_RESERVED 0xfd
+#define PCI_EA_P_IO_RESERVED 0xfe
+/* WARNING: DO NOT EDIT, AUTO-GENERATED CODE - SEE TOP FOR INSTRUCTIONS */
+#define PCI_EA_P_UNAVAILABLE 0xff
+#define PCI_EA_WRITABLE 0x40000000
+#define PCI_EA_ENABLE 0x80000000
+#define PCI_EA_BASE 4
+/* WARNING: DO NOT EDIT, AUTO-GENERATED CODE - SEE TOP FOR INSTRUCTIONS */
+#define PCI_EA_MAX_OFFSET 8
+#define PCI_EA_IS_64 0x00000002
+#define PCI_EA_FIELD_MASK 0xfffffffc
 #define PCI_X_CMD 2
+/* WARNING: DO NOT EDIT, AUTO-GENERATED CODE - SEE TOP FOR INSTRUCTIONS */
 #define PCI_X_CMD_DPERR_E 0x0001
 #define PCI_X_CMD_ERO 0x0002
 #define PCI_X_CMD_READ_512 0x0000
-/* WARNING: DO NOT EDIT, AUTO-GENERATED CODE - SEE TOP FOR INSTRUCTIONS */
 #define PCI_X_CMD_READ_1K 0x0004
+/* WARNING: DO NOT EDIT, AUTO-GENERATED CODE - SEE TOP FOR INSTRUCTIONS */
 #define PCI_X_CMD_READ_2K 0x0008
 #define PCI_X_CMD_READ_4K 0x000c
 #define PCI_X_CMD_MAX_READ 0x000c
-/* WARNING: DO NOT EDIT, AUTO-GENERATED CODE - SEE TOP FOR INSTRUCTIONS */
 #define PCI_X_CMD_SPLIT_1 0x0000
+/* WARNING: DO NOT EDIT, AUTO-GENERATED CODE - SEE TOP FOR INSTRUCTIONS */
 #define PCI_X_CMD_SPLIT_2 0x0010
 #define PCI_X_CMD_SPLIT_3 0x0020
 #define PCI_X_CMD_SPLIT_4 0x0030
-/* WARNING: DO NOT EDIT, AUTO-GENERATED CODE - SEE TOP FOR INSTRUCTIONS */
 #define PCI_X_CMD_SPLIT_8 0x0040
+/* WARNING: DO NOT EDIT, AUTO-GENERATED CODE - SEE TOP FOR INSTRUCTIONS */
 #define PCI_X_CMD_SPLIT_12 0x0050
 #define PCI_X_CMD_SPLIT_16 0x0060
 #define PCI_X_CMD_SPLIT_32 0x0070
-/* WARNING: DO NOT EDIT, AUTO-GENERATED CODE - SEE TOP FOR INSTRUCTIONS */
 #define PCI_X_CMD_MAX_SPLIT 0x0070
+/* WARNING: DO NOT EDIT, AUTO-GENERATED CODE - SEE TOP FOR INSTRUCTIONS */
 #define PCI_X_CMD_VERSION(x) (((x) >> 12) & 3)
 #define PCI_X_STATUS 4
 #define PCI_X_STATUS_DEVFN 0x000000ff
-/* WARNING: DO NOT EDIT, AUTO-GENERATED CODE - SEE TOP FOR INSTRUCTIONS */
 #define PCI_X_STATUS_BUS 0x0000ff00
+/* WARNING: DO NOT EDIT, AUTO-GENERATED CODE - SEE TOP FOR INSTRUCTIONS */
 #define PCI_X_STATUS_64BIT 0x00010000
 #define PCI_X_STATUS_133MHZ 0x00020000
 #define PCI_X_STATUS_SPL_DISC 0x00040000
-/* WARNING: DO NOT EDIT, AUTO-GENERATED CODE - SEE TOP FOR INSTRUCTIONS */
 #define PCI_X_STATUS_UNX_SPL 0x00080000
+/* WARNING: DO NOT EDIT, AUTO-GENERATED CODE - SEE TOP FOR INSTRUCTIONS */
 #define PCI_X_STATUS_COMPLEX 0x00100000
 #define PCI_X_STATUS_MAX_READ 0x00600000
 #define PCI_X_STATUS_MAX_SPLIT 0x03800000
-/* WARNING: DO NOT EDIT, AUTO-GENERATED CODE - SEE TOP FOR INSTRUCTIONS */
 #define PCI_X_STATUS_MAX_CUM 0x1c000000
+/* WARNING: DO NOT EDIT, AUTO-GENERATED CODE - SEE TOP FOR INSTRUCTIONS */
 #define PCI_X_STATUS_SPL_ERR 0x20000000
 #define PCI_X_STATUS_266MHZ 0x40000000
 #define PCI_X_STATUS_533MHZ 0x80000000
-/* WARNING: DO NOT EDIT, AUTO-GENERATED CODE - SEE TOP FOR INSTRUCTIONS */
 #define PCI_X_ECC_CSR 8
+/* WARNING: DO NOT EDIT, AUTO-GENERATED CODE - SEE TOP FOR INSTRUCTIONS */
 #define PCI_CAP_PCIX_SIZEOF_V0 8
 #define PCI_CAP_PCIX_SIZEOF_V1 24
 #define PCI_CAP_PCIX_SIZEOF_V2 PCI_CAP_PCIX_SIZEOF_V1
-/* WARNING: DO NOT EDIT, AUTO-GENERATED CODE - SEE TOP FOR INSTRUCTIONS */
 #define PCI_X_BRIDGE_SSTATUS 2
+/* WARNING: DO NOT EDIT, AUTO-GENERATED CODE - SEE TOP FOR INSTRUCTIONS */
 #define PCI_X_SSTATUS_64BIT 0x0001
 #define PCI_X_SSTATUS_133MHZ 0x0002
 #define PCI_X_SSTATUS_FREQ 0x03c0
-/* WARNING: DO NOT EDIT, AUTO-GENERATED CODE - SEE TOP FOR INSTRUCTIONS */
 #define PCI_X_SSTATUS_VERS 0x3000
+/* WARNING: DO NOT EDIT, AUTO-GENERATED CODE - SEE TOP FOR INSTRUCTIONS */
 #define PCI_X_SSTATUS_V1 0x1000
 #define PCI_X_SSTATUS_V2 0x2000
 #define PCI_X_SSTATUS_266MHZ 0x4000
-/* WARNING: DO NOT EDIT, AUTO-GENERATED CODE - SEE TOP FOR INSTRUCTIONS */
 #define PCI_X_SSTATUS_533MHZ 0x8000
+/* WARNING: DO NOT EDIT, AUTO-GENERATED CODE - SEE TOP FOR INSTRUCTIONS */
 #define PCI_X_BRIDGE_STATUS 4
 #define PCI_SSVID_VENDOR_ID 4
 #define PCI_SSVID_DEVICE_ID 6
-/* WARNING: DO NOT EDIT, AUTO-GENERATED CODE - SEE TOP FOR INSTRUCTIONS */
 #define PCI_EXP_FLAGS 2
+/* WARNING: DO NOT EDIT, AUTO-GENERATED CODE - SEE TOP FOR INSTRUCTIONS */
 #define PCI_EXP_FLAGS_VERS 0x000f
 #define PCI_EXP_FLAGS_TYPE 0x00f0
 #define PCI_EXP_TYPE_ENDPOINT 0x0
-/* WARNING: DO NOT EDIT, AUTO-GENERATED CODE - SEE TOP FOR INSTRUCTIONS */
 #define PCI_EXP_TYPE_LEG_END 0x1
+/* WARNING: DO NOT EDIT, AUTO-GENERATED CODE - SEE TOP FOR INSTRUCTIONS */
 #define PCI_EXP_TYPE_ROOT_PORT 0x4
 #define PCI_EXP_TYPE_UPSTREAM 0x5
 #define PCI_EXP_TYPE_DOWNSTREAM 0x6
-/* WARNING: DO NOT EDIT, AUTO-GENERATED CODE - SEE TOP FOR INSTRUCTIONS */
 #define PCI_EXP_TYPE_PCI_BRIDGE 0x7
+/* WARNING: DO NOT EDIT, AUTO-GENERATED CODE - SEE TOP FOR INSTRUCTIONS */
 #define PCI_EXP_TYPE_PCIE_BRIDGE 0x8
 #define PCI_EXP_TYPE_RC_END 0x9
 #define PCI_EXP_TYPE_RC_EC 0xa
-/* WARNING: DO NOT EDIT, AUTO-GENERATED CODE - SEE TOP FOR INSTRUCTIONS */
 #define PCI_EXP_FLAGS_SLOT 0x0100
+/* WARNING: DO NOT EDIT, AUTO-GENERATED CODE - SEE TOP FOR INSTRUCTIONS */
 #define PCI_EXP_FLAGS_IRQ 0x3e00
 #define PCI_EXP_DEVCAP 4
 #define PCI_EXP_DEVCAP_PAYLOAD 0x00000007
-/* WARNING: DO NOT EDIT, AUTO-GENERATED CODE - SEE TOP FOR INSTRUCTIONS */
 #define PCI_EXP_DEVCAP_PHANTOM 0x00000018
+/* WARNING: DO NOT EDIT, AUTO-GENERATED CODE - SEE TOP FOR INSTRUCTIONS */
 #define PCI_EXP_DEVCAP_EXT_TAG 0x00000020
 #define PCI_EXP_DEVCAP_L0S 0x000001c0
 #define PCI_EXP_DEVCAP_L1 0x00000e00
-/* WARNING: DO NOT EDIT, AUTO-GENERATED CODE - SEE TOP FOR INSTRUCTIONS */
 #define PCI_EXP_DEVCAP_ATN_BUT 0x00001000
+/* WARNING: DO NOT EDIT, AUTO-GENERATED CODE - SEE TOP FOR INSTRUCTIONS */
 #define PCI_EXP_DEVCAP_ATN_IND 0x00002000
 #define PCI_EXP_DEVCAP_PWR_IND 0x00004000
 #define PCI_EXP_DEVCAP_RBER 0x00008000
-/* WARNING: DO NOT EDIT, AUTO-GENERATED CODE - SEE TOP FOR INSTRUCTIONS */
 #define PCI_EXP_DEVCAP_PWR_VAL 0x03fc0000
+/* WARNING: DO NOT EDIT, AUTO-GENERATED CODE - SEE TOP FOR INSTRUCTIONS */
 #define PCI_EXP_DEVCAP_PWR_SCL 0x0c000000
 #define PCI_EXP_DEVCAP_FLR 0x10000000
 #define PCI_EXP_DEVCTL 8
-/* WARNING: DO NOT EDIT, AUTO-GENERATED CODE - SEE TOP FOR INSTRUCTIONS */
 #define PCI_EXP_DEVCTL_CERE 0x0001
+/* WARNING: DO NOT EDIT, AUTO-GENERATED CODE - SEE TOP FOR INSTRUCTIONS */
 #define PCI_EXP_DEVCTL_NFERE 0x0002
 #define PCI_EXP_DEVCTL_FERE 0x0004
 #define PCI_EXP_DEVCTL_URRE 0x0008
-/* WARNING: DO NOT EDIT, AUTO-GENERATED CODE - SEE TOP FOR INSTRUCTIONS */
 #define PCI_EXP_DEVCTL_RELAX_EN 0x0010
+/* WARNING: DO NOT EDIT, AUTO-GENERATED CODE - SEE TOP FOR INSTRUCTIONS */
 #define PCI_EXP_DEVCTL_PAYLOAD 0x00e0
 #define PCI_EXP_DEVCTL_EXT_TAG 0x0100
 #define PCI_EXP_DEVCTL_PHANTOM 0x0200
-/* WARNING: DO NOT EDIT, AUTO-GENERATED CODE - SEE TOP FOR INSTRUCTIONS */
 #define PCI_EXP_DEVCTL_AUX_PME 0x0400
+/* WARNING: DO NOT EDIT, AUTO-GENERATED CODE - SEE TOP FOR INSTRUCTIONS */
 #define PCI_EXP_DEVCTL_NOSNOOP_EN 0x0800
 #define PCI_EXP_DEVCTL_READRQ 0x7000
-#define PCI_EXP_DEVCTL_BCR_FLR 0x8000
+#define PCI_EXP_DEVCTL_READRQ_128B 0x0000
+#define PCI_EXP_DEVCTL_READRQ_256B 0x1000
 /* WARNING: DO NOT EDIT, AUTO-GENERATED CODE - SEE TOP FOR INSTRUCTIONS */
+#define PCI_EXP_DEVCTL_READRQ_512B 0x2000
+#define PCI_EXP_DEVCTL_READRQ_1024B 0x3000
+#define PCI_EXP_DEVCTL_BCR_FLR 0x8000
 #define PCI_EXP_DEVSTA 10
+/* WARNING: DO NOT EDIT, AUTO-GENERATED CODE - SEE TOP FOR INSTRUCTIONS */
 #define PCI_EXP_DEVSTA_CED 0x0001
 #define PCI_EXP_DEVSTA_NFED 0x0002
 #define PCI_EXP_DEVSTA_FED 0x0004
-/* WARNING: DO NOT EDIT, AUTO-GENERATED CODE - SEE TOP FOR INSTRUCTIONS */
 #define PCI_EXP_DEVSTA_URD 0x0008
+/* WARNING: DO NOT EDIT, AUTO-GENERATED CODE - SEE TOP FOR INSTRUCTIONS */
 #define PCI_EXP_DEVSTA_AUXPD 0x0010
 #define PCI_EXP_DEVSTA_TRPND 0x0020
 #define PCI_EXP_LNKCAP 12
-/* WARNING: DO NOT EDIT, AUTO-GENERATED CODE - SEE TOP FOR INSTRUCTIONS */
 #define PCI_EXP_LNKCAP_SLS 0x0000000f
+/* WARNING: DO NOT EDIT, AUTO-GENERATED CODE - SEE TOP FOR INSTRUCTIONS */
 #define PCI_EXP_LNKCAP_SLS_2_5GB 0x00000001
 #define PCI_EXP_LNKCAP_SLS_5_0GB 0x00000002
 #define PCI_EXP_LNKCAP_MLW 0x000003f0
-/* WARNING: DO NOT EDIT, AUTO-GENERATED CODE - SEE TOP FOR INSTRUCTIONS */
 #define PCI_EXP_LNKCAP_ASPMS 0x00000c00
+/* WARNING: DO NOT EDIT, AUTO-GENERATED CODE - SEE TOP FOR INSTRUCTIONS */
 #define PCI_EXP_LNKCAP_L0SEL 0x00007000
 #define PCI_EXP_LNKCAP_L1EL 0x00038000
 #define PCI_EXP_LNKCAP_CLKPM 0x00040000
-/* WARNING: DO NOT EDIT, AUTO-GENERATED CODE - SEE TOP FOR INSTRUCTIONS */
 #define PCI_EXP_LNKCAP_SDERC 0x00080000
+/* WARNING: DO NOT EDIT, AUTO-GENERATED CODE - SEE TOP FOR INSTRUCTIONS */
 #define PCI_EXP_LNKCAP_DLLLARC 0x00100000
 #define PCI_EXP_LNKCAP_LBNC 0x00200000
 #define PCI_EXP_LNKCAP_PN 0xff000000
-/* WARNING: DO NOT EDIT, AUTO-GENERATED CODE - SEE TOP FOR INSTRUCTIONS */
 #define PCI_EXP_LNKCTL 16
+/* WARNING: DO NOT EDIT, AUTO-GENERATED CODE - SEE TOP FOR INSTRUCTIONS */
 #define PCI_EXP_LNKCTL_ASPMC 0x0003
 #define PCI_EXP_LNKCTL_ASPM_L0S 0x0001
 #define PCI_EXP_LNKCTL_ASPM_L1 0x0002
-/* WARNING: DO NOT EDIT, AUTO-GENERATED CODE - SEE TOP FOR INSTRUCTIONS */
 #define PCI_EXP_LNKCTL_RCB 0x0008
+/* WARNING: DO NOT EDIT, AUTO-GENERATED CODE - SEE TOP FOR INSTRUCTIONS */
 #define PCI_EXP_LNKCTL_LD 0x0010
 #define PCI_EXP_LNKCTL_RL 0x0020
 #define PCI_EXP_LNKCTL_CCC 0x0040
-/* WARNING: DO NOT EDIT, AUTO-GENERATED CODE - SEE TOP FOR INSTRUCTIONS */
 #define PCI_EXP_LNKCTL_ES 0x0080
+/* WARNING: DO NOT EDIT, AUTO-GENERATED CODE - SEE TOP FOR INSTRUCTIONS */
 #define PCI_EXP_LNKCTL_CLKREQ_EN 0x0100
 #define PCI_EXP_LNKCTL_HAWD 0x0200
 #define PCI_EXP_LNKCTL_LBMIE 0x0400
-/* WARNING: DO NOT EDIT, AUTO-GENERATED CODE - SEE TOP FOR INSTRUCTIONS */
 #define PCI_EXP_LNKCTL_LABIE 0x0800
+/* WARNING: DO NOT EDIT, AUTO-GENERATED CODE - SEE TOP FOR INSTRUCTIONS */
 #define PCI_EXP_LNKSTA 18
 #define PCI_EXP_LNKSTA_CLS 0x000f
 #define PCI_EXP_LNKSTA_CLS_2_5GB 0x0001
-/* WARNING: DO NOT EDIT, AUTO-GENERATED CODE - SEE TOP FOR INSTRUCTIONS */
 #define PCI_EXP_LNKSTA_CLS_5_0GB 0x0002
+/* WARNING: DO NOT EDIT, AUTO-GENERATED CODE - SEE TOP FOR INSTRUCTIONS */
 #define PCI_EXP_LNKSTA_CLS_8_0GB 0x0003
 #define PCI_EXP_LNKSTA_NLW 0x03f0
 #define PCI_EXP_LNKSTA_NLW_X1 0x0010
-/* WARNING: DO NOT EDIT, AUTO-GENERATED CODE - SEE TOP FOR INSTRUCTIONS */
 #define PCI_EXP_LNKSTA_NLW_X2 0x0020
+/* WARNING: DO NOT EDIT, AUTO-GENERATED CODE - SEE TOP FOR INSTRUCTIONS */
 #define PCI_EXP_LNKSTA_NLW_X4 0x0040
 #define PCI_EXP_LNKSTA_NLW_X8 0x0080
 #define PCI_EXP_LNKSTA_NLW_SHIFT 4
-/* WARNING: DO NOT EDIT, AUTO-GENERATED CODE - SEE TOP FOR INSTRUCTIONS */
 #define PCI_EXP_LNKSTA_LT 0x0800
+/* WARNING: DO NOT EDIT, AUTO-GENERATED CODE - SEE TOP FOR INSTRUCTIONS */
 #define PCI_EXP_LNKSTA_SLC 0x1000
 #define PCI_EXP_LNKSTA_DLLLA 0x2000
 #define PCI_EXP_LNKSTA_LBMS 0x4000
-/* WARNING: DO NOT EDIT, AUTO-GENERATED CODE - SEE TOP FOR INSTRUCTIONS */
 #define PCI_EXP_LNKSTA_LABS 0x8000
+/* WARNING: DO NOT EDIT, AUTO-GENERATED CODE - SEE TOP FOR INSTRUCTIONS */
 #define PCI_CAP_EXP_ENDPOINT_SIZEOF_V1 20
 #define PCI_EXP_SLTCAP 20
 #define PCI_EXP_SLTCAP_ABP 0x00000001
-/* WARNING: DO NOT EDIT, AUTO-GENERATED CODE - SEE TOP FOR INSTRUCTIONS */
 #define PCI_EXP_SLTCAP_PCP 0x00000002
+/* WARNING: DO NOT EDIT, AUTO-GENERATED CODE - SEE TOP FOR INSTRUCTIONS */
 #define PCI_EXP_SLTCAP_MRLSP 0x00000004
 #define PCI_EXP_SLTCAP_AIP 0x00000008
 #define PCI_EXP_SLTCAP_PIP 0x00000010
-/* WARNING: DO NOT EDIT, AUTO-GENERATED CODE - SEE TOP FOR INSTRUCTIONS */
 #define PCI_EXP_SLTCAP_HPS 0x00000020
+/* WARNING: DO NOT EDIT, AUTO-GENERATED CODE - SEE TOP FOR INSTRUCTIONS */
 #define PCI_EXP_SLTCAP_HPC 0x00000040
 #define PCI_EXP_SLTCAP_SPLV 0x00007f80
 #define PCI_EXP_SLTCAP_SPLS 0x00018000
-/* WARNING: DO NOT EDIT, AUTO-GENERATED CODE - SEE TOP FOR INSTRUCTIONS */
 #define PCI_EXP_SLTCAP_EIP 0x00020000
+/* WARNING: DO NOT EDIT, AUTO-GENERATED CODE - SEE TOP FOR INSTRUCTIONS */
 #define PCI_EXP_SLTCAP_NCCS 0x00040000
 #define PCI_EXP_SLTCAP_PSN 0xfff80000
 #define PCI_EXP_SLTCTL 24
-/* WARNING: DO NOT EDIT, AUTO-GENERATED CODE - SEE TOP FOR INSTRUCTIONS */
 #define PCI_EXP_SLTCTL_ABPE 0x0001
+/* WARNING: DO NOT EDIT, AUTO-GENERATED CODE - SEE TOP FOR INSTRUCTIONS */
 #define PCI_EXP_SLTCTL_PFDE 0x0002
 #define PCI_EXP_SLTCTL_MRLSCE 0x0004
 #define PCI_EXP_SLTCTL_PDCE 0x0008
-/* WARNING: DO NOT EDIT, AUTO-GENERATED CODE - SEE TOP FOR INSTRUCTIONS */
 #define PCI_EXP_SLTCTL_CCIE 0x0010
+/* WARNING: DO NOT EDIT, AUTO-GENERATED CODE - SEE TOP FOR INSTRUCTIONS */
 #define PCI_EXP_SLTCTL_HPIE 0x0020
 #define PCI_EXP_SLTCTL_AIC 0x00c0
 #define PCI_EXP_SLTCTL_ATTN_IND_ON 0x0040
-/* WARNING: DO NOT EDIT, AUTO-GENERATED CODE - SEE TOP FOR INSTRUCTIONS */
 #define PCI_EXP_SLTCTL_ATTN_IND_BLINK 0x0080
+/* WARNING: DO NOT EDIT, AUTO-GENERATED CODE - SEE TOP FOR INSTRUCTIONS */
 #define PCI_EXP_SLTCTL_ATTN_IND_OFF 0x00c0
 #define PCI_EXP_SLTCTL_PIC 0x0300
 #define PCI_EXP_SLTCTL_PWR_IND_ON 0x0100
-/* WARNING: DO NOT EDIT, AUTO-GENERATED CODE - SEE TOP FOR INSTRUCTIONS */
 #define PCI_EXP_SLTCTL_PWR_IND_BLINK 0x0200
+/* WARNING: DO NOT EDIT, AUTO-GENERATED CODE - SEE TOP FOR INSTRUCTIONS */
 #define PCI_EXP_SLTCTL_PWR_IND_OFF 0x0300
 #define PCI_EXP_SLTCTL_PCC 0x0400
 #define PCI_EXP_SLTCTL_PWR_ON 0x0000
-/* WARNING: DO NOT EDIT, AUTO-GENERATED CODE - SEE TOP FOR INSTRUCTIONS */
 #define PCI_EXP_SLTCTL_PWR_OFF 0x0400
+/* WARNING: DO NOT EDIT, AUTO-GENERATED CODE - SEE TOP FOR INSTRUCTIONS */
 #define PCI_EXP_SLTCTL_EIC 0x0800
 #define PCI_EXP_SLTCTL_DLLSCE 0x1000
 #define PCI_EXP_SLTSTA 26
-/* WARNING: DO NOT EDIT, AUTO-GENERATED CODE - SEE TOP FOR INSTRUCTIONS */
 #define PCI_EXP_SLTSTA_ABP 0x0001
+/* WARNING: DO NOT EDIT, AUTO-GENERATED CODE - SEE TOP FOR INSTRUCTIONS */
 #define PCI_EXP_SLTSTA_PFD 0x0002
 #define PCI_EXP_SLTSTA_MRLSC 0x0004
 #define PCI_EXP_SLTSTA_PDC 0x0008
-/* WARNING: DO NOT EDIT, AUTO-GENERATED CODE - SEE TOP FOR INSTRUCTIONS */
 #define PCI_EXP_SLTSTA_CC 0x0010
+/* WARNING: DO NOT EDIT, AUTO-GENERATED CODE - SEE TOP FOR INSTRUCTIONS */
 #define PCI_EXP_SLTSTA_MRLSS 0x0020
 #define PCI_EXP_SLTSTA_PDS 0x0040
 #define PCI_EXP_SLTSTA_EIS 0x0080
-/* WARNING: DO NOT EDIT, AUTO-GENERATED CODE - SEE TOP FOR INSTRUCTIONS */
 #define PCI_EXP_SLTSTA_DLLSC 0x0100
+/* WARNING: DO NOT EDIT, AUTO-GENERATED CODE - SEE TOP FOR INSTRUCTIONS */
 #define PCI_EXP_RTCTL 28
 #define PCI_EXP_RTCTL_SECEE 0x0001
 #define PCI_EXP_RTCTL_SENFEE 0x0002
-/* WARNING: DO NOT EDIT, AUTO-GENERATED CODE - SEE TOP FOR INSTRUCTIONS */
 #define PCI_EXP_RTCTL_SEFEE 0x0004
+/* WARNING: DO NOT EDIT, AUTO-GENERATED CODE - SEE TOP FOR INSTRUCTIONS */
 #define PCI_EXP_RTCTL_PMEIE 0x0008
 #define PCI_EXP_RTCTL_CRSSVE 0x0010
 #define PCI_EXP_RTCAP 30
-/* WARNING: DO NOT EDIT, AUTO-GENERATED CODE - SEE TOP FOR INSTRUCTIONS */
 #define PCI_EXP_RTCAP_CRSVIS 0x0001
+/* WARNING: DO NOT EDIT, AUTO-GENERATED CODE - SEE TOP FOR INSTRUCTIONS */
 #define PCI_EXP_RTSTA 32
 #define PCI_EXP_RTSTA_PME 0x00010000
 #define PCI_EXP_RTSTA_PENDING 0x00020000
-/* WARNING: DO NOT EDIT, AUTO-GENERATED CODE - SEE TOP FOR INSTRUCTIONS */
 #define PCI_EXP_DEVCAP2 36
+/* WARNING: DO NOT EDIT, AUTO-GENERATED CODE - SEE TOP FOR INSTRUCTIONS */
 #define PCI_EXP_DEVCAP2_ARI 0x00000020
 #define PCI_EXP_DEVCAP2_LTR 0x00000800
 #define PCI_EXP_DEVCAP2_OBFF_MASK 0x000c0000
-/* WARNING: DO NOT EDIT, AUTO-GENERATED CODE - SEE TOP FOR INSTRUCTIONS */
 #define PCI_EXP_DEVCAP2_OBFF_MSG 0x00040000
+/* WARNING: DO NOT EDIT, AUTO-GENERATED CODE - SEE TOP FOR INSTRUCTIONS */
 #define PCI_EXP_DEVCAP2_OBFF_WAKE 0x00080000
 #define PCI_EXP_DEVCTL2 40
 #define PCI_EXP_DEVCTL2_COMP_TIMEOUT 0x000f
-/* WARNING: DO NOT EDIT, AUTO-GENERATED CODE - SEE TOP FOR INSTRUCTIONS */
 #define PCI_EXP_DEVCTL2_ARI 0x0020
+/* WARNING: DO NOT EDIT, AUTO-GENERATED CODE - SEE TOP FOR INSTRUCTIONS */
 #define PCI_EXP_DEVCTL2_IDO_REQ_EN 0x0100
 #define PCI_EXP_DEVCTL2_IDO_CMP_EN 0x0200
 #define PCI_EXP_DEVCTL2_LTR_EN 0x0400
-/* WARNING: DO NOT EDIT, AUTO-GENERATED CODE - SEE TOP FOR INSTRUCTIONS */
 #define PCI_EXP_DEVCTL2_OBFF_MSGA_EN 0x2000
+/* WARNING: DO NOT EDIT, AUTO-GENERATED CODE - SEE TOP FOR INSTRUCTIONS */
 #define PCI_EXP_DEVCTL2_OBFF_MSGB_EN 0x4000
 #define PCI_EXP_DEVCTL2_OBFF_WAKE_EN 0x6000
 #define PCI_EXP_DEVSTA2 42
-/* WARNING: DO NOT EDIT, AUTO-GENERATED CODE - SEE TOP FOR INSTRUCTIONS */
 #define PCI_CAP_EXP_ENDPOINT_SIZEOF_V2 44
+/* WARNING: DO NOT EDIT, AUTO-GENERATED CODE - SEE TOP FOR INSTRUCTIONS */
 #define PCI_EXP_LNKCAP2 44
 #define PCI_EXP_LNKCAP2_SLS_2_5GB 0x00000002
 #define PCI_EXP_LNKCAP2_SLS_5_0GB 0x00000004
-/* WARNING: DO NOT EDIT, AUTO-GENERATED CODE - SEE TOP FOR INSTRUCTIONS */
 #define PCI_EXP_LNKCAP2_SLS_8_0GB 0x00000008
+/* WARNING: DO NOT EDIT, AUTO-GENERATED CODE - SEE TOP FOR INSTRUCTIONS */
 #define PCI_EXP_LNKCAP2_CROSSLINK 0x00000100
 #define PCI_EXP_LNKCTL2 48
 #define PCI_EXP_LNKSTA2 50
-/* WARNING: DO NOT EDIT, AUTO-GENERATED CODE - SEE TOP FOR INSTRUCTIONS */
 #define PCI_EXP_SLTCAP2 52
+/* WARNING: DO NOT EDIT, AUTO-GENERATED CODE - SEE TOP FOR INSTRUCTIONS */
 #define PCI_EXP_SLTCTL2 56
 #define PCI_EXP_SLTSTA2 58
 #define PCI_EXT_CAP_ID(header) (header & 0x0000ffff)
-/* WARNING: DO NOT EDIT, AUTO-GENERATED CODE - SEE TOP FOR INSTRUCTIONS */
 #define PCI_EXT_CAP_VER(header) ((header >> 16) & 0xf)
+/* WARNING: DO NOT EDIT, AUTO-GENERATED CODE - SEE TOP FOR INSTRUCTIONS */
 #define PCI_EXT_CAP_NEXT(header) ((header >> 20) & 0xffc)
 #define PCI_EXT_CAP_ID_ERR 0x01
 #define PCI_EXT_CAP_ID_VC 0x02
-/* WARNING: DO NOT EDIT, AUTO-GENERATED CODE - SEE TOP FOR INSTRUCTIONS */
 #define PCI_EXT_CAP_ID_DSN 0x03
+/* WARNING: DO NOT EDIT, AUTO-GENERATED CODE - SEE TOP FOR INSTRUCTIONS */
 #define PCI_EXT_CAP_ID_PWR 0x04
 #define PCI_EXT_CAP_ID_RCLD 0x05
 #define PCI_EXT_CAP_ID_RCILC 0x06
-/* WARNING: DO NOT EDIT, AUTO-GENERATED CODE - SEE TOP FOR INSTRUCTIONS */
 #define PCI_EXT_CAP_ID_RCEC 0x07
+/* WARNING: DO NOT EDIT, AUTO-GENERATED CODE - SEE TOP FOR INSTRUCTIONS */
 #define PCI_EXT_CAP_ID_MFVC 0x08
 #define PCI_EXT_CAP_ID_VC9 0x09
 #define PCI_EXT_CAP_ID_RCRB 0x0A
-/* WARNING: DO NOT EDIT, AUTO-GENERATED CODE - SEE TOP FOR INSTRUCTIONS */
 #define PCI_EXT_CAP_ID_VNDR 0x0B
+/* WARNING: DO NOT EDIT, AUTO-GENERATED CODE - SEE TOP FOR INSTRUCTIONS */
 #define PCI_EXT_CAP_ID_CAC 0x0C
 #define PCI_EXT_CAP_ID_ACS 0x0D
 #define PCI_EXT_CAP_ID_ARI 0x0E
-/* WARNING: DO NOT EDIT, AUTO-GENERATED CODE - SEE TOP FOR INSTRUCTIONS */
 #define PCI_EXT_CAP_ID_ATS 0x0F
+/* WARNING: DO NOT EDIT, AUTO-GENERATED CODE - SEE TOP FOR INSTRUCTIONS */
 #define PCI_EXT_CAP_ID_SRIOV 0x10
 #define PCI_EXT_CAP_ID_MRIOV 0x11
 #define PCI_EXT_CAP_ID_MCAST 0x12
-/* WARNING: DO NOT EDIT, AUTO-GENERATED CODE - SEE TOP FOR INSTRUCTIONS */
 #define PCI_EXT_CAP_ID_PRI 0x13
+/* WARNING: DO NOT EDIT, AUTO-GENERATED CODE - SEE TOP FOR INSTRUCTIONS */
 #define PCI_EXT_CAP_ID_AMD_XXX 0x14
 #define PCI_EXT_CAP_ID_REBAR 0x15
 #define PCI_EXT_CAP_ID_DPA 0x16
-/* WARNING: DO NOT EDIT, AUTO-GENERATED CODE - SEE TOP FOR INSTRUCTIONS */
 #define PCI_EXT_CAP_ID_TPH 0x17
+/* WARNING: DO NOT EDIT, AUTO-GENERATED CODE - SEE TOP FOR INSTRUCTIONS */
 #define PCI_EXT_CAP_ID_LTR 0x18
 #define PCI_EXT_CAP_ID_SECPCI 0x19
 #define PCI_EXT_CAP_ID_PMUX 0x1A
-/* WARNING: DO NOT EDIT, AUTO-GENERATED CODE - SEE TOP FOR INSTRUCTIONS */
 #define PCI_EXT_CAP_ID_PASID 0x1B
+/* WARNING: DO NOT EDIT, AUTO-GENERATED CODE - SEE TOP FOR INSTRUCTIONS */
 #define PCI_EXT_CAP_ID_MAX PCI_EXT_CAP_ID_PASID
 #define PCI_EXT_CAP_DSN_SIZEOF 12
 #define PCI_EXT_CAP_MCAST_ENDPOINT_SIZEOF 40
-/* WARNING: DO NOT EDIT, AUTO-GENERATED CODE - SEE TOP FOR INSTRUCTIONS */
 #define PCI_ERR_UNCOR_STATUS 4
+/* WARNING: DO NOT EDIT, AUTO-GENERATED CODE - SEE TOP FOR INSTRUCTIONS */
 #define PCI_ERR_UNC_UND 0x00000001
 #define PCI_ERR_UNC_DLP 0x00000010
 #define PCI_ERR_UNC_SURPDN 0x00000020
-/* WARNING: DO NOT EDIT, AUTO-GENERATED CODE - SEE TOP FOR INSTRUCTIONS */
 #define PCI_ERR_UNC_POISON_TLP 0x00001000
+/* WARNING: DO NOT EDIT, AUTO-GENERATED CODE - SEE TOP FOR INSTRUCTIONS */
 #define PCI_ERR_UNC_FCP 0x00002000
 #define PCI_ERR_UNC_COMP_TIME 0x00004000
 #define PCI_ERR_UNC_COMP_ABORT 0x00008000
-/* WARNING: DO NOT EDIT, AUTO-GENERATED CODE - SEE TOP FOR INSTRUCTIONS */
 #define PCI_ERR_UNC_UNX_COMP 0x00010000
+/* WARNING: DO NOT EDIT, AUTO-GENERATED CODE - SEE TOP FOR INSTRUCTIONS */
 #define PCI_ERR_UNC_RX_OVER 0x00020000
 #define PCI_ERR_UNC_MALF_TLP 0x00040000
 #define PCI_ERR_UNC_ECRC 0x00080000
-/* WARNING: DO NOT EDIT, AUTO-GENERATED CODE - SEE TOP FOR INSTRUCTIONS */
 #define PCI_ERR_UNC_UNSUP 0x00100000
+/* WARNING: DO NOT EDIT, AUTO-GENERATED CODE - SEE TOP FOR INSTRUCTIONS */
 #define PCI_ERR_UNC_ACSV 0x00200000
 #define PCI_ERR_UNC_INTN 0x00400000
 #define PCI_ERR_UNC_MCBTLP 0x00800000
-/* WARNING: DO NOT EDIT, AUTO-GENERATED CODE - SEE TOP FOR INSTRUCTIONS */
 #define PCI_ERR_UNC_ATOMEG 0x01000000
+/* WARNING: DO NOT EDIT, AUTO-GENERATED CODE - SEE TOP FOR INSTRUCTIONS */
 #define PCI_ERR_UNC_TLPPRE 0x02000000
 #define PCI_ERR_UNCOR_MASK 8
 #define PCI_ERR_UNCOR_SEVER 12
-/* WARNING: DO NOT EDIT, AUTO-GENERATED CODE - SEE TOP FOR INSTRUCTIONS */
 #define PCI_ERR_COR_STATUS 16
+/* WARNING: DO NOT EDIT, AUTO-GENERATED CODE - SEE TOP FOR INSTRUCTIONS */
 #define PCI_ERR_COR_RCVR 0x00000001
 #define PCI_ERR_COR_BAD_TLP 0x00000040
 #define PCI_ERR_COR_BAD_DLLP 0x00000080
-/* WARNING: DO NOT EDIT, AUTO-GENERATED CODE - SEE TOP FOR INSTRUCTIONS */
 #define PCI_ERR_COR_REP_ROLL 0x00000100
+/* WARNING: DO NOT EDIT, AUTO-GENERATED CODE - SEE TOP FOR INSTRUCTIONS */
 #define PCI_ERR_COR_REP_TIMER 0x00001000
 #define PCI_ERR_COR_ADV_NFAT 0x00002000
 #define PCI_ERR_COR_INTERNAL 0x00004000
-/* WARNING: DO NOT EDIT, AUTO-GENERATED CODE - SEE TOP FOR INSTRUCTIONS */
 #define PCI_ERR_COR_LOG_OVER 0x00008000
+/* WARNING: DO NOT EDIT, AUTO-GENERATED CODE - SEE TOP FOR INSTRUCTIONS */
 #define PCI_ERR_COR_MASK 20
 #define PCI_ERR_CAP 24
 #define PCI_ERR_CAP_FEP(x) ((x) & 31)
-/* WARNING: DO NOT EDIT, AUTO-GENERATED CODE - SEE TOP FOR INSTRUCTIONS */
 #define PCI_ERR_CAP_ECRC_GENC 0x00000020
+/* WARNING: DO NOT EDIT, AUTO-GENERATED CODE - SEE TOP FOR INSTRUCTIONS */
 #define PCI_ERR_CAP_ECRC_GENE 0x00000040
 #define PCI_ERR_CAP_ECRC_CHKC 0x00000080
 #define PCI_ERR_CAP_ECRC_CHKE 0x00000100
-/* WARNING: DO NOT EDIT, AUTO-GENERATED CODE - SEE TOP FOR INSTRUCTIONS */
 #define PCI_ERR_HEADER_LOG 28
+/* WARNING: DO NOT EDIT, AUTO-GENERATED CODE - SEE TOP FOR INSTRUCTIONS */
 #define PCI_ERR_ROOT_COMMAND 44
 #define PCI_ERR_ROOT_CMD_COR_EN 0x00000001
 #define PCI_ERR_ROOT_CMD_NONFATAL_EN 0x00000002
-/* WARNING: DO NOT EDIT, AUTO-GENERATED CODE - SEE TOP FOR INSTRUCTIONS */
 #define PCI_ERR_ROOT_CMD_FATAL_EN 0x00000004
+/* WARNING: DO NOT EDIT, AUTO-GENERATED CODE - SEE TOP FOR INSTRUCTIONS */
 #define PCI_ERR_ROOT_STATUS 48
 #define PCI_ERR_ROOT_COR_RCV 0x00000001
 #define PCI_ERR_ROOT_MULTI_COR_RCV 0x00000002
-/* WARNING: DO NOT EDIT, AUTO-GENERATED CODE - SEE TOP FOR INSTRUCTIONS */
 #define PCI_ERR_ROOT_UNCOR_RCV 0x00000004
+/* WARNING: DO NOT EDIT, AUTO-GENERATED CODE - SEE TOP FOR INSTRUCTIONS */
 #define PCI_ERR_ROOT_MULTI_UNCOR_RCV 0x00000008
 #define PCI_ERR_ROOT_FIRST_FATAL 0x00000010
 #define PCI_ERR_ROOT_NONFATAL_RCV 0x00000020
-/* WARNING: DO NOT EDIT, AUTO-GENERATED CODE - SEE TOP FOR INSTRUCTIONS */
 #define PCI_ERR_ROOT_FATAL_RCV 0x00000040
+/* WARNING: DO NOT EDIT, AUTO-GENERATED CODE - SEE TOP FOR INSTRUCTIONS */
 #define PCI_ERR_ROOT_ERR_SRC 52
 #define PCI_VC_PORT_CAP1 4
 #define PCI_VC_CAP1_EVCC 0x00000007
-/* WARNING: DO NOT EDIT, AUTO-GENERATED CODE - SEE TOP FOR INSTRUCTIONS */
 #define PCI_VC_CAP1_LPEVCC 0x00000070
+/* WARNING: DO NOT EDIT, AUTO-GENERATED CODE - SEE TOP FOR INSTRUCTIONS */
 #define PCI_VC_CAP1_ARB_SIZE 0x00000c00
 #define PCI_VC_PORT_CAP2 8
 #define PCI_VC_CAP2_32_PHASE 0x00000002
-/* WARNING: DO NOT EDIT, AUTO-GENERATED CODE - SEE TOP FOR INSTRUCTIONS */
 #define PCI_VC_CAP2_64_PHASE 0x00000004
+/* WARNING: DO NOT EDIT, AUTO-GENERATED CODE - SEE TOP FOR INSTRUCTIONS */
 #define PCI_VC_CAP2_128_PHASE 0x00000008
 #define PCI_VC_CAP2_ARB_OFF 0xff000000
 #define PCI_VC_PORT_CTRL 12
-/* WARNING: DO NOT EDIT, AUTO-GENERATED CODE - SEE TOP FOR INSTRUCTIONS */
 #define PCI_VC_PORT_CTRL_LOAD_TABLE 0x00000001
+/* WARNING: DO NOT EDIT, AUTO-GENERATED CODE - SEE TOP FOR INSTRUCTIONS */
 #define PCI_VC_PORT_STATUS 14
 #define PCI_VC_PORT_STATUS_TABLE 0x00000001
 #define PCI_VC_RES_CAP 16
-/* WARNING: DO NOT EDIT, AUTO-GENERATED CODE - SEE TOP FOR INSTRUCTIONS */
 #define PCI_VC_RES_CAP_32_PHASE 0x00000002
+/* WARNING: DO NOT EDIT, AUTO-GENERATED CODE - SEE TOP FOR INSTRUCTIONS */
 #define PCI_VC_RES_CAP_64_PHASE 0x00000004
 #define PCI_VC_RES_CAP_128_PHASE 0x00000008
 #define PCI_VC_RES_CAP_128_PHASE_TB 0x00000010
-/* WARNING: DO NOT EDIT, AUTO-GENERATED CODE - SEE TOP FOR INSTRUCTIONS */
 #define PCI_VC_RES_CAP_256_PHASE 0x00000020
+/* WARNING: DO NOT EDIT, AUTO-GENERATED CODE - SEE TOP FOR INSTRUCTIONS */
 #define PCI_VC_RES_CAP_ARB_OFF 0xff000000
 #define PCI_VC_RES_CTRL 20
 #define PCI_VC_RES_CTRL_LOAD_TABLE 0x00010000
-/* WARNING: DO NOT EDIT, AUTO-GENERATED CODE - SEE TOP FOR INSTRUCTIONS */
 #define PCI_VC_RES_CTRL_ARB_SELECT 0x000e0000
+/* WARNING: DO NOT EDIT, AUTO-GENERATED CODE - SEE TOP FOR INSTRUCTIONS */
 #define PCI_VC_RES_CTRL_ID 0x07000000
 #define PCI_VC_RES_CTRL_ENABLE 0x80000000
 #define PCI_VC_RES_STATUS 26
-/* WARNING: DO NOT EDIT, AUTO-GENERATED CODE - SEE TOP FOR INSTRUCTIONS */
 #define PCI_VC_RES_STATUS_TABLE 0x00000001
+/* WARNING: DO NOT EDIT, AUTO-GENERATED CODE - SEE TOP FOR INSTRUCTIONS */
 #define PCI_VC_RES_STATUS_NEGO 0x00000002
 #define PCI_CAP_VC_BASE_SIZEOF 0x10
 #define PCI_CAP_VC_PER_VC_SIZEOF 0x0C
-/* WARNING: DO NOT EDIT, AUTO-GENERATED CODE - SEE TOP FOR INSTRUCTIONS */
 #define PCI_PWR_DSR 4
+/* WARNING: DO NOT EDIT, AUTO-GENERATED CODE - SEE TOP FOR INSTRUCTIONS */
 #define PCI_PWR_DATA 8
 #define PCI_PWR_DATA_BASE(x) ((x) & 0xff)
 #define PCI_PWR_DATA_SCALE(x) (((x) >> 8) & 3)
-/* WARNING: DO NOT EDIT, AUTO-GENERATED CODE - SEE TOP FOR INSTRUCTIONS */
 #define PCI_PWR_DATA_PM_SUB(x) (((x) >> 10) & 7)
+/* WARNING: DO NOT EDIT, AUTO-GENERATED CODE - SEE TOP FOR INSTRUCTIONS */
 #define PCI_PWR_DATA_PM_STATE(x) (((x) >> 13) & 3)
 #define PCI_PWR_DATA_TYPE(x) (((x) >> 15) & 7)
 #define PCI_PWR_DATA_RAIL(x) (((x) >> 18) & 7)
-/* WARNING: DO NOT EDIT, AUTO-GENERATED CODE - SEE TOP FOR INSTRUCTIONS */
 #define PCI_PWR_CAP 12
+/* WARNING: DO NOT EDIT, AUTO-GENERATED CODE - SEE TOP FOR INSTRUCTIONS */
 #define PCI_PWR_CAP_BUDGET(x) ((x) & 1)
 #define PCI_EXT_CAP_PWR_SIZEOF 16
 #define PCI_VNDR_HEADER 4
-/* WARNING: DO NOT EDIT, AUTO-GENERATED CODE - SEE TOP FOR INSTRUCTIONS */
 #define PCI_VNDR_HEADER_ID(x) ((x) & 0xffff)
+/* WARNING: DO NOT EDIT, AUTO-GENERATED CODE - SEE TOP FOR INSTRUCTIONS */
 #define PCI_VNDR_HEADER_REV(x) (((x) >> 16) & 0xf)
 #define PCI_VNDR_HEADER_LEN(x) (((x) >> 20) & 0xfff)
 #define HT_3BIT_CAP_MASK 0xE0
-/* WARNING: DO NOT EDIT, AUTO-GENERATED CODE - SEE TOP FOR INSTRUCTIONS */
 #define HT_CAPTYPE_SLAVE 0x00
+/* WARNING: DO NOT EDIT, AUTO-GENERATED CODE - SEE TOP FOR INSTRUCTIONS */
 #define HT_CAPTYPE_HOST 0x20
 #define HT_5BIT_CAP_MASK 0xF8
 #define HT_CAPTYPE_IRQ 0x80
-/* WARNING: DO NOT EDIT, AUTO-GENERATED CODE - SEE TOP FOR INSTRUCTIONS */
 #define HT_CAPTYPE_REMAPPING_40 0xA0
+/* WARNING: DO NOT EDIT, AUTO-GENERATED CODE - SEE TOP FOR INSTRUCTIONS */
 #define HT_CAPTYPE_REMAPPING_64 0xA2
 #define HT_CAPTYPE_UNITID_CLUMP 0x90
 #define HT_CAPTYPE_EXTCONF 0x98
-/* WARNING: DO NOT EDIT, AUTO-GENERATED CODE - SEE TOP FOR INSTRUCTIONS */
 #define HT_CAPTYPE_MSI_MAPPING 0xA8
+/* WARNING: DO NOT EDIT, AUTO-GENERATED CODE - SEE TOP FOR INSTRUCTIONS */
 #define HT_MSI_FLAGS 0x02
 #define HT_MSI_FLAGS_ENABLE 0x1
 #define HT_MSI_FLAGS_FIXED 0x2
-/* WARNING: DO NOT EDIT, AUTO-GENERATED CODE - SEE TOP FOR INSTRUCTIONS */
 #define HT_MSI_FIXED_ADDR 0x00000000FEE00000ULL
+/* WARNING: DO NOT EDIT, AUTO-GENERATED CODE - SEE TOP FOR INSTRUCTIONS */
 #define HT_MSI_ADDR_LO 0x04
 #define HT_MSI_ADDR_LO_MASK 0xFFF00000
 #define HT_MSI_ADDR_HI 0x08
-/* WARNING: DO NOT EDIT, AUTO-GENERATED CODE - SEE TOP FOR INSTRUCTIONS */
 #define HT_CAPTYPE_DIRECT_ROUTE 0xB0
+/* WARNING: DO NOT EDIT, AUTO-GENERATED CODE - SEE TOP FOR INSTRUCTIONS */
 #define HT_CAPTYPE_VCSET 0xB8
 #define HT_CAPTYPE_ERROR_RETRY 0xC0
 #define HT_CAPTYPE_GEN3 0xD0
-/* WARNING: DO NOT EDIT, AUTO-GENERATED CODE - SEE TOP FOR INSTRUCTIONS */
 #define HT_CAPTYPE_PM 0xE0
+/* WARNING: DO NOT EDIT, AUTO-GENERATED CODE - SEE TOP FOR INSTRUCTIONS */
 #define HT_CAP_SIZEOF_LONG 28
 #define HT_CAP_SIZEOF_SHORT 24
 #define PCI_ARI_CAP 0x04
-/* WARNING: DO NOT EDIT, AUTO-GENERATED CODE - SEE TOP FOR INSTRUCTIONS */
 #define PCI_ARI_CAP_MFVC 0x0001
+/* WARNING: DO NOT EDIT, AUTO-GENERATED CODE - SEE TOP FOR INSTRUCTIONS */
 #define PCI_ARI_CAP_ACS 0x0002
 #define PCI_ARI_CAP_NFN(x) (((x) >> 8) & 0xff)
 #define PCI_ARI_CTRL 0x06
-/* WARNING: DO NOT EDIT, AUTO-GENERATED CODE - SEE TOP FOR INSTRUCTIONS */
 #define PCI_ARI_CTRL_MFVC 0x0001
+/* WARNING: DO NOT EDIT, AUTO-GENERATED CODE - SEE TOP FOR INSTRUCTIONS */
 #define PCI_ARI_CTRL_ACS 0x0002
 #define PCI_ARI_CTRL_FG(x) (((x) >> 4) & 7)
 #define PCI_EXT_CAP_ARI_SIZEOF 8
-/* WARNING: DO NOT EDIT, AUTO-GENERATED CODE - SEE TOP FOR INSTRUCTIONS */
 #define PCI_ATS_CAP 0x04
+/* WARNING: DO NOT EDIT, AUTO-GENERATED CODE - SEE TOP FOR INSTRUCTIONS */
 #define PCI_ATS_CAP_QDEP(x) ((x) & 0x1f)
 #define PCI_ATS_MAX_QDEP 32
 #define PCI_ATS_CTRL 0x06
-/* WARNING: DO NOT EDIT, AUTO-GENERATED CODE - SEE TOP FOR INSTRUCTIONS */
 #define PCI_ATS_CTRL_ENABLE 0x8000
+/* WARNING: DO NOT EDIT, AUTO-GENERATED CODE - SEE TOP FOR INSTRUCTIONS */
 #define PCI_ATS_CTRL_STU(x) ((x) & 0x1f)
 #define PCI_ATS_MIN_STU 12
 #define PCI_EXT_CAP_ATS_SIZEOF 8
-/* WARNING: DO NOT EDIT, AUTO-GENERATED CODE - SEE TOP FOR INSTRUCTIONS */
 #define PCI_PRI_CTRL 0x04
+/* WARNING: DO NOT EDIT, AUTO-GENERATED CODE - SEE TOP FOR INSTRUCTIONS */
 #define PCI_PRI_CTRL_ENABLE 0x01
 #define PCI_PRI_CTRL_RESET 0x02
 #define PCI_PRI_STATUS 0x06
-/* WARNING: DO NOT EDIT, AUTO-GENERATED CODE - SEE TOP FOR INSTRUCTIONS */
 #define PCI_PRI_STATUS_RF 0x001
+/* WARNING: DO NOT EDIT, AUTO-GENERATED CODE - SEE TOP FOR INSTRUCTIONS */
 #define PCI_PRI_STATUS_UPRGI 0x002
 #define PCI_PRI_STATUS_STOPPED 0x100
 #define PCI_PRI_MAX_REQ 0x08
-/* WARNING: DO NOT EDIT, AUTO-GENERATED CODE - SEE TOP FOR INSTRUCTIONS */
 #define PCI_PRI_ALLOC_REQ 0x0c
+/* WARNING: DO NOT EDIT, AUTO-GENERATED CODE - SEE TOP FOR INSTRUCTIONS */
 #define PCI_EXT_CAP_PRI_SIZEOF 16
 #define PCI_PASID_CAP 0x04
 #define PCI_PASID_CAP_EXEC 0x02
-/* WARNING: DO NOT EDIT, AUTO-GENERATED CODE - SEE TOP FOR INSTRUCTIONS */
 #define PCI_PASID_CAP_PRIV 0x04
+/* WARNING: DO NOT EDIT, AUTO-GENERATED CODE - SEE TOP FOR INSTRUCTIONS */
 #define PCI_PASID_CTRL 0x06
 #define PCI_PASID_CTRL_ENABLE 0x01
 #define PCI_PASID_CTRL_EXEC 0x02
-/* WARNING: DO NOT EDIT, AUTO-GENERATED CODE - SEE TOP FOR INSTRUCTIONS */
 #define PCI_PASID_CTRL_PRIV 0x04
+/* WARNING: DO NOT EDIT, AUTO-GENERATED CODE - SEE TOP FOR INSTRUCTIONS */
 #define PCI_EXT_CAP_PASID_SIZEOF 8
 #define PCI_SRIOV_CAP 0x04
 #define PCI_SRIOV_CAP_VFM 0x01
-/* WARNING: DO NOT EDIT, AUTO-GENERATED CODE - SEE TOP FOR INSTRUCTIONS */
 #define PCI_SRIOV_CAP_INTR(x) ((x) >> 21)
+/* WARNING: DO NOT EDIT, AUTO-GENERATED CODE - SEE TOP FOR INSTRUCTIONS */
 #define PCI_SRIOV_CTRL 0x08
 #define PCI_SRIOV_CTRL_VFE 0x01
 #define PCI_SRIOV_CTRL_VFM 0x02
-/* WARNING: DO NOT EDIT, AUTO-GENERATED CODE - SEE TOP FOR INSTRUCTIONS */
 #define PCI_SRIOV_CTRL_INTR 0x04
+/* WARNING: DO NOT EDIT, AUTO-GENERATED CODE - SEE TOP FOR INSTRUCTIONS */
 #define PCI_SRIOV_CTRL_MSE 0x08
 #define PCI_SRIOV_CTRL_ARI 0x10
 #define PCI_SRIOV_STATUS 0x0a
-/* WARNING: DO NOT EDIT, AUTO-GENERATED CODE - SEE TOP FOR INSTRUCTIONS */
 #define PCI_SRIOV_STATUS_VFM 0x01
+/* WARNING: DO NOT EDIT, AUTO-GENERATED CODE - SEE TOP FOR INSTRUCTIONS */
 #define PCI_SRIOV_INITIAL_VF 0x0c
 #define PCI_SRIOV_TOTAL_VF 0x0e
 #define PCI_SRIOV_NUM_VF 0x10
-/* WARNING: DO NOT EDIT, AUTO-GENERATED CODE - SEE TOP FOR INSTRUCTIONS */
 #define PCI_SRIOV_FUNC_LINK 0x12
+/* WARNING: DO NOT EDIT, AUTO-GENERATED CODE - SEE TOP FOR INSTRUCTIONS */
 #define PCI_SRIOV_VF_OFFSET 0x14
 #define PCI_SRIOV_VF_STRIDE 0x16
 #define PCI_SRIOV_VF_DID 0x1a
-/* WARNING: DO NOT EDIT, AUTO-GENERATED CODE - SEE TOP FOR INSTRUCTIONS */
 #define PCI_SRIOV_SUP_PGSIZE 0x1c
+/* WARNING: DO NOT EDIT, AUTO-GENERATED CODE - SEE TOP FOR INSTRUCTIONS */
 #define PCI_SRIOV_SYS_PGSIZE 0x20
 #define PCI_SRIOV_BAR 0x24
 #define PCI_SRIOV_NUM_BARS 6
-/* WARNING: DO NOT EDIT, AUTO-GENERATED CODE - SEE TOP FOR INSTRUCTIONS */
 #define PCI_SRIOV_VFM 0x3c
+/* WARNING: DO NOT EDIT, AUTO-GENERATED CODE - SEE TOP FOR INSTRUCTIONS */
 #define PCI_SRIOV_VFM_BIR(x) ((x) & 7)
 #define PCI_SRIOV_VFM_OFFSET(x) ((x) & ~7)
 #define PCI_SRIOV_VFM_UA 0x0
-/* WARNING: DO NOT EDIT, AUTO-GENERATED CODE - SEE TOP FOR INSTRUCTIONS */
 #define PCI_SRIOV_VFM_MI 0x1
+/* WARNING: DO NOT EDIT, AUTO-GENERATED CODE - SEE TOP FOR INSTRUCTIONS */
 #define PCI_SRIOV_VFM_MO 0x2
 #define PCI_SRIOV_VFM_AV 0x3
 #define PCI_EXT_CAP_SRIOV_SIZEOF 64
-/* WARNING: DO NOT EDIT, AUTO-GENERATED CODE - SEE TOP FOR INSTRUCTIONS */
 #define PCI_LTR_MAX_SNOOP_LAT 0x4
+/* WARNING: DO NOT EDIT, AUTO-GENERATED CODE - SEE TOP FOR INSTRUCTIONS */
 #define PCI_LTR_MAX_NOSNOOP_LAT 0x6
 #define PCI_LTR_VALUE_MASK 0x000003ff
 #define PCI_LTR_SCALE_MASK 0x00001c00
-/* WARNING: DO NOT EDIT, AUTO-GENERATED CODE - SEE TOP FOR INSTRUCTIONS */
 #define PCI_LTR_SCALE_SHIFT 10
+/* WARNING: DO NOT EDIT, AUTO-GENERATED CODE - SEE TOP FOR INSTRUCTIONS */
 #define PCI_EXT_CAP_LTR_SIZEOF 8
 #define PCI_ACS_CAP 0x04
 #define PCI_ACS_SV 0x01
-/* WARNING: DO NOT EDIT, AUTO-GENERATED CODE - SEE TOP FOR INSTRUCTIONS */
 #define PCI_ACS_TB 0x02
+/* WARNING: DO NOT EDIT, AUTO-GENERATED CODE - SEE TOP FOR INSTRUCTIONS */
 #define PCI_ACS_RR 0x04
 #define PCI_ACS_CR 0x08
 #define PCI_ACS_UF 0x10
-/* WARNING: DO NOT EDIT, AUTO-GENERATED CODE - SEE TOP FOR INSTRUCTIONS */
 #define PCI_ACS_EC 0x20
+/* WARNING: DO NOT EDIT, AUTO-GENERATED CODE - SEE TOP FOR INSTRUCTIONS */
 #define PCI_ACS_DT 0x40
 #define PCI_ACS_EGRESS_BITS 0x05
 #define PCI_ACS_CTRL 0x06
-/* WARNING: DO NOT EDIT, AUTO-GENERATED CODE - SEE TOP FOR INSTRUCTIONS */
 #define PCI_ACS_EGRESS_CTL_V 0x08
+/* WARNING: DO NOT EDIT, AUTO-GENERATED CODE - SEE TOP FOR INSTRUCTIONS */
 #define PCI_VSEC_HDR 4
 #define PCI_VSEC_HDR_LEN_SHIFT 20
 #define PCI_SATA_REGS 4
-/* WARNING: DO NOT EDIT, AUTO-GENERATED CODE - SEE TOP FOR INSTRUCTIONS */
 #define PCI_SATA_REGS_MASK 0xF
+/* WARNING: DO NOT EDIT, AUTO-GENERATED CODE - SEE TOP FOR INSTRUCTIONS */
 #define PCI_SATA_REGS_INLINE 0xF
 #define PCI_SATA_SIZEOF_SHORT 8
 #define PCI_SATA_SIZEOF_LONG 16
-/* WARNING: DO NOT EDIT, AUTO-GENERATED CODE - SEE TOP FOR INSTRUCTIONS */
 #define PCI_REBAR_CTRL 8
+/* WARNING: DO NOT EDIT, AUTO-GENERATED CODE - SEE TOP FOR INSTRUCTIONS */
 #define PCI_REBAR_CTRL_NBAR_MASK (7 << 5)
 #define PCI_REBAR_CTRL_NBAR_SHIFT 5
 #define PCI_DPA_CAP 4
-/* WARNING: DO NOT EDIT, AUTO-GENERATED CODE - SEE TOP FOR INSTRUCTIONS */
 #define PCI_DPA_CAP_SUBSTATE_MASK 0x1F
+/* WARNING: DO NOT EDIT, AUTO-GENERATED CODE - SEE TOP FOR INSTRUCTIONS */
 #define PCI_DPA_BASE_SIZEOF 16
 #define PCI_TPH_CAP 4
 #define PCI_TPH_CAP_LOC_MASK 0x600
-/* WARNING: DO NOT EDIT, AUTO-GENERATED CODE - SEE TOP FOR INSTRUCTIONS */
 #define PCI_TPH_LOC_NONE 0x000
+/* WARNING: DO NOT EDIT, AUTO-GENERATED CODE - SEE TOP FOR INSTRUCTIONS */
 #define PCI_TPH_LOC_CAP 0x200
 #define PCI_TPH_LOC_MSIX 0x400
 #define PCI_TPH_CAP_ST_MASK 0x07FF0000
-/* WARNING: DO NOT EDIT, AUTO-GENERATED CODE - SEE TOP FOR INSTRUCTIONS */
 #define PCI_TPH_CAP_ST_SHIFT 16
+/* WARNING: DO NOT EDIT, AUTO-GENERATED CODE - SEE TOP FOR INSTRUCTIONS */
 #define PCI_TPH_BASE_SIZEOF 12
 #endif
diff --git a/libc/kernel/uapi/linux/perf_event.h b/libc/kernel/uapi/linux/perf_event.h
index ccefa74..0478470 100644
--- a/libc/kernel/uapi/linux/perf_event.h
+++ b/libc/kernel/uapi/linux/perf_event.h
@@ -89,90 +89,120 @@
   PERF_COUNT_SW_ALIGNMENT_FAULTS = 7,
   PERF_COUNT_SW_EMULATION_FAULTS = 8,
   PERF_COUNT_SW_DUMMY = 9,
-  PERF_COUNT_SW_MAX,
+  PERF_COUNT_SW_BPF_OUTPUT = 10,
 /* WARNING: DO NOT EDIT, AUTO-GENERATED CODE - SEE TOP FOR INSTRUCTIONS */
+  PERF_COUNT_SW_MAX,
 };
 enum perf_event_sample_format {
   PERF_SAMPLE_IP = 1U << 0,
-  PERF_SAMPLE_TID = 1U << 1,
 /* WARNING: DO NOT EDIT, AUTO-GENERATED CODE - SEE TOP FOR INSTRUCTIONS */
+  PERF_SAMPLE_TID = 1U << 1,
   PERF_SAMPLE_TIME = 1U << 2,
   PERF_SAMPLE_ADDR = 1U << 3,
   PERF_SAMPLE_READ = 1U << 4,
-  PERF_SAMPLE_CALLCHAIN = 1U << 5,
 /* WARNING: DO NOT EDIT, AUTO-GENERATED CODE - SEE TOP FOR INSTRUCTIONS */
+  PERF_SAMPLE_CALLCHAIN = 1U << 5,
   PERF_SAMPLE_ID = 1U << 6,
   PERF_SAMPLE_CPU = 1U << 7,
   PERF_SAMPLE_PERIOD = 1U << 8,
-  PERF_SAMPLE_STREAM_ID = 1U << 9,
 /* WARNING: DO NOT EDIT, AUTO-GENERATED CODE - SEE TOP FOR INSTRUCTIONS */
+  PERF_SAMPLE_STREAM_ID = 1U << 9,
   PERF_SAMPLE_RAW = 1U << 10,
   PERF_SAMPLE_BRANCH_STACK = 1U << 11,
   PERF_SAMPLE_REGS_USER = 1U << 12,
-  PERF_SAMPLE_STACK_USER = 1U << 13,
 /* WARNING: DO NOT EDIT, AUTO-GENERATED CODE - SEE TOP FOR INSTRUCTIONS */
+  PERF_SAMPLE_STACK_USER = 1U << 13,
   PERF_SAMPLE_WEIGHT = 1U << 14,
   PERF_SAMPLE_DATA_SRC = 1U << 15,
   PERF_SAMPLE_IDENTIFIER = 1U << 16,
-  PERF_SAMPLE_TRANSACTION = 1U << 17,
 /* WARNING: DO NOT EDIT, AUTO-GENERATED CODE - SEE TOP FOR INSTRUCTIONS */
-  PERF_SAMPLE_MAX = 1U << 18,
+  PERF_SAMPLE_TRANSACTION = 1U << 17,
+  PERF_SAMPLE_REGS_INTR = 1U << 18,
+  PERF_SAMPLE_MAX = 1U << 19,
+};
+/* WARNING: DO NOT EDIT, AUTO-GENERATED CODE - SEE TOP FOR INSTRUCTIONS */
+enum perf_branch_sample_type_shift {
+  PERF_SAMPLE_BRANCH_USER_SHIFT = 0,
+  PERF_SAMPLE_BRANCH_KERNEL_SHIFT = 1,
+  PERF_SAMPLE_BRANCH_HV_SHIFT = 2,
+/* WARNING: DO NOT EDIT, AUTO-GENERATED CODE - SEE TOP FOR INSTRUCTIONS */
+  PERF_SAMPLE_BRANCH_ANY_SHIFT = 3,
+  PERF_SAMPLE_BRANCH_ANY_CALL_SHIFT = 4,
+  PERF_SAMPLE_BRANCH_ANY_RETURN_SHIFT = 5,
+  PERF_SAMPLE_BRANCH_IND_CALL_SHIFT = 6,
+/* WARNING: DO NOT EDIT, AUTO-GENERATED CODE - SEE TOP FOR INSTRUCTIONS */
+  PERF_SAMPLE_BRANCH_ABORT_TX_SHIFT = 7,
+  PERF_SAMPLE_BRANCH_IN_TX_SHIFT = 8,
+  PERF_SAMPLE_BRANCH_NO_TX_SHIFT = 9,
+  PERF_SAMPLE_BRANCH_COND_SHIFT = 10,
+/* WARNING: DO NOT EDIT, AUTO-GENERATED CODE - SEE TOP FOR INSTRUCTIONS */
+  PERF_SAMPLE_BRANCH_CALL_STACK_SHIFT = 11,
+  PERF_SAMPLE_BRANCH_IND_JUMP_SHIFT = 12,
+  PERF_SAMPLE_BRANCH_CALL_SHIFT = 13,
+  PERF_SAMPLE_BRANCH_MAX_SHIFT
+/* WARNING: DO NOT EDIT, AUTO-GENERATED CODE - SEE TOP FOR INSTRUCTIONS */
 };
 enum perf_branch_sample_type {
-  PERF_SAMPLE_BRANCH_USER = 1U << 0,
+  PERF_SAMPLE_BRANCH_USER = 1U << PERF_SAMPLE_BRANCH_USER_SHIFT,
+  PERF_SAMPLE_BRANCH_KERNEL = 1U << PERF_SAMPLE_BRANCH_KERNEL_SHIFT,
 /* WARNING: DO NOT EDIT, AUTO-GENERATED CODE - SEE TOP FOR INSTRUCTIONS */
-  PERF_SAMPLE_BRANCH_KERNEL = 1U << 1,
-  PERF_SAMPLE_BRANCH_HV = 1U << 2,
-  PERF_SAMPLE_BRANCH_ANY = 1U << 3,
-  PERF_SAMPLE_BRANCH_ANY_CALL = 1U << 4,
+  PERF_SAMPLE_BRANCH_HV = 1U << PERF_SAMPLE_BRANCH_HV_SHIFT,
+  PERF_SAMPLE_BRANCH_ANY = 1U << PERF_SAMPLE_BRANCH_ANY_SHIFT,
+  PERF_SAMPLE_BRANCH_ANY_CALL = 1U << PERF_SAMPLE_BRANCH_ANY_CALL_SHIFT,
+  PERF_SAMPLE_BRANCH_ANY_RETURN = 1U << PERF_SAMPLE_BRANCH_ANY_RETURN_SHIFT,
 /* WARNING: DO NOT EDIT, AUTO-GENERATED CODE - SEE TOP FOR INSTRUCTIONS */
-  PERF_SAMPLE_BRANCH_ANY_RETURN = 1U << 5,
-  PERF_SAMPLE_BRANCH_IND_CALL = 1U << 6,
-  PERF_SAMPLE_BRANCH_ABORT_TX = 1U << 7,
-  PERF_SAMPLE_BRANCH_IN_TX = 1U << 8,
+  PERF_SAMPLE_BRANCH_IND_CALL = 1U << PERF_SAMPLE_BRANCH_IND_CALL_SHIFT,
+  PERF_SAMPLE_BRANCH_ABORT_TX = 1U << PERF_SAMPLE_BRANCH_ABORT_TX_SHIFT,
+  PERF_SAMPLE_BRANCH_IN_TX = 1U << PERF_SAMPLE_BRANCH_IN_TX_SHIFT,
+  PERF_SAMPLE_BRANCH_NO_TX = 1U << PERF_SAMPLE_BRANCH_NO_TX_SHIFT,
 /* WARNING: DO NOT EDIT, AUTO-GENERATED CODE - SEE TOP FOR INSTRUCTIONS */
-  PERF_SAMPLE_BRANCH_NO_TX = 1U << 9,
-  PERF_SAMPLE_BRANCH_COND = 1U << 10,
-  PERF_SAMPLE_BRANCH_MAX = 1U << 11,
+  PERF_SAMPLE_BRANCH_COND = 1U << PERF_SAMPLE_BRANCH_COND_SHIFT,
+  PERF_SAMPLE_BRANCH_CALL_STACK = 1U << PERF_SAMPLE_BRANCH_CALL_STACK_SHIFT,
+  PERF_SAMPLE_BRANCH_IND_JUMP = 1U << PERF_SAMPLE_BRANCH_IND_JUMP_SHIFT,
+  PERF_SAMPLE_BRANCH_CALL = 1U << PERF_SAMPLE_BRANCH_CALL_SHIFT,
+/* WARNING: DO NOT EDIT, AUTO-GENERATED CODE - SEE TOP FOR INSTRUCTIONS */
+  PERF_SAMPLE_BRANCH_MAX = 1U << PERF_SAMPLE_BRANCH_MAX_SHIFT,
 };
-/* WARNING: DO NOT EDIT, AUTO-GENERATED CODE - SEE TOP FOR INSTRUCTIONS */
 #define PERF_SAMPLE_BRANCH_PLM_ALL (PERF_SAMPLE_BRANCH_USER | PERF_SAMPLE_BRANCH_KERNEL | PERF_SAMPLE_BRANCH_HV)
 enum perf_sample_regs_abi {
+/* WARNING: DO NOT EDIT, AUTO-GENERATED CODE - SEE TOP FOR INSTRUCTIONS */
   PERF_SAMPLE_REGS_ABI_NONE = 0,
   PERF_SAMPLE_REGS_ABI_32 = 1,
-/* WARNING: DO NOT EDIT, AUTO-GENERATED CODE - SEE TOP FOR INSTRUCTIONS */
   PERF_SAMPLE_REGS_ABI_64 = 2,
 };
+/* WARNING: DO NOT EDIT, AUTO-GENERATED CODE - SEE TOP FOR INSTRUCTIONS */
 enum {
   PERF_TXN_ELISION = (1 << 0),
-/* WARNING: DO NOT EDIT, AUTO-GENERATED CODE - SEE TOP FOR INSTRUCTIONS */
   PERF_TXN_TRANSACTION = (1 << 1),
   PERF_TXN_SYNC = (1 << 2),
+/* WARNING: DO NOT EDIT, AUTO-GENERATED CODE - SEE TOP FOR INSTRUCTIONS */
   PERF_TXN_ASYNC = (1 << 3),
   PERF_TXN_RETRY = (1 << 4),
-/* WARNING: DO NOT EDIT, AUTO-GENERATED CODE - SEE TOP FOR INSTRUCTIONS */
   PERF_TXN_CONFLICT = (1 << 5),
   PERF_TXN_CAPACITY_WRITE = (1 << 6),
+/* WARNING: DO NOT EDIT, AUTO-GENERATED CODE - SEE TOP FOR INSTRUCTIONS */
   PERF_TXN_CAPACITY_READ = (1 << 7),
   PERF_TXN_MAX = (1 << 8),
-/* WARNING: DO NOT EDIT, AUTO-GENERATED CODE - SEE TOP FOR INSTRUCTIONS */
   PERF_TXN_ABORT_MASK = (0xffffffffULL << 32),
   PERF_TXN_ABORT_SHIFT = 32,
+/* WARNING: DO NOT EDIT, AUTO-GENERATED CODE - SEE TOP FOR INSTRUCTIONS */
 };
 enum perf_event_read_format {
-/* WARNING: DO NOT EDIT, AUTO-GENERATED CODE - SEE TOP FOR INSTRUCTIONS */
   PERF_FORMAT_TOTAL_TIME_ENABLED = 1U << 0,
   PERF_FORMAT_TOTAL_TIME_RUNNING = 1U << 1,
+/* WARNING: DO NOT EDIT, AUTO-GENERATED CODE - SEE TOP FOR INSTRUCTIONS */
   PERF_FORMAT_ID = 1U << 2,
   PERF_FORMAT_GROUP = 1U << 3,
-/* WARNING: DO NOT EDIT, AUTO-GENERATED CODE - SEE TOP FOR INSTRUCTIONS */
   PERF_FORMAT_MAX = 1U << 4,
 };
+/* WARNING: DO NOT EDIT, AUTO-GENERATED CODE - SEE TOP FOR INSTRUCTIONS */
 #define PERF_ATTR_SIZE_VER0 64
 #define PERF_ATTR_SIZE_VER1 72
-/* WARNING: DO NOT EDIT, AUTO-GENERATED CODE - SEE TOP FOR INSTRUCTIONS */
 #define PERF_ATTR_SIZE_VER2 80
 #define PERF_ATTR_SIZE_VER3 96
+/* WARNING: DO NOT EDIT, AUTO-GENERATED CODE - SEE TOP FOR INSTRUCTIONS */
+#define PERF_ATTR_SIZE_VER4 104
+#define PERF_ATTR_SIZE_VER5 112
 struct perf_event_attr {
   __u32 type;
 /* WARNING: DO NOT EDIT, AUTO-GENERATED CODE - SEE TOP FOR INSTRUCTIONS */
@@ -186,7 +216,7 @@
   __u64 sample_type;
   __u64 read_format;
 /* WARNING: DO NOT EDIT, AUTO-GENERATED CODE - SEE TOP FOR INSTRUCTIONS */
-  __u64 disabled : 1, inherit : 1, pinned : 1, exclusive : 1, exclude_user : 1, exclude_kernel : 1, exclude_hv : 1, exclude_idle : 1, mmap : 1, comm : 1, freq : 1, inherit_stat : 1, enable_on_exec : 1, task : 1, watermark : 1, precise_ip : 2, mmap_data : 1, sample_id_all : 1, exclude_host : 1, exclude_guest : 1, exclude_callchain_kernel : 1, exclude_callchain_user : 1, mmap2 : 1, comm_exec : 1, __reserved_1 : 39;
+  __u64 disabled : 1, inherit : 1, pinned : 1, exclusive : 1, exclude_user : 1, exclude_kernel : 1, exclude_hv : 1, exclude_idle : 1, mmap : 1, comm : 1, freq : 1, inherit_stat : 1, enable_on_exec : 1, task : 1, watermark : 1, precise_ip : 2, mmap_data : 1, sample_id_all : 1, exclude_host : 1, exclude_guest : 1, exclude_callchain_kernel : 1, exclude_callchain_user : 1, mmap2 : 1, comm_exec : 1, use_clockid : 1, context_switch : 1, __reserved_1 : 37;
   union {
     __u32 wakeup_events;
     __u32 wakeup_watermark;
@@ -207,19 +237,24 @@
   __u64 sample_regs_user;
 /* WARNING: DO NOT EDIT, AUTO-GENERATED CODE - SEE TOP FOR INSTRUCTIONS */
   __u32 sample_stack_user;
+  __s32 clockid;
+  __u64 sample_regs_intr;
+  __u32 aux_watermark;
+/* WARNING: DO NOT EDIT, AUTO-GENERATED CODE - SEE TOP FOR INSTRUCTIONS */
   __u32 __reserved_2;
 };
 #define perf_flags(attr) (* (& (attr)->read_format + 1))
-/* WARNING: DO NOT EDIT, AUTO-GENERATED CODE - SEE TOP FOR INSTRUCTIONS */
 #define PERF_EVENT_IOC_ENABLE _IO('$', 0)
+/* WARNING: DO NOT EDIT, AUTO-GENERATED CODE - SEE TOP FOR INSTRUCTIONS */
 #define PERF_EVENT_IOC_DISABLE _IO('$', 1)
 #define PERF_EVENT_IOC_REFRESH _IO('$', 2)
 #define PERF_EVENT_IOC_RESET _IO('$', 3)
-/* WARNING: DO NOT EDIT, AUTO-GENERATED CODE - SEE TOP FOR INSTRUCTIONS */
 #define PERF_EVENT_IOC_PERIOD _IOW('$', 4, __u64)
+/* WARNING: DO NOT EDIT, AUTO-GENERATED CODE - SEE TOP FOR INSTRUCTIONS */
 #define PERF_EVENT_IOC_SET_OUTPUT _IO('$', 5)
 #define PERF_EVENT_IOC_SET_FILTER _IOW('$', 6, char *)
 #define PERF_EVENT_IOC_ID _IOR('$', 7, __u64 *)
+#define PERF_EVENT_IOC_SET_BPF _IOW('$', 8, __u32)
 /* WARNING: DO NOT EDIT, AUTO-GENERATED CODE - SEE TOP FOR INSTRUCTIONS */
 enum perf_event_ioc_flags {
   PERF_IOC_FLAG_GROUP = 1U << 0,
@@ -253,18 +288,28 @@
 /* WARNING: DO NOT EDIT, AUTO-GENERATED CODE - SEE TOP FOR INSTRUCTIONS */
   __u64 data_head;
   __u64 data_tail;
+  __u64 data_offset;
+  __u64 data_size;
+/* WARNING: DO NOT EDIT, AUTO-GENERATED CODE - SEE TOP FOR INSTRUCTIONS */
+  __u64 aux_head;
+  __u64 aux_tail;
+  __u64 aux_offset;
+  __u64 aux_size;
+/* WARNING: DO NOT EDIT, AUTO-GENERATED CODE - SEE TOP FOR INSTRUCTIONS */
 };
 #define PERF_RECORD_MISC_CPUMODE_MASK (7 << 0)
-/* WARNING: DO NOT EDIT, AUTO-GENERATED CODE - SEE TOP FOR INSTRUCTIONS */
 #define PERF_RECORD_MISC_CPUMODE_UNKNOWN (0 << 0)
 #define PERF_RECORD_MISC_KERNEL (1 << 0)
+/* WARNING: DO NOT EDIT, AUTO-GENERATED CODE - SEE TOP FOR INSTRUCTIONS */
 #define PERF_RECORD_MISC_USER (2 << 0)
 #define PERF_RECORD_MISC_HYPERVISOR (3 << 0)
-/* WARNING: DO NOT EDIT, AUTO-GENERATED CODE - SEE TOP FOR INSTRUCTIONS */
 #define PERF_RECORD_MISC_GUEST_KERNEL (4 << 0)
 #define PERF_RECORD_MISC_GUEST_USER (5 << 0)
+/* WARNING: DO NOT EDIT, AUTO-GENERATED CODE - SEE TOP FOR INSTRUCTIONS */
+#define PERF_RECORD_MISC_PROC_MAP_PARSE_TIMEOUT (1 << 12)
 #define PERF_RECORD_MISC_MMAP_DATA (1 << 13)
 #define PERF_RECORD_MISC_COMM_EXEC (1 << 13)
+#define PERF_RECORD_MISC_SWITCH_OUT (1 << 13)
 /* WARNING: DO NOT EDIT, AUTO-GENERATED CODE - SEE TOP FOR INSTRUCTIONS */
 #define PERF_RECORD_MISC_EXACT_IP (1 << 14)
 #define PERF_RECORD_MISC_EXT_RESERVED (1 << 15)
@@ -288,87 +333,96 @@
 /* WARNING: DO NOT EDIT, AUTO-GENERATED CODE - SEE TOP FOR INSTRUCTIONS */
   PERF_RECORD_SAMPLE = 9,
   PERF_RECORD_MMAP2 = 10,
-  PERF_RECORD_MAX,
-};
+  PERF_RECORD_AUX = 11,
+  PERF_RECORD_ITRACE_START = 12,
 /* WARNING: DO NOT EDIT, AUTO-GENERATED CODE - SEE TOP FOR INSTRUCTIONS */
+  PERF_RECORD_LOST_SAMPLES = 13,
+  PERF_RECORD_SWITCH = 14,
+  PERF_RECORD_SWITCH_CPU_WIDE = 15,
+  PERF_RECORD_MAX,
+/* WARNING: DO NOT EDIT, AUTO-GENERATED CODE - SEE TOP FOR INSTRUCTIONS */
+};
 #define PERF_MAX_STACK_DEPTH 127
 enum perf_callchain_context {
   PERF_CONTEXT_HV = (__u64) - 32,
-  PERF_CONTEXT_KERNEL = (__u64) - 128,
 /* WARNING: DO NOT EDIT, AUTO-GENERATED CODE - SEE TOP FOR INSTRUCTIONS */
+  PERF_CONTEXT_KERNEL = (__u64) - 128,
   PERF_CONTEXT_USER = (__u64) - 512,
   PERF_CONTEXT_GUEST = (__u64) - 2048,
   PERF_CONTEXT_GUEST_KERNEL = (__u64) - 2176,
-  PERF_CONTEXT_GUEST_USER = (__u64) - 2560,
 /* WARNING: DO NOT EDIT, AUTO-GENERATED CODE - SEE TOP FOR INSTRUCTIONS */
+  PERF_CONTEXT_GUEST_USER = (__u64) - 2560,
   PERF_CONTEXT_MAX = (__u64) - 4095,
 };
+#define PERF_AUX_FLAG_TRUNCATED 0x01
+/* WARNING: DO NOT EDIT, AUTO-GENERATED CODE - SEE TOP FOR INSTRUCTIONS */
+#define PERF_AUX_FLAG_OVERWRITE 0x02
 #define PERF_FLAG_FD_NO_GROUP (1UL << 0)
 #define PERF_FLAG_FD_OUTPUT (1UL << 1)
-/* WARNING: DO NOT EDIT, AUTO-GENERATED CODE - SEE TOP FOR INSTRUCTIONS */
 #define PERF_FLAG_PID_CGROUP (1UL << 2)
+/* WARNING: DO NOT EDIT, AUTO-GENERATED CODE - SEE TOP FOR INSTRUCTIONS */
 #define PERF_FLAG_FD_CLOEXEC (1UL << 3)
 union perf_mem_data_src {
   __u64 val;
-/* WARNING: DO NOT EDIT, AUTO-GENERATED CODE - SEE TOP FOR INSTRUCTIONS */
   struct {
+/* WARNING: DO NOT EDIT, AUTO-GENERATED CODE - SEE TOP FOR INSTRUCTIONS */
     __u64 mem_op : 5, mem_lvl : 14, mem_snoop : 5, mem_lock : 2, mem_dtlb : 7, mem_rsvd : 31;
   };
 };
-/* WARNING: DO NOT EDIT, AUTO-GENERATED CODE - SEE TOP FOR INSTRUCTIONS */
 #define PERF_MEM_OP_NA 0x01
+/* WARNING: DO NOT EDIT, AUTO-GENERATED CODE - SEE TOP FOR INSTRUCTIONS */
 #define PERF_MEM_OP_LOAD 0x02
 #define PERF_MEM_OP_STORE 0x04
 #define PERF_MEM_OP_PFETCH 0x08
-/* WARNING: DO NOT EDIT, AUTO-GENERATED CODE - SEE TOP FOR INSTRUCTIONS */
 #define PERF_MEM_OP_EXEC 0x10
+/* WARNING: DO NOT EDIT, AUTO-GENERATED CODE - SEE TOP FOR INSTRUCTIONS */
 #define PERF_MEM_OP_SHIFT 0
 #define PERF_MEM_LVL_NA 0x01
 #define PERF_MEM_LVL_HIT 0x02
-/* WARNING: DO NOT EDIT, AUTO-GENERATED CODE - SEE TOP FOR INSTRUCTIONS */
 #define PERF_MEM_LVL_MISS 0x04
+/* WARNING: DO NOT EDIT, AUTO-GENERATED CODE - SEE TOP FOR INSTRUCTIONS */
 #define PERF_MEM_LVL_L1 0x08
 #define PERF_MEM_LVL_LFB 0x10
 #define PERF_MEM_LVL_L2 0x20
-/* WARNING: DO NOT EDIT, AUTO-GENERATED CODE - SEE TOP FOR INSTRUCTIONS */
 #define PERF_MEM_LVL_L3 0x40
+/* WARNING: DO NOT EDIT, AUTO-GENERATED CODE - SEE TOP FOR INSTRUCTIONS */
 #define PERF_MEM_LVL_LOC_RAM 0x80
 #define PERF_MEM_LVL_REM_RAM1 0x100
 #define PERF_MEM_LVL_REM_RAM2 0x200
-/* WARNING: DO NOT EDIT, AUTO-GENERATED CODE - SEE TOP FOR INSTRUCTIONS */
 #define PERF_MEM_LVL_REM_CCE1 0x400
+/* WARNING: DO NOT EDIT, AUTO-GENERATED CODE - SEE TOP FOR INSTRUCTIONS */
 #define PERF_MEM_LVL_REM_CCE2 0x800
 #define PERF_MEM_LVL_IO 0x1000
 #define PERF_MEM_LVL_UNC 0x2000
-/* WARNING: DO NOT EDIT, AUTO-GENERATED CODE - SEE TOP FOR INSTRUCTIONS */
 #define PERF_MEM_LVL_SHIFT 5
+/* WARNING: DO NOT EDIT, AUTO-GENERATED CODE - SEE TOP FOR INSTRUCTIONS */
 #define PERF_MEM_SNOOP_NA 0x01
 #define PERF_MEM_SNOOP_NONE 0x02
 #define PERF_MEM_SNOOP_HIT 0x04
-/* WARNING: DO NOT EDIT, AUTO-GENERATED CODE - SEE TOP FOR INSTRUCTIONS */
 #define PERF_MEM_SNOOP_MISS 0x08
+/* WARNING: DO NOT EDIT, AUTO-GENERATED CODE - SEE TOP FOR INSTRUCTIONS */
 #define PERF_MEM_SNOOP_HITM 0x10
 #define PERF_MEM_SNOOP_SHIFT 19
 #define PERF_MEM_LOCK_NA 0x01
-/* WARNING: DO NOT EDIT, AUTO-GENERATED CODE - SEE TOP FOR INSTRUCTIONS */
 #define PERF_MEM_LOCK_LOCKED 0x02
+/* WARNING: DO NOT EDIT, AUTO-GENERATED CODE - SEE TOP FOR INSTRUCTIONS */
 #define PERF_MEM_LOCK_SHIFT 24
 #define PERF_MEM_TLB_NA 0x01
 #define PERF_MEM_TLB_HIT 0x02
-/* WARNING: DO NOT EDIT, AUTO-GENERATED CODE - SEE TOP FOR INSTRUCTIONS */
 #define PERF_MEM_TLB_MISS 0x04
+/* WARNING: DO NOT EDIT, AUTO-GENERATED CODE - SEE TOP FOR INSTRUCTIONS */
 #define PERF_MEM_TLB_L1 0x08
 #define PERF_MEM_TLB_L2 0x10
 #define PERF_MEM_TLB_WK 0x20
-/* WARNING: DO NOT EDIT, AUTO-GENERATED CODE - SEE TOP FOR INSTRUCTIONS */
 #define PERF_MEM_TLB_OS 0x40
+/* WARNING: DO NOT EDIT, AUTO-GENERATED CODE - SEE TOP FOR INSTRUCTIONS */
 #define PERF_MEM_TLB_SHIFT 26
 #define PERF_MEM_S(a,s) (((__u64) PERF_MEM_ ##a ##_ ##s) << PERF_MEM_ ##a ##_SHIFT)
 struct perf_branch_entry {
-/* WARNING: DO NOT EDIT, AUTO-GENERATED CODE - SEE TOP FOR INSTRUCTIONS */
   __u64 from;
-  __u64 to;
-  __u64 mispred : 1, predicted : 1, in_tx : 1, abort : 1, reserved : 60;
-};
 /* WARNING: DO NOT EDIT, AUTO-GENERATED CODE - SEE TOP FOR INSTRUCTIONS */
+  __u64 to;
+  __u64 mispred : 1, predicted : 1, in_tx : 1, abort : 1, cycles : 16, reserved : 44;
+};
 #endif
+/* WARNING: DO NOT EDIT, AUTO-GENERATED CODE - SEE TOP FOR INSTRUCTIONS */
diff --git a/libc/kernel/uapi/linux/pkt_cls.h b/libc/kernel/uapi/linux/pkt_cls.h
index 8c87bae..99d9873 100644
--- a/libc/kernel/uapi/linux/pkt_cls.h
+++ b/libc/kernel/uapi/linux/pkt_cls.h
@@ -21,368 +21,358 @@
 #include <linux/types.h>
 #include <linux/pkt_sched.h>
 /* WARNING: DO NOT EDIT, AUTO-GENERATED CODE - SEE TOP FOR INSTRUCTIONS */
-#define _TC_MAKE32(x) ((x))
-#define _TC_MAKEMASK1(n) (_TC_MAKE32(1) << _TC_MAKE32(n))
-#define _TC_MAKEMASK(v,n) (_TC_MAKE32((_TC_MAKE32(1) << (v)) - 1) << _TC_MAKE32(n))
-#define _TC_MAKEVALUE(v,n) (_TC_MAKE32(v) << _TC_MAKE32(n))
-/* WARNING: DO NOT EDIT, AUTO-GENERATED CODE - SEE TOP FOR INSTRUCTIONS */
-#define _TC_GETVALUE(v,n,m) ((_TC_MAKE32(v) & _TC_MAKE32(m)) >> _TC_MAKE32(n))
-#define TC_MUNGED _TC_MAKEMASK1(0)
-#define SET_TC_MUNGED(v) (TC_MUNGED | (v & ~TC_MUNGED))
-#define CLR_TC_MUNGED(v) (v & ~TC_MUNGED)
-/* WARNING: DO NOT EDIT, AUTO-GENERATED CODE - SEE TOP FOR INSTRUCTIONS */
-#define TC_OK2MUNGE _TC_MAKEMASK1(1)
-#define SET_TC_OK2MUNGE(v) (TC_OK2MUNGE | (v & ~TC_OK2MUNGE))
-#define CLR_TC_OK2MUNGE(v) (v & ~TC_OK2MUNGE)
-#define S_TC_VERD _TC_MAKE32(2)
-/* WARNING: DO NOT EDIT, AUTO-GENERATED CODE - SEE TOP FOR INSTRUCTIONS */
-#define M_TC_VERD _TC_MAKEMASK(4, S_TC_VERD)
-#define G_TC_VERD(x) _TC_GETVALUE(x, S_TC_VERD, M_TC_VERD)
-#define V_TC_VERD(x) _TC_MAKEVALUE(x, S_TC_VERD)
-#define SET_TC_VERD(v,n) ((V_TC_VERD(n)) | (v & ~M_TC_VERD))
-/* WARNING: DO NOT EDIT, AUTO-GENERATED CODE - SEE TOP FOR INSTRUCTIONS */
-#define S_TC_FROM _TC_MAKE32(6)
-#define M_TC_FROM _TC_MAKEMASK(2, S_TC_FROM)
-#define G_TC_FROM(x) _TC_GETVALUE(x, S_TC_FROM, M_TC_FROM)
-#define V_TC_FROM(x) _TC_MAKEVALUE(x, S_TC_FROM)
-/* WARNING: DO NOT EDIT, AUTO-GENERATED CODE - SEE TOP FOR INSTRUCTIONS */
-#define SET_TC_FROM(v,n) ((V_TC_FROM(n)) | (v & ~M_TC_FROM))
-#define AT_STACK 0x0
-#define AT_INGRESS 0x1
-#define AT_EGRESS 0x2
-/* WARNING: DO NOT EDIT, AUTO-GENERATED CODE - SEE TOP FOR INSTRUCTIONS */
-#define TC_NCLS _TC_MAKEMASK1(8)
-#define SET_TC_NCLS(v) (TC_NCLS | (v & ~TC_NCLS))
-#define CLR_TC_NCLS(v) (v & ~TC_NCLS)
-#define S_TC_RTTL _TC_MAKE32(9)
-/* WARNING: DO NOT EDIT, AUTO-GENERATED CODE - SEE TOP FOR INSTRUCTIONS */
-#define M_TC_RTTL _TC_MAKEMASK(3, S_TC_RTTL)
-#define G_TC_RTTL(x) _TC_GETVALUE(x, S_TC_RTTL, M_TC_RTTL)
-#define V_TC_RTTL(x) _TC_MAKEVALUE(x, S_TC_RTTL)
-#define SET_TC_RTTL(v,n) ((V_TC_RTTL(n)) | (v & ~M_TC_RTTL))
-/* WARNING: DO NOT EDIT, AUTO-GENERATED CODE - SEE TOP FOR INSTRUCTIONS */
-#define S_TC_AT _TC_MAKE32(12)
-#define M_TC_AT _TC_MAKEMASK(2, S_TC_AT)
-#define G_TC_AT(x) _TC_GETVALUE(x, S_TC_AT, M_TC_AT)
-#define V_TC_AT(x) _TC_MAKEVALUE(x, S_TC_AT)
-/* WARNING: DO NOT EDIT, AUTO-GENERATED CODE - SEE TOP FOR INSTRUCTIONS */
-#define SET_TC_AT(v,n) ((V_TC_AT(n)) | (v & ~M_TC_AT))
 enum {
   TCA_ACT_UNSPEC,
   TCA_ACT_KIND,
-/* WARNING: DO NOT EDIT, AUTO-GENERATED CODE - SEE TOP FOR INSTRUCTIONS */
   TCA_ACT_OPTIONS,
+/* WARNING: DO NOT EDIT, AUTO-GENERATED CODE - SEE TOP FOR INSTRUCTIONS */
   TCA_ACT_INDEX,
   TCA_ACT_STATS,
   __TCA_ACT_MAX
-/* WARNING: DO NOT EDIT, AUTO-GENERATED CODE - SEE TOP FOR INSTRUCTIONS */
 };
+/* WARNING: DO NOT EDIT, AUTO-GENERATED CODE - SEE TOP FOR INSTRUCTIONS */
 #define TCA_ACT_MAX __TCA_ACT_MAX
 #define TCA_OLD_COMPAT (TCA_ACT_MAX + 1)
 #define TCA_ACT_MAX_PRIO 32
-/* WARNING: DO NOT EDIT, AUTO-GENERATED CODE - SEE TOP FOR INSTRUCTIONS */
 #define TCA_ACT_BIND 1
+/* WARNING: DO NOT EDIT, AUTO-GENERATED CODE - SEE TOP FOR INSTRUCTIONS */
 #define TCA_ACT_NOBIND 0
 #define TCA_ACT_UNBIND 1
 #define TCA_ACT_NOUNBIND 0
-/* WARNING: DO NOT EDIT, AUTO-GENERATED CODE - SEE TOP FOR INSTRUCTIONS */
 #define TCA_ACT_REPLACE 1
-#define TCA_ACT_NOREPLACE 0
-#define MAX_REC_LOOP 4
-#define MAX_RED_LOOP 4
 /* WARNING: DO NOT EDIT, AUTO-GENERATED CODE - SEE TOP FOR INSTRUCTIONS */
+#define TCA_ACT_NOREPLACE 0
 #define TC_ACT_UNSPEC (- 1)
 #define TC_ACT_OK 0
 #define TC_ACT_RECLASSIFY 1
-#define TC_ACT_SHOT 2
 /* WARNING: DO NOT EDIT, AUTO-GENERATED CODE - SEE TOP FOR INSTRUCTIONS */
+#define TC_ACT_SHOT 2
 #define TC_ACT_PIPE 3
 #define TC_ACT_STOLEN 4
 #define TC_ACT_QUEUED 5
-#define TC_ACT_REPEAT 6
 /* WARNING: DO NOT EDIT, AUTO-GENERATED CODE - SEE TOP FOR INSTRUCTIONS */
+#define TC_ACT_REPEAT 6
+#define TC_ACT_REDIRECT 7
 #define TC_ACT_JUMP 0x10000000
 enum {
+/* WARNING: DO NOT EDIT, AUTO-GENERATED CODE - SEE TOP FOR INSTRUCTIONS */
   TCA_ID_UNSPEC = 0,
   TCA_ID_POLICE = 1,
-/* WARNING: DO NOT EDIT, AUTO-GENERATED CODE - SEE TOP FOR INSTRUCTIONS */
   __TCA_ID_MAX = 255
 };
+/* WARNING: DO NOT EDIT, AUTO-GENERATED CODE - SEE TOP FOR INSTRUCTIONS */
 #define TCA_ID_MAX __TCA_ID_MAX
 struct tc_police {
-/* WARNING: DO NOT EDIT, AUTO-GENERATED CODE - SEE TOP FOR INSTRUCTIONS */
   __u32 index;
   int action;
+/* WARNING: DO NOT EDIT, AUTO-GENERATED CODE - SEE TOP FOR INSTRUCTIONS */
 #define TC_POLICE_UNSPEC TC_ACT_UNSPEC
 #define TC_POLICE_OK TC_ACT_OK
-/* WARNING: DO NOT EDIT, AUTO-GENERATED CODE - SEE TOP FOR INSTRUCTIONS */
 #define TC_POLICE_RECLASSIFY TC_ACT_RECLASSIFY
 #define TC_POLICE_SHOT TC_ACT_SHOT
+/* WARNING: DO NOT EDIT, AUTO-GENERATED CODE - SEE TOP FOR INSTRUCTIONS */
 #define TC_POLICE_PIPE TC_ACT_PIPE
   __u32 limit;
-/* WARNING: DO NOT EDIT, AUTO-GENERATED CODE - SEE TOP FOR INSTRUCTIONS */
   __u32 burst;
   __u32 mtu;
+/* WARNING: DO NOT EDIT, AUTO-GENERATED CODE - SEE TOP FOR INSTRUCTIONS */
   struct tc_ratespec rate;
   struct tc_ratespec peakrate;
-/* WARNING: DO NOT EDIT, AUTO-GENERATED CODE - SEE TOP FOR INSTRUCTIONS */
   int refcnt;
   int bindcnt;
+/* WARNING: DO NOT EDIT, AUTO-GENERATED CODE - SEE TOP FOR INSTRUCTIONS */
   __u32 capab;
 };
-/* WARNING: DO NOT EDIT, AUTO-GENERATED CODE - SEE TOP FOR INSTRUCTIONS */
 struct tcf_t {
   __u64 install;
+/* WARNING: DO NOT EDIT, AUTO-GENERATED CODE - SEE TOP FOR INSTRUCTIONS */
   __u64 lastuse;
   __u64 expires;
-/* WARNING: DO NOT EDIT, AUTO-GENERATED CODE - SEE TOP FOR INSTRUCTIONS */
 };
 struct tc_cnt {
+/* WARNING: DO NOT EDIT, AUTO-GENERATED CODE - SEE TOP FOR INSTRUCTIONS */
   int refcnt;
   int bindcnt;
-/* WARNING: DO NOT EDIT, AUTO-GENERATED CODE - SEE TOP FOR INSTRUCTIONS */
 };
 #define tc_gen __u32 index; __u32 capab; int action; int refcnt; int bindcnt
+/* WARNING: DO NOT EDIT, AUTO-GENERATED CODE - SEE TOP FOR INSTRUCTIONS */
 enum {
   TCA_POLICE_UNSPEC,
-/* WARNING: DO NOT EDIT, AUTO-GENERATED CODE - SEE TOP FOR INSTRUCTIONS */
   TCA_POLICE_TBF,
   TCA_POLICE_RATE,
+/* WARNING: DO NOT EDIT, AUTO-GENERATED CODE - SEE TOP FOR INSTRUCTIONS */
   TCA_POLICE_PEAKRATE,
   TCA_POLICE_AVRATE,
-/* WARNING: DO NOT EDIT, AUTO-GENERATED CODE - SEE TOP FOR INSTRUCTIONS */
   TCA_POLICE_RESULT,
   __TCA_POLICE_MAX
+/* WARNING: DO NOT EDIT, AUTO-GENERATED CODE - SEE TOP FOR INSTRUCTIONS */
 #define TCA_POLICE_RESULT TCA_POLICE_RESULT
 };
-/* WARNING: DO NOT EDIT, AUTO-GENERATED CODE - SEE TOP FOR INSTRUCTIONS */
 #define TCA_POLICE_MAX (__TCA_POLICE_MAX - 1)
 #define TC_U32_HTID(h) ((h) & 0xFFF00000)
+/* WARNING: DO NOT EDIT, AUTO-GENERATED CODE - SEE TOP FOR INSTRUCTIONS */
 #define TC_U32_USERHTID(h) (TC_U32_HTID(h) >> 20)
 #define TC_U32_HASH(h) (((h) >> 12) & 0xFF)
-/* WARNING: DO NOT EDIT, AUTO-GENERATED CODE - SEE TOP FOR INSTRUCTIONS */
 #define TC_U32_NODE(h) ((h) & 0xFFF)
 #define TC_U32_KEY(h) ((h) & 0xFFFFF)
+/* WARNING: DO NOT EDIT, AUTO-GENERATED CODE - SEE TOP FOR INSTRUCTIONS */
 #define TC_U32_UNSPEC 0
 #define TC_U32_ROOT (0xFFF00000)
-/* WARNING: DO NOT EDIT, AUTO-GENERATED CODE - SEE TOP FOR INSTRUCTIONS */
 enum {
   TCA_U32_UNSPEC,
+/* WARNING: DO NOT EDIT, AUTO-GENERATED CODE - SEE TOP FOR INSTRUCTIONS */
   TCA_U32_CLASSID,
   TCA_U32_HASH,
-/* WARNING: DO NOT EDIT, AUTO-GENERATED CODE - SEE TOP FOR INSTRUCTIONS */
   TCA_U32_LINK,
   TCA_U32_DIVISOR,
+/* WARNING: DO NOT EDIT, AUTO-GENERATED CODE - SEE TOP FOR INSTRUCTIONS */
   TCA_U32_SEL,
   TCA_U32_POLICE,
-/* WARNING: DO NOT EDIT, AUTO-GENERATED CODE - SEE TOP FOR INSTRUCTIONS */
   TCA_U32_ACT,
   TCA_U32_INDEV,
+/* WARNING: DO NOT EDIT, AUTO-GENERATED CODE - SEE TOP FOR INSTRUCTIONS */
   TCA_U32_PCNT,
   TCA_U32_MARK,
-/* WARNING: DO NOT EDIT, AUTO-GENERATED CODE - SEE TOP FOR INSTRUCTIONS */
   __TCA_U32_MAX
 };
+/* WARNING: DO NOT EDIT, AUTO-GENERATED CODE - SEE TOP FOR INSTRUCTIONS */
 #define TCA_U32_MAX (__TCA_U32_MAX - 1)
 struct tc_u32_key {
-/* WARNING: DO NOT EDIT, AUTO-GENERATED CODE - SEE TOP FOR INSTRUCTIONS */
   __be32 mask;
   __be32 val;
+/* WARNING: DO NOT EDIT, AUTO-GENERATED CODE - SEE TOP FOR INSTRUCTIONS */
   int off;
   int offmask;
-/* WARNING: DO NOT EDIT, AUTO-GENERATED CODE - SEE TOP FOR INSTRUCTIONS */
 };
 struct tc_u32_sel {
+/* WARNING: DO NOT EDIT, AUTO-GENERATED CODE - SEE TOP FOR INSTRUCTIONS */
   unsigned char flags;
   unsigned char offshift;
-/* WARNING: DO NOT EDIT, AUTO-GENERATED CODE - SEE TOP FOR INSTRUCTIONS */
   unsigned char nkeys;
   __be16 offmask;
+/* WARNING: DO NOT EDIT, AUTO-GENERATED CODE - SEE TOP FOR INSTRUCTIONS */
   __u16 off;
   short offoff;
-/* WARNING: DO NOT EDIT, AUTO-GENERATED CODE - SEE TOP FOR INSTRUCTIONS */
   short hoff;
   __be32 hmask;
+/* WARNING: DO NOT EDIT, AUTO-GENERATED CODE - SEE TOP FOR INSTRUCTIONS */
   struct tc_u32_key keys[0];
 };
-/* WARNING: DO NOT EDIT, AUTO-GENERATED CODE - SEE TOP FOR INSTRUCTIONS */
 struct tc_u32_mark {
   __u32 val;
+/* WARNING: DO NOT EDIT, AUTO-GENERATED CODE - SEE TOP FOR INSTRUCTIONS */
   __u32 mask;
   __u32 success;
-/* WARNING: DO NOT EDIT, AUTO-GENERATED CODE - SEE TOP FOR INSTRUCTIONS */
 };
 struct tc_u32_pcnt {
+/* WARNING: DO NOT EDIT, AUTO-GENERATED CODE - SEE TOP FOR INSTRUCTIONS */
   __u64 rcnt;
   __u64 rhit;
-/* WARNING: DO NOT EDIT, AUTO-GENERATED CODE - SEE TOP FOR INSTRUCTIONS */
   __u64 kcnts[0];
 };
+/* WARNING: DO NOT EDIT, AUTO-GENERATED CODE - SEE TOP FOR INSTRUCTIONS */
 #define TC_U32_TERMINAL 1
 #define TC_U32_OFFSET 2
-/* WARNING: DO NOT EDIT, AUTO-GENERATED CODE - SEE TOP FOR INSTRUCTIONS */
 #define TC_U32_VAROFFSET 4
 #define TC_U32_EAT 8
+/* WARNING: DO NOT EDIT, AUTO-GENERATED CODE - SEE TOP FOR INSTRUCTIONS */
 #define TC_U32_MAXDEPTH 8
 enum {
-/* WARNING: DO NOT EDIT, AUTO-GENERATED CODE - SEE TOP FOR INSTRUCTIONS */
   TCA_RSVP_UNSPEC,
   TCA_RSVP_CLASSID,
+/* WARNING: DO NOT EDIT, AUTO-GENERATED CODE - SEE TOP FOR INSTRUCTIONS */
   TCA_RSVP_DST,
   TCA_RSVP_SRC,
-/* WARNING: DO NOT EDIT, AUTO-GENERATED CODE - SEE TOP FOR INSTRUCTIONS */
   TCA_RSVP_PINFO,
   TCA_RSVP_POLICE,
+/* WARNING: DO NOT EDIT, AUTO-GENERATED CODE - SEE TOP FOR INSTRUCTIONS */
   TCA_RSVP_ACT,
   __TCA_RSVP_MAX
-/* WARNING: DO NOT EDIT, AUTO-GENERATED CODE - SEE TOP FOR INSTRUCTIONS */
 };
 #define TCA_RSVP_MAX (__TCA_RSVP_MAX - 1)
+/* WARNING: DO NOT EDIT, AUTO-GENERATED CODE - SEE TOP FOR INSTRUCTIONS */
 struct tc_rsvp_gpi {
   __u32 key;
-/* WARNING: DO NOT EDIT, AUTO-GENERATED CODE - SEE TOP FOR INSTRUCTIONS */
   __u32 mask;
   int offset;
+/* WARNING: DO NOT EDIT, AUTO-GENERATED CODE - SEE TOP FOR INSTRUCTIONS */
 };
 struct tc_rsvp_pinfo {
-/* WARNING: DO NOT EDIT, AUTO-GENERATED CODE - SEE TOP FOR INSTRUCTIONS */
   struct tc_rsvp_gpi dpi;
   struct tc_rsvp_gpi spi;
+/* WARNING: DO NOT EDIT, AUTO-GENERATED CODE - SEE TOP FOR INSTRUCTIONS */
   __u8 protocol;
   __u8 tunnelid;
-/* WARNING: DO NOT EDIT, AUTO-GENERATED CODE - SEE TOP FOR INSTRUCTIONS */
   __u8 tunnelhdr;
   __u8 pad;
+/* WARNING: DO NOT EDIT, AUTO-GENERATED CODE - SEE TOP FOR INSTRUCTIONS */
 };
 enum {
-/* WARNING: DO NOT EDIT, AUTO-GENERATED CODE - SEE TOP FOR INSTRUCTIONS */
   TCA_ROUTE4_UNSPEC,
   TCA_ROUTE4_CLASSID,
+/* WARNING: DO NOT EDIT, AUTO-GENERATED CODE - SEE TOP FOR INSTRUCTIONS */
   TCA_ROUTE4_TO,
   TCA_ROUTE4_FROM,
-/* WARNING: DO NOT EDIT, AUTO-GENERATED CODE - SEE TOP FOR INSTRUCTIONS */
   TCA_ROUTE4_IIF,
   TCA_ROUTE4_POLICE,
+/* WARNING: DO NOT EDIT, AUTO-GENERATED CODE - SEE TOP FOR INSTRUCTIONS */
   TCA_ROUTE4_ACT,
   __TCA_ROUTE4_MAX
-/* WARNING: DO NOT EDIT, AUTO-GENERATED CODE - SEE TOP FOR INSTRUCTIONS */
 };
 #define TCA_ROUTE4_MAX (__TCA_ROUTE4_MAX - 1)
+/* WARNING: DO NOT EDIT, AUTO-GENERATED CODE - SEE TOP FOR INSTRUCTIONS */
 enum {
   TCA_FW_UNSPEC,
-/* WARNING: DO NOT EDIT, AUTO-GENERATED CODE - SEE TOP FOR INSTRUCTIONS */
   TCA_FW_CLASSID,
   TCA_FW_POLICE,
+/* WARNING: DO NOT EDIT, AUTO-GENERATED CODE - SEE TOP FOR INSTRUCTIONS */
   TCA_FW_INDEV,
   TCA_FW_ACT,
-/* WARNING: DO NOT EDIT, AUTO-GENERATED CODE - SEE TOP FOR INSTRUCTIONS */
   TCA_FW_MASK,
   __TCA_FW_MAX
+/* WARNING: DO NOT EDIT, AUTO-GENERATED CODE - SEE TOP FOR INSTRUCTIONS */
 };
 #define TCA_FW_MAX (__TCA_FW_MAX - 1)
-/* WARNING: DO NOT EDIT, AUTO-GENERATED CODE - SEE TOP FOR INSTRUCTIONS */
 enum {
   TCA_TCINDEX_UNSPEC,
+/* WARNING: DO NOT EDIT, AUTO-GENERATED CODE - SEE TOP FOR INSTRUCTIONS */
   TCA_TCINDEX_HASH,
   TCA_TCINDEX_MASK,
-/* WARNING: DO NOT EDIT, AUTO-GENERATED CODE - SEE TOP FOR INSTRUCTIONS */
   TCA_TCINDEX_SHIFT,
   TCA_TCINDEX_FALL_THROUGH,
+/* WARNING: DO NOT EDIT, AUTO-GENERATED CODE - SEE TOP FOR INSTRUCTIONS */
   TCA_TCINDEX_CLASSID,
   TCA_TCINDEX_POLICE,
-/* WARNING: DO NOT EDIT, AUTO-GENERATED CODE - SEE TOP FOR INSTRUCTIONS */
   TCA_TCINDEX_ACT,
   __TCA_TCINDEX_MAX
+/* WARNING: DO NOT EDIT, AUTO-GENERATED CODE - SEE TOP FOR INSTRUCTIONS */
 };
 #define TCA_TCINDEX_MAX (__TCA_TCINDEX_MAX - 1)
-/* WARNING: DO NOT EDIT, AUTO-GENERATED CODE - SEE TOP FOR INSTRUCTIONS */
 enum {
   FLOW_KEY_SRC,
+/* WARNING: DO NOT EDIT, AUTO-GENERATED CODE - SEE TOP FOR INSTRUCTIONS */
   FLOW_KEY_DST,
   FLOW_KEY_PROTO,
-/* WARNING: DO NOT EDIT, AUTO-GENERATED CODE - SEE TOP FOR INSTRUCTIONS */
   FLOW_KEY_PROTO_SRC,
   FLOW_KEY_PROTO_DST,
+/* WARNING: DO NOT EDIT, AUTO-GENERATED CODE - SEE TOP FOR INSTRUCTIONS */
   FLOW_KEY_IIF,
   FLOW_KEY_PRIORITY,
-/* WARNING: DO NOT EDIT, AUTO-GENERATED CODE - SEE TOP FOR INSTRUCTIONS */
   FLOW_KEY_MARK,
   FLOW_KEY_NFCT,
+/* WARNING: DO NOT EDIT, AUTO-GENERATED CODE - SEE TOP FOR INSTRUCTIONS */
   FLOW_KEY_NFCT_SRC,
   FLOW_KEY_NFCT_DST,
-/* WARNING: DO NOT EDIT, AUTO-GENERATED CODE - SEE TOP FOR INSTRUCTIONS */
   FLOW_KEY_NFCT_PROTO_SRC,
   FLOW_KEY_NFCT_PROTO_DST,
+/* WARNING: DO NOT EDIT, AUTO-GENERATED CODE - SEE TOP FOR INSTRUCTIONS */
   FLOW_KEY_RTCLASSID,
   FLOW_KEY_SKUID,
-/* WARNING: DO NOT EDIT, AUTO-GENERATED CODE - SEE TOP FOR INSTRUCTIONS */
   FLOW_KEY_SKGID,
   FLOW_KEY_VLAN_TAG,
+/* WARNING: DO NOT EDIT, AUTO-GENERATED CODE - SEE TOP FOR INSTRUCTIONS */
   FLOW_KEY_RXHASH,
   __FLOW_KEY_MAX,
-/* WARNING: DO NOT EDIT, AUTO-GENERATED CODE - SEE TOP FOR INSTRUCTIONS */
 };
 #define FLOW_KEY_MAX (__FLOW_KEY_MAX - 1)
+/* WARNING: DO NOT EDIT, AUTO-GENERATED CODE - SEE TOP FOR INSTRUCTIONS */
 enum {
   FLOW_MODE_MAP,
-/* WARNING: DO NOT EDIT, AUTO-GENERATED CODE - SEE TOP FOR INSTRUCTIONS */
   FLOW_MODE_HASH,
 };
+/* WARNING: DO NOT EDIT, AUTO-GENERATED CODE - SEE TOP FOR INSTRUCTIONS */
 enum {
   TCA_FLOW_UNSPEC,
-/* WARNING: DO NOT EDIT, AUTO-GENERATED CODE - SEE TOP FOR INSTRUCTIONS */
   TCA_FLOW_KEYS,
   TCA_FLOW_MODE,
+/* WARNING: DO NOT EDIT, AUTO-GENERATED CODE - SEE TOP FOR INSTRUCTIONS */
   TCA_FLOW_BASECLASS,
   TCA_FLOW_RSHIFT,
-/* WARNING: DO NOT EDIT, AUTO-GENERATED CODE - SEE TOP FOR INSTRUCTIONS */
   TCA_FLOW_ADDEND,
   TCA_FLOW_MASK,
+/* WARNING: DO NOT EDIT, AUTO-GENERATED CODE - SEE TOP FOR INSTRUCTIONS */
   TCA_FLOW_XOR,
   TCA_FLOW_DIVISOR,
-/* WARNING: DO NOT EDIT, AUTO-GENERATED CODE - SEE TOP FOR INSTRUCTIONS */
   TCA_FLOW_ACT,
   TCA_FLOW_POLICE,
+/* WARNING: DO NOT EDIT, AUTO-GENERATED CODE - SEE TOP FOR INSTRUCTIONS */
   TCA_FLOW_EMATCHES,
   TCA_FLOW_PERTURB,
-/* WARNING: DO NOT EDIT, AUTO-GENERATED CODE - SEE TOP FOR INSTRUCTIONS */
   __TCA_FLOW_MAX
 };
+/* WARNING: DO NOT EDIT, AUTO-GENERATED CODE - SEE TOP FOR INSTRUCTIONS */
 #define TCA_FLOW_MAX (__TCA_FLOW_MAX - 1)
 enum {
-/* WARNING: DO NOT EDIT, AUTO-GENERATED CODE - SEE TOP FOR INSTRUCTIONS */
   TCA_BASIC_UNSPEC,
   TCA_BASIC_CLASSID,
+/* WARNING: DO NOT EDIT, AUTO-GENERATED CODE - SEE TOP FOR INSTRUCTIONS */
   TCA_BASIC_EMATCHES,
   TCA_BASIC_ACT,
-/* WARNING: DO NOT EDIT, AUTO-GENERATED CODE - SEE TOP FOR INSTRUCTIONS */
   TCA_BASIC_POLICE,
   __TCA_BASIC_MAX
+/* WARNING: DO NOT EDIT, AUTO-GENERATED CODE - SEE TOP FOR INSTRUCTIONS */
 };
 #define TCA_BASIC_MAX (__TCA_BASIC_MAX - 1)
-/* WARNING: DO NOT EDIT, AUTO-GENERATED CODE - SEE TOP FOR INSTRUCTIONS */
 enum {
   TCA_CGROUP_UNSPEC,
+/* WARNING: DO NOT EDIT, AUTO-GENERATED CODE - SEE TOP FOR INSTRUCTIONS */
   TCA_CGROUP_ACT,
   TCA_CGROUP_POLICE,
-/* WARNING: DO NOT EDIT, AUTO-GENERATED CODE - SEE TOP FOR INSTRUCTIONS */
   TCA_CGROUP_EMATCHES,
   __TCA_CGROUP_MAX,
+/* WARNING: DO NOT EDIT, AUTO-GENERATED CODE - SEE TOP FOR INSTRUCTIONS */
 };
 #define TCA_CGROUP_MAX (__TCA_CGROUP_MAX - 1)
-/* WARNING: DO NOT EDIT, AUTO-GENERATED CODE - SEE TOP FOR INSTRUCTIONS */
+#define TCA_BPF_FLAG_ACT_DIRECT (1 << 0)
 enum {
+/* WARNING: DO NOT EDIT, AUTO-GENERATED CODE - SEE TOP FOR INSTRUCTIONS */
   TCA_BPF_UNSPEC,
   TCA_BPF_ACT,
   TCA_BPF_POLICE,
-/* WARNING: DO NOT EDIT, AUTO-GENERATED CODE - SEE TOP FOR INSTRUCTIONS */
   TCA_BPF_CLASSID,
+/* WARNING: DO NOT EDIT, AUTO-GENERATED CODE - SEE TOP FOR INSTRUCTIONS */
   TCA_BPF_OPS_LEN,
   TCA_BPF_OPS,
-  __TCA_BPF_MAX,
+  TCA_BPF_FD,
+  TCA_BPF_NAME,
 /* WARNING: DO NOT EDIT, AUTO-GENERATED CODE - SEE TOP FOR INSTRUCTIONS */
+  TCA_BPF_FLAGS,
+  __TCA_BPF_MAX,
 };
 #define TCA_BPF_MAX (__TCA_BPF_MAX - 1)
+/* WARNING: DO NOT EDIT, AUTO-GENERATED CODE - SEE TOP FOR INSTRUCTIONS */
+enum {
+  TCA_FLOWER_UNSPEC,
+  TCA_FLOWER_CLASSID,
+  TCA_FLOWER_INDEV,
+/* WARNING: DO NOT EDIT, AUTO-GENERATED CODE - SEE TOP FOR INSTRUCTIONS */
+  TCA_FLOWER_ACT,
+  TCA_FLOWER_KEY_ETH_DST,
+  TCA_FLOWER_KEY_ETH_DST_MASK,
+  TCA_FLOWER_KEY_ETH_SRC,
+/* WARNING: DO NOT EDIT, AUTO-GENERATED CODE - SEE TOP FOR INSTRUCTIONS */
+  TCA_FLOWER_KEY_ETH_SRC_MASK,
+  TCA_FLOWER_KEY_ETH_TYPE,
+  TCA_FLOWER_KEY_IP_PROTO,
+  TCA_FLOWER_KEY_IPV4_SRC,
+/* WARNING: DO NOT EDIT, AUTO-GENERATED CODE - SEE TOP FOR INSTRUCTIONS */
+  TCA_FLOWER_KEY_IPV4_SRC_MASK,
+  TCA_FLOWER_KEY_IPV4_DST,
+  TCA_FLOWER_KEY_IPV4_DST_MASK,
+  TCA_FLOWER_KEY_IPV6_SRC,
+/* WARNING: DO NOT EDIT, AUTO-GENERATED CODE - SEE TOP FOR INSTRUCTIONS */
+  TCA_FLOWER_KEY_IPV6_SRC_MASK,
+  TCA_FLOWER_KEY_IPV6_DST,
+  TCA_FLOWER_KEY_IPV6_DST_MASK,
+  TCA_FLOWER_KEY_TCP_SRC,
+/* WARNING: DO NOT EDIT, AUTO-GENERATED CODE - SEE TOP FOR INSTRUCTIONS */
+  TCA_FLOWER_KEY_TCP_DST,
+  TCA_FLOWER_KEY_UDP_SRC,
+  TCA_FLOWER_KEY_UDP_DST,
+  __TCA_FLOWER_MAX,
+/* WARNING: DO NOT EDIT, AUTO-GENERATED CODE - SEE TOP FOR INSTRUCTIONS */
+};
+#define TCA_FLOWER_MAX (__TCA_FLOWER_MAX - 1)
 struct tcf_ematch_tree_hdr {
   __u16 nmatches;
 /* WARNING: DO NOT EDIT, AUTO-GENERATED CODE - SEE TOP FOR INSTRUCTIONS */
diff --git a/libc/kernel/uapi/linux/pkt_sched.h b/libc/kernel/uapi/linux/pkt_sched.h
index 518f83f..14ffcd4 100644
--- a/libc/kernel/uapi/linux/pkt_sched.h
+++ b/libc/kernel/uapi/linux/pkt_sched.h
@@ -227,441 +227,446 @@
   TCA_GRED_DPS,
 /* WARNING: DO NOT EDIT, AUTO-GENERATED CODE - SEE TOP FOR INSTRUCTIONS */
   TCA_GRED_MAX_P,
+  TCA_GRED_LIMIT,
   __TCA_GRED_MAX,
 };
-#define TCA_GRED_MAX (__TCA_GRED_MAX - 1)
 /* WARNING: DO NOT EDIT, AUTO-GENERATED CODE - SEE TOP FOR INSTRUCTIONS */
+#define TCA_GRED_MAX (__TCA_GRED_MAX - 1)
 struct tc_gred_qopt {
   __u32 limit;
   __u32 qth_min;
-  __u32 qth_max;
 /* WARNING: DO NOT EDIT, AUTO-GENERATED CODE - SEE TOP FOR INSTRUCTIONS */
+  __u32 qth_max;
   __u32 DP;
   __u32 backlog;
   __u32 qave;
-  __u32 forced;
 /* WARNING: DO NOT EDIT, AUTO-GENERATED CODE - SEE TOP FOR INSTRUCTIONS */
+  __u32 forced;
   __u32 early;
   __u32 other;
   __u32 pdrop;
-  __u8 Wlog;
 /* WARNING: DO NOT EDIT, AUTO-GENERATED CODE - SEE TOP FOR INSTRUCTIONS */
+  __u8 Wlog;
   __u8 Plog;
   __u8 Scell_log;
   __u8 prio;
-  __u32 packets;
 /* WARNING: DO NOT EDIT, AUTO-GENERATED CODE - SEE TOP FOR INSTRUCTIONS */
+  __u32 packets;
   __u32 bytesin;
 };
 struct tc_gred_sopt {
-  __u32 DPs;
 /* WARNING: DO NOT EDIT, AUTO-GENERATED CODE - SEE TOP FOR INSTRUCTIONS */
+  __u32 DPs;
   __u32 def_DP;
   __u8 grio;
   __u8 flags;
-  __u16 pad1;
 /* WARNING: DO NOT EDIT, AUTO-GENERATED CODE - SEE TOP FOR INSTRUCTIONS */
+  __u16 pad1;
 };
 enum {
   TCA_CHOKE_UNSPEC,
-  TCA_CHOKE_PARMS,
 /* WARNING: DO NOT EDIT, AUTO-GENERATED CODE - SEE TOP FOR INSTRUCTIONS */
+  TCA_CHOKE_PARMS,
   TCA_CHOKE_STAB,
   TCA_CHOKE_MAX_P,
   __TCA_CHOKE_MAX,
-};
 /* WARNING: DO NOT EDIT, AUTO-GENERATED CODE - SEE TOP FOR INSTRUCTIONS */
+};
 #define TCA_CHOKE_MAX (__TCA_CHOKE_MAX - 1)
 struct tc_choke_qopt {
   __u32 limit;
-  __u32 qth_min;
 /* WARNING: DO NOT EDIT, AUTO-GENERATED CODE - SEE TOP FOR INSTRUCTIONS */
+  __u32 qth_min;
   __u32 qth_max;
   unsigned char Wlog;
   unsigned char Plog;
-  unsigned char Scell_log;
 /* WARNING: DO NOT EDIT, AUTO-GENERATED CODE - SEE TOP FOR INSTRUCTIONS */
+  unsigned char Scell_log;
   unsigned char flags;
 };
 struct tc_choke_xstats {
-  __u32 early;
 /* WARNING: DO NOT EDIT, AUTO-GENERATED CODE - SEE TOP FOR INSTRUCTIONS */
+  __u32 early;
   __u32 pdrop;
   __u32 other;
   __u32 marked;
-  __u32 matched;
 /* WARNING: DO NOT EDIT, AUTO-GENERATED CODE - SEE TOP FOR INSTRUCTIONS */
+  __u32 matched;
 };
 #define TC_HTB_NUMPRIO 8
 #define TC_HTB_MAXDEPTH 8
-#define TC_HTB_PROTOVER 3
 /* WARNING: DO NOT EDIT, AUTO-GENERATED CODE - SEE TOP FOR INSTRUCTIONS */
+#define TC_HTB_PROTOVER 3
 struct tc_htb_opt {
   struct tc_ratespec rate;
   struct tc_ratespec ceil;
-  __u32 buffer;
 /* WARNING: DO NOT EDIT, AUTO-GENERATED CODE - SEE TOP FOR INSTRUCTIONS */
+  __u32 buffer;
   __u32 cbuffer;
   __u32 quantum;
   __u32 level;
-  __u32 prio;
 /* WARNING: DO NOT EDIT, AUTO-GENERATED CODE - SEE TOP FOR INSTRUCTIONS */
+  __u32 prio;
 };
 struct tc_htb_glob {
   __u32 version;
-  __u32 rate2quantum;
 /* WARNING: DO NOT EDIT, AUTO-GENERATED CODE - SEE TOP FOR INSTRUCTIONS */
+  __u32 rate2quantum;
   __u32 defcls;
   __u32 debug;
   __u32 direct_pkts;
-};
 /* WARNING: DO NOT EDIT, AUTO-GENERATED CODE - SEE TOP FOR INSTRUCTIONS */
+};
 enum {
   TCA_HTB_UNSPEC,
   TCA_HTB_PARMS,
-  TCA_HTB_INIT,
 /* WARNING: DO NOT EDIT, AUTO-GENERATED CODE - SEE TOP FOR INSTRUCTIONS */
+  TCA_HTB_INIT,
   TCA_HTB_CTAB,
   TCA_HTB_RTAB,
   TCA_HTB_DIRECT_QLEN,
-  TCA_HTB_RATE64,
 /* WARNING: DO NOT EDIT, AUTO-GENERATED CODE - SEE TOP FOR INSTRUCTIONS */
+  TCA_HTB_RATE64,
   TCA_HTB_CEIL64,
   __TCA_HTB_MAX,
 };
-#define TCA_HTB_MAX (__TCA_HTB_MAX - 1)
 /* WARNING: DO NOT EDIT, AUTO-GENERATED CODE - SEE TOP FOR INSTRUCTIONS */
+#define TCA_HTB_MAX (__TCA_HTB_MAX - 1)
 struct tc_htb_xstats {
   __u32 lends;
   __u32 borrows;
-  __u32 giants;
 /* WARNING: DO NOT EDIT, AUTO-GENERATED CODE - SEE TOP FOR INSTRUCTIONS */
+  __u32 giants;
   __u32 tokens;
   __u32 ctokens;
 };
-struct tc_hfsc_qopt {
 /* WARNING: DO NOT EDIT, AUTO-GENERATED CODE - SEE TOP FOR INSTRUCTIONS */
+struct tc_hfsc_qopt {
   __u16 defcls;
 };
 struct tc_service_curve {
-  __u32 m1;
 /* WARNING: DO NOT EDIT, AUTO-GENERATED CODE - SEE TOP FOR INSTRUCTIONS */
+  __u32 m1;
   __u32 d;
   __u32 m2;
 };
-struct tc_hfsc_stats {
 /* WARNING: DO NOT EDIT, AUTO-GENERATED CODE - SEE TOP FOR INSTRUCTIONS */
+struct tc_hfsc_stats {
   __u64 work;
   __u64 rtwork;
   __u32 period;
-  __u32 level;
 /* WARNING: DO NOT EDIT, AUTO-GENERATED CODE - SEE TOP FOR INSTRUCTIONS */
+  __u32 level;
 };
 enum {
   TCA_HFSC_UNSPEC,
-  TCA_HFSC_RSC,
 /* WARNING: DO NOT EDIT, AUTO-GENERATED CODE - SEE TOP FOR INSTRUCTIONS */
+  TCA_HFSC_RSC,
   TCA_HFSC_FSC,
   TCA_HFSC_USC,
   __TCA_HFSC_MAX,
-};
 /* WARNING: DO NOT EDIT, AUTO-GENERATED CODE - SEE TOP FOR INSTRUCTIONS */
+};
 #define TCA_HFSC_MAX (__TCA_HFSC_MAX - 1)
 #define TC_CBQ_MAXPRIO 8
 #define TC_CBQ_MAXLEVEL 8
-#define TC_CBQ_DEF_EWMA 5
 /* WARNING: DO NOT EDIT, AUTO-GENERATED CODE - SEE TOP FOR INSTRUCTIONS */
+#define TC_CBQ_DEF_EWMA 5
 struct tc_cbq_lssopt {
   unsigned char change;
   unsigned char flags;
-#define TCF_CBQ_LSS_BOUNDED 1
 /* WARNING: DO NOT EDIT, AUTO-GENERATED CODE - SEE TOP FOR INSTRUCTIONS */
+#define TCF_CBQ_LSS_BOUNDED 1
 #define TCF_CBQ_LSS_ISOLATED 2
   unsigned char ewma_log;
   unsigned char level;
-#define TCF_CBQ_LSS_FLAGS 1
 /* WARNING: DO NOT EDIT, AUTO-GENERATED CODE - SEE TOP FOR INSTRUCTIONS */
+#define TCF_CBQ_LSS_FLAGS 1
 #define TCF_CBQ_LSS_EWMA 2
 #define TCF_CBQ_LSS_MAXIDLE 4
 #define TCF_CBQ_LSS_MINIDLE 8
-#define TCF_CBQ_LSS_OFFTIME 0x10
 /* WARNING: DO NOT EDIT, AUTO-GENERATED CODE - SEE TOP FOR INSTRUCTIONS */
+#define TCF_CBQ_LSS_OFFTIME 0x10
 #define TCF_CBQ_LSS_AVPKT 0x20
   __u32 maxidle;
   __u32 minidle;
-  __u32 offtime;
 /* WARNING: DO NOT EDIT, AUTO-GENERATED CODE - SEE TOP FOR INSTRUCTIONS */
+  __u32 offtime;
   __u32 avpkt;
 };
 struct tc_cbq_wrropt {
-  unsigned char flags;
 /* WARNING: DO NOT EDIT, AUTO-GENERATED CODE - SEE TOP FOR INSTRUCTIONS */
+  unsigned char flags;
   unsigned char priority;
   unsigned char cpriority;
   unsigned char __reserved;
-  __u32 allot;
 /* WARNING: DO NOT EDIT, AUTO-GENERATED CODE - SEE TOP FOR INSTRUCTIONS */
+  __u32 allot;
   __u32 weight;
 };
 struct tc_cbq_ovl {
-  unsigned char strategy;
 /* WARNING: DO NOT EDIT, AUTO-GENERATED CODE - SEE TOP FOR INSTRUCTIONS */
+  unsigned char strategy;
 #define TC_CBQ_OVL_CLASSIC 0
 #define TC_CBQ_OVL_DELAY 1
 #define TC_CBQ_OVL_LOWPRIO 2
-#define TC_CBQ_OVL_DROP 3
 /* WARNING: DO NOT EDIT, AUTO-GENERATED CODE - SEE TOP FOR INSTRUCTIONS */
+#define TC_CBQ_OVL_DROP 3
 #define TC_CBQ_OVL_RCLASSIC 4
   unsigned char priority2;
   __u16 pad;
-  __u32 penalty;
 /* WARNING: DO NOT EDIT, AUTO-GENERATED CODE - SEE TOP FOR INSTRUCTIONS */
+  __u32 penalty;
 };
 struct tc_cbq_police {
   unsigned char police;
-  unsigned char __res1;
 /* WARNING: DO NOT EDIT, AUTO-GENERATED CODE - SEE TOP FOR INSTRUCTIONS */
+  unsigned char __res1;
   unsigned short __res2;
 };
 struct tc_cbq_fopt {
-  __u32 split;
 /* WARNING: DO NOT EDIT, AUTO-GENERATED CODE - SEE TOP FOR INSTRUCTIONS */
+  __u32 split;
   __u32 defmap;
   __u32 defchange;
 };
-struct tc_cbq_xstats {
 /* WARNING: DO NOT EDIT, AUTO-GENERATED CODE - SEE TOP FOR INSTRUCTIONS */
+struct tc_cbq_xstats {
   __u32 borrows;
   __u32 overactions;
   __s32 avgidle;
-  __s32 undertime;
 /* WARNING: DO NOT EDIT, AUTO-GENERATED CODE - SEE TOP FOR INSTRUCTIONS */
+  __s32 undertime;
 };
 enum {
   TCA_CBQ_UNSPEC,
-  TCA_CBQ_LSSOPT,
 /* WARNING: DO NOT EDIT, AUTO-GENERATED CODE - SEE TOP FOR INSTRUCTIONS */
+  TCA_CBQ_LSSOPT,
   TCA_CBQ_WRROPT,
   TCA_CBQ_FOPT,
   TCA_CBQ_OVL_STRATEGY,
-  TCA_CBQ_RATE,
 /* WARNING: DO NOT EDIT, AUTO-GENERATED CODE - SEE TOP FOR INSTRUCTIONS */
+  TCA_CBQ_RATE,
   TCA_CBQ_RTAB,
   TCA_CBQ_POLICE,
   __TCA_CBQ_MAX,
-};
 /* WARNING: DO NOT EDIT, AUTO-GENERATED CODE - SEE TOP FOR INSTRUCTIONS */
+};
 #define TCA_CBQ_MAX (__TCA_CBQ_MAX - 1)
 enum {
   TCA_DSMARK_UNSPEC,
-  TCA_DSMARK_INDICES,
 /* WARNING: DO NOT EDIT, AUTO-GENERATED CODE - SEE TOP FOR INSTRUCTIONS */
+  TCA_DSMARK_INDICES,
   TCA_DSMARK_DEFAULT_INDEX,
   TCA_DSMARK_SET_TC_INDEX,
   TCA_DSMARK_MASK,
-  TCA_DSMARK_VALUE,
 /* WARNING: DO NOT EDIT, AUTO-GENERATED CODE - SEE TOP FOR INSTRUCTIONS */
+  TCA_DSMARK_VALUE,
   __TCA_DSMARK_MAX,
 };
 #define TCA_DSMARK_MAX (__TCA_DSMARK_MAX - 1)
-enum {
 /* WARNING: DO NOT EDIT, AUTO-GENERATED CODE - SEE TOP FOR INSTRUCTIONS */
+enum {
   TCA_ATM_UNSPEC,
   TCA_ATM_FD,
   TCA_ATM_PTR,
-  TCA_ATM_HDR,
 /* WARNING: DO NOT EDIT, AUTO-GENERATED CODE - SEE TOP FOR INSTRUCTIONS */
+  TCA_ATM_HDR,
   TCA_ATM_EXCESS,
   TCA_ATM_ADDR,
   TCA_ATM_STATE,
-  __TCA_ATM_MAX,
 /* WARNING: DO NOT EDIT, AUTO-GENERATED CODE - SEE TOP FOR INSTRUCTIONS */
+  __TCA_ATM_MAX,
 };
 #define TCA_ATM_MAX (__TCA_ATM_MAX - 1)
 enum {
-  TCA_NETEM_UNSPEC,
 /* WARNING: DO NOT EDIT, AUTO-GENERATED CODE - SEE TOP FOR INSTRUCTIONS */
+  TCA_NETEM_UNSPEC,
   TCA_NETEM_CORR,
   TCA_NETEM_DELAY_DIST,
   TCA_NETEM_REORDER,
-  TCA_NETEM_CORRUPT,
 /* WARNING: DO NOT EDIT, AUTO-GENERATED CODE - SEE TOP FOR INSTRUCTIONS */
+  TCA_NETEM_CORRUPT,
   TCA_NETEM_LOSS,
   TCA_NETEM_RATE,
   TCA_NETEM_ECN,
-  TCA_NETEM_RATE64,
 /* WARNING: DO NOT EDIT, AUTO-GENERATED CODE - SEE TOP FOR INSTRUCTIONS */
+  TCA_NETEM_RATE64,
   __TCA_NETEM_MAX,
 };
 #define TCA_NETEM_MAX (__TCA_NETEM_MAX - 1)
-struct tc_netem_qopt {
 /* WARNING: DO NOT EDIT, AUTO-GENERATED CODE - SEE TOP FOR INSTRUCTIONS */
+struct tc_netem_qopt {
   __u32 latency;
   __u32 limit;
   __u32 loss;
-  __u32 gap;
 /* WARNING: DO NOT EDIT, AUTO-GENERATED CODE - SEE TOP FOR INSTRUCTIONS */
+  __u32 gap;
   __u32 duplicate;
   __u32 jitter;
 };
-struct tc_netem_corr {
 /* WARNING: DO NOT EDIT, AUTO-GENERATED CODE - SEE TOP FOR INSTRUCTIONS */
+struct tc_netem_corr {
   __u32 delay_corr;
   __u32 loss_corr;
   __u32 dup_corr;
-};
 /* WARNING: DO NOT EDIT, AUTO-GENERATED CODE - SEE TOP FOR INSTRUCTIONS */
+};
 struct tc_netem_reorder {
   __u32 probability;
   __u32 correlation;
-};
 /* WARNING: DO NOT EDIT, AUTO-GENERATED CODE - SEE TOP FOR INSTRUCTIONS */
+};
 struct tc_netem_corrupt {
   __u32 probability;
   __u32 correlation;
-};
 /* WARNING: DO NOT EDIT, AUTO-GENERATED CODE - SEE TOP FOR INSTRUCTIONS */
+};
 struct tc_netem_rate {
   __u32 rate;
   __s32 packet_overhead;
-  __u32 cell_size;
 /* WARNING: DO NOT EDIT, AUTO-GENERATED CODE - SEE TOP FOR INSTRUCTIONS */
+  __u32 cell_size;
   __s32 cell_overhead;
 };
 enum {
-  NETEM_LOSS_UNSPEC,
 /* WARNING: DO NOT EDIT, AUTO-GENERATED CODE - SEE TOP FOR INSTRUCTIONS */
+  NETEM_LOSS_UNSPEC,
   NETEM_LOSS_GI,
   NETEM_LOSS_GE,
   __NETEM_LOSS_MAX
-};
 /* WARNING: DO NOT EDIT, AUTO-GENERATED CODE - SEE TOP FOR INSTRUCTIONS */
+};
 #define NETEM_LOSS_MAX (__NETEM_LOSS_MAX - 1)
 struct tc_netem_gimodel {
   __u32 p13;
-  __u32 p31;
 /* WARNING: DO NOT EDIT, AUTO-GENERATED CODE - SEE TOP FOR INSTRUCTIONS */
+  __u32 p31;
   __u32 p32;
   __u32 p14;
   __u32 p23;
-};
 /* WARNING: DO NOT EDIT, AUTO-GENERATED CODE - SEE TOP FOR INSTRUCTIONS */
+};
 struct tc_netem_gemodel {
   __u32 p;
   __u32 r;
-  __u32 h;
 /* WARNING: DO NOT EDIT, AUTO-GENERATED CODE - SEE TOP FOR INSTRUCTIONS */
+  __u32 h;
   __u32 k1;
 };
 #define NETEM_DIST_SCALE 8192
-#define NETEM_DIST_MAX 16384
 /* WARNING: DO NOT EDIT, AUTO-GENERATED CODE - SEE TOP FOR INSTRUCTIONS */
+#define NETEM_DIST_MAX 16384
 enum {
   TCA_DRR_UNSPEC,
   TCA_DRR_QUANTUM,
-  __TCA_DRR_MAX
 /* WARNING: DO NOT EDIT, AUTO-GENERATED CODE - SEE TOP FOR INSTRUCTIONS */
+  __TCA_DRR_MAX
 };
 #define TCA_DRR_MAX (__TCA_DRR_MAX - 1)
 struct tc_drr_stats {
-  __u32 deficit;
 /* WARNING: DO NOT EDIT, AUTO-GENERATED CODE - SEE TOP FOR INSTRUCTIONS */
+  __u32 deficit;
 };
 #define TC_QOPT_BITMASK 15
 #define TC_QOPT_MAX_QUEUE 16
-struct tc_mqprio_qopt {
 /* WARNING: DO NOT EDIT, AUTO-GENERATED CODE - SEE TOP FOR INSTRUCTIONS */
+struct tc_mqprio_qopt {
   __u8 num_tc;
   __u8 prio_tc_map[TC_QOPT_BITMASK + 1];
   __u8 hw;
-  __u16 count[TC_QOPT_MAX_QUEUE];
 /* WARNING: DO NOT EDIT, AUTO-GENERATED CODE - SEE TOP FOR INSTRUCTIONS */
+  __u16 count[TC_QOPT_MAX_QUEUE];
   __u16 offset[TC_QOPT_MAX_QUEUE];
 };
 enum {
-  TCA_SFB_UNSPEC,
 /* WARNING: DO NOT EDIT, AUTO-GENERATED CODE - SEE TOP FOR INSTRUCTIONS */
+  TCA_SFB_UNSPEC,
   TCA_SFB_PARMS,
   __TCA_SFB_MAX,
 };
-#define TCA_SFB_MAX (__TCA_SFB_MAX - 1)
 /* WARNING: DO NOT EDIT, AUTO-GENERATED CODE - SEE TOP FOR INSTRUCTIONS */
+#define TCA_SFB_MAX (__TCA_SFB_MAX - 1)
 struct tc_sfb_qopt {
   __u32 rehash_interval;
   __u32 warmup_time;
-  __u32 max;
 /* WARNING: DO NOT EDIT, AUTO-GENERATED CODE - SEE TOP FOR INSTRUCTIONS */
+  __u32 max;
   __u32 bin_size;
   __u32 increment;
   __u32 decrement;
-  __u32 limit;
 /* WARNING: DO NOT EDIT, AUTO-GENERATED CODE - SEE TOP FOR INSTRUCTIONS */
+  __u32 limit;
   __u32 penalty_rate;
   __u32 penalty_burst;
 };
-struct tc_sfb_xstats {
 /* WARNING: DO NOT EDIT, AUTO-GENERATED CODE - SEE TOP FOR INSTRUCTIONS */
+struct tc_sfb_xstats {
   __u32 earlydrop;
   __u32 penaltydrop;
   __u32 bucketdrop;
-  __u32 queuedrop;
 /* WARNING: DO NOT EDIT, AUTO-GENERATED CODE - SEE TOP FOR INSTRUCTIONS */
+  __u32 queuedrop;
   __u32 childdrop;
   __u32 marked;
   __u32 maxqlen;
-  __u32 maxprob;
 /* WARNING: DO NOT EDIT, AUTO-GENERATED CODE - SEE TOP FOR INSTRUCTIONS */
+  __u32 maxprob;
   __u32 avgprob;
 };
 #define SFB_MAX_PROB 0xFFFF
-enum {
 /* WARNING: DO NOT EDIT, AUTO-GENERATED CODE - SEE TOP FOR INSTRUCTIONS */
+enum {
   TCA_QFQ_UNSPEC,
   TCA_QFQ_WEIGHT,
   TCA_QFQ_LMAX,
-  __TCA_QFQ_MAX
 /* WARNING: DO NOT EDIT, AUTO-GENERATED CODE - SEE TOP FOR INSTRUCTIONS */
+  __TCA_QFQ_MAX
 };
 #define TCA_QFQ_MAX (__TCA_QFQ_MAX - 1)
 struct tc_qfq_stats {
-  __u32 weight;
 /* WARNING: DO NOT EDIT, AUTO-GENERATED CODE - SEE TOP FOR INSTRUCTIONS */
+  __u32 weight;
   __u32 lmax;
 };
 enum {
-  TCA_CODEL_UNSPEC,
 /* WARNING: DO NOT EDIT, AUTO-GENERATED CODE - SEE TOP FOR INSTRUCTIONS */
+  TCA_CODEL_UNSPEC,
   TCA_CODEL_TARGET,
   TCA_CODEL_LIMIT,
   TCA_CODEL_INTERVAL,
-  TCA_CODEL_ECN,
 /* WARNING: DO NOT EDIT, AUTO-GENERATED CODE - SEE TOP FOR INSTRUCTIONS */
+  TCA_CODEL_ECN,
+  TCA_CODEL_CE_THRESHOLD,
   __TCA_CODEL_MAX
 };
+/* WARNING: DO NOT EDIT, AUTO-GENERATED CODE - SEE TOP FOR INSTRUCTIONS */
 #define TCA_CODEL_MAX (__TCA_CODEL_MAX - 1)
 struct tc_codel_xstats {
-/* WARNING: DO NOT EDIT, AUTO-GENERATED CODE - SEE TOP FOR INSTRUCTIONS */
   __u32 maxpacket;
   __u32 count;
+/* WARNING: DO NOT EDIT, AUTO-GENERATED CODE - SEE TOP FOR INSTRUCTIONS */
   __u32 lastcount;
   __u32 ldelay;
-/* WARNING: DO NOT EDIT, AUTO-GENERATED CODE - SEE TOP FOR INSTRUCTIONS */
   __s32 drop_next;
   __u32 drop_overlimit;
+/* WARNING: DO NOT EDIT, AUTO-GENERATED CODE - SEE TOP FOR INSTRUCTIONS */
   __u32 ecn_mark;
   __u32 dropping;
-/* WARNING: DO NOT EDIT, AUTO-GENERATED CODE - SEE TOP FOR INSTRUCTIONS */
+  __u32 ce_mark;
 };
+/* WARNING: DO NOT EDIT, AUTO-GENERATED CODE - SEE TOP FOR INSTRUCTIONS */
 enum {
   TCA_FQ_CODEL_UNSPEC,
   TCA_FQ_CODEL_TARGET,
-/* WARNING: DO NOT EDIT, AUTO-GENERATED CODE - SEE TOP FOR INSTRUCTIONS */
   TCA_FQ_CODEL_LIMIT,
+/* WARNING: DO NOT EDIT, AUTO-GENERATED CODE - SEE TOP FOR INSTRUCTIONS */
   TCA_FQ_CODEL_INTERVAL,
   TCA_FQ_CODEL_ECN,
   TCA_FQ_CODEL_FLOWS,
-/* WARNING: DO NOT EDIT, AUTO-GENERATED CODE - SEE TOP FOR INSTRUCTIONS */
   TCA_FQ_CODEL_QUANTUM,
+/* WARNING: DO NOT EDIT, AUTO-GENERATED CODE - SEE TOP FOR INSTRUCTIONS */
+  TCA_FQ_CODEL_CE_THRESHOLD,
   __TCA_FQ_CODEL_MAX
 };
 #define TCA_FQ_CODEL_MAX (__TCA_FQ_CODEL_MAX - 1)
@@ -679,110 +684,112 @@
   __u32 new_flow_count;
   __u32 new_flows_len;
   __u32 old_flows_len;
-};
+  __u32 ce_mark;
 /* WARNING: DO NOT EDIT, AUTO-GENERATED CODE - SEE TOP FOR INSTRUCTIONS */
+};
 struct tc_fq_codel_cl_stats {
   __s32 deficit;
   __u32 ldelay;
-  __u32 count;
 /* WARNING: DO NOT EDIT, AUTO-GENERATED CODE - SEE TOP FOR INSTRUCTIONS */
+  __u32 count;
   __u32 lastcount;
   __u32 dropping;
   __s32 drop_next;
-};
 /* WARNING: DO NOT EDIT, AUTO-GENERATED CODE - SEE TOP FOR INSTRUCTIONS */
+};
 struct tc_fq_codel_xstats {
   __u32 type;
   union {
-    struct tc_fq_codel_qd_stats qdisc_stats;
 /* WARNING: DO NOT EDIT, AUTO-GENERATED CODE - SEE TOP FOR INSTRUCTIONS */
+    struct tc_fq_codel_qd_stats qdisc_stats;
     struct tc_fq_codel_cl_stats class_stats;
   };
 };
-enum {
 /* WARNING: DO NOT EDIT, AUTO-GENERATED CODE - SEE TOP FOR INSTRUCTIONS */
+enum {
   TCA_FQ_UNSPEC,
   TCA_FQ_PLIMIT,
   TCA_FQ_FLOW_PLIMIT,
-  TCA_FQ_QUANTUM,
 /* WARNING: DO NOT EDIT, AUTO-GENERATED CODE - SEE TOP FOR INSTRUCTIONS */
+  TCA_FQ_QUANTUM,
   TCA_FQ_INITIAL_QUANTUM,
   TCA_FQ_RATE_ENABLE,
   TCA_FQ_FLOW_DEFAULT_RATE,
-  TCA_FQ_FLOW_MAX_RATE,
 /* WARNING: DO NOT EDIT, AUTO-GENERATED CODE - SEE TOP FOR INSTRUCTIONS */
+  TCA_FQ_FLOW_MAX_RATE,
   TCA_FQ_BUCKETS_LOG,
   TCA_FQ_FLOW_REFILL_DELAY,
+  TCA_FQ_ORPHAN_MASK,
+/* WARNING: DO NOT EDIT, AUTO-GENERATED CODE - SEE TOP FOR INSTRUCTIONS */
   __TCA_FQ_MAX
 };
-/* WARNING: DO NOT EDIT, AUTO-GENERATED CODE - SEE TOP FOR INSTRUCTIONS */
 #define TCA_FQ_MAX (__TCA_FQ_MAX - 1)
 struct tc_fq_qd_stats {
+/* WARNING: DO NOT EDIT, AUTO-GENERATED CODE - SEE TOP FOR INSTRUCTIONS */
   __u64 gc_flows;
   __u64 highprio_packets;
-/* WARNING: DO NOT EDIT, AUTO-GENERATED CODE - SEE TOP FOR INSTRUCTIONS */
   __u64 tcp_retrans;
   __u64 throttled;
+/* WARNING: DO NOT EDIT, AUTO-GENERATED CODE - SEE TOP FOR INSTRUCTIONS */
   __u64 flows_plimit;
   __u64 pkts_too_long;
-/* WARNING: DO NOT EDIT, AUTO-GENERATED CODE - SEE TOP FOR INSTRUCTIONS */
   __u64 allocation_errors;
   __s64 time_next_delayed_flow;
+/* WARNING: DO NOT EDIT, AUTO-GENERATED CODE - SEE TOP FOR INSTRUCTIONS */
   __u32 flows;
   __u32 inactive_flows;
-/* WARNING: DO NOT EDIT, AUTO-GENERATED CODE - SEE TOP FOR INSTRUCTIONS */
   __u32 throttled_flows;
   __u32 pad;
+/* WARNING: DO NOT EDIT, AUTO-GENERATED CODE - SEE TOP FOR INSTRUCTIONS */
 };
 enum {
-/* WARNING: DO NOT EDIT, AUTO-GENERATED CODE - SEE TOP FOR INSTRUCTIONS */
   TCA_HHF_UNSPEC,
   TCA_HHF_BACKLOG_LIMIT,
+/* WARNING: DO NOT EDIT, AUTO-GENERATED CODE - SEE TOP FOR INSTRUCTIONS */
   TCA_HHF_QUANTUM,
   TCA_HHF_HH_FLOWS_LIMIT,
-/* WARNING: DO NOT EDIT, AUTO-GENERATED CODE - SEE TOP FOR INSTRUCTIONS */
   TCA_HHF_RESET_TIMEOUT,
   TCA_HHF_ADMIT_BYTES,
+/* WARNING: DO NOT EDIT, AUTO-GENERATED CODE - SEE TOP FOR INSTRUCTIONS */
   TCA_HHF_EVICT_TIMEOUT,
   TCA_HHF_NON_HH_WEIGHT,
-/* WARNING: DO NOT EDIT, AUTO-GENERATED CODE - SEE TOP FOR INSTRUCTIONS */
   __TCA_HHF_MAX
 };
+/* WARNING: DO NOT EDIT, AUTO-GENERATED CODE - SEE TOP FOR INSTRUCTIONS */
 #define TCA_HHF_MAX (__TCA_HHF_MAX - 1)
 struct tc_hhf_xstats {
-/* WARNING: DO NOT EDIT, AUTO-GENERATED CODE - SEE TOP FOR INSTRUCTIONS */
   __u32 drop_overlimit;
   __u32 hh_overlimit;
+/* WARNING: DO NOT EDIT, AUTO-GENERATED CODE - SEE TOP FOR INSTRUCTIONS */
   __u32 hh_tot_count;
   __u32 hh_cur_count;
-/* WARNING: DO NOT EDIT, AUTO-GENERATED CODE - SEE TOP FOR INSTRUCTIONS */
 };
 enum {
+/* WARNING: DO NOT EDIT, AUTO-GENERATED CODE - SEE TOP FOR INSTRUCTIONS */
   TCA_PIE_UNSPEC,
   TCA_PIE_TARGET,
-/* WARNING: DO NOT EDIT, AUTO-GENERATED CODE - SEE TOP FOR INSTRUCTIONS */
   TCA_PIE_LIMIT,
   TCA_PIE_TUPDATE,
+/* WARNING: DO NOT EDIT, AUTO-GENERATED CODE - SEE TOP FOR INSTRUCTIONS */
   TCA_PIE_ALPHA,
   TCA_PIE_BETA,
-/* WARNING: DO NOT EDIT, AUTO-GENERATED CODE - SEE TOP FOR INSTRUCTIONS */
   TCA_PIE_ECN,
   TCA_PIE_BYTEMODE,
+/* WARNING: DO NOT EDIT, AUTO-GENERATED CODE - SEE TOP FOR INSTRUCTIONS */
   __TCA_PIE_MAX
 };
-/* WARNING: DO NOT EDIT, AUTO-GENERATED CODE - SEE TOP FOR INSTRUCTIONS */
 #define TCA_PIE_MAX (__TCA_PIE_MAX - 1)
 struct tc_pie_xstats {
+/* WARNING: DO NOT EDIT, AUTO-GENERATED CODE - SEE TOP FOR INSTRUCTIONS */
   __u32 prob;
   __u32 delay;
-/* WARNING: DO NOT EDIT, AUTO-GENERATED CODE - SEE TOP FOR INSTRUCTIONS */
   __u32 avg_dq_rate;
   __u32 packets_in;
+/* WARNING: DO NOT EDIT, AUTO-GENERATED CODE - SEE TOP FOR INSTRUCTIONS */
   __u32 dropped;
   __u32 overlimit;
-/* WARNING: DO NOT EDIT, AUTO-GENERATED CODE - SEE TOP FOR INSTRUCTIONS */
   __u32 maxq;
   __u32 ecn_mark;
+/* WARNING: DO NOT EDIT, AUTO-GENERATED CODE - SEE TOP FOR INSTRUCTIONS */
 };
 #endif
-/* WARNING: DO NOT EDIT, AUTO-GENERATED CODE - SEE TOP FOR INSTRUCTIONS */
diff --git a/libc/kernel/uapi/linux/pr.h b/libc/kernel/uapi/linux/pr.h
new file mode 100644
index 0000000..91dedfe
--- /dev/null
+++ b/libc/kernel/uapi/linux/pr.h
@@ -0,0 +1,68 @@
+/****************************************************************************
+ ****************************************************************************
+ ***
+ ***   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_PR_H
+#define _UAPI_PR_H
+enum pr_type {
+  PR_WRITE_EXCLUSIVE = 1,
+/* WARNING: DO NOT EDIT, AUTO-GENERATED CODE - SEE TOP FOR INSTRUCTIONS */
+  PR_EXCLUSIVE_ACCESS = 2,
+  PR_WRITE_EXCLUSIVE_REG_ONLY = 3,
+  PR_EXCLUSIVE_ACCESS_REG_ONLY = 4,
+  PR_WRITE_EXCLUSIVE_ALL_REGS = 5,
+/* WARNING: DO NOT EDIT, AUTO-GENERATED CODE - SEE TOP FOR INSTRUCTIONS */
+  PR_EXCLUSIVE_ACCESS_ALL_REGS = 6,
+};
+struct pr_reservation {
+  __u64 key;
+/* WARNING: DO NOT EDIT, AUTO-GENERATED CODE - SEE TOP FOR INSTRUCTIONS */
+  __u32 type;
+  __u32 flags;
+};
+struct pr_registration {
+/* WARNING: DO NOT EDIT, AUTO-GENERATED CODE - SEE TOP FOR INSTRUCTIONS */
+  __u64 old_key;
+  __u64 new_key;
+  __u32 flags;
+  __u32 __pad;
+/* WARNING: DO NOT EDIT, AUTO-GENERATED CODE - SEE TOP FOR INSTRUCTIONS */
+};
+struct pr_preempt {
+  __u64 old_key;
+  __u64 new_key;
+/* WARNING: DO NOT EDIT, AUTO-GENERATED CODE - SEE TOP FOR INSTRUCTIONS */
+  __u32 type;
+  __u32 flags;
+};
+struct pr_clear {
+/* WARNING: DO NOT EDIT, AUTO-GENERATED CODE - SEE TOP FOR INSTRUCTIONS */
+  __u64 key;
+  __u32 flags;
+  __u32 __pad;
+};
+/* WARNING: DO NOT EDIT, AUTO-GENERATED CODE - SEE TOP FOR INSTRUCTIONS */
+#define PR_FL_IGNORE_KEY (1 << 0)
+#define IOC_PR_REGISTER _IOW('p', 200, struct pr_registration)
+#define IOC_PR_RESERVE _IOW('p', 201, struct pr_reservation)
+#define IOC_PR_RELEASE _IOW('p', 202, struct pr_reservation)
+/* WARNING: DO NOT EDIT, AUTO-GENERATED CODE - SEE TOP FOR INSTRUCTIONS */
+#define IOC_PR_PREEMPT _IOW('p', 203, struct pr_preempt)
+#define IOC_PR_PREEMPT_ABORT _IOW('p', 204, struct pr_preempt)
+#define IOC_PR_CLEAR _IOW('p', 205, struct pr_clear)
+#endif
+/* WARNING: DO NOT EDIT, AUTO-GENERATED CODE - SEE TOP FOR INSTRUCTIONS */
diff --git a/libc/kernel/uapi/linux/prctl.h b/libc/kernel/uapi/linux/prctl.h
index 07898cc..d10c0f6 100644
--- a/libc/kernel/uapi/linux/prctl.h
+++ b/libc/kernel/uapi/linux/prctl.h
@@ -143,4 +143,18 @@
 /* WARNING: DO NOT EDIT, AUTO-GENERATED CODE - SEE TOP FOR INSTRUCTIONS */
 #define PR_SET_THP_DISABLE 41
 #define PR_GET_THP_DISABLE 42
+#define PR_MPX_ENABLE_MANAGEMENT 43
+#define PR_MPX_DISABLE_MANAGEMENT 44
+/* WARNING: DO NOT EDIT, AUTO-GENERATED CODE - SEE TOP FOR INSTRUCTIONS */
+#define PR_SET_FP_MODE 45
+#define PR_GET_FP_MODE 46
+#define PR_FP_MODE_FR (1 << 0)
+#define PR_FP_MODE_FRE (1 << 1)
+/* WARNING: DO NOT EDIT, AUTO-GENERATED CODE - SEE TOP FOR INSTRUCTIONS */
+#define PR_CAP_AMBIENT 47
+#define PR_CAP_AMBIENT_IS_SET 1
+#define PR_CAP_AMBIENT_RAISE 2
+#define PR_CAP_AMBIENT_LOWER 3
+/* WARNING: DO NOT EDIT, AUTO-GENERATED CODE - SEE TOP FOR INSTRUCTIONS */
+#define PR_CAP_AMBIENT_CLEAR_ALL 4
 #endif
diff --git a/libc/kernel/uapi/linux/psci.h b/libc/kernel/uapi/linux/psci.h
index b523abe..fa68516 100644
--- a/libc/kernel/uapi/linux/psci.h
+++ b/libc/kernel/uapi/linux/psci.h
@@ -43,37 +43,49 @@
 /* WARNING: DO NOT EDIT, AUTO-GENERATED CODE - SEE TOP FOR INSTRUCTIONS */
 #define PSCI_0_2_FN64_MIGRATE PSCI_0_2_FN64(5)
 #define PSCI_0_2_FN64_MIGRATE_INFO_UP_CPU PSCI_0_2_FN64(7)
+#define PSCI_1_0_FN_PSCI_FEATURES PSCI_0_2_FN(10)
+#define PSCI_1_0_FN_SYSTEM_SUSPEND PSCI_0_2_FN(14)
+/* WARNING: DO NOT EDIT, AUTO-GENERATED CODE - SEE TOP FOR INSTRUCTIONS */
+#define PSCI_1_0_FN64_SYSTEM_SUSPEND PSCI_0_2_FN64(14)
 #define PSCI_0_2_POWER_STATE_ID_MASK 0xffff
 #define PSCI_0_2_POWER_STATE_ID_SHIFT 0
-/* WARNING: DO NOT EDIT, AUTO-GENERATED CODE - SEE TOP FOR INSTRUCTIONS */
 #define PSCI_0_2_POWER_STATE_TYPE_SHIFT 16
+/* WARNING: DO NOT EDIT, AUTO-GENERATED CODE - SEE TOP FOR INSTRUCTIONS */
 #define PSCI_0_2_POWER_STATE_TYPE_MASK (0x1 << PSCI_0_2_POWER_STATE_TYPE_SHIFT)
 #define PSCI_0_2_POWER_STATE_AFFL_SHIFT 24
 #define PSCI_0_2_POWER_STATE_AFFL_MASK (0x3 << PSCI_0_2_POWER_STATE_AFFL_SHIFT)
+#define PSCI_1_0_EXT_POWER_STATE_ID_MASK 0xfffffff
 /* WARNING: DO NOT EDIT, AUTO-GENERATED CODE - SEE TOP FOR INSTRUCTIONS */
+#define PSCI_1_0_EXT_POWER_STATE_ID_SHIFT 0
+#define PSCI_1_0_EXT_POWER_STATE_TYPE_SHIFT 30
+#define PSCI_1_0_EXT_POWER_STATE_TYPE_MASK (0x1 << PSCI_1_0_EXT_POWER_STATE_TYPE_SHIFT)
 #define PSCI_0_2_AFFINITY_LEVEL_ON 0
+/* WARNING: DO NOT EDIT, AUTO-GENERATED CODE - SEE TOP FOR INSTRUCTIONS */
 #define PSCI_0_2_AFFINITY_LEVEL_OFF 1
 #define PSCI_0_2_AFFINITY_LEVEL_ON_PENDING 2
 #define PSCI_0_2_TOS_UP_MIGRATE 0
-/* WARNING: DO NOT EDIT, AUTO-GENERATED CODE - SEE TOP FOR INSTRUCTIONS */
 #define PSCI_0_2_TOS_UP_NO_MIGRATE 1
+/* WARNING: DO NOT EDIT, AUTO-GENERATED CODE - SEE TOP FOR INSTRUCTIONS */
 #define PSCI_0_2_TOS_MP 2
 #define PSCI_VERSION_MAJOR_SHIFT 16
 #define PSCI_VERSION_MINOR_MASK ((1U << PSCI_VERSION_MAJOR_SHIFT) - 1)
-/* WARNING: DO NOT EDIT, AUTO-GENERATED CODE - SEE TOP FOR INSTRUCTIONS */
 #define PSCI_VERSION_MAJOR_MASK ~PSCI_VERSION_MINOR_MASK
+/* WARNING: DO NOT EDIT, AUTO-GENERATED CODE - SEE TOP FOR INSTRUCTIONS */
 #define PSCI_VERSION_MAJOR(ver) (((ver) & PSCI_VERSION_MAJOR_MASK) >> PSCI_VERSION_MAJOR_SHIFT)
 #define PSCI_VERSION_MINOR(ver) ((ver) & PSCI_VERSION_MINOR_MASK)
-#define PSCI_RET_SUCCESS 0
+#define PSCI_1_0_FEATURES_CPU_SUSPEND_PF_SHIFT 1
+#define PSCI_1_0_FEATURES_CPU_SUSPEND_PF_MASK (0x1 << PSCI_1_0_FEATURES_CPU_SUSPEND_PF_SHIFT)
 /* WARNING: DO NOT EDIT, AUTO-GENERATED CODE - SEE TOP FOR INSTRUCTIONS */
+#define PSCI_RET_SUCCESS 0
 #define PSCI_RET_NOT_SUPPORTED - 1
 #define PSCI_RET_INVALID_PARAMS - 2
 #define PSCI_RET_DENIED - 3
-#define PSCI_RET_ALREADY_ON - 4
 /* WARNING: DO NOT EDIT, AUTO-GENERATED CODE - SEE TOP FOR INSTRUCTIONS */
+#define PSCI_RET_ALREADY_ON - 4
 #define PSCI_RET_ON_PENDING - 5
 #define PSCI_RET_INTERNAL_FAILURE - 6
 #define PSCI_RET_NOT_PRESENT - 7
-#define PSCI_RET_DISABLED - 8
 /* WARNING: DO NOT EDIT, AUTO-GENERATED CODE - SEE TOP FOR INSTRUCTIONS */
+#define PSCI_RET_DISABLED - 8
+#define PSCI_RET_INVALID_ADDRESS - 9
 #endif
diff --git a/libc/kernel/uapi/linux/ptrace.h b/libc/kernel/uapi/linux/ptrace.h
index a3244e9..7550276 100644
--- a/libc/kernel/uapi/linux/ptrace.h
+++ b/libc/kernel/uapi/linux/ptrace.h
@@ -57,29 +57,32 @@
 #define PTRACE_GETSIGMASK 0x420a
 /* WARNING: DO NOT EDIT, AUTO-GENERATED CODE - SEE TOP FOR INSTRUCTIONS */
 #define PTRACE_SETSIGMASK 0x420b
+#define PTRACE_SECCOMP_GET_FILTER 0x420c
 #define PTRACE_PEEKSIGINFO_SHARED (1 << 0)
 #define PTRACE_EVENT_FORK 1
-#define PTRACE_EVENT_VFORK 2
 /* WARNING: DO NOT EDIT, AUTO-GENERATED CODE - SEE TOP FOR INSTRUCTIONS */
+#define PTRACE_EVENT_VFORK 2
 #define PTRACE_EVENT_CLONE 3
 #define PTRACE_EVENT_EXEC 4
 #define PTRACE_EVENT_VFORK_DONE 5
-#define PTRACE_EVENT_EXIT 6
 /* WARNING: DO NOT EDIT, AUTO-GENERATED CODE - SEE TOP FOR INSTRUCTIONS */
+#define PTRACE_EVENT_EXIT 6
 #define PTRACE_EVENT_SECCOMP 7
 #define PTRACE_EVENT_STOP 128
 #define PTRACE_O_TRACESYSGOOD 1
-#define PTRACE_O_TRACEFORK (1 << PTRACE_EVENT_FORK)
 /* WARNING: DO NOT EDIT, AUTO-GENERATED CODE - SEE TOP FOR INSTRUCTIONS */
+#define PTRACE_O_TRACEFORK (1 << PTRACE_EVENT_FORK)
 #define PTRACE_O_TRACEVFORK (1 << PTRACE_EVENT_VFORK)
 #define PTRACE_O_TRACECLONE (1 << PTRACE_EVENT_CLONE)
 #define PTRACE_O_TRACEEXEC (1 << PTRACE_EVENT_EXEC)
-#define PTRACE_O_TRACEVFORKDONE (1 << PTRACE_EVENT_VFORK_DONE)
 /* WARNING: DO NOT EDIT, AUTO-GENERATED CODE - SEE TOP FOR INSTRUCTIONS */
+#define PTRACE_O_TRACEVFORKDONE (1 << PTRACE_EVENT_VFORK_DONE)
 #define PTRACE_O_TRACEEXIT (1 << PTRACE_EVENT_EXIT)
 #define PTRACE_O_TRACESECCOMP (1 << PTRACE_EVENT_SECCOMP)
 #define PTRACE_O_EXITKILL (1 << 20)
-#define PTRACE_O_MASK (0x000000ff | PTRACE_O_EXITKILL)
 /* WARNING: DO NOT EDIT, AUTO-GENERATED CODE - SEE TOP FOR INSTRUCTIONS */
+#define PTRACE_O_SUSPEND_SECCOMP (1 << 21)
+#define PTRACE_O_MASK (0x000000ff | PTRACE_O_EXITKILL | PTRACE_O_SUSPEND_SECCOMP)
 #include <asm/ptrace.h>
 #endif
+/* WARNING: DO NOT EDIT, AUTO-GENERATED CODE - SEE TOP FOR INSTRUCTIONS */
diff --git a/libc/kernel/uapi/linux/quota.h b/libc/kernel/uapi/linux/quota.h
index d5fc707..2c5485f 100644
--- a/libc/kernel/uapi/linux/quota.h
+++ b/libc/kernel/uapi/linux/quota.h
@@ -21,75 +21,85 @@
 #include <linux/errno.h>
 #include <linux/types.h>
 /* WARNING: DO NOT EDIT, AUTO-GENERATED CODE - SEE TOP FOR INSTRUCTIONS */
-#define __DQUOT_VERSION__ "dquot_6.5.2"
-#define MAXQUOTAS 2
+#define __DQUOT_VERSION__ "dquot_6.6.0"
+#define MAXQUOTAS 3
 #define USRQUOTA 0
 #define GRPQUOTA 1
 /* WARNING: DO NOT EDIT, AUTO-GENERATED CODE - SEE TOP FOR INSTRUCTIONS */
-#define INITQFNAMES { "user", "group", "undefined", \
+#define PRJQUOTA 2
+#define INITQFNAMES { "user", "group", "project", "undefined", \
 };
 #define SUBCMDMASK 0x00ff
 #define SUBCMDSHIFT 8
-#define QCMD(cmd,type) (((cmd) << SUBCMDSHIFT) | ((type) & SUBCMDMASK))
 /* WARNING: DO NOT EDIT, AUTO-GENERATED CODE - SEE TOP FOR INSTRUCTIONS */
+#define QCMD(cmd,type) (((cmd) << SUBCMDSHIFT) | ((type) & SUBCMDMASK))
 #define Q_SYNC 0x800001
 #define Q_QUOTAON 0x800002
 #define Q_QUOTAOFF 0x800003
-#define Q_GETFMT 0x800004
 /* WARNING: DO NOT EDIT, AUTO-GENERATED CODE - SEE TOP FOR INSTRUCTIONS */
+#define Q_GETFMT 0x800004
 #define Q_GETINFO 0x800005
 #define Q_SETINFO 0x800006
 #define Q_GETQUOTA 0x800007
-#define Q_SETQUOTA 0x800008
 /* WARNING: DO NOT EDIT, AUTO-GENERATED CODE - SEE TOP FOR INSTRUCTIONS */
+#define Q_SETQUOTA 0x800008
 #define QFMT_VFS_OLD 1
 #define QFMT_VFS_V0 2
 #define QFMT_OCFS2 3
-#define QFMT_VFS_V1 4
 /* WARNING: DO NOT EDIT, AUTO-GENERATED CODE - SEE TOP FOR INSTRUCTIONS */
+#define QFMT_VFS_V1 4
 #define QIF_DQBLKSIZE_BITS 10
 #define QIF_DQBLKSIZE (1 << QIF_DQBLKSIZE_BITS)
 enum {
-  QIF_BLIMITS_B = 0,
 /* WARNING: DO NOT EDIT, AUTO-GENERATED CODE - SEE TOP FOR INSTRUCTIONS */
+  QIF_BLIMITS_B = 0,
   QIF_SPACE_B,
   QIF_ILIMITS_B,
   QIF_INODES_B,
-  QIF_BTIME_B,
 /* WARNING: DO NOT EDIT, AUTO-GENERATED CODE - SEE TOP FOR INSTRUCTIONS */
+  QIF_BTIME_B,
   QIF_ITIME_B,
 };
 #define QIF_BLIMITS (1 << QIF_BLIMITS_B)
-#define QIF_SPACE (1 << QIF_SPACE_B)
 /* WARNING: DO NOT EDIT, AUTO-GENERATED CODE - SEE TOP FOR INSTRUCTIONS */
+#define QIF_SPACE (1 << QIF_SPACE_B)
 #define QIF_ILIMITS (1 << QIF_ILIMITS_B)
 #define QIF_INODES (1 << QIF_INODES_B)
 #define QIF_BTIME (1 << QIF_BTIME_B)
-#define QIF_ITIME (1 << QIF_ITIME_B)
 /* WARNING: DO NOT EDIT, AUTO-GENERATED CODE - SEE TOP FOR INSTRUCTIONS */
+#define QIF_ITIME (1 << QIF_ITIME_B)
 #define QIF_LIMITS (QIF_BLIMITS | QIF_ILIMITS)
 #define QIF_USAGE (QIF_SPACE | QIF_INODES)
 #define QIF_TIMES (QIF_BTIME | QIF_ITIME)
-#define QIF_ALL (QIF_LIMITS | QIF_USAGE | QIF_TIMES)
 /* WARNING: DO NOT EDIT, AUTO-GENERATED CODE - SEE TOP FOR INSTRUCTIONS */
+#define QIF_ALL (QIF_LIMITS | QIF_USAGE | QIF_TIMES)
 struct if_dqblk {
   __u64 dqb_bhardlimit;
   __u64 dqb_bsoftlimit;
-  __u64 dqb_curspace;
 /* WARNING: DO NOT EDIT, AUTO-GENERATED CODE - SEE TOP FOR INSTRUCTIONS */
+  __u64 dqb_curspace;
   __u64 dqb_ihardlimit;
   __u64 dqb_isoftlimit;
   __u64 dqb_curinodes;
-  __u64 dqb_btime;
 /* WARNING: DO NOT EDIT, AUTO-GENERATED CODE - SEE TOP FOR INSTRUCTIONS */
+  __u64 dqb_btime;
   __u64 dqb_itime;
   __u32 dqb_valid;
 };
-#define IIF_BGRACE 1
 /* WARNING: DO NOT EDIT, AUTO-GENERATED CODE - SEE TOP FOR INSTRUCTIONS */
+#define IIF_BGRACE 1
 #define IIF_IGRACE 2
 #define IIF_FLAGS 4
 #define IIF_ALL (IIF_BGRACE | IIF_IGRACE | IIF_FLAGS)
+/* WARNING: DO NOT EDIT, AUTO-GENERATED CODE - SEE TOP FOR INSTRUCTIONS */
+enum {
+  DQF_ROOT_SQUASH_B = 0,
+  DQF_SYS_FILE_B = 16,
+  DQF_PRIVATE
+/* WARNING: DO NOT EDIT, AUTO-GENERATED CODE - SEE TOP FOR INSTRUCTIONS */
+};
+#define DQF_ROOT_SQUASH (1 << DQF_ROOT_SQUASH_B)
+#define DQF_SYS_FILE (1 << DQF_SYS_FILE_B)
 struct if_dqinfo {
 /* WARNING: DO NOT EDIT, AUTO-GENERATED CODE - SEE TOP FOR INSTRUCTIONS */
   __u64 dqi_bgrace;
diff --git a/libc/kernel/uapi/linux/raid/md_p.h b/libc/kernel/uapi/linux/raid/md_p.h
index bdf8e7c..b24e5d6 100644
--- a/libc/kernel/uapi/linux/raid/md_p.h
+++ b/libc/kernel/uapi/linux/raid/md_p.h
@@ -49,21 +49,31 @@
 #define MD_DISK_ACTIVE 1
 #define MD_DISK_SYNC 2
 #define MD_DISK_REMOVED 3
-#define MD_DISK_WRITEMOSTLY 9
+#define MD_DISK_CLUSTER_ADD 4
 /* WARNING: DO NOT EDIT, AUTO-GENERATED CODE - SEE TOP FOR INSTRUCTIONS */
+#define MD_DISK_CANDIDATE 5
+#define MD_DISK_WRITEMOSTLY 9
+#define MD_DISK_JOURNAL 18
+#define MD_DISK_ROLE_SPARE 0xffff
+/* WARNING: DO NOT EDIT, AUTO-GENERATED CODE - SEE TOP FOR INSTRUCTIONS */
+#define MD_DISK_ROLE_FAULTY 0xfffe
+#define MD_DISK_ROLE_JOURNAL 0xfffd
+#define MD_DISK_ROLE_MAX 0xff00
 typedef struct mdp_device_descriptor_s {
+/* WARNING: DO NOT EDIT, AUTO-GENERATED CODE - SEE TOP FOR INSTRUCTIONS */
   __u32 number;
   __u32 major;
   __u32 minor;
-/* WARNING: DO NOT EDIT, AUTO-GENERATED CODE - SEE TOP FOR INSTRUCTIONS */
   __u32 raid_disk;
+/* WARNING: DO NOT EDIT, AUTO-GENERATED CODE - SEE TOP FOR INSTRUCTIONS */
   __u32 state;
   __u32 reserved[MD_SB_DESCRIPTOR_WORDS - 5];
 } mdp_disk_t;
-/* WARNING: DO NOT EDIT, AUTO-GENERATED CODE - SEE TOP FOR INSTRUCTIONS */
 #define MD_SB_MAGIC 0xa92b4efc
+/* WARNING: DO NOT EDIT, AUTO-GENERATED CODE - SEE TOP FOR INSTRUCTIONS */
 #define MD_SB_CLEAN 0
 #define MD_SB_ERRORS 1
+#define MD_SB_CLUSTERED 5
 #define MD_SB_BITMAP_PRESENT 8
 /* WARNING: DO NOT EDIT, AUTO-GENERATED CODE - SEE TOP FOR INSTRUCTIONS */
 typedef struct mdp_superblock_s {
@@ -163,37 +173,94 @@
 /* WARNING: DO NOT EDIT, AUTO-GENERATED CODE - SEE TOP FOR INSTRUCTIONS */
   __le64 data_size;
   __le64 super_offset;
-  __le64 recovery_offset;
-  __le32 dev_number;
+  union {
+    __le64 recovery_offset;
 /* WARNING: DO NOT EDIT, AUTO-GENERATED CODE - SEE TOP FOR INSTRUCTIONS */
+    __le64 journal_tail;
+  };
+  __le32 dev_number;
   __le32 cnt_corrected_read;
+/* WARNING: DO NOT EDIT, AUTO-GENERATED CODE - SEE TOP FOR INSTRUCTIONS */
   __u8 device_uuid[16];
   __u8 devflags;
 #define WriteMostly1 1
-/* WARNING: DO NOT EDIT, AUTO-GENERATED CODE - SEE TOP FOR INSTRUCTIONS */
   __u8 bblog_shift;
+/* WARNING: DO NOT EDIT, AUTO-GENERATED CODE - SEE TOP FOR INSTRUCTIONS */
   __le16 bblog_size;
   __le32 bblog_offset;
   __le64 utime;
-/* WARNING: DO NOT EDIT, AUTO-GENERATED CODE - SEE TOP FOR INSTRUCTIONS */
   __le64 events;
+/* WARNING: DO NOT EDIT, AUTO-GENERATED CODE - SEE TOP FOR INSTRUCTIONS */
   __le64 resync_offset;
   __le32 sb_csum;
   __le32 max_dev;
-/* WARNING: DO NOT EDIT, AUTO-GENERATED CODE - SEE TOP FOR INSTRUCTIONS */
   __u8 pad3[64 - 32];
+/* WARNING: DO NOT EDIT, AUTO-GENERATED CODE - SEE TOP FOR INSTRUCTIONS */
   __le16 dev_roles[0];
 };
 #define MD_FEATURE_BITMAP_OFFSET 1
-/* WARNING: DO NOT EDIT, AUTO-GENERATED CODE - SEE TOP FOR INSTRUCTIONS */
 #define MD_FEATURE_RECOVERY_OFFSET 2
+/* WARNING: DO NOT EDIT, AUTO-GENERATED CODE - SEE TOP FOR INSTRUCTIONS */
 #define MD_FEATURE_RESHAPE_ACTIVE 4
 #define MD_FEATURE_BAD_BLOCKS 8
 #define MD_FEATURE_REPLACEMENT 16
-/* WARNING: DO NOT EDIT, AUTO-GENERATED CODE - SEE TOP FOR INSTRUCTIONS */
 #define MD_FEATURE_RESHAPE_BACKWARDS 32
+/* WARNING: DO NOT EDIT, AUTO-GENERATED CODE - SEE TOP FOR INSTRUCTIONS */
 #define MD_FEATURE_NEW_OFFSET 64
 #define MD_FEATURE_RECOVERY_BITMAP 128
-#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)
+#define MD_FEATURE_CLUSTERED 256
+#define MD_FEATURE_JOURNAL 512
 /* WARNING: DO NOT EDIT, AUTO-GENERATED CODE - SEE TOP FOR INSTRUCTIONS */
+#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)
+struct r5l_payload_header {
+  __le16 type;
+  __le16 flags;
+/* WARNING: DO NOT EDIT, AUTO-GENERATED CODE - SEE TOP FOR INSTRUCTIONS */
+} __attribute__((__packed__));
+enum r5l_payload_type {
+  R5LOG_PAYLOAD_DATA = 0,
+  R5LOG_PAYLOAD_PARITY = 1,
+/* WARNING: DO NOT EDIT, AUTO-GENERATED CODE - SEE TOP FOR INSTRUCTIONS */
+  R5LOG_PAYLOAD_FLUSH = 2,
+};
+struct r5l_payload_data_parity {
+  struct r5l_payload_header header;
+/* WARNING: DO NOT EDIT, AUTO-GENERATED CODE - SEE TOP FOR INSTRUCTIONS */
+  __le32 size;
+  __le64 location;
+  __le32 checksum[];
+} __attribute__((__packed__));
+/* WARNING: DO NOT EDIT, AUTO-GENERATED CODE - SEE TOP FOR INSTRUCTIONS */
+enum r5l_payload_data_parity_flag {
+  R5LOG_PAYLOAD_FLAG_DISCARD = 1,
+  R5LOG_PAYLOAD_FLAG_RESHAPED = 2,
+  R5LOG_PAYLOAD_FLAG_RESHAPING = 3,
+/* WARNING: DO NOT EDIT, AUTO-GENERATED CODE - SEE TOP FOR INSTRUCTIONS */
+};
+struct r5l_payload_flush {
+  struct r5l_payload_header header;
+  __le32 size;
+/* WARNING: DO NOT EDIT, AUTO-GENERATED CODE - SEE TOP FOR INSTRUCTIONS */
+  __le64 flush_stripes[];
+} __attribute__((__packed__));
+enum r5l_payload_flush_flag {
+  R5LOG_PAYLOAD_FLAG_FLUSH_STRIPE = 1,
+/* WARNING: DO NOT EDIT, AUTO-GENERATED CODE - SEE TOP FOR INSTRUCTIONS */
+};
+struct r5l_meta_block {
+  __le32 magic;
+  __le32 checksum;
+/* WARNING: DO NOT EDIT, AUTO-GENERATED CODE - SEE TOP FOR INSTRUCTIONS */
+  __u8 version;
+  __u8 __zero_pading_1;
+  __le16 __zero_pading_2;
+  __le32 meta_size;
+/* WARNING: DO NOT EDIT, AUTO-GENERATED CODE - SEE TOP FOR INSTRUCTIONS */
+  __le64 seq;
+  __le64 position;
+  struct r5l_payload_header payloads[];
+} __attribute__((__packed__));
+/* WARNING: DO NOT EDIT, AUTO-GENERATED CODE - SEE TOP FOR INSTRUCTIONS */
+#define R5LOG_VERSION 0x1
+#define R5LOG_MAGIC 0x6433c509
 #endif
diff --git a/libc/kernel/uapi/linux/raid/md_u.h b/libc/kernel/uapi/linux/raid/md_u.h
index 7a9fa61..66ab2ba 100644
--- a/libc/kernel/uapi/linux/raid/md_u.h
+++ b/libc/kernel/uapi/linux/raid/md_u.h
@@ -48,68 +48,69 @@
 /* WARNING: DO NOT EDIT, AUTO-GENERATED CODE - SEE TOP FOR INSTRUCTIONS */
 #define STOP_ARRAY_RO _IO(MD_MAJOR, 0x33)
 #define RESTART_ARRAY_RW _IO(MD_MAJOR, 0x34)
+#define CLUSTERED_DISK_NACK _IO(MD_MAJOR, 0x35)
 #define MdpMinorShift 6
-typedef struct mdu_version_s {
 /* WARNING: DO NOT EDIT, AUTO-GENERATED CODE - SEE TOP FOR INSTRUCTIONS */
+typedef struct mdu_version_s {
   int major;
   int minor;
   int patchlevel;
-} mdu_version_t;
 /* WARNING: DO NOT EDIT, AUTO-GENERATED CODE - SEE TOP FOR INSTRUCTIONS */
+} mdu_version_t;
 typedef struct mdu_array_info_s {
   int major_version;
   int minor_version;
-  int patch_version;
 /* WARNING: DO NOT EDIT, AUTO-GENERATED CODE - SEE TOP FOR INSTRUCTIONS */
+  int patch_version;
   int ctime;
   int level;
   int size;
-  int nr_disks;
 /* WARNING: DO NOT EDIT, AUTO-GENERATED CODE - SEE TOP FOR INSTRUCTIONS */
+  int nr_disks;
   int raid_disks;
   int md_minor;
   int not_persistent;
-  int utime;
 /* WARNING: DO NOT EDIT, AUTO-GENERATED CODE - SEE TOP FOR INSTRUCTIONS */
+  int utime;
   int state;
   int active_disks;
   int working_disks;
-  int failed_disks;
 /* WARNING: DO NOT EDIT, AUTO-GENERATED CODE - SEE TOP FOR INSTRUCTIONS */
+  int failed_disks;
   int spare_disks;
   int layout;
   int chunk_size;
-} mdu_array_info_t;
 /* WARNING: DO NOT EDIT, AUTO-GENERATED CODE - SEE TOP FOR INSTRUCTIONS */
+} mdu_array_info_t;
 #define LEVEL_MULTIPATH (- 4)
 #define LEVEL_LINEAR (- 1)
 #define LEVEL_FAULTY (- 5)
-#define LEVEL_NONE (- 1000000)
 /* WARNING: DO NOT EDIT, AUTO-GENERATED CODE - SEE TOP FOR INSTRUCTIONS */
+#define LEVEL_NONE (- 1000000)
 typedef struct mdu_disk_info_s {
   int number;
   int major;
-  int minor;
 /* WARNING: DO NOT EDIT, AUTO-GENERATED CODE - SEE TOP FOR INSTRUCTIONS */
+  int minor;
   int raid_disk;
   int state;
 } mdu_disk_info_t;
-typedef struct mdu_start_info_s {
 /* WARNING: DO NOT EDIT, AUTO-GENERATED CODE - SEE TOP FOR INSTRUCTIONS */
+typedef struct mdu_start_info_s {
   int major;
   int minor;
   int raid_disk;
-  int state;
 /* WARNING: DO NOT EDIT, AUTO-GENERATED CODE - SEE TOP FOR INSTRUCTIONS */
+  int state;
 } mdu_start_info_t;
 typedef struct mdu_bitmap_file_s {
   char pathname[4096];
-} mdu_bitmap_file_t;
 /* WARNING: DO NOT EDIT, AUTO-GENERATED CODE - SEE TOP FOR INSTRUCTIONS */
+} mdu_bitmap_file_t;
 typedef struct mdu_param_s {
   int personality;
   int chunk_size;
-  int max_fault;
 /* WARNING: DO NOT EDIT, AUTO-GENERATED CODE - SEE TOP FOR INSTRUCTIONS */
+  int max_fault;
 } mdu_param_t;
 #endif
diff --git a/libc/kernel/uapi/linux/rds.h b/libc/kernel/uapi/linux/rds.h
index 66cb905..ac2f77f 100644
--- a/libc/kernel/uapi/linux/rds.h
+++ b/libc/kernel/uapi/linux/rds.h
@@ -21,203 +21,211 @@
 #include <linux/types.h>
 #define RDS_IB_ABI_VERSION 0x301
 /* WARNING: DO NOT EDIT, AUTO-GENERATED CODE - SEE TOP FOR INSTRUCTIONS */
+#define SOL_RDS 276
 #define RDS_CANCEL_SENT_TO 1
 #define RDS_GET_MR 2
 #define RDS_FREE_MR 3
-#define RDS_RECVERR 5
 /* WARNING: DO NOT EDIT, AUTO-GENERATED CODE - SEE TOP FOR INSTRUCTIONS */
+#define RDS_RECVERR 5
 #define RDS_CONG_MONITOR 6
 #define RDS_GET_MR_FOR_DEST 7
+#define SO_RDS_TRANSPORT 8
+/* WARNING: DO NOT EDIT, AUTO-GENERATED CODE - SEE TOP FOR INSTRUCTIONS */
+#define RDS_TRANS_IB 0
+#define RDS_TRANS_IWARP 1
+#define RDS_TRANS_TCP 2
+#define RDS_TRANS_COUNT 3
+/* WARNING: DO NOT EDIT, AUTO-GENERATED CODE - SEE TOP FOR INSTRUCTIONS */
+#define RDS_TRANS_NONE (~0)
 #define RDS_CMSG_RDMA_ARGS 1
 #define RDS_CMSG_RDMA_DEST 2
-/* WARNING: DO NOT EDIT, AUTO-GENERATED CODE - SEE TOP FOR INSTRUCTIONS */
 #define RDS_CMSG_RDMA_MAP 3
+/* WARNING: DO NOT EDIT, AUTO-GENERATED CODE - SEE TOP FOR INSTRUCTIONS */
 #define RDS_CMSG_RDMA_STATUS 4
 #define RDS_CMSG_CONG_UPDATE 5
 #define RDS_CMSG_ATOMIC_FADD 6
-/* WARNING: DO NOT EDIT, AUTO-GENERATED CODE - SEE TOP FOR INSTRUCTIONS */
 #define RDS_CMSG_ATOMIC_CSWP 7
+/* WARNING: DO NOT EDIT, AUTO-GENERATED CODE - SEE TOP FOR INSTRUCTIONS */
 #define RDS_CMSG_MASKED_ATOMIC_FADD 8
 #define RDS_CMSG_MASKED_ATOMIC_CSWP 9
 #define RDS_INFO_FIRST 10000
-/* WARNING: DO NOT EDIT, AUTO-GENERATED CODE - SEE TOP FOR INSTRUCTIONS */
 #define RDS_INFO_COUNTERS 10000
+/* WARNING: DO NOT EDIT, AUTO-GENERATED CODE - SEE TOP FOR INSTRUCTIONS */
 #define RDS_INFO_CONNECTIONS 10001
 #define RDS_INFO_SEND_MESSAGES 10003
 #define RDS_INFO_RETRANS_MESSAGES 10004
-/* WARNING: DO NOT EDIT, AUTO-GENERATED CODE - SEE TOP FOR INSTRUCTIONS */
 #define RDS_INFO_RECV_MESSAGES 10005
+/* WARNING: DO NOT EDIT, AUTO-GENERATED CODE - SEE TOP FOR INSTRUCTIONS */
 #define RDS_INFO_SOCKETS 10006
 #define RDS_INFO_TCP_SOCKETS 10007
 #define RDS_INFO_IB_CONNECTIONS 10008
-/* WARNING: DO NOT EDIT, AUTO-GENERATED CODE - SEE TOP FOR INSTRUCTIONS */
 #define RDS_INFO_CONNECTION_STATS 10009
+/* WARNING: DO NOT EDIT, AUTO-GENERATED CODE - SEE TOP FOR INSTRUCTIONS */
 #define RDS_INFO_IWARP_CONNECTIONS 10010
 #define RDS_INFO_LAST 10010
 struct rds_info_counter {
-/* WARNING: DO NOT EDIT, AUTO-GENERATED CODE - SEE TOP FOR INSTRUCTIONS */
   uint8_t name[32];
+/* WARNING: DO NOT EDIT, AUTO-GENERATED CODE - SEE TOP FOR INSTRUCTIONS */
   uint64_t value;
 } __attribute__((packed));
 #define RDS_INFO_CONNECTION_FLAG_SENDING 0x01
-/* WARNING: DO NOT EDIT, AUTO-GENERATED CODE - SEE TOP FOR INSTRUCTIONS */
 #define RDS_INFO_CONNECTION_FLAG_CONNECTING 0x02
+/* WARNING: DO NOT EDIT, AUTO-GENERATED CODE - SEE TOP FOR INSTRUCTIONS */
 #define RDS_INFO_CONNECTION_FLAG_CONNECTED 0x04
 #define TRANSNAMSIZ 16
 struct rds_info_connection {
-/* WARNING: DO NOT EDIT, AUTO-GENERATED CODE - SEE TOP FOR INSTRUCTIONS */
   uint64_t next_tx_seq;
+/* WARNING: DO NOT EDIT, AUTO-GENERATED CODE - SEE TOP FOR INSTRUCTIONS */
   uint64_t next_rx_seq;
   __be32 laddr;
   __be32 faddr;
-/* WARNING: DO NOT EDIT, AUTO-GENERATED CODE - SEE TOP FOR INSTRUCTIONS */
   uint8_t transport[TRANSNAMSIZ];
+/* WARNING: DO NOT EDIT, AUTO-GENERATED CODE - SEE TOP FOR INSTRUCTIONS */
   uint8_t flags;
 } __attribute__((packed));
 #define RDS_INFO_MESSAGE_FLAG_ACK 0x01
-/* WARNING: DO NOT EDIT, AUTO-GENERATED CODE - SEE TOP FOR INSTRUCTIONS */
 #define RDS_INFO_MESSAGE_FLAG_FAST_ACK 0x02
+/* WARNING: DO NOT EDIT, AUTO-GENERATED CODE - SEE TOP FOR INSTRUCTIONS */
 struct rds_info_message {
   uint64_t seq;
   uint32_t len;
-/* WARNING: DO NOT EDIT, AUTO-GENERATED CODE - SEE TOP FOR INSTRUCTIONS */
   __be32 laddr;
+/* WARNING: DO NOT EDIT, AUTO-GENERATED CODE - SEE TOP FOR INSTRUCTIONS */
   __be32 faddr;
   __be16 lport;
   __be16 fport;
-/* WARNING: DO NOT EDIT, AUTO-GENERATED CODE - SEE TOP FOR INSTRUCTIONS */
   uint8_t flags;
+/* WARNING: DO NOT EDIT, AUTO-GENERATED CODE - SEE TOP FOR INSTRUCTIONS */
 } __attribute__((packed));
 struct rds_info_socket {
   uint32_t sndbuf;
-/* WARNING: DO NOT EDIT, AUTO-GENERATED CODE - SEE TOP FOR INSTRUCTIONS */
   __be32 bound_addr;
+/* WARNING: DO NOT EDIT, AUTO-GENERATED CODE - SEE TOP FOR INSTRUCTIONS */
   __be32 connected_addr;
   __be16 bound_port;
   __be16 connected_port;
-/* WARNING: DO NOT EDIT, AUTO-GENERATED CODE - SEE TOP FOR INSTRUCTIONS */
   uint32_t rcvbuf;
+/* WARNING: DO NOT EDIT, AUTO-GENERATED CODE - SEE TOP FOR INSTRUCTIONS */
   uint64_t inum;
 } __attribute__((packed));
 struct rds_info_tcp_socket {
-/* WARNING: DO NOT EDIT, AUTO-GENERATED CODE - SEE TOP FOR INSTRUCTIONS */
   __be32 local_addr;
+/* WARNING: DO NOT EDIT, AUTO-GENERATED CODE - SEE TOP FOR INSTRUCTIONS */
   __be16 local_port;
   __be32 peer_addr;
   __be16 peer_port;
-/* WARNING: DO NOT EDIT, AUTO-GENERATED CODE - SEE TOP FOR INSTRUCTIONS */
   uint64_t hdr_rem;
+/* WARNING: DO NOT EDIT, AUTO-GENERATED CODE - SEE TOP FOR INSTRUCTIONS */
   uint64_t data_rem;
   uint32_t last_sent_nxt;
   uint32_t last_expected_una;
-/* WARNING: DO NOT EDIT, AUTO-GENERATED CODE - SEE TOP FOR INSTRUCTIONS */
   uint32_t last_seen_una;
+/* WARNING: DO NOT EDIT, AUTO-GENERATED CODE - SEE TOP FOR INSTRUCTIONS */
 } __attribute__((packed));
 #define RDS_IB_GID_LEN 16
 struct rds_info_rdma_connection {
-/* WARNING: DO NOT EDIT, AUTO-GENERATED CODE - SEE TOP FOR INSTRUCTIONS */
   __be32 src_addr;
+/* WARNING: DO NOT EDIT, AUTO-GENERATED CODE - SEE TOP FOR INSTRUCTIONS */
   __be32 dst_addr;
   uint8_t src_gid[RDS_IB_GID_LEN];
   uint8_t dst_gid[RDS_IB_GID_LEN];
-/* WARNING: DO NOT EDIT, AUTO-GENERATED CODE - SEE TOP FOR INSTRUCTIONS */
   uint32_t max_send_wr;
+/* WARNING: DO NOT EDIT, AUTO-GENERATED CODE - SEE TOP FOR INSTRUCTIONS */
   uint32_t max_recv_wr;
   uint32_t max_send_sge;
   uint32_t rdma_mr_max;
-/* WARNING: DO NOT EDIT, AUTO-GENERATED CODE - SEE TOP FOR INSTRUCTIONS */
   uint32_t rdma_mr_size;
+/* WARNING: DO NOT EDIT, AUTO-GENERATED CODE - SEE TOP FOR INSTRUCTIONS */
 };
 #define RDS_CONG_MONITOR_SIZE 64
 #define RDS_CONG_MONITOR_BIT(port) (((unsigned int) port) % RDS_CONG_MONITOR_SIZE)
-/* WARNING: DO NOT EDIT, AUTO-GENERATED CODE - SEE TOP FOR INSTRUCTIONS */
 #define RDS_CONG_MONITOR_MASK(port) (1ULL << RDS_CONG_MONITOR_BIT(port))
+/* WARNING: DO NOT EDIT, AUTO-GENERATED CODE - SEE TOP FOR INSTRUCTIONS */
 typedef uint64_t rds_rdma_cookie_t;
 struct rds_iovec {
   uint64_t addr;
-/* WARNING: DO NOT EDIT, AUTO-GENERATED CODE - SEE TOP FOR INSTRUCTIONS */
   uint64_t bytes;
+/* WARNING: DO NOT EDIT, AUTO-GENERATED CODE - SEE TOP FOR INSTRUCTIONS */
 };
 struct rds_get_mr_args {
   struct rds_iovec vec;
-/* WARNING: DO NOT EDIT, AUTO-GENERATED CODE - SEE TOP FOR INSTRUCTIONS */
   uint64_t cookie_addr;
+/* WARNING: DO NOT EDIT, AUTO-GENERATED CODE - SEE TOP FOR INSTRUCTIONS */
   uint64_t flags;
 };
 struct rds_get_mr_for_dest_args {
-/* WARNING: DO NOT EDIT, AUTO-GENERATED CODE - SEE TOP FOR INSTRUCTIONS */
   struct sockaddr_storage dest_addr;
+/* WARNING: DO NOT EDIT, AUTO-GENERATED CODE - SEE TOP FOR INSTRUCTIONS */
   struct rds_iovec vec;
   uint64_t cookie_addr;
   uint64_t flags;
-/* WARNING: DO NOT EDIT, AUTO-GENERATED CODE - SEE TOP FOR INSTRUCTIONS */
 };
+/* WARNING: DO NOT EDIT, AUTO-GENERATED CODE - SEE TOP FOR INSTRUCTIONS */
 struct rds_free_mr_args {
   rds_rdma_cookie_t cookie;
   uint64_t flags;
-/* WARNING: DO NOT EDIT, AUTO-GENERATED CODE - SEE TOP FOR INSTRUCTIONS */
 };
+/* WARNING: DO NOT EDIT, AUTO-GENERATED CODE - SEE TOP FOR INSTRUCTIONS */
 struct rds_rdma_args {
   rds_rdma_cookie_t cookie;
   struct rds_iovec remote_vec;
-/* WARNING: DO NOT EDIT, AUTO-GENERATED CODE - SEE TOP FOR INSTRUCTIONS */
   uint64_t local_vec_addr;
+/* WARNING: DO NOT EDIT, AUTO-GENERATED CODE - SEE TOP FOR INSTRUCTIONS */
   uint64_t nr_local;
   uint64_t flags;
   uint64_t user_token;
-/* WARNING: DO NOT EDIT, AUTO-GENERATED CODE - SEE TOP FOR INSTRUCTIONS */
 };
+/* WARNING: DO NOT EDIT, AUTO-GENERATED CODE - SEE TOP FOR INSTRUCTIONS */
 struct rds_atomic_args {
   rds_rdma_cookie_t cookie;
   uint64_t local_addr;
-/* WARNING: DO NOT EDIT, AUTO-GENERATED CODE - SEE TOP FOR INSTRUCTIONS */
   uint64_t remote_addr;
+/* WARNING: DO NOT EDIT, AUTO-GENERATED CODE - SEE TOP FOR INSTRUCTIONS */
   union {
     struct {
       uint64_t compare;
-/* WARNING: DO NOT EDIT, AUTO-GENERATED CODE - SEE TOP FOR INSTRUCTIONS */
       uint64_t swap;
+/* WARNING: DO NOT EDIT, AUTO-GENERATED CODE - SEE TOP FOR INSTRUCTIONS */
     } cswp;
     struct {
       uint64_t add;
-/* WARNING: DO NOT EDIT, AUTO-GENERATED CODE - SEE TOP FOR INSTRUCTIONS */
     } fadd;
+/* WARNING: DO NOT EDIT, AUTO-GENERATED CODE - SEE TOP FOR INSTRUCTIONS */
     struct {
       uint64_t compare;
       uint64_t swap;
-/* WARNING: DO NOT EDIT, AUTO-GENERATED CODE - SEE TOP FOR INSTRUCTIONS */
       uint64_t compare_mask;
+/* WARNING: DO NOT EDIT, AUTO-GENERATED CODE - SEE TOP FOR INSTRUCTIONS */
       uint64_t swap_mask;
     } m_cswp;
     struct {
-/* WARNING: DO NOT EDIT, AUTO-GENERATED CODE - SEE TOP FOR INSTRUCTIONS */
       uint64_t add;
+/* WARNING: DO NOT EDIT, AUTO-GENERATED CODE - SEE TOP FOR INSTRUCTIONS */
       uint64_t nocarry_mask;
     } m_fadd;
   };
-/* WARNING: DO NOT EDIT, AUTO-GENERATED CODE - SEE TOP FOR INSTRUCTIONS */
   uint64_t flags;
+/* WARNING: DO NOT EDIT, AUTO-GENERATED CODE - SEE TOP FOR INSTRUCTIONS */
   uint64_t user_token;
 };
 struct rds_rdma_notify {
-/* WARNING: DO NOT EDIT, AUTO-GENERATED CODE - SEE TOP FOR INSTRUCTIONS */
   uint64_t user_token;
+/* WARNING: DO NOT EDIT, AUTO-GENERATED CODE - SEE TOP FOR INSTRUCTIONS */
   int32_t status;
 };
 #define RDS_RDMA_SUCCESS 0
-/* WARNING: DO NOT EDIT, AUTO-GENERATED CODE - SEE TOP FOR INSTRUCTIONS */
 #define RDS_RDMA_REMOTE_ERROR 1
+/* WARNING: DO NOT EDIT, AUTO-GENERATED CODE - SEE TOP FOR INSTRUCTIONS */
 #define RDS_RDMA_CANCELED 2
 #define RDS_RDMA_DROPPED 3
 #define RDS_RDMA_OTHER_ERROR 4
-/* WARNING: DO NOT EDIT, AUTO-GENERATED CODE - SEE TOP FOR INSTRUCTIONS */
 #define RDS_RDMA_READWRITE 0x0001
+/* WARNING: DO NOT EDIT, AUTO-GENERATED CODE - SEE TOP FOR INSTRUCTIONS */
 #define RDS_RDMA_FENCE 0x0002
 #define RDS_RDMA_INVALIDATE 0x0004
 #define RDS_RDMA_USE_ONCE 0x0008
-/* WARNING: DO NOT EDIT, AUTO-GENERATED CODE - SEE TOP FOR INSTRUCTIONS */
 #define RDS_RDMA_DONTWAIT 0x0010
+/* WARNING: DO NOT EDIT, AUTO-GENERATED CODE - SEE TOP FOR INSTRUCTIONS */
 #define RDS_RDMA_NOTIFY_ME 0x0020
 #define RDS_RDMA_SILENT 0x0040
 #endif
-/* WARNING: DO NOT EDIT, AUTO-GENERATED CODE - SEE TOP FOR INSTRUCTIONS */
diff --git a/libc/kernel/uapi/linux/rtnetlink.h b/libc/kernel/uapi/linux/rtnetlink.h
index f0779cf..81b709b 100644
--- a/libc/kernel/uapi/linux/rtnetlink.h
+++ b/libc/kernel/uapi/linux/rtnetlink.h
@@ -144,95 +144,105 @@
 #define RTM_DELMDB RTM_DELMDB
   RTM_GETMDB = 86,
 #define RTM_GETMDB RTM_GETMDB
-  __RTM_MAX,
+  RTM_NEWNSID = 88,
 /* WARNING: DO NOT EDIT, AUTO-GENERATED CODE - SEE TOP FOR INSTRUCTIONS */
+#define RTM_NEWNSID RTM_NEWNSID
+  RTM_DELNSID = 89,
+#define RTM_DELNSID RTM_DELNSID
+  RTM_GETNSID = 90,
+/* WARNING: DO NOT EDIT, AUTO-GENERATED CODE - SEE TOP FOR INSTRUCTIONS */
+#define RTM_GETNSID RTM_GETNSID
+  __RTM_MAX,
 #define RTM_MAX (((__RTM_MAX + 3) & ~3) - 1)
 };
+/* WARNING: DO NOT EDIT, AUTO-GENERATED CODE - SEE TOP FOR INSTRUCTIONS */
 #define RTM_NR_MSGTYPES (RTM_MAX + 1 - RTM_BASE)
 #define RTM_NR_FAMILIES (RTM_NR_MSGTYPES >> 2)
-/* WARNING: DO NOT EDIT, AUTO-GENERATED CODE - SEE TOP FOR INSTRUCTIONS */
 #define RTM_FAM(cmd) (((cmd) - RTM_BASE) >> 2)
 struct rtattr {
+/* WARNING: DO NOT EDIT, AUTO-GENERATED CODE - SEE TOP FOR INSTRUCTIONS */
   unsigned short rta_len;
   unsigned short rta_type;
-/* WARNING: DO NOT EDIT, AUTO-GENERATED CODE - SEE TOP FOR INSTRUCTIONS */
 };
-#define RTA_ALIGNTO 4
+#define RTA_ALIGNTO 4U
+/* WARNING: DO NOT EDIT, AUTO-GENERATED CODE - SEE TOP FOR INSTRUCTIONS */
 #define RTA_ALIGN(len) (((len) + RTA_ALIGNTO - 1) & ~(RTA_ALIGNTO - 1))
 #define RTA_OK(rta,len) ((len) >= (int) sizeof(struct rtattr) && (rta)->rta_len >= sizeof(struct rtattr) && (rta)->rta_len <= (len))
-/* WARNING: DO NOT EDIT, AUTO-GENERATED CODE - SEE TOP FOR INSTRUCTIONS */
 #define RTA_NEXT(rta,attrlen) ((attrlen) -= RTA_ALIGN((rta)->rta_len), (struct rtattr *) (((char *) (rta)) + RTA_ALIGN((rta)->rta_len)))
 #define RTA_LENGTH(len) (RTA_ALIGN(sizeof(struct rtattr)) + (len))
+/* WARNING: DO NOT EDIT, AUTO-GENERATED CODE - SEE TOP FOR INSTRUCTIONS */
 #define RTA_SPACE(len) RTA_ALIGN(RTA_LENGTH(len))
 #define RTA_DATA(rta) ((void *) (((char *) (rta)) + RTA_LENGTH(0)))
-/* WARNING: DO NOT EDIT, AUTO-GENERATED CODE - SEE TOP FOR INSTRUCTIONS */
 #define RTA_PAYLOAD(rta) ((int) ((rta)->rta_len) - RTA_LENGTH(0))
 struct rtmsg {
+/* WARNING: DO NOT EDIT, AUTO-GENERATED CODE - SEE TOP FOR INSTRUCTIONS */
   unsigned char rtm_family;
   unsigned char rtm_dst_len;
-/* WARNING: DO NOT EDIT, AUTO-GENERATED CODE - SEE TOP FOR INSTRUCTIONS */
   unsigned char rtm_src_len;
   unsigned char rtm_tos;
+/* WARNING: DO NOT EDIT, AUTO-GENERATED CODE - SEE TOP FOR INSTRUCTIONS */
   unsigned char rtm_table;
   unsigned char rtm_protocol;
-/* WARNING: DO NOT EDIT, AUTO-GENERATED CODE - SEE TOP FOR INSTRUCTIONS */
   unsigned char rtm_scope;
   unsigned char rtm_type;
+/* WARNING: DO NOT EDIT, AUTO-GENERATED CODE - SEE TOP FOR INSTRUCTIONS */
   unsigned rtm_flags;
 };
-/* WARNING: DO NOT EDIT, AUTO-GENERATED CODE - SEE TOP FOR INSTRUCTIONS */
 enum {
   RTN_UNSPEC,
+/* WARNING: DO NOT EDIT, AUTO-GENERATED CODE - SEE TOP FOR INSTRUCTIONS */
   RTN_UNICAST,
   RTN_LOCAL,
-/* WARNING: DO NOT EDIT, AUTO-GENERATED CODE - SEE TOP FOR INSTRUCTIONS */
   RTN_BROADCAST,
   RTN_ANYCAST,
+/* WARNING: DO NOT EDIT, AUTO-GENERATED CODE - SEE TOP FOR INSTRUCTIONS */
   RTN_MULTICAST,
   RTN_BLACKHOLE,
-/* WARNING: DO NOT EDIT, AUTO-GENERATED CODE - SEE TOP FOR INSTRUCTIONS */
   RTN_UNREACHABLE,
   RTN_PROHIBIT,
+/* WARNING: DO NOT EDIT, AUTO-GENERATED CODE - SEE TOP FOR INSTRUCTIONS */
   RTN_THROW,
   RTN_NAT,
-/* WARNING: DO NOT EDIT, AUTO-GENERATED CODE - SEE TOP FOR INSTRUCTIONS */
   RTN_XRESOLVE,
   __RTN_MAX
+/* WARNING: DO NOT EDIT, AUTO-GENERATED CODE - SEE TOP FOR INSTRUCTIONS */
 };
 #define RTN_MAX (__RTN_MAX - 1)
-/* WARNING: DO NOT EDIT, AUTO-GENERATED CODE - SEE TOP FOR INSTRUCTIONS */
 #define RTPROT_UNSPEC 0
 #define RTPROT_REDIRECT 1
+/* WARNING: DO NOT EDIT, AUTO-GENERATED CODE - SEE TOP FOR INSTRUCTIONS */
 #define RTPROT_KERNEL 2
 #define RTPROT_BOOT 3
-/* WARNING: DO NOT EDIT, AUTO-GENERATED CODE - SEE TOP FOR INSTRUCTIONS */
 #define RTPROT_STATIC 4
 #define RTPROT_GATED 8
+/* WARNING: DO NOT EDIT, AUTO-GENERATED CODE - SEE TOP FOR INSTRUCTIONS */
 #define RTPROT_RA 9
 #define RTPROT_MRT 10
-/* WARNING: DO NOT EDIT, AUTO-GENERATED CODE - SEE TOP FOR INSTRUCTIONS */
 #define RTPROT_ZEBRA 11
 #define RTPROT_BIRD 12
+/* WARNING: DO NOT EDIT, AUTO-GENERATED CODE - SEE TOP FOR INSTRUCTIONS */
 #define RTPROT_DNROUTED 13
 #define RTPROT_XORP 14
-/* WARNING: DO NOT EDIT, AUTO-GENERATED CODE - SEE TOP FOR INSTRUCTIONS */
 #define RTPROT_NTK 15
 #define RTPROT_DHCP 16
-#define RTPROT_MROUTED 17
-enum rt_scope_t {
 /* WARNING: DO NOT EDIT, AUTO-GENERATED CODE - SEE TOP FOR INSTRUCTIONS */
+#define RTPROT_MROUTED 17
+#define RTPROT_BABEL 42
+enum rt_scope_t {
   RT_SCOPE_UNIVERSE = 0,
+/* WARNING: DO NOT EDIT, AUTO-GENERATED CODE - SEE TOP FOR INSTRUCTIONS */
   RT_SCOPE_SITE = 200,
   RT_SCOPE_LINK = 253,
   RT_SCOPE_HOST = 254,
-/* WARNING: DO NOT EDIT, AUTO-GENERATED CODE - SEE TOP FOR INSTRUCTIONS */
   RT_SCOPE_NOWHERE = 255
+/* WARNING: DO NOT EDIT, AUTO-GENERATED CODE - SEE TOP FOR INSTRUCTIONS */
 };
 #define RTM_F_NOTIFY 0x100
 #define RTM_F_CLONED 0x200
-/* WARNING: DO NOT EDIT, AUTO-GENERATED CODE - SEE TOP FOR INSTRUCTIONS */
 #define RTM_F_EQUALIZE 0x400
+/* WARNING: DO NOT EDIT, AUTO-GENERATED CODE - SEE TOP FOR INSTRUCTIONS */
 #define RTM_F_PREFIX 0x800
+#define RTM_F_LOOKUP_TABLE 0x1000
 enum rt_class_t {
   RT_TABLE_UNSPEC = 0,
 /* WARNING: DO NOT EDIT, AUTO-GENERATED CODE - SEE TOP FOR INSTRUCTIONS */
@@ -267,23 +277,33 @@
   RTA_MARK,
 /* WARNING: DO NOT EDIT, AUTO-GENERATED CODE - SEE TOP FOR INSTRUCTIONS */
   RTA_MFC_STATS,
+  RTA_VIA,
+  RTA_NEWDST,
+  RTA_PREF,
+/* WARNING: DO NOT EDIT, AUTO-GENERATED CODE - SEE TOP FOR INSTRUCTIONS */
+  RTA_ENCAP_TYPE,
+  RTA_ENCAP,
   __RTA_MAX
 };
-#define RTA_MAX (__RTA_MAX - 1)
 /* WARNING: DO NOT EDIT, AUTO-GENERATED CODE - SEE TOP FOR INSTRUCTIONS */
+#define RTA_MAX (__RTA_MAX - 1)
 #define RTM_RTA(r) ((struct rtattr *) (((char *) (r)) + NLMSG_ALIGN(sizeof(struct rtmsg))))
 #define RTM_PAYLOAD(n) NLMSG_PAYLOAD(n, sizeof(struct rtmsg))
 struct rtnexthop {
-  unsigned short rtnh_len;
 /* WARNING: DO NOT EDIT, AUTO-GENERATED CODE - SEE TOP FOR INSTRUCTIONS */
+  unsigned short rtnh_len;
   unsigned char rtnh_flags;
   unsigned char rtnh_hops;
   int rtnh_ifindex;
-};
 /* WARNING: DO NOT EDIT, AUTO-GENERATED CODE - SEE TOP FOR INSTRUCTIONS */
+};
 #define RTNH_F_DEAD 1
 #define RTNH_F_PERVASIVE 2
 #define RTNH_F_ONLINK 4
+/* WARNING: DO NOT EDIT, AUTO-GENERATED CODE - SEE TOP FOR INSTRUCTIONS */
+#define RTNH_F_OFFLOAD 8
+#define RTNH_F_LINKDOWN 16
+#define RTNH_COMPARE_MASK (RTNH_F_DEAD | RTNH_F_LINKDOWN)
 #define RTNH_ALIGNTO 4
 /* WARNING: DO NOT EDIT, AUTO-GENERATED CODE - SEE TOP FOR INSTRUCTIONS */
 #define RTNH_ALIGN(len) (((len) + RTNH_ALIGNTO - 1) & ~(RTNH_ALIGNTO - 1))
@@ -293,6 +313,11 @@
 /* WARNING: DO NOT EDIT, AUTO-GENERATED CODE - SEE TOP FOR INSTRUCTIONS */
 #define RTNH_SPACE(len) RTNH_ALIGN(RTNH_LENGTH(len))
 #define RTNH_DATA(rtnh) ((struct rtattr *) (((char *) (rtnh)) + RTNH_LENGTH(0)))
+struct rtvia {
+  __kernel_sa_family_t rtvia_family;
+/* WARNING: DO NOT EDIT, AUTO-GENERATED CODE - SEE TOP FOR INSTRUCTIONS */
+  __u8 rtvia_addr[0];
+};
 struct rta_cacheinfo {
   __u32 rta_clntref;
 /* WARNING: DO NOT EDIT, AUTO-GENERATED CODE - SEE TOP FOR INSTRUCTIONS */
@@ -348,233 +373,244 @@
 /* WARNING: DO NOT EDIT, AUTO-GENERATED CODE - SEE TOP FOR INSTRUCTIONS */
   RTAX_QUICKACK,
 #define RTAX_QUICKACK RTAX_QUICKACK
+  RTAX_CC_ALGO,
+#define RTAX_CC_ALGO RTAX_CC_ALGO
+/* WARNING: DO NOT EDIT, AUTO-GENERATED CODE - SEE TOP FOR INSTRUCTIONS */
   __RTAX_MAX
 };
-/* WARNING: DO NOT EDIT, AUTO-GENERATED CODE - SEE TOP FOR INSTRUCTIONS */
 #define RTAX_MAX (__RTAX_MAX - 1)
-#define RTAX_FEATURE_ECN 0x00000001
-#define RTAX_FEATURE_SACK 0x00000002
-#define RTAX_FEATURE_TIMESTAMP 0x00000004
+#define RTAX_FEATURE_ECN (1 << 0)
 /* WARNING: DO NOT EDIT, AUTO-GENERATED CODE - SEE TOP FOR INSTRUCTIONS */
-#define RTAX_FEATURE_ALLFRAG 0x00000008
+#define RTAX_FEATURE_SACK (1 << 1)
+#define RTAX_FEATURE_TIMESTAMP (1 << 2)
+#define RTAX_FEATURE_ALLFRAG (1 << 3)
+#define RTAX_FEATURE_MASK (RTAX_FEATURE_ECN | RTAX_FEATURE_SACK | RTAX_FEATURE_TIMESTAMP | RTAX_FEATURE_ALLFRAG)
+/* WARNING: DO NOT EDIT, AUTO-GENERATED CODE - SEE TOP FOR INSTRUCTIONS */
 struct rta_session {
   __u8 proto;
   __u8 pad1;
-/* WARNING: DO NOT EDIT, AUTO-GENERATED CODE - SEE TOP FOR INSTRUCTIONS */
   __u16 pad2;
+/* WARNING: DO NOT EDIT, AUTO-GENERATED CODE - SEE TOP FOR INSTRUCTIONS */
   union {
     struct {
       __u16 sport;
-/* WARNING: DO NOT EDIT, AUTO-GENERATED CODE - SEE TOP FOR INSTRUCTIONS */
       __u16 dport;
+/* WARNING: DO NOT EDIT, AUTO-GENERATED CODE - SEE TOP FOR INSTRUCTIONS */
     } ports;
     struct {
       __u8 type;
-/* WARNING: DO NOT EDIT, AUTO-GENERATED CODE - SEE TOP FOR INSTRUCTIONS */
       __u8 code;
+/* WARNING: DO NOT EDIT, AUTO-GENERATED CODE - SEE TOP FOR INSTRUCTIONS */
       __u16 ident;
     } icmpt;
     __u32 spi;
-/* WARNING: DO NOT EDIT, AUTO-GENERATED CODE - SEE TOP FOR INSTRUCTIONS */
   } u;
+/* WARNING: DO NOT EDIT, AUTO-GENERATED CODE - SEE TOP FOR INSTRUCTIONS */
 };
 struct rta_mfc_stats {
   __u64 mfcs_packets;
-/* WARNING: DO NOT EDIT, AUTO-GENERATED CODE - SEE TOP FOR INSTRUCTIONS */
   __u64 mfcs_bytes;
+/* WARNING: DO NOT EDIT, AUTO-GENERATED CODE - SEE TOP FOR INSTRUCTIONS */
   __u64 mfcs_wrong_if;
 };
 struct rtgenmsg {
-/* WARNING: DO NOT EDIT, AUTO-GENERATED CODE - SEE TOP FOR INSTRUCTIONS */
   unsigned char rtgen_family;
+/* WARNING: DO NOT EDIT, AUTO-GENERATED CODE - SEE TOP FOR INSTRUCTIONS */
 };
 struct ifinfomsg {
   unsigned char ifi_family;
-/* WARNING: DO NOT EDIT, AUTO-GENERATED CODE - SEE TOP FOR INSTRUCTIONS */
   unsigned char __ifi_pad;
+/* WARNING: DO NOT EDIT, AUTO-GENERATED CODE - SEE TOP FOR INSTRUCTIONS */
   unsigned short ifi_type;
   int ifi_index;
   unsigned ifi_flags;
-/* WARNING: DO NOT EDIT, AUTO-GENERATED CODE - SEE TOP FOR INSTRUCTIONS */
   unsigned ifi_change;
+/* WARNING: DO NOT EDIT, AUTO-GENERATED CODE - SEE TOP FOR INSTRUCTIONS */
 };
 struct prefixmsg {
   unsigned char prefix_family;
-/* WARNING: DO NOT EDIT, AUTO-GENERATED CODE - SEE TOP FOR INSTRUCTIONS */
   unsigned char prefix_pad1;
+/* WARNING: DO NOT EDIT, AUTO-GENERATED CODE - SEE TOP FOR INSTRUCTIONS */
   unsigned short prefix_pad2;
   int prefix_ifindex;
   unsigned char prefix_type;
-/* WARNING: DO NOT EDIT, AUTO-GENERATED CODE - SEE TOP FOR INSTRUCTIONS */
   unsigned char prefix_len;
+/* WARNING: DO NOT EDIT, AUTO-GENERATED CODE - SEE TOP FOR INSTRUCTIONS */
   unsigned char prefix_flags;
   unsigned char prefix_pad3;
 };
-/* WARNING: DO NOT EDIT, AUTO-GENERATED CODE - SEE TOP FOR INSTRUCTIONS */
 enum {
+/* WARNING: DO NOT EDIT, AUTO-GENERATED CODE - SEE TOP FOR INSTRUCTIONS */
   PREFIX_UNSPEC,
   PREFIX_ADDRESS,
   PREFIX_CACHEINFO,
-/* WARNING: DO NOT EDIT, AUTO-GENERATED CODE - SEE TOP FOR INSTRUCTIONS */
   __PREFIX_MAX
+/* WARNING: DO NOT EDIT, AUTO-GENERATED CODE - SEE TOP FOR INSTRUCTIONS */
 };
 #define PREFIX_MAX (__PREFIX_MAX - 1)
 struct prefix_cacheinfo {
-/* WARNING: DO NOT EDIT, AUTO-GENERATED CODE - SEE TOP FOR INSTRUCTIONS */
   __u32 preferred_time;
+/* WARNING: DO NOT EDIT, AUTO-GENERATED CODE - SEE TOP FOR INSTRUCTIONS */
   __u32 valid_time;
 };
 struct tcmsg {
-/* WARNING: DO NOT EDIT, AUTO-GENERATED CODE - SEE TOP FOR INSTRUCTIONS */
   unsigned char tcm_family;
+/* WARNING: DO NOT EDIT, AUTO-GENERATED CODE - SEE TOP FOR INSTRUCTIONS */
   unsigned char tcm__pad1;
   unsigned short tcm__pad2;
   int tcm_ifindex;
-/* WARNING: DO NOT EDIT, AUTO-GENERATED CODE - SEE TOP FOR INSTRUCTIONS */
   __u32 tcm_handle;
+/* WARNING: DO NOT EDIT, AUTO-GENERATED CODE - SEE TOP FOR INSTRUCTIONS */
   __u32 tcm_parent;
   __u32 tcm_info;
 };
-/* WARNING: DO NOT EDIT, AUTO-GENERATED CODE - SEE TOP FOR INSTRUCTIONS */
 enum {
+/* WARNING: DO NOT EDIT, AUTO-GENERATED CODE - SEE TOP FOR INSTRUCTIONS */
   TCA_UNSPEC,
   TCA_KIND,
   TCA_OPTIONS,
-/* WARNING: DO NOT EDIT, AUTO-GENERATED CODE - SEE TOP FOR INSTRUCTIONS */
   TCA_STATS,
+/* WARNING: DO NOT EDIT, AUTO-GENERATED CODE - SEE TOP FOR INSTRUCTIONS */
   TCA_XSTATS,
   TCA_RATE,
   TCA_FCNT,
-/* WARNING: DO NOT EDIT, AUTO-GENERATED CODE - SEE TOP FOR INSTRUCTIONS */
   TCA_STATS2,
+/* WARNING: DO NOT EDIT, AUTO-GENERATED CODE - SEE TOP FOR INSTRUCTIONS */
   TCA_STAB,
   __TCA_MAX
 };
-/* WARNING: DO NOT EDIT, AUTO-GENERATED CODE - SEE TOP FOR INSTRUCTIONS */
 #define TCA_MAX (__TCA_MAX - 1)
+/* WARNING: DO NOT EDIT, AUTO-GENERATED CODE - SEE TOP FOR INSTRUCTIONS */
 #define TCA_RTA(r) ((struct rtattr *) (((char *) (r)) + NLMSG_ALIGN(sizeof(struct tcmsg))))
 #define TCA_PAYLOAD(n) NLMSG_PAYLOAD(n, sizeof(struct tcmsg))
 struct nduseroptmsg {
-/* WARNING: DO NOT EDIT, AUTO-GENERATED CODE - SEE TOP FOR INSTRUCTIONS */
   unsigned char nduseropt_family;
+/* WARNING: DO NOT EDIT, AUTO-GENERATED CODE - SEE TOP FOR INSTRUCTIONS */
   unsigned char nduseropt_pad1;
   unsigned short nduseropt_opts_len;
   int nduseropt_ifindex;
-/* WARNING: DO NOT EDIT, AUTO-GENERATED CODE - SEE TOP FOR INSTRUCTIONS */
   __u8 nduseropt_icmp_type;
+/* WARNING: DO NOT EDIT, AUTO-GENERATED CODE - SEE TOP FOR INSTRUCTIONS */
   __u8 nduseropt_icmp_code;
   unsigned short nduseropt_pad2;
   unsigned int nduseropt_pad3;
-/* WARNING: DO NOT EDIT, AUTO-GENERATED CODE - SEE TOP FOR INSTRUCTIONS */
 };
+/* WARNING: DO NOT EDIT, AUTO-GENERATED CODE - SEE TOP FOR INSTRUCTIONS */
 enum {
   NDUSEROPT_UNSPEC,
   NDUSEROPT_SRCADDR,
-/* WARNING: DO NOT EDIT, AUTO-GENERATED CODE - SEE TOP FOR INSTRUCTIONS */
   __NDUSEROPT_MAX
+/* WARNING: DO NOT EDIT, AUTO-GENERATED CODE - SEE TOP FOR INSTRUCTIONS */
 };
 #define NDUSEROPT_MAX (__NDUSEROPT_MAX - 1)
 #define RTMGRP_LINK 1
-/* WARNING: DO NOT EDIT, AUTO-GENERATED CODE - SEE TOP FOR INSTRUCTIONS */
 #define RTMGRP_NOTIFY 2
+/* WARNING: DO NOT EDIT, AUTO-GENERATED CODE - SEE TOP FOR INSTRUCTIONS */
 #define RTMGRP_NEIGH 4
 #define RTMGRP_TC 8
 #define RTMGRP_IPV4_IFADDR 0x10
-/* WARNING: DO NOT EDIT, AUTO-GENERATED CODE - SEE TOP FOR INSTRUCTIONS */
 #define RTMGRP_IPV4_MROUTE 0x20
+/* WARNING: DO NOT EDIT, AUTO-GENERATED CODE - SEE TOP FOR INSTRUCTIONS */
 #define RTMGRP_IPV4_ROUTE 0x40
 #define RTMGRP_IPV4_RULE 0x80
 #define RTMGRP_IPV6_IFADDR 0x100
-/* WARNING: DO NOT EDIT, AUTO-GENERATED CODE - SEE TOP FOR INSTRUCTIONS */
 #define RTMGRP_IPV6_MROUTE 0x200
+/* WARNING: DO NOT EDIT, AUTO-GENERATED CODE - SEE TOP FOR INSTRUCTIONS */
 #define RTMGRP_IPV6_ROUTE 0x400
 #define RTMGRP_IPV6_IFINFO 0x800
 #define RTMGRP_DECnet_IFADDR 0x1000
-/* WARNING: DO NOT EDIT, AUTO-GENERATED CODE - SEE TOP FOR INSTRUCTIONS */
 #define RTMGRP_DECnet_ROUTE 0x4000
+/* WARNING: DO NOT EDIT, AUTO-GENERATED CODE - SEE TOP FOR INSTRUCTIONS */
 #define RTMGRP_IPV6_PREFIX 0x20000
 enum rtnetlink_groups {
   RTNLGRP_NONE,
-/* WARNING: DO NOT EDIT, AUTO-GENERATED CODE - SEE TOP FOR INSTRUCTIONS */
 #define RTNLGRP_NONE RTNLGRP_NONE
+/* WARNING: DO NOT EDIT, AUTO-GENERATED CODE - SEE TOP FOR INSTRUCTIONS */
   RTNLGRP_LINK,
 #define RTNLGRP_LINK RTNLGRP_LINK
   RTNLGRP_NOTIFY,
-/* WARNING: DO NOT EDIT, AUTO-GENERATED CODE - SEE TOP FOR INSTRUCTIONS */
 #define RTNLGRP_NOTIFY RTNLGRP_NOTIFY
+/* WARNING: DO NOT EDIT, AUTO-GENERATED CODE - SEE TOP FOR INSTRUCTIONS */
   RTNLGRP_NEIGH,
 #define RTNLGRP_NEIGH RTNLGRP_NEIGH
   RTNLGRP_TC,
-/* WARNING: DO NOT EDIT, AUTO-GENERATED CODE - SEE TOP FOR INSTRUCTIONS */
 #define RTNLGRP_TC RTNLGRP_TC
+/* WARNING: DO NOT EDIT, AUTO-GENERATED CODE - SEE TOP FOR INSTRUCTIONS */
   RTNLGRP_IPV4_IFADDR,
 #define RTNLGRP_IPV4_IFADDR RTNLGRP_IPV4_IFADDR
   RTNLGRP_IPV4_MROUTE,
-/* WARNING: DO NOT EDIT, AUTO-GENERATED CODE - SEE TOP FOR INSTRUCTIONS */
 #define RTNLGRP_IPV4_MROUTE RTNLGRP_IPV4_MROUTE
+/* WARNING: DO NOT EDIT, AUTO-GENERATED CODE - SEE TOP FOR INSTRUCTIONS */
   RTNLGRP_IPV4_ROUTE,
 #define RTNLGRP_IPV4_ROUTE RTNLGRP_IPV4_ROUTE
   RTNLGRP_IPV4_RULE,
-/* WARNING: DO NOT EDIT, AUTO-GENERATED CODE - SEE TOP FOR INSTRUCTIONS */
 #define RTNLGRP_IPV4_RULE RTNLGRP_IPV4_RULE
+/* WARNING: DO NOT EDIT, AUTO-GENERATED CODE - SEE TOP FOR INSTRUCTIONS */
   RTNLGRP_IPV6_IFADDR,
 #define RTNLGRP_IPV6_IFADDR RTNLGRP_IPV6_IFADDR
   RTNLGRP_IPV6_MROUTE,
-/* WARNING: DO NOT EDIT, AUTO-GENERATED CODE - SEE TOP FOR INSTRUCTIONS */
 #define RTNLGRP_IPV6_MROUTE RTNLGRP_IPV6_MROUTE
+/* WARNING: DO NOT EDIT, AUTO-GENERATED CODE - SEE TOP FOR INSTRUCTIONS */
   RTNLGRP_IPV6_ROUTE,
 #define RTNLGRP_IPV6_ROUTE RTNLGRP_IPV6_ROUTE
   RTNLGRP_IPV6_IFINFO,
-/* WARNING: DO NOT EDIT, AUTO-GENERATED CODE - SEE TOP FOR INSTRUCTIONS */
 #define RTNLGRP_IPV6_IFINFO RTNLGRP_IPV6_IFINFO
+/* WARNING: DO NOT EDIT, AUTO-GENERATED CODE - SEE TOP FOR INSTRUCTIONS */
   RTNLGRP_DECnet_IFADDR,
 #define RTNLGRP_DECnet_IFADDR RTNLGRP_DECnet_IFADDR
   RTNLGRP_NOP2,
-/* WARNING: DO NOT EDIT, AUTO-GENERATED CODE - SEE TOP FOR INSTRUCTIONS */
   RTNLGRP_DECnet_ROUTE,
+/* WARNING: DO NOT EDIT, AUTO-GENERATED CODE - SEE TOP FOR INSTRUCTIONS */
 #define RTNLGRP_DECnet_ROUTE RTNLGRP_DECnet_ROUTE
   RTNLGRP_DECnet_RULE,
 #define RTNLGRP_DECnet_RULE RTNLGRP_DECnet_RULE
-/* WARNING: DO NOT EDIT, AUTO-GENERATED CODE - SEE TOP FOR INSTRUCTIONS */
   RTNLGRP_NOP4,
+/* WARNING: DO NOT EDIT, AUTO-GENERATED CODE - SEE TOP FOR INSTRUCTIONS */
   RTNLGRP_IPV6_PREFIX,
 #define RTNLGRP_IPV6_PREFIX RTNLGRP_IPV6_PREFIX
   RTNLGRP_IPV6_RULE,
-/* WARNING: DO NOT EDIT, AUTO-GENERATED CODE - SEE TOP FOR INSTRUCTIONS */
 #define RTNLGRP_IPV6_RULE RTNLGRP_IPV6_RULE
+/* WARNING: DO NOT EDIT, AUTO-GENERATED CODE - SEE TOP FOR INSTRUCTIONS */
   RTNLGRP_ND_USEROPT,
 #define RTNLGRP_ND_USEROPT RTNLGRP_ND_USEROPT
   RTNLGRP_PHONET_IFADDR,
-/* WARNING: DO NOT EDIT, AUTO-GENERATED CODE - SEE TOP FOR INSTRUCTIONS */
 #define RTNLGRP_PHONET_IFADDR RTNLGRP_PHONET_IFADDR
+/* WARNING: DO NOT EDIT, AUTO-GENERATED CODE - SEE TOP FOR INSTRUCTIONS */
   RTNLGRP_PHONET_ROUTE,
 #define RTNLGRP_PHONET_ROUTE RTNLGRP_PHONET_ROUTE
   RTNLGRP_DCB,
-/* WARNING: DO NOT EDIT, AUTO-GENERATED CODE - SEE TOP FOR INSTRUCTIONS */
 #define RTNLGRP_DCB RTNLGRP_DCB
+/* WARNING: DO NOT EDIT, AUTO-GENERATED CODE - SEE TOP FOR INSTRUCTIONS */
   RTNLGRP_IPV4_NETCONF,
 #define RTNLGRP_IPV4_NETCONF RTNLGRP_IPV4_NETCONF
   RTNLGRP_IPV6_NETCONF,
-/* WARNING: DO NOT EDIT, AUTO-GENERATED CODE - SEE TOP FOR INSTRUCTIONS */
 #define RTNLGRP_IPV6_NETCONF RTNLGRP_IPV6_NETCONF
+/* WARNING: DO NOT EDIT, AUTO-GENERATED CODE - SEE TOP FOR INSTRUCTIONS */
   RTNLGRP_MDB,
 #define RTNLGRP_MDB RTNLGRP_MDB
-  __RTNLGRP_MAX
+  RTNLGRP_MPLS_ROUTE,
+#define RTNLGRP_MPLS_ROUTE RTNLGRP_MPLS_ROUTE
 /* WARNING: DO NOT EDIT, AUTO-GENERATED CODE - SEE TOP FOR INSTRUCTIONS */
+  RTNLGRP_NSID,
+#define RTNLGRP_NSID RTNLGRP_NSID
+  __RTNLGRP_MAX
 };
+/* WARNING: DO NOT EDIT, AUTO-GENERATED CODE - SEE TOP FOR INSTRUCTIONS */
 #define RTNLGRP_MAX (__RTNLGRP_MAX - 1)
 struct tcamsg {
   unsigned char tca_family;
-/* WARNING: DO NOT EDIT, AUTO-GENERATED CODE - SEE TOP FOR INSTRUCTIONS */
   unsigned char tca__pad1;
+/* WARNING: DO NOT EDIT, AUTO-GENERATED CODE - SEE TOP FOR INSTRUCTIONS */
   unsigned short tca__pad2;
 };
 #define TA_RTA(r) ((struct rtattr *) (((char *) (r)) + NLMSG_ALIGN(sizeof(struct tcamsg))))
-/* WARNING: DO NOT EDIT, AUTO-GENERATED CODE - SEE TOP FOR INSTRUCTIONS */
 #define TA_PAYLOAD(n) NLMSG_PAYLOAD(n, sizeof(struct tcamsg))
+/* WARNING: DO NOT EDIT, AUTO-GENERATED CODE - SEE TOP FOR INSTRUCTIONS */
 #define TCA_ACT_TAB 1
 #define TCAA_MAX 1
 #define RTEXT_FILTER_VF (1 << 0)
-/* WARNING: DO NOT EDIT, AUTO-GENERATED CODE - SEE TOP FOR INSTRUCTIONS */
 #define RTEXT_FILTER_BRVLAN (1 << 1)
+/* WARNING: DO NOT EDIT, AUTO-GENERATED CODE - SEE TOP FOR INSTRUCTIONS */
+#define RTEXT_FILTER_BRVLAN_COMPRESSED (1 << 2)
+#define RTEXT_FILTER_SKIP_STATS (1 << 3)
 #endif
diff --git a/libc/kernel/uapi/linux/scif_ioctl.h b/libc/kernel/uapi/linux/scif_ioctl.h
new file mode 100644
index 0000000..6bb51ce
--- /dev/null
+++ b/libc/kernel/uapi/linux/scif_ioctl.h
@@ -0,0 +1,111 @@
+/****************************************************************************
+ ****************************************************************************
+ ***
+ ***   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 SCIF_IOCTL_H
+#define SCIF_IOCTL_H
+#include <linux/types.h>
+struct scif_port_id {
+/* WARNING: DO NOT EDIT, AUTO-GENERATED CODE - SEE TOP FOR INSTRUCTIONS */
+  __u16 node;
+  __u16 port;
+};
+struct scifioctl_connect {
+/* WARNING: DO NOT EDIT, AUTO-GENERATED CODE - SEE TOP FOR INSTRUCTIONS */
+  struct scif_port_id self;
+  struct scif_port_id peer;
+};
+struct scifioctl_accept {
+/* WARNING: DO NOT EDIT, AUTO-GENERATED CODE - SEE TOP FOR INSTRUCTIONS */
+  __s32 flags;
+  struct scif_port_id peer;
+  __u64 endpt;
+};
+/* WARNING: DO NOT EDIT, AUTO-GENERATED CODE - SEE TOP FOR INSTRUCTIONS */
+struct scifioctl_msg {
+  __u64 msg;
+  __s32 len;
+  __s32 flags;
+/* WARNING: DO NOT EDIT, AUTO-GENERATED CODE - SEE TOP FOR INSTRUCTIONS */
+  __s32 out_len;
+};
+struct scifioctl_reg {
+  __u64 addr;
+/* WARNING: DO NOT EDIT, AUTO-GENERATED CODE - SEE TOP FOR INSTRUCTIONS */
+  __u64 len;
+  __s64 offset;
+  __s32 prot;
+  __s32 flags;
+/* WARNING: DO NOT EDIT, AUTO-GENERATED CODE - SEE TOP FOR INSTRUCTIONS */
+  __s64 out_offset;
+};
+struct scifioctl_unreg {
+  __s64 offset;
+/* WARNING: DO NOT EDIT, AUTO-GENERATED CODE - SEE TOP FOR INSTRUCTIONS */
+  __u64 len;
+};
+struct scifioctl_copy {
+  __s64 loffset;
+/* WARNING: DO NOT EDIT, AUTO-GENERATED CODE - SEE TOP FOR INSTRUCTIONS */
+  __u64 len;
+  __s64 roffset;
+  __u64 addr;
+  __s32 flags;
+/* WARNING: DO NOT EDIT, AUTO-GENERATED CODE - SEE TOP FOR INSTRUCTIONS */
+};
+struct scifioctl_fence_mark {
+  __s32 flags;
+  __u64 mark;
+/* WARNING: DO NOT EDIT, AUTO-GENERATED CODE - SEE TOP FOR INSTRUCTIONS */
+};
+struct scifioctl_fence_signal {
+  __s64 loff;
+  __u64 lval;
+/* WARNING: DO NOT EDIT, AUTO-GENERATED CODE - SEE TOP FOR INSTRUCTIONS */
+  __s64 roff;
+  __u64 rval;
+  __s32 flags;
+};
+/* WARNING: DO NOT EDIT, AUTO-GENERATED CODE - SEE TOP FOR INSTRUCTIONS */
+struct scifioctl_node_ids {
+  __u64 nodes;
+  __u64 self;
+  __s32 len;
+/* WARNING: DO NOT EDIT, AUTO-GENERATED CODE - SEE TOP FOR INSTRUCTIONS */
+};
+#define SCIF_BIND _IOWR('s', 1, __u64)
+#define SCIF_LISTEN _IOW('s', 2, __s32)
+#define SCIF_CONNECT _IOWR('s', 3, struct scifioctl_connect)
+/* WARNING: DO NOT EDIT, AUTO-GENERATED CODE - SEE TOP FOR INSTRUCTIONS */
+#define SCIF_ACCEPTREQ _IOWR('s', 4, struct scifioctl_accept)
+#define SCIF_ACCEPTREG _IOWR('s', 5, __u64)
+#define SCIF_SEND _IOWR('s', 6, struct scifioctl_msg)
+#define SCIF_RECV _IOWR('s', 7, struct scifioctl_msg)
+/* WARNING: DO NOT EDIT, AUTO-GENERATED CODE - SEE TOP FOR INSTRUCTIONS */
+#define SCIF_REG _IOWR('s', 8, struct scifioctl_reg)
+#define SCIF_UNREG _IOWR('s', 9, struct scifioctl_unreg)
+#define SCIF_READFROM _IOWR('s', 10, struct scifioctl_copy)
+#define SCIF_WRITETO _IOWR('s', 11, struct scifioctl_copy)
+/* WARNING: DO NOT EDIT, AUTO-GENERATED CODE - SEE TOP FOR INSTRUCTIONS */
+#define SCIF_VREADFROM _IOWR('s', 12, struct scifioctl_copy)
+#define SCIF_VWRITETO _IOWR('s', 13, struct scifioctl_copy)
+#define SCIF_GET_NODEIDS _IOWR('s', 14, struct scifioctl_node_ids)
+#define SCIF_FENCE_MARK _IOWR('s', 15, struct scifioctl_fence_mark)
+/* WARNING: DO NOT EDIT, AUTO-GENERATED CODE - SEE TOP FOR INSTRUCTIONS */
+#define SCIF_FENCE_WAIT _IOWR('s', 16, __s32)
+#define SCIF_FENCE_SIGNAL _IOWR('s', 17, struct scifioctl_fence_signal)
+#endif
diff --git a/libc/kernel/uapi/linux/screen_info.h b/libc/kernel/uapi/linux/screen_info.h
index cfe22fd..e210fbb 100644
--- a/libc/kernel/uapi/linux/screen_info.h
+++ b/libc/kernel/uapi/linux/screen_info.h
@@ -62,27 +62,29 @@
   __u16 vesa_attributes;
 /* WARNING: DO NOT EDIT, AUTO-GENERATED CODE - SEE TOP FOR INSTRUCTIONS */
   __u32 capabilities;
-  __u8 _reserved[6];
+  __u32 ext_lfb_base;
+  __u8 _reserved[2];
 } __attribute__((packed));
-#define VIDEO_TYPE_MDA 0x10
 /* WARNING: DO NOT EDIT, AUTO-GENERATED CODE - SEE TOP FOR INSTRUCTIONS */
+#define VIDEO_TYPE_MDA 0x10
 #define VIDEO_TYPE_CGA 0x11
 #define VIDEO_TYPE_EGAM 0x20
 #define VIDEO_TYPE_EGAC 0x21
-#define VIDEO_TYPE_VGAC 0x22
 /* WARNING: DO NOT EDIT, AUTO-GENERATED CODE - SEE TOP FOR INSTRUCTIONS */
+#define VIDEO_TYPE_VGAC 0x22
 #define VIDEO_TYPE_VLFB 0x23
 #define VIDEO_TYPE_PICA_S3 0x30
 #define VIDEO_TYPE_MIPS_G364 0x31
-#define VIDEO_TYPE_SGI 0x33
 /* WARNING: DO NOT EDIT, AUTO-GENERATED CODE - SEE TOP FOR INSTRUCTIONS */
+#define VIDEO_TYPE_SGI 0x33
 #define VIDEO_TYPE_TGAC 0x40
 #define VIDEO_TYPE_SUN 0x50
 #define VIDEO_TYPE_SUNPCI 0x51
-#define VIDEO_TYPE_PMAC 0x60
 /* WARNING: DO NOT EDIT, AUTO-GENERATED CODE - SEE TOP FOR INSTRUCTIONS */
+#define VIDEO_TYPE_PMAC 0x60
 #define VIDEO_TYPE_EFI 0x70
 #define VIDEO_FLAGS_NOCURSOR (1 << 0)
 #define VIDEO_CAPABILITY_SKIP_QUIRKS (1 << 0)
-#endif
 /* WARNING: DO NOT EDIT, AUTO-GENERATED CODE - SEE TOP FOR INSTRUCTIONS */
+#define VIDEO_CAPABILITY_64BIT_BASE (1 << 1)
+#endif
diff --git a/libc/kernel/uapi/linux/securebits.h b/libc/kernel/uapi/linux/securebits.h
index a644d5a..ee9e61b 100644
--- a/libc/kernel/uapi/linux/securebits.h
+++ b/libc/kernel/uapi/linux/securebits.h
@@ -36,6 +36,11 @@
 #define SECBIT_KEEP_CAPS (issecure_mask(SECURE_KEEP_CAPS))
 #define SECBIT_KEEP_CAPS_LOCKED (issecure_mask(SECURE_KEEP_CAPS_LOCKED))
 /* WARNING: DO NOT EDIT, AUTO-GENERATED CODE - SEE TOP FOR INSTRUCTIONS */
-#define SECURE_ALL_BITS (issecure_mask(SECURE_NOROOT) | issecure_mask(SECURE_NO_SETUID_FIXUP) | issecure_mask(SECURE_KEEP_CAPS))
+#define SECURE_NO_CAP_AMBIENT_RAISE 6
+#define SECURE_NO_CAP_AMBIENT_RAISE_LOCKED 7
+#define SECBIT_NO_CAP_AMBIENT_RAISE (issecure_mask(SECURE_NO_CAP_AMBIENT_RAISE))
+#define SECBIT_NO_CAP_AMBIENT_RAISE_LOCKED (issecure_mask(SECURE_NO_CAP_AMBIENT_RAISE_LOCKED))
+/* WARNING: DO NOT EDIT, AUTO-GENERATED CODE - SEE TOP FOR INSTRUCTIONS */
+#define SECURE_ALL_BITS (issecure_mask(SECURE_NOROOT) | issecure_mask(SECURE_NO_SETUID_FIXUP) | issecure_mask(SECURE_KEEP_CAPS) | issecure_mask(SECURE_NO_CAP_AMBIENT_RAISE))
 #define SECURE_ALL_LOCKS (SECURE_ALL_BITS << 1)
 #endif
diff --git a/libc/kernel/uapi/linux/sem.h b/libc/kernel/uapi/linux/sem.h
index 04909d5..4f3632b 100644
--- a/libc/kernel/uapi/linux/sem.h
+++ b/libc/kernel/uapi/linux/sem.h
@@ -76,10 +76,10 @@
   int semaem;
 };
 /* WARNING: DO NOT EDIT, AUTO-GENERATED CODE - SEE TOP FOR INSTRUCTIONS */
-#define SEMMNI 128
-#define SEMMSL 250
+#define SEMMNI 32000
+#define SEMMSL 32000
 #define SEMMNS (SEMMNI * SEMMSL)
-#define SEMOPM 32
+#define SEMOPM 500
 /* WARNING: DO NOT EDIT, AUTO-GENERATED CODE - SEE TOP FOR INSTRUCTIONS */
 #define SEMVMX 32767
 #define SEMAEM SEMVMX
diff --git a/libc/kernel/uapi/linux/serial.h b/libc/kernel/uapi/linux/serial.h
index 300176b..494dc9a 100644
--- a/libc/kernel/uapi/linux/serial.h
+++ b/libc/kernel/uapi/linux/serial.h
@@ -71,6 +71,11 @@
 #define SERIAL_IO_HUB6 1
 #define SERIAL_IO_MEM 2
 /* WARNING: DO NOT EDIT, AUTO-GENERATED CODE - SEE TOP FOR INSTRUCTIONS */
+#define SERIAL_IO_MEM32 3
+#define SERIAL_IO_AU 4
+#define SERIAL_IO_TSI 5
+#define SERIAL_IO_MEM32BE 6
+/* WARNING: DO NOT EDIT, AUTO-GENERATED CODE - SEE TOP FOR INSTRUCTIONS */
 #define UART_CLEAR_FIFO 0x01
 #define UART_USE_FIFO 0x02
 #define UART_STARTECH 0x04
diff --git a/libc/kernel/uapi/linux/serial_core.h b/libc/kernel/uapi/linux/serial_core.h
index e310f8d..dcda903 100644
--- a/libc/kernel/uapi/linux/serial_core.h
+++ b/libc/kernel/uapi/linux/serial_core.h
@@ -56,95 +56,103 @@
 #define PORT_ALTR_16550_F64 27
 #define PORT_ALTR_16550_F128 28
 /* WARNING: DO NOT EDIT, AUTO-GENERATED CODE - SEE TOP FOR INSTRUCTIONS */
-#define PORT_MAX_8250 28
+#define PORT_RT2880 29
+#define PORT_16550A_FSL64 30
+#define PORT_MAX_8250 30
 #define PORT_PXA 31
+/* WARNING: DO NOT EDIT, AUTO-GENERATED CODE - SEE TOP FOR INSTRUCTIONS */
 #define PORT_AMBA 32
 #define PORT_CLPS711X 33
-/* WARNING: DO NOT EDIT, AUTO-GENERATED CODE - SEE TOP FOR INSTRUCTIONS */
 #define PORT_SA1100 34
 #define PORT_UART00 35
+/* WARNING: DO NOT EDIT, AUTO-GENERATED CODE - SEE TOP FOR INSTRUCTIONS */
 #define PORT_21285 37
 #define PORT_SUNZILOG 38
-/* WARNING: DO NOT EDIT, AUTO-GENERATED CODE - SEE TOP FOR INSTRUCTIONS */
 #define PORT_SUNSAB 39
 #define PORT_DZ 46
+/* WARNING: DO NOT EDIT, AUTO-GENERATED CODE - SEE TOP FOR INSTRUCTIONS */
 #define PORT_ZS 47
 #define PORT_MUX 48
-/* WARNING: DO NOT EDIT, AUTO-GENERATED CODE - SEE TOP FOR INSTRUCTIONS */
 #define PORT_ATMEL 49
 #define PORT_MAC_ZILOG 50
+/* WARNING: DO NOT EDIT, AUTO-GENERATED CODE - SEE TOP FOR INSTRUCTIONS */
 #define PORT_PMAC_ZILOG 51
 #define PORT_SCI 52
-/* WARNING: DO NOT EDIT, AUTO-GENERATED CODE - SEE TOP FOR INSTRUCTIONS */
 #define PORT_SCIF 53
 #define PORT_IRDA 54
+/* WARNING: DO NOT EDIT, AUTO-GENERATED CODE - SEE TOP FOR INSTRUCTIONS */
 #define PORT_S3C2410 55
 #define PORT_IP22ZILOG 56
-/* WARNING: DO NOT EDIT, AUTO-GENERATED CODE - SEE TOP FOR INSTRUCTIONS */
 #define PORT_LH7A40X 57
 #define PORT_CPM 58
+/* WARNING: DO NOT EDIT, AUTO-GENERATED CODE - SEE TOP FOR INSTRUCTIONS */
 #define PORT_MPC52xx 59
 #define PORT_ICOM 60
-/* WARNING: DO NOT EDIT, AUTO-GENERATED CODE - SEE TOP FOR INSTRUCTIONS */
 #define PORT_S3C2440 61
 #define PORT_IMX 62
+/* WARNING: DO NOT EDIT, AUTO-GENERATED CODE - SEE TOP FOR INSTRUCTIONS */
 #define PORT_MPSC 63
 #define PORT_TXX9 64
-/* WARNING: DO NOT EDIT, AUTO-GENERATED CODE - SEE TOP FOR INSTRUCTIONS */
 #define PORT_VR41XX_SIU 65
 #define PORT_VR41XX_DSIU 66
+/* WARNING: DO NOT EDIT, AUTO-GENERATED CODE - SEE TOP FOR INSTRUCTIONS */
 #define PORT_S3C2400 67
 #define PORT_M32R_SIO 68
-/* WARNING: DO NOT EDIT, AUTO-GENERATED CODE - SEE TOP FOR INSTRUCTIONS */
 #define PORT_JSM 69
 #define PORT_PNX8XXX 70
+/* WARNING: DO NOT EDIT, AUTO-GENERATED CODE - SEE TOP FOR INSTRUCTIONS */
 #define PORT_NETX 71
 #define PORT_SUNHV 72
-/* WARNING: DO NOT EDIT, AUTO-GENERATED CODE - SEE TOP FOR INSTRUCTIONS */
 #define PORT_S3C2412 73
 #define PORT_UARTLITE 74
+/* WARNING: DO NOT EDIT, AUTO-GENERATED CODE - SEE TOP FOR INSTRUCTIONS */
 #define PORT_BFIN 75
 #define PORT_KS8695 76
-/* WARNING: DO NOT EDIT, AUTO-GENERATED CODE - SEE TOP FOR INSTRUCTIONS */
 #define PORT_SB1250_DUART 77
 #define PORT_MCF 78
+/* WARNING: DO NOT EDIT, AUTO-GENERATED CODE - SEE TOP FOR INSTRUCTIONS */
 #define PORT_BFIN_SPORT 79
 #define PORT_MN10300 80
-/* WARNING: DO NOT EDIT, AUTO-GENERATED CODE - SEE TOP FOR INSTRUCTIONS */
 #define PORT_MN10300_CTS 81
 #define PORT_SC26XX 82
+/* WARNING: DO NOT EDIT, AUTO-GENERATED CODE - SEE TOP FOR INSTRUCTIONS */
 #define PORT_SCIFA 83
 #define PORT_S3C6400 84
-/* WARNING: DO NOT EDIT, AUTO-GENERATED CODE - SEE TOP FOR INSTRUCTIONS */
 #define PORT_NWPSERIAL 85
 #define PORT_MAX3100 86
+/* WARNING: DO NOT EDIT, AUTO-GENERATED CODE - SEE TOP FOR INSTRUCTIONS */
 #define PORT_TIMBUART 87
 #define PORT_MSM 88
-/* WARNING: DO NOT EDIT, AUTO-GENERATED CODE - SEE TOP FOR INSTRUCTIONS */
 #define PORT_BCM63XX 89
 #define PORT_APBUART 90
+/* WARNING: DO NOT EDIT, AUTO-GENERATED CODE - SEE TOP FOR INSTRUCTIONS */
 #define PORT_ALTERA_JTAGUART 91
 #define PORT_ALTERA_UART 92
-/* WARNING: DO NOT EDIT, AUTO-GENERATED CODE - SEE TOP FOR INSTRUCTIONS */
 #define PORT_SCIFB 93
 #define PORT_MAX310X 94
+/* WARNING: DO NOT EDIT, AUTO-GENERATED CODE - SEE TOP FOR INSTRUCTIONS */
 #define PORT_MFD 95
 #define PORT_OMAP 96
-/* WARNING: DO NOT EDIT, AUTO-GENERATED CODE - SEE TOP FOR INSTRUCTIONS */
 #define PORT_VT8500 97
 #define PORT_XUARTPS 98
+/* WARNING: DO NOT EDIT, AUTO-GENERATED CODE - SEE TOP FOR INSTRUCTIONS */
 #define PORT_AR933X 99
 #define PORT_EFMUART 100
-/* WARNING: DO NOT EDIT, AUTO-GENERATED CODE - SEE TOP FOR INSTRUCTIONS */
 #define PORT_ARC 101
 #define PORT_RP2 102
+/* WARNING: DO NOT EDIT, AUTO-GENERATED CODE - SEE TOP FOR INSTRUCTIONS */
 #define PORT_LPUART 103
 #define PORT_HSCIF 104
-/* WARNING: DO NOT EDIT, AUTO-GENERATED CODE - SEE TOP FOR INSTRUCTIONS */
 #define PORT_ASC 105
 #define PORT_TILEGX 106
+/* WARNING: DO NOT EDIT, AUTO-GENERATED CODE - SEE TOP FOR INSTRUCTIONS */
 #define PORT_MEN_Z135 107
 #define PORT_SC16IS7XX 108
-/* WARNING: DO NOT EDIT, AUTO-GENERATED CODE - SEE TOP FOR INSTRUCTIONS */
 #define PORT_MESON 109
+#define PORT_DIGICOLOR 110
+/* WARNING: DO NOT EDIT, AUTO-GENERATED CODE - SEE TOP FOR INSTRUCTIONS */
+#define PORT_SPRD 111
+#define PORT_CRIS 112
+#define PORT_STM32 113
 #endif
+/* WARNING: DO NOT EDIT, AUTO-GENERATED CODE - SEE TOP FOR INSTRUCTIONS */
diff --git a/libc/kernel/uapi/linux/serial_reg.h b/libc/kernel/uapi/linux/serial_reg.h
index f68c54b..570bbed 100644
--- a/libc/kernel/uapi/linux/serial_reg.h
+++ b/libc/kernel/uapi/linux/serial_reg.h
@@ -197,21 +197,6 @@
 #define UART_FCR_PXAR16 0x80
 /* WARNING: DO NOT EDIT, AUTO-GENERATED CODE - SEE TOP FOR INSTRUCTIONS */
 #define UART_FCR_PXAR32 0xc0
-#define UART_FCR_HSU_64_1B 0x00
-#define UART_FCR_HSU_64_16B 0x40
-#define UART_FCR_HSU_64_32B 0x80
-/* WARNING: DO NOT EDIT, AUTO-GENERATED CODE - SEE TOP FOR INSTRUCTIONS */
-#define UART_FCR_HSU_64_56B 0xc0
-#define UART_FCR_HSU_16_1B 0x00
-#define UART_FCR_HSU_16_4B 0x40
-#define UART_FCR_HSU_16_8B 0x80
-/* WARNING: DO NOT EDIT, AUTO-GENERATED CODE - SEE TOP FOR INSTRUCTIONS */
-#define UART_FCR_HSU_16_14B 0xc0
-#define UART_FCR_HSU_64B_FIFO 0x20
-#define UART_FCR_HSU_16B_FIFO 0x00
-#define UART_FCR_HALF_EMPT_TXI 0x00
-/* WARNING: DO NOT EDIT, AUTO-GENERATED CODE - SEE TOP FOR INSTRUCTIONS */
-#define UART_FCR_FULL_EMPT_TXI 0x08
 #define UART_ASR 0x01
 #define UART_RFL 0x03
 #define UART_TFL 0x04
@@ -277,18 +262,23 @@
 #define SERIAL_RSA_BAUD_BASE (921600)
 /* WARNING: DO NOT EDIT, AUTO-GENERATED CODE - SEE TOP FOR INSTRUCTIONS */
 #define SERIAL_RSA_BAUD_BASE_LO (SERIAL_RSA_BAUD_BASE / 8)
+#define OMAP1_UART1_BASE 0xfffb0000
+#define OMAP1_UART2_BASE 0xfffb0800
+#define OMAP1_UART3_BASE 0xfffb9800
+/* WARNING: DO NOT EDIT, AUTO-GENERATED CODE - SEE TOP FOR INSTRUCTIONS */
 #define UART_OMAP_MDR1 0x08
 #define UART_OMAP_MDR2 0x09
 #define UART_OMAP_SCR 0x10
-/* WARNING: DO NOT EDIT, AUTO-GENERATED CODE - SEE TOP FOR INSTRUCTIONS */
 #define UART_OMAP_SSR 0x11
+/* WARNING: DO NOT EDIT, AUTO-GENERATED CODE - SEE TOP FOR INSTRUCTIONS */
 #define UART_OMAP_EBLR 0x12
 #define UART_OMAP_OSC_12M_SEL 0x13
 #define UART_OMAP_MVER 0x14
-/* WARNING: DO NOT EDIT, AUTO-GENERATED CODE - SEE TOP FOR INSTRUCTIONS */
 #define UART_OMAP_SYSC 0x15
+/* WARNING: DO NOT EDIT, AUTO-GENERATED CODE - SEE TOP FOR INSTRUCTIONS */
 #define UART_OMAP_SYSS 0x16
 #define UART_OMAP_WER 0x17
+#define UART_OMAP_TX_LVL 0x1a
 #define UART_OMAP_MDR1_16X_MODE 0x00
 /* WARNING: DO NOT EDIT, AUTO-GENERATED CODE - SEE TOP FOR INSTRUCTIONS */
 #define UART_OMAP_MDR1_SIR_MODE 0x01
diff --git a/libc/kernel/uapi/linux/snmp.h b/libc/kernel/uapi/linux/snmp.h
index ab163cc..e8ddf61 100644
--- a/libc/kernel/uapi/linux/snmp.h
+++ b/libc/kernel/uapi/linux/snmp.h
@@ -154,180 +154,198 @@
   UDP_MIB_RCVBUFERRORS,
   UDP_MIB_SNDBUFERRORS,
   UDP_MIB_CSUMERRORS,
-  __UDP_MIB_MAX
+  UDP_MIB_IGNOREDMULTI,
 /* WARNING: DO NOT EDIT, AUTO-GENERATED CODE - SEE TOP FOR INSTRUCTIONS */
+  __UDP_MIB_MAX
 };
 enum {
   LINUX_MIB_NUM = 0,
-  LINUX_MIB_SYNCOOKIESSENT,
 /* WARNING: DO NOT EDIT, AUTO-GENERATED CODE - SEE TOP FOR INSTRUCTIONS */
+  LINUX_MIB_SYNCOOKIESSENT,
   LINUX_MIB_SYNCOOKIESRECV,
   LINUX_MIB_SYNCOOKIESFAILED,
   LINUX_MIB_EMBRYONICRSTS,
-  LINUX_MIB_PRUNECALLED,
 /* WARNING: DO NOT EDIT, AUTO-GENERATED CODE - SEE TOP FOR INSTRUCTIONS */
+  LINUX_MIB_PRUNECALLED,
   LINUX_MIB_RCVPRUNED,
   LINUX_MIB_OFOPRUNED,
   LINUX_MIB_OUTOFWINDOWICMPS,
-  LINUX_MIB_LOCKDROPPEDICMPS,
 /* WARNING: DO NOT EDIT, AUTO-GENERATED CODE - SEE TOP FOR INSTRUCTIONS */
+  LINUX_MIB_LOCKDROPPEDICMPS,
   LINUX_MIB_ARPFILTER,
   LINUX_MIB_TIMEWAITED,
   LINUX_MIB_TIMEWAITRECYCLED,
-  LINUX_MIB_TIMEWAITKILLED,
 /* WARNING: DO NOT EDIT, AUTO-GENERATED CODE - SEE TOP FOR INSTRUCTIONS */
+  LINUX_MIB_TIMEWAITKILLED,
   LINUX_MIB_PAWSPASSIVEREJECTED,
   LINUX_MIB_PAWSACTIVEREJECTED,
   LINUX_MIB_PAWSESTABREJECTED,
-  LINUX_MIB_DELAYEDACKS,
 /* WARNING: DO NOT EDIT, AUTO-GENERATED CODE - SEE TOP FOR INSTRUCTIONS */
+  LINUX_MIB_DELAYEDACKS,
   LINUX_MIB_DELAYEDACKLOCKED,
   LINUX_MIB_DELAYEDACKLOST,
   LINUX_MIB_LISTENOVERFLOWS,
-  LINUX_MIB_LISTENDROPS,
 /* WARNING: DO NOT EDIT, AUTO-GENERATED CODE - SEE TOP FOR INSTRUCTIONS */
+  LINUX_MIB_LISTENDROPS,
   LINUX_MIB_TCPPREQUEUED,
   LINUX_MIB_TCPDIRECTCOPYFROMBACKLOG,
   LINUX_MIB_TCPDIRECTCOPYFROMPREQUEUE,
-  LINUX_MIB_TCPPREQUEUEDROPPED,
 /* WARNING: DO NOT EDIT, AUTO-GENERATED CODE - SEE TOP FOR INSTRUCTIONS */
+  LINUX_MIB_TCPPREQUEUEDROPPED,
   LINUX_MIB_TCPHPHITS,
   LINUX_MIB_TCPHPHITSTOUSER,
   LINUX_MIB_TCPPUREACKS,
-  LINUX_MIB_TCPHPACKS,
 /* WARNING: DO NOT EDIT, AUTO-GENERATED CODE - SEE TOP FOR INSTRUCTIONS */
+  LINUX_MIB_TCPHPACKS,
   LINUX_MIB_TCPRENORECOVERY,
   LINUX_MIB_TCPSACKRECOVERY,
   LINUX_MIB_TCPSACKRENEGING,
-  LINUX_MIB_TCPFACKREORDER,
 /* WARNING: DO NOT EDIT, AUTO-GENERATED CODE - SEE TOP FOR INSTRUCTIONS */
+  LINUX_MIB_TCPFACKREORDER,
   LINUX_MIB_TCPSACKREORDER,
   LINUX_MIB_TCPRENOREORDER,
   LINUX_MIB_TCPTSREORDER,
-  LINUX_MIB_TCPFULLUNDO,
 /* WARNING: DO NOT EDIT, AUTO-GENERATED CODE - SEE TOP FOR INSTRUCTIONS */
+  LINUX_MIB_TCPFULLUNDO,
   LINUX_MIB_TCPPARTIALUNDO,
   LINUX_MIB_TCPDSACKUNDO,
   LINUX_MIB_TCPLOSSUNDO,
-  LINUX_MIB_TCPLOSTRETRANSMIT,
 /* WARNING: DO NOT EDIT, AUTO-GENERATED CODE - SEE TOP FOR INSTRUCTIONS */
+  LINUX_MIB_TCPLOSTRETRANSMIT,
   LINUX_MIB_TCPRENOFAILURES,
   LINUX_MIB_TCPSACKFAILURES,
   LINUX_MIB_TCPLOSSFAILURES,
-  LINUX_MIB_TCPFASTRETRANS,
 /* WARNING: DO NOT EDIT, AUTO-GENERATED CODE - SEE TOP FOR INSTRUCTIONS */
+  LINUX_MIB_TCPFASTRETRANS,
   LINUX_MIB_TCPFORWARDRETRANS,
   LINUX_MIB_TCPSLOWSTARTRETRANS,
   LINUX_MIB_TCPTIMEOUTS,
-  LINUX_MIB_TCPLOSSPROBES,
 /* WARNING: DO NOT EDIT, AUTO-GENERATED CODE - SEE TOP FOR INSTRUCTIONS */
+  LINUX_MIB_TCPLOSSPROBES,
   LINUX_MIB_TCPLOSSPROBERECOVERY,
   LINUX_MIB_TCPRENORECOVERYFAIL,
   LINUX_MIB_TCPSACKRECOVERYFAIL,
-  LINUX_MIB_TCPSCHEDULERFAILED,
 /* WARNING: DO NOT EDIT, AUTO-GENERATED CODE - SEE TOP FOR INSTRUCTIONS */
+  LINUX_MIB_TCPSCHEDULERFAILED,
   LINUX_MIB_TCPRCVCOLLAPSED,
   LINUX_MIB_TCPDSACKOLDSENT,
   LINUX_MIB_TCPDSACKOFOSENT,
-  LINUX_MIB_TCPDSACKRECV,
 /* WARNING: DO NOT EDIT, AUTO-GENERATED CODE - SEE TOP FOR INSTRUCTIONS */
+  LINUX_MIB_TCPDSACKRECV,
   LINUX_MIB_TCPDSACKOFORECV,
   LINUX_MIB_TCPABORTONDATA,
   LINUX_MIB_TCPABORTONCLOSE,
-  LINUX_MIB_TCPABORTONMEMORY,
 /* WARNING: DO NOT EDIT, AUTO-GENERATED CODE - SEE TOP FOR INSTRUCTIONS */
+  LINUX_MIB_TCPABORTONMEMORY,
   LINUX_MIB_TCPABORTONTIMEOUT,
   LINUX_MIB_TCPABORTONLINGER,
   LINUX_MIB_TCPABORTFAILED,
-  LINUX_MIB_TCPMEMORYPRESSURES,
 /* WARNING: DO NOT EDIT, AUTO-GENERATED CODE - SEE TOP FOR INSTRUCTIONS */
+  LINUX_MIB_TCPMEMORYPRESSURES,
   LINUX_MIB_TCPSACKDISCARD,
   LINUX_MIB_TCPDSACKIGNOREDOLD,
   LINUX_MIB_TCPDSACKIGNOREDNOUNDO,
-  LINUX_MIB_TCPSPURIOUSRTOS,
 /* WARNING: DO NOT EDIT, AUTO-GENERATED CODE - SEE TOP FOR INSTRUCTIONS */
+  LINUX_MIB_TCPSPURIOUSRTOS,
   LINUX_MIB_TCPMD5NOTFOUND,
   LINUX_MIB_TCPMD5UNEXPECTED,
   LINUX_MIB_SACKSHIFTED,
-  LINUX_MIB_SACKMERGED,
 /* WARNING: DO NOT EDIT, AUTO-GENERATED CODE - SEE TOP FOR INSTRUCTIONS */
+  LINUX_MIB_SACKMERGED,
   LINUX_MIB_SACKSHIFTFALLBACK,
   LINUX_MIB_TCPBACKLOGDROP,
   LINUX_MIB_TCPMINTTLDROP,
-  LINUX_MIB_TCPDEFERACCEPTDROP,
 /* WARNING: DO NOT EDIT, AUTO-GENERATED CODE - SEE TOP FOR INSTRUCTIONS */
+  LINUX_MIB_TCPDEFERACCEPTDROP,
   LINUX_MIB_IPRPFILTER,
   LINUX_MIB_TCPTIMEWAITOVERFLOW,
   LINUX_MIB_TCPREQQFULLDOCOOKIES,
-  LINUX_MIB_TCPREQQFULLDROP,
 /* WARNING: DO NOT EDIT, AUTO-GENERATED CODE - SEE TOP FOR INSTRUCTIONS */
+  LINUX_MIB_TCPREQQFULLDROP,
   LINUX_MIB_TCPRETRANSFAIL,
   LINUX_MIB_TCPRCVCOALESCE,
   LINUX_MIB_TCPOFOQUEUE,
-  LINUX_MIB_TCPOFODROP,
 /* WARNING: DO NOT EDIT, AUTO-GENERATED CODE - SEE TOP FOR INSTRUCTIONS */
+  LINUX_MIB_TCPOFODROP,
   LINUX_MIB_TCPOFOMERGE,
   LINUX_MIB_TCPCHALLENGEACK,
   LINUX_MIB_TCPSYNCHALLENGE,
-  LINUX_MIB_TCPFASTOPENACTIVE,
 /* WARNING: DO NOT EDIT, AUTO-GENERATED CODE - SEE TOP FOR INSTRUCTIONS */
+  LINUX_MIB_TCPFASTOPENACTIVE,
   LINUX_MIB_TCPFASTOPENACTIVEFAIL,
   LINUX_MIB_TCPFASTOPENPASSIVE,
   LINUX_MIB_TCPFASTOPENPASSIVEFAIL,
-  LINUX_MIB_TCPFASTOPENLISTENOVERFLOW,
 /* WARNING: DO NOT EDIT, AUTO-GENERATED CODE - SEE TOP FOR INSTRUCTIONS */
+  LINUX_MIB_TCPFASTOPENLISTENOVERFLOW,
   LINUX_MIB_TCPFASTOPENCOOKIEREQD,
   LINUX_MIB_TCPSPURIOUS_RTX_HOSTQUEUES,
   LINUX_MIB_BUSYPOLLRXPACKETS,
-  LINUX_MIB_TCPAUTOCORKING,
 /* WARNING: DO NOT EDIT, AUTO-GENERATED CODE - SEE TOP FOR INSTRUCTIONS */
+  LINUX_MIB_TCPAUTOCORKING,
   LINUX_MIB_TCPFROMZEROWINDOWADV,
   LINUX_MIB_TCPTOZEROWINDOWADV,
   LINUX_MIB_TCPWANTZEROWINDOWADV,
-  LINUX_MIB_TCPSYNRETRANS,
 /* WARNING: DO NOT EDIT, AUTO-GENERATED CODE - SEE TOP FOR INSTRUCTIONS */
+  LINUX_MIB_TCPSYNRETRANS,
   LINUX_MIB_TCPORIGDATASENT,
+  LINUX_MIB_TCPHYSTARTTRAINDETECT,
+  LINUX_MIB_TCPHYSTARTTRAINCWND,
+/* WARNING: DO NOT EDIT, AUTO-GENERATED CODE - SEE TOP FOR INSTRUCTIONS */
+  LINUX_MIB_TCPHYSTARTDELAYDETECT,
+  LINUX_MIB_TCPHYSTARTDELAYCWND,
+  LINUX_MIB_TCPACKSKIPPEDSYNRECV,
+  LINUX_MIB_TCPACKSKIPPEDPAWS,
+/* WARNING: DO NOT EDIT, AUTO-GENERATED CODE - SEE TOP FOR INSTRUCTIONS */
+  LINUX_MIB_TCPACKSKIPPEDSEQ,
+  LINUX_MIB_TCPACKSKIPPEDFINWAIT2,
+  LINUX_MIB_TCPACKSKIPPEDTIMEWAIT,
+  LINUX_MIB_TCPACKSKIPPEDCHALLENGE,
+/* WARNING: DO NOT EDIT, AUTO-GENERATED CODE - SEE TOP FOR INSTRUCTIONS */
+  LINUX_MIB_TCPWINPROBE,
+  LINUX_MIB_TCPKEEPALIVE,
+  LINUX_MIB_TCPMTUPFAIL,
+  LINUX_MIB_TCPMTUPSUCCESS,
+/* WARNING: DO NOT EDIT, AUTO-GENERATED CODE - SEE TOP FOR INSTRUCTIONS */
   __LINUX_MIB_MAX
 };
 enum {
-/* WARNING: DO NOT EDIT, AUTO-GENERATED CODE - SEE TOP FOR INSTRUCTIONS */
   LINUX_MIB_XFRMNUM = 0,
+/* WARNING: DO NOT EDIT, AUTO-GENERATED CODE - SEE TOP FOR INSTRUCTIONS */
   LINUX_MIB_XFRMINERROR,
   LINUX_MIB_XFRMINBUFFERERROR,
   LINUX_MIB_XFRMINHDRERROR,
-/* WARNING: DO NOT EDIT, AUTO-GENERATED CODE - SEE TOP FOR INSTRUCTIONS */
   LINUX_MIB_XFRMINNOSTATES,
+/* WARNING: DO NOT EDIT, AUTO-GENERATED CODE - SEE TOP FOR INSTRUCTIONS */
   LINUX_MIB_XFRMINSTATEPROTOERROR,
   LINUX_MIB_XFRMINSTATEMODEERROR,
   LINUX_MIB_XFRMINSTATESEQERROR,
-/* WARNING: DO NOT EDIT, AUTO-GENERATED CODE - SEE TOP FOR INSTRUCTIONS */
   LINUX_MIB_XFRMINSTATEEXPIRED,
+/* WARNING: DO NOT EDIT, AUTO-GENERATED CODE - SEE TOP FOR INSTRUCTIONS */
   LINUX_MIB_XFRMINSTATEMISMATCH,
   LINUX_MIB_XFRMINSTATEINVALID,
   LINUX_MIB_XFRMINTMPLMISMATCH,
-/* WARNING: DO NOT EDIT, AUTO-GENERATED CODE - SEE TOP FOR INSTRUCTIONS */
   LINUX_MIB_XFRMINNOPOLS,
+/* WARNING: DO NOT EDIT, AUTO-GENERATED CODE - SEE TOP FOR INSTRUCTIONS */
   LINUX_MIB_XFRMINPOLBLOCK,
   LINUX_MIB_XFRMINPOLERROR,
   LINUX_MIB_XFRMOUTERROR,
-/* WARNING: DO NOT EDIT, AUTO-GENERATED CODE - SEE TOP FOR INSTRUCTIONS */
   LINUX_MIB_XFRMOUTBUNDLEGENERROR,
+/* WARNING: DO NOT EDIT, AUTO-GENERATED CODE - SEE TOP FOR INSTRUCTIONS */
   LINUX_MIB_XFRMOUTBUNDLECHECKERROR,
   LINUX_MIB_XFRMOUTNOSTATES,
   LINUX_MIB_XFRMOUTSTATEPROTOERROR,
-/* WARNING: DO NOT EDIT, AUTO-GENERATED CODE - SEE TOP FOR INSTRUCTIONS */
   LINUX_MIB_XFRMOUTSTATEMODEERROR,
+/* WARNING: DO NOT EDIT, AUTO-GENERATED CODE - SEE TOP FOR INSTRUCTIONS */
   LINUX_MIB_XFRMOUTSTATESEQERROR,
   LINUX_MIB_XFRMOUTSTATEEXPIRED,
   LINUX_MIB_XFRMOUTPOLBLOCK,
-/* WARNING: DO NOT EDIT, AUTO-GENERATED CODE - SEE TOP FOR INSTRUCTIONS */
   LINUX_MIB_XFRMOUTPOLDEAD,
+/* WARNING: DO NOT EDIT, AUTO-GENERATED CODE - SEE TOP FOR INSTRUCTIONS */
   LINUX_MIB_XFRMOUTPOLERROR,
   LINUX_MIB_XFRMFWDHDRERROR,
   LINUX_MIB_XFRMOUTSTATEINVALID,
-/* WARNING: DO NOT EDIT, AUTO-GENERATED CODE - SEE TOP FOR INSTRUCTIONS */
   LINUX_MIB_XFRMACQUIREERROR,
+/* WARNING: DO NOT EDIT, AUTO-GENERATED CODE - SEE TOP FOR INSTRUCTIONS */
   __LINUX_MIB_XFRMMAX
 };
 #endif
-/* WARNING: DO NOT EDIT, AUTO-GENERATED CODE - SEE TOP FOR INSTRUCTIONS */
diff --git a/libc/kernel/uapi/linux/sock_diag.h b/libc/kernel/uapi/linux/sock_diag.h
index 052779e..4d9e440 100644
--- a/libc/kernel/uapi/linux/sock_diag.h
+++ b/libc/kernel/uapi/linux/sock_diag.h
@@ -39,5 +39,16 @@
   SK_MEMINFO_BACKLOG,
   SK_MEMINFO_VARS,
 };
-#endif
+enum sknetlink_groups {
 /* WARNING: DO NOT EDIT, AUTO-GENERATED CODE - SEE TOP FOR INSTRUCTIONS */
+  SKNLGRP_NONE,
+  SKNLGRP_INET_TCP_DESTROY,
+  SKNLGRP_INET_UDP_DESTROY,
+  SKNLGRP_INET6_TCP_DESTROY,
+/* WARNING: DO NOT EDIT, AUTO-GENERATED CODE - SEE TOP FOR INSTRUCTIONS */
+  SKNLGRP_INET6_UDP_DESTROY,
+  __SKNLGRP_MAX,
+};
+#define SKNLGRP_MAX (__SKNLGRP_MAX - 1)
+/* WARNING: DO NOT EDIT, AUTO-GENERATED CODE - SEE TOP FOR INSTRUCTIONS */
+#endif
diff --git a/libc/kernel/uapi/linux/stm.h b/libc/kernel/uapi/linux/stm.h
new file mode 100644
index 0000000..3677551
--- /dev/null
+++ b/libc/kernel/uapi/linux/stm.h
@@ -0,0 +1,38 @@
+/****************************************************************************
+ ****************************************************************************
+ ***
+ ***   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_STM_H
+#define _UAPI_LINUX_STM_H
+#include <linux/types.h>
+struct stp_policy_id {
+/* WARNING: DO NOT EDIT, AUTO-GENERATED CODE - SEE TOP FOR INSTRUCTIONS */
+  __u32 size;
+  __u16 master;
+  __u16 channel;
+  __u16 width;
+/* WARNING: DO NOT EDIT, AUTO-GENERATED CODE - SEE TOP FOR INSTRUCTIONS */
+  __u16 __reserved_0;
+  __u32 __reserved_1;
+  char id[0];
+};
+/* WARNING: DO NOT EDIT, AUTO-GENERATED CODE - SEE TOP FOR INSTRUCTIONS */
+#define STP_POLICY_ID_SET _IOWR('%', 0, struct stp_policy_id)
+#define STP_POLICY_ID_GET _IOR('%', 1, struct stp_policy_id)
+#define STP_SET_OPTIONS _IOW('%', 2, __u64)
+#endif
+/* WARNING: DO NOT EDIT, AUTO-GENERATED CODE - SEE TOP FOR INSTRUCTIONS */
diff --git a/libc/kernel/uapi/linux/sysctl.h b/libc/kernel/uapi/linux/sysctl.h
index 2cac5f3..a3e6878 100644
--- a/libc/kernel/uapi/linux/sysctl.h
+++ b/libc/kernel/uapi/linux/sysctl.h
@@ -151,810 +151,811 @@
   KERN_NMI_WATCHDOG = 75,
   KERN_PANIC_ON_NMI = 76,
 /* WARNING: DO NOT EDIT, AUTO-GENERATED CODE - SEE TOP FOR INSTRUCTIONS */
+  KERN_PANIC_ON_WARN = 77,
 };
 enum {
   VM_UNUSED1 = 1,
-  VM_UNUSED2 = 2,
 /* WARNING: DO NOT EDIT, AUTO-GENERATED CODE - SEE TOP FOR INSTRUCTIONS */
+  VM_UNUSED2 = 2,
   VM_UNUSED3 = 3,
   VM_UNUSED4 = 4,
   VM_OVERCOMMIT_MEMORY = 5,
-  VM_UNUSED5 = 6,
 /* WARNING: DO NOT EDIT, AUTO-GENERATED CODE - SEE TOP FOR INSTRUCTIONS */
+  VM_UNUSED5 = 6,
   VM_UNUSED7 = 7,
   VM_UNUSED8 = 8,
   VM_UNUSED9 = 9,
-  VM_PAGE_CLUSTER = 10,
 /* WARNING: DO NOT EDIT, AUTO-GENERATED CODE - SEE TOP FOR INSTRUCTIONS */
+  VM_PAGE_CLUSTER = 10,
   VM_DIRTY_BACKGROUND = 11,
   VM_DIRTY_RATIO = 12,
   VM_DIRTY_WB_CS = 13,
-  VM_DIRTY_EXPIRE_CS = 14,
 /* WARNING: DO NOT EDIT, AUTO-GENERATED CODE - SEE TOP FOR INSTRUCTIONS */
+  VM_DIRTY_EXPIRE_CS = 14,
   VM_NR_PDFLUSH_THREADS = 15,
   VM_OVERCOMMIT_RATIO = 16,
   VM_PAGEBUF = 17,
-  VM_HUGETLB_PAGES = 18,
 /* WARNING: DO NOT EDIT, AUTO-GENERATED CODE - SEE TOP FOR INSTRUCTIONS */
+  VM_HUGETLB_PAGES = 18,
   VM_SWAPPINESS = 19,
   VM_LOWMEM_RESERVE_RATIO = 20,
   VM_MIN_FREE_KBYTES = 21,
-  VM_MAX_MAP_COUNT = 22,
 /* WARNING: DO NOT EDIT, AUTO-GENERATED CODE - SEE TOP FOR INSTRUCTIONS */
+  VM_MAX_MAP_COUNT = 22,
   VM_LAPTOP_MODE = 23,
   VM_BLOCK_DUMP = 24,
   VM_HUGETLB_GROUP = 25,
-  VM_VFS_CACHE_PRESSURE = 26,
 /* WARNING: DO NOT EDIT, AUTO-GENERATED CODE - SEE TOP FOR INSTRUCTIONS */
+  VM_VFS_CACHE_PRESSURE = 26,
   VM_LEGACY_VA_LAYOUT = 27,
   VM_SWAP_TOKEN_TIMEOUT = 28,
   VM_DROP_PAGECACHE = 29,
-  VM_PERCPU_PAGELIST_FRACTION = 30,
 /* WARNING: DO NOT EDIT, AUTO-GENERATED CODE - SEE TOP FOR INSTRUCTIONS */
+  VM_PERCPU_PAGELIST_FRACTION = 30,
   VM_ZONE_RECLAIM_MODE = 31,
   VM_MIN_UNMAPPED = 32,
   VM_PANIC_ON_OOM = 33,
-  VM_VDSO_ENABLED = 34,
 /* WARNING: DO NOT EDIT, AUTO-GENERATED CODE - SEE TOP FOR INSTRUCTIONS */
+  VM_VDSO_ENABLED = 34,
   VM_MIN_SLAB = 35,
 };
 enum {
-  NET_CORE = 1,
 /* WARNING: DO NOT EDIT, AUTO-GENERATED CODE - SEE TOP FOR INSTRUCTIONS */
+  NET_CORE = 1,
   NET_ETHER = 2,
   NET_802 = 3,
   NET_UNIX = 4,
-  NET_IPV4 = 5,
 /* WARNING: DO NOT EDIT, AUTO-GENERATED CODE - SEE TOP FOR INSTRUCTIONS */
+  NET_IPV4 = 5,
   NET_IPX = 6,
   NET_ATALK = 7,
   NET_NETROM = 8,
-  NET_AX25 = 9,
 /* WARNING: DO NOT EDIT, AUTO-GENERATED CODE - SEE TOP FOR INSTRUCTIONS */
+  NET_AX25 = 9,
   NET_BRIDGE = 10,
   NET_ROSE = 11,
   NET_IPV6 = 12,
-  NET_X25 = 13,
 /* WARNING: DO NOT EDIT, AUTO-GENERATED CODE - SEE TOP FOR INSTRUCTIONS */
+  NET_X25 = 13,
   NET_TR = 14,
   NET_DECNET = 15,
   NET_ECONET = 16,
-  NET_SCTP = 17,
 /* WARNING: DO NOT EDIT, AUTO-GENERATED CODE - SEE TOP FOR INSTRUCTIONS */
+  NET_SCTP = 17,
   NET_LLC = 18,
   NET_NETFILTER = 19,
   NET_DCCP = 20,
-  NET_IRDA = 412,
 /* WARNING: DO NOT EDIT, AUTO-GENERATED CODE - SEE TOP FOR INSTRUCTIONS */
+  NET_IRDA = 412,
 };
 enum {
   RANDOM_POOLSIZE = 1,
-  RANDOM_ENTROPY_COUNT = 2,
 /* WARNING: DO NOT EDIT, AUTO-GENERATED CODE - SEE TOP FOR INSTRUCTIONS */
+  RANDOM_ENTROPY_COUNT = 2,
   RANDOM_READ_THRESH = 3,
   RANDOM_WRITE_THRESH = 4,
   RANDOM_BOOT_ID = 5,
-  RANDOM_UUID = 6
 /* WARNING: DO NOT EDIT, AUTO-GENERATED CODE - SEE TOP FOR INSTRUCTIONS */
+  RANDOM_UUID = 6
 };
 enum {
   PTY_MAX = 1,
-  PTY_NR = 2
 /* WARNING: DO NOT EDIT, AUTO-GENERATED CODE - SEE TOP FOR INSTRUCTIONS */
+  PTY_NR = 2
 };
 enum {
   BUS_ISA_MEM_BASE = 1,
-  BUS_ISA_PORT_BASE = 2,
 /* WARNING: DO NOT EDIT, AUTO-GENERATED CODE - SEE TOP FOR INSTRUCTIONS */
+  BUS_ISA_PORT_BASE = 2,
   BUS_ISA_PORT_SHIFT = 3
 };
 enum {
-  NET_CORE_WMEM_MAX = 1,
 /* WARNING: DO NOT EDIT, AUTO-GENERATED CODE - SEE TOP FOR INSTRUCTIONS */
+  NET_CORE_WMEM_MAX = 1,
   NET_CORE_RMEM_MAX = 2,
   NET_CORE_WMEM_DEFAULT = 3,
   NET_CORE_RMEM_DEFAULT = 4,
-  NET_CORE_MAX_BACKLOG = 6,
 /* WARNING: DO NOT EDIT, AUTO-GENERATED CODE - SEE TOP FOR INSTRUCTIONS */
+  NET_CORE_MAX_BACKLOG = 6,
   NET_CORE_FASTROUTE = 7,
   NET_CORE_MSG_COST = 8,
   NET_CORE_MSG_BURST = 9,
-  NET_CORE_OPTMEM_MAX = 10,
 /* WARNING: DO NOT EDIT, AUTO-GENERATED CODE - SEE TOP FOR INSTRUCTIONS */
+  NET_CORE_OPTMEM_MAX = 10,
   NET_CORE_HOT_LIST_LENGTH = 11,
   NET_CORE_DIVERT_VERSION = 12,
   NET_CORE_NO_CONG_THRESH = 13,
-  NET_CORE_NO_CONG = 14,
 /* WARNING: DO NOT EDIT, AUTO-GENERATED CODE - SEE TOP FOR INSTRUCTIONS */
+  NET_CORE_NO_CONG = 14,
   NET_CORE_LO_CONG = 15,
   NET_CORE_MOD_CONG = 16,
   NET_CORE_DEV_WEIGHT = 17,
-  NET_CORE_SOMAXCONN = 18,
 /* WARNING: DO NOT EDIT, AUTO-GENERATED CODE - SEE TOP FOR INSTRUCTIONS */
+  NET_CORE_SOMAXCONN = 18,
   NET_CORE_BUDGET = 19,
   NET_CORE_AEVENT_ETIME = 20,
   NET_CORE_AEVENT_RSEQTH = 21,
-  NET_CORE_WARNINGS = 22,
 /* WARNING: DO NOT EDIT, AUTO-GENERATED CODE - SEE TOP FOR INSTRUCTIONS */
+  NET_CORE_WARNINGS = 22,
 };
 enum {
   NET_UNIX_DESTROY_DELAY = 1,
-  NET_UNIX_DELETE_DELAY = 2,
 /* WARNING: DO NOT EDIT, AUTO-GENERATED CODE - SEE TOP FOR INSTRUCTIONS */
+  NET_UNIX_DELETE_DELAY = 2,
   NET_UNIX_MAX_DGRAM_QLEN = 3,
 };
 enum {
-  NET_NF_CONNTRACK_MAX = 1,
 /* WARNING: DO NOT EDIT, AUTO-GENERATED CODE - SEE TOP FOR INSTRUCTIONS */
+  NET_NF_CONNTRACK_MAX = 1,
   NET_NF_CONNTRACK_TCP_TIMEOUT_SYN_SENT = 2,
   NET_NF_CONNTRACK_TCP_TIMEOUT_SYN_RECV = 3,
   NET_NF_CONNTRACK_TCP_TIMEOUT_ESTABLISHED = 4,
-  NET_NF_CONNTRACK_TCP_TIMEOUT_FIN_WAIT = 5,
 /* WARNING: DO NOT EDIT, AUTO-GENERATED CODE - SEE TOP FOR INSTRUCTIONS */
+  NET_NF_CONNTRACK_TCP_TIMEOUT_FIN_WAIT = 5,
   NET_NF_CONNTRACK_TCP_TIMEOUT_CLOSE_WAIT = 6,
   NET_NF_CONNTRACK_TCP_TIMEOUT_LAST_ACK = 7,
   NET_NF_CONNTRACK_TCP_TIMEOUT_TIME_WAIT = 8,
-  NET_NF_CONNTRACK_TCP_TIMEOUT_CLOSE = 9,
 /* WARNING: DO NOT EDIT, AUTO-GENERATED CODE - SEE TOP FOR INSTRUCTIONS */
+  NET_NF_CONNTRACK_TCP_TIMEOUT_CLOSE = 9,
   NET_NF_CONNTRACK_UDP_TIMEOUT = 10,
   NET_NF_CONNTRACK_UDP_TIMEOUT_STREAM = 11,
   NET_NF_CONNTRACK_ICMP_TIMEOUT = 12,
-  NET_NF_CONNTRACK_GENERIC_TIMEOUT = 13,
 /* WARNING: DO NOT EDIT, AUTO-GENERATED CODE - SEE TOP FOR INSTRUCTIONS */
+  NET_NF_CONNTRACK_GENERIC_TIMEOUT = 13,
   NET_NF_CONNTRACK_BUCKETS = 14,
   NET_NF_CONNTRACK_LOG_INVALID = 15,
   NET_NF_CONNTRACK_TCP_TIMEOUT_MAX_RETRANS = 16,
-  NET_NF_CONNTRACK_TCP_LOOSE = 17,
 /* WARNING: DO NOT EDIT, AUTO-GENERATED CODE - SEE TOP FOR INSTRUCTIONS */
+  NET_NF_CONNTRACK_TCP_LOOSE = 17,
   NET_NF_CONNTRACK_TCP_BE_LIBERAL = 18,
   NET_NF_CONNTRACK_TCP_MAX_RETRANS = 19,
   NET_NF_CONNTRACK_SCTP_TIMEOUT_CLOSED = 20,
-  NET_NF_CONNTRACK_SCTP_TIMEOUT_COOKIE_WAIT = 21,
 /* WARNING: DO NOT EDIT, AUTO-GENERATED CODE - SEE TOP FOR INSTRUCTIONS */
+  NET_NF_CONNTRACK_SCTP_TIMEOUT_COOKIE_WAIT = 21,
   NET_NF_CONNTRACK_SCTP_TIMEOUT_COOKIE_ECHOED = 22,
   NET_NF_CONNTRACK_SCTP_TIMEOUT_ESTABLISHED = 23,
   NET_NF_CONNTRACK_SCTP_TIMEOUT_SHUTDOWN_SENT = 24,
-  NET_NF_CONNTRACK_SCTP_TIMEOUT_SHUTDOWN_RECD = 25,
 /* WARNING: DO NOT EDIT, AUTO-GENERATED CODE - SEE TOP FOR INSTRUCTIONS */
+  NET_NF_CONNTRACK_SCTP_TIMEOUT_SHUTDOWN_RECD = 25,
   NET_NF_CONNTRACK_SCTP_TIMEOUT_SHUTDOWN_ACK_SENT = 26,
   NET_NF_CONNTRACK_COUNT = 27,
   NET_NF_CONNTRACK_ICMPV6_TIMEOUT = 28,
-  NET_NF_CONNTRACK_FRAG6_TIMEOUT = 29,
 /* WARNING: DO NOT EDIT, AUTO-GENERATED CODE - SEE TOP FOR INSTRUCTIONS */
+  NET_NF_CONNTRACK_FRAG6_TIMEOUT = 29,
   NET_NF_CONNTRACK_FRAG6_LOW_THRESH = 30,
   NET_NF_CONNTRACK_FRAG6_HIGH_THRESH = 31,
   NET_NF_CONNTRACK_CHECKSUM = 32,
-};
 /* WARNING: DO NOT EDIT, AUTO-GENERATED CODE - SEE TOP FOR INSTRUCTIONS */
+};
 enum {
   NET_IPV4_FORWARD = 8,
   NET_IPV4_DYNADDR = 9,
-  NET_IPV4_CONF = 16,
 /* WARNING: DO NOT EDIT, AUTO-GENERATED CODE - SEE TOP FOR INSTRUCTIONS */
+  NET_IPV4_CONF = 16,
   NET_IPV4_NEIGH = 17,
   NET_IPV4_ROUTE = 18,
   NET_IPV4_FIB_HASH = 19,
-  NET_IPV4_NETFILTER = 20,
 /* WARNING: DO NOT EDIT, AUTO-GENERATED CODE - SEE TOP FOR INSTRUCTIONS */
+  NET_IPV4_NETFILTER = 20,
   NET_IPV4_TCP_TIMESTAMPS = 33,
   NET_IPV4_TCP_WINDOW_SCALING = 34,
   NET_IPV4_TCP_SACK = 35,
-  NET_IPV4_TCP_RETRANS_COLLAPSE = 36,
 /* WARNING: DO NOT EDIT, AUTO-GENERATED CODE - SEE TOP FOR INSTRUCTIONS */
+  NET_IPV4_TCP_RETRANS_COLLAPSE = 36,
   NET_IPV4_DEFAULT_TTL = 37,
   NET_IPV4_AUTOCONFIG = 38,
   NET_IPV4_NO_PMTU_DISC = 39,
-  NET_IPV4_TCP_SYN_RETRIES = 40,
 /* WARNING: DO NOT EDIT, AUTO-GENERATED CODE - SEE TOP FOR INSTRUCTIONS */
+  NET_IPV4_TCP_SYN_RETRIES = 40,
   NET_IPV4_IPFRAG_HIGH_THRESH = 41,
   NET_IPV4_IPFRAG_LOW_THRESH = 42,
   NET_IPV4_IPFRAG_TIME = 43,
-  NET_IPV4_TCP_MAX_KA_PROBES = 44,
 /* WARNING: DO NOT EDIT, AUTO-GENERATED CODE - SEE TOP FOR INSTRUCTIONS */
+  NET_IPV4_TCP_MAX_KA_PROBES = 44,
   NET_IPV4_TCP_KEEPALIVE_TIME = 45,
   NET_IPV4_TCP_KEEPALIVE_PROBES = 46,
   NET_IPV4_TCP_RETRIES1 = 47,
-  NET_IPV4_TCP_RETRIES2 = 48,
 /* WARNING: DO NOT EDIT, AUTO-GENERATED CODE - SEE TOP FOR INSTRUCTIONS */
+  NET_IPV4_TCP_RETRIES2 = 48,
   NET_IPV4_TCP_FIN_TIMEOUT = 49,
   NET_IPV4_IP_MASQ_DEBUG = 50,
   NET_TCP_SYNCOOKIES = 51,
-  NET_TCP_STDURG = 52,
 /* WARNING: DO NOT EDIT, AUTO-GENERATED CODE - SEE TOP FOR INSTRUCTIONS */
+  NET_TCP_STDURG = 52,
   NET_TCP_RFC1337 = 53,
   NET_TCP_SYN_TAILDROP = 54,
   NET_TCP_MAX_SYN_BACKLOG = 55,
-  NET_IPV4_LOCAL_PORT_RANGE = 56,
 /* WARNING: DO NOT EDIT, AUTO-GENERATED CODE - SEE TOP FOR INSTRUCTIONS */
+  NET_IPV4_LOCAL_PORT_RANGE = 56,
   NET_IPV4_ICMP_ECHO_IGNORE_ALL = 57,
   NET_IPV4_ICMP_ECHO_IGNORE_BROADCASTS = 58,
   NET_IPV4_ICMP_SOURCEQUENCH_RATE = 59,
-  NET_IPV4_ICMP_DESTUNREACH_RATE = 60,
 /* WARNING: DO NOT EDIT, AUTO-GENERATED CODE - SEE TOP FOR INSTRUCTIONS */
+  NET_IPV4_ICMP_DESTUNREACH_RATE = 60,
   NET_IPV4_ICMP_TIMEEXCEED_RATE = 61,
   NET_IPV4_ICMP_PARAMPROB_RATE = 62,
   NET_IPV4_ICMP_ECHOREPLY_RATE = 63,
-  NET_IPV4_ICMP_IGNORE_BOGUS_ERROR_RESPONSES = 64,
 /* WARNING: DO NOT EDIT, AUTO-GENERATED CODE - SEE TOP FOR INSTRUCTIONS */
+  NET_IPV4_ICMP_IGNORE_BOGUS_ERROR_RESPONSES = 64,
   NET_IPV4_IGMP_MAX_MEMBERSHIPS = 65,
   NET_TCP_TW_RECYCLE = 66,
   NET_IPV4_ALWAYS_DEFRAG = 67,
-  NET_IPV4_TCP_KEEPALIVE_INTVL = 68,
 /* WARNING: DO NOT EDIT, AUTO-GENERATED CODE - SEE TOP FOR INSTRUCTIONS */
+  NET_IPV4_TCP_KEEPALIVE_INTVL = 68,
   NET_IPV4_INET_PEER_THRESHOLD = 69,
   NET_IPV4_INET_PEER_MINTTL = 70,
   NET_IPV4_INET_PEER_MAXTTL = 71,
-  NET_IPV4_INET_PEER_GC_MINTIME = 72,
 /* WARNING: DO NOT EDIT, AUTO-GENERATED CODE - SEE TOP FOR INSTRUCTIONS */
+  NET_IPV4_INET_PEER_GC_MINTIME = 72,
   NET_IPV4_INET_PEER_GC_MAXTIME = 73,
   NET_TCP_ORPHAN_RETRIES = 74,
   NET_TCP_ABORT_ON_OVERFLOW = 75,
-  NET_TCP_SYNACK_RETRIES = 76,
 /* WARNING: DO NOT EDIT, AUTO-GENERATED CODE - SEE TOP FOR INSTRUCTIONS */
+  NET_TCP_SYNACK_RETRIES = 76,
   NET_TCP_MAX_ORPHANS = 77,
   NET_TCP_MAX_TW_BUCKETS = 78,
   NET_TCP_FACK = 79,
-  NET_TCP_REORDERING = 80,
 /* WARNING: DO NOT EDIT, AUTO-GENERATED CODE - SEE TOP FOR INSTRUCTIONS */
+  NET_TCP_REORDERING = 80,
   NET_TCP_ECN = 81,
   NET_TCP_DSACK = 82,
   NET_TCP_MEM = 83,
-  NET_TCP_WMEM = 84,
 /* WARNING: DO NOT EDIT, AUTO-GENERATED CODE - SEE TOP FOR INSTRUCTIONS */
+  NET_TCP_WMEM = 84,
   NET_TCP_RMEM = 85,
   NET_TCP_APP_WIN = 86,
   NET_TCP_ADV_WIN_SCALE = 87,
-  NET_IPV4_NONLOCAL_BIND = 88,
 /* WARNING: DO NOT EDIT, AUTO-GENERATED CODE - SEE TOP FOR INSTRUCTIONS */
+  NET_IPV4_NONLOCAL_BIND = 88,
   NET_IPV4_ICMP_RATELIMIT = 89,
   NET_IPV4_ICMP_RATEMASK = 90,
   NET_TCP_TW_REUSE = 91,
-  NET_TCP_FRTO = 92,
 /* WARNING: DO NOT EDIT, AUTO-GENERATED CODE - SEE TOP FOR INSTRUCTIONS */
+  NET_TCP_FRTO = 92,
   NET_TCP_LOW_LATENCY = 93,
   NET_IPV4_IPFRAG_SECRET_INTERVAL = 94,
   NET_IPV4_IGMP_MAX_MSF = 96,
-  NET_TCP_NO_METRICS_SAVE = 97,
 /* WARNING: DO NOT EDIT, AUTO-GENERATED CODE - SEE TOP FOR INSTRUCTIONS */
+  NET_TCP_NO_METRICS_SAVE = 97,
   NET_TCP_DEFAULT_WIN_SCALE = 105,
   NET_TCP_MODERATE_RCVBUF = 106,
   NET_TCP_TSO_WIN_DIVISOR = 107,
-  NET_TCP_BIC_BETA = 108,
 /* WARNING: DO NOT EDIT, AUTO-GENERATED CODE - SEE TOP FOR INSTRUCTIONS */
+  NET_TCP_BIC_BETA = 108,
   NET_IPV4_ICMP_ERRORS_USE_INBOUND_IFADDR = 109,
   NET_TCP_CONG_CONTROL = 110,
   NET_TCP_ABC = 111,
-  NET_IPV4_IPFRAG_MAX_DIST = 112,
 /* WARNING: DO NOT EDIT, AUTO-GENERATED CODE - SEE TOP FOR INSTRUCTIONS */
+  NET_IPV4_IPFRAG_MAX_DIST = 112,
   NET_TCP_MTU_PROBING = 113,
   NET_TCP_BASE_MSS = 114,
   NET_IPV4_TCP_WORKAROUND_SIGNED_WINDOWS = 115,
-  NET_TCP_DMA_COPYBREAK = 116,
 /* WARNING: DO NOT EDIT, AUTO-GENERATED CODE - SEE TOP FOR INSTRUCTIONS */
+  NET_TCP_DMA_COPYBREAK = 116,
   NET_TCP_SLOW_START_AFTER_IDLE = 117,
   NET_CIPSOV4_CACHE_ENABLE = 118,
   NET_CIPSOV4_CACHE_BUCKET_SIZE = 119,
-  NET_CIPSOV4_RBM_OPTFMT = 120,
 /* WARNING: DO NOT EDIT, AUTO-GENERATED CODE - SEE TOP FOR INSTRUCTIONS */
+  NET_CIPSOV4_RBM_OPTFMT = 120,
   NET_CIPSOV4_RBM_STRICTVALID = 121,
   NET_TCP_AVAIL_CONG_CONTROL = 122,
   NET_TCP_ALLOWED_CONG_CONTROL = 123,
-  NET_TCP_MAX_SSTHRESH = 124,
 /* WARNING: DO NOT EDIT, AUTO-GENERATED CODE - SEE TOP FOR INSTRUCTIONS */
+  NET_TCP_MAX_SSTHRESH = 124,
   NET_TCP_FRTO_RESPONSE = 125,
 };
 enum {
-  NET_IPV4_ROUTE_FLUSH = 1,
 /* WARNING: DO NOT EDIT, AUTO-GENERATED CODE - SEE TOP FOR INSTRUCTIONS */
+  NET_IPV4_ROUTE_FLUSH = 1,
   NET_IPV4_ROUTE_MIN_DELAY = 2,
   NET_IPV4_ROUTE_MAX_DELAY = 3,
   NET_IPV4_ROUTE_GC_THRESH = 4,
-  NET_IPV4_ROUTE_MAX_SIZE = 5,
 /* WARNING: DO NOT EDIT, AUTO-GENERATED CODE - SEE TOP FOR INSTRUCTIONS */
+  NET_IPV4_ROUTE_MAX_SIZE = 5,
   NET_IPV4_ROUTE_GC_MIN_INTERVAL = 6,
   NET_IPV4_ROUTE_GC_TIMEOUT = 7,
   NET_IPV4_ROUTE_GC_INTERVAL = 8,
-  NET_IPV4_ROUTE_REDIRECT_LOAD = 9,
 /* WARNING: DO NOT EDIT, AUTO-GENERATED CODE - SEE TOP FOR INSTRUCTIONS */
+  NET_IPV4_ROUTE_REDIRECT_LOAD = 9,
   NET_IPV4_ROUTE_REDIRECT_NUMBER = 10,
   NET_IPV4_ROUTE_REDIRECT_SILENCE = 11,
   NET_IPV4_ROUTE_ERROR_COST = 12,
-  NET_IPV4_ROUTE_ERROR_BURST = 13,
 /* WARNING: DO NOT EDIT, AUTO-GENERATED CODE - SEE TOP FOR INSTRUCTIONS */
+  NET_IPV4_ROUTE_ERROR_BURST = 13,
   NET_IPV4_ROUTE_GC_ELASTICITY = 14,
   NET_IPV4_ROUTE_MTU_EXPIRES = 15,
   NET_IPV4_ROUTE_MIN_PMTU = 16,
-  NET_IPV4_ROUTE_MIN_ADVMSS = 17,
 /* WARNING: DO NOT EDIT, AUTO-GENERATED CODE - SEE TOP FOR INSTRUCTIONS */
+  NET_IPV4_ROUTE_MIN_ADVMSS = 17,
   NET_IPV4_ROUTE_SECRET_INTERVAL = 18,
   NET_IPV4_ROUTE_GC_MIN_INTERVAL_MS = 19,
 };
-enum {
 /* WARNING: DO NOT EDIT, AUTO-GENERATED CODE - SEE TOP FOR INSTRUCTIONS */
+enum {
   NET_PROTO_CONF_ALL = - 2,
   NET_PROTO_CONF_DEFAULT = - 3
 };
-enum {
 /* WARNING: DO NOT EDIT, AUTO-GENERATED CODE - SEE TOP FOR INSTRUCTIONS */
+enum {
   NET_IPV4_CONF_FORWARDING = 1,
   NET_IPV4_CONF_MC_FORWARDING = 2,
   NET_IPV4_CONF_PROXY_ARP = 3,
-  NET_IPV4_CONF_ACCEPT_REDIRECTS = 4,
 /* WARNING: DO NOT EDIT, AUTO-GENERATED CODE - SEE TOP FOR INSTRUCTIONS */
+  NET_IPV4_CONF_ACCEPT_REDIRECTS = 4,
   NET_IPV4_CONF_SECURE_REDIRECTS = 5,
   NET_IPV4_CONF_SEND_REDIRECTS = 6,
   NET_IPV4_CONF_SHARED_MEDIA = 7,
-  NET_IPV4_CONF_RP_FILTER = 8,
 /* WARNING: DO NOT EDIT, AUTO-GENERATED CODE - SEE TOP FOR INSTRUCTIONS */
+  NET_IPV4_CONF_RP_FILTER = 8,
   NET_IPV4_CONF_ACCEPT_SOURCE_ROUTE = 9,
   NET_IPV4_CONF_BOOTP_RELAY = 10,
   NET_IPV4_CONF_LOG_MARTIANS = 11,
-  NET_IPV4_CONF_TAG = 12,
 /* WARNING: DO NOT EDIT, AUTO-GENERATED CODE - SEE TOP FOR INSTRUCTIONS */
+  NET_IPV4_CONF_TAG = 12,
   NET_IPV4_CONF_ARPFILTER = 13,
   NET_IPV4_CONF_MEDIUM_ID = 14,
   NET_IPV4_CONF_NOXFRM = 15,
-  NET_IPV4_CONF_NOPOLICY = 16,
 /* WARNING: DO NOT EDIT, AUTO-GENERATED CODE - SEE TOP FOR INSTRUCTIONS */
+  NET_IPV4_CONF_NOPOLICY = 16,
   NET_IPV4_CONF_FORCE_IGMP_VERSION = 17,
   NET_IPV4_CONF_ARP_ANNOUNCE = 18,
   NET_IPV4_CONF_ARP_IGNORE = 19,
-  NET_IPV4_CONF_PROMOTE_SECONDARIES = 20,
 /* WARNING: DO NOT EDIT, AUTO-GENERATED CODE - SEE TOP FOR INSTRUCTIONS */
+  NET_IPV4_CONF_PROMOTE_SECONDARIES = 20,
   NET_IPV4_CONF_ARP_ACCEPT = 21,
   NET_IPV4_CONF_ARP_NOTIFY = 22,
 };
-enum {
 /* WARNING: DO NOT EDIT, AUTO-GENERATED CODE - SEE TOP FOR INSTRUCTIONS */
+enum {
   NET_IPV4_NF_CONNTRACK_MAX = 1,
   NET_IPV4_NF_CONNTRACK_TCP_TIMEOUT_SYN_SENT = 2,
   NET_IPV4_NF_CONNTRACK_TCP_TIMEOUT_SYN_RECV = 3,
-  NET_IPV4_NF_CONNTRACK_TCP_TIMEOUT_ESTABLISHED = 4,
 /* WARNING: DO NOT EDIT, AUTO-GENERATED CODE - SEE TOP FOR INSTRUCTIONS */
+  NET_IPV4_NF_CONNTRACK_TCP_TIMEOUT_ESTABLISHED = 4,
   NET_IPV4_NF_CONNTRACK_TCP_TIMEOUT_FIN_WAIT = 5,
   NET_IPV4_NF_CONNTRACK_TCP_TIMEOUT_CLOSE_WAIT = 6,
   NET_IPV4_NF_CONNTRACK_TCP_TIMEOUT_LAST_ACK = 7,
-  NET_IPV4_NF_CONNTRACK_TCP_TIMEOUT_TIME_WAIT = 8,
 /* WARNING: DO NOT EDIT, AUTO-GENERATED CODE - SEE TOP FOR INSTRUCTIONS */
+  NET_IPV4_NF_CONNTRACK_TCP_TIMEOUT_TIME_WAIT = 8,
   NET_IPV4_NF_CONNTRACK_TCP_TIMEOUT_CLOSE = 9,
   NET_IPV4_NF_CONNTRACK_UDP_TIMEOUT = 10,
   NET_IPV4_NF_CONNTRACK_UDP_TIMEOUT_STREAM = 11,
-  NET_IPV4_NF_CONNTRACK_ICMP_TIMEOUT = 12,
 /* WARNING: DO NOT EDIT, AUTO-GENERATED CODE - SEE TOP FOR INSTRUCTIONS */
+  NET_IPV4_NF_CONNTRACK_ICMP_TIMEOUT = 12,
   NET_IPV4_NF_CONNTRACK_GENERIC_TIMEOUT = 13,
   NET_IPV4_NF_CONNTRACK_BUCKETS = 14,
   NET_IPV4_NF_CONNTRACK_LOG_INVALID = 15,
-  NET_IPV4_NF_CONNTRACK_TCP_TIMEOUT_MAX_RETRANS = 16,
 /* WARNING: DO NOT EDIT, AUTO-GENERATED CODE - SEE TOP FOR INSTRUCTIONS */
+  NET_IPV4_NF_CONNTRACK_TCP_TIMEOUT_MAX_RETRANS = 16,
   NET_IPV4_NF_CONNTRACK_TCP_LOOSE = 17,
   NET_IPV4_NF_CONNTRACK_TCP_BE_LIBERAL = 18,
   NET_IPV4_NF_CONNTRACK_TCP_MAX_RETRANS = 19,
-  NET_IPV4_NF_CONNTRACK_SCTP_TIMEOUT_CLOSED = 20,
 /* WARNING: DO NOT EDIT, AUTO-GENERATED CODE - SEE TOP FOR INSTRUCTIONS */
+  NET_IPV4_NF_CONNTRACK_SCTP_TIMEOUT_CLOSED = 20,
   NET_IPV4_NF_CONNTRACK_SCTP_TIMEOUT_COOKIE_WAIT = 21,
   NET_IPV4_NF_CONNTRACK_SCTP_TIMEOUT_COOKIE_ECHOED = 22,
   NET_IPV4_NF_CONNTRACK_SCTP_TIMEOUT_ESTABLISHED = 23,
-  NET_IPV4_NF_CONNTRACK_SCTP_TIMEOUT_SHUTDOWN_SENT = 24,
 /* WARNING: DO NOT EDIT, AUTO-GENERATED CODE - SEE TOP FOR INSTRUCTIONS */
+  NET_IPV4_NF_CONNTRACK_SCTP_TIMEOUT_SHUTDOWN_SENT = 24,
   NET_IPV4_NF_CONNTRACK_SCTP_TIMEOUT_SHUTDOWN_RECD = 25,
   NET_IPV4_NF_CONNTRACK_SCTP_TIMEOUT_SHUTDOWN_ACK_SENT = 26,
   NET_IPV4_NF_CONNTRACK_COUNT = 27,
-  NET_IPV4_NF_CONNTRACK_CHECKSUM = 28,
 /* WARNING: DO NOT EDIT, AUTO-GENERATED CODE - SEE TOP FOR INSTRUCTIONS */
+  NET_IPV4_NF_CONNTRACK_CHECKSUM = 28,
 };
 enum {
   NET_IPV6_CONF = 16,
-  NET_IPV6_NEIGH = 17,
 /* WARNING: DO NOT EDIT, AUTO-GENERATED CODE - SEE TOP FOR INSTRUCTIONS */
+  NET_IPV6_NEIGH = 17,
   NET_IPV6_ROUTE = 18,
   NET_IPV6_ICMP = 19,
   NET_IPV6_BINDV6ONLY = 20,
-  NET_IPV6_IP6FRAG_HIGH_THRESH = 21,
 /* WARNING: DO NOT EDIT, AUTO-GENERATED CODE - SEE TOP FOR INSTRUCTIONS */
+  NET_IPV6_IP6FRAG_HIGH_THRESH = 21,
   NET_IPV6_IP6FRAG_LOW_THRESH = 22,
   NET_IPV6_IP6FRAG_TIME = 23,
   NET_IPV6_IP6FRAG_SECRET_INTERVAL = 24,
-  NET_IPV6_MLD_MAX_MSF = 25,
 /* WARNING: DO NOT EDIT, AUTO-GENERATED CODE - SEE TOP FOR INSTRUCTIONS */
+  NET_IPV6_MLD_MAX_MSF = 25,
 };
 enum {
   NET_IPV6_ROUTE_FLUSH = 1,
-  NET_IPV6_ROUTE_GC_THRESH = 2,
 /* WARNING: DO NOT EDIT, AUTO-GENERATED CODE - SEE TOP FOR INSTRUCTIONS */
+  NET_IPV6_ROUTE_GC_THRESH = 2,
   NET_IPV6_ROUTE_MAX_SIZE = 3,
   NET_IPV6_ROUTE_GC_MIN_INTERVAL = 4,
   NET_IPV6_ROUTE_GC_TIMEOUT = 5,
-  NET_IPV6_ROUTE_GC_INTERVAL = 6,
 /* WARNING: DO NOT EDIT, AUTO-GENERATED CODE - SEE TOP FOR INSTRUCTIONS */
+  NET_IPV6_ROUTE_GC_INTERVAL = 6,
   NET_IPV6_ROUTE_GC_ELASTICITY = 7,
   NET_IPV6_ROUTE_MTU_EXPIRES = 8,
   NET_IPV6_ROUTE_MIN_ADVMSS = 9,
-  NET_IPV6_ROUTE_GC_MIN_INTERVAL_MS = 10
 /* WARNING: DO NOT EDIT, AUTO-GENERATED CODE - SEE TOP FOR INSTRUCTIONS */
+  NET_IPV6_ROUTE_GC_MIN_INTERVAL_MS = 10
 };
 enum {
   NET_IPV6_FORWARDING = 1,
-  NET_IPV6_HOP_LIMIT = 2,
 /* WARNING: DO NOT EDIT, AUTO-GENERATED CODE - SEE TOP FOR INSTRUCTIONS */
+  NET_IPV6_HOP_LIMIT = 2,
   NET_IPV6_MTU = 3,
   NET_IPV6_ACCEPT_RA = 4,
   NET_IPV6_ACCEPT_REDIRECTS = 5,
-  NET_IPV6_AUTOCONF = 6,
 /* WARNING: DO NOT EDIT, AUTO-GENERATED CODE - SEE TOP FOR INSTRUCTIONS */
+  NET_IPV6_AUTOCONF = 6,
   NET_IPV6_DAD_TRANSMITS = 7,
   NET_IPV6_RTR_SOLICITS = 8,
   NET_IPV6_RTR_SOLICIT_INTERVAL = 9,
-  NET_IPV6_RTR_SOLICIT_DELAY = 10,
 /* WARNING: DO NOT EDIT, AUTO-GENERATED CODE - SEE TOP FOR INSTRUCTIONS */
+  NET_IPV6_RTR_SOLICIT_DELAY = 10,
   NET_IPV6_USE_TEMPADDR = 11,
   NET_IPV6_TEMP_VALID_LFT = 12,
   NET_IPV6_TEMP_PREFERED_LFT = 13,
-  NET_IPV6_REGEN_MAX_RETRY = 14,
 /* WARNING: DO NOT EDIT, AUTO-GENERATED CODE - SEE TOP FOR INSTRUCTIONS */
+  NET_IPV6_REGEN_MAX_RETRY = 14,
   NET_IPV6_MAX_DESYNC_FACTOR = 15,
   NET_IPV6_MAX_ADDRESSES = 16,
   NET_IPV6_FORCE_MLD_VERSION = 17,
-  NET_IPV6_ACCEPT_RA_DEFRTR = 18,
 /* WARNING: DO NOT EDIT, AUTO-GENERATED CODE - SEE TOP FOR INSTRUCTIONS */
+  NET_IPV6_ACCEPT_RA_DEFRTR = 18,
   NET_IPV6_ACCEPT_RA_PINFO = 19,
   NET_IPV6_ACCEPT_RA_RTR_PREF = 20,
   NET_IPV6_RTR_PROBE_INTERVAL = 21,
-  NET_IPV6_ACCEPT_RA_RT_INFO_MAX_PLEN = 22,
 /* WARNING: DO NOT EDIT, AUTO-GENERATED CODE - SEE TOP FOR INSTRUCTIONS */
+  NET_IPV6_ACCEPT_RA_RT_INFO_MAX_PLEN = 22,
   NET_IPV6_PROXY_NDP = 23,
   NET_IPV6_ACCEPT_SOURCE_ROUTE = 25,
   NET_IPV6_ACCEPT_RA_FROM_LOCAL = 26,
-  __NET_IPV6_MAX
 /* WARNING: DO NOT EDIT, AUTO-GENERATED CODE - SEE TOP FOR INSTRUCTIONS */
+  __NET_IPV6_MAX
 };
 enum {
   NET_IPV6_ICMP_RATELIMIT = 1
-};
 /* WARNING: DO NOT EDIT, AUTO-GENERATED CODE - SEE TOP FOR INSTRUCTIONS */
+};
 enum {
   NET_NEIGH_MCAST_SOLICIT = 1,
   NET_NEIGH_UCAST_SOLICIT = 2,
-  NET_NEIGH_APP_SOLICIT = 3,
 /* WARNING: DO NOT EDIT, AUTO-GENERATED CODE - SEE TOP FOR INSTRUCTIONS */
+  NET_NEIGH_APP_SOLICIT = 3,
   NET_NEIGH_RETRANS_TIME = 4,
   NET_NEIGH_REACHABLE_TIME = 5,
   NET_NEIGH_DELAY_PROBE_TIME = 6,
-  NET_NEIGH_GC_STALE_TIME = 7,
 /* WARNING: DO NOT EDIT, AUTO-GENERATED CODE - SEE TOP FOR INSTRUCTIONS */
+  NET_NEIGH_GC_STALE_TIME = 7,
   NET_NEIGH_UNRES_QLEN = 8,
   NET_NEIGH_PROXY_QLEN = 9,
   NET_NEIGH_ANYCAST_DELAY = 10,
-  NET_NEIGH_PROXY_DELAY = 11,
 /* WARNING: DO NOT EDIT, AUTO-GENERATED CODE - SEE TOP FOR INSTRUCTIONS */
+  NET_NEIGH_PROXY_DELAY = 11,
   NET_NEIGH_LOCKTIME = 12,
   NET_NEIGH_GC_INTERVAL = 13,
   NET_NEIGH_GC_THRESH1 = 14,
-  NET_NEIGH_GC_THRESH2 = 15,
 /* WARNING: DO NOT EDIT, AUTO-GENERATED CODE - SEE TOP FOR INSTRUCTIONS */
+  NET_NEIGH_GC_THRESH2 = 15,
   NET_NEIGH_GC_THRESH3 = 16,
   NET_NEIGH_RETRANS_TIME_MS = 17,
   NET_NEIGH_REACHABLE_TIME_MS = 18,
-};
 /* WARNING: DO NOT EDIT, AUTO-GENERATED CODE - SEE TOP FOR INSTRUCTIONS */
+};
 enum {
   NET_DCCP_DEFAULT = 1,
 };
-enum {
 /* WARNING: DO NOT EDIT, AUTO-GENERATED CODE - SEE TOP FOR INSTRUCTIONS */
+enum {
   NET_IPX_PPROP_BROADCASTING = 1,
   NET_IPX_FORWARDING = 2
 };
-enum {
 /* WARNING: DO NOT EDIT, AUTO-GENERATED CODE - SEE TOP FOR INSTRUCTIONS */
+enum {
   NET_LLC2 = 1,
   NET_LLC_STATION = 2,
 };
-enum {
 /* WARNING: DO NOT EDIT, AUTO-GENERATED CODE - SEE TOP FOR INSTRUCTIONS */
+enum {
   NET_LLC2_TIMEOUT = 1,
 };
 enum {
-  NET_LLC_STATION_ACK_TIMEOUT = 1,
 /* WARNING: DO NOT EDIT, AUTO-GENERATED CODE - SEE TOP FOR INSTRUCTIONS */
+  NET_LLC_STATION_ACK_TIMEOUT = 1,
 };
 enum {
   NET_LLC2_ACK_TIMEOUT = 1,
-  NET_LLC2_P_TIMEOUT = 2,
 /* WARNING: DO NOT EDIT, AUTO-GENERATED CODE - SEE TOP FOR INSTRUCTIONS */
+  NET_LLC2_P_TIMEOUT = 2,
   NET_LLC2_REJ_TIMEOUT = 3,
   NET_LLC2_BUSY_TIMEOUT = 4,
 };
-enum {
 /* WARNING: DO NOT EDIT, AUTO-GENERATED CODE - SEE TOP FOR INSTRUCTIONS */
+enum {
   NET_ATALK_AARP_EXPIRY_TIME = 1,
   NET_ATALK_AARP_TICK_TIME = 2,
   NET_ATALK_AARP_RETRANSMIT_LIMIT = 3,
-  NET_ATALK_AARP_RESOLVE_TIME = 4
 /* WARNING: DO NOT EDIT, AUTO-GENERATED CODE - SEE TOP FOR INSTRUCTIONS */
+  NET_ATALK_AARP_RESOLVE_TIME = 4
 };
 enum {
   NET_NETROM_DEFAULT_PATH_QUALITY = 1,
-  NET_NETROM_OBSOLESCENCE_COUNT_INITIALISER = 2,
 /* WARNING: DO NOT EDIT, AUTO-GENERATED CODE - SEE TOP FOR INSTRUCTIONS */
+  NET_NETROM_OBSOLESCENCE_COUNT_INITIALISER = 2,
   NET_NETROM_NETWORK_TTL_INITIALISER = 3,
   NET_NETROM_TRANSPORT_TIMEOUT = 4,
   NET_NETROM_TRANSPORT_MAXIMUM_TRIES = 5,
-  NET_NETROM_TRANSPORT_ACKNOWLEDGE_DELAY = 6,
 /* WARNING: DO NOT EDIT, AUTO-GENERATED CODE - SEE TOP FOR INSTRUCTIONS */
+  NET_NETROM_TRANSPORT_ACKNOWLEDGE_DELAY = 6,
   NET_NETROM_TRANSPORT_BUSY_DELAY = 7,
   NET_NETROM_TRANSPORT_REQUESTED_WINDOW_SIZE = 8,
   NET_NETROM_TRANSPORT_NO_ACTIVITY_TIMEOUT = 9,
-  NET_NETROM_ROUTING_CONTROL = 10,
 /* WARNING: DO NOT EDIT, AUTO-GENERATED CODE - SEE TOP FOR INSTRUCTIONS */
+  NET_NETROM_ROUTING_CONTROL = 10,
   NET_NETROM_LINK_FAILS_COUNT = 11,
   NET_NETROM_RESET = 12
 };
-enum {
 /* WARNING: DO NOT EDIT, AUTO-GENERATED CODE - SEE TOP FOR INSTRUCTIONS */
+enum {
   NET_AX25_IP_DEFAULT_MODE = 1,
   NET_AX25_DEFAULT_MODE = 2,
   NET_AX25_BACKOFF_TYPE = 3,
-  NET_AX25_CONNECT_MODE = 4,
 /* WARNING: DO NOT EDIT, AUTO-GENERATED CODE - SEE TOP FOR INSTRUCTIONS */
+  NET_AX25_CONNECT_MODE = 4,
   NET_AX25_STANDARD_WINDOW = 5,
   NET_AX25_EXTENDED_WINDOW = 6,
   NET_AX25_T1_TIMEOUT = 7,
-  NET_AX25_T2_TIMEOUT = 8,
 /* WARNING: DO NOT EDIT, AUTO-GENERATED CODE - SEE TOP FOR INSTRUCTIONS */
+  NET_AX25_T2_TIMEOUT = 8,
   NET_AX25_T3_TIMEOUT = 9,
   NET_AX25_IDLE_TIMEOUT = 10,
   NET_AX25_N2 = 11,
-  NET_AX25_PACLEN = 12,
 /* WARNING: DO NOT EDIT, AUTO-GENERATED CODE - SEE TOP FOR INSTRUCTIONS */
+  NET_AX25_PACLEN = 12,
   NET_AX25_PROTOCOL = 13,
   NET_AX25_DAMA_SLAVE_TIMEOUT = 14
 };
-enum {
 /* WARNING: DO NOT EDIT, AUTO-GENERATED CODE - SEE TOP FOR INSTRUCTIONS */
+enum {
   NET_ROSE_RESTART_REQUEST_TIMEOUT = 1,
   NET_ROSE_CALL_REQUEST_TIMEOUT = 2,
   NET_ROSE_RESET_REQUEST_TIMEOUT = 3,
-  NET_ROSE_CLEAR_REQUEST_TIMEOUT = 4,
 /* WARNING: DO NOT EDIT, AUTO-GENERATED CODE - SEE TOP FOR INSTRUCTIONS */
+  NET_ROSE_CLEAR_REQUEST_TIMEOUT = 4,
   NET_ROSE_ACK_HOLD_BACK_TIMEOUT = 5,
   NET_ROSE_ROUTING_CONTROL = 6,
   NET_ROSE_LINK_FAIL_TIMEOUT = 7,
-  NET_ROSE_MAX_VCS = 8,
 /* WARNING: DO NOT EDIT, AUTO-GENERATED CODE - SEE TOP FOR INSTRUCTIONS */
+  NET_ROSE_MAX_VCS = 8,
   NET_ROSE_WINDOW_SIZE = 9,
   NET_ROSE_NO_ACTIVITY_TIMEOUT = 10
 };
-enum {
 /* WARNING: DO NOT EDIT, AUTO-GENERATED CODE - SEE TOP FOR INSTRUCTIONS */
+enum {
   NET_X25_RESTART_REQUEST_TIMEOUT = 1,
   NET_X25_CALL_REQUEST_TIMEOUT = 2,
   NET_X25_RESET_REQUEST_TIMEOUT = 3,
-  NET_X25_CLEAR_REQUEST_TIMEOUT = 4,
 /* WARNING: DO NOT EDIT, AUTO-GENERATED CODE - SEE TOP FOR INSTRUCTIONS */
+  NET_X25_CLEAR_REQUEST_TIMEOUT = 4,
   NET_X25_ACK_HOLD_BACK_TIMEOUT = 5,
   NET_X25_FORWARD = 6
 };
-enum {
 /* WARNING: DO NOT EDIT, AUTO-GENERATED CODE - SEE TOP FOR INSTRUCTIONS */
+enum {
   NET_TR_RIF_TIMEOUT = 1
 };
 enum {
-  NET_DECNET_NODE_TYPE = 1,
 /* WARNING: DO NOT EDIT, AUTO-GENERATED CODE - SEE TOP FOR INSTRUCTIONS */
+  NET_DECNET_NODE_TYPE = 1,
   NET_DECNET_NODE_ADDRESS = 2,
   NET_DECNET_NODE_NAME = 3,
   NET_DECNET_DEFAULT_DEVICE = 4,
-  NET_DECNET_TIME_WAIT = 5,
 /* WARNING: DO NOT EDIT, AUTO-GENERATED CODE - SEE TOP FOR INSTRUCTIONS */
+  NET_DECNET_TIME_WAIT = 5,
   NET_DECNET_DN_COUNT = 6,
   NET_DECNET_DI_COUNT = 7,
   NET_DECNET_DR_COUNT = 8,
-  NET_DECNET_DST_GC_INTERVAL = 9,
 /* WARNING: DO NOT EDIT, AUTO-GENERATED CODE - SEE TOP FOR INSTRUCTIONS */
+  NET_DECNET_DST_GC_INTERVAL = 9,
   NET_DECNET_CONF = 10,
   NET_DECNET_NO_FC_MAX_CWND = 11,
   NET_DECNET_MEM = 12,
-  NET_DECNET_RMEM = 13,
 /* WARNING: DO NOT EDIT, AUTO-GENERATED CODE - SEE TOP FOR INSTRUCTIONS */
+  NET_DECNET_RMEM = 13,
   NET_DECNET_WMEM = 14,
   NET_DECNET_DEBUG_LEVEL = 255
 };
-enum {
 /* WARNING: DO NOT EDIT, AUTO-GENERATED CODE - SEE TOP FOR INSTRUCTIONS */
+enum {
   NET_DECNET_CONF_LOOPBACK = - 2,
   NET_DECNET_CONF_DDCMP = - 3,
   NET_DECNET_CONF_PPP = - 4,
-  NET_DECNET_CONF_X25 = - 5,
 /* WARNING: DO NOT EDIT, AUTO-GENERATED CODE - SEE TOP FOR INSTRUCTIONS */
+  NET_DECNET_CONF_X25 = - 5,
   NET_DECNET_CONF_GRE = - 6,
   NET_DECNET_CONF_ETHER = - 7
 };
-enum {
 /* WARNING: DO NOT EDIT, AUTO-GENERATED CODE - SEE TOP FOR INSTRUCTIONS */
+enum {
   NET_DECNET_CONF_DEV_PRIORITY = 1,
   NET_DECNET_CONF_DEV_T1 = 2,
   NET_DECNET_CONF_DEV_T2 = 3,
-  NET_DECNET_CONF_DEV_T3 = 4,
 /* WARNING: DO NOT EDIT, AUTO-GENERATED CODE - SEE TOP FOR INSTRUCTIONS */
+  NET_DECNET_CONF_DEV_T3 = 4,
   NET_DECNET_CONF_DEV_FORWARDING = 5,
   NET_DECNET_CONF_DEV_BLKSIZE = 6,
   NET_DECNET_CONF_DEV_STATE = 7
-};
 /* WARNING: DO NOT EDIT, AUTO-GENERATED CODE - SEE TOP FOR INSTRUCTIONS */
+};
 enum {
   NET_SCTP_RTO_INITIAL = 1,
   NET_SCTP_RTO_MIN = 2,
-  NET_SCTP_RTO_MAX = 3,
 /* WARNING: DO NOT EDIT, AUTO-GENERATED CODE - SEE TOP FOR INSTRUCTIONS */
+  NET_SCTP_RTO_MAX = 3,
   NET_SCTP_RTO_ALPHA = 4,
   NET_SCTP_RTO_BETA = 5,
   NET_SCTP_VALID_COOKIE_LIFE = 6,
-  NET_SCTP_ASSOCIATION_MAX_RETRANS = 7,
 /* WARNING: DO NOT EDIT, AUTO-GENERATED CODE - SEE TOP FOR INSTRUCTIONS */
+  NET_SCTP_ASSOCIATION_MAX_RETRANS = 7,
   NET_SCTP_PATH_MAX_RETRANS = 8,
   NET_SCTP_MAX_INIT_RETRANSMITS = 9,
   NET_SCTP_HB_INTERVAL = 10,
-  NET_SCTP_PRESERVE_ENABLE = 11,
 /* WARNING: DO NOT EDIT, AUTO-GENERATED CODE - SEE TOP FOR INSTRUCTIONS */
+  NET_SCTP_PRESERVE_ENABLE = 11,
   NET_SCTP_MAX_BURST = 12,
   NET_SCTP_ADDIP_ENABLE = 13,
   NET_SCTP_PRSCTP_ENABLE = 14,
-  NET_SCTP_SNDBUF_POLICY = 15,
 /* WARNING: DO NOT EDIT, AUTO-GENERATED CODE - SEE TOP FOR INSTRUCTIONS */
+  NET_SCTP_SNDBUF_POLICY = 15,
   NET_SCTP_SACK_TIMEOUT = 16,
   NET_SCTP_RCVBUF_POLICY = 17,
 };
-enum {
 /* WARNING: DO NOT EDIT, AUTO-GENERATED CODE - SEE TOP FOR INSTRUCTIONS */
+enum {
   NET_BRIDGE_NF_CALL_ARPTABLES = 1,
   NET_BRIDGE_NF_CALL_IPTABLES = 2,
   NET_BRIDGE_NF_CALL_IP6TABLES = 3,
-  NET_BRIDGE_NF_FILTER_VLAN_TAGGED = 4,
 /* WARNING: DO NOT EDIT, AUTO-GENERATED CODE - SEE TOP FOR INSTRUCTIONS */
+  NET_BRIDGE_NF_FILTER_VLAN_TAGGED = 4,
   NET_BRIDGE_NF_FILTER_PPPOE_TAGGED = 5,
 };
 enum {
-  NET_IRDA_DISCOVERY = 1,
 /* WARNING: DO NOT EDIT, AUTO-GENERATED CODE - SEE TOP FOR INSTRUCTIONS */
+  NET_IRDA_DISCOVERY = 1,
   NET_IRDA_DEVNAME = 2,
   NET_IRDA_DEBUG = 3,
   NET_IRDA_FAST_POLL = 4,
-  NET_IRDA_DISCOVERY_SLOTS = 5,
 /* WARNING: DO NOT EDIT, AUTO-GENERATED CODE - SEE TOP FOR INSTRUCTIONS */
+  NET_IRDA_DISCOVERY_SLOTS = 5,
   NET_IRDA_DISCOVERY_TIMEOUT = 6,
   NET_IRDA_SLOT_TIMEOUT = 7,
   NET_IRDA_MAX_BAUD_RATE = 8,
-  NET_IRDA_MIN_TX_TURN_TIME = 9,
 /* WARNING: DO NOT EDIT, AUTO-GENERATED CODE - SEE TOP FOR INSTRUCTIONS */
+  NET_IRDA_MIN_TX_TURN_TIME = 9,
   NET_IRDA_MAX_TX_DATA_SIZE = 10,
   NET_IRDA_MAX_TX_WINDOW = 11,
   NET_IRDA_MAX_NOREPLY_TIME = 12,
-  NET_IRDA_WARN_NOREPLY_TIME = 13,
 /* WARNING: DO NOT EDIT, AUTO-GENERATED CODE - SEE TOP FOR INSTRUCTIONS */
+  NET_IRDA_WARN_NOREPLY_TIME = 13,
   NET_IRDA_LAP_KEEPALIVE_TIME = 14,
 };
 enum {
-  FS_NRINODE = 1,
 /* WARNING: DO NOT EDIT, AUTO-GENERATED CODE - SEE TOP FOR INSTRUCTIONS */
+  FS_NRINODE = 1,
   FS_STATINODE = 2,
   FS_MAXINODE = 3,
   FS_NRDQUOT = 4,
-  FS_MAXDQUOT = 5,
 /* WARNING: DO NOT EDIT, AUTO-GENERATED CODE - SEE TOP FOR INSTRUCTIONS */
+  FS_MAXDQUOT = 5,
   FS_NRFILE = 6,
   FS_MAXFILE = 7,
   FS_DENTRY = 8,
-  FS_NRSUPER = 9,
 /* WARNING: DO NOT EDIT, AUTO-GENERATED CODE - SEE TOP FOR INSTRUCTIONS */
+  FS_NRSUPER = 9,
   FS_MAXSUPER = 10,
   FS_OVERFLOWUID = 11,
   FS_OVERFLOWGID = 12,
-  FS_LEASES = 13,
 /* WARNING: DO NOT EDIT, AUTO-GENERATED CODE - SEE TOP FOR INSTRUCTIONS */
+  FS_LEASES = 13,
   FS_DIR_NOTIFY = 14,
   FS_LEASE_TIME = 15,
   FS_DQSTATS = 16,
-  FS_XFS = 17,
 /* WARNING: DO NOT EDIT, AUTO-GENERATED CODE - SEE TOP FOR INSTRUCTIONS */
+  FS_XFS = 17,
   FS_AIO_NR = 18,
   FS_AIO_MAX_NR = 19,
   FS_INOTIFY = 20,
-  FS_OCFS2 = 988,
 /* WARNING: DO NOT EDIT, AUTO-GENERATED CODE - SEE TOP FOR INSTRUCTIONS */
+  FS_OCFS2 = 988,
 };
 enum {
   FS_DQ_LOOKUPS = 1,
-  FS_DQ_DROPS = 2,
 /* WARNING: DO NOT EDIT, AUTO-GENERATED CODE - SEE TOP FOR INSTRUCTIONS */
+  FS_DQ_DROPS = 2,
   FS_DQ_READS = 3,
   FS_DQ_WRITES = 4,
   FS_DQ_CACHE_HITS = 5,
-  FS_DQ_ALLOCATED = 6,
 /* WARNING: DO NOT EDIT, AUTO-GENERATED CODE - SEE TOP FOR INSTRUCTIONS */
+  FS_DQ_ALLOCATED = 6,
   FS_DQ_FREE = 7,
   FS_DQ_SYNCS = 8,
   FS_DQ_WARNINGS = 9,
-};
 /* WARNING: DO NOT EDIT, AUTO-GENERATED CODE - SEE TOP FOR INSTRUCTIONS */
+};
 enum {
   DEV_CDROM = 1,
   DEV_HWMON = 2,
-  DEV_PARPORT = 3,
 /* WARNING: DO NOT EDIT, AUTO-GENERATED CODE - SEE TOP FOR INSTRUCTIONS */
+  DEV_PARPORT = 3,
   DEV_RAID = 4,
   DEV_MAC_HID = 5,
   DEV_SCSI = 6,
-  DEV_IPMI = 7,
 /* WARNING: DO NOT EDIT, AUTO-GENERATED CODE - SEE TOP FOR INSTRUCTIONS */
+  DEV_IPMI = 7,
 };
 enum {
   DEV_CDROM_INFO = 1,
-  DEV_CDROM_AUTOCLOSE = 2,
 /* WARNING: DO NOT EDIT, AUTO-GENERATED CODE - SEE TOP FOR INSTRUCTIONS */
+  DEV_CDROM_AUTOCLOSE = 2,
   DEV_CDROM_AUTOEJECT = 3,
   DEV_CDROM_DEBUG = 4,
   DEV_CDROM_LOCK = 5,
-  DEV_CDROM_CHECK_MEDIA = 6
 /* WARNING: DO NOT EDIT, AUTO-GENERATED CODE - SEE TOP FOR INSTRUCTIONS */
+  DEV_CDROM_CHECK_MEDIA = 6
 };
 enum {
   DEV_PARPORT_DEFAULT = - 3
-};
 /* WARNING: DO NOT EDIT, AUTO-GENERATED CODE - SEE TOP FOR INSTRUCTIONS */
+};
 enum {
   DEV_RAID_SPEED_LIMIT_MIN = 1,
   DEV_RAID_SPEED_LIMIT_MAX = 2
-};
 /* WARNING: DO NOT EDIT, AUTO-GENERATED CODE - SEE TOP FOR INSTRUCTIONS */
+};
 enum {
   DEV_PARPORT_DEFAULT_TIMESLICE = 1,
   DEV_PARPORT_DEFAULT_SPINTIME = 2
-};
 /* WARNING: DO NOT EDIT, AUTO-GENERATED CODE - SEE TOP FOR INSTRUCTIONS */
+};
 enum {
   DEV_PARPORT_SPINTIME = 1,
   DEV_PARPORT_BASE_ADDR = 2,
-  DEV_PARPORT_IRQ = 3,
 /* WARNING: DO NOT EDIT, AUTO-GENERATED CODE - SEE TOP FOR INSTRUCTIONS */
+  DEV_PARPORT_IRQ = 3,
   DEV_PARPORT_DMA = 4,
   DEV_PARPORT_MODES = 5,
   DEV_PARPORT_DEVICES = 6,
-  DEV_PARPORT_AUTOPROBE = 16
 /* WARNING: DO NOT EDIT, AUTO-GENERATED CODE - SEE TOP FOR INSTRUCTIONS */
+  DEV_PARPORT_AUTOPROBE = 16
 };
 enum {
   DEV_PARPORT_DEVICES_ACTIVE = - 3,
-};
 /* WARNING: DO NOT EDIT, AUTO-GENERATED CODE - SEE TOP FOR INSTRUCTIONS */
+};
 enum {
   DEV_PARPORT_DEVICE_TIMESLICE = 1,
 };
-enum {
 /* WARNING: DO NOT EDIT, AUTO-GENERATED CODE - SEE TOP FOR INSTRUCTIONS */
+enum {
   DEV_MAC_HID_KEYBOARD_SENDS_LINUX_KEYCODES = 1,
   DEV_MAC_HID_KEYBOARD_LOCK_KEYCODES = 2,
   DEV_MAC_HID_MOUSE_BUTTON_EMULATION = 3,
-  DEV_MAC_HID_MOUSE_BUTTON2_KEYCODE = 4,
 /* WARNING: DO NOT EDIT, AUTO-GENERATED CODE - SEE TOP FOR INSTRUCTIONS */
+  DEV_MAC_HID_MOUSE_BUTTON2_KEYCODE = 4,
   DEV_MAC_HID_MOUSE_BUTTON3_KEYCODE = 5,
   DEV_MAC_HID_ADB_MOUSE_SENDS_KEYCODES = 6
 };
-enum {
 /* WARNING: DO NOT EDIT, AUTO-GENERATED CODE - SEE TOP FOR INSTRUCTIONS */
+enum {
   DEV_SCSI_LOGGING_LEVEL = 1,
 };
 enum {
-  DEV_IPMI_POWEROFF_POWERCYCLE = 1,
 /* WARNING: DO NOT EDIT, AUTO-GENERATED CODE - SEE TOP FOR INSTRUCTIONS */
+  DEV_IPMI_POWEROFF_POWERCYCLE = 1,
 };
 enum {
   ABI_DEFHANDLER_COFF = 1,
-  ABI_DEFHANDLER_ELF = 2,
 /* WARNING: DO NOT EDIT, AUTO-GENERATED CODE - SEE TOP FOR INSTRUCTIONS */
+  ABI_DEFHANDLER_ELF = 2,
   ABI_DEFHANDLER_LCALL7 = 3,
   ABI_DEFHANDLER_LIBCSO = 4,
   ABI_TRACE = 5,
-  ABI_FAKE_UTSNAME = 6,
 /* WARNING: DO NOT EDIT, AUTO-GENERATED CODE - SEE TOP FOR INSTRUCTIONS */
+  ABI_FAKE_UTSNAME = 6,
 };
 #endif
diff --git a/libc/kernel/uapi/linux/target_core_user.h b/libc/kernel/uapi/linux/target_core_user.h
index 7e0cf43..343414c 100644
--- a/libc/kernel/uapi/linux/target_core_user.h
+++ b/libc/kernel/uapi/linux/target_core_user.h
@@ -21,8 +21,8 @@
 #include <linux/types.h>
 #include <linux/uio.h>
 /* WARNING: DO NOT EDIT, AUTO-GENERATED CODE - SEE TOP FOR INSTRUCTIONS */
-#define TCMU_VERSION "1.0"
-#define TCMU_MAILBOX_VERSION 1
+#define TCMU_VERSION "2.0"
+#define TCMU_MAILBOX_VERSION 2
 #define ALIGN_SIZE 64
 struct tcmu_mailbox {
 /* WARNING: DO NOT EDIT, AUTO-GENERATED CODE - SEE TOP FOR INSTRUCTIONS */
@@ -42,50 +42,58 @@
 struct tcmu_cmd_entry_hdr {
 /* WARNING: DO NOT EDIT, AUTO-GENERATED CODE - SEE TOP FOR INSTRUCTIONS */
   __u32 len_op;
+  __u16 cmd_id;
+  __u8 kflags;
+#define TCMU_UFLAG_UNKNOWN_OP 0x1
+/* WARNING: DO NOT EDIT, AUTO-GENERATED CODE - SEE TOP FOR INSTRUCTIONS */
+  __u8 uflags;
 } __packed;
 #define TCMU_OP_MASK 0x7
 #define TCMU_SENSE_BUFFERSIZE 96
 /* WARNING: DO NOT EDIT, AUTO-GENERATED CODE - SEE TOP FOR INSTRUCTIONS */
 struct tcmu_cmd_entry {
   struct tcmu_cmd_entry_hdr hdr;
-  uint16_t cmd_id;
-  uint16_t __pad1;
-/* WARNING: DO NOT EDIT, AUTO-GENERATED CODE - SEE TOP FOR INSTRUCTIONS */
   union {
     struct {
-      uint64_t cdb_off;
-      uint64_t iov_cnt;
 /* WARNING: DO NOT EDIT, AUTO-GENERATED CODE - SEE TOP FOR INSTRUCTIONS */
+      uint32_t iov_cnt;
+      uint32_t iov_bidi_cnt;
+      uint32_t iov_dif_cnt;
+      uint64_t cdb_off;
+/* WARNING: DO NOT EDIT, AUTO-GENERATED CODE - SEE TOP FOR INSTRUCTIONS */
+      uint64_t __pad1;
+      uint64_t __pad2;
       struct iovec iov[0];
     } req;
+/* WARNING: DO NOT EDIT, AUTO-GENERATED CODE - SEE TOP FOR INSTRUCTIONS */
     struct {
       uint8_t scsi_status;
-/* WARNING: DO NOT EDIT, AUTO-GENERATED CODE - SEE TOP FOR INSTRUCTIONS */
       uint8_t __pad1;
       uint16_t __pad2;
+/* WARNING: DO NOT EDIT, AUTO-GENERATED CODE - SEE TOP FOR INSTRUCTIONS */
       uint32_t __pad3;
       char sense_buffer[TCMU_SENSE_BUFFERSIZE];
-/* WARNING: DO NOT EDIT, AUTO-GENERATED CODE - SEE TOP FOR INSTRUCTIONS */
     } rsp;
   };
+/* WARNING: DO NOT EDIT, AUTO-GENERATED CODE - SEE TOP FOR INSTRUCTIONS */
 } __packed;
 #define TCMU_OP_ALIGN_SIZE sizeof(uint64_t)
-/* WARNING: DO NOT EDIT, AUTO-GENERATED CODE - SEE TOP FOR INSTRUCTIONS */
 enum tcmu_genl_cmd {
   TCMU_CMD_UNSPEC,
+/* WARNING: DO NOT EDIT, AUTO-GENERATED CODE - SEE TOP FOR INSTRUCTIONS */
   TCMU_CMD_ADDED_DEVICE,
   TCMU_CMD_REMOVED_DEVICE,
-/* WARNING: DO NOT EDIT, AUTO-GENERATED CODE - SEE TOP FOR INSTRUCTIONS */
   __TCMU_CMD_MAX,
 };
+/* WARNING: DO NOT EDIT, AUTO-GENERATED CODE - SEE TOP FOR INSTRUCTIONS */
 #define TCMU_CMD_MAX (__TCMU_CMD_MAX - 1)
 enum tcmu_genl_attr {
-/* WARNING: DO NOT EDIT, AUTO-GENERATED CODE - SEE TOP FOR INSTRUCTIONS */
   TCMU_ATTR_UNSPEC,
   TCMU_ATTR_DEVICE,
+/* WARNING: DO NOT EDIT, AUTO-GENERATED CODE - SEE TOP FOR INSTRUCTIONS */
   TCMU_ATTR_MINOR,
   __TCMU_ATTR_MAX,
-/* WARNING: DO NOT EDIT, AUTO-GENERATED CODE - SEE TOP FOR INSTRUCTIONS */
 };
 #define TCMU_ATTR_MAX (__TCMU_ATTR_MAX - 1)
+/* WARNING: DO NOT EDIT, AUTO-GENERATED CODE - SEE TOP FOR INSTRUCTIONS */
 #endif
diff --git a/libc/kernel/uapi/linux/tc_act/tc_bpf.h b/libc/kernel/uapi/linux/tc_act/tc_bpf.h
new file mode 100644
index 0000000..6b59128
--- /dev/null
+++ b/libc/kernel/uapi/linux/tc_act/tc_bpf.h
@@ -0,0 +1,41 @@
+/****************************************************************************
+ ****************************************************************************
+ ***
+ ***   This header was automatically generated from a Linux kernel header
+ ***   of the same name, to make information necessary for userspace to
+ ***   call into the kernel available to libc.  It contains only constants,
+ ***   structures, and macros generated from the original header, and thus,
+ ***   contains no copyrightable information.
+ ***
+ ***   To edit the content of this header, modify the corresponding
+ ***   source file (e.g. under external/kernel-headers/original/) then
+ ***   run bionic/libc/kernel/tools/update_all.py
+ ***
+ ***   Any manual change here will be lost the next time this script will
+ ***   be run. You've been warned!
+ ***
+ ****************************************************************************
+ ****************************************************************************/
+#ifndef __LINUX_TC_BPF_H
+#define __LINUX_TC_BPF_H
+#include <linux/pkt_cls.h>
+#define TCA_ACT_BPF 13
+/* WARNING: DO NOT EDIT, AUTO-GENERATED CODE - SEE TOP FOR INSTRUCTIONS */
+struct tc_act_bpf {
+  tc_gen;
+};
+enum {
+/* WARNING: DO NOT EDIT, AUTO-GENERATED CODE - SEE TOP FOR INSTRUCTIONS */
+  TCA_ACT_BPF_UNSPEC,
+  TCA_ACT_BPF_TM,
+  TCA_ACT_BPF_PARMS,
+  TCA_ACT_BPF_OPS_LEN,
+/* WARNING: DO NOT EDIT, AUTO-GENERATED CODE - SEE TOP FOR INSTRUCTIONS */
+  TCA_ACT_BPF_OPS,
+  TCA_ACT_BPF_FD,
+  TCA_ACT_BPF_NAME,
+  __TCA_ACT_BPF_MAX,
+/* WARNING: DO NOT EDIT, AUTO-GENERATED CODE - SEE TOP FOR INSTRUCTIONS */
+};
+#define TCA_ACT_BPF_MAX (__TCA_ACT_BPF_MAX - 1)
+#endif
diff --git a/libc/kernel/uapi/linux/tc_act/tc_connmark.h b/libc/kernel/uapi/linux/tc_act/tc_connmark.h
new file mode 100644
index 0000000..6dd64f0
--- /dev/null
+++ b/libc/kernel/uapi/linux/tc_act/tc_connmark.h
@@ -0,0 +1,39 @@
+/****************************************************************************
+ ****************************************************************************
+ ***
+ ***   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_TC_CONNMARK_H
+#define __UAPI_TC_CONNMARK_H
+#include <linux/types.h>
+#include <linux/pkt_cls.h>
+/* WARNING: DO NOT EDIT, AUTO-GENERATED CODE - SEE TOP FOR INSTRUCTIONS */
+#define TCA_ACT_CONNMARK 14
+struct tc_connmark {
+  tc_gen;
+  __u16 zone;
+/* WARNING: DO NOT EDIT, AUTO-GENERATED CODE - SEE TOP FOR INSTRUCTIONS */
+};
+enum {
+  TCA_CONNMARK_UNSPEC,
+  TCA_CONNMARK_PARMS,
+/* WARNING: DO NOT EDIT, AUTO-GENERATED CODE - SEE TOP FOR INSTRUCTIONS */
+  TCA_CONNMARK_TM,
+  __TCA_CONNMARK_MAX
+};
+#define TCA_CONNMARK_MAX (__TCA_CONNMARK_MAX - 1)
+/* WARNING: DO NOT EDIT, AUTO-GENERATED CODE - SEE TOP FOR INSTRUCTIONS */
+#endif
diff --git a/libc/kernel/uapi/linux/tc_act/tc_vlan.h b/libc/kernel/uapi/linux/tc_act/tc_vlan.h
new file mode 100644
index 0000000..f9b4d29
--- /dev/null
+++ b/libc/kernel/uapi/linux/tc_act/tc_vlan.h
@@ -0,0 +1,43 @@
+/****************************************************************************
+ ****************************************************************************
+ ***
+ ***   This header was automatically generated from a Linux kernel header
+ ***   of the same name, to make information necessary for userspace to
+ ***   call into the kernel available to libc.  It contains only constants,
+ ***   structures, and macros generated from the original header, and thus,
+ ***   contains no copyrightable information.
+ ***
+ ***   To edit the content of this header, modify the corresponding
+ ***   source file (e.g. under external/kernel-headers/original/) then
+ ***   run bionic/libc/kernel/tools/update_all.py
+ ***
+ ***   Any manual change here will be lost the next time this script will
+ ***   be run. You've been warned!
+ ***
+ ****************************************************************************
+ ****************************************************************************/
+#ifndef __LINUX_TC_VLAN_H
+#define __LINUX_TC_VLAN_H
+#include <linux/pkt_cls.h>
+#define TCA_ACT_VLAN 12
+/* WARNING: DO NOT EDIT, AUTO-GENERATED CODE - SEE TOP FOR INSTRUCTIONS */
+#define TCA_VLAN_ACT_POP 1
+#define TCA_VLAN_ACT_PUSH 2
+struct tc_vlan {
+  tc_gen;
+/* WARNING: DO NOT EDIT, AUTO-GENERATED CODE - SEE TOP FOR INSTRUCTIONS */
+  int v_action;
+};
+enum {
+  TCA_VLAN_UNSPEC,
+/* WARNING: DO NOT EDIT, AUTO-GENERATED CODE - SEE TOP FOR INSTRUCTIONS */
+  TCA_VLAN_TM,
+  TCA_VLAN_PARMS,
+  TCA_VLAN_PUSH_VLAN_ID,
+  TCA_VLAN_PUSH_VLAN_PROTOCOL,
+/* WARNING: DO NOT EDIT, AUTO-GENERATED CODE - SEE TOP FOR INSTRUCTIONS */
+  __TCA_VLAN_MAX,
+};
+#define TCA_VLAN_MAX (__TCA_VLAN_MAX - 1)
+#endif
+/* WARNING: DO NOT EDIT, AUTO-GENERATED CODE - SEE TOP FOR INSTRUCTIONS */
diff --git a/libc/kernel/uapi/linux/tcp.h b/libc/kernel/uapi/linux/tcp.h
index 3347bc1..ce36178 100644
--- a/libc/kernel/uapi/linux/tcp.h
+++ b/libc/kernel/uapi/linux/tcp.h
@@ -96,93 +96,101 @@
 #define TCP_TIMESTAMP 24
 #define TCP_NOTSENT_LOWAT 25
 /* WARNING: DO NOT EDIT, AUTO-GENERATED CODE - SEE TOP FOR INSTRUCTIONS */
+#define TCP_CC_INFO 26
+#define TCP_SAVE_SYN 27
+#define TCP_SAVED_SYN 28
 struct tcp_repair_opt {
+/* WARNING: DO NOT EDIT, AUTO-GENERATED CODE - SEE TOP FOR INSTRUCTIONS */
   __u32 opt_code;
   __u32 opt_val;
 };
-/* WARNING: DO NOT EDIT, AUTO-GENERATED CODE - SEE TOP FOR INSTRUCTIONS */
 enum {
+/* WARNING: DO NOT EDIT, AUTO-GENERATED CODE - SEE TOP FOR INSTRUCTIONS */
   TCP_NO_QUEUE,
   TCP_RECV_QUEUE,
   TCP_SEND_QUEUE,
-/* WARNING: DO NOT EDIT, AUTO-GENERATED CODE - SEE TOP FOR INSTRUCTIONS */
   TCP_QUEUES_NR,
+/* WARNING: DO NOT EDIT, AUTO-GENERATED CODE - SEE TOP FOR INSTRUCTIONS */
 };
 #define TCPI_OPT_TIMESTAMPS 1
 #define TCPI_OPT_SACK 2
-/* WARNING: DO NOT EDIT, AUTO-GENERATED CODE - SEE TOP FOR INSTRUCTIONS */
 #define TCPI_OPT_WSCALE 4
+/* WARNING: DO NOT EDIT, AUTO-GENERATED CODE - SEE TOP FOR INSTRUCTIONS */
 #define TCPI_OPT_ECN 8
 #define TCPI_OPT_ECN_SEEN 16
 #define TCPI_OPT_SYN_DATA 32
-/* WARNING: DO NOT EDIT, AUTO-GENERATED CODE - SEE TOP FOR INSTRUCTIONS */
 enum tcp_ca_state {
+/* WARNING: DO NOT EDIT, AUTO-GENERATED CODE - SEE TOP FOR INSTRUCTIONS */
   TCP_CA_Open = 0,
 #define TCPF_CA_Open (1 << TCP_CA_Open)
   TCP_CA_Disorder = 1,
-/* WARNING: DO NOT EDIT, AUTO-GENERATED CODE - SEE TOP FOR INSTRUCTIONS */
 #define TCPF_CA_Disorder (1 << TCP_CA_Disorder)
+/* WARNING: DO NOT EDIT, AUTO-GENERATED CODE - SEE TOP FOR INSTRUCTIONS */
   TCP_CA_CWR = 2,
 #define TCPF_CA_CWR (1 << TCP_CA_CWR)
   TCP_CA_Recovery = 3,
-/* WARNING: DO NOT EDIT, AUTO-GENERATED CODE - SEE TOP FOR INSTRUCTIONS */
 #define TCPF_CA_Recovery (1 << TCP_CA_Recovery)
+/* WARNING: DO NOT EDIT, AUTO-GENERATED CODE - SEE TOP FOR INSTRUCTIONS */
   TCP_CA_Loss = 4
 #define TCPF_CA_Loss (1 << TCP_CA_Loss)
 };
-/* WARNING: DO NOT EDIT, AUTO-GENERATED CODE - SEE TOP FOR INSTRUCTIONS */
 struct tcp_info {
+/* WARNING: DO NOT EDIT, AUTO-GENERATED CODE - SEE TOP FOR INSTRUCTIONS */
   __u8 tcpi_state;
   __u8 tcpi_ca_state;
   __u8 tcpi_retransmits;
-/* WARNING: DO NOT EDIT, AUTO-GENERATED CODE - SEE TOP FOR INSTRUCTIONS */
   __u8 tcpi_probes;
+/* WARNING: DO NOT EDIT, AUTO-GENERATED CODE - SEE TOP FOR INSTRUCTIONS */
   __u8 tcpi_backoff;
   __u8 tcpi_options;
   __u8 tcpi_snd_wscale : 4, tcpi_rcv_wscale : 4;
-/* WARNING: DO NOT EDIT, AUTO-GENERATED CODE - SEE TOP FOR INSTRUCTIONS */
   __u32 tcpi_rto;
+/* WARNING: DO NOT EDIT, AUTO-GENERATED CODE - SEE TOP FOR INSTRUCTIONS */
   __u32 tcpi_ato;
   __u32 tcpi_snd_mss;
   __u32 tcpi_rcv_mss;
-/* WARNING: DO NOT EDIT, AUTO-GENERATED CODE - SEE TOP FOR INSTRUCTIONS */
   __u32 tcpi_unacked;
+/* WARNING: DO NOT EDIT, AUTO-GENERATED CODE - SEE TOP FOR INSTRUCTIONS */
   __u32 tcpi_sacked;
   __u32 tcpi_lost;
   __u32 tcpi_retrans;
-/* WARNING: DO NOT EDIT, AUTO-GENERATED CODE - SEE TOP FOR INSTRUCTIONS */
   __u32 tcpi_fackets;
+/* WARNING: DO NOT EDIT, AUTO-GENERATED CODE - SEE TOP FOR INSTRUCTIONS */
   __u32 tcpi_last_data_sent;
   __u32 tcpi_last_ack_sent;
   __u32 tcpi_last_data_recv;
-/* WARNING: DO NOT EDIT, AUTO-GENERATED CODE - SEE TOP FOR INSTRUCTIONS */
   __u32 tcpi_last_ack_recv;
+/* WARNING: DO NOT EDIT, AUTO-GENERATED CODE - SEE TOP FOR INSTRUCTIONS */
   __u32 tcpi_pmtu;
   __u32 tcpi_rcv_ssthresh;
   __u32 tcpi_rtt;
-/* WARNING: DO NOT EDIT, AUTO-GENERATED CODE - SEE TOP FOR INSTRUCTIONS */
   __u32 tcpi_rttvar;
+/* WARNING: DO NOT EDIT, AUTO-GENERATED CODE - SEE TOP FOR INSTRUCTIONS */
   __u32 tcpi_snd_ssthresh;
   __u32 tcpi_snd_cwnd;
   __u32 tcpi_advmss;
-/* WARNING: DO NOT EDIT, AUTO-GENERATED CODE - SEE TOP FOR INSTRUCTIONS */
   __u32 tcpi_reordering;
+/* WARNING: DO NOT EDIT, AUTO-GENERATED CODE - SEE TOP FOR INSTRUCTIONS */
   __u32 tcpi_rcv_rtt;
   __u32 tcpi_rcv_space;
   __u32 tcpi_total_retrans;
-/* WARNING: DO NOT EDIT, AUTO-GENERATED CODE - SEE TOP FOR INSTRUCTIONS */
   __u64 tcpi_pacing_rate;
+/* WARNING: DO NOT EDIT, AUTO-GENERATED CODE - SEE TOP FOR INSTRUCTIONS */
   __u64 tcpi_max_pacing_rate;
+  __u64 tcpi_bytes_acked;
+  __u64 tcpi_bytes_received;
+  __u32 tcpi_segs_out;
+/* WARNING: DO NOT EDIT, AUTO-GENERATED CODE - SEE TOP FOR INSTRUCTIONS */
+  __u32 tcpi_segs_in;
 };
 #define TCP_MD5SIG_MAXKEYLEN 80
-/* WARNING: DO NOT EDIT, AUTO-GENERATED CODE - SEE TOP FOR INSTRUCTIONS */
 struct tcp_md5sig {
+/* WARNING: DO NOT EDIT, AUTO-GENERATED CODE - SEE TOP FOR INSTRUCTIONS */
   struct __kernel_sockaddr_storage tcpm_addr;
   __u16 __tcpm_pad1;
   __u16 tcpm_keylen;
-/* WARNING: DO NOT EDIT, AUTO-GENERATED CODE - SEE TOP FOR INSTRUCTIONS */
   __u32 __tcpm_pad2;
+/* WARNING: DO NOT EDIT, AUTO-GENERATED CODE - SEE TOP FOR INSTRUCTIONS */
   __u8 tcpm_key[TCP_MD5SIG_MAXKEYLEN];
 };
 #endif
-/* WARNING: DO NOT EDIT, AUTO-GENERATED CODE - SEE TOP FOR INSTRUCTIONS */
diff --git a/libc/kernel/uapi/linux/thermal.h b/libc/kernel/uapi/linux/thermal.h
new file mode 100644
index 0000000..e4e24e0
--- /dev/null
+++ b/libc/kernel/uapi/linux/thermal.h
@@ -0,0 +1,49 @@
+/****************************************************************************
+ ****************************************************************************
+ ***
+ ***   This header was automatically generated from a Linux kernel header
+ ***   of the same name, to make information necessary for userspace to
+ ***   call into the kernel available to libc.  It contains only constants,
+ ***   structures, and macros generated from the original header, and thus,
+ ***   contains no copyrightable information.
+ ***
+ ***   To edit the content of this header, modify the corresponding
+ ***   source file (e.g. under external/kernel-headers/original/) then
+ ***   run bionic/libc/kernel/tools/update_all.py
+ ***
+ ***   Any manual change here will be lost the next time this script will
+ ***   be run. You've been warned!
+ ***
+ ****************************************************************************
+ ****************************************************************************/
+#ifndef _UAPI_LINUX_THERMAL_H
+#define _UAPI_LINUX_THERMAL_H
+#define THERMAL_NAME_LENGTH 20
+#define THERMAL_GENL_FAMILY_NAME "thermal_event"
+/* WARNING: DO NOT EDIT, AUTO-GENERATED CODE - SEE TOP FOR INSTRUCTIONS */
+#define THERMAL_GENL_VERSION 0x01
+#define THERMAL_GENL_MCAST_GROUP_NAME "thermal_mc_grp"
+enum events {
+  THERMAL_AUX0,
+/* WARNING: DO NOT EDIT, AUTO-GENERATED CODE - SEE TOP FOR INSTRUCTIONS */
+  THERMAL_AUX1,
+  THERMAL_CRITICAL,
+  THERMAL_DEV_FAULT,
+};
+/* WARNING: DO NOT EDIT, AUTO-GENERATED CODE - SEE TOP FOR INSTRUCTIONS */
+enum {
+  THERMAL_GENL_ATTR_UNSPEC,
+  THERMAL_GENL_ATTR_EVENT,
+  __THERMAL_GENL_ATTR_MAX,
+/* WARNING: DO NOT EDIT, AUTO-GENERATED CODE - SEE TOP FOR INSTRUCTIONS */
+};
+#define THERMAL_GENL_ATTR_MAX (__THERMAL_GENL_ATTR_MAX - 1)
+enum {
+  THERMAL_GENL_CMD_UNSPEC,
+/* WARNING: DO NOT EDIT, AUTO-GENERATED CODE - SEE TOP FOR INSTRUCTIONS */
+  THERMAL_GENL_CMD_EVENT,
+  __THERMAL_GENL_CMD_MAX,
+};
+#define THERMAL_GENL_CMD_MAX (__THERMAL_GENL_CMD_MAX - 1)
+/* WARNING: DO NOT EDIT, AUTO-GENERATED CODE - SEE TOP FOR INSTRUCTIONS */
+#endif
diff --git a/libc/kernel/uapi/linux/tipc_netlink.h b/libc/kernel/uapi/linux/tipc_netlink.h
new file mode 100644
index 0000000..9d4796f
--- /dev/null
+++ b/libc/kernel/uapi/linux/tipc_netlink.h
@@ -0,0 +1,235 @@
+/****************************************************************************
+ ****************************************************************************
+ ***
+ ***   This header was automatically generated from a Linux kernel header
+ ***   of the same name, to make information necessary for userspace to
+ ***   call into the kernel available to libc.  It contains only constants,
+ ***   structures, and macros generated from the original header, and thus,
+ ***   contains no copyrightable information.
+ ***
+ ***   To edit the content of this header, modify the corresponding
+ ***   source file (e.g. under external/kernel-headers/original/) then
+ ***   run bionic/libc/kernel/tools/update_all.py
+ ***
+ ***   Any manual change here will be lost the next time this script will
+ ***   be run. You've been warned!
+ ***
+ ****************************************************************************
+ ****************************************************************************/
+#ifndef _LINUX_TIPC_NETLINK_H_
+#define _LINUX_TIPC_NETLINK_H_
+#define TIPC_GENL_V2_NAME "TIPCv2"
+#define TIPC_GENL_V2_VERSION 0x1
+/* WARNING: DO NOT EDIT, AUTO-GENERATED CODE - SEE TOP FOR INSTRUCTIONS */
+enum {
+  TIPC_NL_UNSPEC,
+  TIPC_NL_LEGACY,
+  TIPC_NL_BEARER_DISABLE,
+/* WARNING: DO NOT EDIT, AUTO-GENERATED CODE - SEE TOP FOR INSTRUCTIONS */
+  TIPC_NL_BEARER_ENABLE,
+  TIPC_NL_BEARER_GET,
+  TIPC_NL_BEARER_SET,
+  TIPC_NL_SOCK_GET,
+/* WARNING: DO NOT EDIT, AUTO-GENERATED CODE - SEE TOP FOR INSTRUCTIONS */
+  TIPC_NL_PUBL_GET,
+  TIPC_NL_LINK_GET,
+  TIPC_NL_LINK_SET,
+  TIPC_NL_LINK_RESET_STATS,
+/* WARNING: DO NOT EDIT, AUTO-GENERATED CODE - SEE TOP FOR INSTRUCTIONS */
+  TIPC_NL_MEDIA_GET,
+  TIPC_NL_MEDIA_SET,
+  TIPC_NL_NODE_GET,
+  TIPC_NL_NET_GET,
+/* WARNING: DO NOT EDIT, AUTO-GENERATED CODE - SEE TOP FOR INSTRUCTIONS */
+  TIPC_NL_NET_SET,
+  TIPC_NL_NAME_TABLE_GET,
+  __TIPC_NL_CMD_MAX,
+  TIPC_NL_CMD_MAX = __TIPC_NL_CMD_MAX - 1
+/* WARNING: DO NOT EDIT, AUTO-GENERATED CODE - SEE TOP FOR INSTRUCTIONS */
+};
+enum {
+  TIPC_NLA_UNSPEC,
+  TIPC_NLA_BEARER,
+/* WARNING: DO NOT EDIT, AUTO-GENERATED CODE - SEE TOP FOR INSTRUCTIONS */
+  TIPC_NLA_SOCK,
+  TIPC_NLA_PUBL,
+  TIPC_NLA_LINK,
+  TIPC_NLA_MEDIA,
+/* WARNING: DO NOT EDIT, AUTO-GENERATED CODE - SEE TOP FOR INSTRUCTIONS */
+  TIPC_NLA_NODE,
+  TIPC_NLA_NET,
+  TIPC_NLA_NAME_TABLE,
+  __TIPC_NLA_MAX,
+/* WARNING: DO NOT EDIT, AUTO-GENERATED CODE - SEE TOP FOR INSTRUCTIONS */
+  TIPC_NLA_MAX = __TIPC_NLA_MAX - 1
+};
+enum {
+  TIPC_NLA_BEARER_UNSPEC,
+/* WARNING: DO NOT EDIT, AUTO-GENERATED CODE - SEE TOP FOR INSTRUCTIONS */
+  TIPC_NLA_BEARER_NAME,
+  TIPC_NLA_BEARER_PROP,
+  TIPC_NLA_BEARER_DOMAIN,
+  TIPC_NLA_BEARER_UDP_OPTS,
+/* WARNING: DO NOT EDIT, AUTO-GENERATED CODE - SEE TOP FOR INSTRUCTIONS */
+  __TIPC_NLA_BEARER_MAX,
+  TIPC_NLA_BEARER_MAX = __TIPC_NLA_BEARER_MAX - 1
+};
+enum {
+/* WARNING: DO NOT EDIT, AUTO-GENERATED CODE - SEE TOP FOR INSTRUCTIONS */
+  TIPC_NLA_UDP_UNSPEC,
+  TIPC_NLA_UDP_LOCAL,
+  TIPC_NLA_UDP_REMOTE,
+  __TIPC_NLA_UDP_MAX,
+/* WARNING: DO NOT EDIT, AUTO-GENERATED CODE - SEE TOP FOR INSTRUCTIONS */
+  TIPC_NLA_UDP_MAX = __TIPC_NLA_UDP_MAX - 1
+};
+enum {
+  TIPC_NLA_SOCK_UNSPEC,
+/* WARNING: DO NOT EDIT, AUTO-GENERATED CODE - SEE TOP FOR INSTRUCTIONS */
+  TIPC_NLA_SOCK_ADDR,
+  TIPC_NLA_SOCK_REF,
+  TIPC_NLA_SOCK_CON,
+  TIPC_NLA_SOCK_HAS_PUBL,
+/* WARNING: DO NOT EDIT, AUTO-GENERATED CODE - SEE TOP FOR INSTRUCTIONS */
+  __TIPC_NLA_SOCK_MAX,
+  TIPC_NLA_SOCK_MAX = __TIPC_NLA_SOCK_MAX - 1
+};
+enum {
+/* WARNING: DO NOT EDIT, AUTO-GENERATED CODE - SEE TOP FOR INSTRUCTIONS */
+  TIPC_NLA_LINK_UNSPEC,
+  TIPC_NLA_LINK_NAME,
+  TIPC_NLA_LINK_DEST,
+  TIPC_NLA_LINK_MTU,
+/* WARNING: DO NOT EDIT, AUTO-GENERATED CODE - SEE TOP FOR INSTRUCTIONS */
+  TIPC_NLA_LINK_BROADCAST,
+  TIPC_NLA_LINK_UP,
+  TIPC_NLA_LINK_ACTIVE,
+  TIPC_NLA_LINK_PROP,
+/* WARNING: DO NOT EDIT, AUTO-GENERATED CODE - SEE TOP FOR INSTRUCTIONS */
+  TIPC_NLA_LINK_STATS,
+  TIPC_NLA_LINK_RX,
+  TIPC_NLA_LINK_TX,
+  __TIPC_NLA_LINK_MAX,
+/* WARNING: DO NOT EDIT, AUTO-GENERATED CODE - SEE TOP FOR INSTRUCTIONS */
+  TIPC_NLA_LINK_MAX = __TIPC_NLA_LINK_MAX - 1
+};
+enum {
+  TIPC_NLA_MEDIA_UNSPEC,
+/* WARNING: DO NOT EDIT, AUTO-GENERATED CODE - SEE TOP FOR INSTRUCTIONS */
+  TIPC_NLA_MEDIA_NAME,
+  TIPC_NLA_MEDIA_PROP,
+  __TIPC_NLA_MEDIA_MAX,
+  TIPC_NLA_MEDIA_MAX = __TIPC_NLA_MEDIA_MAX - 1
+/* WARNING: DO NOT EDIT, AUTO-GENERATED CODE - SEE TOP FOR INSTRUCTIONS */
+};
+enum {
+  TIPC_NLA_NODE_UNSPEC,
+  TIPC_NLA_NODE_ADDR,
+/* WARNING: DO NOT EDIT, AUTO-GENERATED CODE - SEE TOP FOR INSTRUCTIONS */
+  TIPC_NLA_NODE_UP,
+  __TIPC_NLA_NODE_MAX,
+  TIPC_NLA_NODE_MAX = __TIPC_NLA_NODE_MAX - 1
+};
+/* WARNING: DO NOT EDIT, AUTO-GENERATED CODE - SEE TOP FOR INSTRUCTIONS */
+enum {
+  TIPC_NLA_NET_UNSPEC,
+  TIPC_NLA_NET_ID,
+  TIPC_NLA_NET_ADDR,
+/* WARNING: DO NOT EDIT, AUTO-GENERATED CODE - SEE TOP FOR INSTRUCTIONS */
+  __TIPC_NLA_NET_MAX,
+  TIPC_NLA_NET_MAX = __TIPC_NLA_NET_MAX - 1
+};
+enum {
+/* WARNING: DO NOT EDIT, AUTO-GENERATED CODE - SEE TOP FOR INSTRUCTIONS */
+  TIPC_NLA_NAME_TABLE_UNSPEC,
+  TIPC_NLA_NAME_TABLE_PUBL,
+  __TIPC_NLA_NAME_TABLE_MAX,
+  TIPC_NLA_NAME_TABLE_MAX = __TIPC_NLA_NAME_TABLE_MAX - 1
+/* WARNING: DO NOT EDIT, AUTO-GENERATED CODE - SEE TOP FOR INSTRUCTIONS */
+};
+enum {
+  TIPC_NLA_PUBL_UNSPEC,
+  TIPC_NLA_PUBL_TYPE,
+/* WARNING: DO NOT EDIT, AUTO-GENERATED CODE - SEE TOP FOR INSTRUCTIONS */
+  TIPC_NLA_PUBL_LOWER,
+  TIPC_NLA_PUBL_UPPER,
+  TIPC_NLA_PUBL_SCOPE,
+  TIPC_NLA_PUBL_NODE,
+/* WARNING: DO NOT EDIT, AUTO-GENERATED CODE - SEE TOP FOR INSTRUCTIONS */
+  TIPC_NLA_PUBL_REF,
+  TIPC_NLA_PUBL_KEY,
+  __TIPC_NLA_PUBL_MAX,
+  TIPC_NLA_PUBL_MAX = __TIPC_NLA_PUBL_MAX - 1
+/* WARNING: DO NOT EDIT, AUTO-GENERATED CODE - SEE TOP FOR INSTRUCTIONS */
+};
+enum {
+  TIPC_NLA_CON_UNSPEC,
+  TIPC_NLA_CON_FLAG,
+/* WARNING: DO NOT EDIT, AUTO-GENERATED CODE - SEE TOP FOR INSTRUCTIONS */
+  TIPC_NLA_CON_NODE,
+  TIPC_NLA_CON_SOCK,
+  TIPC_NLA_CON_TYPE,
+  TIPC_NLA_CON_INST,
+/* WARNING: DO NOT EDIT, AUTO-GENERATED CODE - SEE TOP FOR INSTRUCTIONS */
+  __TIPC_NLA_CON_MAX,
+  TIPC_NLA_CON_MAX = __TIPC_NLA_CON_MAX - 1
+};
+enum {
+/* WARNING: DO NOT EDIT, AUTO-GENERATED CODE - SEE TOP FOR INSTRUCTIONS */
+  TIPC_NLA_PROP_UNSPEC,
+  TIPC_NLA_PROP_PRIO,
+  TIPC_NLA_PROP_TOL,
+  TIPC_NLA_PROP_WIN,
+/* WARNING: DO NOT EDIT, AUTO-GENERATED CODE - SEE TOP FOR INSTRUCTIONS */
+  __TIPC_NLA_PROP_MAX,
+  TIPC_NLA_PROP_MAX = __TIPC_NLA_PROP_MAX - 1
+};
+enum {
+/* WARNING: DO NOT EDIT, AUTO-GENERATED CODE - SEE TOP FOR INSTRUCTIONS */
+  TIPC_NLA_STATS_UNSPEC,
+  TIPC_NLA_STATS_RX_INFO,
+  TIPC_NLA_STATS_RX_FRAGMENTS,
+  TIPC_NLA_STATS_RX_FRAGMENTED,
+/* WARNING: DO NOT EDIT, AUTO-GENERATED CODE - SEE TOP FOR INSTRUCTIONS */
+  TIPC_NLA_STATS_RX_BUNDLES,
+  TIPC_NLA_STATS_RX_BUNDLED,
+  TIPC_NLA_STATS_TX_INFO,
+  TIPC_NLA_STATS_TX_FRAGMENTS,
+/* WARNING: DO NOT EDIT, AUTO-GENERATED CODE - SEE TOP FOR INSTRUCTIONS */
+  TIPC_NLA_STATS_TX_FRAGMENTED,
+  TIPC_NLA_STATS_TX_BUNDLES,
+  TIPC_NLA_STATS_TX_BUNDLED,
+  TIPC_NLA_STATS_MSG_PROF_TOT,
+/* WARNING: DO NOT EDIT, AUTO-GENERATED CODE - SEE TOP FOR INSTRUCTIONS */
+  TIPC_NLA_STATS_MSG_LEN_CNT,
+  TIPC_NLA_STATS_MSG_LEN_TOT,
+  TIPC_NLA_STATS_MSG_LEN_P0,
+  TIPC_NLA_STATS_MSG_LEN_P1,
+/* WARNING: DO NOT EDIT, AUTO-GENERATED CODE - SEE TOP FOR INSTRUCTIONS */
+  TIPC_NLA_STATS_MSG_LEN_P2,
+  TIPC_NLA_STATS_MSG_LEN_P3,
+  TIPC_NLA_STATS_MSG_LEN_P4,
+  TIPC_NLA_STATS_MSG_LEN_P5,
+/* WARNING: DO NOT EDIT, AUTO-GENERATED CODE - SEE TOP FOR INSTRUCTIONS */
+  TIPC_NLA_STATS_MSG_LEN_P6,
+  TIPC_NLA_STATS_RX_STATES,
+  TIPC_NLA_STATS_RX_PROBES,
+  TIPC_NLA_STATS_RX_NACKS,
+/* WARNING: DO NOT EDIT, AUTO-GENERATED CODE - SEE TOP FOR INSTRUCTIONS */
+  TIPC_NLA_STATS_RX_DEFERRED,
+  TIPC_NLA_STATS_TX_STATES,
+  TIPC_NLA_STATS_TX_PROBES,
+  TIPC_NLA_STATS_TX_NACKS,
+/* WARNING: DO NOT EDIT, AUTO-GENERATED CODE - SEE TOP FOR INSTRUCTIONS */
+  TIPC_NLA_STATS_TX_ACKS,
+  TIPC_NLA_STATS_RETRANSMITTED,
+  TIPC_NLA_STATS_DUPLICATES,
+  TIPC_NLA_STATS_LINK_CONGS,
+/* WARNING: DO NOT EDIT, AUTO-GENERATED CODE - SEE TOP FOR INSTRUCTIONS */
+  TIPC_NLA_STATS_MAX_QUEUE,
+  TIPC_NLA_STATS_AVG_QUEUE,
+  __TIPC_NLA_STATS_MAX,
+  TIPC_NLA_STATS_MAX = __TIPC_NLA_STATS_MAX - 1
+/* WARNING: DO NOT EDIT, AUTO-GENERATED CODE - SEE TOP FOR INSTRUCTIONS */
+};
+#endif
diff --git a/libc/kernel/uapi/linux/toshiba.h b/libc/kernel/uapi/linux/toshiba.h
index 04e8ee5..9d3449c 100644
--- a/libc/kernel/uapi/linux/toshiba.h
+++ b/libc/kernel/uapi/linux/toshiba.h
@@ -21,15 +21,19 @@
 #define TOSH_PROC "/proc/toshiba"
 #define TOSH_DEVICE "/dev/toshiba"
 /* WARNING: DO NOT EDIT, AUTO-GENERATED CODE - SEE TOP FOR INSTRUCTIONS */
-#define TOSH_SMM _IOWR('t', 0x90, int)
+#define TOSHIBA_ACPI_PROC "/proc/acpi/toshiba"
+#define TOSHIBA_ACPI_DEVICE "/dev/toshiba_acpi"
 typedef struct {
   unsigned int eax;
-  unsigned int ebx __attribute__((packed));
 /* WARNING: DO NOT EDIT, AUTO-GENERATED CODE - SEE TOP FOR INSTRUCTIONS */
+  unsigned int ebx __attribute__((packed));
   unsigned int ecx __attribute__((packed));
   unsigned int edx __attribute__((packed));
   unsigned int esi __attribute__((packed));
-  unsigned int edi __attribute__((packed));
 /* WARNING: DO NOT EDIT, AUTO-GENERATED CODE - SEE TOP FOR INSTRUCTIONS */
+  unsigned int edi __attribute__((packed));
 } SMMRegisters;
+#define TOSH_SMM _IOWR('t', 0x90, SMMRegisters)
+#define TOSHIBA_ACPI_SCI _IOWR('t', 0x91, SMMRegisters)
+/* WARNING: DO NOT EDIT, AUTO-GENERATED CODE - SEE TOP FOR INSTRUCTIONS */
 #endif
diff --git a/libc/kernel/uapi/linux/tty.h b/libc/kernel/uapi/linux/tty.h
index 05347a3..c26e836 100644
--- a/libc/kernel/uapi/linux/tty.h
+++ b/libc/kernel/uapi/linux/tty.h
@@ -51,4 +51,5 @@
 #define N_TRACESINK 23
 #define N_TRACEROUTER 24
 /* WARNING: DO NOT EDIT, AUTO-GENERATED CODE - SEE TOP FOR INSTRUCTIONS */
+#define N_NCI 25
 #endif
diff --git a/libc/kernel/uapi/linux/tty_flags.h b/libc/kernel/uapi/linux/tty_flags.h
index bcc5f60..12fae79 100644
--- a/libc/kernel/uapi/linux/tty_flags.h
+++ b/libc/kernel/uapi/linux/tty_flags.h
@@ -38,57 +38,61 @@
 /* WARNING: DO NOT EDIT, AUTO-GENERATED CODE - SEE TOP FOR INSTRUCTIONS */
 #define ASYNCB_BUGGY_UART 14
 #define ASYNCB_AUTOPROBE 15
-#define ASYNCB_LAST_USER 15
-#define ASYNCB_INITIALIZED 31
+#define ASYNCB_MAGIC_MULTIPLIER 16
+#define ASYNCB_LAST_USER 16
 /* WARNING: DO NOT EDIT, AUTO-GENERATED CODE - SEE TOP FOR INSTRUCTIONS */
+#define ASYNCB_INITIALIZED 31
 #define ASYNCB_SUSPENDED 30
 #define ASYNCB_NORMAL_ACTIVE 29
 #define ASYNCB_BOOT_AUTOCONF 28
-#define ASYNCB_CLOSING 27
 /* WARNING: DO NOT EDIT, AUTO-GENERATED CODE - SEE TOP FOR INSTRUCTIONS */
+#define ASYNCB_CLOSING 27
 #define ASYNCB_CTS_FLOW 26
 #define ASYNCB_CHECK_CD 25
 #define ASYNCB_SHARE_IRQ 24
-#define ASYNCB_CONS_FLOW 23
 /* WARNING: DO NOT EDIT, AUTO-GENERATED CODE - SEE TOP FOR INSTRUCTIONS */
+#define ASYNCB_CONS_FLOW 23
 #define ASYNCB_FIRST_KERNEL 22
 #define ASYNC_HUP_NOTIFY (1U << ASYNCB_HUP_NOTIFY)
 #define ASYNC_SUSPENDED (1U << ASYNCB_SUSPENDED)
-#define ASYNC_FOURPORT (1U << ASYNCB_FOURPORT)
 /* WARNING: DO NOT EDIT, AUTO-GENERATED CODE - SEE TOP FOR INSTRUCTIONS */
+#define ASYNC_FOURPORT (1U << ASYNCB_FOURPORT)
 #define ASYNC_SAK (1U << ASYNCB_SAK)
 #define ASYNC_SPLIT_TERMIOS (1U << ASYNCB_SPLIT_TERMIOS)
 #define ASYNC_SPD_HI (1U << ASYNCB_SPD_HI)
-#define ASYNC_SPD_VHI (1U << ASYNCB_SPD_VHI)
 /* WARNING: DO NOT EDIT, AUTO-GENERATED CODE - SEE TOP FOR INSTRUCTIONS */
+#define ASYNC_SPD_VHI (1U << ASYNCB_SPD_VHI)
 #define ASYNC_SKIP_TEST (1U << ASYNCB_SKIP_TEST)
 #define ASYNC_AUTO_IRQ (1U << ASYNCB_AUTO_IRQ)
 #define ASYNC_SESSION_LOCKOUT (1U << ASYNCB_SESSION_LOCKOUT)
-#define ASYNC_PGRP_LOCKOUT (1U << ASYNCB_PGRP_LOCKOUT)
 /* WARNING: DO NOT EDIT, AUTO-GENERATED CODE - SEE TOP FOR INSTRUCTIONS */
+#define ASYNC_PGRP_LOCKOUT (1U << ASYNCB_PGRP_LOCKOUT)
 #define ASYNC_CALLOUT_NOHUP (1U << ASYNCB_CALLOUT_NOHUP)
 #define ASYNC_HARDPPS_CD (1U << ASYNCB_HARDPPS_CD)
 #define ASYNC_SPD_SHI (1U << ASYNCB_SPD_SHI)
-#define ASYNC_LOW_LATENCY (1U << ASYNCB_LOW_LATENCY)
 /* WARNING: DO NOT EDIT, AUTO-GENERATED CODE - SEE TOP FOR INSTRUCTIONS */
+#define ASYNC_LOW_LATENCY (1U << ASYNCB_LOW_LATENCY)
 #define ASYNC_BUGGY_UART (1U << ASYNCB_BUGGY_UART)
 #define ASYNC_AUTOPROBE (1U << ASYNCB_AUTOPROBE)
-#define ASYNC_FLAGS ((1U << (ASYNCB_LAST_USER + 1)) - 1)
-#define ASYNC_USR_MASK (ASYNC_SPD_MASK | ASYNC_CALLOUT_NOHUP | ASYNC_LOW_LATENCY)
+#define ASYNC_MAGIC_MULTIPLIER (1U << ASYNCB_MAGIC_MULTIPLIER)
 /* WARNING: DO NOT EDIT, AUTO-GENERATED CODE - SEE TOP FOR INSTRUCTIONS */
+#define ASYNC_FLAGS ((1U << (ASYNCB_LAST_USER + 1)) - 1)
+#define ASYNC_DEPRECATED (ASYNC_SESSION_LOCKOUT | ASYNC_PGRP_LOCKOUT | ASYNC_CALLOUT_NOHUP | ASYNC_AUTOPROBE)
+#define ASYNC_USR_MASK (ASYNC_SPD_MASK | ASYNC_CALLOUT_NOHUP | ASYNC_LOW_LATENCY)
 #define ASYNC_SPD_CUST (ASYNC_SPD_HI | ASYNC_SPD_VHI)
+/* WARNING: DO NOT EDIT, AUTO-GENERATED CODE - SEE TOP FOR INSTRUCTIONS */
 #define ASYNC_SPD_WARP (ASYNC_SPD_HI | ASYNC_SPD_SHI)
 #define ASYNC_SPD_MASK (ASYNC_SPD_HI | ASYNC_SPD_VHI | ASYNC_SPD_SHI)
 #define ASYNC_INITIALIZED (1U << ASYNCB_INITIALIZED)
-/* WARNING: DO NOT EDIT, AUTO-GENERATED CODE - SEE TOP FOR INSTRUCTIONS */
 #define ASYNC_NORMAL_ACTIVE (1U << ASYNCB_NORMAL_ACTIVE)
+/* WARNING: DO NOT EDIT, AUTO-GENERATED CODE - SEE TOP FOR INSTRUCTIONS */
 #define ASYNC_BOOT_AUTOCONF (1U << ASYNCB_BOOT_AUTOCONF)
 #define ASYNC_CLOSING (1U << ASYNCB_CLOSING)
 #define ASYNC_CTS_FLOW (1U << ASYNCB_CTS_FLOW)
-/* WARNING: DO NOT EDIT, AUTO-GENERATED CODE - SEE TOP FOR INSTRUCTIONS */
 #define ASYNC_CHECK_CD (1U << ASYNCB_CHECK_CD)
+/* WARNING: DO NOT EDIT, AUTO-GENERATED CODE - SEE TOP FOR INSTRUCTIONS */
 #define ASYNC_SHARE_IRQ (1U << ASYNCB_SHARE_IRQ)
 #define ASYNC_CONS_FLOW (1U << ASYNCB_CONS_FLOW)
 #define ASYNC_INTERNAL_FLAGS (~((1U << ASYNCB_FIRST_KERNEL) - 1))
-/* WARNING: DO NOT EDIT, AUTO-GENERATED CODE - SEE TOP FOR INSTRUCTIONS */
 #endif
+/* WARNING: DO NOT EDIT, AUTO-GENERATED CODE - SEE TOP FOR INSTRUCTIONS */
diff --git a/libc/kernel/uapi/linux/udp.h b/libc/kernel/uapi/linux/udp.h
index e1d546c..a3e9e97 100644
--- a/libc/kernel/uapi/linux/udp.h
+++ b/libc/kernel/uapi/linux/udp.h
@@ -19,7 +19,7 @@
 #ifndef _UAPI_LINUX_UDP_H
 #define _UAPI_LINUX_UDP_H
 #include <linux/types.h>
-struct udphdr {
+struct __kernel_udphdr {
 /* WARNING: DO NOT EDIT, AUTO-GENERATED CODE - SEE TOP FOR INSTRUCTIONS */
   __be16 source;
   __be16 dest;
diff --git a/libc/kernel/uapi/linux/uinput.h b/libc/kernel/uapi/linux/uinput.h
index 845affc..018d8a8 100644
--- a/libc/kernel/uapi/linux/uinput.h
+++ b/libc/kernel/uapi/linux/uinput.h
@@ -58,8 +58,8 @@
 /* WARNING: DO NOT EDIT, AUTO-GENERATED CODE - SEE TOP FOR INSTRUCTIONS */
 #define UI_BEGIN_FF_ERASE _IOWR(UINPUT_IOCTL_BASE, 202, struct uinput_ff_erase)
 #define UI_END_FF_ERASE _IOW(UINPUT_IOCTL_BASE, 203, struct uinput_ff_erase)
-#define UI_GET_SYSNAME(len) _IOC(_IOC_READ, UINPUT_IOCTL_BASE, 300, len)
-#define UI_GET_VERSION _IOR(UINPUT_IOCTL_BASE, 301, unsigned int)
+#define UI_GET_SYSNAME(len) _IOC(_IOC_READ, UINPUT_IOCTL_BASE, 44, len)
+#define UI_GET_VERSION _IOR(UINPUT_IOCTL_BASE, 45, unsigned int)
 /* WARNING: DO NOT EDIT, AUTO-GENERATED CODE - SEE TOP FOR INSTRUCTIONS */
 #define EV_UINPUT 0x0101
 #define UI_FF_UPLOAD 1
diff --git a/libc/kernel/uapi/linux/usb/cdc.h b/libc/kernel/uapi/linux/usb/cdc.h
index 81123cb..4f02fcf 100644
--- a/libc/kernel/uapi/linux/usb/cdc.h
+++ b/libc/kernel/uapi/linux/usb/cdc.h
@@ -16,8 +16,8 @@
  ***
  ****************************************************************************
  ****************************************************************************/
-#ifndef __LINUX_USB_CDC_H
-#define __LINUX_USB_CDC_H
+#ifndef __UAPI_LINUX_USB_CDC_H
+#define __UAPI_LINUX_USB_CDC_H
 #include <linux/types.h>
 #define USB_CDC_SUBCLASS_ACM 0x02
 /* WARNING: DO NOT EDIT, AUTO-GENERATED CODE - SEE TOP FOR INSTRUCTIONS */
diff --git a/libc/kernel/uapi/linux/usb/ch9.h b/libc/kernel/uapi/linux/usb/ch9.h
index c2dd92d..8b96af9 100644
--- a/libc/kernel/uapi/linux/usb/ch9.h
+++ b/libc/kernel/uapi/linux/usb/ch9.h
@@ -307,235 +307,272 @@
   __u8 bmAttributes;
 /* WARNING: DO NOT EDIT, AUTO-GENERATED CODE - SEE TOP FOR INSTRUCTIONS */
 } __attribute__((packed));
-#define USB_OTG_SRP (1 << 0)
-#define USB_OTG_HNP (1 << 1)
-struct usb_debug_descriptor {
-/* WARNING: DO NOT EDIT, AUTO-GENERATED CODE - SEE TOP FOR INSTRUCTIONS */
+struct usb_otg20_descriptor {
   __u8 bLength;
   __u8 bDescriptorType;
+/* WARNING: DO NOT EDIT, AUTO-GENERATED CODE - SEE TOP FOR INSTRUCTIONS */
+  __u8 bmAttributes;
+  __le16 bcdOTG;
+} __attribute__((packed));
+#define USB_OTG_SRP (1 << 0)
+/* WARNING: DO NOT EDIT, AUTO-GENERATED CODE - SEE TOP FOR INSTRUCTIONS */
+#define USB_OTG_HNP (1 << 1)
+#define USB_OTG_ADP (1 << 2)
+struct usb_debug_descriptor {
+  __u8 bLength;
+/* WARNING: DO NOT EDIT, AUTO-GENERATED CODE - SEE TOP FOR INSTRUCTIONS */
+  __u8 bDescriptorType;
   __u8 bDebugInEndpoint;
   __u8 bDebugOutEndpoint;
-/* WARNING: DO NOT EDIT, AUTO-GENERATED CODE - SEE TOP FOR INSTRUCTIONS */
 } __attribute__((packed));
+/* WARNING: DO NOT EDIT, AUTO-GENERATED CODE - SEE TOP FOR INSTRUCTIONS */
 struct usb_interface_assoc_descriptor {
   __u8 bLength;
   __u8 bDescriptorType;
-/* WARNING: DO NOT EDIT, AUTO-GENERATED CODE - SEE TOP FOR INSTRUCTIONS */
   __u8 bFirstInterface;
+/* WARNING: DO NOT EDIT, AUTO-GENERATED CODE - SEE TOP FOR INSTRUCTIONS */
   __u8 bInterfaceCount;
   __u8 bFunctionClass;
   __u8 bFunctionSubClass;
-/* WARNING: DO NOT EDIT, AUTO-GENERATED CODE - SEE TOP FOR INSTRUCTIONS */
   __u8 bFunctionProtocol;
+/* WARNING: DO NOT EDIT, AUTO-GENERATED CODE - SEE TOP FOR INSTRUCTIONS */
   __u8 iFunction;
 } __attribute__((packed));
 struct usb_security_descriptor {
-/* WARNING: DO NOT EDIT, AUTO-GENERATED CODE - SEE TOP FOR INSTRUCTIONS */
   __u8 bLength;
+/* WARNING: DO NOT EDIT, AUTO-GENERATED CODE - SEE TOP FOR INSTRUCTIONS */
   __u8 bDescriptorType;
   __le16 wTotalLength;
   __u8 bNumEncryptionTypes;
-/* WARNING: DO NOT EDIT, AUTO-GENERATED CODE - SEE TOP FOR INSTRUCTIONS */
 } __attribute__((packed));
+/* WARNING: DO NOT EDIT, AUTO-GENERATED CODE - SEE TOP FOR INSTRUCTIONS */
 struct usb_key_descriptor {
   __u8 bLength;
   __u8 bDescriptorType;
-/* WARNING: DO NOT EDIT, AUTO-GENERATED CODE - SEE TOP FOR INSTRUCTIONS */
   __u8 tTKID[3];
+/* WARNING: DO NOT EDIT, AUTO-GENERATED CODE - SEE TOP FOR INSTRUCTIONS */
   __u8 bReserved;
   __u8 bKeyData[0];
 } __attribute__((packed));
-/* WARNING: DO NOT EDIT, AUTO-GENERATED CODE - SEE TOP FOR INSTRUCTIONS */
 struct usb_encryption_descriptor {
+/* WARNING: DO NOT EDIT, AUTO-GENERATED CODE - SEE TOP FOR INSTRUCTIONS */
   __u8 bLength;
   __u8 bDescriptorType;
   __u8 bEncryptionType;
-/* WARNING: DO NOT EDIT, AUTO-GENERATED CODE - SEE TOP FOR INSTRUCTIONS */
 #define USB_ENC_TYPE_UNSECURE 0
+/* WARNING: DO NOT EDIT, AUTO-GENERATED CODE - SEE TOP FOR INSTRUCTIONS */
 #define USB_ENC_TYPE_WIRED 1
 #define USB_ENC_TYPE_CCM_1 2
 #define USB_ENC_TYPE_RSA_1 3
-/* WARNING: DO NOT EDIT, AUTO-GENERATED CODE - SEE TOP FOR INSTRUCTIONS */
   __u8 bEncryptionValue;
+/* WARNING: DO NOT EDIT, AUTO-GENERATED CODE - SEE TOP FOR INSTRUCTIONS */
   __u8 bAuthKeyIndex;
 } __attribute__((packed));
 struct usb_bos_descriptor {
-/* WARNING: DO NOT EDIT, AUTO-GENERATED CODE - SEE TOP FOR INSTRUCTIONS */
   __u8 bLength;
+/* WARNING: DO NOT EDIT, AUTO-GENERATED CODE - SEE TOP FOR INSTRUCTIONS */
   __u8 bDescriptorType;
   __le16 wTotalLength;
   __u8 bNumDeviceCaps;
-/* WARNING: DO NOT EDIT, AUTO-GENERATED CODE - SEE TOP FOR INSTRUCTIONS */
 } __attribute__((packed));
+/* WARNING: DO NOT EDIT, AUTO-GENERATED CODE - SEE TOP FOR INSTRUCTIONS */
 #define USB_DT_BOS_SIZE 5
 struct usb_dev_cap_header {
   __u8 bLength;
-/* WARNING: DO NOT EDIT, AUTO-GENERATED CODE - SEE TOP FOR INSTRUCTIONS */
   __u8 bDescriptorType;
+/* WARNING: DO NOT EDIT, AUTO-GENERATED CODE - SEE TOP FOR INSTRUCTIONS */
   __u8 bDevCapabilityType;
 } __attribute__((packed));
 #define USB_CAP_TYPE_WIRELESS_USB 1
-/* WARNING: DO NOT EDIT, AUTO-GENERATED CODE - SEE TOP FOR INSTRUCTIONS */
 struct usb_wireless_cap_descriptor {
+/* WARNING: DO NOT EDIT, AUTO-GENERATED CODE - SEE TOP FOR INSTRUCTIONS */
   __u8 bLength;
   __u8 bDescriptorType;
   __u8 bDevCapabilityType;
-/* WARNING: DO NOT EDIT, AUTO-GENERATED CODE - SEE TOP FOR INSTRUCTIONS */
   __u8 bmAttributes;
+/* WARNING: DO NOT EDIT, AUTO-GENERATED CODE - SEE TOP FOR INSTRUCTIONS */
 #define USB_WIRELESS_P2P_DRD (1 << 1)
 #define USB_WIRELESS_BEACON_MASK (3 << 2)
 #define USB_WIRELESS_BEACON_SELF (1 << 2)
-/* WARNING: DO NOT EDIT, AUTO-GENERATED CODE - SEE TOP FOR INSTRUCTIONS */
 #define USB_WIRELESS_BEACON_DIRECTED (2 << 2)
+/* WARNING: DO NOT EDIT, AUTO-GENERATED CODE - SEE TOP FOR INSTRUCTIONS */
 #define USB_WIRELESS_BEACON_NONE (3 << 2)
   __le16 wPHYRates;
 #define USB_WIRELESS_PHY_53 (1 << 0)
-/* WARNING: DO NOT EDIT, AUTO-GENERATED CODE - SEE TOP FOR INSTRUCTIONS */
 #define USB_WIRELESS_PHY_80 (1 << 1)
+/* WARNING: DO NOT EDIT, AUTO-GENERATED CODE - SEE TOP FOR INSTRUCTIONS */
 #define USB_WIRELESS_PHY_107 (1 << 2)
 #define USB_WIRELESS_PHY_160 (1 << 3)
 #define USB_WIRELESS_PHY_200 (1 << 4)
-/* WARNING: DO NOT EDIT, AUTO-GENERATED CODE - SEE TOP FOR INSTRUCTIONS */
 #define USB_WIRELESS_PHY_320 (1 << 5)
+/* WARNING: DO NOT EDIT, AUTO-GENERATED CODE - SEE TOP FOR INSTRUCTIONS */
 #define USB_WIRELESS_PHY_400 (1 << 6)
 #define USB_WIRELESS_PHY_480 (1 << 7)
   __u8 bmTFITXPowerInfo;
-/* WARNING: DO NOT EDIT, AUTO-GENERATED CODE - SEE TOP FOR INSTRUCTIONS */
   __u8 bmFFITXPowerInfo;
+/* WARNING: DO NOT EDIT, AUTO-GENERATED CODE - SEE TOP FOR INSTRUCTIONS */
   __le16 bmBandGroup;
   __u8 bReserved;
 } __attribute__((packed));
-/* WARNING: DO NOT EDIT, AUTO-GENERATED CODE - SEE TOP FOR INSTRUCTIONS */
 #define USB_CAP_TYPE_EXT 2
+/* WARNING: DO NOT EDIT, AUTO-GENERATED CODE - SEE TOP FOR INSTRUCTIONS */
 struct usb_ext_cap_descriptor {
   __u8 bLength;
   __u8 bDescriptorType;
-/* WARNING: DO NOT EDIT, AUTO-GENERATED CODE - SEE TOP FOR INSTRUCTIONS */
   __u8 bDevCapabilityType;
+/* WARNING: DO NOT EDIT, AUTO-GENERATED CODE - SEE TOP FOR INSTRUCTIONS */
   __le32 bmAttributes;
 #define USB_LPM_SUPPORT (1 << 1)
 #define USB_BESL_SUPPORT (1 << 2)
-/* WARNING: DO NOT EDIT, AUTO-GENERATED CODE - SEE TOP FOR INSTRUCTIONS */
 #define USB_BESL_BASELINE_VALID (1 << 3)
+/* WARNING: DO NOT EDIT, AUTO-GENERATED CODE - SEE TOP FOR INSTRUCTIONS */
 #define USB_BESL_DEEP_VALID (1 << 4)
 #define USB_GET_BESL_BASELINE(p) (((p) & (0xf << 8)) >> 8)
 #define USB_GET_BESL_DEEP(p) (((p) & (0xf << 12)) >> 12)
-/* WARNING: DO NOT EDIT, AUTO-GENERATED CODE - SEE TOP FOR INSTRUCTIONS */
 } __attribute__((packed));
+/* WARNING: DO NOT EDIT, AUTO-GENERATED CODE - SEE TOP FOR INSTRUCTIONS */
 #define USB_DT_USB_EXT_CAP_SIZE 7
 #define USB_SS_CAP_TYPE 3
 struct usb_ss_cap_descriptor {
-/* WARNING: DO NOT EDIT, AUTO-GENERATED CODE - SEE TOP FOR INSTRUCTIONS */
   __u8 bLength;
+/* WARNING: DO NOT EDIT, AUTO-GENERATED CODE - SEE TOP FOR INSTRUCTIONS */
   __u8 bDescriptorType;
   __u8 bDevCapabilityType;
   __u8 bmAttributes;
-/* WARNING: DO NOT EDIT, AUTO-GENERATED CODE - SEE TOP FOR INSTRUCTIONS */
 #define USB_LTM_SUPPORT (1 << 1)
+/* WARNING: DO NOT EDIT, AUTO-GENERATED CODE - SEE TOP FOR INSTRUCTIONS */
   __le16 wSpeedSupported;
 #define USB_LOW_SPEED_OPERATION (1)
 #define USB_FULL_SPEED_OPERATION (1 << 1)
-/* WARNING: DO NOT EDIT, AUTO-GENERATED CODE - SEE TOP FOR INSTRUCTIONS */
 #define USB_HIGH_SPEED_OPERATION (1 << 2)
+/* WARNING: DO NOT EDIT, AUTO-GENERATED CODE - SEE TOP FOR INSTRUCTIONS */
 #define USB_5GBPS_OPERATION (1 << 3)
   __u8 bFunctionalitySupport;
   __u8 bU1devExitLat;
-/* WARNING: DO NOT EDIT, AUTO-GENERATED CODE - SEE TOP FOR INSTRUCTIONS */
   __le16 bU2DevExitLat;
+/* WARNING: DO NOT EDIT, AUTO-GENERATED CODE - SEE TOP FOR INSTRUCTIONS */
 } __attribute__((packed));
 #define USB_DT_USB_SS_CAP_SIZE 10
 #define CONTAINER_ID_TYPE 4
-/* WARNING: DO NOT EDIT, AUTO-GENERATED CODE - SEE TOP FOR INSTRUCTIONS */
 struct usb_ss_container_id_descriptor {
+/* WARNING: DO NOT EDIT, AUTO-GENERATED CODE - SEE TOP FOR INSTRUCTIONS */
+  __u8 bLength;
+  __u8 bDescriptorType;
+  __u8 bDevCapabilityType;
+  __u8 bReserved;
+/* WARNING: DO NOT EDIT, AUTO-GENERATED CODE - SEE TOP FOR INSTRUCTIONS */
+  __u8 ContainerID[16];
+} __attribute__((packed));
+#define USB_DT_USB_SS_CONTN_ID_SIZE 20
+#define USB_SSP_CAP_TYPE 0xa
+/* WARNING: DO NOT EDIT, AUTO-GENERATED CODE - SEE TOP FOR INSTRUCTIONS */
+struct usb_ssp_cap_descriptor {
   __u8 bLength;
   __u8 bDescriptorType;
   __u8 bDevCapabilityType;
 /* WARNING: DO NOT EDIT, AUTO-GENERATED CODE - SEE TOP FOR INSTRUCTIONS */
   __u8 bReserved;
-  __u8 ContainerID[16];
-} __attribute__((packed));
-#define USB_DT_USB_SS_CONTN_ID_SIZE 20
+  __le32 bmAttributes;
+#define USB_SSP_SUBLINK_SPEED_ATTRIBS (0x1f << 0)
+#define USB_SSP_SUBLINK_SPEED_IDS (0xf << 5)
 /* WARNING: DO NOT EDIT, AUTO-GENERATED CODE - SEE TOP FOR INSTRUCTIONS */
+  __u16 wFunctionalitySupport;
+#define USB_SSP_MIN_SUBLINK_SPEED_ATTRIBUTE_ID (0xf)
+#define USB_SSP_MIN_RX_LANE_COUNT (0xf << 8)
+#define USB_SSP_MIN_TX_LANE_COUNT (0xf << 12)
+/* WARNING: DO NOT EDIT, AUTO-GENERATED CODE - SEE TOP FOR INSTRUCTIONS */
+  __le16 wReserved;
+  __le32 bmSublinkSpeedAttr[1];
+#define USB_SSP_SUBLINK_SPEED_SSID (0xf)
+#define USB_SSP_SUBLINK_SPEED_LSE (0x3 << 4)
+/* WARNING: DO NOT EDIT, AUTO-GENERATED CODE - SEE TOP FOR INSTRUCTIONS */
+#define USB_SSP_SUBLINK_SPEED_ST (0x3 << 6)
+#define USB_SSP_SUBLINK_SPEED_RSVD (0x3f << 8)
+#define USB_SSP_SUBLINK_SPEED_LP (0x3 << 14)
+#define USB_SSP_SUBLINK_SPEED_LSM (0xff << 16)
+/* WARNING: DO NOT EDIT, AUTO-GENERATED CODE - SEE TOP FOR INSTRUCTIONS */
+} __attribute__((packed));
 struct usb_wireless_ep_comp_descriptor {
   __u8 bLength;
   __u8 bDescriptorType;
-  __u8 bMaxBurst;
 /* WARNING: DO NOT EDIT, AUTO-GENERATED CODE - SEE TOP FOR INSTRUCTIONS */
+  __u8 bMaxBurst;
   __u8 bMaxSequence;
   __le16 wMaxStreamDelay;
   __le16 wOverTheAirPacketSize;
-  __u8 bOverTheAirInterval;
 /* WARNING: DO NOT EDIT, AUTO-GENERATED CODE - SEE TOP FOR INSTRUCTIONS */
+  __u8 bOverTheAirInterval;
   __u8 bmCompAttributes;
 #define USB_ENDPOINT_SWITCH_MASK 0x03
 #define USB_ENDPOINT_SWITCH_NO 0
-#define USB_ENDPOINT_SWITCH_SWITCH 1
 /* WARNING: DO NOT EDIT, AUTO-GENERATED CODE - SEE TOP FOR INSTRUCTIONS */
+#define USB_ENDPOINT_SWITCH_SWITCH 1
 #define USB_ENDPOINT_SWITCH_SCALE 2
 } __attribute__((packed));
 struct usb_handshake {
-  __u8 bMessageNumber;
 /* WARNING: DO NOT EDIT, AUTO-GENERATED CODE - SEE TOP FOR INSTRUCTIONS */
+  __u8 bMessageNumber;
   __u8 bStatus;
   __u8 tTKID[3];
   __u8 bReserved;
-  __u8 CDID[16];
 /* WARNING: DO NOT EDIT, AUTO-GENERATED CODE - SEE TOP FOR INSTRUCTIONS */
+  __u8 CDID[16];
   __u8 nonce[16];
   __u8 MIC[8];
 } __attribute__((packed));
-struct usb_connection_context {
 /* WARNING: DO NOT EDIT, AUTO-GENERATED CODE - SEE TOP FOR INSTRUCTIONS */
+struct usb_connection_context {
   __u8 CHID[16];
   __u8 CDID[16];
   __u8 CK[16];
-} __attribute__((packed));
 /* WARNING: DO NOT EDIT, AUTO-GENERATED CODE - SEE TOP FOR INSTRUCTIONS */
+} __attribute__((packed));
 enum usb_device_speed {
   USB_SPEED_UNKNOWN = 0,
   USB_SPEED_LOW,
-  USB_SPEED_FULL,
 /* WARNING: DO NOT EDIT, AUTO-GENERATED CODE - SEE TOP FOR INSTRUCTIONS */
+  USB_SPEED_FULL,
   USB_SPEED_HIGH,
   USB_SPEED_WIRELESS,
   USB_SPEED_SUPER,
-};
 /* WARNING: DO NOT EDIT, AUTO-GENERATED CODE - SEE TOP FOR INSTRUCTIONS */
+};
 enum usb_device_state {
   USB_STATE_NOTATTACHED = 0,
   USB_STATE_ATTACHED,
-  USB_STATE_POWERED,
 /* WARNING: DO NOT EDIT, AUTO-GENERATED CODE - SEE TOP FOR INSTRUCTIONS */
+  USB_STATE_POWERED,
   USB_STATE_RECONNECTING,
   USB_STATE_UNAUTHENTICATED,
   USB_STATE_DEFAULT,
-  USB_STATE_ADDRESS,
 /* WARNING: DO NOT EDIT, AUTO-GENERATED CODE - SEE TOP FOR INSTRUCTIONS */
+  USB_STATE_ADDRESS,
   USB_STATE_CONFIGURED,
   USB_STATE_SUSPENDED
 };
-enum usb3_link_state {
 /* WARNING: DO NOT EDIT, AUTO-GENERATED CODE - SEE TOP FOR INSTRUCTIONS */
+enum usb3_link_state {
   USB3_LPM_U0 = 0,
   USB3_LPM_U1,
   USB3_LPM_U2,
-  USB3_LPM_U3
 /* WARNING: DO NOT EDIT, AUTO-GENERATED CODE - SEE TOP FOR INSTRUCTIONS */
+  USB3_LPM_U3
 };
 #define USB3_LPM_DISABLED 0x0
 #define USB3_LPM_U1_MAX_TIMEOUT 0x7F
-#define USB3_LPM_U2_MAX_TIMEOUT 0xFE
 /* WARNING: DO NOT EDIT, AUTO-GENERATED CODE - SEE TOP FOR INSTRUCTIONS */
+#define USB3_LPM_U2_MAX_TIMEOUT 0xFE
 #define USB3_LPM_DEVICE_INITIATED 0xFF
 struct usb_set_sel_req {
   __u8 u1_sel;
-  __u8 u1_pel;
 /* WARNING: DO NOT EDIT, AUTO-GENERATED CODE - SEE TOP FOR INSTRUCTIONS */
+  __u8 u1_pel;
   __le16 u2_sel;
   __le16 u2_pel;
 } __attribute__((packed));
-#define USB3_LPM_MAX_U1_SEL_PEL 0xFF
 /* WARNING: DO NOT EDIT, AUTO-GENERATED CODE - SEE TOP FOR INSTRUCTIONS */
+#define USB3_LPM_MAX_U1_SEL_PEL 0xFF
 #define USB3_LPM_MAX_U2_SEL_PEL 0xFFFF
 #define USB_SELF_POWER_VBUS_MAX_DRAW 100
 #endif
+/* WARNING: DO NOT EDIT, AUTO-GENERATED CODE - SEE TOP FOR INSTRUCTIONS */
diff --git a/libc/kernel/uapi/linux/usb/functionfs.h b/libc/kernel/uapi/linux/usb/functionfs.h
index f3f4da4..4d09720 100644
--- a/libc/kernel/uapi/linux/usb/functionfs.h
+++ b/libc/kernel/uapi/linux/usb/functionfs.h
@@ -36,95 +36,96 @@
   FUNCTIONFS_HAS_MS_OS_DESC = 8,
   FUNCTIONFS_VIRTUAL_ADDR = 16,
 /* WARNING: DO NOT EDIT, AUTO-GENERATED CODE - SEE TOP FOR INSTRUCTIONS */
+  FUNCTIONFS_EVENTFD = 32,
 };
 struct usb_endpoint_descriptor_no_audio {
   __u8 bLength;
-  __u8 bDescriptorType;
 /* WARNING: DO NOT EDIT, AUTO-GENERATED CODE - SEE TOP FOR INSTRUCTIONS */
+  __u8 bDescriptorType;
   __u8 bEndpointAddress;
   __u8 bmAttributes;
   __le16 wMaxPacketSize;
-  __u8 bInterval;
 /* WARNING: DO NOT EDIT, AUTO-GENERATED CODE - SEE TOP FOR INSTRUCTIONS */
+  __u8 bInterval;
 } __attribute__((packed));
 struct usb_functionfs_descs_head_v2 {
   __le32 magic;
-  __le32 length;
 /* WARNING: DO NOT EDIT, AUTO-GENERATED CODE - SEE TOP FOR INSTRUCTIONS */
+  __le32 length;
   __le32 flags;
 } __attribute__((packed));
 struct usb_functionfs_descs_head {
-  __le32 magic;
 /* WARNING: DO NOT EDIT, AUTO-GENERATED CODE - SEE TOP FOR INSTRUCTIONS */
+  __le32 magic;
   __le32 length;
   __le32 fs_count;
   __le32 hs_count;
-} __attribute__((packed, deprecated));
 /* WARNING: DO NOT EDIT, AUTO-GENERATED CODE - SEE TOP FOR INSTRUCTIONS */
+} __attribute__((packed, deprecated));
 struct usb_os_desc_header {
   __u8 interface;
   __le32 dwLength;
-  __le16 bcdVersion;
 /* WARNING: DO NOT EDIT, AUTO-GENERATED CODE - SEE TOP FOR INSTRUCTIONS */
+  __le16 bcdVersion;
   __le16 wIndex;
   union {
     struct {
-      __u8 bCount;
 /* WARNING: DO NOT EDIT, AUTO-GENERATED CODE - SEE TOP FOR INSTRUCTIONS */
+      __u8 bCount;
       __u8 Reserved;
     };
     __le16 wCount;
-  };
 /* WARNING: DO NOT EDIT, AUTO-GENERATED CODE - SEE TOP FOR INSTRUCTIONS */
+  };
 } __attribute__((packed));
 struct usb_ext_compat_desc {
   __u8 bFirstInterfaceNumber;
-  __u8 Reserved1;
 /* WARNING: DO NOT EDIT, AUTO-GENERATED CODE - SEE TOP FOR INSTRUCTIONS */
+  __u8 Reserved1;
   __u8 CompatibleID[8];
   __u8 SubCompatibleID[8];
   __u8 Reserved2[6];
-};
 /* WARNING: DO NOT EDIT, AUTO-GENERATED CODE - SEE TOP FOR INSTRUCTIONS */
+};
 struct usb_ext_prop_desc {
   __le32 dwSize;
   __le32 dwPropertyDataType;
-  __le16 wPropertyNameLength;
 /* WARNING: DO NOT EDIT, AUTO-GENERATED CODE - SEE TOP FOR INSTRUCTIONS */
+  __le16 wPropertyNameLength;
 } __attribute__((packed));
 struct usb_functionfs_strings_head {
   __le32 magic;
-  __le32 length;
 /* WARNING: DO NOT EDIT, AUTO-GENERATED CODE - SEE TOP FOR INSTRUCTIONS */
+  __le32 length;
   __le32 str_count;
   __le32 lang_count;
 } __attribute__((packed));
-enum usb_functionfs_event_type {
 /* WARNING: DO NOT EDIT, AUTO-GENERATED CODE - SEE TOP FOR INSTRUCTIONS */
+enum usb_functionfs_event_type {
   FUNCTIONFS_BIND,
   FUNCTIONFS_UNBIND,
   FUNCTIONFS_ENABLE,
-  FUNCTIONFS_DISABLE,
 /* WARNING: DO NOT EDIT, AUTO-GENERATED CODE - SEE TOP FOR INSTRUCTIONS */
+  FUNCTIONFS_DISABLE,
   FUNCTIONFS_SETUP,
   FUNCTIONFS_SUSPEND,
   FUNCTIONFS_RESUME
-};
 /* WARNING: DO NOT EDIT, AUTO-GENERATED CODE - SEE TOP FOR INSTRUCTIONS */
+};
 struct usb_functionfs_event {
   union {
     struct usb_ctrlrequest setup;
-  } __attribute__((packed)) u;
 /* WARNING: DO NOT EDIT, AUTO-GENERATED CODE - SEE TOP FOR INSTRUCTIONS */
+  } __attribute__((packed)) u;
   __u8 type;
   __u8 _pad[3];
 } __attribute__((packed));
-#define FUNCTIONFS_FIFO_STATUS _IO('g', 1)
 /* WARNING: DO NOT EDIT, AUTO-GENERATED CODE - SEE TOP FOR INSTRUCTIONS */
+#define FUNCTIONFS_FIFO_STATUS _IO('g', 1)
 #define FUNCTIONFS_FIFO_FLUSH _IO('g', 2)
 #define FUNCTIONFS_CLEAR_HALT _IO('g', 3)
 #define FUNCTIONFS_INTERFACE_REVMAP _IO('g', 128)
-#define FUNCTIONFS_ENDPOINT_REVMAP _IO('g', 129)
 /* WARNING: DO NOT EDIT, AUTO-GENERATED CODE - SEE TOP FOR INSTRUCTIONS */
+#define FUNCTIONFS_ENDPOINT_REVMAP _IO('g', 129)
 #define FUNCTIONFS_ENDPOINT_DESC _IOR('g', 130, struct usb_endpoint_descriptor)
 #endif
diff --git a/libc/kernel/uapi/linux/usbdevice_fs.h b/libc/kernel/uapi/linux/usbdevice_fs.h
index 0aa2062..285b003 100644
--- a/libc/kernel/uapi/linux/usbdevice_fs.h
+++ b/libc/kernel/uapi/linux/usbdevice_fs.h
@@ -118,61 +118,62 @@
 /* WARNING: DO NOT EDIT, AUTO-GENERATED CODE - SEE TOP FOR INSTRUCTIONS */
 #define USBDEVFS_CAP_NO_PACKET_SIZE_LIM 0x04
 #define USBDEVFS_CAP_BULK_SCATTER_GATHER 0x08
+#define USBDEVFS_CAP_REAP_AFTER_DISCONNECT 0x10
 #define USBDEVFS_DISCONNECT_CLAIM_IF_DRIVER 0x01
-#define USBDEVFS_DISCONNECT_CLAIM_EXCEPT_DRIVER 0x02
 /* WARNING: DO NOT EDIT, AUTO-GENERATED CODE - SEE TOP FOR INSTRUCTIONS */
+#define USBDEVFS_DISCONNECT_CLAIM_EXCEPT_DRIVER 0x02
 struct usbdevfs_disconnect_claim {
   unsigned int interface;
   unsigned int flags;
-  char driver[USBDEVFS_MAXDRIVERNAME + 1];
 /* WARNING: DO NOT EDIT, AUTO-GENERATED CODE - SEE TOP FOR INSTRUCTIONS */
+  char driver[USBDEVFS_MAXDRIVERNAME + 1];
 };
 struct usbdevfs_streams {
   unsigned int num_streams;
-  unsigned int num_eps;
 /* WARNING: DO NOT EDIT, AUTO-GENERATED CODE - SEE TOP FOR INSTRUCTIONS */
+  unsigned int num_eps;
   unsigned char eps[0];
 };
 #define USBDEVFS_CONTROL _IOWR('U', 0, struct usbdevfs_ctrltransfer)
-#define USBDEVFS_CONTROL32 _IOWR('U', 0, struct usbdevfs_ctrltransfer32)
 /* WARNING: DO NOT EDIT, AUTO-GENERATED CODE - SEE TOP FOR INSTRUCTIONS */
+#define USBDEVFS_CONTROL32 _IOWR('U', 0, struct usbdevfs_ctrltransfer32)
 #define USBDEVFS_BULK _IOWR('U', 2, struct usbdevfs_bulktransfer)
 #define USBDEVFS_BULK32 _IOWR('U', 2, struct usbdevfs_bulktransfer32)
 #define USBDEVFS_RESETEP _IOR('U', 3, unsigned int)
-#define USBDEVFS_SETINTERFACE _IOR('U', 4, struct usbdevfs_setinterface)
 /* WARNING: DO NOT EDIT, AUTO-GENERATED CODE - SEE TOP FOR INSTRUCTIONS */
+#define USBDEVFS_SETINTERFACE _IOR('U', 4, struct usbdevfs_setinterface)
 #define USBDEVFS_SETCONFIGURATION _IOR('U', 5, unsigned int)
 #define USBDEVFS_GETDRIVER _IOW('U', 8, struct usbdevfs_getdriver)
 #define USBDEVFS_SUBMITURB _IOR('U', 10, struct usbdevfs_urb)
-#define USBDEVFS_SUBMITURB32 _IOR('U', 10, struct usbdevfs_urb32)
 /* WARNING: DO NOT EDIT, AUTO-GENERATED CODE - SEE TOP FOR INSTRUCTIONS */
+#define USBDEVFS_SUBMITURB32 _IOR('U', 10, struct usbdevfs_urb32)
 #define USBDEVFS_DISCARDURB _IO('U', 11)
 #define USBDEVFS_REAPURB _IOW('U', 12, void *)
 #define USBDEVFS_REAPURB32 _IOW('U', 12, __u32)
-#define USBDEVFS_REAPURBNDELAY _IOW('U', 13, void *)
 /* WARNING: DO NOT EDIT, AUTO-GENERATED CODE - SEE TOP FOR INSTRUCTIONS */
+#define USBDEVFS_REAPURBNDELAY _IOW('U', 13, void *)
 #define USBDEVFS_REAPURBNDELAY32 _IOW('U', 13, __u32)
 #define USBDEVFS_DISCSIGNAL _IOR('U', 14, struct usbdevfs_disconnectsignal)
 #define USBDEVFS_DISCSIGNAL32 _IOR('U', 14, struct usbdevfs_disconnectsignal32)
-#define USBDEVFS_CLAIMINTERFACE _IOR('U', 15, unsigned int)
 /* WARNING: DO NOT EDIT, AUTO-GENERATED CODE - SEE TOP FOR INSTRUCTIONS */
+#define USBDEVFS_CLAIMINTERFACE _IOR('U', 15, unsigned int)
 #define USBDEVFS_RELEASEINTERFACE _IOR('U', 16, unsigned int)
 #define USBDEVFS_CONNECTINFO _IOW('U', 17, struct usbdevfs_connectinfo)
 #define USBDEVFS_IOCTL _IOWR('U', 18, struct usbdevfs_ioctl)
-#define USBDEVFS_IOCTL32 _IOWR('U', 18, struct usbdevfs_ioctl32)
 /* WARNING: DO NOT EDIT, AUTO-GENERATED CODE - SEE TOP FOR INSTRUCTIONS */
+#define USBDEVFS_IOCTL32 _IOWR('U', 18, struct usbdevfs_ioctl32)
 #define USBDEVFS_HUB_PORTINFO _IOR('U', 19, struct usbdevfs_hub_portinfo)
 #define USBDEVFS_RESET _IO('U', 20)
 #define USBDEVFS_CLEAR_HALT _IOR('U', 21, unsigned int)
-#define USBDEVFS_DISCONNECT _IO('U', 22)
 /* WARNING: DO NOT EDIT, AUTO-GENERATED CODE - SEE TOP FOR INSTRUCTIONS */
+#define USBDEVFS_DISCONNECT _IO('U', 22)
 #define USBDEVFS_CONNECT _IO('U', 23)
 #define USBDEVFS_CLAIM_PORT _IOR('U', 24, unsigned int)
 #define USBDEVFS_RELEASE_PORT _IOR('U', 25, unsigned int)
-#define USBDEVFS_GET_CAPABILITIES _IOR('U', 26, __u32)
 /* WARNING: DO NOT EDIT, AUTO-GENERATED CODE - SEE TOP FOR INSTRUCTIONS */
+#define USBDEVFS_GET_CAPABILITIES _IOR('U', 26, __u32)
 #define USBDEVFS_DISCONNECT_CLAIM _IOR('U', 27, struct usbdevfs_disconnect_claim)
 #define USBDEVFS_ALLOC_STREAMS _IOR('U', 28, struct usbdevfs_streams)
 #define USBDEVFS_FREE_STREAMS _IOR('U', 29, struct usbdevfs_streams)
-#endif
 /* WARNING: DO NOT EDIT, AUTO-GENERATED CODE - SEE TOP FOR INSTRUCTIONS */
+#endif
diff --git a/libc/kernel/uapi/linux/userfaultfd.h b/libc/kernel/uapi/linux/userfaultfd.h
new file mode 100644
index 0000000..e4e0998
--- /dev/null
+++ b/libc/kernel/uapi/linux/userfaultfd.h
@@ -0,0 +1,106 @@
+/****************************************************************************
+ ****************************************************************************
+ ***
+ ***   This header was automatically generated from a Linux kernel header
+ ***   of the same name, to make information necessary for userspace to
+ ***   call into the kernel available to libc.  It contains only constants,
+ ***   structures, and macros generated from the original header, and thus,
+ ***   contains no copyrightable information.
+ ***
+ ***   To edit the content of this header, modify the corresponding
+ ***   source file (e.g. under external/kernel-headers/original/) then
+ ***   run bionic/libc/kernel/tools/update_all.py
+ ***
+ ***   Any manual change here will be lost the next time this script will
+ ***   be run. You've been warned!
+ ***
+ ****************************************************************************
+ ****************************************************************************/
+#ifndef _LINUX_USERFAULTFD_H
+#define _LINUX_USERFAULTFD_H
+#include <linux/types.h>
+#define UFFD_API ((__u64) 0xAA)
+/* WARNING: DO NOT EDIT, AUTO-GENERATED CODE - SEE TOP FOR INSTRUCTIONS */
+#define UFFD_API_FEATURES (0)
+#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 _UFFDIO_REGISTER (0x00)
+/* WARNING: DO NOT EDIT, AUTO-GENERATED CODE - SEE TOP FOR INSTRUCTIONS */
+#define _UFFDIO_UNREGISTER (0x01)
+#define _UFFDIO_WAKE (0x02)
+#define _UFFDIO_COPY (0x03)
+#define _UFFDIO_ZEROPAGE (0x04)
+/* WARNING: DO NOT EDIT, AUTO-GENERATED CODE - SEE TOP FOR INSTRUCTIONS */
+#define _UFFDIO_API (0x3F)
+#define UFFDIO 0xAA
+#define UFFDIO_API _IOWR(UFFDIO, _UFFDIO_API, struct uffdio_api)
+#define UFFDIO_REGISTER _IOWR(UFFDIO, _UFFDIO_REGISTER, struct uffdio_register)
+/* WARNING: DO NOT EDIT, AUTO-GENERATED CODE - SEE TOP FOR INSTRUCTIONS */
+#define UFFDIO_UNREGISTER _IOR(UFFDIO, _UFFDIO_UNREGISTER, struct uffdio_range)
+#define UFFDIO_WAKE _IOR(UFFDIO, _UFFDIO_WAKE, struct uffdio_range)
+#define UFFDIO_COPY _IOWR(UFFDIO, _UFFDIO_COPY, struct uffdio_copy)
+#define UFFDIO_ZEROPAGE _IOWR(UFFDIO, _UFFDIO_ZEROPAGE, struct uffdio_zeropage)
+/* WARNING: DO NOT EDIT, AUTO-GENERATED CODE - SEE TOP FOR INSTRUCTIONS */
+struct uffd_msg {
+  __u8 event;
+  __u8 reserved1;
+  __u16 reserved2;
+/* WARNING: DO NOT EDIT, AUTO-GENERATED CODE - SEE TOP FOR INSTRUCTIONS */
+  __u32 reserved3;
+  union {
+    struct {
+      __u64 flags;
+/* WARNING: DO NOT EDIT, AUTO-GENERATED CODE - SEE TOP FOR INSTRUCTIONS */
+      __u64 address;
+    } pagefault;
+    struct {
+      __u64 reserved1;
+/* WARNING: DO NOT EDIT, AUTO-GENERATED CODE - SEE TOP FOR INSTRUCTIONS */
+      __u64 reserved2;
+      __u64 reserved3;
+    } reserved;
+  } arg;
+/* WARNING: DO NOT EDIT, AUTO-GENERATED CODE - SEE TOP FOR INSTRUCTIONS */
+} __packed;
+#define UFFD_EVENT_PAGEFAULT 0x12
+#define UFFD_PAGEFAULT_FLAG_WRITE (1 << 0)
+#define UFFD_PAGEFAULT_FLAG_WP (1 << 1)
+/* WARNING: DO NOT EDIT, AUTO-GENERATED CODE - SEE TOP FOR INSTRUCTIONS */
+struct uffdio_api {
+  __u64 api;
+  __u64 features;
+  __u64 ioctls;
+/* WARNING: DO NOT EDIT, AUTO-GENERATED CODE - SEE TOP FOR INSTRUCTIONS */
+};
+struct uffdio_range {
+  __u64 start;
+  __u64 len;
+/* WARNING: DO NOT EDIT, AUTO-GENERATED CODE - SEE TOP FOR INSTRUCTIONS */
+};
+struct uffdio_register {
+  struct uffdio_range range;
+#define UFFDIO_REGISTER_MODE_MISSING ((__u64) 1 << 0)
+/* WARNING: DO NOT EDIT, AUTO-GENERATED CODE - SEE TOP FOR INSTRUCTIONS */
+#define UFFDIO_REGISTER_MODE_WP ((__u64) 1 << 1)
+  __u64 mode;
+  __u64 ioctls;
+};
+/* WARNING: DO NOT EDIT, AUTO-GENERATED CODE - SEE TOP FOR INSTRUCTIONS */
+struct uffdio_copy {
+  __u64 dst;
+  __u64 src;
+  __u64 len;
+/* WARNING: DO NOT EDIT, AUTO-GENERATED CODE - SEE TOP FOR INSTRUCTIONS */
+#define UFFDIO_COPY_MODE_DONTWAKE ((__u64) 1 << 0)
+  __u64 mode;
+  __s64 copy;
+};
+/* WARNING: DO NOT EDIT, AUTO-GENERATED CODE - SEE TOP FOR INSTRUCTIONS */
+struct uffdio_zeropage {
+  struct uffdio_range range;
+#define UFFDIO_ZEROPAGE_MODE_DONTWAKE ((__u64) 1 << 0)
+  __u64 mode;
+/* WARNING: DO NOT EDIT, AUTO-GENERATED CODE - SEE TOP FOR INSTRUCTIONS */
+  __s64 zeropage;
+};
+#endif
diff --git a/libc/kernel/uapi/linux/userio.h b/libc/kernel/uapi/linux/userio.h
new file mode 100644
index 0000000..81bed08
--- /dev/null
+++ b/libc/kernel/uapi/linux/userio.h
@@ -0,0 +1,34 @@
+/****************************************************************************
+ ****************************************************************************
+ ***
+ ***   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 _USERIO_H
+#define _USERIO_H
+#include <linux/types.h>
+enum userio_cmd_type {
+/* WARNING: DO NOT EDIT, AUTO-GENERATED CODE - SEE TOP FOR INSTRUCTIONS */
+  USERIO_CMD_REGISTER = 0,
+  USERIO_CMD_SET_PORT_TYPE = 1,
+  USERIO_CMD_SEND_INTERRUPT = 2
+};
+/* WARNING: DO NOT EDIT, AUTO-GENERATED CODE - SEE TOP FOR INSTRUCTIONS */
+struct userio_cmd {
+  __u8 type;
+  __u8 data;
+} __attribute__((__packed__));
+/* WARNING: DO NOT EDIT, AUTO-GENERATED CODE - SEE TOP FOR INSTRUCTIONS */
+#endif
diff --git a/libc/kernel/uapi/linux/v4l2-common.h b/libc/kernel/uapi/linux/v4l2-common.h
index a379a7e..1ed1770 100644
--- a/libc/kernel/uapi/linux/v4l2-common.h
+++ b/libc/kernel/uapi/linux/v4l2-common.h
@@ -23,33 +23,34 @@
 /* WARNING: DO NOT EDIT, AUTO-GENERATED CODE - SEE TOP FOR INSTRUCTIONS */
 #define V4L2_SEL_TGT_CROP_DEFAULT 0x0001
 #define V4L2_SEL_TGT_CROP_BOUNDS 0x0002
+#define V4L2_SEL_TGT_NATIVE_SIZE 0x0003
 #define V4L2_SEL_TGT_COMPOSE 0x0100
-#define V4L2_SEL_TGT_COMPOSE_DEFAULT 0x0101
 /* WARNING: DO NOT EDIT, AUTO-GENERATED CODE - SEE TOP FOR INSTRUCTIONS */
+#define V4L2_SEL_TGT_COMPOSE_DEFAULT 0x0101
 #define V4L2_SEL_TGT_COMPOSE_BOUNDS 0x0102
 #define V4L2_SEL_TGT_COMPOSE_PADDED 0x0103
 #define V4L2_SEL_TGT_CROP_ACTIVE V4L2_SEL_TGT_CROP
-#define V4L2_SEL_TGT_COMPOSE_ACTIVE V4L2_SEL_TGT_COMPOSE
 /* WARNING: DO NOT EDIT, AUTO-GENERATED CODE - SEE TOP FOR INSTRUCTIONS */
+#define V4L2_SEL_TGT_COMPOSE_ACTIVE V4L2_SEL_TGT_COMPOSE
 #define V4L2_SUBDEV_SEL_TGT_CROP_ACTUAL V4L2_SEL_TGT_CROP
 #define V4L2_SUBDEV_SEL_TGT_COMPOSE_ACTUAL V4L2_SEL_TGT_COMPOSE
 #define V4L2_SUBDEV_SEL_TGT_CROP_BOUNDS V4L2_SEL_TGT_CROP_BOUNDS
-#define V4L2_SUBDEV_SEL_TGT_COMPOSE_BOUNDS V4L2_SEL_TGT_COMPOSE_BOUNDS
 /* WARNING: DO NOT EDIT, AUTO-GENERATED CODE - SEE TOP FOR INSTRUCTIONS */
+#define V4L2_SUBDEV_SEL_TGT_COMPOSE_BOUNDS V4L2_SEL_TGT_COMPOSE_BOUNDS
 #define V4L2_SEL_FLAG_GE (1 << 0)
 #define V4L2_SEL_FLAG_LE (1 << 1)
 #define V4L2_SEL_FLAG_KEEP_CONFIG (1 << 2)
-#define V4L2_SUBDEV_SEL_FLAG_SIZE_GE V4L2_SEL_FLAG_GE
 /* WARNING: DO NOT EDIT, AUTO-GENERATED CODE - SEE TOP FOR INSTRUCTIONS */
+#define V4L2_SUBDEV_SEL_FLAG_SIZE_GE V4L2_SEL_FLAG_GE
 #define V4L2_SUBDEV_SEL_FLAG_SIZE_LE V4L2_SEL_FLAG_LE
 #define V4L2_SUBDEV_SEL_FLAG_KEEP_CONFIG V4L2_SEL_FLAG_KEEP_CONFIG
 struct v4l2_edid {
-  __u32 pad;
 /* WARNING: DO NOT EDIT, AUTO-GENERATED CODE - SEE TOP FOR INSTRUCTIONS */
+  __u32 pad;
   __u32 start_block;
   __u32 blocks;
   __u32 reserved[5];
-  __u8 * edid;
 /* WARNING: DO NOT EDIT, AUTO-GENERATED CODE - SEE TOP FOR INSTRUCTIONS */
+  __u8 * edid;
 };
 #endif
diff --git a/libc/kernel/uapi/linux/v4l2-controls.h b/libc/kernel/uapi/linux/v4l2-controls.h
index 024aa4d..8267d37 100644
--- a/libc/kernel/uapi/linux/v4l2-controls.h
+++ b/libc/kernel/uapi/linux/v4l2-controls.h
@@ -127,868 +127,872 @@
 #define V4L2_CID_USER_TI_VPE_BASE (V4L2_CID_USER_BASE + 0x1050)
 /* WARNING: DO NOT EDIT, AUTO-GENERATED CODE - SEE TOP FOR INSTRUCTIONS */
 #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_MPEG_BASE (V4L2_CTRL_CLASS_MPEG | 0x900)
+/* WARNING: DO NOT EDIT, AUTO-GENERATED CODE - SEE TOP FOR INSTRUCTIONS */
 #define V4L2_CID_MPEG_CLASS (V4L2_CTRL_CLASS_MPEG | 1)
 #define V4L2_CID_MPEG_STREAM_TYPE (V4L2_CID_MPEG_BASE + 0)
-/* WARNING: DO NOT EDIT, AUTO-GENERATED CODE - SEE TOP FOR INSTRUCTIONS */
 enum v4l2_mpeg_stream_type {
   V4L2_MPEG_STREAM_TYPE_MPEG2_PS = 0,
+/* WARNING: DO NOT EDIT, AUTO-GENERATED CODE - SEE TOP FOR INSTRUCTIONS */
   V4L2_MPEG_STREAM_TYPE_MPEG2_TS = 1,
   V4L2_MPEG_STREAM_TYPE_MPEG1_SS = 2,
-/* WARNING: DO NOT EDIT, AUTO-GENERATED CODE - SEE TOP FOR INSTRUCTIONS */
   V4L2_MPEG_STREAM_TYPE_MPEG2_DVD = 3,
   V4L2_MPEG_STREAM_TYPE_MPEG1_VCD = 4,
+/* WARNING: DO NOT EDIT, AUTO-GENERATED CODE - SEE TOP FOR INSTRUCTIONS */
   V4L2_MPEG_STREAM_TYPE_MPEG2_SVCD = 5,
 };
-/* WARNING: DO NOT EDIT, AUTO-GENERATED CODE - SEE TOP FOR INSTRUCTIONS */
 #define V4L2_CID_MPEG_STREAM_PID_PMT (V4L2_CID_MPEG_BASE + 1)
 #define V4L2_CID_MPEG_STREAM_PID_AUDIO (V4L2_CID_MPEG_BASE + 2)
+/* WARNING: DO NOT EDIT, AUTO-GENERATED CODE - SEE TOP FOR INSTRUCTIONS */
 #define V4L2_CID_MPEG_STREAM_PID_VIDEO (V4L2_CID_MPEG_BASE + 3)
 #define V4L2_CID_MPEG_STREAM_PID_PCR (V4L2_CID_MPEG_BASE + 4)
-/* WARNING: DO NOT EDIT, AUTO-GENERATED CODE - SEE TOP FOR INSTRUCTIONS */
 #define V4L2_CID_MPEG_STREAM_PES_ID_AUDIO (V4L2_CID_MPEG_BASE + 5)
 #define V4L2_CID_MPEG_STREAM_PES_ID_VIDEO (V4L2_CID_MPEG_BASE + 6)
+/* WARNING: DO NOT EDIT, AUTO-GENERATED CODE - SEE TOP FOR INSTRUCTIONS */
 #define V4L2_CID_MPEG_STREAM_VBI_FMT (V4L2_CID_MPEG_BASE + 7)
 enum v4l2_mpeg_stream_vbi_fmt {
-/* WARNING: DO NOT EDIT, AUTO-GENERATED CODE - SEE TOP FOR INSTRUCTIONS */
   V4L2_MPEG_STREAM_VBI_FMT_NONE = 0,
   V4L2_MPEG_STREAM_VBI_FMT_IVTV = 1,
+/* WARNING: DO NOT EDIT, AUTO-GENERATED CODE - SEE TOP FOR INSTRUCTIONS */
 };
 #define V4L2_CID_MPEG_AUDIO_SAMPLING_FREQ (V4L2_CID_MPEG_BASE + 100)
-/* WARNING: DO NOT EDIT, AUTO-GENERATED CODE - SEE TOP FOR INSTRUCTIONS */
 enum v4l2_mpeg_audio_sampling_freq {
   V4L2_MPEG_AUDIO_SAMPLING_FREQ_44100 = 0,
+/* WARNING: DO NOT EDIT, AUTO-GENERATED CODE - SEE TOP FOR INSTRUCTIONS */
   V4L2_MPEG_AUDIO_SAMPLING_FREQ_48000 = 1,
   V4L2_MPEG_AUDIO_SAMPLING_FREQ_32000 = 2,
-/* WARNING: DO NOT EDIT, AUTO-GENERATED CODE - SEE TOP FOR INSTRUCTIONS */
 };
 #define V4L2_CID_MPEG_AUDIO_ENCODING (V4L2_CID_MPEG_BASE + 101)
+/* WARNING: DO NOT EDIT, AUTO-GENERATED CODE - SEE TOP FOR INSTRUCTIONS */
 enum v4l2_mpeg_audio_encoding {
   V4L2_MPEG_AUDIO_ENCODING_LAYER_1 = 0,
-/* WARNING: DO NOT EDIT, AUTO-GENERATED CODE - SEE TOP FOR INSTRUCTIONS */
   V4L2_MPEG_AUDIO_ENCODING_LAYER_2 = 1,
   V4L2_MPEG_AUDIO_ENCODING_LAYER_3 = 2,
+/* WARNING: DO NOT EDIT, AUTO-GENERATED CODE - SEE TOP FOR INSTRUCTIONS */
   V4L2_MPEG_AUDIO_ENCODING_AAC = 3,
   V4L2_MPEG_AUDIO_ENCODING_AC3 = 4,
-/* WARNING: DO NOT EDIT, AUTO-GENERATED CODE - SEE TOP FOR INSTRUCTIONS */
 };
 #define V4L2_CID_MPEG_AUDIO_L1_BITRATE (V4L2_CID_MPEG_BASE + 102)
+/* WARNING: DO NOT EDIT, AUTO-GENERATED CODE - SEE TOP FOR INSTRUCTIONS */
 enum v4l2_mpeg_audio_l1_bitrate {
   V4L2_MPEG_AUDIO_L1_BITRATE_32K = 0,
-/* WARNING: DO NOT EDIT, AUTO-GENERATED CODE - SEE TOP FOR INSTRUCTIONS */
   V4L2_MPEG_AUDIO_L1_BITRATE_64K = 1,
   V4L2_MPEG_AUDIO_L1_BITRATE_96K = 2,
+/* WARNING: DO NOT EDIT, AUTO-GENERATED CODE - SEE TOP FOR INSTRUCTIONS */
   V4L2_MPEG_AUDIO_L1_BITRATE_128K = 3,
   V4L2_MPEG_AUDIO_L1_BITRATE_160K = 4,
-/* WARNING: DO NOT EDIT, AUTO-GENERATED CODE - SEE TOP FOR INSTRUCTIONS */
   V4L2_MPEG_AUDIO_L1_BITRATE_192K = 5,
   V4L2_MPEG_AUDIO_L1_BITRATE_224K = 6,
+/* WARNING: DO NOT EDIT, AUTO-GENERATED CODE - SEE TOP FOR INSTRUCTIONS */
   V4L2_MPEG_AUDIO_L1_BITRATE_256K = 7,
   V4L2_MPEG_AUDIO_L1_BITRATE_288K = 8,
-/* WARNING: DO NOT EDIT, AUTO-GENERATED CODE - SEE TOP FOR INSTRUCTIONS */
   V4L2_MPEG_AUDIO_L1_BITRATE_320K = 9,
   V4L2_MPEG_AUDIO_L1_BITRATE_352K = 10,
+/* WARNING: DO NOT EDIT, AUTO-GENERATED CODE - SEE TOP FOR INSTRUCTIONS */
   V4L2_MPEG_AUDIO_L1_BITRATE_384K = 11,
   V4L2_MPEG_AUDIO_L1_BITRATE_416K = 12,
-/* WARNING: DO NOT EDIT, AUTO-GENERATED CODE - SEE TOP FOR INSTRUCTIONS */
   V4L2_MPEG_AUDIO_L1_BITRATE_448K = 13,
 };
+/* WARNING: DO NOT EDIT, AUTO-GENERATED CODE - SEE TOP FOR INSTRUCTIONS */
 #define V4L2_CID_MPEG_AUDIO_L2_BITRATE (V4L2_CID_MPEG_BASE + 103)
 enum v4l2_mpeg_audio_l2_bitrate {
-/* WARNING: DO NOT EDIT, AUTO-GENERATED CODE - SEE TOP FOR INSTRUCTIONS */
   V4L2_MPEG_AUDIO_L2_BITRATE_32K = 0,
   V4L2_MPEG_AUDIO_L2_BITRATE_48K = 1,
+/* WARNING: DO NOT EDIT, AUTO-GENERATED CODE - SEE TOP FOR INSTRUCTIONS */
   V4L2_MPEG_AUDIO_L2_BITRATE_56K = 2,
   V4L2_MPEG_AUDIO_L2_BITRATE_64K = 3,
-/* WARNING: DO NOT EDIT, AUTO-GENERATED CODE - SEE TOP FOR INSTRUCTIONS */
   V4L2_MPEG_AUDIO_L2_BITRATE_80K = 4,
   V4L2_MPEG_AUDIO_L2_BITRATE_96K = 5,
+/* WARNING: DO NOT EDIT, AUTO-GENERATED CODE - SEE TOP FOR INSTRUCTIONS */
   V4L2_MPEG_AUDIO_L2_BITRATE_112K = 6,
   V4L2_MPEG_AUDIO_L2_BITRATE_128K = 7,
-/* WARNING: DO NOT EDIT, AUTO-GENERATED CODE - SEE TOP FOR INSTRUCTIONS */
   V4L2_MPEG_AUDIO_L2_BITRATE_160K = 8,
   V4L2_MPEG_AUDIO_L2_BITRATE_192K = 9,
+/* WARNING: DO NOT EDIT, AUTO-GENERATED CODE - SEE TOP FOR INSTRUCTIONS */
   V4L2_MPEG_AUDIO_L2_BITRATE_224K = 10,
   V4L2_MPEG_AUDIO_L2_BITRATE_256K = 11,
-/* WARNING: DO NOT EDIT, AUTO-GENERATED CODE - SEE TOP FOR INSTRUCTIONS */
   V4L2_MPEG_AUDIO_L2_BITRATE_320K = 12,
   V4L2_MPEG_AUDIO_L2_BITRATE_384K = 13,
+/* WARNING: DO NOT EDIT, AUTO-GENERATED CODE - SEE TOP FOR INSTRUCTIONS */
 };
 #define V4L2_CID_MPEG_AUDIO_L3_BITRATE (V4L2_CID_MPEG_BASE + 104)
-/* WARNING: DO NOT EDIT, AUTO-GENERATED CODE - SEE TOP FOR INSTRUCTIONS */
 enum v4l2_mpeg_audio_l3_bitrate {
   V4L2_MPEG_AUDIO_L3_BITRATE_32K = 0,
+/* WARNING: DO NOT EDIT, AUTO-GENERATED CODE - SEE TOP FOR INSTRUCTIONS */
   V4L2_MPEG_AUDIO_L3_BITRATE_40K = 1,
   V4L2_MPEG_AUDIO_L3_BITRATE_48K = 2,
-/* WARNING: DO NOT EDIT, AUTO-GENERATED CODE - SEE TOP FOR INSTRUCTIONS */
   V4L2_MPEG_AUDIO_L3_BITRATE_56K = 3,
   V4L2_MPEG_AUDIO_L3_BITRATE_64K = 4,
+/* WARNING: DO NOT EDIT, AUTO-GENERATED CODE - SEE TOP FOR INSTRUCTIONS */
   V4L2_MPEG_AUDIO_L3_BITRATE_80K = 5,
   V4L2_MPEG_AUDIO_L3_BITRATE_96K = 6,
-/* WARNING: DO NOT EDIT, AUTO-GENERATED CODE - SEE TOP FOR INSTRUCTIONS */
   V4L2_MPEG_AUDIO_L3_BITRATE_112K = 7,
   V4L2_MPEG_AUDIO_L3_BITRATE_128K = 8,
+/* WARNING: DO NOT EDIT, AUTO-GENERATED CODE - SEE TOP FOR INSTRUCTIONS */
   V4L2_MPEG_AUDIO_L3_BITRATE_160K = 9,
   V4L2_MPEG_AUDIO_L3_BITRATE_192K = 10,
-/* WARNING: DO NOT EDIT, AUTO-GENERATED CODE - SEE TOP FOR INSTRUCTIONS */
   V4L2_MPEG_AUDIO_L3_BITRATE_224K = 11,
   V4L2_MPEG_AUDIO_L3_BITRATE_256K = 12,
+/* WARNING: DO NOT EDIT, AUTO-GENERATED CODE - SEE TOP FOR INSTRUCTIONS */
   V4L2_MPEG_AUDIO_L3_BITRATE_320K = 13,
 };
-/* WARNING: DO NOT EDIT, AUTO-GENERATED CODE - SEE TOP FOR INSTRUCTIONS */
 #define V4L2_CID_MPEG_AUDIO_MODE (V4L2_CID_MPEG_BASE + 105)
 enum v4l2_mpeg_audio_mode {
+/* WARNING: DO NOT EDIT, AUTO-GENERATED CODE - SEE TOP FOR INSTRUCTIONS */
   V4L2_MPEG_AUDIO_MODE_STEREO = 0,
   V4L2_MPEG_AUDIO_MODE_JOINT_STEREO = 1,
-/* WARNING: DO NOT EDIT, AUTO-GENERATED CODE - SEE TOP FOR INSTRUCTIONS */
   V4L2_MPEG_AUDIO_MODE_DUAL = 2,
   V4L2_MPEG_AUDIO_MODE_MONO = 3,
+/* WARNING: DO NOT EDIT, AUTO-GENERATED CODE - SEE TOP FOR INSTRUCTIONS */
 };
 #define V4L2_CID_MPEG_AUDIO_MODE_EXTENSION (V4L2_CID_MPEG_BASE + 106)
-/* WARNING: DO NOT EDIT, AUTO-GENERATED CODE - SEE TOP FOR INSTRUCTIONS */
 enum v4l2_mpeg_audio_mode_extension {
   V4L2_MPEG_AUDIO_MODE_EXTENSION_BOUND_4 = 0,
+/* WARNING: DO NOT EDIT, AUTO-GENERATED CODE - SEE TOP FOR INSTRUCTIONS */
   V4L2_MPEG_AUDIO_MODE_EXTENSION_BOUND_8 = 1,
   V4L2_MPEG_AUDIO_MODE_EXTENSION_BOUND_12 = 2,
-/* WARNING: DO NOT EDIT, AUTO-GENERATED CODE - SEE TOP FOR INSTRUCTIONS */
   V4L2_MPEG_AUDIO_MODE_EXTENSION_BOUND_16 = 3,
 };
+/* WARNING: DO NOT EDIT, AUTO-GENERATED CODE - SEE TOP FOR INSTRUCTIONS */
 #define V4L2_CID_MPEG_AUDIO_EMPHASIS (V4L2_CID_MPEG_BASE + 107)
 enum v4l2_mpeg_audio_emphasis {
-/* WARNING: DO NOT EDIT, AUTO-GENERATED CODE - SEE TOP FOR INSTRUCTIONS */
   V4L2_MPEG_AUDIO_EMPHASIS_NONE = 0,
   V4L2_MPEG_AUDIO_EMPHASIS_50_DIV_15_uS = 1,
+/* WARNING: DO NOT EDIT, AUTO-GENERATED CODE - SEE TOP FOR INSTRUCTIONS */
   V4L2_MPEG_AUDIO_EMPHASIS_CCITT_J17 = 2,
 };
-/* WARNING: DO NOT EDIT, AUTO-GENERATED CODE - SEE TOP FOR INSTRUCTIONS */
 #define V4L2_CID_MPEG_AUDIO_CRC (V4L2_CID_MPEG_BASE + 108)
 enum v4l2_mpeg_audio_crc {
+/* WARNING: DO NOT EDIT, AUTO-GENERATED CODE - SEE TOP FOR INSTRUCTIONS */
   V4L2_MPEG_AUDIO_CRC_NONE = 0,
   V4L2_MPEG_AUDIO_CRC_CRC16 = 1,
-/* WARNING: DO NOT EDIT, AUTO-GENERATED CODE - SEE TOP FOR INSTRUCTIONS */
 };
 #define V4L2_CID_MPEG_AUDIO_MUTE (V4L2_CID_MPEG_BASE + 109)
+/* WARNING: DO NOT EDIT, AUTO-GENERATED CODE - SEE TOP FOR INSTRUCTIONS */
 #define V4L2_CID_MPEG_AUDIO_AAC_BITRATE (V4L2_CID_MPEG_BASE + 110)
 #define V4L2_CID_MPEG_AUDIO_AC3_BITRATE (V4L2_CID_MPEG_BASE + 111)
-/* WARNING: DO NOT EDIT, AUTO-GENERATED CODE - SEE TOP FOR INSTRUCTIONS */
 enum v4l2_mpeg_audio_ac3_bitrate {
   V4L2_MPEG_AUDIO_AC3_BITRATE_32K = 0,
+/* WARNING: DO NOT EDIT, AUTO-GENERATED CODE - SEE TOP FOR INSTRUCTIONS */
   V4L2_MPEG_AUDIO_AC3_BITRATE_40K = 1,
   V4L2_MPEG_AUDIO_AC3_BITRATE_48K = 2,
-/* WARNING: DO NOT EDIT, AUTO-GENERATED CODE - SEE TOP FOR INSTRUCTIONS */
   V4L2_MPEG_AUDIO_AC3_BITRATE_56K = 3,
   V4L2_MPEG_AUDIO_AC3_BITRATE_64K = 4,
+/* WARNING: DO NOT EDIT, AUTO-GENERATED CODE - SEE TOP FOR INSTRUCTIONS */
   V4L2_MPEG_AUDIO_AC3_BITRATE_80K = 5,
   V4L2_MPEG_AUDIO_AC3_BITRATE_96K = 6,
-/* WARNING: DO NOT EDIT, AUTO-GENERATED CODE - SEE TOP FOR INSTRUCTIONS */
   V4L2_MPEG_AUDIO_AC3_BITRATE_112K = 7,
   V4L2_MPEG_AUDIO_AC3_BITRATE_128K = 8,
+/* WARNING: DO NOT EDIT, AUTO-GENERATED CODE - SEE TOP FOR INSTRUCTIONS */
   V4L2_MPEG_AUDIO_AC3_BITRATE_160K = 9,
   V4L2_MPEG_AUDIO_AC3_BITRATE_192K = 10,
-/* WARNING: DO NOT EDIT, AUTO-GENERATED CODE - SEE TOP FOR INSTRUCTIONS */
   V4L2_MPEG_AUDIO_AC3_BITRATE_224K = 11,
   V4L2_MPEG_AUDIO_AC3_BITRATE_256K = 12,
+/* WARNING: DO NOT EDIT, AUTO-GENERATED CODE - SEE TOP FOR INSTRUCTIONS */
   V4L2_MPEG_AUDIO_AC3_BITRATE_320K = 13,
   V4L2_MPEG_AUDIO_AC3_BITRATE_384K = 14,
-/* WARNING: DO NOT EDIT, AUTO-GENERATED CODE - SEE TOP FOR INSTRUCTIONS */
   V4L2_MPEG_AUDIO_AC3_BITRATE_448K = 15,
   V4L2_MPEG_AUDIO_AC3_BITRATE_512K = 16,
+/* WARNING: DO NOT EDIT, AUTO-GENERATED CODE - SEE TOP FOR INSTRUCTIONS */
   V4L2_MPEG_AUDIO_AC3_BITRATE_576K = 17,
   V4L2_MPEG_AUDIO_AC3_BITRATE_640K = 18,
-/* WARNING: DO NOT EDIT, AUTO-GENERATED CODE - SEE TOP FOR INSTRUCTIONS */
 };
 #define V4L2_CID_MPEG_AUDIO_DEC_PLAYBACK (V4L2_CID_MPEG_BASE + 112)
+/* WARNING: DO NOT EDIT, AUTO-GENERATED CODE - SEE TOP FOR INSTRUCTIONS */
 enum v4l2_mpeg_audio_dec_playback {
   V4L2_MPEG_AUDIO_DEC_PLAYBACK_AUTO = 0,
-/* WARNING: DO NOT EDIT, AUTO-GENERATED CODE - SEE TOP FOR INSTRUCTIONS */
   V4L2_MPEG_AUDIO_DEC_PLAYBACK_STEREO = 1,
   V4L2_MPEG_AUDIO_DEC_PLAYBACK_LEFT = 2,
+/* WARNING: DO NOT EDIT, AUTO-GENERATED CODE - SEE TOP FOR INSTRUCTIONS */
   V4L2_MPEG_AUDIO_DEC_PLAYBACK_RIGHT = 3,
   V4L2_MPEG_AUDIO_DEC_PLAYBACK_MONO = 4,
-/* WARNING: DO NOT EDIT, AUTO-GENERATED CODE - SEE TOP FOR INSTRUCTIONS */
   V4L2_MPEG_AUDIO_DEC_PLAYBACK_SWAPPED_STEREO = 5,
 };
+/* WARNING: DO NOT EDIT, AUTO-GENERATED CODE - SEE TOP FOR INSTRUCTIONS */
 #define V4L2_CID_MPEG_AUDIO_DEC_MULTILINGUAL_PLAYBACK (V4L2_CID_MPEG_BASE + 113)
 #define V4L2_CID_MPEG_VIDEO_ENCODING (V4L2_CID_MPEG_BASE + 200)
-/* WARNING: DO NOT EDIT, AUTO-GENERATED CODE - SEE TOP FOR INSTRUCTIONS */
 enum v4l2_mpeg_video_encoding {
   V4L2_MPEG_VIDEO_ENCODING_MPEG_1 = 0,
+/* WARNING: DO NOT EDIT, AUTO-GENERATED CODE - SEE TOP FOR INSTRUCTIONS */
   V4L2_MPEG_VIDEO_ENCODING_MPEG_2 = 1,
   V4L2_MPEG_VIDEO_ENCODING_MPEG_4_AVC = 2,
-/* WARNING: DO NOT EDIT, AUTO-GENERATED CODE - SEE TOP FOR INSTRUCTIONS */
 };
 #define V4L2_CID_MPEG_VIDEO_ASPECT (V4L2_CID_MPEG_BASE + 201)
+/* WARNING: DO NOT EDIT, AUTO-GENERATED CODE - SEE TOP FOR INSTRUCTIONS */
 enum v4l2_mpeg_video_aspect {
   V4L2_MPEG_VIDEO_ASPECT_1x1 = 0,
-/* WARNING: DO NOT EDIT, AUTO-GENERATED CODE - SEE TOP FOR INSTRUCTIONS */
   V4L2_MPEG_VIDEO_ASPECT_4x3 = 1,
   V4L2_MPEG_VIDEO_ASPECT_16x9 = 2,
+/* WARNING: DO NOT EDIT, AUTO-GENERATED CODE - SEE TOP FOR INSTRUCTIONS */
   V4L2_MPEG_VIDEO_ASPECT_221x100 = 3,
 };
-/* WARNING: DO NOT EDIT, AUTO-GENERATED CODE - SEE TOP FOR INSTRUCTIONS */
 #define V4L2_CID_MPEG_VIDEO_B_FRAMES (V4L2_CID_MPEG_BASE + 202)
 #define V4L2_CID_MPEG_VIDEO_GOP_SIZE (V4L2_CID_MPEG_BASE + 203)
+/* WARNING: DO NOT EDIT, AUTO-GENERATED CODE - SEE TOP FOR INSTRUCTIONS */
 #define V4L2_CID_MPEG_VIDEO_GOP_CLOSURE (V4L2_CID_MPEG_BASE + 204)
 #define V4L2_CID_MPEG_VIDEO_PULLDOWN (V4L2_CID_MPEG_BASE + 205)
-/* WARNING: DO NOT EDIT, AUTO-GENERATED CODE - SEE TOP FOR INSTRUCTIONS */
 #define V4L2_CID_MPEG_VIDEO_BITRATE_MODE (V4L2_CID_MPEG_BASE + 206)
 enum v4l2_mpeg_video_bitrate_mode {
+/* WARNING: DO NOT EDIT, AUTO-GENERATED CODE - SEE TOP FOR INSTRUCTIONS */
   V4L2_MPEG_VIDEO_BITRATE_MODE_VBR = 0,
   V4L2_MPEG_VIDEO_BITRATE_MODE_CBR = 1,
-/* WARNING: DO NOT EDIT, AUTO-GENERATED CODE - SEE TOP FOR INSTRUCTIONS */
 };
 #define V4L2_CID_MPEG_VIDEO_BITRATE (V4L2_CID_MPEG_BASE + 207)
+/* WARNING: DO NOT EDIT, AUTO-GENERATED CODE - SEE TOP FOR INSTRUCTIONS */
 #define V4L2_CID_MPEG_VIDEO_BITRATE_PEAK (V4L2_CID_MPEG_BASE + 208)
 #define V4L2_CID_MPEG_VIDEO_TEMPORAL_DECIMATION (V4L2_CID_MPEG_BASE + 209)
-/* WARNING: DO NOT EDIT, AUTO-GENERATED CODE - SEE TOP FOR INSTRUCTIONS */
 #define V4L2_CID_MPEG_VIDEO_MUTE (V4L2_CID_MPEG_BASE + 210)
 #define V4L2_CID_MPEG_VIDEO_MUTE_YUV (V4L2_CID_MPEG_BASE + 211)
+/* WARNING: DO NOT EDIT, AUTO-GENERATED CODE - SEE TOP FOR INSTRUCTIONS */
 #define V4L2_CID_MPEG_VIDEO_DECODER_SLICE_INTERFACE (V4L2_CID_MPEG_BASE + 212)
 #define V4L2_CID_MPEG_VIDEO_DECODER_MPEG4_DEBLOCK_FILTER (V4L2_CID_MPEG_BASE + 213)
-/* WARNING: DO NOT EDIT, AUTO-GENERATED CODE - SEE TOP FOR INSTRUCTIONS */
 #define V4L2_CID_MPEG_VIDEO_CYCLIC_INTRA_REFRESH_MB (V4L2_CID_MPEG_BASE + 214)
 #define V4L2_CID_MPEG_VIDEO_FRAME_RC_ENABLE (V4L2_CID_MPEG_BASE + 215)
+/* WARNING: DO NOT EDIT, AUTO-GENERATED CODE - SEE TOP FOR INSTRUCTIONS */
 #define V4L2_CID_MPEG_VIDEO_HEADER_MODE (V4L2_CID_MPEG_BASE + 216)
 enum v4l2_mpeg_video_header_mode {
-/* WARNING: DO NOT EDIT, AUTO-GENERATED CODE - SEE TOP FOR INSTRUCTIONS */
   V4L2_MPEG_VIDEO_HEADER_MODE_SEPARATE = 0,
   V4L2_MPEG_VIDEO_HEADER_MODE_JOINED_WITH_1ST_FRAME = 1,
+/* WARNING: DO NOT EDIT, AUTO-GENERATED CODE - SEE TOP FOR INSTRUCTIONS */
 };
 #define V4L2_CID_MPEG_VIDEO_MAX_REF_PIC (V4L2_CID_MPEG_BASE + 217)
-/* WARNING: DO NOT EDIT, AUTO-GENERATED CODE - SEE TOP FOR INSTRUCTIONS */
 #define V4L2_CID_MPEG_VIDEO_MB_RC_ENABLE (V4L2_CID_MPEG_BASE + 218)
 #define V4L2_CID_MPEG_VIDEO_MULTI_SLICE_MAX_BYTES (V4L2_CID_MPEG_BASE + 219)
+/* WARNING: DO NOT EDIT, AUTO-GENERATED CODE - SEE TOP FOR INSTRUCTIONS */
 #define V4L2_CID_MPEG_VIDEO_MULTI_SLICE_MAX_MB (V4L2_CID_MPEG_BASE + 220)
 #define V4L2_CID_MPEG_VIDEO_MULTI_SLICE_MODE (V4L2_CID_MPEG_BASE + 221)
-/* WARNING: DO NOT EDIT, AUTO-GENERATED CODE - SEE TOP FOR INSTRUCTIONS */
 enum v4l2_mpeg_video_multi_slice_mode {
   V4L2_MPEG_VIDEO_MULTI_SLICE_MODE_SINGLE = 0,
+/* WARNING: DO NOT EDIT, AUTO-GENERATED CODE - SEE TOP FOR INSTRUCTIONS */
   V4L2_MPEG_VIDEO_MULTI_SICE_MODE_MAX_MB = 1,
   V4L2_MPEG_VIDEO_MULTI_SICE_MODE_MAX_BYTES = 2,
-/* WARNING: DO NOT EDIT, AUTO-GENERATED CODE - SEE TOP FOR INSTRUCTIONS */
 };
 #define V4L2_CID_MPEG_VIDEO_VBV_SIZE (V4L2_CID_MPEG_BASE + 222)
+/* WARNING: DO NOT EDIT, AUTO-GENERATED CODE - SEE TOP FOR INSTRUCTIONS */
 #define V4L2_CID_MPEG_VIDEO_DEC_PTS (V4L2_CID_MPEG_BASE + 223)
 #define V4L2_CID_MPEG_VIDEO_DEC_FRAME (V4L2_CID_MPEG_BASE + 224)
-/* WARNING: DO NOT EDIT, AUTO-GENERATED CODE - SEE TOP FOR INSTRUCTIONS */
 #define V4L2_CID_MPEG_VIDEO_VBV_DELAY (V4L2_CID_MPEG_BASE + 225)
 #define V4L2_CID_MPEG_VIDEO_REPEAT_SEQ_HEADER (V4L2_CID_MPEG_BASE + 226)
+/* WARNING: DO NOT EDIT, AUTO-GENERATED CODE - SEE TOP FOR INSTRUCTIONS */
 #define V4L2_CID_MPEG_VIDEO_MV_H_SEARCH_RANGE (V4L2_CID_MPEG_BASE + 227)
 #define V4L2_CID_MPEG_VIDEO_MV_V_SEARCH_RANGE (V4L2_CID_MPEG_BASE + 228)
-/* WARNING: DO NOT EDIT, AUTO-GENERATED CODE - SEE TOP FOR INSTRUCTIONS */
 #define V4L2_CID_MPEG_VIDEO_H263_I_FRAME_QP (V4L2_CID_MPEG_BASE + 300)
 #define V4L2_CID_MPEG_VIDEO_H263_P_FRAME_QP (V4L2_CID_MPEG_BASE + 301)
+/* WARNING: DO NOT EDIT, AUTO-GENERATED CODE - SEE TOP FOR INSTRUCTIONS */
 #define V4L2_CID_MPEG_VIDEO_H263_B_FRAME_QP (V4L2_CID_MPEG_BASE + 302)
 #define V4L2_CID_MPEG_VIDEO_H263_MIN_QP (V4L2_CID_MPEG_BASE + 303)
-/* WARNING: DO NOT EDIT, AUTO-GENERATED CODE - SEE TOP FOR INSTRUCTIONS */
 #define V4L2_CID_MPEG_VIDEO_H263_MAX_QP (V4L2_CID_MPEG_BASE + 304)
 #define V4L2_CID_MPEG_VIDEO_H264_I_FRAME_QP (V4L2_CID_MPEG_BASE + 350)
+/* WARNING: DO NOT EDIT, AUTO-GENERATED CODE - SEE TOP FOR INSTRUCTIONS */
 #define V4L2_CID_MPEG_VIDEO_H264_P_FRAME_QP (V4L2_CID_MPEG_BASE + 351)
 #define V4L2_CID_MPEG_VIDEO_H264_B_FRAME_QP (V4L2_CID_MPEG_BASE + 352)
-/* WARNING: DO NOT EDIT, AUTO-GENERATED CODE - SEE TOP FOR INSTRUCTIONS */
 #define V4L2_CID_MPEG_VIDEO_H264_MIN_QP (V4L2_CID_MPEG_BASE + 353)
 #define V4L2_CID_MPEG_VIDEO_H264_MAX_QP (V4L2_CID_MPEG_BASE + 354)
+/* WARNING: DO NOT EDIT, AUTO-GENERATED CODE - SEE TOP FOR INSTRUCTIONS */
 #define V4L2_CID_MPEG_VIDEO_H264_8X8_TRANSFORM (V4L2_CID_MPEG_BASE + 355)
 #define V4L2_CID_MPEG_VIDEO_H264_CPB_SIZE (V4L2_CID_MPEG_BASE + 356)
-/* WARNING: DO NOT EDIT, AUTO-GENERATED CODE - SEE TOP FOR INSTRUCTIONS */
 #define V4L2_CID_MPEG_VIDEO_H264_ENTROPY_MODE (V4L2_CID_MPEG_BASE + 357)
 enum v4l2_mpeg_video_h264_entropy_mode {
+/* WARNING: DO NOT EDIT, AUTO-GENERATED CODE - SEE TOP FOR INSTRUCTIONS */
   V4L2_MPEG_VIDEO_H264_ENTROPY_MODE_CAVLC = 0,
   V4L2_MPEG_VIDEO_H264_ENTROPY_MODE_CABAC = 1,
-/* WARNING: DO NOT EDIT, AUTO-GENERATED CODE - SEE TOP FOR INSTRUCTIONS */
 };
 #define V4L2_CID_MPEG_VIDEO_H264_I_PERIOD (V4L2_CID_MPEG_BASE + 358)
+/* WARNING: DO NOT EDIT, AUTO-GENERATED CODE - SEE TOP FOR INSTRUCTIONS */
 #define V4L2_CID_MPEG_VIDEO_H264_LEVEL (V4L2_CID_MPEG_BASE + 359)
 enum v4l2_mpeg_video_h264_level {
-/* WARNING: DO NOT EDIT, AUTO-GENERATED CODE - SEE TOP FOR INSTRUCTIONS */
   V4L2_MPEG_VIDEO_H264_LEVEL_1_0 = 0,
   V4L2_MPEG_VIDEO_H264_LEVEL_1B = 1,
+/* WARNING: DO NOT EDIT, AUTO-GENERATED CODE - SEE TOP FOR INSTRUCTIONS */
   V4L2_MPEG_VIDEO_H264_LEVEL_1_1 = 2,
   V4L2_MPEG_VIDEO_H264_LEVEL_1_2 = 3,
-/* WARNING: DO NOT EDIT, AUTO-GENERATED CODE - SEE TOP FOR INSTRUCTIONS */
   V4L2_MPEG_VIDEO_H264_LEVEL_1_3 = 4,
   V4L2_MPEG_VIDEO_H264_LEVEL_2_0 = 5,
+/* WARNING: DO NOT EDIT, AUTO-GENERATED CODE - SEE TOP FOR INSTRUCTIONS */
   V4L2_MPEG_VIDEO_H264_LEVEL_2_1 = 6,
   V4L2_MPEG_VIDEO_H264_LEVEL_2_2 = 7,
-/* WARNING: DO NOT EDIT, AUTO-GENERATED CODE - SEE TOP FOR INSTRUCTIONS */
   V4L2_MPEG_VIDEO_H264_LEVEL_3_0 = 8,
   V4L2_MPEG_VIDEO_H264_LEVEL_3_1 = 9,
+/* WARNING: DO NOT EDIT, AUTO-GENERATED CODE - SEE TOP FOR INSTRUCTIONS */
   V4L2_MPEG_VIDEO_H264_LEVEL_3_2 = 10,
   V4L2_MPEG_VIDEO_H264_LEVEL_4_0 = 11,
-/* WARNING: DO NOT EDIT, AUTO-GENERATED CODE - SEE TOP FOR INSTRUCTIONS */
   V4L2_MPEG_VIDEO_H264_LEVEL_4_1 = 12,
   V4L2_MPEG_VIDEO_H264_LEVEL_4_2 = 13,
+/* WARNING: DO NOT EDIT, AUTO-GENERATED CODE - SEE TOP FOR INSTRUCTIONS */
   V4L2_MPEG_VIDEO_H264_LEVEL_5_0 = 14,
   V4L2_MPEG_VIDEO_H264_LEVEL_5_1 = 15,
-/* WARNING: DO NOT EDIT, AUTO-GENERATED CODE - SEE TOP FOR INSTRUCTIONS */
 };
 #define V4L2_CID_MPEG_VIDEO_H264_LOOP_FILTER_ALPHA (V4L2_CID_MPEG_BASE + 360)
+/* WARNING: DO NOT EDIT, AUTO-GENERATED CODE - SEE TOP FOR INSTRUCTIONS */
 #define V4L2_CID_MPEG_VIDEO_H264_LOOP_FILTER_BETA (V4L2_CID_MPEG_BASE + 361)
 #define V4L2_CID_MPEG_VIDEO_H264_LOOP_FILTER_MODE (V4L2_CID_MPEG_BASE + 362)
-/* WARNING: DO NOT EDIT, AUTO-GENERATED CODE - SEE TOP FOR INSTRUCTIONS */
 enum v4l2_mpeg_video_h264_loop_filter_mode {
   V4L2_MPEG_VIDEO_H264_LOOP_FILTER_MODE_ENABLED = 0,
+/* WARNING: DO NOT EDIT, AUTO-GENERATED CODE - SEE TOP FOR INSTRUCTIONS */
   V4L2_MPEG_VIDEO_H264_LOOP_FILTER_MODE_DISABLED = 1,
   V4L2_MPEG_VIDEO_H264_LOOP_FILTER_MODE_DISABLED_AT_SLICE_BOUNDARY = 2,
-/* WARNING: DO NOT EDIT, AUTO-GENERATED CODE - SEE TOP FOR INSTRUCTIONS */
 };
 #define V4L2_CID_MPEG_VIDEO_H264_PROFILE (V4L2_CID_MPEG_BASE + 363)
+/* WARNING: DO NOT EDIT, AUTO-GENERATED CODE - SEE TOP FOR INSTRUCTIONS */
 enum v4l2_mpeg_video_h264_profile {
   V4L2_MPEG_VIDEO_H264_PROFILE_BASELINE = 0,
-/* WARNING: DO NOT EDIT, AUTO-GENERATED CODE - SEE TOP FOR INSTRUCTIONS */
   V4L2_MPEG_VIDEO_H264_PROFILE_CONSTRAINED_BASELINE = 1,
   V4L2_MPEG_VIDEO_H264_PROFILE_MAIN = 2,
+/* WARNING: DO NOT EDIT, AUTO-GENERATED CODE - SEE TOP FOR INSTRUCTIONS */
   V4L2_MPEG_VIDEO_H264_PROFILE_EXTENDED = 3,
   V4L2_MPEG_VIDEO_H264_PROFILE_HIGH = 4,
-/* WARNING: DO NOT EDIT, AUTO-GENERATED CODE - SEE TOP FOR INSTRUCTIONS */
   V4L2_MPEG_VIDEO_H264_PROFILE_HIGH_10 = 5,
   V4L2_MPEG_VIDEO_H264_PROFILE_HIGH_422 = 6,
+/* WARNING: DO NOT EDIT, AUTO-GENERATED CODE - SEE TOP FOR INSTRUCTIONS */
   V4L2_MPEG_VIDEO_H264_PROFILE_HIGH_444_PREDICTIVE = 7,
   V4L2_MPEG_VIDEO_H264_PROFILE_HIGH_10_INTRA = 8,
-/* WARNING: DO NOT EDIT, AUTO-GENERATED CODE - SEE TOP FOR INSTRUCTIONS */
   V4L2_MPEG_VIDEO_H264_PROFILE_HIGH_422_INTRA = 9,
   V4L2_MPEG_VIDEO_H264_PROFILE_HIGH_444_INTRA = 10,
+/* WARNING: DO NOT EDIT, AUTO-GENERATED CODE - SEE TOP FOR INSTRUCTIONS */
   V4L2_MPEG_VIDEO_H264_PROFILE_CAVLC_444_INTRA = 11,
   V4L2_MPEG_VIDEO_H264_PROFILE_SCALABLE_BASELINE = 12,
-/* WARNING: DO NOT EDIT, AUTO-GENERATED CODE - SEE TOP FOR INSTRUCTIONS */
   V4L2_MPEG_VIDEO_H264_PROFILE_SCALABLE_HIGH = 13,
   V4L2_MPEG_VIDEO_H264_PROFILE_SCALABLE_HIGH_INTRA = 14,
+/* WARNING: DO NOT EDIT, AUTO-GENERATED CODE - SEE TOP FOR INSTRUCTIONS */
   V4L2_MPEG_VIDEO_H264_PROFILE_STEREO_HIGH = 15,
   V4L2_MPEG_VIDEO_H264_PROFILE_MULTIVIEW_HIGH = 16,
-/* WARNING: DO NOT EDIT, AUTO-GENERATED CODE - SEE TOP FOR INSTRUCTIONS */
 };
 #define V4L2_CID_MPEG_VIDEO_H264_VUI_EXT_SAR_HEIGHT (V4L2_CID_MPEG_BASE + 364)
+/* WARNING: DO NOT EDIT, AUTO-GENERATED CODE - SEE TOP FOR INSTRUCTIONS */
 #define V4L2_CID_MPEG_VIDEO_H264_VUI_EXT_SAR_WIDTH (V4L2_CID_MPEG_BASE + 365)
 #define V4L2_CID_MPEG_VIDEO_H264_VUI_SAR_ENABLE (V4L2_CID_MPEG_BASE + 366)
-/* WARNING: DO NOT EDIT, AUTO-GENERATED CODE - SEE TOP FOR INSTRUCTIONS */
 #define V4L2_CID_MPEG_VIDEO_H264_VUI_SAR_IDC (V4L2_CID_MPEG_BASE + 367)
 enum v4l2_mpeg_video_h264_vui_sar_idc {
+/* WARNING: DO NOT EDIT, AUTO-GENERATED CODE - SEE TOP FOR INSTRUCTIONS */
   V4L2_MPEG_VIDEO_H264_VUI_SAR_IDC_UNSPECIFIED = 0,
   V4L2_MPEG_VIDEO_H264_VUI_SAR_IDC_1x1 = 1,
-/* WARNING: DO NOT EDIT, AUTO-GENERATED CODE - SEE TOP FOR INSTRUCTIONS */
   V4L2_MPEG_VIDEO_H264_VUI_SAR_IDC_12x11 = 2,
   V4L2_MPEG_VIDEO_H264_VUI_SAR_IDC_10x11 = 3,
+/* WARNING: DO NOT EDIT, AUTO-GENERATED CODE - SEE TOP FOR INSTRUCTIONS */
   V4L2_MPEG_VIDEO_H264_VUI_SAR_IDC_16x11 = 4,
   V4L2_MPEG_VIDEO_H264_VUI_SAR_IDC_40x33 = 5,
-/* WARNING: DO NOT EDIT, AUTO-GENERATED CODE - SEE TOP FOR INSTRUCTIONS */
   V4L2_MPEG_VIDEO_H264_VUI_SAR_IDC_24x11 = 6,
   V4L2_MPEG_VIDEO_H264_VUI_SAR_IDC_20x11 = 7,
+/* WARNING: DO NOT EDIT, AUTO-GENERATED CODE - SEE TOP FOR INSTRUCTIONS */
   V4L2_MPEG_VIDEO_H264_VUI_SAR_IDC_32x11 = 8,
   V4L2_MPEG_VIDEO_H264_VUI_SAR_IDC_80x33 = 9,
-/* WARNING: DO NOT EDIT, AUTO-GENERATED CODE - SEE TOP FOR INSTRUCTIONS */
   V4L2_MPEG_VIDEO_H264_VUI_SAR_IDC_18x11 = 10,
   V4L2_MPEG_VIDEO_H264_VUI_SAR_IDC_15x11 = 11,
+/* WARNING: DO NOT EDIT, AUTO-GENERATED CODE - SEE TOP FOR INSTRUCTIONS */
   V4L2_MPEG_VIDEO_H264_VUI_SAR_IDC_64x33 = 12,
   V4L2_MPEG_VIDEO_H264_VUI_SAR_IDC_160x99 = 13,
-/* WARNING: DO NOT EDIT, AUTO-GENERATED CODE - SEE TOP FOR INSTRUCTIONS */
   V4L2_MPEG_VIDEO_H264_VUI_SAR_IDC_4x3 = 14,
   V4L2_MPEG_VIDEO_H264_VUI_SAR_IDC_3x2 = 15,
+/* WARNING: DO NOT EDIT, AUTO-GENERATED CODE - SEE TOP FOR INSTRUCTIONS */
   V4L2_MPEG_VIDEO_H264_VUI_SAR_IDC_2x1 = 16,
   V4L2_MPEG_VIDEO_H264_VUI_SAR_IDC_EXTENDED = 17,
-/* WARNING: DO NOT EDIT, AUTO-GENERATED CODE - SEE TOP FOR INSTRUCTIONS */
 };
 #define V4L2_CID_MPEG_VIDEO_H264_SEI_FRAME_PACKING (V4L2_CID_MPEG_BASE + 368)
+/* WARNING: DO NOT EDIT, AUTO-GENERATED CODE - SEE TOP FOR INSTRUCTIONS */
 #define V4L2_CID_MPEG_VIDEO_H264_SEI_FP_CURRENT_FRAME_0 (V4L2_CID_MPEG_BASE + 369)
 #define V4L2_CID_MPEG_VIDEO_H264_SEI_FP_ARRANGEMENT_TYPE (V4L2_CID_MPEG_BASE + 370)
-/* WARNING: DO NOT EDIT, AUTO-GENERATED CODE - SEE TOP FOR INSTRUCTIONS */
 enum v4l2_mpeg_video_h264_sei_fp_arrangement_type {
   V4L2_MPEG_VIDEO_H264_SEI_FP_ARRANGEMENT_TYPE_CHECKERBOARD = 0,
+/* WARNING: DO NOT EDIT, AUTO-GENERATED CODE - SEE TOP FOR INSTRUCTIONS */
   V4L2_MPEG_VIDEO_H264_SEI_FP_ARRANGEMENT_TYPE_COLUMN = 1,
   V4L2_MPEG_VIDEO_H264_SEI_FP_ARRANGEMENT_TYPE_ROW = 2,
-/* WARNING: DO NOT EDIT, AUTO-GENERATED CODE - SEE TOP FOR INSTRUCTIONS */
   V4L2_MPEG_VIDEO_H264_SEI_FP_ARRANGEMENT_TYPE_SIDE_BY_SIDE = 3,
   V4L2_MPEG_VIDEO_H264_SEI_FP_ARRANGEMENT_TYPE_TOP_BOTTOM = 4,
+/* WARNING: DO NOT EDIT, AUTO-GENERATED CODE - SEE TOP FOR INSTRUCTIONS */
   V4L2_MPEG_VIDEO_H264_SEI_FP_ARRANGEMENT_TYPE_TEMPORAL = 5,
 };
-/* WARNING: DO NOT EDIT, AUTO-GENERATED CODE - SEE TOP FOR INSTRUCTIONS */
 #define V4L2_CID_MPEG_VIDEO_H264_FMO (V4L2_CID_MPEG_BASE + 371)
 #define V4L2_CID_MPEG_VIDEO_H264_FMO_MAP_TYPE (V4L2_CID_MPEG_BASE + 372)
+/* WARNING: DO NOT EDIT, AUTO-GENERATED CODE - SEE TOP FOR INSTRUCTIONS */
 enum v4l2_mpeg_video_h264_fmo_map_type {
   V4L2_MPEG_VIDEO_H264_FMO_MAP_TYPE_INTERLEAVED_SLICES = 0,
-/* WARNING: DO NOT EDIT, AUTO-GENERATED CODE - SEE TOP FOR INSTRUCTIONS */
   V4L2_MPEG_VIDEO_H264_FMO_MAP_TYPE_SCATTERED_SLICES = 1,
   V4L2_MPEG_VIDEO_H264_FMO_MAP_TYPE_FOREGROUND_WITH_LEFT_OVER = 2,
+/* WARNING: DO NOT EDIT, AUTO-GENERATED CODE - SEE TOP FOR INSTRUCTIONS */
   V4L2_MPEG_VIDEO_H264_FMO_MAP_TYPE_BOX_OUT = 3,
   V4L2_MPEG_VIDEO_H264_FMO_MAP_TYPE_RASTER_SCAN = 4,
-/* WARNING: DO NOT EDIT, AUTO-GENERATED CODE - SEE TOP FOR INSTRUCTIONS */
   V4L2_MPEG_VIDEO_H264_FMO_MAP_TYPE_WIPE_SCAN = 5,
   V4L2_MPEG_VIDEO_H264_FMO_MAP_TYPE_EXPLICIT = 6,
+/* WARNING: DO NOT EDIT, AUTO-GENERATED CODE - SEE TOP FOR INSTRUCTIONS */
 };
 #define V4L2_CID_MPEG_VIDEO_H264_FMO_SLICE_GROUP (V4L2_CID_MPEG_BASE + 373)
-/* WARNING: DO NOT EDIT, AUTO-GENERATED CODE - SEE TOP FOR INSTRUCTIONS */
 #define V4L2_CID_MPEG_VIDEO_H264_FMO_CHANGE_DIRECTION (V4L2_CID_MPEG_BASE + 374)
 enum v4l2_mpeg_video_h264_fmo_change_dir {
+/* WARNING: DO NOT EDIT, AUTO-GENERATED CODE - SEE TOP FOR INSTRUCTIONS */
   V4L2_MPEG_VIDEO_H264_FMO_CHANGE_DIR_RIGHT = 0,
   V4L2_MPEG_VIDEO_H264_FMO_CHANGE_DIR_LEFT = 1,
-/* WARNING: DO NOT EDIT, AUTO-GENERATED CODE - SEE TOP FOR INSTRUCTIONS */
 };
 #define V4L2_CID_MPEG_VIDEO_H264_FMO_CHANGE_RATE (V4L2_CID_MPEG_BASE + 375)
+/* WARNING: DO NOT EDIT, AUTO-GENERATED CODE - SEE TOP FOR INSTRUCTIONS */
 #define V4L2_CID_MPEG_VIDEO_H264_FMO_RUN_LENGTH (V4L2_CID_MPEG_BASE + 376)
 #define V4L2_CID_MPEG_VIDEO_H264_ASO (V4L2_CID_MPEG_BASE + 377)
-/* WARNING: DO NOT EDIT, AUTO-GENERATED CODE - SEE TOP FOR INSTRUCTIONS */
 #define V4L2_CID_MPEG_VIDEO_H264_ASO_SLICE_ORDER (V4L2_CID_MPEG_BASE + 378)
 #define V4L2_CID_MPEG_VIDEO_H264_HIERARCHICAL_CODING (V4L2_CID_MPEG_BASE + 379)
+/* WARNING: DO NOT EDIT, AUTO-GENERATED CODE - SEE TOP FOR INSTRUCTIONS */
 #define V4L2_CID_MPEG_VIDEO_H264_HIERARCHICAL_CODING_TYPE (V4L2_CID_MPEG_BASE + 380)
 enum v4l2_mpeg_video_h264_hierarchical_coding_type {
-/* WARNING: DO NOT EDIT, AUTO-GENERATED CODE - SEE TOP FOR INSTRUCTIONS */
   V4L2_MPEG_VIDEO_H264_HIERARCHICAL_CODING_B = 0,
   V4L2_MPEG_VIDEO_H264_HIERARCHICAL_CODING_P = 1,
+/* WARNING: DO NOT EDIT, AUTO-GENERATED CODE - SEE TOP FOR INSTRUCTIONS */
 };
 #define V4L2_CID_MPEG_VIDEO_H264_HIERARCHICAL_CODING_LAYER (V4L2_CID_MPEG_BASE + 381)
-/* WARNING: DO NOT EDIT, AUTO-GENERATED CODE - SEE TOP FOR INSTRUCTIONS */
 #define V4L2_CID_MPEG_VIDEO_H264_HIERARCHICAL_CODING_LAYER_QP (V4L2_CID_MPEG_BASE + 382)
 #define V4L2_CID_MPEG_VIDEO_MPEG4_I_FRAME_QP (V4L2_CID_MPEG_BASE + 400)
+/* WARNING: DO NOT EDIT, AUTO-GENERATED CODE - SEE TOP FOR INSTRUCTIONS */
 #define V4L2_CID_MPEG_VIDEO_MPEG4_P_FRAME_QP (V4L2_CID_MPEG_BASE + 401)
 #define V4L2_CID_MPEG_VIDEO_MPEG4_B_FRAME_QP (V4L2_CID_MPEG_BASE + 402)
-/* WARNING: DO NOT EDIT, AUTO-GENERATED CODE - SEE TOP FOR INSTRUCTIONS */
 #define V4L2_CID_MPEG_VIDEO_MPEG4_MIN_QP (V4L2_CID_MPEG_BASE + 403)
 #define V4L2_CID_MPEG_VIDEO_MPEG4_MAX_QP (V4L2_CID_MPEG_BASE + 404)
+/* WARNING: DO NOT EDIT, AUTO-GENERATED CODE - SEE TOP FOR INSTRUCTIONS */
 #define V4L2_CID_MPEG_VIDEO_MPEG4_LEVEL (V4L2_CID_MPEG_BASE + 405)
 enum v4l2_mpeg_video_mpeg4_level {
-/* WARNING: DO NOT EDIT, AUTO-GENERATED CODE - SEE TOP FOR INSTRUCTIONS */
   V4L2_MPEG_VIDEO_MPEG4_LEVEL_0 = 0,
   V4L2_MPEG_VIDEO_MPEG4_LEVEL_0B = 1,
+/* WARNING: DO NOT EDIT, AUTO-GENERATED CODE - SEE TOP FOR INSTRUCTIONS */
   V4L2_MPEG_VIDEO_MPEG4_LEVEL_1 = 2,
   V4L2_MPEG_VIDEO_MPEG4_LEVEL_2 = 3,
-/* WARNING: DO NOT EDIT, AUTO-GENERATED CODE - SEE TOP FOR INSTRUCTIONS */
   V4L2_MPEG_VIDEO_MPEG4_LEVEL_3 = 4,
   V4L2_MPEG_VIDEO_MPEG4_LEVEL_3B = 5,
+/* WARNING: DO NOT EDIT, AUTO-GENERATED CODE - SEE TOP FOR INSTRUCTIONS */
   V4L2_MPEG_VIDEO_MPEG4_LEVEL_4 = 6,
   V4L2_MPEG_VIDEO_MPEG4_LEVEL_5 = 7,
-/* WARNING: DO NOT EDIT, AUTO-GENERATED CODE - SEE TOP FOR INSTRUCTIONS */
 };
 #define V4L2_CID_MPEG_VIDEO_MPEG4_PROFILE (V4L2_CID_MPEG_BASE + 406)
+/* WARNING: DO NOT EDIT, AUTO-GENERATED CODE - SEE TOP FOR INSTRUCTIONS */
 enum v4l2_mpeg_video_mpeg4_profile {
   V4L2_MPEG_VIDEO_MPEG4_PROFILE_SIMPLE = 0,
-/* WARNING: DO NOT EDIT, AUTO-GENERATED CODE - SEE TOP FOR INSTRUCTIONS */
   V4L2_MPEG_VIDEO_MPEG4_PROFILE_ADVANCED_SIMPLE = 1,
   V4L2_MPEG_VIDEO_MPEG4_PROFILE_CORE = 2,
+/* WARNING: DO NOT EDIT, AUTO-GENERATED CODE - SEE TOP FOR INSTRUCTIONS */
   V4L2_MPEG_VIDEO_MPEG4_PROFILE_SIMPLE_SCALABLE = 3,
   V4L2_MPEG_VIDEO_MPEG4_PROFILE_ADVANCED_CODING_EFFICIENCY = 4,
-/* WARNING: DO NOT EDIT, AUTO-GENERATED CODE - SEE TOP FOR INSTRUCTIONS */
 };
 #define V4L2_CID_MPEG_VIDEO_MPEG4_QPEL (V4L2_CID_MPEG_BASE + 407)
+/* WARNING: DO NOT EDIT, AUTO-GENERATED CODE - SEE TOP FOR INSTRUCTIONS */
 #define V4L2_CID_MPEG_VIDEO_VPX_NUM_PARTITIONS (V4L2_CID_MPEG_BASE + 500)
 enum v4l2_vp8_num_partitions {
-/* WARNING: DO NOT EDIT, AUTO-GENERATED CODE - SEE TOP FOR INSTRUCTIONS */
   V4L2_CID_MPEG_VIDEO_VPX_1_PARTITION = 0,
   V4L2_CID_MPEG_VIDEO_VPX_2_PARTITIONS = 1,
+/* WARNING: DO NOT EDIT, AUTO-GENERATED CODE - SEE TOP FOR INSTRUCTIONS */
   V4L2_CID_MPEG_VIDEO_VPX_4_PARTITIONS = 2,
   V4L2_CID_MPEG_VIDEO_VPX_8_PARTITIONS = 3,
-/* WARNING: DO NOT EDIT, AUTO-GENERATED CODE - SEE TOP FOR INSTRUCTIONS */
 };
 #define V4L2_CID_MPEG_VIDEO_VPX_IMD_DISABLE_4X4 (V4L2_CID_MPEG_BASE + 501)
+/* WARNING: DO NOT EDIT, AUTO-GENERATED CODE - SEE TOP FOR INSTRUCTIONS */
 #define V4L2_CID_MPEG_VIDEO_VPX_NUM_REF_FRAMES (V4L2_CID_MPEG_BASE + 502)
 enum v4l2_vp8_num_ref_frames {
-/* WARNING: DO NOT EDIT, AUTO-GENERATED CODE - SEE TOP FOR INSTRUCTIONS */
   V4L2_CID_MPEG_VIDEO_VPX_1_REF_FRAME = 0,
   V4L2_CID_MPEG_VIDEO_VPX_2_REF_FRAME = 1,
+/* WARNING: DO NOT EDIT, AUTO-GENERATED CODE - SEE TOP FOR INSTRUCTIONS */
   V4L2_CID_MPEG_VIDEO_VPX_3_REF_FRAME = 2,
 };
-/* WARNING: DO NOT EDIT, AUTO-GENERATED CODE - SEE TOP FOR INSTRUCTIONS */
 #define V4L2_CID_MPEG_VIDEO_VPX_FILTER_LEVEL (V4L2_CID_MPEG_BASE + 503)
 #define V4L2_CID_MPEG_VIDEO_VPX_FILTER_SHARPNESS (V4L2_CID_MPEG_BASE + 504)
+/* WARNING: DO NOT EDIT, AUTO-GENERATED CODE - SEE TOP FOR INSTRUCTIONS */
 #define V4L2_CID_MPEG_VIDEO_VPX_GOLDEN_FRAME_REF_PERIOD (V4L2_CID_MPEG_BASE + 505)
 #define V4L2_CID_MPEG_VIDEO_VPX_GOLDEN_FRAME_SEL (V4L2_CID_MPEG_BASE + 506)
-/* WARNING: DO NOT EDIT, AUTO-GENERATED CODE - SEE TOP FOR INSTRUCTIONS */
 enum v4l2_vp8_golden_frame_sel {
   V4L2_CID_MPEG_VIDEO_VPX_GOLDEN_FRAME_USE_PREV = 0,
+/* WARNING: DO NOT EDIT, AUTO-GENERATED CODE - SEE TOP FOR INSTRUCTIONS */
   V4L2_CID_MPEG_VIDEO_VPX_GOLDEN_FRAME_USE_REF_PERIOD = 1,
 };
-/* WARNING: DO NOT EDIT, AUTO-GENERATED CODE - SEE TOP FOR INSTRUCTIONS */
 #define V4L2_CID_MPEG_VIDEO_VPX_MIN_QP (V4L2_CID_MPEG_BASE + 507)
 #define V4L2_CID_MPEG_VIDEO_VPX_MAX_QP (V4L2_CID_MPEG_BASE + 508)
+/* WARNING: DO NOT EDIT, AUTO-GENERATED CODE - SEE TOP FOR INSTRUCTIONS */
 #define V4L2_CID_MPEG_VIDEO_VPX_I_FRAME_QP (V4L2_CID_MPEG_BASE + 509)
 #define V4L2_CID_MPEG_VIDEO_VPX_P_FRAME_QP (V4L2_CID_MPEG_BASE + 510)
-/* WARNING: DO NOT EDIT, AUTO-GENERATED CODE - SEE TOP FOR INSTRUCTIONS */
 #define V4L2_CID_MPEG_VIDEO_VPX_PROFILE (V4L2_CID_MPEG_BASE + 511)
 #define V4L2_CID_MPEG_CX2341X_BASE (V4L2_CTRL_CLASS_MPEG | 0x1000)
+/* WARNING: DO NOT EDIT, AUTO-GENERATED CODE - SEE TOP FOR INSTRUCTIONS */
 #define V4L2_CID_MPEG_CX2341X_VIDEO_SPATIAL_FILTER_MODE (V4L2_CID_MPEG_CX2341X_BASE + 0)
 enum v4l2_mpeg_cx2341x_video_spatial_filter_mode {
-/* WARNING: DO NOT EDIT, AUTO-GENERATED CODE - SEE TOP FOR INSTRUCTIONS */
   V4L2_MPEG_CX2341X_VIDEO_SPATIAL_FILTER_MODE_MANUAL = 0,
   V4L2_MPEG_CX2341X_VIDEO_SPATIAL_FILTER_MODE_AUTO = 1,
+/* WARNING: DO NOT EDIT, AUTO-GENERATED CODE - SEE TOP FOR INSTRUCTIONS */
 };
 #define V4L2_CID_MPEG_CX2341X_VIDEO_SPATIAL_FILTER (V4L2_CID_MPEG_CX2341X_BASE + 1)
-/* WARNING: DO NOT EDIT, AUTO-GENERATED CODE - SEE TOP FOR INSTRUCTIONS */
 #define V4L2_CID_MPEG_CX2341X_VIDEO_LUMA_SPATIAL_FILTER_TYPE (V4L2_CID_MPEG_CX2341X_BASE + 2)
 enum v4l2_mpeg_cx2341x_video_luma_spatial_filter_type {
+/* WARNING: DO NOT EDIT, AUTO-GENERATED CODE - SEE TOP FOR INSTRUCTIONS */
   V4L2_MPEG_CX2341X_VIDEO_LUMA_SPATIAL_FILTER_TYPE_OFF = 0,
   V4L2_MPEG_CX2341X_VIDEO_LUMA_SPATIAL_FILTER_TYPE_1D_HOR = 1,
-/* WARNING: DO NOT EDIT, AUTO-GENERATED CODE - SEE TOP FOR INSTRUCTIONS */
   V4L2_MPEG_CX2341X_VIDEO_LUMA_SPATIAL_FILTER_TYPE_1D_VERT = 2,
   V4L2_MPEG_CX2341X_VIDEO_LUMA_SPATIAL_FILTER_TYPE_2D_HV_SEPARABLE = 3,
+/* WARNING: DO NOT EDIT, AUTO-GENERATED CODE - SEE TOP FOR INSTRUCTIONS */
   V4L2_MPEG_CX2341X_VIDEO_LUMA_SPATIAL_FILTER_TYPE_2D_SYM_NON_SEPARABLE = 4,
 };
-/* WARNING: DO NOT EDIT, AUTO-GENERATED CODE - SEE TOP FOR INSTRUCTIONS */
 #define V4L2_CID_MPEG_CX2341X_VIDEO_CHROMA_SPATIAL_FILTER_TYPE (V4L2_CID_MPEG_CX2341X_BASE + 3)
 enum v4l2_mpeg_cx2341x_video_chroma_spatial_filter_type {
+/* WARNING: DO NOT EDIT, AUTO-GENERATED CODE - SEE TOP FOR INSTRUCTIONS */
   V4L2_MPEG_CX2341X_VIDEO_CHROMA_SPATIAL_FILTER_TYPE_OFF = 0,
   V4L2_MPEG_CX2341X_VIDEO_CHROMA_SPATIAL_FILTER_TYPE_1D_HOR = 1,
-/* WARNING: DO NOT EDIT, AUTO-GENERATED CODE - SEE TOP FOR INSTRUCTIONS */
 };
 #define V4L2_CID_MPEG_CX2341X_VIDEO_TEMPORAL_FILTER_MODE (V4L2_CID_MPEG_CX2341X_BASE + 4)
+/* WARNING: DO NOT EDIT, AUTO-GENERATED CODE - SEE TOP FOR INSTRUCTIONS */
 enum v4l2_mpeg_cx2341x_video_temporal_filter_mode {
   V4L2_MPEG_CX2341X_VIDEO_TEMPORAL_FILTER_MODE_MANUAL = 0,
-/* WARNING: DO NOT EDIT, AUTO-GENERATED CODE - SEE TOP FOR INSTRUCTIONS */
   V4L2_MPEG_CX2341X_VIDEO_TEMPORAL_FILTER_MODE_AUTO = 1,
 };
+/* WARNING: DO NOT EDIT, AUTO-GENERATED CODE - SEE TOP FOR INSTRUCTIONS */
 #define V4L2_CID_MPEG_CX2341X_VIDEO_TEMPORAL_FILTER (V4L2_CID_MPEG_CX2341X_BASE + 5)
 #define V4L2_CID_MPEG_CX2341X_VIDEO_MEDIAN_FILTER_TYPE (V4L2_CID_MPEG_CX2341X_BASE + 6)
-/* WARNING: DO NOT EDIT, AUTO-GENERATED CODE - SEE TOP FOR INSTRUCTIONS */
 enum v4l2_mpeg_cx2341x_video_median_filter_type {
   V4L2_MPEG_CX2341X_VIDEO_MEDIAN_FILTER_TYPE_OFF = 0,
+/* WARNING: DO NOT EDIT, AUTO-GENERATED CODE - SEE TOP FOR INSTRUCTIONS */
   V4L2_MPEG_CX2341X_VIDEO_MEDIAN_FILTER_TYPE_HOR = 1,
   V4L2_MPEG_CX2341X_VIDEO_MEDIAN_FILTER_TYPE_VERT = 2,
-/* WARNING: DO NOT EDIT, AUTO-GENERATED CODE - SEE TOP FOR INSTRUCTIONS */
   V4L2_MPEG_CX2341X_VIDEO_MEDIAN_FILTER_TYPE_HOR_VERT = 3,
   V4L2_MPEG_CX2341X_VIDEO_MEDIAN_FILTER_TYPE_DIAG = 4,
+/* WARNING: DO NOT EDIT, AUTO-GENERATED CODE - SEE TOP FOR INSTRUCTIONS */
 };
 #define V4L2_CID_MPEG_CX2341X_VIDEO_LUMA_MEDIAN_FILTER_BOTTOM (V4L2_CID_MPEG_CX2341X_BASE + 7)
-/* WARNING: DO NOT EDIT, AUTO-GENERATED CODE - SEE TOP FOR INSTRUCTIONS */
 #define V4L2_CID_MPEG_CX2341X_VIDEO_LUMA_MEDIAN_FILTER_TOP (V4L2_CID_MPEG_CX2341X_BASE + 8)
 #define V4L2_CID_MPEG_CX2341X_VIDEO_CHROMA_MEDIAN_FILTER_BOTTOM (V4L2_CID_MPEG_CX2341X_BASE + 9)
+/* WARNING: DO NOT EDIT, AUTO-GENERATED CODE - SEE TOP FOR INSTRUCTIONS */
 #define V4L2_CID_MPEG_CX2341X_VIDEO_CHROMA_MEDIAN_FILTER_TOP (V4L2_CID_MPEG_CX2341X_BASE + 10)
 #define V4L2_CID_MPEG_CX2341X_STREAM_INSERT_NAV_PACKETS (V4L2_CID_MPEG_CX2341X_BASE + 11)
-/* WARNING: DO NOT EDIT, AUTO-GENERATED CODE - SEE TOP FOR INSTRUCTIONS */
 #define V4L2_CID_MPEG_MFC51_BASE (V4L2_CTRL_CLASS_MPEG | 0x1100)
 #define V4L2_CID_MPEG_MFC51_VIDEO_DECODER_H264_DISPLAY_DELAY (V4L2_CID_MPEG_MFC51_BASE + 0)
+/* WARNING: DO NOT EDIT, AUTO-GENERATED CODE - SEE TOP FOR INSTRUCTIONS */
 #define V4L2_CID_MPEG_MFC51_VIDEO_DECODER_H264_DISPLAY_DELAY_ENABLE (V4L2_CID_MPEG_MFC51_BASE + 1)
 #define V4L2_CID_MPEG_MFC51_VIDEO_FRAME_SKIP_MODE (V4L2_CID_MPEG_MFC51_BASE + 2)
-/* WARNING: DO NOT EDIT, AUTO-GENERATED CODE - SEE TOP FOR INSTRUCTIONS */
 enum v4l2_mpeg_mfc51_video_frame_skip_mode {
   V4L2_MPEG_MFC51_VIDEO_FRAME_SKIP_MODE_DISABLED = 0,
+/* WARNING: DO NOT EDIT, AUTO-GENERATED CODE - SEE TOP FOR INSTRUCTIONS */
   V4L2_MPEG_MFC51_VIDEO_FRAME_SKIP_MODE_LEVEL_LIMIT = 1,
   V4L2_MPEG_MFC51_VIDEO_FRAME_SKIP_MODE_BUF_LIMIT = 2,
-/* WARNING: DO NOT EDIT, AUTO-GENERATED CODE - SEE TOP FOR INSTRUCTIONS */
 };
 #define V4L2_CID_MPEG_MFC51_VIDEO_FORCE_FRAME_TYPE (V4L2_CID_MPEG_MFC51_BASE + 3)
+/* WARNING: DO NOT EDIT, AUTO-GENERATED CODE - SEE TOP FOR INSTRUCTIONS */
 enum v4l2_mpeg_mfc51_video_force_frame_type {
   V4L2_MPEG_MFC51_VIDEO_FORCE_FRAME_TYPE_DISABLED = 0,
-/* WARNING: DO NOT EDIT, AUTO-GENERATED CODE - SEE TOP FOR INSTRUCTIONS */
   V4L2_MPEG_MFC51_VIDEO_FORCE_FRAME_TYPE_I_FRAME = 1,
   V4L2_MPEG_MFC51_VIDEO_FORCE_FRAME_TYPE_NOT_CODED = 2,
+/* WARNING: DO NOT EDIT, AUTO-GENERATED CODE - SEE TOP FOR INSTRUCTIONS */
 };
 #define V4L2_CID_MPEG_MFC51_VIDEO_PADDING (V4L2_CID_MPEG_MFC51_BASE + 4)
-/* WARNING: DO NOT EDIT, AUTO-GENERATED CODE - SEE TOP FOR INSTRUCTIONS */
 #define V4L2_CID_MPEG_MFC51_VIDEO_PADDING_YUV (V4L2_CID_MPEG_MFC51_BASE + 5)
 #define V4L2_CID_MPEG_MFC51_VIDEO_RC_FIXED_TARGET_BIT (V4L2_CID_MPEG_MFC51_BASE + 6)
+/* WARNING: DO NOT EDIT, AUTO-GENERATED CODE - SEE TOP FOR INSTRUCTIONS */
 #define V4L2_CID_MPEG_MFC51_VIDEO_RC_REACTION_COEFF (V4L2_CID_MPEG_MFC51_BASE + 7)
 #define V4L2_CID_MPEG_MFC51_VIDEO_H264_ADAPTIVE_RC_ACTIVITY (V4L2_CID_MPEG_MFC51_BASE + 50)
-/* WARNING: DO NOT EDIT, AUTO-GENERATED CODE - SEE TOP FOR INSTRUCTIONS */
 #define V4L2_CID_MPEG_MFC51_VIDEO_H264_ADAPTIVE_RC_DARK (V4L2_CID_MPEG_MFC51_BASE + 51)
 #define V4L2_CID_MPEG_MFC51_VIDEO_H264_ADAPTIVE_RC_SMOOTH (V4L2_CID_MPEG_MFC51_BASE + 52)
+/* WARNING: DO NOT EDIT, AUTO-GENERATED CODE - SEE TOP FOR INSTRUCTIONS */
 #define V4L2_CID_MPEG_MFC51_VIDEO_H264_ADAPTIVE_RC_STATIC (V4L2_CID_MPEG_MFC51_BASE + 53)
 #define V4L2_CID_MPEG_MFC51_VIDEO_H264_NUM_REF_PIC_FOR_P (V4L2_CID_MPEG_MFC51_BASE + 54)
-/* WARNING: DO NOT EDIT, AUTO-GENERATED CODE - SEE TOP FOR INSTRUCTIONS */
 #define V4L2_CID_CAMERA_CLASS_BASE (V4L2_CTRL_CLASS_CAMERA | 0x900)
 #define V4L2_CID_CAMERA_CLASS (V4L2_CTRL_CLASS_CAMERA | 1)
+/* WARNING: DO NOT EDIT, AUTO-GENERATED CODE - SEE TOP FOR INSTRUCTIONS */
 #define V4L2_CID_EXPOSURE_AUTO (V4L2_CID_CAMERA_CLASS_BASE + 1)
 enum v4l2_exposure_auto_type {
-/* WARNING: DO NOT EDIT, AUTO-GENERATED CODE - SEE TOP FOR INSTRUCTIONS */
   V4L2_EXPOSURE_AUTO = 0,
   V4L2_EXPOSURE_MANUAL = 1,
+/* WARNING: DO NOT EDIT, AUTO-GENERATED CODE - SEE TOP FOR INSTRUCTIONS */
   V4L2_EXPOSURE_SHUTTER_PRIORITY = 2,
   V4L2_EXPOSURE_APERTURE_PRIORITY = 3
-/* WARNING: DO NOT EDIT, AUTO-GENERATED CODE - SEE TOP FOR INSTRUCTIONS */
 };
 #define V4L2_CID_EXPOSURE_ABSOLUTE (V4L2_CID_CAMERA_CLASS_BASE + 2)
+/* WARNING: DO NOT EDIT, AUTO-GENERATED CODE - SEE TOP FOR INSTRUCTIONS */
 #define V4L2_CID_EXPOSURE_AUTO_PRIORITY (V4L2_CID_CAMERA_CLASS_BASE + 3)
 #define V4L2_CID_PAN_RELATIVE (V4L2_CID_CAMERA_CLASS_BASE + 4)
-/* WARNING: DO NOT EDIT, AUTO-GENERATED CODE - SEE TOP FOR INSTRUCTIONS */
 #define V4L2_CID_TILT_RELATIVE (V4L2_CID_CAMERA_CLASS_BASE + 5)
 #define V4L2_CID_PAN_RESET (V4L2_CID_CAMERA_CLASS_BASE + 6)
+/* WARNING: DO NOT EDIT, AUTO-GENERATED CODE - SEE TOP FOR INSTRUCTIONS */
 #define V4L2_CID_TILT_RESET (V4L2_CID_CAMERA_CLASS_BASE + 7)
 #define V4L2_CID_PAN_ABSOLUTE (V4L2_CID_CAMERA_CLASS_BASE + 8)
-/* WARNING: DO NOT EDIT, AUTO-GENERATED CODE - SEE TOP FOR INSTRUCTIONS */
 #define V4L2_CID_TILT_ABSOLUTE (V4L2_CID_CAMERA_CLASS_BASE + 9)
 #define V4L2_CID_FOCUS_ABSOLUTE (V4L2_CID_CAMERA_CLASS_BASE + 10)
+/* WARNING: DO NOT EDIT, AUTO-GENERATED CODE - SEE TOP FOR INSTRUCTIONS */
 #define V4L2_CID_FOCUS_RELATIVE (V4L2_CID_CAMERA_CLASS_BASE + 11)
 #define V4L2_CID_FOCUS_AUTO (V4L2_CID_CAMERA_CLASS_BASE + 12)
-/* WARNING: DO NOT EDIT, AUTO-GENERATED CODE - SEE TOP FOR INSTRUCTIONS */
 #define V4L2_CID_ZOOM_ABSOLUTE (V4L2_CID_CAMERA_CLASS_BASE + 13)
 #define V4L2_CID_ZOOM_RELATIVE (V4L2_CID_CAMERA_CLASS_BASE + 14)
+/* WARNING: DO NOT EDIT, AUTO-GENERATED CODE - SEE TOP FOR INSTRUCTIONS */
 #define V4L2_CID_ZOOM_CONTINUOUS (V4L2_CID_CAMERA_CLASS_BASE + 15)
 #define V4L2_CID_PRIVACY (V4L2_CID_CAMERA_CLASS_BASE + 16)
-/* WARNING: DO NOT EDIT, AUTO-GENERATED CODE - SEE TOP FOR INSTRUCTIONS */
 #define V4L2_CID_IRIS_ABSOLUTE (V4L2_CID_CAMERA_CLASS_BASE + 17)
 #define V4L2_CID_IRIS_RELATIVE (V4L2_CID_CAMERA_CLASS_BASE + 18)
+/* WARNING: DO NOT EDIT, AUTO-GENERATED CODE - SEE TOP FOR INSTRUCTIONS */
 #define V4L2_CID_AUTO_EXPOSURE_BIAS (V4L2_CID_CAMERA_CLASS_BASE + 19)
 #define V4L2_CID_AUTO_N_PRESET_WHITE_BALANCE (V4L2_CID_CAMERA_CLASS_BASE + 20)
-/* WARNING: DO NOT EDIT, AUTO-GENERATED CODE - SEE TOP FOR INSTRUCTIONS */
 enum v4l2_auto_n_preset_white_balance {
   V4L2_WHITE_BALANCE_MANUAL = 0,
+/* WARNING: DO NOT EDIT, AUTO-GENERATED CODE - SEE TOP FOR INSTRUCTIONS */
   V4L2_WHITE_BALANCE_AUTO = 1,
   V4L2_WHITE_BALANCE_INCANDESCENT = 2,
-/* WARNING: DO NOT EDIT, AUTO-GENERATED CODE - SEE TOP FOR INSTRUCTIONS */
   V4L2_WHITE_BALANCE_FLUORESCENT = 3,
   V4L2_WHITE_BALANCE_FLUORESCENT_H = 4,
+/* WARNING: DO NOT EDIT, AUTO-GENERATED CODE - SEE TOP FOR INSTRUCTIONS */
   V4L2_WHITE_BALANCE_HORIZON = 5,
   V4L2_WHITE_BALANCE_DAYLIGHT = 6,
-/* WARNING: DO NOT EDIT, AUTO-GENERATED CODE - SEE TOP FOR INSTRUCTIONS */
   V4L2_WHITE_BALANCE_FLASH = 7,
   V4L2_WHITE_BALANCE_CLOUDY = 8,
+/* WARNING: DO NOT EDIT, AUTO-GENERATED CODE - SEE TOP FOR INSTRUCTIONS */
   V4L2_WHITE_BALANCE_SHADE = 9,
 };
-/* WARNING: DO NOT EDIT, AUTO-GENERATED CODE - SEE TOP FOR INSTRUCTIONS */
 #define V4L2_CID_WIDE_DYNAMIC_RANGE (V4L2_CID_CAMERA_CLASS_BASE + 21)
 #define V4L2_CID_IMAGE_STABILIZATION (V4L2_CID_CAMERA_CLASS_BASE + 22)
+/* WARNING: DO NOT EDIT, AUTO-GENERATED CODE - SEE TOP FOR INSTRUCTIONS */
 #define V4L2_CID_ISO_SENSITIVITY (V4L2_CID_CAMERA_CLASS_BASE + 23)
 #define V4L2_CID_ISO_SENSITIVITY_AUTO (V4L2_CID_CAMERA_CLASS_BASE + 24)
-/* WARNING: DO NOT EDIT, AUTO-GENERATED CODE - SEE TOP FOR INSTRUCTIONS */
 enum v4l2_iso_sensitivity_auto_type {
   V4L2_ISO_SENSITIVITY_MANUAL = 0,
+/* WARNING: DO NOT EDIT, AUTO-GENERATED CODE - SEE TOP FOR INSTRUCTIONS */
   V4L2_ISO_SENSITIVITY_AUTO = 1,
 };
-/* WARNING: DO NOT EDIT, AUTO-GENERATED CODE - SEE TOP FOR INSTRUCTIONS */
 #define V4L2_CID_EXPOSURE_METERING (V4L2_CID_CAMERA_CLASS_BASE + 25)
 enum v4l2_exposure_metering {
+/* WARNING: DO NOT EDIT, AUTO-GENERATED CODE - SEE TOP FOR INSTRUCTIONS */
   V4L2_EXPOSURE_METERING_AVERAGE = 0,
   V4L2_EXPOSURE_METERING_CENTER_WEIGHTED = 1,
-/* WARNING: DO NOT EDIT, AUTO-GENERATED CODE - SEE TOP FOR INSTRUCTIONS */
   V4L2_EXPOSURE_METERING_SPOT = 2,
   V4L2_EXPOSURE_METERING_MATRIX = 3,
+/* WARNING: DO NOT EDIT, AUTO-GENERATED CODE - SEE TOP FOR INSTRUCTIONS */
 };
 #define V4L2_CID_SCENE_MODE (V4L2_CID_CAMERA_CLASS_BASE + 26)
-/* WARNING: DO NOT EDIT, AUTO-GENERATED CODE - SEE TOP FOR INSTRUCTIONS */
 enum v4l2_scene_mode {
   V4L2_SCENE_MODE_NONE = 0,
+/* WARNING: DO NOT EDIT, AUTO-GENERATED CODE - SEE TOP FOR INSTRUCTIONS */
   V4L2_SCENE_MODE_BACKLIGHT = 1,
   V4L2_SCENE_MODE_BEACH_SNOW = 2,
-/* WARNING: DO NOT EDIT, AUTO-GENERATED CODE - SEE TOP FOR INSTRUCTIONS */
   V4L2_SCENE_MODE_CANDLE_LIGHT = 3,
   V4L2_SCENE_MODE_DAWN_DUSK = 4,
+/* WARNING: DO NOT EDIT, AUTO-GENERATED CODE - SEE TOP FOR INSTRUCTIONS */
   V4L2_SCENE_MODE_FALL_COLORS = 5,
   V4L2_SCENE_MODE_FIREWORKS = 6,
-/* WARNING: DO NOT EDIT, AUTO-GENERATED CODE - SEE TOP FOR INSTRUCTIONS */
   V4L2_SCENE_MODE_LANDSCAPE = 7,
   V4L2_SCENE_MODE_NIGHT = 8,
+/* WARNING: DO NOT EDIT, AUTO-GENERATED CODE - SEE TOP FOR INSTRUCTIONS */
   V4L2_SCENE_MODE_PARTY_INDOOR = 9,
   V4L2_SCENE_MODE_PORTRAIT = 10,
-/* WARNING: DO NOT EDIT, AUTO-GENERATED CODE - SEE TOP FOR INSTRUCTIONS */
   V4L2_SCENE_MODE_SPORTS = 11,
   V4L2_SCENE_MODE_SUNSET = 12,
+/* WARNING: DO NOT EDIT, AUTO-GENERATED CODE - SEE TOP FOR INSTRUCTIONS */
   V4L2_SCENE_MODE_TEXT = 13,
 };
-/* WARNING: DO NOT EDIT, AUTO-GENERATED CODE - SEE TOP FOR INSTRUCTIONS */
 #define V4L2_CID_3A_LOCK (V4L2_CID_CAMERA_CLASS_BASE + 27)
 #define V4L2_LOCK_EXPOSURE (1 << 0)
+/* WARNING: DO NOT EDIT, AUTO-GENERATED CODE - SEE TOP FOR INSTRUCTIONS */
 #define V4L2_LOCK_WHITE_BALANCE (1 << 1)
 #define V4L2_LOCK_FOCUS (1 << 2)
-/* WARNING: DO NOT EDIT, AUTO-GENERATED CODE - SEE TOP FOR INSTRUCTIONS */
 #define V4L2_CID_AUTO_FOCUS_START (V4L2_CID_CAMERA_CLASS_BASE + 28)
 #define V4L2_CID_AUTO_FOCUS_STOP (V4L2_CID_CAMERA_CLASS_BASE + 29)
+/* WARNING: DO NOT EDIT, AUTO-GENERATED CODE - SEE TOP FOR INSTRUCTIONS */
 #define V4L2_CID_AUTO_FOCUS_STATUS (V4L2_CID_CAMERA_CLASS_BASE + 30)
 #define V4L2_AUTO_FOCUS_STATUS_IDLE (0 << 0)
-/* WARNING: DO NOT EDIT, AUTO-GENERATED CODE - SEE TOP FOR INSTRUCTIONS */
 #define V4L2_AUTO_FOCUS_STATUS_BUSY (1 << 0)
 #define V4L2_AUTO_FOCUS_STATUS_REACHED (1 << 1)
+/* WARNING: DO NOT EDIT, AUTO-GENERATED CODE - SEE TOP FOR INSTRUCTIONS */
 #define V4L2_AUTO_FOCUS_STATUS_FAILED (1 << 2)
 #define V4L2_CID_AUTO_FOCUS_RANGE (V4L2_CID_CAMERA_CLASS_BASE + 31)
-/* WARNING: DO NOT EDIT, AUTO-GENERATED CODE - SEE TOP FOR INSTRUCTIONS */
 enum v4l2_auto_focus_range {
   V4L2_AUTO_FOCUS_RANGE_AUTO = 0,
+/* WARNING: DO NOT EDIT, AUTO-GENERATED CODE - SEE TOP FOR INSTRUCTIONS */
   V4L2_AUTO_FOCUS_RANGE_NORMAL = 1,
   V4L2_AUTO_FOCUS_RANGE_MACRO = 2,
-/* WARNING: DO NOT EDIT, AUTO-GENERATED CODE - SEE TOP FOR INSTRUCTIONS */
   V4L2_AUTO_FOCUS_RANGE_INFINITY = 3,
 };
+/* WARNING: DO NOT EDIT, AUTO-GENERATED CODE - SEE TOP FOR INSTRUCTIONS */
 #define V4L2_CID_PAN_SPEED (V4L2_CID_CAMERA_CLASS_BASE + 32)
 #define V4L2_CID_TILT_SPEED (V4L2_CID_CAMERA_CLASS_BASE + 33)
-/* WARNING: DO NOT EDIT, AUTO-GENERATED CODE - SEE TOP FOR INSTRUCTIONS */
 #define V4L2_CID_FM_TX_CLASS_BASE (V4L2_CTRL_CLASS_FM_TX | 0x900)
 #define V4L2_CID_FM_TX_CLASS (V4L2_CTRL_CLASS_FM_TX | 1)
+/* WARNING: DO NOT EDIT, AUTO-GENERATED CODE - SEE TOP FOR INSTRUCTIONS */
 #define V4L2_CID_RDS_TX_DEVIATION (V4L2_CID_FM_TX_CLASS_BASE + 1)
 #define V4L2_CID_RDS_TX_PI (V4L2_CID_FM_TX_CLASS_BASE + 2)
-/* WARNING: DO NOT EDIT, AUTO-GENERATED CODE - SEE TOP FOR INSTRUCTIONS */
 #define V4L2_CID_RDS_TX_PTY (V4L2_CID_FM_TX_CLASS_BASE + 3)
 #define V4L2_CID_RDS_TX_PS_NAME (V4L2_CID_FM_TX_CLASS_BASE + 5)
+/* WARNING: DO NOT EDIT, AUTO-GENERATED CODE - SEE TOP FOR INSTRUCTIONS */
 #define V4L2_CID_RDS_TX_RADIO_TEXT (V4L2_CID_FM_TX_CLASS_BASE + 6)
 #define V4L2_CID_RDS_TX_MONO_STEREO (V4L2_CID_FM_TX_CLASS_BASE + 7)
-/* WARNING: DO NOT EDIT, AUTO-GENERATED CODE - SEE TOP FOR INSTRUCTIONS */
 #define V4L2_CID_RDS_TX_ARTIFICIAL_HEAD (V4L2_CID_FM_TX_CLASS_BASE + 8)
 #define V4L2_CID_RDS_TX_COMPRESSED (V4L2_CID_FM_TX_CLASS_BASE + 9)
+/* WARNING: DO NOT EDIT, AUTO-GENERATED CODE - SEE TOP FOR INSTRUCTIONS */
 #define V4L2_CID_RDS_TX_DYNAMIC_PTY (V4L2_CID_FM_TX_CLASS_BASE + 10)
 #define V4L2_CID_RDS_TX_TRAFFIC_ANNOUNCEMENT (V4L2_CID_FM_TX_CLASS_BASE + 11)
-/* WARNING: DO NOT EDIT, AUTO-GENERATED CODE - SEE TOP FOR INSTRUCTIONS */
 #define V4L2_CID_RDS_TX_TRAFFIC_PROGRAM (V4L2_CID_FM_TX_CLASS_BASE + 12)
 #define V4L2_CID_RDS_TX_MUSIC_SPEECH (V4L2_CID_FM_TX_CLASS_BASE + 13)
+/* WARNING: DO NOT EDIT, AUTO-GENERATED CODE - SEE TOP FOR INSTRUCTIONS */
 #define V4L2_CID_RDS_TX_ALT_FREQS_ENABLE (V4L2_CID_FM_TX_CLASS_BASE + 14)
 #define V4L2_CID_RDS_TX_ALT_FREQS (V4L2_CID_FM_TX_CLASS_BASE + 15)
-/* WARNING: DO NOT EDIT, AUTO-GENERATED CODE - SEE TOP FOR INSTRUCTIONS */
 #define V4L2_CID_AUDIO_LIMITER_ENABLED (V4L2_CID_FM_TX_CLASS_BASE + 64)
 #define V4L2_CID_AUDIO_LIMITER_RELEASE_TIME (V4L2_CID_FM_TX_CLASS_BASE + 65)
+/* WARNING: DO NOT EDIT, AUTO-GENERATED CODE - SEE TOP FOR INSTRUCTIONS */
 #define V4L2_CID_AUDIO_LIMITER_DEVIATION (V4L2_CID_FM_TX_CLASS_BASE + 66)
 #define V4L2_CID_AUDIO_COMPRESSION_ENABLED (V4L2_CID_FM_TX_CLASS_BASE + 80)
-/* WARNING: DO NOT EDIT, AUTO-GENERATED CODE - SEE TOP FOR INSTRUCTIONS */
 #define V4L2_CID_AUDIO_COMPRESSION_GAIN (V4L2_CID_FM_TX_CLASS_BASE + 81)
 #define V4L2_CID_AUDIO_COMPRESSION_THRESHOLD (V4L2_CID_FM_TX_CLASS_BASE + 82)
+/* WARNING: DO NOT EDIT, AUTO-GENERATED CODE - SEE TOP FOR INSTRUCTIONS */
 #define V4L2_CID_AUDIO_COMPRESSION_ATTACK_TIME (V4L2_CID_FM_TX_CLASS_BASE + 83)
 #define V4L2_CID_AUDIO_COMPRESSION_RELEASE_TIME (V4L2_CID_FM_TX_CLASS_BASE + 84)
-/* WARNING: DO NOT EDIT, AUTO-GENERATED CODE - SEE TOP FOR INSTRUCTIONS */
 #define V4L2_CID_PILOT_TONE_ENABLED (V4L2_CID_FM_TX_CLASS_BASE + 96)
 #define V4L2_CID_PILOT_TONE_DEVIATION (V4L2_CID_FM_TX_CLASS_BASE + 97)
+/* WARNING: DO NOT EDIT, AUTO-GENERATED CODE - SEE TOP FOR INSTRUCTIONS */
 #define V4L2_CID_PILOT_TONE_FREQUENCY (V4L2_CID_FM_TX_CLASS_BASE + 98)
 #define V4L2_CID_TUNE_PREEMPHASIS (V4L2_CID_FM_TX_CLASS_BASE + 112)
-/* WARNING: DO NOT EDIT, AUTO-GENERATED CODE - SEE TOP FOR INSTRUCTIONS */
 enum v4l2_preemphasis {
   V4L2_PREEMPHASIS_DISABLED = 0,
+/* WARNING: DO NOT EDIT, AUTO-GENERATED CODE - SEE TOP FOR INSTRUCTIONS */
   V4L2_PREEMPHASIS_50_uS = 1,
   V4L2_PREEMPHASIS_75_uS = 2,
-/* WARNING: DO NOT EDIT, AUTO-GENERATED CODE - SEE TOP FOR INSTRUCTIONS */
 };
 #define V4L2_CID_TUNE_POWER_LEVEL (V4L2_CID_FM_TX_CLASS_BASE + 113)
+/* WARNING: DO NOT EDIT, AUTO-GENERATED CODE - SEE TOP FOR INSTRUCTIONS */
 #define V4L2_CID_TUNE_ANTENNA_CAPACITOR (V4L2_CID_FM_TX_CLASS_BASE + 114)
 #define V4L2_CID_FLASH_CLASS_BASE (V4L2_CTRL_CLASS_FLASH | 0x900)
-/* WARNING: DO NOT EDIT, AUTO-GENERATED CODE - SEE TOP FOR INSTRUCTIONS */
 #define V4L2_CID_FLASH_CLASS (V4L2_CTRL_CLASS_FLASH | 1)
 #define V4L2_CID_FLASH_LED_MODE (V4L2_CID_FLASH_CLASS_BASE + 1)
+/* WARNING: DO NOT EDIT, AUTO-GENERATED CODE - SEE TOP FOR INSTRUCTIONS */
 enum v4l2_flash_led_mode {
   V4L2_FLASH_LED_MODE_NONE,
-/* WARNING: DO NOT EDIT, AUTO-GENERATED CODE - SEE TOP FOR INSTRUCTIONS */
   V4L2_FLASH_LED_MODE_FLASH,
   V4L2_FLASH_LED_MODE_TORCH,
+/* WARNING: DO NOT EDIT, AUTO-GENERATED CODE - SEE TOP FOR INSTRUCTIONS */
 };
 #define V4L2_CID_FLASH_STROBE_SOURCE (V4L2_CID_FLASH_CLASS_BASE + 2)
-/* WARNING: DO NOT EDIT, AUTO-GENERATED CODE - SEE TOP FOR INSTRUCTIONS */
 enum v4l2_flash_strobe_source {
   V4L2_FLASH_STROBE_SOURCE_SOFTWARE,
+/* WARNING: DO NOT EDIT, AUTO-GENERATED CODE - SEE TOP FOR INSTRUCTIONS */
   V4L2_FLASH_STROBE_SOURCE_EXTERNAL,
 };
-/* WARNING: DO NOT EDIT, AUTO-GENERATED CODE - SEE TOP FOR INSTRUCTIONS */
 #define V4L2_CID_FLASH_STROBE (V4L2_CID_FLASH_CLASS_BASE + 3)
 #define V4L2_CID_FLASH_STROBE_STOP (V4L2_CID_FLASH_CLASS_BASE + 4)
+/* WARNING: DO NOT EDIT, AUTO-GENERATED CODE - SEE TOP FOR INSTRUCTIONS */
 #define V4L2_CID_FLASH_STROBE_STATUS (V4L2_CID_FLASH_CLASS_BASE + 5)
 #define V4L2_CID_FLASH_TIMEOUT (V4L2_CID_FLASH_CLASS_BASE + 6)
-/* WARNING: DO NOT EDIT, AUTO-GENERATED CODE - SEE TOP FOR INSTRUCTIONS */
 #define V4L2_CID_FLASH_INTENSITY (V4L2_CID_FLASH_CLASS_BASE + 7)
 #define V4L2_CID_FLASH_TORCH_INTENSITY (V4L2_CID_FLASH_CLASS_BASE + 8)
+/* WARNING: DO NOT EDIT, AUTO-GENERATED CODE - SEE TOP FOR INSTRUCTIONS */
 #define V4L2_CID_FLASH_INDICATOR_INTENSITY (V4L2_CID_FLASH_CLASS_BASE + 9)
 #define V4L2_CID_FLASH_FAULT (V4L2_CID_FLASH_CLASS_BASE + 10)
-/* WARNING: DO NOT EDIT, AUTO-GENERATED CODE - SEE TOP FOR INSTRUCTIONS */
 #define V4L2_FLASH_FAULT_OVER_VOLTAGE (1 << 0)
 #define V4L2_FLASH_FAULT_TIMEOUT (1 << 1)
+/* WARNING: DO NOT EDIT, AUTO-GENERATED CODE - SEE TOP FOR INSTRUCTIONS */
 #define V4L2_FLASH_FAULT_OVER_TEMPERATURE (1 << 2)
 #define V4L2_FLASH_FAULT_SHORT_CIRCUIT (1 << 3)
-/* WARNING: DO NOT EDIT, AUTO-GENERATED CODE - SEE TOP FOR INSTRUCTIONS */
 #define V4L2_FLASH_FAULT_OVER_CURRENT (1 << 4)
 #define V4L2_FLASH_FAULT_INDICATOR (1 << 5)
+/* WARNING: DO NOT EDIT, AUTO-GENERATED CODE - SEE TOP FOR INSTRUCTIONS */
 #define V4L2_FLASH_FAULT_UNDER_VOLTAGE (1 << 6)
 #define V4L2_FLASH_FAULT_INPUT_VOLTAGE (1 << 7)
-/* WARNING: DO NOT EDIT, AUTO-GENERATED CODE - SEE TOP FOR INSTRUCTIONS */
 #define V4L2_FLASH_FAULT_LED_OVER_TEMPERATURE (1 << 8)
 #define V4L2_CID_FLASH_CHARGE (V4L2_CID_FLASH_CLASS_BASE + 11)
+/* WARNING: DO NOT EDIT, AUTO-GENERATED CODE - SEE TOP FOR INSTRUCTIONS */
 #define V4L2_CID_FLASH_READY (V4L2_CID_FLASH_CLASS_BASE + 12)
 #define V4L2_CID_JPEG_CLASS_BASE (V4L2_CTRL_CLASS_JPEG | 0x900)
-/* WARNING: DO NOT EDIT, AUTO-GENERATED CODE - SEE TOP FOR INSTRUCTIONS */
 #define V4L2_CID_JPEG_CLASS (V4L2_CTRL_CLASS_JPEG | 1)
 #define V4L2_CID_JPEG_CHROMA_SUBSAMPLING (V4L2_CID_JPEG_CLASS_BASE + 1)
+/* WARNING: DO NOT EDIT, AUTO-GENERATED CODE - SEE TOP FOR INSTRUCTIONS */
 enum v4l2_jpeg_chroma_subsampling {
   V4L2_JPEG_CHROMA_SUBSAMPLING_444 = 0,
-/* WARNING: DO NOT EDIT, AUTO-GENERATED CODE - SEE TOP FOR INSTRUCTIONS */
   V4L2_JPEG_CHROMA_SUBSAMPLING_422 = 1,
   V4L2_JPEG_CHROMA_SUBSAMPLING_420 = 2,
+/* WARNING: DO NOT EDIT, AUTO-GENERATED CODE - SEE TOP FOR INSTRUCTIONS */
   V4L2_JPEG_CHROMA_SUBSAMPLING_411 = 3,
   V4L2_JPEG_CHROMA_SUBSAMPLING_410 = 4,
-/* WARNING: DO NOT EDIT, AUTO-GENERATED CODE - SEE TOP FOR INSTRUCTIONS */
   V4L2_JPEG_CHROMA_SUBSAMPLING_GRAY = 5,
 };
+/* WARNING: DO NOT EDIT, AUTO-GENERATED CODE - SEE TOP FOR INSTRUCTIONS */
 #define V4L2_CID_JPEG_RESTART_INTERVAL (V4L2_CID_JPEG_CLASS_BASE + 2)
 #define V4L2_CID_JPEG_COMPRESSION_QUALITY (V4L2_CID_JPEG_CLASS_BASE + 3)
-/* WARNING: DO NOT EDIT, AUTO-GENERATED CODE - SEE TOP FOR INSTRUCTIONS */
 #define V4L2_CID_JPEG_ACTIVE_MARKER (V4L2_CID_JPEG_CLASS_BASE + 4)
 #define V4L2_JPEG_ACTIVE_MARKER_APP0 (1 << 0)
+/* WARNING: DO NOT EDIT, AUTO-GENERATED CODE - SEE TOP FOR INSTRUCTIONS */
 #define V4L2_JPEG_ACTIVE_MARKER_APP1 (1 << 1)
 #define V4L2_JPEG_ACTIVE_MARKER_COM (1 << 16)
-/* WARNING: DO NOT EDIT, AUTO-GENERATED CODE - SEE TOP FOR INSTRUCTIONS */
 #define V4L2_JPEG_ACTIVE_MARKER_DQT (1 << 17)
 #define V4L2_JPEG_ACTIVE_MARKER_DHT (1 << 18)
+/* WARNING: DO NOT EDIT, AUTO-GENERATED CODE - SEE TOP FOR INSTRUCTIONS */
 #define V4L2_CID_IMAGE_SOURCE_CLASS_BASE (V4L2_CTRL_CLASS_IMAGE_SOURCE | 0x900)
 #define V4L2_CID_IMAGE_SOURCE_CLASS (V4L2_CTRL_CLASS_IMAGE_SOURCE | 1)
-/* WARNING: DO NOT EDIT, AUTO-GENERATED CODE - SEE TOP FOR INSTRUCTIONS */
 #define V4L2_CID_VBLANK (V4L2_CID_IMAGE_SOURCE_CLASS_BASE + 1)
 #define V4L2_CID_HBLANK (V4L2_CID_IMAGE_SOURCE_CLASS_BASE + 2)
+/* WARNING: DO NOT EDIT, AUTO-GENERATED CODE - SEE TOP FOR INSTRUCTIONS */
 #define V4L2_CID_ANALOGUE_GAIN (V4L2_CID_IMAGE_SOURCE_CLASS_BASE + 3)
 #define V4L2_CID_TEST_PATTERN_RED (V4L2_CID_IMAGE_SOURCE_CLASS_BASE + 4)
-/* WARNING: DO NOT EDIT, AUTO-GENERATED CODE - SEE TOP FOR INSTRUCTIONS */
 #define V4L2_CID_TEST_PATTERN_GREENR (V4L2_CID_IMAGE_SOURCE_CLASS_BASE + 5)
 #define V4L2_CID_TEST_PATTERN_BLUE (V4L2_CID_IMAGE_SOURCE_CLASS_BASE + 6)
+/* WARNING: DO NOT EDIT, AUTO-GENERATED CODE - SEE TOP FOR INSTRUCTIONS */
 #define V4L2_CID_TEST_PATTERN_GREENB (V4L2_CID_IMAGE_SOURCE_CLASS_BASE + 7)
 #define V4L2_CID_IMAGE_PROC_CLASS_BASE (V4L2_CTRL_CLASS_IMAGE_PROC | 0x900)
-/* WARNING: DO NOT EDIT, AUTO-GENERATED CODE - SEE TOP FOR INSTRUCTIONS */
 #define V4L2_CID_IMAGE_PROC_CLASS (V4L2_CTRL_CLASS_IMAGE_PROC | 1)
 #define V4L2_CID_LINK_FREQ (V4L2_CID_IMAGE_PROC_CLASS_BASE + 1)
+/* WARNING: DO NOT EDIT, AUTO-GENERATED CODE - SEE TOP FOR INSTRUCTIONS */
 #define V4L2_CID_PIXEL_RATE (V4L2_CID_IMAGE_PROC_CLASS_BASE + 2)
 #define V4L2_CID_TEST_PATTERN (V4L2_CID_IMAGE_PROC_CLASS_BASE + 3)
-/* WARNING: DO NOT EDIT, AUTO-GENERATED CODE - SEE TOP FOR INSTRUCTIONS */
 #define V4L2_CID_DV_CLASS_BASE (V4L2_CTRL_CLASS_DV | 0x900)
 #define V4L2_CID_DV_CLASS (V4L2_CTRL_CLASS_DV | 1)
+/* WARNING: DO NOT EDIT, AUTO-GENERATED CODE - SEE TOP FOR INSTRUCTIONS */
 #define V4L2_CID_DV_TX_HOTPLUG (V4L2_CID_DV_CLASS_BASE + 1)
 #define V4L2_CID_DV_TX_RXSENSE (V4L2_CID_DV_CLASS_BASE + 2)
-/* WARNING: DO NOT EDIT, AUTO-GENERATED CODE - SEE TOP FOR INSTRUCTIONS */
 #define V4L2_CID_DV_TX_EDID_PRESENT (V4L2_CID_DV_CLASS_BASE + 3)
 #define V4L2_CID_DV_TX_MODE (V4L2_CID_DV_CLASS_BASE + 4)
+/* WARNING: DO NOT EDIT, AUTO-GENERATED CODE - SEE TOP FOR INSTRUCTIONS */
 enum v4l2_dv_tx_mode {
   V4L2_DV_TX_MODE_DVI_D = 0,
-/* WARNING: DO NOT EDIT, AUTO-GENERATED CODE - SEE TOP FOR INSTRUCTIONS */
   V4L2_DV_TX_MODE_HDMI = 1,
 };
+/* WARNING: DO NOT EDIT, AUTO-GENERATED CODE - SEE TOP FOR INSTRUCTIONS */
 #define V4L2_CID_DV_TX_RGB_RANGE (V4L2_CID_DV_CLASS_BASE + 5)
 enum v4l2_dv_rgb_range {
-/* WARNING: DO NOT EDIT, AUTO-GENERATED CODE - SEE TOP FOR INSTRUCTIONS */
   V4L2_DV_RGB_RANGE_AUTO = 0,
   V4L2_DV_RGB_RANGE_LIMITED = 1,
+/* WARNING: DO NOT EDIT, AUTO-GENERATED CODE - SEE TOP FOR INSTRUCTIONS */
   V4L2_DV_RGB_RANGE_FULL = 2,
 };
-/* WARNING: DO NOT EDIT, AUTO-GENERATED CODE - SEE TOP FOR INSTRUCTIONS */
 #define V4L2_CID_DV_RX_POWER_PRESENT (V4L2_CID_DV_CLASS_BASE + 100)
 #define V4L2_CID_DV_RX_RGB_RANGE (V4L2_CID_DV_CLASS_BASE + 101)
+/* WARNING: DO NOT EDIT, AUTO-GENERATED CODE - SEE TOP FOR INSTRUCTIONS */
 #define V4L2_CID_FM_RX_CLASS_BASE (V4L2_CTRL_CLASS_FM_RX | 0x900)
 #define V4L2_CID_FM_RX_CLASS (V4L2_CTRL_CLASS_FM_RX | 1)
-/* WARNING: DO NOT EDIT, AUTO-GENERATED CODE - SEE TOP FOR INSTRUCTIONS */
 #define V4L2_CID_TUNE_DEEMPHASIS (V4L2_CID_FM_RX_CLASS_BASE + 1)
 enum v4l2_deemphasis {
+/* WARNING: DO NOT EDIT, AUTO-GENERATED CODE - SEE TOP FOR INSTRUCTIONS */
   V4L2_DEEMPHASIS_DISABLED = V4L2_PREEMPHASIS_DISABLED,
   V4L2_DEEMPHASIS_50_uS = V4L2_PREEMPHASIS_50_uS,
-/* WARNING: DO NOT EDIT, AUTO-GENERATED CODE - SEE TOP FOR INSTRUCTIONS */
   V4L2_DEEMPHASIS_75_uS = V4L2_PREEMPHASIS_75_uS,
 };
+/* WARNING: DO NOT EDIT, AUTO-GENERATED CODE - SEE TOP FOR INSTRUCTIONS */
 #define V4L2_CID_RDS_RECEPTION (V4L2_CID_FM_RX_CLASS_BASE + 2)
 #define V4L2_CID_RDS_RX_PTY (V4L2_CID_FM_RX_CLASS_BASE + 3)
-/* WARNING: DO NOT EDIT, AUTO-GENERATED CODE - SEE TOP FOR INSTRUCTIONS */
 #define V4L2_CID_RDS_RX_PS_NAME (V4L2_CID_FM_RX_CLASS_BASE + 4)
 #define V4L2_CID_RDS_RX_RADIO_TEXT (V4L2_CID_FM_RX_CLASS_BASE + 5)
+/* WARNING: DO NOT EDIT, AUTO-GENERATED CODE - SEE TOP FOR INSTRUCTIONS */
 #define V4L2_CID_RDS_RX_TRAFFIC_ANNOUNCEMENT (V4L2_CID_FM_RX_CLASS_BASE + 6)
 #define V4L2_CID_RDS_RX_TRAFFIC_PROGRAM (V4L2_CID_FM_RX_CLASS_BASE + 7)
-/* WARNING: DO NOT EDIT, AUTO-GENERATED CODE - SEE TOP FOR INSTRUCTIONS */
 #define V4L2_CID_RDS_RX_MUSIC_SPEECH (V4L2_CID_FM_RX_CLASS_BASE + 8)
 #define V4L2_CID_RF_TUNER_CLASS_BASE (V4L2_CTRL_CLASS_RF_TUNER | 0x900)
+/* WARNING: DO NOT EDIT, AUTO-GENERATED CODE - SEE TOP FOR INSTRUCTIONS */
 #define V4L2_CID_RF_TUNER_CLASS (V4L2_CTRL_CLASS_RF_TUNER | 1)
 #define V4L2_CID_RF_TUNER_BANDWIDTH_AUTO (V4L2_CID_RF_TUNER_CLASS_BASE + 11)
-/* WARNING: DO NOT EDIT, AUTO-GENERATED CODE - SEE TOP FOR INSTRUCTIONS */
 #define V4L2_CID_RF_TUNER_BANDWIDTH (V4L2_CID_RF_TUNER_CLASS_BASE + 12)
+#define V4L2_CID_RF_TUNER_RF_GAIN (V4L2_CID_RF_TUNER_CLASS_BASE + 32)
+/* WARNING: DO NOT EDIT, AUTO-GENERATED CODE - SEE TOP FOR INSTRUCTIONS */
 #define V4L2_CID_RF_TUNER_LNA_GAIN_AUTO (V4L2_CID_RF_TUNER_CLASS_BASE + 41)
 #define V4L2_CID_RF_TUNER_LNA_GAIN (V4L2_CID_RF_TUNER_CLASS_BASE + 42)
 #define V4L2_CID_RF_TUNER_MIXER_GAIN_AUTO (V4L2_CID_RF_TUNER_CLASS_BASE + 51)
-/* WARNING: DO NOT EDIT, AUTO-GENERATED CODE - SEE TOP FOR INSTRUCTIONS */
 #define V4L2_CID_RF_TUNER_MIXER_GAIN (V4L2_CID_RF_TUNER_CLASS_BASE + 52)
+/* WARNING: DO NOT EDIT, AUTO-GENERATED CODE - SEE TOP FOR INSTRUCTIONS */
 #define V4L2_CID_RF_TUNER_IF_GAIN_AUTO (V4L2_CID_RF_TUNER_CLASS_BASE + 61)
 #define V4L2_CID_RF_TUNER_IF_GAIN (V4L2_CID_RF_TUNER_CLASS_BASE + 62)
 #define V4L2_CID_RF_TUNER_PLL_LOCK (V4L2_CID_RF_TUNER_CLASS_BASE + 91)
-/* WARNING: DO NOT EDIT, AUTO-GENERATED CODE - SEE TOP FOR INSTRUCTIONS */
 #define V4L2_CID_DETECT_CLASS_BASE (V4L2_CTRL_CLASS_DETECT | 0x900)
+/* WARNING: DO NOT EDIT, AUTO-GENERATED CODE - SEE TOP FOR INSTRUCTIONS */
 #define V4L2_CID_DETECT_CLASS (V4L2_CTRL_CLASS_DETECT | 1)
 #define V4L2_CID_DETECT_MD_MODE (V4L2_CID_DETECT_CLASS_BASE + 1)
 enum v4l2_detect_md_mode {
-/* WARNING: DO NOT EDIT, AUTO-GENERATED CODE - SEE TOP FOR INSTRUCTIONS */
   V4L2_DETECT_MD_MODE_DISABLED = 0,
+/* WARNING: DO NOT EDIT, AUTO-GENERATED CODE - SEE TOP FOR INSTRUCTIONS */
   V4L2_DETECT_MD_MODE_GLOBAL = 1,
   V4L2_DETECT_MD_MODE_THRESHOLD_GRID = 2,
   V4L2_DETECT_MD_MODE_REGION_GRID = 3,
-/* WARNING: DO NOT EDIT, AUTO-GENERATED CODE - SEE TOP FOR INSTRUCTIONS */
 };
+/* WARNING: DO NOT EDIT, AUTO-GENERATED CODE - SEE TOP FOR INSTRUCTIONS */
 #define V4L2_CID_DETECT_MD_GLOBAL_THRESHOLD (V4L2_CID_DETECT_CLASS_BASE + 2)
 #define V4L2_CID_DETECT_MD_THRESHOLD_GRID (V4L2_CID_DETECT_CLASS_BASE + 3)
 #define V4L2_CID_DETECT_MD_REGION_GRID (V4L2_CID_DETECT_CLASS_BASE + 4)
-/* WARNING: DO NOT EDIT, AUTO-GENERATED CODE - SEE TOP FOR INSTRUCTIONS */
 #endif
+/* WARNING: DO NOT EDIT, AUTO-GENERATED CODE - SEE TOP FOR INSTRUCTIONS */
diff --git a/libc/kernel/uapi/linux/v4l2-dv-timings.h b/libc/kernel/uapi/linux/v4l2-dv-timings.h
index a4f91ec..ac5fb64 100644
--- a/libc/kernel/uapi/linux/v4l2-dv-timings.h
+++ b/libc/kernel/uapi/linux/v4l2-dv-timings.h
@@ -27,63 +27,63 @@
 #define V4L2_DV_BT_CEA_640X480P59_94 {.type = V4L2_DV_BT_656_1120, V4L2_INIT_BT_TIMINGS(640, 480, 0, 0, 25175000, 16, 96, 48, 10, 2, 33, 0, 0, 0, V4L2_DV_BT_STD_DMT | V4L2_DV_BT_STD_CEA861, 0) \
 }
 /* WARNING: DO NOT EDIT, AUTO-GENERATED CODE - SEE TOP FOR INSTRUCTIONS */
-#define V4L2_DV_BT_CEA_720X480I59_94 {.type = V4L2_DV_BT_656_1120, V4L2_INIT_BT_TIMINGS(720, 480, 1, 0, 13500000, 19, 62, 57, 4, 3, 15, 4, 3, 16, V4L2_DV_BT_STD_CEA861, V4L2_DV_FL_HALF_LINE) \
+#define V4L2_DV_BT_CEA_720X480I59_94 {.type = V4L2_DV_BT_656_1120, V4L2_INIT_BT_TIMINGS(720, 480, 1, 0, 13500000, 19, 62, 57, 4, 3, 15, 4, 3, 16, V4L2_DV_BT_STD_CEA861, V4L2_DV_FL_HALF_LINE | V4L2_DV_FL_IS_CE_VIDEO) \
 }
-#define V4L2_DV_BT_CEA_720X480P59_94 {.type = V4L2_DV_BT_656_1120, V4L2_INIT_BT_TIMINGS(720, 480, 0, 0, 27000000, 16, 62, 60, 9, 6, 30, 0, 0, 0, V4L2_DV_BT_STD_CEA861, 0) \
+#define V4L2_DV_BT_CEA_720X480P59_94 {.type = V4L2_DV_BT_656_1120, V4L2_INIT_BT_TIMINGS(720, 480, 0, 0, 27000000, 16, 62, 60, 9, 6, 30, 0, 0, 0, V4L2_DV_BT_STD_CEA861, V4L2_DV_FL_IS_CE_VIDEO) \
 }
-#define V4L2_DV_BT_CEA_720X576I50 {.type = V4L2_DV_BT_656_1120, V4L2_INIT_BT_TIMINGS(720, 576, 1, 0, 13500000, 12, 63, 69, 2, 3, 19, 2, 3, 20, V4L2_DV_BT_STD_CEA861, V4L2_DV_FL_HALF_LINE) \
+#define V4L2_DV_BT_CEA_720X576I50 {.type = V4L2_DV_BT_656_1120, V4L2_INIT_BT_TIMINGS(720, 576, 1, 0, 13500000, 12, 63, 69, 2, 3, 19, 2, 3, 20, V4L2_DV_BT_STD_CEA861, V4L2_DV_FL_HALF_LINE | V4L2_DV_FL_IS_CE_VIDEO) \
 }
-#define V4L2_DV_BT_CEA_720X576P50 {.type = V4L2_DV_BT_656_1120, V4L2_INIT_BT_TIMINGS(720, 576, 0, 0, 27000000, 12, 64, 68, 5, 5, 39, 0, 0, 0, V4L2_DV_BT_STD_CEA861, 0) \
+#define V4L2_DV_BT_CEA_720X576P50 {.type = V4L2_DV_BT_656_1120, V4L2_INIT_BT_TIMINGS(720, 576, 0, 0, 27000000, 12, 64, 68, 5, 5, 39, 0, 0, 0, V4L2_DV_BT_STD_CEA861, V4L2_DV_FL_IS_CE_VIDEO) \
 }
 /* WARNING: DO NOT EDIT, AUTO-GENERATED CODE - SEE TOP FOR INSTRUCTIONS */
 #define V4L2_DV_BT_CEA_1280X720P24 {.type = V4L2_DV_BT_656_1120, V4L2_INIT_BT_TIMINGS(1280, 720, 0, V4L2_DV_HSYNC_POS_POL | V4L2_DV_VSYNC_POS_POL, 59400000, 1760, 40, 220, 5, 5, 20, 0, 0, 0, V4L2_DV_BT_STD_DMT | V4L2_DV_BT_STD_CEA861, V4L2_DV_FL_CAN_REDUCE_FPS) \
 }
-#define V4L2_DV_BT_CEA_1280X720P25 {.type = V4L2_DV_BT_656_1120, V4L2_INIT_BT_TIMINGS(1280, 720, 0, V4L2_DV_HSYNC_POS_POL | V4L2_DV_VSYNC_POS_POL, 74250000, 2420, 40, 220, 5, 5, 20, 0, 0, 0, V4L2_DV_BT_STD_CEA861, 0) \
+#define V4L2_DV_BT_CEA_1280X720P25 {.type = V4L2_DV_BT_656_1120, V4L2_INIT_BT_TIMINGS(1280, 720, 0, V4L2_DV_HSYNC_POS_POL | V4L2_DV_VSYNC_POS_POL, 74250000, 2420, 40, 220, 5, 5, 20, 0, 0, 0, V4L2_DV_BT_STD_CEA861, V4L2_DV_FL_IS_CE_VIDEO) \
 }
-#define V4L2_DV_BT_CEA_1280X720P30 {.type = V4L2_DV_BT_656_1120, V4L2_INIT_BT_TIMINGS(1280, 720, 0, V4L2_DV_HSYNC_POS_POL | V4L2_DV_VSYNC_POS_POL, 74250000, 1760, 40, 220, 5, 5, 20, 0, 0, 0, V4L2_DV_BT_STD_CEA861, V4L2_DV_FL_CAN_REDUCE_FPS) \
+#define V4L2_DV_BT_CEA_1280X720P30 {.type = V4L2_DV_BT_656_1120, V4L2_INIT_BT_TIMINGS(1280, 720, 0, V4L2_DV_HSYNC_POS_POL | V4L2_DV_VSYNC_POS_POL, 74250000, 1760, 40, 220, 5, 5, 20, 0, 0, 0, V4L2_DV_BT_STD_CEA861, V4L2_DV_FL_CAN_REDUCE_FPS | V4L2_DV_FL_IS_CE_VIDEO) \
 }
-#define V4L2_DV_BT_CEA_1280X720P50 {.type = V4L2_DV_BT_656_1120, V4L2_INIT_BT_TIMINGS(1280, 720, 0, V4L2_DV_HSYNC_POS_POL | V4L2_DV_VSYNC_POS_POL, 74250000, 440, 40, 220, 5, 5, 20, 0, 0, 0, V4L2_DV_BT_STD_CEA861, 0) \
+#define V4L2_DV_BT_CEA_1280X720P50 {.type = V4L2_DV_BT_656_1120, V4L2_INIT_BT_TIMINGS(1280, 720, 0, V4L2_DV_HSYNC_POS_POL | V4L2_DV_VSYNC_POS_POL, 74250000, 440, 40, 220, 5, 5, 20, 0, 0, 0, V4L2_DV_BT_STD_CEA861, V4L2_DV_FL_IS_CE_VIDEO) \
 }
 /* WARNING: DO NOT EDIT, AUTO-GENERATED CODE - SEE TOP FOR INSTRUCTIONS */
-#define V4L2_DV_BT_CEA_1280X720P60 {.type = V4L2_DV_BT_656_1120, V4L2_INIT_BT_TIMINGS(1280, 720, 0, V4L2_DV_HSYNC_POS_POL | V4L2_DV_VSYNC_POS_POL, 74250000, 110, 40, 220, 5, 5, 20, 0, 0, 0, V4L2_DV_BT_STD_CEA861, V4L2_DV_FL_CAN_REDUCE_FPS) \
+#define V4L2_DV_BT_CEA_1280X720P60 {.type = V4L2_DV_BT_656_1120, V4L2_INIT_BT_TIMINGS(1280, 720, 0, V4L2_DV_HSYNC_POS_POL | V4L2_DV_VSYNC_POS_POL, 74250000, 110, 40, 220, 5, 5, 20, 0, 0, 0, V4L2_DV_BT_STD_CEA861, V4L2_DV_FL_CAN_REDUCE_FPS | V4L2_DV_FL_IS_CE_VIDEO) \
 }
-#define V4L2_DV_BT_CEA_1920X1080P24 {.type = V4L2_DV_BT_656_1120, V4L2_INIT_BT_TIMINGS(1920, 1080, 0, V4L2_DV_HSYNC_POS_POL | V4L2_DV_VSYNC_POS_POL, 74250000, 638, 44, 148, 4, 5, 36, 0, 0, 0, V4L2_DV_BT_STD_CEA861, V4L2_DV_FL_CAN_REDUCE_FPS) \
+#define V4L2_DV_BT_CEA_1920X1080P24 {.type = V4L2_DV_BT_656_1120, V4L2_INIT_BT_TIMINGS(1920, 1080, 0, V4L2_DV_HSYNC_POS_POL | V4L2_DV_VSYNC_POS_POL, 74250000, 638, 44, 148, 4, 5, 36, 0, 0, 0, V4L2_DV_BT_STD_CEA861, V4L2_DV_FL_CAN_REDUCE_FPS | V4L2_DV_FL_IS_CE_VIDEO) \
 }
-#define V4L2_DV_BT_CEA_1920X1080P25 {.type = V4L2_DV_BT_656_1120, V4L2_INIT_BT_TIMINGS(1920, 1080, 0, V4L2_DV_HSYNC_POS_POL | V4L2_DV_VSYNC_POS_POL, 74250000, 528, 44, 148, 4, 5, 36, 0, 0, 0, V4L2_DV_BT_STD_CEA861, 0) \
+#define V4L2_DV_BT_CEA_1920X1080P25 {.type = V4L2_DV_BT_656_1120, V4L2_INIT_BT_TIMINGS(1920, 1080, 0, V4L2_DV_HSYNC_POS_POL | V4L2_DV_VSYNC_POS_POL, 74250000, 528, 44, 148, 4, 5, 36, 0, 0, 0, V4L2_DV_BT_STD_CEA861, V4L2_DV_FL_IS_CE_VIDEO) \
 }
-#define V4L2_DV_BT_CEA_1920X1080P30 {.type = V4L2_DV_BT_656_1120, V4L2_INIT_BT_TIMINGS(1920, 1080, 0, V4L2_DV_HSYNC_POS_POL | V4L2_DV_VSYNC_POS_POL, 74250000, 88, 44, 148, 4, 5, 36, 0, 0, 0, V4L2_DV_BT_STD_CEA861, V4L2_DV_FL_CAN_REDUCE_FPS) \
+#define V4L2_DV_BT_CEA_1920X1080P30 {.type = V4L2_DV_BT_656_1120, V4L2_INIT_BT_TIMINGS(1920, 1080, 0, V4L2_DV_HSYNC_POS_POL | V4L2_DV_VSYNC_POS_POL, 74250000, 88, 44, 148, 4, 5, 36, 0, 0, 0, V4L2_DV_BT_STD_CEA861, V4L2_DV_FL_CAN_REDUCE_FPS | V4L2_DV_FL_IS_CE_VIDEO) \
 }
 /* WARNING: DO NOT EDIT, AUTO-GENERATED CODE - SEE TOP FOR INSTRUCTIONS */
-#define V4L2_DV_BT_CEA_1920X1080I50 {.type = V4L2_DV_BT_656_1120, V4L2_INIT_BT_TIMINGS(1920, 1080, 1, V4L2_DV_HSYNC_POS_POL | V4L2_DV_VSYNC_POS_POL, 74250000, 528, 44, 148, 2, 5, 15, 2, 5, 16, V4L2_DV_BT_STD_CEA861, V4L2_DV_FL_HALF_LINE) \
+#define V4L2_DV_BT_CEA_1920X1080I50 {.type = V4L2_DV_BT_656_1120, V4L2_INIT_BT_TIMINGS(1920, 1080, 1, V4L2_DV_HSYNC_POS_POL | V4L2_DV_VSYNC_POS_POL, 74250000, 528, 44, 148, 2, 5, 15, 2, 5, 16, V4L2_DV_BT_STD_CEA861, V4L2_DV_FL_HALF_LINE | V4L2_DV_FL_IS_CE_VIDEO) \
 }
-#define V4L2_DV_BT_CEA_1920X1080P50 {.type = V4L2_DV_BT_656_1120, V4L2_INIT_BT_TIMINGS(1920, 1080, 0, V4L2_DV_HSYNC_POS_POL | V4L2_DV_VSYNC_POS_POL, 148500000, 528, 44, 148, 4, 5, 36, 0, 0, 0, V4L2_DV_BT_STD_CEA861, 0) \
+#define V4L2_DV_BT_CEA_1920X1080P50 {.type = V4L2_DV_BT_656_1120, V4L2_INIT_BT_TIMINGS(1920, 1080, 0, V4L2_DV_HSYNC_POS_POL | V4L2_DV_VSYNC_POS_POL, 148500000, 528, 44, 148, 4, 5, 36, 0, 0, 0, V4L2_DV_BT_STD_CEA861, V4L2_DV_FL_IS_CE_VIDEO) \
 }
-#define V4L2_DV_BT_CEA_1920X1080I60 {.type = V4L2_DV_BT_656_1120, V4L2_INIT_BT_TIMINGS(1920, 1080, 1, V4L2_DV_HSYNC_POS_POL | V4L2_DV_VSYNC_POS_POL, 74250000, 88, 44, 148, 2, 5, 15, 2, 5, 16, V4L2_DV_BT_STD_CEA861, V4L2_DV_FL_CAN_REDUCE_FPS | V4L2_DV_FL_HALF_LINE) \
+#define V4L2_DV_BT_CEA_1920X1080I60 {.type = V4L2_DV_BT_656_1120, V4L2_INIT_BT_TIMINGS(1920, 1080, 1, V4L2_DV_HSYNC_POS_POL | V4L2_DV_VSYNC_POS_POL, 74250000, 88, 44, 148, 2, 5, 15, 2, 5, 16, V4L2_DV_BT_STD_CEA861, V4L2_DV_FL_CAN_REDUCE_FPS | V4L2_DV_FL_HALF_LINE | V4L2_DV_FL_IS_CE_VIDEO) \
 }
-#define V4L2_DV_BT_CEA_1920X1080P60 {.type = V4L2_DV_BT_656_1120, V4L2_INIT_BT_TIMINGS(1920, 1080, 0, V4L2_DV_HSYNC_POS_POL | V4L2_DV_VSYNC_POS_POL, 148500000, 88, 44, 148, 4, 5, 36, 0, 0, 0, V4L2_DV_BT_STD_DMT | V4L2_DV_BT_STD_CEA861, V4L2_DV_FL_CAN_REDUCE_FPS) \
+#define V4L2_DV_BT_CEA_1920X1080P60 {.type = V4L2_DV_BT_656_1120, V4L2_INIT_BT_TIMINGS(1920, 1080, 0, V4L2_DV_HSYNC_POS_POL | V4L2_DV_VSYNC_POS_POL, 148500000, 88, 44, 148, 4, 5, 36, 0, 0, 0, V4L2_DV_BT_STD_DMT | V4L2_DV_BT_STD_CEA861, V4L2_DV_FL_CAN_REDUCE_FPS | V4L2_DV_FL_IS_CE_VIDEO) \
 }
 /* WARNING: DO NOT EDIT, AUTO-GENERATED CODE - SEE TOP FOR INSTRUCTIONS */
-#define V4L2_DV_BT_CEA_3840X2160P24 {.type = V4L2_DV_BT_656_1120, V4L2_INIT_BT_TIMINGS(3840, 2160, 0, V4L2_DV_HSYNC_POS_POL, 297000000, 1276, 88, 296, 8, 10, 72, 0, 0, 0, V4L2_DV_BT_STD_CEA861, V4L2_DV_FL_CAN_REDUCE_FPS) \
+#define V4L2_DV_BT_CEA_3840X2160P24 {.type = V4L2_DV_BT_656_1120, V4L2_INIT_BT_TIMINGS(3840, 2160, 0, V4L2_DV_HSYNC_POS_POL, 297000000, 1276, 88, 296, 8, 10, 72, 0, 0, 0, V4L2_DV_BT_STD_CEA861, V4L2_DV_FL_CAN_REDUCE_FPS | V4L2_DV_FL_IS_CE_VIDEO) \
 }
-#define V4L2_DV_BT_CEA_3840X2160P25 {.type = V4L2_DV_BT_656_1120, V4L2_INIT_BT_TIMINGS(3840, 2160, 0, V4L2_DV_HSYNC_POS_POL, 297000000, 1056, 88, 296, 8, 10, 72, 0, 0, 0, V4L2_DV_BT_STD_CEA861, 0) \
+#define V4L2_DV_BT_CEA_3840X2160P25 {.type = V4L2_DV_BT_656_1120, V4L2_INIT_BT_TIMINGS(3840, 2160, 0, V4L2_DV_HSYNC_POS_POL, 297000000, 1056, 88, 296, 8, 10, 72, 0, 0, 0, V4L2_DV_BT_STD_CEA861, V4L2_DV_FL_IS_CE_VIDEO) \
 }
-#define V4L2_DV_BT_CEA_3840X2160P30 {.type = V4L2_DV_BT_656_1120, V4L2_INIT_BT_TIMINGS(3840, 2160, 0, V4L2_DV_HSYNC_POS_POL, 297000000, 176, 88, 296, 8, 10, 72, 0, 0, 0, V4L2_DV_BT_STD_CEA861, V4L2_DV_FL_CAN_REDUCE_FPS) \
+#define V4L2_DV_BT_CEA_3840X2160P30 {.type = V4L2_DV_BT_656_1120, V4L2_INIT_BT_TIMINGS(3840, 2160, 0, V4L2_DV_HSYNC_POS_POL, 297000000, 176, 88, 296, 8, 10, 72, 0, 0, 0, V4L2_DV_BT_STD_CEA861, V4L2_DV_FL_CAN_REDUCE_FPS | V4L2_DV_FL_IS_CE_VIDEO) \
 }
-#define V4L2_DV_BT_CEA_3840X2160P50 {.type = V4L2_DV_BT_656_1120, V4L2_INIT_BT_TIMINGS(3840, 2160, 0, V4L2_DV_HSYNC_POS_POL, 594000000, 1056, 88, 296, 8, 10, 72, 0, 0, 0, V4L2_DV_BT_STD_CEA861, 0) \
+#define V4L2_DV_BT_CEA_3840X2160P50 {.type = V4L2_DV_BT_656_1120, V4L2_INIT_BT_TIMINGS(3840, 2160, 0, V4L2_DV_HSYNC_POS_POL, 594000000, 1056, 88, 296, 8, 10, 72, 0, 0, 0, V4L2_DV_BT_STD_CEA861, V4L2_DV_FL_IS_CE_VIDEO) \
 }
 /* WARNING: DO NOT EDIT, AUTO-GENERATED CODE - SEE TOP FOR INSTRUCTIONS */
-#define V4L2_DV_BT_CEA_3840X2160P60 {.type = V4L2_DV_BT_656_1120, V4L2_INIT_BT_TIMINGS(3840, 2160, 0, V4L2_DV_HSYNC_POS_POL, 594000000, 176, 88, 296, 8, 10, 72, 0, 0, 0, V4L2_DV_BT_STD_CEA861, V4L2_DV_FL_CAN_REDUCE_FPS) \
+#define V4L2_DV_BT_CEA_3840X2160P60 {.type = V4L2_DV_BT_656_1120, V4L2_INIT_BT_TIMINGS(3840, 2160, 0, V4L2_DV_HSYNC_POS_POL, 594000000, 176, 88, 296, 8, 10, 72, 0, 0, 0, V4L2_DV_BT_STD_CEA861, V4L2_DV_FL_CAN_REDUCE_FPS | V4L2_DV_FL_IS_CE_VIDEO) \
 }
-#define V4L2_DV_BT_CEA_4096X2160P24 {.type = V4L2_DV_BT_656_1120, V4L2_INIT_BT_TIMINGS(4096, 2160, 0, V4L2_DV_HSYNC_POS_POL, 297000000, 1020, 88, 296, 8, 10, 72, 0, 0, 0, V4L2_DV_BT_STD_CEA861, V4L2_DV_FL_CAN_REDUCE_FPS) \
+#define V4L2_DV_BT_CEA_4096X2160P24 {.type = V4L2_DV_BT_656_1120, V4L2_INIT_BT_TIMINGS(4096, 2160, 0, V4L2_DV_HSYNC_POS_POL, 297000000, 1020, 88, 296, 8, 10, 72, 0, 0, 0, V4L2_DV_BT_STD_CEA861, V4L2_DV_FL_CAN_REDUCE_FPS | V4L2_DV_FL_IS_CE_VIDEO) \
 }
-#define V4L2_DV_BT_CEA_4096X2160P25 {.type = V4L2_DV_BT_656_1120, V4L2_INIT_BT_TIMINGS(4096, 2160, 0, V4L2_DV_HSYNC_POS_POL, 297000000, 968, 88, 128, 8, 10, 72, 0, 0, 0, V4L2_DV_BT_STD_CEA861, 0) \
+#define V4L2_DV_BT_CEA_4096X2160P25 {.type = V4L2_DV_BT_656_1120, V4L2_INIT_BT_TIMINGS(4096, 2160, 0, V4L2_DV_HSYNC_POS_POL, 297000000, 968, 88, 128, 8, 10, 72, 0, 0, 0, V4L2_DV_BT_STD_CEA861, V4L2_DV_FL_IS_CE_VIDEO) \
 }
-#define V4L2_DV_BT_CEA_4096X2160P30 {.type = V4L2_DV_BT_656_1120, V4L2_INIT_BT_TIMINGS(4096, 2160, 0, V4L2_DV_HSYNC_POS_POL, 297000000, 88, 88, 128, 8, 10, 72, 0, 0, 0, V4L2_DV_BT_STD_CEA861, V4L2_DV_FL_CAN_REDUCE_FPS) \
+#define V4L2_DV_BT_CEA_4096X2160P30 {.type = V4L2_DV_BT_656_1120, V4L2_INIT_BT_TIMINGS(4096, 2160, 0, V4L2_DV_HSYNC_POS_POL, 297000000, 88, 88, 128, 8, 10, 72, 0, 0, 0, V4L2_DV_BT_STD_CEA861, V4L2_DV_FL_CAN_REDUCE_FPS | V4L2_DV_FL_IS_CE_VIDEO) \
 }
 /* WARNING: DO NOT EDIT, AUTO-GENERATED CODE - SEE TOP FOR INSTRUCTIONS */
-#define V4L2_DV_BT_CEA_4096X2160P50 {.type = V4L2_DV_BT_656_1120, V4L2_INIT_BT_TIMINGS(4096, 2160, 0, V4L2_DV_HSYNC_POS_POL, 594000000, 968, 88, 128, 8, 10, 72, 0, 0, 0, V4L2_DV_BT_STD_CEA861, 0) \
+#define V4L2_DV_BT_CEA_4096X2160P50 {.type = V4L2_DV_BT_656_1120, V4L2_INIT_BT_TIMINGS(4096, 2160, 0, V4L2_DV_HSYNC_POS_POL, 594000000, 968, 88, 128, 8, 10, 72, 0, 0, 0, V4L2_DV_BT_STD_CEA861, V4L2_DV_FL_IS_CE_VIDEO) \
 }
-#define V4L2_DV_BT_CEA_4096X2160P60 {.type = V4L2_DV_BT_656_1120, V4L2_INIT_BT_TIMINGS(4096, 2160, 0, V4L2_DV_HSYNC_POS_POL, 594000000, 88, 88, 128, 8, 10, 72, 0, 0, 0, V4L2_DV_BT_STD_CEA861, V4L2_DV_FL_CAN_REDUCE_FPS) \
+#define V4L2_DV_BT_CEA_4096X2160P60 {.type = V4L2_DV_BT_656_1120, V4L2_INIT_BT_TIMINGS(4096, 2160, 0, V4L2_DV_HSYNC_POS_POL, 594000000, 88, 88, 128, 8, 10, 72, 0, 0, 0, V4L2_DV_BT_STD_CEA861, V4L2_DV_FL_CAN_REDUCE_FPS | V4L2_DV_FL_IS_CE_VIDEO) \
 }
 #define V4L2_DV_BT_DMT_640X350P85 {.type = V4L2_DV_BT_656_1120, V4L2_INIT_BT_TIMINGS(640, 350, 0, V4L2_DV_HSYNC_POS_POL, 31500000, 32, 64, 96, 32, 3, 60, 0, 0, 0, V4L2_DV_BT_STD_DMT, 0) \
 }
diff --git a/libc/kernel/uapi/linux/v4l2-mediabus.h b/libc/kernel/uapi/linux/v4l2-mediabus.h
index 2c2b0e7..266ecdc 100644
--- a/libc/kernel/uapi/linux/v4l2-mediabus.h
+++ b/libc/kernel/uapi/linux/v4l2-mediabus.h
@@ -18,114 +18,121 @@
  ****************************************************************************/
 #ifndef __LINUX_V4L2_MEDIABUS_H
 #define __LINUX_V4L2_MEDIABUS_H
+#include <linux/media-bus-format.h>
 #include <linux/types.h>
+/* WARNING: DO NOT EDIT, AUTO-GENERATED CODE - SEE TOP FOR INSTRUCTIONS */
 #include <linux/videodev2.h>
-/* WARNING: DO NOT EDIT, AUTO-GENERATED CODE - SEE TOP FOR INSTRUCTIONS */
-enum v4l2_mbus_pixelcode {
-  V4L2_MBUS_FMT_FIXED = 0x0001,
-  V4L2_MBUS_FMT_RGB444_2X8_PADHI_BE = 0x1001,
-  V4L2_MBUS_FMT_RGB444_2X8_PADHI_LE = 0x1002,
-/* WARNING: DO NOT EDIT, AUTO-GENERATED CODE - SEE TOP FOR INSTRUCTIONS */
-  V4L2_MBUS_FMT_RGB555_2X8_PADHI_BE = 0x1003,
-  V4L2_MBUS_FMT_RGB555_2X8_PADHI_LE = 0x1004,
-  V4L2_MBUS_FMT_BGR565_2X8_BE = 0x1005,
-  V4L2_MBUS_FMT_BGR565_2X8_LE = 0x1006,
-/* WARNING: DO NOT EDIT, AUTO-GENERATED CODE - SEE TOP FOR INSTRUCTIONS */
-  V4L2_MBUS_FMT_RGB565_2X8_BE = 0x1007,
-  V4L2_MBUS_FMT_RGB565_2X8_LE = 0x1008,
-  V4L2_MBUS_FMT_RGB666_1X18 = 0x1009,
-  V4L2_MBUS_FMT_RGB888_1X24 = 0x100a,
-/* WARNING: DO NOT EDIT, AUTO-GENERATED CODE - SEE TOP FOR INSTRUCTIONS */
-  V4L2_MBUS_FMT_RGB888_2X12_BE = 0x100b,
-  V4L2_MBUS_FMT_RGB888_2X12_LE = 0x100c,
-  V4L2_MBUS_FMT_ARGB8888_1X32 = 0x100d,
-  V4L2_MBUS_FMT_Y8_1X8 = 0x2001,
-/* WARNING: DO NOT EDIT, AUTO-GENERATED CODE - SEE TOP FOR INSTRUCTIONS */
-  V4L2_MBUS_FMT_UV8_1X8 = 0x2015,
-  V4L2_MBUS_FMT_UYVY8_1_5X8 = 0x2002,
-  V4L2_MBUS_FMT_VYUY8_1_5X8 = 0x2003,
-  V4L2_MBUS_FMT_YUYV8_1_5X8 = 0x2004,
-/* WARNING: DO NOT EDIT, AUTO-GENERATED CODE - SEE TOP FOR INSTRUCTIONS */
-  V4L2_MBUS_FMT_YVYU8_1_5X8 = 0x2005,
-  V4L2_MBUS_FMT_UYVY8_2X8 = 0x2006,
-  V4L2_MBUS_FMT_VYUY8_2X8 = 0x2007,
-  V4L2_MBUS_FMT_YUYV8_2X8 = 0x2008,
-/* WARNING: DO NOT EDIT, AUTO-GENERATED CODE - SEE TOP FOR INSTRUCTIONS */
-  V4L2_MBUS_FMT_YVYU8_2X8 = 0x2009,
-  V4L2_MBUS_FMT_Y10_1X10 = 0x200a,
-  V4L2_MBUS_FMT_UYVY10_2X10 = 0x2018,
-  V4L2_MBUS_FMT_VYUY10_2X10 = 0x2019,
-/* WARNING: DO NOT EDIT, AUTO-GENERATED CODE - SEE TOP FOR INSTRUCTIONS */
-  V4L2_MBUS_FMT_YUYV10_2X10 = 0x200b,
-  V4L2_MBUS_FMT_YVYU10_2X10 = 0x200c,
-  V4L2_MBUS_FMT_Y12_1X12 = 0x2013,
-  V4L2_MBUS_FMT_UYVY8_1X16 = 0x200f,
-/* WARNING: DO NOT EDIT, AUTO-GENERATED CODE - SEE TOP FOR INSTRUCTIONS */
-  V4L2_MBUS_FMT_VYUY8_1X16 = 0x2010,
-  V4L2_MBUS_FMT_YUYV8_1X16 = 0x2011,
-  V4L2_MBUS_FMT_YVYU8_1X16 = 0x2012,
-  V4L2_MBUS_FMT_YDYUYDYV8_1X16 = 0x2014,
-/* WARNING: DO NOT EDIT, AUTO-GENERATED CODE - SEE TOP FOR INSTRUCTIONS */
-  V4L2_MBUS_FMT_UYVY10_1X20 = 0x201a,
-  V4L2_MBUS_FMT_VYUY10_1X20 = 0x201b,
-  V4L2_MBUS_FMT_YUYV10_1X20 = 0x200d,
-  V4L2_MBUS_FMT_YVYU10_1X20 = 0x200e,
-/* WARNING: DO NOT EDIT, AUTO-GENERATED CODE - SEE TOP FOR INSTRUCTIONS */
-  V4L2_MBUS_FMT_YUV10_1X30 = 0x2016,
-  V4L2_MBUS_FMT_AYUV8_1X32 = 0x2017,
-  V4L2_MBUS_FMT_UYVY12_2X12 = 0x201c,
-  V4L2_MBUS_FMT_VYUY12_2X12 = 0x201d,
-/* WARNING: DO NOT EDIT, AUTO-GENERATED CODE - SEE TOP FOR INSTRUCTIONS */
-  V4L2_MBUS_FMT_YUYV12_2X12 = 0x201e,
-  V4L2_MBUS_FMT_YVYU12_2X12 = 0x201f,
-  V4L2_MBUS_FMT_UYVY12_1X24 = 0x2020,
-  V4L2_MBUS_FMT_VYUY12_1X24 = 0x2021,
-/* WARNING: DO NOT EDIT, AUTO-GENERATED CODE - SEE TOP FOR INSTRUCTIONS */
-  V4L2_MBUS_FMT_YUYV12_1X24 = 0x2022,
-  V4L2_MBUS_FMT_YVYU12_1X24 = 0x2023,
-  V4L2_MBUS_FMT_SBGGR8_1X8 = 0x3001,
-  V4L2_MBUS_FMT_SGBRG8_1X8 = 0x3013,
-/* WARNING: DO NOT EDIT, AUTO-GENERATED CODE - SEE TOP FOR INSTRUCTIONS */
-  V4L2_MBUS_FMT_SGRBG8_1X8 = 0x3002,
-  V4L2_MBUS_FMT_SRGGB8_1X8 = 0x3014,
-  V4L2_MBUS_FMT_SBGGR10_ALAW8_1X8 = 0x3015,
-  V4L2_MBUS_FMT_SGBRG10_ALAW8_1X8 = 0x3016,
-/* WARNING: DO NOT EDIT, AUTO-GENERATED CODE - SEE TOP FOR INSTRUCTIONS */
-  V4L2_MBUS_FMT_SGRBG10_ALAW8_1X8 = 0x3017,
-  V4L2_MBUS_FMT_SRGGB10_ALAW8_1X8 = 0x3018,
-  V4L2_MBUS_FMT_SBGGR10_DPCM8_1X8 = 0x300b,
-  V4L2_MBUS_FMT_SGBRG10_DPCM8_1X8 = 0x300c,
-/* WARNING: DO NOT EDIT, AUTO-GENERATED CODE - SEE TOP FOR INSTRUCTIONS */
-  V4L2_MBUS_FMT_SGRBG10_DPCM8_1X8 = 0x3009,
-  V4L2_MBUS_FMT_SRGGB10_DPCM8_1X8 = 0x300d,
-  V4L2_MBUS_FMT_SBGGR10_2X8_PADHI_BE = 0x3003,
-  V4L2_MBUS_FMT_SBGGR10_2X8_PADHI_LE = 0x3004,
-/* WARNING: DO NOT EDIT, AUTO-GENERATED CODE - SEE TOP FOR INSTRUCTIONS */
-  V4L2_MBUS_FMT_SBGGR10_2X8_PADLO_BE = 0x3005,
-  V4L2_MBUS_FMT_SBGGR10_2X8_PADLO_LE = 0x3006,
-  V4L2_MBUS_FMT_SBGGR10_1X10 = 0x3007,
-  V4L2_MBUS_FMT_SGBRG10_1X10 = 0x300e,
-/* WARNING: DO NOT EDIT, AUTO-GENERATED CODE - SEE TOP FOR INSTRUCTIONS */
-  V4L2_MBUS_FMT_SGRBG10_1X10 = 0x300a,
-  V4L2_MBUS_FMT_SRGGB10_1X10 = 0x300f,
-  V4L2_MBUS_FMT_SBGGR12_1X12 = 0x3008,
-  V4L2_MBUS_FMT_SGBRG12_1X12 = 0x3010,
-/* WARNING: DO NOT EDIT, AUTO-GENERATED CODE - SEE TOP FOR INSTRUCTIONS */
-  V4L2_MBUS_FMT_SGRBG12_1X12 = 0x3011,
-  V4L2_MBUS_FMT_SRGGB12_1X12 = 0x3012,
-  V4L2_MBUS_FMT_JPEG_1X8 = 0x4001,
-  V4L2_MBUS_FMT_S5C_UYVY_JPEG_1X8 = 0x5001,
-/* WARNING: DO NOT EDIT, AUTO-GENERATED CODE - SEE TOP FOR INSTRUCTIONS */
-  V4L2_MBUS_FMT_AHSV8888_1X32 = 0x6001,
-};
 struct v4l2_mbus_framefmt {
   __u32 width;
-/* WARNING: DO NOT EDIT, AUTO-GENERATED CODE - SEE TOP FOR INSTRUCTIONS */
   __u32 height;
+/* WARNING: DO NOT EDIT, AUTO-GENERATED CODE - SEE TOP FOR INSTRUCTIONS */
   __u32 code;
   __u32 field;
   __u32 colorspace;
+  __u16 ycbcr_enc;
 /* WARNING: DO NOT EDIT, AUTO-GENERATED CODE - SEE TOP FOR INSTRUCTIONS */
-  __u32 reserved[7];
+  __u16 quantization;
+  __u16 xfer_func;
+  __u16 reserved[11];
+};
+/* WARNING: DO NOT EDIT, AUTO-GENERATED CODE - SEE TOP FOR INSTRUCTIONS */
+#define V4L2_MBUS_FROM_MEDIA_BUS_FMT(name) V4L2_MBUS_FMT_ ##name = MEDIA_BUS_FMT_ ##name
+enum v4l2_mbus_pixelcode {
+  V4L2_MBUS_FROM_MEDIA_BUS_FMT(FIXED),
+  V4L2_MBUS_FROM_MEDIA_BUS_FMT(RGB444_2X8_PADHI_BE),
+/* WARNING: DO NOT EDIT, AUTO-GENERATED CODE - SEE TOP FOR INSTRUCTIONS */
+  V4L2_MBUS_FROM_MEDIA_BUS_FMT(RGB444_2X8_PADHI_LE),
+  V4L2_MBUS_FROM_MEDIA_BUS_FMT(RGB555_2X8_PADHI_BE),
+  V4L2_MBUS_FROM_MEDIA_BUS_FMT(RGB555_2X8_PADHI_LE),
+  V4L2_MBUS_FROM_MEDIA_BUS_FMT(BGR565_2X8_BE),
+/* WARNING: DO NOT EDIT, AUTO-GENERATED CODE - SEE TOP FOR INSTRUCTIONS */
+  V4L2_MBUS_FROM_MEDIA_BUS_FMT(BGR565_2X8_LE),
+  V4L2_MBUS_FROM_MEDIA_BUS_FMT(RGB565_2X8_BE),
+  V4L2_MBUS_FROM_MEDIA_BUS_FMT(RGB565_2X8_LE),
+  V4L2_MBUS_FROM_MEDIA_BUS_FMT(RGB666_1X18),
+/* WARNING: DO NOT EDIT, AUTO-GENERATED CODE - SEE TOP FOR INSTRUCTIONS */
+  V4L2_MBUS_FROM_MEDIA_BUS_FMT(RGB888_1X24),
+  V4L2_MBUS_FROM_MEDIA_BUS_FMT(RGB888_2X12_BE),
+  V4L2_MBUS_FROM_MEDIA_BUS_FMT(RGB888_2X12_LE),
+  V4L2_MBUS_FROM_MEDIA_BUS_FMT(ARGB8888_1X32),
+/* WARNING: DO NOT EDIT, AUTO-GENERATED CODE - SEE TOP FOR INSTRUCTIONS */
+  V4L2_MBUS_FROM_MEDIA_BUS_FMT(Y8_1X8),
+  V4L2_MBUS_FROM_MEDIA_BUS_FMT(UV8_1X8),
+  V4L2_MBUS_FROM_MEDIA_BUS_FMT(UYVY8_1_5X8),
+  V4L2_MBUS_FROM_MEDIA_BUS_FMT(VYUY8_1_5X8),
+/* WARNING: DO NOT EDIT, AUTO-GENERATED CODE - SEE TOP FOR INSTRUCTIONS */
+  V4L2_MBUS_FROM_MEDIA_BUS_FMT(YUYV8_1_5X8),
+  V4L2_MBUS_FROM_MEDIA_BUS_FMT(YVYU8_1_5X8),
+  V4L2_MBUS_FROM_MEDIA_BUS_FMT(UYVY8_2X8),
+  V4L2_MBUS_FROM_MEDIA_BUS_FMT(VYUY8_2X8),
+/* WARNING: DO NOT EDIT, AUTO-GENERATED CODE - SEE TOP FOR INSTRUCTIONS */
+  V4L2_MBUS_FROM_MEDIA_BUS_FMT(YUYV8_2X8),
+  V4L2_MBUS_FROM_MEDIA_BUS_FMT(YVYU8_2X8),
+  V4L2_MBUS_FROM_MEDIA_BUS_FMT(Y10_1X10),
+  V4L2_MBUS_FROM_MEDIA_BUS_FMT(UYVY10_2X10),
+/* WARNING: DO NOT EDIT, AUTO-GENERATED CODE - SEE TOP FOR INSTRUCTIONS */
+  V4L2_MBUS_FROM_MEDIA_BUS_FMT(VYUY10_2X10),
+  V4L2_MBUS_FROM_MEDIA_BUS_FMT(YUYV10_2X10),
+  V4L2_MBUS_FROM_MEDIA_BUS_FMT(YVYU10_2X10),
+  V4L2_MBUS_FROM_MEDIA_BUS_FMT(Y12_1X12),
+/* WARNING: DO NOT EDIT, AUTO-GENERATED CODE - SEE TOP FOR INSTRUCTIONS */
+  V4L2_MBUS_FROM_MEDIA_BUS_FMT(UYVY8_1X16),
+  V4L2_MBUS_FROM_MEDIA_BUS_FMT(VYUY8_1X16),
+  V4L2_MBUS_FROM_MEDIA_BUS_FMT(YUYV8_1X16),
+  V4L2_MBUS_FROM_MEDIA_BUS_FMT(YVYU8_1X16),
+/* WARNING: DO NOT EDIT, AUTO-GENERATED CODE - SEE TOP FOR INSTRUCTIONS */
+  V4L2_MBUS_FROM_MEDIA_BUS_FMT(YDYUYDYV8_1X16),
+  V4L2_MBUS_FROM_MEDIA_BUS_FMT(UYVY10_1X20),
+  V4L2_MBUS_FROM_MEDIA_BUS_FMT(VYUY10_1X20),
+  V4L2_MBUS_FROM_MEDIA_BUS_FMT(YUYV10_1X20),
+/* WARNING: DO NOT EDIT, AUTO-GENERATED CODE - SEE TOP FOR INSTRUCTIONS */
+  V4L2_MBUS_FROM_MEDIA_BUS_FMT(YVYU10_1X20),
+  V4L2_MBUS_FROM_MEDIA_BUS_FMT(YUV10_1X30),
+  V4L2_MBUS_FROM_MEDIA_BUS_FMT(AYUV8_1X32),
+  V4L2_MBUS_FROM_MEDIA_BUS_FMT(UYVY12_2X12),
+/* WARNING: DO NOT EDIT, AUTO-GENERATED CODE - SEE TOP FOR INSTRUCTIONS */
+  V4L2_MBUS_FROM_MEDIA_BUS_FMT(VYUY12_2X12),
+  V4L2_MBUS_FROM_MEDIA_BUS_FMT(YUYV12_2X12),
+  V4L2_MBUS_FROM_MEDIA_BUS_FMT(YVYU12_2X12),
+  V4L2_MBUS_FROM_MEDIA_BUS_FMT(UYVY12_1X24),
+/* WARNING: DO NOT EDIT, AUTO-GENERATED CODE - SEE TOP FOR INSTRUCTIONS */
+  V4L2_MBUS_FROM_MEDIA_BUS_FMT(VYUY12_1X24),
+  V4L2_MBUS_FROM_MEDIA_BUS_FMT(YUYV12_1X24),
+  V4L2_MBUS_FROM_MEDIA_BUS_FMT(YVYU12_1X24),
+  V4L2_MBUS_FROM_MEDIA_BUS_FMT(SBGGR8_1X8),
+/* WARNING: DO NOT EDIT, AUTO-GENERATED CODE - SEE TOP FOR INSTRUCTIONS */
+  V4L2_MBUS_FROM_MEDIA_BUS_FMT(SGBRG8_1X8),
+  V4L2_MBUS_FROM_MEDIA_BUS_FMT(SGRBG8_1X8),
+  V4L2_MBUS_FROM_MEDIA_BUS_FMT(SRGGB8_1X8),
+  V4L2_MBUS_FROM_MEDIA_BUS_FMT(SBGGR10_ALAW8_1X8),
+/* WARNING: DO NOT EDIT, AUTO-GENERATED CODE - SEE TOP FOR INSTRUCTIONS */
+  V4L2_MBUS_FROM_MEDIA_BUS_FMT(SGBRG10_ALAW8_1X8),
+  V4L2_MBUS_FROM_MEDIA_BUS_FMT(SGRBG10_ALAW8_1X8),
+  V4L2_MBUS_FROM_MEDIA_BUS_FMT(SRGGB10_ALAW8_1X8),
+  V4L2_MBUS_FROM_MEDIA_BUS_FMT(SBGGR10_DPCM8_1X8),
+/* WARNING: DO NOT EDIT, AUTO-GENERATED CODE - SEE TOP FOR INSTRUCTIONS */
+  V4L2_MBUS_FROM_MEDIA_BUS_FMT(SGBRG10_DPCM8_1X8),
+  V4L2_MBUS_FROM_MEDIA_BUS_FMT(SGRBG10_DPCM8_1X8),
+  V4L2_MBUS_FROM_MEDIA_BUS_FMT(SRGGB10_DPCM8_1X8),
+  V4L2_MBUS_FROM_MEDIA_BUS_FMT(SBGGR10_2X8_PADHI_BE),
+/* WARNING: DO NOT EDIT, AUTO-GENERATED CODE - SEE TOP FOR INSTRUCTIONS */
+  V4L2_MBUS_FROM_MEDIA_BUS_FMT(SBGGR10_2X8_PADHI_LE),
+  V4L2_MBUS_FROM_MEDIA_BUS_FMT(SBGGR10_2X8_PADLO_BE),
+  V4L2_MBUS_FROM_MEDIA_BUS_FMT(SBGGR10_2X8_PADLO_LE),
+  V4L2_MBUS_FROM_MEDIA_BUS_FMT(SBGGR10_1X10),
+/* WARNING: DO NOT EDIT, AUTO-GENERATED CODE - SEE TOP FOR INSTRUCTIONS */
+  V4L2_MBUS_FROM_MEDIA_BUS_FMT(SGBRG10_1X10),
+  V4L2_MBUS_FROM_MEDIA_BUS_FMT(SGRBG10_1X10),
+  V4L2_MBUS_FROM_MEDIA_BUS_FMT(SRGGB10_1X10),
+  V4L2_MBUS_FROM_MEDIA_BUS_FMT(SBGGR12_1X12),
+/* WARNING: DO NOT EDIT, AUTO-GENERATED CODE - SEE TOP FOR INSTRUCTIONS */
+  V4L2_MBUS_FROM_MEDIA_BUS_FMT(SGBRG12_1X12),
+  V4L2_MBUS_FROM_MEDIA_BUS_FMT(SGRBG12_1X12),
+  V4L2_MBUS_FROM_MEDIA_BUS_FMT(SRGGB12_1X12),
+  V4L2_MBUS_FROM_MEDIA_BUS_FMT(JPEG_1X8),
+/* WARNING: DO NOT EDIT, AUTO-GENERATED CODE - SEE TOP FOR INSTRUCTIONS */
+  V4L2_MBUS_FROM_MEDIA_BUS_FMT(S5C_UYVY_JPEG_1X8),
+  V4L2_MBUS_FROM_MEDIA_BUS_FMT(AHSV8888_1X32),
 };
 #endif
+/* WARNING: DO NOT EDIT, AUTO-GENERATED CODE - SEE TOP FOR INSTRUCTIONS */
diff --git a/libc/kernel/uapi/linux/v4l2-subdev.h b/libc/kernel/uapi/linux/v4l2-subdev.h
index 653f846..57b4dd7 100644
--- a/libc/kernel/uapi/linux/v4l2-subdev.h
+++ b/libc/kernel/uapi/linux/v4l2-subdev.h
@@ -48,71 +48,74 @@
 /* WARNING: DO NOT EDIT, AUTO-GENERATED CODE - SEE TOP FOR INSTRUCTIONS */
   __u32 index;
   __u32 code;
-  __u32 reserved[9];
-};
+  __u32 which;
+  __u32 reserved[8];
 /* WARNING: DO NOT EDIT, AUTO-GENERATED CODE - SEE TOP FOR INSTRUCTIONS */
+};
 struct v4l2_subdev_frame_size_enum {
   __u32 index;
   __u32 pad;
-  __u32 code;
 /* WARNING: DO NOT EDIT, AUTO-GENERATED CODE - SEE TOP FOR INSTRUCTIONS */
+  __u32 code;
   __u32 min_width;
   __u32 max_width;
   __u32 min_height;
+/* WARNING: DO NOT EDIT, AUTO-GENERATED CODE - SEE TOP FOR INSTRUCTIONS */
   __u32 max_height;
-/* WARNING: DO NOT EDIT, AUTO-GENERATED CODE - SEE TOP FOR INSTRUCTIONS */
-  __u32 reserved[9];
-};
-struct v4l2_subdev_frame_interval {
-  __u32 pad;
-/* WARNING: DO NOT EDIT, AUTO-GENERATED CODE - SEE TOP FOR INSTRUCTIONS */
-  struct v4l2_fract interval;
-  __u32 reserved[9];
-};
-struct v4l2_subdev_frame_interval_enum {
-/* WARNING: DO NOT EDIT, AUTO-GENERATED CODE - SEE TOP FOR INSTRUCTIONS */
-  __u32 index;
-  __u32 pad;
-  __u32 code;
-  __u32 width;
-/* WARNING: DO NOT EDIT, AUTO-GENERATED CODE - SEE TOP FOR INSTRUCTIONS */
-  __u32 height;
-  struct v4l2_fract interval;
-  __u32 reserved[9];
-};
-/* WARNING: DO NOT EDIT, AUTO-GENERATED CODE - SEE TOP FOR INSTRUCTIONS */
-struct v4l2_subdev_selection {
   __u32 which;
-  __u32 pad;
-  __u32 target;
-/* WARNING: DO NOT EDIT, AUTO-GENERATED CODE - SEE TOP FOR INSTRUCTIONS */
-  __u32 flags;
-  struct v4l2_rect r;
   __u32 reserved[8];
 };
 /* WARNING: DO NOT EDIT, AUTO-GENERATED CODE - SEE TOP FOR INSTRUCTIONS */
+struct v4l2_subdev_frame_interval {
+  __u32 pad;
+  struct v4l2_fract interval;
+  __u32 reserved[9];
+/* WARNING: DO NOT EDIT, AUTO-GENERATED CODE - SEE TOP FOR INSTRUCTIONS */
+};
+struct v4l2_subdev_frame_interval_enum {
+  __u32 index;
+  __u32 pad;
+/* WARNING: DO NOT EDIT, AUTO-GENERATED CODE - SEE TOP FOR INSTRUCTIONS */
+  __u32 code;
+  __u32 width;
+  __u32 height;
+  struct v4l2_fract interval;
+/* WARNING: DO NOT EDIT, AUTO-GENERATED CODE - SEE TOP FOR INSTRUCTIONS */
+  __u32 which;
+  __u32 reserved[8];
+};
+struct v4l2_subdev_selection {
+/* WARNING: DO NOT EDIT, AUTO-GENERATED CODE - SEE TOP FOR INSTRUCTIONS */
+  __u32 which;
+  __u32 pad;
+  __u32 target;
+  __u32 flags;
+/* WARNING: DO NOT EDIT, AUTO-GENERATED CODE - SEE TOP FOR INSTRUCTIONS */
+  struct v4l2_rect r;
+  __u32 reserved[8];
+};
 #define v4l2_subdev_edid v4l2_edid
+/* WARNING: DO NOT EDIT, AUTO-GENERATED CODE - SEE TOP FOR INSTRUCTIONS */
 #define VIDIOC_SUBDEV_G_FMT _IOWR('V', 4, struct v4l2_subdev_format)
 #define VIDIOC_SUBDEV_S_FMT _IOWR('V', 5, struct v4l2_subdev_format)
 #define VIDIOC_SUBDEV_G_FRAME_INTERVAL _IOWR('V', 21, struct v4l2_subdev_frame_interval)
-/* WARNING: DO NOT EDIT, AUTO-GENERATED CODE - SEE TOP FOR INSTRUCTIONS */
 #define VIDIOC_SUBDEV_S_FRAME_INTERVAL _IOWR('V', 22, struct v4l2_subdev_frame_interval)
+/* WARNING: DO NOT EDIT, AUTO-GENERATED CODE - SEE TOP FOR INSTRUCTIONS */
 #define VIDIOC_SUBDEV_ENUM_MBUS_CODE _IOWR('V', 2, struct v4l2_subdev_mbus_code_enum)
 #define VIDIOC_SUBDEV_ENUM_FRAME_SIZE _IOWR('V', 74, struct v4l2_subdev_frame_size_enum)
 #define VIDIOC_SUBDEV_ENUM_FRAME_INTERVAL _IOWR('V', 75, struct v4l2_subdev_frame_interval_enum)
-/* WARNING: DO NOT EDIT, AUTO-GENERATED CODE - SEE TOP FOR INSTRUCTIONS */
 #define VIDIOC_SUBDEV_G_CROP _IOWR('V', 59, struct v4l2_subdev_crop)
+/* WARNING: DO NOT EDIT, AUTO-GENERATED CODE - SEE TOP FOR INSTRUCTIONS */
 #define VIDIOC_SUBDEV_S_CROP _IOWR('V', 60, struct v4l2_subdev_crop)
 #define VIDIOC_SUBDEV_G_SELECTION _IOWR('V', 61, struct v4l2_subdev_selection)
 #define VIDIOC_SUBDEV_S_SELECTION _IOWR('V', 62, struct v4l2_subdev_selection)
-/* WARNING: DO NOT EDIT, AUTO-GENERATED CODE - SEE TOP FOR INSTRUCTIONS */
 #define VIDIOC_SUBDEV_G_EDID _IOWR('V', 40, struct v4l2_edid)
+/* WARNING: DO NOT EDIT, AUTO-GENERATED CODE - SEE TOP FOR INSTRUCTIONS */
 #define VIDIOC_SUBDEV_S_EDID _IOWR('V', 41, struct v4l2_edid)
 #define VIDIOC_SUBDEV_S_DV_TIMINGS _IOWR('V', 87, struct v4l2_dv_timings)
 #define VIDIOC_SUBDEV_G_DV_TIMINGS _IOWR('V', 88, struct v4l2_dv_timings)
-/* WARNING: DO NOT EDIT, AUTO-GENERATED CODE - SEE TOP FOR INSTRUCTIONS */
 #define VIDIOC_SUBDEV_ENUM_DV_TIMINGS _IOWR('V', 98, struct v4l2_enum_dv_timings)
+/* WARNING: DO NOT EDIT, AUTO-GENERATED CODE - SEE TOP FOR INSTRUCTIONS */
 #define VIDIOC_SUBDEV_QUERY_DV_TIMINGS _IOR('V', 99, struct v4l2_dv_timings)
 #define VIDIOC_SUBDEV_DV_TIMINGS_CAP _IOWR('V', 100, struct v4l2_dv_timings_cap)
 #endif
-/* WARNING: DO NOT EDIT, AUTO-GENERATED CODE - SEE TOP FOR INSTRUCTIONS */
diff --git a/libc/kernel/uapi/linux/version.h b/libc/kernel/uapi/linux/version.h
index a6c6a2f..7bd7753 100644
--- a/libc/kernel/uapi/linux/version.h
+++ b/libc/kernel/uapi/linux/version.h
@@ -16,5 +16,5 @@
  ***
  ****************************************************************************
  ****************************************************************************/
-#define LINUX_VERSION_CODE 201226
+#define LINUX_VERSION_CODE 263169
 #define KERNEL_VERSION(a,b,c) (((a) << 16) + ((b) << 8) + (c))
diff --git a/libc/kernel/uapi/linux/vfio.h b/libc/kernel/uapi/linux/vfio.h
index 32db70e..1ca071f 100644
--- a/libc/kernel/uapi/linux/vfio.h
+++ b/libc/kernel/uapi/linux/vfio.h
@@ -29,109 +29,114 @@
 #define VFIO_DMA_CC_IOMMU 4
 #define VFIO_EEH 5
 #define VFIO_TYPE1_NESTING_IOMMU 6
-#define VFIO_TYPE (';')
+#define VFIO_SPAPR_TCE_v2_IOMMU 7
 /* WARNING: DO NOT EDIT, AUTO-GENERATED CODE - SEE TOP FOR INSTRUCTIONS */
+#define VFIO_TYPE (';')
 #define VFIO_BASE 100
 #define VFIO_GET_API_VERSION _IO(VFIO_TYPE, VFIO_BASE + 0)
 #define VFIO_CHECK_EXTENSION _IO(VFIO_TYPE, VFIO_BASE + 1)
-#define VFIO_SET_IOMMU _IO(VFIO_TYPE, VFIO_BASE + 2)
 /* WARNING: DO NOT EDIT, AUTO-GENERATED CODE - SEE TOP FOR INSTRUCTIONS */
+#define VFIO_SET_IOMMU _IO(VFIO_TYPE, VFIO_BASE + 2)
 struct vfio_group_status {
   __u32 argsz;
   __u32 flags;
-#define VFIO_GROUP_FLAGS_VIABLE (1 << 0)
 /* WARNING: DO NOT EDIT, AUTO-GENERATED CODE - SEE TOP FOR INSTRUCTIONS */
+#define VFIO_GROUP_FLAGS_VIABLE (1 << 0)
 #define VFIO_GROUP_FLAGS_CONTAINER_SET (1 << 1)
 };
 #define VFIO_GROUP_GET_STATUS _IO(VFIO_TYPE, VFIO_BASE + 3)
-#define VFIO_GROUP_SET_CONTAINER _IO(VFIO_TYPE, VFIO_BASE + 4)
 /* WARNING: DO NOT EDIT, AUTO-GENERATED CODE - SEE TOP FOR INSTRUCTIONS */
+#define VFIO_GROUP_SET_CONTAINER _IO(VFIO_TYPE, VFIO_BASE + 4)
 #define VFIO_GROUP_UNSET_CONTAINER _IO(VFIO_TYPE, VFIO_BASE + 5)
 #define VFIO_GROUP_GET_DEVICE_FD _IO(VFIO_TYPE, VFIO_BASE + 6)
 struct vfio_device_info {
-  __u32 argsz;
 /* WARNING: DO NOT EDIT, AUTO-GENERATED CODE - SEE TOP FOR INSTRUCTIONS */
+  __u32 argsz;
   __u32 flags;
 #define VFIO_DEVICE_FLAGS_RESET (1 << 0)
 #define VFIO_DEVICE_FLAGS_PCI (1 << 1)
-  __u32 num_regions;
 /* WARNING: DO NOT EDIT, AUTO-GENERATED CODE - SEE TOP FOR INSTRUCTIONS */
+#define VFIO_DEVICE_FLAGS_PLATFORM (1 << 2)
+#define VFIO_DEVICE_FLAGS_AMBA (1 << 3)
+  __u32 num_regions;
   __u32 num_irqs;
+/* WARNING: DO NOT EDIT, AUTO-GENERATED CODE - SEE TOP FOR INSTRUCTIONS */
 };
 #define VFIO_DEVICE_GET_INFO _IO(VFIO_TYPE, VFIO_BASE + 7)
 struct vfio_region_info {
-/* WARNING: DO NOT EDIT, AUTO-GENERATED CODE - SEE TOP FOR INSTRUCTIONS */
   __u32 argsz;
+/* WARNING: DO NOT EDIT, AUTO-GENERATED CODE - SEE TOP FOR INSTRUCTIONS */
   __u32 flags;
 #define VFIO_REGION_INFO_FLAG_READ (1 << 0)
 #define VFIO_REGION_INFO_FLAG_WRITE (1 << 1)
-/* WARNING: DO NOT EDIT, AUTO-GENERATED CODE - SEE TOP FOR INSTRUCTIONS */
 #define VFIO_REGION_INFO_FLAG_MMAP (1 << 2)
+/* WARNING: DO NOT EDIT, AUTO-GENERATED CODE - SEE TOP FOR INSTRUCTIONS */
   __u32 index;
   __u32 resv;
   __u64 size;
-/* WARNING: DO NOT EDIT, AUTO-GENERATED CODE - SEE TOP FOR INSTRUCTIONS */
   __u64 offset;
+/* WARNING: DO NOT EDIT, AUTO-GENERATED CODE - SEE TOP FOR INSTRUCTIONS */
 };
 #define VFIO_DEVICE_GET_REGION_INFO _IO(VFIO_TYPE, VFIO_BASE + 8)
 struct vfio_irq_info {
-/* WARNING: DO NOT EDIT, AUTO-GENERATED CODE - SEE TOP FOR INSTRUCTIONS */
   __u32 argsz;
+/* WARNING: DO NOT EDIT, AUTO-GENERATED CODE - SEE TOP FOR INSTRUCTIONS */
   __u32 flags;
 #define VFIO_IRQ_INFO_EVENTFD (1 << 0)
 #define VFIO_IRQ_INFO_MASKABLE (1 << 1)
-/* WARNING: DO NOT EDIT, AUTO-GENERATED CODE - SEE TOP FOR INSTRUCTIONS */
 #define VFIO_IRQ_INFO_AUTOMASKED (1 << 2)
+/* WARNING: DO NOT EDIT, AUTO-GENERATED CODE - SEE TOP FOR INSTRUCTIONS */
 #define VFIO_IRQ_INFO_NORESIZE (1 << 3)
   __u32 index;
   __u32 count;
-/* WARNING: DO NOT EDIT, AUTO-GENERATED CODE - SEE TOP FOR INSTRUCTIONS */
 };
+/* WARNING: DO NOT EDIT, AUTO-GENERATED CODE - SEE TOP FOR INSTRUCTIONS */
 #define VFIO_DEVICE_GET_IRQ_INFO _IO(VFIO_TYPE, VFIO_BASE + 9)
 struct vfio_irq_set {
   __u32 argsz;
-/* WARNING: DO NOT EDIT, AUTO-GENERATED CODE - SEE TOP FOR INSTRUCTIONS */
   __u32 flags;
+/* WARNING: DO NOT EDIT, AUTO-GENERATED CODE - SEE TOP FOR INSTRUCTIONS */
 #define VFIO_IRQ_SET_DATA_NONE (1 << 0)
 #define VFIO_IRQ_SET_DATA_BOOL (1 << 1)
 #define VFIO_IRQ_SET_DATA_EVENTFD (1 << 2)
-/* WARNING: DO NOT EDIT, AUTO-GENERATED CODE - SEE TOP FOR INSTRUCTIONS */
 #define VFIO_IRQ_SET_ACTION_MASK (1 << 3)
+/* WARNING: DO NOT EDIT, AUTO-GENERATED CODE - SEE TOP FOR INSTRUCTIONS */
 #define VFIO_IRQ_SET_ACTION_UNMASK (1 << 4)
 #define VFIO_IRQ_SET_ACTION_TRIGGER (1 << 5)
   __u32 index;
-/* WARNING: DO NOT EDIT, AUTO-GENERATED CODE - SEE TOP FOR INSTRUCTIONS */
   __u32 start;
+/* WARNING: DO NOT EDIT, AUTO-GENERATED CODE - SEE TOP FOR INSTRUCTIONS */
   __u32 count;
   __u8 data[];
 };
-/* WARNING: DO NOT EDIT, AUTO-GENERATED CODE - SEE TOP FOR INSTRUCTIONS */
 #define VFIO_DEVICE_SET_IRQS _IO(VFIO_TYPE, VFIO_BASE + 10)
+/* WARNING: DO NOT EDIT, AUTO-GENERATED CODE - SEE TOP FOR INSTRUCTIONS */
 #define VFIO_IRQ_SET_DATA_TYPE_MASK (VFIO_IRQ_SET_DATA_NONE | VFIO_IRQ_SET_DATA_BOOL | VFIO_IRQ_SET_DATA_EVENTFD)
 #define VFIO_IRQ_SET_ACTION_TYPE_MASK (VFIO_IRQ_SET_ACTION_MASK | VFIO_IRQ_SET_ACTION_UNMASK | VFIO_IRQ_SET_ACTION_TRIGGER)
 #define VFIO_DEVICE_RESET _IO(VFIO_TYPE, VFIO_BASE + 11)
-/* WARNING: DO NOT EDIT, AUTO-GENERATED CODE - SEE TOP FOR INSTRUCTIONS */
 enum {
+/* WARNING: DO NOT EDIT, AUTO-GENERATED CODE - SEE TOP FOR INSTRUCTIONS */
   VFIO_PCI_BAR0_REGION_INDEX,
   VFIO_PCI_BAR1_REGION_INDEX,
   VFIO_PCI_BAR2_REGION_INDEX,
-/* WARNING: DO NOT EDIT, AUTO-GENERATED CODE - SEE TOP FOR INSTRUCTIONS */
   VFIO_PCI_BAR3_REGION_INDEX,
+/* WARNING: DO NOT EDIT, AUTO-GENERATED CODE - SEE TOP FOR INSTRUCTIONS */
   VFIO_PCI_BAR4_REGION_INDEX,
   VFIO_PCI_BAR5_REGION_INDEX,
   VFIO_PCI_ROM_REGION_INDEX,
-/* WARNING: DO NOT EDIT, AUTO-GENERATED CODE - SEE TOP FOR INSTRUCTIONS */
   VFIO_PCI_CONFIG_REGION_INDEX,
+/* WARNING: DO NOT EDIT, AUTO-GENERATED CODE - SEE TOP FOR INSTRUCTIONS */
   VFIO_PCI_VGA_REGION_INDEX,
   VFIO_PCI_NUM_REGIONS
 };
-/* WARNING: DO NOT EDIT, AUTO-GENERATED CODE - SEE TOP FOR INSTRUCTIONS */
 enum {
+/* WARNING: DO NOT EDIT, AUTO-GENERATED CODE - SEE TOP FOR INSTRUCTIONS */
   VFIO_PCI_INTX_IRQ_INDEX,
   VFIO_PCI_MSI_IRQ_INDEX,
   VFIO_PCI_MSIX_IRQ_INDEX,
-/* WARNING: DO NOT EDIT, AUTO-GENERATED CODE - SEE TOP FOR INSTRUCTIONS */
   VFIO_PCI_ERR_IRQ_INDEX,
+/* WARNING: DO NOT EDIT, AUTO-GENERATED CODE - SEE TOP FOR INSTRUCTIONS */
+  VFIO_PCI_REQ_IRQ_INDEX,
   VFIO_PCI_NUM_IRQS
 };
 struct vfio_pci_dependent_device {
@@ -192,19 +197,39 @@
 #define VFIO_IOMMU_ENABLE _IO(VFIO_TYPE, VFIO_BASE + 15)
 /* WARNING: DO NOT EDIT, AUTO-GENERATED CODE - SEE TOP FOR INSTRUCTIONS */
 #define VFIO_IOMMU_DISABLE _IO(VFIO_TYPE, VFIO_BASE + 16)
+struct vfio_iommu_spapr_tce_ddw_info {
+  __u64 pgsizes;
+  __u32 max_dynamic_windows_supported;
+/* WARNING: DO NOT EDIT, AUTO-GENERATED CODE - SEE TOP FOR INSTRUCTIONS */
+  __u32 levels;
+};
 struct vfio_iommu_spapr_tce_info {
   __u32 argsz;
-  __u32 flags;
 /* WARNING: DO NOT EDIT, AUTO-GENERATED CODE - SEE TOP FOR INSTRUCTIONS */
+  __u32 flags;
+#define VFIO_IOMMU_SPAPR_INFO_DDW (1 << 0)
   __u32 dma32_window_start;
   __u32 dma32_window_size;
+/* WARNING: DO NOT EDIT, AUTO-GENERATED CODE - SEE TOP FOR INSTRUCTIONS */
+  struct vfio_iommu_spapr_tce_ddw_info ddw;
 };
 #define VFIO_IOMMU_SPAPR_TCE_GET_INFO _IO(VFIO_TYPE, VFIO_BASE + 12)
+struct vfio_eeh_pe_err {
 /* WARNING: DO NOT EDIT, AUTO-GENERATED CODE - SEE TOP FOR INSTRUCTIONS */
+  __u32 type;
+  __u32 func;
+  __u64 addr;
+  __u64 mask;
+/* WARNING: DO NOT EDIT, AUTO-GENERATED CODE - SEE TOP FOR INSTRUCTIONS */
+};
 struct vfio_eeh_pe_op {
   __u32 argsz;
   __u32 flags;
+/* WARNING: DO NOT EDIT, AUTO-GENERATED CODE - SEE TOP FOR INSTRUCTIONS */
   __u32 op;
+  union {
+    struct vfio_eeh_pe_err err;
+  };
 /* WARNING: DO NOT EDIT, AUTO-GENERATED CODE - SEE TOP FOR INSTRUCTIONS */
 };
 #define VFIO_EEH_PE_DISABLE 0
@@ -224,6 +249,36 @@
 #define VFIO_EEH_PE_RESET_HOT 6
 #define VFIO_EEH_PE_RESET_FUNDAMENTAL 7
 #define VFIO_EEH_PE_CONFIGURE 8
+#define VFIO_EEH_PE_INJECT_ERR 9
+/* WARNING: DO NOT EDIT, AUTO-GENERATED CODE - SEE TOP FOR INSTRUCTIONS */
 #define VFIO_EEH_PE_OP _IO(VFIO_TYPE, VFIO_BASE + 21)
+struct vfio_iommu_spapr_register_memory {
+  __u32 argsz;
+  __u32 flags;
+/* WARNING: DO NOT EDIT, AUTO-GENERATED CODE - SEE TOP FOR INSTRUCTIONS */
+  __u64 vaddr;
+  __u64 size;
+};
+#define VFIO_IOMMU_SPAPR_REGISTER_MEMORY _IO(VFIO_TYPE, VFIO_BASE + 17)
+/* WARNING: DO NOT EDIT, AUTO-GENERATED CODE - SEE TOP FOR INSTRUCTIONS */
+#define VFIO_IOMMU_SPAPR_UNREGISTER_MEMORY _IO(VFIO_TYPE, VFIO_BASE + 18)
+struct vfio_iommu_spapr_tce_create {
+  __u32 argsz;
+  __u32 flags;
+/* WARNING: DO NOT EDIT, AUTO-GENERATED CODE - SEE TOP FOR INSTRUCTIONS */
+  __u32 page_shift;
+  __u64 window_size;
+  __u32 levels;
+  __u64 start_addr;
+/* WARNING: DO NOT EDIT, AUTO-GENERATED CODE - SEE TOP FOR INSTRUCTIONS */
+};
+#define VFIO_IOMMU_SPAPR_TCE_CREATE _IO(VFIO_TYPE, VFIO_BASE + 19)
+struct vfio_iommu_spapr_tce_remove {
+  __u32 argsz;
+/* WARNING: DO NOT EDIT, AUTO-GENERATED CODE - SEE TOP FOR INSTRUCTIONS */
+  __u32 flags;
+  __u64 start_addr;
+};
+#define VFIO_IOMMU_SPAPR_TCE_REMOVE _IO(VFIO_TYPE, VFIO_BASE + 20)
 /* WARNING: DO NOT EDIT, AUTO-GENERATED CODE - SEE TOP FOR INSTRUCTIONS */
 #endif
diff --git a/libc/kernel/uapi/linux/vhost.h b/libc/kernel/uapi/linux/vhost.h
index 0a66e7a..f5e8f4f 100644
--- a/libc/kernel/uapi/linux/vhost.h
+++ b/libc/kernel/uapi/linux/vhost.h
@@ -76,6 +76,11 @@
 #define VHOST_SET_VRING_BASE _IOW(VHOST_VIRTIO, 0x12, struct vhost_vring_state)
 #define VHOST_GET_VRING_BASE _IOWR(VHOST_VIRTIO, 0x12, struct vhost_vring_state)
 /* WARNING: DO NOT EDIT, AUTO-GENERATED CODE - SEE TOP FOR INSTRUCTIONS */
+#define VHOST_VRING_LITTLE_ENDIAN 0
+#define VHOST_VRING_BIG_ENDIAN 1
+#define VHOST_SET_VRING_ENDIAN _IOW(VHOST_VIRTIO, 0x13, struct vhost_vring_state)
+#define VHOST_GET_VRING_ENDIAN _IOW(VHOST_VIRTIO, 0x14, struct vhost_vring_state)
+/* WARNING: DO NOT EDIT, AUTO-GENERATED CODE - SEE TOP FOR INSTRUCTIONS */
 #define VHOST_SET_VRING_KICK _IOW(VHOST_VIRTIO, 0x20, struct vhost_vring_file)
 #define VHOST_SET_VRING_CALL _IOW(VHOST_VIRTIO, 0x21, struct vhost_vring_file)
 #define VHOST_SET_VRING_ERR _IOW(VHOST_VIRTIO, 0x22, struct vhost_vring_file)
diff --git a/libc/kernel/uapi/linux/videodev2.h b/libc/kernel/uapi/linux/videodev2.h
index df3ebc3..ab6a3cf 100644
--- a/libc/kernel/uapi/linux/videodev2.h
+++ b/libc/kernel/uapi/linux/videodev2.h
@@ -66,680 +66,740 @@
   V4L2_BUF_TYPE_VIDEO_OUTPUT_MPLANE = 10,
   V4L2_BUF_TYPE_SDR_CAPTURE = 11,
 /* WARNING: DO NOT EDIT, AUTO-GENERATED CODE - SEE TOP FOR INSTRUCTIONS */
+  V4L2_BUF_TYPE_SDR_OUTPUT = 12,
   V4L2_BUF_TYPE_PRIVATE = 0x80,
 };
 #define V4L2_TYPE_IS_MULTIPLANAR(type) ((type) == V4L2_BUF_TYPE_VIDEO_CAPTURE_MPLANE || (type) == V4L2_BUF_TYPE_VIDEO_OUTPUT_MPLANE)
-#define V4L2_TYPE_IS_OUTPUT(type) ((type) == V4L2_BUF_TYPE_VIDEO_OUTPUT || (type) == V4L2_BUF_TYPE_VIDEO_OUTPUT_MPLANE || (type) == V4L2_BUF_TYPE_VIDEO_OVERLAY || (type) == V4L2_BUF_TYPE_VIDEO_OUTPUT_OVERLAY || (type) == V4L2_BUF_TYPE_VBI_OUTPUT || (type) == V4L2_BUF_TYPE_SLICED_VBI_OUTPUT)
 /* WARNING: DO NOT EDIT, AUTO-GENERATED CODE - SEE TOP FOR INSTRUCTIONS */
+#define V4L2_TYPE_IS_OUTPUT(type) ((type) == V4L2_BUF_TYPE_VIDEO_OUTPUT || (type) == V4L2_BUF_TYPE_VIDEO_OUTPUT_MPLANE || (type) == V4L2_BUF_TYPE_VIDEO_OVERLAY || (type) == V4L2_BUF_TYPE_VIDEO_OUTPUT_OVERLAY || (type) == V4L2_BUF_TYPE_VBI_OUTPUT || (type) == V4L2_BUF_TYPE_SLICED_VBI_OUTPUT || (type) == V4L2_BUF_TYPE_SDR_OUTPUT)
 enum v4l2_tuner_type {
   V4L2_TUNER_RADIO = 1,
   V4L2_TUNER_ANALOG_TV = 2,
-  V4L2_TUNER_DIGITAL_TV = 3,
 /* WARNING: DO NOT EDIT, AUTO-GENERATED CODE - SEE TOP FOR INSTRUCTIONS */
-  V4L2_TUNER_ADC = 4,
+  V4L2_TUNER_DIGITAL_TV = 3,
+  V4L2_TUNER_SDR = 4,
   V4L2_TUNER_RF = 5,
 };
-enum v4l2_memory {
 /* WARNING: DO NOT EDIT, AUTO-GENERATED CODE - SEE TOP FOR INSTRUCTIONS */
+#define V4L2_TUNER_ADC V4L2_TUNER_SDR
+enum v4l2_memory {
   V4L2_MEMORY_MMAP = 1,
   V4L2_MEMORY_USERPTR = 2,
+/* WARNING: DO NOT EDIT, AUTO-GENERATED CODE - SEE TOP FOR INSTRUCTIONS */
   V4L2_MEMORY_OVERLAY = 3,
   V4L2_MEMORY_DMABUF = 4,
-/* WARNING: DO NOT EDIT, AUTO-GENERATED CODE - SEE TOP FOR INSTRUCTIONS */
 };
 enum v4l2_colorspace {
+/* WARNING: DO NOT EDIT, AUTO-GENERATED CODE - SEE TOP FOR INSTRUCTIONS */
+  V4L2_COLORSPACE_DEFAULT = 0,
   V4L2_COLORSPACE_SMPTE170M = 1,
   V4L2_COLORSPACE_SMPTE240M = 2,
-/* WARNING: DO NOT EDIT, AUTO-GENERATED CODE - SEE TOP FOR INSTRUCTIONS */
   V4L2_COLORSPACE_REC709 = 3,
+/* WARNING: DO NOT EDIT, AUTO-GENERATED CODE - SEE TOP FOR INSTRUCTIONS */
   V4L2_COLORSPACE_BT878 = 4,
   V4L2_COLORSPACE_470_SYSTEM_M = 5,
   V4L2_COLORSPACE_470_SYSTEM_BG = 6,
-/* WARNING: DO NOT EDIT, AUTO-GENERATED CODE - SEE TOP FOR INSTRUCTIONS */
   V4L2_COLORSPACE_JPEG = 7,
-  V4L2_COLORSPACE_SRGB = 8,
-};
-enum v4l2_priority {
 /* WARNING: DO NOT EDIT, AUTO-GENERATED CODE - SEE TOP FOR INSTRUCTIONS */
+  V4L2_COLORSPACE_SRGB = 8,
+  V4L2_COLORSPACE_ADOBERGB = 9,
+  V4L2_COLORSPACE_BT2020 = 10,
+  V4L2_COLORSPACE_RAW = 11,
+/* WARNING: DO NOT EDIT, AUTO-GENERATED CODE - SEE TOP FOR INSTRUCTIONS */
+  V4L2_COLORSPACE_DCI_P3 = 12,
+};
+#define V4L2_MAP_COLORSPACE_DEFAULT(is_sdtv,is_hdtv) ((is_sdtv) ? V4L2_COLORSPACE_SMPTE170M : ((is_hdtv) ? V4L2_COLORSPACE_REC709 : V4L2_COLORSPACE_SRGB))
+enum v4l2_xfer_func {
+/* WARNING: DO NOT EDIT, AUTO-GENERATED CODE - SEE TOP FOR INSTRUCTIONS */
+  V4L2_XFER_FUNC_DEFAULT = 0,
+  V4L2_XFER_FUNC_709 = 1,
+  V4L2_XFER_FUNC_SRGB = 2,
+  V4L2_XFER_FUNC_ADOBERGB = 3,
+/* WARNING: DO NOT EDIT, AUTO-GENERATED CODE - SEE TOP FOR INSTRUCTIONS */
+  V4L2_XFER_FUNC_SMPTE240M = 4,
+  V4L2_XFER_FUNC_NONE = 5,
+  V4L2_XFER_FUNC_DCI_P3 = 6,
+  V4L2_XFER_FUNC_SMPTE2084 = 7,
+/* WARNING: DO NOT EDIT, AUTO-GENERATED CODE - SEE TOP FOR INSTRUCTIONS */
+};
+#define V4L2_MAP_XFER_FUNC_DEFAULT(colsp) ((colsp) == V4L2_COLORSPACE_ADOBERGB ? V4L2_XFER_FUNC_ADOBERGB : ((colsp) == V4L2_COLORSPACE_SMPTE240M ? V4L2_XFER_FUNC_SMPTE240M : ((colsp) == V4L2_COLORSPACE_DCI_P3 ? V4L2_XFER_FUNC_DCI_P3 : ((colsp) == V4L2_COLORSPACE_RAW ? V4L2_XFER_FUNC_NONE : ((colsp) == V4L2_COLORSPACE_SRGB || (colsp) == V4L2_COLORSPACE_JPEG ? V4L2_XFER_FUNC_SRGB : V4L2_XFER_FUNC_709)))))
+enum v4l2_ycbcr_encoding {
+  V4L2_YCBCR_ENC_DEFAULT = 0,
+/* WARNING: DO NOT EDIT, AUTO-GENERATED CODE - SEE TOP FOR INSTRUCTIONS */
+  V4L2_YCBCR_ENC_601 = 1,
+  V4L2_YCBCR_ENC_709 = 2,
+  V4L2_YCBCR_ENC_XV601 = 3,
+  V4L2_YCBCR_ENC_XV709 = 4,
+/* WARNING: DO NOT EDIT, AUTO-GENERATED CODE - SEE TOP FOR INSTRUCTIONS */
+  V4L2_YCBCR_ENC_SYCC = 5,
+  V4L2_YCBCR_ENC_BT2020 = 6,
+  V4L2_YCBCR_ENC_BT2020_CONST_LUM = 7,
+  V4L2_YCBCR_ENC_SMPTE240M = 8,
+/* WARNING: DO NOT EDIT, AUTO-GENERATED CODE - SEE TOP FOR INSTRUCTIONS */
+};
+#define V4L2_MAP_YCBCR_ENC_DEFAULT(colsp) (((colsp) == V4L2_COLORSPACE_REC709 || (colsp) == V4L2_COLORSPACE_DCI_P3) ? V4L2_YCBCR_ENC_709 : ((colsp) == V4L2_COLORSPACE_BT2020 ? V4L2_YCBCR_ENC_BT2020 : ((colsp) == V4L2_COLORSPACE_SMPTE240M ? V4L2_YCBCR_ENC_SMPTE240M : V4L2_YCBCR_ENC_601)))
+enum v4l2_quantization {
+  V4L2_QUANTIZATION_DEFAULT = 0,
+/* WARNING: DO NOT EDIT, AUTO-GENERATED CODE - SEE TOP FOR INSTRUCTIONS */
+  V4L2_QUANTIZATION_FULL_RANGE = 1,
+  V4L2_QUANTIZATION_LIM_RANGE = 2,
+};
+#define V4L2_MAP_QUANTIZATION_DEFAULT(is_rgb,colsp,ycbcr_enc) (((is_rgb) && (colsp) == V4L2_COLORSPACE_BT2020) ? V4L2_QUANTIZATION_LIM_RANGE : (((is_rgb) || (ycbcr_enc) == V4L2_YCBCR_ENC_XV601 || (ycbcr_enc) == V4L2_YCBCR_ENC_XV709 || (colsp) == V4L2_COLORSPACE_JPEG) ? V4L2_QUANTIZATION_FULL_RANGE : V4L2_QUANTIZATION_LIM_RANGE))
+/* WARNING: DO NOT EDIT, AUTO-GENERATED CODE - SEE TOP FOR INSTRUCTIONS */
+enum v4l2_priority {
   V4L2_PRIORITY_UNSET = 0,
   V4L2_PRIORITY_BACKGROUND = 1,
   V4L2_PRIORITY_INTERACTIVE = 2,
-  V4L2_PRIORITY_RECORD = 3,
 /* WARNING: DO NOT EDIT, AUTO-GENERATED CODE - SEE TOP FOR INSTRUCTIONS */
+  V4L2_PRIORITY_RECORD = 3,
   V4L2_PRIORITY_DEFAULT = V4L2_PRIORITY_INTERACTIVE,
 };
 struct v4l2_rect {
-  __s32 left;
 /* WARNING: DO NOT EDIT, AUTO-GENERATED CODE - SEE TOP FOR INSTRUCTIONS */
+  __s32 left;
   __s32 top;
   __u32 width;
   __u32 height;
-};
 /* WARNING: DO NOT EDIT, AUTO-GENERATED CODE - SEE TOP FOR INSTRUCTIONS */
+};
 struct v4l2_fract {
   __u32 numerator;
   __u32 denominator;
-};
 /* WARNING: DO NOT EDIT, AUTO-GENERATED CODE - SEE TOP FOR INSTRUCTIONS */
+};
 struct v4l2_capability {
   __u8 driver[16];
   __u8 card[32];
-  __u8 bus_info[32];
 /* WARNING: DO NOT EDIT, AUTO-GENERATED CODE - SEE TOP FOR INSTRUCTIONS */
+  __u8 bus_info[32];
   __u32 version;
   __u32 capabilities;
   __u32 device_caps;
-  __u32 reserved[3];
 /* WARNING: DO NOT EDIT, AUTO-GENERATED CODE - SEE TOP FOR INSTRUCTIONS */
+  __u32 reserved[3];
 };
 #define V4L2_CAP_VIDEO_CAPTURE 0x00000001
 #define V4L2_CAP_VIDEO_OUTPUT 0x00000002
-#define V4L2_CAP_VIDEO_OVERLAY 0x00000004
 /* WARNING: DO NOT EDIT, AUTO-GENERATED CODE - SEE TOP FOR INSTRUCTIONS */
+#define V4L2_CAP_VIDEO_OVERLAY 0x00000004
 #define V4L2_CAP_VBI_CAPTURE 0x00000010
 #define V4L2_CAP_VBI_OUTPUT 0x00000020
 #define V4L2_CAP_SLICED_VBI_CAPTURE 0x00000040
-#define V4L2_CAP_SLICED_VBI_OUTPUT 0x00000080
 /* WARNING: DO NOT EDIT, AUTO-GENERATED CODE - SEE TOP FOR INSTRUCTIONS */
+#define V4L2_CAP_SLICED_VBI_OUTPUT 0x00000080
 #define V4L2_CAP_RDS_CAPTURE 0x00000100
 #define V4L2_CAP_VIDEO_OUTPUT_OVERLAY 0x00000200
 #define V4L2_CAP_HW_FREQ_SEEK 0x00000400
-#define V4L2_CAP_RDS_OUTPUT 0x00000800
 /* WARNING: DO NOT EDIT, AUTO-GENERATED CODE - SEE TOP FOR INSTRUCTIONS */
+#define V4L2_CAP_RDS_OUTPUT 0x00000800
 #define V4L2_CAP_VIDEO_CAPTURE_MPLANE 0x00001000
 #define V4L2_CAP_VIDEO_OUTPUT_MPLANE 0x00002000
 #define V4L2_CAP_VIDEO_M2M_MPLANE 0x00004000
-#define V4L2_CAP_VIDEO_M2M 0x00008000
 /* WARNING: DO NOT EDIT, AUTO-GENERATED CODE - SEE TOP FOR INSTRUCTIONS */
+#define V4L2_CAP_VIDEO_M2M 0x00008000
 #define V4L2_CAP_TUNER 0x00010000
 #define V4L2_CAP_AUDIO 0x00020000
 #define V4L2_CAP_RADIO 0x00040000
-#define V4L2_CAP_MODULATOR 0x00080000
 /* WARNING: DO NOT EDIT, AUTO-GENERATED CODE - SEE TOP FOR INSTRUCTIONS */
+#define V4L2_CAP_MODULATOR 0x00080000
 #define V4L2_CAP_SDR_CAPTURE 0x00100000
 #define V4L2_CAP_EXT_PIX_FORMAT 0x00200000
+#define V4L2_CAP_SDR_OUTPUT 0x00400000
+/* WARNING: DO NOT EDIT, AUTO-GENERATED CODE - SEE TOP FOR INSTRUCTIONS */
 #define V4L2_CAP_READWRITE 0x01000000
 #define V4L2_CAP_ASYNCIO 0x02000000
-/* WARNING: DO NOT EDIT, AUTO-GENERATED CODE - SEE TOP FOR INSTRUCTIONS */
 #define V4L2_CAP_STREAMING 0x04000000
 #define V4L2_CAP_DEVICE_CAPS 0x80000000
+/* WARNING: DO NOT EDIT, AUTO-GENERATED CODE - SEE TOP FOR INSTRUCTIONS */
 struct v4l2_pix_format {
   __u32 width;
-/* WARNING: DO NOT EDIT, AUTO-GENERATED CODE - SEE TOP FOR INSTRUCTIONS */
   __u32 height;
   __u32 pixelformat;
+/* WARNING: DO NOT EDIT, AUTO-GENERATED CODE - SEE TOP FOR INSTRUCTIONS */
   __u32 field;
   __u32 bytesperline;
-/* WARNING: DO NOT EDIT, AUTO-GENERATED CODE - SEE TOP FOR INSTRUCTIONS */
   __u32 sizeimage;
   __u32 colorspace;
+/* WARNING: DO NOT EDIT, AUTO-GENERATED CODE - SEE TOP FOR INSTRUCTIONS */
   __u32 priv;
   __u32 flags;
+  __u32 ycbcr_enc;
+  __u32 quantization;
 /* WARNING: DO NOT EDIT, AUTO-GENERATED CODE - SEE TOP FOR INSTRUCTIONS */
+  __u32 xfer_func;
 };
 #define V4L2_PIX_FMT_RGB332 v4l2_fourcc('R', 'G', 'B', '1')
 #define V4L2_PIX_FMT_RGB444 v4l2_fourcc('R', '4', '4', '4')
-#define V4L2_PIX_FMT_ARGB444 v4l2_fourcc('A', 'R', '1', '2')
 /* WARNING: DO NOT EDIT, AUTO-GENERATED CODE - SEE TOP FOR INSTRUCTIONS */
+#define V4L2_PIX_FMT_ARGB444 v4l2_fourcc('A', 'R', '1', '2')
 #define V4L2_PIX_FMT_XRGB444 v4l2_fourcc('X', 'R', '1', '2')
 #define V4L2_PIX_FMT_RGB555 v4l2_fourcc('R', 'G', 'B', 'O')
 #define V4L2_PIX_FMT_ARGB555 v4l2_fourcc('A', 'R', '1', '5')
-#define V4L2_PIX_FMT_XRGB555 v4l2_fourcc('X', 'R', '1', '5')
 /* WARNING: DO NOT EDIT, AUTO-GENERATED CODE - SEE TOP FOR INSTRUCTIONS */
+#define V4L2_PIX_FMT_XRGB555 v4l2_fourcc('X', 'R', '1', '5')
 #define V4L2_PIX_FMT_RGB565 v4l2_fourcc('R', 'G', 'B', 'P')
 #define V4L2_PIX_FMT_RGB555X v4l2_fourcc('R', 'G', 'B', 'Q')
 #define V4L2_PIX_FMT_ARGB555X v4l2_fourcc_be('A', 'R', '1', '5')
-#define V4L2_PIX_FMT_XRGB555X v4l2_fourcc_be('X', 'R', '1', '5')
 /* WARNING: DO NOT EDIT, AUTO-GENERATED CODE - SEE TOP FOR INSTRUCTIONS */
+#define V4L2_PIX_FMT_XRGB555X v4l2_fourcc_be('X', 'R', '1', '5')
 #define V4L2_PIX_FMT_RGB565X v4l2_fourcc('R', 'G', 'B', 'R')
 #define V4L2_PIX_FMT_BGR666 v4l2_fourcc('B', 'G', 'R', 'H')
 #define V4L2_PIX_FMT_BGR24 v4l2_fourcc('B', 'G', 'R', '3')
-#define V4L2_PIX_FMT_RGB24 v4l2_fourcc('R', 'G', 'B', '3')
 /* WARNING: DO NOT EDIT, AUTO-GENERATED CODE - SEE TOP FOR INSTRUCTIONS */
+#define V4L2_PIX_FMT_RGB24 v4l2_fourcc('R', 'G', 'B', '3')
 #define V4L2_PIX_FMT_BGR32 v4l2_fourcc('B', 'G', 'R', '4')
 #define V4L2_PIX_FMT_ABGR32 v4l2_fourcc('A', 'R', '2', '4')
 #define V4L2_PIX_FMT_XBGR32 v4l2_fourcc('X', 'R', '2', '4')
-#define V4L2_PIX_FMT_RGB32 v4l2_fourcc('R', 'G', 'B', '4')
 /* WARNING: DO NOT EDIT, AUTO-GENERATED CODE - SEE TOP FOR INSTRUCTIONS */
+#define V4L2_PIX_FMT_RGB32 v4l2_fourcc('R', 'G', 'B', '4')
 #define V4L2_PIX_FMT_ARGB32 v4l2_fourcc('B', 'A', '2', '4')
 #define V4L2_PIX_FMT_XRGB32 v4l2_fourcc('B', 'X', '2', '4')
 #define V4L2_PIX_FMT_GREY v4l2_fourcc('G', 'R', 'E', 'Y')
-#define V4L2_PIX_FMT_Y4 v4l2_fourcc('Y', '0', '4', ' ')
 /* WARNING: DO NOT EDIT, AUTO-GENERATED CODE - SEE TOP FOR INSTRUCTIONS */
+#define V4L2_PIX_FMT_Y4 v4l2_fourcc('Y', '0', '4', ' ')
 #define V4L2_PIX_FMT_Y6 v4l2_fourcc('Y', '0', '6', ' ')
 #define V4L2_PIX_FMT_Y10 v4l2_fourcc('Y', '1', '0', ' ')
 #define V4L2_PIX_FMT_Y12 v4l2_fourcc('Y', '1', '2', ' ')
-#define V4L2_PIX_FMT_Y16 v4l2_fourcc('Y', '1', '6', ' ')
 /* WARNING: DO NOT EDIT, AUTO-GENERATED CODE - SEE TOP FOR INSTRUCTIONS */
+#define V4L2_PIX_FMT_Y16 v4l2_fourcc('Y', '1', '6', ' ')
+#define V4L2_PIX_FMT_Y16_BE v4l2_fourcc_be('Y', '1', '6', ' ')
 #define V4L2_PIX_FMT_Y10BPACK v4l2_fourcc('Y', '1', '0', 'B')
 #define V4L2_PIX_FMT_PAL8 v4l2_fourcc('P', 'A', 'L', '8')
+/* WARNING: DO NOT EDIT, AUTO-GENERATED CODE - SEE TOP FOR INSTRUCTIONS */
 #define V4L2_PIX_FMT_UV8 v4l2_fourcc('U', 'V', '8', ' ')
 #define V4L2_PIX_FMT_YVU410 v4l2_fourcc('Y', 'V', 'U', '9')
-/* WARNING: DO NOT EDIT, AUTO-GENERATED CODE - SEE TOP FOR INSTRUCTIONS */
 #define V4L2_PIX_FMT_YVU420 v4l2_fourcc('Y', 'V', '1', '2')
 #define V4L2_PIX_FMT_YUYV v4l2_fourcc('Y', 'U', 'Y', 'V')
+/* WARNING: DO NOT EDIT, AUTO-GENERATED CODE - SEE TOP FOR INSTRUCTIONS */
 #define V4L2_PIX_FMT_YYUV v4l2_fourcc('Y', 'Y', 'U', 'V')
 #define V4L2_PIX_FMT_YVYU v4l2_fourcc('Y', 'V', 'Y', 'U')
-/* WARNING: DO NOT EDIT, AUTO-GENERATED CODE - SEE TOP FOR INSTRUCTIONS */
 #define V4L2_PIX_FMT_UYVY v4l2_fourcc('U', 'Y', 'V', 'Y')
 #define V4L2_PIX_FMT_VYUY v4l2_fourcc('V', 'Y', 'U', 'Y')
+/* WARNING: DO NOT EDIT, AUTO-GENERATED CODE - SEE TOP FOR INSTRUCTIONS */
 #define V4L2_PIX_FMT_YUV422P v4l2_fourcc('4', '2', '2', 'P')
 #define V4L2_PIX_FMT_YUV411P v4l2_fourcc('4', '1', '1', 'P')
-/* WARNING: DO NOT EDIT, AUTO-GENERATED CODE - SEE TOP FOR INSTRUCTIONS */
 #define V4L2_PIX_FMT_Y41P v4l2_fourcc('Y', '4', '1', 'P')
 #define V4L2_PIX_FMT_YUV444 v4l2_fourcc('Y', '4', '4', '4')
+/* WARNING: DO NOT EDIT, AUTO-GENERATED CODE - SEE TOP FOR INSTRUCTIONS */
 #define V4L2_PIX_FMT_YUV555 v4l2_fourcc('Y', 'U', 'V', 'O')
 #define V4L2_PIX_FMT_YUV565 v4l2_fourcc('Y', 'U', 'V', 'P')
-/* WARNING: DO NOT EDIT, AUTO-GENERATED CODE - SEE TOP FOR INSTRUCTIONS */
 #define V4L2_PIX_FMT_YUV32 v4l2_fourcc('Y', 'U', 'V', '4')
 #define V4L2_PIX_FMT_YUV410 v4l2_fourcc('Y', 'U', 'V', '9')
+/* WARNING: DO NOT EDIT, AUTO-GENERATED CODE - SEE TOP FOR INSTRUCTIONS */
 #define V4L2_PIX_FMT_YUV420 v4l2_fourcc('Y', 'U', '1', '2')
 #define V4L2_PIX_FMT_HI240 v4l2_fourcc('H', 'I', '2', '4')
-/* WARNING: DO NOT EDIT, AUTO-GENERATED CODE - SEE TOP FOR INSTRUCTIONS */
 #define V4L2_PIX_FMT_HM12 v4l2_fourcc('H', 'M', '1', '2')
 #define V4L2_PIX_FMT_M420 v4l2_fourcc('M', '4', '2', '0')
+/* WARNING: DO NOT EDIT, AUTO-GENERATED CODE - SEE TOP FOR INSTRUCTIONS */
 #define V4L2_PIX_FMT_NV12 v4l2_fourcc('N', 'V', '1', '2')
 #define V4L2_PIX_FMT_NV21 v4l2_fourcc('N', 'V', '2', '1')
-/* WARNING: DO NOT EDIT, AUTO-GENERATED CODE - SEE TOP FOR INSTRUCTIONS */
 #define V4L2_PIX_FMT_NV16 v4l2_fourcc('N', 'V', '1', '6')
 #define V4L2_PIX_FMT_NV61 v4l2_fourcc('N', 'V', '6', '1')
+/* WARNING: DO NOT EDIT, AUTO-GENERATED CODE - SEE TOP FOR INSTRUCTIONS */
 #define V4L2_PIX_FMT_NV24 v4l2_fourcc('N', 'V', '2', '4')
 #define V4L2_PIX_FMT_NV42 v4l2_fourcc('N', 'V', '4', '2')
-/* WARNING: DO NOT EDIT, AUTO-GENERATED CODE - SEE TOP FOR INSTRUCTIONS */
 #define V4L2_PIX_FMT_NV12M v4l2_fourcc('N', 'M', '1', '2')
 #define V4L2_PIX_FMT_NV21M v4l2_fourcc('N', 'M', '2', '1')
+/* WARNING: DO NOT EDIT, AUTO-GENERATED CODE - SEE TOP FOR INSTRUCTIONS */
 #define V4L2_PIX_FMT_NV16M v4l2_fourcc('N', 'M', '1', '6')
 #define V4L2_PIX_FMT_NV61M v4l2_fourcc('N', 'M', '6', '1')
-/* WARNING: DO NOT EDIT, AUTO-GENERATED CODE - SEE TOP FOR INSTRUCTIONS */
 #define V4L2_PIX_FMT_NV12MT v4l2_fourcc('T', 'M', '1', '2')
 #define V4L2_PIX_FMT_NV12MT_16X16 v4l2_fourcc('V', 'M', '1', '2')
+/* WARNING: DO NOT EDIT, AUTO-GENERATED CODE - SEE TOP FOR INSTRUCTIONS */
 #define V4L2_PIX_FMT_YUV420M v4l2_fourcc('Y', 'M', '1', '2')
 #define V4L2_PIX_FMT_YVU420M v4l2_fourcc('Y', 'M', '2', '1')
-/* WARNING: DO NOT EDIT, AUTO-GENERATED CODE - SEE TOP FOR INSTRUCTIONS */
 #define V4L2_PIX_FMT_SBGGR8 v4l2_fourcc('B', 'A', '8', '1')
 #define V4L2_PIX_FMT_SGBRG8 v4l2_fourcc('G', 'B', 'R', 'G')
+/* WARNING: DO NOT EDIT, AUTO-GENERATED CODE - SEE TOP FOR INSTRUCTIONS */
 #define V4L2_PIX_FMT_SGRBG8 v4l2_fourcc('G', 'R', 'B', 'G')
 #define V4L2_PIX_FMT_SRGGB8 v4l2_fourcc('R', 'G', 'G', 'B')
-/* WARNING: DO NOT EDIT, AUTO-GENERATED CODE - SEE TOP FOR INSTRUCTIONS */
 #define V4L2_PIX_FMT_SBGGR10 v4l2_fourcc('B', 'G', '1', '0')
 #define V4L2_PIX_FMT_SGBRG10 v4l2_fourcc('G', 'B', '1', '0')
+/* WARNING: DO NOT EDIT, AUTO-GENERATED CODE - SEE TOP FOR INSTRUCTIONS */
 #define V4L2_PIX_FMT_SGRBG10 v4l2_fourcc('B', 'A', '1', '0')
 #define V4L2_PIX_FMT_SRGGB10 v4l2_fourcc('R', 'G', '1', '0')
+#define V4L2_PIX_FMT_SBGGR10P v4l2_fourcc('p', 'B', 'A', 'A')
+#define V4L2_PIX_FMT_SGBRG10P v4l2_fourcc('p', 'G', 'A', 'A')
 /* WARNING: DO NOT EDIT, AUTO-GENERATED CODE - SEE TOP FOR INSTRUCTIONS */
-#define V4L2_PIX_FMT_SBGGR12 v4l2_fourcc('B', 'G', '1', '2')
-#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')
-/* WARNING: DO NOT EDIT, AUTO-GENERATED CODE - SEE TOP FOR INSTRUCTIONS */
+#define V4L2_PIX_FMT_SGRBG10P v4l2_fourcc('p', 'g', 'A', 'A')
+#define V4L2_PIX_FMT_SRGGB10P v4l2_fourcc('p', 'R', 'A', 'A')
 #define V4L2_PIX_FMT_SBGGR10ALAW8 v4l2_fourcc('a', 'B', 'A', '8')
 #define V4L2_PIX_FMT_SGBRG10ALAW8 v4l2_fourcc('a', 'G', 'A', '8')
+/* WARNING: DO NOT EDIT, AUTO-GENERATED CODE - SEE TOP FOR INSTRUCTIONS */
 #define V4L2_PIX_FMT_SGRBG10ALAW8 v4l2_fourcc('a', 'g', 'A', '8')
 #define V4L2_PIX_FMT_SRGGB10ALAW8 v4l2_fourcc('a', 'R', 'A', '8')
-/* WARNING: DO NOT EDIT, AUTO-GENERATED CODE - SEE TOP FOR INSTRUCTIONS */
 #define V4L2_PIX_FMT_SBGGR10DPCM8 v4l2_fourcc('b', 'B', 'A', '8')
 #define V4L2_PIX_FMT_SGBRG10DPCM8 v4l2_fourcc('b', 'G', 'A', '8')
+/* WARNING: DO NOT EDIT, AUTO-GENERATED CODE - SEE TOP FOR INSTRUCTIONS */
 #define V4L2_PIX_FMT_SGRBG10DPCM8 v4l2_fourcc('B', 'D', '1', '0')
 #define V4L2_PIX_FMT_SRGGB10DPCM8 v4l2_fourcc('b', 'R', 'A', '8')
+#define V4L2_PIX_FMT_SBGGR12 v4l2_fourcc('B', 'G', '1', '2')
+#define V4L2_PIX_FMT_SGBRG12 v4l2_fourcc('G', 'B', '1', '2')
 /* WARNING: DO NOT EDIT, AUTO-GENERATED CODE - SEE TOP FOR INSTRUCTIONS */
+#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_SBGGR16 v4l2_fourcc('B', 'Y', 'R', '2')
 #define V4L2_PIX_FMT_MJPEG v4l2_fourcc('M', 'J', 'P', 'G')
+/* WARNING: DO NOT EDIT, AUTO-GENERATED CODE - SEE TOP FOR INSTRUCTIONS */
 #define V4L2_PIX_FMT_JPEG v4l2_fourcc('J', 'P', 'E', 'G')
 #define V4L2_PIX_FMT_DV v4l2_fourcc('d', 'v', 's', 'd')
-/* WARNING: DO NOT EDIT, AUTO-GENERATED CODE - SEE TOP FOR INSTRUCTIONS */
 #define V4L2_PIX_FMT_MPEG v4l2_fourcc('M', 'P', 'E', 'G')
 #define V4L2_PIX_FMT_H264 v4l2_fourcc('H', '2', '6', '4')
+/* WARNING: DO NOT EDIT, AUTO-GENERATED CODE - SEE TOP FOR INSTRUCTIONS */
 #define V4L2_PIX_FMT_H264_NO_SC v4l2_fourcc('A', 'V', 'C', '1')
 #define V4L2_PIX_FMT_H264_MVC v4l2_fourcc('M', '2', '6', '4')
-/* WARNING: DO NOT EDIT, AUTO-GENERATED CODE - SEE TOP FOR INSTRUCTIONS */
 #define V4L2_PIX_FMT_H263 v4l2_fourcc('H', '2', '6', '3')
 #define V4L2_PIX_FMT_MPEG1 v4l2_fourcc('M', 'P', 'G', '1')
+/* WARNING: DO NOT EDIT, AUTO-GENERATED CODE - SEE TOP FOR INSTRUCTIONS */
 #define V4L2_PIX_FMT_MPEG2 v4l2_fourcc('M', 'P', 'G', '2')
 #define V4L2_PIX_FMT_MPEG4 v4l2_fourcc('M', 'P', 'G', '4')
-/* WARNING: DO NOT EDIT, AUTO-GENERATED CODE - SEE TOP FOR INSTRUCTIONS */
 #define V4L2_PIX_FMT_XVID v4l2_fourcc('X', 'V', 'I', 'D')
 #define V4L2_PIX_FMT_VC1_ANNEX_G v4l2_fourcc('V', 'C', '1', 'G')
+/* WARNING: DO NOT EDIT, AUTO-GENERATED CODE - SEE TOP FOR INSTRUCTIONS */
 #define V4L2_PIX_FMT_VC1_ANNEX_L v4l2_fourcc('V', 'C', '1', 'L')
 #define V4L2_PIX_FMT_VP8 v4l2_fourcc('V', 'P', '8', '0')
-/* WARNING: DO NOT EDIT, AUTO-GENERATED CODE - SEE TOP FOR INSTRUCTIONS */
 #define V4L2_PIX_FMT_CPIA1 v4l2_fourcc('C', 'P', 'I', 'A')
 #define V4L2_PIX_FMT_WNVA v4l2_fourcc('W', 'N', 'V', 'A')
+/* WARNING: DO NOT EDIT, AUTO-GENERATED CODE - SEE TOP FOR INSTRUCTIONS */
 #define V4L2_PIX_FMT_SN9C10X v4l2_fourcc('S', '9', '1', '0')
 #define V4L2_PIX_FMT_SN9C20X_I420 v4l2_fourcc('S', '9', '2', '0')
-/* WARNING: DO NOT EDIT, AUTO-GENERATED CODE - SEE TOP FOR INSTRUCTIONS */
 #define V4L2_PIX_FMT_PWC1 v4l2_fourcc('P', 'W', 'C', '1')
 #define V4L2_PIX_FMT_PWC2 v4l2_fourcc('P', 'W', 'C', '2')
+/* WARNING: DO NOT EDIT, AUTO-GENERATED CODE - SEE TOP FOR INSTRUCTIONS */
 #define V4L2_PIX_FMT_ET61X251 v4l2_fourcc('E', '6', '2', '5')
 #define V4L2_PIX_FMT_SPCA501 v4l2_fourcc('S', '5', '0', '1')
-/* WARNING: DO NOT EDIT, AUTO-GENERATED CODE - SEE TOP FOR INSTRUCTIONS */
 #define V4L2_PIX_FMT_SPCA505 v4l2_fourcc('S', '5', '0', '5')
 #define V4L2_PIX_FMT_SPCA508 v4l2_fourcc('S', '5', '0', '8')
+/* WARNING: DO NOT EDIT, AUTO-GENERATED CODE - SEE TOP FOR INSTRUCTIONS */
 #define V4L2_PIX_FMT_SPCA561 v4l2_fourcc('S', '5', '6', '1')
 #define V4L2_PIX_FMT_PAC207 v4l2_fourcc('P', '2', '0', '7')
-/* WARNING: DO NOT EDIT, AUTO-GENERATED CODE - SEE TOP FOR INSTRUCTIONS */
 #define V4L2_PIX_FMT_MR97310A v4l2_fourcc('M', '3', '1', '0')
 #define V4L2_PIX_FMT_JL2005BCD v4l2_fourcc('J', 'L', '2', '0')
+/* WARNING: DO NOT EDIT, AUTO-GENERATED CODE - SEE TOP FOR INSTRUCTIONS */
 #define V4L2_PIX_FMT_SN9C2028 v4l2_fourcc('S', 'O', 'N', 'X')
 #define V4L2_PIX_FMT_SQ905C v4l2_fourcc('9', '0', '5', 'C')
-/* WARNING: DO NOT EDIT, AUTO-GENERATED CODE - SEE TOP FOR INSTRUCTIONS */
 #define V4L2_PIX_FMT_PJPG v4l2_fourcc('P', 'J', 'P', 'G')
 #define V4L2_PIX_FMT_OV511 v4l2_fourcc('O', '5', '1', '1')
+/* WARNING: DO NOT EDIT, AUTO-GENERATED CODE - SEE TOP FOR INSTRUCTIONS */
 #define V4L2_PIX_FMT_OV518 v4l2_fourcc('O', '5', '1', '8')
 #define V4L2_PIX_FMT_STV0680 v4l2_fourcc('S', '6', '8', '0')
-/* WARNING: DO NOT EDIT, AUTO-GENERATED CODE - SEE TOP FOR INSTRUCTIONS */
 #define V4L2_PIX_FMT_TM6000 v4l2_fourcc('T', 'M', '6', '0')
 #define V4L2_PIX_FMT_CIT_YYVYUY v4l2_fourcc('C', 'I', 'T', 'V')
+/* WARNING: DO NOT EDIT, AUTO-GENERATED CODE - SEE TOP FOR INSTRUCTIONS */
 #define V4L2_PIX_FMT_KONICA420 v4l2_fourcc('K', 'O', 'N', 'I')
 #define V4L2_PIX_FMT_JPGL v4l2_fourcc('J', 'P', 'G', 'L')
-/* WARNING: DO NOT EDIT, AUTO-GENERATED CODE - SEE TOP FOR INSTRUCTIONS */
 #define V4L2_PIX_FMT_SE401 v4l2_fourcc('S', '4', '0', '1')
 #define V4L2_PIX_FMT_S5C_UYVY_JPG v4l2_fourcc('S', '5', 'C', 'I')
+/* WARNING: DO NOT EDIT, AUTO-GENERATED CODE - SEE TOP FOR INSTRUCTIONS */
 #define V4L2_SDR_FMT_CU8 v4l2_fourcc('C', 'U', '0', '8')
 #define V4L2_SDR_FMT_CU16LE v4l2_fourcc('C', 'U', '1', '6')
-/* WARNING: DO NOT EDIT, AUTO-GENERATED CODE - SEE TOP FOR INSTRUCTIONS */
 #define V4L2_SDR_FMT_CS8 v4l2_fourcc('C', 'S', '0', '8')
 #define V4L2_SDR_FMT_CS14LE v4l2_fourcc('C', 'S', '1', '4')
+/* WARNING: DO NOT EDIT, AUTO-GENERATED CODE - SEE TOP FOR INSTRUCTIONS */
 #define V4L2_SDR_FMT_RU12LE v4l2_fourcc('R', 'U', '1', '2')
 #define V4L2_PIX_FMT_PRIV_MAGIC 0xfeedcafe
-/* WARNING: DO NOT EDIT, AUTO-GENERATED CODE - SEE TOP FOR INSTRUCTIONS */
 #define V4L2_PIX_FMT_FLAG_PREMUL_ALPHA 0x00000001
 struct v4l2_fmtdesc {
+/* WARNING: DO NOT EDIT, AUTO-GENERATED CODE - SEE TOP FOR INSTRUCTIONS */
   __u32 index;
   __u32 type;
-/* WARNING: DO NOT EDIT, AUTO-GENERATED CODE - SEE TOP FOR INSTRUCTIONS */
   __u32 flags;
   __u8 description[32];
+/* WARNING: DO NOT EDIT, AUTO-GENERATED CODE - SEE TOP FOR INSTRUCTIONS */
   __u32 pixelformat;
   __u32 reserved[4];
-/* WARNING: DO NOT EDIT, AUTO-GENERATED CODE - SEE TOP FOR INSTRUCTIONS */
 };
 #define V4L2_FMT_FLAG_COMPRESSED 0x0001
+/* WARNING: DO NOT EDIT, AUTO-GENERATED CODE - SEE TOP FOR INSTRUCTIONS */
 #define V4L2_FMT_FLAG_EMULATED 0x0002
 enum v4l2_frmsizetypes {
-/* WARNING: DO NOT EDIT, AUTO-GENERATED CODE - SEE TOP FOR INSTRUCTIONS */
   V4L2_FRMSIZE_TYPE_DISCRETE = 1,
   V4L2_FRMSIZE_TYPE_CONTINUOUS = 2,
+/* WARNING: DO NOT EDIT, AUTO-GENERATED CODE - SEE TOP FOR INSTRUCTIONS */
   V4L2_FRMSIZE_TYPE_STEPWISE = 3,
 };
-/* WARNING: DO NOT EDIT, AUTO-GENERATED CODE - SEE TOP FOR INSTRUCTIONS */
 struct v4l2_frmsize_discrete {
   __u32 width;
+/* WARNING: DO NOT EDIT, AUTO-GENERATED CODE - SEE TOP FOR INSTRUCTIONS */
   __u32 height;
 };
-/* WARNING: DO NOT EDIT, AUTO-GENERATED CODE - SEE TOP FOR INSTRUCTIONS */
 struct v4l2_frmsize_stepwise {
   __u32 min_width;
+/* WARNING: DO NOT EDIT, AUTO-GENERATED CODE - SEE TOP FOR INSTRUCTIONS */
   __u32 max_width;
   __u32 step_width;
-/* WARNING: DO NOT EDIT, AUTO-GENERATED CODE - SEE TOP FOR INSTRUCTIONS */
   __u32 min_height;
   __u32 max_height;
+/* WARNING: DO NOT EDIT, AUTO-GENERATED CODE - SEE TOP FOR INSTRUCTIONS */
   __u32 step_height;
 };
-/* WARNING: DO NOT EDIT, AUTO-GENERATED CODE - SEE TOP FOR INSTRUCTIONS */
 struct v4l2_frmsizeenum {
   __u32 index;
+/* WARNING: DO NOT EDIT, AUTO-GENERATED CODE - SEE TOP FOR INSTRUCTIONS */
   __u32 pixel_format;
   __u32 type;
-/* WARNING: DO NOT EDIT, AUTO-GENERATED CODE - SEE TOP FOR INSTRUCTIONS */
   union {
     struct v4l2_frmsize_discrete discrete;
+/* WARNING: DO NOT EDIT, AUTO-GENERATED CODE - SEE TOP FOR INSTRUCTIONS */
     struct v4l2_frmsize_stepwise stepwise;
   };
-/* WARNING: DO NOT EDIT, AUTO-GENERATED CODE - SEE TOP FOR INSTRUCTIONS */
   __u32 reserved[2];
 };
+/* WARNING: DO NOT EDIT, AUTO-GENERATED CODE - SEE TOP FOR INSTRUCTIONS */
 enum v4l2_frmivaltypes {
   V4L2_FRMIVAL_TYPE_DISCRETE = 1,
-/* WARNING: DO NOT EDIT, AUTO-GENERATED CODE - SEE TOP FOR INSTRUCTIONS */
   V4L2_FRMIVAL_TYPE_CONTINUOUS = 2,
   V4L2_FRMIVAL_TYPE_STEPWISE = 3,
+/* WARNING: DO NOT EDIT, AUTO-GENERATED CODE - SEE TOP FOR INSTRUCTIONS */
 };
 struct v4l2_frmival_stepwise {
-/* WARNING: DO NOT EDIT, AUTO-GENERATED CODE - SEE TOP FOR INSTRUCTIONS */
   struct v4l2_fract min;
   struct v4l2_fract max;
+/* WARNING: DO NOT EDIT, AUTO-GENERATED CODE - SEE TOP FOR INSTRUCTIONS */
   struct v4l2_fract step;
 };
-/* WARNING: DO NOT EDIT, AUTO-GENERATED CODE - SEE TOP FOR INSTRUCTIONS */
 struct v4l2_frmivalenum {
   __u32 index;
+/* WARNING: DO NOT EDIT, AUTO-GENERATED CODE - SEE TOP FOR INSTRUCTIONS */
   __u32 pixel_format;
   __u32 width;
-/* WARNING: DO NOT EDIT, AUTO-GENERATED CODE - SEE TOP FOR INSTRUCTIONS */
   __u32 height;
   __u32 type;
+/* WARNING: DO NOT EDIT, AUTO-GENERATED CODE - SEE TOP FOR INSTRUCTIONS */
   union {
     struct v4l2_fract discrete;
-/* WARNING: DO NOT EDIT, AUTO-GENERATED CODE - SEE TOP FOR INSTRUCTIONS */
     struct v4l2_frmival_stepwise stepwise;
   };
+/* WARNING: DO NOT EDIT, AUTO-GENERATED CODE - SEE TOP FOR INSTRUCTIONS */
   __u32 reserved[2];
 };
-/* WARNING: DO NOT EDIT, AUTO-GENERATED CODE - SEE TOP FOR INSTRUCTIONS */
 struct v4l2_timecode {
   __u32 type;
+/* WARNING: DO NOT EDIT, AUTO-GENERATED CODE - SEE TOP FOR INSTRUCTIONS */
   __u32 flags;
   __u8 frames;
-/* WARNING: DO NOT EDIT, AUTO-GENERATED CODE - SEE TOP FOR INSTRUCTIONS */
   __u8 seconds;
   __u8 minutes;
+/* WARNING: DO NOT EDIT, AUTO-GENERATED CODE - SEE TOP FOR INSTRUCTIONS */
   __u8 hours;
   __u8 userbits[4];
-/* WARNING: DO NOT EDIT, AUTO-GENERATED CODE - SEE TOP FOR INSTRUCTIONS */
 };
 #define V4L2_TC_TYPE_24FPS 1
+/* WARNING: DO NOT EDIT, AUTO-GENERATED CODE - SEE TOP FOR INSTRUCTIONS */
 #define V4L2_TC_TYPE_25FPS 2
 #define V4L2_TC_TYPE_30FPS 3
-/* WARNING: DO NOT EDIT, AUTO-GENERATED CODE - SEE TOP FOR INSTRUCTIONS */
 #define V4L2_TC_TYPE_50FPS 4
 #define V4L2_TC_TYPE_60FPS 5
+/* WARNING: DO NOT EDIT, AUTO-GENERATED CODE - SEE TOP FOR INSTRUCTIONS */
 #define V4L2_TC_FLAG_DROPFRAME 0x0001
 #define V4L2_TC_FLAG_COLORFRAME 0x0002
-/* WARNING: DO NOT EDIT, AUTO-GENERATED CODE - SEE TOP FOR INSTRUCTIONS */
 #define V4L2_TC_USERBITS_field 0x000C
 #define V4L2_TC_USERBITS_USERDEFINED 0x0000
+/* WARNING: DO NOT EDIT, AUTO-GENERATED CODE - SEE TOP FOR INSTRUCTIONS */
 #define V4L2_TC_USERBITS_8BITCHARS 0x0008
 struct v4l2_jpegcompression {
-/* WARNING: DO NOT EDIT, AUTO-GENERATED CODE - SEE TOP FOR INSTRUCTIONS */
   int quality;
   int APPn;
+/* WARNING: DO NOT EDIT, AUTO-GENERATED CODE - SEE TOP FOR INSTRUCTIONS */
   int APP_len;
   char APP_data[60];
-/* WARNING: DO NOT EDIT, AUTO-GENERATED CODE - SEE TOP FOR INSTRUCTIONS */
   int COM_len;
   char COM_data[60];
+/* WARNING: DO NOT EDIT, AUTO-GENERATED CODE - SEE TOP FOR INSTRUCTIONS */
   __u32 jpeg_markers;
 #define V4L2_JPEG_MARKER_DHT (1 << 3)
-/* WARNING: DO NOT EDIT, AUTO-GENERATED CODE - SEE TOP FOR INSTRUCTIONS */
 #define V4L2_JPEG_MARKER_DQT (1 << 4)
 #define V4L2_JPEG_MARKER_DRI (1 << 5)
+/* WARNING: DO NOT EDIT, AUTO-GENERATED CODE - SEE TOP FOR INSTRUCTIONS */
 #define V4L2_JPEG_MARKER_COM (1 << 6)
 #define V4L2_JPEG_MARKER_APP (1 << 7)
-/* WARNING: DO NOT EDIT, AUTO-GENERATED CODE - SEE TOP FOR INSTRUCTIONS */
 };
 struct v4l2_requestbuffers {
+/* WARNING: DO NOT EDIT, AUTO-GENERATED CODE - SEE TOP FOR INSTRUCTIONS */
   __u32 count;
   __u32 type;
-/* WARNING: DO NOT EDIT, AUTO-GENERATED CODE - SEE TOP FOR INSTRUCTIONS */
   __u32 memory;
   __u32 reserved[2];
+/* WARNING: DO NOT EDIT, AUTO-GENERATED CODE - SEE TOP FOR INSTRUCTIONS */
 };
 struct v4l2_plane {
-/* WARNING: DO NOT EDIT, AUTO-GENERATED CODE - SEE TOP FOR INSTRUCTIONS */
   __u32 bytesused;
   __u32 length;
+/* WARNING: DO NOT EDIT, AUTO-GENERATED CODE - SEE TOP FOR INSTRUCTIONS */
   union {
     __u32 mem_offset;
-/* WARNING: DO NOT EDIT, AUTO-GENERATED CODE - SEE TOP FOR INSTRUCTIONS */
     unsigned long userptr;
     __s32 fd;
+/* WARNING: DO NOT EDIT, AUTO-GENERATED CODE - SEE TOP FOR INSTRUCTIONS */
   } m;
   __u32 data_offset;
-/* WARNING: DO NOT EDIT, AUTO-GENERATED CODE - SEE TOP FOR INSTRUCTIONS */
   __u32 reserved[11];
 };
+/* WARNING: DO NOT EDIT, AUTO-GENERATED CODE - SEE TOP FOR INSTRUCTIONS */
 struct v4l2_buffer {
   __u32 index;
-/* WARNING: DO NOT EDIT, AUTO-GENERATED CODE - SEE TOP FOR INSTRUCTIONS */
   __u32 type;
   __u32 bytesused;
+/* WARNING: DO NOT EDIT, AUTO-GENERATED CODE - SEE TOP FOR INSTRUCTIONS */
   __u32 flags;
   __u32 field;
-/* WARNING: DO NOT EDIT, AUTO-GENERATED CODE - SEE TOP FOR INSTRUCTIONS */
   struct timeval timestamp;
   struct v4l2_timecode timecode;
+/* WARNING: DO NOT EDIT, AUTO-GENERATED CODE - SEE TOP FOR INSTRUCTIONS */
   __u32 sequence;
   __u32 memory;
-/* WARNING: DO NOT EDIT, AUTO-GENERATED CODE - SEE TOP FOR INSTRUCTIONS */
   union {
     __u32 offset;
+/* WARNING: DO NOT EDIT, AUTO-GENERATED CODE - SEE TOP FOR INSTRUCTIONS */
     unsigned long userptr;
     struct v4l2_plane * planes;
-/* WARNING: DO NOT EDIT, AUTO-GENERATED CODE - SEE TOP FOR INSTRUCTIONS */
     __s32 fd;
   } m;
+/* WARNING: DO NOT EDIT, AUTO-GENERATED CODE - SEE TOP FOR INSTRUCTIONS */
   __u32 length;
   __u32 reserved2;
-/* WARNING: DO NOT EDIT, AUTO-GENERATED CODE - SEE TOP FOR INSTRUCTIONS */
   __u32 reserved;
 };
+/* WARNING: DO NOT EDIT, AUTO-GENERATED CODE - SEE TOP FOR INSTRUCTIONS */
 #define V4L2_BUF_FLAG_MAPPED 0x00000001
 #define V4L2_BUF_FLAG_QUEUED 0x00000002
-/* WARNING: DO NOT EDIT, AUTO-GENERATED CODE - SEE TOP FOR INSTRUCTIONS */
 #define V4L2_BUF_FLAG_DONE 0x00000004
 #define V4L2_BUF_FLAG_KEYFRAME 0x00000008
+/* WARNING: DO NOT EDIT, AUTO-GENERATED CODE - SEE TOP FOR INSTRUCTIONS */
 #define V4L2_BUF_FLAG_PFRAME 0x00000010
 #define V4L2_BUF_FLAG_BFRAME 0x00000020
-/* WARNING: DO NOT EDIT, AUTO-GENERATED CODE - SEE TOP FOR INSTRUCTIONS */
 #define V4L2_BUF_FLAG_ERROR 0x00000040
 #define V4L2_BUF_FLAG_TIMECODE 0x00000100
+/* WARNING: DO NOT EDIT, AUTO-GENERATED CODE - SEE TOP FOR INSTRUCTIONS */
 #define V4L2_BUF_FLAG_PREPARED 0x00000400
 #define V4L2_BUF_FLAG_NO_CACHE_INVALIDATE 0x00000800
-/* WARNING: DO NOT EDIT, AUTO-GENERATED CODE - SEE TOP FOR INSTRUCTIONS */
 #define V4L2_BUF_FLAG_NO_CACHE_CLEAN 0x00001000
 #define V4L2_BUF_FLAG_TIMESTAMP_MASK 0x0000e000
+/* WARNING: DO NOT EDIT, AUTO-GENERATED CODE - SEE TOP FOR INSTRUCTIONS */
 #define V4L2_BUF_FLAG_TIMESTAMP_UNKNOWN 0x00000000
 #define V4L2_BUF_FLAG_TIMESTAMP_MONOTONIC 0x00002000
-/* WARNING: DO NOT EDIT, AUTO-GENERATED CODE - SEE TOP FOR INSTRUCTIONS */
 #define V4L2_BUF_FLAG_TIMESTAMP_COPY 0x00004000
 #define V4L2_BUF_FLAG_TSTAMP_SRC_MASK 0x00070000
+/* WARNING: DO NOT EDIT, AUTO-GENERATED CODE - SEE TOP FOR INSTRUCTIONS */
 #define V4L2_BUF_FLAG_TSTAMP_SRC_EOF 0x00000000
 #define V4L2_BUF_FLAG_TSTAMP_SRC_SOE 0x00010000
-/* WARNING: DO NOT EDIT, AUTO-GENERATED CODE - SEE TOP FOR INSTRUCTIONS */
+#define V4L2_BUF_FLAG_LAST 0x00100000
 struct v4l2_exportbuffer {
+/* WARNING: DO NOT EDIT, AUTO-GENERATED CODE - SEE TOP FOR INSTRUCTIONS */
   __u32 type;
   __u32 index;
   __u32 plane;
-/* WARNING: DO NOT EDIT, AUTO-GENERATED CODE - SEE TOP FOR INSTRUCTIONS */
   __u32 flags;
+/* WARNING: DO NOT EDIT, AUTO-GENERATED CODE - SEE TOP FOR INSTRUCTIONS */
   __s32 fd;
   __u32 reserved[11];
 };
-/* WARNING: DO NOT EDIT, AUTO-GENERATED CODE - SEE TOP FOR INSTRUCTIONS */
 struct v4l2_framebuffer {
+/* WARNING: DO NOT EDIT, AUTO-GENERATED CODE - SEE TOP FOR INSTRUCTIONS */
   __u32 capability;
   __u32 flags;
   void * base;
-/* WARNING: DO NOT EDIT, AUTO-GENERATED CODE - SEE TOP FOR INSTRUCTIONS */
   struct {
+/* WARNING: DO NOT EDIT, AUTO-GENERATED CODE - SEE TOP FOR INSTRUCTIONS */
     __u32 width;
     __u32 height;
     __u32 pixelformat;
-/* WARNING: DO NOT EDIT, AUTO-GENERATED CODE - SEE TOP FOR INSTRUCTIONS */
     __u32 field;
+/* WARNING: DO NOT EDIT, AUTO-GENERATED CODE - SEE TOP FOR INSTRUCTIONS */
     __u32 bytesperline;
     __u32 sizeimage;
     __u32 colorspace;
-/* WARNING: DO NOT EDIT, AUTO-GENERATED CODE - SEE TOP FOR INSTRUCTIONS */
     __u32 priv;
+/* WARNING: DO NOT EDIT, AUTO-GENERATED CODE - SEE TOP FOR INSTRUCTIONS */
   } fmt;
 };
 #define V4L2_FBUF_CAP_EXTERNOVERLAY 0x0001
-/* WARNING: DO NOT EDIT, AUTO-GENERATED CODE - SEE TOP FOR INSTRUCTIONS */
 #define V4L2_FBUF_CAP_CHROMAKEY 0x0002
+/* WARNING: DO NOT EDIT, AUTO-GENERATED CODE - SEE TOP FOR INSTRUCTIONS */
 #define V4L2_FBUF_CAP_LIST_CLIPPING 0x0004
 #define V4L2_FBUF_CAP_BITMAP_CLIPPING 0x0008
 #define V4L2_FBUF_CAP_LOCAL_ALPHA 0x0010
-/* WARNING: DO NOT EDIT, AUTO-GENERATED CODE - SEE TOP FOR INSTRUCTIONS */
 #define V4L2_FBUF_CAP_GLOBAL_ALPHA 0x0020
+/* WARNING: DO NOT EDIT, AUTO-GENERATED CODE - SEE TOP FOR INSTRUCTIONS */
 #define V4L2_FBUF_CAP_LOCAL_INV_ALPHA 0x0040
 #define V4L2_FBUF_CAP_SRC_CHROMAKEY 0x0080
 #define V4L2_FBUF_FLAG_PRIMARY 0x0001
-/* WARNING: DO NOT EDIT, AUTO-GENERATED CODE - SEE TOP FOR INSTRUCTIONS */
 #define V4L2_FBUF_FLAG_OVERLAY 0x0002
+/* WARNING: DO NOT EDIT, AUTO-GENERATED CODE - SEE TOP FOR INSTRUCTIONS */
 #define V4L2_FBUF_FLAG_CHROMAKEY 0x0004
 #define V4L2_FBUF_FLAG_LOCAL_ALPHA 0x0008
 #define V4L2_FBUF_FLAG_GLOBAL_ALPHA 0x0010
-/* WARNING: DO NOT EDIT, AUTO-GENERATED CODE - SEE TOP FOR INSTRUCTIONS */
 #define V4L2_FBUF_FLAG_LOCAL_INV_ALPHA 0x0020
+/* WARNING: DO NOT EDIT, AUTO-GENERATED CODE - SEE TOP FOR INSTRUCTIONS */
 #define V4L2_FBUF_FLAG_SRC_CHROMAKEY 0x0040
 struct v4l2_clip {
   struct v4l2_rect c;
-/* WARNING: DO NOT EDIT, AUTO-GENERATED CODE - SEE TOP FOR INSTRUCTIONS */
   struct v4l2_clip __user * next;
+/* WARNING: DO NOT EDIT, AUTO-GENERATED CODE - SEE TOP FOR INSTRUCTIONS */
 };
 struct v4l2_window {
   struct v4l2_rect w;
-/* WARNING: DO NOT EDIT, AUTO-GENERATED CODE - SEE TOP FOR INSTRUCTIONS */
   __u32 field;
+/* WARNING: DO NOT EDIT, AUTO-GENERATED CODE - SEE TOP FOR INSTRUCTIONS */
   __u32 chromakey;
   struct v4l2_clip __user * clips;
   __u32 clipcount;
-/* WARNING: DO NOT EDIT, AUTO-GENERATED CODE - SEE TOP FOR INSTRUCTIONS */
   void __user * bitmap;
+/* WARNING: DO NOT EDIT, AUTO-GENERATED CODE - SEE TOP FOR INSTRUCTIONS */
   __u8 global_alpha;
 };
 struct v4l2_captureparm {
-/* WARNING: DO NOT EDIT, AUTO-GENERATED CODE - SEE TOP FOR INSTRUCTIONS */
   __u32 capability;
+/* WARNING: DO NOT EDIT, AUTO-GENERATED CODE - SEE TOP FOR INSTRUCTIONS */
   __u32 capturemode;
   struct v4l2_fract timeperframe;
   __u32 extendedmode;
-/* WARNING: DO NOT EDIT, AUTO-GENERATED CODE - SEE TOP FOR INSTRUCTIONS */
   __u32 readbuffers;
+/* WARNING: DO NOT EDIT, AUTO-GENERATED CODE - SEE TOP FOR INSTRUCTIONS */
   __u32 reserved[4];
 };
 #define V4L2_MODE_HIGHQUALITY 0x0001
-/* WARNING: DO NOT EDIT, AUTO-GENERATED CODE - SEE TOP FOR INSTRUCTIONS */
 #define V4L2_CAP_TIMEPERFRAME 0x1000
+/* WARNING: DO NOT EDIT, AUTO-GENERATED CODE - SEE TOP FOR INSTRUCTIONS */
 struct v4l2_outputparm {
   __u32 capability;
   __u32 outputmode;
-/* WARNING: DO NOT EDIT, AUTO-GENERATED CODE - SEE TOP FOR INSTRUCTIONS */
   struct v4l2_fract timeperframe;
+/* WARNING: DO NOT EDIT, AUTO-GENERATED CODE - SEE TOP FOR INSTRUCTIONS */
   __u32 extendedmode;
   __u32 writebuffers;
   __u32 reserved[4];
-/* WARNING: DO NOT EDIT, AUTO-GENERATED CODE - SEE TOP FOR INSTRUCTIONS */
 };
+/* WARNING: DO NOT EDIT, AUTO-GENERATED CODE - SEE TOP FOR INSTRUCTIONS */
 struct v4l2_cropcap {
   __u32 type;
   struct v4l2_rect bounds;
-/* WARNING: DO NOT EDIT, AUTO-GENERATED CODE - SEE TOP FOR INSTRUCTIONS */
   struct v4l2_rect defrect;
+/* WARNING: DO NOT EDIT, AUTO-GENERATED CODE - SEE TOP FOR INSTRUCTIONS */
   struct v4l2_fract pixelaspect;
 };
 struct v4l2_crop {
-/* WARNING: DO NOT EDIT, AUTO-GENERATED CODE - SEE TOP FOR INSTRUCTIONS */
   __u32 type;
+/* WARNING: DO NOT EDIT, AUTO-GENERATED CODE - SEE TOP FOR INSTRUCTIONS */
   struct v4l2_rect c;
 };
 struct v4l2_selection {
-/* WARNING: DO NOT EDIT, AUTO-GENERATED CODE - SEE TOP FOR INSTRUCTIONS */
   __u32 type;
+/* WARNING: DO NOT EDIT, AUTO-GENERATED CODE - SEE TOP FOR INSTRUCTIONS */
   __u32 target;
   __u32 flags;
   struct v4l2_rect r;
-/* WARNING: DO NOT EDIT, AUTO-GENERATED CODE - SEE TOP FOR INSTRUCTIONS */
   __u32 reserved[9];
+/* WARNING: DO NOT EDIT, AUTO-GENERATED CODE - SEE TOP FOR INSTRUCTIONS */
 };
 typedef __u64 v4l2_std_id;
 #define V4L2_STD_PAL_B ((v4l2_std_id) 0x00000001)
-/* WARNING: DO NOT EDIT, AUTO-GENERATED CODE - SEE TOP FOR INSTRUCTIONS */
 #define V4L2_STD_PAL_B1 ((v4l2_std_id) 0x00000002)
+/* WARNING: DO NOT EDIT, AUTO-GENERATED CODE - SEE TOP FOR INSTRUCTIONS */
 #define V4L2_STD_PAL_G ((v4l2_std_id) 0x00000004)
 #define V4L2_STD_PAL_H ((v4l2_std_id) 0x00000008)
 #define V4L2_STD_PAL_I ((v4l2_std_id) 0x00000010)
-/* WARNING: DO NOT EDIT, AUTO-GENERATED CODE - SEE TOP FOR INSTRUCTIONS */
 #define V4L2_STD_PAL_D ((v4l2_std_id) 0x00000020)
+/* WARNING: DO NOT EDIT, AUTO-GENERATED CODE - SEE TOP FOR INSTRUCTIONS */
 #define V4L2_STD_PAL_D1 ((v4l2_std_id) 0x00000040)
 #define V4L2_STD_PAL_K ((v4l2_std_id) 0x00000080)
 #define V4L2_STD_PAL_M ((v4l2_std_id) 0x00000100)
-/* WARNING: DO NOT EDIT, AUTO-GENERATED CODE - SEE TOP FOR INSTRUCTIONS */
 #define V4L2_STD_PAL_N ((v4l2_std_id) 0x00000200)
+/* WARNING: DO NOT EDIT, AUTO-GENERATED CODE - SEE TOP FOR INSTRUCTIONS */
 #define V4L2_STD_PAL_Nc ((v4l2_std_id) 0x00000400)
 #define V4L2_STD_PAL_60 ((v4l2_std_id) 0x00000800)
 #define V4L2_STD_NTSC_M ((v4l2_std_id) 0x00001000)
-/* WARNING: DO NOT EDIT, AUTO-GENERATED CODE - SEE TOP FOR INSTRUCTIONS */
 #define V4L2_STD_NTSC_M_JP ((v4l2_std_id) 0x00002000)
+/* WARNING: DO NOT EDIT, AUTO-GENERATED CODE - SEE TOP FOR INSTRUCTIONS */
 #define V4L2_STD_NTSC_443 ((v4l2_std_id) 0x00004000)
 #define V4L2_STD_NTSC_M_KR ((v4l2_std_id) 0x00008000)
 #define V4L2_STD_SECAM_B ((v4l2_std_id) 0x00010000)
-/* WARNING: DO NOT EDIT, AUTO-GENERATED CODE - SEE TOP FOR INSTRUCTIONS */
 #define V4L2_STD_SECAM_D ((v4l2_std_id) 0x00020000)
+/* WARNING: DO NOT EDIT, AUTO-GENERATED CODE - SEE TOP FOR INSTRUCTIONS */
 #define V4L2_STD_SECAM_G ((v4l2_std_id) 0x00040000)
 #define V4L2_STD_SECAM_H ((v4l2_std_id) 0x00080000)
 #define V4L2_STD_SECAM_K ((v4l2_std_id) 0x00100000)
-/* WARNING: DO NOT EDIT, AUTO-GENERATED CODE - SEE TOP FOR INSTRUCTIONS */
 #define V4L2_STD_SECAM_K1 ((v4l2_std_id) 0x00200000)
+/* WARNING: DO NOT EDIT, AUTO-GENERATED CODE - SEE TOP FOR INSTRUCTIONS */
 #define V4L2_STD_SECAM_L ((v4l2_std_id) 0x00400000)
 #define V4L2_STD_SECAM_LC ((v4l2_std_id) 0x00800000)
 #define V4L2_STD_ATSC_8_VSB ((v4l2_std_id) 0x01000000)
-/* WARNING: DO NOT EDIT, AUTO-GENERATED CODE - SEE TOP FOR INSTRUCTIONS */
 #define V4L2_STD_ATSC_16_VSB ((v4l2_std_id) 0x02000000)
+/* WARNING: DO NOT EDIT, AUTO-GENERATED CODE - SEE TOP FOR INSTRUCTIONS */
 #define V4L2_STD_NTSC (V4L2_STD_NTSC_M | V4L2_STD_NTSC_M_JP | V4L2_STD_NTSC_M_KR)
 #define V4L2_STD_SECAM_DK (V4L2_STD_SECAM_D | V4L2_STD_SECAM_K | V4L2_STD_SECAM_K1)
 #define V4L2_STD_SECAM (V4L2_STD_SECAM_B | V4L2_STD_SECAM_G | V4L2_STD_SECAM_H | V4L2_STD_SECAM_DK | V4L2_STD_SECAM_L | V4L2_STD_SECAM_LC)
-/* WARNING: DO NOT EDIT, AUTO-GENERATED CODE - SEE TOP FOR INSTRUCTIONS */
 #define V4L2_STD_PAL_BG (V4L2_STD_PAL_B | V4L2_STD_PAL_B1 | V4L2_STD_PAL_G)
+/* WARNING: DO NOT EDIT, AUTO-GENERATED CODE - SEE TOP FOR INSTRUCTIONS */
 #define V4L2_STD_PAL_DK (V4L2_STD_PAL_D | V4L2_STD_PAL_D1 | V4L2_STD_PAL_K)
 #define V4L2_STD_PAL (V4L2_STD_PAL_BG | V4L2_STD_PAL_DK | V4L2_STD_PAL_H | V4L2_STD_PAL_I)
 #define V4L2_STD_B (V4L2_STD_PAL_B | V4L2_STD_PAL_B1 | V4L2_STD_SECAM_B)
-/* WARNING: DO NOT EDIT, AUTO-GENERATED CODE - SEE TOP FOR INSTRUCTIONS */
 #define V4L2_STD_G (V4L2_STD_PAL_G | V4L2_STD_SECAM_G)
+/* WARNING: DO NOT EDIT, AUTO-GENERATED CODE - SEE TOP FOR INSTRUCTIONS */
 #define V4L2_STD_H (V4L2_STD_PAL_H | V4L2_STD_SECAM_H)
 #define V4L2_STD_L (V4L2_STD_SECAM_L | V4L2_STD_SECAM_LC)
 #define V4L2_STD_GH (V4L2_STD_G | V4L2_STD_H)
-/* WARNING: DO NOT EDIT, AUTO-GENERATED CODE - SEE TOP FOR INSTRUCTIONS */
 #define V4L2_STD_DK (V4L2_STD_PAL_DK | V4L2_STD_SECAM_DK)
+/* WARNING: DO NOT EDIT, AUTO-GENERATED CODE - SEE TOP FOR INSTRUCTIONS */
 #define V4L2_STD_BG (V4L2_STD_B | V4L2_STD_G)
 #define V4L2_STD_MN (V4L2_STD_PAL_M | V4L2_STD_PAL_N | V4L2_STD_PAL_Nc | V4L2_STD_NTSC)
 #define V4L2_STD_MTS (V4L2_STD_NTSC_M | V4L2_STD_PAL_M | V4L2_STD_PAL_N | V4L2_STD_PAL_Nc)
-/* WARNING: DO NOT EDIT, AUTO-GENERATED CODE - SEE TOP FOR INSTRUCTIONS */
 #define V4L2_STD_525_60 (V4L2_STD_PAL_M | V4L2_STD_PAL_60 | V4L2_STD_NTSC | V4L2_STD_NTSC_443)
+/* WARNING: DO NOT EDIT, AUTO-GENERATED CODE - SEE TOP FOR INSTRUCTIONS */
 #define V4L2_STD_625_50 (V4L2_STD_PAL | V4L2_STD_PAL_N | V4L2_STD_PAL_Nc | V4L2_STD_SECAM)
 #define V4L2_STD_ATSC (V4L2_STD_ATSC_8_VSB | V4L2_STD_ATSC_16_VSB)
 #define V4L2_STD_UNKNOWN 0
-/* WARNING: DO NOT EDIT, AUTO-GENERATED CODE - SEE TOP FOR INSTRUCTIONS */
 #define V4L2_STD_ALL (V4L2_STD_525_60 | V4L2_STD_625_50)
+/* WARNING: DO NOT EDIT, AUTO-GENERATED CODE - SEE TOP FOR INSTRUCTIONS */
 struct v4l2_standard {
   __u32 index;
   v4l2_std_id id;
-/* WARNING: DO NOT EDIT, AUTO-GENERATED CODE - SEE TOP FOR INSTRUCTIONS */
   __u8 name[24];
+/* WARNING: DO NOT EDIT, AUTO-GENERATED CODE - SEE TOP FOR INSTRUCTIONS */
   struct v4l2_fract frameperiod;
   __u32 framelines;
   __u32 reserved[4];
-/* WARNING: DO NOT EDIT, AUTO-GENERATED CODE - SEE TOP FOR INSTRUCTIONS */
 };
+/* WARNING: DO NOT EDIT, AUTO-GENERATED CODE - SEE TOP FOR INSTRUCTIONS */
 struct v4l2_bt_timings {
   __u32 width;
   __u32 height;
-/* WARNING: DO NOT EDIT, AUTO-GENERATED CODE - SEE TOP FOR INSTRUCTIONS */
   __u32 interlaced;
+/* WARNING: DO NOT EDIT, AUTO-GENERATED CODE - SEE TOP FOR INSTRUCTIONS */
   __u32 polarities;
   __u64 pixelclock;
   __u32 hfrontporch;
-/* WARNING: DO NOT EDIT, AUTO-GENERATED CODE - SEE TOP FOR INSTRUCTIONS */
   __u32 hsync;
+/* WARNING: DO NOT EDIT, AUTO-GENERATED CODE - SEE TOP FOR INSTRUCTIONS */
   __u32 hbackporch;
   __u32 vfrontporch;
   __u32 vsync;
-/* WARNING: DO NOT EDIT, AUTO-GENERATED CODE - SEE TOP FOR INSTRUCTIONS */
   __u32 vbackporch;
+/* WARNING: DO NOT EDIT, AUTO-GENERATED CODE - SEE TOP FOR INSTRUCTIONS */
   __u32 il_vfrontporch;
   __u32 il_vsync;
   __u32 il_vbackporch;
-/* WARNING: DO NOT EDIT, AUTO-GENERATED CODE - SEE TOP FOR INSTRUCTIONS */
   __u32 standards;
+/* WARNING: DO NOT EDIT, AUTO-GENERATED CODE - SEE TOP FOR INSTRUCTIONS */
   __u32 flags;
   __u32 reserved[14];
 } __attribute__((packed));
-/* WARNING: DO NOT EDIT, AUTO-GENERATED CODE - SEE TOP FOR INSTRUCTIONS */
 #define V4L2_DV_PROGRESSIVE 0
+/* WARNING: DO NOT EDIT, AUTO-GENERATED CODE - SEE TOP FOR INSTRUCTIONS */
 #define V4L2_DV_INTERLACED 1
 #define V4L2_DV_VSYNC_POS_POL 0x00000001
 #define V4L2_DV_HSYNC_POS_POL 0x00000002
-/* WARNING: DO NOT EDIT, AUTO-GENERATED CODE - SEE TOP FOR INSTRUCTIONS */
 #define V4L2_DV_BT_STD_CEA861 (1 << 0)
+/* WARNING: DO NOT EDIT, AUTO-GENERATED CODE - SEE TOP FOR INSTRUCTIONS */
 #define V4L2_DV_BT_STD_DMT (1 << 1)
 #define V4L2_DV_BT_STD_CVT (1 << 2)
 #define V4L2_DV_BT_STD_GTF (1 << 3)
-/* WARNING: DO NOT EDIT, AUTO-GENERATED CODE - SEE TOP FOR INSTRUCTIONS */
 #define V4L2_DV_FL_REDUCED_BLANKING (1 << 0)
+/* WARNING: DO NOT EDIT, AUTO-GENERATED CODE - SEE TOP FOR INSTRUCTIONS */
 #define V4L2_DV_FL_CAN_REDUCE_FPS (1 << 1)
 #define V4L2_DV_FL_REDUCED_FPS (1 << 2)
 #define V4L2_DV_FL_HALF_LINE (1 << 3)
+#define V4L2_DV_FL_IS_CE_VIDEO (1 << 4)
 /* WARNING: DO NOT EDIT, AUTO-GENERATED CODE - SEE TOP FOR INSTRUCTIONS */
 #define V4L2_DV_BT_BLANKING_WIDTH(bt) ((bt)->hfrontporch + (bt)->hsync + (bt)->hbackporch)
 #define V4L2_DV_BT_FRAME_WIDTH(bt) ((bt)->width + V4L2_DV_BT_BLANKING_WIDTH(bt))
@@ -829,167 +889,172 @@
 #define V4L2_IN_CAP_DV_TIMINGS 0x00000002
 #define V4L2_IN_CAP_CUSTOM_TIMINGS V4L2_IN_CAP_DV_TIMINGS
 #define V4L2_IN_CAP_STD 0x00000004
-struct v4l2_output {
+#define V4L2_IN_CAP_NATIVE_SIZE 0x00000008
 /* WARNING: DO NOT EDIT, AUTO-GENERATED CODE - SEE TOP FOR INSTRUCTIONS */
+struct v4l2_output {
   __u32 index;
   __u8 name[32];
   __u32 type;
-  __u32 audioset;
 /* WARNING: DO NOT EDIT, AUTO-GENERATED CODE - SEE TOP FOR INSTRUCTIONS */
+  __u32 audioset;
   __u32 modulator;
   v4l2_std_id std;
   __u32 capabilities;
-  __u32 reserved[3];
 /* WARNING: DO NOT EDIT, AUTO-GENERATED CODE - SEE TOP FOR INSTRUCTIONS */
+  __u32 reserved[3];
 };
 #define V4L2_OUTPUT_TYPE_MODULATOR 1
 #define V4L2_OUTPUT_TYPE_ANALOG 2
-#define V4L2_OUTPUT_TYPE_ANALOGVGAOVERLAY 3
 /* WARNING: DO NOT EDIT, AUTO-GENERATED CODE - SEE TOP FOR INSTRUCTIONS */
+#define V4L2_OUTPUT_TYPE_ANALOGVGAOVERLAY 3
 #define V4L2_OUT_CAP_DV_TIMINGS 0x00000002
 #define V4L2_OUT_CAP_CUSTOM_TIMINGS V4L2_OUT_CAP_DV_TIMINGS
 #define V4L2_OUT_CAP_STD 0x00000004
-struct v4l2_control {
 /* WARNING: DO NOT EDIT, AUTO-GENERATED CODE - SEE TOP FOR INSTRUCTIONS */
+#define V4L2_OUT_CAP_NATIVE_SIZE 0x00000008
+struct v4l2_control {
   __u32 id;
   __s32 value;
+/* WARNING: DO NOT EDIT, AUTO-GENERATED CODE - SEE TOP FOR INSTRUCTIONS */
 };
 struct v4l2_ext_control {
-/* WARNING: DO NOT EDIT, AUTO-GENERATED CODE - SEE TOP FOR INSTRUCTIONS */
   __u32 id;
   __u32 size;
+/* WARNING: DO NOT EDIT, AUTO-GENERATED CODE - SEE TOP FOR INSTRUCTIONS */
   __u32 reserved2[1];
   union {
-/* WARNING: DO NOT EDIT, AUTO-GENERATED CODE - SEE TOP FOR INSTRUCTIONS */
     __s32 value;
     __s64 value64;
+/* WARNING: DO NOT EDIT, AUTO-GENERATED CODE - SEE TOP FOR INSTRUCTIONS */
     char __user * string;
     __u8 __user * p_u8;
-/* WARNING: DO NOT EDIT, AUTO-GENERATED CODE - SEE TOP FOR INSTRUCTIONS */
     __u16 __user * p_u16;
     __u32 __user * p_u32;
+/* WARNING: DO NOT EDIT, AUTO-GENERATED CODE - SEE TOP FOR INSTRUCTIONS */
     void __user * ptr;
   };
-/* WARNING: DO NOT EDIT, AUTO-GENERATED CODE - SEE TOP FOR INSTRUCTIONS */
 } __attribute__((packed));
 struct v4l2_ext_controls {
+/* WARNING: DO NOT EDIT, AUTO-GENERATED CODE - SEE TOP FOR INSTRUCTIONS */
   __u32 ctrl_class;
   __u32 count;
-/* WARNING: DO NOT EDIT, AUTO-GENERATED CODE - SEE TOP FOR INSTRUCTIONS */
   __u32 error_idx;
   __u32 reserved[2];
+/* WARNING: DO NOT EDIT, AUTO-GENERATED CODE - SEE TOP FOR INSTRUCTIONS */
   struct v4l2_ext_control * controls;
 };
-/* WARNING: DO NOT EDIT, AUTO-GENERATED CODE - SEE TOP FOR INSTRUCTIONS */
 #define V4L2_CTRL_ID_MASK (0x0fffffff)
 #define V4L2_CTRL_ID2CLASS(id) ((id) & 0x0fff0000UL)
+/* WARNING: DO NOT EDIT, AUTO-GENERATED CODE - SEE TOP FOR INSTRUCTIONS */
 #define V4L2_CTRL_DRIVER_PRIV(id) (((id) & 0xffff) >= 0x1000)
 #define V4L2_CTRL_MAX_DIMS (4)
-/* WARNING: DO NOT EDIT, AUTO-GENERATED CODE - SEE TOP FOR INSTRUCTIONS */
 enum v4l2_ctrl_type {
   V4L2_CTRL_TYPE_INTEGER = 1,
+/* WARNING: DO NOT EDIT, AUTO-GENERATED CODE - SEE TOP FOR INSTRUCTIONS */
   V4L2_CTRL_TYPE_BOOLEAN = 2,
   V4L2_CTRL_TYPE_MENU = 3,
-/* WARNING: DO NOT EDIT, AUTO-GENERATED CODE - SEE TOP FOR INSTRUCTIONS */
   V4L2_CTRL_TYPE_BUTTON = 4,
   V4L2_CTRL_TYPE_INTEGER64 = 5,
+/* WARNING: DO NOT EDIT, AUTO-GENERATED CODE - SEE TOP FOR INSTRUCTIONS */
   V4L2_CTRL_TYPE_CTRL_CLASS = 6,
   V4L2_CTRL_TYPE_STRING = 7,
-/* WARNING: DO NOT EDIT, AUTO-GENERATED CODE - SEE TOP FOR INSTRUCTIONS */
   V4L2_CTRL_TYPE_BITMASK = 8,
   V4L2_CTRL_TYPE_INTEGER_MENU = 9,
+/* WARNING: DO NOT EDIT, AUTO-GENERATED CODE - SEE TOP FOR INSTRUCTIONS */
   V4L2_CTRL_COMPOUND_TYPES = 0x0100,
   V4L2_CTRL_TYPE_U8 = 0x0100,
-/* WARNING: DO NOT EDIT, AUTO-GENERATED CODE - SEE TOP FOR INSTRUCTIONS */
   V4L2_CTRL_TYPE_U16 = 0x0101,
   V4L2_CTRL_TYPE_U32 = 0x0102,
+/* WARNING: DO NOT EDIT, AUTO-GENERATED CODE - SEE TOP FOR INSTRUCTIONS */
 };
 struct v4l2_queryctrl {
-/* WARNING: DO NOT EDIT, AUTO-GENERATED CODE - SEE TOP FOR INSTRUCTIONS */
   __u32 id;
   __u32 type;
+/* WARNING: DO NOT EDIT, AUTO-GENERATED CODE - SEE TOP FOR INSTRUCTIONS */
   __u8 name[32];
   __s32 minimum;
-/* WARNING: DO NOT EDIT, AUTO-GENERATED CODE - SEE TOP FOR INSTRUCTIONS */
   __s32 maximum;
   __s32 step;
+/* WARNING: DO NOT EDIT, AUTO-GENERATED CODE - SEE TOP FOR INSTRUCTIONS */
   __s32 default_value;
   __u32 flags;
-/* WARNING: DO NOT EDIT, AUTO-GENERATED CODE - SEE TOP FOR INSTRUCTIONS */
   __u32 reserved[2];
 };
+/* WARNING: DO NOT EDIT, AUTO-GENERATED CODE - SEE TOP FOR INSTRUCTIONS */
 struct v4l2_query_ext_ctrl {
   __u32 id;
-/* WARNING: DO NOT EDIT, AUTO-GENERATED CODE - SEE TOP FOR INSTRUCTIONS */
   __u32 type;
   char name[32];
+/* WARNING: DO NOT EDIT, AUTO-GENERATED CODE - SEE TOP FOR INSTRUCTIONS */
   __s64 minimum;
   __s64 maximum;
-/* WARNING: DO NOT EDIT, AUTO-GENERATED CODE - SEE TOP FOR INSTRUCTIONS */
   __u64 step;
   __s64 default_value;
+/* WARNING: DO NOT EDIT, AUTO-GENERATED CODE - SEE TOP FOR INSTRUCTIONS */
   __u32 flags;
   __u32 elem_size;
-/* WARNING: DO NOT EDIT, AUTO-GENERATED CODE - SEE TOP FOR INSTRUCTIONS */
   __u32 elems;
   __u32 nr_of_dims;
+/* WARNING: DO NOT EDIT, AUTO-GENERATED CODE - SEE TOP FOR INSTRUCTIONS */
   __u32 dims[V4L2_CTRL_MAX_DIMS];
   __u32 reserved[32];
-/* WARNING: DO NOT EDIT, AUTO-GENERATED CODE - SEE TOP FOR INSTRUCTIONS */
 };
 struct v4l2_querymenu {
+/* WARNING: DO NOT EDIT, AUTO-GENERATED CODE - SEE TOP FOR INSTRUCTIONS */
   __u32 id;
   __u32 index;
-/* WARNING: DO NOT EDIT, AUTO-GENERATED CODE - SEE TOP FOR INSTRUCTIONS */
   union {
     __u8 name[32];
+/* WARNING: DO NOT EDIT, AUTO-GENERATED CODE - SEE TOP FOR INSTRUCTIONS */
     __s64 value;
   };
-/* WARNING: DO NOT EDIT, AUTO-GENERATED CODE - SEE TOP FOR INSTRUCTIONS */
   __u32 reserved;
 } __attribute__((packed));
+/* WARNING: DO NOT EDIT, AUTO-GENERATED CODE - SEE TOP FOR INSTRUCTIONS */
 #define V4L2_CTRL_FLAG_DISABLED 0x0001
 #define V4L2_CTRL_FLAG_GRABBED 0x0002
-/* WARNING: DO NOT EDIT, AUTO-GENERATED CODE - SEE TOP FOR INSTRUCTIONS */
 #define V4L2_CTRL_FLAG_READ_ONLY 0x0004
 #define V4L2_CTRL_FLAG_UPDATE 0x0008
+/* WARNING: DO NOT EDIT, AUTO-GENERATED CODE - SEE TOP FOR INSTRUCTIONS */
 #define V4L2_CTRL_FLAG_INACTIVE 0x0010
 #define V4L2_CTRL_FLAG_SLIDER 0x0020
-/* WARNING: DO NOT EDIT, AUTO-GENERATED CODE - SEE TOP FOR INSTRUCTIONS */
 #define V4L2_CTRL_FLAG_WRITE_ONLY 0x0040
 #define V4L2_CTRL_FLAG_VOLATILE 0x0080
-#define V4L2_CTRL_FLAG_HAS_PAYLOAD 0x0100
-#define V4L2_CTRL_FLAG_NEXT_CTRL 0x80000000
 /* WARNING: DO NOT EDIT, AUTO-GENERATED CODE - SEE TOP FOR INSTRUCTIONS */
+#define V4L2_CTRL_FLAG_HAS_PAYLOAD 0x0100
+#define V4L2_CTRL_FLAG_EXECUTE_ON_WRITE 0x0200
+#define V4L2_CTRL_FLAG_NEXT_CTRL 0x80000000
 #define V4L2_CTRL_FLAG_NEXT_COMPOUND 0x40000000
+/* WARNING: DO NOT EDIT, AUTO-GENERATED CODE - SEE TOP FOR INSTRUCTIONS */
 #define V4L2_CID_MAX_CTRLS 1024
 #define V4L2_CID_PRIVATE_BASE 0x08000000
 struct v4l2_tuner {
-/* WARNING: DO NOT EDIT, AUTO-GENERATED CODE - SEE TOP FOR INSTRUCTIONS */
   __u32 index;
+/* WARNING: DO NOT EDIT, AUTO-GENERATED CODE - SEE TOP FOR INSTRUCTIONS */
   __u8 name[32];
   __u32 type;
   __u32 capability;
-/* WARNING: DO NOT EDIT, AUTO-GENERATED CODE - SEE TOP FOR INSTRUCTIONS */
   __u32 rangelow;
+/* WARNING: DO NOT EDIT, AUTO-GENERATED CODE - SEE TOP FOR INSTRUCTIONS */
   __u32 rangehigh;
   __u32 rxsubchans;
   __u32 audmode;
-/* WARNING: DO NOT EDIT, AUTO-GENERATED CODE - SEE TOP FOR INSTRUCTIONS */
   __s32 signal;
+/* WARNING: DO NOT EDIT, AUTO-GENERATED CODE - SEE TOP FOR INSTRUCTIONS */
   __s32 afc;
   __u32 reserved[4];
 };
-/* WARNING: DO NOT EDIT, AUTO-GENERATED CODE - SEE TOP FOR INSTRUCTIONS */
 struct v4l2_modulator {
+/* WARNING: DO NOT EDIT, AUTO-GENERATED CODE - SEE TOP FOR INSTRUCTIONS */
   __u32 index;
   __u8 name[32];
   __u32 capability;
-/* WARNING: DO NOT EDIT, AUTO-GENERATED CODE - SEE TOP FOR INSTRUCTIONS */
   __u32 rangelow;
+/* WARNING: DO NOT EDIT, AUTO-GENERATED CODE - SEE TOP FOR INSTRUCTIONS */
   __u32 rangehigh;
   __u32 txsubchans;
-  __u32 reserved[4];
+  __u32 type;
+  __u32 reserved[3];
 /* WARNING: DO NOT EDIT, AUTO-GENERATED CODE - SEE TOP FOR INSTRUCTIONS */
 };
 #define V4L2_TUNER_CAP_LOW 0x0001
@@ -1256,8 +1321,8 @@
 struct v4l2_plane_pix_format {
   __u32 sizeimage;
 /* WARNING: DO NOT EDIT, AUTO-GENERATED CODE - SEE TOP FOR INSTRUCTIONS */
-  __u16 bytesperline;
-  __u16 reserved[7];
+  __u32 bytesperline;
+  __u16 reserved[6];
 } __attribute__((packed));
 struct v4l2_pix_format_mplane {
 /* WARNING: DO NOT EDIT, AUTO-GENERATED CODE - SEE TOP FOR INSTRUCTIONS */
@@ -1271,265 +1336,269 @@
   __u8 num_planes;
   __u8 flags;
 /* WARNING: DO NOT EDIT, AUTO-GENERATED CODE - SEE TOP FOR INSTRUCTIONS */
-  __u8 reserved[10];
+  __u8 ycbcr_enc;
+  __u8 quantization;
+  __u8 xfer_func;
+  __u8 reserved[7];
+/* WARNING: DO NOT EDIT, AUTO-GENERATED CODE - SEE TOP FOR INSTRUCTIONS */
 } __attribute__((packed));
 struct v4l2_sdr_format {
   __u32 pixelformat;
-/* WARNING: DO NOT EDIT, AUTO-GENERATED CODE - SEE TOP FOR INSTRUCTIONS */
   __u32 buffersize;
+/* WARNING: DO NOT EDIT, AUTO-GENERATED CODE - SEE TOP FOR INSTRUCTIONS */
   __u8 reserved[24];
 } __attribute__((packed));
 struct v4l2_format {
-/* WARNING: DO NOT EDIT, AUTO-GENERATED CODE - SEE TOP FOR INSTRUCTIONS */
   __u32 type;
+/* WARNING: DO NOT EDIT, AUTO-GENERATED CODE - SEE TOP FOR INSTRUCTIONS */
   union {
     struct v4l2_pix_format pix;
     struct v4l2_pix_format_mplane pix_mp;
-/* WARNING: DO NOT EDIT, AUTO-GENERATED CODE - SEE TOP FOR INSTRUCTIONS */
     struct v4l2_window win;
+/* WARNING: DO NOT EDIT, AUTO-GENERATED CODE - SEE TOP FOR INSTRUCTIONS */
     struct v4l2_vbi_format vbi;
     struct v4l2_sliced_vbi_format sliced;
     struct v4l2_sdr_format sdr;
-/* WARNING: DO NOT EDIT, AUTO-GENERATED CODE - SEE TOP FOR INSTRUCTIONS */
     __u8 raw_data[200];
+/* WARNING: DO NOT EDIT, AUTO-GENERATED CODE - SEE TOP FOR INSTRUCTIONS */
   } fmt;
 };
 struct v4l2_streamparm {
-/* WARNING: DO NOT EDIT, AUTO-GENERATED CODE - SEE TOP FOR INSTRUCTIONS */
   __u32 type;
+/* WARNING: DO NOT EDIT, AUTO-GENERATED CODE - SEE TOP FOR INSTRUCTIONS */
   union {
     struct v4l2_captureparm capture;
     struct v4l2_outputparm output;
-/* WARNING: DO NOT EDIT, AUTO-GENERATED CODE - SEE TOP FOR INSTRUCTIONS */
     __u8 raw_data[200];
+/* WARNING: DO NOT EDIT, AUTO-GENERATED CODE - SEE TOP FOR INSTRUCTIONS */
   } parm;
 };
 #define V4L2_EVENT_ALL 0
-/* WARNING: DO NOT EDIT, AUTO-GENERATED CODE - SEE TOP FOR INSTRUCTIONS */
 #define V4L2_EVENT_VSYNC 1
+/* WARNING: DO NOT EDIT, AUTO-GENERATED CODE - SEE TOP FOR INSTRUCTIONS */
 #define V4L2_EVENT_EOS 2
 #define V4L2_EVENT_CTRL 3
 #define V4L2_EVENT_FRAME_SYNC 4
-/* WARNING: DO NOT EDIT, AUTO-GENERATED CODE - SEE TOP FOR INSTRUCTIONS */
 #define V4L2_EVENT_SOURCE_CHANGE 5
+/* WARNING: DO NOT EDIT, AUTO-GENERATED CODE - SEE TOP FOR INSTRUCTIONS */
 #define V4L2_EVENT_MOTION_DET 6
 #define V4L2_EVENT_PRIVATE_START 0x08000000
 struct v4l2_event_vsync {
-/* WARNING: DO NOT EDIT, AUTO-GENERATED CODE - SEE TOP FOR INSTRUCTIONS */
   __u8 field;
+/* WARNING: DO NOT EDIT, AUTO-GENERATED CODE - SEE TOP FOR INSTRUCTIONS */
 } __attribute__((packed));
 #define V4L2_EVENT_CTRL_CH_VALUE (1 << 0)
 #define V4L2_EVENT_CTRL_CH_FLAGS (1 << 1)
-/* WARNING: DO NOT EDIT, AUTO-GENERATED CODE - SEE TOP FOR INSTRUCTIONS */
 #define V4L2_EVENT_CTRL_CH_RANGE (1 << 2)
+/* WARNING: DO NOT EDIT, AUTO-GENERATED CODE - SEE TOP FOR INSTRUCTIONS */
 struct v4l2_event_ctrl {
   __u32 changes;
   __u32 type;
-/* WARNING: DO NOT EDIT, AUTO-GENERATED CODE - SEE TOP FOR INSTRUCTIONS */
   union {
+/* WARNING: DO NOT EDIT, AUTO-GENERATED CODE - SEE TOP FOR INSTRUCTIONS */
     __s32 value;
     __s64 value64;
   };
-/* WARNING: DO NOT EDIT, AUTO-GENERATED CODE - SEE TOP FOR INSTRUCTIONS */
   __u32 flags;
+/* WARNING: DO NOT EDIT, AUTO-GENERATED CODE - SEE TOP FOR INSTRUCTIONS */
   __s32 minimum;
   __s32 maximum;
   __s32 step;
-/* WARNING: DO NOT EDIT, AUTO-GENERATED CODE - SEE TOP FOR INSTRUCTIONS */
   __s32 default_value;
+/* WARNING: DO NOT EDIT, AUTO-GENERATED CODE - SEE TOP FOR INSTRUCTIONS */
 };
 struct v4l2_event_frame_sync {
   __u32 frame_sequence;
-/* WARNING: DO NOT EDIT, AUTO-GENERATED CODE - SEE TOP FOR INSTRUCTIONS */
 };
+/* WARNING: DO NOT EDIT, AUTO-GENERATED CODE - SEE TOP FOR INSTRUCTIONS */
 #define V4L2_EVENT_SRC_CH_RESOLUTION (1 << 0)
 struct v4l2_event_src_change {
   __u32 changes;
-/* WARNING: DO NOT EDIT, AUTO-GENERATED CODE - SEE TOP FOR INSTRUCTIONS */
 };
+/* WARNING: DO NOT EDIT, AUTO-GENERATED CODE - SEE TOP FOR INSTRUCTIONS */
 #define V4L2_EVENT_MD_FL_HAVE_FRAME_SEQ (1 << 0)
 struct v4l2_event_motion_det {
   __u32 flags;
-/* WARNING: DO NOT EDIT, AUTO-GENERATED CODE - SEE TOP FOR INSTRUCTIONS */
   __u32 frame_sequence;
+/* WARNING: DO NOT EDIT, AUTO-GENERATED CODE - SEE TOP FOR INSTRUCTIONS */
   __u32 region_mask;
 };
 struct v4l2_event {
-/* WARNING: DO NOT EDIT, AUTO-GENERATED CODE - SEE TOP FOR INSTRUCTIONS */
   __u32 type;
+/* WARNING: DO NOT EDIT, AUTO-GENERATED CODE - SEE TOP FOR INSTRUCTIONS */
   union {
     struct v4l2_event_vsync vsync;
     struct v4l2_event_ctrl ctrl;
-/* WARNING: DO NOT EDIT, AUTO-GENERATED CODE - SEE TOP FOR INSTRUCTIONS */
     struct v4l2_event_frame_sync frame_sync;
+/* WARNING: DO NOT EDIT, AUTO-GENERATED CODE - SEE TOP FOR INSTRUCTIONS */
     struct v4l2_event_src_change src_change;
     struct v4l2_event_motion_det motion_det;
     __u8 data[64];
-/* WARNING: DO NOT EDIT, AUTO-GENERATED CODE - SEE TOP FOR INSTRUCTIONS */
   } u;
+/* WARNING: DO NOT EDIT, AUTO-GENERATED CODE - SEE TOP FOR INSTRUCTIONS */
   __u32 pending;
   __u32 sequence;
   struct timespec timestamp;
-/* WARNING: DO NOT EDIT, AUTO-GENERATED CODE - SEE TOP FOR INSTRUCTIONS */
   __u32 id;
+/* WARNING: DO NOT EDIT, AUTO-GENERATED CODE - SEE TOP FOR INSTRUCTIONS */
   __u32 reserved[8];
 };
 #define V4L2_EVENT_SUB_FL_SEND_INITIAL (1 << 0)
-/* WARNING: DO NOT EDIT, AUTO-GENERATED CODE - SEE TOP FOR INSTRUCTIONS */
 #define V4L2_EVENT_SUB_FL_ALLOW_FEEDBACK (1 << 1)
+/* WARNING: DO NOT EDIT, AUTO-GENERATED CODE - SEE TOP FOR INSTRUCTIONS */
 struct v4l2_event_subscription {
   __u32 type;
   __u32 id;
-/* WARNING: DO NOT EDIT, AUTO-GENERATED CODE - SEE TOP FOR INSTRUCTIONS */
   __u32 flags;
+/* WARNING: DO NOT EDIT, AUTO-GENERATED CODE - SEE TOP FOR INSTRUCTIONS */
   __u32 reserved[5];
 };
 #define V4L2_CHIP_MATCH_BRIDGE 0
-/* WARNING: DO NOT EDIT, AUTO-GENERATED CODE - SEE TOP FOR INSTRUCTIONS */
 #define V4L2_CHIP_MATCH_SUBDEV 4
+/* WARNING: DO NOT EDIT, AUTO-GENERATED CODE - SEE TOP FOR INSTRUCTIONS */
 #define V4L2_CHIP_MATCH_HOST V4L2_CHIP_MATCH_BRIDGE
 #define V4L2_CHIP_MATCH_I2C_DRIVER 1
 #define V4L2_CHIP_MATCH_I2C_ADDR 2
-/* WARNING: DO NOT EDIT, AUTO-GENERATED CODE - SEE TOP FOR INSTRUCTIONS */
 #define V4L2_CHIP_MATCH_AC97 3
+/* WARNING: DO NOT EDIT, AUTO-GENERATED CODE - SEE TOP FOR INSTRUCTIONS */
 struct v4l2_dbg_match {
   __u32 type;
   union {
-/* WARNING: DO NOT EDIT, AUTO-GENERATED CODE - SEE TOP FOR INSTRUCTIONS */
     __u32 addr;
+/* WARNING: DO NOT EDIT, AUTO-GENERATED CODE - SEE TOP FOR INSTRUCTIONS */
     char name[32];
   };
 } __attribute__((packed));
-/* WARNING: DO NOT EDIT, AUTO-GENERATED CODE - SEE TOP FOR INSTRUCTIONS */
 struct v4l2_dbg_register {
+/* WARNING: DO NOT EDIT, AUTO-GENERATED CODE - SEE TOP FOR INSTRUCTIONS */
   struct v4l2_dbg_match match;
   __u32 size;
   __u64 reg;
-/* WARNING: DO NOT EDIT, AUTO-GENERATED CODE - SEE TOP FOR INSTRUCTIONS */
   __u64 val;
+/* WARNING: DO NOT EDIT, AUTO-GENERATED CODE - SEE TOP FOR INSTRUCTIONS */
 } __attribute__((packed));
 #define V4L2_CHIP_FL_READABLE (1 << 0)
 #define V4L2_CHIP_FL_WRITABLE (1 << 1)
-/* WARNING: DO NOT EDIT, AUTO-GENERATED CODE - SEE TOP FOR INSTRUCTIONS */
 struct v4l2_dbg_chip_info {
+/* WARNING: DO NOT EDIT, AUTO-GENERATED CODE - SEE TOP FOR INSTRUCTIONS */
   struct v4l2_dbg_match match;
   char name[32];
   __u32 flags;
-/* WARNING: DO NOT EDIT, AUTO-GENERATED CODE - SEE TOP FOR INSTRUCTIONS */
   __u32 reserved[32];
+/* WARNING: DO NOT EDIT, AUTO-GENERATED CODE - SEE TOP FOR INSTRUCTIONS */
 } __attribute__((packed));
 struct v4l2_create_buffers {
   __u32 index;
-/* WARNING: DO NOT EDIT, AUTO-GENERATED CODE - SEE TOP FOR INSTRUCTIONS */
   __u32 count;
+/* WARNING: DO NOT EDIT, AUTO-GENERATED CODE - SEE TOP FOR INSTRUCTIONS */
   __u32 memory;
   struct v4l2_format format;
   __u32 reserved[8];
-/* WARNING: DO NOT EDIT, AUTO-GENERATED CODE - SEE TOP FOR INSTRUCTIONS */
 };
+/* WARNING: DO NOT EDIT, AUTO-GENERATED CODE - SEE TOP FOR INSTRUCTIONS */
 #define VIDIOC_QUERYCAP _IOR('V', 0, struct v4l2_capability)
 #define VIDIOC_RESERVED _IO('V', 1)
 #define VIDIOC_ENUM_FMT _IOWR('V', 2, struct v4l2_fmtdesc)
-/* WARNING: DO NOT EDIT, AUTO-GENERATED CODE - SEE TOP FOR INSTRUCTIONS */
 #define VIDIOC_G_FMT _IOWR('V', 4, struct v4l2_format)
+/* WARNING: DO NOT EDIT, AUTO-GENERATED CODE - SEE TOP FOR INSTRUCTIONS */
 #define VIDIOC_S_FMT _IOWR('V', 5, struct v4l2_format)
 #define VIDIOC_REQBUFS _IOWR('V', 8, struct v4l2_requestbuffers)
 #define VIDIOC_QUERYBUF _IOWR('V', 9, struct v4l2_buffer)
-/* WARNING: DO NOT EDIT, AUTO-GENERATED CODE - SEE TOP FOR INSTRUCTIONS */
 #define VIDIOC_G_FBUF _IOR('V', 10, struct v4l2_framebuffer)
+/* WARNING: DO NOT EDIT, AUTO-GENERATED CODE - SEE TOP FOR INSTRUCTIONS */
 #define VIDIOC_S_FBUF _IOW('V', 11, struct v4l2_framebuffer)
 #define VIDIOC_OVERLAY _IOW('V', 14, int)
 #define VIDIOC_QBUF _IOWR('V', 15, struct v4l2_buffer)
-/* WARNING: DO NOT EDIT, AUTO-GENERATED CODE - SEE TOP FOR INSTRUCTIONS */
 #define VIDIOC_EXPBUF _IOWR('V', 16, struct v4l2_exportbuffer)
+/* WARNING: DO NOT EDIT, AUTO-GENERATED CODE - SEE TOP FOR INSTRUCTIONS */
 #define VIDIOC_DQBUF _IOWR('V', 17, struct v4l2_buffer)
 #define VIDIOC_STREAMON _IOW('V', 18, int)
 #define VIDIOC_STREAMOFF _IOW('V', 19, int)
-/* WARNING: DO NOT EDIT, AUTO-GENERATED CODE - SEE TOP FOR INSTRUCTIONS */
 #define VIDIOC_G_PARM _IOWR('V', 21, struct v4l2_streamparm)
+/* WARNING: DO NOT EDIT, AUTO-GENERATED CODE - SEE TOP FOR INSTRUCTIONS */
 #define VIDIOC_S_PARM _IOWR('V', 22, struct v4l2_streamparm)
 #define VIDIOC_G_STD _IOR('V', 23, v4l2_std_id)
 #define VIDIOC_S_STD _IOW('V', 24, v4l2_std_id)
-/* WARNING: DO NOT EDIT, AUTO-GENERATED CODE - SEE TOP FOR INSTRUCTIONS */
 #define VIDIOC_ENUMSTD _IOWR('V', 25, struct v4l2_standard)
+/* WARNING: DO NOT EDIT, AUTO-GENERATED CODE - SEE TOP FOR INSTRUCTIONS */
 #define VIDIOC_ENUMINPUT _IOWR('V', 26, struct v4l2_input)
 #define VIDIOC_G_CTRL _IOWR('V', 27, struct v4l2_control)
 #define VIDIOC_S_CTRL _IOWR('V', 28, struct v4l2_control)
-/* WARNING: DO NOT EDIT, AUTO-GENERATED CODE - SEE TOP FOR INSTRUCTIONS */
 #define VIDIOC_G_TUNER _IOWR('V', 29, struct v4l2_tuner)
+/* WARNING: DO NOT EDIT, AUTO-GENERATED CODE - SEE TOP FOR INSTRUCTIONS */
 #define VIDIOC_S_TUNER _IOW('V', 30, struct v4l2_tuner)
 #define VIDIOC_G_AUDIO _IOR('V', 33, struct v4l2_audio)
 #define VIDIOC_S_AUDIO _IOW('V', 34, struct v4l2_audio)
-/* WARNING: DO NOT EDIT, AUTO-GENERATED CODE - SEE TOP FOR INSTRUCTIONS */
 #define VIDIOC_QUERYCTRL _IOWR('V', 36, struct v4l2_queryctrl)
+/* WARNING: DO NOT EDIT, AUTO-GENERATED CODE - SEE TOP FOR INSTRUCTIONS */
 #define VIDIOC_QUERYMENU _IOWR('V', 37, struct v4l2_querymenu)
 #define VIDIOC_G_INPUT _IOR('V', 38, int)
 #define VIDIOC_S_INPUT _IOWR('V', 39, int)
-/* WARNING: DO NOT EDIT, AUTO-GENERATED CODE - SEE TOP FOR INSTRUCTIONS */
 #define VIDIOC_G_EDID _IOWR('V', 40, struct v4l2_edid)
+/* WARNING: DO NOT EDIT, AUTO-GENERATED CODE - SEE TOP FOR INSTRUCTIONS */
 #define VIDIOC_S_EDID _IOWR('V', 41, struct v4l2_edid)
 #define VIDIOC_G_OUTPUT _IOR('V', 46, int)
 #define VIDIOC_S_OUTPUT _IOWR('V', 47, int)
-/* WARNING: DO NOT EDIT, AUTO-GENERATED CODE - SEE TOP FOR INSTRUCTIONS */
 #define VIDIOC_ENUMOUTPUT _IOWR('V', 48, struct v4l2_output)
+/* WARNING: DO NOT EDIT, AUTO-GENERATED CODE - SEE TOP FOR INSTRUCTIONS */
 #define VIDIOC_G_AUDOUT _IOR('V', 49, struct v4l2_audioout)
 #define VIDIOC_S_AUDOUT _IOW('V', 50, struct v4l2_audioout)
 #define VIDIOC_G_MODULATOR _IOWR('V', 54, struct v4l2_modulator)
-/* WARNING: DO NOT EDIT, AUTO-GENERATED CODE - SEE TOP FOR INSTRUCTIONS */
 #define VIDIOC_S_MODULATOR _IOW('V', 55, struct v4l2_modulator)
+/* WARNING: DO NOT EDIT, AUTO-GENERATED CODE - SEE TOP FOR INSTRUCTIONS */
 #define VIDIOC_G_FREQUENCY _IOWR('V', 56, struct v4l2_frequency)
 #define VIDIOC_S_FREQUENCY _IOW('V', 57, struct v4l2_frequency)
 #define VIDIOC_CROPCAP _IOWR('V', 58, struct v4l2_cropcap)
-/* WARNING: DO NOT EDIT, AUTO-GENERATED CODE - SEE TOP FOR INSTRUCTIONS */
 #define VIDIOC_G_CROP _IOWR('V', 59, struct v4l2_crop)
+/* WARNING: DO NOT EDIT, AUTO-GENERATED CODE - SEE TOP FOR INSTRUCTIONS */
 #define VIDIOC_S_CROP _IOW('V', 60, struct v4l2_crop)
 #define VIDIOC_G_JPEGCOMP _IOR('V', 61, struct v4l2_jpegcompression)
 #define VIDIOC_S_JPEGCOMP _IOW('V', 62, struct v4l2_jpegcompression)
-/* WARNING: DO NOT EDIT, AUTO-GENERATED CODE - SEE TOP FOR INSTRUCTIONS */
 #define VIDIOC_QUERYSTD _IOR('V', 63, v4l2_std_id)
+/* WARNING: DO NOT EDIT, AUTO-GENERATED CODE - SEE TOP FOR INSTRUCTIONS */
 #define VIDIOC_TRY_FMT _IOWR('V', 64, struct v4l2_format)
 #define VIDIOC_ENUMAUDIO _IOWR('V', 65, struct v4l2_audio)
 #define VIDIOC_ENUMAUDOUT _IOWR('V', 66, struct v4l2_audioout)
-/* WARNING: DO NOT EDIT, AUTO-GENERATED CODE - SEE TOP FOR INSTRUCTIONS */
 #define VIDIOC_G_PRIORITY _IOR('V', 67, __u32)
+/* WARNING: DO NOT EDIT, AUTO-GENERATED CODE - SEE TOP FOR INSTRUCTIONS */
 #define VIDIOC_S_PRIORITY _IOW('V', 68, __u32)
 #define VIDIOC_G_SLICED_VBI_CAP _IOWR('V', 69, struct v4l2_sliced_vbi_cap)
 #define VIDIOC_LOG_STATUS _IO('V', 70)
-/* WARNING: DO NOT EDIT, AUTO-GENERATED CODE - SEE TOP FOR INSTRUCTIONS */
 #define VIDIOC_G_EXT_CTRLS _IOWR('V', 71, struct v4l2_ext_controls)
+/* WARNING: DO NOT EDIT, AUTO-GENERATED CODE - SEE TOP FOR INSTRUCTIONS */
 #define VIDIOC_S_EXT_CTRLS _IOWR('V', 72, struct v4l2_ext_controls)
 #define VIDIOC_TRY_EXT_CTRLS _IOWR('V', 73, struct v4l2_ext_controls)
 #define VIDIOC_ENUM_FRAMESIZES _IOWR('V', 74, struct v4l2_frmsizeenum)
-/* WARNING: DO NOT EDIT, AUTO-GENERATED CODE - SEE TOP FOR INSTRUCTIONS */
 #define VIDIOC_ENUM_FRAMEINTERVALS _IOWR('V', 75, struct v4l2_frmivalenum)
+/* WARNING: DO NOT EDIT, AUTO-GENERATED CODE - SEE TOP FOR INSTRUCTIONS */
 #define VIDIOC_G_ENC_INDEX _IOR('V', 76, struct v4l2_enc_idx)
 #define VIDIOC_ENCODER_CMD _IOWR('V', 77, struct v4l2_encoder_cmd)
 #define VIDIOC_TRY_ENCODER_CMD _IOWR('V', 78, struct v4l2_encoder_cmd)
-/* WARNING: DO NOT EDIT, AUTO-GENERATED CODE - SEE TOP FOR INSTRUCTIONS */
 #define VIDIOC_DBG_S_REGISTER _IOW('V', 79, struct v4l2_dbg_register)
+/* WARNING: DO NOT EDIT, AUTO-GENERATED CODE - SEE TOP FOR INSTRUCTIONS */
 #define VIDIOC_DBG_G_REGISTER _IOWR('V', 80, struct v4l2_dbg_register)
 #define VIDIOC_S_HW_FREQ_SEEK _IOW('V', 82, struct v4l2_hw_freq_seek)
 #define VIDIOC_S_DV_TIMINGS _IOWR('V', 87, struct v4l2_dv_timings)
-/* WARNING: DO NOT EDIT, AUTO-GENERATED CODE - SEE TOP FOR INSTRUCTIONS */
 #define VIDIOC_G_DV_TIMINGS _IOWR('V', 88, struct v4l2_dv_timings)
+/* WARNING: DO NOT EDIT, AUTO-GENERATED CODE - SEE TOP FOR INSTRUCTIONS */
 #define VIDIOC_DQEVENT _IOR('V', 89, struct v4l2_event)
 #define VIDIOC_SUBSCRIBE_EVENT _IOW('V', 90, struct v4l2_event_subscription)
 #define VIDIOC_UNSUBSCRIBE_EVENT _IOW('V', 91, struct v4l2_event_subscription)
-/* WARNING: DO NOT EDIT, AUTO-GENERATED CODE - SEE TOP FOR INSTRUCTIONS */
 #define VIDIOC_CREATE_BUFS _IOWR('V', 92, struct v4l2_create_buffers)
+/* WARNING: DO NOT EDIT, AUTO-GENERATED CODE - SEE TOP FOR INSTRUCTIONS */
 #define VIDIOC_PREPARE_BUF _IOWR('V', 93, struct v4l2_buffer)
 #define VIDIOC_G_SELECTION _IOWR('V', 94, struct v4l2_selection)
 #define VIDIOC_S_SELECTION _IOWR('V', 95, struct v4l2_selection)
-/* WARNING: DO NOT EDIT, AUTO-GENERATED CODE - SEE TOP FOR INSTRUCTIONS */
 #define VIDIOC_DECODER_CMD _IOWR('V', 96, struct v4l2_decoder_cmd)
+/* WARNING: DO NOT EDIT, AUTO-GENERATED CODE - SEE TOP FOR INSTRUCTIONS */
 #define VIDIOC_TRY_DECODER_CMD _IOWR('V', 97, struct v4l2_decoder_cmd)
 #define VIDIOC_ENUM_DV_TIMINGS _IOWR('V', 98, struct v4l2_enum_dv_timings)
 #define VIDIOC_QUERY_DV_TIMINGS _IOR('V', 99, struct v4l2_dv_timings)
-/* WARNING: DO NOT EDIT, AUTO-GENERATED CODE - SEE TOP FOR INSTRUCTIONS */
 #define VIDIOC_DV_TIMINGS_CAP _IOWR('V', 100, struct v4l2_dv_timings_cap)
+/* WARNING: DO NOT EDIT, AUTO-GENERATED CODE - SEE TOP FOR INSTRUCTIONS */
 #define VIDIOC_ENUM_FREQ_BANDS _IOWR('V', 101, struct v4l2_frequency_band)
 #define VIDIOC_DBG_G_CHIP_INFO _IOWR('V', 102, struct v4l2_dbg_chip_info)
 #define VIDIOC_QUERY_EXT_CTRL _IOWR('V', 103, struct v4l2_query_ext_ctrl)
-/* WARNING: DO NOT EDIT, AUTO-GENERATED CODE - SEE TOP FOR INSTRUCTIONS */
 #define BASE_VIDIOC_PRIVATE 192
+/* WARNING: DO NOT EDIT, AUTO-GENERATED CODE - SEE TOP FOR INSTRUCTIONS */
 #endif
diff --git a/libc/kernel/uapi/linux/virtio_balloon.h b/libc/kernel/uapi/linux/virtio_balloon.h
index 027b65f..7f02dc5 100644
--- a/libc/kernel/uapi/linux/virtio_balloon.h
+++ b/libc/kernel/uapi/linux/virtio_balloon.h
@@ -18,29 +18,33 @@
  ****************************************************************************/
 #ifndef _LINUX_VIRTIO_BALLOON_H
 #define _LINUX_VIRTIO_BALLOON_H
+#include <linux/types.h>
+#include <linux/virtio_types.h>
+/* WARNING: DO NOT EDIT, AUTO-GENERATED CODE - SEE TOP FOR INSTRUCTIONS */
 #include <linux/virtio_ids.h>
 #include <linux/virtio_config.h>
-/* WARNING: DO NOT EDIT, AUTO-GENERATED CODE - SEE TOP FOR INSTRUCTIONS */
 #define VIRTIO_BALLOON_F_MUST_TELL_HOST 0
 #define VIRTIO_BALLOON_F_STATS_VQ 1
+/* WARNING: DO NOT EDIT, AUTO-GENERATED CODE - SEE TOP FOR INSTRUCTIONS */
+#define VIRTIO_BALLOON_F_DEFLATE_ON_OOM 2
 #define VIRTIO_BALLOON_PFN_SHIFT 12
 struct virtio_balloon_config {
+  __u32 num_pages;
 /* WARNING: DO NOT EDIT, AUTO-GENERATED CODE - SEE TOP FOR INSTRUCTIONS */
-  __le32 num_pages;
-  __le32 actual;
+  __u32 actual;
 };
 #define VIRTIO_BALLOON_S_SWAP_IN 0
-/* WARNING: DO NOT EDIT, AUTO-GENERATED CODE - SEE TOP FOR INSTRUCTIONS */
 #define VIRTIO_BALLOON_S_SWAP_OUT 1
+/* WARNING: DO NOT EDIT, AUTO-GENERATED CODE - SEE TOP FOR INSTRUCTIONS */
 #define VIRTIO_BALLOON_S_MAJFLT 2
 #define VIRTIO_BALLOON_S_MINFLT 3
 #define VIRTIO_BALLOON_S_MEMFREE 4
-/* WARNING: DO NOT EDIT, AUTO-GENERATED CODE - SEE TOP FOR INSTRUCTIONS */
 #define VIRTIO_BALLOON_S_MEMTOT 5
+/* WARNING: DO NOT EDIT, AUTO-GENERATED CODE - SEE TOP FOR INSTRUCTIONS */
 #define VIRTIO_BALLOON_S_NR 6
 struct virtio_balloon_stat {
-  __u16 tag;
+  __virtio16 tag;
+  __virtio64 val;
 /* WARNING: DO NOT EDIT, AUTO-GENERATED CODE - SEE TOP FOR INSTRUCTIONS */
-  __u64 val;
 } __attribute__((packed));
 #endif
diff --git a/libc/kernel/uapi/linux/virtio_blk.h b/libc/kernel/uapi/linux/virtio_blk.h
index b6a22d0..9dc7aa7 100644
--- a/libc/kernel/uapi/linux/virtio_blk.h
+++ b/libc/kernel/uapi/linux/virtio_blk.h
@@ -22,68 +22,79 @@
 #include <linux/virtio_ids.h>
 /* WARNING: DO NOT EDIT, AUTO-GENERATED CODE - SEE TOP FOR INSTRUCTIONS */
 #include <linux/virtio_config.h>
-#define VIRTIO_BLK_F_BARRIER 0
+#include <linux/virtio_types.h>
 #define VIRTIO_BLK_F_SIZE_MAX 1
 #define VIRTIO_BLK_F_SEG_MAX 2
 /* WARNING: DO NOT EDIT, AUTO-GENERATED CODE - SEE TOP FOR INSTRUCTIONS */
 #define VIRTIO_BLK_F_GEOMETRY 4
 #define VIRTIO_BLK_F_RO 5
 #define VIRTIO_BLK_F_BLK_SIZE 6
+#define VIRTIO_BLK_F_TOPOLOGY 10
+/* WARNING: DO NOT EDIT, AUTO-GENERATED CODE - SEE TOP FOR INSTRUCTIONS */
+#define VIRTIO_BLK_F_MQ 12
+#ifndef VIRTIO_BLK_NO_LEGACY
+#define VIRTIO_BLK_F_BARRIER 0
 #define VIRTIO_BLK_F_SCSI 7
 /* WARNING: DO NOT EDIT, AUTO-GENERATED CODE - SEE TOP FOR INSTRUCTIONS */
 #define VIRTIO_BLK_F_WCE 9
-#define VIRTIO_BLK_F_TOPOLOGY 10
 #define VIRTIO_BLK_F_CONFIG_WCE 11
-#define VIRTIO_BLK_F_MQ 12
-/* WARNING: DO NOT EDIT, AUTO-GENERATED CODE - SEE TOP FOR INSTRUCTIONS */
 #define VIRTIO_BLK_F_FLUSH VIRTIO_BLK_F_WCE
+#endif
+/* WARNING: DO NOT EDIT, AUTO-GENERATED CODE - SEE TOP FOR INSTRUCTIONS */
 #define VIRTIO_BLK_ID_BYTES 20
 struct virtio_blk_config {
   __u64 capacity;
-/* WARNING: DO NOT EDIT, AUTO-GENERATED CODE - SEE TOP FOR INSTRUCTIONS */
   __u32 size_max;
+/* WARNING: DO NOT EDIT, AUTO-GENERATED CODE - SEE TOP FOR INSTRUCTIONS */
   __u32 seg_max;
   struct virtio_blk_geometry {
     __u16 cylinders;
-/* WARNING: DO NOT EDIT, AUTO-GENERATED CODE - SEE TOP FOR INSTRUCTIONS */
     __u8 heads;
+/* WARNING: DO NOT EDIT, AUTO-GENERATED CODE - SEE TOP FOR INSTRUCTIONS */
     __u8 sectors;
   } geometry;
   __u32 blk_size;
-/* WARNING: DO NOT EDIT, AUTO-GENERATED CODE - SEE TOP FOR INSTRUCTIONS */
   __u8 physical_block_exp;
+/* WARNING: DO NOT EDIT, AUTO-GENERATED CODE - SEE TOP FOR INSTRUCTIONS */
   __u8 alignment_offset;
   __u16 min_io_size;
   __u32 opt_io_size;
-/* WARNING: DO NOT EDIT, AUTO-GENERATED CODE - SEE TOP FOR INSTRUCTIONS */
   __u8 wce;
+/* WARNING: DO NOT EDIT, AUTO-GENERATED CODE - SEE TOP FOR INSTRUCTIONS */
   __u8 unused;
   __u16 num_queues;
 } __attribute__((packed));
-/* WARNING: DO NOT EDIT, AUTO-GENERATED CODE - SEE TOP FOR INSTRUCTIONS */
 #define VIRTIO_BLK_T_IN 0
+/* WARNING: DO NOT EDIT, AUTO-GENERATED CODE - SEE TOP FOR INSTRUCTIONS */
 #define VIRTIO_BLK_T_OUT 1
+#ifndef VIRTIO_BLK_NO_LEGACY
 #define VIRTIO_BLK_T_SCSI_CMD 2
+#endif
+/* WARNING: DO NOT EDIT, AUTO-GENERATED CODE - SEE TOP FOR INSTRUCTIONS */
 #define VIRTIO_BLK_T_FLUSH 4
-/* WARNING: DO NOT EDIT, AUTO-GENERATED CODE - SEE TOP FOR INSTRUCTIONS */
 #define VIRTIO_BLK_T_GET_ID 8
+#ifndef VIRTIO_BLK_NO_LEGACY
 #define VIRTIO_BLK_T_BARRIER 0x80000000
-struct virtio_blk_outhdr {
-  __u32 type;
 /* WARNING: DO NOT EDIT, AUTO-GENERATED CODE - SEE TOP FOR INSTRUCTIONS */
-  __u32 ioprio;
-  __u64 sector;
+#endif
+struct virtio_blk_outhdr {
+  __virtio32 type;
+  __virtio32 ioprio;
+/* WARNING: DO NOT EDIT, AUTO-GENERATED CODE - SEE TOP FOR INSTRUCTIONS */
+  __virtio64 sector;
 };
+#ifndef VIRTIO_BLK_NO_LEGACY
 struct virtio_scsi_inhdr {
 /* WARNING: DO NOT EDIT, AUTO-GENERATED CODE - SEE TOP FOR INSTRUCTIONS */
-  __u32 errors;
-  __u32 data_len;
-  __u32 sense_len;
-  __u32 residual;
+  __virtio32 errors;
+  __virtio32 data_len;
+  __virtio32 sense_len;
+  __virtio32 residual;
 /* WARNING: DO NOT EDIT, AUTO-GENERATED CODE - SEE TOP FOR INSTRUCTIONS */
 };
+#endif
 #define VIRTIO_BLK_S_OK 0
 #define VIRTIO_BLK_S_IOERR 1
-#define VIRTIO_BLK_S_UNSUPP 2
 /* WARNING: DO NOT EDIT, AUTO-GENERATED CODE - SEE TOP FOR INSTRUCTIONS */
+#define VIRTIO_BLK_S_UNSUPP 2
 #endif
diff --git a/libc/kernel/uapi/linux/virtio_config.h b/libc/kernel/uapi/linux/virtio_config.h
index 0d1fc62..1f41faf 100644
--- a/libc/kernel/uapi/linux/virtio_config.h
+++ b/libc/kernel/uapi/linux/virtio_config.h
@@ -23,11 +23,16 @@
 /* WARNING: DO NOT EDIT, AUTO-GENERATED CODE - SEE TOP FOR INSTRUCTIONS */
 #define VIRTIO_CONFIG_S_DRIVER 2
 #define VIRTIO_CONFIG_S_DRIVER_OK 4
+#define VIRTIO_CONFIG_S_FEATURES_OK 8
 #define VIRTIO_CONFIG_S_FAILED 0x80
-#define VIRTIO_TRANSPORT_F_START 28
 /* WARNING: DO NOT EDIT, AUTO-GENERATED CODE - SEE TOP FOR INSTRUCTIONS */
-#define VIRTIO_TRANSPORT_F_END 32
+#define VIRTIO_TRANSPORT_F_START 28
+#define VIRTIO_TRANSPORT_F_END 33
+#ifndef VIRTIO_CONFIG_NO_LEGACY
 #define VIRTIO_F_NOTIFY_ON_EMPTY 24
+/* WARNING: DO NOT EDIT, AUTO-GENERATED CODE - SEE TOP FOR INSTRUCTIONS */
 #define VIRTIO_F_ANY_LAYOUT 27
 #endif
+#define VIRTIO_F_VERSION_1 32
+#endif
 /* WARNING: DO NOT EDIT, AUTO-GENERATED CODE - SEE TOP FOR INSTRUCTIONS */
diff --git a/libc/kernel/uapi/linux/virtio_console.h b/libc/kernel/uapi/linux/virtio_console.h
index 9ccf770..c2c8073 100644
--- a/libc/kernel/uapi/linux/virtio_console.h
+++ b/libc/kernel/uapi/linux/virtio_console.h
@@ -19,36 +19,37 @@
 #ifndef _UAPI_LINUX_VIRTIO_CONSOLE_H
 #define _UAPI_LINUX_VIRTIO_CONSOLE_H
 #include <linux/types.h>
-#include <linux/virtio_ids.h>
+#include <linux/virtio_types.h>
 /* WARNING: DO NOT EDIT, AUTO-GENERATED CODE - SEE TOP FOR INSTRUCTIONS */
+#include <linux/virtio_ids.h>
 #include <linux/virtio_config.h>
 #define VIRTIO_CONSOLE_F_SIZE 0
 #define VIRTIO_CONSOLE_F_MULTIPORT 1
-#define VIRTIO_CONSOLE_F_EMERG_WRITE 2
 /* WARNING: DO NOT EDIT, AUTO-GENERATED CODE - SEE TOP FOR INSTRUCTIONS */
+#define VIRTIO_CONSOLE_F_EMERG_WRITE 2
 #define VIRTIO_CONSOLE_BAD_ID (~(__u32) 0)
 struct virtio_console_config {
   __u16 cols;
-  __u16 rows;
 /* WARNING: DO NOT EDIT, AUTO-GENERATED CODE - SEE TOP FOR INSTRUCTIONS */
+  __u16 rows;
   __u32 max_nr_ports;
   __u32 emerg_wr;
 } __attribute__((packed));
+/* WARNING: DO NOT EDIT, AUTO-GENERATED CODE - SEE TOP FOR INSTRUCTIONS */
 struct virtio_console_control {
+  __virtio32 id;
+  __virtio16 event;
+  __virtio16 value;
 /* WARNING: DO NOT EDIT, AUTO-GENERATED CODE - SEE TOP FOR INSTRUCTIONS */
-  __u32 id;
-  __u16 event;
-  __u16 value;
 };
-/* WARNING: DO NOT EDIT, AUTO-GENERATED CODE - SEE TOP FOR INSTRUCTIONS */
 #define VIRTIO_CONSOLE_DEVICE_READY 0
 #define VIRTIO_CONSOLE_PORT_ADD 1
 #define VIRTIO_CONSOLE_PORT_REMOVE 2
-#define VIRTIO_CONSOLE_PORT_READY 3
 /* WARNING: DO NOT EDIT, AUTO-GENERATED CODE - SEE TOP FOR INSTRUCTIONS */
+#define VIRTIO_CONSOLE_PORT_READY 3
 #define VIRTIO_CONSOLE_CONSOLE_PORT 4
 #define VIRTIO_CONSOLE_RESIZE 5
 #define VIRTIO_CONSOLE_PORT_OPEN 6
-#define VIRTIO_CONSOLE_PORT_NAME 7
 /* WARNING: DO NOT EDIT, AUTO-GENERATED CODE - SEE TOP FOR INSTRUCTIONS */
+#define VIRTIO_CONSOLE_PORT_NAME 7
 #endif
diff --git a/libc/kernel/uapi/linux/virtio_gpu.h b/libc/kernel/uapi/linux/virtio_gpu.h
new file mode 100644
index 0000000..f7887d9
--- /dev/null
+++ b/libc/kernel/uapi/linux/virtio_gpu.h
@@ -0,0 +1,278 @@
+/****************************************************************************
+ ****************************************************************************
+ ***
+ ***   This header was automatically generated from a Linux kernel header
+ ***   of the same name, to make information necessary for userspace to
+ ***   call into the kernel available to libc.  It contains only constants,
+ ***   structures, and macros generated from the original header, and thus,
+ ***   contains no copyrightable information.
+ ***
+ ***   To edit the content of this header, modify the corresponding
+ ***   source file (e.g. under external/kernel-headers/original/) then
+ ***   run bionic/libc/kernel/tools/update_all.py
+ ***
+ ***   Any manual change here will be lost the next time this script will
+ ***   be run. You've been warned!
+ ***
+ ****************************************************************************
+ ****************************************************************************/
+#ifndef VIRTIO_GPU_HW_H
+#define VIRTIO_GPU_HW_H
+#include <linux/types.h>
+#define VIRTIO_GPU_F_VIRGL 0
+/* WARNING: DO NOT EDIT, AUTO-GENERATED CODE - SEE TOP FOR INSTRUCTIONS */
+enum virtio_gpu_ctrl_type {
+  VIRTIO_GPU_UNDEFINED = 0,
+  VIRTIO_GPU_CMD_GET_DISPLAY_INFO = 0x0100,
+  VIRTIO_GPU_CMD_RESOURCE_CREATE_2D,
+/* WARNING: DO NOT EDIT, AUTO-GENERATED CODE - SEE TOP FOR INSTRUCTIONS */
+  VIRTIO_GPU_CMD_RESOURCE_UNREF,
+  VIRTIO_GPU_CMD_SET_SCANOUT,
+  VIRTIO_GPU_CMD_RESOURCE_FLUSH,
+  VIRTIO_GPU_CMD_TRANSFER_TO_HOST_2D,
+/* WARNING: DO NOT EDIT, AUTO-GENERATED CODE - SEE TOP FOR INSTRUCTIONS */
+  VIRTIO_GPU_CMD_RESOURCE_ATTACH_BACKING,
+  VIRTIO_GPU_CMD_RESOURCE_DETACH_BACKING,
+  VIRTIO_GPU_CMD_GET_CAPSET_INFO,
+  VIRTIO_GPU_CMD_GET_CAPSET,
+/* WARNING: DO NOT EDIT, AUTO-GENERATED CODE - SEE TOP FOR INSTRUCTIONS */
+  VIRTIO_GPU_CMD_CTX_CREATE = 0x0200,
+  VIRTIO_GPU_CMD_CTX_DESTROY,
+  VIRTIO_GPU_CMD_CTX_ATTACH_RESOURCE,
+  VIRTIO_GPU_CMD_CTX_DETACH_RESOURCE,
+/* WARNING: DO NOT EDIT, AUTO-GENERATED CODE - SEE TOP FOR INSTRUCTIONS */
+  VIRTIO_GPU_CMD_RESOURCE_CREATE_3D,
+  VIRTIO_GPU_CMD_TRANSFER_TO_HOST_3D,
+  VIRTIO_GPU_CMD_TRANSFER_FROM_HOST_3D,
+  VIRTIO_GPU_CMD_SUBMIT_3D,
+/* WARNING: DO NOT EDIT, AUTO-GENERATED CODE - SEE TOP FOR INSTRUCTIONS */
+  VIRTIO_GPU_CMD_UPDATE_CURSOR = 0x0300,
+  VIRTIO_GPU_CMD_MOVE_CURSOR,
+  VIRTIO_GPU_RESP_OK_NODATA = 0x1100,
+  VIRTIO_GPU_RESP_OK_DISPLAY_INFO,
+/* WARNING: DO NOT EDIT, AUTO-GENERATED CODE - SEE TOP FOR INSTRUCTIONS */
+  VIRTIO_GPU_RESP_OK_CAPSET_INFO,
+  VIRTIO_GPU_RESP_OK_CAPSET,
+  VIRTIO_GPU_RESP_ERR_UNSPEC = 0x1200,
+  VIRTIO_GPU_RESP_ERR_OUT_OF_MEMORY,
+/* WARNING: DO NOT EDIT, AUTO-GENERATED CODE - SEE TOP FOR INSTRUCTIONS */
+  VIRTIO_GPU_RESP_ERR_INVALID_SCANOUT_ID,
+  VIRTIO_GPU_RESP_ERR_INVALID_RESOURCE_ID,
+  VIRTIO_GPU_RESP_ERR_INVALID_CONTEXT_ID,
+  VIRTIO_GPU_RESP_ERR_INVALID_PARAMETER,
+/* WARNING: DO NOT EDIT, AUTO-GENERATED CODE - SEE TOP FOR INSTRUCTIONS */
+};
+#define VIRTIO_GPU_FLAG_FENCE (1 << 0)
+struct virtio_gpu_ctrl_hdr {
+  __le32 type;
+/* WARNING: DO NOT EDIT, AUTO-GENERATED CODE - SEE TOP FOR INSTRUCTIONS */
+  __le32 flags;
+  __le64 fence_id;
+  __le32 ctx_id;
+  __le32 padding;
+/* WARNING: DO NOT EDIT, AUTO-GENERATED CODE - SEE TOP FOR INSTRUCTIONS */
+};
+struct virtio_gpu_cursor_pos {
+  __le32 scanout_id;
+  __le32 x;
+/* WARNING: DO NOT EDIT, AUTO-GENERATED CODE - SEE TOP FOR INSTRUCTIONS */
+  __le32 y;
+  __le32 padding;
+};
+struct virtio_gpu_update_cursor {
+/* WARNING: DO NOT EDIT, AUTO-GENERATED CODE - SEE TOP FOR INSTRUCTIONS */
+  struct virtio_gpu_ctrl_hdr hdr;
+  struct virtio_gpu_cursor_pos pos;
+  __le32 resource_id;
+  __le32 hot_x;
+/* WARNING: DO NOT EDIT, AUTO-GENERATED CODE - SEE TOP FOR INSTRUCTIONS */
+  __le32 hot_y;
+  __le32 padding;
+};
+struct virtio_gpu_rect {
+/* WARNING: DO NOT EDIT, AUTO-GENERATED CODE - SEE TOP FOR INSTRUCTIONS */
+  __le32 x;
+  __le32 y;
+  __le32 width;
+  __le32 height;
+/* WARNING: DO NOT EDIT, AUTO-GENERATED CODE - SEE TOP FOR INSTRUCTIONS */
+};
+struct virtio_gpu_resource_unref {
+  struct virtio_gpu_ctrl_hdr hdr;
+  __le32 resource_id;
+/* WARNING: DO NOT EDIT, AUTO-GENERATED CODE - SEE TOP FOR INSTRUCTIONS */
+  __le32 padding;
+};
+struct virtio_gpu_resource_create_2d {
+  struct virtio_gpu_ctrl_hdr hdr;
+/* WARNING: DO NOT EDIT, AUTO-GENERATED CODE - SEE TOP FOR INSTRUCTIONS */
+  __le32 resource_id;
+  __le32 format;
+  __le32 width;
+  __le32 height;
+/* WARNING: DO NOT EDIT, AUTO-GENERATED CODE - SEE TOP FOR INSTRUCTIONS */
+};
+struct virtio_gpu_set_scanout {
+  struct virtio_gpu_ctrl_hdr hdr;
+  struct virtio_gpu_rect r;
+/* WARNING: DO NOT EDIT, AUTO-GENERATED CODE - SEE TOP FOR INSTRUCTIONS */
+  __le32 scanout_id;
+  __le32 resource_id;
+};
+struct virtio_gpu_resource_flush {
+/* WARNING: DO NOT EDIT, AUTO-GENERATED CODE - SEE TOP FOR INSTRUCTIONS */
+  struct virtio_gpu_ctrl_hdr hdr;
+  struct virtio_gpu_rect r;
+  __le32 resource_id;
+  __le32 padding;
+/* WARNING: DO NOT EDIT, AUTO-GENERATED CODE - SEE TOP FOR INSTRUCTIONS */
+};
+struct virtio_gpu_transfer_to_host_2d {
+  struct virtio_gpu_ctrl_hdr hdr;
+  struct virtio_gpu_rect r;
+/* WARNING: DO NOT EDIT, AUTO-GENERATED CODE - SEE TOP FOR INSTRUCTIONS */
+  __le64 offset;
+  __le32 resource_id;
+  __le32 padding;
+};
+/* WARNING: DO NOT EDIT, AUTO-GENERATED CODE - SEE TOP FOR INSTRUCTIONS */
+struct virtio_gpu_mem_entry {
+  __le64 addr;
+  __le32 length;
+  __le32 padding;
+/* WARNING: DO NOT EDIT, AUTO-GENERATED CODE - SEE TOP FOR INSTRUCTIONS */
+};
+struct virtio_gpu_resource_attach_backing {
+  struct virtio_gpu_ctrl_hdr hdr;
+  __le32 resource_id;
+/* WARNING: DO NOT EDIT, AUTO-GENERATED CODE - SEE TOP FOR INSTRUCTIONS */
+  __le32 nr_entries;
+};
+struct virtio_gpu_resource_detach_backing {
+  struct virtio_gpu_ctrl_hdr hdr;
+/* WARNING: DO NOT EDIT, AUTO-GENERATED CODE - SEE TOP FOR INSTRUCTIONS */
+  __le32 resource_id;
+  __le32 padding;
+};
+#define VIRTIO_GPU_MAX_SCANOUTS 16
+/* WARNING: DO NOT EDIT, AUTO-GENERATED CODE - SEE TOP FOR INSTRUCTIONS */
+struct virtio_gpu_resp_display_info {
+  struct virtio_gpu_ctrl_hdr hdr;
+  struct virtio_gpu_display_one {
+    struct virtio_gpu_rect r;
+/* WARNING: DO NOT EDIT, AUTO-GENERATED CODE - SEE TOP FOR INSTRUCTIONS */
+    __le32 enabled;
+    __le32 flags;
+  } pmodes[VIRTIO_GPU_MAX_SCANOUTS];
+};
+/* WARNING: DO NOT EDIT, AUTO-GENERATED CODE - SEE TOP FOR INSTRUCTIONS */
+struct virtio_gpu_box {
+  __le32 x, y, z;
+  __le32 w, h, d;
+};
+/* WARNING: DO NOT EDIT, AUTO-GENERATED CODE - SEE TOP FOR INSTRUCTIONS */
+struct virtio_gpu_transfer_host_3d {
+  struct virtio_gpu_ctrl_hdr hdr;
+  struct virtio_gpu_box box;
+  __le64 offset;
+/* WARNING: DO NOT EDIT, AUTO-GENERATED CODE - SEE TOP FOR INSTRUCTIONS */
+  __le32 resource_id;
+  __le32 level;
+  __le32 stride;
+  __le32 layer_stride;
+/* WARNING: DO NOT EDIT, AUTO-GENERATED CODE - SEE TOP FOR INSTRUCTIONS */
+};
+#define VIRTIO_GPU_RESOURCE_FLAG_Y_0_TOP (1 << 0)
+struct virtio_gpu_resource_create_3d {
+  struct virtio_gpu_ctrl_hdr hdr;
+/* WARNING: DO NOT EDIT, AUTO-GENERATED CODE - SEE TOP FOR INSTRUCTIONS */
+  __le32 resource_id;
+  __le32 target;
+  __le32 format;
+  __le32 bind;
+/* WARNING: DO NOT EDIT, AUTO-GENERATED CODE - SEE TOP FOR INSTRUCTIONS */
+  __le32 width;
+  __le32 height;
+  __le32 depth;
+  __le32 array_size;
+/* WARNING: DO NOT EDIT, AUTO-GENERATED CODE - SEE TOP FOR INSTRUCTIONS */
+  __le32 last_level;
+  __le32 nr_samples;
+  __le32 flags;
+  __le32 padding;
+/* WARNING: DO NOT EDIT, AUTO-GENERATED CODE - SEE TOP FOR INSTRUCTIONS */
+};
+struct virtio_gpu_ctx_create {
+  struct virtio_gpu_ctrl_hdr hdr;
+  __le32 nlen;
+/* WARNING: DO NOT EDIT, AUTO-GENERATED CODE - SEE TOP FOR INSTRUCTIONS */
+  __le32 padding;
+  char debug_name[64];
+};
+struct virtio_gpu_ctx_destroy {
+/* WARNING: DO NOT EDIT, AUTO-GENERATED CODE - SEE TOP FOR INSTRUCTIONS */
+  struct virtio_gpu_ctrl_hdr hdr;
+};
+struct virtio_gpu_ctx_resource {
+  struct virtio_gpu_ctrl_hdr hdr;
+/* WARNING: DO NOT EDIT, AUTO-GENERATED CODE - SEE TOP FOR INSTRUCTIONS */
+  __le32 resource_id;
+  __le32 padding;
+};
+struct virtio_gpu_cmd_submit {
+/* WARNING: DO NOT EDIT, AUTO-GENERATED CODE - SEE TOP FOR INSTRUCTIONS */
+  struct virtio_gpu_ctrl_hdr hdr;
+  __le32 size;
+  __le32 padding;
+};
+/* WARNING: DO NOT EDIT, AUTO-GENERATED CODE - SEE TOP FOR INSTRUCTIONS */
+#define VIRTIO_GPU_CAPSET_VIRGL 1
+struct virtio_gpu_get_capset_info {
+  struct virtio_gpu_ctrl_hdr hdr;
+  __le32 capset_index;
+/* WARNING: DO NOT EDIT, AUTO-GENERATED CODE - SEE TOP FOR INSTRUCTIONS */
+  __le32 padding;
+};
+struct virtio_gpu_resp_capset_info {
+  struct virtio_gpu_ctrl_hdr hdr;
+/* WARNING: DO NOT EDIT, AUTO-GENERATED CODE - SEE TOP FOR INSTRUCTIONS */
+  __le32 capset_id;
+  __le32 capset_max_version;
+  __le32 capset_max_size;
+  __le32 padding;
+/* WARNING: DO NOT EDIT, AUTO-GENERATED CODE - SEE TOP FOR INSTRUCTIONS */
+};
+struct virtio_gpu_get_capset {
+  struct virtio_gpu_ctrl_hdr hdr;
+  __le32 capset_id;
+/* WARNING: DO NOT EDIT, AUTO-GENERATED CODE - SEE TOP FOR INSTRUCTIONS */
+  __le32 capset_version;
+};
+struct virtio_gpu_resp_capset {
+  struct virtio_gpu_ctrl_hdr hdr;
+/* WARNING: DO NOT EDIT, AUTO-GENERATED CODE - SEE TOP FOR INSTRUCTIONS */
+  uint8_t capset_data[];
+};
+#define VIRTIO_GPU_EVENT_DISPLAY (1 << 0)
+struct virtio_gpu_config {
+/* WARNING: DO NOT EDIT, AUTO-GENERATED CODE - SEE TOP FOR INSTRUCTIONS */
+  __u32 events_read;
+  __u32 events_clear;
+  __u32 num_scanouts;
+  __u32 num_capsets;
+/* WARNING: DO NOT EDIT, AUTO-GENERATED CODE - SEE TOP FOR INSTRUCTIONS */
+};
+enum virtio_gpu_formats {
+  VIRTIO_GPU_FORMAT_B8G8R8A8_UNORM = 1,
+  VIRTIO_GPU_FORMAT_B8G8R8X8_UNORM = 2,
+/* WARNING: DO NOT EDIT, AUTO-GENERATED CODE - SEE TOP FOR INSTRUCTIONS */
+  VIRTIO_GPU_FORMAT_A8R8G8B8_UNORM = 3,
+  VIRTIO_GPU_FORMAT_X8R8G8B8_UNORM = 4,
+  VIRTIO_GPU_FORMAT_R8G8B8A8_UNORM = 67,
+  VIRTIO_GPU_FORMAT_X8B8G8R8_UNORM = 68,
+/* WARNING: DO NOT EDIT, AUTO-GENERATED CODE - SEE TOP FOR INSTRUCTIONS */
+  VIRTIO_GPU_FORMAT_A8B8G8R8_UNORM = 121,
+  VIRTIO_GPU_FORMAT_R8G8B8X8_UNORM = 134,
+};
+#endif
+/* WARNING: DO NOT EDIT, AUTO-GENERATED CODE - SEE TOP FOR INSTRUCTIONS */
diff --git a/libc/kernel/uapi/linux/virtio_ids.h b/libc/kernel/uapi/linux/virtio_ids.h
index b4817c0..3f3e764 100644
--- a/libc/kernel/uapi/linux/virtio_ids.h
+++ b/libc/kernel/uapi/linux/virtio_ids.h
@@ -31,4 +31,6 @@
 #define VIRTIO_ID_RPROC_SERIAL 11
 #define VIRTIO_ID_CAIF 12
 /* WARNING: DO NOT EDIT, AUTO-GENERATED CODE - SEE TOP FOR INSTRUCTIONS */
+#define VIRTIO_ID_GPU 16
+#define VIRTIO_ID_INPUT 18
 #endif
diff --git a/libc/kernel/uapi/linux/virtio_input.h b/libc/kernel/uapi/linux/virtio_input.h
new file mode 100644
index 0000000..2dcf0fc
--- /dev/null
+++ b/libc/kernel/uapi/linux/virtio_input.h
@@ -0,0 +1,71 @@
+/****************************************************************************
+ ****************************************************************************
+ ***
+ ***   This header was automatically generated from a Linux kernel header
+ ***   of the same name, to make information necessary for userspace to
+ ***   call into the kernel available to libc.  It contains only constants,
+ ***   structures, and macros generated from the original header, and thus,
+ ***   contains no copyrightable information.
+ ***
+ ***   To edit the content of this header, modify the corresponding
+ ***   source file (e.g. under external/kernel-headers/original/) then
+ ***   run bionic/libc/kernel/tools/update_all.py
+ ***
+ ***   Any manual change here will be lost the next time this script will
+ ***   be run. You've been warned!
+ ***
+ ****************************************************************************
+ ****************************************************************************/
+#ifndef _LINUX_VIRTIO_INPUT_H
+#define _LINUX_VIRTIO_INPUT_H
+#include <linux/types.h>
+enum virtio_input_config_select {
+/* WARNING: DO NOT EDIT, AUTO-GENERATED CODE - SEE TOP FOR INSTRUCTIONS */
+  VIRTIO_INPUT_CFG_UNSET = 0x00,
+  VIRTIO_INPUT_CFG_ID_NAME = 0x01,
+  VIRTIO_INPUT_CFG_ID_SERIAL = 0x02,
+  VIRTIO_INPUT_CFG_ID_DEVIDS = 0x03,
+/* WARNING: DO NOT EDIT, AUTO-GENERATED CODE - SEE TOP FOR INSTRUCTIONS */
+  VIRTIO_INPUT_CFG_PROP_BITS = 0x10,
+  VIRTIO_INPUT_CFG_EV_BITS = 0x11,
+  VIRTIO_INPUT_CFG_ABS_INFO = 0x12,
+};
+/* WARNING: DO NOT EDIT, AUTO-GENERATED CODE - SEE TOP FOR INSTRUCTIONS */
+struct virtio_input_absinfo {
+  __u32 min;
+  __u32 max;
+  __u32 fuzz;
+/* WARNING: DO NOT EDIT, AUTO-GENERATED CODE - SEE TOP FOR INSTRUCTIONS */
+  __u32 flat;
+  __u32 res;
+};
+struct virtio_input_devids {
+/* WARNING: DO NOT EDIT, AUTO-GENERATED CODE - SEE TOP FOR INSTRUCTIONS */
+  __u16 bustype;
+  __u16 vendor;
+  __u16 product;
+  __u16 version;
+/* WARNING: DO NOT EDIT, AUTO-GENERATED CODE - SEE TOP FOR INSTRUCTIONS */
+};
+struct virtio_input_config {
+  __u8 select;
+  __u8 subsel;
+/* WARNING: DO NOT EDIT, AUTO-GENERATED CODE - SEE TOP FOR INSTRUCTIONS */
+  __u8 size;
+  __u8 reserved[5];
+  union {
+    char string[128];
+/* WARNING: DO NOT EDIT, AUTO-GENERATED CODE - SEE TOP FOR INSTRUCTIONS */
+    __u8 bitmap[128];
+    struct virtio_input_absinfo abs;
+    struct virtio_input_devids ids;
+  } u;
+/* WARNING: DO NOT EDIT, AUTO-GENERATED CODE - SEE TOP FOR INSTRUCTIONS */
+};
+struct virtio_input_event {
+  __le16 type;
+  __le16 code;
+/* WARNING: DO NOT EDIT, AUTO-GENERATED CODE - SEE TOP FOR INSTRUCTIONS */
+  __le32 value;
+};
+#endif
diff --git a/libc/kernel/uapi/linux/virtio_net.h b/libc/kernel/uapi/linux/virtio_net.h
index fef8070..e5e4b6c 100644
--- a/libc/kernel/uapi/linux/virtio_net.h
+++ b/libc/kernel/uapi/linux/virtio_net.h
@@ -22,33 +22,38 @@
 #include <linux/virtio_ids.h>
 /* WARNING: DO NOT EDIT, AUTO-GENERATED CODE - SEE TOP FOR INSTRUCTIONS */
 #include <linux/virtio_config.h>
+#include <linux/virtio_types.h>
 #include <linux/if_ether.h>
 #define VIRTIO_NET_F_CSUM 0
+/* WARNING: DO NOT EDIT, AUTO-GENERATED CODE - SEE TOP FOR INSTRUCTIONS */
 #define VIRTIO_NET_F_GUEST_CSUM 1
-/* WARNING: DO NOT EDIT, AUTO-GENERATED CODE - SEE TOP FOR INSTRUCTIONS */
+#define VIRTIO_NET_F_CTRL_GUEST_OFFLOADS 2
 #define VIRTIO_NET_F_MAC 5
-#define VIRTIO_NET_F_GSO 6
 #define VIRTIO_NET_F_GUEST_TSO4 7
-#define VIRTIO_NET_F_GUEST_TSO6 8
 /* WARNING: DO NOT EDIT, AUTO-GENERATED CODE - SEE TOP FOR INSTRUCTIONS */
+#define VIRTIO_NET_F_GUEST_TSO6 8
 #define VIRTIO_NET_F_GUEST_ECN 9
 #define VIRTIO_NET_F_GUEST_UFO 10
 #define VIRTIO_NET_F_HOST_TSO4 11
-#define VIRTIO_NET_F_HOST_TSO6 12
 /* WARNING: DO NOT EDIT, AUTO-GENERATED CODE - SEE TOP FOR INSTRUCTIONS */
+#define VIRTIO_NET_F_HOST_TSO6 12
 #define VIRTIO_NET_F_HOST_ECN 13
 #define VIRTIO_NET_F_HOST_UFO 14
 #define VIRTIO_NET_F_MRG_RXBUF 15
-#define VIRTIO_NET_F_STATUS 16
 /* WARNING: DO NOT EDIT, AUTO-GENERATED CODE - SEE TOP FOR INSTRUCTIONS */
+#define VIRTIO_NET_F_STATUS 16
 #define VIRTIO_NET_F_CTRL_VQ 17
 #define VIRTIO_NET_F_CTRL_RX 18
 #define VIRTIO_NET_F_CTRL_VLAN 19
-#define VIRTIO_NET_F_CTRL_RX_EXTRA 20
 /* WARNING: DO NOT EDIT, AUTO-GENERATED CODE - SEE TOP FOR INSTRUCTIONS */
+#define VIRTIO_NET_F_CTRL_RX_EXTRA 20
 #define VIRTIO_NET_F_GUEST_ANNOUNCE 21
 #define VIRTIO_NET_F_MQ 22
 #define VIRTIO_NET_F_CTRL_MAC_ADDR 23
+/* WARNING: DO NOT EDIT, AUTO-GENERATED CODE - SEE TOP FOR INSTRUCTIONS */
+#ifndef VIRTIO_NET_NO_LEGACY
+#define VIRTIO_NET_F_GSO 6
+#endif
 #define VIRTIO_NET_S_LINK_UP 1
 /* WARNING: DO NOT EDIT, AUTO-GENERATED CODE - SEE TOP FOR INSTRUCTIONS */
 #define VIRTIO_NET_S_ANNOUNCE 2
@@ -58,7 +63,7 @@
 /* WARNING: DO NOT EDIT, AUTO-GENERATED CODE - SEE TOP FOR INSTRUCTIONS */
   __u16 max_virtqueue_pairs;
 } __attribute__((packed));
-struct virtio_net_hdr {
+struct virtio_net_hdr_v1 {
 #define VIRTIO_NET_HDR_F_NEEDS_CSUM 1
 /* WARNING: DO NOT EDIT, AUTO-GENERATED CODE - SEE TOP FOR INSTRUCTIONS */
 #define VIRTIO_NET_HDR_F_DATA_VALID 2
@@ -71,56 +76,73 @@
 #define VIRTIO_NET_HDR_GSO_ECN 0x80
   __u8 gso_type;
 /* WARNING: DO NOT EDIT, AUTO-GENERATED CODE - SEE TOP FOR INSTRUCTIONS */
-  __u16 hdr_len;
-  __u16 gso_size;
-  __u16 csum_start;
-  __u16 csum_offset;
+  __virtio16 hdr_len;
+  __virtio16 gso_size;
+  __virtio16 csum_start;
+  __virtio16 csum_offset;
 /* WARNING: DO NOT EDIT, AUTO-GENERATED CODE - SEE TOP FOR INSTRUCTIONS */
+  __virtio16 num_buffers;
+};
+#ifndef VIRTIO_NET_NO_LEGACY
+struct virtio_net_hdr {
+/* WARNING: DO NOT EDIT, AUTO-GENERATED CODE - SEE TOP FOR INSTRUCTIONS */
+  __u8 flags;
+  __u8 gso_type;
+  __virtio16 hdr_len;
+  __virtio16 gso_size;
+/* WARNING: DO NOT EDIT, AUTO-GENERATED CODE - SEE TOP FOR INSTRUCTIONS */
+  __virtio16 csum_start;
+  __virtio16 csum_offset;
 };
 struct virtio_net_hdr_mrg_rxbuf {
-  struct virtio_net_hdr hdr;
-  __u16 num_buffers;
 /* WARNING: DO NOT EDIT, AUTO-GENERATED CODE - SEE TOP FOR INSTRUCTIONS */
+  struct virtio_net_hdr hdr;
+  __virtio16 num_buffers;
 };
+#endif
+/* WARNING: DO NOT EDIT, AUTO-GENERATED CODE - SEE TOP FOR INSTRUCTIONS */
 struct virtio_net_ctrl_hdr {
   __u8 class;
   __u8 cmd;
-/* WARNING: DO NOT EDIT, AUTO-GENERATED CODE - SEE TOP FOR INSTRUCTIONS */
 } __attribute__((packed));
+/* WARNING: DO NOT EDIT, AUTO-GENERATED CODE - SEE TOP FOR INSTRUCTIONS */
 typedef __u8 virtio_net_ctrl_ack;
 #define VIRTIO_NET_OK 0
 #define VIRTIO_NET_ERR 1
-/* WARNING: DO NOT EDIT, AUTO-GENERATED CODE - SEE TOP FOR INSTRUCTIONS */
 #define VIRTIO_NET_CTRL_RX 0
+/* WARNING: DO NOT EDIT, AUTO-GENERATED CODE - SEE TOP FOR INSTRUCTIONS */
 #define VIRTIO_NET_CTRL_RX_PROMISC 0
 #define VIRTIO_NET_CTRL_RX_ALLMULTI 1
 #define VIRTIO_NET_CTRL_RX_ALLUNI 2
-/* WARNING: DO NOT EDIT, AUTO-GENERATED CODE - SEE TOP FOR INSTRUCTIONS */
 #define VIRTIO_NET_CTRL_RX_NOMULTI 3
+/* WARNING: DO NOT EDIT, AUTO-GENERATED CODE - SEE TOP FOR INSTRUCTIONS */
 #define VIRTIO_NET_CTRL_RX_NOUNI 4
 #define VIRTIO_NET_CTRL_RX_NOBCAST 5
 struct virtio_net_ctrl_mac {
+  __virtio32 entries;
 /* WARNING: DO NOT EDIT, AUTO-GENERATED CODE - SEE TOP FOR INSTRUCTIONS */
-  __u32 entries;
   __u8 macs[][ETH_ALEN];
 } __attribute__((packed));
 #define VIRTIO_NET_CTRL_MAC 1
-/* WARNING: DO NOT EDIT, AUTO-GENERATED CODE - SEE TOP FOR INSTRUCTIONS */
 #define VIRTIO_NET_CTRL_MAC_TABLE_SET 0
+/* WARNING: DO NOT EDIT, AUTO-GENERATED CODE - SEE TOP FOR INSTRUCTIONS */
 #define VIRTIO_NET_CTRL_MAC_ADDR_SET 1
 #define VIRTIO_NET_CTRL_VLAN 2
 #define VIRTIO_NET_CTRL_VLAN_ADD 0
-/* WARNING: DO NOT EDIT, AUTO-GENERATED CODE - SEE TOP FOR INSTRUCTIONS */
 #define VIRTIO_NET_CTRL_VLAN_DEL 1
+/* WARNING: DO NOT EDIT, AUTO-GENERATED CODE - SEE TOP FOR INSTRUCTIONS */
 #define VIRTIO_NET_CTRL_ANNOUNCE 3
 #define VIRTIO_NET_CTRL_ANNOUNCE_ACK 0
 struct virtio_net_ctrl_mq {
+  __virtio16 virtqueue_pairs;
 /* WARNING: DO NOT EDIT, AUTO-GENERATED CODE - SEE TOP FOR INSTRUCTIONS */
-  __u16 virtqueue_pairs;
 };
 #define VIRTIO_NET_CTRL_MQ 4
 #define VIRTIO_NET_CTRL_MQ_VQ_PAIRS_SET 0
-/* WARNING: DO NOT EDIT, AUTO-GENERATED CODE - SEE TOP FOR INSTRUCTIONS */
 #define VIRTIO_NET_CTRL_MQ_VQ_PAIRS_MIN 1
+/* WARNING: DO NOT EDIT, AUTO-GENERATED CODE - SEE TOP FOR INSTRUCTIONS */
 #define VIRTIO_NET_CTRL_MQ_VQ_PAIRS_MAX 0x8000
+#define VIRTIO_NET_CTRL_GUEST_OFFLOADS 5
+#define VIRTIO_NET_CTRL_GUEST_OFFLOADS_SET 0
 #endif
+/* WARNING: DO NOT EDIT, AUTO-GENERATED CODE - SEE TOP FOR INSTRUCTIONS */
diff --git a/libc/kernel/uapi/linux/virtio_pci.h b/libc/kernel/uapi/linux/virtio_pci.h
index affd6c9..f1072aa 100644
--- a/libc/kernel/uapi/linux/virtio_pci.h
+++ b/libc/kernel/uapi/linux/virtio_pci.h
@@ -18,27 +18,121 @@
  ****************************************************************************/
 #ifndef _LINUX_VIRTIO_PCI_H
 #define _LINUX_VIRTIO_PCI_H
-#include <linux/virtio_config.h>
-#define VIRTIO_PCI_HOST_FEATURES 0
+#include <linux/types.h>
+#ifndef VIRTIO_PCI_NO_LEGACY
 /* WARNING: DO NOT EDIT, AUTO-GENERATED CODE - SEE TOP FOR INSTRUCTIONS */
+#define VIRTIO_PCI_HOST_FEATURES 0
 #define VIRTIO_PCI_GUEST_FEATURES 4
 #define VIRTIO_PCI_QUEUE_PFN 8
 #define VIRTIO_PCI_QUEUE_NUM 12
-#define VIRTIO_PCI_QUEUE_SEL 14
 /* WARNING: DO NOT EDIT, AUTO-GENERATED CODE - SEE TOP FOR INSTRUCTIONS */
+#define VIRTIO_PCI_QUEUE_SEL 14
 #define VIRTIO_PCI_QUEUE_NOTIFY 16
 #define VIRTIO_PCI_STATUS 18
 #define VIRTIO_PCI_ISR 19
-#define VIRTIO_PCI_ISR_CONFIG 0x2
 /* WARNING: DO NOT EDIT, AUTO-GENERATED CODE - SEE TOP FOR INSTRUCTIONS */
 #define VIRTIO_MSI_CONFIG_VECTOR 20
 #define VIRTIO_MSI_QUEUE_VECTOR 22
-#define VIRTIO_MSI_NO_VECTOR 0xffff
 #define VIRTIO_PCI_CONFIG_OFF(msix_enabled) ((msix_enabled) ? 24 : 20)
-/* WARNING: DO NOT EDIT, AUTO-GENERATED CODE - SEE TOP FOR INSTRUCTIONS */
 #define VIRTIO_PCI_CONFIG(dev) VIRTIO_PCI_CONFIG_OFF((dev)->msix_enabled)
+/* WARNING: DO NOT EDIT, AUTO-GENERATED CODE - SEE TOP FOR INSTRUCTIONS */
 #define VIRTIO_PCI_ABI_VERSION 0
 #define VIRTIO_PCI_QUEUE_ADDR_SHIFT 12
 #define VIRTIO_PCI_VRING_ALIGN 4096
-/* WARNING: DO NOT EDIT, AUTO-GENERATED CODE - SEE TOP FOR INSTRUCTIONS */
 #endif
+/* WARNING: DO NOT EDIT, AUTO-GENERATED CODE - SEE TOP FOR INSTRUCTIONS */
+#define VIRTIO_PCI_ISR_CONFIG 0x2
+#define VIRTIO_MSI_NO_VECTOR 0xffff
+#ifndef VIRTIO_PCI_NO_MODERN
+#define VIRTIO_PCI_CAP_COMMON_CFG 1
+/* WARNING: DO NOT EDIT, AUTO-GENERATED CODE - SEE TOP FOR INSTRUCTIONS */
+#define VIRTIO_PCI_CAP_NOTIFY_CFG 2
+#define VIRTIO_PCI_CAP_ISR_CFG 3
+#define VIRTIO_PCI_CAP_DEVICE_CFG 4
+#define VIRTIO_PCI_CAP_PCI_CFG 5
+/* WARNING: DO NOT EDIT, AUTO-GENERATED CODE - SEE TOP FOR INSTRUCTIONS */
+struct virtio_pci_cap {
+  __u8 cap_vndr;
+  __u8 cap_next;
+  __u8 cap_len;
+/* WARNING: DO NOT EDIT, AUTO-GENERATED CODE - SEE TOP FOR INSTRUCTIONS */
+  __u8 cfg_type;
+  __u8 bar;
+  __u8 padding[3];
+  __le32 offset;
+/* WARNING: DO NOT EDIT, AUTO-GENERATED CODE - SEE TOP FOR INSTRUCTIONS */
+  __le32 length;
+};
+struct virtio_pci_notify_cap {
+  struct virtio_pci_cap cap;
+/* WARNING: DO NOT EDIT, AUTO-GENERATED CODE - SEE TOP FOR INSTRUCTIONS */
+  __le32 notify_off_multiplier;
+};
+struct virtio_pci_common_cfg {
+  __le32 device_feature_select;
+/* WARNING: DO NOT EDIT, AUTO-GENERATED CODE - SEE TOP FOR INSTRUCTIONS */
+  __le32 device_feature;
+  __le32 guest_feature_select;
+  __le32 guest_feature;
+  __le16 msix_config;
+/* WARNING: DO NOT EDIT, AUTO-GENERATED CODE - SEE TOP FOR INSTRUCTIONS */
+  __le16 num_queues;
+  __u8 device_status;
+  __u8 config_generation;
+  __le16 queue_select;
+/* WARNING: DO NOT EDIT, AUTO-GENERATED CODE - SEE TOP FOR INSTRUCTIONS */
+  __le16 queue_size;
+  __le16 queue_msix_vector;
+  __le16 queue_enable;
+  __le16 queue_notify_off;
+/* WARNING: DO NOT EDIT, AUTO-GENERATED CODE - SEE TOP FOR INSTRUCTIONS */
+  __le32 queue_desc_lo;
+  __le32 queue_desc_hi;
+  __le32 queue_avail_lo;
+  __le32 queue_avail_hi;
+/* WARNING: DO NOT EDIT, AUTO-GENERATED CODE - SEE TOP FOR INSTRUCTIONS */
+  __le32 queue_used_lo;
+  __le32 queue_used_hi;
+};
+struct virtio_pci_cfg_cap {
+/* WARNING: DO NOT EDIT, AUTO-GENERATED CODE - SEE TOP FOR INSTRUCTIONS */
+  struct virtio_pci_cap cap;
+  __u8 pci_cfg_data[4];
+};
+#define VIRTIO_PCI_CAP_VNDR 0
+/* WARNING: DO NOT EDIT, AUTO-GENERATED CODE - SEE TOP FOR INSTRUCTIONS */
+#define VIRTIO_PCI_CAP_NEXT 1
+#define VIRTIO_PCI_CAP_LEN 2
+#define VIRTIO_PCI_CAP_CFG_TYPE 3
+#define VIRTIO_PCI_CAP_BAR 4
+/* WARNING: DO NOT EDIT, AUTO-GENERATED CODE - SEE TOP FOR INSTRUCTIONS */
+#define VIRTIO_PCI_CAP_OFFSET 8
+#define VIRTIO_PCI_CAP_LENGTH 12
+#define VIRTIO_PCI_NOTIFY_CAP_MULT 16
+#define VIRTIO_PCI_COMMON_DFSELECT 0
+/* WARNING: DO NOT EDIT, AUTO-GENERATED CODE - SEE TOP FOR INSTRUCTIONS */
+#define VIRTIO_PCI_COMMON_DF 4
+#define VIRTIO_PCI_COMMON_GFSELECT 8
+#define VIRTIO_PCI_COMMON_GF 12
+#define VIRTIO_PCI_COMMON_MSIX 16
+/* WARNING: DO NOT EDIT, AUTO-GENERATED CODE - SEE TOP FOR INSTRUCTIONS */
+#define VIRTIO_PCI_COMMON_NUMQ 18
+#define VIRTIO_PCI_COMMON_STATUS 20
+#define VIRTIO_PCI_COMMON_CFGGENERATION 21
+#define VIRTIO_PCI_COMMON_Q_SELECT 22
+/* WARNING: DO NOT EDIT, AUTO-GENERATED CODE - SEE TOP FOR INSTRUCTIONS */
+#define VIRTIO_PCI_COMMON_Q_SIZE 24
+#define VIRTIO_PCI_COMMON_Q_MSIX 26
+#define VIRTIO_PCI_COMMON_Q_ENABLE 28
+#define VIRTIO_PCI_COMMON_Q_NOFF 30
+/* WARNING: DO NOT EDIT, AUTO-GENERATED CODE - SEE TOP FOR INSTRUCTIONS */
+#define VIRTIO_PCI_COMMON_Q_DESCLO 32
+#define VIRTIO_PCI_COMMON_Q_DESCHI 36
+#define VIRTIO_PCI_COMMON_Q_AVAILLO 40
+#define VIRTIO_PCI_COMMON_Q_AVAILHI 44
+/* WARNING: DO NOT EDIT, AUTO-GENERATED CODE - SEE TOP FOR INSTRUCTIONS */
+#define VIRTIO_PCI_COMMON_Q_USEDLO 48
+#define VIRTIO_PCI_COMMON_Q_USEDHI 52
+#endif
+#endif
+/* WARNING: DO NOT EDIT, AUTO-GENERATED CODE - SEE TOP FOR INSTRUCTIONS */
diff --git a/libc/kernel/uapi/linux/virtio_ring.h b/libc/kernel/uapi/linux/virtio_ring.h
index a171874..3e85e10 100644
--- a/libc/kernel/uapi/linux/virtio_ring.h
+++ b/libc/kernel/uapi/linux/virtio_ring.h
@@ -18,49 +18,56 @@
  ****************************************************************************/
 #ifndef _UAPI_LINUX_VIRTIO_RING_H
 #define _UAPI_LINUX_VIRTIO_RING_H
+#include <stdint.h>
 #include <linux/types.h>
-#define VRING_DESC_F_NEXT 1
 /* WARNING: DO NOT EDIT, AUTO-GENERATED CODE - SEE TOP FOR INSTRUCTIONS */
+#include <linux/virtio_types.h>
+#define VRING_DESC_F_NEXT 1
 #define VRING_DESC_F_WRITE 2
 #define VRING_DESC_F_INDIRECT 4
+/* WARNING: DO NOT EDIT, AUTO-GENERATED CODE - SEE TOP FOR INSTRUCTIONS */
 #define VRING_USED_F_NO_NOTIFY 1
 #define VRING_AVAIL_F_NO_INTERRUPT 1
-/* WARNING: DO NOT EDIT, AUTO-GENERATED CODE - SEE TOP FOR INSTRUCTIONS */
 #define VIRTIO_RING_F_INDIRECT_DESC 28
 #define VIRTIO_RING_F_EVENT_IDX 29
+/* WARNING: DO NOT EDIT, AUTO-GENERATED CODE - SEE TOP FOR INSTRUCTIONS */
 struct vring_desc {
-  __u64 addr;
+  __virtio64 addr;
+  __virtio32 len;
+  __virtio16 flags;
 /* WARNING: DO NOT EDIT, AUTO-GENERATED CODE - SEE TOP FOR INSTRUCTIONS */
-  __u32 len;
-  __u16 flags;
-  __u16 next;
+  __virtio16 next;
 };
-/* WARNING: DO NOT EDIT, AUTO-GENERATED CODE - SEE TOP FOR INSTRUCTIONS */
 struct vring_avail {
-  __u16 flags;
-  __u16 idx;
-  __u16 ring[];
+  __virtio16 flags;
 /* WARNING: DO NOT EDIT, AUTO-GENERATED CODE - SEE TOP FOR INSTRUCTIONS */
+  __virtio16 idx;
+  __virtio16 ring[];
 };
 struct vring_used_elem {
-  __u32 id;
-  __u32 len;
 /* WARNING: DO NOT EDIT, AUTO-GENERATED CODE - SEE TOP FOR INSTRUCTIONS */
+  __virtio32 id;
+  __virtio32 len;
 };
 struct vring_used {
-  __u16 flags;
-  __u16 idx;
 /* WARNING: DO NOT EDIT, AUTO-GENERATED CODE - SEE TOP FOR INSTRUCTIONS */
+  __virtio16 flags;
+  __virtio16 idx;
   struct vring_used_elem ring[];
 };
+/* WARNING: DO NOT EDIT, AUTO-GENERATED CODE - SEE TOP FOR INSTRUCTIONS */
 struct vring {
   unsigned int num;
-/* WARNING: DO NOT EDIT, AUTO-GENERATED CODE - SEE TOP FOR INSTRUCTIONS */
   struct vring_desc * desc;
   struct vring_avail * avail;
+/* WARNING: DO NOT EDIT, AUTO-GENERATED CODE - SEE TOP FOR INSTRUCTIONS */
   struct vring_used * used;
 };
+#define VRING_AVAIL_ALIGN_SIZE 2
+#define VRING_USED_ALIGN_SIZE 4
 /* WARNING: DO NOT EDIT, AUTO-GENERATED CODE - SEE TOP FOR INSTRUCTIONS */
+#define VRING_DESC_ALIGN_SIZE 16
 #define vring_used_event(vr) ((vr)->avail->ring[(vr)->num])
-#define vring_avail_event(vr) (* (__u16 *) & (vr)->used->ring[(vr)->num])
+#define vring_avail_event(vr) (* (__virtio16 *) & (vr)->used->ring[(vr)->num])
 #endif
+/* WARNING: DO NOT EDIT, AUTO-GENERATED CODE - SEE TOP FOR INSTRUCTIONS */
diff --git a/libc/kernel/uapi/linux/virtio_scsi.h b/libc/kernel/uapi/linux/virtio_scsi.h
new file mode 100644
index 0000000..9bd9ef5
--- /dev/null
+++ b/libc/kernel/uapi/linux/virtio_scsi.h
@@ -0,0 +1,159 @@
+/****************************************************************************
+ ****************************************************************************
+ ***
+ ***   This header was automatically generated from a Linux kernel header
+ ***   of the same name, to make information necessary for userspace to
+ ***   call into the kernel available to libc.  It contains only constants,
+ ***   structures, and macros generated from the original header, and thus,
+ ***   contains no copyrightable information.
+ ***
+ ***   To edit the content of this header, modify the corresponding
+ ***   source file (e.g. under external/kernel-headers/original/) then
+ ***   run bionic/libc/kernel/tools/update_all.py
+ ***
+ ***   Any manual change here will be lost the next time this script will
+ ***   be run. You've been warned!
+ ***
+ ****************************************************************************
+ ****************************************************************************/
+#ifndef _LINUX_VIRTIO_SCSI_H
+#define _LINUX_VIRTIO_SCSI_H
+#include <linux/virtio_types.h>
+#define VIRTIO_SCSI_CDB_DEFAULT_SIZE 32
+/* WARNING: DO NOT EDIT, AUTO-GENERATED CODE - SEE TOP FOR INSTRUCTIONS */
+#define VIRTIO_SCSI_SENSE_DEFAULT_SIZE 96
+#ifndef VIRTIO_SCSI_CDB_SIZE
+#define VIRTIO_SCSI_CDB_SIZE VIRTIO_SCSI_CDB_DEFAULT_SIZE
+#endif
+/* WARNING: DO NOT EDIT, AUTO-GENERATED CODE - SEE TOP FOR INSTRUCTIONS */
+#ifndef VIRTIO_SCSI_SENSE_SIZE
+#define VIRTIO_SCSI_SENSE_SIZE VIRTIO_SCSI_SENSE_DEFAULT_SIZE
+#endif
+struct virtio_scsi_cmd_req {
+/* WARNING: DO NOT EDIT, AUTO-GENERATED CODE - SEE TOP FOR INSTRUCTIONS */
+  __u8 lun[8];
+  __virtio64 tag;
+  __u8 task_attr;
+  __u8 prio;
+/* WARNING: DO NOT EDIT, AUTO-GENERATED CODE - SEE TOP FOR INSTRUCTIONS */
+  __u8 crn;
+  __u8 cdb[VIRTIO_SCSI_CDB_SIZE];
+} __attribute__((packed));
+struct virtio_scsi_cmd_req_pi {
+/* WARNING: DO NOT EDIT, AUTO-GENERATED CODE - SEE TOP FOR INSTRUCTIONS */
+  __u8 lun[8];
+  __virtio64 tag;
+  __u8 task_attr;
+  __u8 prio;
+/* WARNING: DO NOT EDIT, AUTO-GENERATED CODE - SEE TOP FOR INSTRUCTIONS */
+  __u8 crn;
+  __virtio32 pi_bytesout;
+  __virtio32 pi_bytesin;
+  __u8 cdb[VIRTIO_SCSI_CDB_SIZE];
+/* WARNING: DO NOT EDIT, AUTO-GENERATED CODE - SEE TOP FOR INSTRUCTIONS */
+} __attribute__((packed));
+struct virtio_scsi_cmd_resp {
+  __virtio32 sense_len;
+  __virtio32 resid;
+/* WARNING: DO NOT EDIT, AUTO-GENERATED CODE - SEE TOP FOR INSTRUCTIONS */
+  __virtio16 status_qualifier;
+  __u8 status;
+  __u8 response;
+  __u8 sense[VIRTIO_SCSI_SENSE_SIZE];
+/* WARNING: DO NOT EDIT, AUTO-GENERATED CODE - SEE TOP FOR INSTRUCTIONS */
+} __attribute__((packed));
+struct virtio_scsi_ctrl_tmf_req {
+  __virtio32 type;
+  __virtio32 subtype;
+/* WARNING: DO NOT EDIT, AUTO-GENERATED CODE - SEE TOP FOR INSTRUCTIONS */
+  __u8 lun[8];
+  __virtio64 tag;
+} __attribute__((packed));
+struct virtio_scsi_ctrl_tmf_resp {
+/* WARNING: DO NOT EDIT, AUTO-GENERATED CODE - SEE TOP FOR INSTRUCTIONS */
+  __u8 response;
+} __attribute__((packed));
+struct virtio_scsi_ctrl_an_req {
+  __virtio32 type;
+/* WARNING: DO NOT EDIT, AUTO-GENERATED CODE - SEE TOP FOR INSTRUCTIONS */
+  __u8 lun[8];
+  __virtio32 event_requested;
+} __attribute__((packed));
+struct virtio_scsi_ctrl_an_resp {
+/* WARNING: DO NOT EDIT, AUTO-GENERATED CODE - SEE TOP FOR INSTRUCTIONS */
+  __virtio32 event_actual;
+  __u8 response;
+} __attribute__((packed));
+struct virtio_scsi_event {
+/* WARNING: DO NOT EDIT, AUTO-GENERATED CODE - SEE TOP FOR INSTRUCTIONS */
+  __virtio32 event;
+  __u8 lun[8];
+  __virtio32 reason;
+} __attribute__((packed));
+/* WARNING: DO NOT EDIT, AUTO-GENERATED CODE - SEE TOP FOR INSTRUCTIONS */
+struct virtio_scsi_config {
+  __u32 num_queues;
+  __u32 seg_max;
+  __u32 max_sectors;
+/* WARNING: DO NOT EDIT, AUTO-GENERATED CODE - SEE TOP FOR INSTRUCTIONS */
+  __u32 cmd_per_lun;
+  __u32 event_info_size;
+  __u32 sense_size;
+  __u32 cdb_size;
+/* WARNING: DO NOT EDIT, AUTO-GENERATED CODE - SEE TOP FOR INSTRUCTIONS */
+  __u16 max_channel;
+  __u16 max_target;
+  __u32 max_lun;
+} __attribute__((packed));
+/* WARNING: DO NOT EDIT, AUTO-GENERATED CODE - SEE TOP FOR INSTRUCTIONS */
+#define VIRTIO_SCSI_F_INOUT 0
+#define VIRTIO_SCSI_F_HOTPLUG 1
+#define VIRTIO_SCSI_F_CHANGE 2
+#define VIRTIO_SCSI_F_T10_PI 3
+/* WARNING: DO NOT EDIT, AUTO-GENERATED CODE - SEE TOP FOR INSTRUCTIONS */
+#define VIRTIO_SCSI_S_OK 0
+#define VIRTIO_SCSI_S_OVERRUN 1
+#define VIRTIO_SCSI_S_ABORTED 2
+#define VIRTIO_SCSI_S_BAD_TARGET 3
+/* WARNING: DO NOT EDIT, AUTO-GENERATED CODE - SEE TOP FOR INSTRUCTIONS */
+#define VIRTIO_SCSI_S_RESET 4
+#define VIRTIO_SCSI_S_BUSY 5
+#define VIRTIO_SCSI_S_TRANSPORT_FAILURE 6
+#define VIRTIO_SCSI_S_TARGET_FAILURE 7
+/* WARNING: DO NOT EDIT, AUTO-GENERATED CODE - SEE TOP FOR INSTRUCTIONS */
+#define VIRTIO_SCSI_S_NEXUS_FAILURE 8
+#define VIRTIO_SCSI_S_FAILURE 9
+#define VIRTIO_SCSI_S_FUNCTION_SUCCEEDED 10
+#define VIRTIO_SCSI_S_FUNCTION_REJECTED 11
+/* WARNING: DO NOT EDIT, AUTO-GENERATED CODE - SEE TOP FOR INSTRUCTIONS */
+#define VIRTIO_SCSI_S_INCORRECT_LUN 12
+#define VIRTIO_SCSI_T_TMF 0
+#define VIRTIO_SCSI_T_AN_QUERY 1
+#define VIRTIO_SCSI_T_AN_SUBSCRIBE 2
+/* WARNING: DO NOT EDIT, AUTO-GENERATED CODE - SEE TOP FOR INSTRUCTIONS */
+#define VIRTIO_SCSI_T_TMF_ABORT_TASK 0
+#define VIRTIO_SCSI_T_TMF_ABORT_TASK_SET 1
+#define VIRTIO_SCSI_T_TMF_CLEAR_ACA 2
+#define VIRTIO_SCSI_T_TMF_CLEAR_TASK_SET 3
+/* WARNING: DO NOT EDIT, AUTO-GENERATED CODE - SEE TOP FOR INSTRUCTIONS */
+#define VIRTIO_SCSI_T_TMF_I_T_NEXUS_RESET 4
+#define VIRTIO_SCSI_T_TMF_LOGICAL_UNIT_RESET 5
+#define VIRTIO_SCSI_T_TMF_QUERY_TASK 6
+#define VIRTIO_SCSI_T_TMF_QUERY_TASK_SET 7
+/* WARNING: DO NOT EDIT, AUTO-GENERATED CODE - SEE TOP FOR INSTRUCTIONS */
+#define VIRTIO_SCSI_T_EVENTS_MISSED 0x80000000
+#define VIRTIO_SCSI_T_NO_EVENT 0
+#define VIRTIO_SCSI_T_TRANSPORT_RESET 1
+#define VIRTIO_SCSI_T_ASYNC_NOTIFY 2
+/* WARNING: DO NOT EDIT, AUTO-GENERATED CODE - SEE TOP FOR INSTRUCTIONS */
+#define VIRTIO_SCSI_T_PARAM_CHANGE 3
+#define VIRTIO_SCSI_EVT_RESET_HARD 0
+#define VIRTIO_SCSI_EVT_RESET_RESCAN 1
+#define VIRTIO_SCSI_EVT_RESET_REMOVED 2
+/* WARNING: DO NOT EDIT, AUTO-GENERATED CODE - SEE TOP FOR INSTRUCTIONS */
+#define VIRTIO_SCSI_S_SIMPLE 0
+#define VIRTIO_SCSI_S_ORDERED 1
+#define VIRTIO_SCSI_S_HEAD 2
+#define VIRTIO_SCSI_S_ACA 3
+/* WARNING: DO NOT EDIT, AUTO-GENERATED CODE - SEE TOP FOR INSTRUCTIONS */
+#endif
diff --git a/libc/kernel/uapi/linux/virtio_types.h b/libc/kernel/uapi/linux/virtio_types.h
new file mode 100644
index 0000000..e398216
--- /dev/null
+++ b/libc/kernel/uapi/linux/virtio_types.h
@@ -0,0 +1,26 @@
+/****************************************************************************
+ ****************************************************************************
+ ***
+ ***   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_VIRTIO_TYPES_H
+#define _UAPI_LINUX_VIRTIO_TYPES_H
+#include <linux/types.h>
+typedef __u16 __bitwise__ __virtio16;
+/* WARNING: DO NOT EDIT, AUTO-GENERATED CODE - SEE TOP FOR INSTRUCTIONS */
+typedef __u32 __bitwise__ __virtio32;
+typedef __u64 __bitwise__ __virtio64;
+#endif
diff --git a/libc/kernel/uapi/linux/vsp1.h b/libc/kernel/uapi/linux/vsp1.h
index 28f7fcd..f708b63 100644
--- a/libc/kernel/uapi/linux/vsp1.h
+++ b/libc/kernel/uapi/linux/vsp1.h
@@ -23,7 +23,7 @@
 /* WARNING: DO NOT EDIT, AUTO-GENERATED CODE - SEE TOP FOR INSTRUCTIONS */
 #define VIDIOC_VSP1_LUT_CONFIG _IOWR('V', BASE_VIDIOC_PRIVATE + 1, struct vsp1_lut_config)
 struct vsp1_lut_config {
-  u32 lut[256];
+  __u32 lut[256];
 };
 /* WARNING: DO NOT EDIT, AUTO-GENERATED CODE - SEE TOP FOR INSTRUCTIONS */
 #endif
diff --git a/libc/kernel/uapi/linux/vt.h b/libc/kernel/uapi/linux/vt.h
index c9a8245..5bea24e 100644
--- a/libc/kernel/uapi/linux/vt.h
+++ b/libc/kernel/uapi/linux/vt.h
@@ -96,5 +96,4 @@
 };
 #define VT_SETACTIVATE 0x560F
 /* WARNING: DO NOT EDIT, AUTO-GENERATED CODE - SEE TOP FOR INSTRUCTIONS */
-#define vt_get_kmsg_redirect() vt_kmsg_redirect(- 1)
 #endif
diff --git a/libc/kernel/uapi/linux/xfrm.h b/libc/kernel/uapi/linux/xfrm.h
index 3ab173a..27f9436 100644
--- a/libc/kernel/uapi/linux/xfrm.h
+++ b/libc/kernel/uapi/linux/xfrm.h
@@ -18,534 +18,537 @@
  ****************************************************************************/
 #ifndef _LINUX_XFRM_H
 #define _LINUX_XFRM_H
+#include <linux/in6.h>
 #include <linux/types.h>
-typedef union {
 /* WARNING: DO NOT EDIT, AUTO-GENERATED CODE - SEE TOP FOR INSTRUCTIONS */
+typedef union {
   __be32 a4;
   __be32 a6[4];
+  struct in6_addr in6;
+/* WARNING: DO NOT EDIT, AUTO-GENERATED CODE - SEE TOP FOR INSTRUCTIONS */
 } xfrm_address_t;
 struct xfrm_id {
-/* WARNING: DO NOT EDIT, AUTO-GENERATED CODE - SEE TOP FOR INSTRUCTIONS */
   xfrm_address_t daddr;
   __be32 spi;
+/* WARNING: DO NOT EDIT, AUTO-GENERATED CODE - SEE TOP FOR INSTRUCTIONS */
   __u8 proto;
 };
-/* WARNING: DO NOT EDIT, AUTO-GENERATED CODE - SEE TOP FOR INSTRUCTIONS */
 struct xfrm_sec_ctx {
   __u8 ctx_doi;
+/* WARNING: DO NOT EDIT, AUTO-GENERATED CODE - SEE TOP FOR INSTRUCTIONS */
   __u8 ctx_alg;
   __u16 ctx_len;
-/* WARNING: DO NOT EDIT, AUTO-GENERATED CODE - SEE TOP FOR INSTRUCTIONS */
   __u32 ctx_sid;
   char ctx_str[0];
+/* WARNING: DO NOT EDIT, AUTO-GENERATED CODE - SEE TOP FOR INSTRUCTIONS */
 };
 #define XFRM_SC_DOI_RESERVED 0
-/* WARNING: DO NOT EDIT, AUTO-GENERATED CODE - SEE TOP FOR INSTRUCTIONS */
 #define XFRM_SC_DOI_LSM 1
 #define XFRM_SC_ALG_RESERVED 0
+/* WARNING: DO NOT EDIT, AUTO-GENERATED CODE - SEE TOP FOR INSTRUCTIONS */
 #define XFRM_SC_ALG_SELINUX 1
 struct xfrm_selector {
-/* WARNING: DO NOT EDIT, AUTO-GENERATED CODE - SEE TOP FOR INSTRUCTIONS */
   xfrm_address_t daddr;
   xfrm_address_t saddr;
+/* WARNING: DO NOT EDIT, AUTO-GENERATED CODE - SEE TOP FOR INSTRUCTIONS */
   __be16 dport;
   __be16 dport_mask;
-/* WARNING: DO NOT EDIT, AUTO-GENERATED CODE - SEE TOP FOR INSTRUCTIONS */
   __be16 sport;
   __be16 sport_mask;
+/* WARNING: DO NOT EDIT, AUTO-GENERATED CODE - SEE TOP FOR INSTRUCTIONS */
   __u16 family;
   __u8 prefixlen_d;
-/* WARNING: DO NOT EDIT, AUTO-GENERATED CODE - SEE TOP FOR INSTRUCTIONS */
   __u8 prefixlen_s;
   __u8 proto;
+/* WARNING: DO NOT EDIT, AUTO-GENERATED CODE - SEE TOP FOR INSTRUCTIONS */
   int ifindex;
   __kernel_uid32_t user;
-/* WARNING: DO NOT EDIT, AUTO-GENERATED CODE - SEE TOP FOR INSTRUCTIONS */
 };
 #define XFRM_INF (~(__u64) 0)
+/* WARNING: DO NOT EDIT, AUTO-GENERATED CODE - SEE TOP FOR INSTRUCTIONS */
 struct xfrm_lifetime_cfg {
   __u64 soft_byte_limit;
-/* WARNING: DO NOT EDIT, AUTO-GENERATED CODE - SEE TOP FOR INSTRUCTIONS */
   __u64 hard_byte_limit;
   __u64 soft_packet_limit;
+/* WARNING: DO NOT EDIT, AUTO-GENERATED CODE - SEE TOP FOR INSTRUCTIONS */
   __u64 hard_packet_limit;
   __u64 soft_add_expires_seconds;
-/* WARNING: DO NOT EDIT, AUTO-GENERATED CODE - SEE TOP FOR INSTRUCTIONS */
   __u64 hard_add_expires_seconds;
   __u64 soft_use_expires_seconds;
+/* WARNING: DO NOT EDIT, AUTO-GENERATED CODE - SEE TOP FOR INSTRUCTIONS */
   __u64 hard_use_expires_seconds;
 };
-/* WARNING: DO NOT EDIT, AUTO-GENERATED CODE - SEE TOP FOR INSTRUCTIONS */
 struct xfrm_lifetime_cur {
   __u64 bytes;
+/* WARNING: DO NOT EDIT, AUTO-GENERATED CODE - SEE TOP FOR INSTRUCTIONS */
   __u64 packets;
   __u64 add_time;
-/* WARNING: DO NOT EDIT, AUTO-GENERATED CODE - SEE TOP FOR INSTRUCTIONS */
   __u64 use_time;
 };
+/* WARNING: DO NOT EDIT, AUTO-GENERATED CODE - SEE TOP FOR INSTRUCTIONS */
 struct xfrm_replay_state {
   __u32 oseq;
-/* WARNING: DO NOT EDIT, AUTO-GENERATED CODE - SEE TOP FOR INSTRUCTIONS */
   __u32 seq;
   __u32 bitmap;
+/* WARNING: DO NOT EDIT, AUTO-GENERATED CODE - SEE TOP FOR INSTRUCTIONS */
 };
 #define XFRMA_REPLAY_ESN_MAX 4096
-/* WARNING: DO NOT EDIT, AUTO-GENERATED CODE - SEE TOP FOR INSTRUCTIONS */
 struct xfrm_replay_state_esn {
   unsigned int bmp_len;
+/* WARNING: DO NOT EDIT, AUTO-GENERATED CODE - SEE TOP FOR INSTRUCTIONS */
   __u32 oseq;
   __u32 seq;
-/* WARNING: DO NOT EDIT, AUTO-GENERATED CODE - SEE TOP FOR INSTRUCTIONS */
   __u32 oseq_hi;
   __u32 seq_hi;
+/* WARNING: DO NOT EDIT, AUTO-GENERATED CODE - SEE TOP FOR INSTRUCTIONS */
   __u32 replay_window;
   __u32 bmp[0];
-/* WARNING: DO NOT EDIT, AUTO-GENERATED CODE - SEE TOP FOR INSTRUCTIONS */
 };
 struct xfrm_algo {
+/* WARNING: DO NOT EDIT, AUTO-GENERATED CODE - SEE TOP FOR INSTRUCTIONS */
   char alg_name[64];
   unsigned int alg_key_len;
-/* WARNING: DO NOT EDIT, AUTO-GENERATED CODE - SEE TOP FOR INSTRUCTIONS */
   char alg_key[0];
 };
+/* WARNING: DO NOT EDIT, AUTO-GENERATED CODE - SEE TOP FOR INSTRUCTIONS */
 struct xfrm_algo_auth {
   char alg_name[64];
-/* WARNING: DO NOT EDIT, AUTO-GENERATED CODE - SEE TOP FOR INSTRUCTIONS */
   unsigned int alg_key_len;
   unsigned int alg_trunc_len;
+/* WARNING: DO NOT EDIT, AUTO-GENERATED CODE - SEE TOP FOR INSTRUCTIONS */
   char alg_key[0];
 };
-/* WARNING: DO NOT EDIT, AUTO-GENERATED CODE - SEE TOP FOR INSTRUCTIONS */
 struct xfrm_algo_aead {
   char alg_name[64];
+/* WARNING: DO NOT EDIT, AUTO-GENERATED CODE - SEE TOP FOR INSTRUCTIONS */
   unsigned int alg_key_len;
   unsigned int alg_icv_len;
-/* WARNING: DO NOT EDIT, AUTO-GENERATED CODE - SEE TOP FOR INSTRUCTIONS */
   char alg_key[0];
 };
+/* WARNING: DO NOT EDIT, AUTO-GENERATED CODE - SEE TOP FOR INSTRUCTIONS */
 struct xfrm_stats {
   __u32 replay_window;
-/* WARNING: DO NOT EDIT, AUTO-GENERATED CODE - SEE TOP FOR INSTRUCTIONS */
   __u32 replay;
   __u32 integrity_failed;
+/* WARNING: DO NOT EDIT, AUTO-GENERATED CODE - SEE TOP FOR INSTRUCTIONS */
 };
 enum {
-/* WARNING: DO NOT EDIT, AUTO-GENERATED CODE - SEE TOP FOR INSTRUCTIONS */
   XFRM_POLICY_TYPE_MAIN = 0,
   XFRM_POLICY_TYPE_SUB = 1,
+/* WARNING: DO NOT EDIT, AUTO-GENERATED CODE - SEE TOP FOR INSTRUCTIONS */
   XFRM_POLICY_TYPE_MAX = 2,
   XFRM_POLICY_TYPE_ANY = 255
-/* WARNING: DO NOT EDIT, AUTO-GENERATED CODE - SEE TOP FOR INSTRUCTIONS */
 };
 enum {
+/* WARNING: DO NOT EDIT, AUTO-GENERATED CODE - SEE TOP FOR INSTRUCTIONS */
   XFRM_POLICY_IN = 0,
   XFRM_POLICY_OUT = 1,
-/* WARNING: DO NOT EDIT, AUTO-GENERATED CODE - SEE TOP FOR INSTRUCTIONS */
   XFRM_POLICY_FWD = 2,
   XFRM_POLICY_MASK = 3,
+/* WARNING: DO NOT EDIT, AUTO-GENERATED CODE - SEE TOP FOR INSTRUCTIONS */
   XFRM_POLICY_MAX = 3
 };
-/* WARNING: DO NOT EDIT, AUTO-GENERATED CODE - SEE TOP FOR INSTRUCTIONS */
 enum {
   XFRM_SHARE_ANY,
+/* WARNING: DO NOT EDIT, AUTO-GENERATED CODE - SEE TOP FOR INSTRUCTIONS */
   XFRM_SHARE_SESSION,
   XFRM_SHARE_USER,
-/* WARNING: DO NOT EDIT, AUTO-GENERATED CODE - SEE TOP FOR INSTRUCTIONS */
   XFRM_SHARE_UNIQUE
 };
+/* WARNING: DO NOT EDIT, AUTO-GENERATED CODE - SEE TOP FOR INSTRUCTIONS */
 #define XFRM_MODE_TRANSPORT 0
 #define XFRM_MODE_TUNNEL 1
-/* WARNING: DO NOT EDIT, AUTO-GENERATED CODE - SEE TOP FOR INSTRUCTIONS */
 #define XFRM_MODE_ROUTEOPTIMIZATION 2
 #define XFRM_MODE_IN_TRIGGER 3
+/* WARNING: DO NOT EDIT, AUTO-GENERATED CODE - SEE TOP FOR INSTRUCTIONS */
 #define XFRM_MODE_BEET 4
 #define XFRM_MODE_MAX 5
-/* WARNING: DO NOT EDIT, AUTO-GENERATED CODE - SEE TOP FOR INSTRUCTIONS */
 enum {
   XFRM_MSG_BASE = 0x10,
+/* WARNING: DO NOT EDIT, AUTO-GENERATED CODE - SEE TOP FOR INSTRUCTIONS */
   XFRM_MSG_NEWSA = 0x10,
 #define XFRM_MSG_NEWSA XFRM_MSG_NEWSA
-/* WARNING: DO NOT EDIT, AUTO-GENERATED CODE - SEE TOP FOR INSTRUCTIONS */
   XFRM_MSG_DELSA,
 #define XFRM_MSG_DELSA XFRM_MSG_DELSA
+/* WARNING: DO NOT EDIT, AUTO-GENERATED CODE - SEE TOP FOR INSTRUCTIONS */
   XFRM_MSG_GETSA,
 #define XFRM_MSG_GETSA XFRM_MSG_GETSA
-/* WARNING: DO NOT EDIT, AUTO-GENERATED CODE - SEE TOP FOR INSTRUCTIONS */
   XFRM_MSG_NEWPOLICY,
 #define XFRM_MSG_NEWPOLICY XFRM_MSG_NEWPOLICY
+/* WARNING: DO NOT EDIT, AUTO-GENERATED CODE - SEE TOP FOR INSTRUCTIONS */
   XFRM_MSG_DELPOLICY,
 #define XFRM_MSG_DELPOLICY XFRM_MSG_DELPOLICY
-/* WARNING: DO NOT EDIT, AUTO-GENERATED CODE - SEE TOP FOR INSTRUCTIONS */
   XFRM_MSG_GETPOLICY,
 #define XFRM_MSG_GETPOLICY XFRM_MSG_GETPOLICY
+/* WARNING: DO NOT EDIT, AUTO-GENERATED CODE - SEE TOP FOR INSTRUCTIONS */
   XFRM_MSG_ALLOCSPI,
 #define XFRM_MSG_ALLOCSPI XFRM_MSG_ALLOCSPI
-/* WARNING: DO NOT EDIT, AUTO-GENERATED CODE - SEE TOP FOR INSTRUCTIONS */
   XFRM_MSG_ACQUIRE,
 #define XFRM_MSG_ACQUIRE XFRM_MSG_ACQUIRE
+/* WARNING: DO NOT EDIT, AUTO-GENERATED CODE - SEE TOP FOR INSTRUCTIONS */
   XFRM_MSG_EXPIRE,
 #define XFRM_MSG_EXPIRE XFRM_MSG_EXPIRE
-/* WARNING: DO NOT EDIT, AUTO-GENERATED CODE - SEE TOP FOR INSTRUCTIONS */
   XFRM_MSG_UPDPOLICY,
 #define XFRM_MSG_UPDPOLICY XFRM_MSG_UPDPOLICY
+/* WARNING: DO NOT EDIT, AUTO-GENERATED CODE - SEE TOP FOR INSTRUCTIONS */
   XFRM_MSG_UPDSA,
 #define XFRM_MSG_UPDSA XFRM_MSG_UPDSA
-/* WARNING: DO NOT EDIT, AUTO-GENERATED CODE - SEE TOP FOR INSTRUCTIONS */
   XFRM_MSG_POLEXPIRE,
 #define XFRM_MSG_POLEXPIRE XFRM_MSG_POLEXPIRE
+/* WARNING: DO NOT EDIT, AUTO-GENERATED CODE - SEE TOP FOR INSTRUCTIONS */
   XFRM_MSG_FLUSHSA,
 #define XFRM_MSG_FLUSHSA XFRM_MSG_FLUSHSA
-/* WARNING: DO NOT EDIT, AUTO-GENERATED CODE - SEE TOP FOR INSTRUCTIONS */
   XFRM_MSG_FLUSHPOLICY,
 #define XFRM_MSG_FLUSHPOLICY XFRM_MSG_FLUSHPOLICY
+/* WARNING: DO NOT EDIT, AUTO-GENERATED CODE - SEE TOP FOR INSTRUCTIONS */
   XFRM_MSG_NEWAE,
 #define XFRM_MSG_NEWAE XFRM_MSG_NEWAE
-/* WARNING: DO NOT EDIT, AUTO-GENERATED CODE - SEE TOP FOR INSTRUCTIONS */
   XFRM_MSG_GETAE,
 #define XFRM_MSG_GETAE XFRM_MSG_GETAE
+/* WARNING: DO NOT EDIT, AUTO-GENERATED CODE - SEE TOP FOR INSTRUCTIONS */
   XFRM_MSG_REPORT,
 #define XFRM_MSG_REPORT XFRM_MSG_REPORT
-/* WARNING: DO NOT EDIT, AUTO-GENERATED CODE - SEE TOP FOR INSTRUCTIONS */
   XFRM_MSG_MIGRATE,
 #define XFRM_MSG_MIGRATE XFRM_MSG_MIGRATE
+/* WARNING: DO NOT EDIT, AUTO-GENERATED CODE - SEE TOP FOR INSTRUCTIONS */
   XFRM_MSG_NEWSADINFO,
 #define XFRM_MSG_NEWSADINFO XFRM_MSG_NEWSADINFO
-/* WARNING: DO NOT EDIT, AUTO-GENERATED CODE - SEE TOP FOR INSTRUCTIONS */
   XFRM_MSG_GETSADINFO,
 #define XFRM_MSG_GETSADINFO XFRM_MSG_GETSADINFO
+/* WARNING: DO NOT EDIT, AUTO-GENERATED CODE - SEE TOP FOR INSTRUCTIONS */
   XFRM_MSG_NEWSPDINFO,
 #define XFRM_MSG_NEWSPDINFO XFRM_MSG_NEWSPDINFO
-/* WARNING: DO NOT EDIT, AUTO-GENERATED CODE - SEE TOP FOR INSTRUCTIONS */
   XFRM_MSG_GETSPDINFO,
 #define XFRM_MSG_GETSPDINFO XFRM_MSG_GETSPDINFO
+/* WARNING: DO NOT EDIT, AUTO-GENERATED CODE - SEE TOP FOR INSTRUCTIONS */
   XFRM_MSG_MAPPING,
 #define XFRM_MSG_MAPPING XFRM_MSG_MAPPING
-/* WARNING: DO NOT EDIT, AUTO-GENERATED CODE - SEE TOP FOR INSTRUCTIONS */
   __XFRM_MSG_MAX
 };
+/* WARNING: DO NOT EDIT, AUTO-GENERATED CODE - SEE TOP FOR INSTRUCTIONS */
 #define XFRM_MSG_MAX (__XFRM_MSG_MAX - 1)
 #define XFRM_NR_MSGTYPES (XFRM_MSG_MAX + 1 - XFRM_MSG_BASE)
-/* WARNING: DO NOT EDIT, AUTO-GENERATED CODE - SEE TOP FOR INSTRUCTIONS */
 struct xfrm_user_sec_ctx {
   __u16 len;
+/* WARNING: DO NOT EDIT, AUTO-GENERATED CODE - SEE TOP FOR INSTRUCTIONS */
   __u16 exttype;
   __u8 ctx_alg;
-/* WARNING: DO NOT EDIT, AUTO-GENERATED CODE - SEE TOP FOR INSTRUCTIONS */
   __u8 ctx_doi;
   __u16 ctx_len;
+/* WARNING: DO NOT EDIT, AUTO-GENERATED CODE - SEE TOP FOR INSTRUCTIONS */
 };
 struct xfrm_user_tmpl {
-/* WARNING: DO NOT EDIT, AUTO-GENERATED CODE - SEE TOP FOR INSTRUCTIONS */
   struct xfrm_id id;
   __u16 family;
+/* WARNING: DO NOT EDIT, AUTO-GENERATED CODE - SEE TOP FOR INSTRUCTIONS */
   xfrm_address_t saddr;
   __u32 reqid;
-/* WARNING: DO NOT EDIT, AUTO-GENERATED CODE - SEE TOP FOR INSTRUCTIONS */
   __u8 mode;
   __u8 share;
+/* WARNING: DO NOT EDIT, AUTO-GENERATED CODE - SEE TOP FOR INSTRUCTIONS */
   __u8 optional;
   __u32 aalgos;
-/* WARNING: DO NOT EDIT, AUTO-GENERATED CODE - SEE TOP FOR INSTRUCTIONS */
   __u32 ealgos;
   __u32 calgos;
+/* WARNING: DO NOT EDIT, AUTO-GENERATED CODE - SEE TOP FOR INSTRUCTIONS */
 };
 struct xfrm_encap_tmpl {
-/* WARNING: DO NOT EDIT, AUTO-GENERATED CODE - SEE TOP FOR INSTRUCTIONS */
   __u16 encap_type;
   __be16 encap_sport;
+/* WARNING: DO NOT EDIT, AUTO-GENERATED CODE - SEE TOP FOR INSTRUCTIONS */
   __be16 encap_dport;
   xfrm_address_t encap_oa;
-/* WARNING: DO NOT EDIT, AUTO-GENERATED CODE - SEE TOP FOR INSTRUCTIONS */
 };
 enum xfrm_ae_ftype_t {
+/* WARNING: DO NOT EDIT, AUTO-GENERATED CODE - SEE TOP FOR INSTRUCTIONS */
   XFRM_AE_UNSPEC,
   XFRM_AE_RTHR = 1,
-/* WARNING: DO NOT EDIT, AUTO-GENERATED CODE - SEE TOP FOR INSTRUCTIONS */
   XFRM_AE_RVAL = 2,
   XFRM_AE_LVAL = 4,
+/* WARNING: DO NOT EDIT, AUTO-GENERATED CODE - SEE TOP FOR INSTRUCTIONS */
   XFRM_AE_ETHR = 8,
   XFRM_AE_CR = 16,
-/* WARNING: DO NOT EDIT, AUTO-GENERATED CODE - SEE TOP FOR INSTRUCTIONS */
   XFRM_AE_CE = 32,
   XFRM_AE_CU = 64,
+/* WARNING: DO NOT EDIT, AUTO-GENERATED CODE - SEE TOP FOR INSTRUCTIONS */
   __XFRM_AE_MAX
 #define XFRM_AE_MAX (__XFRM_AE_MAX - 1)
-/* WARNING: DO NOT EDIT, AUTO-GENERATED CODE - SEE TOP FOR INSTRUCTIONS */
 };
 struct xfrm_userpolicy_type {
+/* WARNING: DO NOT EDIT, AUTO-GENERATED CODE - SEE TOP FOR INSTRUCTIONS */
   __u8 type;
   __u16 reserved1;
-/* WARNING: DO NOT EDIT, AUTO-GENERATED CODE - SEE TOP FOR INSTRUCTIONS */
   __u8 reserved2;
 };
+/* WARNING: DO NOT EDIT, AUTO-GENERATED CODE - SEE TOP FOR INSTRUCTIONS */
 enum xfrm_attr_type_t {
   XFRMA_UNSPEC,
-/* WARNING: DO NOT EDIT, AUTO-GENERATED CODE - SEE TOP FOR INSTRUCTIONS */
   XFRMA_ALG_AUTH,
   XFRMA_ALG_CRYPT,
+/* WARNING: DO NOT EDIT, AUTO-GENERATED CODE - SEE TOP FOR INSTRUCTIONS */
   XFRMA_ALG_COMP,
   XFRMA_ENCAP,
-/* WARNING: DO NOT EDIT, AUTO-GENERATED CODE - SEE TOP FOR INSTRUCTIONS */
   XFRMA_TMPL,
   XFRMA_SA,
+/* WARNING: DO NOT EDIT, AUTO-GENERATED CODE - SEE TOP FOR INSTRUCTIONS */
   XFRMA_POLICY,
   XFRMA_SEC_CTX,
-/* WARNING: DO NOT EDIT, AUTO-GENERATED CODE - SEE TOP FOR INSTRUCTIONS */
   XFRMA_LTIME_VAL,
   XFRMA_REPLAY_VAL,
+/* WARNING: DO NOT EDIT, AUTO-GENERATED CODE - SEE TOP FOR INSTRUCTIONS */
   XFRMA_REPLAY_THRESH,
   XFRMA_ETIMER_THRESH,
-/* WARNING: DO NOT EDIT, AUTO-GENERATED CODE - SEE TOP FOR INSTRUCTIONS */
   XFRMA_SRCADDR,
   XFRMA_COADDR,
+/* WARNING: DO NOT EDIT, AUTO-GENERATED CODE - SEE TOP FOR INSTRUCTIONS */
   XFRMA_LASTUSED,
   XFRMA_POLICY_TYPE,
-/* WARNING: DO NOT EDIT, AUTO-GENERATED CODE - SEE TOP FOR INSTRUCTIONS */
   XFRMA_MIGRATE,
   XFRMA_ALG_AEAD,
+/* WARNING: DO NOT EDIT, AUTO-GENERATED CODE - SEE TOP FOR INSTRUCTIONS */
   XFRMA_KMADDRESS,
   XFRMA_ALG_AUTH_TRUNC,
-/* WARNING: DO NOT EDIT, AUTO-GENERATED CODE - SEE TOP FOR INSTRUCTIONS */
   XFRMA_MARK,
   XFRMA_TFCPAD,
+/* WARNING: DO NOT EDIT, AUTO-GENERATED CODE - SEE TOP FOR INSTRUCTIONS */
   XFRMA_REPLAY_ESN_VAL,
   XFRMA_SA_EXTRA_FLAGS,
-/* WARNING: DO NOT EDIT, AUTO-GENERATED CODE - SEE TOP FOR INSTRUCTIONS */
   XFRMA_PROTO,
   XFRMA_ADDRESS_FILTER,
+/* WARNING: DO NOT EDIT, AUTO-GENERATED CODE - SEE TOP FOR INSTRUCTIONS */
   __XFRMA_MAX
 #define XFRMA_MAX (__XFRMA_MAX - 1)
-/* WARNING: DO NOT EDIT, AUTO-GENERATED CODE - SEE TOP FOR INSTRUCTIONS */
 };
 struct xfrm_mark {
+/* WARNING: DO NOT EDIT, AUTO-GENERATED CODE - SEE TOP FOR INSTRUCTIONS */
   __u32 v;
   __u32 m;
-/* WARNING: DO NOT EDIT, AUTO-GENERATED CODE - SEE TOP FOR INSTRUCTIONS */
 };
 enum xfrm_sadattr_type_t {
+/* WARNING: DO NOT EDIT, AUTO-GENERATED CODE - SEE TOP FOR INSTRUCTIONS */
   XFRMA_SAD_UNSPEC,
   XFRMA_SAD_CNT,
-/* WARNING: DO NOT EDIT, AUTO-GENERATED CODE - SEE TOP FOR INSTRUCTIONS */
   XFRMA_SAD_HINFO,
   __XFRMA_SAD_MAX
+/* WARNING: DO NOT EDIT, AUTO-GENERATED CODE - SEE TOP FOR INSTRUCTIONS */
 #define XFRMA_SAD_MAX (__XFRMA_SAD_MAX - 1)
 };
-/* WARNING: DO NOT EDIT, AUTO-GENERATED CODE - SEE TOP FOR INSTRUCTIONS */
 struct xfrmu_sadhinfo {
   __u32 sadhcnt;
+/* WARNING: DO NOT EDIT, AUTO-GENERATED CODE - SEE TOP FOR INSTRUCTIONS */
   __u32 sadhmcnt;
 };
-/* WARNING: DO NOT EDIT, AUTO-GENERATED CODE - SEE TOP FOR INSTRUCTIONS */
 enum xfrm_spdattr_type_t {
   XFRMA_SPD_UNSPEC,
+/* WARNING: DO NOT EDIT, AUTO-GENERATED CODE - SEE TOP FOR INSTRUCTIONS */
   XFRMA_SPD_INFO,
   XFRMA_SPD_HINFO,
-/* WARNING: DO NOT EDIT, AUTO-GENERATED CODE - SEE TOP FOR INSTRUCTIONS */
   XFRMA_SPD_IPV4_HTHRESH,
   XFRMA_SPD_IPV6_HTHRESH,
+/* WARNING: DO NOT EDIT, AUTO-GENERATED CODE - SEE TOP FOR INSTRUCTIONS */
   __XFRMA_SPD_MAX
 #define XFRMA_SPD_MAX (__XFRMA_SPD_MAX - 1)
-/* WARNING: DO NOT EDIT, AUTO-GENERATED CODE - SEE TOP FOR INSTRUCTIONS */
 };
 struct xfrmu_spdinfo {
+/* WARNING: DO NOT EDIT, AUTO-GENERATED CODE - SEE TOP FOR INSTRUCTIONS */
   __u32 incnt;
   __u32 outcnt;
-/* WARNING: DO NOT EDIT, AUTO-GENERATED CODE - SEE TOP FOR INSTRUCTIONS */
   __u32 fwdcnt;
   __u32 inscnt;
+/* WARNING: DO NOT EDIT, AUTO-GENERATED CODE - SEE TOP FOR INSTRUCTIONS */
   __u32 outscnt;
   __u32 fwdscnt;
-/* WARNING: DO NOT EDIT, AUTO-GENERATED CODE - SEE TOP FOR INSTRUCTIONS */
 };
 struct xfrmu_spdhinfo {
+/* WARNING: DO NOT EDIT, AUTO-GENERATED CODE - SEE TOP FOR INSTRUCTIONS */
   __u32 spdhcnt;
   __u32 spdhmcnt;
-/* WARNING: DO NOT EDIT, AUTO-GENERATED CODE - SEE TOP FOR INSTRUCTIONS */
 };
 struct xfrmu_spdhthresh {
+/* WARNING: DO NOT EDIT, AUTO-GENERATED CODE - SEE TOP FOR INSTRUCTIONS */
   __u8 lbits;
   __u8 rbits;
-/* WARNING: DO NOT EDIT, AUTO-GENERATED CODE - SEE TOP FOR INSTRUCTIONS */
 };
 struct xfrm_usersa_info {
+/* WARNING: DO NOT EDIT, AUTO-GENERATED CODE - SEE TOP FOR INSTRUCTIONS */
   struct xfrm_selector sel;
   struct xfrm_id id;
-/* WARNING: DO NOT EDIT, AUTO-GENERATED CODE - SEE TOP FOR INSTRUCTIONS */
   xfrm_address_t saddr;
   struct xfrm_lifetime_cfg lft;
+/* WARNING: DO NOT EDIT, AUTO-GENERATED CODE - SEE TOP FOR INSTRUCTIONS */
   struct xfrm_lifetime_cur curlft;
   struct xfrm_stats stats;
-/* WARNING: DO NOT EDIT, AUTO-GENERATED CODE - SEE TOP FOR INSTRUCTIONS */
   __u32 seq;
   __u32 reqid;
+/* WARNING: DO NOT EDIT, AUTO-GENERATED CODE - SEE TOP FOR INSTRUCTIONS */
   __u16 family;
   __u8 mode;
-/* WARNING: DO NOT EDIT, AUTO-GENERATED CODE - SEE TOP FOR INSTRUCTIONS */
   __u8 replay_window;
   __u8 flags;
+/* WARNING: DO NOT EDIT, AUTO-GENERATED CODE - SEE TOP FOR INSTRUCTIONS */
 #define XFRM_STATE_NOECN 1
 #define XFRM_STATE_DECAP_DSCP 2
-/* WARNING: DO NOT EDIT, AUTO-GENERATED CODE - SEE TOP FOR INSTRUCTIONS */
 #define XFRM_STATE_NOPMTUDISC 4
 #define XFRM_STATE_WILDRECV 8
+/* WARNING: DO NOT EDIT, AUTO-GENERATED CODE - SEE TOP FOR INSTRUCTIONS */
 #define XFRM_STATE_ICMP 16
 #define XFRM_STATE_AF_UNSPEC 32
-/* WARNING: DO NOT EDIT, AUTO-GENERATED CODE - SEE TOP FOR INSTRUCTIONS */
 #define XFRM_STATE_ALIGN4 64
 #define XFRM_STATE_ESN 128
+/* WARNING: DO NOT EDIT, AUTO-GENERATED CODE - SEE TOP FOR INSTRUCTIONS */
 };
 #define XFRM_SA_XFLAG_DONT_ENCAP_DSCP 1
-/* WARNING: DO NOT EDIT, AUTO-GENERATED CODE - SEE TOP FOR INSTRUCTIONS */
 struct xfrm_usersa_id {
   xfrm_address_t daddr;
+/* WARNING: DO NOT EDIT, AUTO-GENERATED CODE - SEE TOP FOR INSTRUCTIONS */
   __be32 spi;
   __u16 family;
-/* WARNING: DO NOT EDIT, AUTO-GENERATED CODE - SEE TOP FOR INSTRUCTIONS */
   __u8 proto;
 };
+/* WARNING: DO NOT EDIT, AUTO-GENERATED CODE - SEE TOP FOR INSTRUCTIONS */
 struct xfrm_aevent_id {
   struct xfrm_usersa_id sa_id;
-/* WARNING: DO NOT EDIT, AUTO-GENERATED CODE - SEE TOP FOR INSTRUCTIONS */
   xfrm_address_t saddr;
   __u32 flags;
+/* WARNING: DO NOT EDIT, AUTO-GENERATED CODE - SEE TOP FOR INSTRUCTIONS */
   __u32 reqid;
 };
-/* WARNING: DO NOT EDIT, AUTO-GENERATED CODE - SEE TOP FOR INSTRUCTIONS */
 struct xfrm_userspi_info {
   struct xfrm_usersa_info info;
+/* WARNING: DO NOT EDIT, AUTO-GENERATED CODE - SEE TOP FOR INSTRUCTIONS */
   __u32 min;
   __u32 max;
-/* WARNING: DO NOT EDIT, AUTO-GENERATED CODE - SEE TOP FOR INSTRUCTIONS */
 };
 struct xfrm_userpolicy_info {
+/* WARNING: DO NOT EDIT, AUTO-GENERATED CODE - SEE TOP FOR INSTRUCTIONS */
   struct xfrm_selector sel;
   struct xfrm_lifetime_cfg lft;
-/* WARNING: DO NOT EDIT, AUTO-GENERATED CODE - SEE TOP FOR INSTRUCTIONS */
   struct xfrm_lifetime_cur curlft;
   __u32 priority;
+/* WARNING: DO NOT EDIT, AUTO-GENERATED CODE - SEE TOP FOR INSTRUCTIONS */
   __u32 index;
   __u8 dir;
-/* WARNING: DO NOT EDIT, AUTO-GENERATED CODE - SEE TOP FOR INSTRUCTIONS */
   __u8 action;
 #define XFRM_POLICY_ALLOW 0
+/* WARNING: DO NOT EDIT, AUTO-GENERATED CODE - SEE TOP FOR INSTRUCTIONS */
 #define XFRM_POLICY_BLOCK 1
   __u8 flags;
-/* WARNING: DO NOT EDIT, AUTO-GENERATED CODE - SEE TOP FOR INSTRUCTIONS */
 #define XFRM_POLICY_LOCALOK 1
 #define XFRM_POLICY_ICMP 2
+/* WARNING: DO NOT EDIT, AUTO-GENERATED CODE - SEE TOP FOR INSTRUCTIONS */
   __u8 share;
 };
-/* WARNING: DO NOT EDIT, AUTO-GENERATED CODE - SEE TOP FOR INSTRUCTIONS */
 struct xfrm_userpolicy_id {
   struct xfrm_selector sel;
+/* WARNING: DO NOT EDIT, AUTO-GENERATED CODE - SEE TOP FOR INSTRUCTIONS */
   __u32 index;
   __u8 dir;
-/* WARNING: DO NOT EDIT, AUTO-GENERATED CODE - SEE TOP FOR INSTRUCTIONS */
 };
 struct xfrm_user_acquire {
+/* WARNING: DO NOT EDIT, AUTO-GENERATED CODE - SEE TOP FOR INSTRUCTIONS */
   struct xfrm_id id;
   xfrm_address_t saddr;
-/* WARNING: DO NOT EDIT, AUTO-GENERATED CODE - SEE TOP FOR INSTRUCTIONS */
   struct xfrm_selector sel;
   struct xfrm_userpolicy_info policy;
+/* WARNING: DO NOT EDIT, AUTO-GENERATED CODE - SEE TOP FOR INSTRUCTIONS */
   __u32 aalgos;
   __u32 ealgos;
-/* WARNING: DO NOT EDIT, AUTO-GENERATED CODE - SEE TOP FOR INSTRUCTIONS */
   __u32 calgos;
   __u32 seq;
+/* WARNING: DO NOT EDIT, AUTO-GENERATED CODE - SEE TOP FOR INSTRUCTIONS */
 };
 struct xfrm_user_expire {
-/* WARNING: DO NOT EDIT, AUTO-GENERATED CODE - SEE TOP FOR INSTRUCTIONS */
   struct xfrm_usersa_info state;
   __u8 hard;
+/* WARNING: DO NOT EDIT, AUTO-GENERATED CODE - SEE TOP FOR INSTRUCTIONS */
 };
 struct xfrm_user_polexpire {
-/* WARNING: DO NOT EDIT, AUTO-GENERATED CODE - SEE TOP FOR INSTRUCTIONS */
   struct xfrm_userpolicy_info pol;
   __u8 hard;
+/* WARNING: DO NOT EDIT, AUTO-GENERATED CODE - SEE TOP FOR INSTRUCTIONS */
 };
 struct xfrm_usersa_flush {
-/* WARNING: DO NOT EDIT, AUTO-GENERATED CODE - SEE TOP FOR INSTRUCTIONS */
   __u8 proto;
 };
+/* WARNING: DO NOT EDIT, AUTO-GENERATED CODE - SEE TOP FOR INSTRUCTIONS */
 struct xfrm_user_report {
   __u8 proto;
-/* WARNING: DO NOT EDIT, AUTO-GENERATED CODE - SEE TOP FOR INSTRUCTIONS */
   struct xfrm_selector sel;
 };
+/* WARNING: DO NOT EDIT, AUTO-GENERATED CODE - SEE TOP FOR INSTRUCTIONS */
 struct xfrm_user_kmaddress {
   xfrm_address_t local;
-/* WARNING: DO NOT EDIT, AUTO-GENERATED CODE - SEE TOP FOR INSTRUCTIONS */
   xfrm_address_t remote;
   __u32 reserved;
+/* WARNING: DO NOT EDIT, AUTO-GENERATED CODE - SEE TOP FOR INSTRUCTIONS */
   __u16 family;
 };
-/* WARNING: DO NOT EDIT, AUTO-GENERATED CODE - SEE TOP FOR INSTRUCTIONS */
 struct xfrm_user_migrate {
   xfrm_address_t old_daddr;
+/* WARNING: DO NOT EDIT, AUTO-GENERATED CODE - SEE TOP FOR INSTRUCTIONS */
   xfrm_address_t old_saddr;
   xfrm_address_t new_daddr;
-/* WARNING: DO NOT EDIT, AUTO-GENERATED CODE - SEE TOP FOR INSTRUCTIONS */
   xfrm_address_t new_saddr;
   __u8 proto;
+/* WARNING: DO NOT EDIT, AUTO-GENERATED CODE - SEE TOP FOR INSTRUCTIONS */
   __u8 mode;
   __u16 reserved;
-/* WARNING: DO NOT EDIT, AUTO-GENERATED CODE - SEE TOP FOR INSTRUCTIONS */
   __u32 reqid;
   __u16 old_family;
+/* WARNING: DO NOT EDIT, AUTO-GENERATED CODE - SEE TOP FOR INSTRUCTIONS */
   __u16 new_family;
 };
-/* WARNING: DO NOT EDIT, AUTO-GENERATED CODE - SEE TOP FOR INSTRUCTIONS */
 struct xfrm_user_mapping {
   struct xfrm_usersa_id id;
+/* WARNING: DO NOT EDIT, AUTO-GENERATED CODE - SEE TOP FOR INSTRUCTIONS */
   __u32 reqid;
   xfrm_address_t old_saddr;
-/* WARNING: DO NOT EDIT, AUTO-GENERATED CODE - SEE TOP FOR INSTRUCTIONS */
   xfrm_address_t new_saddr;
   __be16 old_sport;
+/* WARNING: DO NOT EDIT, AUTO-GENERATED CODE - SEE TOP FOR INSTRUCTIONS */
   __be16 new_sport;
 };
-/* WARNING: DO NOT EDIT, AUTO-GENERATED CODE - SEE TOP FOR INSTRUCTIONS */
 struct xfrm_address_filter {
   xfrm_address_t saddr;
+/* WARNING: DO NOT EDIT, AUTO-GENERATED CODE - SEE TOP FOR INSTRUCTIONS */
   xfrm_address_t daddr;
   __u16 family;
-/* WARNING: DO NOT EDIT, AUTO-GENERATED CODE - SEE TOP FOR INSTRUCTIONS */
   __u8 splen;
   __u8 dplen;
+/* WARNING: DO NOT EDIT, AUTO-GENERATED CODE - SEE TOP FOR INSTRUCTIONS */
 };
 #define XFRMGRP_ACQUIRE 1
-/* WARNING: DO NOT EDIT, AUTO-GENERATED CODE - SEE TOP FOR INSTRUCTIONS */
 #define XFRMGRP_EXPIRE 2
 #define XFRMGRP_SA 4
+/* WARNING: DO NOT EDIT, AUTO-GENERATED CODE - SEE TOP FOR INSTRUCTIONS */
 #define XFRMGRP_POLICY 8
 #define XFRMGRP_REPORT 0x20
-/* WARNING: DO NOT EDIT, AUTO-GENERATED CODE - SEE TOP FOR INSTRUCTIONS */
 enum xfrm_nlgroups {
   XFRMNLGRP_NONE,
+/* WARNING: DO NOT EDIT, AUTO-GENERATED CODE - SEE TOP FOR INSTRUCTIONS */
 #define XFRMNLGRP_NONE XFRMNLGRP_NONE
   XFRMNLGRP_ACQUIRE,
-/* WARNING: DO NOT EDIT, AUTO-GENERATED CODE - SEE TOP FOR INSTRUCTIONS */
 #define XFRMNLGRP_ACQUIRE XFRMNLGRP_ACQUIRE
   XFRMNLGRP_EXPIRE,
+/* WARNING: DO NOT EDIT, AUTO-GENERATED CODE - SEE TOP FOR INSTRUCTIONS */
 #define XFRMNLGRP_EXPIRE XFRMNLGRP_EXPIRE
   XFRMNLGRP_SA,
-/* WARNING: DO NOT EDIT, AUTO-GENERATED CODE - SEE TOP FOR INSTRUCTIONS */
 #define XFRMNLGRP_SA XFRMNLGRP_SA
   XFRMNLGRP_POLICY,
+/* WARNING: DO NOT EDIT, AUTO-GENERATED CODE - SEE TOP FOR INSTRUCTIONS */
 #define XFRMNLGRP_POLICY XFRMNLGRP_POLICY
   XFRMNLGRP_AEVENTS,
-/* WARNING: DO NOT EDIT, AUTO-GENERATED CODE - SEE TOP FOR INSTRUCTIONS */
 #define XFRMNLGRP_AEVENTS XFRMNLGRP_AEVENTS
   XFRMNLGRP_REPORT,
+/* WARNING: DO NOT EDIT, AUTO-GENERATED CODE - SEE TOP FOR INSTRUCTIONS */
 #define XFRMNLGRP_REPORT XFRMNLGRP_REPORT
   XFRMNLGRP_MIGRATE,
-/* WARNING: DO NOT EDIT, AUTO-GENERATED CODE - SEE TOP FOR INSTRUCTIONS */
 #define XFRMNLGRP_MIGRATE XFRMNLGRP_MIGRATE
   XFRMNLGRP_MAPPING,
+/* WARNING: DO NOT EDIT, AUTO-GENERATED CODE - SEE TOP FOR INSTRUCTIONS */
 #define XFRMNLGRP_MAPPING XFRMNLGRP_MAPPING
   __XFRMNLGRP_MAX
-/* WARNING: DO NOT EDIT, AUTO-GENERATED CODE - SEE TOP FOR INSTRUCTIONS */
 };
 #define XFRMNLGRP_MAX (__XFRMNLGRP_MAX - 1)
+/* WARNING: DO NOT EDIT, AUTO-GENERATED CODE - SEE TOP FOR INSTRUCTIONS */
 #endif
diff --git a/libc/kernel/uapi/linux/xilinx-v4l2-controls.h b/libc/kernel/uapi/linux/xilinx-v4l2-controls.h
new file mode 100644
index 0000000..3a7fdbb
--- /dev/null
+++ b/libc/kernel/uapi/linux/xilinx-v4l2-controls.h
@@ -0,0 +1,48 @@
+/****************************************************************************
+ ****************************************************************************
+ ***
+ ***   This header was automatically generated from a Linux kernel header
+ ***   of the same name, to make information necessary for userspace to
+ ***   call into the kernel available to libc.  It contains only constants,
+ ***   structures, and macros generated from the original header, and thus,
+ ***   contains no copyrightable information.
+ ***
+ ***   To edit the content of this header, modify the corresponding
+ ***   source file (e.g. under external/kernel-headers/original/) then
+ ***   run bionic/libc/kernel/tools/update_all.py
+ ***
+ ***   Any manual change here will be lost the next time this script will
+ ***   be run. You've been warned!
+ ***
+ ****************************************************************************
+ ****************************************************************************/
+#ifndef __UAPI_XILINX_V4L2_CONTROLS_H__
+#define __UAPI_XILINX_V4L2_CONTROLS_H__
+#include <linux/v4l2-controls.h>
+#define V4L2_CID_XILINX_OFFSET 0xc000
+/* WARNING: DO NOT EDIT, AUTO-GENERATED CODE - SEE TOP FOR INSTRUCTIONS */
+#define V4L2_CID_XILINX_BASE (V4L2_CID_USER_BASE + V4L2_CID_XILINX_OFFSET)
+#define V4L2_CID_XILINX_TPG (V4L2_CID_USER_BASE + 0xc000)
+#define V4L2_CID_XILINX_TPG_CROSS_HAIRS (V4L2_CID_XILINX_TPG + 1)
+#define V4L2_CID_XILINX_TPG_MOVING_BOX (V4L2_CID_XILINX_TPG + 2)
+/* WARNING: DO NOT EDIT, AUTO-GENERATED CODE - SEE TOP FOR INSTRUCTIONS */
+#define V4L2_CID_XILINX_TPG_COLOR_MASK (V4L2_CID_XILINX_TPG + 3)
+#define V4L2_CID_XILINX_TPG_STUCK_PIXEL (V4L2_CID_XILINX_TPG + 4)
+#define V4L2_CID_XILINX_TPG_NOISE (V4L2_CID_XILINX_TPG + 5)
+#define V4L2_CID_XILINX_TPG_MOTION (V4L2_CID_XILINX_TPG + 6)
+/* WARNING: DO NOT EDIT, AUTO-GENERATED CODE - SEE TOP FOR INSTRUCTIONS */
+#define V4L2_CID_XILINX_TPG_MOTION_SPEED (V4L2_CID_XILINX_TPG + 7)
+#define V4L2_CID_XILINX_TPG_CROSS_HAIR_ROW (V4L2_CID_XILINX_TPG + 8)
+#define V4L2_CID_XILINX_TPG_CROSS_HAIR_COLUMN (V4L2_CID_XILINX_TPG + 9)
+#define V4L2_CID_XILINX_TPG_ZPLATE_HOR_START (V4L2_CID_XILINX_TPG + 10)
+/* WARNING: DO NOT EDIT, AUTO-GENERATED CODE - SEE TOP FOR INSTRUCTIONS */
+#define V4L2_CID_XILINX_TPG_ZPLATE_HOR_SPEED (V4L2_CID_XILINX_TPG + 11)
+#define V4L2_CID_XILINX_TPG_ZPLATE_VER_START (V4L2_CID_XILINX_TPG + 12)
+#define V4L2_CID_XILINX_TPG_ZPLATE_VER_SPEED (V4L2_CID_XILINX_TPG + 13)
+#define V4L2_CID_XILINX_TPG_BOX_SIZE (V4L2_CID_XILINX_TPG + 14)
+/* WARNING: DO NOT EDIT, AUTO-GENERATED CODE - SEE TOP FOR INSTRUCTIONS */
+#define V4L2_CID_XILINX_TPG_BOX_COLOR (V4L2_CID_XILINX_TPG + 15)
+#define V4L2_CID_XILINX_TPG_STUCK_PIXEL_THRESH (V4L2_CID_XILINX_TPG + 16)
+#define V4L2_CID_XILINX_TPG_NOISE_GAIN (V4L2_CID_XILINX_TPG + 17)
+#endif
+/* WARNING: DO NOT EDIT, AUTO-GENERATED CODE - SEE TOP FOR INSTRUCTIONS */
diff --git a/libc/kernel/uapi/misc/cxl.h b/libc/kernel/uapi/misc/cxl.h
index 150a0d9..e13a55b 100644
--- a/libc/kernel/uapi/misc/cxl.h
+++ b/libc/kernel/uapi/misc/cxl.h
@@ -38,59 +38,81 @@
 /* WARNING: DO NOT EDIT, AUTO-GENERATED CODE - SEE TOP FOR INSTRUCTIONS */
 #define CXL_START_WORK_AMR 0x0000000000000001ULL
 #define CXL_START_WORK_NUM_IRQS 0x0000000000000002ULL
-#define CXL_START_WORK_ALL (CXL_START_WORK_AMR | CXL_START_WORK_NUM_IRQS)
+#define CXL_START_WORK_ERR_FF 0x0000000000000004ULL
+#define CXL_START_WORK_ALL (CXL_START_WORK_AMR | CXL_START_WORK_NUM_IRQS | CXL_START_WORK_ERR_FF)
+/* WARNING: DO NOT EDIT, AUTO-GENERATED CODE - SEE TOP FOR INSTRUCTIONS */
+#define CXL_MODE_DEDICATED 0x1
+#define CXL_MODE_DIRECTED 0x2
+#define CXL_AFUID_FLAG_SLAVE 0x1
+struct cxl_afu_id {
+/* WARNING: DO NOT EDIT, AUTO-GENERATED CODE - SEE TOP FOR INSTRUCTIONS */
+  __u64 flags;
+  __u32 card_id;
+  __u32 afu_offset;
+  __u32 afu_mode;
+/* WARNING: DO NOT EDIT, AUTO-GENERATED CODE - SEE TOP FOR INSTRUCTIONS */
+  __u32 reserved1;
+  __u64 reserved2;
+  __u64 reserved3;
+  __u64 reserved4;
+/* WARNING: DO NOT EDIT, AUTO-GENERATED CODE - SEE TOP FOR INSTRUCTIONS */
+  __u64 reserved5;
+  __u64 reserved6;
+};
 #define CXL_MAGIC 0xCA
 /* WARNING: DO NOT EDIT, AUTO-GENERATED CODE - SEE TOP FOR INSTRUCTIONS */
 #define CXL_IOCTL_START_WORK _IOW(CXL_MAGIC, 0x00, struct cxl_ioctl_start_work)
 #define CXL_IOCTL_GET_PROCESS_ELEMENT _IOR(CXL_MAGIC, 0x01, __u32)
+#define CXL_IOCTL_GET_AFU_ID _IOR(CXL_MAGIC, 0x02, struct cxl_afu_id)
 #define CXL_READ_MIN_SIZE 0x1000
-enum cxl_event_type {
 /* WARNING: DO NOT EDIT, AUTO-GENERATED CODE - SEE TOP FOR INSTRUCTIONS */
+enum cxl_event_type {
   CXL_EVENT_RESERVED = 0,
   CXL_EVENT_AFU_INTERRUPT = 1,
   CXL_EVENT_DATA_STORAGE = 2,
-  CXL_EVENT_AFU_ERROR = 3,
 /* WARNING: DO NOT EDIT, AUTO-GENERATED CODE - SEE TOP FOR INSTRUCTIONS */
+  CXL_EVENT_AFU_ERROR = 3,
 };
 struct cxl_event_header {
   __u16 type;
-  __u16 size;
 /* WARNING: DO NOT EDIT, AUTO-GENERATED CODE - SEE TOP FOR INSTRUCTIONS */
+  __u16 size;
   __u16 process_element;
   __u16 reserved1;
 };
-struct cxl_event_afu_interrupt {
 /* WARNING: DO NOT EDIT, AUTO-GENERATED CODE - SEE TOP FOR INSTRUCTIONS */
+struct cxl_event_afu_interrupt {
   __u16 flags;
   __u16 irq;
   __u32 reserved1;
-};
 /* WARNING: DO NOT EDIT, AUTO-GENERATED CODE - SEE TOP FOR INSTRUCTIONS */
+};
 struct cxl_event_data_storage {
   __u16 flags;
   __u16 reserved1;
-  __u32 reserved2;
 /* WARNING: DO NOT EDIT, AUTO-GENERATED CODE - SEE TOP FOR INSTRUCTIONS */
+  __u32 reserved2;
   __u64 addr;
   __u64 dsisr;
   __u64 reserved3;
-};
 /* WARNING: DO NOT EDIT, AUTO-GENERATED CODE - SEE TOP FOR INSTRUCTIONS */
+};
 struct cxl_event_afu_error {
   __u16 flags;
   __u16 reserved1;
-  __u32 reserved2;
 /* WARNING: DO NOT EDIT, AUTO-GENERATED CODE - SEE TOP FOR INSTRUCTIONS */
+  __u32 reserved2;
   __u64 error;
 };
 struct cxl_event {
-  struct cxl_event_header header;
 /* WARNING: DO NOT EDIT, AUTO-GENERATED CODE - SEE TOP FOR INSTRUCTIONS */
+  struct cxl_event_header header;
   union {
     struct cxl_event_afu_interrupt irq;
     struct cxl_event_data_storage fault;
-    struct cxl_event_afu_error afu_error;
 /* WARNING: DO NOT EDIT, AUTO-GENERATED CODE - SEE TOP FOR INSTRUCTIONS */
+    struct cxl_event_afu_error afu_error;
   };
 };
 #endif
+/* WARNING: DO NOT EDIT, AUTO-GENERATED CODE - SEE TOP FOR INSTRUCTIONS */
diff --git a/libc/kernel/uapi/mtd/mtd-user.h b/libc/kernel/uapi/mtd/mtd-user.h
index 83a8635..b78a46e 100644
--- a/libc/kernel/uapi/mtd/mtd-user.h
+++ b/libc/kernel/uapi/mtd/mtd-user.h
@@ -18,13 +18,12 @@
  ****************************************************************************/
 #ifndef __MTD_USER_H__
 #define __MTD_USER_H__
-#include <stdint.h>
 #include <mtd/mtd-abi.h>
-/* WARNING: DO NOT EDIT, AUTO-GENERATED CODE - SEE TOP FOR INSTRUCTIONS */
 typedef struct mtd_info_user mtd_info_t;
+/* WARNING: DO NOT EDIT, AUTO-GENERATED CODE - SEE TOP FOR INSTRUCTIONS */
 typedef struct erase_info_user erase_info_t;
 typedef struct region_info_user region_info_t;
 typedef struct nand_oobinfo nand_oobinfo_t;
-/* WARNING: DO NOT EDIT, AUTO-GENERATED CODE - SEE TOP FOR INSTRUCTIONS */
 typedef struct nand_ecclayout_user nand_ecclayout_t;
+/* WARNING: DO NOT EDIT, AUTO-GENERATED CODE - SEE TOP FOR INSTRUCTIONS */
 #endif
diff --git a/libc/kernel/uapi/rdma/hfi/hfi1_user.h b/libc/kernel/uapi/rdma/hfi/hfi1_user.h
new file mode 100644
index 0000000..a0079b5
--- /dev/null
+++ b/libc/kernel/uapi/rdma/hfi/hfi1_user.h
@@ -0,0 +1,239 @@
+/****************************************************************************
+ ****************************************************************************
+ ***
+ ***   This header was automatically generated from a Linux kernel header
+ ***   of the same name, to make information necessary for userspace to
+ ***   call into the kernel available to libc.  It contains only constants,
+ ***   structures, and macros generated from the original header, and thus,
+ ***   contains no copyrightable information.
+ ***
+ ***   To edit the content of this header, modify the corresponding
+ ***   source file (e.g. under external/kernel-headers/original/) then
+ ***   run bionic/libc/kernel/tools/update_all.py
+ ***
+ ***   Any manual change here will be lost the next time this script will
+ ***   be run. You've been warned!
+ ***
+ ****************************************************************************
+ ****************************************************************************/
+#ifndef _LINUX__HFI1_USER_H
+#define _LINUX__HFI1_USER_H
+#include <linux/types.h>
+#define HFI1_USER_SWMAJOR 4
+/* WARNING: DO NOT EDIT, AUTO-GENERATED CODE - SEE TOP FOR INSTRUCTIONS */
+#define HFI1_USER_SWMINOR 0
+#define HFI1_CAP_DMA_RTAIL (1UL << 0)
+#define HFI1_CAP_SDMA (1UL << 1)
+#define HFI1_CAP_SDMA_AHG (1UL << 2)
+/* WARNING: DO NOT EDIT, AUTO-GENERATED CODE - SEE TOP FOR INSTRUCTIONS */
+#define HFI1_CAP_EXTENDED_PSN (1UL << 3)
+#define HFI1_CAP_HDRSUPP (1UL << 4)
+#define HFI1_CAP_USE_SDMA_HEAD (1UL << 6)
+#define HFI1_CAP_MULTI_PKT_EGR (1UL << 7)
+/* WARNING: DO NOT EDIT, AUTO-GENERATED CODE - SEE TOP FOR INSTRUCTIONS */
+#define HFI1_CAP_NODROP_RHQ_FULL (1UL << 8)
+#define HFI1_CAP_NODROP_EGR_FULL (1UL << 9)
+#define HFI1_CAP_TID_UNMAP (1UL << 10)
+#define HFI1_CAP_PRINT_UNIMPL (1UL << 11)
+/* WARNING: DO NOT EDIT, AUTO-GENERATED CODE - SEE TOP FOR INSTRUCTIONS */
+#define HFI1_CAP_ALLOW_PERM_JKEY (1UL << 12)
+#define HFI1_CAP_NO_INTEGRITY (1UL << 13)
+#define HFI1_CAP_PKEY_CHECK (1UL << 14)
+#define HFI1_CAP_STATIC_RATE_CTRL (1UL << 15)
+/* WARNING: DO NOT EDIT, AUTO-GENERATED CODE - SEE TOP FOR INSTRUCTIONS */
+#define HFI1_CAP_SDMA_HEAD_CHECK (1UL << 17)
+#define HFI1_CAP_EARLY_CREDIT_RETURN (1UL << 18)
+#define HFI1_RCVHDR_ENTSIZE_2 (1UL << 0)
+#define HFI1_RCVHDR_ENTSIZE_16 (1UL << 1)
+/* WARNING: DO NOT EDIT, AUTO-GENERATED CODE - SEE TOP FOR INSTRUCTIONS */
+#define HFI1_RCVDHR_ENTSIZE_32 (1UL << 2)
+#define HFI1_ALG_ACROSS 0
+#define HFI1_ALG_WITHIN 1
+#define HFI1_ALG_COUNT 2
+/* WARNING: DO NOT EDIT, AUTO-GENERATED CODE - SEE TOP FOR INSTRUCTIONS */
+#define HFI1_CMD_ASSIGN_CTXT 1
+#define HFI1_CMD_CTXT_INFO 2
+#define HFI1_CMD_USER_INFO 3
+#define HFI1_CMD_TID_UPDATE 4
+/* WARNING: DO NOT EDIT, AUTO-GENERATED CODE - SEE TOP FOR INSTRUCTIONS */
+#define HFI1_CMD_TID_FREE 5
+#define HFI1_CMD_CREDIT_UPD 6
+#define HFI1_CMD_SDMA_STATUS_UPD 7
+#define HFI1_CMD_RECV_CTRL 8
+/* WARNING: DO NOT EDIT, AUTO-GENERATED CODE - SEE TOP FOR INSTRUCTIONS */
+#define HFI1_CMD_POLL_TYPE 9
+#define HFI1_CMD_ACK_EVENT 10
+#define HFI1_CMD_SET_PKEY 11
+#define HFI1_CMD_CTXT_RESET 12
+/* WARNING: DO NOT EDIT, AUTO-GENERATED CODE - SEE TOP FOR INSTRUCTIONS */
+#define HFI1_CMD_EP_INFO 64
+#define HFI1_CMD_EP_ERASE_CHIP 65
+#define HFI1_CMD_EP_ERASE_P0 66
+#define HFI1_CMD_EP_ERASE_P1 67
+/* WARNING: DO NOT EDIT, AUTO-GENERATED CODE - SEE TOP FOR INSTRUCTIONS */
+#define HFI1_CMD_EP_READ_P0 68
+#define HFI1_CMD_EP_READ_P1 69
+#define HFI1_CMD_EP_WRITE_P0 70
+#define HFI1_CMD_EP_WRITE_P1 71
+/* WARNING: DO NOT EDIT, AUTO-GENERATED CODE - SEE TOP FOR INSTRUCTIONS */
+#define _HFI1_EVENT_FROZEN_BIT 0
+#define _HFI1_EVENT_LINKDOWN_BIT 1
+#define _HFI1_EVENT_LID_CHANGE_BIT 2
+#define _HFI1_EVENT_LMC_CHANGE_BIT 3
+/* WARNING: DO NOT EDIT, AUTO-GENERATED CODE - SEE TOP FOR INSTRUCTIONS */
+#define _HFI1_EVENT_SL2VL_CHANGE_BIT 4
+#define _HFI1_MAX_EVENT_BIT _HFI1_EVENT_SL2VL_CHANGE_BIT
+#define HFI1_EVENT_FROZEN (1UL << _HFI1_EVENT_FROZEN_BIT)
+#define HFI1_EVENT_LINKDOWN_BIT (1UL << _HFI1_EVENT_LINKDOWN_BIT)
+/* WARNING: DO NOT EDIT, AUTO-GENERATED CODE - SEE TOP FOR INSTRUCTIONS */
+#define HFI1_EVENT_LID_CHANGE_BIT (1UL << _HFI1_EVENT_LID_CHANGE_BIT)
+#define HFI1_EVENT_LMC_CHANGE_BIT (1UL << _HFI1_EVENT_LMC_CHANGE_BIT)
+#define HFI1_EVENT_SL2VL_CHANGE_BIT (1UL << _HFI1_EVENT_SL2VL_CHANGE_BIT)
+#define HFI1_STATUS_INITTED 0x1
+/* WARNING: DO NOT EDIT, AUTO-GENERATED CODE - SEE TOP FOR INSTRUCTIONS */
+#define HFI1_STATUS_CHIP_PRESENT 0x20
+#define HFI1_STATUS_IB_READY 0x40
+#define HFI1_STATUS_IB_CONF 0x80
+#define HFI1_STATUS_HWERROR 0x200
+/* WARNING: DO NOT EDIT, AUTO-GENERATED CODE - SEE TOP FOR INSTRUCTIONS */
+#define HFI1_MAX_SHARED_CTXTS 8
+#define HFI1_POLL_TYPE_ANYRCV 0x0
+#define HFI1_POLL_TYPE_URGENT 0x1
+struct hfi1_user_info {
+/* WARNING: DO NOT EDIT, AUTO-GENERATED CODE - SEE TOP FOR INSTRUCTIONS */
+  __u32 userversion;
+  __u16 pad;
+  __u16 hfi1_alg;
+  __u16 subctxt_cnt;
+/* WARNING: DO NOT EDIT, AUTO-GENERATED CODE - SEE TOP FOR INSTRUCTIONS */
+  __u16 subctxt_id;
+  __u8 uuid[16];
+};
+struct hfi1_ctxt_info {
+/* WARNING: DO NOT EDIT, AUTO-GENERATED CODE - SEE TOP FOR INSTRUCTIONS */
+  __u64 runtime_flags;
+  __u32 rcvegr_size;
+  __u16 num_active;
+  __u16 unit;
+/* WARNING: DO NOT EDIT, AUTO-GENERATED CODE - SEE TOP FOR INSTRUCTIONS */
+  __u16 ctxt;
+  __u16 subctxt;
+  __u16 rcvtids;
+  __u16 credits;
+/* WARNING: DO NOT EDIT, AUTO-GENERATED CODE - SEE TOP FOR INSTRUCTIONS */
+  __u16 numa_node;
+  __u16 rec_cpu;
+  __u16 send_ctxt;
+  __u16 egrtids;
+/* WARNING: DO NOT EDIT, AUTO-GENERATED CODE - SEE TOP FOR INSTRUCTIONS */
+  __u16 rcvhdrq_cnt;
+  __u16 rcvhdrq_entsize;
+  __u16 sdma_ring_size;
+};
+/* WARNING: DO NOT EDIT, AUTO-GENERATED CODE - SEE TOP FOR INSTRUCTIONS */
+struct hfi1_tid_info {
+  __u64 vaddr;
+  __u64 tidlist;
+  __u32 tidcnt;
+/* WARNING: DO NOT EDIT, AUTO-GENERATED CODE - SEE TOP FOR INSTRUCTIONS */
+  __u32 length;
+  __u64 tidmap;
+};
+struct hfi1_cmd {
+/* WARNING: DO NOT EDIT, AUTO-GENERATED CODE - SEE TOP FOR INSTRUCTIONS */
+  __u32 type;
+  __u32 len;
+  __u64 addr;
+};
+/* WARNING: DO NOT EDIT, AUTO-GENERATED CODE - SEE TOP FOR INSTRUCTIONS */
+enum hfi1_sdma_comp_state {
+  FREE = 0,
+  QUEUED,
+  COMPLETE,
+/* WARNING: DO NOT EDIT, AUTO-GENERATED CODE - SEE TOP FOR INSTRUCTIONS */
+  ERROR
+};
+struct hfi1_sdma_comp_entry {
+  __u32 status;
+/* WARNING: DO NOT EDIT, AUTO-GENERATED CODE - SEE TOP FOR INSTRUCTIONS */
+  __u32 errcode;
+};
+struct hfi1_status {
+  __u64 dev;
+/* WARNING: DO NOT EDIT, AUTO-GENERATED CODE - SEE TOP FOR INSTRUCTIONS */
+  __u64 port;
+  char freezemsg[0];
+};
+struct hfi1_base_info {
+/* WARNING: DO NOT EDIT, AUTO-GENERATED CODE - SEE TOP FOR INSTRUCTIONS */
+  __u32 hw_version;
+  __u32 sw_version;
+  __u16 jkey;
+  __u16 padding1;
+/* WARNING: DO NOT EDIT, AUTO-GENERATED CODE - SEE TOP FOR INSTRUCTIONS */
+  __u32 bthqp;
+  __u64 sc_credits_addr;
+  __u64 pio_bufbase_sop;
+  __u64 pio_bufbase;
+/* WARNING: DO NOT EDIT, AUTO-GENERATED CODE - SEE TOP FOR INSTRUCTIONS */
+  __u64 rcvhdr_bufbase;
+  __u64 rcvegr_bufbase;
+  __u64 sdma_comp_bufbase;
+  __u64 user_regbase;
+/* WARNING: DO NOT EDIT, AUTO-GENERATED CODE - SEE TOP FOR INSTRUCTIONS */
+  __u64 events_bufbase;
+  __u64 status_bufbase;
+  __u64 rcvhdrtail_base;
+  __u64 subctxt_uregbase;
+/* WARNING: DO NOT EDIT, AUTO-GENERATED CODE - SEE TOP FOR INSTRUCTIONS */
+  __u64 subctxt_rcvegrbuf;
+  __u64 subctxt_rcvhdrbuf;
+};
+enum sdma_req_opcode {
+/* WARNING: DO NOT EDIT, AUTO-GENERATED CODE - SEE TOP FOR INSTRUCTIONS */
+  EXPECTED = 0,
+  EAGER
+};
+#define HFI1_SDMA_REQ_VERSION_MASK 0xF
+/* WARNING: DO NOT EDIT, AUTO-GENERATED CODE - SEE TOP FOR INSTRUCTIONS */
+#define HFI1_SDMA_REQ_VERSION_SHIFT 0x0
+#define HFI1_SDMA_REQ_OPCODE_MASK 0xF
+#define HFI1_SDMA_REQ_OPCODE_SHIFT 0x4
+#define HFI1_SDMA_REQ_IOVCNT_MASK 0xFF
+/* WARNING: DO NOT EDIT, AUTO-GENERATED CODE - SEE TOP FOR INSTRUCTIONS */
+#define HFI1_SDMA_REQ_IOVCNT_SHIFT 0x8
+struct sdma_req_info {
+  __u16 ctrl;
+  __u16 npkts;
+/* WARNING: DO NOT EDIT, AUTO-GENERATED CODE - SEE TOP FOR INSTRUCTIONS */
+  __u16 fragsize;
+  __u16 comp_idx;
+} __packed;
+struct hfi1_kdeth_header {
+/* WARNING: DO NOT EDIT, AUTO-GENERATED CODE - SEE TOP FOR INSTRUCTIONS */
+  __le32 ver_tid_offset;
+  __le16 jkey;
+  __le16 hcrc;
+  __le32 swdata[7];
+/* WARNING: DO NOT EDIT, AUTO-GENERATED CODE - SEE TOP FOR INSTRUCTIONS */
+} __packed;
+struct hfi1_pkt_header {
+  __le16 pbc[4];
+  __be16 lrh[4];
+/* WARNING: DO NOT EDIT, AUTO-GENERATED CODE - SEE TOP FOR INSTRUCTIONS */
+  __be32 bth[3];
+  struct hfi1_kdeth_header kdeth;
+} __packed;
+enum hfi1_ureg {
+/* WARNING: DO NOT EDIT, AUTO-GENERATED CODE - SEE TOP FOR INSTRUCTIONS */
+  ur_rcvhdrtail = 0,
+  ur_rcvhdrhead = 1,
+  ur_rcvegrindextail = 2,
+  ur_rcvegrindexhead = 3,
+/* WARNING: DO NOT EDIT, AUTO-GENERATED CODE - SEE TOP FOR INSTRUCTIONS */
+  ur_rcvegroffsettail = 4,
+  ur_maxreg,
+  ur_rcvtidflowtable = 256
+};
+/* WARNING: DO NOT EDIT, AUTO-GENERATED CODE - SEE TOP FOR INSTRUCTIONS */
+#endif
diff --git a/libc/kernel/uapi/rdma/ib_user_verbs.h b/libc/kernel/uapi/rdma/ib_user_verbs.h
index 9c23ac2..a3ed5db 100644
--- a/libc/kernel/uapi/rdma/ib_user_verbs.h
+++ b/libc/kernel/uapi/rdma/ib_user_verbs.h
@@ -77,106 +77,136 @@
 };
 /* WARNING: DO NOT EDIT, AUTO-GENERATED CODE - SEE TOP FOR INSTRUCTIONS */
 enum {
-  IB_USER_VERBS_EX_CMD_CREATE_FLOW = IB_USER_VERBS_CMD_THRESHOLD,
-  IB_USER_VERBS_EX_CMD_DESTROY_FLOW
-};
+  IB_USER_VERBS_EX_CMD_QUERY_DEVICE = IB_USER_VERBS_CMD_QUERY_DEVICE,
+  IB_USER_VERBS_EX_CMD_CREATE_CQ = IB_USER_VERBS_CMD_CREATE_CQ,
+  IB_USER_VERBS_EX_CMD_CREATE_QP = IB_USER_VERBS_CMD_CREATE_QP,
 /* WARNING: DO NOT EDIT, AUTO-GENERATED CODE - SEE TOP FOR INSTRUCTIONS */
+  IB_USER_VERBS_EX_CMD_CREATE_FLOW = IB_USER_VERBS_CMD_THRESHOLD,
+  IB_USER_VERBS_EX_CMD_DESTROY_FLOW,
+};
 struct ib_uverbs_async_event_desc {
+/* WARNING: DO NOT EDIT, AUTO-GENERATED CODE - SEE TOP FOR INSTRUCTIONS */
   __u64 element;
   __u32 event_type;
   __u32 reserved;
-/* WARNING: DO NOT EDIT, AUTO-GENERATED CODE - SEE TOP FOR INSTRUCTIONS */
 };
+/* WARNING: DO NOT EDIT, AUTO-GENERATED CODE - SEE TOP FOR INSTRUCTIONS */
 struct ib_uverbs_comp_event_desc {
   __u64 cq_handle;
 };
-/* WARNING: DO NOT EDIT, AUTO-GENERATED CODE - SEE TOP FOR INSTRUCTIONS */
 #define IB_USER_VERBS_CMD_COMMAND_MASK 0xff
+/* WARNING: DO NOT EDIT, AUTO-GENERATED CODE - SEE TOP FOR INSTRUCTIONS */
 #define IB_USER_VERBS_CMD_FLAGS_MASK 0xff000000u
 #define IB_USER_VERBS_CMD_FLAGS_SHIFT 24
 #define IB_USER_VERBS_CMD_FLAG_EXTENDED 0x80
-/* WARNING: DO NOT EDIT, AUTO-GENERATED CODE - SEE TOP FOR INSTRUCTIONS */
 struct ib_uverbs_cmd_hdr {
+/* WARNING: DO NOT EDIT, AUTO-GENERATED CODE - SEE TOP FOR INSTRUCTIONS */
   __u32 command;
   __u16 in_words;
   __u16 out_words;
-/* WARNING: DO NOT EDIT, AUTO-GENERATED CODE - SEE TOP FOR INSTRUCTIONS */
 };
+/* WARNING: DO NOT EDIT, AUTO-GENERATED CODE - SEE TOP FOR INSTRUCTIONS */
 struct ib_uverbs_ex_cmd_hdr {
   __u64 response;
   __u16 provider_in_words;
-/* WARNING: DO NOT EDIT, AUTO-GENERATED CODE - SEE TOP FOR INSTRUCTIONS */
   __u16 provider_out_words;
+/* WARNING: DO NOT EDIT, AUTO-GENERATED CODE - SEE TOP FOR INSTRUCTIONS */
   __u32 cmd_hdr_reserved;
 };
 struct ib_uverbs_get_context {
-/* WARNING: DO NOT EDIT, AUTO-GENERATED CODE - SEE TOP FOR INSTRUCTIONS */
   __u64 response;
+/* WARNING: DO NOT EDIT, AUTO-GENERATED CODE - SEE TOP FOR INSTRUCTIONS */
   __u64 driver_data[0];
 };
 struct ib_uverbs_get_context_resp {
-/* WARNING: DO NOT EDIT, AUTO-GENERATED CODE - SEE TOP FOR INSTRUCTIONS */
   __u32 async_fd;
+/* WARNING: DO NOT EDIT, AUTO-GENERATED CODE - SEE TOP FOR INSTRUCTIONS */
   __u32 num_comp_vectors;
 };
 struct ib_uverbs_query_device {
-/* WARNING: DO NOT EDIT, AUTO-GENERATED CODE - SEE TOP FOR INSTRUCTIONS */
   __u64 response;
+/* WARNING: DO NOT EDIT, AUTO-GENERATED CODE - SEE TOP FOR INSTRUCTIONS */
   __u64 driver_data[0];
 };
 struct ib_uverbs_query_device_resp {
-/* WARNING: DO NOT EDIT, AUTO-GENERATED CODE - SEE TOP FOR INSTRUCTIONS */
   __u64 fw_ver;
+/* WARNING: DO NOT EDIT, AUTO-GENERATED CODE - SEE TOP FOR INSTRUCTIONS */
   __be64 node_guid;
   __be64 sys_image_guid;
   __u64 max_mr_size;
-/* WARNING: DO NOT EDIT, AUTO-GENERATED CODE - SEE TOP FOR INSTRUCTIONS */
   __u64 page_size_cap;
+/* WARNING: DO NOT EDIT, AUTO-GENERATED CODE - SEE TOP FOR INSTRUCTIONS */
   __u32 vendor_id;
   __u32 vendor_part_id;
   __u32 hw_ver;
-/* WARNING: DO NOT EDIT, AUTO-GENERATED CODE - SEE TOP FOR INSTRUCTIONS */
   __u32 max_qp;
+/* WARNING: DO NOT EDIT, AUTO-GENERATED CODE - SEE TOP FOR INSTRUCTIONS */
   __u32 max_qp_wr;
   __u32 device_cap_flags;
   __u32 max_sge;
-/* WARNING: DO NOT EDIT, AUTO-GENERATED CODE - SEE TOP FOR INSTRUCTIONS */
   __u32 max_sge_rd;
+/* WARNING: DO NOT EDIT, AUTO-GENERATED CODE - SEE TOP FOR INSTRUCTIONS */
   __u32 max_cq;
   __u32 max_cqe;
   __u32 max_mr;
-/* WARNING: DO NOT EDIT, AUTO-GENERATED CODE - SEE TOP FOR INSTRUCTIONS */
   __u32 max_pd;
+/* WARNING: DO NOT EDIT, AUTO-GENERATED CODE - SEE TOP FOR INSTRUCTIONS */
   __u32 max_qp_rd_atom;
   __u32 max_ee_rd_atom;
   __u32 max_res_rd_atom;
-/* WARNING: DO NOT EDIT, AUTO-GENERATED CODE - SEE TOP FOR INSTRUCTIONS */
   __u32 max_qp_init_rd_atom;
+/* WARNING: DO NOT EDIT, AUTO-GENERATED CODE - SEE TOP FOR INSTRUCTIONS */
   __u32 max_ee_init_rd_atom;
   __u32 atomic_cap;
   __u32 max_ee;
-/* WARNING: DO NOT EDIT, AUTO-GENERATED CODE - SEE TOP FOR INSTRUCTIONS */
   __u32 max_rdd;
+/* WARNING: DO NOT EDIT, AUTO-GENERATED CODE - SEE TOP FOR INSTRUCTIONS */
   __u32 max_mw;
   __u32 max_raw_ipv6_qp;
   __u32 max_raw_ethy_qp;
-/* WARNING: DO NOT EDIT, AUTO-GENERATED CODE - SEE TOP FOR INSTRUCTIONS */
   __u32 max_mcast_grp;
+/* WARNING: DO NOT EDIT, AUTO-GENERATED CODE - SEE TOP FOR INSTRUCTIONS */
   __u32 max_mcast_qp_attach;
   __u32 max_total_mcast_qp_attach;
   __u32 max_ah;
-/* WARNING: DO NOT EDIT, AUTO-GENERATED CODE - SEE TOP FOR INSTRUCTIONS */
   __u32 max_fmr;
+/* WARNING: DO NOT EDIT, AUTO-GENERATED CODE - SEE TOP FOR INSTRUCTIONS */
   __u32 max_map_per_fmr;
   __u32 max_srq;
   __u32 max_srq_wr;
-/* WARNING: DO NOT EDIT, AUTO-GENERATED CODE - SEE TOP FOR INSTRUCTIONS */
   __u32 max_srq_sge;
+/* WARNING: DO NOT EDIT, AUTO-GENERATED CODE - SEE TOP FOR INSTRUCTIONS */
   __u16 max_pkeys;
   __u8 local_ca_ack_delay;
   __u8 phys_port_cnt;
-/* WARNING: DO NOT EDIT, AUTO-GENERATED CODE - SEE TOP FOR INSTRUCTIONS */
   __u8 reserved[4];
+/* WARNING: DO NOT EDIT, AUTO-GENERATED CODE - SEE TOP FOR INSTRUCTIONS */
+};
+struct ib_uverbs_ex_query_device {
+  __u32 comp_mask;
+  __u32 reserved;
+/* WARNING: DO NOT EDIT, AUTO-GENERATED CODE - SEE TOP FOR INSTRUCTIONS */
+};
+struct ib_uverbs_odp_caps {
+  __u64 general_caps;
+  struct {
+/* WARNING: DO NOT EDIT, AUTO-GENERATED CODE - SEE TOP FOR INSTRUCTIONS */
+    __u32 rc_odp_caps;
+    __u32 uc_odp_caps;
+    __u32 ud_odp_caps;
+  } per_transport_caps;
+/* WARNING: DO NOT EDIT, AUTO-GENERATED CODE - SEE TOP FOR INSTRUCTIONS */
+  __u32 reserved;
+};
+struct ib_uverbs_ex_query_device_resp {
+  struct ib_uverbs_query_device_resp base;
+/* WARNING: DO NOT EDIT, AUTO-GENERATED CODE - SEE TOP FOR INSTRUCTIONS */
+  __u32 comp_mask;
+  __u32 response_length;
+  struct ib_uverbs_odp_caps odp_caps;
+  __u64 timestamp_mask;
+/* WARNING: DO NOT EDIT, AUTO-GENERATED CODE - SEE TOP FOR INSTRUCTIONS */
+  __u64 hca_core_clock;
 };
 struct ib_uverbs_query_port {
   __u64 response;
@@ -316,163 +346,203 @@
   __u64 driver_data[0];
 };
 /* WARNING: DO NOT EDIT, AUTO-GENERATED CODE - SEE TOP FOR INSTRUCTIONS */
+struct ib_uverbs_ex_create_cq {
+  __u64 user_handle;
+  __u32 cqe;
+  __u32 comp_vector;
+/* WARNING: DO NOT EDIT, AUTO-GENERATED CODE - SEE TOP FOR INSTRUCTIONS */
+  __s32 comp_channel;
+  __u32 comp_mask;
+  __u32 flags;
+  __u32 reserved;
+/* WARNING: DO NOT EDIT, AUTO-GENERATED CODE - SEE TOP FOR INSTRUCTIONS */
+};
 struct ib_uverbs_create_cq_resp {
   __u32 cq_handle;
   __u32 cqe;
-};
 /* WARNING: DO NOT EDIT, AUTO-GENERATED CODE - SEE TOP FOR INSTRUCTIONS */
+};
+struct ib_uverbs_ex_create_cq_resp {
+  struct ib_uverbs_create_cq_resp base;
+  __u32 comp_mask;
+/* WARNING: DO NOT EDIT, AUTO-GENERATED CODE - SEE TOP FOR INSTRUCTIONS */
+  __u32 response_length;
+};
 struct ib_uverbs_resize_cq {
   __u64 response;
+/* WARNING: DO NOT EDIT, AUTO-GENERATED CODE - SEE TOP FOR INSTRUCTIONS */
   __u32 cq_handle;
   __u32 cqe;
-/* WARNING: DO NOT EDIT, AUTO-GENERATED CODE - SEE TOP FOR INSTRUCTIONS */
   __u64 driver_data[0];
 };
+/* WARNING: DO NOT EDIT, AUTO-GENERATED CODE - SEE TOP FOR INSTRUCTIONS */
 struct ib_uverbs_resize_cq_resp {
   __u32 cqe;
-/* WARNING: DO NOT EDIT, AUTO-GENERATED CODE - SEE TOP FOR INSTRUCTIONS */
   __u32 reserved;
   __u64 driver_data[0];
+/* WARNING: DO NOT EDIT, AUTO-GENERATED CODE - SEE TOP FOR INSTRUCTIONS */
 };
 struct ib_uverbs_poll_cq {
-/* WARNING: DO NOT EDIT, AUTO-GENERATED CODE - SEE TOP FOR INSTRUCTIONS */
   __u64 response;
   __u32 cq_handle;
+/* WARNING: DO NOT EDIT, AUTO-GENERATED CODE - SEE TOP FOR INSTRUCTIONS */
   __u32 ne;
 };
-/* WARNING: DO NOT EDIT, AUTO-GENERATED CODE - SEE TOP FOR INSTRUCTIONS */
 struct ib_uverbs_wc {
   __u64 wr_id;
+/* WARNING: DO NOT EDIT, AUTO-GENERATED CODE - SEE TOP FOR INSTRUCTIONS */
   __u32 status;
   __u32 opcode;
-/* WARNING: DO NOT EDIT, AUTO-GENERATED CODE - SEE TOP FOR INSTRUCTIONS */
   __u32 vendor_err;
   __u32 byte_len;
+/* WARNING: DO NOT EDIT, AUTO-GENERATED CODE - SEE TOP FOR INSTRUCTIONS */
   union {
     __u32 imm_data;
-/* WARNING: DO NOT EDIT, AUTO-GENERATED CODE - SEE TOP FOR INSTRUCTIONS */
     __u32 invalidate_rkey;
   } ex;
+/* WARNING: DO NOT EDIT, AUTO-GENERATED CODE - SEE TOP FOR INSTRUCTIONS */
   __u32 qp_num;
   __u32 src_qp;
-/* WARNING: DO NOT EDIT, AUTO-GENERATED CODE - SEE TOP FOR INSTRUCTIONS */
   __u32 wc_flags;
   __u16 pkey_index;
+/* WARNING: DO NOT EDIT, AUTO-GENERATED CODE - SEE TOP FOR INSTRUCTIONS */
   __u16 slid;
   __u8 sl;
-/* WARNING: DO NOT EDIT, AUTO-GENERATED CODE - SEE TOP FOR INSTRUCTIONS */
   __u8 dlid_path_bits;
   __u8 port_num;
+/* WARNING: DO NOT EDIT, AUTO-GENERATED CODE - SEE TOP FOR INSTRUCTIONS */
   __u8 reserved;
 };
-/* WARNING: DO NOT EDIT, AUTO-GENERATED CODE - SEE TOP FOR INSTRUCTIONS */
 struct ib_uverbs_poll_cq_resp {
   __u32 count;
+/* WARNING: DO NOT EDIT, AUTO-GENERATED CODE - SEE TOP FOR INSTRUCTIONS */
   __u32 reserved;
   struct ib_uverbs_wc wc[0];
-/* WARNING: DO NOT EDIT, AUTO-GENERATED CODE - SEE TOP FOR INSTRUCTIONS */
 };
 struct ib_uverbs_req_notify_cq {
+/* WARNING: DO NOT EDIT, AUTO-GENERATED CODE - SEE TOP FOR INSTRUCTIONS */
   __u32 cq_handle;
   __u32 solicited_only;
-/* WARNING: DO NOT EDIT, AUTO-GENERATED CODE - SEE TOP FOR INSTRUCTIONS */
 };
 struct ib_uverbs_destroy_cq {
+/* WARNING: DO NOT EDIT, AUTO-GENERATED CODE - SEE TOP FOR INSTRUCTIONS */
   __u64 response;
   __u32 cq_handle;
-/* WARNING: DO NOT EDIT, AUTO-GENERATED CODE - SEE TOP FOR INSTRUCTIONS */
   __u32 reserved;
 };
+/* WARNING: DO NOT EDIT, AUTO-GENERATED CODE - SEE TOP FOR INSTRUCTIONS */
 struct ib_uverbs_destroy_cq_resp {
   __u32 comp_events_reported;
-/* WARNING: DO NOT EDIT, AUTO-GENERATED CODE - SEE TOP FOR INSTRUCTIONS */
   __u32 async_events_reported;
 };
+/* WARNING: DO NOT EDIT, AUTO-GENERATED CODE - SEE TOP FOR INSTRUCTIONS */
 struct ib_uverbs_global_route {
   __u8 dgid[16];
-/* WARNING: DO NOT EDIT, AUTO-GENERATED CODE - SEE TOP FOR INSTRUCTIONS */
   __u32 flow_label;
   __u8 sgid_index;
+/* WARNING: DO NOT EDIT, AUTO-GENERATED CODE - SEE TOP FOR INSTRUCTIONS */
   __u8 hop_limit;
   __u8 traffic_class;
-/* WARNING: DO NOT EDIT, AUTO-GENERATED CODE - SEE TOP FOR INSTRUCTIONS */
   __u8 reserved;
 };
+/* WARNING: DO NOT EDIT, AUTO-GENERATED CODE - SEE TOP FOR INSTRUCTIONS */
 struct ib_uverbs_ah_attr {
   struct ib_uverbs_global_route grh;
-/* WARNING: DO NOT EDIT, AUTO-GENERATED CODE - SEE TOP FOR INSTRUCTIONS */
   __u16 dlid;
   __u8 sl;
+/* WARNING: DO NOT EDIT, AUTO-GENERATED CODE - SEE TOP FOR INSTRUCTIONS */
   __u8 src_path_bits;
   __u8 static_rate;
-/* WARNING: DO NOT EDIT, AUTO-GENERATED CODE - SEE TOP FOR INSTRUCTIONS */
   __u8 is_global;
   __u8 port_num;
+/* WARNING: DO NOT EDIT, AUTO-GENERATED CODE - SEE TOP FOR INSTRUCTIONS */
   __u8 reserved;
 };
-/* WARNING: DO NOT EDIT, AUTO-GENERATED CODE - SEE TOP FOR INSTRUCTIONS */
 struct ib_uverbs_qp_attr {
   __u32 qp_attr_mask;
+/* WARNING: DO NOT EDIT, AUTO-GENERATED CODE - SEE TOP FOR INSTRUCTIONS */
   __u32 qp_state;
   __u32 cur_qp_state;
-/* WARNING: DO NOT EDIT, AUTO-GENERATED CODE - SEE TOP FOR INSTRUCTIONS */
   __u32 path_mtu;
   __u32 path_mig_state;
+/* WARNING: DO NOT EDIT, AUTO-GENERATED CODE - SEE TOP FOR INSTRUCTIONS */
   __u32 qkey;
   __u32 rq_psn;
-/* WARNING: DO NOT EDIT, AUTO-GENERATED CODE - SEE TOP FOR INSTRUCTIONS */
   __u32 sq_psn;
   __u32 dest_qp_num;
+/* WARNING: DO NOT EDIT, AUTO-GENERATED CODE - SEE TOP FOR INSTRUCTIONS */
   __u32 qp_access_flags;
   struct ib_uverbs_ah_attr ah_attr;
-/* WARNING: DO NOT EDIT, AUTO-GENERATED CODE - SEE TOP FOR INSTRUCTIONS */
   struct ib_uverbs_ah_attr alt_ah_attr;
   __u32 max_send_wr;
+/* WARNING: DO NOT EDIT, AUTO-GENERATED CODE - SEE TOP FOR INSTRUCTIONS */
   __u32 max_recv_wr;
   __u32 max_send_sge;
-/* WARNING: DO NOT EDIT, AUTO-GENERATED CODE - SEE TOP FOR INSTRUCTIONS */
   __u32 max_recv_sge;
   __u32 max_inline_data;
+/* WARNING: DO NOT EDIT, AUTO-GENERATED CODE - SEE TOP FOR INSTRUCTIONS */
   __u16 pkey_index;
   __u16 alt_pkey_index;
-/* WARNING: DO NOT EDIT, AUTO-GENERATED CODE - SEE TOP FOR INSTRUCTIONS */
   __u8 en_sqd_async_notify;
   __u8 sq_draining;
+/* WARNING: DO NOT EDIT, AUTO-GENERATED CODE - SEE TOP FOR INSTRUCTIONS */
   __u8 max_rd_atomic;
   __u8 max_dest_rd_atomic;
-/* WARNING: DO NOT EDIT, AUTO-GENERATED CODE - SEE TOP FOR INSTRUCTIONS */
   __u8 min_rnr_timer;
   __u8 port_num;
+/* WARNING: DO NOT EDIT, AUTO-GENERATED CODE - SEE TOP FOR INSTRUCTIONS */
   __u8 timeout;
   __u8 retry_cnt;
-/* WARNING: DO NOT EDIT, AUTO-GENERATED CODE - SEE TOP FOR INSTRUCTIONS */
   __u8 rnr_retry;
   __u8 alt_port_num;
+/* WARNING: DO NOT EDIT, AUTO-GENERATED CODE - SEE TOP FOR INSTRUCTIONS */
   __u8 alt_timeout;
   __u8 reserved[5];
-/* WARNING: DO NOT EDIT, AUTO-GENERATED CODE - SEE TOP FOR INSTRUCTIONS */
 };
 struct ib_uverbs_create_qp {
+/* WARNING: DO NOT EDIT, AUTO-GENERATED CODE - SEE TOP FOR INSTRUCTIONS */
   __u64 response;
   __u64 user_handle;
-/* WARNING: DO NOT EDIT, AUTO-GENERATED CODE - SEE TOP FOR INSTRUCTIONS */
   __u32 pd_handle;
   __u32 send_cq_handle;
+/* WARNING: DO NOT EDIT, AUTO-GENERATED CODE - SEE TOP FOR INSTRUCTIONS */
+  __u32 recv_cq_handle;
+  __u32 srq_handle;
+  __u32 max_send_wr;
+  __u32 max_recv_wr;
+/* WARNING: DO NOT EDIT, AUTO-GENERATED CODE - SEE TOP FOR INSTRUCTIONS */
+  __u32 max_send_sge;
+  __u32 max_recv_sge;
+  __u32 max_inline_data;
+  __u8 sq_sig_all;
+/* WARNING: DO NOT EDIT, AUTO-GENERATED CODE - SEE TOP FOR INSTRUCTIONS */
+  __u8 qp_type;
+  __u8 is_srq;
+  __u8 reserved;
+  __u64 driver_data[0];
+/* WARNING: DO NOT EDIT, AUTO-GENERATED CODE - SEE TOP FOR INSTRUCTIONS */
+};
+struct ib_uverbs_ex_create_qp {
+  __u64 user_handle;
+  __u32 pd_handle;
+/* WARNING: DO NOT EDIT, AUTO-GENERATED CODE - SEE TOP FOR INSTRUCTIONS */
+  __u32 send_cq_handle;
   __u32 recv_cq_handle;
   __u32 srq_handle;
-/* WARNING: DO NOT EDIT, AUTO-GENERATED CODE - SEE TOP FOR INSTRUCTIONS */
   __u32 max_send_wr;
+/* WARNING: DO NOT EDIT, AUTO-GENERATED CODE - SEE TOP FOR INSTRUCTIONS */
   __u32 max_recv_wr;
   __u32 max_send_sge;
   __u32 max_recv_sge;
-/* WARNING: DO NOT EDIT, AUTO-GENERATED CODE - SEE TOP FOR INSTRUCTIONS */
   __u32 max_inline_data;
+/* WARNING: DO NOT EDIT, AUTO-GENERATED CODE - SEE TOP FOR INSTRUCTIONS */
   __u8 sq_sig_all;
   __u8 qp_type;
   __u8 is_srq;
-/* WARNING: DO NOT EDIT, AUTO-GENERATED CODE - SEE TOP FOR INSTRUCTIONS */
   __u8 reserved;
-  __u64 driver_data[0];
+/* WARNING: DO NOT EDIT, AUTO-GENERATED CODE - SEE TOP FOR INSTRUCTIONS */
+  __u32 comp_mask;
+  __u32 create_flags;
 };
 struct ib_uverbs_open_qp {
 /* WARNING: DO NOT EDIT, AUTO-GENERATED CODE - SEE TOP FOR INSTRUCTIONS */
@@ -498,412 +568,418 @@
 /* WARNING: DO NOT EDIT, AUTO-GENERATED CODE - SEE TOP FOR INSTRUCTIONS */
   __u32 reserved;
 };
-struct ib_uverbs_qp_dest {
-  __u8 dgid[16];
+struct ib_uverbs_ex_create_qp_resp {
+  struct ib_uverbs_create_qp_resp base;
 /* WARNING: DO NOT EDIT, AUTO-GENERATED CODE - SEE TOP FOR INSTRUCTIONS */
+  __u32 comp_mask;
+  __u32 response_length;
+};
+struct ib_uverbs_qp_dest {
+/* WARNING: DO NOT EDIT, AUTO-GENERATED CODE - SEE TOP FOR INSTRUCTIONS */
+  __u8 dgid[16];
   __u32 flow_label;
   __u16 dlid;
   __u16 reserved;
-  __u8 sgid_index;
 /* WARNING: DO NOT EDIT, AUTO-GENERATED CODE - SEE TOP FOR INSTRUCTIONS */
+  __u8 sgid_index;
   __u8 hop_limit;
   __u8 traffic_class;
   __u8 sl;
-  __u8 src_path_bits;
 /* WARNING: DO NOT EDIT, AUTO-GENERATED CODE - SEE TOP FOR INSTRUCTIONS */
+  __u8 src_path_bits;
   __u8 static_rate;
   __u8 is_global;
   __u8 port_num;
-};
 /* WARNING: DO NOT EDIT, AUTO-GENERATED CODE - SEE TOP FOR INSTRUCTIONS */
+};
 struct ib_uverbs_query_qp {
   __u64 response;
   __u32 qp_handle;
-  __u32 attr_mask;
 /* WARNING: DO NOT EDIT, AUTO-GENERATED CODE - SEE TOP FOR INSTRUCTIONS */
+  __u32 attr_mask;
   __u64 driver_data[0];
 };
 struct ib_uverbs_query_qp_resp {
-  struct ib_uverbs_qp_dest dest;
 /* WARNING: DO NOT EDIT, AUTO-GENERATED CODE - SEE TOP FOR INSTRUCTIONS */
+  struct ib_uverbs_qp_dest dest;
   struct ib_uverbs_qp_dest alt_dest;
   __u32 max_send_wr;
   __u32 max_recv_wr;
-  __u32 max_send_sge;
 /* WARNING: DO NOT EDIT, AUTO-GENERATED CODE - SEE TOP FOR INSTRUCTIONS */
+  __u32 max_send_sge;
   __u32 max_recv_sge;
   __u32 max_inline_data;
   __u32 qkey;
-  __u32 rq_psn;
 /* WARNING: DO NOT EDIT, AUTO-GENERATED CODE - SEE TOP FOR INSTRUCTIONS */
+  __u32 rq_psn;
   __u32 sq_psn;
   __u32 dest_qp_num;
   __u32 qp_access_flags;
-  __u16 pkey_index;
 /* WARNING: DO NOT EDIT, AUTO-GENERATED CODE - SEE TOP FOR INSTRUCTIONS */
+  __u16 pkey_index;
   __u16 alt_pkey_index;
   __u8 qp_state;
   __u8 cur_qp_state;
-  __u8 path_mtu;
 /* WARNING: DO NOT EDIT, AUTO-GENERATED CODE - SEE TOP FOR INSTRUCTIONS */
+  __u8 path_mtu;
   __u8 path_mig_state;
   __u8 sq_draining;
   __u8 max_rd_atomic;
-  __u8 max_dest_rd_atomic;
 /* WARNING: DO NOT EDIT, AUTO-GENERATED CODE - SEE TOP FOR INSTRUCTIONS */
+  __u8 max_dest_rd_atomic;
   __u8 min_rnr_timer;
   __u8 port_num;
   __u8 timeout;
-  __u8 retry_cnt;
 /* WARNING: DO NOT EDIT, AUTO-GENERATED CODE - SEE TOP FOR INSTRUCTIONS */
+  __u8 retry_cnt;
   __u8 rnr_retry;
   __u8 alt_port_num;
   __u8 alt_timeout;
-  __u8 sq_sig_all;
 /* WARNING: DO NOT EDIT, AUTO-GENERATED CODE - SEE TOP FOR INSTRUCTIONS */
+  __u8 sq_sig_all;
   __u8 reserved[5];
   __u64 driver_data[0];
 };
-struct ib_uverbs_modify_qp {
 /* WARNING: DO NOT EDIT, AUTO-GENERATED CODE - SEE TOP FOR INSTRUCTIONS */
+struct ib_uverbs_modify_qp {
   struct ib_uverbs_qp_dest dest;
   struct ib_uverbs_qp_dest alt_dest;
   __u32 qp_handle;
-  __u32 attr_mask;
 /* WARNING: DO NOT EDIT, AUTO-GENERATED CODE - SEE TOP FOR INSTRUCTIONS */
+  __u32 attr_mask;
   __u32 qkey;
   __u32 rq_psn;
   __u32 sq_psn;
-  __u32 dest_qp_num;
 /* WARNING: DO NOT EDIT, AUTO-GENERATED CODE - SEE TOP FOR INSTRUCTIONS */
+  __u32 dest_qp_num;
   __u32 qp_access_flags;
   __u16 pkey_index;
   __u16 alt_pkey_index;
-  __u8 qp_state;
 /* WARNING: DO NOT EDIT, AUTO-GENERATED CODE - SEE TOP FOR INSTRUCTIONS */
+  __u8 qp_state;
   __u8 cur_qp_state;
   __u8 path_mtu;
   __u8 path_mig_state;
-  __u8 en_sqd_async_notify;
 /* WARNING: DO NOT EDIT, AUTO-GENERATED CODE - SEE TOP FOR INSTRUCTIONS */
+  __u8 en_sqd_async_notify;
   __u8 max_rd_atomic;
   __u8 max_dest_rd_atomic;
   __u8 min_rnr_timer;
-  __u8 port_num;
 /* WARNING: DO NOT EDIT, AUTO-GENERATED CODE - SEE TOP FOR INSTRUCTIONS */
+  __u8 port_num;
   __u8 timeout;
   __u8 retry_cnt;
   __u8 rnr_retry;
-  __u8 alt_port_num;
 /* WARNING: DO NOT EDIT, AUTO-GENERATED CODE - SEE TOP FOR INSTRUCTIONS */
+  __u8 alt_port_num;
   __u8 alt_timeout;
   __u8 reserved[2];
   __u64 driver_data[0];
-};
 /* WARNING: DO NOT EDIT, AUTO-GENERATED CODE - SEE TOP FOR INSTRUCTIONS */
+};
 struct ib_uverbs_modify_qp_resp {
 };
 struct ib_uverbs_destroy_qp {
-  __u64 response;
 /* WARNING: DO NOT EDIT, AUTO-GENERATED CODE - SEE TOP FOR INSTRUCTIONS */
+  __u64 response;
   __u32 qp_handle;
   __u32 reserved;
 };
-struct ib_uverbs_destroy_qp_resp {
 /* WARNING: DO NOT EDIT, AUTO-GENERATED CODE - SEE TOP FOR INSTRUCTIONS */
+struct ib_uverbs_destroy_qp_resp {
   __u32 events_reported;
 };
 struct ib_uverbs_sge {
-  __u64 addr;
 /* WARNING: DO NOT EDIT, AUTO-GENERATED CODE - SEE TOP FOR INSTRUCTIONS */
+  __u64 addr;
   __u32 length;
   __u32 lkey;
 };
-struct ib_uverbs_send_wr {
 /* WARNING: DO NOT EDIT, AUTO-GENERATED CODE - SEE TOP FOR INSTRUCTIONS */
+struct ib_uverbs_send_wr {
   __u64 wr_id;
   __u32 num_sge;
   __u32 opcode;
-  __u32 send_flags;
 /* WARNING: DO NOT EDIT, AUTO-GENERATED CODE - SEE TOP FOR INSTRUCTIONS */
+  __u32 send_flags;
   union {
     __u32 imm_data;
     __u32 invalidate_rkey;
-  } ex;
 /* WARNING: DO NOT EDIT, AUTO-GENERATED CODE - SEE TOP FOR INSTRUCTIONS */
+  } ex;
   union {
     struct {
       __u64 remote_addr;
-      __u32 rkey;
 /* WARNING: DO NOT EDIT, AUTO-GENERATED CODE - SEE TOP FOR INSTRUCTIONS */
+      __u32 rkey;
       __u32 reserved;
     } rdma;
     struct {
-      __u64 remote_addr;
 /* WARNING: DO NOT EDIT, AUTO-GENERATED CODE - SEE TOP FOR INSTRUCTIONS */
+      __u64 remote_addr;
       __u64 compare_add;
       __u64 swap;
       __u32 rkey;
-      __u32 reserved;
 /* WARNING: DO NOT EDIT, AUTO-GENERATED CODE - SEE TOP FOR INSTRUCTIONS */
+      __u32 reserved;
     } atomic;
     struct {
       __u32 ah;
-      __u32 remote_qpn;
 /* WARNING: DO NOT EDIT, AUTO-GENERATED CODE - SEE TOP FOR INSTRUCTIONS */
+      __u32 remote_qpn;
       __u32 remote_qkey;
       __u32 reserved;
     } ud;
-  } wr;
 /* WARNING: DO NOT EDIT, AUTO-GENERATED CODE - SEE TOP FOR INSTRUCTIONS */
+  } wr;
 };
 struct ib_uverbs_post_send {
   __u64 response;
-  __u32 qp_handle;
 /* WARNING: DO NOT EDIT, AUTO-GENERATED CODE - SEE TOP FOR INSTRUCTIONS */
+  __u32 qp_handle;
   __u32 wr_count;
   __u32 sge_count;
   __u32 wqe_size;
-  struct ib_uverbs_send_wr send_wr[0];
 /* WARNING: DO NOT EDIT, AUTO-GENERATED CODE - SEE TOP FOR INSTRUCTIONS */
+  struct ib_uverbs_send_wr send_wr[0];
 };
 struct ib_uverbs_post_send_resp {
   __u32 bad_wr;
-};
 /* WARNING: DO NOT EDIT, AUTO-GENERATED CODE - SEE TOP FOR INSTRUCTIONS */
+};
 struct ib_uverbs_recv_wr {
   __u64 wr_id;
   __u32 num_sge;
-  __u32 reserved;
 /* WARNING: DO NOT EDIT, AUTO-GENERATED CODE - SEE TOP FOR INSTRUCTIONS */
+  __u32 reserved;
 };
 struct ib_uverbs_post_recv {
   __u64 response;
-  __u32 qp_handle;
 /* WARNING: DO NOT EDIT, AUTO-GENERATED CODE - SEE TOP FOR INSTRUCTIONS */
+  __u32 qp_handle;
   __u32 wr_count;
   __u32 sge_count;
   __u32 wqe_size;
-  struct ib_uverbs_recv_wr recv_wr[0];
 /* WARNING: DO NOT EDIT, AUTO-GENERATED CODE - SEE TOP FOR INSTRUCTIONS */
+  struct ib_uverbs_recv_wr recv_wr[0];
 };
 struct ib_uverbs_post_recv_resp {
   __u32 bad_wr;
-};
 /* WARNING: DO NOT EDIT, AUTO-GENERATED CODE - SEE TOP FOR INSTRUCTIONS */
+};
 struct ib_uverbs_post_srq_recv {
   __u64 response;
   __u32 srq_handle;
-  __u32 wr_count;
 /* WARNING: DO NOT EDIT, AUTO-GENERATED CODE - SEE TOP FOR INSTRUCTIONS */
+  __u32 wr_count;
   __u32 sge_count;
   __u32 wqe_size;
   struct ib_uverbs_recv_wr recv[0];
-};
 /* WARNING: DO NOT EDIT, AUTO-GENERATED CODE - SEE TOP FOR INSTRUCTIONS */
+};
 struct ib_uverbs_post_srq_recv_resp {
   __u32 bad_wr;
 };
-struct ib_uverbs_create_ah {
 /* WARNING: DO NOT EDIT, AUTO-GENERATED CODE - SEE TOP FOR INSTRUCTIONS */
+struct ib_uverbs_create_ah {
   __u64 response;
   __u64 user_handle;
   __u32 pd_handle;
-  __u32 reserved;
 /* WARNING: DO NOT EDIT, AUTO-GENERATED CODE - SEE TOP FOR INSTRUCTIONS */
+  __u32 reserved;
   struct ib_uverbs_ah_attr attr;
 };
 struct ib_uverbs_create_ah_resp {
-  __u32 ah_handle;
 /* WARNING: DO NOT EDIT, AUTO-GENERATED CODE - SEE TOP FOR INSTRUCTIONS */
+  __u32 ah_handle;
 };
 struct ib_uverbs_destroy_ah {
   __u32 ah_handle;
-};
 /* WARNING: DO NOT EDIT, AUTO-GENERATED CODE - SEE TOP FOR INSTRUCTIONS */
+};
 struct ib_uverbs_attach_mcast {
   __u8 gid[16];
   __u32 qp_handle;
-  __u16 mlid;
 /* WARNING: DO NOT EDIT, AUTO-GENERATED CODE - SEE TOP FOR INSTRUCTIONS */
+  __u16 mlid;
   __u16 reserved;
   __u64 driver_data[0];
 };
-struct ib_uverbs_detach_mcast {
 /* WARNING: DO NOT EDIT, AUTO-GENERATED CODE - SEE TOP FOR INSTRUCTIONS */
+struct ib_uverbs_detach_mcast {
   __u8 gid[16];
   __u32 qp_handle;
   __u16 mlid;
-  __u16 reserved;
 /* WARNING: DO NOT EDIT, AUTO-GENERATED CODE - SEE TOP FOR INSTRUCTIONS */
+  __u16 reserved;
   __u64 driver_data[0];
 };
 struct ib_uverbs_flow_spec_hdr {
-  __u32 type;
 /* WARNING: DO NOT EDIT, AUTO-GENERATED CODE - SEE TOP FOR INSTRUCTIONS */
+  __u32 type;
   __u16 size;
   __u16 reserved;
   __u64 flow_spec_data[0];
-};
 /* WARNING: DO NOT EDIT, AUTO-GENERATED CODE - SEE TOP FOR INSTRUCTIONS */
+};
 struct ib_uverbs_flow_eth_filter {
   __u8 dst_mac[6];
   __u8 src_mac[6];
-  __be16 ether_type;
 /* WARNING: DO NOT EDIT, AUTO-GENERATED CODE - SEE TOP FOR INSTRUCTIONS */
+  __be16 ether_type;
   __be16 vlan_tag;
 };
 struct ib_uverbs_flow_spec_eth {
-  union {
 /* WARNING: DO NOT EDIT, AUTO-GENERATED CODE - SEE TOP FOR INSTRUCTIONS */
+  union {
     struct ib_uverbs_flow_spec_hdr hdr;
     struct {
       __u32 type;
-      __u16 size;
 /* WARNING: DO NOT EDIT, AUTO-GENERATED CODE - SEE TOP FOR INSTRUCTIONS */
+      __u16 size;
       __u16 reserved;
     };
   };
-  struct ib_uverbs_flow_eth_filter val;
 /* WARNING: DO NOT EDIT, AUTO-GENERATED CODE - SEE TOP FOR INSTRUCTIONS */
+  struct ib_uverbs_flow_eth_filter val;
   struct ib_uverbs_flow_eth_filter mask;
 };
 struct ib_uverbs_flow_ipv4_filter {
-  __be32 src_ip;
 /* WARNING: DO NOT EDIT, AUTO-GENERATED CODE - SEE TOP FOR INSTRUCTIONS */
+  __be32 src_ip;
   __be32 dst_ip;
 };
 struct ib_uverbs_flow_spec_ipv4 {
-  union {
 /* WARNING: DO NOT EDIT, AUTO-GENERATED CODE - SEE TOP FOR INSTRUCTIONS */
+  union {
     struct ib_uverbs_flow_spec_hdr hdr;
     struct {
       __u32 type;
-      __u16 size;
 /* WARNING: DO NOT EDIT, AUTO-GENERATED CODE - SEE TOP FOR INSTRUCTIONS */
+      __u16 size;
       __u16 reserved;
     };
   };
-  struct ib_uverbs_flow_ipv4_filter val;
 /* WARNING: DO NOT EDIT, AUTO-GENERATED CODE - SEE TOP FOR INSTRUCTIONS */
+  struct ib_uverbs_flow_ipv4_filter val;
   struct ib_uverbs_flow_ipv4_filter mask;
 };
 struct ib_uverbs_flow_tcp_udp_filter {
-  __be16 dst_port;
 /* WARNING: DO NOT EDIT, AUTO-GENERATED CODE - SEE TOP FOR INSTRUCTIONS */
+  __be16 dst_port;
   __be16 src_port;
 };
 struct ib_uverbs_flow_spec_tcp_udp {
-  union {
 /* WARNING: DO NOT EDIT, AUTO-GENERATED CODE - SEE TOP FOR INSTRUCTIONS */
+  union {
     struct ib_uverbs_flow_spec_hdr hdr;
     struct {
       __u32 type;
-      __u16 size;
 /* WARNING: DO NOT EDIT, AUTO-GENERATED CODE - SEE TOP FOR INSTRUCTIONS */
+      __u16 size;
       __u16 reserved;
     };
   };
-  struct ib_uverbs_flow_tcp_udp_filter val;
 /* WARNING: DO NOT EDIT, AUTO-GENERATED CODE - SEE TOP FOR INSTRUCTIONS */
+  struct ib_uverbs_flow_tcp_udp_filter val;
   struct ib_uverbs_flow_tcp_udp_filter mask;
 };
 struct ib_uverbs_flow_attr {
-  __u32 type;
 /* WARNING: DO NOT EDIT, AUTO-GENERATED CODE - SEE TOP FOR INSTRUCTIONS */
+  __u32 type;
   __u16 size;
   __u16 priority;
   __u8 num_of_specs;
-  __u8 reserved[2];
 /* WARNING: DO NOT EDIT, AUTO-GENERATED CODE - SEE TOP FOR INSTRUCTIONS */
+  __u8 reserved[2];
   __u8 port;
   __u32 flags;
   struct ib_uverbs_flow_spec_hdr flow_specs[0];
-};
 /* WARNING: DO NOT EDIT, AUTO-GENERATED CODE - SEE TOP FOR INSTRUCTIONS */
+};
 struct ib_uverbs_create_flow {
   __u32 comp_mask;
   __u32 qp_handle;
-  struct ib_uverbs_flow_attr flow_attr;
 /* WARNING: DO NOT EDIT, AUTO-GENERATED CODE - SEE TOP FOR INSTRUCTIONS */
+  struct ib_uverbs_flow_attr flow_attr;
 };
 struct ib_uverbs_create_flow_resp {
   __u32 comp_mask;
-  __u32 flow_handle;
 /* WARNING: DO NOT EDIT, AUTO-GENERATED CODE - SEE TOP FOR INSTRUCTIONS */
+  __u32 flow_handle;
 };
 struct ib_uverbs_destroy_flow {
   __u32 comp_mask;
-  __u32 flow_handle;
 /* WARNING: DO NOT EDIT, AUTO-GENERATED CODE - SEE TOP FOR INSTRUCTIONS */
+  __u32 flow_handle;
 };
 struct ib_uverbs_create_srq {
   __u64 response;
-  __u64 user_handle;
 /* WARNING: DO NOT EDIT, AUTO-GENERATED CODE - SEE TOP FOR INSTRUCTIONS */
+  __u64 user_handle;
   __u32 pd_handle;
   __u32 max_wr;
   __u32 max_sge;
-  __u32 srq_limit;
 /* WARNING: DO NOT EDIT, AUTO-GENERATED CODE - SEE TOP FOR INSTRUCTIONS */
+  __u32 srq_limit;
   __u64 driver_data[0];
 };
 struct ib_uverbs_create_xsrq {
-  __u64 response;
 /* WARNING: DO NOT EDIT, AUTO-GENERATED CODE - SEE TOP FOR INSTRUCTIONS */
+  __u64 response;
   __u64 user_handle;
   __u32 srq_type;
   __u32 pd_handle;
-  __u32 max_wr;
 /* WARNING: DO NOT EDIT, AUTO-GENERATED CODE - SEE TOP FOR INSTRUCTIONS */
+  __u32 max_wr;
   __u32 max_sge;
   __u32 srq_limit;
   __u32 reserved;
-  __u32 xrcd_handle;
 /* WARNING: DO NOT EDIT, AUTO-GENERATED CODE - SEE TOP FOR INSTRUCTIONS */
+  __u32 xrcd_handle;
   __u32 cq_handle;
   __u64 driver_data[0];
 };
-struct ib_uverbs_create_srq_resp {
 /* WARNING: DO NOT EDIT, AUTO-GENERATED CODE - SEE TOP FOR INSTRUCTIONS */
+struct ib_uverbs_create_srq_resp {
   __u32 srq_handle;
   __u32 max_wr;
   __u32 max_sge;
-  __u32 srqn;
 /* WARNING: DO NOT EDIT, AUTO-GENERATED CODE - SEE TOP FOR INSTRUCTIONS */
+  __u32 srqn;
 };
 struct ib_uverbs_modify_srq {
   __u32 srq_handle;
-  __u32 attr_mask;
 /* WARNING: DO NOT EDIT, AUTO-GENERATED CODE - SEE TOP FOR INSTRUCTIONS */
+  __u32 attr_mask;
   __u32 max_wr;
   __u32 srq_limit;
   __u64 driver_data[0];
-};
 /* WARNING: DO NOT EDIT, AUTO-GENERATED CODE - SEE TOP FOR INSTRUCTIONS */
+};
 struct ib_uverbs_query_srq {
   __u64 response;
   __u32 srq_handle;
-  __u32 reserved;
 /* WARNING: DO NOT EDIT, AUTO-GENERATED CODE - SEE TOP FOR INSTRUCTIONS */
+  __u32 reserved;
   __u64 driver_data[0];
 };
 struct ib_uverbs_query_srq_resp {
-  __u32 max_wr;
 /* WARNING: DO NOT EDIT, AUTO-GENERATED CODE - SEE TOP FOR INSTRUCTIONS */
+  __u32 max_wr;
   __u32 max_sge;
   __u32 srq_limit;
   __u32 reserved;
-};
 /* WARNING: DO NOT EDIT, AUTO-GENERATED CODE - SEE TOP FOR INSTRUCTIONS */
+};
 struct ib_uverbs_destroy_srq {
   __u64 response;
   __u32 srq_handle;
-  __u32 reserved;
 /* WARNING: DO NOT EDIT, AUTO-GENERATED CODE - SEE TOP FOR INSTRUCTIONS */
+  __u32 reserved;
 };
 struct ib_uverbs_destroy_srq_resp {
   __u32 events_reported;
-};
 /* WARNING: DO NOT EDIT, AUTO-GENERATED CODE - SEE TOP FOR INSTRUCTIONS */
+};
 #endif
diff --git a/libc/kernel/uapi/rdma/rdma_netlink.h b/libc/kernel/uapi/rdma/rdma_netlink.h
index e49bfff..b35703a 100644
--- a/libc/kernel/uapi/rdma/rdma_netlink.h
+++ b/libc/kernel/uapi/rdma/rdma_netlink.h
@@ -24,132 +24,180 @@
   RDMA_NL_RDMA_CM = 1,
   RDMA_NL_NES,
   RDMA_NL_C4IW,
-  RDMA_NL_NUM_CLIENTS
+  RDMA_NL_LS,
 /* WARNING: DO NOT EDIT, AUTO-GENERATED CODE - SEE TOP FOR INSTRUCTIONS */
+  RDMA_NL_NUM_CLIENTS
 };
 enum {
   RDMA_NL_GROUP_CM = 1,
-  RDMA_NL_GROUP_IWPM,
 /* WARNING: DO NOT EDIT, AUTO-GENERATED CODE - SEE TOP FOR INSTRUCTIONS */
+  RDMA_NL_GROUP_IWPM,
+  RDMA_NL_GROUP_LS,
   RDMA_NL_NUM_GROUPS
 };
+/* WARNING: DO NOT EDIT, AUTO-GENERATED CODE - SEE TOP FOR INSTRUCTIONS */
 #define RDMA_NL_GET_CLIENT(type) ((type & (((1 << 6) - 1) << 10)) >> 10)
 #define RDMA_NL_GET_OP(type) (type & ((1 << 10) - 1))
-/* WARNING: DO NOT EDIT, AUTO-GENERATED CODE - SEE TOP FOR INSTRUCTIONS */
 #define RDMA_NL_GET_TYPE(client,op) ((client << 10) + op)
 enum {
+/* WARNING: DO NOT EDIT, AUTO-GENERATED CODE - SEE TOP FOR INSTRUCTIONS */
   RDMA_NL_RDMA_CM_ID_STATS = 0,
   RDMA_NL_RDMA_CM_NUM_OPS
-/* WARNING: DO NOT EDIT, AUTO-GENERATED CODE - SEE TOP FOR INSTRUCTIONS */
 };
 enum {
+/* WARNING: DO NOT EDIT, AUTO-GENERATED CODE - SEE TOP FOR INSTRUCTIONS */
   RDMA_NL_RDMA_CM_ATTR_SRC_ADDR = 1,
   RDMA_NL_RDMA_CM_ATTR_DST_ADDR,
-/* WARNING: DO NOT EDIT, AUTO-GENERATED CODE - SEE TOP FOR INSTRUCTIONS */
   RDMA_NL_RDMA_CM_NUM_ATTR,
 };
+/* WARNING: DO NOT EDIT, AUTO-GENERATED CODE - SEE TOP FOR INSTRUCTIONS */
 enum {
   RDMA_NL_IWPM_REG_PID = 0,
-/* WARNING: DO NOT EDIT, AUTO-GENERATED CODE - SEE TOP FOR INSTRUCTIONS */
   RDMA_NL_IWPM_ADD_MAPPING,
   RDMA_NL_IWPM_QUERY_MAPPING,
-  RDMA_NL_IWPM_REMOVE_MAPPING,
-  RDMA_NL_IWPM_HANDLE_ERR,
 /* WARNING: DO NOT EDIT, AUTO-GENERATED CODE - SEE TOP FOR INSTRUCTIONS */
+  RDMA_NL_IWPM_REMOVE_MAPPING,
+  RDMA_NL_IWPM_REMOTE_INFO,
+  RDMA_NL_IWPM_HANDLE_ERR,
   RDMA_NL_IWPM_MAPINFO,
+/* WARNING: DO NOT EDIT, AUTO-GENERATED CODE - SEE TOP FOR INSTRUCTIONS */
   RDMA_NL_IWPM_MAPINFO_NUM,
   RDMA_NL_IWPM_NUM_OPS
 };
-/* WARNING: DO NOT EDIT, AUTO-GENERATED CODE - SEE TOP FOR INSTRUCTIONS */
 struct rdma_cm_id_stats {
+/* WARNING: DO NOT EDIT, AUTO-GENERATED CODE - SEE TOP FOR INSTRUCTIONS */
   __u32 qp_num;
   __u32 bound_dev_if;
   __u32 port_space;
-/* WARNING: DO NOT EDIT, AUTO-GENERATED CODE - SEE TOP FOR INSTRUCTIONS */
   __s32 pid;
+/* WARNING: DO NOT EDIT, AUTO-GENERATED CODE - SEE TOP FOR INSTRUCTIONS */
   __u8 cm_state;
   __u8 node_type;
   __u8 port_num;
-/* WARNING: DO NOT EDIT, AUTO-GENERATED CODE - SEE TOP FOR INSTRUCTIONS */
   __u8 qp_type;
+/* WARNING: DO NOT EDIT, AUTO-GENERATED CODE - SEE TOP FOR INSTRUCTIONS */
 };
 enum {
   IWPM_NLA_REG_PID_UNSPEC = 0,
-/* WARNING: DO NOT EDIT, AUTO-GENERATED CODE - SEE TOP FOR INSTRUCTIONS */
   IWPM_NLA_REG_PID_SEQ,
+/* WARNING: DO NOT EDIT, AUTO-GENERATED CODE - SEE TOP FOR INSTRUCTIONS */
   IWPM_NLA_REG_IF_NAME,
   IWPM_NLA_REG_IBDEV_NAME,
   IWPM_NLA_REG_ULIB_NAME,
-/* WARNING: DO NOT EDIT, AUTO-GENERATED CODE - SEE TOP FOR INSTRUCTIONS */
   IWPM_NLA_REG_PID_MAX
+/* WARNING: DO NOT EDIT, AUTO-GENERATED CODE - SEE TOP FOR INSTRUCTIONS */
 };
 enum {
   IWPM_NLA_RREG_PID_UNSPEC = 0,
-/* WARNING: DO NOT EDIT, AUTO-GENERATED CODE - SEE TOP FOR INSTRUCTIONS */
   IWPM_NLA_RREG_PID_SEQ,
+/* WARNING: DO NOT EDIT, AUTO-GENERATED CODE - SEE TOP FOR INSTRUCTIONS */
   IWPM_NLA_RREG_IBDEV_NAME,
   IWPM_NLA_RREG_ULIB_NAME,
   IWPM_NLA_RREG_ULIB_VER,
-/* WARNING: DO NOT EDIT, AUTO-GENERATED CODE - SEE TOP FOR INSTRUCTIONS */
   IWPM_NLA_RREG_PID_ERR,
+/* WARNING: DO NOT EDIT, AUTO-GENERATED CODE - SEE TOP FOR INSTRUCTIONS */
   IWPM_NLA_RREG_PID_MAX
 };
 enum {
-/* WARNING: DO NOT EDIT, AUTO-GENERATED CODE - SEE TOP FOR INSTRUCTIONS */
   IWPM_NLA_MANAGE_MAPPING_UNSPEC = 0,
+/* WARNING: DO NOT EDIT, AUTO-GENERATED CODE - SEE TOP FOR INSTRUCTIONS */
   IWPM_NLA_MANAGE_MAPPING_SEQ,
   IWPM_NLA_MANAGE_ADDR,
   IWPM_NLA_MANAGE_MAPPED_LOC_ADDR,
-/* WARNING: DO NOT EDIT, AUTO-GENERATED CODE - SEE TOP FOR INSTRUCTIONS */
   IWPM_NLA_RMANAGE_MAPPING_ERR,
+/* WARNING: DO NOT EDIT, AUTO-GENERATED CODE - SEE TOP FOR INSTRUCTIONS */
   IWPM_NLA_RMANAGE_MAPPING_MAX
 };
 #define IWPM_NLA_MANAGE_MAPPING_MAX 3
-/* WARNING: DO NOT EDIT, AUTO-GENERATED CODE - SEE TOP FOR INSTRUCTIONS */
 #define IWPM_NLA_QUERY_MAPPING_MAX 4
+/* WARNING: DO NOT EDIT, AUTO-GENERATED CODE - SEE TOP FOR INSTRUCTIONS */
 #define IWPM_NLA_MAPINFO_SEND_MAX 3
 enum {
   IWPM_NLA_QUERY_MAPPING_UNSPEC = 0,
-/* WARNING: DO NOT EDIT, AUTO-GENERATED CODE - SEE TOP FOR INSTRUCTIONS */
   IWPM_NLA_QUERY_MAPPING_SEQ,
+/* WARNING: DO NOT EDIT, AUTO-GENERATED CODE - SEE TOP FOR INSTRUCTIONS */
   IWPM_NLA_QUERY_LOCAL_ADDR,
   IWPM_NLA_QUERY_REMOTE_ADDR,
   IWPM_NLA_RQUERY_MAPPED_LOC_ADDR,
-/* WARNING: DO NOT EDIT, AUTO-GENERATED CODE - SEE TOP FOR INSTRUCTIONS */
   IWPM_NLA_RQUERY_MAPPED_REM_ADDR,
+/* WARNING: DO NOT EDIT, AUTO-GENERATED CODE - SEE TOP FOR INSTRUCTIONS */
   IWPM_NLA_RQUERY_MAPPING_ERR,
   IWPM_NLA_RQUERY_MAPPING_MAX
 };
-/* WARNING: DO NOT EDIT, AUTO-GENERATED CODE - SEE TOP FOR INSTRUCTIONS */
 enum {
+/* WARNING: DO NOT EDIT, AUTO-GENERATED CODE - SEE TOP FOR INSTRUCTIONS */
   IWPM_NLA_MAPINFO_REQ_UNSPEC = 0,
   IWPM_NLA_MAPINFO_ULIB_NAME,
   IWPM_NLA_MAPINFO_ULIB_VER,
-/* WARNING: DO NOT EDIT, AUTO-GENERATED CODE - SEE TOP FOR INSTRUCTIONS */
   IWPM_NLA_MAPINFO_REQ_MAX
+/* WARNING: DO NOT EDIT, AUTO-GENERATED CODE - SEE TOP FOR INSTRUCTIONS */
 };
 enum {
   IWPM_NLA_MAPINFO_UNSPEC = 0,
-/* WARNING: DO NOT EDIT, AUTO-GENERATED CODE - SEE TOP FOR INSTRUCTIONS */
   IWPM_NLA_MAPINFO_LOCAL_ADDR,
+/* WARNING: DO NOT EDIT, AUTO-GENERATED CODE - SEE TOP FOR INSTRUCTIONS */
   IWPM_NLA_MAPINFO_MAPPED_ADDR,
   IWPM_NLA_MAPINFO_MAX
 };
-/* WARNING: DO NOT EDIT, AUTO-GENERATED CODE - SEE TOP FOR INSTRUCTIONS */
 enum {
+/* WARNING: DO NOT EDIT, AUTO-GENERATED CODE - SEE TOP FOR INSTRUCTIONS */
   IWPM_NLA_MAPINFO_NUM_UNSPEC = 0,
   IWPM_NLA_MAPINFO_SEQ,
   IWPM_NLA_MAPINFO_SEND_NUM,
-/* WARNING: DO NOT EDIT, AUTO-GENERATED CODE - SEE TOP FOR INSTRUCTIONS */
   IWPM_NLA_MAPINFO_ACK_NUM,
+/* WARNING: DO NOT EDIT, AUTO-GENERATED CODE - SEE TOP FOR INSTRUCTIONS */
   IWPM_NLA_MAPINFO_NUM_MAX
 };
 enum {
-/* WARNING: DO NOT EDIT, AUTO-GENERATED CODE - SEE TOP FOR INSTRUCTIONS */
   IWPM_NLA_ERR_UNSPEC = 0,
+/* WARNING: DO NOT EDIT, AUTO-GENERATED CODE - SEE TOP FOR INSTRUCTIONS */
   IWPM_NLA_ERR_SEQ,
   IWPM_NLA_ERR_CODE,
   IWPM_NLA_ERR_MAX
+};
+/* WARNING: DO NOT EDIT, AUTO-GENERATED CODE - SEE TOP FOR INSTRUCTIONS */
+enum {
+  RDMA_NL_LS_OP_RESOLVE = 0,
+  RDMA_NL_LS_OP_SET_TIMEOUT,
+  RDMA_NL_LS_NUM_OPS
 /* WARNING: DO NOT EDIT, AUTO-GENERATED CODE - SEE TOP FOR INSTRUCTIONS */
 };
+#define RDMA_NL_LS_F_ERR 0x0100
+enum {
+  LS_RESOLVE_PATH_USE_ALL = 0,
+/* WARNING: DO NOT EDIT, AUTO-GENERATED CODE - SEE TOP FOR INSTRUCTIONS */
+  LS_RESOLVE_PATH_USE_UNIDIRECTIONAL,
+  LS_RESOLVE_PATH_USE_GMP,
+  LS_RESOLVE_PATH_USE_MAX
+};
+/* WARNING: DO NOT EDIT, AUTO-GENERATED CODE - SEE TOP FOR INSTRUCTIONS */
+#define LS_DEVICE_NAME_MAX 64
+struct rdma_ls_resolve_header {
+  __u8 device_name[LS_DEVICE_NAME_MAX];
+  __u8 port_num;
+/* WARNING: DO NOT EDIT, AUTO-GENERATED CODE - SEE TOP FOR INSTRUCTIONS */
+  __u8 path_use;
+};
+#define RDMA_NLA_F_MANDATORY (1 << 13)
+#define RDMA_NLA_TYPE_MASK (~(NLA_F_NESTED | NLA_F_NET_BYTEORDER | RDMA_NLA_F_MANDATORY))
+/* WARNING: DO NOT EDIT, AUTO-GENERATED CODE - SEE TOP FOR INSTRUCTIONS */
+enum {
+  LS_NLA_TYPE_UNSPEC = 0,
+  LS_NLA_TYPE_PATH_RECORD,
+  LS_NLA_TYPE_TIMEOUT,
+/* WARNING: DO NOT EDIT, AUTO-GENERATED CODE - SEE TOP FOR INSTRUCTIONS */
+  LS_NLA_TYPE_SERVICE_ID,
+  LS_NLA_TYPE_DGID,
+  LS_NLA_TYPE_SGID,
+  LS_NLA_TYPE_TCLASS,
+/* WARNING: DO NOT EDIT, AUTO-GENERATED CODE - SEE TOP FOR INSTRUCTIONS */
+  LS_NLA_TYPE_PKEY,
+  LS_NLA_TYPE_QOS_CLASS,
+  LS_NLA_TYPE_MAX
+};
+/* WARNING: DO NOT EDIT, AUTO-GENERATED CODE - SEE TOP FOR INSTRUCTIONS */
+struct rdma_nla_ls_gid {
+  __u8 gid[16];
+};
 #endif
+/* WARNING: DO NOT EDIT, AUTO-GENERATED CODE - SEE TOP FOR INSTRUCTIONS */
diff --git a/libc/kernel/uapi/scsi/cxlflash_ioctl.h b/libc/kernel/uapi/scsi/cxlflash_ioctl.h
new file mode 100644
index 0000000..fe7c822
--- /dev/null
+++ b/libc/kernel/uapi/scsi/cxlflash_ioctl.h
@@ -0,0 +1,168 @@
+/****************************************************************************
+ ****************************************************************************
+ ***
+ ***   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 _CXLFLASH_IOCTL_H
+#define _CXLFLASH_IOCTL_H
+#include <linux/types.h>
+#define DK_CXLFLASH_VERSION_0 0
+/* WARNING: DO NOT EDIT, AUTO-GENERATED CODE - SEE TOP FOR INSTRUCTIONS */
+struct dk_cxlflash_hdr {
+  __u16 version;
+  __u16 rsvd[3];
+  __u64 flags;
+/* WARNING: DO NOT EDIT, AUTO-GENERATED CODE - SEE TOP FOR INSTRUCTIONS */
+  __u64 return_flags;
+};
+#define DK_CXLFLASH_ATTACH_REUSE_CONTEXT 0x8000000000000000ULL
+struct dk_cxlflash_attach {
+/* WARNING: DO NOT EDIT, AUTO-GENERATED CODE - SEE TOP FOR INSTRUCTIONS */
+  struct dk_cxlflash_hdr hdr;
+  __u64 num_interrupts;
+  __u64 context_id;
+  __u64 mmio_size;
+/* WARNING: DO NOT EDIT, AUTO-GENERATED CODE - SEE TOP FOR INSTRUCTIONS */
+  __u64 block_size;
+  __u64 adap_fd;
+  __u64 last_lba;
+  __u64 max_xfer;
+/* WARNING: DO NOT EDIT, AUTO-GENERATED CODE - SEE TOP FOR INSTRUCTIONS */
+  __u64 reserved[8];
+};
+struct dk_cxlflash_detach {
+  struct dk_cxlflash_hdr hdr;
+/* WARNING: DO NOT EDIT, AUTO-GENERATED CODE - SEE TOP FOR INSTRUCTIONS */
+  __u64 context_id;
+  __u64 reserved[8];
+};
+struct dk_cxlflash_udirect {
+/* WARNING: DO NOT EDIT, AUTO-GENERATED CODE - SEE TOP FOR INSTRUCTIONS */
+  struct dk_cxlflash_hdr hdr;
+  __u64 context_id;
+  __u64 rsrc_handle;
+  __u64 last_lba;
+/* WARNING: DO NOT EDIT, AUTO-GENERATED CODE - SEE TOP FOR INSTRUCTIONS */
+  __u64 reserved[8];
+};
+#define DK_CXLFLASH_UVIRTUAL_NEED_WRITE_SAME 0x8000000000000000ULL
+struct dk_cxlflash_uvirtual {
+/* WARNING: DO NOT EDIT, AUTO-GENERATED CODE - SEE TOP FOR INSTRUCTIONS */
+  struct dk_cxlflash_hdr hdr;
+  __u64 context_id;
+  __u64 lun_size;
+  __u64 rsrc_handle;
+/* WARNING: DO NOT EDIT, AUTO-GENERATED CODE - SEE TOP FOR INSTRUCTIONS */
+  __u64 last_lba;
+  __u64 reserved[8];
+};
+struct dk_cxlflash_release {
+/* WARNING: DO NOT EDIT, AUTO-GENERATED CODE - SEE TOP FOR INSTRUCTIONS */
+  struct dk_cxlflash_hdr hdr;
+  __u64 context_id;
+  __u64 rsrc_handle;
+  __u64 reserved[8];
+/* WARNING: DO NOT EDIT, AUTO-GENERATED CODE - SEE TOP FOR INSTRUCTIONS */
+};
+struct dk_cxlflash_resize {
+  struct dk_cxlflash_hdr hdr;
+  __u64 context_id;
+/* WARNING: DO NOT EDIT, AUTO-GENERATED CODE - SEE TOP FOR INSTRUCTIONS */
+  __u64 rsrc_handle;
+  __u64 req_size;
+  __u64 last_lba;
+  __u64 reserved[8];
+/* WARNING: DO NOT EDIT, AUTO-GENERATED CODE - SEE TOP FOR INSTRUCTIONS */
+};
+struct dk_cxlflash_clone {
+  struct dk_cxlflash_hdr hdr;
+  __u64 context_id_src;
+/* WARNING: DO NOT EDIT, AUTO-GENERATED CODE - SEE TOP FOR INSTRUCTIONS */
+  __u64 context_id_dst;
+  __u64 adap_fd_src;
+  __u64 reserved[8];
+};
+/* WARNING: DO NOT EDIT, AUTO-GENERATED CODE - SEE TOP FOR INSTRUCTIONS */
+#define DK_CXLFLASH_VERIFY_SENSE_LEN 18
+#define DK_CXLFLASH_VERIFY_HINT_SENSE 0x8000000000000000ULL
+struct dk_cxlflash_verify {
+  struct dk_cxlflash_hdr hdr;
+/* WARNING: DO NOT EDIT, AUTO-GENERATED CODE - SEE TOP FOR INSTRUCTIONS */
+  __u64 context_id;
+  __u64 rsrc_handle;
+  __u64 hint;
+  __u64 last_lba;
+/* WARNING: DO NOT EDIT, AUTO-GENERATED CODE - SEE TOP FOR INSTRUCTIONS */
+  __u8 sense_data[DK_CXLFLASH_VERIFY_SENSE_LEN];
+  __u8 pad[6];
+  __u64 reserved[8];
+};
+/* WARNING: DO NOT EDIT, AUTO-GENERATED CODE - SEE TOP FOR INSTRUCTIONS */
+#define DK_CXLFLASH_RECOVER_AFU_CONTEXT_RESET 0x8000000000000000ULL
+struct dk_cxlflash_recover_afu {
+  struct dk_cxlflash_hdr hdr;
+  __u64 reason;
+/* WARNING: DO NOT EDIT, AUTO-GENERATED CODE - SEE TOP FOR INSTRUCTIONS */
+  __u64 context_id;
+  __u64 mmio_size;
+  __u64 adap_fd;
+  __u64 reserved[8];
+/* WARNING: DO NOT EDIT, AUTO-GENERATED CODE - SEE TOP FOR INSTRUCTIONS */
+};
+#define DK_CXLFLASH_MANAGE_LUN_WWID_LEN 16
+#define DK_CXLFLASH_MANAGE_LUN_ENABLE_SUPERPIPE 0x8000000000000000ULL
+#define DK_CXLFLASH_MANAGE_LUN_DISABLE_SUPERPIPE 0x4000000000000000ULL
+/* WARNING: DO NOT EDIT, AUTO-GENERATED CODE - SEE TOP FOR INSTRUCTIONS */
+#define DK_CXLFLASH_MANAGE_LUN_ALL_PORTS_ACCESSIBLE 0x2000000000000000ULL
+struct dk_cxlflash_manage_lun {
+  struct dk_cxlflash_hdr hdr;
+  __u8 wwid[DK_CXLFLASH_MANAGE_LUN_WWID_LEN];
+/* WARNING: DO NOT EDIT, AUTO-GENERATED CODE - SEE TOP FOR INSTRUCTIONS */
+  __u64 reserved[8];
+};
+union cxlflash_ioctls {
+  struct dk_cxlflash_attach attach;
+/* WARNING: DO NOT EDIT, AUTO-GENERATED CODE - SEE TOP FOR INSTRUCTIONS */
+  struct dk_cxlflash_detach detach;
+  struct dk_cxlflash_udirect udirect;
+  struct dk_cxlflash_uvirtual uvirtual;
+  struct dk_cxlflash_release release;
+/* WARNING: DO NOT EDIT, AUTO-GENERATED CODE - SEE TOP FOR INSTRUCTIONS */
+  struct dk_cxlflash_resize resize;
+  struct dk_cxlflash_clone clone;
+  struct dk_cxlflash_verify verify;
+  struct dk_cxlflash_recover_afu recover_afu;
+/* WARNING: DO NOT EDIT, AUTO-GENERATED CODE - SEE TOP FOR INSTRUCTIONS */
+  struct dk_cxlflash_manage_lun manage_lun;
+};
+#define MAX_CXLFLASH_IOCTL_SZ (sizeof(union cxlflash_ioctls))
+#define CXL_MAGIC 0xCA
+/* WARNING: DO NOT EDIT, AUTO-GENERATED CODE - SEE TOP FOR INSTRUCTIONS */
+#define CXL_IOWR(_n,_s) _IOWR(CXL_MAGIC, _n, struct _s)
+#define DK_CXLFLASH_ATTACH CXL_IOWR(0x80, dk_cxlflash_attach)
+#define DK_CXLFLASH_USER_DIRECT CXL_IOWR(0x81, dk_cxlflash_udirect)
+#define DK_CXLFLASH_RELEASE CXL_IOWR(0x82, dk_cxlflash_release)
+/* WARNING: DO NOT EDIT, AUTO-GENERATED CODE - SEE TOP FOR INSTRUCTIONS */
+#define DK_CXLFLASH_DETACH CXL_IOWR(0x83, dk_cxlflash_detach)
+#define DK_CXLFLASH_VERIFY CXL_IOWR(0x84, dk_cxlflash_verify)
+#define DK_CXLFLASH_RECOVER_AFU CXL_IOWR(0x85, dk_cxlflash_recover_afu)
+#define DK_CXLFLASH_MANAGE_LUN CXL_IOWR(0x86, dk_cxlflash_manage_lun)
+/* WARNING: DO NOT EDIT, AUTO-GENERATED CODE - SEE TOP FOR INSTRUCTIONS */
+#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)
+#endif
+/* WARNING: DO NOT EDIT, AUTO-GENERATED CODE - SEE TOP FOR INSTRUCTIONS */
diff --git a/libc/kernel/uapi/sound/asequencer.h b/libc/kernel/uapi/sound/asequencer.h
index fb58991..3596012 100644
--- a/libc/kernel/uapi/sound/asequencer.h
+++ b/libc/kernel/uapi/sound/asequencer.h
@@ -18,483 +18,484 @@
  ****************************************************************************/
 #ifndef _UAPI__SOUND_ASEQUENCER_H
 #define _UAPI__SOUND_ASEQUENCER_H
+#include <sound/asound.h>
 #define SNDRV_SEQ_VERSION SNDRV_PROTOCOL_VERSION(1, 0, 1)
-#define SNDRV_SEQ_EVENT_SYSTEM 0
 /* WARNING: DO NOT EDIT, AUTO-GENERATED CODE - SEE TOP FOR INSTRUCTIONS */
+#define SNDRV_SEQ_EVENT_SYSTEM 0
 #define SNDRV_SEQ_EVENT_RESULT 1
 #define SNDRV_SEQ_EVENT_NOTE 5
 #define SNDRV_SEQ_EVENT_NOTEON 6
-#define SNDRV_SEQ_EVENT_NOTEOFF 7
 /* WARNING: DO NOT EDIT, AUTO-GENERATED CODE - SEE TOP FOR INSTRUCTIONS */
+#define SNDRV_SEQ_EVENT_NOTEOFF 7
 #define SNDRV_SEQ_EVENT_KEYPRESS 8
 #define SNDRV_SEQ_EVENT_CONTROLLER 10
 #define SNDRV_SEQ_EVENT_PGMCHANGE 11
-#define SNDRV_SEQ_EVENT_CHANPRESS 12
 /* WARNING: DO NOT EDIT, AUTO-GENERATED CODE - SEE TOP FOR INSTRUCTIONS */
+#define SNDRV_SEQ_EVENT_CHANPRESS 12
 #define SNDRV_SEQ_EVENT_PITCHBEND 13
 #define SNDRV_SEQ_EVENT_CONTROL14 14
 #define SNDRV_SEQ_EVENT_NONREGPARAM 15
-#define SNDRV_SEQ_EVENT_REGPARAM 16
 /* WARNING: DO NOT EDIT, AUTO-GENERATED CODE - SEE TOP FOR INSTRUCTIONS */
+#define SNDRV_SEQ_EVENT_REGPARAM 16
 #define SNDRV_SEQ_EVENT_SONGPOS 20
 #define SNDRV_SEQ_EVENT_SONGSEL 21
 #define SNDRV_SEQ_EVENT_QFRAME 22
-#define SNDRV_SEQ_EVENT_TIMESIGN 23
 /* WARNING: DO NOT EDIT, AUTO-GENERATED CODE - SEE TOP FOR INSTRUCTIONS */
+#define SNDRV_SEQ_EVENT_TIMESIGN 23
 #define SNDRV_SEQ_EVENT_KEYSIGN 24
 #define SNDRV_SEQ_EVENT_START 30
 #define SNDRV_SEQ_EVENT_CONTINUE 31
-#define SNDRV_SEQ_EVENT_STOP 32
 /* WARNING: DO NOT EDIT, AUTO-GENERATED CODE - SEE TOP FOR INSTRUCTIONS */
+#define SNDRV_SEQ_EVENT_STOP 32
 #define SNDRV_SEQ_EVENT_SETPOS_TICK 33
 #define SNDRV_SEQ_EVENT_SETPOS_TIME 34
 #define SNDRV_SEQ_EVENT_TEMPO 35
-#define SNDRV_SEQ_EVENT_CLOCK 36
 /* WARNING: DO NOT EDIT, AUTO-GENERATED CODE - SEE TOP FOR INSTRUCTIONS */
+#define SNDRV_SEQ_EVENT_CLOCK 36
 #define SNDRV_SEQ_EVENT_TICK 37
 #define SNDRV_SEQ_EVENT_QUEUE_SKEW 38
 #define SNDRV_SEQ_EVENT_TUNE_REQUEST 40
-#define SNDRV_SEQ_EVENT_RESET 41
 /* WARNING: DO NOT EDIT, AUTO-GENERATED CODE - SEE TOP FOR INSTRUCTIONS */
+#define SNDRV_SEQ_EVENT_RESET 41
 #define SNDRV_SEQ_EVENT_SENSING 42
 #define SNDRV_SEQ_EVENT_ECHO 50
 #define SNDRV_SEQ_EVENT_OSS 51
-#define SNDRV_SEQ_EVENT_CLIENT_START 60
 /* WARNING: DO NOT EDIT, AUTO-GENERATED CODE - SEE TOP FOR INSTRUCTIONS */
+#define SNDRV_SEQ_EVENT_CLIENT_START 60
 #define SNDRV_SEQ_EVENT_CLIENT_EXIT 61
 #define SNDRV_SEQ_EVENT_CLIENT_CHANGE 62
 #define SNDRV_SEQ_EVENT_PORT_START 63
-#define SNDRV_SEQ_EVENT_PORT_EXIT 64
 /* WARNING: DO NOT EDIT, AUTO-GENERATED CODE - SEE TOP FOR INSTRUCTIONS */
+#define SNDRV_SEQ_EVENT_PORT_EXIT 64
 #define SNDRV_SEQ_EVENT_PORT_CHANGE 65
 #define SNDRV_SEQ_EVENT_PORT_SUBSCRIBED 66
 #define SNDRV_SEQ_EVENT_PORT_UNSUBSCRIBED 67
-#define SNDRV_SEQ_EVENT_USR0 90
 /* WARNING: DO NOT EDIT, AUTO-GENERATED CODE - SEE TOP FOR INSTRUCTIONS */
+#define SNDRV_SEQ_EVENT_USR0 90
 #define SNDRV_SEQ_EVENT_USR1 91
 #define SNDRV_SEQ_EVENT_USR2 92
 #define SNDRV_SEQ_EVENT_USR3 93
-#define SNDRV_SEQ_EVENT_USR4 94
 /* WARNING: DO NOT EDIT, AUTO-GENERATED CODE - SEE TOP FOR INSTRUCTIONS */
+#define SNDRV_SEQ_EVENT_USR4 94
 #define SNDRV_SEQ_EVENT_USR5 95
 #define SNDRV_SEQ_EVENT_USR6 96
 #define SNDRV_SEQ_EVENT_USR7 97
-#define SNDRV_SEQ_EVENT_USR8 98
 /* WARNING: DO NOT EDIT, AUTO-GENERATED CODE - SEE TOP FOR INSTRUCTIONS */
+#define SNDRV_SEQ_EVENT_USR8 98
 #define SNDRV_SEQ_EVENT_USR9 99
 #define SNDRV_SEQ_EVENT_SYSEX 130
 #define SNDRV_SEQ_EVENT_BOUNCE 131
-#define SNDRV_SEQ_EVENT_USR_VAR0 135
 /* WARNING: DO NOT EDIT, AUTO-GENERATED CODE - SEE TOP FOR INSTRUCTIONS */
+#define SNDRV_SEQ_EVENT_USR_VAR0 135
 #define SNDRV_SEQ_EVENT_USR_VAR1 136
 #define SNDRV_SEQ_EVENT_USR_VAR2 137
 #define SNDRV_SEQ_EVENT_USR_VAR3 138
-#define SNDRV_SEQ_EVENT_USR_VAR4 139
 /* WARNING: DO NOT EDIT, AUTO-GENERATED CODE - SEE TOP FOR INSTRUCTIONS */
+#define SNDRV_SEQ_EVENT_USR_VAR4 139
 #define SNDRV_SEQ_EVENT_KERNEL_ERROR 150
 #define SNDRV_SEQ_EVENT_KERNEL_QUOTE 151
 #define SNDRV_SEQ_EVENT_NONE 255
-typedef unsigned char snd_seq_event_type_t;
 /* WARNING: DO NOT EDIT, AUTO-GENERATED CODE - SEE TOP FOR INSTRUCTIONS */
+typedef unsigned char snd_seq_event_type_t;
 struct snd_seq_addr {
   unsigned char client;
   unsigned char port;
-};
 /* WARNING: DO NOT EDIT, AUTO-GENERATED CODE - SEE TOP FOR INSTRUCTIONS */
+};
 struct snd_seq_connect {
   struct snd_seq_addr sender;
   struct snd_seq_addr dest;
-};
 /* WARNING: DO NOT EDIT, AUTO-GENERATED CODE - SEE TOP FOR INSTRUCTIONS */
+};
 #define SNDRV_SEQ_ADDRESS_UNKNOWN 253
 #define SNDRV_SEQ_ADDRESS_SUBSCRIBERS 254
 #define SNDRV_SEQ_ADDRESS_BROADCAST 255
-#define SNDRV_SEQ_QUEUE_DIRECT 253
 /* WARNING: DO NOT EDIT, AUTO-GENERATED CODE - SEE TOP FOR INSTRUCTIONS */
+#define SNDRV_SEQ_QUEUE_DIRECT 253
 #define SNDRV_SEQ_TIME_STAMP_TICK (0 << 0)
 #define SNDRV_SEQ_TIME_STAMP_REAL (1 << 0)
 #define SNDRV_SEQ_TIME_STAMP_MASK (1 << 0)
-#define SNDRV_SEQ_TIME_MODE_ABS (0 << 1)
 /* WARNING: DO NOT EDIT, AUTO-GENERATED CODE - SEE TOP FOR INSTRUCTIONS */
+#define SNDRV_SEQ_TIME_MODE_ABS (0 << 1)
 #define SNDRV_SEQ_TIME_MODE_REL (1 << 1)
 #define SNDRV_SEQ_TIME_MODE_MASK (1 << 1)
 #define SNDRV_SEQ_EVENT_LENGTH_FIXED (0 << 2)
-#define SNDRV_SEQ_EVENT_LENGTH_VARIABLE (1 << 2)
 /* WARNING: DO NOT EDIT, AUTO-GENERATED CODE - SEE TOP FOR INSTRUCTIONS */
+#define SNDRV_SEQ_EVENT_LENGTH_VARIABLE (1 << 2)
 #define SNDRV_SEQ_EVENT_LENGTH_VARUSR (2 << 2)
 #define SNDRV_SEQ_EVENT_LENGTH_MASK (3 << 2)
 #define SNDRV_SEQ_PRIORITY_NORMAL (0 << 4)
-#define SNDRV_SEQ_PRIORITY_HIGH (1 << 4)
 /* WARNING: DO NOT EDIT, AUTO-GENERATED CODE - SEE TOP FOR INSTRUCTIONS */
+#define SNDRV_SEQ_PRIORITY_HIGH (1 << 4)
 #define SNDRV_SEQ_PRIORITY_MASK (1 << 4)
 struct snd_seq_ev_note {
   unsigned char channel;
-  unsigned char note;
 /* WARNING: DO NOT EDIT, AUTO-GENERATED CODE - SEE TOP FOR INSTRUCTIONS */
+  unsigned char note;
   unsigned char velocity;
   unsigned char off_velocity;
   unsigned int duration;
-};
 /* WARNING: DO NOT EDIT, AUTO-GENERATED CODE - SEE TOP FOR INSTRUCTIONS */
+};
 struct snd_seq_ev_ctrl {
   unsigned char channel;
   unsigned char unused1, unused2, unused3;
-  unsigned int param;
 /* WARNING: DO NOT EDIT, AUTO-GENERATED CODE - SEE TOP FOR INSTRUCTIONS */
+  unsigned int param;
   signed int value;
 };
 struct snd_seq_ev_raw8 {
-  unsigned char d[12];
 /* WARNING: DO NOT EDIT, AUTO-GENERATED CODE - SEE TOP FOR INSTRUCTIONS */
+  unsigned char d[12];
 };
 struct snd_seq_ev_raw32 {
   unsigned int d[3];
-};
 /* WARNING: DO NOT EDIT, AUTO-GENERATED CODE - SEE TOP FOR INSTRUCTIONS */
+};
 struct snd_seq_ev_ext {
   unsigned int len;
   void * ptr;
-} __attribute__((packed));
 /* WARNING: DO NOT EDIT, AUTO-GENERATED CODE - SEE TOP FOR INSTRUCTIONS */
+} __attribute__((packed));
 struct snd_seq_result {
   int event;
   int result;
-};
 /* WARNING: DO NOT EDIT, AUTO-GENERATED CODE - SEE TOP FOR INSTRUCTIONS */
+};
 struct snd_seq_real_time {
   unsigned int tv_sec;
   unsigned int tv_nsec;
-};
 /* WARNING: DO NOT EDIT, AUTO-GENERATED CODE - SEE TOP FOR INSTRUCTIONS */
+};
 typedef unsigned int snd_seq_tick_time_t;
 union snd_seq_timestamp {
   snd_seq_tick_time_t tick;
-  struct snd_seq_real_time time;
 /* WARNING: DO NOT EDIT, AUTO-GENERATED CODE - SEE TOP FOR INSTRUCTIONS */
+  struct snd_seq_real_time time;
 };
 struct snd_seq_queue_skew {
   unsigned int value;
-  unsigned int base;
 /* WARNING: DO NOT EDIT, AUTO-GENERATED CODE - SEE TOP FOR INSTRUCTIONS */
+  unsigned int base;
 };
 struct snd_seq_ev_queue_control {
   unsigned char queue;
-  unsigned char pad[3];
 /* WARNING: DO NOT EDIT, AUTO-GENERATED CODE - SEE TOP FOR INSTRUCTIONS */
+  unsigned char pad[3];
   union {
     signed int value;
     union snd_seq_timestamp time;
-    unsigned int position;
 /* WARNING: DO NOT EDIT, AUTO-GENERATED CODE - SEE TOP FOR INSTRUCTIONS */
+    unsigned int position;
     struct snd_seq_queue_skew skew;
     unsigned int d32[2];
     unsigned char d8[8];
-  } param;
 /* WARNING: DO NOT EDIT, AUTO-GENERATED CODE - SEE TOP FOR INSTRUCTIONS */
+  } param;
 };
 struct snd_seq_ev_quote {
   struct snd_seq_addr origin;
-  unsigned short value;
 /* WARNING: DO NOT EDIT, AUTO-GENERATED CODE - SEE TOP FOR INSTRUCTIONS */
+  unsigned short value;
   struct snd_seq_event * event;
 } __attribute__((packed));
 struct snd_seq_event {
-  snd_seq_event_type_t type;
 /* WARNING: DO NOT EDIT, AUTO-GENERATED CODE - SEE TOP FOR INSTRUCTIONS */
+  snd_seq_event_type_t type;
   unsigned char flags;
   char tag;
   unsigned char queue;
-  union snd_seq_timestamp time;
 /* WARNING: DO NOT EDIT, AUTO-GENERATED CODE - SEE TOP FOR INSTRUCTIONS */
+  union snd_seq_timestamp time;
   struct snd_seq_addr source;
   struct snd_seq_addr dest;
   union {
-    struct snd_seq_ev_note note;
 /* WARNING: DO NOT EDIT, AUTO-GENERATED CODE - SEE TOP FOR INSTRUCTIONS */
+    struct snd_seq_ev_note note;
     struct snd_seq_ev_ctrl control;
     struct snd_seq_ev_raw8 raw8;
     struct snd_seq_ev_raw32 raw32;
-    struct snd_seq_ev_ext ext;
 /* WARNING: DO NOT EDIT, AUTO-GENERATED CODE - SEE TOP FOR INSTRUCTIONS */
+    struct snd_seq_ev_ext ext;
     struct snd_seq_ev_queue_control queue;
     union snd_seq_timestamp time;
     struct snd_seq_addr addr;
-    struct snd_seq_connect connect;
 /* WARNING: DO NOT EDIT, AUTO-GENERATED CODE - SEE TOP FOR INSTRUCTIONS */
+    struct snd_seq_connect connect;
     struct snd_seq_result result;
     struct snd_seq_ev_quote quote;
   } data;
-};
 /* WARNING: DO NOT EDIT, AUTO-GENERATED CODE - SEE TOP FOR INSTRUCTIONS */
+};
 struct snd_seq_event_bounce {
   int err;
   struct snd_seq_event event;
-};
 /* WARNING: DO NOT EDIT, AUTO-GENERATED CODE - SEE TOP FOR INSTRUCTIONS */
+};
 struct snd_seq_system_info {
   int queues;
   int clients;
-  int ports;
 /* WARNING: DO NOT EDIT, AUTO-GENERATED CODE - SEE TOP FOR INSTRUCTIONS */
+  int ports;
   int channels;
   int cur_clients;
   int cur_queues;
-  char reserved[24];
 /* WARNING: DO NOT EDIT, AUTO-GENERATED CODE - SEE TOP FOR INSTRUCTIONS */
+  char reserved[24];
 };
 struct snd_seq_running_info {
   unsigned char client;
-  unsigned char big_endian;
 /* WARNING: DO NOT EDIT, AUTO-GENERATED CODE - SEE TOP FOR INSTRUCTIONS */
+  unsigned char big_endian;
   unsigned char cpu_mode;
   unsigned char pad;
   unsigned char reserved[12];
-};
 /* WARNING: DO NOT EDIT, AUTO-GENERATED CODE - SEE TOP FOR INSTRUCTIONS */
+};
 #define SNDRV_SEQ_CLIENT_SYSTEM 0
 #define SNDRV_SEQ_CLIENT_DUMMY 14
 #define SNDRV_SEQ_CLIENT_OSS 15
-typedef int __bitwise snd_seq_client_type_t;
 /* WARNING: DO NOT EDIT, AUTO-GENERATED CODE - SEE TOP FOR INSTRUCTIONS */
+typedef int __bitwise snd_seq_client_type_t;
 #define NO_CLIENT ((__force snd_seq_client_type_t) 0)
 #define USER_CLIENT ((__force snd_seq_client_type_t) 1)
 #define KERNEL_CLIENT ((__force snd_seq_client_type_t) 2)
-#define SNDRV_SEQ_FILTER_BROADCAST (1 << 0)
 /* WARNING: DO NOT EDIT, AUTO-GENERATED CODE - SEE TOP FOR INSTRUCTIONS */
+#define SNDRV_SEQ_FILTER_BROADCAST (1 << 0)
 #define SNDRV_SEQ_FILTER_MULTICAST (1 << 1)
 #define SNDRV_SEQ_FILTER_BOUNCE (1 << 2)
 #define SNDRV_SEQ_FILTER_USE_EVENT (1 << 31)
-struct snd_seq_client_info {
 /* WARNING: DO NOT EDIT, AUTO-GENERATED CODE - SEE TOP FOR INSTRUCTIONS */
+struct snd_seq_client_info {
   int client;
   snd_seq_client_type_t type;
   char name[64];
-  unsigned int filter;
 /* WARNING: DO NOT EDIT, AUTO-GENERATED CODE - SEE TOP FOR INSTRUCTIONS */
+  unsigned int filter;
   unsigned char multicast_filter[8];
   unsigned char event_filter[32];
   int num_ports;
-  int event_lost;
 /* WARNING: DO NOT EDIT, AUTO-GENERATED CODE - SEE TOP FOR INSTRUCTIONS */
+  int event_lost;
   char reserved[64];
 };
 struct snd_seq_client_pool {
-  int client;
 /* WARNING: DO NOT EDIT, AUTO-GENERATED CODE - SEE TOP FOR INSTRUCTIONS */
+  int client;
   int output_pool;
   int input_pool;
   int output_room;
-  int output_free;
 /* WARNING: DO NOT EDIT, AUTO-GENERATED CODE - SEE TOP FOR INSTRUCTIONS */
+  int output_free;
   int input_free;
   char reserved[64];
 };
-#define SNDRV_SEQ_REMOVE_INPUT (1 << 0)
 /* WARNING: DO NOT EDIT, AUTO-GENERATED CODE - SEE TOP FOR INSTRUCTIONS */
+#define SNDRV_SEQ_REMOVE_INPUT (1 << 0)
 #define SNDRV_SEQ_REMOVE_OUTPUT (1 << 1)
 #define SNDRV_SEQ_REMOVE_DEST (1 << 2)
 #define SNDRV_SEQ_REMOVE_DEST_CHANNEL (1 << 3)
-#define SNDRV_SEQ_REMOVE_TIME_BEFORE (1 << 4)
 /* WARNING: DO NOT EDIT, AUTO-GENERATED CODE - SEE TOP FOR INSTRUCTIONS */
+#define SNDRV_SEQ_REMOVE_TIME_BEFORE (1 << 4)
 #define SNDRV_SEQ_REMOVE_TIME_AFTER (1 << 5)
 #define SNDRV_SEQ_REMOVE_TIME_TICK (1 << 6)
 #define SNDRV_SEQ_REMOVE_EVENT_TYPE (1 << 7)
-#define SNDRV_SEQ_REMOVE_IGNORE_OFF (1 << 8)
 /* WARNING: DO NOT EDIT, AUTO-GENERATED CODE - SEE TOP FOR INSTRUCTIONS */
+#define SNDRV_SEQ_REMOVE_IGNORE_OFF (1 << 8)
 #define SNDRV_SEQ_REMOVE_TAG_MATCH (1 << 9)
 struct snd_seq_remove_events {
   unsigned int remove_mode;
-  union snd_seq_timestamp time;
 /* WARNING: DO NOT EDIT, AUTO-GENERATED CODE - SEE TOP FOR INSTRUCTIONS */
+  union snd_seq_timestamp time;
   unsigned char queue;
   struct snd_seq_addr dest;
   unsigned char channel;
-  int type;
 /* WARNING: DO NOT EDIT, AUTO-GENERATED CODE - SEE TOP FOR INSTRUCTIONS */
+  int type;
   char tag;
   int reserved[10];
 };
-#define SNDRV_SEQ_PORT_SYSTEM_TIMER 0
 /* WARNING: DO NOT EDIT, AUTO-GENERATED CODE - SEE TOP FOR INSTRUCTIONS */
+#define SNDRV_SEQ_PORT_SYSTEM_TIMER 0
 #define SNDRV_SEQ_PORT_SYSTEM_ANNOUNCE 1
 #define SNDRV_SEQ_PORT_CAP_READ (1 << 0)
 #define SNDRV_SEQ_PORT_CAP_WRITE (1 << 1)
-#define SNDRV_SEQ_PORT_CAP_SYNC_READ (1 << 2)
 /* WARNING: DO NOT EDIT, AUTO-GENERATED CODE - SEE TOP FOR INSTRUCTIONS */
+#define SNDRV_SEQ_PORT_CAP_SYNC_READ (1 << 2)
 #define SNDRV_SEQ_PORT_CAP_SYNC_WRITE (1 << 3)
 #define SNDRV_SEQ_PORT_CAP_DUPLEX (1 << 4)
 #define SNDRV_SEQ_PORT_CAP_SUBS_READ (1 << 5)
-#define SNDRV_SEQ_PORT_CAP_SUBS_WRITE (1 << 6)
 /* WARNING: DO NOT EDIT, AUTO-GENERATED CODE - SEE TOP FOR INSTRUCTIONS */
+#define SNDRV_SEQ_PORT_CAP_SUBS_WRITE (1 << 6)
 #define SNDRV_SEQ_PORT_CAP_NO_EXPORT (1 << 7)
 #define SNDRV_SEQ_PORT_TYPE_SPECIFIC (1 << 0)
 #define SNDRV_SEQ_PORT_TYPE_MIDI_GENERIC (1 << 1)
-#define SNDRV_SEQ_PORT_TYPE_MIDI_GM (1 << 2)
 /* WARNING: DO NOT EDIT, AUTO-GENERATED CODE - SEE TOP FOR INSTRUCTIONS */
+#define SNDRV_SEQ_PORT_TYPE_MIDI_GM (1 << 2)
 #define SNDRV_SEQ_PORT_TYPE_MIDI_GS (1 << 3)
 #define SNDRV_SEQ_PORT_TYPE_MIDI_XG (1 << 4)
 #define SNDRV_SEQ_PORT_TYPE_MIDI_MT32 (1 << 5)
-#define SNDRV_SEQ_PORT_TYPE_MIDI_GM2 (1 << 6)
 /* WARNING: DO NOT EDIT, AUTO-GENERATED CODE - SEE TOP FOR INSTRUCTIONS */
+#define SNDRV_SEQ_PORT_TYPE_MIDI_GM2 (1 << 6)
 #define SNDRV_SEQ_PORT_TYPE_SYNTH (1 << 10)
 #define SNDRV_SEQ_PORT_TYPE_DIRECT_SAMPLE (1 << 11)
 #define SNDRV_SEQ_PORT_TYPE_SAMPLE (1 << 12)
-#define SNDRV_SEQ_PORT_TYPE_HARDWARE (1 << 16)
 /* WARNING: DO NOT EDIT, AUTO-GENERATED CODE - SEE TOP FOR INSTRUCTIONS */
+#define SNDRV_SEQ_PORT_TYPE_HARDWARE (1 << 16)
 #define SNDRV_SEQ_PORT_TYPE_SOFTWARE (1 << 17)
 #define SNDRV_SEQ_PORT_TYPE_SYNTHESIZER (1 << 18)
 #define SNDRV_SEQ_PORT_TYPE_PORT (1 << 19)
-#define SNDRV_SEQ_PORT_TYPE_APPLICATION (1 << 20)
 /* WARNING: DO NOT EDIT, AUTO-GENERATED CODE - SEE TOP FOR INSTRUCTIONS */
+#define SNDRV_SEQ_PORT_TYPE_APPLICATION (1 << 20)
 #define SNDRV_SEQ_PORT_FLG_GIVEN_PORT (1 << 0)
 #define SNDRV_SEQ_PORT_FLG_TIMESTAMP (1 << 1)
 #define SNDRV_SEQ_PORT_FLG_TIME_REAL (1 << 2)
-struct snd_seq_port_info {
 /* WARNING: DO NOT EDIT, AUTO-GENERATED CODE - SEE TOP FOR INSTRUCTIONS */
+struct snd_seq_port_info {
   struct snd_seq_addr addr;
   char name[64];
   unsigned int capability;
-  unsigned int type;
 /* WARNING: DO NOT EDIT, AUTO-GENERATED CODE - SEE TOP FOR INSTRUCTIONS */
+  unsigned int type;
   int midi_channels;
   int midi_voices;
   int synth_voices;
-  int read_use;
 /* WARNING: DO NOT EDIT, AUTO-GENERATED CODE - SEE TOP FOR INSTRUCTIONS */
+  int read_use;
   int write_use;
   void * kernel;
   unsigned int flags;
-  unsigned char time_queue;
 /* WARNING: DO NOT EDIT, AUTO-GENERATED CODE - SEE TOP FOR INSTRUCTIONS */
+  unsigned char time_queue;
   char reserved[59];
 };
 #define SNDRV_SEQ_QUEUE_FLG_SYNC (1 << 0)
-struct snd_seq_queue_info {
 /* WARNING: DO NOT EDIT, AUTO-GENERATED CODE - SEE TOP FOR INSTRUCTIONS */
+struct snd_seq_queue_info {
   int queue;
   int owner;
   unsigned locked : 1;
-  char name[64];
 /* WARNING: DO NOT EDIT, AUTO-GENERATED CODE - SEE TOP FOR INSTRUCTIONS */
+  char name[64];
   unsigned int flags;
   char reserved[60];
 };
-struct snd_seq_queue_status {
 /* WARNING: DO NOT EDIT, AUTO-GENERATED CODE - SEE TOP FOR INSTRUCTIONS */
+struct snd_seq_queue_status {
   int queue;
   int events;
   snd_seq_tick_time_t tick;
-  struct snd_seq_real_time time;
 /* WARNING: DO NOT EDIT, AUTO-GENERATED CODE - SEE TOP FOR INSTRUCTIONS */
+  struct snd_seq_real_time time;
   int running;
   int flags;
   char reserved[64];
-};
 /* WARNING: DO NOT EDIT, AUTO-GENERATED CODE - SEE TOP FOR INSTRUCTIONS */
+};
 struct snd_seq_queue_tempo {
   int queue;
   unsigned int tempo;
-  int ppq;
 /* WARNING: DO NOT EDIT, AUTO-GENERATED CODE - SEE TOP FOR INSTRUCTIONS */
+  int ppq;
   unsigned int skew_value;
   unsigned int skew_base;
   char reserved[24];
-};
 /* WARNING: DO NOT EDIT, AUTO-GENERATED CODE - SEE TOP FOR INSTRUCTIONS */
+};
 #define SNDRV_SEQ_TIMER_ALSA 0
 #define SNDRV_SEQ_TIMER_MIDI_CLOCK 1
 #define SNDRV_SEQ_TIMER_MIDI_TICK 2
-struct snd_seq_queue_timer {
 /* WARNING: DO NOT EDIT, AUTO-GENERATED CODE - SEE TOP FOR INSTRUCTIONS */
+struct snd_seq_queue_timer {
   int queue;
   int type;
   union {
-    struct {
 /* WARNING: DO NOT EDIT, AUTO-GENERATED CODE - SEE TOP FOR INSTRUCTIONS */
+    struct {
       struct snd_timer_id id;
       unsigned int resolution;
     } alsa;
-  } u;
 /* WARNING: DO NOT EDIT, AUTO-GENERATED CODE - SEE TOP FOR INSTRUCTIONS */
+  } u;
   char reserved[64];
 };
 struct snd_seq_queue_client {
-  int queue;
 /* WARNING: DO NOT EDIT, AUTO-GENERATED CODE - SEE TOP FOR INSTRUCTIONS */
+  int queue;
   int client;
   int used;
   char reserved[64];
-};
 /* WARNING: DO NOT EDIT, AUTO-GENERATED CODE - SEE TOP FOR INSTRUCTIONS */
+};
 #define SNDRV_SEQ_PORT_SUBS_EXCLUSIVE (1 << 0)
 #define SNDRV_SEQ_PORT_SUBS_TIMESTAMP (1 << 1)
 #define SNDRV_SEQ_PORT_SUBS_TIME_REAL (1 << 2)
-struct snd_seq_port_subscribe {
 /* WARNING: DO NOT EDIT, AUTO-GENERATED CODE - SEE TOP FOR INSTRUCTIONS */
+struct snd_seq_port_subscribe {
   struct snd_seq_addr sender;
   struct snd_seq_addr dest;
   unsigned int voices;
-  unsigned int flags;
 /* WARNING: DO NOT EDIT, AUTO-GENERATED CODE - SEE TOP FOR INSTRUCTIONS */
+  unsigned int flags;
   unsigned char queue;
   unsigned char pad[3];
   char reserved[64];
-};
 /* WARNING: DO NOT EDIT, AUTO-GENERATED CODE - SEE TOP FOR INSTRUCTIONS */
+};
 #define SNDRV_SEQ_QUERY_SUBS_READ 0
 #define SNDRV_SEQ_QUERY_SUBS_WRITE 1
 struct snd_seq_query_subs {
-  struct snd_seq_addr root;
 /* WARNING: DO NOT EDIT, AUTO-GENERATED CODE - SEE TOP FOR INSTRUCTIONS */
+  struct snd_seq_addr root;
   int type;
   int index;
   int num_subs;
-  struct snd_seq_addr addr;
 /* WARNING: DO NOT EDIT, AUTO-GENERATED CODE - SEE TOP FOR INSTRUCTIONS */
+  struct snd_seq_addr addr;
   unsigned char queue;
   unsigned int flags;
   char reserved[64];
-};
 /* WARNING: DO NOT EDIT, AUTO-GENERATED CODE - SEE TOP FOR INSTRUCTIONS */
+};
 #define SNDRV_SEQ_IOCTL_PVERSION _IOR('S', 0x00, int)
 #define SNDRV_SEQ_IOCTL_CLIENT_ID _IOR('S', 0x01, int)
 #define SNDRV_SEQ_IOCTL_SYSTEM_INFO _IOWR('S', 0x02, struct snd_seq_system_info)
-#define SNDRV_SEQ_IOCTL_RUNNING_MODE _IOWR('S', 0x03, struct snd_seq_running_info)
 /* WARNING: DO NOT EDIT, AUTO-GENERATED CODE - SEE TOP FOR INSTRUCTIONS */
+#define SNDRV_SEQ_IOCTL_RUNNING_MODE _IOWR('S', 0x03, struct snd_seq_running_info)
 #define SNDRV_SEQ_IOCTL_GET_CLIENT_INFO _IOWR('S', 0x10, struct snd_seq_client_info)
 #define SNDRV_SEQ_IOCTL_SET_CLIENT_INFO _IOW('S', 0x11, struct snd_seq_client_info)
 #define SNDRV_SEQ_IOCTL_CREATE_PORT _IOWR('S', 0x20, struct snd_seq_port_info)
-#define SNDRV_SEQ_IOCTL_DELETE_PORT _IOW('S', 0x21, struct snd_seq_port_info)
 /* WARNING: DO NOT EDIT, AUTO-GENERATED CODE - SEE TOP FOR INSTRUCTIONS */
+#define SNDRV_SEQ_IOCTL_DELETE_PORT _IOW('S', 0x21, struct snd_seq_port_info)
 #define SNDRV_SEQ_IOCTL_GET_PORT_INFO _IOWR('S', 0x22, struct snd_seq_port_info)
 #define SNDRV_SEQ_IOCTL_SET_PORT_INFO _IOW('S', 0x23, struct snd_seq_port_info)
 #define SNDRV_SEQ_IOCTL_SUBSCRIBE_PORT _IOW('S', 0x30, struct snd_seq_port_subscribe)
-#define SNDRV_SEQ_IOCTL_UNSUBSCRIBE_PORT _IOW('S', 0x31, struct snd_seq_port_subscribe)
 /* WARNING: DO NOT EDIT, AUTO-GENERATED CODE - SEE TOP FOR INSTRUCTIONS */
+#define SNDRV_SEQ_IOCTL_UNSUBSCRIBE_PORT _IOW('S', 0x31, struct snd_seq_port_subscribe)
 #define SNDRV_SEQ_IOCTL_CREATE_QUEUE _IOWR('S', 0x32, struct snd_seq_queue_info)
 #define SNDRV_SEQ_IOCTL_DELETE_QUEUE _IOW('S', 0x33, struct snd_seq_queue_info)
 #define SNDRV_SEQ_IOCTL_GET_QUEUE_INFO _IOWR('S', 0x34, struct snd_seq_queue_info)
-#define SNDRV_SEQ_IOCTL_SET_QUEUE_INFO _IOWR('S', 0x35, struct snd_seq_queue_info)
 /* WARNING: DO NOT EDIT, AUTO-GENERATED CODE - SEE TOP FOR INSTRUCTIONS */
+#define SNDRV_SEQ_IOCTL_SET_QUEUE_INFO _IOWR('S', 0x35, struct snd_seq_queue_info)
 #define SNDRV_SEQ_IOCTL_GET_NAMED_QUEUE _IOWR('S', 0x36, struct snd_seq_queue_info)
 #define SNDRV_SEQ_IOCTL_GET_QUEUE_STATUS _IOWR('S', 0x40, struct snd_seq_queue_status)
 #define SNDRV_SEQ_IOCTL_GET_QUEUE_TEMPO _IOWR('S', 0x41, struct snd_seq_queue_tempo)
-#define SNDRV_SEQ_IOCTL_SET_QUEUE_TEMPO _IOW('S', 0x42, struct snd_seq_queue_tempo)
 /* WARNING: DO NOT EDIT, AUTO-GENERATED CODE - SEE TOP FOR INSTRUCTIONS */
+#define SNDRV_SEQ_IOCTL_SET_QUEUE_TEMPO _IOW('S', 0x42, struct snd_seq_queue_tempo)
 #define SNDRV_SEQ_IOCTL_GET_QUEUE_OWNER _IOWR('S', 0x43, struct snd_seq_queue_owner)
 #define SNDRV_SEQ_IOCTL_SET_QUEUE_OWNER _IOW('S', 0x44, struct snd_seq_queue_owner)
 #define SNDRV_SEQ_IOCTL_GET_QUEUE_TIMER _IOWR('S', 0x45, struct snd_seq_queue_timer)
-#define SNDRV_SEQ_IOCTL_SET_QUEUE_TIMER _IOW('S', 0x46, struct snd_seq_queue_timer)
 /* WARNING: DO NOT EDIT, AUTO-GENERATED CODE - SEE TOP FOR INSTRUCTIONS */
+#define SNDRV_SEQ_IOCTL_SET_QUEUE_TIMER _IOW('S', 0x46, struct snd_seq_queue_timer)
 #define SNDRV_SEQ_IOCTL_GET_QUEUE_CLIENT _IOWR('S', 0x49, struct snd_seq_queue_client)
 #define SNDRV_SEQ_IOCTL_SET_QUEUE_CLIENT _IOW('S', 0x4a, struct snd_seq_queue_client)
 #define SNDRV_SEQ_IOCTL_GET_CLIENT_POOL _IOWR('S', 0x4b, struct snd_seq_client_pool)
-#define SNDRV_SEQ_IOCTL_SET_CLIENT_POOL _IOW('S', 0x4c, struct snd_seq_client_pool)
 /* WARNING: DO NOT EDIT, AUTO-GENERATED CODE - SEE TOP FOR INSTRUCTIONS */
+#define SNDRV_SEQ_IOCTL_SET_CLIENT_POOL _IOW('S', 0x4c, struct snd_seq_client_pool)
 #define SNDRV_SEQ_IOCTL_REMOVE_EVENTS _IOW('S', 0x4e, struct snd_seq_remove_events)
 #define SNDRV_SEQ_IOCTL_QUERY_SUBS _IOWR('S', 0x4f, struct snd_seq_query_subs)
 #define SNDRV_SEQ_IOCTL_GET_SUBSCRIPTION _IOWR('S', 0x50, struct snd_seq_port_subscribe)
-#define SNDRV_SEQ_IOCTL_QUERY_NEXT_CLIENT _IOWR('S', 0x51, struct snd_seq_client_info)
 /* WARNING: DO NOT EDIT, AUTO-GENERATED CODE - SEE TOP FOR INSTRUCTIONS */
+#define SNDRV_SEQ_IOCTL_QUERY_NEXT_CLIENT _IOWR('S', 0x51, struct snd_seq_client_info)
 #define SNDRV_SEQ_IOCTL_QUERY_NEXT_PORT _IOWR('S', 0x52, struct snd_seq_port_info)
 #endif
diff --git a/libc/kernel/uapi/sound/asoc.h b/libc/kernel/uapi/sound/asoc.h
new file mode 100644
index 0000000..a4fac22
--- /dev/null
+++ b/libc/kernel/uapi/sound/asoc.h
@@ -0,0 +1,289 @@
+/****************************************************************************
+ ****************************************************************************
+ ***
+ ***   This header was automatically generated from a Linux kernel header
+ ***   of the same name, to make information necessary for userspace to
+ ***   call into the kernel available to libc.  It contains only constants,
+ ***   structures, and macros generated from the original header, and thus,
+ ***   contains no copyrightable information.
+ ***
+ ***   To edit the content of this header, modify the corresponding
+ ***   source file (e.g. under external/kernel-headers/original/) then
+ ***   run bionic/libc/kernel/tools/update_all.py
+ ***
+ ***   Any manual change here will be lost the next time this script will
+ ***   be run. You've been warned!
+ ***
+ ****************************************************************************
+ ****************************************************************************/
+#ifndef __LINUX_UAPI_SND_ASOC_H
+#define __LINUX_UAPI_SND_ASOC_H
+#include <linux/types.h>
+#include <sound/asound.h>
+/* WARNING: DO NOT EDIT, AUTO-GENERATED CODE - SEE TOP FOR INSTRUCTIONS */
+#error This API is an early revision and not enabled in the current
+#error kernel release , it will be enabled in a future kernel version
+#error with incompatible changes to what is here .
+#define SND_SOC_TPLG_MAX_CHAN 8
+/* WARNING: DO NOT EDIT, AUTO-GENERATED CODE - SEE TOP FOR INSTRUCTIONS */
+#define SND_SOC_TPLG_MAX_FORMATS 16
+#define SND_SOC_TPLG_STREAM_CONFIG_MAX 8
+#define SND_SOC_TPLG_CTL_VOLSW 1
+#define SND_SOC_TPLG_CTL_VOLSW_SX 2
+/* WARNING: DO NOT EDIT, AUTO-GENERATED CODE - SEE TOP FOR INSTRUCTIONS */
+#define SND_SOC_TPLG_CTL_VOLSW_XR_SX 3
+#define SND_SOC_TPLG_CTL_ENUM 4
+#define SND_SOC_TPLG_CTL_BYTES 5
+#define SND_SOC_TPLG_CTL_ENUM_VALUE 6
+/* WARNING: DO NOT EDIT, AUTO-GENERATED CODE - SEE TOP FOR INSTRUCTIONS */
+#define SND_SOC_TPLG_CTL_RANGE 7
+#define SND_SOC_TPLG_CTL_STROBE 8
+#define SND_SOC_TPLG_DAPM_CTL_VOLSW 64
+#define SND_SOC_TPLG_DAPM_CTL_ENUM_DOUBLE 65
+/* WARNING: DO NOT EDIT, AUTO-GENERATED CODE - SEE TOP FOR INSTRUCTIONS */
+#define SND_SOC_TPLG_DAPM_CTL_ENUM_VIRT 66
+#define SND_SOC_TPLG_DAPM_CTL_ENUM_VALUE 67
+#define SND_SOC_TPLG_DAPM_CTL_PIN 68
+#define SND_SOC_TPLG_DAPM_INPUT 0
+/* WARNING: DO NOT EDIT, AUTO-GENERATED CODE - SEE TOP FOR INSTRUCTIONS */
+#define SND_SOC_TPLG_DAPM_OUTPUT 1
+#define SND_SOC_TPLG_DAPM_MUX 2
+#define SND_SOC_TPLG_DAPM_MIXER 3
+#define SND_SOC_TPLG_DAPM_PGA 4
+/* WARNING: DO NOT EDIT, AUTO-GENERATED CODE - SEE TOP FOR INSTRUCTIONS */
+#define SND_SOC_TPLG_DAPM_OUT_DRV 5
+#define SND_SOC_TPLG_DAPM_ADC 6
+#define SND_SOC_TPLG_DAPM_DAC 7
+#define SND_SOC_TPLG_DAPM_SWITCH 8
+/* WARNING: DO NOT EDIT, AUTO-GENERATED CODE - SEE TOP FOR INSTRUCTIONS */
+#define SND_SOC_TPLG_DAPM_PRE 9
+#define SND_SOC_TPLG_DAPM_POST 10
+#define SND_SOC_TPLG_DAPM_AIF_IN 11
+#define SND_SOC_TPLG_DAPM_AIF_OUT 12
+/* WARNING: DO NOT EDIT, AUTO-GENERATED CODE - SEE TOP FOR INSTRUCTIONS */
+#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
+/* WARNING: DO NOT EDIT, AUTO-GENERATED CODE - SEE TOP FOR INSTRUCTIONS */
+#define SND_SOC_TPLG_MAGIC 0x41536F43
+#define SND_SOC_TPLG_NUM_TEXTS 16
+#define SND_SOC_TPLG_ABI_VERSION 0x4
+#define SND_SOC_TPLG_TLV_SIZE 32
+/* WARNING: DO NOT EDIT, AUTO-GENERATED CODE - SEE TOP FOR INSTRUCTIONS */
+#define SND_SOC_TPLG_TYPE_MIXER 1
+#define SND_SOC_TPLG_TYPE_BYTES 2
+#define SND_SOC_TPLG_TYPE_ENUM 3
+#define SND_SOC_TPLG_TYPE_DAPM_GRAPH 4
+/* WARNING: DO NOT EDIT, AUTO-GENERATED CODE - SEE TOP FOR INSTRUCTIONS */
+#define SND_SOC_TPLG_TYPE_DAPM_WIDGET 5
+#define SND_SOC_TPLG_TYPE_DAI_LINK 6
+#define SND_SOC_TPLG_TYPE_PCM 7
+#define SND_SOC_TPLG_TYPE_MANIFEST 8
+/* WARNING: DO NOT EDIT, AUTO-GENERATED CODE - SEE TOP FOR INSTRUCTIONS */
+#define SND_SOC_TPLG_TYPE_CODEC_LINK 9
+#define SND_SOC_TPLG_TYPE_BACKEND_LINK 10
+#define SND_SOC_TPLG_TYPE_PDATA 11
+#define SND_SOC_TPLG_TYPE_MAX SND_SOC_TPLG_TYPE_PDATA
+/* WARNING: DO NOT EDIT, AUTO-GENERATED CODE - SEE TOP FOR INSTRUCTIONS */
+#define SND_SOC_TPLG_TYPE_VENDOR_FW 1000
+#define SND_SOC_TPLG_TYPE_VENDOR_CONFIG 1001
+#define SND_SOC_TPLG_TYPE_VENDOR_COEFF 1002
+#define SND_SOC_TPLG_TYPEVENDOR_CODEC 1003
+/* WARNING: DO NOT EDIT, AUTO-GENERATED CODE - SEE TOP FOR INSTRUCTIONS */
+#define SND_SOC_TPLG_STREAM_PLAYBACK 0
+#define SND_SOC_TPLG_STREAM_CAPTURE 1
+struct snd_soc_tplg_hdr {
+  __le32 magic;
+/* WARNING: DO NOT EDIT, AUTO-GENERATED CODE - SEE TOP FOR INSTRUCTIONS */
+  __le32 abi;
+  __le32 version;
+  __le32 type;
+  __le32 size;
+/* WARNING: DO NOT EDIT, AUTO-GENERATED CODE - SEE TOP FOR INSTRUCTIONS */
+  __le32 vendor_type;
+  __le32 payload_size;
+  __le32 index;
+  __le32 count;
+/* WARNING: DO NOT EDIT, AUTO-GENERATED CODE - SEE TOP FOR INSTRUCTIONS */
+} __attribute__((packed));
+struct snd_soc_tplg_private {
+  __le32 size;
+  char data[0];
+/* WARNING: DO NOT EDIT, AUTO-GENERATED CODE - SEE TOP FOR INSTRUCTIONS */
+} __attribute__((packed));
+struct snd_soc_tplg_tlv_dbscale {
+  __le32 min;
+  __le32 step;
+/* WARNING: DO NOT EDIT, AUTO-GENERATED CODE - SEE TOP FOR INSTRUCTIONS */
+  __le32 mute;
+} __attribute__((packed));
+struct snd_soc_tplg_ctl_tlv {
+  __le32 size;
+/* WARNING: DO NOT EDIT, AUTO-GENERATED CODE - SEE TOP FOR INSTRUCTIONS */
+  __le32 type;
+  union {
+    __le32 data[SND_SOC_TPLG_TLV_SIZE];
+    struct snd_soc_tplg_tlv_dbscale scale;
+/* WARNING: DO NOT EDIT, AUTO-GENERATED CODE - SEE TOP FOR INSTRUCTIONS */
+  };
+} __attribute__((packed));
+struct snd_soc_tplg_channel {
+  __le32 size;
+/* WARNING: DO NOT EDIT, AUTO-GENERATED CODE - SEE TOP FOR INSTRUCTIONS */
+  __le32 reg;
+  __le32 shift;
+  __le32 id;
+} __attribute__((packed));
+/* WARNING: DO NOT EDIT, AUTO-GENERATED CODE - SEE TOP FOR INSTRUCTIONS */
+struct snd_soc_tplg_io_ops {
+  __le32 get;
+  __le32 put;
+  __le32 info;
+/* WARNING: DO NOT EDIT, AUTO-GENERATED CODE - SEE TOP FOR INSTRUCTIONS */
+} __attribute__((packed));
+struct snd_soc_tplg_ctl_hdr {
+  __le32 size;
+  __le32 type;
+/* WARNING: DO NOT EDIT, AUTO-GENERATED CODE - SEE TOP FOR INSTRUCTIONS */
+  char name[SNDRV_CTL_ELEM_ID_NAME_MAXLEN];
+  __le32 access;
+  struct snd_soc_tplg_io_ops ops;
+  struct snd_soc_tplg_ctl_tlv tlv;
+/* WARNING: DO NOT EDIT, AUTO-GENERATED CODE - SEE TOP FOR INSTRUCTIONS */
+} __attribute__((packed));
+struct snd_soc_tplg_stream_caps {
+  __le32 size;
+  char name[SNDRV_CTL_ELEM_ID_NAME_MAXLEN];
+/* WARNING: DO NOT EDIT, AUTO-GENERATED CODE - SEE TOP FOR INSTRUCTIONS */
+  __le64 formats;
+  __le32 rates;
+  __le32 rate_min;
+  __le32 rate_max;
+/* WARNING: DO NOT EDIT, AUTO-GENERATED CODE - SEE TOP FOR INSTRUCTIONS */
+  __le32 channels_min;
+  __le32 channels_max;
+  __le32 periods_min;
+  __le32 periods_max;
+/* WARNING: DO NOT EDIT, AUTO-GENERATED CODE - SEE TOP FOR INSTRUCTIONS */
+  __le32 period_size_min;
+  __le32 period_size_max;
+  __le32 buffer_size_min;
+  __le32 buffer_size_max;
+/* WARNING: DO NOT EDIT, AUTO-GENERATED CODE - SEE TOP FOR INSTRUCTIONS */
+} __attribute__((packed));
+struct snd_soc_tplg_stream {
+  __le32 size;
+  char name[SNDRV_CTL_ELEM_ID_NAME_MAXLEN];
+/* WARNING: DO NOT EDIT, AUTO-GENERATED CODE - SEE TOP FOR INSTRUCTIONS */
+  __le64 format;
+  __le32 rate;
+  __le32 period_bytes;
+  __le32 buffer_bytes;
+/* WARNING: DO NOT EDIT, AUTO-GENERATED CODE - SEE TOP FOR INSTRUCTIONS */
+  __le32 channels;
+} __attribute__((packed));
+struct snd_soc_tplg_manifest {
+  __le32 size;
+/* WARNING: DO NOT EDIT, AUTO-GENERATED CODE - SEE TOP FOR INSTRUCTIONS */
+  __le32 control_elems;
+  __le32 widget_elems;
+  __le32 graph_elems;
+  __le32 dai_elems;
+/* WARNING: DO NOT EDIT, AUTO-GENERATED CODE - SEE TOP FOR INSTRUCTIONS */
+  __le32 dai_link_elems;
+  struct snd_soc_tplg_private priv;
+} __attribute__((packed));
+struct snd_soc_tplg_mixer_control {
+/* WARNING: DO NOT EDIT, AUTO-GENERATED CODE - SEE TOP FOR INSTRUCTIONS */
+  struct snd_soc_tplg_ctl_hdr hdr;
+  __le32 size;
+  __le32 min;
+  __le32 max;
+/* WARNING: DO NOT EDIT, AUTO-GENERATED CODE - SEE TOP FOR INSTRUCTIONS */
+  __le32 platform_max;
+  __le32 invert;
+  __le32 num_channels;
+  struct snd_soc_tplg_channel channel[SND_SOC_TPLG_MAX_CHAN];
+/* WARNING: DO NOT EDIT, AUTO-GENERATED CODE - SEE TOP FOR INSTRUCTIONS */
+  struct snd_soc_tplg_private priv;
+} __attribute__((packed));
+struct snd_soc_tplg_enum_control {
+  struct snd_soc_tplg_ctl_hdr hdr;
+/* WARNING: DO NOT EDIT, AUTO-GENERATED CODE - SEE TOP FOR INSTRUCTIONS */
+  __le32 size;
+  __le32 num_channels;
+  struct snd_soc_tplg_channel channel[SND_SOC_TPLG_MAX_CHAN];
+  __le32 items;
+/* WARNING: DO NOT EDIT, AUTO-GENERATED CODE - SEE TOP FOR INSTRUCTIONS */
+  __le32 mask;
+  __le32 count;
+  char texts[SND_SOC_TPLG_NUM_TEXTS][SNDRV_CTL_ELEM_ID_NAME_MAXLEN];
+  __le32 values[SND_SOC_TPLG_NUM_TEXTS * SNDRV_CTL_ELEM_ID_NAME_MAXLEN / 4];
+/* WARNING: DO NOT EDIT, AUTO-GENERATED CODE - SEE TOP FOR INSTRUCTIONS */
+  struct snd_soc_tplg_private priv;
+} __attribute__((packed));
+struct snd_soc_tplg_bytes_control {
+  struct snd_soc_tplg_ctl_hdr hdr;
+/* WARNING: DO NOT EDIT, AUTO-GENERATED CODE - SEE TOP FOR INSTRUCTIONS */
+  __le32 size;
+  __le32 max;
+  __le32 mask;
+  __le32 base;
+/* WARNING: DO NOT EDIT, AUTO-GENERATED CODE - SEE TOP FOR INSTRUCTIONS */
+  __le32 num_regs;
+  struct snd_soc_tplg_io_ops ext_ops;
+  struct snd_soc_tplg_private priv;
+} __attribute__((packed));
+/* WARNING: DO NOT EDIT, AUTO-GENERATED CODE - SEE TOP FOR INSTRUCTIONS */
+struct snd_soc_tplg_dapm_graph_elem {
+  char sink[SNDRV_CTL_ELEM_ID_NAME_MAXLEN];
+  char control[SNDRV_CTL_ELEM_ID_NAME_MAXLEN];
+  char source[SNDRV_CTL_ELEM_ID_NAME_MAXLEN];
+/* WARNING: DO NOT EDIT, AUTO-GENERATED CODE - SEE TOP FOR INSTRUCTIONS */
+} __attribute__((packed));
+struct snd_soc_tplg_dapm_widget {
+  __le32 size;
+  __le32 id;
+/* WARNING: DO NOT EDIT, AUTO-GENERATED CODE - SEE TOP FOR INSTRUCTIONS */
+  char name[SNDRV_CTL_ELEM_ID_NAME_MAXLEN];
+  char sname[SNDRV_CTL_ELEM_ID_NAME_MAXLEN];
+  __le32 reg;
+  __le32 shift;
+/* WARNING: DO NOT EDIT, AUTO-GENERATED CODE - SEE TOP FOR INSTRUCTIONS */
+  __le32 mask;
+  __le32 subseq;
+  __le32 invert;
+  __le32 ignore_suspend;
+/* WARNING: DO NOT EDIT, AUTO-GENERATED CODE - SEE TOP FOR INSTRUCTIONS */
+  __le16 event_flags;
+  __le16 event_type;
+  __le32 num_kcontrols;
+  struct snd_soc_tplg_private priv;
+/* WARNING: DO NOT EDIT, AUTO-GENERATED CODE - SEE TOP FOR INSTRUCTIONS */
+} __attribute__((packed));
+struct snd_soc_tplg_pcm {
+  __le32 size;
+  char pcm_name[SNDRV_CTL_ELEM_ID_NAME_MAXLEN];
+/* WARNING: DO NOT EDIT, AUTO-GENERATED CODE - SEE TOP FOR INSTRUCTIONS */
+  char dai_name[SNDRV_CTL_ELEM_ID_NAME_MAXLEN];
+  __le32 pcm_id;
+  __le32 dai_id;
+  __le32 playback;
+/* WARNING: DO NOT EDIT, AUTO-GENERATED CODE - SEE TOP FOR INSTRUCTIONS */
+  __le32 capture;
+  __le32 compress;
+  struct snd_soc_tplg_stream stream[SND_SOC_TPLG_STREAM_CONFIG_MAX];
+  __le32 num_streams;
+/* WARNING: DO NOT EDIT, AUTO-GENERATED CODE - SEE TOP FOR INSTRUCTIONS */
+  struct snd_soc_tplg_stream_caps caps[2];
+} __attribute__((packed));
+struct snd_soc_tplg_link_config {
+  __le32 size;
+/* WARNING: DO NOT EDIT, AUTO-GENERATED CODE - SEE TOP FOR INSTRUCTIONS */
+  __le32 id;
+  struct snd_soc_tplg_stream stream[SND_SOC_TPLG_STREAM_CONFIG_MAX];
+  __le32 num_streams;
+} __attribute__((packed));
+/* WARNING: DO NOT EDIT, AUTO-GENERATED CODE - SEE TOP FOR INSTRUCTIONS */
+#endif
diff --git a/libc/kernel/uapi/sound/asound.h b/libc/kernel/uapi/sound/asound.h
index 1419fe8..0dfff8b 100644
--- a/libc/kernel/uapi/sound/asound.h
+++ b/libc/kernel/uapi/sound/asound.h
@@ -19,59 +19,64 @@
 #ifndef _UAPI__SOUND_ASOUND_H
 #define _UAPI__SOUND_ASOUND_H
 #include <linux/types.h>
-#define SNDRV_PROTOCOL_VERSION(major,minor,subminor) (((major) << 16) | ((minor) << 8) | (subminor))
+#include <stdlib.h>
 /* WARNING: DO NOT EDIT, AUTO-GENERATED CODE - SEE TOP FOR INSTRUCTIONS */
+#define SNDRV_PROTOCOL_VERSION(major,minor,subminor) (((major) << 16) | ((minor) << 8) | (subminor))
 #define SNDRV_PROTOCOL_MAJOR(version) (((version) >> 16) & 0xffff)
 #define SNDRV_PROTOCOL_MINOR(version) (((version) >> 8) & 0xff)
 #define SNDRV_PROTOCOL_MICRO(version) ((version) & 0xff)
-#define SNDRV_PROTOCOL_INCOMPATIBLE(kversion,uversion) (SNDRV_PROTOCOL_MAJOR(kversion) != SNDRV_PROTOCOL_MAJOR(uversion) || (SNDRV_PROTOCOL_MAJOR(kversion) == SNDRV_PROTOCOL_MAJOR(uversion) && SNDRV_PROTOCOL_MINOR(kversion) != SNDRV_PROTOCOL_MINOR(uversion)))
 /* WARNING: DO NOT EDIT, AUTO-GENERATED CODE - SEE TOP FOR INSTRUCTIONS */
+#define SNDRV_PROTOCOL_INCOMPATIBLE(kversion,uversion) (SNDRV_PROTOCOL_MAJOR(kversion) != SNDRV_PROTOCOL_MAJOR(uversion) || (SNDRV_PROTOCOL_MAJOR(kversion) == SNDRV_PROTOCOL_MAJOR(uversion) && SNDRV_PROTOCOL_MINOR(kversion) != SNDRV_PROTOCOL_MINOR(uversion)))
 struct snd_aes_iec958 {
   unsigned char status[24];
   unsigned char subcode[147];
-  unsigned char pad;
 /* WARNING: DO NOT EDIT, AUTO-GENERATED CODE - SEE TOP FOR INSTRUCTIONS */
+  unsigned char pad;
   unsigned char dig_subframe[4];
 };
 struct snd_cea_861_aud_if {
-  unsigned char db1_ct_cc;
 /* WARNING: DO NOT EDIT, AUTO-GENERATED CODE - SEE TOP FOR INSTRUCTIONS */
+  unsigned char db1_ct_cc;
   unsigned char db2_sf_ss;
   unsigned char db3;
   unsigned char db4_ca;
-  unsigned char db5_dminh_lsv;
 /* WARNING: DO NOT EDIT, AUTO-GENERATED CODE - SEE TOP FOR INSTRUCTIONS */
+  unsigned char db5_dminh_lsv;
 };
 #define SNDRV_HWDEP_VERSION SNDRV_PROTOCOL_VERSION(1, 0, 1)
 enum {
-  SNDRV_HWDEP_IFACE_OPL2 = 0,
 /* WARNING: DO NOT EDIT, AUTO-GENERATED CODE - SEE TOP FOR INSTRUCTIONS */
+  SNDRV_HWDEP_IFACE_OPL2 = 0,
   SNDRV_HWDEP_IFACE_OPL3,
   SNDRV_HWDEP_IFACE_OPL4,
   SNDRV_HWDEP_IFACE_SB16CSP,
-  SNDRV_HWDEP_IFACE_EMU10K1,
 /* WARNING: DO NOT EDIT, AUTO-GENERATED CODE - SEE TOP FOR INSTRUCTIONS */
+  SNDRV_HWDEP_IFACE_EMU10K1,
   SNDRV_HWDEP_IFACE_YSS225,
   SNDRV_HWDEP_IFACE_ICS2115,
   SNDRV_HWDEP_IFACE_SSCAPE,
-  SNDRV_HWDEP_IFACE_VX,
 /* WARNING: DO NOT EDIT, AUTO-GENERATED CODE - SEE TOP FOR INSTRUCTIONS */
+  SNDRV_HWDEP_IFACE_VX,
   SNDRV_HWDEP_IFACE_MIXART,
   SNDRV_HWDEP_IFACE_USX2Y,
   SNDRV_HWDEP_IFACE_EMUX_WAVETABLE,
-  SNDRV_HWDEP_IFACE_BLUETOOTH,
 /* WARNING: DO NOT EDIT, AUTO-GENERATED CODE - SEE TOP FOR INSTRUCTIONS */
+  SNDRV_HWDEP_IFACE_BLUETOOTH,
   SNDRV_HWDEP_IFACE_USX2Y_PCM,
   SNDRV_HWDEP_IFACE_PCXHR,
   SNDRV_HWDEP_IFACE_SB_RC,
-  SNDRV_HWDEP_IFACE_HDA,
 /* WARNING: DO NOT EDIT, AUTO-GENERATED CODE - SEE TOP FOR INSTRUCTIONS */
+  SNDRV_HWDEP_IFACE_HDA,
   SNDRV_HWDEP_IFACE_USB_STREAM,
   SNDRV_HWDEP_IFACE_FW_DICE,
   SNDRV_HWDEP_IFACE_FW_FIREWORKS,
-  SNDRV_HWDEP_IFACE_FW_BEBOB,
 /* WARNING: DO NOT EDIT, AUTO-GENERATED CODE - SEE TOP FOR INSTRUCTIONS */
-  SNDRV_HWDEP_IFACE_LAST = SNDRV_HWDEP_IFACE_FW_BEBOB
+  SNDRV_HWDEP_IFACE_FW_BEBOB,
+  SNDRV_HWDEP_IFACE_FW_OXFW,
+  SNDRV_HWDEP_IFACE_FW_DIGI00X,
+  SNDRV_HWDEP_IFACE_FW_TASCAM,
+/* WARNING: DO NOT EDIT, AUTO-GENERATED CODE - SEE TOP FOR INSTRUCTIONS */
+  SNDRV_HWDEP_IFACE_LAST = SNDRV_HWDEP_IFACE_FW_TASCAM
 };
 struct snd_hwdep_info {
   unsigned int device;
@@ -107,7 +112,7 @@
 #define SNDRV_HWDEP_IOCTL_DSP_STATUS _IOR('H', 0x02, struct snd_hwdep_dsp_status)
 /* WARNING: DO NOT EDIT, AUTO-GENERATED CODE - SEE TOP FOR INSTRUCTIONS */
 #define SNDRV_HWDEP_IOCTL_DSP_LOAD _IOW('H', 0x03, struct snd_hwdep_dsp_image)
-#define SNDRV_PCM_VERSION SNDRV_PROTOCOL_VERSION(2, 0, 12)
+#define SNDRV_PCM_VERSION SNDRV_PROTOCOL_VERSION(2, 0, 13)
 typedef unsigned long snd_pcm_uframes_t;
 typedef signed long snd_pcm_sframes_t;
 /* WARNING: DO NOT EDIT, AUTO-GENERATED CODE - SEE TOP FOR INSTRUCTIONS */
@@ -253,160 +258,180 @@
 /* WARNING: DO NOT EDIT, AUTO-GENERATED CODE - SEE TOP FOR INSTRUCTIONS */
 #define SNDRV_PCM_INFO_NO_PERIOD_WAKEUP 0x00800000
 #define SNDRV_PCM_INFO_HAS_WALL_CLOCK 0x01000000
-#define SNDRV_PCM_INFO_FIFO_IN_FRAMES 0x80000000
-typedef int __bitwise snd_pcm_state_t;
+#define SNDRV_PCM_INFO_HAS_LINK_ATIME 0x01000000
+#define SNDRV_PCM_INFO_HAS_LINK_ABSOLUTE_ATIME 0x02000000
 /* WARNING: DO NOT EDIT, AUTO-GENERATED CODE - SEE TOP FOR INSTRUCTIONS */
+#define SNDRV_PCM_INFO_HAS_LINK_ESTIMATED_ATIME 0x04000000
+#define SNDRV_PCM_INFO_HAS_LINK_SYNCHRONIZED_ATIME 0x08000000
+#define SNDRV_PCM_INFO_DRAIN_TRIGGER 0x40000000
+#define SNDRV_PCM_INFO_FIFO_IN_FRAMES 0x80000000
+/* WARNING: DO NOT EDIT, AUTO-GENERATED CODE - SEE TOP FOR INSTRUCTIONS */
+typedef int __bitwise snd_pcm_state_t;
 #define SNDRV_PCM_STATE_OPEN ((__force snd_pcm_state_t) 0)
 #define SNDRV_PCM_STATE_SETUP ((__force snd_pcm_state_t) 1)
 #define SNDRV_PCM_STATE_PREPARED ((__force snd_pcm_state_t) 2)
-#define SNDRV_PCM_STATE_RUNNING ((__force snd_pcm_state_t) 3)
 /* WARNING: DO NOT EDIT, AUTO-GENERATED CODE - SEE TOP FOR INSTRUCTIONS */
+#define SNDRV_PCM_STATE_RUNNING ((__force snd_pcm_state_t) 3)
 #define SNDRV_PCM_STATE_XRUN ((__force snd_pcm_state_t) 4)
 #define SNDRV_PCM_STATE_DRAINING ((__force snd_pcm_state_t) 5)
 #define SNDRV_PCM_STATE_PAUSED ((__force snd_pcm_state_t) 6)
-#define SNDRV_PCM_STATE_SUSPENDED ((__force snd_pcm_state_t) 7)
 /* WARNING: DO NOT EDIT, AUTO-GENERATED CODE - SEE TOP FOR INSTRUCTIONS */
+#define SNDRV_PCM_STATE_SUSPENDED ((__force snd_pcm_state_t) 7)
 #define SNDRV_PCM_STATE_DISCONNECTED ((__force snd_pcm_state_t) 8)
 #define SNDRV_PCM_STATE_LAST SNDRV_PCM_STATE_DISCONNECTED
 enum {
-  SNDRV_PCM_MMAP_OFFSET_DATA = 0x00000000,
 /* WARNING: DO NOT EDIT, AUTO-GENERATED CODE - SEE TOP FOR INSTRUCTIONS */
+  SNDRV_PCM_MMAP_OFFSET_DATA = 0x00000000,
   SNDRV_PCM_MMAP_OFFSET_STATUS = 0x80000000,
   SNDRV_PCM_MMAP_OFFSET_CONTROL = 0x81000000,
 };
-union snd_pcm_sync_id {
 /* WARNING: DO NOT EDIT, AUTO-GENERATED CODE - SEE TOP FOR INSTRUCTIONS */
+union snd_pcm_sync_id {
   unsigned char id[16];
   unsigned short id16[8];
   unsigned int id32[4];
-};
 /* WARNING: DO NOT EDIT, AUTO-GENERATED CODE - SEE TOP FOR INSTRUCTIONS */
+};
 struct snd_pcm_info {
   unsigned int device;
   unsigned int subdevice;
-  int stream;
 /* WARNING: DO NOT EDIT, AUTO-GENERATED CODE - SEE TOP FOR INSTRUCTIONS */
+  int stream;
   int card;
   unsigned char id[64];
   unsigned char name[80];
-  unsigned char subname[32];
 /* WARNING: DO NOT EDIT, AUTO-GENERATED CODE - SEE TOP FOR INSTRUCTIONS */
+  unsigned char subname[32];
   int dev_class;
   int dev_subclass;
   unsigned int subdevices_count;
-  unsigned int subdevices_avail;
 /* WARNING: DO NOT EDIT, AUTO-GENERATED CODE - SEE TOP FOR INSTRUCTIONS */
+  unsigned int subdevices_avail;
   union snd_pcm_sync_id sync;
   unsigned char reserved[64];
 };
-typedef int snd_pcm_hw_param_t;
 /* WARNING: DO NOT EDIT, AUTO-GENERATED CODE - SEE TOP FOR INSTRUCTIONS */
+typedef int snd_pcm_hw_param_t;
 #define SNDRV_PCM_HW_PARAM_ACCESS 0
 #define SNDRV_PCM_HW_PARAM_FORMAT 1
 #define SNDRV_PCM_HW_PARAM_SUBFORMAT 2
-#define SNDRV_PCM_HW_PARAM_FIRST_MASK SNDRV_PCM_HW_PARAM_ACCESS
 /* WARNING: DO NOT EDIT, AUTO-GENERATED CODE - SEE TOP FOR INSTRUCTIONS */
+#define SNDRV_PCM_HW_PARAM_FIRST_MASK SNDRV_PCM_HW_PARAM_ACCESS
 #define SNDRV_PCM_HW_PARAM_LAST_MASK SNDRV_PCM_HW_PARAM_SUBFORMAT
 #define SNDRV_PCM_HW_PARAM_SAMPLE_BITS 8
 #define SNDRV_PCM_HW_PARAM_FRAME_BITS 9
-#define SNDRV_PCM_HW_PARAM_CHANNELS 10
 /* WARNING: DO NOT EDIT, AUTO-GENERATED CODE - SEE TOP FOR INSTRUCTIONS */
+#define SNDRV_PCM_HW_PARAM_CHANNELS 10
 #define SNDRV_PCM_HW_PARAM_RATE 11
 #define SNDRV_PCM_HW_PARAM_PERIOD_TIME 12
 #define SNDRV_PCM_HW_PARAM_PERIOD_SIZE 13
-#define SNDRV_PCM_HW_PARAM_PERIOD_BYTES 14
 /* WARNING: DO NOT EDIT, AUTO-GENERATED CODE - SEE TOP FOR INSTRUCTIONS */
+#define SNDRV_PCM_HW_PARAM_PERIOD_BYTES 14
 #define SNDRV_PCM_HW_PARAM_PERIODS 15
 #define SNDRV_PCM_HW_PARAM_BUFFER_TIME 16
 #define SNDRV_PCM_HW_PARAM_BUFFER_SIZE 17
-#define SNDRV_PCM_HW_PARAM_BUFFER_BYTES 18
 /* WARNING: DO NOT EDIT, AUTO-GENERATED CODE - SEE TOP FOR INSTRUCTIONS */
+#define SNDRV_PCM_HW_PARAM_BUFFER_BYTES 18
 #define SNDRV_PCM_HW_PARAM_TICK_TIME 19
 #define SNDRV_PCM_HW_PARAM_FIRST_INTERVAL SNDRV_PCM_HW_PARAM_SAMPLE_BITS
 #define SNDRV_PCM_HW_PARAM_LAST_INTERVAL SNDRV_PCM_HW_PARAM_TICK_TIME
-#define SNDRV_PCM_HW_PARAMS_NORESAMPLE (1 << 0)
 /* WARNING: DO NOT EDIT, AUTO-GENERATED CODE - SEE TOP FOR INSTRUCTIONS */
+#define SNDRV_PCM_HW_PARAMS_NORESAMPLE (1 << 0)
 #define SNDRV_PCM_HW_PARAMS_EXPORT_BUFFER (1 << 1)
 #define SNDRV_PCM_HW_PARAMS_NO_PERIOD_WAKEUP (1 << 2)
 struct snd_interval {
-  unsigned int min, max;
 /* WARNING: DO NOT EDIT, AUTO-GENERATED CODE - SEE TOP FOR INSTRUCTIONS */
+  unsigned int min, max;
   unsigned int openmin : 1, openmax : 1, integer : 1, empty : 1;
 };
 #define SNDRV_MASK_MAX 256
-struct snd_mask {
 /* WARNING: DO NOT EDIT, AUTO-GENERATED CODE - SEE TOP FOR INSTRUCTIONS */
+struct snd_mask {
   __u32 bits[(SNDRV_MASK_MAX + 31) / 32];
 };
 struct snd_pcm_hw_params {
-  unsigned int flags;
 /* WARNING: DO NOT EDIT, AUTO-GENERATED CODE - SEE TOP FOR INSTRUCTIONS */
+  unsigned int flags;
   struct snd_mask masks[SNDRV_PCM_HW_PARAM_LAST_MASK - SNDRV_PCM_HW_PARAM_FIRST_MASK + 1];
   struct snd_mask mres[5];
   struct snd_interval intervals[SNDRV_PCM_HW_PARAM_LAST_INTERVAL - SNDRV_PCM_HW_PARAM_FIRST_INTERVAL + 1];
-  struct snd_interval ires[9];
 /* WARNING: DO NOT EDIT, AUTO-GENERATED CODE - SEE TOP FOR INSTRUCTIONS */
+  struct snd_interval ires[9];
   unsigned int rmask;
   unsigned int cmask;
   unsigned int info;
-  unsigned int msbits;
 /* WARNING: DO NOT EDIT, AUTO-GENERATED CODE - SEE TOP FOR INSTRUCTIONS */
+  unsigned int msbits;
   unsigned int rate_num;
   unsigned int rate_den;
   snd_pcm_uframes_t fifo_size;
-  unsigned char reserved[64];
 /* WARNING: DO NOT EDIT, AUTO-GENERATED CODE - SEE TOP FOR INSTRUCTIONS */
+  unsigned char reserved[64];
 };
 enum {
   SNDRV_PCM_TSTAMP_NONE = 0,
-  SNDRV_PCM_TSTAMP_ENABLE,
 /* WARNING: DO NOT EDIT, AUTO-GENERATED CODE - SEE TOP FOR INSTRUCTIONS */
+  SNDRV_PCM_TSTAMP_ENABLE,
   SNDRV_PCM_TSTAMP_LAST = SNDRV_PCM_TSTAMP_ENABLE,
 };
 struct snd_pcm_sw_params {
-  int tstamp_mode;
 /* WARNING: DO NOT EDIT, AUTO-GENERATED CODE - SEE TOP FOR INSTRUCTIONS */
+  int tstamp_mode;
   unsigned int period_step;
   unsigned int sleep_min;
   snd_pcm_uframes_t avail_min;
-  snd_pcm_uframes_t xfer_align;
 /* WARNING: DO NOT EDIT, AUTO-GENERATED CODE - SEE TOP FOR INSTRUCTIONS */
+  snd_pcm_uframes_t xfer_align;
   snd_pcm_uframes_t start_threshold;
   snd_pcm_uframes_t stop_threshold;
   snd_pcm_uframes_t silence_threshold;
-  snd_pcm_uframes_t silence_size;
 /* WARNING: DO NOT EDIT, AUTO-GENERATED CODE - SEE TOP FOR INSTRUCTIONS */
+  snd_pcm_uframes_t silence_size;
   snd_pcm_uframes_t boundary;
   unsigned int proto;
   unsigned int tstamp_type;
-  unsigned char reserved[56];
 /* WARNING: DO NOT EDIT, AUTO-GENERATED CODE - SEE TOP FOR INSTRUCTIONS */
+  unsigned char reserved[56];
 };
 struct snd_pcm_channel_info {
   unsigned int channel;
-  __kernel_off_t offset;
 /* WARNING: DO NOT EDIT, AUTO-GENERATED CODE - SEE TOP FOR INSTRUCTIONS */
+  __kernel_off_t offset;
   unsigned int first;
   unsigned int step;
 };
-struct snd_pcm_status {
 /* WARNING: DO NOT EDIT, AUTO-GENERATED CODE - SEE TOP FOR INSTRUCTIONS */
+enum {
+  SNDRV_PCM_AUDIO_TSTAMP_TYPE_COMPAT = 0,
+  SNDRV_PCM_AUDIO_TSTAMP_TYPE_DEFAULT = 1,
+  SNDRV_PCM_AUDIO_TSTAMP_TYPE_LINK = 2,
+/* WARNING: DO NOT EDIT, AUTO-GENERATED CODE - SEE TOP FOR INSTRUCTIONS */
+  SNDRV_PCM_AUDIO_TSTAMP_TYPE_LINK_ABSOLUTE = 3,
+  SNDRV_PCM_AUDIO_TSTAMP_TYPE_LINK_ESTIMATED = 4,
+  SNDRV_PCM_AUDIO_TSTAMP_TYPE_LINK_SYNCHRONIZED = 5,
+  SNDRV_PCM_AUDIO_TSTAMP_TYPE_LAST = SNDRV_PCM_AUDIO_TSTAMP_TYPE_LINK_SYNCHRONIZED
+/* WARNING: DO NOT EDIT, AUTO-GENERATED CODE - SEE TOP FOR INSTRUCTIONS */
+};
+struct snd_pcm_status {
   snd_pcm_state_t state;
   struct timespec trigger_tstamp;
+/* WARNING: DO NOT EDIT, AUTO-GENERATED CODE - SEE TOP FOR INSTRUCTIONS */
   struct timespec tstamp;
   snd_pcm_uframes_t appl_ptr;
-/* WARNING: DO NOT EDIT, AUTO-GENERATED CODE - SEE TOP FOR INSTRUCTIONS */
   snd_pcm_uframes_t hw_ptr;
   snd_pcm_sframes_t delay;
+/* WARNING: DO NOT EDIT, AUTO-GENERATED CODE - SEE TOP FOR INSTRUCTIONS */
   snd_pcm_uframes_t avail;
   snd_pcm_uframes_t avail_max;
-/* WARNING: DO NOT EDIT, AUTO-GENERATED CODE - SEE TOP FOR INSTRUCTIONS */
   snd_pcm_uframes_t overrange;
   snd_pcm_state_t suspended_state;
-  __u32 reserved_alignment;
-  struct timespec audio_tstamp;
 /* WARNING: DO NOT EDIT, AUTO-GENERATED CODE - SEE TOP FOR INSTRUCTIONS */
-  unsigned char reserved[56 - sizeof(struct timespec)];
+  __u32 audio_tstamp_data;
+  struct timespec audio_tstamp;
+  struct timespec driver_tstamp;
+  __u32 audio_tstamp_accuracy;
+/* WARNING: DO NOT EDIT, AUTO-GENERATED CODE - SEE TOP FOR INSTRUCTIONS */
+  unsigned char reserved[52 - 2 * sizeof(struct timespec)];
 };
 struct snd_pcm_mmap_status {
   snd_pcm_state_t state;
@@ -529,467 +554,468 @@
 #define SNDRV_PCM_IOCTL_DELAY _IOR('A', 0x21, snd_pcm_sframes_t)
 #define SNDRV_PCM_IOCTL_HWSYNC _IO('A', 0x22)
 #define SNDRV_PCM_IOCTL_SYNC_PTR _IOWR('A', 0x23, struct snd_pcm_sync_ptr)
-#define SNDRV_PCM_IOCTL_CHANNEL_INFO _IOR('A', 0x32, struct snd_pcm_channel_info)
+#define SNDRV_PCM_IOCTL_STATUS_EXT _IOWR('A', 0x24, struct snd_pcm_status)
 /* WARNING: DO NOT EDIT, AUTO-GENERATED CODE - SEE TOP FOR INSTRUCTIONS */
+#define SNDRV_PCM_IOCTL_CHANNEL_INFO _IOR('A', 0x32, struct snd_pcm_channel_info)
 #define SNDRV_PCM_IOCTL_PREPARE _IO('A', 0x40)
 #define SNDRV_PCM_IOCTL_RESET _IO('A', 0x41)
 #define SNDRV_PCM_IOCTL_START _IO('A', 0x42)
-#define SNDRV_PCM_IOCTL_DROP _IO('A', 0x43)
 /* WARNING: DO NOT EDIT, AUTO-GENERATED CODE - SEE TOP FOR INSTRUCTIONS */
+#define SNDRV_PCM_IOCTL_DROP _IO('A', 0x43)
 #define SNDRV_PCM_IOCTL_DRAIN _IO('A', 0x44)
 #define SNDRV_PCM_IOCTL_PAUSE _IOW('A', 0x45, int)
 #define SNDRV_PCM_IOCTL_REWIND _IOW('A', 0x46, snd_pcm_uframes_t)
-#define SNDRV_PCM_IOCTL_RESUME _IO('A', 0x47)
 /* WARNING: DO NOT EDIT, AUTO-GENERATED CODE - SEE TOP FOR INSTRUCTIONS */
+#define SNDRV_PCM_IOCTL_RESUME _IO('A', 0x47)
 #define SNDRV_PCM_IOCTL_XRUN _IO('A', 0x48)
 #define SNDRV_PCM_IOCTL_FORWARD _IOW('A', 0x49, snd_pcm_uframes_t)
 #define SNDRV_PCM_IOCTL_WRITEI_FRAMES _IOW('A', 0x50, struct snd_xferi)
-#define SNDRV_PCM_IOCTL_READI_FRAMES _IOR('A', 0x51, struct snd_xferi)
 /* WARNING: DO NOT EDIT, AUTO-GENERATED CODE - SEE TOP FOR INSTRUCTIONS */
+#define SNDRV_PCM_IOCTL_READI_FRAMES _IOR('A', 0x51, struct snd_xferi)
 #define SNDRV_PCM_IOCTL_WRITEN_FRAMES _IOW('A', 0x52, struct snd_xfern)
 #define SNDRV_PCM_IOCTL_READN_FRAMES _IOR('A', 0x53, struct snd_xfern)
 #define SNDRV_PCM_IOCTL_LINK _IOW('A', 0x60, int)
-#define SNDRV_PCM_IOCTL_UNLINK _IO('A', 0x61)
 /* WARNING: DO NOT EDIT, AUTO-GENERATED CODE - SEE TOP FOR INSTRUCTIONS */
+#define SNDRV_PCM_IOCTL_UNLINK _IO('A', 0x61)
 #define SNDRV_RAWMIDI_VERSION SNDRV_PROTOCOL_VERSION(2, 0, 0)
 enum {
   SNDRV_RAWMIDI_STREAM_OUTPUT = 0,
-  SNDRV_RAWMIDI_STREAM_INPUT,
 /* WARNING: DO NOT EDIT, AUTO-GENERATED CODE - SEE TOP FOR INSTRUCTIONS */
+  SNDRV_RAWMIDI_STREAM_INPUT,
   SNDRV_RAWMIDI_STREAM_LAST = SNDRV_RAWMIDI_STREAM_INPUT,
 };
 #define SNDRV_RAWMIDI_INFO_OUTPUT 0x00000001
-#define SNDRV_RAWMIDI_INFO_INPUT 0x00000002
 /* WARNING: DO NOT EDIT, AUTO-GENERATED CODE - SEE TOP FOR INSTRUCTIONS */
+#define SNDRV_RAWMIDI_INFO_INPUT 0x00000002
 #define SNDRV_RAWMIDI_INFO_DUPLEX 0x00000004
 struct snd_rawmidi_info {
   unsigned int device;
-  unsigned int subdevice;
 /* WARNING: DO NOT EDIT, AUTO-GENERATED CODE - SEE TOP FOR INSTRUCTIONS */
+  unsigned int subdevice;
   int stream;
   int card;
   unsigned int flags;
-  unsigned char id[64];
 /* WARNING: DO NOT EDIT, AUTO-GENERATED CODE - SEE TOP FOR INSTRUCTIONS */
+  unsigned char id[64];
   unsigned char name[80];
   unsigned char subname[32];
   unsigned int subdevices_count;
-  unsigned int subdevices_avail;
 /* WARNING: DO NOT EDIT, AUTO-GENERATED CODE - SEE TOP FOR INSTRUCTIONS */
+  unsigned int subdevices_avail;
   unsigned char reserved[64];
 };
 struct snd_rawmidi_params {
-  int stream;
 /* WARNING: DO NOT EDIT, AUTO-GENERATED CODE - SEE TOP FOR INSTRUCTIONS */
+  int stream;
   size_t buffer_size;
   size_t avail_min;
   unsigned int no_active_sensing : 1;
-  unsigned char reserved[16];
 /* WARNING: DO NOT EDIT, AUTO-GENERATED CODE - SEE TOP FOR INSTRUCTIONS */
+  unsigned char reserved[16];
 };
 struct snd_rawmidi_status {
   int stream;
-  struct timespec tstamp;
 /* WARNING: DO NOT EDIT, AUTO-GENERATED CODE - SEE TOP FOR INSTRUCTIONS */
+  struct timespec tstamp;
   size_t avail;
   size_t xruns;
   unsigned char reserved[16];
-};
 /* WARNING: DO NOT EDIT, AUTO-GENERATED CODE - SEE TOP FOR INSTRUCTIONS */
+};
 #define SNDRV_RAWMIDI_IOCTL_PVERSION _IOR('W', 0x00, int)
 #define SNDRV_RAWMIDI_IOCTL_INFO _IOR('W', 0x01, struct snd_rawmidi_info)
 #define SNDRV_RAWMIDI_IOCTL_PARAMS _IOWR('W', 0x10, struct snd_rawmidi_params)
-#define SNDRV_RAWMIDI_IOCTL_STATUS _IOWR('W', 0x20, struct snd_rawmidi_status)
 /* WARNING: DO NOT EDIT, AUTO-GENERATED CODE - SEE TOP FOR INSTRUCTIONS */
+#define SNDRV_RAWMIDI_IOCTL_STATUS _IOWR('W', 0x20, struct snd_rawmidi_status)
 #define SNDRV_RAWMIDI_IOCTL_DROP _IOW('W', 0x30, int)
 #define SNDRV_RAWMIDI_IOCTL_DRAIN _IOW('W', 0x31, int)
 #define SNDRV_TIMER_VERSION SNDRV_PROTOCOL_VERSION(2, 0, 6)
-enum {
 /* WARNING: DO NOT EDIT, AUTO-GENERATED CODE - SEE TOP FOR INSTRUCTIONS */
+enum {
   SNDRV_TIMER_CLASS_NONE = - 1,
   SNDRV_TIMER_CLASS_SLAVE = 0,
   SNDRV_TIMER_CLASS_GLOBAL,
-  SNDRV_TIMER_CLASS_CARD,
 /* WARNING: DO NOT EDIT, AUTO-GENERATED CODE - SEE TOP FOR INSTRUCTIONS */
+  SNDRV_TIMER_CLASS_CARD,
   SNDRV_TIMER_CLASS_PCM,
   SNDRV_TIMER_CLASS_LAST = SNDRV_TIMER_CLASS_PCM,
 };
-enum {
 /* WARNING: DO NOT EDIT, AUTO-GENERATED CODE - SEE TOP FOR INSTRUCTIONS */
+enum {
   SNDRV_TIMER_SCLASS_NONE = 0,
   SNDRV_TIMER_SCLASS_APPLICATION,
   SNDRV_TIMER_SCLASS_SEQUENCER,
-  SNDRV_TIMER_SCLASS_OSS_SEQUENCER,
 /* WARNING: DO NOT EDIT, AUTO-GENERATED CODE - SEE TOP FOR INSTRUCTIONS */
+  SNDRV_TIMER_SCLASS_OSS_SEQUENCER,
   SNDRV_TIMER_SCLASS_LAST = SNDRV_TIMER_SCLASS_OSS_SEQUENCER,
 };
 #define SNDRV_TIMER_GLOBAL_SYSTEM 0
-#define SNDRV_TIMER_GLOBAL_RTC 1
 /* WARNING: DO NOT EDIT, AUTO-GENERATED CODE - SEE TOP FOR INSTRUCTIONS */
+#define SNDRV_TIMER_GLOBAL_RTC 1
 #define SNDRV_TIMER_GLOBAL_HPET 2
 #define SNDRV_TIMER_GLOBAL_HRTIMER 3
 #define SNDRV_TIMER_FLG_SLAVE (1 << 0)
-struct snd_timer_id {
 /* WARNING: DO NOT EDIT, AUTO-GENERATED CODE - SEE TOP FOR INSTRUCTIONS */
+struct snd_timer_id {
   int dev_class;
   int dev_sclass;
   int card;
-  int device;
 /* WARNING: DO NOT EDIT, AUTO-GENERATED CODE - SEE TOP FOR INSTRUCTIONS */
+  int device;
   int subdevice;
 };
 struct snd_timer_ginfo {
-  struct snd_timer_id tid;
 /* WARNING: DO NOT EDIT, AUTO-GENERATED CODE - SEE TOP FOR INSTRUCTIONS */
+  struct snd_timer_id tid;
   unsigned int flags;
   int card;
   unsigned char id[64];
-  unsigned char name[80];
 /* WARNING: DO NOT EDIT, AUTO-GENERATED CODE - SEE TOP FOR INSTRUCTIONS */
+  unsigned char name[80];
   unsigned long reserved0;
   unsigned long resolution;
   unsigned long resolution_min;
-  unsigned long resolution_max;
 /* WARNING: DO NOT EDIT, AUTO-GENERATED CODE - SEE TOP FOR INSTRUCTIONS */
+  unsigned long resolution_max;
   unsigned int clients;
   unsigned char reserved[32];
 };
-struct snd_timer_gparams {
 /* WARNING: DO NOT EDIT, AUTO-GENERATED CODE - SEE TOP FOR INSTRUCTIONS */
+struct snd_timer_gparams {
   struct snd_timer_id tid;
   unsigned long period_num;
   unsigned long period_den;
-  unsigned char reserved[32];
 /* WARNING: DO NOT EDIT, AUTO-GENERATED CODE - SEE TOP FOR INSTRUCTIONS */
+  unsigned char reserved[32];
 };
 struct snd_timer_gstatus {
   struct snd_timer_id tid;
-  unsigned long resolution;
 /* WARNING: DO NOT EDIT, AUTO-GENERATED CODE - SEE TOP FOR INSTRUCTIONS */
+  unsigned long resolution;
   unsigned long resolution_num;
   unsigned long resolution_den;
   unsigned char reserved[32];
-};
 /* WARNING: DO NOT EDIT, AUTO-GENERATED CODE - SEE TOP FOR INSTRUCTIONS */
+};
 struct snd_timer_select {
   struct snd_timer_id id;
   unsigned char reserved[32];
-};
 /* WARNING: DO NOT EDIT, AUTO-GENERATED CODE - SEE TOP FOR INSTRUCTIONS */
+};
 struct snd_timer_info {
   unsigned int flags;
   int card;
-  unsigned char id[64];
 /* WARNING: DO NOT EDIT, AUTO-GENERATED CODE - SEE TOP FOR INSTRUCTIONS */
+  unsigned char id[64];
   unsigned char name[80];
   unsigned long reserved0;
   unsigned long resolution;
-  unsigned char reserved[64];
 /* WARNING: DO NOT EDIT, AUTO-GENERATED CODE - SEE TOP FOR INSTRUCTIONS */
+  unsigned char reserved[64];
 };
 #define SNDRV_TIMER_PSFLG_AUTO (1 << 0)
 #define SNDRV_TIMER_PSFLG_EXCLUSIVE (1 << 1)
-#define SNDRV_TIMER_PSFLG_EARLY_EVENT (1 << 2)
 /* WARNING: DO NOT EDIT, AUTO-GENERATED CODE - SEE TOP FOR INSTRUCTIONS */
+#define SNDRV_TIMER_PSFLG_EARLY_EVENT (1 << 2)
 struct snd_timer_params {
   unsigned int flags;
   unsigned int ticks;
-  unsigned int queue_size;
 /* WARNING: DO NOT EDIT, AUTO-GENERATED CODE - SEE TOP FOR INSTRUCTIONS */
+  unsigned int queue_size;
   unsigned int reserved0;
   unsigned int filter;
   unsigned char reserved[60];
-};
 /* WARNING: DO NOT EDIT, AUTO-GENERATED CODE - SEE TOP FOR INSTRUCTIONS */
+};
 struct snd_timer_status {
   struct timespec tstamp;
   unsigned int resolution;
-  unsigned int lost;
 /* WARNING: DO NOT EDIT, AUTO-GENERATED CODE - SEE TOP FOR INSTRUCTIONS */
+  unsigned int lost;
   unsigned int overrun;
   unsigned int queue;
   unsigned char reserved[64];
-};
 /* WARNING: DO NOT EDIT, AUTO-GENERATED CODE - SEE TOP FOR INSTRUCTIONS */
+};
 #define SNDRV_TIMER_IOCTL_PVERSION _IOR('T', 0x00, int)
 #define SNDRV_TIMER_IOCTL_NEXT_DEVICE _IOWR('T', 0x01, struct snd_timer_id)
 #define SNDRV_TIMER_IOCTL_TREAD _IOW('T', 0x02, int)
-#define SNDRV_TIMER_IOCTL_GINFO _IOWR('T', 0x03, struct snd_timer_ginfo)
 /* WARNING: DO NOT EDIT, AUTO-GENERATED CODE - SEE TOP FOR INSTRUCTIONS */
+#define SNDRV_TIMER_IOCTL_GINFO _IOWR('T', 0x03, struct snd_timer_ginfo)
 #define SNDRV_TIMER_IOCTL_GPARAMS _IOW('T', 0x04, struct snd_timer_gparams)
 #define SNDRV_TIMER_IOCTL_GSTATUS _IOWR('T', 0x05, struct snd_timer_gstatus)
 #define SNDRV_TIMER_IOCTL_SELECT _IOW('T', 0x10, struct snd_timer_select)
-#define SNDRV_TIMER_IOCTL_INFO _IOR('T', 0x11, struct snd_timer_info)
 /* WARNING: DO NOT EDIT, AUTO-GENERATED CODE - SEE TOP FOR INSTRUCTIONS */
+#define SNDRV_TIMER_IOCTL_INFO _IOR('T', 0x11, struct snd_timer_info)
 #define SNDRV_TIMER_IOCTL_PARAMS _IOW('T', 0x12, struct snd_timer_params)
 #define SNDRV_TIMER_IOCTL_STATUS _IOR('T', 0x14, struct snd_timer_status)
 #define SNDRV_TIMER_IOCTL_START _IO('T', 0xa0)
-#define SNDRV_TIMER_IOCTL_STOP _IO('T', 0xa1)
 /* WARNING: DO NOT EDIT, AUTO-GENERATED CODE - SEE TOP FOR INSTRUCTIONS */
+#define SNDRV_TIMER_IOCTL_STOP _IO('T', 0xa1)
 #define SNDRV_TIMER_IOCTL_CONTINUE _IO('T', 0xa2)
 #define SNDRV_TIMER_IOCTL_PAUSE _IO('T', 0xa3)
 struct snd_timer_read {
-  unsigned int resolution;
 /* WARNING: DO NOT EDIT, AUTO-GENERATED CODE - SEE TOP FOR INSTRUCTIONS */
+  unsigned int resolution;
   unsigned int ticks;
 };
 enum {
-  SNDRV_TIMER_EVENT_RESOLUTION = 0,
 /* WARNING: DO NOT EDIT, AUTO-GENERATED CODE - SEE TOP FOR INSTRUCTIONS */
+  SNDRV_TIMER_EVENT_RESOLUTION = 0,
   SNDRV_TIMER_EVENT_TICK,
   SNDRV_TIMER_EVENT_START,
   SNDRV_TIMER_EVENT_STOP,
-  SNDRV_TIMER_EVENT_CONTINUE,
 /* WARNING: DO NOT EDIT, AUTO-GENERATED CODE - SEE TOP FOR INSTRUCTIONS */
+  SNDRV_TIMER_EVENT_CONTINUE,
   SNDRV_TIMER_EVENT_PAUSE,
   SNDRV_TIMER_EVENT_EARLY,
   SNDRV_TIMER_EVENT_SUSPEND,
-  SNDRV_TIMER_EVENT_RESUME,
 /* WARNING: DO NOT EDIT, AUTO-GENERATED CODE - SEE TOP FOR INSTRUCTIONS */
+  SNDRV_TIMER_EVENT_RESUME,
   SNDRV_TIMER_EVENT_MSTART = SNDRV_TIMER_EVENT_START + 10,
   SNDRV_TIMER_EVENT_MSTOP = SNDRV_TIMER_EVENT_STOP + 10,
   SNDRV_TIMER_EVENT_MCONTINUE = SNDRV_TIMER_EVENT_CONTINUE + 10,
-  SNDRV_TIMER_EVENT_MPAUSE = SNDRV_TIMER_EVENT_PAUSE + 10,
 /* WARNING: DO NOT EDIT, AUTO-GENERATED CODE - SEE TOP FOR INSTRUCTIONS */
+  SNDRV_TIMER_EVENT_MPAUSE = SNDRV_TIMER_EVENT_PAUSE + 10,
   SNDRV_TIMER_EVENT_MSUSPEND = SNDRV_TIMER_EVENT_SUSPEND + 10,
   SNDRV_TIMER_EVENT_MRESUME = SNDRV_TIMER_EVENT_RESUME + 10,
 };
-struct snd_timer_tread {
 /* WARNING: DO NOT EDIT, AUTO-GENERATED CODE - SEE TOP FOR INSTRUCTIONS */
+struct snd_timer_tread {
   int event;
   struct timespec tstamp;
   unsigned int val;
-};
 /* WARNING: DO NOT EDIT, AUTO-GENERATED CODE - SEE TOP FOR INSTRUCTIONS */
+};
 #define SNDRV_CTL_VERSION SNDRV_PROTOCOL_VERSION(2, 0, 7)
 struct snd_ctl_card_info {
   int card;
-  int pad;
 /* WARNING: DO NOT EDIT, AUTO-GENERATED CODE - SEE TOP FOR INSTRUCTIONS */
+  int pad;
   unsigned char id[16];
   unsigned char driver[16];
   unsigned char name[32];
-  unsigned char longname[80];
 /* WARNING: DO NOT EDIT, AUTO-GENERATED CODE - SEE TOP FOR INSTRUCTIONS */
+  unsigned char longname[80];
   unsigned char reserved_[16];
   unsigned char mixername[80];
   unsigned char components[128];
-};
 /* WARNING: DO NOT EDIT, AUTO-GENERATED CODE - SEE TOP FOR INSTRUCTIONS */
+};
 typedef int __bitwise snd_ctl_elem_type_t;
 #define SNDRV_CTL_ELEM_TYPE_NONE ((__force snd_ctl_elem_type_t) 0)
 #define SNDRV_CTL_ELEM_TYPE_BOOLEAN ((__force snd_ctl_elem_type_t) 1)
-#define SNDRV_CTL_ELEM_TYPE_INTEGER ((__force snd_ctl_elem_type_t) 2)
 /* WARNING: DO NOT EDIT, AUTO-GENERATED CODE - SEE TOP FOR INSTRUCTIONS */
+#define SNDRV_CTL_ELEM_TYPE_INTEGER ((__force snd_ctl_elem_type_t) 2)
 #define SNDRV_CTL_ELEM_TYPE_ENUMERATED ((__force snd_ctl_elem_type_t) 3)
 #define SNDRV_CTL_ELEM_TYPE_BYTES ((__force snd_ctl_elem_type_t) 4)
 #define SNDRV_CTL_ELEM_TYPE_IEC958 ((__force snd_ctl_elem_type_t) 5)
-#define SNDRV_CTL_ELEM_TYPE_INTEGER64 ((__force snd_ctl_elem_type_t) 6)
 /* WARNING: DO NOT EDIT, AUTO-GENERATED CODE - SEE TOP FOR INSTRUCTIONS */
+#define SNDRV_CTL_ELEM_TYPE_INTEGER64 ((__force snd_ctl_elem_type_t) 6)
 #define SNDRV_CTL_ELEM_TYPE_LAST SNDRV_CTL_ELEM_TYPE_INTEGER64
 typedef int __bitwise snd_ctl_elem_iface_t;
 #define SNDRV_CTL_ELEM_IFACE_CARD ((__force snd_ctl_elem_iface_t) 0)
-#define SNDRV_CTL_ELEM_IFACE_HWDEP ((__force snd_ctl_elem_iface_t) 1)
 /* WARNING: DO NOT EDIT, AUTO-GENERATED CODE - SEE TOP FOR INSTRUCTIONS */
+#define SNDRV_CTL_ELEM_IFACE_HWDEP ((__force snd_ctl_elem_iface_t) 1)
 #define SNDRV_CTL_ELEM_IFACE_MIXER ((__force snd_ctl_elem_iface_t) 2)
 #define SNDRV_CTL_ELEM_IFACE_PCM ((__force snd_ctl_elem_iface_t) 3)
 #define SNDRV_CTL_ELEM_IFACE_RAWMIDI ((__force snd_ctl_elem_iface_t) 4)
-#define SNDRV_CTL_ELEM_IFACE_TIMER ((__force snd_ctl_elem_iface_t) 5)
 /* WARNING: DO NOT EDIT, AUTO-GENERATED CODE - SEE TOP FOR INSTRUCTIONS */
+#define SNDRV_CTL_ELEM_IFACE_TIMER ((__force snd_ctl_elem_iface_t) 5)
 #define SNDRV_CTL_ELEM_IFACE_SEQUENCER ((__force snd_ctl_elem_iface_t) 6)
 #define SNDRV_CTL_ELEM_IFACE_LAST SNDRV_CTL_ELEM_IFACE_SEQUENCER
 #define SNDRV_CTL_ELEM_ACCESS_READ (1 << 0)
-#define SNDRV_CTL_ELEM_ACCESS_WRITE (1 << 1)
 /* WARNING: DO NOT EDIT, AUTO-GENERATED CODE - SEE TOP FOR INSTRUCTIONS */
+#define SNDRV_CTL_ELEM_ACCESS_WRITE (1 << 1)
 #define SNDRV_CTL_ELEM_ACCESS_READWRITE (SNDRV_CTL_ELEM_ACCESS_READ | SNDRV_CTL_ELEM_ACCESS_WRITE)
 #define SNDRV_CTL_ELEM_ACCESS_VOLATILE (1 << 2)
 #define SNDRV_CTL_ELEM_ACCESS_TIMESTAMP (1 << 3)
-#define SNDRV_CTL_ELEM_ACCESS_TLV_READ (1 << 4)
 /* WARNING: DO NOT EDIT, AUTO-GENERATED CODE - SEE TOP FOR INSTRUCTIONS */
+#define SNDRV_CTL_ELEM_ACCESS_TLV_READ (1 << 4)
 #define SNDRV_CTL_ELEM_ACCESS_TLV_WRITE (1 << 5)
 #define SNDRV_CTL_ELEM_ACCESS_TLV_READWRITE (SNDRV_CTL_ELEM_ACCESS_TLV_READ | SNDRV_CTL_ELEM_ACCESS_TLV_WRITE)
 #define SNDRV_CTL_ELEM_ACCESS_TLV_COMMAND (1 << 6)
-#define SNDRV_CTL_ELEM_ACCESS_INACTIVE (1 << 8)
 /* WARNING: DO NOT EDIT, AUTO-GENERATED CODE - SEE TOP FOR INSTRUCTIONS */
+#define SNDRV_CTL_ELEM_ACCESS_INACTIVE (1 << 8)
 #define SNDRV_CTL_ELEM_ACCESS_LOCK (1 << 9)
 #define SNDRV_CTL_ELEM_ACCESS_OWNER (1 << 10)
 #define SNDRV_CTL_ELEM_ACCESS_TLV_CALLBACK (1 << 28)
-#define SNDRV_CTL_ELEM_ACCESS_USER (1 << 29)
 /* WARNING: DO NOT EDIT, AUTO-GENERATED CODE - SEE TOP FOR INSTRUCTIONS */
+#define SNDRV_CTL_ELEM_ACCESS_USER (1 << 29)
 #define SNDRV_CTL_POWER_D0 0x0000
 #define SNDRV_CTL_POWER_D1 0x0100
 #define SNDRV_CTL_POWER_D2 0x0200
-#define SNDRV_CTL_POWER_D3 0x0300
 /* WARNING: DO NOT EDIT, AUTO-GENERATED CODE - SEE TOP FOR INSTRUCTIONS */
+#define SNDRV_CTL_POWER_D3 0x0300
 #define SNDRV_CTL_POWER_D3hot (SNDRV_CTL_POWER_D3 | 0x0000)
 #define SNDRV_CTL_POWER_D3cold (SNDRV_CTL_POWER_D3 | 0x0001)
 #define SNDRV_CTL_ELEM_ID_NAME_MAXLEN 44
-struct snd_ctl_elem_id {
 /* WARNING: DO NOT EDIT, AUTO-GENERATED CODE - SEE TOP FOR INSTRUCTIONS */
+struct snd_ctl_elem_id {
   unsigned int numid;
   snd_ctl_elem_iface_t iface;
   unsigned int device;
-  unsigned int subdevice;
 /* WARNING: DO NOT EDIT, AUTO-GENERATED CODE - SEE TOP FOR INSTRUCTIONS */
-  unsigned char name[44];
+  unsigned int subdevice;
+  unsigned char name[SNDRV_CTL_ELEM_ID_NAME_MAXLEN];
   unsigned int index;
 };
-struct snd_ctl_elem_list {
 /* WARNING: DO NOT EDIT, AUTO-GENERATED CODE - SEE TOP FOR INSTRUCTIONS */
+struct snd_ctl_elem_list {
   unsigned int offset;
   unsigned int space;
   unsigned int used;
-  unsigned int count;
 /* WARNING: DO NOT EDIT, AUTO-GENERATED CODE - SEE TOP FOR INSTRUCTIONS */
+  unsigned int count;
   struct snd_ctl_elem_id __user * pids;
   unsigned char reserved[50];
 };
-struct snd_ctl_elem_info {
 /* WARNING: DO NOT EDIT, AUTO-GENERATED CODE - SEE TOP FOR INSTRUCTIONS */
+struct snd_ctl_elem_info {
   struct snd_ctl_elem_id id;
   snd_ctl_elem_type_t type;
   unsigned int access;
-  unsigned int count;
 /* WARNING: DO NOT EDIT, AUTO-GENERATED CODE - SEE TOP FOR INSTRUCTIONS */
+  unsigned int count;
   __kernel_pid_t owner;
   union {
     struct {
-      long min;
 /* WARNING: DO NOT EDIT, AUTO-GENERATED CODE - SEE TOP FOR INSTRUCTIONS */
+      long min;
       long max;
       long step;
     } integer;
-    struct {
 /* WARNING: DO NOT EDIT, AUTO-GENERATED CODE - SEE TOP FOR INSTRUCTIONS */
+    struct {
       long long min;
       long long max;
       long long step;
-    } integer64;
 /* WARNING: DO NOT EDIT, AUTO-GENERATED CODE - SEE TOP FOR INSTRUCTIONS */
+    } integer64;
     struct {
       unsigned int items;
       unsigned int item;
-      char name[64];
 /* WARNING: DO NOT EDIT, AUTO-GENERATED CODE - SEE TOP FOR INSTRUCTIONS */
+      char name[64];
       __u64 names_ptr;
       unsigned int names_length;
     } enumerated;
-    unsigned char reserved[128];
 /* WARNING: DO NOT EDIT, AUTO-GENERATED CODE - SEE TOP FOR INSTRUCTIONS */
+    unsigned char reserved[128];
   } value;
   union {
     unsigned short d[4];
-    unsigned short * d_ptr;
 /* WARNING: DO NOT EDIT, AUTO-GENERATED CODE - SEE TOP FOR INSTRUCTIONS */
+    unsigned short * d_ptr;
   } dimen;
   unsigned char reserved[64 - 4 * sizeof(unsigned short)];
 };
-struct snd_ctl_elem_value {
 /* WARNING: DO NOT EDIT, AUTO-GENERATED CODE - SEE TOP FOR INSTRUCTIONS */
+struct snd_ctl_elem_value {
   struct snd_ctl_elem_id id;
   unsigned int indirect : 1;
   union {
-    union {
 /* WARNING: DO NOT EDIT, AUTO-GENERATED CODE - SEE TOP FOR INSTRUCTIONS */
+    union {
       long value[128];
       long * value_ptr;
     } integer;
-    union {
 /* WARNING: DO NOT EDIT, AUTO-GENERATED CODE - SEE TOP FOR INSTRUCTIONS */
+    union {
       long long value[64];
       long long * value_ptr;
     } integer64;
-    union {
 /* WARNING: DO NOT EDIT, AUTO-GENERATED CODE - SEE TOP FOR INSTRUCTIONS */
+    union {
       unsigned int item[128];
       unsigned int * item_ptr;
     } enumerated;
-    union {
 /* WARNING: DO NOT EDIT, AUTO-GENERATED CODE - SEE TOP FOR INSTRUCTIONS */
+    union {
       unsigned char data[512];
       unsigned char * data_ptr;
     } bytes;
-    struct snd_aes_iec958 iec958;
 /* WARNING: DO NOT EDIT, AUTO-GENERATED CODE - SEE TOP FOR INSTRUCTIONS */
+    struct snd_aes_iec958 iec958;
   } value;
   struct timespec tstamp;
   unsigned char reserved[128 - sizeof(struct timespec)];
-};
 /* WARNING: DO NOT EDIT, AUTO-GENERATED CODE - SEE TOP FOR INSTRUCTIONS */
+};
 struct snd_ctl_tlv {
   unsigned int numid;
   unsigned int length;
-  unsigned int tlv[0];
 /* WARNING: DO NOT EDIT, AUTO-GENERATED CODE - SEE TOP FOR INSTRUCTIONS */
+  unsigned int tlv[0];
 };
 #define SNDRV_CTL_IOCTL_PVERSION _IOR('U', 0x00, int)
 #define SNDRV_CTL_IOCTL_CARD_INFO _IOR('U', 0x01, struct snd_ctl_card_info)
-#define SNDRV_CTL_IOCTL_ELEM_LIST _IOWR('U', 0x10, struct snd_ctl_elem_list)
 /* WARNING: DO NOT EDIT, AUTO-GENERATED CODE - SEE TOP FOR INSTRUCTIONS */
+#define SNDRV_CTL_IOCTL_ELEM_LIST _IOWR('U', 0x10, struct snd_ctl_elem_list)
 #define SNDRV_CTL_IOCTL_ELEM_INFO _IOWR('U', 0x11, struct snd_ctl_elem_info)
 #define SNDRV_CTL_IOCTL_ELEM_READ _IOWR('U', 0x12, struct snd_ctl_elem_value)
 #define SNDRV_CTL_IOCTL_ELEM_WRITE _IOWR('U', 0x13, struct snd_ctl_elem_value)
-#define SNDRV_CTL_IOCTL_ELEM_LOCK _IOW('U', 0x14, struct snd_ctl_elem_id)
 /* WARNING: DO NOT EDIT, AUTO-GENERATED CODE - SEE TOP FOR INSTRUCTIONS */
+#define SNDRV_CTL_IOCTL_ELEM_LOCK _IOW('U', 0x14, struct snd_ctl_elem_id)
 #define SNDRV_CTL_IOCTL_ELEM_UNLOCK _IOW('U', 0x15, struct snd_ctl_elem_id)
 #define SNDRV_CTL_IOCTL_SUBSCRIBE_EVENTS _IOWR('U', 0x16, int)
 #define SNDRV_CTL_IOCTL_ELEM_ADD _IOWR('U', 0x17, struct snd_ctl_elem_info)
-#define SNDRV_CTL_IOCTL_ELEM_REPLACE _IOWR('U', 0x18, struct snd_ctl_elem_info)
 /* WARNING: DO NOT EDIT, AUTO-GENERATED CODE - SEE TOP FOR INSTRUCTIONS */
+#define SNDRV_CTL_IOCTL_ELEM_REPLACE _IOWR('U', 0x18, struct snd_ctl_elem_info)
 #define SNDRV_CTL_IOCTL_ELEM_REMOVE _IOWR('U', 0x19, struct snd_ctl_elem_id)
 #define SNDRV_CTL_IOCTL_TLV_READ _IOWR('U', 0x1a, struct snd_ctl_tlv)
 #define SNDRV_CTL_IOCTL_TLV_WRITE _IOWR('U', 0x1b, struct snd_ctl_tlv)
-#define SNDRV_CTL_IOCTL_TLV_COMMAND _IOWR('U', 0x1c, struct snd_ctl_tlv)
 /* WARNING: DO NOT EDIT, AUTO-GENERATED CODE - SEE TOP FOR INSTRUCTIONS */
+#define SNDRV_CTL_IOCTL_TLV_COMMAND _IOWR('U', 0x1c, struct snd_ctl_tlv)
 #define SNDRV_CTL_IOCTL_HWDEP_NEXT_DEVICE _IOWR('U', 0x20, int)
 #define SNDRV_CTL_IOCTL_HWDEP_INFO _IOR('U', 0x21, struct snd_hwdep_info)
 #define SNDRV_CTL_IOCTL_PCM_NEXT_DEVICE _IOR('U', 0x30, int)
-#define SNDRV_CTL_IOCTL_PCM_INFO _IOWR('U', 0x31, struct snd_pcm_info)
 /* WARNING: DO NOT EDIT, AUTO-GENERATED CODE - SEE TOP FOR INSTRUCTIONS */
+#define SNDRV_CTL_IOCTL_PCM_INFO _IOWR('U', 0x31, struct snd_pcm_info)
 #define SNDRV_CTL_IOCTL_PCM_PREFER_SUBDEVICE _IOW('U', 0x32, int)
 #define SNDRV_CTL_IOCTL_RAWMIDI_NEXT_DEVICE _IOWR('U', 0x40, int)
 #define SNDRV_CTL_IOCTL_RAWMIDI_INFO _IOWR('U', 0x41, struct snd_rawmidi_info)
-#define SNDRV_CTL_IOCTL_RAWMIDI_PREFER_SUBDEVICE _IOW('U', 0x42, int)
 /* WARNING: DO NOT EDIT, AUTO-GENERATED CODE - SEE TOP FOR INSTRUCTIONS */
+#define SNDRV_CTL_IOCTL_RAWMIDI_PREFER_SUBDEVICE _IOW('U', 0x42, int)
 #define SNDRV_CTL_IOCTL_POWER _IOWR('U', 0xd0, int)
 #define SNDRV_CTL_IOCTL_POWER_STATE _IOR('U', 0xd1, int)
 enum sndrv_ctl_event_type {
-  SNDRV_CTL_EVENT_ELEM = 0,
 /* WARNING: DO NOT EDIT, AUTO-GENERATED CODE - SEE TOP FOR INSTRUCTIONS */
+  SNDRV_CTL_EVENT_ELEM = 0,
   SNDRV_CTL_EVENT_LAST = SNDRV_CTL_EVENT_ELEM,
 };
 #define SNDRV_CTL_EVENT_MASK_VALUE (1 << 0)
-#define SNDRV_CTL_EVENT_MASK_INFO (1 << 1)
 /* WARNING: DO NOT EDIT, AUTO-GENERATED CODE - SEE TOP FOR INSTRUCTIONS */
+#define SNDRV_CTL_EVENT_MASK_INFO (1 << 1)
 #define SNDRV_CTL_EVENT_MASK_ADD (1 << 2)
 #define SNDRV_CTL_EVENT_MASK_TLV (1 << 3)
 #define SNDRV_CTL_EVENT_MASK_REMOVE (~0U)
-struct snd_ctl_event {
 /* WARNING: DO NOT EDIT, AUTO-GENERATED CODE - SEE TOP FOR INSTRUCTIONS */
+struct snd_ctl_event {
   int type;
   union {
     struct {
-      unsigned int mask;
 /* WARNING: DO NOT EDIT, AUTO-GENERATED CODE - SEE TOP FOR INSTRUCTIONS */
+      unsigned int mask;
       struct snd_ctl_elem_id id;
     } elem;
     unsigned char data8[60];
-  } data;
 /* WARNING: DO NOT EDIT, AUTO-GENERATED CODE - SEE TOP FOR INSTRUCTIONS */
+  } data;
 };
 #define SNDRV_CTL_NAME_NONE ""
 #define SNDRV_CTL_NAME_PLAYBACK "Playback "
-#define SNDRV_CTL_NAME_CAPTURE "Capture "
 /* WARNING: DO NOT EDIT, AUTO-GENERATED CODE - SEE TOP FOR INSTRUCTIONS */
+#define SNDRV_CTL_NAME_CAPTURE "Capture "
 #define SNDRV_CTL_NAME_IEC958_NONE ""
 #define SNDRV_CTL_NAME_IEC958_SWITCH "Switch"
 #define SNDRV_CTL_NAME_IEC958_VOLUME "Volume"
-#define SNDRV_CTL_NAME_IEC958_DEFAULT "Default"
 /* WARNING: DO NOT EDIT, AUTO-GENERATED CODE - SEE TOP FOR INSTRUCTIONS */
+#define SNDRV_CTL_NAME_IEC958_DEFAULT "Default"
 #define SNDRV_CTL_NAME_IEC958_MASK "Mask"
 #define SNDRV_CTL_NAME_IEC958_CON_MASK "Con Mask"
 #define SNDRV_CTL_NAME_IEC958_PRO_MASK "Pro Mask"
-#define SNDRV_CTL_NAME_IEC958_PCM_STREAM "PCM Stream"
 /* WARNING: DO NOT EDIT, AUTO-GENERATED CODE - SEE TOP FOR INSTRUCTIONS */
+#define SNDRV_CTL_NAME_IEC958_PCM_STREAM "PCM Stream"
 #define SNDRV_CTL_NAME_IEC958(expl,direction,what) "IEC958 " expl SNDRV_CTL_NAME_ ##direction SNDRV_CTL_NAME_IEC958_ ##what
 #endif
diff --git a/libc/kernel/uapi/sound/compress_offload.h b/libc/kernel/uapi/sound/compress_offload.h
index 8928cbf..0f6077f 100644
--- a/libc/kernel/uapi/sound/compress_offload.h
+++ b/libc/kernel/uapi/sound/compress_offload.h
@@ -72,7 +72,7 @@
   struct snd_codec_desc descriptor[MAX_NUM_CODEC_DESCRIPTORS];
 /* WARNING: DO NOT EDIT, AUTO-GENERATED CODE - SEE TOP FOR INSTRUCTIONS */
 } __attribute__((packed, aligned(4)));
-enum {
+enum sndrv_compress_encoder {
   SNDRV_COMPRESS_ENCODER_PADDING = 1,
   SNDRV_COMPRESS_ENCODER_DELAY = 2,
 /* WARNING: DO NOT EDIT, AUTO-GENERATED CODE - SEE TOP FOR INSTRUCTIONS */
diff --git a/libc/kernel/uapi/sound/emu10k1.h b/libc/kernel/uapi/sound/emu10k1.h
index 9701227..b03fce6 100644
--- a/libc/kernel/uapi/sound/emu10k1.h
+++ b/libc/kernel/uapi/sound/emu10k1.h
@@ -19,368 +19,371 @@
 #ifndef _UAPI__SOUND_EMU10K1_H
 #define _UAPI__SOUND_EMU10K1_H
 #include <linux/types.h>
-#define EMU10K1_CARD_CREATIVE 0x00000000
+#include <sound/asound.h>
 /* WARNING: DO NOT EDIT, AUTO-GENERATED CODE - SEE TOP FOR INSTRUCTIONS */
+#define EMU10K1_CARD_CREATIVE 0x00000000
 #define EMU10K1_CARD_EMUAPS 0x00000001
 #define EMU10K1_FX8010_PCM_COUNT 8
+#define __EMU10K1_DECLARE_BITMAP(name,bits) unsigned long name[(bits) / (sizeof(unsigned long) * 8)]
+/* WARNING: DO NOT EDIT, AUTO-GENERATED CODE - SEE TOP FOR INSTRUCTIONS */
 #define iMAC0 0x00
 #define iMAC1 0x01
-/* WARNING: DO NOT EDIT, AUTO-GENERATED CODE - SEE TOP FOR INSTRUCTIONS */
 #define iMAC2 0x02
 #define iMAC3 0x03
+/* WARNING: DO NOT EDIT, AUTO-GENERATED CODE - SEE TOP FOR INSTRUCTIONS */
 #define iMACINT0 0x04
 #define iMACINT1 0x05
-/* WARNING: DO NOT EDIT, AUTO-GENERATED CODE - SEE TOP FOR INSTRUCTIONS */
 #define iACC3 0x06
 #define iMACMV 0x07
+/* WARNING: DO NOT EDIT, AUTO-GENERATED CODE - SEE TOP FOR INSTRUCTIONS */
 #define iANDXOR 0x08
 #define iTSTNEG 0x09
-/* WARNING: DO NOT EDIT, AUTO-GENERATED CODE - SEE TOP FOR INSTRUCTIONS */
 #define iLIMITGE 0x0a
 #define iLIMITLT 0x0b
+/* WARNING: DO NOT EDIT, AUTO-GENERATED CODE - SEE TOP FOR INSTRUCTIONS */
 #define iLOG 0x0c
 #define iEXP 0x0d
-/* WARNING: DO NOT EDIT, AUTO-GENERATED CODE - SEE TOP FOR INSTRUCTIONS */
 #define iINTERP 0x0e
 #define iSKIP 0x0f
+/* WARNING: DO NOT EDIT, AUTO-GENERATED CODE - SEE TOP FOR INSTRUCTIONS */
 #define FXBUS(x) (0x00 + (x))
 #define EXTIN(x) (0x10 + (x))
-/* WARNING: DO NOT EDIT, AUTO-GENERATED CODE - SEE TOP FOR INSTRUCTIONS */
 #define EXTOUT(x) (0x20 + (x))
 #define FXBUS2(x) (0x30 + (x))
+/* WARNING: DO NOT EDIT, AUTO-GENERATED CODE - SEE TOP FOR INSTRUCTIONS */
 #define C_00000000 0x40
 #define C_00000001 0x41
-/* WARNING: DO NOT EDIT, AUTO-GENERATED CODE - SEE TOP FOR INSTRUCTIONS */
 #define C_00000002 0x42
 #define C_00000003 0x43
+/* WARNING: DO NOT EDIT, AUTO-GENERATED CODE - SEE TOP FOR INSTRUCTIONS */
 #define C_00000004 0x44
 #define C_00000008 0x45
-/* WARNING: DO NOT EDIT, AUTO-GENERATED CODE - SEE TOP FOR INSTRUCTIONS */
 #define C_00000010 0x46
 #define C_00000020 0x47
+/* WARNING: DO NOT EDIT, AUTO-GENERATED CODE - SEE TOP FOR INSTRUCTIONS */
 #define C_00000100 0x48
 #define C_00010000 0x49
-/* WARNING: DO NOT EDIT, AUTO-GENERATED CODE - SEE TOP FOR INSTRUCTIONS */
 #define C_00080000 0x4a
 #define C_10000000 0x4b
+/* WARNING: DO NOT EDIT, AUTO-GENERATED CODE - SEE TOP FOR INSTRUCTIONS */
 #define C_20000000 0x4c
 #define C_40000000 0x4d
-/* WARNING: DO NOT EDIT, AUTO-GENERATED CODE - SEE TOP FOR INSTRUCTIONS */
 #define C_80000000 0x4e
 #define C_7fffffff 0x4f
+/* WARNING: DO NOT EDIT, AUTO-GENERATED CODE - SEE TOP FOR INSTRUCTIONS */
 #define C_ffffffff 0x50
 #define C_fffffffe 0x51
-/* WARNING: DO NOT EDIT, AUTO-GENERATED CODE - SEE TOP FOR INSTRUCTIONS */
 #define C_c0000000 0x52
 #define C_4f1bbcdc 0x53
+/* WARNING: DO NOT EDIT, AUTO-GENERATED CODE - SEE TOP FOR INSTRUCTIONS */
 #define C_5a7ef9db 0x54
 #define C_00100000 0x55
-/* WARNING: DO NOT EDIT, AUTO-GENERATED CODE - SEE TOP FOR INSTRUCTIONS */
 #define GPR_ACCU 0x56
 #define GPR_COND 0x57
+/* WARNING: DO NOT EDIT, AUTO-GENERATED CODE - SEE TOP FOR INSTRUCTIONS */
 #define GPR_NOISE0 0x58
 #define GPR_NOISE1 0x59
-/* WARNING: DO NOT EDIT, AUTO-GENERATED CODE - SEE TOP FOR INSTRUCTIONS */
 #define GPR_IRQ 0x5a
 #define GPR_DBAC 0x5b
+/* WARNING: DO NOT EDIT, AUTO-GENERATED CODE - SEE TOP FOR INSTRUCTIONS */
 #define GPR(x) (FXGPREGBASE + (x))
 #define ITRAM_DATA(x) (TANKMEMDATAREGBASE + 0x00 + (x))
-/* WARNING: DO NOT EDIT, AUTO-GENERATED CODE - SEE TOP FOR INSTRUCTIONS */
 #define ETRAM_DATA(x) (TANKMEMDATAREGBASE + 0x80 + (x))
 #define ITRAM_ADDR(x) (TANKMEMADDRREGBASE + 0x00 + (x))
+/* WARNING: DO NOT EDIT, AUTO-GENERATED CODE - SEE TOP FOR INSTRUCTIONS */
 #define ETRAM_ADDR(x) (TANKMEMADDRREGBASE + 0x80 + (x))
 #define A_ITRAM_DATA(x) (TANKMEMDATAREGBASE + 0x00 + (x))
-/* WARNING: DO NOT EDIT, AUTO-GENERATED CODE - SEE TOP FOR INSTRUCTIONS */
 #define A_ETRAM_DATA(x) (TANKMEMDATAREGBASE + 0xc0 + (x))
 #define A_ITRAM_ADDR(x) (TANKMEMADDRREGBASE + 0x00 + (x))
+/* WARNING: DO NOT EDIT, AUTO-GENERATED CODE - SEE TOP FOR INSTRUCTIONS */
 #define A_ETRAM_ADDR(x) (TANKMEMADDRREGBASE + 0xc0 + (x))
 #define A_ITRAM_CTL(x) (A_TANKMEMCTLREGBASE + 0x00 + (x))
-/* WARNING: DO NOT EDIT, AUTO-GENERATED CODE - SEE TOP FOR INSTRUCTIONS */
 #define A_ETRAM_CTL(x) (A_TANKMEMCTLREGBASE + 0xc0 + (x))
 #define A_FXBUS(x) (0x00 + (x))
+/* WARNING: DO NOT EDIT, AUTO-GENERATED CODE - SEE TOP FOR INSTRUCTIONS */
 #define A_EXTIN(x) (0x40 + (x))
 #define A_P16VIN(x) (0x50 + (x))
-/* WARNING: DO NOT EDIT, AUTO-GENERATED CODE - SEE TOP FOR INSTRUCTIONS */
 #define A_EXTOUT(x) (0x60 + (x))
 #define A_FXBUS2(x) (0x80 + (x))
+/* WARNING: DO NOT EDIT, AUTO-GENERATED CODE - SEE TOP FOR INSTRUCTIONS */
 #define A_EMU32OUTH(x) (0xa0 + (x))
 #define A_EMU32OUTL(x) (0xb0 + (x))
-/* WARNING: DO NOT EDIT, AUTO-GENERATED CODE - SEE TOP FOR INSTRUCTIONS */
 #define A3_EMU32IN(x) (0x160 + (x))
 #define A3_EMU32OUT(x) (0x1E0 + (x))
+/* WARNING: DO NOT EDIT, AUTO-GENERATED CODE - SEE TOP FOR INSTRUCTIONS */
 #define A_GPR(x) (A_FXGPREGBASE + (x))
 #define CC_REG_NORMALIZED C_00000001
-/* WARNING: DO NOT EDIT, AUTO-GENERATED CODE - SEE TOP FOR INSTRUCTIONS */
 #define CC_REG_BORROW C_00000002
 #define CC_REG_MINUS C_00000004
+/* WARNING: DO NOT EDIT, AUTO-GENERATED CODE - SEE TOP FOR INSTRUCTIONS */
 #define CC_REG_ZERO C_00000008
 #define CC_REG_SATURATE C_00000010
-/* WARNING: DO NOT EDIT, AUTO-GENERATED CODE - SEE TOP FOR INSTRUCTIONS */
 #define CC_REG_NONZERO C_00000100
 #define FXBUS_PCM_LEFT 0x00
+/* WARNING: DO NOT EDIT, AUTO-GENERATED CODE - SEE TOP FOR INSTRUCTIONS */
 #define FXBUS_PCM_RIGHT 0x01
 #define FXBUS_PCM_LEFT_REAR 0x02
-/* WARNING: DO NOT EDIT, AUTO-GENERATED CODE - SEE TOP FOR INSTRUCTIONS */
 #define FXBUS_PCM_RIGHT_REAR 0x03
 #define FXBUS_MIDI_LEFT 0x04
+/* WARNING: DO NOT EDIT, AUTO-GENERATED CODE - SEE TOP FOR INSTRUCTIONS */
 #define FXBUS_MIDI_RIGHT 0x05
 #define FXBUS_PCM_CENTER 0x06
-/* WARNING: DO NOT EDIT, AUTO-GENERATED CODE - SEE TOP FOR INSTRUCTIONS */
 #define FXBUS_PCM_LFE 0x07
 #define FXBUS_PCM_LEFT_FRONT 0x08
+/* WARNING: DO NOT EDIT, AUTO-GENERATED CODE - SEE TOP FOR INSTRUCTIONS */
 #define FXBUS_PCM_RIGHT_FRONT 0x09
 #define FXBUS_MIDI_REVERB 0x0c
-/* WARNING: DO NOT EDIT, AUTO-GENERATED CODE - SEE TOP FOR INSTRUCTIONS */
 #define FXBUS_MIDI_CHORUS 0x0d
 #define FXBUS_PCM_LEFT_SIDE 0x0e
+/* WARNING: DO NOT EDIT, AUTO-GENERATED CODE - SEE TOP FOR INSTRUCTIONS */
 #define FXBUS_PCM_RIGHT_SIDE 0x0f
 #define FXBUS_PT_LEFT 0x14
-/* WARNING: DO NOT EDIT, AUTO-GENERATED CODE - SEE TOP FOR INSTRUCTIONS */
 #define FXBUS_PT_RIGHT 0x15
 #define EXTIN_AC97_L 0x00
+/* WARNING: DO NOT EDIT, AUTO-GENERATED CODE - SEE TOP FOR INSTRUCTIONS */
 #define EXTIN_AC97_R 0x01
 #define EXTIN_SPDIF_CD_L 0x02
-/* WARNING: DO NOT EDIT, AUTO-GENERATED CODE - SEE TOP FOR INSTRUCTIONS */
 #define EXTIN_SPDIF_CD_R 0x03
 #define EXTIN_ZOOM_L 0x04
+/* WARNING: DO NOT EDIT, AUTO-GENERATED CODE - SEE TOP FOR INSTRUCTIONS */
 #define EXTIN_ZOOM_R 0x05
 #define EXTIN_TOSLINK_L 0x06
-/* WARNING: DO NOT EDIT, AUTO-GENERATED CODE - SEE TOP FOR INSTRUCTIONS */
 #define EXTIN_TOSLINK_R 0x07
 #define EXTIN_LINE1_L 0x08
+/* WARNING: DO NOT EDIT, AUTO-GENERATED CODE - SEE TOP FOR INSTRUCTIONS */
 #define EXTIN_LINE1_R 0x09
 #define EXTIN_COAX_SPDIF_L 0x0a
-/* WARNING: DO NOT EDIT, AUTO-GENERATED CODE - SEE TOP FOR INSTRUCTIONS */
 #define EXTIN_COAX_SPDIF_R 0x0b
 #define EXTIN_LINE2_L 0x0c
+/* WARNING: DO NOT EDIT, AUTO-GENERATED CODE - SEE TOP FOR INSTRUCTIONS */
 #define EXTIN_LINE2_R 0x0d
 #define EXTOUT_AC97_L 0x00
-/* WARNING: DO NOT EDIT, AUTO-GENERATED CODE - SEE TOP FOR INSTRUCTIONS */
 #define EXTOUT_AC97_R 0x01
 #define EXTOUT_TOSLINK_L 0x02
+/* WARNING: DO NOT EDIT, AUTO-GENERATED CODE - SEE TOP FOR INSTRUCTIONS */
 #define EXTOUT_TOSLINK_R 0x03
 #define EXTOUT_AC97_CENTER 0x04
-/* WARNING: DO NOT EDIT, AUTO-GENERATED CODE - SEE TOP FOR INSTRUCTIONS */
 #define EXTOUT_AC97_LFE 0x05
 #define EXTOUT_HEADPHONE_L 0x06
+/* WARNING: DO NOT EDIT, AUTO-GENERATED CODE - SEE TOP FOR INSTRUCTIONS */
 #define EXTOUT_HEADPHONE_R 0x07
 #define EXTOUT_REAR_L 0x08
-/* WARNING: DO NOT EDIT, AUTO-GENERATED CODE - SEE TOP FOR INSTRUCTIONS */
 #define EXTOUT_REAR_R 0x09
 #define EXTOUT_ADC_CAP_L 0x0a
+/* WARNING: DO NOT EDIT, AUTO-GENERATED CODE - SEE TOP FOR INSTRUCTIONS */
 #define EXTOUT_ADC_CAP_R 0x0b
 #define EXTOUT_MIC_CAP 0x0c
-/* WARNING: DO NOT EDIT, AUTO-GENERATED CODE - SEE TOP FOR INSTRUCTIONS */
 #define EXTOUT_AC97_REAR_L 0x0d
 #define EXTOUT_AC97_REAR_R 0x0e
+/* WARNING: DO NOT EDIT, AUTO-GENERATED CODE - SEE TOP FOR INSTRUCTIONS */
 #define EXTOUT_ACENTER 0x11
 #define EXTOUT_ALFE 0x12
-/* WARNING: DO NOT EDIT, AUTO-GENERATED CODE - SEE TOP FOR INSTRUCTIONS */
 #define A_EXTIN_AC97_L 0x00
 #define A_EXTIN_AC97_R 0x01
+/* WARNING: DO NOT EDIT, AUTO-GENERATED CODE - SEE TOP FOR INSTRUCTIONS */
 #define A_EXTIN_SPDIF_CD_L 0x02
 #define A_EXTIN_SPDIF_CD_R 0x03
-/* WARNING: DO NOT EDIT, AUTO-GENERATED CODE - SEE TOP FOR INSTRUCTIONS */
 #define A_EXTIN_OPT_SPDIF_L 0x04
 #define A_EXTIN_OPT_SPDIF_R 0x05
+/* WARNING: DO NOT EDIT, AUTO-GENERATED CODE - SEE TOP FOR INSTRUCTIONS */
 #define A_EXTIN_LINE2_L 0x08
 #define A_EXTIN_LINE2_R 0x09
-/* WARNING: DO NOT EDIT, AUTO-GENERATED CODE - SEE TOP FOR INSTRUCTIONS */
 #define A_EXTIN_ADC_L 0x0a
 #define A_EXTIN_ADC_R 0x0b
+/* WARNING: DO NOT EDIT, AUTO-GENERATED CODE - SEE TOP FOR INSTRUCTIONS */
 #define A_EXTIN_AUX2_L 0x0c
 #define A_EXTIN_AUX2_R 0x0d
-/* WARNING: DO NOT EDIT, AUTO-GENERATED CODE - SEE TOP FOR INSTRUCTIONS */
 #define A_EXTOUT_FRONT_L 0x00
 #define A_EXTOUT_FRONT_R 0x01
+/* WARNING: DO NOT EDIT, AUTO-GENERATED CODE - SEE TOP FOR INSTRUCTIONS */
 #define A_EXTOUT_CENTER 0x02
 #define A_EXTOUT_LFE 0x03
-/* WARNING: DO NOT EDIT, AUTO-GENERATED CODE - SEE TOP FOR INSTRUCTIONS */
 #define A_EXTOUT_HEADPHONE_L 0x04
 #define A_EXTOUT_HEADPHONE_R 0x05
+/* WARNING: DO NOT EDIT, AUTO-GENERATED CODE - SEE TOP FOR INSTRUCTIONS */
 #define A_EXTOUT_REAR_L 0x06
 #define A_EXTOUT_REAR_R 0x07
-/* WARNING: DO NOT EDIT, AUTO-GENERATED CODE - SEE TOP FOR INSTRUCTIONS */
 #define A_EXTOUT_AFRONT_L 0x08
 #define A_EXTOUT_AFRONT_R 0x09
+/* WARNING: DO NOT EDIT, AUTO-GENERATED CODE - SEE TOP FOR INSTRUCTIONS */
 #define A_EXTOUT_ACENTER 0x0a
 #define A_EXTOUT_ALFE 0x0b
-/* WARNING: DO NOT EDIT, AUTO-GENERATED CODE - SEE TOP FOR INSTRUCTIONS */
 #define A_EXTOUT_ASIDE_L 0x0c
 #define A_EXTOUT_ASIDE_R 0x0d
+/* WARNING: DO NOT EDIT, AUTO-GENERATED CODE - SEE TOP FOR INSTRUCTIONS */
 #define A_EXTOUT_AREAR_L 0x0e
 #define A_EXTOUT_AREAR_R 0x0f
-/* WARNING: DO NOT EDIT, AUTO-GENERATED CODE - SEE TOP FOR INSTRUCTIONS */
 #define A_EXTOUT_AC97_L 0x10
 #define A_EXTOUT_AC97_R 0x11
+/* WARNING: DO NOT EDIT, AUTO-GENERATED CODE - SEE TOP FOR INSTRUCTIONS */
 #define A_EXTOUT_ADC_CAP_L 0x16
 #define A_EXTOUT_ADC_CAP_R 0x17
-/* WARNING: DO NOT EDIT, AUTO-GENERATED CODE - SEE TOP FOR INSTRUCTIONS */
 #define A_EXTOUT_MIC_CAP 0x18
 #define A_C_00000000 0xc0
+/* WARNING: DO NOT EDIT, AUTO-GENERATED CODE - SEE TOP FOR INSTRUCTIONS */
 #define A_C_00000001 0xc1
 #define A_C_00000002 0xc2
-/* WARNING: DO NOT EDIT, AUTO-GENERATED CODE - SEE TOP FOR INSTRUCTIONS */
 #define A_C_00000003 0xc3
 #define A_C_00000004 0xc4
+/* WARNING: DO NOT EDIT, AUTO-GENERATED CODE - SEE TOP FOR INSTRUCTIONS */
 #define A_C_00000008 0xc5
 #define A_C_00000010 0xc6
-/* WARNING: DO NOT EDIT, AUTO-GENERATED CODE - SEE TOP FOR INSTRUCTIONS */
 #define A_C_00000020 0xc7
 #define A_C_00000100 0xc8
+/* WARNING: DO NOT EDIT, AUTO-GENERATED CODE - SEE TOP FOR INSTRUCTIONS */
 #define A_C_00010000 0xc9
 #define A_C_00000800 0xca
-/* WARNING: DO NOT EDIT, AUTO-GENERATED CODE - SEE TOP FOR INSTRUCTIONS */
 #define A_C_10000000 0xcb
 #define A_C_20000000 0xcc
+/* WARNING: DO NOT EDIT, AUTO-GENERATED CODE - SEE TOP FOR INSTRUCTIONS */
 #define A_C_40000000 0xcd
 #define A_C_80000000 0xce
-/* WARNING: DO NOT EDIT, AUTO-GENERATED CODE - SEE TOP FOR INSTRUCTIONS */
 #define A_C_7fffffff 0xcf
 #define A_C_ffffffff 0xd0
+/* WARNING: DO NOT EDIT, AUTO-GENERATED CODE - SEE TOP FOR INSTRUCTIONS */
 #define A_C_fffffffe 0xd1
 #define A_C_c0000000 0xd2
-/* WARNING: DO NOT EDIT, AUTO-GENERATED CODE - SEE TOP FOR INSTRUCTIONS */
 #define A_C_4f1bbcdc 0xd3
 #define A_C_5a7ef9db 0xd4
+/* WARNING: DO NOT EDIT, AUTO-GENERATED CODE - SEE TOP FOR INSTRUCTIONS */
 #define A_C_00100000 0xd5
 #define A_GPR_ACCU 0xd6
-/* WARNING: DO NOT EDIT, AUTO-GENERATED CODE - SEE TOP FOR INSTRUCTIONS */
 #define A_GPR_COND 0xd7
 #define A_GPR_NOISE0 0xd8
+/* WARNING: DO NOT EDIT, AUTO-GENERATED CODE - SEE TOP FOR INSTRUCTIONS */
 #define A_GPR_NOISE1 0xd9
 #define A_GPR_IRQ 0xda
-/* WARNING: DO NOT EDIT, AUTO-GENERATED CODE - SEE TOP FOR INSTRUCTIONS */
 #define A_GPR_DBAC 0xdb
 #define A_GPR_DBACE 0xde
+/* WARNING: DO NOT EDIT, AUTO-GENERATED CODE - SEE TOP FOR INSTRUCTIONS */
 #define EMU10K1_DBG_ZC 0x80000000
 #define EMU10K1_DBG_SATURATION_OCCURED 0x02000000
-/* WARNING: DO NOT EDIT, AUTO-GENERATED CODE - SEE TOP FOR INSTRUCTIONS */
 #define EMU10K1_DBG_SATURATION_ADDR 0x01ff0000
 #define EMU10K1_DBG_SINGLE_STEP 0x00008000
+/* WARNING: DO NOT EDIT, AUTO-GENERATED CODE - SEE TOP FOR INSTRUCTIONS */
 #define EMU10K1_DBG_STEP 0x00004000
 #define EMU10K1_DBG_CONDITION_CODE 0x00003e00
-/* WARNING: DO NOT EDIT, AUTO-GENERATED CODE - SEE TOP FOR INSTRUCTIONS */
 #define EMU10K1_DBG_SINGLE_STEP_ADDR 0x000001ff
 #define TANKMEMADDRREG_ADDR_MASK 0x000fffff
+/* WARNING: DO NOT EDIT, AUTO-GENERATED CODE - SEE TOP FOR INSTRUCTIONS */
 #define TANKMEMADDRREG_CLEAR 0x00800000
 #define TANKMEMADDRREG_ALIGN 0x00400000
-/* WARNING: DO NOT EDIT, AUTO-GENERATED CODE - SEE TOP FOR INSTRUCTIONS */
 #define TANKMEMADDRREG_WRITE 0x00200000
 #define TANKMEMADDRREG_READ 0x00100000
+/* WARNING: DO NOT EDIT, AUTO-GENERATED CODE - SEE TOP FOR INSTRUCTIONS */
 struct snd_emu10k1_fx8010_info {
   unsigned int internal_tram_size;
-/* WARNING: DO NOT EDIT, AUTO-GENERATED CODE - SEE TOP FOR INSTRUCTIONS */
   unsigned int external_tram_size;
   char fxbus_names[16][32];
+/* WARNING: DO NOT EDIT, AUTO-GENERATED CODE - SEE TOP FOR INSTRUCTIONS */
   char extin_names[16][32];
   char extout_names[32][32];
-/* WARNING: DO NOT EDIT, AUTO-GENERATED CODE - SEE TOP FOR INSTRUCTIONS */
   unsigned int gpr_controls;
 };
+/* WARNING: DO NOT EDIT, AUTO-GENERATED CODE - SEE TOP FOR INSTRUCTIONS */
 #define EMU10K1_GPR_TRANSLATION_NONE 0
 #define EMU10K1_GPR_TRANSLATION_TABLE100 1
-/* WARNING: DO NOT EDIT, AUTO-GENERATED CODE - SEE TOP FOR INSTRUCTIONS */
 #define EMU10K1_GPR_TRANSLATION_BASS 2
 #define EMU10K1_GPR_TRANSLATION_TREBLE 3
+/* WARNING: DO NOT EDIT, AUTO-GENERATED CODE - SEE TOP FOR INSTRUCTIONS */
 #define EMU10K1_GPR_TRANSLATION_ONOFF 4
 struct snd_emu10k1_fx8010_control_gpr {
-/* WARNING: DO NOT EDIT, AUTO-GENERATED CODE - SEE TOP FOR INSTRUCTIONS */
   struct snd_ctl_elem_id id;
   unsigned int vcount;
+/* WARNING: DO NOT EDIT, AUTO-GENERATED CODE - SEE TOP FOR INSTRUCTIONS */
   unsigned int count;
   unsigned short gpr[32];
-/* WARNING: DO NOT EDIT, AUTO-GENERATED CODE - SEE TOP FOR INSTRUCTIONS */
   unsigned int value[32];
   unsigned int min;
+/* WARNING: DO NOT EDIT, AUTO-GENERATED CODE - SEE TOP FOR INSTRUCTIONS */
   unsigned int max;
   unsigned int translation;
-/* WARNING: DO NOT EDIT, AUTO-GENERATED CODE - SEE TOP FOR INSTRUCTIONS */
   const unsigned int * tlv;
 };
+/* WARNING: DO NOT EDIT, AUTO-GENERATED CODE - SEE TOP FOR INSTRUCTIONS */
 struct snd_emu10k1_fx8010_control_old_gpr {
   struct snd_ctl_elem_id id;
-/* WARNING: DO NOT EDIT, AUTO-GENERATED CODE - SEE TOP FOR INSTRUCTIONS */
   unsigned int vcount;
   unsigned int count;
+/* WARNING: DO NOT EDIT, AUTO-GENERATED CODE - SEE TOP FOR INSTRUCTIONS */
   unsigned short gpr[32];
   unsigned int value[32];
-/* WARNING: DO NOT EDIT, AUTO-GENERATED CODE - SEE TOP FOR INSTRUCTIONS */
   unsigned int min;
   unsigned int max;
+/* WARNING: DO NOT EDIT, AUTO-GENERATED CODE - SEE TOP FOR INSTRUCTIONS */
   unsigned int translation;
 };
-/* WARNING: DO NOT EDIT, AUTO-GENERATED CODE - SEE TOP FOR INSTRUCTIONS */
 struct snd_emu10k1_fx8010_code {
   char name[128];
-  DECLARE_BITMAP(gpr_valid, 0x200);
-  __u32 __user * gpr_map;
 /* WARNING: DO NOT EDIT, AUTO-GENERATED CODE - SEE TOP FOR INSTRUCTIONS */
+  __EMU10K1_DECLARE_BITMAP(gpr_valid, 0x200);
+  __u32 __user * gpr_map;
   unsigned int gpr_add_control_count;
   struct snd_emu10k1_fx8010_control_gpr __user * gpr_add_controls;
+/* WARNING: DO NOT EDIT, AUTO-GENERATED CODE - SEE TOP FOR INSTRUCTIONS */
   unsigned int gpr_del_control_count;
   struct snd_ctl_elem_id __user * gpr_del_controls;
-/* WARNING: DO NOT EDIT, AUTO-GENERATED CODE - SEE TOP FOR INSTRUCTIONS */
   unsigned int gpr_list_control_count;
   unsigned int gpr_list_control_total;
-  struct snd_emu10k1_fx8010_control_gpr __user * gpr_list_controls;
-  DECLARE_BITMAP(tram_valid, 0x100);
 /* WARNING: DO NOT EDIT, AUTO-GENERATED CODE - SEE TOP FOR INSTRUCTIONS */
+  struct snd_emu10k1_fx8010_control_gpr __user * gpr_list_controls;
+  __EMU10K1_DECLARE_BITMAP(tram_valid, 0x100);
   __u32 __user * tram_data_map;
   __u32 __user * tram_addr_map;
-  DECLARE_BITMAP(code_valid, 1024);
-  __u32 __user * code;
 /* WARNING: DO NOT EDIT, AUTO-GENERATED CODE - SEE TOP FOR INSTRUCTIONS */
+  __EMU10K1_DECLARE_BITMAP(code_valid, 1024);
+  __u32 __user * code;
 };
 struct snd_emu10k1_fx8010_tram {
+/* WARNING: DO NOT EDIT, AUTO-GENERATED CODE - SEE TOP FOR INSTRUCTIONS */
   unsigned int address;
   unsigned int size;
-/* WARNING: DO NOT EDIT, AUTO-GENERATED CODE - SEE TOP FOR INSTRUCTIONS */
   unsigned int * samples;
 };
+/* WARNING: DO NOT EDIT, AUTO-GENERATED CODE - SEE TOP FOR INSTRUCTIONS */
 struct snd_emu10k1_fx8010_pcm_rec {
   unsigned int substream;
-/* WARNING: DO NOT EDIT, AUTO-GENERATED CODE - SEE TOP FOR INSTRUCTIONS */
   unsigned int res1;
   unsigned int channels;
+/* WARNING: DO NOT EDIT, AUTO-GENERATED CODE - SEE TOP FOR INSTRUCTIONS */
   unsigned int tram_start;
   unsigned int buffer_size;
-/* WARNING: DO NOT EDIT, AUTO-GENERATED CODE - SEE TOP FOR INSTRUCTIONS */
   unsigned short gpr_size;
   unsigned short gpr_ptr;
+/* WARNING: DO NOT EDIT, AUTO-GENERATED CODE - SEE TOP FOR INSTRUCTIONS */
   unsigned short gpr_count;
   unsigned short gpr_tmpcount;
-/* WARNING: DO NOT EDIT, AUTO-GENERATED CODE - SEE TOP FOR INSTRUCTIONS */
   unsigned short gpr_trigger;
   unsigned short gpr_running;
+/* WARNING: DO NOT EDIT, AUTO-GENERATED CODE - SEE TOP FOR INSTRUCTIONS */
   unsigned char pad;
   unsigned char etram[32];
-/* WARNING: DO NOT EDIT, AUTO-GENERATED CODE - SEE TOP FOR INSTRUCTIONS */
   unsigned int res2;
 };
+/* WARNING: DO NOT EDIT, AUTO-GENERATED CODE - SEE TOP FOR INSTRUCTIONS */
 #define SNDRV_EMU10K1_VERSION SNDRV_PROTOCOL_VERSION(1, 0, 1)
 #define SNDRV_EMU10K1_IOCTL_INFO _IOR('H', 0x10, struct snd_emu10k1_fx8010_info)
-/* WARNING: DO NOT EDIT, AUTO-GENERATED CODE - SEE TOP FOR INSTRUCTIONS */
 #define SNDRV_EMU10K1_IOCTL_CODE_POKE _IOW('H', 0x11, struct snd_emu10k1_fx8010_code)
 #define SNDRV_EMU10K1_IOCTL_CODE_PEEK _IOWR('H', 0x12, struct snd_emu10k1_fx8010_code)
+/* WARNING: DO NOT EDIT, AUTO-GENERATED CODE - SEE TOP FOR INSTRUCTIONS */
 #define SNDRV_EMU10K1_IOCTL_TRAM_SETUP _IOW('H', 0x20, int)
 #define SNDRV_EMU10K1_IOCTL_TRAM_POKE _IOW('H', 0x21, struct snd_emu10k1_fx8010_tram)
-/* WARNING: DO NOT EDIT, AUTO-GENERATED CODE - SEE TOP FOR INSTRUCTIONS */
 #define SNDRV_EMU10K1_IOCTL_TRAM_PEEK _IOWR('H', 0x22, struct snd_emu10k1_fx8010_tram)
 #define SNDRV_EMU10K1_IOCTL_PCM_POKE _IOW('H', 0x30, struct snd_emu10k1_fx8010_pcm_rec)
+/* WARNING: DO NOT EDIT, AUTO-GENERATED CODE - SEE TOP FOR INSTRUCTIONS */
 #define SNDRV_EMU10K1_IOCTL_PCM_PEEK _IOWR('H', 0x31, struct snd_emu10k1_fx8010_pcm_rec)
 #define SNDRV_EMU10K1_IOCTL_PVERSION _IOR('H', 0x40, int)
-/* WARNING: DO NOT EDIT, AUTO-GENERATED CODE - SEE TOP FOR INSTRUCTIONS */
 #define SNDRV_EMU10K1_IOCTL_STOP _IO('H', 0x80)
 #define SNDRV_EMU10K1_IOCTL_CONTINUE _IO('H', 0x81)
+/* WARNING: DO NOT EDIT, AUTO-GENERATED CODE - SEE TOP FOR INSTRUCTIONS */
 #define SNDRV_EMU10K1_IOCTL_ZERO_TRAM_COUNTER _IO('H', 0x82)
 #define SNDRV_EMU10K1_IOCTL_SINGLE_STEP _IOW('H', 0x83, int)
-/* WARNING: DO NOT EDIT, AUTO-GENERATED CODE - SEE TOP FOR INSTRUCTIONS */
 #define SNDRV_EMU10K1_IOCTL_DBG_READ _IOR('H', 0x84, int)
 typedef struct snd_emu10k1_fx8010_info emu10k1_fx8010_info_t;
+/* WARNING: DO NOT EDIT, AUTO-GENERATED CODE - SEE TOP FOR INSTRUCTIONS */
 typedef struct snd_emu10k1_fx8010_control_gpr emu10k1_fx8010_control_gpr_t;
 typedef struct snd_emu10k1_fx8010_code emu10k1_fx8010_code_t;
-/* WARNING: DO NOT EDIT, AUTO-GENERATED CODE - SEE TOP FOR INSTRUCTIONS */
 typedef struct snd_emu10k1_fx8010_tram emu10k1_fx8010_tram_t;
 typedef struct snd_emu10k1_fx8010_pcm_rec emu10k1_fx8010_pcm_t;
+/* WARNING: DO NOT EDIT, AUTO-GENERATED CODE - SEE TOP FOR INSTRUCTIONS */
 #endif
diff --git a/libc/kernel/uapi/sound/firewire.h b/libc/kernel/uapi/sound/firewire.h
index 7965fc4..f489408 100644
--- a/libc/kernel/uapi/sound/firewire.h
+++ b/libc/kernel/uapi/sound/firewire.h
@@ -24,58 +24,70 @@
 #define SNDRV_FIREWIRE_EVENT_LOCK_STATUS 0x000010cc
 #define SNDRV_FIREWIRE_EVENT_DICE_NOTIFICATION 0xd1ce004e
 #define SNDRV_FIREWIRE_EVENT_EFW_RESPONSE 0x4e617475
-struct snd_firewire_event_common {
+#define SNDRV_FIREWIRE_EVENT_DIGI00X_MESSAGE 0x746e736c
 /* WARNING: DO NOT EDIT, AUTO-GENERATED CODE - SEE TOP FOR INSTRUCTIONS */
+struct snd_firewire_event_common {
   unsigned int type;
 };
 struct snd_firewire_event_lock_status {
-  unsigned int type;
 /* WARNING: DO NOT EDIT, AUTO-GENERATED CODE - SEE TOP FOR INSTRUCTIONS */
+  unsigned int type;
   unsigned int status;
 };
 struct snd_firewire_event_dice_notification {
-  unsigned int type;
 /* WARNING: DO NOT EDIT, AUTO-GENERATED CODE - SEE TOP FOR INSTRUCTIONS */
+  unsigned int type;
   unsigned int notification;
 };
 #define SND_EFW_TRANSACTION_USER_SEQNUM_MAX ((__u32) ((__u16) ~0) - 1)
-struct snd_efw_transaction {
 /* WARNING: DO NOT EDIT, AUTO-GENERATED CODE - SEE TOP FOR INSTRUCTIONS */
+struct snd_efw_transaction {
   __be32 length;
   __be32 version;
   __be32 seqnum;
-  __be32 category;
 /* WARNING: DO NOT EDIT, AUTO-GENERATED CODE - SEE TOP FOR INSTRUCTIONS */
+  __be32 category;
   __be32 command;
   __be32 status;
   __be32 params[0];
-};
 /* WARNING: DO NOT EDIT, AUTO-GENERATED CODE - SEE TOP FOR INSTRUCTIONS */
+};
 struct snd_firewire_event_efw_response {
   unsigned int type;
   __be32 response[0];
-};
 /* WARNING: DO NOT EDIT, AUTO-GENERATED CODE - SEE TOP FOR INSTRUCTIONS */
+};
+struct snd_firewire_event_digi00x_message {
+  unsigned int type;
+  __u32 message;
+/* WARNING: DO NOT EDIT, AUTO-GENERATED CODE - SEE TOP FOR INSTRUCTIONS */
+};
 union snd_firewire_event {
   struct snd_firewire_event_common common;
   struct snd_firewire_event_lock_status lock_status;
-  struct snd_firewire_event_dice_notification dice_notification;
 /* WARNING: DO NOT EDIT, AUTO-GENERATED CODE - SEE TOP FOR INSTRUCTIONS */
+  struct snd_firewire_event_dice_notification dice_notification;
   struct snd_firewire_event_efw_response efw_response;
+  struct snd_firewire_event_digi00x_message digi00x_message;
 };
+/* WARNING: DO NOT EDIT, AUTO-GENERATED CODE - SEE TOP FOR INSTRUCTIONS */
 #define SNDRV_FIREWIRE_IOCTL_GET_INFO _IOR('H', 0xf8, struct snd_firewire_get_info)
 #define SNDRV_FIREWIRE_IOCTL_LOCK _IO('H', 0xf9)
-/* WARNING: DO NOT EDIT, AUTO-GENERATED CODE - SEE TOP FOR INSTRUCTIONS */
 #define SNDRV_FIREWIRE_IOCTL_UNLOCK _IO('H', 0xfa)
 #define SNDRV_FIREWIRE_TYPE_DICE 1
+/* WARNING: DO NOT EDIT, AUTO-GENERATED CODE - SEE TOP FOR INSTRUCTIONS */
 #define SNDRV_FIREWIRE_TYPE_FIREWORKS 2
 #define SNDRV_FIREWIRE_TYPE_BEBOB 3
+#define SNDRV_FIREWIRE_TYPE_OXFW 4
+#define SNDRV_FIREWIRE_TYPE_DIGI00X 5
 /* WARNING: DO NOT EDIT, AUTO-GENERATED CODE - SEE TOP FOR INSTRUCTIONS */
+#define SNDRV_FIREWIRE_TYPE_TASCAM 6
 struct snd_firewire_get_info {
   unsigned int type;
   unsigned int card;
-  unsigned char guid[8];
 /* WARNING: DO NOT EDIT, AUTO-GENERATED CODE - SEE TOP FOR INSTRUCTIONS */
+  unsigned char guid[8];
   char device_name[16];
 };
 #endif
+/* WARNING: DO NOT EDIT, AUTO-GENERATED CODE - SEE TOP FOR INSTRUCTIONS */
diff --git a/libc/kernel/uapi/sound/hdspm.h b/libc/kernel/uapi/sound/hdspm.h
index 16d03ba..586507b 100644
--- a/libc/kernel/uapi/sound/hdspm.h
+++ b/libc/kernel/uapi/sound/hdspm.h
@@ -18,167 +18,168 @@
  ****************************************************************************/
 #ifndef __SOUND_HDSPM_H
 #define __SOUND_HDSPM_H
+#include <linux/types.h>
 #define HDSPM_MAX_CHANNELS 64
-enum hdspm_io_type {
 /* WARNING: DO NOT EDIT, AUTO-GENERATED CODE - SEE TOP FOR INSTRUCTIONS */
+enum hdspm_io_type {
   MADI,
   MADIface,
   AIO,
-  AES32,
 /* WARNING: DO NOT EDIT, AUTO-GENERATED CODE - SEE TOP FOR INSTRUCTIONS */
+  AES32,
   RayDAT
 };
 enum hdspm_speed {
-  ss,
 /* WARNING: DO NOT EDIT, AUTO-GENERATED CODE - SEE TOP FOR INSTRUCTIONS */
+  ss,
   ds,
   qs
 };
+/* WARNING: DO NOT EDIT, AUTO-GENERATED CODE - SEE TOP FOR INSTRUCTIONS */
 struct hdspm_peak_rms {
+  __u32 input_peaks[64];
+  __u32 playback_peaks[64];
+  __u32 output_peaks[64];
 /* WARNING: DO NOT EDIT, AUTO-GENERATED CODE - SEE TOP FOR INSTRUCTIONS */
-  uint32_t input_peaks[64];
-  uint32_t playback_peaks[64];
-  uint32_t output_peaks[64];
-  uint64_t input_rms[64];
+  __u64 input_rms[64];
+  __u64 playback_rms[64];
+  __u64 output_rms[64];
+  __u8 speed;
 /* WARNING: DO NOT EDIT, AUTO-GENERATED CODE - SEE TOP FOR INSTRUCTIONS */
-  uint64_t playback_rms[64];
-  uint64_t output_rms[64];
-  uint8_t speed;
   int status2;
-/* WARNING: DO NOT EDIT, AUTO-GENERATED CODE - SEE TOP FOR INSTRUCTIONS */
 };
 #define SNDRV_HDSPM_IOCTL_GET_PEAK_RMS _IOR('H', 0x42, struct hdspm_peak_rms)
 struct hdspm_config {
-  unsigned char pref_sync_ref;
 /* WARNING: DO NOT EDIT, AUTO-GENERATED CODE - SEE TOP FOR INSTRUCTIONS */
+  unsigned char pref_sync_ref;
   unsigned char wordclock_sync_check;
   unsigned char madi_sync_check;
   unsigned int system_sample_rate;
-  unsigned int autosync_sample_rate;
 /* WARNING: DO NOT EDIT, AUTO-GENERATED CODE - SEE TOP FOR INSTRUCTIONS */
+  unsigned int autosync_sample_rate;
   unsigned char system_clock_mode;
   unsigned char clock_source;
   unsigned char autosync_ref;
-  unsigned char line_out;
 /* WARNING: DO NOT EDIT, AUTO-GENERATED CODE - SEE TOP FOR INSTRUCTIONS */
+  unsigned char line_out;
   unsigned int passthru;
   unsigned int analog_out;
 };
-#define SNDRV_HDSPM_IOCTL_GET_CONFIG _IOR('H', 0x41, struct hdspm_config)
 /* WARNING: DO NOT EDIT, AUTO-GENERATED CODE - SEE TOP FOR INSTRUCTIONS */
+#define SNDRV_HDSPM_IOCTL_GET_CONFIG _IOR('H', 0x41, struct hdspm_config)
 enum hdspm_ltc_format {
   format_invalid,
   fps_24,
-  fps_25,
 /* WARNING: DO NOT EDIT, AUTO-GENERATED CODE - SEE TOP FOR INSTRUCTIONS */
+  fps_25,
   fps_2997,
   fps_30
 };
-enum hdspm_ltc_frame {
 /* WARNING: DO NOT EDIT, AUTO-GENERATED CODE - SEE TOP FOR INSTRUCTIONS */
+enum hdspm_ltc_frame {
   frame_invalid,
   drop_frame,
   full_frame
-};
 /* WARNING: DO NOT EDIT, AUTO-GENERATED CODE - SEE TOP FOR INSTRUCTIONS */
+};
 enum hdspm_ltc_input_format {
   ntsc,
   pal,
-  no_video
 /* WARNING: DO NOT EDIT, AUTO-GENERATED CODE - SEE TOP FOR INSTRUCTIONS */
+  no_video
 };
 struct hdspm_ltc {
   unsigned int ltc;
-  enum hdspm_ltc_format format;
 /* WARNING: DO NOT EDIT, AUTO-GENERATED CODE - SEE TOP FOR INSTRUCTIONS */
+  enum hdspm_ltc_format format;
   enum hdspm_ltc_frame frame;
   enum hdspm_ltc_input_format input_format;
 };
-#define SNDRV_HDSPM_IOCTL_GET_LTC _IOR('H', 0x46, struct hdspm_ltc)
 /* WARNING: DO NOT EDIT, AUTO-GENERATED CODE - SEE TOP FOR INSTRUCTIONS */
+#define SNDRV_HDSPM_IOCTL_GET_LTC _IOR('H', 0x46, struct hdspm_ltc)
 enum hdspm_sync {
   hdspm_sync_no_lock = 0,
   hdspm_sync_lock = 1,
-  hdspm_sync_sync = 2
 /* WARNING: DO NOT EDIT, AUTO-GENERATED CODE - SEE TOP FOR INSTRUCTIONS */
+  hdspm_sync_sync = 2
 };
 enum hdspm_madi_input {
   hdspm_input_optical = 0,
-  hdspm_input_coax = 1
 /* WARNING: DO NOT EDIT, AUTO-GENERATED CODE - SEE TOP FOR INSTRUCTIONS */
+  hdspm_input_coax = 1
 };
 enum hdspm_madi_channel_format {
   hdspm_format_ch_64 = 0,
-  hdspm_format_ch_56 = 1
 /* WARNING: DO NOT EDIT, AUTO-GENERATED CODE - SEE TOP FOR INSTRUCTIONS */
+  hdspm_format_ch_56 = 1
 };
 enum hdspm_madi_frame_format {
   hdspm_frame_48 = 0,
-  hdspm_frame_96 = 1
 /* WARNING: DO NOT EDIT, AUTO-GENERATED CODE - SEE TOP FOR INSTRUCTIONS */
+  hdspm_frame_96 = 1
 };
 enum hdspm_syncsource {
   syncsource_wc = 0,
-  syncsource_madi = 1,
 /* WARNING: DO NOT EDIT, AUTO-GENERATED CODE - SEE TOP FOR INSTRUCTIONS */
+  syncsource_madi = 1,
   syncsource_tco = 2,
   syncsource_sync = 3,
   syncsource_none = 4
+/* WARNING: DO NOT EDIT, AUTO-GENERATED CODE - SEE TOP FOR INSTRUCTIONS */
 };
-/* WARNING: DO NOT EDIT, AUTO-GENERATED CODE - SEE TOP FOR INSTRUCTIONS */
 struct hdspm_status {
-  uint8_t card_type;
+  __u8 card_type;
   enum hdspm_syncsource autosync_source;
-  uint64_t card_clock;
 /* WARNING: DO NOT EDIT, AUTO-GENERATED CODE - SEE TOP FOR INSTRUCTIONS */
-  uint32_t master_period;
+  __u64 card_clock;
+  __u32 master_period;
   union {
     struct {
-      uint8_t sync_wc;
 /* WARNING: DO NOT EDIT, AUTO-GENERATED CODE - SEE TOP FOR INSTRUCTIONS */
-      uint8_t sync_madi;
-      uint8_t sync_tco;
-      uint8_t sync_in;
-      uint8_t madi_input;
+      __u8 sync_wc;
+      __u8 sync_madi;
+      __u8 sync_tco;
+      __u8 sync_in;
 /* WARNING: DO NOT EDIT, AUTO-GENERATED CODE - SEE TOP FOR INSTRUCTIONS */
-      uint8_t channel_format;
-      uint8_t frame_format;
+      __u8 madi_input;
+      __u8 channel_format;
+      __u8 frame_format;
     } madi;
-  } card_specific;
 /* WARNING: DO NOT EDIT, AUTO-GENERATED CODE - SEE TOP FOR INSTRUCTIONS */
+  } card_specific;
 };
 #define SNDRV_HDSPM_IOCTL_GET_STATUS _IOR('H', 0x47, struct hdspm_status)
 #define HDSPM_ADDON_TCO 1
-struct hdspm_version {
 /* WARNING: DO NOT EDIT, AUTO-GENERATED CODE - SEE TOP FOR INSTRUCTIONS */
-  uint8_t card_type;
+struct hdspm_version {
+  __u8 card_type;
   char cardname[20];
   unsigned int serial;
-  unsigned short firmware_rev;
 /* WARNING: DO NOT EDIT, AUTO-GENERATED CODE - SEE TOP FOR INSTRUCTIONS */
+  unsigned short firmware_rev;
   int addons;
 };
 #define SNDRV_HDSPM_IOCTL_GET_VERSION _IOR('H', 0x48, struct hdspm_version)
-#define HDSPM_MIXER_CHANNELS HDSPM_MAX_CHANNELS
 /* WARNING: DO NOT EDIT, AUTO-GENERATED CODE - SEE TOP FOR INSTRUCTIONS */
+#define HDSPM_MIXER_CHANNELS HDSPM_MAX_CHANNELS
 struct hdspm_channelfader {
   unsigned int in[HDSPM_MIXER_CHANNELS];
   unsigned int pb[HDSPM_MIXER_CHANNELS];
-};
 /* WARNING: DO NOT EDIT, AUTO-GENERATED CODE - SEE TOP FOR INSTRUCTIONS */
+};
 struct hdspm_mixer {
   struct hdspm_channelfader ch[HDSPM_MIXER_CHANNELS];
 };
-struct hdspm_mixer_ioctl {
 /* WARNING: DO NOT EDIT, AUTO-GENERATED CODE - SEE TOP FOR INSTRUCTIONS */
+struct hdspm_mixer_ioctl {
   struct hdspm_mixer * mixer;
 };
 #define SNDRV_HDSPM_IOCTL_GET_MIXER _IOR('H', 0x44, struct hdspm_mixer_ioctl)
-typedef struct hdspm_peak_rms hdspm_peak_rms_t;
 /* WARNING: DO NOT EDIT, AUTO-GENERATED CODE - SEE TOP FOR INSTRUCTIONS */
+typedef struct hdspm_peak_rms hdspm_peak_rms_t;
 typedef struct hdspm_config_info hdspm_config_info_t;
 typedef struct hdspm_version hdspm_version_t;
 typedef struct hdspm_channelfader snd_hdspm_channelfader_t;
-typedef struct hdspm_mixer hdspm_mixer_t;
 /* WARNING: DO NOT EDIT, AUTO-GENERATED CODE - SEE TOP FOR INSTRUCTIONS */
+typedef struct hdspm_mixer hdspm_mixer_t;
 #endif
diff --git a/libc/kernel/uapi/sound/tlv.h b/libc/kernel/uapi/sound/tlv.h
new file mode 100644
index 0000000..09f6ae4
--- /dev/null
+++ b/libc/kernel/uapi/sound/tlv.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 __UAPI_SOUND_TLV_H
+#define __UAPI_SOUND_TLV_H
+#define SNDRV_CTL_TLVT_CONTAINER 0
+#define SNDRV_CTL_TLVT_DB_SCALE 1
+/* WARNING: DO NOT EDIT, AUTO-GENERATED CODE - SEE TOP FOR INSTRUCTIONS */
+#define SNDRV_CTL_TLVT_DB_LINEAR 2
+#define SNDRV_CTL_TLVT_DB_RANGE 3
+#define SNDRV_CTL_TLVT_DB_MINMAX 4
+#define SNDRV_CTL_TLVT_DB_MINMAX_MUTE 5
+/* WARNING: DO NOT EDIT, AUTO-GENERATED CODE - SEE TOP FOR INSTRUCTIONS */
+#define SNDRV_CTL_TLVT_CHMAP_FIXED 0x101
+#define SNDRV_CTL_TLVT_CHMAP_VAR 0x102
+#define SNDRV_CTL_TLVT_CHMAP_PAIRED 0x103
+#endif
+/* WARNING: DO NOT EDIT, AUTO-GENERATED CODE - SEE TOP FOR INSTRUCTIONS */
diff --git a/libc/kernel/uapi/sound/usb_stream.h b/libc/kernel/uapi/sound/usb_stream.h
new file mode 100644
index 0000000..8393a26
--- /dev/null
+++ b/libc/kernel/uapi/sound/usb_stream.h
@@ -0,0 +1,74 @@
+/****************************************************************************
+ ****************************************************************************
+ ***
+ ***   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__SOUND_USB_STREAM_H
+#define _UAPI__SOUND_USB_STREAM_H
+#define USB_STREAM_INTERFACE_VERSION 2
+#define SNDRV_USB_STREAM_IOCTL_SET_PARAMS _IOW('H', 0x90, struct usb_stream_config)
+/* WARNING: DO NOT EDIT, AUTO-GENERATED CODE - SEE TOP FOR INSTRUCTIONS */
+struct usb_stream_packet {
+  unsigned offset;
+  unsigned length;
+};
+/* WARNING: DO NOT EDIT, AUTO-GENERATED CODE - SEE TOP FOR INSTRUCTIONS */
+struct usb_stream_config {
+  unsigned version;
+  unsigned sample_rate;
+  unsigned period_frames;
+/* WARNING: DO NOT EDIT, AUTO-GENERATED CODE - SEE TOP FOR INSTRUCTIONS */
+  unsigned frame_size;
+};
+struct usb_stream {
+  struct usb_stream_config cfg;
+/* WARNING: DO NOT EDIT, AUTO-GENERATED CODE - SEE TOP FOR INSTRUCTIONS */
+  unsigned read_size;
+  unsigned write_size;
+  int period_size;
+  unsigned state;
+/* WARNING: DO NOT EDIT, AUTO-GENERATED CODE - SEE TOP FOR INSTRUCTIONS */
+  int idle_insize;
+  int idle_outsize;
+  int sync_packet;
+  unsigned insize_done;
+/* WARNING: DO NOT EDIT, AUTO-GENERATED CODE - SEE TOP FOR INSTRUCTIONS */
+  unsigned periods_done;
+  unsigned periods_polled;
+  struct usb_stream_packet outpacket[2];
+  unsigned inpackets;
+/* WARNING: DO NOT EDIT, AUTO-GENERATED CODE - SEE TOP FOR INSTRUCTIONS */
+  unsigned inpacket_head;
+  unsigned inpacket_split;
+  unsigned inpacket_split_at;
+  unsigned next_inpacket_split;
+/* WARNING: DO NOT EDIT, AUTO-GENERATED CODE - SEE TOP FOR INSTRUCTIONS */
+  unsigned next_inpacket_split_at;
+  struct usb_stream_packet inpacket[0];
+};
+enum usb_stream_state {
+/* WARNING: DO NOT EDIT, AUTO-GENERATED CODE - SEE TOP FOR INSTRUCTIONS */
+  usb_stream_invalid,
+  usb_stream_stopped,
+  usb_stream_sync0,
+  usb_stream_sync1,
+/* WARNING: DO NOT EDIT, AUTO-GENERATED CODE - SEE TOP FOR INSTRUCTIONS */
+  usb_stream_ready,
+  usb_stream_running,
+  usb_stream_xrun,
+};
+/* WARNING: DO NOT EDIT, AUTO-GENERATED CODE - SEE TOP FOR INSTRUCTIONS */
+#endif
diff --git a/libc/kernel/uapi/xen/gntalloc.h b/libc/kernel/uapi/xen/gntalloc.h
index 1710f4a..ff54635 100644
--- a/libc/kernel/uapi/xen/gntalloc.h
+++ b/libc/kernel/uapi/xen/gntalloc.h
@@ -18,32 +18,33 @@
  ****************************************************************************/
 #ifndef __LINUX_PUBLIC_GNTALLOC_H__
 #define __LINUX_PUBLIC_GNTALLOC_H__
+#include <linux/types.h>
 #define IOCTL_GNTALLOC_ALLOC_GREF _IOC(_IOC_NONE, 'G', 5, sizeof(struct ioctl_gntalloc_alloc_gref))
+/* WARNING: DO NOT EDIT, AUTO-GENERATED CODE - SEE TOP FOR INSTRUCTIONS */
 struct ioctl_gntalloc_alloc_gref {
+  __u16 domid;
+  __u16 flags;
+  __u32 count;
 /* WARNING: DO NOT EDIT, AUTO-GENERATED CODE - SEE TOP FOR INSTRUCTIONS */
-  uint16_t domid;
-  uint16_t flags;
-  uint32_t count;
-  uint64_t index;
-/* WARNING: DO NOT EDIT, AUTO-GENERATED CODE - SEE TOP FOR INSTRUCTIONS */
-  uint32_t gref_ids[1];
+  __u64 index;
+  __u32 gref_ids[1];
 };
 #define GNTALLOC_FLAG_WRITABLE 1
+/* WARNING: DO NOT EDIT, AUTO-GENERATED CODE - SEE TOP FOR INSTRUCTIONS */
 #define IOCTL_GNTALLOC_DEALLOC_GREF _IOC(_IOC_NONE, 'G', 6, sizeof(struct ioctl_gntalloc_dealloc_gref))
-/* WARNING: DO NOT EDIT, AUTO-GENERATED CODE - SEE TOP FOR INSTRUCTIONS */
 struct ioctl_gntalloc_dealloc_gref {
-  uint64_t index;
-  uint32_t count;
-};
+  __u64 index;
+  __u32 count;
 /* WARNING: DO NOT EDIT, AUTO-GENERATED CODE - SEE TOP FOR INSTRUCTIONS */
+};
 #define IOCTL_GNTALLOC_SET_UNMAP_NOTIFY _IOC(_IOC_NONE, 'G', 7, sizeof(struct ioctl_gntalloc_unmap_notify))
 struct ioctl_gntalloc_unmap_notify {
-  uint64_t index;
-  uint32_t action;
+  __u64 index;
 /* WARNING: DO NOT EDIT, AUTO-GENERATED CODE - SEE TOP FOR INSTRUCTIONS */
-  uint32_t event_channel_port;
+  __u32 action;
+  __u32 event_channel_port;
 };
 #define UNMAP_NOTIFY_CLEAR_BYTE 0x1
-#define UNMAP_NOTIFY_SEND_EVENT 0x2
 /* WARNING: DO NOT EDIT, AUTO-GENERATED CODE - SEE TOP FOR INSTRUCTIONS */
+#define UNMAP_NOTIFY_SEND_EVENT 0x2
 #endif
diff --git a/libc/kernel/uapi/xen/gntdev.h b/libc/kernel/uapi/xen/gntdev.h
index c00e5ab..89e5eb0 100644
--- a/libc/kernel/uapi/xen/gntdev.h
+++ b/libc/kernel/uapi/xen/gntdev.h
@@ -18,49 +18,51 @@
  ****************************************************************************/
 #ifndef __LINUX_PUBLIC_GNTDEV_H__
 #define __LINUX_PUBLIC_GNTDEV_H__
+#include <linux/types.h>
 struct ioctl_gntdev_grant_ref {
-  uint32_t domid;
 /* WARNING: DO NOT EDIT, AUTO-GENERATED CODE - SEE TOP FOR INSTRUCTIONS */
-  uint32_t ref;
+  __u32 domid;
+  __u32 ref;
 };
 #define IOCTL_GNTDEV_MAP_GRANT_REF _IOC(_IOC_NONE, 'G', 0, sizeof(struct ioctl_gntdev_map_grant_ref))
+/* WARNING: DO NOT EDIT, AUTO-GENERATED CODE - SEE TOP FOR INSTRUCTIONS */
 struct ioctl_gntdev_map_grant_ref {
+  __u32 count;
+  __u32 pad;
+  __u64 index;
 /* WARNING: DO NOT EDIT, AUTO-GENERATED CODE - SEE TOP FOR INSTRUCTIONS */
-  uint32_t count;
-  uint32_t pad;
-  uint64_t index;
   struct ioctl_gntdev_grant_ref refs[1];
-/* WARNING: DO NOT EDIT, AUTO-GENERATED CODE - SEE TOP FOR INSTRUCTIONS */
 };
 #define IOCTL_GNTDEV_UNMAP_GRANT_REF _IOC(_IOC_NONE, 'G', 1, sizeof(struct ioctl_gntdev_unmap_grant_ref))
 struct ioctl_gntdev_unmap_grant_ref {
-  uint64_t index;
 /* WARNING: DO NOT EDIT, AUTO-GENERATED CODE - SEE TOP FOR INSTRUCTIONS */
-  uint32_t count;
-  uint32_t pad;
+  __u64 index;
+  __u32 count;
+  __u32 pad;
 };
+/* WARNING: DO NOT EDIT, AUTO-GENERATED CODE - SEE TOP FOR INSTRUCTIONS */
 #define IOCTL_GNTDEV_GET_OFFSET_FOR_VADDR _IOC(_IOC_NONE, 'G', 2, sizeof(struct ioctl_gntdev_get_offset_for_vaddr))
-/* WARNING: DO NOT EDIT, AUTO-GENERATED CODE - SEE TOP FOR INSTRUCTIONS */
 struct ioctl_gntdev_get_offset_for_vaddr {
-  uint64_t vaddr;
-  uint64_t offset;
-  uint32_t count;
+  __u64 vaddr;
+  __u64 offset;
 /* WARNING: DO NOT EDIT, AUTO-GENERATED CODE - SEE TOP FOR INSTRUCTIONS */
-  uint32_t pad;
+  __u32 count;
+  __u32 pad;
 };
 #define IOCTL_GNTDEV_SET_MAX_GRANTS _IOC(_IOC_NONE, 'G', 3, sizeof(struct ioctl_gntdev_set_max_grants))
-struct ioctl_gntdev_set_max_grants {
 /* WARNING: DO NOT EDIT, AUTO-GENERATED CODE - SEE TOP FOR INSTRUCTIONS */
-  uint32_t count;
+struct ioctl_gntdev_set_max_grants {
+  __u32 count;
 };
 #define IOCTL_GNTDEV_SET_UNMAP_NOTIFY _IOC(_IOC_NONE, 'G', 7, sizeof(struct ioctl_gntdev_unmap_notify))
+/* WARNING: DO NOT EDIT, AUTO-GENERATED CODE - SEE TOP FOR INSTRUCTIONS */
 struct ioctl_gntdev_unmap_notify {
+  __u64 index;
+  __u32 action;
+  __u32 event_channel_port;
 /* WARNING: DO NOT EDIT, AUTO-GENERATED CODE - SEE TOP FOR INSTRUCTIONS */
-  uint64_t index;
-  uint32_t action;
-  uint32_t event_channel_port;
 };
-/* WARNING: DO NOT EDIT, AUTO-GENERATED CODE - SEE TOP FOR INSTRUCTIONS */
 #define UNMAP_NOTIFY_CLEAR_BYTE 0x1
 #define UNMAP_NOTIFY_SEND_EVENT 0x2
 #endif
+/* WARNING: DO NOT EDIT, AUTO-GENERATED CODE - SEE TOP FOR INSTRUCTIONS */
diff --git a/libc/libc.map b/libc/libc.arm.brillo.map
similarity index 90%
rename from libc/libc.map
rename to libc/libc.arm.brillo.map
index 47c52a4..4e5b5c8 100644
--- a/libc/libc.map
+++ b/libc/libc.arm.brillo.map
@@ -1,3 +1,4 @@
+# Generated by genversionscripts.py. Do not edit.
 LIBC {
   global:
     __assert;
@@ -9,44 +10,25 @@
     __b64_ntop;
     __b64_pton;
     __brk; # arm x86 mips
-    __cmpdf2; # arm
     __cmsg_nxthdr;
     __connect; # arm x86 mips
     __ctype_get_mb_cur_max;
     __cxa_atexit;
     __cxa_finalize;
     __cxa_thread_atexit_impl;
-    __divdf3; # arm
-    __divdi3; # arm x86 mips
-    __divsf3; # arm
-    __divsi3; # arm
     __dn_comp;
     __dn_count_labels;
     __dn_skipname;
     __epoll_pwait; # arm x86 mips
-    __eqdf2; # arm
     __errno;
     __exit; # arm x86 mips
-    __extendsfdf2; # arm
-    __fadvise64; # x86 mips
     __fbufsize;
     __fcntl64; # arm x86 mips
     __FD_CLR_chk;
     __FD_ISSET_chk;
     __FD_SET_chk;
     __fgets_chk;
-    __fixdfsi; # arm
-    __fixsfsi; # arm
-    __fixunssfsi; # arm
     __flbf;
-    __floatdidf; # arm
-    __floatdisf; # arm
-    __floatsidf; # arm
-    __floatsisf; # arm
-    __floatundidf; # arm
-    __floatundisf; # arm
-    __floatunsidf; # arm
-    __floatunsisf; # arm
     __fp_nquery;
     __fp_query;
     __fpclassify;
@@ -58,23 +40,14 @@
     __freadable;
     __fsetlocking;
     __fstatfs64; # arm x86 mips
-    __futex_wait; # arm x86 mips
-    __futex_wake; # arm x86 mips
     __fwritable;
-    __gedf2; # arm
     __get_h_errno;
-    __get_thread; # arm x86 mips
-    __get_tls; # arm x86 mips
     __getcpu; # arm x86 mips
     __getcwd; # arm x86 mips
-    __getdents64; # arm x86 mips
     __getpid; # arm x86 mips
     __getpriority; # arm x86 mips
     __gnu_basename;
-    __gnu_ldivmod_helper; # arm
     __gnu_strerror_r;
-    __gnu_uldivmod_helper; # arm
-    __gtdf2; # arm
     __hostalias;
     __ioctl; # arm x86 mips
     __isfinite;
@@ -89,27 +62,19 @@
     __isnormal;
     __isnormalf;
     __isnormall;
-    __isthreaded;
-    __ledf2; # arm
+    __isthreaded; # arm x86 mips
     __libc_current_sigrtmax;
     __libc_current_sigrtmin;
     __libc_init;
     __llseek; # arm x86 mips
     __loc_aton;
     __loc_ntoa;
-    __lshrdi3; # arm
-    __ltdf2; # arm
     __memchr_chk;
     __memcpy_chk;
     __memmove_chk;
     __memrchr_chk;
     __memset_chk;
     __mmap2; # arm x86 mips
-    __moddi3; # x86 mips
-    __muldf3; # arm
-    __muldi3; # arm
-    __mulsf3; # arm
-    __nedf2; # arm
     __ns_format_ttl; # arm x86 mips
     __ns_get16; # arm x86 mips
     __ns_get32; # arm x86 mips
@@ -132,7 +97,6 @@
     __ns_skiprr; # arm x86 mips
     __ns_sprintrr; # arm x86 mips
     __ns_sprintrrf; # arm x86 mips
-    __open; # arm x86 mips
     __open_2;
     __openat; # arm x86 mips
     __openat_2;
@@ -149,11 +113,7 @@
     __p_time;
     __p_type;
     __p_type_syms;
-    __page_shift; # arm x86 mips
-    __page_size; # arm x86 mips
     __poll_chk;
-    __popcount_tab; # arm
-    __popcountsi2; # arm x86 mips
     __ppoll; # arm x86 mips
     __ppoll_chk;
     __pread64_chk;
@@ -162,7 +122,6 @@
     __pselect6; # arm x86 mips
     __pthread_cleanup_pop;
     __pthread_cleanup_push;
-    __pthread_gettid; # arm x86 mips
     __ptrace; # arm x86 mips
     __putlong;
     __putshort;
@@ -192,7 +151,6 @@
     __res_send;
     __res_send_setqhook;
     __res_send_setrhook;
-    __restore_core_regs; # arm
     __rt_sigaction; # arm x86 mips
     __rt_sigpending; # arm x86 mips
     __rt_sigprocmask; # arm x86 mips
@@ -202,28 +160,13 @@
     __sched_cpucount;
     __sched_cpufree;
     __sched_getaffinity; # arm x86 mips
-    __sclose; # arm x86 mips
-    __sdidinit; # arm x86 mips
-    __set_errno; # arm x86 mips
-    __set_thread_area; # x86
     __set_tid_address; # arm x86 mips
     __set_tls; # arm mips
     __sF;
-    __sflags; # arm x86 mips
-    __sflush; # arm x86 mips
-    __sfp; # arm x86 mips
-    __sglue; # arm x86 mips
     __sigaction; # arm x86 mips
-    __signalfd4; # arm x86 mips
-    __sinit; # arm x86 mips
-    __smakebuf; # arm x86 mips
     __snprintf_chk;
     __socket; # arm x86 mips
     __sprintf_chk;
-    __sread; # arm x86 mips
-    __srefill; # arm x86 mips
-    __srget; # arm x86 mips
-    __sseek; # arm x86 mips
     __stack_chk_fail;
     __stack_chk_guard;
     __statfs64; # arm x86 mips
@@ -240,11 +183,6 @@
     __strncpy_chk;
     __strncpy_chk2;
     __strrchr_chk;
-    __subdf3; # arm
-    __subsf3; # arm
-    __swbuf; # arm x86 mips
-    __swrite; # arm x86 mips
-    __swsetup; # arm x86 mips
     __sym_ntop;
     __sym_ntos;
     __sym_ston;
@@ -268,23 +206,14 @@
     __timer_getoverrun; # arm x86 mips
     __timer_gettime; # arm x86 mips
     __timer_settime; # arm x86 mips
-    __truncdfsf2; # arm
-    __udivdi3; # arm x86 mips
-    __udivsi3; # arm
     __umask_chk;
-    __umoddi3; # x86 mips
-    __unorddf2; # arm
-    __unordsf2; # arm
     __vsnprintf_chk;
     __vsprintf_chk;
-    __wait4; # arm x86 mips
     __waitid; # arm x86 mips
     _ctype_;
     _Exit;
     _exit;
-    _flush_cache; # mips
     _flushlbf;
-    _fwalk; # arm x86 mips
     _getlong;
     _getshort;
     _longjmp;
@@ -305,15 +234,9 @@
     alarm;
     alphasort;
     alphasort64;
-    android_getaddrinfofornet;
-    android_getaddrinfofornetcontext;
-    android_gethostbyaddrfornet;
-    android_gethostbynamefornet;
     android_set_abort_message;
     arc4random;
-    arc4random_addrandom; # arm x86 mips
     arc4random_buf;
-    arc4random_stir; # arm x86 mips
     arc4random_uniform;
     asctime;
     asctime64; # arm x86 mips
@@ -327,14 +250,11 @@
     atoll;
     basename;
     basename_r; # arm x86 mips
-    bcopy; # arm x86 mips
     bind;
     bindresvport;
     brk;
-    bsd_signal; # arm x86 mips
     bsearch;
     btowc;
-    bzero; # arm x86 mips
     c16rtomb;
     c32rtomb;
     cacheflush; # arm mips
@@ -387,9 +307,7 @@
     dup3;
     duplocale;
     endmntent;
-    endpwent;
     endservent;
-    endusershell;
     endutent;
     environ;
     epoll_create;
@@ -421,8 +339,6 @@
     execvpe;
     exit;
     faccessat;
-    fake_gmtime_r; # arm x86 mips
-    fake_localtime_r; # arm x86 mips
     fallocate;
     fallocate64;
     fchdir;
@@ -435,7 +351,6 @@
     fdatasync;
     fdopen;
     fdopendir;
-    fdprintf; # arm x86 mips
     feof;
     feof_unlocked;
     ferror;
@@ -467,7 +382,6 @@
     fputws;
     fread;
     free;
-    free_malloc_leak_info;
     freeaddrinfo;
     freelocale;
     fremovexattr;
@@ -488,7 +402,6 @@
     fsync;
     ftell;
     ftello;
-    ftime; # arm x86 mips
     ftok;
     ftruncate;
     ftruncate64;
@@ -509,7 +422,6 @@
     fwscanf;
     gai_strerror;
     get_avphys_pages;
-    get_malloc_leak_info;
     get_nprocs;
     get_nprocs_conf;
     get_phys_pages;
@@ -521,8 +433,6 @@
     getchar_unlocked;
     getcwd;
     getdelim;
-    getdents; # arm x86 mips
-    getdtablesize; # arm x86 mips
     getegid;
     getenv;
     geteuid;
@@ -580,7 +490,6 @@
     gettid;
     gettimeofday;
     getuid;
-    getusershell;
     getutent;
     getwc;
     getwchar;
@@ -598,7 +507,6 @@
     if_nametoindex;
     imaxabs;
     imaxdiv;
-    index; # arm x86 mips
     inet_addr;
     inet_aton;
     inet_lnaof;
@@ -651,7 +559,6 @@
     isprint_l;
     ispunct;
     ispunct_l;
-    issetugid; # arm x86 mips
     isspace;
     isspace_l;
     isupper;
@@ -741,7 +648,6 @@
     mempcpy;
     memrchr;
     memset;
-    memswap; # arm x86 mips
     mincore;
     mkdir;
     mkdirat;
@@ -761,7 +667,6 @@
     mktemp;
     mktime;
     mktime64; # arm x86 mips
-    mktime_tz;
     mlock;
     mlockall;
     mmap;
@@ -780,28 +685,6 @@
     nftw64;
     nice;
     nrand48;
-    ns_format_ttl; # arm64 x86_64 mips64
-    ns_get16; # arm64 x86_64 mips64
-    ns_get32; # arm64 x86_64 mips64
-    ns_initparse; # arm64 x86_64 mips64
-    ns_makecanon; # arm64 x86_64 mips64
-    ns_msg_getflag; # arm64 x86_64 mips64
-    ns_name_compress; # arm64 x86_64 mips64
-    ns_name_ntol; # arm64 x86_64 mips64
-    ns_name_ntop; # arm64 x86_64 mips64
-    ns_name_pack; # arm64 x86_64 mips64
-    ns_name_pton; # arm64 x86_64 mips64
-    ns_name_rollback; # arm64 x86_64 mips64
-    ns_name_skip; # arm64 x86_64 mips64
-    ns_name_uncompress; # arm64 x86_64 mips64
-    ns_name_unpack; # arm64 x86_64 mips64
-    ns_parserr; # arm64 x86_64 mips64
-    ns_put16; # arm64 x86_64 mips64
-    ns_put32; # arm64 x86_64 mips64
-    ns_samename; # arm64 x86_64 mips64
-    ns_skiprr; # arm64 x86_64 mips64
-    ns_sprintrr; # arm64 x86_64 mips64
-    ns_sprintrrf; # arm64 x86_64 mips64
     nsdispatch;
     ntohl;
     ntohs;
@@ -840,7 +723,6 @@
     pread;
     pread64;
     printf;
-    prlimit; # arm64 x86_64 mips64
     prlimit64;
     process_vm_readv;
     process_vm_writev;
@@ -855,7 +737,6 @@
     pthread_attr_getschedpolicy;
     pthread_attr_getscope;
     pthread_attr_getstack;
-    pthread_attr_getstackaddr; # arm x86 mips
     pthread_attr_getstacksize;
     pthread_attr_init;
     pthread_attr_setdetachstate;
@@ -864,7 +745,6 @@
     pthread_attr_setschedpolicy;
     pthread_attr_setscope;
     pthread_attr_setstack;
-    pthread_attr_setstackaddr; # arm x86 mips
     pthread_attr_setstacksize;
     pthread_cond_broadcast;
     pthread_cond_destroy;
@@ -980,7 +860,6 @@
     res_mkquery;
     res_query;
     res_search;
-    restore_core_regs; # arm
     rewind;
     rewinddir;
     rmdir;
@@ -1051,7 +930,6 @@
     setstate;
     settimeofday;
     setuid;
-    setusershell;
     setutent;
     setvbuf;
     setxattr;
@@ -1124,8 +1002,6 @@
     strncpy;
     strndup;
     strnlen;
-    strntoimax; # arm x86 mips
-    strntoumax; # arm x86 mips
     strpbrk;
     strptime;
     strrchr;
@@ -1144,7 +1020,6 @@
     strtoll;
     strtoll_l;
     strtoq;
-    strtotimeval; # arm x86 mips
     strtoul;
     strtoull;
     strtoull_l;
@@ -1166,7 +1041,6 @@
     sysinfo;
     syslog;
     system;
-    sysv_signal; # arm x86 mips
     tcdrain;
     tcflow;
     tcflush;
@@ -1198,7 +1072,6 @@
     timerfd_settime;
     times;
     timezone;
-    tkill; # arm x86 mips
     tmpfile;
     tmpnam;
     toascii;
@@ -1240,7 +1113,6 @@
     vdprintf;
     verr;
     verrx;
-    vfdprintf; # arm x86 mips
     vfork;
     vfprintf;
     vfscanf;
@@ -1260,7 +1132,6 @@
     vwprintf;
     vwscanf;
     wait;
-    wait3; # arm x86 mips
     wait4;
     waitid;
     waitpid;
@@ -1309,7 +1180,6 @@
     wcstoull;
     wcstoull_l;
     wcstoumax;
-    wcswcs; # arm x86 mips
     wcswidth;
     wcsxfrm;
     wcsxfrm_l;
@@ -1332,6 +1202,71 @@
     *;
 };
 
+LIBC_N {
+  global:
+    __aeabi_atexit; # arm
+    __aeabi_memclr; # arm
+    __aeabi_memclr4; # arm
+    __aeabi_memclr8; # arm
+    __aeabi_memcpy; # arm
+    __aeabi_memcpy4; # arm
+    __aeabi_memcpy8; # arm
+    __aeabi_memmove; # arm
+    __aeabi_memmove4; # arm
+    __aeabi_memmove8; # arm
+    __aeabi_memset; # arm
+    __aeabi_memset4; # arm
+    __aeabi_memset8; # arm
+    __fread_chk;
+    __fwrite_chk;
+    __getcwd_chk;
+    __gnu_Unwind_Find_exidx; # arm
+    __pwrite_chk;
+    __pwrite64_chk;
+    __write_chk;
+    adjtimex;
+    clock_adjtime;
+    fgetpos64;
+    fileno_unlocked;
+    fopen64;
+    freeifaddrs;
+    freopen64;
+    fseeko64;
+    fsetpos64;
+    ftello64;
+    funopen64;
+    getgrgid_r;
+    getgrnam_r;
+    getifaddrs;
+    if_freenameindex;
+    if_nameindex;
+    in6addr_any;
+    in6addr_loopback;
+    lockf;
+    lockf64;
+    preadv;
+    preadv64;
+    prlimit; # arm mips x86
+    pthread_barrierattr_destroy;
+    pthread_barrierattr_getpshared;
+    pthread_barrierattr_init;
+    pthread_barrierattr_setpshared;
+    pthread_barrier_destroy;
+    pthread_barrier_init;
+    pthread_barrier_wait;
+    pthread_spin_destroy;
+    pthread_spin_init;
+    pthread_spin_lock;
+    pthread_spin_trylock;
+    pthread_spin_unlock;
+    pwritev;
+    pwritev64;
+    scandirat;
+    scandirat64;
+    strchrnul;
+    tmpfile64;
+} LIBC;
+
 LIBC_PRIVATE {
   global:
     ___Unwind_Backtrace; # arm
@@ -1408,8 +1343,29 @@
     __ashrdi3; # arm
     __bionic_brk; # arm x86 mips
     __bionic_libgcc_compat_symbols; # arm x86
-    __bionic_libgcc_unwind_symbols; # arm
+    __cmpdf2; # arm
+    __divdf3; # arm
+    __divdi3; # arm x86 mips
+    __divsf3; # arm
+    __divsi3; # arm
     __dso_handle; # arm
+    __eqdf2; # arm
+    __extendsfdf2; # arm
+    __fixdfsi; # arm
+    __fixsfsi; # arm
+    __fixunssfsi; # arm
+    __floatdidf; # arm
+    __floatdisf; # arm
+    __floatsidf; # arm
+    __floatsisf; # arm
+    __floatundidf; # arm
+    __floatundisf; # arm
+    __floatunsidf; # arm
+    __floatunsisf; # arm
+    __gedf2; # arm
+    __getdents64; # arm x86 mips
+    __gnu_ldivmod_helper; # arm
+    __gnu_uldivmod_helper; # arm
     __gnu_Unwind_Backtrace; # arm
     __gnu_unwind_execute; # arm
     __gnu_Unwind_Find_exidx; # arm
@@ -1428,6 +1384,38 @@
     __gnu_Unwind_Save_VFP_D_16_to_31; # arm
     __gnu_Unwind_Save_WMMXC; # arm
     __gnu_Unwind_Save_WMMXD; # arm
+    __gtdf2; # arm
+    __ledf2; # arm
+    __lshrdi3; # arm
+    __ltdf2; # arm
+    __muldf3; # arm
+    __muldi3; # arm
+    __mulsf3; # arm
+    __nedf2; # arm
+    __popcount_tab; # arm
+    __popcountsi2; # arm x86 mips
+    __restore_core_regs; # arm
+    __sclose; # arm x86 mips
+    __sflags; # arm x86 mips
+    __sflush; # arm x86 mips
+    __sfp; # arm x86 mips
+    __sglue; # arm x86 mips
+    __smakebuf; # arm x86 mips
+    __sread; # arm x86 mips
+    __srefill; # arm x86 mips
+    __srget; # arm x86 mips
+    __sseek; # arm x86 mips
+    __subdf3; # arm
+    __subsf3; # arm
+    __swbuf; # arm x86 mips
+    __swrite; # arm x86 mips
+    __swsetup; # arm x86 mips
+    __truncdfsf2; # arm
+    __udivdi3; # arm x86 mips
+    __udivsi3; # arm
+    __unorddf2; # arm
+    __unordsf2; # arm
+    _fwalk; # arm x86 mips
     _Unwind_Backtrace; # arm
     _Unwind_Complete; # arm
     _Unwind_DeleteException; # arm
@@ -1443,14 +1431,28 @@
     _Unwind_VRS_Get; # arm
     _Unwind_VRS_Pop; # arm
     _Unwind_VRS_Set; # arm
+    android_getaddrinfofornet;
+    android_getaddrinfofornetcontext;
+    android_gethostbyaddrfornet;
+    android_gethostbynamefornet;
     atexit; # arm
-    dlmalloc; # arm x86 mips
-    dlmalloc_inspect_all;
-    dlmalloc_trim;
-    dlmalloc_usable_size; # arm x86 mips
+    free_malloc_leak_info;
+    get_malloc_leak_info;
     gMallocLeakZygoteChild;
+    restore_core_regs; # arm
     SHA1Final; # arm x86 mips
     SHA1Init; # arm x86 mips
     SHA1Transform; # arm x86 mips
     SHA1Update; # arm x86 mips
-} LIBC;
+} LIBC_N;
+
+LIBC_PLATFORM {
+  global:
+    android_net_res_stats_get_info_for_net;
+    android_net_res_stats_aggregate;
+    android_net_res_stats_get_usable_servers;
+    malloc_backtrace;
+    malloc_disable;
+    malloc_enable;
+    malloc_iterate;
+} LIBC_N;
diff --git a/libc/libc.map b/libc/libc.arm.map
similarity index 88%
copy from libc/libc.map
copy to libc/libc.arm.map
index 47c52a4..38f8437 100644
--- a/libc/libc.map
+++ b/libc/libc.arm.map
@@ -1,3 +1,4 @@
+# Generated by genversionscripts.py. Do not edit.
 LIBC {
   global:
     __assert;
@@ -9,44 +10,25 @@
     __b64_ntop;
     __b64_pton;
     __brk; # arm x86 mips
-    __cmpdf2; # arm
     __cmsg_nxthdr;
     __connect; # arm x86 mips
     __ctype_get_mb_cur_max;
     __cxa_atexit;
     __cxa_finalize;
     __cxa_thread_atexit_impl;
-    __divdf3; # arm
-    __divdi3; # arm x86 mips
-    __divsf3; # arm
-    __divsi3; # arm
     __dn_comp;
     __dn_count_labels;
     __dn_skipname;
     __epoll_pwait; # arm x86 mips
-    __eqdf2; # arm
     __errno;
     __exit; # arm x86 mips
-    __extendsfdf2; # arm
-    __fadvise64; # x86 mips
     __fbufsize;
     __fcntl64; # arm x86 mips
     __FD_CLR_chk;
     __FD_ISSET_chk;
     __FD_SET_chk;
     __fgets_chk;
-    __fixdfsi; # arm
-    __fixsfsi; # arm
-    __fixunssfsi; # arm
     __flbf;
-    __floatdidf; # arm
-    __floatdisf; # arm
-    __floatsidf; # arm
-    __floatsisf; # arm
-    __floatundidf; # arm
-    __floatundisf; # arm
-    __floatunsidf; # arm
-    __floatunsisf; # arm
     __fp_nquery;
     __fp_query;
     __fpclassify;
@@ -58,23 +40,14 @@
     __freadable;
     __fsetlocking;
     __fstatfs64; # arm x86 mips
-    __futex_wait; # arm x86 mips
-    __futex_wake; # arm x86 mips
     __fwritable;
-    __gedf2; # arm
     __get_h_errno;
-    __get_thread; # arm x86 mips
-    __get_tls; # arm x86 mips
     __getcpu; # arm x86 mips
     __getcwd; # arm x86 mips
-    __getdents64; # arm x86 mips
     __getpid; # arm x86 mips
     __getpriority; # arm x86 mips
     __gnu_basename;
-    __gnu_ldivmod_helper; # arm
     __gnu_strerror_r;
-    __gnu_uldivmod_helper; # arm
-    __gtdf2; # arm
     __hostalias;
     __ioctl; # arm x86 mips
     __isfinite;
@@ -89,27 +62,19 @@
     __isnormal;
     __isnormalf;
     __isnormall;
-    __isthreaded;
-    __ledf2; # arm
+    __isthreaded; # arm x86 mips
     __libc_current_sigrtmax;
     __libc_current_sigrtmin;
     __libc_init;
     __llseek; # arm x86 mips
     __loc_aton;
     __loc_ntoa;
-    __lshrdi3; # arm
-    __ltdf2; # arm
     __memchr_chk;
     __memcpy_chk;
     __memmove_chk;
     __memrchr_chk;
     __memset_chk;
     __mmap2; # arm x86 mips
-    __moddi3; # x86 mips
-    __muldf3; # arm
-    __muldi3; # arm
-    __mulsf3; # arm
-    __nedf2; # arm
     __ns_format_ttl; # arm x86 mips
     __ns_get16; # arm x86 mips
     __ns_get32; # arm x86 mips
@@ -132,7 +97,6 @@
     __ns_skiprr; # arm x86 mips
     __ns_sprintrr; # arm x86 mips
     __ns_sprintrrf; # arm x86 mips
-    __open; # arm x86 mips
     __open_2;
     __openat; # arm x86 mips
     __openat_2;
@@ -149,11 +113,7 @@
     __p_time;
     __p_type;
     __p_type_syms;
-    __page_shift; # arm x86 mips
-    __page_size; # arm x86 mips
     __poll_chk;
-    __popcount_tab; # arm
-    __popcountsi2; # arm x86 mips
     __ppoll; # arm x86 mips
     __ppoll_chk;
     __pread64_chk;
@@ -162,7 +122,6 @@
     __pselect6; # arm x86 mips
     __pthread_cleanup_pop;
     __pthread_cleanup_push;
-    __pthread_gettid; # arm x86 mips
     __ptrace; # arm x86 mips
     __putlong;
     __putshort;
@@ -192,7 +151,6 @@
     __res_send;
     __res_send_setqhook;
     __res_send_setrhook;
-    __restore_core_regs; # arm
     __rt_sigaction; # arm x86 mips
     __rt_sigpending; # arm x86 mips
     __rt_sigprocmask; # arm x86 mips
@@ -202,28 +160,13 @@
     __sched_cpucount;
     __sched_cpufree;
     __sched_getaffinity; # arm x86 mips
-    __sclose; # arm x86 mips
-    __sdidinit; # arm x86 mips
-    __set_errno; # arm x86 mips
-    __set_thread_area; # x86
     __set_tid_address; # arm x86 mips
     __set_tls; # arm mips
     __sF;
-    __sflags; # arm x86 mips
-    __sflush; # arm x86 mips
-    __sfp; # arm x86 mips
-    __sglue; # arm x86 mips
     __sigaction; # arm x86 mips
-    __signalfd4; # arm x86 mips
-    __sinit; # arm x86 mips
-    __smakebuf; # arm x86 mips
     __snprintf_chk;
     __socket; # arm x86 mips
     __sprintf_chk;
-    __sread; # arm x86 mips
-    __srefill; # arm x86 mips
-    __srget; # arm x86 mips
-    __sseek; # arm x86 mips
     __stack_chk_fail;
     __stack_chk_guard;
     __statfs64; # arm x86 mips
@@ -240,11 +183,6 @@
     __strncpy_chk;
     __strncpy_chk2;
     __strrchr_chk;
-    __subdf3; # arm
-    __subsf3; # arm
-    __swbuf; # arm x86 mips
-    __swrite; # arm x86 mips
-    __swsetup; # arm x86 mips
     __sym_ntop;
     __sym_ntos;
     __sym_ston;
@@ -268,23 +206,14 @@
     __timer_getoverrun; # arm x86 mips
     __timer_gettime; # arm x86 mips
     __timer_settime; # arm x86 mips
-    __truncdfsf2; # arm
-    __udivdi3; # arm x86 mips
-    __udivsi3; # arm
     __umask_chk;
-    __umoddi3; # x86 mips
-    __unorddf2; # arm
-    __unordsf2; # arm
     __vsnprintf_chk;
     __vsprintf_chk;
-    __wait4; # arm x86 mips
     __waitid; # arm x86 mips
     _ctype_;
     _Exit;
     _exit;
-    _flush_cache; # mips
     _flushlbf;
-    _fwalk; # arm x86 mips
     _getlong;
     _getshort;
     _longjmp;
@@ -305,15 +234,9 @@
     alarm;
     alphasort;
     alphasort64;
-    android_getaddrinfofornet;
-    android_getaddrinfofornetcontext;
-    android_gethostbyaddrfornet;
-    android_gethostbynamefornet;
     android_set_abort_message;
     arc4random;
-    arc4random_addrandom; # arm x86 mips
     arc4random_buf;
-    arc4random_stir; # arm x86 mips
     arc4random_uniform;
     asctime;
     asctime64; # arm x86 mips
@@ -327,14 +250,11 @@
     atoll;
     basename;
     basename_r; # arm x86 mips
-    bcopy; # arm x86 mips
     bind;
     bindresvport;
     brk;
-    bsd_signal; # arm x86 mips
     bsearch;
     btowc;
-    bzero; # arm x86 mips
     c16rtomb;
     c32rtomb;
     cacheflush; # arm mips
@@ -387,9 +307,7 @@
     dup3;
     duplocale;
     endmntent;
-    endpwent;
     endservent;
-    endusershell;
     endutent;
     environ;
     epoll_create;
@@ -421,8 +339,6 @@
     execvpe;
     exit;
     faccessat;
-    fake_gmtime_r; # arm x86 mips
-    fake_localtime_r; # arm x86 mips
     fallocate;
     fallocate64;
     fchdir;
@@ -435,7 +351,6 @@
     fdatasync;
     fdopen;
     fdopendir;
-    fdprintf; # arm x86 mips
     feof;
     feof_unlocked;
     ferror;
@@ -467,7 +382,6 @@
     fputws;
     fread;
     free;
-    free_malloc_leak_info;
     freeaddrinfo;
     freelocale;
     fremovexattr;
@@ -488,7 +402,6 @@
     fsync;
     ftell;
     ftello;
-    ftime; # arm x86 mips
     ftok;
     ftruncate;
     ftruncate64;
@@ -509,7 +422,6 @@
     fwscanf;
     gai_strerror;
     get_avphys_pages;
-    get_malloc_leak_info;
     get_nprocs;
     get_nprocs_conf;
     get_phys_pages;
@@ -521,8 +433,6 @@
     getchar_unlocked;
     getcwd;
     getdelim;
-    getdents; # arm x86 mips
-    getdtablesize; # arm x86 mips
     getegid;
     getenv;
     geteuid;
@@ -580,7 +490,6 @@
     gettid;
     gettimeofday;
     getuid;
-    getusershell;
     getutent;
     getwc;
     getwchar;
@@ -598,7 +507,6 @@
     if_nametoindex;
     imaxabs;
     imaxdiv;
-    index; # arm x86 mips
     inet_addr;
     inet_aton;
     inet_lnaof;
@@ -651,7 +559,6 @@
     isprint_l;
     ispunct;
     ispunct_l;
-    issetugid; # arm x86 mips
     isspace;
     isspace_l;
     isupper;
@@ -741,7 +648,6 @@
     mempcpy;
     memrchr;
     memset;
-    memswap; # arm x86 mips
     mincore;
     mkdir;
     mkdirat;
@@ -761,7 +667,6 @@
     mktemp;
     mktime;
     mktime64; # arm x86 mips
-    mktime_tz;
     mlock;
     mlockall;
     mmap;
@@ -780,28 +685,6 @@
     nftw64;
     nice;
     nrand48;
-    ns_format_ttl; # arm64 x86_64 mips64
-    ns_get16; # arm64 x86_64 mips64
-    ns_get32; # arm64 x86_64 mips64
-    ns_initparse; # arm64 x86_64 mips64
-    ns_makecanon; # arm64 x86_64 mips64
-    ns_msg_getflag; # arm64 x86_64 mips64
-    ns_name_compress; # arm64 x86_64 mips64
-    ns_name_ntol; # arm64 x86_64 mips64
-    ns_name_ntop; # arm64 x86_64 mips64
-    ns_name_pack; # arm64 x86_64 mips64
-    ns_name_pton; # arm64 x86_64 mips64
-    ns_name_rollback; # arm64 x86_64 mips64
-    ns_name_skip; # arm64 x86_64 mips64
-    ns_name_uncompress; # arm64 x86_64 mips64
-    ns_name_unpack; # arm64 x86_64 mips64
-    ns_parserr; # arm64 x86_64 mips64
-    ns_put16; # arm64 x86_64 mips64
-    ns_put32; # arm64 x86_64 mips64
-    ns_samename; # arm64 x86_64 mips64
-    ns_skiprr; # arm64 x86_64 mips64
-    ns_sprintrr; # arm64 x86_64 mips64
-    ns_sprintrrf; # arm64 x86_64 mips64
     nsdispatch;
     ntohl;
     ntohs;
@@ -840,7 +723,6 @@
     pread;
     pread64;
     printf;
-    prlimit; # arm64 x86_64 mips64
     prlimit64;
     process_vm_readv;
     process_vm_writev;
@@ -855,7 +737,6 @@
     pthread_attr_getschedpolicy;
     pthread_attr_getscope;
     pthread_attr_getstack;
-    pthread_attr_getstackaddr; # arm x86 mips
     pthread_attr_getstacksize;
     pthread_attr_init;
     pthread_attr_setdetachstate;
@@ -864,7 +745,6 @@
     pthread_attr_setschedpolicy;
     pthread_attr_setscope;
     pthread_attr_setstack;
-    pthread_attr_setstackaddr; # arm x86 mips
     pthread_attr_setstacksize;
     pthread_cond_broadcast;
     pthread_cond_destroy;
@@ -980,7 +860,6 @@
     res_mkquery;
     res_query;
     res_search;
-    restore_core_regs; # arm
     rewind;
     rewinddir;
     rmdir;
@@ -1051,7 +930,6 @@
     setstate;
     settimeofday;
     setuid;
-    setusershell;
     setutent;
     setvbuf;
     setxattr;
@@ -1124,8 +1002,6 @@
     strncpy;
     strndup;
     strnlen;
-    strntoimax; # arm x86 mips
-    strntoumax; # arm x86 mips
     strpbrk;
     strptime;
     strrchr;
@@ -1144,7 +1020,6 @@
     strtoll;
     strtoll_l;
     strtoq;
-    strtotimeval; # arm x86 mips
     strtoul;
     strtoull;
     strtoull_l;
@@ -1166,7 +1041,6 @@
     sysinfo;
     syslog;
     system;
-    sysv_signal; # arm x86 mips
     tcdrain;
     tcflow;
     tcflush;
@@ -1198,7 +1072,6 @@
     timerfd_settime;
     times;
     timezone;
-    tkill; # arm x86 mips
     tmpfile;
     tmpnam;
     toascii;
@@ -1240,7 +1113,6 @@
     vdprintf;
     verr;
     verrx;
-    vfdprintf; # arm x86 mips
     vfork;
     vfprintf;
     vfscanf;
@@ -1260,7 +1132,6 @@
     vwprintf;
     vwscanf;
     wait;
-    wait3; # arm x86 mips
     wait4;
     waitid;
     waitpid;
@@ -1309,7 +1180,6 @@
     wcstoull;
     wcstoull_l;
     wcstoumax;
-    wcswcs; # arm x86 mips
     wcswidth;
     wcsxfrm;
     wcsxfrm_l;
@@ -1332,6 +1202,71 @@
     *;
 };
 
+LIBC_N {
+  global:
+    __aeabi_atexit; # arm
+    __aeabi_memclr; # arm
+    __aeabi_memclr4; # arm
+    __aeabi_memclr8; # arm
+    __aeabi_memcpy; # arm
+    __aeabi_memcpy4; # arm
+    __aeabi_memcpy8; # arm
+    __aeabi_memmove; # arm
+    __aeabi_memmove4; # arm
+    __aeabi_memmove8; # arm
+    __aeabi_memset; # arm
+    __aeabi_memset4; # arm
+    __aeabi_memset8; # arm
+    __fread_chk;
+    __fwrite_chk;
+    __getcwd_chk;
+    __gnu_Unwind_Find_exidx; # arm
+    __pwrite_chk;
+    __pwrite64_chk;
+    __write_chk;
+    adjtimex;
+    clock_adjtime;
+    fgetpos64;
+    fileno_unlocked;
+    fopen64;
+    freeifaddrs;
+    freopen64;
+    fseeko64;
+    fsetpos64;
+    ftello64;
+    funopen64;
+    getgrgid_r;
+    getgrnam_r;
+    getifaddrs;
+    if_freenameindex;
+    if_nameindex;
+    in6addr_any;
+    in6addr_loopback;
+    lockf;
+    lockf64;
+    preadv;
+    preadv64;
+    prlimit; # arm mips x86
+    pthread_barrierattr_destroy;
+    pthread_barrierattr_getpshared;
+    pthread_barrierattr_init;
+    pthread_barrierattr_setpshared;
+    pthread_barrier_destroy;
+    pthread_barrier_init;
+    pthread_barrier_wait;
+    pthread_spin_destroy;
+    pthread_spin_init;
+    pthread_spin_lock;
+    pthread_spin_trylock;
+    pthread_spin_unlock;
+    pwritev;
+    pwritev64;
+    scandirat;
+    scandirat64;
+    strchrnul;
+    tmpfile64;
+} LIBC;
+
 LIBC_PRIVATE {
   global:
     ___Unwind_Backtrace; # arm
@@ -1408,8 +1343,33 @@
     __ashrdi3; # arm
     __bionic_brk; # arm x86 mips
     __bionic_libgcc_compat_symbols; # arm x86
-    __bionic_libgcc_unwind_symbols; # arm
+    __cmpdf2; # arm
+    __divdf3; # arm
+    __divdi3; # arm x86 mips
+    __divsf3; # arm
+    __divsi3; # arm
     __dso_handle; # arm
+    __eqdf2; # arm
+    __extendsfdf2; # arm
+    __fixdfsi; # arm
+    __fixsfsi; # arm
+    __fixunssfsi; # arm
+    __floatdidf; # arm
+    __floatdisf; # arm
+    __floatsidf; # arm
+    __floatsisf; # arm
+    __floatundidf; # arm
+    __floatundisf; # arm
+    __floatunsidf; # arm
+    __floatunsisf; # arm
+    __futex_wait; # arm x86 mips nobrillo
+    __futex_wake; # arm x86 mips nobrillo
+    __gedf2; # arm
+    __get_thread; # arm x86 mips nobrillo
+    __get_tls; # arm x86 mips nobrillo
+    __getdents64; # arm x86 mips
+    __gnu_ldivmod_helper; # arm
+    __gnu_uldivmod_helper; # arm
     __gnu_Unwind_Backtrace; # arm
     __gnu_unwind_execute; # arm
     __gnu_Unwind_Find_exidx; # arm
@@ -1428,6 +1388,46 @@
     __gnu_Unwind_Save_VFP_D_16_to_31; # arm
     __gnu_Unwind_Save_WMMXC; # arm
     __gnu_Unwind_Save_WMMXD; # arm
+    __gtdf2; # arm
+    __ledf2; # arm
+    __lshrdi3; # arm
+    __ltdf2; # arm
+    __muldf3; # arm
+    __muldi3; # arm
+    __mulsf3; # arm
+    __nedf2; # arm
+    __open; # arm x86 mips nobrillo
+    __page_shift; # arm x86 mips nobrillo
+    __page_size; # arm x86 mips nobrillo
+    __popcount_tab; # arm
+    __popcountsi2; # arm x86 mips
+    __pthread_gettid; # arm x86 mips nobrillo
+    __restore_core_regs; # arm
+    __sclose; # arm x86 mips
+    __sdidinit; # arm x86 mips nobrillo
+    __set_errno; # arm x86 mips nobrillo
+    __sflags; # arm x86 mips
+    __sflush; # arm x86 mips
+    __sfp; # arm x86 mips
+    __sglue; # arm x86 mips
+    __sinit; # arm x86 mips nobrillo
+    __smakebuf; # arm x86 mips
+    __sread; # arm x86 mips
+    __srefill; # arm x86 mips
+    __srget; # arm x86 mips
+    __sseek; # arm x86 mips
+    __subdf3; # arm
+    __subsf3; # arm
+    __swbuf; # arm x86 mips
+    __swrite; # arm x86 mips
+    __swsetup; # arm x86 mips
+    __truncdfsf2; # arm
+    __udivdi3; # arm x86 mips
+    __udivsi3; # arm
+    __unorddf2; # arm
+    __unordsf2; # arm
+    __wait4; # arm x86 mips nobrillo
+    _fwalk; # arm x86 mips
     _Unwind_Backtrace; # arm
     _Unwind_Complete; # arm
     _Unwind_DeleteException; # arm
@@ -1443,14 +1443,55 @@
     _Unwind_VRS_Get; # arm
     _Unwind_VRS_Pop; # arm
     _Unwind_VRS_Set; # arm
+    android_getaddrinfofornet;
+    android_getaddrinfofornetcontext;
+    android_gethostbyaddrfornet;
+    android_gethostbynamefornet;
+    arc4random_addrandom; # arm x86 mips nobrillo
+    arc4random_stir; # arm x86 mips nobrillo
     atexit; # arm
-    dlmalloc; # arm x86 mips
-    dlmalloc_inspect_all;
-    dlmalloc_trim;
-    dlmalloc_usable_size; # arm x86 mips
+    bcopy; # arm x86 mips nobrillo
+    bzero; # arm x86 mips nobrillo
+    bsd_signal; # arm x86 mips nobrillo
+    dlmalloc; # arm x86 mips nobrillo
+    dlmalloc_inspect_all; # arm x86 mips nobrillo
+    dlmalloc_trim; # arm x86 mips nobrillo
+    dlmalloc_usable_size; # arm x86 mips nobrillo
+    endpwent; # arm x86 mips nobrillo
+    fdprintf; # arm x86 mips nobrillo
+    free_malloc_leak_info;
+    ftime; # arm x86 mips nobrillo
+    get_malloc_leak_info;
+    getdents; # arm x86 mips nobrillo
+    getdtablesize; # arm x86 mips nobrillo
     gMallocLeakZygoteChild;
+    index; # arm x86 mips nobrillo
+    issetugid; # arm x86 mips nobrillo
+    memswap; # arm x86 mips nobrillo
+    pthread_attr_getstackaddr; # arm x86 mips nobrillo
+    pthread_attr_setstackaddr; # arm x86 mips nobrillo
+    restore_core_regs; # arm
     SHA1Final; # arm x86 mips
     SHA1Init; # arm x86 mips
     SHA1Transform; # arm x86 mips
     SHA1Update; # arm x86 mips
-} LIBC;
+    strntoimax; # arm x86 mips nobrillo
+    strntoumax; # arm x86 mips nobrillo
+    strtotimeval; # arm x86 mips nobrillo
+    sysv_signal; # arm x86 mips nobrillo
+    tkill; # arm x86 mips nobrillo
+    vfdprintf; # arm x86 mips nobrillo
+    wait3; # arm x86 mips nobrillo
+    wcswcs; # arm x86 mips nobrillo
+} LIBC_N;
+
+LIBC_PLATFORM {
+  global:
+    android_net_res_stats_get_info_for_net;
+    android_net_res_stats_aggregate;
+    android_net_res_stats_get_usable_servers;
+    malloc_backtrace;
+    malloc_disable;
+    malloc_enable;
+    malloc_iterate;
+} LIBC_N;
diff --git a/libc/libc.map b/libc/libc.arm64.map
similarity index 67%
copy from libc/libc.map
copy to libc/libc.arm64.map
index 47c52a4..afbd0ee 100644
--- a/libc/libc.map
+++ b/libc/libc.arm64.map
@@ -1,52 +1,25 @@
+# Generated by genversionscripts.py. Do not edit.
 LIBC {
   global:
     __assert;
     __assert2;
-    __atomic_cmpxchg; # arm
-    __atomic_dec; # arm
-    __atomic_inc; # arm
-    __atomic_swap; # arm
     __b64_ntop;
     __b64_pton;
-    __brk; # arm x86 mips
-    __cmpdf2; # arm
     __cmsg_nxthdr;
-    __connect; # arm x86 mips
     __ctype_get_mb_cur_max;
     __cxa_atexit;
     __cxa_finalize;
     __cxa_thread_atexit_impl;
-    __divdf3; # arm
-    __divdi3; # arm x86 mips
-    __divsf3; # arm
-    __divsi3; # arm
     __dn_comp;
     __dn_count_labels;
     __dn_skipname;
-    __epoll_pwait; # arm x86 mips
-    __eqdf2; # arm
     __errno;
-    __exit; # arm x86 mips
-    __extendsfdf2; # arm
-    __fadvise64; # x86 mips
     __fbufsize;
-    __fcntl64; # arm x86 mips
     __FD_CLR_chk;
     __FD_ISSET_chk;
     __FD_SET_chk;
     __fgets_chk;
-    __fixdfsi; # arm
-    __fixsfsi; # arm
-    __fixunssfsi; # arm
     __flbf;
-    __floatdidf; # arm
-    __floatdisf; # arm
-    __floatsidf; # arm
-    __floatsisf; # arm
-    __floatundidf; # arm
-    __floatundisf; # arm
-    __floatunsidf; # arm
-    __floatunsisf; # arm
     __fp_nquery;
     __fp_query;
     __fpclassify;
@@ -57,26 +30,11 @@
     __fpurge;
     __freadable;
     __fsetlocking;
-    __fstatfs64; # arm x86 mips
-    __futex_wait; # arm x86 mips
-    __futex_wake; # arm x86 mips
     __fwritable;
-    __gedf2; # arm
     __get_h_errno;
-    __get_thread; # arm x86 mips
-    __get_tls; # arm x86 mips
-    __getcpu; # arm x86 mips
-    __getcwd; # arm x86 mips
-    __getdents64; # arm x86 mips
-    __getpid; # arm x86 mips
-    __getpriority; # arm x86 mips
     __gnu_basename;
-    __gnu_ldivmod_helper; # arm
     __gnu_strerror_r;
-    __gnu_uldivmod_helper; # arm
-    __gtdf2; # arm
     __hostalias;
-    __ioctl; # arm x86 mips
     __isfinite;
     __isfinitef;
     __isfinitel;
@@ -89,52 +47,17 @@
     __isnormal;
     __isnormalf;
     __isnormall;
-    __isthreaded;
-    __ledf2; # arm
     __libc_current_sigrtmax;
     __libc_current_sigrtmin;
     __libc_init;
-    __llseek; # arm x86 mips
     __loc_aton;
     __loc_ntoa;
-    __lshrdi3; # arm
-    __ltdf2; # arm
     __memchr_chk;
     __memcpy_chk;
     __memmove_chk;
     __memrchr_chk;
     __memset_chk;
-    __mmap2; # arm x86 mips
-    __moddi3; # x86 mips
-    __muldf3; # arm
-    __muldi3; # arm
-    __mulsf3; # arm
-    __nedf2; # arm
-    __ns_format_ttl; # arm x86 mips
-    __ns_get16; # arm x86 mips
-    __ns_get32; # arm x86 mips
-    __ns_initparse; # arm x86 mips
-    __ns_makecanon; # arm x86 mips
-    __ns_msg_getflag; # arm x86 mips
-    __ns_name_compress; # arm x86 mips
-    __ns_name_ntol; # arm x86 mips
-    __ns_name_ntop; # arm x86 mips
-    __ns_name_pack; # arm x86 mips
-    __ns_name_pton; # arm x86 mips
-    __ns_name_rollback; # arm x86 mips
-    __ns_name_skip; # arm x86 mips
-    __ns_name_uncompress; # arm x86 mips
-    __ns_name_unpack; # arm x86 mips
-    __ns_parserr; # arm x86 mips
-    __ns_put16; # arm x86 mips
-    __ns_put32; # arm x86 mips
-    __ns_samename; # arm x86 mips
-    __ns_skiprr; # arm x86 mips
-    __ns_sprintrr; # arm x86 mips
-    __ns_sprintrrf; # arm x86 mips
-    __open; # arm x86 mips
     __open_2;
-    __openat; # arm x86 mips
     __openat_2;
     __p_cdname;
     __p_cdnname;
@@ -149,27 +72,18 @@
     __p_time;
     __p_type;
     __p_type_syms;
-    __page_shift; # arm x86 mips
-    __page_size; # arm x86 mips
     __poll_chk;
-    __popcount_tab; # arm
-    __popcountsi2; # arm x86 mips
-    __ppoll; # arm x86 mips
     __ppoll_chk;
     __pread64_chk;
     __pread_chk;
     __progname;
-    __pselect6; # arm x86 mips
     __pthread_cleanup_pop;
     __pthread_cleanup_push;
-    __pthread_gettid; # arm x86 mips
-    __ptrace; # arm x86 mips
     __putlong;
     __putshort;
     __read_chk;
     __readlink_chk;
     __readlinkat_chk;
-    __reboot; # arm x86 mips
     __recvfrom_chk;
     __register_atfork;
     __res_close;
@@ -192,41 +106,14 @@
     __res_send;
     __res_send_setqhook;
     __res_send_setrhook;
-    __restore_core_regs; # arm
-    __rt_sigaction; # arm x86 mips
-    __rt_sigpending; # arm x86 mips
-    __rt_sigprocmask; # arm x86 mips
-    __rt_sigsuspend; # arm x86 mips
-    __rt_sigtimedwait; # arm x86 mips
     __sched_cpualloc;
     __sched_cpucount;
     __sched_cpufree;
-    __sched_getaffinity; # arm x86 mips
-    __sclose; # arm x86 mips
-    __sdidinit; # arm x86 mips
-    __set_errno; # arm x86 mips
-    __set_thread_area; # x86
-    __set_tid_address; # arm x86 mips
-    __set_tls; # arm mips
     __sF;
-    __sflags; # arm x86 mips
-    __sflush; # arm x86 mips
-    __sfp; # arm x86 mips
-    __sglue; # arm x86 mips
-    __sigaction; # arm x86 mips
-    __signalfd4; # arm x86 mips
-    __sinit; # arm x86 mips
-    __smakebuf; # arm x86 mips
     __snprintf_chk;
-    __socket; # arm x86 mips
     __sprintf_chk;
-    __sread; # arm x86 mips
-    __srefill; # arm x86 mips
-    __srget; # arm x86 mips
-    __sseek; # arm x86 mips
     __stack_chk_fail;
     __stack_chk_guard;
-    __statfs64; # arm x86 mips
     __stpcpy_chk;
     __stpncpy_chk;
     __stpncpy_chk2;
@@ -240,11 +127,6 @@
     __strncpy_chk;
     __strncpy_chk2;
     __strrchr_chk;
-    __subdf3; # arm
-    __subsf3; # arm
-    __swbuf; # arm x86 mips
-    __swrite; # arm x86 mips
-    __swsetup; # arm x86 mips
     __sym_ntop;
     __sym_ntos;
     __sym_ston;
@@ -263,28 +145,13 @@
     __system_property_set_filename;
     __system_property_update;
     __system_property_wait_any;
-    __timer_create; # arm x86 mips
-    __timer_delete; # arm x86 mips
-    __timer_getoverrun; # arm x86 mips
-    __timer_gettime; # arm x86 mips
-    __timer_settime; # arm x86 mips
-    __truncdfsf2; # arm
-    __udivdi3; # arm x86 mips
-    __udivsi3; # arm
     __umask_chk;
-    __umoddi3; # x86 mips
-    __unorddf2; # arm
-    __unordsf2; # arm
     __vsnprintf_chk;
     __vsprintf_chk;
-    __wait4; # arm x86 mips
-    __waitid; # arm x86 mips
     _ctype_;
     _Exit;
     _exit;
-    _flush_cache; # mips
     _flushlbf;
-    _fwalk; # arm x86 mips
     _getlong;
     _getshort;
     _longjmp;
@@ -293,9 +160,7 @@
     _resolv_set_nameservers_for_net;
     _setjmp;
     _tolower;
-    _tolower_tab_; # arm x86 mips
     _toupper;
-    _toupper_tab_; # arm x86 mips
     abort;
     abs;
     accept;
@@ -305,19 +170,11 @@
     alarm;
     alphasort;
     alphasort64;
-    android_getaddrinfofornet;
-    android_getaddrinfofornetcontext;
-    android_gethostbyaddrfornet;
-    android_gethostbynamefornet;
     android_set_abort_message;
     arc4random;
-    arc4random_addrandom; # arm x86 mips
     arc4random_buf;
-    arc4random_stir; # arm x86 mips
     arc4random_uniform;
     asctime;
-    asctime64; # arm x86 mips
-    asctime64_r; # arm x86 mips
     asctime_r;
     asprintf;
     at_quick_exit;
@@ -326,18 +183,13 @@
     atol;
     atoll;
     basename;
-    basename_r; # arm x86 mips
-    bcopy; # arm x86 mips
     bind;
     bindresvport;
     brk;
-    bsd_signal; # arm x86 mips
     bsearch;
     btowc;
-    bzero; # arm x86 mips
     c16rtomb;
     c32rtomb;
-    cacheflush; # arm mips
     calloc;
     capget;
     capset;
@@ -368,8 +220,6 @@
     creat;
     creat64;
     ctime;
-    ctime64; # arm x86 mips
-    ctime64_r; # arm x86 mips
     ctime_r;
     daemon;
     daylight;
@@ -377,7 +227,6 @@
     difftime;
     dirfd;
     dirname;
-    dirname_r; # arm x86 mips
     div;
     dn_expand;
     dprintf;
@@ -387,9 +236,7 @@
     dup3;
     duplocale;
     endmntent;
-    endpwent;
     endservent;
-    endusershell;
     endutent;
     environ;
     epoll_create;
@@ -421,8 +268,6 @@
     execvpe;
     exit;
     faccessat;
-    fake_gmtime_r; # arm x86 mips
-    fake_localtime_r; # arm x86 mips
     fallocate;
     fallocate64;
     fchdir;
@@ -435,7 +280,6 @@
     fdatasync;
     fdopen;
     fdopendir;
-    fdprintf; # arm x86 mips
     feof;
     feof_unlocked;
     ferror;
@@ -467,7 +311,6 @@
     fputws;
     fread;
     free;
-    free_malloc_leak_info;
     freeaddrinfo;
     freelocale;
     fremovexattr;
@@ -488,7 +331,6 @@
     fsync;
     ftell;
     ftello;
-    ftime; # arm x86 mips
     ftok;
     ftruncate;
     ftruncate64;
@@ -509,7 +351,6 @@
     fwscanf;
     gai_strerror;
     get_avphys_pages;
-    get_malloc_leak_info;
     get_nprocs;
     get_nprocs_conf;
     get_phys_pages;
@@ -521,8 +362,6 @@
     getchar_unlocked;
     getcwd;
     getdelim;
-    getdents; # arm x86 mips
-    getdtablesize; # arm x86 mips
     getegid;
     getenv;
     geteuid;
@@ -580,14 +419,11 @@
     gettid;
     gettimeofday;
     getuid;
-    getusershell;
     getutent;
     getwc;
     getwchar;
     getxattr;
     gmtime;
-    gmtime64; # arm x86 mips
-    gmtime64_r; # arm x86 mips
     gmtime_r;
     grantpt;
     herror;
@@ -598,7 +434,6 @@
     if_nametoindex;
     imaxabs;
     imaxdiv;
-    index; # arm x86 mips
     inet_addr;
     inet_aton;
     inet_lnaof;
@@ -651,7 +486,6 @@
     isprint_l;
     ispunct;
     ispunct_l;
-    issetugid; # arm x86 mips
     isspace;
     isspace_l;
     isupper;
@@ -704,8 +538,6 @@
     llistxattr;
     localeconv;
     localtime;
-    localtime64; # arm x86 mips
-    localtime64_r; # arm x86 mips
     localtime_r;
     login_tty;
     longjmp;
@@ -741,7 +573,6 @@
     mempcpy;
     memrchr;
     memset;
-    memswap; # arm x86 mips
     mincore;
     mkdir;
     mkdirat;
@@ -760,8 +591,6 @@
     mkstemps64;
     mktemp;
     mktime;
-    mktime64; # arm x86 mips
-    mktime_tz;
     mlock;
     mlockall;
     mmap;
@@ -855,7 +684,6 @@
     pthread_attr_getschedpolicy;
     pthread_attr_getscope;
     pthread_attr_getstack;
-    pthread_attr_getstackaddr; # arm x86 mips
     pthread_attr_getstacksize;
     pthread_attr_init;
     pthread_attr_setdetachstate;
@@ -864,17 +692,12 @@
     pthread_attr_setschedpolicy;
     pthread_attr_setscope;
     pthread_attr_setstack;
-    pthread_attr_setstackaddr; # arm x86 mips
     pthread_attr_setstacksize;
     pthread_cond_broadcast;
     pthread_cond_destroy;
     pthread_cond_init;
     pthread_cond_signal;
     pthread_cond_timedwait;
-    pthread_cond_timedwait_monotonic; # arm x86 mips
-    pthread_cond_timedwait_monotonic_np; # arm x86 mips
-    pthread_cond_timedwait_relative_np; # arm x86 mips
-    pthread_cond_timeout_np; # arm x86 mips
     pthread_cond_wait;
     pthread_condattr_destroy;
     pthread_condattr_getclock;
@@ -898,7 +721,6 @@
     pthread_mutex_destroy;
     pthread_mutex_init;
     pthread_mutex_lock;
-    pthread_mutex_lock_timeout_np; # arm x86 mips
     pthread_mutex_timedlock;
     pthread_mutex_trylock;
     pthread_mutex_unlock;
@@ -939,10 +761,8 @@
     putenv;
     puts;
     pututline;
-    putw; # arm x86 mips
     putwc;
     putwchar;
-    pvalloc; # arm x86 mips
     pwrite;
     pwrite64;
     qsort;
@@ -980,7 +800,6 @@
     res_mkquery;
     res_query;
     res_search;
-    restore_core_regs; # arm
     rewind;
     rewinddir;
     rmdir;
@@ -1051,7 +870,6 @@
     setstate;
     settimeofday;
     setuid;
-    setusershell;
     setutent;
     setvbuf;
     setxattr;
@@ -1124,8 +942,6 @@
     strncpy;
     strndup;
     strnlen;
-    strntoimax; # arm x86 mips
-    strntoumax; # arm x86 mips
     strpbrk;
     strptime;
     strrchr;
@@ -1144,7 +960,6 @@
     strtoll;
     strtoll_l;
     strtoq;
-    strtotimeval; # arm x86 mips
     strtoul;
     strtoull;
     strtoull_l;
@@ -1166,7 +981,6 @@
     sysinfo;
     syslog;
     system;
-    sysv_signal; # arm x86 mips
     tcdrain;
     tcflow;
     tcflush;
@@ -1185,9 +999,7 @@
     tgkill;
     time;
     timegm;
-    timegm64; # arm x86 mips
     timelocal;
-    timelocal64; # arm x86 mips
     timer_create;
     timer_delete;
     timer_getoverrun;
@@ -1198,7 +1010,6 @@
     timerfd_settime;
     times;
     timezone;
-    tkill; # arm x86 mips
     tmpfile;
     tmpnam;
     toascii;
@@ -1235,12 +1046,10 @@
     utimensat;
     utimes;
     utmpname;
-    valloc; # arm x86 mips
     vasprintf;
     vdprintf;
     verr;
     verrx;
-    vfdprintf; # arm x86 mips
     vfork;
     vfprintf;
     vfscanf;
@@ -1260,7 +1069,6 @@
     vwprintf;
     vwscanf;
     wait;
-    wait3; # arm x86 mips
     wait4;
     waitid;
     waitpid;
@@ -1309,7 +1117,6 @@
     wcstoull;
     wcstoull_l;
     wcstoumax;
-    wcswcs; # arm x86 mips
     wcswidth;
     wcsxfrm;
     wcsxfrm_l;
@@ -1332,125 +1139,74 @@
     *;
 };
 
+LIBC_N {
+  global:
+    __fread_chk;
+    __fwrite_chk;
+    __getcwd_chk;
+    __pwrite_chk;
+    __pwrite64_chk;
+    __write_chk;
+    adjtimex;
+    clock_adjtime;
+    fgetpos64;
+    fileno_unlocked;
+    fopen64;
+    freeifaddrs;
+    freopen64;
+    fseeko64;
+    fsetpos64;
+    ftello64;
+    funopen64;
+    getgrgid_r;
+    getgrnam_r;
+    getifaddrs;
+    if_freenameindex;
+    if_nameindex;
+    in6addr_any;
+    in6addr_loopback;
+    lockf;
+    lockf64;
+    preadv;
+    preadv64;
+    pthread_barrierattr_destroy;
+    pthread_barrierattr_getpshared;
+    pthread_barrierattr_init;
+    pthread_barrierattr_setpshared;
+    pthread_barrier_destroy;
+    pthread_barrier_init;
+    pthread_barrier_wait;
+    pthread_spin_destroy;
+    pthread_spin_init;
+    pthread_spin_lock;
+    pthread_spin_trylock;
+    pthread_spin_unlock;
+    pwritev;
+    pwritev64;
+    scandirat;
+    scandirat64;
+    strchrnul;
+    tmpfile64;
+} LIBC;
+
 LIBC_PRIVATE {
   global:
-    ___Unwind_Backtrace; # arm
-    ___Unwind_ForcedUnwind; # arm
-    ___Unwind_RaiseException; # arm
-    ___Unwind_Resume; # arm
-    ___Unwind_Resume_or_Rethrow; # arm
-    __accept4; # arm x86 mips
-    __adddf3; # arm
-    __addsf3; # arm
-    __aeabi_atexit; # arm
-    __aeabi_cdcmpeq; # arm
-    __aeabi_cdcmple; # arm
-    __aeabi_cdrcmple; # arm
-    __aeabi_d2f; # arm
-    __aeabi_d2iz; # arm
-    __aeabi_dadd; # arm
-    __aeabi_dcmpeq; # arm
-    __aeabi_dcmpge; # arm
-    __aeabi_dcmpgt; # arm
-    __aeabi_dcmple; # arm
-    __aeabi_dcmplt; # arm
-    __aeabi_dcmpun; # arm
-    __aeabi_ddiv; # arm
-    __aeabi_dmul; # arm
-    __aeabi_drsub; # arm
-    __aeabi_dsub; # arm
-    __aeabi_f2d; # arm
-    __aeabi_f2iz; # arm
-    __aeabi_f2uiz; # arm
-    __aeabi_fadd; # arm
-    __aeabi_fcmpun; # arm
-    __aeabi_fdiv; # arm
-    __aeabi_fmul; # arm
-    __aeabi_frsub; # arm
-    __aeabi_fsub; # arm
-    __aeabi_i2d; # arm
-    __aeabi_i2f; # arm
-    __aeabi_idiv; # arm
-    __aeabi_idiv0; # arm
-    __aeabi_idivmod; # arm
-    __aeabi_l2d; # arm
-    __aeabi_l2f; # arm
-    __aeabi_lasr; # arm
-    __aeabi_ldiv0; # arm
-    __aeabi_ldivmod; # arm
-    __aeabi_llsl; # arm
-    __aeabi_llsr; # arm
-    __aeabi_lmul; # arm
-    __aeabi_memclr; # arm
-    __aeabi_memclr4; # arm
-    __aeabi_memclr8; # arm
-    __aeabi_memcpy; # arm
-    __aeabi_memcpy4; # arm
-    __aeabi_memcpy8; # arm
-    __aeabi_memmove; # arm
-    __aeabi_memmove4; # arm
-    __aeabi_memmove8; # arm
-    __aeabi_memset; # arm
-    __aeabi_memset4; # arm
-    __aeabi_memset8; # arm
-    __aeabi_ui2d; # arm
-    __aeabi_ui2f; # arm
-    __aeabi_uidiv; # arm
-    __aeabi_uidivmod; # arm
-    __aeabi_ul2d; # arm
-    __aeabi_ul2f; # arm
-    __aeabi_uldivmod; # arm
-    __aeabi_unwind_cpp_pr0; # arm
-    __aeabi_unwind_cpp_pr1; # arm
-    __aeabi_unwind_cpp_pr2; # arm
-    __arm_fadvise64_64; # arm
-    __ashldi3; # arm
-    __ashrdi3; # arm
-    __bionic_brk; # arm x86 mips
-    __bionic_libgcc_compat_symbols; # arm x86
-    __bionic_libgcc_unwind_symbols; # arm
-    __dso_handle; # arm
-    __gnu_Unwind_Backtrace; # arm
-    __gnu_unwind_execute; # arm
-    __gnu_Unwind_Find_exidx; # arm
-    __gnu_Unwind_ForcedUnwind; # arm
-    __gnu_unwind_frame; # arm
-    __gnu_Unwind_RaiseException; # arm
-    __gnu_Unwind_Restore_VFP; # arm
-    __gnu_Unwind_Restore_VFP_D; # arm
-    __gnu_Unwind_Restore_VFP_D_16_to_31; # arm
-    __gnu_Unwind_Restore_WMMXC; # arm
-    __gnu_Unwind_Restore_WMMXD; # arm
-    __gnu_Unwind_Resume; # arm
-    __gnu_Unwind_Resume_or_Rethrow; # arm
-    __gnu_Unwind_Save_VFP; # arm
-    __gnu_Unwind_Save_VFP_D; # arm
-    __gnu_Unwind_Save_VFP_D_16_to_31; # arm
-    __gnu_Unwind_Save_WMMXC; # arm
-    __gnu_Unwind_Save_WMMXD; # arm
-    _Unwind_Backtrace; # arm
-    _Unwind_Complete; # arm
-    _Unwind_DeleteException; # arm
-    _Unwind_ForcedUnwind; # arm
-    _Unwind_GetCFA; # arm
-    _Unwind_GetDataRelBase; # arm
-    _Unwind_GetLanguageSpecificData; # arm
-    _Unwind_GetRegionStart; # arm
-    _Unwind_GetTextRelBase; # arm
-    _Unwind_RaiseException; # arm
-    _Unwind_Resume; # arm
-    _Unwind_Resume_or_Rethrow; # arm
-    _Unwind_VRS_Get; # arm
-    _Unwind_VRS_Pop; # arm
-    _Unwind_VRS_Set; # arm
-    atexit; # arm
-    dlmalloc; # arm x86 mips
-    dlmalloc_inspect_all;
-    dlmalloc_trim;
-    dlmalloc_usable_size; # arm x86 mips
+    android_getaddrinfofornet;
+    android_getaddrinfofornetcontext;
+    android_gethostbyaddrfornet;
+    android_gethostbynamefornet;
+    free_malloc_leak_info;
+    get_malloc_leak_info;
     gMallocLeakZygoteChild;
-    SHA1Final; # arm x86 mips
-    SHA1Init; # arm x86 mips
-    SHA1Transform; # arm x86 mips
-    SHA1Update; # arm x86 mips
-} LIBC;
+} LIBC_N;
+
+LIBC_PLATFORM {
+  global:
+    android_net_res_stats_get_info_for_net;
+    android_net_res_stats_aggregate;
+    android_net_res_stats_get_usable_servers;
+    malloc_backtrace;
+    malloc_disable;
+    malloc_enable;
+    malloc_iterate;
+} LIBC_N;
diff --git a/libc/libc.map b/libc/libc.map.txt
similarity index 88%
copy from libc/libc.map
copy to libc/libc.map.txt
index 47c52a4..0e41f6c 100644
--- a/libc/libc.map
+++ b/libc/libc.map.txt
@@ -9,25 +9,18 @@
     __b64_ntop;
     __b64_pton;
     __brk; # arm x86 mips
-    __cmpdf2; # arm
     __cmsg_nxthdr;
     __connect; # arm x86 mips
     __ctype_get_mb_cur_max;
     __cxa_atexit;
     __cxa_finalize;
     __cxa_thread_atexit_impl;
-    __divdf3; # arm
-    __divdi3; # arm x86 mips
-    __divsf3; # arm
-    __divsi3; # arm
     __dn_comp;
     __dn_count_labels;
     __dn_skipname;
     __epoll_pwait; # arm x86 mips
-    __eqdf2; # arm
     __errno;
     __exit; # arm x86 mips
-    __extendsfdf2; # arm
     __fadvise64; # x86 mips
     __fbufsize;
     __fcntl64; # arm x86 mips
@@ -35,18 +28,7 @@
     __FD_ISSET_chk;
     __FD_SET_chk;
     __fgets_chk;
-    __fixdfsi; # arm
-    __fixsfsi; # arm
-    __fixunssfsi; # arm
     __flbf;
-    __floatdidf; # arm
-    __floatdisf; # arm
-    __floatsidf; # arm
-    __floatsisf; # arm
-    __floatundidf; # arm
-    __floatundisf; # arm
-    __floatunsidf; # arm
-    __floatunsisf; # arm
     __fp_nquery;
     __fp_query;
     __fpclassify;
@@ -58,23 +40,14 @@
     __freadable;
     __fsetlocking;
     __fstatfs64; # arm x86 mips
-    __futex_wait; # arm x86 mips
-    __futex_wake; # arm x86 mips
     __fwritable;
-    __gedf2; # arm
     __get_h_errno;
-    __get_thread; # arm x86 mips
-    __get_tls; # arm x86 mips
     __getcpu; # arm x86 mips
     __getcwd; # arm x86 mips
-    __getdents64; # arm x86 mips
     __getpid; # arm x86 mips
     __getpriority; # arm x86 mips
     __gnu_basename;
-    __gnu_ldivmod_helper; # arm
     __gnu_strerror_r;
-    __gnu_uldivmod_helper; # arm
-    __gtdf2; # arm
     __hostalias;
     __ioctl; # arm x86 mips
     __isfinite;
@@ -89,27 +62,19 @@
     __isnormal;
     __isnormalf;
     __isnormall;
-    __isthreaded;
-    __ledf2; # arm
+    __isthreaded; # arm x86 mips
     __libc_current_sigrtmax;
     __libc_current_sigrtmin;
     __libc_init;
     __llseek; # arm x86 mips
     __loc_aton;
     __loc_ntoa;
-    __lshrdi3; # arm
-    __ltdf2; # arm
     __memchr_chk;
     __memcpy_chk;
     __memmove_chk;
     __memrchr_chk;
     __memset_chk;
     __mmap2; # arm x86 mips
-    __moddi3; # x86 mips
-    __muldf3; # arm
-    __muldi3; # arm
-    __mulsf3; # arm
-    __nedf2; # arm
     __ns_format_ttl; # arm x86 mips
     __ns_get16; # arm x86 mips
     __ns_get32; # arm x86 mips
@@ -132,7 +97,6 @@
     __ns_skiprr; # arm x86 mips
     __ns_sprintrr; # arm x86 mips
     __ns_sprintrrf; # arm x86 mips
-    __open; # arm x86 mips
     __open_2;
     __openat; # arm x86 mips
     __openat_2;
@@ -149,11 +113,7 @@
     __p_time;
     __p_type;
     __p_type_syms;
-    __page_shift; # arm x86 mips
-    __page_size; # arm x86 mips
     __poll_chk;
-    __popcount_tab; # arm
-    __popcountsi2; # arm x86 mips
     __ppoll; # arm x86 mips
     __ppoll_chk;
     __pread64_chk;
@@ -162,7 +122,6 @@
     __pselect6; # arm x86 mips
     __pthread_cleanup_pop;
     __pthread_cleanup_push;
-    __pthread_gettid; # arm x86 mips
     __ptrace; # arm x86 mips
     __putlong;
     __putshort;
@@ -192,7 +151,6 @@
     __res_send;
     __res_send_setqhook;
     __res_send_setrhook;
-    __restore_core_regs; # arm
     __rt_sigaction; # arm x86 mips
     __rt_sigpending; # arm x86 mips
     __rt_sigprocmask; # arm x86 mips
@@ -202,28 +160,14 @@
     __sched_cpucount;
     __sched_cpufree;
     __sched_getaffinity; # arm x86 mips
-    __sclose; # arm x86 mips
-    __sdidinit; # arm x86 mips
-    __set_errno; # arm x86 mips
     __set_thread_area; # x86
     __set_tid_address; # arm x86 mips
     __set_tls; # arm mips
     __sF;
-    __sflags; # arm x86 mips
-    __sflush; # arm x86 mips
-    __sfp; # arm x86 mips
-    __sglue; # arm x86 mips
     __sigaction; # arm x86 mips
-    __signalfd4; # arm x86 mips
-    __sinit; # arm x86 mips
-    __smakebuf; # arm x86 mips
     __snprintf_chk;
     __socket; # arm x86 mips
     __sprintf_chk;
-    __sread; # arm x86 mips
-    __srefill; # arm x86 mips
-    __srget; # arm x86 mips
-    __sseek; # arm x86 mips
     __stack_chk_fail;
     __stack_chk_guard;
     __statfs64; # arm x86 mips
@@ -240,11 +184,6 @@
     __strncpy_chk;
     __strncpy_chk2;
     __strrchr_chk;
-    __subdf3; # arm
-    __subsf3; # arm
-    __swbuf; # arm x86 mips
-    __swrite; # arm x86 mips
-    __swsetup; # arm x86 mips
     __sym_ntop;
     __sym_ntos;
     __sym_ston;
@@ -268,23 +207,15 @@
     __timer_getoverrun; # arm x86 mips
     __timer_gettime; # arm x86 mips
     __timer_settime; # arm x86 mips
-    __truncdfsf2; # arm
-    __udivdi3; # arm x86 mips
-    __udivsi3; # arm
     __umask_chk;
-    __umoddi3; # x86 mips
-    __unorddf2; # arm
-    __unordsf2; # arm
     __vsnprintf_chk;
     __vsprintf_chk;
-    __wait4; # arm x86 mips
     __waitid; # arm x86 mips
     _ctype_;
     _Exit;
     _exit;
     _flush_cache; # mips
     _flushlbf;
-    _fwalk; # arm x86 mips
     _getlong;
     _getshort;
     _longjmp;
@@ -305,15 +236,9 @@
     alarm;
     alphasort;
     alphasort64;
-    android_getaddrinfofornet;
-    android_getaddrinfofornetcontext;
-    android_gethostbyaddrfornet;
-    android_gethostbynamefornet;
     android_set_abort_message;
     arc4random;
-    arc4random_addrandom; # arm x86 mips
     arc4random_buf;
-    arc4random_stir; # arm x86 mips
     arc4random_uniform;
     asctime;
     asctime64; # arm x86 mips
@@ -327,14 +252,11 @@
     atoll;
     basename;
     basename_r; # arm x86 mips
-    bcopy; # arm x86 mips
     bind;
     bindresvport;
     brk;
-    bsd_signal; # arm x86 mips
     bsearch;
     btowc;
-    bzero; # arm x86 mips
     c16rtomb;
     c32rtomb;
     cacheflush; # arm mips
@@ -387,9 +309,7 @@
     dup3;
     duplocale;
     endmntent;
-    endpwent;
     endservent;
-    endusershell;
     endutent;
     environ;
     epoll_create;
@@ -421,8 +341,6 @@
     execvpe;
     exit;
     faccessat;
-    fake_gmtime_r; # arm x86 mips
-    fake_localtime_r; # arm x86 mips
     fallocate;
     fallocate64;
     fchdir;
@@ -435,7 +353,6 @@
     fdatasync;
     fdopen;
     fdopendir;
-    fdprintf; # arm x86 mips
     feof;
     feof_unlocked;
     ferror;
@@ -467,7 +384,6 @@
     fputws;
     fread;
     free;
-    free_malloc_leak_info;
     freeaddrinfo;
     freelocale;
     fremovexattr;
@@ -488,7 +404,6 @@
     fsync;
     ftell;
     ftello;
-    ftime; # arm x86 mips
     ftok;
     ftruncate;
     ftruncate64;
@@ -509,7 +424,6 @@
     fwscanf;
     gai_strerror;
     get_avphys_pages;
-    get_malloc_leak_info;
     get_nprocs;
     get_nprocs_conf;
     get_phys_pages;
@@ -521,8 +435,6 @@
     getchar_unlocked;
     getcwd;
     getdelim;
-    getdents; # arm x86 mips
-    getdtablesize; # arm x86 mips
     getegid;
     getenv;
     geteuid;
@@ -580,7 +492,6 @@
     gettid;
     gettimeofday;
     getuid;
-    getusershell;
     getutent;
     getwc;
     getwchar;
@@ -598,7 +509,6 @@
     if_nametoindex;
     imaxabs;
     imaxdiv;
-    index; # arm x86 mips
     inet_addr;
     inet_aton;
     inet_lnaof;
@@ -651,7 +561,6 @@
     isprint_l;
     ispunct;
     ispunct_l;
-    issetugid; # arm x86 mips
     isspace;
     isspace_l;
     isupper;
@@ -741,7 +650,6 @@
     mempcpy;
     memrchr;
     memset;
-    memswap; # arm x86 mips
     mincore;
     mkdir;
     mkdirat;
@@ -761,7 +669,6 @@
     mktemp;
     mktime;
     mktime64; # arm x86 mips
-    mktime_tz;
     mlock;
     mlockall;
     mmap;
@@ -855,7 +762,6 @@
     pthread_attr_getschedpolicy;
     pthread_attr_getscope;
     pthread_attr_getstack;
-    pthread_attr_getstackaddr; # arm x86 mips
     pthread_attr_getstacksize;
     pthread_attr_init;
     pthread_attr_setdetachstate;
@@ -864,7 +770,6 @@
     pthread_attr_setschedpolicy;
     pthread_attr_setscope;
     pthread_attr_setstack;
-    pthread_attr_setstackaddr; # arm x86 mips
     pthread_attr_setstacksize;
     pthread_cond_broadcast;
     pthread_cond_destroy;
@@ -980,7 +885,6 @@
     res_mkquery;
     res_query;
     res_search;
-    restore_core_regs; # arm
     rewind;
     rewinddir;
     rmdir;
@@ -1051,7 +955,6 @@
     setstate;
     settimeofday;
     setuid;
-    setusershell;
     setutent;
     setvbuf;
     setxattr;
@@ -1124,8 +1027,6 @@
     strncpy;
     strndup;
     strnlen;
-    strntoimax; # arm x86 mips
-    strntoumax; # arm x86 mips
     strpbrk;
     strptime;
     strrchr;
@@ -1144,7 +1045,6 @@
     strtoll;
     strtoll_l;
     strtoq;
-    strtotimeval; # arm x86 mips
     strtoul;
     strtoull;
     strtoull_l;
@@ -1166,7 +1066,6 @@
     sysinfo;
     syslog;
     system;
-    sysv_signal; # arm x86 mips
     tcdrain;
     tcflow;
     tcflush;
@@ -1198,7 +1097,6 @@
     timerfd_settime;
     times;
     timezone;
-    tkill; # arm x86 mips
     tmpfile;
     tmpnam;
     toascii;
@@ -1240,7 +1138,6 @@
     vdprintf;
     verr;
     verrx;
-    vfdprintf; # arm x86 mips
     vfork;
     vfprintf;
     vfscanf;
@@ -1260,7 +1157,6 @@
     vwprintf;
     vwscanf;
     wait;
-    wait3; # arm x86 mips
     wait4;
     waitid;
     waitpid;
@@ -1309,7 +1205,6 @@
     wcstoull;
     wcstoull_l;
     wcstoumax;
-    wcswcs; # arm x86 mips
     wcswidth;
     wcsxfrm;
     wcsxfrm_l;
@@ -1332,6 +1227,71 @@
     *;
 };
 
+LIBC_N {
+  global:
+    __aeabi_atexit; # arm
+    __aeabi_memclr; # arm
+    __aeabi_memclr4; # arm
+    __aeabi_memclr8; # arm
+    __aeabi_memcpy; # arm
+    __aeabi_memcpy4; # arm
+    __aeabi_memcpy8; # arm
+    __aeabi_memmove; # arm
+    __aeabi_memmove4; # arm
+    __aeabi_memmove8; # arm
+    __aeabi_memset; # arm
+    __aeabi_memset4; # arm
+    __aeabi_memset8; # arm
+    __fread_chk;
+    __fwrite_chk;
+    __getcwd_chk;
+    __gnu_Unwind_Find_exidx; # arm
+    __pwrite_chk;
+    __pwrite64_chk;
+    __write_chk;
+    adjtimex;
+    clock_adjtime;
+    fgetpos64;
+    fileno_unlocked;
+    fopen64;
+    freeifaddrs;
+    freopen64;
+    fseeko64;
+    fsetpos64;
+    ftello64;
+    funopen64;
+    getgrgid_r;
+    getgrnam_r;
+    getifaddrs;
+    if_freenameindex;
+    if_nameindex;
+    in6addr_any;
+    in6addr_loopback;
+    lockf;
+    lockf64;
+    preadv;
+    preadv64;
+    prlimit; # arm mips x86
+    pthread_barrierattr_destroy;
+    pthread_barrierattr_getpshared;
+    pthread_barrierattr_init;
+    pthread_barrierattr_setpshared;
+    pthread_barrier_destroy;
+    pthread_barrier_init;
+    pthread_barrier_wait;
+    pthread_spin_destroy;
+    pthread_spin_init;
+    pthread_spin_lock;
+    pthread_spin_trylock;
+    pthread_spin_unlock;
+    pwritev;
+    pwritev64;
+    scandirat;
+    scandirat64;
+    strchrnul;
+    tmpfile64;
+} LIBC;
+
 LIBC_PRIVATE {
   global:
     ___Unwind_Backtrace; # arm
@@ -1408,8 +1368,33 @@
     __ashrdi3; # arm
     __bionic_brk; # arm x86 mips
     __bionic_libgcc_compat_symbols; # arm x86
-    __bionic_libgcc_unwind_symbols; # arm
+    __cmpdf2; # arm
+    __divdf3; # arm
+    __divdi3; # arm x86 mips
+    __divsf3; # arm
+    __divsi3; # arm
     __dso_handle; # arm
+    __eqdf2; # arm
+    __extendsfdf2; # arm
+    __fixdfsi; # arm
+    __fixsfsi; # arm
+    __fixunssfsi; # arm
+    __floatdidf; # arm
+    __floatdisf; # arm
+    __floatsidf; # arm
+    __floatsisf; # arm
+    __floatundidf; # arm
+    __floatundisf; # arm
+    __floatunsidf; # arm
+    __floatunsisf; # arm
+    __futex_wait; # arm x86 mips nobrillo
+    __futex_wake; # arm x86 mips nobrillo
+    __gedf2; # arm
+    __get_thread; # arm x86 mips nobrillo
+    __get_tls; # arm x86 mips nobrillo
+    __getdents64; # arm x86 mips
+    __gnu_ldivmod_helper; # arm
+    __gnu_uldivmod_helper; # arm
     __gnu_Unwind_Backtrace; # arm
     __gnu_unwind_execute; # arm
     __gnu_Unwind_Find_exidx; # arm
@@ -1428,6 +1413,47 @@
     __gnu_Unwind_Save_VFP_D_16_to_31; # arm
     __gnu_Unwind_Save_WMMXC; # arm
     __gnu_Unwind_Save_WMMXD; # arm
+    __gtdf2; # arm
+    __ledf2; # arm
+    __lshrdi3; # arm
+    __ltdf2; # arm
+    __muldf3; # arm
+    __muldi3; # arm
+    __mulsf3; # arm
+    __nedf2; # arm
+    __open; # arm x86 mips nobrillo
+    __page_shift; # arm x86 mips nobrillo
+    __page_size; # arm x86 mips nobrillo
+    __popcount_tab; # arm
+    __popcountsi2; # arm x86 mips
+    __pthread_gettid; # arm x86 mips nobrillo
+    __restore_core_regs; # arm
+    __sclose; # arm x86 mips
+    __sdidinit; # arm x86 mips nobrillo
+    __set_errno; # arm x86 mips nobrillo
+    __sflags; # arm x86 mips
+    __sflush; # arm x86 mips
+    __sfp; # arm x86 mips
+    __sglue; # arm x86 mips
+    __sinit; # arm x86 mips nobrillo
+    __smakebuf; # arm x86 mips
+    __sread; # arm x86 mips
+    __srefill; # arm x86 mips
+    __srget; # arm x86 mips
+    __sseek; # arm x86 mips
+    __subdf3; # arm
+    __subsf3; # arm
+    __swbuf; # arm x86 mips
+    __swrite; # arm x86 mips
+    __swsetup; # arm x86 mips
+    __truncdfsf2; # arm
+    __udivdi3; # arm x86 mips
+    __udivsi3; # arm
+    __umoddi3; # x86 mips
+    __unorddf2; # arm
+    __unordsf2; # arm
+    __wait4; # arm x86 mips nobrillo
+    _fwalk; # arm x86 mips
     _Unwind_Backtrace; # arm
     _Unwind_Complete; # arm
     _Unwind_DeleteException; # arm
@@ -1443,14 +1469,55 @@
     _Unwind_VRS_Get; # arm
     _Unwind_VRS_Pop; # arm
     _Unwind_VRS_Set; # arm
+    android_getaddrinfofornet;
+    android_getaddrinfofornetcontext;
+    android_gethostbyaddrfornet;
+    android_gethostbynamefornet;
+    arc4random_addrandom; # arm x86 mips nobrillo
+    arc4random_stir; # arm x86 mips nobrillo
     atexit; # arm
-    dlmalloc; # arm x86 mips
-    dlmalloc_inspect_all;
-    dlmalloc_trim;
-    dlmalloc_usable_size; # arm x86 mips
+    bcopy; # arm x86 mips nobrillo
+    bzero; # arm x86 mips nobrillo
+    bsd_signal; # arm x86 mips nobrillo
+    dlmalloc; # arm x86 mips nobrillo
+    dlmalloc_inspect_all; # arm x86 mips nobrillo
+    dlmalloc_trim; # arm x86 mips nobrillo
+    dlmalloc_usable_size; # arm x86 mips nobrillo
+    endpwent; # arm x86 mips nobrillo
+    fdprintf; # arm x86 mips nobrillo
+    free_malloc_leak_info;
+    ftime; # arm x86 mips nobrillo
+    get_malloc_leak_info;
+    getdents; # arm x86 mips nobrillo
+    getdtablesize; # arm x86 mips nobrillo
     gMallocLeakZygoteChild;
+    index; # arm x86 mips nobrillo
+    issetugid; # arm x86 mips nobrillo
+    memswap; # arm x86 mips nobrillo
+    pthread_attr_getstackaddr; # arm x86 mips nobrillo
+    pthread_attr_setstackaddr; # arm x86 mips nobrillo
+    restore_core_regs; # arm
     SHA1Final; # arm x86 mips
     SHA1Init; # arm x86 mips
     SHA1Transform; # arm x86 mips
     SHA1Update; # arm x86 mips
-} LIBC;
+    strntoimax; # arm x86 mips nobrillo
+    strntoumax; # arm x86 mips nobrillo
+    strtotimeval; # arm x86 mips nobrillo
+    sysv_signal; # arm x86 mips nobrillo
+    tkill; # arm x86 mips nobrillo
+    vfdprintf; # arm x86 mips nobrillo
+    wait3; # arm x86 mips nobrillo
+    wcswcs; # arm x86 mips nobrillo
+} LIBC_N;
+
+LIBC_PLATFORM {
+  global:
+    android_net_res_stats_get_info_for_net;
+    android_net_res_stats_aggregate;
+    android_net_res_stats_get_usable_servers;
+    malloc_backtrace;
+    malloc_disable;
+    malloc_enable;
+    malloc_iterate;
+} LIBC_N;
diff --git a/libc/libc.map b/libc/libc.mips.brillo.map
similarity index 76%
copy from libc/libc.map
copy to libc/libc.mips.brillo.map
index 47c52a4..d11a5ab 100644
--- a/libc/libc.map
+++ b/libc/libc.mips.brillo.map
@@ -1,33 +1,23 @@
+# Generated by genversionscripts.py. Do not edit.
 LIBC {
   global:
     __assert;
     __assert2;
-    __atomic_cmpxchg; # arm
-    __atomic_dec; # arm
-    __atomic_inc; # arm
-    __atomic_swap; # arm
     __b64_ntop;
     __b64_pton;
     __brk; # arm x86 mips
-    __cmpdf2; # arm
     __cmsg_nxthdr;
     __connect; # arm x86 mips
     __ctype_get_mb_cur_max;
     __cxa_atexit;
     __cxa_finalize;
     __cxa_thread_atexit_impl;
-    __divdf3; # arm
-    __divdi3; # arm x86 mips
-    __divsf3; # arm
-    __divsi3; # arm
     __dn_comp;
     __dn_count_labels;
     __dn_skipname;
     __epoll_pwait; # arm x86 mips
-    __eqdf2; # arm
     __errno;
     __exit; # arm x86 mips
-    __extendsfdf2; # arm
     __fadvise64; # x86 mips
     __fbufsize;
     __fcntl64; # arm x86 mips
@@ -35,18 +25,7 @@
     __FD_ISSET_chk;
     __FD_SET_chk;
     __fgets_chk;
-    __fixdfsi; # arm
-    __fixsfsi; # arm
-    __fixunssfsi; # arm
     __flbf;
-    __floatdidf; # arm
-    __floatdisf; # arm
-    __floatsidf; # arm
-    __floatsisf; # arm
-    __floatundidf; # arm
-    __floatundisf; # arm
-    __floatunsidf; # arm
-    __floatunsisf; # arm
     __fp_nquery;
     __fp_query;
     __fpclassify;
@@ -58,23 +37,14 @@
     __freadable;
     __fsetlocking;
     __fstatfs64; # arm x86 mips
-    __futex_wait; # arm x86 mips
-    __futex_wake; # arm x86 mips
     __fwritable;
-    __gedf2; # arm
     __get_h_errno;
-    __get_thread; # arm x86 mips
-    __get_tls; # arm x86 mips
     __getcpu; # arm x86 mips
     __getcwd; # arm x86 mips
-    __getdents64; # arm x86 mips
     __getpid; # arm x86 mips
     __getpriority; # arm x86 mips
     __gnu_basename;
-    __gnu_ldivmod_helper; # arm
     __gnu_strerror_r;
-    __gnu_uldivmod_helper; # arm
-    __gtdf2; # arm
     __hostalias;
     __ioctl; # arm x86 mips
     __isfinite;
@@ -89,27 +59,19 @@
     __isnormal;
     __isnormalf;
     __isnormall;
-    __isthreaded;
-    __ledf2; # arm
+    __isthreaded; # arm x86 mips
     __libc_current_sigrtmax;
     __libc_current_sigrtmin;
     __libc_init;
     __llseek; # arm x86 mips
     __loc_aton;
     __loc_ntoa;
-    __lshrdi3; # arm
-    __ltdf2; # arm
     __memchr_chk;
     __memcpy_chk;
     __memmove_chk;
     __memrchr_chk;
     __memset_chk;
     __mmap2; # arm x86 mips
-    __moddi3; # x86 mips
-    __muldf3; # arm
-    __muldi3; # arm
-    __mulsf3; # arm
-    __nedf2; # arm
     __ns_format_ttl; # arm x86 mips
     __ns_get16; # arm x86 mips
     __ns_get32; # arm x86 mips
@@ -132,7 +94,6 @@
     __ns_skiprr; # arm x86 mips
     __ns_sprintrr; # arm x86 mips
     __ns_sprintrrf; # arm x86 mips
-    __open; # arm x86 mips
     __open_2;
     __openat; # arm x86 mips
     __openat_2;
@@ -149,11 +110,7 @@
     __p_time;
     __p_type;
     __p_type_syms;
-    __page_shift; # arm x86 mips
-    __page_size; # arm x86 mips
     __poll_chk;
-    __popcount_tab; # arm
-    __popcountsi2; # arm x86 mips
     __ppoll; # arm x86 mips
     __ppoll_chk;
     __pread64_chk;
@@ -162,7 +119,6 @@
     __pselect6; # arm x86 mips
     __pthread_cleanup_pop;
     __pthread_cleanup_push;
-    __pthread_gettid; # arm x86 mips
     __ptrace; # arm x86 mips
     __putlong;
     __putshort;
@@ -192,7 +148,6 @@
     __res_send;
     __res_send_setqhook;
     __res_send_setrhook;
-    __restore_core_regs; # arm
     __rt_sigaction; # arm x86 mips
     __rt_sigpending; # arm x86 mips
     __rt_sigprocmask; # arm x86 mips
@@ -202,28 +157,13 @@
     __sched_cpucount;
     __sched_cpufree;
     __sched_getaffinity; # arm x86 mips
-    __sclose; # arm x86 mips
-    __sdidinit; # arm x86 mips
-    __set_errno; # arm x86 mips
-    __set_thread_area; # x86
     __set_tid_address; # arm x86 mips
     __set_tls; # arm mips
     __sF;
-    __sflags; # arm x86 mips
-    __sflush; # arm x86 mips
-    __sfp; # arm x86 mips
-    __sglue; # arm x86 mips
     __sigaction; # arm x86 mips
-    __signalfd4; # arm x86 mips
-    __sinit; # arm x86 mips
-    __smakebuf; # arm x86 mips
     __snprintf_chk;
     __socket; # arm x86 mips
     __sprintf_chk;
-    __sread; # arm x86 mips
-    __srefill; # arm x86 mips
-    __srget; # arm x86 mips
-    __sseek; # arm x86 mips
     __stack_chk_fail;
     __stack_chk_guard;
     __statfs64; # arm x86 mips
@@ -240,11 +180,6 @@
     __strncpy_chk;
     __strncpy_chk2;
     __strrchr_chk;
-    __subdf3; # arm
-    __subsf3; # arm
-    __swbuf; # arm x86 mips
-    __swrite; # arm x86 mips
-    __swsetup; # arm x86 mips
     __sym_ntop;
     __sym_ntos;
     __sym_ston;
@@ -268,23 +203,15 @@
     __timer_getoverrun; # arm x86 mips
     __timer_gettime; # arm x86 mips
     __timer_settime; # arm x86 mips
-    __truncdfsf2; # arm
-    __udivdi3; # arm x86 mips
-    __udivsi3; # arm
     __umask_chk;
-    __umoddi3; # x86 mips
-    __unorddf2; # arm
-    __unordsf2; # arm
     __vsnprintf_chk;
     __vsprintf_chk;
-    __wait4; # arm x86 mips
     __waitid; # arm x86 mips
     _ctype_;
     _Exit;
     _exit;
     _flush_cache; # mips
     _flushlbf;
-    _fwalk; # arm x86 mips
     _getlong;
     _getshort;
     _longjmp;
@@ -305,15 +232,9 @@
     alarm;
     alphasort;
     alphasort64;
-    android_getaddrinfofornet;
-    android_getaddrinfofornetcontext;
-    android_gethostbyaddrfornet;
-    android_gethostbynamefornet;
     android_set_abort_message;
     arc4random;
-    arc4random_addrandom; # arm x86 mips
     arc4random_buf;
-    arc4random_stir; # arm x86 mips
     arc4random_uniform;
     asctime;
     asctime64; # arm x86 mips
@@ -327,14 +248,11 @@
     atoll;
     basename;
     basename_r; # arm x86 mips
-    bcopy; # arm x86 mips
     bind;
     bindresvport;
     brk;
-    bsd_signal; # arm x86 mips
     bsearch;
     btowc;
-    bzero; # arm x86 mips
     c16rtomb;
     c32rtomb;
     cacheflush; # arm mips
@@ -387,9 +305,7 @@
     dup3;
     duplocale;
     endmntent;
-    endpwent;
     endservent;
-    endusershell;
     endutent;
     environ;
     epoll_create;
@@ -421,8 +337,6 @@
     execvpe;
     exit;
     faccessat;
-    fake_gmtime_r; # arm x86 mips
-    fake_localtime_r; # arm x86 mips
     fallocate;
     fallocate64;
     fchdir;
@@ -435,7 +349,6 @@
     fdatasync;
     fdopen;
     fdopendir;
-    fdprintf; # arm x86 mips
     feof;
     feof_unlocked;
     ferror;
@@ -467,7 +380,6 @@
     fputws;
     fread;
     free;
-    free_malloc_leak_info;
     freeaddrinfo;
     freelocale;
     fremovexattr;
@@ -488,7 +400,6 @@
     fsync;
     ftell;
     ftello;
-    ftime; # arm x86 mips
     ftok;
     ftruncate;
     ftruncate64;
@@ -509,7 +420,6 @@
     fwscanf;
     gai_strerror;
     get_avphys_pages;
-    get_malloc_leak_info;
     get_nprocs;
     get_nprocs_conf;
     get_phys_pages;
@@ -521,8 +431,6 @@
     getchar_unlocked;
     getcwd;
     getdelim;
-    getdents; # arm x86 mips
-    getdtablesize; # arm x86 mips
     getegid;
     getenv;
     geteuid;
@@ -580,7 +488,6 @@
     gettid;
     gettimeofday;
     getuid;
-    getusershell;
     getutent;
     getwc;
     getwchar;
@@ -598,7 +505,6 @@
     if_nametoindex;
     imaxabs;
     imaxdiv;
-    index; # arm x86 mips
     inet_addr;
     inet_aton;
     inet_lnaof;
@@ -651,7 +557,6 @@
     isprint_l;
     ispunct;
     ispunct_l;
-    issetugid; # arm x86 mips
     isspace;
     isspace_l;
     isupper;
@@ -741,7 +646,6 @@
     mempcpy;
     memrchr;
     memset;
-    memswap; # arm x86 mips
     mincore;
     mkdir;
     mkdirat;
@@ -761,7 +665,6 @@
     mktemp;
     mktime;
     mktime64; # arm x86 mips
-    mktime_tz;
     mlock;
     mlockall;
     mmap;
@@ -780,28 +683,6 @@
     nftw64;
     nice;
     nrand48;
-    ns_format_ttl; # arm64 x86_64 mips64
-    ns_get16; # arm64 x86_64 mips64
-    ns_get32; # arm64 x86_64 mips64
-    ns_initparse; # arm64 x86_64 mips64
-    ns_makecanon; # arm64 x86_64 mips64
-    ns_msg_getflag; # arm64 x86_64 mips64
-    ns_name_compress; # arm64 x86_64 mips64
-    ns_name_ntol; # arm64 x86_64 mips64
-    ns_name_ntop; # arm64 x86_64 mips64
-    ns_name_pack; # arm64 x86_64 mips64
-    ns_name_pton; # arm64 x86_64 mips64
-    ns_name_rollback; # arm64 x86_64 mips64
-    ns_name_skip; # arm64 x86_64 mips64
-    ns_name_uncompress; # arm64 x86_64 mips64
-    ns_name_unpack; # arm64 x86_64 mips64
-    ns_parserr; # arm64 x86_64 mips64
-    ns_put16; # arm64 x86_64 mips64
-    ns_put32; # arm64 x86_64 mips64
-    ns_samename; # arm64 x86_64 mips64
-    ns_skiprr; # arm64 x86_64 mips64
-    ns_sprintrr; # arm64 x86_64 mips64
-    ns_sprintrrf; # arm64 x86_64 mips64
     nsdispatch;
     ntohl;
     ntohs;
@@ -840,7 +721,6 @@
     pread;
     pread64;
     printf;
-    prlimit; # arm64 x86_64 mips64
     prlimit64;
     process_vm_readv;
     process_vm_writev;
@@ -855,7 +735,6 @@
     pthread_attr_getschedpolicy;
     pthread_attr_getscope;
     pthread_attr_getstack;
-    pthread_attr_getstackaddr; # arm x86 mips
     pthread_attr_getstacksize;
     pthread_attr_init;
     pthread_attr_setdetachstate;
@@ -864,7 +743,6 @@
     pthread_attr_setschedpolicy;
     pthread_attr_setscope;
     pthread_attr_setstack;
-    pthread_attr_setstackaddr; # arm x86 mips
     pthread_attr_setstacksize;
     pthread_cond_broadcast;
     pthread_cond_destroy;
@@ -980,7 +858,6 @@
     res_mkquery;
     res_query;
     res_search;
-    restore_core_regs; # arm
     rewind;
     rewinddir;
     rmdir;
@@ -1051,7 +928,6 @@
     setstate;
     settimeofday;
     setuid;
-    setusershell;
     setutent;
     setvbuf;
     setxattr;
@@ -1124,8 +1000,6 @@
     strncpy;
     strndup;
     strnlen;
-    strntoimax; # arm x86 mips
-    strntoumax; # arm x86 mips
     strpbrk;
     strptime;
     strrchr;
@@ -1144,7 +1018,6 @@
     strtoll;
     strtoll_l;
     strtoq;
-    strtotimeval; # arm x86 mips
     strtoul;
     strtoull;
     strtoull_l;
@@ -1166,7 +1039,6 @@
     sysinfo;
     syslog;
     system;
-    sysv_signal; # arm x86 mips
     tcdrain;
     tcflow;
     tcflush;
@@ -1198,7 +1070,6 @@
     timerfd_settime;
     times;
     timezone;
-    tkill; # arm x86 mips
     tmpfile;
     tmpnam;
     toascii;
@@ -1240,7 +1111,6 @@
     vdprintf;
     verr;
     verrx;
-    vfdprintf; # arm x86 mips
     vfork;
     vfprintf;
     vfscanf;
@@ -1260,7 +1130,6 @@
     vwprintf;
     vwscanf;
     wait;
-    wait3; # arm x86 mips
     wait4;
     waitid;
     waitpid;
@@ -1309,7 +1178,6 @@
     wcstoull;
     wcstoull_l;
     wcstoumax;
-    wcswcs; # arm x86 mips
     wcswidth;
     wcsxfrm;
     wcsxfrm_l;
@@ -1332,125 +1200,100 @@
     *;
 };
 
+LIBC_N {
+  global:
+    __fread_chk;
+    __fwrite_chk;
+    __getcwd_chk;
+    __pwrite_chk;
+    __pwrite64_chk;
+    __write_chk;
+    adjtimex;
+    clock_adjtime;
+    fgetpos64;
+    fileno_unlocked;
+    fopen64;
+    freeifaddrs;
+    freopen64;
+    fseeko64;
+    fsetpos64;
+    ftello64;
+    funopen64;
+    getgrgid_r;
+    getgrnam_r;
+    getifaddrs;
+    if_freenameindex;
+    if_nameindex;
+    in6addr_any;
+    in6addr_loopback;
+    lockf;
+    lockf64;
+    preadv;
+    preadv64;
+    prlimit; # arm mips x86
+    pthread_barrierattr_destroy;
+    pthread_barrierattr_getpshared;
+    pthread_barrierattr_init;
+    pthread_barrierattr_setpshared;
+    pthread_barrier_destroy;
+    pthread_barrier_init;
+    pthread_barrier_wait;
+    pthread_spin_destroy;
+    pthread_spin_init;
+    pthread_spin_lock;
+    pthread_spin_trylock;
+    pthread_spin_unlock;
+    pwritev;
+    pwritev64;
+    scandirat;
+    scandirat64;
+    strchrnul;
+    tmpfile64;
+} LIBC;
+
 LIBC_PRIVATE {
   global:
-    ___Unwind_Backtrace; # arm
-    ___Unwind_ForcedUnwind; # arm
-    ___Unwind_RaiseException; # arm
-    ___Unwind_Resume; # arm
-    ___Unwind_Resume_or_Rethrow; # arm
     __accept4; # arm x86 mips
-    __adddf3; # arm
-    __addsf3; # arm
-    __aeabi_atexit; # arm
-    __aeabi_cdcmpeq; # arm
-    __aeabi_cdcmple; # arm
-    __aeabi_cdrcmple; # arm
-    __aeabi_d2f; # arm
-    __aeabi_d2iz; # arm
-    __aeabi_dadd; # arm
-    __aeabi_dcmpeq; # arm
-    __aeabi_dcmpge; # arm
-    __aeabi_dcmpgt; # arm
-    __aeabi_dcmple; # arm
-    __aeabi_dcmplt; # arm
-    __aeabi_dcmpun; # arm
-    __aeabi_ddiv; # arm
-    __aeabi_dmul; # arm
-    __aeabi_drsub; # arm
-    __aeabi_dsub; # arm
-    __aeabi_f2d; # arm
-    __aeabi_f2iz; # arm
-    __aeabi_f2uiz; # arm
-    __aeabi_fadd; # arm
-    __aeabi_fcmpun; # arm
-    __aeabi_fdiv; # arm
-    __aeabi_fmul; # arm
-    __aeabi_frsub; # arm
-    __aeabi_fsub; # arm
-    __aeabi_i2d; # arm
-    __aeabi_i2f; # arm
-    __aeabi_idiv; # arm
-    __aeabi_idiv0; # arm
-    __aeabi_idivmod; # arm
-    __aeabi_l2d; # arm
-    __aeabi_l2f; # arm
-    __aeabi_lasr; # arm
-    __aeabi_ldiv0; # arm
-    __aeabi_ldivmod; # arm
-    __aeabi_llsl; # arm
-    __aeabi_llsr; # arm
-    __aeabi_lmul; # arm
-    __aeabi_memclr; # arm
-    __aeabi_memclr4; # arm
-    __aeabi_memclr8; # arm
-    __aeabi_memcpy; # arm
-    __aeabi_memcpy4; # arm
-    __aeabi_memcpy8; # arm
-    __aeabi_memmove; # arm
-    __aeabi_memmove4; # arm
-    __aeabi_memmove8; # arm
-    __aeabi_memset; # arm
-    __aeabi_memset4; # arm
-    __aeabi_memset8; # arm
-    __aeabi_ui2d; # arm
-    __aeabi_ui2f; # arm
-    __aeabi_uidiv; # arm
-    __aeabi_uidivmod; # arm
-    __aeabi_ul2d; # arm
-    __aeabi_ul2f; # arm
-    __aeabi_uldivmod; # arm
-    __aeabi_unwind_cpp_pr0; # arm
-    __aeabi_unwind_cpp_pr1; # arm
-    __aeabi_unwind_cpp_pr2; # arm
-    __arm_fadvise64_64; # arm
-    __ashldi3; # arm
-    __ashrdi3; # arm
     __bionic_brk; # arm x86 mips
-    __bionic_libgcc_compat_symbols; # arm x86
-    __bionic_libgcc_unwind_symbols; # arm
-    __dso_handle; # arm
-    __gnu_Unwind_Backtrace; # arm
-    __gnu_unwind_execute; # arm
-    __gnu_Unwind_Find_exidx; # arm
-    __gnu_Unwind_ForcedUnwind; # arm
-    __gnu_unwind_frame; # arm
-    __gnu_Unwind_RaiseException; # arm
-    __gnu_Unwind_Restore_VFP; # arm
-    __gnu_Unwind_Restore_VFP_D; # arm
-    __gnu_Unwind_Restore_VFP_D_16_to_31; # arm
-    __gnu_Unwind_Restore_WMMXC; # arm
-    __gnu_Unwind_Restore_WMMXD; # arm
-    __gnu_Unwind_Resume; # arm
-    __gnu_Unwind_Resume_or_Rethrow; # arm
-    __gnu_Unwind_Save_VFP; # arm
-    __gnu_Unwind_Save_VFP_D; # arm
-    __gnu_Unwind_Save_VFP_D_16_to_31; # arm
-    __gnu_Unwind_Save_WMMXC; # arm
-    __gnu_Unwind_Save_WMMXD; # arm
-    _Unwind_Backtrace; # arm
-    _Unwind_Complete; # arm
-    _Unwind_DeleteException; # arm
-    _Unwind_ForcedUnwind; # arm
-    _Unwind_GetCFA; # arm
-    _Unwind_GetDataRelBase; # arm
-    _Unwind_GetLanguageSpecificData; # arm
-    _Unwind_GetRegionStart; # arm
-    _Unwind_GetTextRelBase; # arm
-    _Unwind_RaiseException; # arm
-    _Unwind_Resume; # arm
-    _Unwind_Resume_or_Rethrow; # arm
-    _Unwind_VRS_Get; # arm
-    _Unwind_VRS_Pop; # arm
-    _Unwind_VRS_Set; # arm
-    atexit; # arm
-    dlmalloc; # arm x86 mips
-    dlmalloc_inspect_all;
-    dlmalloc_trim;
-    dlmalloc_usable_size; # arm x86 mips
+    __divdi3; # arm x86 mips
+    __getdents64; # arm x86 mips
+    __popcountsi2; # arm x86 mips
+    __sclose; # arm x86 mips
+    __sflags; # arm x86 mips
+    __sflush; # arm x86 mips
+    __sfp; # arm x86 mips
+    __sglue; # arm x86 mips
+    __smakebuf; # arm x86 mips
+    __sread; # arm x86 mips
+    __srefill; # arm x86 mips
+    __srget; # arm x86 mips
+    __sseek; # arm x86 mips
+    __swbuf; # arm x86 mips
+    __swrite; # arm x86 mips
+    __swsetup; # arm x86 mips
+    __udivdi3; # arm x86 mips
+    __umoddi3; # x86 mips
+    _fwalk; # arm x86 mips
+    android_getaddrinfofornet;
+    android_getaddrinfofornetcontext;
+    android_gethostbyaddrfornet;
+    android_gethostbynamefornet;
+    free_malloc_leak_info;
+    get_malloc_leak_info;
     gMallocLeakZygoteChild;
     SHA1Final; # arm x86 mips
     SHA1Init; # arm x86 mips
     SHA1Transform; # arm x86 mips
     SHA1Update; # arm x86 mips
-} LIBC;
+} LIBC_N;
+
+LIBC_PLATFORM {
+  global:
+    android_net_res_stats_get_info_for_net;
+    android_net_res_stats_aggregate;
+    android_net_res_stats_get_usable_servers;
+    malloc_backtrace;
+    malloc_disable;
+    malloc_enable;
+    malloc_iterate;
+} LIBC_N;
diff --git a/libc/libc.map b/libc/libc.mips.map
similarity index 76%
copy from libc/libc.map
copy to libc/libc.mips.map
index 47c52a4..46c835b 100644
--- a/libc/libc.map
+++ b/libc/libc.mips.map
@@ -1,33 +1,23 @@
+# Generated by genversionscripts.py. Do not edit.
 LIBC {
   global:
     __assert;
     __assert2;
-    __atomic_cmpxchg; # arm
-    __atomic_dec; # arm
-    __atomic_inc; # arm
-    __atomic_swap; # arm
     __b64_ntop;
     __b64_pton;
     __brk; # arm x86 mips
-    __cmpdf2; # arm
     __cmsg_nxthdr;
     __connect; # arm x86 mips
     __ctype_get_mb_cur_max;
     __cxa_atexit;
     __cxa_finalize;
     __cxa_thread_atexit_impl;
-    __divdf3; # arm
-    __divdi3; # arm x86 mips
-    __divsf3; # arm
-    __divsi3; # arm
     __dn_comp;
     __dn_count_labels;
     __dn_skipname;
     __epoll_pwait; # arm x86 mips
-    __eqdf2; # arm
     __errno;
     __exit; # arm x86 mips
-    __extendsfdf2; # arm
     __fadvise64; # x86 mips
     __fbufsize;
     __fcntl64; # arm x86 mips
@@ -35,18 +25,7 @@
     __FD_ISSET_chk;
     __FD_SET_chk;
     __fgets_chk;
-    __fixdfsi; # arm
-    __fixsfsi; # arm
-    __fixunssfsi; # arm
     __flbf;
-    __floatdidf; # arm
-    __floatdisf; # arm
-    __floatsidf; # arm
-    __floatsisf; # arm
-    __floatundidf; # arm
-    __floatundisf; # arm
-    __floatunsidf; # arm
-    __floatunsisf; # arm
     __fp_nquery;
     __fp_query;
     __fpclassify;
@@ -58,23 +37,14 @@
     __freadable;
     __fsetlocking;
     __fstatfs64; # arm x86 mips
-    __futex_wait; # arm x86 mips
-    __futex_wake; # arm x86 mips
     __fwritable;
-    __gedf2; # arm
     __get_h_errno;
-    __get_thread; # arm x86 mips
-    __get_tls; # arm x86 mips
     __getcpu; # arm x86 mips
     __getcwd; # arm x86 mips
-    __getdents64; # arm x86 mips
     __getpid; # arm x86 mips
     __getpriority; # arm x86 mips
     __gnu_basename;
-    __gnu_ldivmod_helper; # arm
     __gnu_strerror_r;
-    __gnu_uldivmod_helper; # arm
-    __gtdf2; # arm
     __hostalias;
     __ioctl; # arm x86 mips
     __isfinite;
@@ -89,27 +59,19 @@
     __isnormal;
     __isnormalf;
     __isnormall;
-    __isthreaded;
-    __ledf2; # arm
+    __isthreaded; # arm x86 mips
     __libc_current_sigrtmax;
     __libc_current_sigrtmin;
     __libc_init;
     __llseek; # arm x86 mips
     __loc_aton;
     __loc_ntoa;
-    __lshrdi3; # arm
-    __ltdf2; # arm
     __memchr_chk;
     __memcpy_chk;
     __memmove_chk;
     __memrchr_chk;
     __memset_chk;
     __mmap2; # arm x86 mips
-    __moddi3; # x86 mips
-    __muldf3; # arm
-    __muldi3; # arm
-    __mulsf3; # arm
-    __nedf2; # arm
     __ns_format_ttl; # arm x86 mips
     __ns_get16; # arm x86 mips
     __ns_get32; # arm x86 mips
@@ -132,7 +94,6 @@
     __ns_skiprr; # arm x86 mips
     __ns_sprintrr; # arm x86 mips
     __ns_sprintrrf; # arm x86 mips
-    __open; # arm x86 mips
     __open_2;
     __openat; # arm x86 mips
     __openat_2;
@@ -149,11 +110,7 @@
     __p_time;
     __p_type;
     __p_type_syms;
-    __page_shift; # arm x86 mips
-    __page_size; # arm x86 mips
     __poll_chk;
-    __popcount_tab; # arm
-    __popcountsi2; # arm x86 mips
     __ppoll; # arm x86 mips
     __ppoll_chk;
     __pread64_chk;
@@ -162,7 +119,6 @@
     __pselect6; # arm x86 mips
     __pthread_cleanup_pop;
     __pthread_cleanup_push;
-    __pthread_gettid; # arm x86 mips
     __ptrace; # arm x86 mips
     __putlong;
     __putshort;
@@ -192,7 +148,6 @@
     __res_send;
     __res_send_setqhook;
     __res_send_setrhook;
-    __restore_core_regs; # arm
     __rt_sigaction; # arm x86 mips
     __rt_sigpending; # arm x86 mips
     __rt_sigprocmask; # arm x86 mips
@@ -202,28 +157,13 @@
     __sched_cpucount;
     __sched_cpufree;
     __sched_getaffinity; # arm x86 mips
-    __sclose; # arm x86 mips
-    __sdidinit; # arm x86 mips
-    __set_errno; # arm x86 mips
-    __set_thread_area; # x86
     __set_tid_address; # arm x86 mips
     __set_tls; # arm mips
     __sF;
-    __sflags; # arm x86 mips
-    __sflush; # arm x86 mips
-    __sfp; # arm x86 mips
-    __sglue; # arm x86 mips
     __sigaction; # arm x86 mips
-    __signalfd4; # arm x86 mips
-    __sinit; # arm x86 mips
-    __smakebuf; # arm x86 mips
     __snprintf_chk;
     __socket; # arm x86 mips
     __sprintf_chk;
-    __sread; # arm x86 mips
-    __srefill; # arm x86 mips
-    __srget; # arm x86 mips
-    __sseek; # arm x86 mips
     __stack_chk_fail;
     __stack_chk_guard;
     __statfs64; # arm x86 mips
@@ -240,11 +180,6 @@
     __strncpy_chk;
     __strncpy_chk2;
     __strrchr_chk;
-    __subdf3; # arm
-    __subsf3; # arm
-    __swbuf; # arm x86 mips
-    __swrite; # arm x86 mips
-    __swsetup; # arm x86 mips
     __sym_ntop;
     __sym_ntos;
     __sym_ston;
@@ -268,23 +203,15 @@
     __timer_getoverrun; # arm x86 mips
     __timer_gettime; # arm x86 mips
     __timer_settime; # arm x86 mips
-    __truncdfsf2; # arm
-    __udivdi3; # arm x86 mips
-    __udivsi3; # arm
     __umask_chk;
-    __umoddi3; # x86 mips
-    __unorddf2; # arm
-    __unordsf2; # arm
     __vsnprintf_chk;
     __vsprintf_chk;
-    __wait4; # arm x86 mips
     __waitid; # arm x86 mips
     _ctype_;
     _Exit;
     _exit;
     _flush_cache; # mips
     _flushlbf;
-    _fwalk; # arm x86 mips
     _getlong;
     _getshort;
     _longjmp;
@@ -305,15 +232,9 @@
     alarm;
     alphasort;
     alphasort64;
-    android_getaddrinfofornet;
-    android_getaddrinfofornetcontext;
-    android_gethostbyaddrfornet;
-    android_gethostbynamefornet;
     android_set_abort_message;
     arc4random;
-    arc4random_addrandom; # arm x86 mips
     arc4random_buf;
-    arc4random_stir; # arm x86 mips
     arc4random_uniform;
     asctime;
     asctime64; # arm x86 mips
@@ -327,14 +248,11 @@
     atoll;
     basename;
     basename_r; # arm x86 mips
-    bcopy; # arm x86 mips
     bind;
     bindresvport;
     brk;
-    bsd_signal; # arm x86 mips
     bsearch;
     btowc;
-    bzero; # arm x86 mips
     c16rtomb;
     c32rtomb;
     cacheflush; # arm mips
@@ -387,9 +305,7 @@
     dup3;
     duplocale;
     endmntent;
-    endpwent;
     endservent;
-    endusershell;
     endutent;
     environ;
     epoll_create;
@@ -421,8 +337,6 @@
     execvpe;
     exit;
     faccessat;
-    fake_gmtime_r; # arm x86 mips
-    fake_localtime_r; # arm x86 mips
     fallocate;
     fallocate64;
     fchdir;
@@ -435,7 +349,6 @@
     fdatasync;
     fdopen;
     fdopendir;
-    fdprintf; # arm x86 mips
     feof;
     feof_unlocked;
     ferror;
@@ -467,7 +380,6 @@
     fputws;
     fread;
     free;
-    free_malloc_leak_info;
     freeaddrinfo;
     freelocale;
     fremovexattr;
@@ -488,7 +400,6 @@
     fsync;
     ftell;
     ftello;
-    ftime; # arm x86 mips
     ftok;
     ftruncate;
     ftruncate64;
@@ -509,7 +420,6 @@
     fwscanf;
     gai_strerror;
     get_avphys_pages;
-    get_malloc_leak_info;
     get_nprocs;
     get_nprocs_conf;
     get_phys_pages;
@@ -521,8 +431,6 @@
     getchar_unlocked;
     getcwd;
     getdelim;
-    getdents; # arm x86 mips
-    getdtablesize; # arm x86 mips
     getegid;
     getenv;
     geteuid;
@@ -580,7 +488,6 @@
     gettid;
     gettimeofday;
     getuid;
-    getusershell;
     getutent;
     getwc;
     getwchar;
@@ -598,7 +505,6 @@
     if_nametoindex;
     imaxabs;
     imaxdiv;
-    index; # arm x86 mips
     inet_addr;
     inet_aton;
     inet_lnaof;
@@ -651,7 +557,6 @@
     isprint_l;
     ispunct;
     ispunct_l;
-    issetugid; # arm x86 mips
     isspace;
     isspace_l;
     isupper;
@@ -741,7 +646,6 @@
     mempcpy;
     memrchr;
     memset;
-    memswap; # arm x86 mips
     mincore;
     mkdir;
     mkdirat;
@@ -761,7 +665,6 @@
     mktemp;
     mktime;
     mktime64; # arm x86 mips
-    mktime_tz;
     mlock;
     mlockall;
     mmap;
@@ -780,28 +683,6 @@
     nftw64;
     nice;
     nrand48;
-    ns_format_ttl; # arm64 x86_64 mips64
-    ns_get16; # arm64 x86_64 mips64
-    ns_get32; # arm64 x86_64 mips64
-    ns_initparse; # arm64 x86_64 mips64
-    ns_makecanon; # arm64 x86_64 mips64
-    ns_msg_getflag; # arm64 x86_64 mips64
-    ns_name_compress; # arm64 x86_64 mips64
-    ns_name_ntol; # arm64 x86_64 mips64
-    ns_name_ntop; # arm64 x86_64 mips64
-    ns_name_pack; # arm64 x86_64 mips64
-    ns_name_pton; # arm64 x86_64 mips64
-    ns_name_rollback; # arm64 x86_64 mips64
-    ns_name_skip; # arm64 x86_64 mips64
-    ns_name_uncompress; # arm64 x86_64 mips64
-    ns_name_unpack; # arm64 x86_64 mips64
-    ns_parserr; # arm64 x86_64 mips64
-    ns_put16; # arm64 x86_64 mips64
-    ns_put32; # arm64 x86_64 mips64
-    ns_samename; # arm64 x86_64 mips64
-    ns_skiprr; # arm64 x86_64 mips64
-    ns_sprintrr; # arm64 x86_64 mips64
-    ns_sprintrrf; # arm64 x86_64 mips64
     nsdispatch;
     ntohl;
     ntohs;
@@ -840,7 +721,6 @@
     pread;
     pread64;
     printf;
-    prlimit; # arm64 x86_64 mips64
     prlimit64;
     process_vm_readv;
     process_vm_writev;
@@ -855,7 +735,6 @@
     pthread_attr_getschedpolicy;
     pthread_attr_getscope;
     pthread_attr_getstack;
-    pthread_attr_getstackaddr; # arm x86 mips
     pthread_attr_getstacksize;
     pthread_attr_init;
     pthread_attr_setdetachstate;
@@ -864,7 +743,6 @@
     pthread_attr_setschedpolicy;
     pthread_attr_setscope;
     pthread_attr_setstack;
-    pthread_attr_setstackaddr; # arm x86 mips
     pthread_attr_setstacksize;
     pthread_cond_broadcast;
     pthread_cond_destroy;
@@ -980,7 +858,6 @@
     res_mkquery;
     res_query;
     res_search;
-    restore_core_regs; # arm
     rewind;
     rewinddir;
     rmdir;
@@ -1051,7 +928,6 @@
     setstate;
     settimeofday;
     setuid;
-    setusershell;
     setutent;
     setvbuf;
     setxattr;
@@ -1124,8 +1000,6 @@
     strncpy;
     strndup;
     strnlen;
-    strntoimax; # arm x86 mips
-    strntoumax; # arm x86 mips
     strpbrk;
     strptime;
     strrchr;
@@ -1144,7 +1018,6 @@
     strtoll;
     strtoll_l;
     strtoq;
-    strtotimeval; # arm x86 mips
     strtoul;
     strtoull;
     strtoull_l;
@@ -1166,7 +1039,6 @@
     sysinfo;
     syslog;
     system;
-    sysv_signal; # arm x86 mips
     tcdrain;
     tcflow;
     tcflush;
@@ -1198,7 +1070,6 @@
     timerfd_settime;
     times;
     timezone;
-    tkill; # arm x86 mips
     tmpfile;
     tmpnam;
     toascii;
@@ -1240,7 +1111,6 @@
     vdprintf;
     verr;
     verrx;
-    vfdprintf; # arm x86 mips
     vfork;
     vfprintf;
     vfscanf;
@@ -1260,7 +1130,6 @@
     vwprintf;
     vwscanf;
     wait;
-    wait3; # arm x86 mips
     wait4;
     waitid;
     waitpid;
@@ -1309,7 +1178,6 @@
     wcstoull;
     wcstoull_l;
     wcstoumax;
-    wcswcs; # arm x86 mips
     wcswidth;
     wcsxfrm;
     wcsxfrm_l;
@@ -1332,125 +1200,139 @@
     *;
 };
 
+LIBC_N {
+  global:
+    __fread_chk;
+    __fwrite_chk;
+    __getcwd_chk;
+    __pwrite_chk;
+    __pwrite64_chk;
+    __write_chk;
+    adjtimex;
+    clock_adjtime;
+    fgetpos64;
+    fileno_unlocked;
+    fopen64;
+    freeifaddrs;
+    freopen64;
+    fseeko64;
+    fsetpos64;
+    ftello64;
+    funopen64;
+    getgrgid_r;
+    getgrnam_r;
+    getifaddrs;
+    if_freenameindex;
+    if_nameindex;
+    in6addr_any;
+    in6addr_loopback;
+    lockf;
+    lockf64;
+    preadv;
+    preadv64;
+    prlimit; # arm mips x86
+    pthread_barrierattr_destroy;
+    pthread_barrierattr_getpshared;
+    pthread_barrierattr_init;
+    pthread_barrierattr_setpshared;
+    pthread_barrier_destroy;
+    pthread_barrier_init;
+    pthread_barrier_wait;
+    pthread_spin_destroy;
+    pthread_spin_init;
+    pthread_spin_lock;
+    pthread_spin_trylock;
+    pthread_spin_unlock;
+    pwritev;
+    pwritev64;
+    scandirat;
+    scandirat64;
+    strchrnul;
+    tmpfile64;
+} LIBC;
+
 LIBC_PRIVATE {
   global:
-    ___Unwind_Backtrace; # arm
-    ___Unwind_ForcedUnwind; # arm
-    ___Unwind_RaiseException; # arm
-    ___Unwind_Resume; # arm
-    ___Unwind_Resume_or_Rethrow; # arm
     __accept4; # arm x86 mips
-    __adddf3; # arm
-    __addsf3; # arm
-    __aeabi_atexit; # arm
-    __aeabi_cdcmpeq; # arm
-    __aeabi_cdcmple; # arm
-    __aeabi_cdrcmple; # arm
-    __aeabi_d2f; # arm
-    __aeabi_d2iz; # arm
-    __aeabi_dadd; # arm
-    __aeabi_dcmpeq; # arm
-    __aeabi_dcmpge; # arm
-    __aeabi_dcmpgt; # arm
-    __aeabi_dcmple; # arm
-    __aeabi_dcmplt; # arm
-    __aeabi_dcmpun; # arm
-    __aeabi_ddiv; # arm
-    __aeabi_dmul; # arm
-    __aeabi_drsub; # arm
-    __aeabi_dsub; # arm
-    __aeabi_f2d; # arm
-    __aeabi_f2iz; # arm
-    __aeabi_f2uiz; # arm
-    __aeabi_fadd; # arm
-    __aeabi_fcmpun; # arm
-    __aeabi_fdiv; # arm
-    __aeabi_fmul; # arm
-    __aeabi_frsub; # arm
-    __aeabi_fsub; # arm
-    __aeabi_i2d; # arm
-    __aeabi_i2f; # arm
-    __aeabi_idiv; # arm
-    __aeabi_idiv0; # arm
-    __aeabi_idivmod; # arm
-    __aeabi_l2d; # arm
-    __aeabi_l2f; # arm
-    __aeabi_lasr; # arm
-    __aeabi_ldiv0; # arm
-    __aeabi_ldivmod; # arm
-    __aeabi_llsl; # arm
-    __aeabi_llsr; # arm
-    __aeabi_lmul; # arm
-    __aeabi_memclr; # arm
-    __aeabi_memclr4; # arm
-    __aeabi_memclr8; # arm
-    __aeabi_memcpy; # arm
-    __aeabi_memcpy4; # arm
-    __aeabi_memcpy8; # arm
-    __aeabi_memmove; # arm
-    __aeabi_memmove4; # arm
-    __aeabi_memmove8; # arm
-    __aeabi_memset; # arm
-    __aeabi_memset4; # arm
-    __aeabi_memset8; # arm
-    __aeabi_ui2d; # arm
-    __aeabi_ui2f; # arm
-    __aeabi_uidiv; # arm
-    __aeabi_uidivmod; # arm
-    __aeabi_ul2d; # arm
-    __aeabi_ul2f; # arm
-    __aeabi_uldivmod; # arm
-    __aeabi_unwind_cpp_pr0; # arm
-    __aeabi_unwind_cpp_pr1; # arm
-    __aeabi_unwind_cpp_pr2; # arm
-    __arm_fadvise64_64; # arm
-    __ashldi3; # arm
-    __ashrdi3; # arm
     __bionic_brk; # arm x86 mips
-    __bionic_libgcc_compat_symbols; # arm x86
-    __bionic_libgcc_unwind_symbols; # arm
-    __dso_handle; # arm
-    __gnu_Unwind_Backtrace; # arm
-    __gnu_unwind_execute; # arm
-    __gnu_Unwind_Find_exidx; # arm
-    __gnu_Unwind_ForcedUnwind; # arm
-    __gnu_unwind_frame; # arm
-    __gnu_Unwind_RaiseException; # arm
-    __gnu_Unwind_Restore_VFP; # arm
-    __gnu_Unwind_Restore_VFP_D; # arm
-    __gnu_Unwind_Restore_VFP_D_16_to_31; # arm
-    __gnu_Unwind_Restore_WMMXC; # arm
-    __gnu_Unwind_Restore_WMMXD; # arm
-    __gnu_Unwind_Resume; # arm
-    __gnu_Unwind_Resume_or_Rethrow; # arm
-    __gnu_Unwind_Save_VFP; # arm
-    __gnu_Unwind_Save_VFP_D; # arm
-    __gnu_Unwind_Save_VFP_D_16_to_31; # arm
-    __gnu_Unwind_Save_WMMXC; # arm
-    __gnu_Unwind_Save_WMMXD; # arm
-    _Unwind_Backtrace; # arm
-    _Unwind_Complete; # arm
-    _Unwind_DeleteException; # arm
-    _Unwind_ForcedUnwind; # arm
-    _Unwind_GetCFA; # arm
-    _Unwind_GetDataRelBase; # arm
-    _Unwind_GetLanguageSpecificData; # arm
-    _Unwind_GetRegionStart; # arm
-    _Unwind_GetTextRelBase; # arm
-    _Unwind_RaiseException; # arm
-    _Unwind_Resume; # arm
-    _Unwind_Resume_or_Rethrow; # arm
-    _Unwind_VRS_Get; # arm
-    _Unwind_VRS_Pop; # arm
-    _Unwind_VRS_Set; # arm
-    atexit; # arm
-    dlmalloc; # arm x86 mips
-    dlmalloc_inspect_all;
-    dlmalloc_trim;
-    dlmalloc_usable_size; # arm x86 mips
+    __divdi3; # arm x86 mips
+    __futex_wait; # arm x86 mips nobrillo
+    __futex_wake; # arm x86 mips nobrillo
+    __get_thread; # arm x86 mips nobrillo
+    __get_tls; # arm x86 mips nobrillo
+    __getdents64; # arm x86 mips
+    __open; # arm x86 mips nobrillo
+    __page_shift; # arm x86 mips nobrillo
+    __page_size; # arm x86 mips nobrillo
+    __popcountsi2; # arm x86 mips
+    __pthread_gettid; # arm x86 mips nobrillo
+    __sclose; # arm x86 mips
+    __sdidinit; # arm x86 mips nobrillo
+    __set_errno; # arm x86 mips nobrillo
+    __sflags; # arm x86 mips
+    __sflush; # arm x86 mips
+    __sfp; # arm x86 mips
+    __sglue; # arm x86 mips
+    __sinit; # arm x86 mips nobrillo
+    __smakebuf; # arm x86 mips
+    __sread; # arm x86 mips
+    __srefill; # arm x86 mips
+    __srget; # arm x86 mips
+    __sseek; # arm x86 mips
+    __swbuf; # arm x86 mips
+    __swrite; # arm x86 mips
+    __swsetup; # arm x86 mips
+    __udivdi3; # arm x86 mips
+    __umoddi3; # x86 mips
+    __wait4; # arm x86 mips nobrillo
+    _fwalk; # arm x86 mips
+    android_getaddrinfofornet;
+    android_getaddrinfofornetcontext;
+    android_gethostbyaddrfornet;
+    android_gethostbynamefornet;
+    arc4random_addrandom; # arm x86 mips nobrillo
+    arc4random_stir; # arm x86 mips nobrillo
+    bcopy; # arm x86 mips nobrillo
+    bzero; # arm x86 mips nobrillo
+    bsd_signal; # arm x86 mips nobrillo
+    dlmalloc; # arm x86 mips nobrillo
+    dlmalloc_inspect_all; # arm x86 mips nobrillo
+    dlmalloc_trim; # arm x86 mips nobrillo
+    dlmalloc_usable_size; # arm x86 mips nobrillo
+    endpwent; # arm x86 mips nobrillo
+    fdprintf; # arm x86 mips nobrillo
+    free_malloc_leak_info;
+    ftime; # arm x86 mips nobrillo
+    get_malloc_leak_info;
+    getdents; # arm x86 mips nobrillo
+    getdtablesize; # arm x86 mips nobrillo
     gMallocLeakZygoteChild;
+    index; # arm x86 mips nobrillo
+    issetugid; # arm x86 mips nobrillo
+    memswap; # arm x86 mips nobrillo
+    pthread_attr_getstackaddr; # arm x86 mips nobrillo
+    pthread_attr_setstackaddr; # arm x86 mips nobrillo
     SHA1Final; # arm x86 mips
     SHA1Init; # arm x86 mips
     SHA1Transform; # arm x86 mips
     SHA1Update; # arm x86 mips
-} LIBC;
+    strntoimax; # arm x86 mips nobrillo
+    strntoumax; # arm x86 mips nobrillo
+    strtotimeval; # arm x86 mips nobrillo
+    sysv_signal; # arm x86 mips nobrillo
+    tkill; # arm x86 mips nobrillo
+    vfdprintf; # arm x86 mips nobrillo
+    wait3; # arm x86 mips nobrillo
+    wcswcs; # arm x86 mips nobrillo
+} LIBC_N;
+
+LIBC_PLATFORM {
+  global:
+    android_net_res_stats_get_info_for_net;
+    android_net_res_stats_aggregate;
+    android_net_res_stats_get_usable_servers;
+    malloc_backtrace;
+    malloc_disable;
+    malloc_enable;
+    malloc_iterate;
+} LIBC_N;
diff --git a/libc/libc.map b/libc/libc.mips64.map
similarity index 67%
copy from libc/libc.map
copy to libc/libc.mips64.map
index 47c52a4..afbd0ee 100644
--- a/libc/libc.map
+++ b/libc/libc.mips64.map
@@ -1,52 +1,25 @@
+# Generated by genversionscripts.py. Do not edit.
 LIBC {
   global:
     __assert;
     __assert2;
-    __atomic_cmpxchg; # arm
-    __atomic_dec; # arm
-    __atomic_inc; # arm
-    __atomic_swap; # arm
     __b64_ntop;
     __b64_pton;
-    __brk; # arm x86 mips
-    __cmpdf2; # arm
     __cmsg_nxthdr;
-    __connect; # arm x86 mips
     __ctype_get_mb_cur_max;
     __cxa_atexit;
     __cxa_finalize;
     __cxa_thread_atexit_impl;
-    __divdf3; # arm
-    __divdi3; # arm x86 mips
-    __divsf3; # arm
-    __divsi3; # arm
     __dn_comp;
     __dn_count_labels;
     __dn_skipname;
-    __epoll_pwait; # arm x86 mips
-    __eqdf2; # arm
     __errno;
-    __exit; # arm x86 mips
-    __extendsfdf2; # arm
-    __fadvise64; # x86 mips
     __fbufsize;
-    __fcntl64; # arm x86 mips
     __FD_CLR_chk;
     __FD_ISSET_chk;
     __FD_SET_chk;
     __fgets_chk;
-    __fixdfsi; # arm
-    __fixsfsi; # arm
-    __fixunssfsi; # arm
     __flbf;
-    __floatdidf; # arm
-    __floatdisf; # arm
-    __floatsidf; # arm
-    __floatsisf; # arm
-    __floatundidf; # arm
-    __floatundisf; # arm
-    __floatunsidf; # arm
-    __floatunsisf; # arm
     __fp_nquery;
     __fp_query;
     __fpclassify;
@@ -57,26 +30,11 @@
     __fpurge;
     __freadable;
     __fsetlocking;
-    __fstatfs64; # arm x86 mips
-    __futex_wait; # arm x86 mips
-    __futex_wake; # arm x86 mips
     __fwritable;
-    __gedf2; # arm
     __get_h_errno;
-    __get_thread; # arm x86 mips
-    __get_tls; # arm x86 mips
-    __getcpu; # arm x86 mips
-    __getcwd; # arm x86 mips
-    __getdents64; # arm x86 mips
-    __getpid; # arm x86 mips
-    __getpriority; # arm x86 mips
     __gnu_basename;
-    __gnu_ldivmod_helper; # arm
     __gnu_strerror_r;
-    __gnu_uldivmod_helper; # arm
-    __gtdf2; # arm
     __hostalias;
-    __ioctl; # arm x86 mips
     __isfinite;
     __isfinitef;
     __isfinitel;
@@ -89,52 +47,17 @@
     __isnormal;
     __isnormalf;
     __isnormall;
-    __isthreaded;
-    __ledf2; # arm
     __libc_current_sigrtmax;
     __libc_current_sigrtmin;
     __libc_init;
-    __llseek; # arm x86 mips
     __loc_aton;
     __loc_ntoa;
-    __lshrdi3; # arm
-    __ltdf2; # arm
     __memchr_chk;
     __memcpy_chk;
     __memmove_chk;
     __memrchr_chk;
     __memset_chk;
-    __mmap2; # arm x86 mips
-    __moddi3; # x86 mips
-    __muldf3; # arm
-    __muldi3; # arm
-    __mulsf3; # arm
-    __nedf2; # arm
-    __ns_format_ttl; # arm x86 mips
-    __ns_get16; # arm x86 mips
-    __ns_get32; # arm x86 mips
-    __ns_initparse; # arm x86 mips
-    __ns_makecanon; # arm x86 mips
-    __ns_msg_getflag; # arm x86 mips
-    __ns_name_compress; # arm x86 mips
-    __ns_name_ntol; # arm x86 mips
-    __ns_name_ntop; # arm x86 mips
-    __ns_name_pack; # arm x86 mips
-    __ns_name_pton; # arm x86 mips
-    __ns_name_rollback; # arm x86 mips
-    __ns_name_skip; # arm x86 mips
-    __ns_name_uncompress; # arm x86 mips
-    __ns_name_unpack; # arm x86 mips
-    __ns_parserr; # arm x86 mips
-    __ns_put16; # arm x86 mips
-    __ns_put32; # arm x86 mips
-    __ns_samename; # arm x86 mips
-    __ns_skiprr; # arm x86 mips
-    __ns_sprintrr; # arm x86 mips
-    __ns_sprintrrf; # arm x86 mips
-    __open; # arm x86 mips
     __open_2;
-    __openat; # arm x86 mips
     __openat_2;
     __p_cdname;
     __p_cdnname;
@@ -149,27 +72,18 @@
     __p_time;
     __p_type;
     __p_type_syms;
-    __page_shift; # arm x86 mips
-    __page_size; # arm x86 mips
     __poll_chk;
-    __popcount_tab; # arm
-    __popcountsi2; # arm x86 mips
-    __ppoll; # arm x86 mips
     __ppoll_chk;
     __pread64_chk;
     __pread_chk;
     __progname;
-    __pselect6; # arm x86 mips
     __pthread_cleanup_pop;
     __pthread_cleanup_push;
-    __pthread_gettid; # arm x86 mips
-    __ptrace; # arm x86 mips
     __putlong;
     __putshort;
     __read_chk;
     __readlink_chk;
     __readlinkat_chk;
-    __reboot; # arm x86 mips
     __recvfrom_chk;
     __register_atfork;
     __res_close;
@@ -192,41 +106,14 @@
     __res_send;
     __res_send_setqhook;
     __res_send_setrhook;
-    __restore_core_regs; # arm
-    __rt_sigaction; # arm x86 mips
-    __rt_sigpending; # arm x86 mips
-    __rt_sigprocmask; # arm x86 mips
-    __rt_sigsuspend; # arm x86 mips
-    __rt_sigtimedwait; # arm x86 mips
     __sched_cpualloc;
     __sched_cpucount;
     __sched_cpufree;
-    __sched_getaffinity; # arm x86 mips
-    __sclose; # arm x86 mips
-    __sdidinit; # arm x86 mips
-    __set_errno; # arm x86 mips
-    __set_thread_area; # x86
-    __set_tid_address; # arm x86 mips
-    __set_tls; # arm mips
     __sF;
-    __sflags; # arm x86 mips
-    __sflush; # arm x86 mips
-    __sfp; # arm x86 mips
-    __sglue; # arm x86 mips
-    __sigaction; # arm x86 mips
-    __signalfd4; # arm x86 mips
-    __sinit; # arm x86 mips
-    __smakebuf; # arm x86 mips
     __snprintf_chk;
-    __socket; # arm x86 mips
     __sprintf_chk;
-    __sread; # arm x86 mips
-    __srefill; # arm x86 mips
-    __srget; # arm x86 mips
-    __sseek; # arm x86 mips
     __stack_chk_fail;
     __stack_chk_guard;
-    __statfs64; # arm x86 mips
     __stpcpy_chk;
     __stpncpy_chk;
     __stpncpy_chk2;
@@ -240,11 +127,6 @@
     __strncpy_chk;
     __strncpy_chk2;
     __strrchr_chk;
-    __subdf3; # arm
-    __subsf3; # arm
-    __swbuf; # arm x86 mips
-    __swrite; # arm x86 mips
-    __swsetup; # arm x86 mips
     __sym_ntop;
     __sym_ntos;
     __sym_ston;
@@ -263,28 +145,13 @@
     __system_property_set_filename;
     __system_property_update;
     __system_property_wait_any;
-    __timer_create; # arm x86 mips
-    __timer_delete; # arm x86 mips
-    __timer_getoverrun; # arm x86 mips
-    __timer_gettime; # arm x86 mips
-    __timer_settime; # arm x86 mips
-    __truncdfsf2; # arm
-    __udivdi3; # arm x86 mips
-    __udivsi3; # arm
     __umask_chk;
-    __umoddi3; # x86 mips
-    __unorddf2; # arm
-    __unordsf2; # arm
     __vsnprintf_chk;
     __vsprintf_chk;
-    __wait4; # arm x86 mips
-    __waitid; # arm x86 mips
     _ctype_;
     _Exit;
     _exit;
-    _flush_cache; # mips
     _flushlbf;
-    _fwalk; # arm x86 mips
     _getlong;
     _getshort;
     _longjmp;
@@ -293,9 +160,7 @@
     _resolv_set_nameservers_for_net;
     _setjmp;
     _tolower;
-    _tolower_tab_; # arm x86 mips
     _toupper;
-    _toupper_tab_; # arm x86 mips
     abort;
     abs;
     accept;
@@ -305,19 +170,11 @@
     alarm;
     alphasort;
     alphasort64;
-    android_getaddrinfofornet;
-    android_getaddrinfofornetcontext;
-    android_gethostbyaddrfornet;
-    android_gethostbynamefornet;
     android_set_abort_message;
     arc4random;
-    arc4random_addrandom; # arm x86 mips
     arc4random_buf;
-    arc4random_stir; # arm x86 mips
     arc4random_uniform;
     asctime;
-    asctime64; # arm x86 mips
-    asctime64_r; # arm x86 mips
     asctime_r;
     asprintf;
     at_quick_exit;
@@ -326,18 +183,13 @@
     atol;
     atoll;
     basename;
-    basename_r; # arm x86 mips
-    bcopy; # arm x86 mips
     bind;
     bindresvport;
     brk;
-    bsd_signal; # arm x86 mips
     bsearch;
     btowc;
-    bzero; # arm x86 mips
     c16rtomb;
     c32rtomb;
-    cacheflush; # arm mips
     calloc;
     capget;
     capset;
@@ -368,8 +220,6 @@
     creat;
     creat64;
     ctime;
-    ctime64; # arm x86 mips
-    ctime64_r; # arm x86 mips
     ctime_r;
     daemon;
     daylight;
@@ -377,7 +227,6 @@
     difftime;
     dirfd;
     dirname;
-    dirname_r; # arm x86 mips
     div;
     dn_expand;
     dprintf;
@@ -387,9 +236,7 @@
     dup3;
     duplocale;
     endmntent;
-    endpwent;
     endservent;
-    endusershell;
     endutent;
     environ;
     epoll_create;
@@ -421,8 +268,6 @@
     execvpe;
     exit;
     faccessat;
-    fake_gmtime_r; # arm x86 mips
-    fake_localtime_r; # arm x86 mips
     fallocate;
     fallocate64;
     fchdir;
@@ -435,7 +280,6 @@
     fdatasync;
     fdopen;
     fdopendir;
-    fdprintf; # arm x86 mips
     feof;
     feof_unlocked;
     ferror;
@@ -467,7 +311,6 @@
     fputws;
     fread;
     free;
-    free_malloc_leak_info;
     freeaddrinfo;
     freelocale;
     fremovexattr;
@@ -488,7 +331,6 @@
     fsync;
     ftell;
     ftello;
-    ftime; # arm x86 mips
     ftok;
     ftruncate;
     ftruncate64;
@@ -509,7 +351,6 @@
     fwscanf;
     gai_strerror;
     get_avphys_pages;
-    get_malloc_leak_info;
     get_nprocs;
     get_nprocs_conf;
     get_phys_pages;
@@ -521,8 +362,6 @@
     getchar_unlocked;
     getcwd;
     getdelim;
-    getdents; # arm x86 mips
-    getdtablesize; # arm x86 mips
     getegid;
     getenv;
     geteuid;
@@ -580,14 +419,11 @@
     gettid;
     gettimeofday;
     getuid;
-    getusershell;
     getutent;
     getwc;
     getwchar;
     getxattr;
     gmtime;
-    gmtime64; # arm x86 mips
-    gmtime64_r; # arm x86 mips
     gmtime_r;
     grantpt;
     herror;
@@ -598,7 +434,6 @@
     if_nametoindex;
     imaxabs;
     imaxdiv;
-    index; # arm x86 mips
     inet_addr;
     inet_aton;
     inet_lnaof;
@@ -651,7 +486,6 @@
     isprint_l;
     ispunct;
     ispunct_l;
-    issetugid; # arm x86 mips
     isspace;
     isspace_l;
     isupper;
@@ -704,8 +538,6 @@
     llistxattr;
     localeconv;
     localtime;
-    localtime64; # arm x86 mips
-    localtime64_r; # arm x86 mips
     localtime_r;
     login_tty;
     longjmp;
@@ -741,7 +573,6 @@
     mempcpy;
     memrchr;
     memset;
-    memswap; # arm x86 mips
     mincore;
     mkdir;
     mkdirat;
@@ -760,8 +591,6 @@
     mkstemps64;
     mktemp;
     mktime;
-    mktime64; # arm x86 mips
-    mktime_tz;
     mlock;
     mlockall;
     mmap;
@@ -855,7 +684,6 @@
     pthread_attr_getschedpolicy;
     pthread_attr_getscope;
     pthread_attr_getstack;
-    pthread_attr_getstackaddr; # arm x86 mips
     pthread_attr_getstacksize;
     pthread_attr_init;
     pthread_attr_setdetachstate;
@@ -864,17 +692,12 @@
     pthread_attr_setschedpolicy;
     pthread_attr_setscope;
     pthread_attr_setstack;
-    pthread_attr_setstackaddr; # arm x86 mips
     pthread_attr_setstacksize;
     pthread_cond_broadcast;
     pthread_cond_destroy;
     pthread_cond_init;
     pthread_cond_signal;
     pthread_cond_timedwait;
-    pthread_cond_timedwait_monotonic; # arm x86 mips
-    pthread_cond_timedwait_monotonic_np; # arm x86 mips
-    pthread_cond_timedwait_relative_np; # arm x86 mips
-    pthread_cond_timeout_np; # arm x86 mips
     pthread_cond_wait;
     pthread_condattr_destroy;
     pthread_condattr_getclock;
@@ -898,7 +721,6 @@
     pthread_mutex_destroy;
     pthread_mutex_init;
     pthread_mutex_lock;
-    pthread_mutex_lock_timeout_np; # arm x86 mips
     pthread_mutex_timedlock;
     pthread_mutex_trylock;
     pthread_mutex_unlock;
@@ -939,10 +761,8 @@
     putenv;
     puts;
     pututline;
-    putw; # arm x86 mips
     putwc;
     putwchar;
-    pvalloc; # arm x86 mips
     pwrite;
     pwrite64;
     qsort;
@@ -980,7 +800,6 @@
     res_mkquery;
     res_query;
     res_search;
-    restore_core_regs; # arm
     rewind;
     rewinddir;
     rmdir;
@@ -1051,7 +870,6 @@
     setstate;
     settimeofday;
     setuid;
-    setusershell;
     setutent;
     setvbuf;
     setxattr;
@@ -1124,8 +942,6 @@
     strncpy;
     strndup;
     strnlen;
-    strntoimax; # arm x86 mips
-    strntoumax; # arm x86 mips
     strpbrk;
     strptime;
     strrchr;
@@ -1144,7 +960,6 @@
     strtoll;
     strtoll_l;
     strtoq;
-    strtotimeval; # arm x86 mips
     strtoul;
     strtoull;
     strtoull_l;
@@ -1166,7 +981,6 @@
     sysinfo;
     syslog;
     system;
-    sysv_signal; # arm x86 mips
     tcdrain;
     tcflow;
     tcflush;
@@ -1185,9 +999,7 @@
     tgkill;
     time;
     timegm;
-    timegm64; # arm x86 mips
     timelocal;
-    timelocal64; # arm x86 mips
     timer_create;
     timer_delete;
     timer_getoverrun;
@@ -1198,7 +1010,6 @@
     timerfd_settime;
     times;
     timezone;
-    tkill; # arm x86 mips
     tmpfile;
     tmpnam;
     toascii;
@@ -1235,12 +1046,10 @@
     utimensat;
     utimes;
     utmpname;
-    valloc; # arm x86 mips
     vasprintf;
     vdprintf;
     verr;
     verrx;
-    vfdprintf; # arm x86 mips
     vfork;
     vfprintf;
     vfscanf;
@@ -1260,7 +1069,6 @@
     vwprintf;
     vwscanf;
     wait;
-    wait3; # arm x86 mips
     wait4;
     waitid;
     waitpid;
@@ -1309,7 +1117,6 @@
     wcstoull;
     wcstoull_l;
     wcstoumax;
-    wcswcs; # arm x86 mips
     wcswidth;
     wcsxfrm;
     wcsxfrm_l;
@@ -1332,125 +1139,74 @@
     *;
 };
 
+LIBC_N {
+  global:
+    __fread_chk;
+    __fwrite_chk;
+    __getcwd_chk;
+    __pwrite_chk;
+    __pwrite64_chk;
+    __write_chk;
+    adjtimex;
+    clock_adjtime;
+    fgetpos64;
+    fileno_unlocked;
+    fopen64;
+    freeifaddrs;
+    freopen64;
+    fseeko64;
+    fsetpos64;
+    ftello64;
+    funopen64;
+    getgrgid_r;
+    getgrnam_r;
+    getifaddrs;
+    if_freenameindex;
+    if_nameindex;
+    in6addr_any;
+    in6addr_loopback;
+    lockf;
+    lockf64;
+    preadv;
+    preadv64;
+    pthread_barrierattr_destroy;
+    pthread_barrierattr_getpshared;
+    pthread_barrierattr_init;
+    pthread_barrierattr_setpshared;
+    pthread_barrier_destroy;
+    pthread_barrier_init;
+    pthread_barrier_wait;
+    pthread_spin_destroy;
+    pthread_spin_init;
+    pthread_spin_lock;
+    pthread_spin_trylock;
+    pthread_spin_unlock;
+    pwritev;
+    pwritev64;
+    scandirat;
+    scandirat64;
+    strchrnul;
+    tmpfile64;
+} LIBC;
+
 LIBC_PRIVATE {
   global:
-    ___Unwind_Backtrace; # arm
-    ___Unwind_ForcedUnwind; # arm
-    ___Unwind_RaiseException; # arm
-    ___Unwind_Resume; # arm
-    ___Unwind_Resume_or_Rethrow; # arm
-    __accept4; # arm x86 mips
-    __adddf3; # arm
-    __addsf3; # arm
-    __aeabi_atexit; # arm
-    __aeabi_cdcmpeq; # arm
-    __aeabi_cdcmple; # arm
-    __aeabi_cdrcmple; # arm
-    __aeabi_d2f; # arm
-    __aeabi_d2iz; # arm
-    __aeabi_dadd; # arm
-    __aeabi_dcmpeq; # arm
-    __aeabi_dcmpge; # arm
-    __aeabi_dcmpgt; # arm
-    __aeabi_dcmple; # arm
-    __aeabi_dcmplt; # arm
-    __aeabi_dcmpun; # arm
-    __aeabi_ddiv; # arm
-    __aeabi_dmul; # arm
-    __aeabi_drsub; # arm
-    __aeabi_dsub; # arm
-    __aeabi_f2d; # arm
-    __aeabi_f2iz; # arm
-    __aeabi_f2uiz; # arm
-    __aeabi_fadd; # arm
-    __aeabi_fcmpun; # arm
-    __aeabi_fdiv; # arm
-    __aeabi_fmul; # arm
-    __aeabi_frsub; # arm
-    __aeabi_fsub; # arm
-    __aeabi_i2d; # arm
-    __aeabi_i2f; # arm
-    __aeabi_idiv; # arm
-    __aeabi_idiv0; # arm
-    __aeabi_idivmod; # arm
-    __aeabi_l2d; # arm
-    __aeabi_l2f; # arm
-    __aeabi_lasr; # arm
-    __aeabi_ldiv0; # arm
-    __aeabi_ldivmod; # arm
-    __aeabi_llsl; # arm
-    __aeabi_llsr; # arm
-    __aeabi_lmul; # arm
-    __aeabi_memclr; # arm
-    __aeabi_memclr4; # arm
-    __aeabi_memclr8; # arm
-    __aeabi_memcpy; # arm
-    __aeabi_memcpy4; # arm
-    __aeabi_memcpy8; # arm
-    __aeabi_memmove; # arm
-    __aeabi_memmove4; # arm
-    __aeabi_memmove8; # arm
-    __aeabi_memset; # arm
-    __aeabi_memset4; # arm
-    __aeabi_memset8; # arm
-    __aeabi_ui2d; # arm
-    __aeabi_ui2f; # arm
-    __aeabi_uidiv; # arm
-    __aeabi_uidivmod; # arm
-    __aeabi_ul2d; # arm
-    __aeabi_ul2f; # arm
-    __aeabi_uldivmod; # arm
-    __aeabi_unwind_cpp_pr0; # arm
-    __aeabi_unwind_cpp_pr1; # arm
-    __aeabi_unwind_cpp_pr2; # arm
-    __arm_fadvise64_64; # arm
-    __ashldi3; # arm
-    __ashrdi3; # arm
-    __bionic_brk; # arm x86 mips
-    __bionic_libgcc_compat_symbols; # arm x86
-    __bionic_libgcc_unwind_symbols; # arm
-    __dso_handle; # arm
-    __gnu_Unwind_Backtrace; # arm
-    __gnu_unwind_execute; # arm
-    __gnu_Unwind_Find_exidx; # arm
-    __gnu_Unwind_ForcedUnwind; # arm
-    __gnu_unwind_frame; # arm
-    __gnu_Unwind_RaiseException; # arm
-    __gnu_Unwind_Restore_VFP; # arm
-    __gnu_Unwind_Restore_VFP_D; # arm
-    __gnu_Unwind_Restore_VFP_D_16_to_31; # arm
-    __gnu_Unwind_Restore_WMMXC; # arm
-    __gnu_Unwind_Restore_WMMXD; # arm
-    __gnu_Unwind_Resume; # arm
-    __gnu_Unwind_Resume_or_Rethrow; # arm
-    __gnu_Unwind_Save_VFP; # arm
-    __gnu_Unwind_Save_VFP_D; # arm
-    __gnu_Unwind_Save_VFP_D_16_to_31; # arm
-    __gnu_Unwind_Save_WMMXC; # arm
-    __gnu_Unwind_Save_WMMXD; # arm
-    _Unwind_Backtrace; # arm
-    _Unwind_Complete; # arm
-    _Unwind_DeleteException; # arm
-    _Unwind_ForcedUnwind; # arm
-    _Unwind_GetCFA; # arm
-    _Unwind_GetDataRelBase; # arm
-    _Unwind_GetLanguageSpecificData; # arm
-    _Unwind_GetRegionStart; # arm
-    _Unwind_GetTextRelBase; # arm
-    _Unwind_RaiseException; # arm
-    _Unwind_Resume; # arm
-    _Unwind_Resume_or_Rethrow; # arm
-    _Unwind_VRS_Get; # arm
-    _Unwind_VRS_Pop; # arm
-    _Unwind_VRS_Set; # arm
-    atexit; # arm
-    dlmalloc; # arm x86 mips
-    dlmalloc_inspect_all;
-    dlmalloc_trim;
-    dlmalloc_usable_size; # arm x86 mips
+    android_getaddrinfofornet;
+    android_getaddrinfofornetcontext;
+    android_gethostbyaddrfornet;
+    android_gethostbynamefornet;
+    free_malloc_leak_info;
+    get_malloc_leak_info;
     gMallocLeakZygoteChild;
-    SHA1Final; # arm x86 mips
-    SHA1Init; # arm x86 mips
-    SHA1Transform; # arm x86 mips
-    SHA1Update; # arm x86 mips
-} LIBC;
+} LIBC_N;
+
+LIBC_PLATFORM {
+  global:
+    android_net_res_stats_get_info_for_net;
+    android_net_res_stats_aggregate;
+    android_net_res_stats_get_usable_servers;
+    malloc_backtrace;
+    malloc_disable;
+    malloc_enable;
+    malloc_iterate;
+} LIBC_N;
diff --git a/libc/libc.map b/libc/libc.x86.brillo.map
similarity index 76%
copy from libc/libc.map
copy to libc/libc.x86.brillo.map
index 47c52a4..34f5e0e 100644
--- a/libc/libc.map
+++ b/libc/libc.x86.brillo.map
@@ -1,33 +1,23 @@
+# Generated by genversionscripts.py. Do not edit.
 LIBC {
   global:
     __assert;
     __assert2;
-    __atomic_cmpxchg; # arm
-    __atomic_dec; # arm
-    __atomic_inc; # arm
-    __atomic_swap; # arm
     __b64_ntop;
     __b64_pton;
     __brk; # arm x86 mips
-    __cmpdf2; # arm
     __cmsg_nxthdr;
     __connect; # arm x86 mips
     __ctype_get_mb_cur_max;
     __cxa_atexit;
     __cxa_finalize;
     __cxa_thread_atexit_impl;
-    __divdf3; # arm
-    __divdi3; # arm x86 mips
-    __divsf3; # arm
-    __divsi3; # arm
     __dn_comp;
     __dn_count_labels;
     __dn_skipname;
     __epoll_pwait; # arm x86 mips
-    __eqdf2; # arm
     __errno;
     __exit; # arm x86 mips
-    __extendsfdf2; # arm
     __fadvise64; # x86 mips
     __fbufsize;
     __fcntl64; # arm x86 mips
@@ -35,18 +25,7 @@
     __FD_ISSET_chk;
     __FD_SET_chk;
     __fgets_chk;
-    __fixdfsi; # arm
-    __fixsfsi; # arm
-    __fixunssfsi; # arm
     __flbf;
-    __floatdidf; # arm
-    __floatdisf; # arm
-    __floatsidf; # arm
-    __floatsisf; # arm
-    __floatundidf; # arm
-    __floatundisf; # arm
-    __floatunsidf; # arm
-    __floatunsisf; # arm
     __fp_nquery;
     __fp_query;
     __fpclassify;
@@ -58,23 +37,14 @@
     __freadable;
     __fsetlocking;
     __fstatfs64; # arm x86 mips
-    __futex_wait; # arm x86 mips
-    __futex_wake; # arm x86 mips
     __fwritable;
-    __gedf2; # arm
     __get_h_errno;
-    __get_thread; # arm x86 mips
-    __get_tls; # arm x86 mips
     __getcpu; # arm x86 mips
     __getcwd; # arm x86 mips
-    __getdents64; # arm x86 mips
     __getpid; # arm x86 mips
     __getpriority; # arm x86 mips
     __gnu_basename;
-    __gnu_ldivmod_helper; # arm
     __gnu_strerror_r;
-    __gnu_uldivmod_helper; # arm
-    __gtdf2; # arm
     __hostalias;
     __ioctl; # arm x86 mips
     __isfinite;
@@ -89,27 +59,19 @@
     __isnormal;
     __isnormalf;
     __isnormall;
-    __isthreaded;
-    __ledf2; # arm
+    __isthreaded; # arm x86 mips
     __libc_current_sigrtmax;
     __libc_current_sigrtmin;
     __libc_init;
     __llseek; # arm x86 mips
     __loc_aton;
     __loc_ntoa;
-    __lshrdi3; # arm
-    __ltdf2; # arm
     __memchr_chk;
     __memcpy_chk;
     __memmove_chk;
     __memrchr_chk;
     __memset_chk;
     __mmap2; # arm x86 mips
-    __moddi3; # x86 mips
-    __muldf3; # arm
-    __muldi3; # arm
-    __mulsf3; # arm
-    __nedf2; # arm
     __ns_format_ttl; # arm x86 mips
     __ns_get16; # arm x86 mips
     __ns_get32; # arm x86 mips
@@ -132,7 +94,6 @@
     __ns_skiprr; # arm x86 mips
     __ns_sprintrr; # arm x86 mips
     __ns_sprintrrf; # arm x86 mips
-    __open; # arm x86 mips
     __open_2;
     __openat; # arm x86 mips
     __openat_2;
@@ -149,11 +110,7 @@
     __p_time;
     __p_type;
     __p_type_syms;
-    __page_shift; # arm x86 mips
-    __page_size; # arm x86 mips
     __poll_chk;
-    __popcount_tab; # arm
-    __popcountsi2; # arm x86 mips
     __ppoll; # arm x86 mips
     __ppoll_chk;
     __pread64_chk;
@@ -162,7 +119,6 @@
     __pselect6; # arm x86 mips
     __pthread_cleanup_pop;
     __pthread_cleanup_push;
-    __pthread_gettid; # arm x86 mips
     __ptrace; # arm x86 mips
     __putlong;
     __putshort;
@@ -192,7 +148,6 @@
     __res_send;
     __res_send_setqhook;
     __res_send_setrhook;
-    __restore_core_regs; # arm
     __rt_sigaction; # arm x86 mips
     __rt_sigpending; # arm x86 mips
     __rt_sigprocmask; # arm x86 mips
@@ -202,28 +157,13 @@
     __sched_cpucount;
     __sched_cpufree;
     __sched_getaffinity; # arm x86 mips
-    __sclose; # arm x86 mips
-    __sdidinit; # arm x86 mips
-    __set_errno; # arm x86 mips
     __set_thread_area; # x86
     __set_tid_address; # arm x86 mips
-    __set_tls; # arm mips
     __sF;
-    __sflags; # arm x86 mips
-    __sflush; # arm x86 mips
-    __sfp; # arm x86 mips
-    __sglue; # arm x86 mips
     __sigaction; # arm x86 mips
-    __signalfd4; # arm x86 mips
-    __sinit; # arm x86 mips
-    __smakebuf; # arm x86 mips
     __snprintf_chk;
     __socket; # arm x86 mips
     __sprintf_chk;
-    __sread; # arm x86 mips
-    __srefill; # arm x86 mips
-    __srget; # arm x86 mips
-    __sseek; # arm x86 mips
     __stack_chk_fail;
     __stack_chk_guard;
     __statfs64; # arm x86 mips
@@ -240,11 +180,6 @@
     __strncpy_chk;
     __strncpy_chk2;
     __strrchr_chk;
-    __subdf3; # arm
-    __subsf3; # arm
-    __swbuf; # arm x86 mips
-    __swrite; # arm x86 mips
-    __swsetup; # arm x86 mips
     __sym_ntop;
     __sym_ntos;
     __sym_ston;
@@ -268,23 +203,14 @@
     __timer_getoverrun; # arm x86 mips
     __timer_gettime; # arm x86 mips
     __timer_settime; # arm x86 mips
-    __truncdfsf2; # arm
-    __udivdi3; # arm x86 mips
-    __udivsi3; # arm
     __umask_chk;
-    __umoddi3; # x86 mips
-    __unorddf2; # arm
-    __unordsf2; # arm
     __vsnprintf_chk;
     __vsprintf_chk;
-    __wait4; # arm x86 mips
     __waitid; # arm x86 mips
     _ctype_;
     _Exit;
     _exit;
-    _flush_cache; # mips
     _flushlbf;
-    _fwalk; # arm x86 mips
     _getlong;
     _getshort;
     _longjmp;
@@ -305,15 +231,9 @@
     alarm;
     alphasort;
     alphasort64;
-    android_getaddrinfofornet;
-    android_getaddrinfofornetcontext;
-    android_gethostbyaddrfornet;
-    android_gethostbynamefornet;
     android_set_abort_message;
     arc4random;
-    arc4random_addrandom; # arm x86 mips
     arc4random_buf;
-    arc4random_stir; # arm x86 mips
     arc4random_uniform;
     asctime;
     asctime64; # arm x86 mips
@@ -327,17 +247,13 @@
     atoll;
     basename;
     basename_r; # arm x86 mips
-    bcopy; # arm x86 mips
     bind;
     bindresvport;
     brk;
-    bsd_signal; # arm x86 mips
     bsearch;
     btowc;
-    bzero; # arm x86 mips
     c16rtomb;
     c32rtomb;
-    cacheflush; # arm mips
     calloc;
     capget;
     capset;
@@ -387,9 +303,7 @@
     dup3;
     duplocale;
     endmntent;
-    endpwent;
     endservent;
-    endusershell;
     endutent;
     environ;
     epoll_create;
@@ -421,8 +335,6 @@
     execvpe;
     exit;
     faccessat;
-    fake_gmtime_r; # arm x86 mips
-    fake_localtime_r; # arm x86 mips
     fallocate;
     fallocate64;
     fchdir;
@@ -435,7 +347,6 @@
     fdatasync;
     fdopen;
     fdopendir;
-    fdprintf; # arm x86 mips
     feof;
     feof_unlocked;
     ferror;
@@ -467,7 +378,6 @@
     fputws;
     fread;
     free;
-    free_malloc_leak_info;
     freeaddrinfo;
     freelocale;
     fremovexattr;
@@ -488,7 +398,6 @@
     fsync;
     ftell;
     ftello;
-    ftime; # arm x86 mips
     ftok;
     ftruncate;
     ftruncate64;
@@ -509,7 +418,6 @@
     fwscanf;
     gai_strerror;
     get_avphys_pages;
-    get_malloc_leak_info;
     get_nprocs;
     get_nprocs_conf;
     get_phys_pages;
@@ -521,8 +429,6 @@
     getchar_unlocked;
     getcwd;
     getdelim;
-    getdents; # arm x86 mips
-    getdtablesize; # arm x86 mips
     getegid;
     getenv;
     geteuid;
@@ -580,7 +486,6 @@
     gettid;
     gettimeofday;
     getuid;
-    getusershell;
     getutent;
     getwc;
     getwchar;
@@ -598,7 +503,6 @@
     if_nametoindex;
     imaxabs;
     imaxdiv;
-    index; # arm x86 mips
     inet_addr;
     inet_aton;
     inet_lnaof;
@@ -651,7 +555,6 @@
     isprint_l;
     ispunct;
     ispunct_l;
-    issetugid; # arm x86 mips
     isspace;
     isspace_l;
     isupper;
@@ -741,7 +644,6 @@
     mempcpy;
     memrchr;
     memset;
-    memswap; # arm x86 mips
     mincore;
     mkdir;
     mkdirat;
@@ -761,7 +663,6 @@
     mktemp;
     mktime;
     mktime64; # arm x86 mips
-    mktime_tz;
     mlock;
     mlockall;
     mmap;
@@ -780,28 +681,6 @@
     nftw64;
     nice;
     nrand48;
-    ns_format_ttl; # arm64 x86_64 mips64
-    ns_get16; # arm64 x86_64 mips64
-    ns_get32; # arm64 x86_64 mips64
-    ns_initparse; # arm64 x86_64 mips64
-    ns_makecanon; # arm64 x86_64 mips64
-    ns_msg_getflag; # arm64 x86_64 mips64
-    ns_name_compress; # arm64 x86_64 mips64
-    ns_name_ntol; # arm64 x86_64 mips64
-    ns_name_ntop; # arm64 x86_64 mips64
-    ns_name_pack; # arm64 x86_64 mips64
-    ns_name_pton; # arm64 x86_64 mips64
-    ns_name_rollback; # arm64 x86_64 mips64
-    ns_name_skip; # arm64 x86_64 mips64
-    ns_name_uncompress; # arm64 x86_64 mips64
-    ns_name_unpack; # arm64 x86_64 mips64
-    ns_parserr; # arm64 x86_64 mips64
-    ns_put16; # arm64 x86_64 mips64
-    ns_put32; # arm64 x86_64 mips64
-    ns_samename; # arm64 x86_64 mips64
-    ns_skiprr; # arm64 x86_64 mips64
-    ns_sprintrr; # arm64 x86_64 mips64
-    ns_sprintrrf; # arm64 x86_64 mips64
     nsdispatch;
     ntohl;
     ntohs;
@@ -840,7 +719,6 @@
     pread;
     pread64;
     printf;
-    prlimit; # arm64 x86_64 mips64
     prlimit64;
     process_vm_readv;
     process_vm_writev;
@@ -855,7 +733,6 @@
     pthread_attr_getschedpolicy;
     pthread_attr_getscope;
     pthread_attr_getstack;
-    pthread_attr_getstackaddr; # arm x86 mips
     pthread_attr_getstacksize;
     pthread_attr_init;
     pthread_attr_setdetachstate;
@@ -864,7 +741,6 @@
     pthread_attr_setschedpolicy;
     pthread_attr_setscope;
     pthread_attr_setstack;
-    pthread_attr_setstackaddr; # arm x86 mips
     pthread_attr_setstacksize;
     pthread_cond_broadcast;
     pthread_cond_destroy;
@@ -980,7 +856,6 @@
     res_mkquery;
     res_query;
     res_search;
-    restore_core_regs; # arm
     rewind;
     rewinddir;
     rmdir;
@@ -1051,7 +926,6 @@
     setstate;
     settimeofday;
     setuid;
-    setusershell;
     setutent;
     setvbuf;
     setxattr;
@@ -1124,8 +998,6 @@
     strncpy;
     strndup;
     strnlen;
-    strntoimax; # arm x86 mips
-    strntoumax; # arm x86 mips
     strpbrk;
     strptime;
     strrchr;
@@ -1144,7 +1016,6 @@
     strtoll;
     strtoll_l;
     strtoq;
-    strtotimeval; # arm x86 mips
     strtoul;
     strtoull;
     strtoull_l;
@@ -1166,7 +1037,6 @@
     sysinfo;
     syslog;
     system;
-    sysv_signal; # arm x86 mips
     tcdrain;
     tcflow;
     tcflush;
@@ -1198,7 +1068,6 @@
     timerfd_settime;
     times;
     timezone;
-    tkill; # arm x86 mips
     tmpfile;
     tmpnam;
     toascii;
@@ -1240,7 +1109,6 @@
     vdprintf;
     verr;
     verrx;
-    vfdprintf; # arm x86 mips
     vfork;
     vfprintf;
     vfscanf;
@@ -1260,7 +1128,6 @@
     vwprintf;
     vwscanf;
     wait;
-    wait3; # arm x86 mips
     wait4;
     waitid;
     waitpid;
@@ -1309,7 +1176,6 @@
     wcstoull;
     wcstoull_l;
     wcstoumax;
-    wcswcs; # arm x86 mips
     wcswidth;
     wcsxfrm;
     wcsxfrm_l;
@@ -1332,125 +1198,101 @@
     *;
 };
 
+LIBC_N {
+  global:
+    __fread_chk;
+    __fwrite_chk;
+    __getcwd_chk;
+    __pwrite_chk;
+    __pwrite64_chk;
+    __write_chk;
+    adjtimex;
+    clock_adjtime;
+    fgetpos64;
+    fileno_unlocked;
+    fopen64;
+    freeifaddrs;
+    freopen64;
+    fseeko64;
+    fsetpos64;
+    ftello64;
+    funopen64;
+    getgrgid_r;
+    getgrnam_r;
+    getifaddrs;
+    if_freenameindex;
+    if_nameindex;
+    in6addr_any;
+    in6addr_loopback;
+    lockf;
+    lockf64;
+    preadv;
+    preadv64;
+    prlimit; # arm mips x86
+    pthread_barrierattr_destroy;
+    pthread_barrierattr_getpshared;
+    pthread_barrierattr_init;
+    pthread_barrierattr_setpshared;
+    pthread_barrier_destroy;
+    pthread_barrier_init;
+    pthread_barrier_wait;
+    pthread_spin_destroy;
+    pthread_spin_init;
+    pthread_spin_lock;
+    pthread_spin_trylock;
+    pthread_spin_unlock;
+    pwritev;
+    pwritev64;
+    scandirat;
+    scandirat64;
+    strchrnul;
+    tmpfile64;
+} LIBC;
+
 LIBC_PRIVATE {
   global:
-    ___Unwind_Backtrace; # arm
-    ___Unwind_ForcedUnwind; # arm
-    ___Unwind_RaiseException; # arm
-    ___Unwind_Resume; # arm
-    ___Unwind_Resume_or_Rethrow; # arm
     __accept4; # arm x86 mips
-    __adddf3; # arm
-    __addsf3; # arm
-    __aeabi_atexit; # arm
-    __aeabi_cdcmpeq; # arm
-    __aeabi_cdcmple; # arm
-    __aeabi_cdrcmple; # arm
-    __aeabi_d2f; # arm
-    __aeabi_d2iz; # arm
-    __aeabi_dadd; # arm
-    __aeabi_dcmpeq; # arm
-    __aeabi_dcmpge; # arm
-    __aeabi_dcmpgt; # arm
-    __aeabi_dcmple; # arm
-    __aeabi_dcmplt; # arm
-    __aeabi_dcmpun; # arm
-    __aeabi_ddiv; # arm
-    __aeabi_dmul; # arm
-    __aeabi_drsub; # arm
-    __aeabi_dsub; # arm
-    __aeabi_f2d; # arm
-    __aeabi_f2iz; # arm
-    __aeabi_f2uiz; # arm
-    __aeabi_fadd; # arm
-    __aeabi_fcmpun; # arm
-    __aeabi_fdiv; # arm
-    __aeabi_fmul; # arm
-    __aeabi_frsub; # arm
-    __aeabi_fsub; # arm
-    __aeabi_i2d; # arm
-    __aeabi_i2f; # arm
-    __aeabi_idiv; # arm
-    __aeabi_idiv0; # arm
-    __aeabi_idivmod; # arm
-    __aeabi_l2d; # arm
-    __aeabi_l2f; # arm
-    __aeabi_lasr; # arm
-    __aeabi_ldiv0; # arm
-    __aeabi_ldivmod; # arm
-    __aeabi_llsl; # arm
-    __aeabi_llsr; # arm
-    __aeabi_lmul; # arm
-    __aeabi_memclr; # arm
-    __aeabi_memclr4; # arm
-    __aeabi_memclr8; # arm
-    __aeabi_memcpy; # arm
-    __aeabi_memcpy4; # arm
-    __aeabi_memcpy8; # arm
-    __aeabi_memmove; # arm
-    __aeabi_memmove4; # arm
-    __aeabi_memmove8; # arm
-    __aeabi_memset; # arm
-    __aeabi_memset4; # arm
-    __aeabi_memset8; # arm
-    __aeabi_ui2d; # arm
-    __aeabi_ui2f; # arm
-    __aeabi_uidiv; # arm
-    __aeabi_uidivmod; # arm
-    __aeabi_ul2d; # arm
-    __aeabi_ul2f; # arm
-    __aeabi_uldivmod; # arm
-    __aeabi_unwind_cpp_pr0; # arm
-    __aeabi_unwind_cpp_pr1; # arm
-    __aeabi_unwind_cpp_pr2; # arm
-    __arm_fadvise64_64; # arm
-    __ashldi3; # arm
-    __ashrdi3; # arm
     __bionic_brk; # arm x86 mips
     __bionic_libgcc_compat_symbols; # arm x86
-    __bionic_libgcc_unwind_symbols; # arm
-    __dso_handle; # arm
-    __gnu_Unwind_Backtrace; # arm
-    __gnu_unwind_execute; # arm
-    __gnu_Unwind_Find_exidx; # arm
-    __gnu_Unwind_ForcedUnwind; # arm
-    __gnu_unwind_frame; # arm
-    __gnu_Unwind_RaiseException; # arm
-    __gnu_Unwind_Restore_VFP; # arm
-    __gnu_Unwind_Restore_VFP_D; # arm
-    __gnu_Unwind_Restore_VFP_D_16_to_31; # arm
-    __gnu_Unwind_Restore_WMMXC; # arm
-    __gnu_Unwind_Restore_WMMXD; # arm
-    __gnu_Unwind_Resume; # arm
-    __gnu_Unwind_Resume_or_Rethrow; # arm
-    __gnu_Unwind_Save_VFP; # arm
-    __gnu_Unwind_Save_VFP_D; # arm
-    __gnu_Unwind_Save_VFP_D_16_to_31; # arm
-    __gnu_Unwind_Save_WMMXC; # arm
-    __gnu_Unwind_Save_WMMXD; # arm
-    _Unwind_Backtrace; # arm
-    _Unwind_Complete; # arm
-    _Unwind_DeleteException; # arm
-    _Unwind_ForcedUnwind; # arm
-    _Unwind_GetCFA; # arm
-    _Unwind_GetDataRelBase; # arm
-    _Unwind_GetLanguageSpecificData; # arm
-    _Unwind_GetRegionStart; # arm
-    _Unwind_GetTextRelBase; # arm
-    _Unwind_RaiseException; # arm
-    _Unwind_Resume; # arm
-    _Unwind_Resume_or_Rethrow; # arm
-    _Unwind_VRS_Get; # arm
-    _Unwind_VRS_Pop; # arm
-    _Unwind_VRS_Set; # arm
-    atexit; # arm
-    dlmalloc; # arm x86 mips
-    dlmalloc_inspect_all;
-    dlmalloc_trim;
-    dlmalloc_usable_size; # arm x86 mips
+    __divdi3; # arm x86 mips
+    __getdents64; # arm x86 mips
+    __popcountsi2; # arm x86 mips
+    __sclose; # arm x86 mips
+    __sflags; # arm x86 mips
+    __sflush; # arm x86 mips
+    __sfp; # arm x86 mips
+    __sglue; # arm x86 mips
+    __smakebuf; # arm x86 mips
+    __sread; # arm x86 mips
+    __srefill; # arm x86 mips
+    __srget; # arm x86 mips
+    __sseek; # arm x86 mips
+    __swbuf; # arm x86 mips
+    __swrite; # arm x86 mips
+    __swsetup; # arm x86 mips
+    __udivdi3; # arm x86 mips
+    __umoddi3; # x86 mips
+    _fwalk; # arm x86 mips
+    android_getaddrinfofornet;
+    android_getaddrinfofornetcontext;
+    android_gethostbyaddrfornet;
+    android_gethostbynamefornet;
+    free_malloc_leak_info;
+    get_malloc_leak_info;
     gMallocLeakZygoteChild;
     SHA1Final; # arm x86 mips
     SHA1Init; # arm x86 mips
     SHA1Transform; # arm x86 mips
     SHA1Update; # arm x86 mips
-} LIBC;
+} LIBC_N;
+
+LIBC_PLATFORM {
+  global:
+    android_net_res_stats_get_info_for_net;
+    android_net_res_stats_aggregate;
+    android_net_res_stats_get_usable_servers;
+    malloc_backtrace;
+    malloc_disable;
+    malloc_enable;
+    malloc_iterate;
+} LIBC_N;
diff --git a/libc/libc.map b/libc/libc.x86.map
similarity index 76%
copy from libc/libc.map
copy to libc/libc.x86.map
index 47c52a4..9417d56 100644
--- a/libc/libc.map
+++ b/libc/libc.x86.map
@@ -1,33 +1,23 @@
+# Generated by genversionscripts.py. Do not edit.
 LIBC {
   global:
     __assert;
     __assert2;
-    __atomic_cmpxchg; # arm
-    __atomic_dec; # arm
-    __atomic_inc; # arm
-    __atomic_swap; # arm
     __b64_ntop;
     __b64_pton;
     __brk; # arm x86 mips
-    __cmpdf2; # arm
     __cmsg_nxthdr;
     __connect; # arm x86 mips
     __ctype_get_mb_cur_max;
     __cxa_atexit;
     __cxa_finalize;
     __cxa_thread_atexit_impl;
-    __divdf3; # arm
-    __divdi3; # arm x86 mips
-    __divsf3; # arm
-    __divsi3; # arm
     __dn_comp;
     __dn_count_labels;
     __dn_skipname;
     __epoll_pwait; # arm x86 mips
-    __eqdf2; # arm
     __errno;
     __exit; # arm x86 mips
-    __extendsfdf2; # arm
     __fadvise64; # x86 mips
     __fbufsize;
     __fcntl64; # arm x86 mips
@@ -35,18 +25,7 @@
     __FD_ISSET_chk;
     __FD_SET_chk;
     __fgets_chk;
-    __fixdfsi; # arm
-    __fixsfsi; # arm
-    __fixunssfsi; # arm
     __flbf;
-    __floatdidf; # arm
-    __floatdisf; # arm
-    __floatsidf; # arm
-    __floatsisf; # arm
-    __floatundidf; # arm
-    __floatundisf; # arm
-    __floatunsidf; # arm
-    __floatunsisf; # arm
     __fp_nquery;
     __fp_query;
     __fpclassify;
@@ -58,23 +37,14 @@
     __freadable;
     __fsetlocking;
     __fstatfs64; # arm x86 mips
-    __futex_wait; # arm x86 mips
-    __futex_wake; # arm x86 mips
     __fwritable;
-    __gedf2; # arm
     __get_h_errno;
-    __get_thread; # arm x86 mips
-    __get_tls; # arm x86 mips
     __getcpu; # arm x86 mips
     __getcwd; # arm x86 mips
-    __getdents64; # arm x86 mips
     __getpid; # arm x86 mips
     __getpriority; # arm x86 mips
     __gnu_basename;
-    __gnu_ldivmod_helper; # arm
     __gnu_strerror_r;
-    __gnu_uldivmod_helper; # arm
-    __gtdf2; # arm
     __hostalias;
     __ioctl; # arm x86 mips
     __isfinite;
@@ -89,27 +59,19 @@
     __isnormal;
     __isnormalf;
     __isnormall;
-    __isthreaded;
-    __ledf2; # arm
+    __isthreaded; # arm x86 mips
     __libc_current_sigrtmax;
     __libc_current_sigrtmin;
     __libc_init;
     __llseek; # arm x86 mips
     __loc_aton;
     __loc_ntoa;
-    __lshrdi3; # arm
-    __ltdf2; # arm
     __memchr_chk;
     __memcpy_chk;
     __memmove_chk;
     __memrchr_chk;
     __memset_chk;
     __mmap2; # arm x86 mips
-    __moddi3; # x86 mips
-    __muldf3; # arm
-    __muldi3; # arm
-    __mulsf3; # arm
-    __nedf2; # arm
     __ns_format_ttl; # arm x86 mips
     __ns_get16; # arm x86 mips
     __ns_get32; # arm x86 mips
@@ -132,7 +94,6 @@
     __ns_skiprr; # arm x86 mips
     __ns_sprintrr; # arm x86 mips
     __ns_sprintrrf; # arm x86 mips
-    __open; # arm x86 mips
     __open_2;
     __openat; # arm x86 mips
     __openat_2;
@@ -149,11 +110,7 @@
     __p_time;
     __p_type;
     __p_type_syms;
-    __page_shift; # arm x86 mips
-    __page_size; # arm x86 mips
     __poll_chk;
-    __popcount_tab; # arm
-    __popcountsi2; # arm x86 mips
     __ppoll; # arm x86 mips
     __ppoll_chk;
     __pread64_chk;
@@ -162,7 +119,6 @@
     __pselect6; # arm x86 mips
     __pthread_cleanup_pop;
     __pthread_cleanup_push;
-    __pthread_gettid; # arm x86 mips
     __ptrace; # arm x86 mips
     __putlong;
     __putshort;
@@ -192,7 +148,6 @@
     __res_send;
     __res_send_setqhook;
     __res_send_setrhook;
-    __restore_core_regs; # arm
     __rt_sigaction; # arm x86 mips
     __rt_sigpending; # arm x86 mips
     __rt_sigprocmask; # arm x86 mips
@@ -202,28 +157,13 @@
     __sched_cpucount;
     __sched_cpufree;
     __sched_getaffinity; # arm x86 mips
-    __sclose; # arm x86 mips
-    __sdidinit; # arm x86 mips
-    __set_errno; # arm x86 mips
     __set_thread_area; # x86
     __set_tid_address; # arm x86 mips
-    __set_tls; # arm mips
     __sF;
-    __sflags; # arm x86 mips
-    __sflush; # arm x86 mips
-    __sfp; # arm x86 mips
-    __sglue; # arm x86 mips
     __sigaction; # arm x86 mips
-    __signalfd4; # arm x86 mips
-    __sinit; # arm x86 mips
-    __smakebuf; # arm x86 mips
     __snprintf_chk;
     __socket; # arm x86 mips
     __sprintf_chk;
-    __sread; # arm x86 mips
-    __srefill; # arm x86 mips
-    __srget; # arm x86 mips
-    __sseek; # arm x86 mips
     __stack_chk_fail;
     __stack_chk_guard;
     __statfs64; # arm x86 mips
@@ -240,11 +180,6 @@
     __strncpy_chk;
     __strncpy_chk2;
     __strrchr_chk;
-    __subdf3; # arm
-    __subsf3; # arm
-    __swbuf; # arm x86 mips
-    __swrite; # arm x86 mips
-    __swsetup; # arm x86 mips
     __sym_ntop;
     __sym_ntos;
     __sym_ston;
@@ -268,23 +203,14 @@
     __timer_getoverrun; # arm x86 mips
     __timer_gettime; # arm x86 mips
     __timer_settime; # arm x86 mips
-    __truncdfsf2; # arm
-    __udivdi3; # arm x86 mips
-    __udivsi3; # arm
     __umask_chk;
-    __umoddi3; # x86 mips
-    __unorddf2; # arm
-    __unordsf2; # arm
     __vsnprintf_chk;
     __vsprintf_chk;
-    __wait4; # arm x86 mips
     __waitid; # arm x86 mips
     _ctype_;
     _Exit;
     _exit;
-    _flush_cache; # mips
     _flushlbf;
-    _fwalk; # arm x86 mips
     _getlong;
     _getshort;
     _longjmp;
@@ -305,15 +231,9 @@
     alarm;
     alphasort;
     alphasort64;
-    android_getaddrinfofornet;
-    android_getaddrinfofornetcontext;
-    android_gethostbyaddrfornet;
-    android_gethostbynamefornet;
     android_set_abort_message;
     arc4random;
-    arc4random_addrandom; # arm x86 mips
     arc4random_buf;
-    arc4random_stir; # arm x86 mips
     arc4random_uniform;
     asctime;
     asctime64; # arm x86 mips
@@ -327,17 +247,13 @@
     atoll;
     basename;
     basename_r; # arm x86 mips
-    bcopy; # arm x86 mips
     bind;
     bindresvport;
     brk;
-    bsd_signal; # arm x86 mips
     bsearch;
     btowc;
-    bzero; # arm x86 mips
     c16rtomb;
     c32rtomb;
-    cacheflush; # arm mips
     calloc;
     capget;
     capset;
@@ -387,9 +303,7 @@
     dup3;
     duplocale;
     endmntent;
-    endpwent;
     endservent;
-    endusershell;
     endutent;
     environ;
     epoll_create;
@@ -421,8 +335,6 @@
     execvpe;
     exit;
     faccessat;
-    fake_gmtime_r; # arm x86 mips
-    fake_localtime_r; # arm x86 mips
     fallocate;
     fallocate64;
     fchdir;
@@ -435,7 +347,6 @@
     fdatasync;
     fdopen;
     fdopendir;
-    fdprintf; # arm x86 mips
     feof;
     feof_unlocked;
     ferror;
@@ -467,7 +378,6 @@
     fputws;
     fread;
     free;
-    free_malloc_leak_info;
     freeaddrinfo;
     freelocale;
     fremovexattr;
@@ -488,7 +398,6 @@
     fsync;
     ftell;
     ftello;
-    ftime; # arm x86 mips
     ftok;
     ftruncate;
     ftruncate64;
@@ -509,7 +418,6 @@
     fwscanf;
     gai_strerror;
     get_avphys_pages;
-    get_malloc_leak_info;
     get_nprocs;
     get_nprocs_conf;
     get_phys_pages;
@@ -521,8 +429,6 @@
     getchar_unlocked;
     getcwd;
     getdelim;
-    getdents; # arm x86 mips
-    getdtablesize; # arm x86 mips
     getegid;
     getenv;
     geteuid;
@@ -580,7 +486,6 @@
     gettid;
     gettimeofday;
     getuid;
-    getusershell;
     getutent;
     getwc;
     getwchar;
@@ -598,7 +503,6 @@
     if_nametoindex;
     imaxabs;
     imaxdiv;
-    index; # arm x86 mips
     inet_addr;
     inet_aton;
     inet_lnaof;
@@ -651,7 +555,6 @@
     isprint_l;
     ispunct;
     ispunct_l;
-    issetugid; # arm x86 mips
     isspace;
     isspace_l;
     isupper;
@@ -741,7 +644,6 @@
     mempcpy;
     memrchr;
     memset;
-    memswap; # arm x86 mips
     mincore;
     mkdir;
     mkdirat;
@@ -761,7 +663,6 @@
     mktemp;
     mktime;
     mktime64; # arm x86 mips
-    mktime_tz;
     mlock;
     mlockall;
     mmap;
@@ -780,28 +681,6 @@
     nftw64;
     nice;
     nrand48;
-    ns_format_ttl; # arm64 x86_64 mips64
-    ns_get16; # arm64 x86_64 mips64
-    ns_get32; # arm64 x86_64 mips64
-    ns_initparse; # arm64 x86_64 mips64
-    ns_makecanon; # arm64 x86_64 mips64
-    ns_msg_getflag; # arm64 x86_64 mips64
-    ns_name_compress; # arm64 x86_64 mips64
-    ns_name_ntol; # arm64 x86_64 mips64
-    ns_name_ntop; # arm64 x86_64 mips64
-    ns_name_pack; # arm64 x86_64 mips64
-    ns_name_pton; # arm64 x86_64 mips64
-    ns_name_rollback; # arm64 x86_64 mips64
-    ns_name_skip; # arm64 x86_64 mips64
-    ns_name_uncompress; # arm64 x86_64 mips64
-    ns_name_unpack; # arm64 x86_64 mips64
-    ns_parserr; # arm64 x86_64 mips64
-    ns_put16; # arm64 x86_64 mips64
-    ns_put32; # arm64 x86_64 mips64
-    ns_samename; # arm64 x86_64 mips64
-    ns_skiprr; # arm64 x86_64 mips64
-    ns_sprintrr; # arm64 x86_64 mips64
-    ns_sprintrrf; # arm64 x86_64 mips64
     nsdispatch;
     ntohl;
     ntohs;
@@ -840,7 +719,6 @@
     pread;
     pread64;
     printf;
-    prlimit; # arm64 x86_64 mips64
     prlimit64;
     process_vm_readv;
     process_vm_writev;
@@ -855,7 +733,6 @@
     pthread_attr_getschedpolicy;
     pthread_attr_getscope;
     pthread_attr_getstack;
-    pthread_attr_getstackaddr; # arm x86 mips
     pthread_attr_getstacksize;
     pthread_attr_init;
     pthread_attr_setdetachstate;
@@ -864,7 +741,6 @@
     pthread_attr_setschedpolicy;
     pthread_attr_setscope;
     pthread_attr_setstack;
-    pthread_attr_setstackaddr; # arm x86 mips
     pthread_attr_setstacksize;
     pthread_cond_broadcast;
     pthread_cond_destroy;
@@ -980,7 +856,6 @@
     res_mkquery;
     res_query;
     res_search;
-    restore_core_regs; # arm
     rewind;
     rewinddir;
     rmdir;
@@ -1051,7 +926,6 @@
     setstate;
     settimeofday;
     setuid;
-    setusershell;
     setutent;
     setvbuf;
     setxattr;
@@ -1124,8 +998,6 @@
     strncpy;
     strndup;
     strnlen;
-    strntoimax; # arm x86 mips
-    strntoumax; # arm x86 mips
     strpbrk;
     strptime;
     strrchr;
@@ -1144,7 +1016,6 @@
     strtoll;
     strtoll_l;
     strtoq;
-    strtotimeval; # arm x86 mips
     strtoul;
     strtoull;
     strtoull_l;
@@ -1166,7 +1037,6 @@
     sysinfo;
     syslog;
     system;
-    sysv_signal; # arm x86 mips
     tcdrain;
     tcflow;
     tcflush;
@@ -1198,7 +1068,6 @@
     timerfd_settime;
     times;
     timezone;
-    tkill; # arm x86 mips
     tmpfile;
     tmpnam;
     toascii;
@@ -1240,7 +1109,6 @@
     vdprintf;
     verr;
     verrx;
-    vfdprintf; # arm x86 mips
     vfork;
     vfprintf;
     vfscanf;
@@ -1260,7 +1128,6 @@
     vwprintf;
     vwscanf;
     wait;
-    wait3; # arm x86 mips
     wait4;
     waitid;
     waitpid;
@@ -1309,7 +1176,6 @@
     wcstoull;
     wcstoull_l;
     wcstoumax;
-    wcswcs; # arm x86 mips
     wcswidth;
     wcsxfrm;
     wcsxfrm_l;
@@ -1332,125 +1198,140 @@
     *;
 };
 
+LIBC_N {
+  global:
+    __fread_chk;
+    __fwrite_chk;
+    __getcwd_chk;
+    __pwrite_chk;
+    __pwrite64_chk;
+    __write_chk;
+    adjtimex;
+    clock_adjtime;
+    fgetpos64;
+    fileno_unlocked;
+    fopen64;
+    freeifaddrs;
+    freopen64;
+    fseeko64;
+    fsetpos64;
+    ftello64;
+    funopen64;
+    getgrgid_r;
+    getgrnam_r;
+    getifaddrs;
+    if_freenameindex;
+    if_nameindex;
+    in6addr_any;
+    in6addr_loopback;
+    lockf;
+    lockf64;
+    preadv;
+    preadv64;
+    prlimit; # arm mips x86
+    pthread_barrierattr_destroy;
+    pthread_barrierattr_getpshared;
+    pthread_barrierattr_init;
+    pthread_barrierattr_setpshared;
+    pthread_barrier_destroy;
+    pthread_barrier_init;
+    pthread_barrier_wait;
+    pthread_spin_destroy;
+    pthread_spin_init;
+    pthread_spin_lock;
+    pthread_spin_trylock;
+    pthread_spin_unlock;
+    pwritev;
+    pwritev64;
+    scandirat;
+    scandirat64;
+    strchrnul;
+    tmpfile64;
+} LIBC;
+
 LIBC_PRIVATE {
   global:
-    ___Unwind_Backtrace; # arm
-    ___Unwind_ForcedUnwind; # arm
-    ___Unwind_RaiseException; # arm
-    ___Unwind_Resume; # arm
-    ___Unwind_Resume_or_Rethrow; # arm
     __accept4; # arm x86 mips
-    __adddf3; # arm
-    __addsf3; # arm
-    __aeabi_atexit; # arm
-    __aeabi_cdcmpeq; # arm
-    __aeabi_cdcmple; # arm
-    __aeabi_cdrcmple; # arm
-    __aeabi_d2f; # arm
-    __aeabi_d2iz; # arm
-    __aeabi_dadd; # arm
-    __aeabi_dcmpeq; # arm
-    __aeabi_dcmpge; # arm
-    __aeabi_dcmpgt; # arm
-    __aeabi_dcmple; # arm
-    __aeabi_dcmplt; # arm
-    __aeabi_dcmpun; # arm
-    __aeabi_ddiv; # arm
-    __aeabi_dmul; # arm
-    __aeabi_drsub; # arm
-    __aeabi_dsub; # arm
-    __aeabi_f2d; # arm
-    __aeabi_f2iz; # arm
-    __aeabi_f2uiz; # arm
-    __aeabi_fadd; # arm
-    __aeabi_fcmpun; # arm
-    __aeabi_fdiv; # arm
-    __aeabi_fmul; # arm
-    __aeabi_frsub; # arm
-    __aeabi_fsub; # arm
-    __aeabi_i2d; # arm
-    __aeabi_i2f; # arm
-    __aeabi_idiv; # arm
-    __aeabi_idiv0; # arm
-    __aeabi_idivmod; # arm
-    __aeabi_l2d; # arm
-    __aeabi_l2f; # arm
-    __aeabi_lasr; # arm
-    __aeabi_ldiv0; # arm
-    __aeabi_ldivmod; # arm
-    __aeabi_llsl; # arm
-    __aeabi_llsr; # arm
-    __aeabi_lmul; # arm
-    __aeabi_memclr; # arm
-    __aeabi_memclr4; # arm
-    __aeabi_memclr8; # arm
-    __aeabi_memcpy; # arm
-    __aeabi_memcpy4; # arm
-    __aeabi_memcpy8; # arm
-    __aeabi_memmove; # arm
-    __aeabi_memmove4; # arm
-    __aeabi_memmove8; # arm
-    __aeabi_memset; # arm
-    __aeabi_memset4; # arm
-    __aeabi_memset8; # arm
-    __aeabi_ui2d; # arm
-    __aeabi_ui2f; # arm
-    __aeabi_uidiv; # arm
-    __aeabi_uidivmod; # arm
-    __aeabi_ul2d; # arm
-    __aeabi_ul2f; # arm
-    __aeabi_uldivmod; # arm
-    __aeabi_unwind_cpp_pr0; # arm
-    __aeabi_unwind_cpp_pr1; # arm
-    __aeabi_unwind_cpp_pr2; # arm
-    __arm_fadvise64_64; # arm
-    __ashldi3; # arm
-    __ashrdi3; # arm
     __bionic_brk; # arm x86 mips
     __bionic_libgcc_compat_symbols; # arm x86
-    __bionic_libgcc_unwind_symbols; # arm
-    __dso_handle; # arm
-    __gnu_Unwind_Backtrace; # arm
-    __gnu_unwind_execute; # arm
-    __gnu_Unwind_Find_exidx; # arm
-    __gnu_Unwind_ForcedUnwind; # arm
-    __gnu_unwind_frame; # arm
-    __gnu_Unwind_RaiseException; # arm
-    __gnu_Unwind_Restore_VFP; # arm
-    __gnu_Unwind_Restore_VFP_D; # arm
-    __gnu_Unwind_Restore_VFP_D_16_to_31; # arm
-    __gnu_Unwind_Restore_WMMXC; # arm
-    __gnu_Unwind_Restore_WMMXD; # arm
-    __gnu_Unwind_Resume; # arm
-    __gnu_Unwind_Resume_or_Rethrow; # arm
-    __gnu_Unwind_Save_VFP; # arm
-    __gnu_Unwind_Save_VFP_D; # arm
-    __gnu_Unwind_Save_VFP_D_16_to_31; # arm
-    __gnu_Unwind_Save_WMMXC; # arm
-    __gnu_Unwind_Save_WMMXD; # arm
-    _Unwind_Backtrace; # arm
-    _Unwind_Complete; # arm
-    _Unwind_DeleteException; # arm
-    _Unwind_ForcedUnwind; # arm
-    _Unwind_GetCFA; # arm
-    _Unwind_GetDataRelBase; # arm
-    _Unwind_GetLanguageSpecificData; # arm
-    _Unwind_GetRegionStart; # arm
-    _Unwind_GetTextRelBase; # arm
-    _Unwind_RaiseException; # arm
-    _Unwind_Resume; # arm
-    _Unwind_Resume_or_Rethrow; # arm
-    _Unwind_VRS_Get; # arm
-    _Unwind_VRS_Pop; # arm
-    _Unwind_VRS_Set; # arm
-    atexit; # arm
-    dlmalloc; # arm x86 mips
-    dlmalloc_inspect_all;
-    dlmalloc_trim;
-    dlmalloc_usable_size; # arm x86 mips
+    __divdi3; # arm x86 mips
+    __futex_wait; # arm x86 mips nobrillo
+    __futex_wake; # arm x86 mips nobrillo
+    __get_thread; # arm x86 mips nobrillo
+    __get_tls; # arm x86 mips nobrillo
+    __getdents64; # arm x86 mips
+    __open; # arm x86 mips nobrillo
+    __page_shift; # arm x86 mips nobrillo
+    __page_size; # arm x86 mips nobrillo
+    __popcountsi2; # arm x86 mips
+    __pthread_gettid; # arm x86 mips nobrillo
+    __sclose; # arm x86 mips
+    __sdidinit; # arm x86 mips nobrillo
+    __set_errno; # arm x86 mips nobrillo
+    __sflags; # arm x86 mips
+    __sflush; # arm x86 mips
+    __sfp; # arm x86 mips
+    __sglue; # arm x86 mips
+    __sinit; # arm x86 mips nobrillo
+    __smakebuf; # arm x86 mips
+    __sread; # arm x86 mips
+    __srefill; # arm x86 mips
+    __srget; # arm x86 mips
+    __sseek; # arm x86 mips
+    __swbuf; # arm x86 mips
+    __swrite; # arm x86 mips
+    __swsetup; # arm x86 mips
+    __udivdi3; # arm x86 mips
+    __umoddi3; # x86 mips
+    __wait4; # arm x86 mips nobrillo
+    _fwalk; # arm x86 mips
+    android_getaddrinfofornet;
+    android_getaddrinfofornetcontext;
+    android_gethostbyaddrfornet;
+    android_gethostbynamefornet;
+    arc4random_addrandom; # arm x86 mips nobrillo
+    arc4random_stir; # arm x86 mips nobrillo
+    bcopy; # arm x86 mips nobrillo
+    bzero; # arm x86 mips nobrillo
+    bsd_signal; # arm x86 mips nobrillo
+    dlmalloc; # arm x86 mips nobrillo
+    dlmalloc_inspect_all; # arm x86 mips nobrillo
+    dlmalloc_trim; # arm x86 mips nobrillo
+    dlmalloc_usable_size; # arm x86 mips nobrillo
+    endpwent; # arm x86 mips nobrillo
+    fdprintf; # arm x86 mips nobrillo
+    free_malloc_leak_info;
+    ftime; # arm x86 mips nobrillo
+    get_malloc_leak_info;
+    getdents; # arm x86 mips nobrillo
+    getdtablesize; # arm x86 mips nobrillo
     gMallocLeakZygoteChild;
+    index; # arm x86 mips nobrillo
+    issetugid; # arm x86 mips nobrillo
+    memswap; # arm x86 mips nobrillo
+    pthread_attr_getstackaddr; # arm x86 mips nobrillo
+    pthread_attr_setstackaddr; # arm x86 mips nobrillo
     SHA1Final; # arm x86 mips
     SHA1Init; # arm x86 mips
     SHA1Transform; # arm x86 mips
     SHA1Update; # arm x86 mips
-} LIBC;
+    strntoimax; # arm x86 mips nobrillo
+    strntoumax; # arm x86 mips nobrillo
+    strtotimeval; # arm x86 mips nobrillo
+    sysv_signal; # arm x86 mips nobrillo
+    tkill; # arm x86 mips nobrillo
+    vfdprintf; # arm x86 mips nobrillo
+    wait3; # arm x86 mips nobrillo
+    wcswcs; # arm x86 mips nobrillo
+} LIBC_N;
+
+LIBC_PLATFORM {
+  global:
+    android_net_res_stats_get_info_for_net;
+    android_net_res_stats_aggregate;
+    android_net_res_stats_get_usable_servers;
+    malloc_backtrace;
+    malloc_disable;
+    malloc_enable;
+    malloc_iterate;
+} LIBC_N;
diff --git a/libc/libc.map b/libc/libc.x86_64.map
similarity index 67%
copy from libc/libc.map
copy to libc/libc.x86_64.map
index 47c52a4..afbd0ee 100644
--- a/libc/libc.map
+++ b/libc/libc.x86_64.map
@@ -1,52 +1,25 @@
+# Generated by genversionscripts.py. Do not edit.
 LIBC {
   global:
     __assert;
     __assert2;
-    __atomic_cmpxchg; # arm
-    __atomic_dec; # arm
-    __atomic_inc; # arm
-    __atomic_swap; # arm
     __b64_ntop;
     __b64_pton;
-    __brk; # arm x86 mips
-    __cmpdf2; # arm
     __cmsg_nxthdr;
-    __connect; # arm x86 mips
     __ctype_get_mb_cur_max;
     __cxa_atexit;
     __cxa_finalize;
     __cxa_thread_atexit_impl;
-    __divdf3; # arm
-    __divdi3; # arm x86 mips
-    __divsf3; # arm
-    __divsi3; # arm
     __dn_comp;
     __dn_count_labels;
     __dn_skipname;
-    __epoll_pwait; # arm x86 mips
-    __eqdf2; # arm
     __errno;
-    __exit; # arm x86 mips
-    __extendsfdf2; # arm
-    __fadvise64; # x86 mips
     __fbufsize;
-    __fcntl64; # arm x86 mips
     __FD_CLR_chk;
     __FD_ISSET_chk;
     __FD_SET_chk;
     __fgets_chk;
-    __fixdfsi; # arm
-    __fixsfsi; # arm
-    __fixunssfsi; # arm
     __flbf;
-    __floatdidf; # arm
-    __floatdisf; # arm
-    __floatsidf; # arm
-    __floatsisf; # arm
-    __floatundidf; # arm
-    __floatundisf; # arm
-    __floatunsidf; # arm
-    __floatunsisf; # arm
     __fp_nquery;
     __fp_query;
     __fpclassify;
@@ -57,26 +30,11 @@
     __fpurge;
     __freadable;
     __fsetlocking;
-    __fstatfs64; # arm x86 mips
-    __futex_wait; # arm x86 mips
-    __futex_wake; # arm x86 mips
     __fwritable;
-    __gedf2; # arm
     __get_h_errno;
-    __get_thread; # arm x86 mips
-    __get_tls; # arm x86 mips
-    __getcpu; # arm x86 mips
-    __getcwd; # arm x86 mips
-    __getdents64; # arm x86 mips
-    __getpid; # arm x86 mips
-    __getpriority; # arm x86 mips
     __gnu_basename;
-    __gnu_ldivmod_helper; # arm
     __gnu_strerror_r;
-    __gnu_uldivmod_helper; # arm
-    __gtdf2; # arm
     __hostalias;
-    __ioctl; # arm x86 mips
     __isfinite;
     __isfinitef;
     __isfinitel;
@@ -89,52 +47,17 @@
     __isnormal;
     __isnormalf;
     __isnormall;
-    __isthreaded;
-    __ledf2; # arm
     __libc_current_sigrtmax;
     __libc_current_sigrtmin;
     __libc_init;
-    __llseek; # arm x86 mips
     __loc_aton;
     __loc_ntoa;
-    __lshrdi3; # arm
-    __ltdf2; # arm
     __memchr_chk;
     __memcpy_chk;
     __memmove_chk;
     __memrchr_chk;
     __memset_chk;
-    __mmap2; # arm x86 mips
-    __moddi3; # x86 mips
-    __muldf3; # arm
-    __muldi3; # arm
-    __mulsf3; # arm
-    __nedf2; # arm
-    __ns_format_ttl; # arm x86 mips
-    __ns_get16; # arm x86 mips
-    __ns_get32; # arm x86 mips
-    __ns_initparse; # arm x86 mips
-    __ns_makecanon; # arm x86 mips
-    __ns_msg_getflag; # arm x86 mips
-    __ns_name_compress; # arm x86 mips
-    __ns_name_ntol; # arm x86 mips
-    __ns_name_ntop; # arm x86 mips
-    __ns_name_pack; # arm x86 mips
-    __ns_name_pton; # arm x86 mips
-    __ns_name_rollback; # arm x86 mips
-    __ns_name_skip; # arm x86 mips
-    __ns_name_uncompress; # arm x86 mips
-    __ns_name_unpack; # arm x86 mips
-    __ns_parserr; # arm x86 mips
-    __ns_put16; # arm x86 mips
-    __ns_put32; # arm x86 mips
-    __ns_samename; # arm x86 mips
-    __ns_skiprr; # arm x86 mips
-    __ns_sprintrr; # arm x86 mips
-    __ns_sprintrrf; # arm x86 mips
-    __open; # arm x86 mips
     __open_2;
-    __openat; # arm x86 mips
     __openat_2;
     __p_cdname;
     __p_cdnname;
@@ -149,27 +72,18 @@
     __p_time;
     __p_type;
     __p_type_syms;
-    __page_shift; # arm x86 mips
-    __page_size; # arm x86 mips
     __poll_chk;
-    __popcount_tab; # arm
-    __popcountsi2; # arm x86 mips
-    __ppoll; # arm x86 mips
     __ppoll_chk;
     __pread64_chk;
     __pread_chk;
     __progname;
-    __pselect6; # arm x86 mips
     __pthread_cleanup_pop;
     __pthread_cleanup_push;
-    __pthread_gettid; # arm x86 mips
-    __ptrace; # arm x86 mips
     __putlong;
     __putshort;
     __read_chk;
     __readlink_chk;
     __readlinkat_chk;
-    __reboot; # arm x86 mips
     __recvfrom_chk;
     __register_atfork;
     __res_close;
@@ -192,41 +106,14 @@
     __res_send;
     __res_send_setqhook;
     __res_send_setrhook;
-    __restore_core_regs; # arm
-    __rt_sigaction; # arm x86 mips
-    __rt_sigpending; # arm x86 mips
-    __rt_sigprocmask; # arm x86 mips
-    __rt_sigsuspend; # arm x86 mips
-    __rt_sigtimedwait; # arm x86 mips
     __sched_cpualloc;
     __sched_cpucount;
     __sched_cpufree;
-    __sched_getaffinity; # arm x86 mips
-    __sclose; # arm x86 mips
-    __sdidinit; # arm x86 mips
-    __set_errno; # arm x86 mips
-    __set_thread_area; # x86
-    __set_tid_address; # arm x86 mips
-    __set_tls; # arm mips
     __sF;
-    __sflags; # arm x86 mips
-    __sflush; # arm x86 mips
-    __sfp; # arm x86 mips
-    __sglue; # arm x86 mips
-    __sigaction; # arm x86 mips
-    __signalfd4; # arm x86 mips
-    __sinit; # arm x86 mips
-    __smakebuf; # arm x86 mips
     __snprintf_chk;
-    __socket; # arm x86 mips
     __sprintf_chk;
-    __sread; # arm x86 mips
-    __srefill; # arm x86 mips
-    __srget; # arm x86 mips
-    __sseek; # arm x86 mips
     __stack_chk_fail;
     __stack_chk_guard;
-    __statfs64; # arm x86 mips
     __stpcpy_chk;
     __stpncpy_chk;
     __stpncpy_chk2;
@@ -240,11 +127,6 @@
     __strncpy_chk;
     __strncpy_chk2;
     __strrchr_chk;
-    __subdf3; # arm
-    __subsf3; # arm
-    __swbuf; # arm x86 mips
-    __swrite; # arm x86 mips
-    __swsetup; # arm x86 mips
     __sym_ntop;
     __sym_ntos;
     __sym_ston;
@@ -263,28 +145,13 @@
     __system_property_set_filename;
     __system_property_update;
     __system_property_wait_any;
-    __timer_create; # arm x86 mips
-    __timer_delete; # arm x86 mips
-    __timer_getoverrun; # arm x86 mips
-    __timer_gettime; # arm x86 mips
-    __timer_settime; # arm x86 mips
-    __truncdfsf2; # arm
-    __udivdi3; # arm x86 mips
-    __udivsi3; # arm
     __umask_chk;
-    __umoddi3; # x86 mips
-    __unorddf2; # arm
-    __unordsf2; # arm
     __vsnprintf_chk;
     __vsprintf_chk;
-    __wait4; # arm x86 mips
-    __waitid; # arm x86 mips
     _ctype_;
     _Exit;
     _exit;
-    _flush_cache; # mips
     _flushlbf;
-    _fwalk; # arm x86 mips
     _getlong;
     _getshort;
     _longjmp;
@@ -293,9 +160,7 @@
     _resolv_set_nameservers_for_net;
     _setjmp;
     _tolower;
-    _tolower_tab_; # arm x86 mips
     _toupper;
-    _toupper_tab_; # arm x86 mips
     abort;
     abs;
     accept;
@@ -305,19 +170,11 @@
     alarm;
     alphasort;
     alphasort64;
-    android_getaddrinfofornet;
-    android_getaddrinfofornetcontext;
-    android_gethostbyaddrfornet;
-    android_gethostbynamefornet;
     android_set_abort_message;
     arc4random;
-    arc4random_addrandom; # arm x86 mips
     arc4random_buf;
-    arc4random_stir; # arm x86 mips
     arc4random_uniform;
     asctime;
-    asctime64; # arm x86 mips
-    asctime64_r; # arm x86 mips
     asctime_r;
     asprintf;
     at_quick_exit;
@@ -326,18 +183,13 @@
     atol;
     atoll;
     basename;
-    basename_r; # arm x86 mips
-    bcopy; # arm x86 mips
     bind;
     bindresvport;
     brk;
-    bsd_signal; # arm x86 mips
     bsearch;
     btowc;
-    bzero; # arm x86 mips
     c16rtomb;
     c32rtomb;
-    cacheflush; # arm mips
     calloc;
     capget;
     capset;
@@ -368,8 +220,6 @@
     creat;
     creat64;
     ctime;
-    ctime64; # arm x86 mips
-    ctime64_r; # arm x86 mips
     ctime_r;
     daemon;
     daylight;
@@ -377,7 +227,6 @@
     difftime;
     dirfd;
     dirname;
-    dirname_r; # arm x86 mips
     div;
     dn_expand;
     dprintf;
@@ -387,9 +236,7 @@
     dup3;
     duplocale;
     endmntent;
-    endpwent;
     endservent;
-    endusershell;
     endutent;
     environ;
     epoll_create;
@@ -421,8 +268,6 @@
     execvpe;
     exit;
     faccessat;
-    fake_gmtime_r; # arm x86 mips
-    fake_localtime_r; # arm x86 mips
     fallocate;
     fallocate64;
     fchdir;
@@ -435,7 +280,6 @@
     fdatasync;
     fdopen;
     fdopendir;
-    fdprintf; # arm x86 mips
     feof;
     feof_unlocked;
     ferror;
@@ -467,7 +311,6 @@
     fputws;
     fread;
     free;
-    free_malloc_leak_info;
     freeaddrinfo;
     freelocale;
     fremovexattr;
@@ -488,7 +331,6 @@
     fsync;
     ftell;
     ftello;
-    ftime; # arm x86 mips
     ftok;
     ftruncate;
     ftruncate64;
@@ -509,7 +351,6 @@
     fwscanf;
     gai_strerror;
     get_avphys_pages;
-    get_malloc_leak_info;
     get_nprocs;
     get_nprocs_conf;
     get_phys_pages;
@@ -521,8 +362,6 @@
     getchar_unlocked;
     getcwd;
     getdelim;
-    getdents; # arm x86 mips
-    getdtablesize; # arm x86 mips
     getegid;
     getenv;
     geteuid;
@@ -580,14 +419,11 @@
     gettid;
     gettimeofday;
     getuid;
-    getusershell;
     getutent;
     getwc;
     getwchar;
     getxattr;
     gmtime;
-    gmtime64; # arm x86 mips
-    gmtime64_r; # arm x86 mips
     gmtime_r;
     grantpt;
     herror;
@@ -598,7 +434,6 @@
     if_nametoindex;
     imaxabs;
     imaxdiv;
-    index; # arm x86 mips
     inet_addr;
     inet_aton;
     inet_lnaof;
@@ -651,7 +486,6 @@
     isprint_l;
     ispunct;
     ispunct_l;
-    issetugid; # arm x86 mips
     isspace;
     isspace_l;
     isupper;
@@ -704,8 +538,6 @@
     llistxattr;
     localeconv;
     localtime;
-    localtime64; # arm x86 mips
-    localtime64_r; # arm x86 mips
     localtime_r;
     login_tty;
     longjmp;
@@ -741,7 +573,6 @@
     mempcpy;
     memrchr;
     memset;
-    memswap; # arm x86 mips
     mincore;
     mkdir;
     mkdirat;
@@ -760,8 +591,6 @@
     mkstemps64;
     mktemp;
     mktime;
-    mktime64; # arm x86 mips
-    mktime_tz;
     mlock;
     mlockall;
     mmap;
@@ -855,7 +684,6 @@
     pthread_attr_getschedpolicy;
     pthread_attr_getscope;
     pthread_attr_getstack;
-    pthread_attr_getstackaddr; # arm x86 mips
     pthread_attr_getstacksize;
     pthread_attr_init;
     pthread_attr_setdetachstate;
@@ -864,17 +692,12 @@
     pthread_attr_setschedpolicy;
     pthread_attr_setscope;
     pthread_attr_setstack;
-    pthread_attr_setstackaddr; # arm x86 mips
     pthread_attr_setstacksize;
     pthread_cond_broadcast;
     pthread_cond_destroy;
     pthread_cond_init;
     pthread_cond_signal;
     pthread_cond_timedwait;
-    pthread_cond_timedwait_monotonic; # arm x86 mips
-    pthread_cond_timedwait_monotonic_np; # arm x86 mips
-    pthread_cond_timedwait_relative_np; # arm x86 mips
-    pthread_cond_timeout_np; # arm x86 mips
     pthread_cond_wait;
     pthread_condattr_destroy;
     pthread_condattr_getclock;
@@ -898,7 +721,6 @@
     pthread_mutex_destroy;
     pthread_mutex_init;
     pthread_mutex_lock;
-    pthread_mutex_lock_timeout_np; # arm x86 mips
     pthread_mutex_timedlock;
     pthread_mutex_trylock;
     pthread_mutex_unlock;
@@ -939,10 +761,8 @@
     putenv;
     puts;
     pututline;
-    putw; # arm x86 mips
     putwc;
     putwchar;
-    pvalloc; # arm x86 mips
     pwrite;
     pwrite64;
     qsort;
@@ -980,7 +800,6 @@
     res_mkquery;
     res_query;
     res_search;
-    restore_core_regs; # arm
     rewind;
     rewinddir;
     rmdir;
@@ -1051,7 +870,6 @@
     setstate;
     settimeofday;
     setuid;
-    setusershell;
     setutent;
     setvbuf;
     setxattr;
@@ -1124,8 +942,6 @@
     strncpy;
     strndup;
     strnlen;
-    strntoimax; # arm x86 mips
-    strntoumax; # arm x86 mips
     strpbrk;
     strptime;
     strrchr;
@@ -1144,7 +960,6 @@
     strtoll;
     strtoll_l;
     strtoq;
-    strtotimeval; # arm x86 mips
     strtoul;
     strtoull;
     strtoull_l;
@@ -1166,7 +981,6 @@
     sysinfo;
     syslog;
     system;
-    sysv_signal; # arm x86 mips
     tcdrain;
     tcflow;
     tcflush;
@@ -1185,9 +999,7 @@
     tgkill;
     time;
     timegm;
-    timegm64; # arm x86 mips
     timelocal;
-    timelocal64; # arm x86 mips
     timer_create;
     timer_delete;
     timer_getoverrun;
@@ -1198,7 +1010,6 @@
     timerfd_settime;
     times;
     timezone;
-    tkill; # arm x86 mips
     tmpfile;
     tmpnam;
     toascii;
@@ -1235,12 +1046,10 @@
     utimensat;
     utimes;
     utmpname;
-    valloc; # arm x86 mips
     vasprintf;
     vdprintf;
     verr;
     verrx;
-    vfdprintf; # arm x86 mips
     vfork;
     vfprintf;
     vfscanf;
@@ -1260,7 +1069,6 @@
     vwprintf;
     vwscanf;
     wait;
-    wait3; # arm x86 mips
     wait4;
     waitid;
     waitpid;
@@ -1309,7 +1117,6 @@
     wcstoull;
     wcstoull_l;
     wcstoumax;
-    wcswcs; # arm x86 mips
     wcswidth;
     wcsxfrm;
     wcsxfrm_l;
@@ -1332,125 +1139,74 @@
     *;
 };
 
+LIBC_N {
+  global:
+    __fread_chk;
+    __fwrite_chk;
+    __getcwd_chk;
+    __pwrite_chk;
+    __pwrite64_chk;
+    __write_chk;
+    adjtimex;
+    clock_adjtime;
+    fgetpos64;
+    fileno_unlocked;
+    fopen64;
+    freeifaddrs;
+    freopen64;
+    fseeko64;
+    fsetpos64;
+    ftello64;
+    funopen64;
+    getgrgid_r;
+    getgrnam_r;
+    getifaddrs;
+    if_freenameindex;
+    if_nameindex;
+    in6addr_any;
+    in6addr_loopback;
+    lockf;
+    lockf64;
+    preadv;
+    preadv64;
+    pthread_barrierattr_destroy;
+    pthread_barrierattr_getpshared;
+    pthread_barrierattr_init;
+    pthread_barrierattr_setpshared;
+    pthread_barrier_destroy;
+    pthread_barrier_init;
+    pthread_barrier_wait;
+    pthread_spin_destroy;
+    pthread_spin_init;
+    pthread_spin_lock;
+    pthread_spin_trylock;
+    pthread_spin_unlock;
+    pwritev;
+    pwritev64;
+    scandirat;
+    scandirat64;
+    strchrnul;
+    tmpfile64;
+} LIBC;
+
 LIBC_PRIVATE {
   global:
-    ___Unwind_Backtrace; # arm
-    ___Unwind_ForcedUnwind; # arm
-    ___Unwind_RaiseException; # arm
-    ___Unwind_Resume; # arm
-    ___Unwind_Resume_or_Rethrow; # arm
-    __accept4; # arm x86 mips
-    __adddf3; # arm
-    __addsf3; # arm
-    __aeabi_atexit; # arm
-    __aeabi_cdcmpeq; # arm
-    __aeabi_cdcmple; # arm
-    __aeabi_cdrcmple; # arm
-    __aeabi_d2f; # arm
-    __aeabi_d2iz; # arm
-    __aeabi_dadd; # arm
-    __aeabi_dcmpeq; # arm
-    __aeabi_dcmpge; # arm
-    __aeabi_dcmpgt; # arm
-    __aeabi_dcmple; # arm
-    __aeabi_dcmplt; # arm
-    __aeabi_dcmpun; # arm
-    __aeabi_ddiv; # arm
-    __aeabi_dmul; # arm
-    __aeabi_drsub; # arm
-    __aeabi_dsub; # arm
-    __aeabi_f2d; # arm
-    __aeabi_f2iz; # arm
-    __aeabi_f2uiz; # arm
-    __aeabi_fadd; # arm
-    __aeabi_fcmpun; # arm
-    __aeabi_fdiv; # arm
-    __aeabi_fmul; # arm
-    __aeabi_frsub; # arm
-    __aeabi_fsub; # arm
-    __aeabi_i2d; # arm
-    __aeabi_i2f; # arm
-    __aeabi_idiv; # arm
-    __aeabi_idiv0; # arm
-    __aeabi_idivmod; # arm
-    __aeabi_l2d; # arm
-    __aeabi_l2f; # arm
-    __aeabi_lasr; # arm
-    __aeabi_ldiv0; # arm
-    __aeabi_ldivmod; # arm
-    __aeabi_llsl; # arm
-    __aeabi_llsr; # arm
-    __aeabi_lmul; # arm
-    __aeabi_memclr; # arm
-    __aeabi_memclr4; # arm
-    __aeabi_memclr8; # arm
-    __aeabi_memcpy; # arm
-    __aeabi_memcpy4; # arm
-    __aeabi_memcpy8; # arm
-    __aeabi_memmove; # arm
-    __aeabi_memmove4; # arm
-    __aeabi_memmove8; # arm
-    __aeabi_memset; # arm
-    __aeabi_memset4; # arm
-    __aeabi_memset8; # arm
-    __aeabi_ui2d; # arm
-    __aeabi_ui2f; # arm
-    __aeabi_uidiv; # arm
-    __aeabi_uidivmod; # arm
-    __aeabi_ul2d; # arm
-    __aeabi_ul2f; # arm
-    __aeabi_uldivmod; # arm
-    __aeabi_unwind_cpp_pr0; # arm
-    __aeabi_unwind_cpp_pr1; # arm
-    __aeabi_unwind_cpp_pr2; # arm
-    __arm_fadvise64_64; # arm
-    __ashldi3; # arm
-    __ashrdi3; # arm
-    __bionic_brk; # arm x86 mips
-    __bionic_libgcc_compat_symbols; # arm x86
-    __bionic_libgcc_unwind_symbols; # arm
-    __dso_handle; # arm
-    __gnu_Unwind_Backtrace; # arm
-    __gnu_unwind_execute; # arm
-    __gnu_Unwind_Find_exidx; # arm
-    __gnu_Unwind_ForcedUnwind; # arm
-    __gnu_unwind_frame; # arm
-    __gnu_Unwind_RaiseException; # arm
-    __gnu_Unwind_Restore_VFP; # arm
-    __gnu_Unwind_Restore_VFP_D; # arm
-    __gnu_Unwind_Restore_VFP_D_16_to_31; # arm
-    __gnu_Unwind_Restore_WMMXC; # arm
-    __gnu_Unwind_Restore_WMMXD; # arm
-    __gnu_Unwind_Resume; # arm
-    __gnu_Unwind_Resume_or_Rethrow; # arm
-    __gnu_Unwind_Save_VFP; # arm
-    __gnu_Unwind_Save_VFP_D; # arm
-    __gnu_Unwind_Save_VFP_D_16_to_31; # arm
-    __gnu_Unwind_Save_WMMXC; # arm
-    __gnu_Unwind_Save_WMMXD; # arm
-    _Unwind_Backtrace; # arm
-    _Unwind_Complete; # arm
-    _Unwind_DeleteException; # arm
-    _Unwind_ForcedUnwind; # arm
-    _Unwind_GetCFA; # arm
-    _Unwind_GetDataRelBase; # arm
-    _Unwind_GetLanguageSpecificData; # arm
-    _Unwind_GetRegionStart; # arm
-    _Unwind_GetTextRelBase; # arm
-    _Unwind_RaiseException; # arm
-    _Unwind_Resume; # arm
-    _Unwind_Resume_or_Rethrow; # arm
-    _Unwind_VRS_Get; # arm
-    _Unwind_VRS_Pop; # arm
-    _Unwind_VRS_Set; # arm
-    atexit; # arm
-    dlmalloc; # arm x86 mips
-    dlmalloc_inspect_all;
-    dlmalloc_trim;
-    dlmalloc_usable_size; # arm x86 mips
+    android_getaddrinfofornet;
+    android_getaddrinfofornetcontext;
+    android_gethostbyaddrfornet;
+    android_gethostbynamefornet;
+    free_malloc_leak_info;
+    get_malloc_leak_info;
     gMallocLeakZygoteChild;
-    SHA1Final; # arm x86 mips
-    SHA1Init; # arm x86 mips
-    SHA1Transform; # arm x86 mips
-    SHA1Update; # arm x86 mips
-} LIBC;
+} LIBC_N;
+
+LIBC_PLATFORM {
+  global:
+    android_net_res_stats_get_info_for_net;
+    android_net_res_stats_aggregate;
+    android_net_res_stats_get_usable_servers;
+    malloc_backtrace;
+    malloc_disable;
+    malloc_enable;
+    malloc_iterate;
+} LIBC_N;
diff --git a/libc/malloc_debug/Android.mk b/libc/malloc_debug/Android.mk
new file mode 100644
index 0000000..3576611
--- /dev/null
+++ b/libc/malloc_debug/Android.mk
@@ -0,0 +1,109 @@
+LOCAL_PATH := $(call my-dir)
+
+libc_malloc_debug_src_files := \
+    BacktraceData.cpp \
+    Config.cpp \
+    DebugData.cpp \
+    debug_disable.cpp \
+    FreeTrackData.cpp \
+    GuardData.cpp \
+    malloc_debug.cpp \
+    TrackData.cpp \
+
+# ==============================================================
+# libc_malloc_debug_backtrace.a
+# ==============================================================
+# Used by libmemunreachable
+include $(CLEAR_VARS)
+
+LOCAL_MODULE := libc_malloc_debug_backtrace
+
+LOCAL_SRC_FILES := \
+    backtrace.cpp \
+    MapData.cpp \
+
+LOCAL_CXX_STL := libc++_static
+
+LOCAL_STATIC_LIBRARIES += \
+    libc_logging \
+
+LOCAL_C_INCLUDES += bionic/libc
+LOCAL_EXPORT_C_INCLUDE_DIRS += $(LOCAL_PATH)
+
+LOCAL_SANITIZE := never
+LOCAL_NATIVE_COVERAGE := false
+
+# -Wno-error=format-zero-length needed for gcc to compile.
+LOCAL_CFLAGS := \
+    -Wall \
+    -Werror \
+    -Wno-error=format-zero-length \
+
+include $(BUILD_STATIC_LIBRARY)
+
+# ==============================================================
+# libc_malloc_debug.so
+# ==============================================================
+include $(CLEAR_VARS)
+
+LOCAL_MODULE := libc_malloc_debug
+
+LOCAL_SRC_FILES := \
+    $(libc_malloc_debug_src_files) \
+
+LOCAL_CXX_STL := libc++_static
+
+# Only need this for arm since libc++ uses its own unwind code that
+# doesn't mix with the other default unwind code.
+LOCAL_STATIC_LIBRARIES_arm := libunwind_llvm
+
+LOCAL_STATIC_LIBRARIES += \
+    libc_malloc_debug_backtrace \
+    libc_logging \
+
+LOCAL_LDFLAGS_32 := -Wl,--version-script,$(LOCAL_PATH)/exported32.map
+LOCAL_LDFLAGS_64 := -Wl,--version-script,$(LOCAL_PATH)/exported64.map
+LOCAL_ALLOW_UNDEFINED_SYMBOLS := true
+LOCAL_C_INCLUDES += bionic/libc
+
+LOCAL_SANITIZE := never
+LOCAL_NATIVE_COVERAGE := false
+
+# -Wno-error=format-zero-length needed for gcc to compile.
+LOCAL_CFLAGS := \
+    -Wall \
+    -Werror \
+    -fno-stack-protector \
+    -Wno-error=format-zero-length \
+
+include $(BUILD_SHARED_LIBRARY)
+
+# ==============================================================
+# Unit Tests
+# ==============================================================
+include $(CLEAR_VARS)
+
+LOCAL_MODULE := malloc_debug_unit_tests
+LOCAL_MODULE_STEM_32 := $(LOCAL_MODULE)32
+LOCAL_MODULE_STEM_64 := $(LOCAL_MODULE)64
+
+LOCAL_SRC_FILES := \
+    tests/backtrace_fake.cpp \
+    tests/log_fake.cpp \
+    tests/libc_fake.cpp \
+    tests/property_fake.cpp \
+    tests/malloc_debug_config_tests.cpp \
+    tests/malloc_debug_unit_tests.cpp \
+    $(libc_malloc_debug_src_files) \
+
+LOCAL_C_INCLUDES := $(LOCAL_PATH)/tests
+LOCAL_C_INCLUDES += bionic/libc
+
+LOCAL_SHARED_LIBRARIES := libbase
+
+LOCAL_CFLAGS := \
+    -Wall \
+    -Werror \
+    -Wno-error=format-zero-length \
+
+include $(BUILD_NATIVE_TEST)
diff --git a/libc/malloc_debug/BacktraceData.cpp b/libc/malloc_debug/BacktraceData.cpp
new file mode 100644
index 0000000..400e282
--- /dev/null
+++ b/libc/malloc_debug/BacktraceData.cpp
@@ -0,0 +1,79 @@
+/*
+ * Copyright (C) 2015 The Android Open Source Project
+ * All rights reserved.
+ *
+ * Redistribution and use in source and binary forms, with or without
+ * modification, are permitted provided that the following conditions
+ * are met:
+ *  * Redistributions of source code must retain the above copyright
+ *    notice, this list of conditions and the following disclaimer.
+ *  * Redistributions in binary form must reproduce the above copyright
+ *    notice, this list of conditions and the following disclaimer in
+ *    the documentation and/or other materials provided with the
+ *    distribution.
+ *
+ * THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS
+ * "AS IS" AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT
+ * LIMITED TO, THE IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS
+ * FOR A PARTICULAR PURPOSE ARE DISCLAIMED. IN NO EVENT SHALL THE
+ * COPYRIGHT OWNER OR CONTRIBUTORS BE LIABLE FOR ANY DIRECT, INDIRECT,
+ * INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING,
+ * BUT NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; LOSS
+ * OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED
+ * AND ON ANY THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY,
+ * OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT
+ * OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF
+ * SUCH DAMAGE.
+ */
+
+#include <errno.h>
+#include <signal.h>
+#include <stdint.h>
+#include <stdlib.h>
+#include <sys/types.h>
+#include <unistd.h>
+
+#include <private/bionic_macros.h>
+
+#include "BacktraceData.h"
+#include "Config.h"
+#include "DebugData.h"
+#include "debug_log.h"
+#include "malloc_debug.h"
+
+BacktraceData::BacktraceData(const Config& config, size_t* offset) {
+  size_t hdr_len = sizeof(BacktraceHeader) + sizeof(uintptr_t) * config.backtrace_frames;
+  alloc_offset_ = *offset;
+  *offset += BIONIC_ALIGN(hdr_len, MINIMUM_ALIGNMENT_BYTES);
+}
+
+static BacktraceData* g_backtrace_data = nullptr;
+
+static void EnableToggle(int, siginfo_t*, void*) {
+  if (g_backtrace_data->enabled()) {
+    g_backtrace_data->set_enabled(false);
+  } else {
+    g_backtrace_data->set_enabled(true);
+  }
+}
+
+bool BacktraceData::Initialize(const Config& config) {
+  enabled_ = config.backtrace_enabled;
+  if (config.backtrace_enable_on_signal) {
+    g_backtrace_data = this;
+
+    struct sigaction enable_act;
+    memset(&enable_act, 0, sizeof(enable_act));
+
+    enable_act.sa_sigaction = EnableToggle;
+    enable_act.sa_flags = SA_RESTART | SA_SIGINFO | SA_ONSTACK;
+    sigemptyset(&enable_act.sa_mask);
+    if (sigaction(config.backtrace_signal, &enable_act, nullptr) != 0) {
+      error_log("Unable to set up backtrace signal enable function: %s", strerror(errno));
+      return false;
+    }
+    info_log("%s: Run: 'kill -%d %d' to enable backtracing.", getprogname(),
+             config.backtrace_signal, getpid());
+  }
+  return true;
+}
diff --git a/libc/bionic/debug_stacktrace.h b/libc/malloc_debug/BacktraceData.h
similarity index 66%
copy from libc/bionic/debug_stacktrace.h
copy to libc/malloc_debug/BacktraceData.h
index 2cf8636..842e372 100644
--- a/libc/bionic/debug_stacktrace.h
+++ b/libc/malloc_debug/BacktraceData.h
@@ -1,5 +1,5 @@
 /*
- * Copyright (C) 2013 The Android Open Source Project
+ * Copyright (C) 2015 The Android Open Source Project
  * All rights reserved.
  *
  * Redistribution and use in source and binary forms, with or without
@@ -26,15 +26,34 @@
  * SUCH DAMAGE.
  */
 
-#ifndef DEBUG_STACKTRACE_H
-#define DEBUG_STACKTRACE_H
+#ifndef DEBUG_MALLOC_BACKTRACEDATA_H
+#define DEBUG_MALLOC_BACKTRACEDATA_H
 
 #include <stdint.h>
-#include <sys/cdefs.h>
 
-__LIBC_HIDDEN__ void backtrace_startup();
-__LIBC_HIDDEN__ void backtrace_shutdown();
-__LIBC_HIDDEN__ int get_backtrace(uintptr_t* stack_frames, size_t max_depth);
-__LIBC_HIDDEN__ void log_backtrace(uintptr_t* stack_frames, size_t frame_count);
+#include <private/bionic_macros.h>
 
-#endif /* DEBUG_STACKTRACE_H */
+// Forward declarations.
+struct Config;
+
+class BacktraceData {
+ public:
+  BacktraceData(const Config& config, size_t* offset);
+  virtual ~BacktraceData() = default;
+
+  bool Initialize(const Config& config);
+
+  inline size_t alloc_offset() { return alloc_offset_; }
+
+  bool enabled() { return enabled_; }
+  void set_enabled(bool enabled) { enabled_ = enabled; }
+
+ private:
+  size_t alloc_offset_ = 0;
+
+  volatile bool enabled_ = false;
+
+  DISALLOW_COPY_AND_ASSIGN(BacktraceData);
+};
+
+#endif // DEBUG_MALLOC_BACKTRACEDATA_H
diff --git a/libc/malloc_debug/Config.cpp b/libc/malloc_debug/Config.cpp
new file mode 100644
index 0000000..cc60086
--- /dev/null
+++ b/libc/malloc_debug/Config.cpp
@@ -0,0 +1,391 @@
+/*
+ * Copyright (C) 2015 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 <limits.h>
+#include <signal.h>
+#include <stdlib.h>
+#include <string.h>
+#include <sys/cdefs.h>
+
+#include <string>
+#include <vector>
+
+#include <sys/system_properties.h>
+
+#include <private/bionic_macros.h>
+
+#include "Config.h"
+#include "debug_log.h"
+
+// Config constants
+static constexpr uint8_t DEFAULT_FILL_ALLOC_VALUE = 0xeb;
+static constexpr uint8_t DEFAULT_FILL_FREE_VALUE = 0xef;
+
+static constexpr uint8_t DEFAULT_FRONT_GUARD_VALUE = 0xaa;
+static constexpr uint8_t DEFAULT_REAR_GUARD_VALUE = 0xbb;
+
+// Used as the default for all guard values.
+static constexpr size_t DEFAULT_GUARD_BYTES = 32;
+static constexpr size_t MAX_GUARD_BYTES = 16384;
+
+static constexpr size_t DEFAULT_BACKTRACE_FRAMES = 16;
+static constexpr size_t MAX_BACKTRACE_FRAMES = 256;
+
+static constexpr size_t DEFAULT_EXPAND_BYTES = 16;
+static constexpr size_t MAX_EXPAND_BYTES = 16384;
+
+static constexpr size_t DEFAULT_FREE_TRACK_ALLOCATIONS = 100;
+static constexpr size_t MAX_FREE_TRACK_ALLOCATIONS = 16384;
+
+struct Feature {
+  Feature(std::string name, size_t default_value, size_t min_value, size_t max_value,
+          uint64_t option, size_t* value, bool* config, bool combo_option)
+      : name(name), default_value(default_value), min_value(min_value), max_value(max_value),
+        option(option), value(value), config(config), combo_option(combo_option) {}
+  std::string name;
+  size_t default_value = 0;
+  size_t min_value = 0;
+  size_t max_value = 0;
+
+  uint64_t option = 0;
+  size_t* value = nullptr;
+  bool* config = nullptr;
+  // If set to true, then all of the options following are set on until
+  // for which the combo_option value is set.
+  bool combo_option = false;
+};
+
+class PropertyParser {
+ public:
+  PropertyParser(const char* property) : cur_(property) {}
+
+  bool Get(std::string* property, size_t* value, bool* value_set);
+
+  bool Done() { return done_; }
+
+  void LogUsage();
+
+ private:
+  const char* cur_ = nullptr;
+
+  bool done_ = false;
+
+  DISALLOW_COPY_AND_ASSIGN(PropertyParser);
+};
+
+bool PropertyParser::Get(std::string* property, size_t* value, bool* value_set) {
+  // Process each property name we can find.
+  while (isspace(*cur_))
+    ++cur_;
+
+  if (*cur_ == '\0') {
+    done_ = true;
+    return false;
+  }
+
+  const char* property_start = cur_;
+  while (!isspace(*cur_) && *cur_ != '=' && *cur_ != '\0')
+    ++cur_;
+
+  *property = std::string(property_start, cur_ - property_start);
+
+  // Skip any spaces after the name.
+  while (isspace(*cur_) && *cur_ != '=' && *cur_ != '\0')
+    ++cur_;
+
+  if (*cur_ == '=') {
+    ++cur_;
+    errno = 0;
+    *value_set = true;
+    char* end;
+    long read_value = strtol(cur_, const_cast<char**>(&end), 10);
+    if (errno != 0) {
+      error_log("%s: bad value for option '%s': %s", getprogname(), property->c_str(),
+                strerror(errno));
+      return false;
+    }
+    if (cur_ == end || (!isspace(*end) && *end != '\0')) {
+      if (cur_ == end) {
+        error_log("%s: bad value for option '%s'", getprogname(), property->c_str());
+      } else {
+        error_log("%s: bad value for option '%s', non space found after option: %s",
+                  getprogname(), property->c_str(), end);
+      }
+      return false;
+    } else if (read_value < 0) {
+      error_log("%s: bad value for option '%s', value cannot be negative: %ld",
+                getprogname(), property->c_str(), read_value);
+      return false;
+    }
+    *value = static_cast<size_t>(read_value);
+    cur_ = end;
+  } else {
+    *value_set = false;
+  }
+  return true;
+}
+
+void PropertyParser::LogUsage() {
+  error_log("malloc debug options usage:");
+  error_log("");
+  error_log("  front_guard[=XX]");
+  error_log("    Enables a front guard on all allocations. If XX is set");
+  error_log("    it sets the number of bytes in the guard. The default is");
+  error_log("    %zu bytes, the max bytes is %zu.", DEFAULT_GUARD_BYTES, MAX_GUARD_BYTES);
+  error_log("");
+  error_log("  rear_guard[=XX]");
+  error_log("    Enables a rear guard on all allocations. If XX is set");
+  error_log("    it sets the number of bytes in the guard. The default is");
+  error_log("    %zu bytes, the max bytes is %zu.", DEFAULT_GUARD_BYTES, MAX_GUARD_BYTES);
+  error_log("");
+  error_log("  guard[=XX]");
+  error_log("    Enables both a front guard and a rear guard on all allocations.");
+  error_log("    If XX is set it sets the number of bytes in both guards.");
+  error_log("    The default is %zu bytes, the max bytes is %zu.",
+            DEFAULT_GUARD_BYTES, MAX_GUARD_BYTES);
+  error_log("");
+  error_log("  backtrace[=XX]");
+  error_log("    Enable capturing the backtrace at the point of allocation.");
+  error_log("    If XX is set it sets the number of backtrace frames.");
+  error_log("    The default is %zu frames, the max number of frames is %zu.",
+            DEFAULT_BACKTRACE_FRAMES, MAX_BACKTRACE_FRAMES);
+  error_log("");
+  error_log("  backtrace_enable_on_signal[=XX]");
+  error_log("    Enable capturing the backtrace at the point of allocation.");
+  error_log("    The backtrace capture is not enabled until the process");
+  error_log("    receives a signal. If XX is set it sets the number of backtrace");
+  error_log("    frames. The default is %zu frames, the max number of frames is %zu.",
+            DEFAULT_BACKTRACE_FRAMES, MAX_BACKTRACE_FRAMES);
+  error_log("");
+  error_log("  fill_on_alloc[=XX]");
+  error_log("    On first allocation, fill with the value 0x%02x.", DEFAULT_FILL_ALLOC_VALUE);
+  error_log("    If XX is set it will only fill up to XX bytes of the");
+  error_log("    allocation. The default is to fill the entire allocation.");
+  error_log("");
+  error_log("  fill_on_free[=XX]");
+  error_log("    On free, fill with the value 0x%02x. If XX is set it will",
+            DEFAULT_FILL_FREE_VALUE);
+  error_log("    only fill up to XX bytes of the allocation. The default is to");
+  error_log("    fill the entire allocation.");
+  error_log("");
+  error_log("  fill[=XX]");
+  error_log("    On both first allocation free, fill with the value 0x%02x on",
+            DEFAULT_FILL_ALLOC_VALUE);
+  error_log("    first allocation and the value 0x%02x. If XX is set, only fill",
+            DEFAULT_FILL_FREE_VALUE);
+  error_log("    up to XX bytes. The default is to fill the entire allocation.");
+  error_log("");
+  error_log("  expand_alloc[=XX]");
+  error_log("    Allocate an extra number of bytes for every allocation call.");
+  error_log("    If XX is set, that is the number of bytes to expand the");
+  error_log("    allocation by. The default is %zu bytes, the max bytes is %zu.",
+            DEFAULT_EXPAND_BYTES, MAX_EXPAND_BYTES);
+  error_log("");
+  error_log("  free_track[=XX]");
+  error_log("    When a pointer is freed, do not free the memory right away.");
+  error_log("    Instead, keep XX of these allocations around and then verify");
+  error_log("    that they have not been modified when the total number of freed");
+  error_log("    allocations exceeds the XX amount. When the program terminates,");
+  error_log("    the rest of these allocations are verified. When this option is");
+  error_log("    enabled, it automatically records the backtrace at the time of the free.");
+  error_log("    The default is to record %zu allocations, the max allocations",
+            DEFAULT_FREE_TRACK_ALLOCATIONS);
+  error_log("    to record is %zu.", MAX_FREE_TRACK_ALLOCATIONS);
+  error_log("");
+  error_log("  free_track_backtrace_num_frames[=XX]");
+  error_log("    This option only has meaning if free_track is set. This indicates");
+  error_log("    how many backtrace frames to capture when an allocation is freed.");
+  error_log("    If XX is set, that is the number of frames to capture. If XX");
+  error_log("    is set to zero, then no backtrace will be captured.");
+  error_log("    The default is to record %zu frames, the max number of frames is %zu.",
+            DEFAULT_BACKTRACE_FRAMES, MAX_BACKTRACE_FRAMES);
+  error_log("");
+  error_log("  leak_track");
+  error_log("    Enable the leak tracking of memory allocations.");
+}
+
+static bool SetFeature(
+    const std::string name, const Feature& feature, size_t value, bool value_set) {
+  if (feature.config) {
+    *feature.config = true;
+  }
+  if (feature.value != nullptr) {
+    if (value_set) {
+      if (value < feature.min_value) {
+        error_log("%s: bad value for option '%s', value must be >= %zu: %zu",
+                  getprogname(), name.c_str(), feature.min_value, value);
+        return false;
+      } else if (value > feature.max_value) {
+        error_log("%s: bad value for option '%s', value must be <= %zu: %zu",
+                  getprogname(), name.c_str(), feature.max_value, value);
+        return false;
+      }
+      *feature.value = value;
+    } else {
+      *feature.value = feature.default_value;
+    }
+  } else if (value_set) {
+     error_log("%s: value set for option '%s' which does not take a value",
+               getprogname(), name.c_str());
+     return false;
+  }
+  return true;
+}
+
+// This function is designed to be called once. A second call will not
+// reset all variables.
+bool Config::SetFromProperties() {
+  char property_str[PROP_VALUE_MAX];
+  memset(property_str, 0, sizeof(property_str));
+  if (!__system_property_get("libc.debug.malloc.options", property_str)) {
+    return false;
+  }
+
+  // Initialize a few default values.
+  fill_alloc_value = DEFAULT_FILL_ALLOC_VALUE;
+  fill_free_value = DEFAULT_FILL_FREE_VALUE;
+  front_guard_value = DEFAULT_FRONT_GUARD_VALUE;
+  rear_guard_value = DEFAULT_REAR_GUARD_VALUE;
+  backtrace_signal = SIGRTMAX - 19;
+  free_track_backtrace_num_frames = 16;
+
+  // Parse the options are of the format:
+  //   option_name or option_name=XX
+
+  // Supported features:
+  const Feature features[] = {
+    Feature("guard", DEFAULT_GUARD_BYTES, 1, MAX_GUARD_BYTES, 0, nullptr, nullptr, true),
+    // Enable front guard. Value is the size of the guard.
+    Feature("front_guard", DEFAULT_GUARD_BYTES, 1, MAX_GUARD_BYTES, FRONT_GUARD,
+            &this->front_guard_bytes, nullptr, true),
+    // Enable end guard. Value is the size of the guard.
+    Feature("rear_guard", DEFAULT_GUARD_BYTES, 1, MAX_GUARD_BYTES, REAR_GUARD,
+            &this->rear_guard_bytes, nullptr, true),
+
+    // Enable logging the backtrace on allocation. Value is the total
+    // number of frames to log.
+    Feature("backtrace", DEFAULT_BACKTRACE_FRAMES, 1, MAX_BACKTRACE_FRAMES,
+            BACKTRACE | TRACK_ALLOCS, &this->backtrace_frames, &this->backtrace_enabled, false),
+    // Enable gathering backtrace values on a signal.
+    Feature("backtrace_enable_on_signal", DEFAULT_BACKTRACE_FRAMES, 1, MAX_BACKTRACE_FRAMES,
+            BACKTRACE | TRACK_ALLOCS, &this->backtrace_frames, &this->backtrace_enable_on_signal,
+            false),
+
+    Feature("fill", SIZE_MAX, 1, SIZE_MAX, 0, nullptr, nullptr, true),
+    // Fill the allocation with an arbitrary pattern on allocation.
+    // Value is the number of bytes of the allocation to fill
+    // (default entire allocation).
+    Feature("fill_on_alloc", SIZE_MAX, 1, SIZE_MAX, FILL_ON_ALLOC, &this->fill_on_alloc_bytes,
+            nullptr, true),
+    // Fill the allocation with an arbitrary pattern on free.
+    // Value is the number of bytes of the allocation to fill
+    // (default entire allocation).
+    Feature("fill_on_free", SIZE_MAX, 1, SIZE_MAX, FILL_ON_FREE, &this->fill_on_free_bytes, nullptr, true),
+
+    // Expand the size of every alloc by this number bytes. Value is
+    // the total number of bytes to expand every allocation by.
+    Feature ("expand_alloc", DEFAULT_EXPAND_BYTES, 1, MAX_EXPAND_BYTES, EXPAND_ALLOC,
+             &this->expand_alloc_bytes, nullptr, false),
+
+    // Keep track of the freed allocations and verify at a later date
+    // that they have not been used. Turning this on, also turns on
+    // fill on free.
+    Feature("free_track", DEFAULT_FREE_TRACK_ALLOCATIONS, 1, MAX_FREE_TRACK_ALLOCATIONS,
+            FREE_TRACK | FILL_ON_FREE, &this->free_track_allocations, nullptr, false),
+    // Number of backtrace frames to keep when free_track is enabled. If this
+    // value is set to zero, no backtrace will be kept.
+    Feature("free_track_backtrace_num_frames", DEFAULT_BACKTRACE_FRAMES,
+            0, MAX_BACKTRACE_FRAMES, 0, &this->free_track_backtrace_num_frames, nullptr, false),
+
+    // Enable printing leaked allocations.
+    Feature("leak_track", 0, 0, 0, LEAK_TRACK | TRACK_ALLOCS, nullptr, nullptr, false),
+  };
+
+  // Process each property name we can find.
+  std::string property;
+  size_t value;
+  bool value_set;
+  PropertyParser parser(property_str);
+  bool valid = true;
+  while (valid && parser.Get(&property, &value, &value_set)) {
+    bool found = false;
+    for (size_t i = 0; i < sizeof(features)/sizeof(Feature); i++) {
+      if (property == features[i].name) {
+        if (features[i].option == 0 && features[i].combo_option) {
+          i++;
+          for (; i < sizeof(features)/sizeof(Feature) && features[i].combo_option; i++) {
+            if (!SetFeature(property, features[i], value, value_set)) {
+              valid = false;
+              break;
+            }
+            options |= features[i].option;
+          }
+          if (!valid) {
+            break;
+          }
+        } else {
+          if (!SetFeature(property, features[i], value, value_set)) {
+            valid = false;
+            break;
+          }
+          options |= features[i].option;
+        }
+        found = true;
+        break;
+      }
+    }
+    if (valid && !found) {
+      error_log("%s: unknown option %s", getprogname(), property.c_str());
+      valid = false;
+      break;
+    }
+  }
+
+  valid = valid && parser.Done();
+
+  if (valid) {
+    // It's necessary to align the front guard to MINIMUM_ALIGNMENT_BYTES to
+    // make sure that the header is aligned properly.
+    if (options & FRONT_GUARD) {
+      front_guard_bytes = BIONIC_ALIGN(front_guard_bytes, MINIMUM_ALIGNMENT_BYTES);
+    }
+
+    // This situation can occur if the free_track option is specified and
+    // the fill_on_free option is not. In this case, indicate the whole
+    // allocation should be filled.
+    if ((options & FILL_ON_FREE) && fill_on_free_bytes == 0) {
+      fill_on_free_bytes = SIZE_MAX;
+    }
+  } else {
+    parser.LogUsage();
+  }
+
+  return valid;
+}
diff --git a/libc/malloc_debug/Config.h b/libc/malloc_debug/Config.h
new file mode 100644
index 0000000..cb1de5a
--- /dev/null
+++ b/libc/malloc_debug/Config.h
@@ -0,0 +1,81 @@
+/*
+ * Copyright (C) 2015 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 MALLOC_DEBUG_CONFIG_H
+#define MALLOC_DEBUG_CONFIG_H
+
+#include <stdint.h>
+
+constexpr uint64_t FRONT_GUARD = 0x1;
+constexpr uint64_t REAR_GUARD = 0x2;
+constexpr uint64_t BACKTRACE = 0x4;
+constexpr uint64_t FILL_ON_ALLOC = 0x8;
+constexpr uint64_t FILL_ON_FREE = 0x10;
+constexpr uint64_t EXPAND_ALLOC = 0x20;
+constexpr uint64_t FREE_TRACK = 0x40;
+constexpr uint64_t TRACK_ALLOCS = 0x80;
+constexpr uint64_t LEAK_TRACK = 0x100;
+
+// In order to guarantee posix compliance, set the minimum alignment
+// to 8 bytes for 32 bit systems and 16 bytes for 64 bit systems.
+#if defined(__LP64__)
+constexpr size_t MINIMUM_ALIGNMENT_BYTES = 16;
+#else
+constexpr size_t MINIMUM_ALIGNMENT_BYTES = 8;
+#endif
+
+// If only one or more of these options is set, then no special header is needed.
+constexpr uint64_t NO_HEADER_OPTIONS = FILL_ON_ALLOC | FILL_ON_FREE | EXPAND_ALLOC;
+
+struct Config {
+  bool SetFromProperties();
+
+  size_t front_guard_bytes = 0;
+  size_t rear_guard_bytes = 0;
+
+  bool backtrace_enable_on_signal = false;
+  int backtrace_signal = 0;
+  bool backtrace_enabled = false;
+  size_t backtrace_frames = 0;
+
+  size_t fill_on_alloc_bytes = 0;
+  size_t fill_on_free_bytes = 0;
+
+  size_t expand_alloc_bytes = 0;
+
+  size_t free_track_allocations = 0;
+  size_t free_track_backtrace_num_frames = 0;
+
+  uint64_t options = 0;
+  uint8_t fill_alloc_value;
+  uint8_t fill_free_value;
+  uint8_t front_guard_value;
+  uint8_t rear_guard_value;
+};
+
+#endif  // MALLOC_DEBUG_CONFIG_H
diff --git a/libc/malloc_debug/DebugData.cpp b/libc/malloc_debug/DebugData.cpp
new file mode 100644
index 0000000..0447566
--- /dev/null
+++ b/libc/malloc_debug/DebugData.cpp
@@ -0,0 +1,102 @@
+/*
+ * Copyright (C) 2015 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 <stdint.h>
+
+#include "BacktraceData.h"
+#include "Config.h"
+#include "DebugData.h"
+#include "debug_disable.h"
+#include "FreeTrackData.h"
+#include "GuardData.h"
+#include "malloc_debug.h"
+#include "TrackData.h"
+
+bool DebugData::Initialize() {
+  if (!config_.SetFromProperties()) {
+    return false;
+  }
+
+  // Check to see if the options that require a header are enabled.
+  if ((config_.options & ~(NO_HEADER_OPTIONS)) != 0) {
+    need_header_ = true;
+
+    // Initialize all of the static header offsets.
+    pointer_offset_ = BIONIC_ALIGN(sizeof(Header), MINIMUM_ALIGNMENT_BYTES);
+
+    if (config_.options & BACKTRACE) {
+      backtrace.reset(new BacktraceData(config_, &pointer_offset_));
+      if (!backtrace->Initialize(config_)) {
+        return false;
+      }
+    }
+
+    if (config_.options & FRONT_GUARD) {
+      front_guard.reset(new FrontGuardData(config_, &pointer_offset_));
+    }
+
+    extra_bytes_ = pointer_offset_;
+
+    // Initialize all of the non-header data.
+    if (config_.options & REAR_GUARD) {
+      rear_guard.reset(new RearGuardData(config_));
+      extra_bytes_ += config_.rear_guard_bytes;
+    }
+
+    if (config_.options & FREE_TRACK) {
+      free_track.reset(new FreeTrackData(config_));
+    }
+
+    if (config_.options & TRACK_ALLOCS) {
+      track.reset(new TrackData());
+    }
+  }
+
+  if (config_.options & EXPAND_ALLOC) {
+    extra_bytes_ += config_.expand_alloc_bytes;
+  }
+  return true;
+}
+
+void DebugData::PrepareFork() {
+  if (track != nullptr) {
+    track->PrepareFork();
+  }
+}
+
+void DebugData::PostForkParent() {
+  if (track != nullptr) {
+    track->PostForkParent();
+  }
+}
+
+void DebugData::PostForkChild() {
+  if (track != nullptr) {
+    track->PostForkChild();
+  }
+}
diff --git a/libc/malloc_debug/DebugData.h b/libc/malloc_debug/DebugData.h
new file mode 100644
index 0000000..4600b33
--- /dev/null
+++ b/libc/malloc_debug/DebugData.h
@@ -0,0 +1,106 @@
+/*
+ * Copyright (C) 2015 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 DEBUG_MALLOC_DEBUGDATA_H
+#define DEBUG_MALLOC_DEBUGDATA_H
+
+#include <stdint.h>
+
+#include <memory>
+#include <vector>
+
+#include <private/bionic_macros.h>
+
+#include "BacktraceData.h"
+#include "Config.h"
+#include "FreeTrackData.h"
+#include "GuardData.h"
+#include "malloc_debug.h"
+#include "TrackData.h"
+
+class DebugData {
+ public:
+  DebugData() = default;
+  ~DebugData() = default;
+
+  bool Initialize();
+
+  static bool Disabled();
+
+  inline void* GetPointer(const Header* header) {
+    uintptr_t value = reinterpret_cast<uintptr_t>(header);
+    return reinterpret_cast<void*>(value + pointer_offset_);
+  }
+
+  Header* GetHeader(const void* pointer) {
+    uintptr_t value = reinterpret_cast<uintptr_t>(pointer);
+    return reinterpret_cast<Header*>(value - pointer_offset_);
+  }
+
+  BacktraceHeader* GetAllocBacktrace(const Header* header) {
+    uintptr_t value = reinterpret_cast<uintptr_t>(header);
+    return reinterpret_cast<BacktraceHeader*>(value + backtrace->alloc_offset());
+  }
+
+  uint8_t* GetFrontGuard(const Header* header) {
+    uintptr_t value = reinterpret_cast<uintptr_t>(header);
+    return reinterpret_cast<uint8_t*>(value + front_guard->offset());
+  }
+
+  uint8_t* GetRearGuard(const Header* header) {
+    uintptr_t value = reinterpret_cast<uintptr_t>(GetPointer(header));
+    return reinterpret_cast<uint8_t*>(value + header->real_size());
+  }
+
+  const Config& config() { return config_; }
+  size_t pointer_offset() { return pointer_offset_; }
+  bool need_header() { return need_header_; }
+  size_t extra_bytes() { return extra_bytes_; }
+
+  void PrepareFork();
+  void PostForkParent();
+  void PostForkChild();
+
+  std::unique_ptr<BacktraceData> backtrace;
+  std::unique_ptr<TrackData> track;
+  std::unique_ptr<FrontGuardData> front_guard;
+  std::unique_ptr<RearGuardData> rear_guard;
+  std::unique_ptr<FreeTrackData> free_track;
+
+ private:
+  size_t extra_bytes_ = 0;
+
+  size_t pointer_offset_ = 0;
+  bool need_header_ = false;
+
+  Config config_;
+
+  DISALLOW_COPY_AND_ASSIGN(DebugData);
+};
+
+#endif // MALLOC_DEBUG_DEBUGDATA_H
diff --git a/libc/malloc_debug/FreeTrackData.cpp b/libc/malloc_debug/FreeTrackData.cpp
new file mode 100644
index 0000000..470f40b
--- /dev/null
+++ b/libc/malloc_debug/FreeTrackData.cpp
@@ -0,0 +1,141 @@
+/*
+ * Copyright (C) 2015 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 <stdint.h>
+
+#include "backtrace.h"
+#include "Config.h"
+#include "DebugData.h"
+#include "debug_disable.h"
+#include "debug_log.h"
+#include "FreeTrackData.h"
+#include "malloc_debug.h"
+
+FreeTrackData::FreeTrackData(const Config& config)
+    : backtrace_num_frames_(config.free_track_backtrace_num_frames) {
+  cmp_mem_.resize(4096);
+  memset(cmp_mem_.data(), config.fill_free_value, cmp_mem_.size());
+}
+
+void FreeTrackData::LogFreeError(DebugData& debug, const Header* header,
+                                 const uint8_t* pointer) {
+  ScopedDisableDebugCalls disable;
+
+  error_log(LOG_DIVIDER);
+  error_log("+++ ALLOCATION %p USED AFTER FREE", pointer);
+  uint8_t fill_free_value = debug.config().fill_free_value;
+  for (size_t i = 0; i < header->usable_size; i++) {
+    if (pointer[i] != fill_free_value) {
+      error_log("  allocation[%zu] = 0x%02x (expected 0x%02x)", i, pointer[i], fill_free_value);
+    }
+  }
+  auto back_iter = backtraces_.find(header);
+  if (back_iter != backtraces_.end()) {
+    const BacktraceHeader* back_header = back_iter->second;
+    error_log("Backtrace at time of free:");
+    backtrace_log(&back_header->frames[0], back_header->num_frames);
+  }
+  error_log(LOG_DIVIDER);
+}
+
+void FreeTrackData::VerifyAndFree(DebugData& debug, const Header* header,
+                                  const void* pointer) {
+  ScopedDisableDebugCalls disable;
+
+  if (header->tag != DEBUG_FREE_TAG) {
+    error_log(LOG_DIVIDER);
+    error_log("+++ ALLOCATION %p HAS CORRUPTED HEADER TAG 0x%x AFTER FREE", pointer, header->tag);
+    error_log(LOG_DIVIDER);
+  } else {
+    const uint8_t* memory = reinterpret_cast<const uint8_t*>(pointer);
+    size_t bytes = header->usable_size;
+    bytes = (bytes < debug.config().fill_on_free_bytes) ? bytes : debug.config().fill_on_free_bytes;
+    while (bytes > 0) {
+      size_t bytes_to_cmp = (bytes < cmp_mem_.size()) ? bytes : cmp_mem_.size();
+      if (memcmp(memory, cmp_mem_.data(), bytes_to_cmp) != 0) {
+        LogFreeError(debug, header, reinterpret_cast<const uint8_t*>(pointer));
+        break;
+      }
+      bytes -= bytes_to_cmp;
+      memory = &memory[bytes_to_cmp];
+    }
+  }
+
+  auto back_iter = backtraces_.find(header);
+  if (back_iter != backtraces_.end()) {
+    g_dispatch->free(reinterpret_cast<void*>(back_iter->second));
+    backtraces_.erase(header);
+  }
+  g_dispatch->free(header->orig_pointer);
+}
+
+void FreeTrackData::Add(DebugData& debug, const Header* header) {
+  // Make sure the stl calls below don't call the debug_XXX functions.
+  ScopedDisableDebugCalls disable;
+
+  pthread_mutex_lock(&mutex_);
+  if (list_.size() == debug.config().free_track_allocations) {
+    const Header* old_header = list_.back();
+    VerifyAndFree(debug, old_header, debug.GetPointer(old_header));
+    list_.pop_back();
+  }
+
+  if (backtrace_num_frames_ > 0) {
+    BacktraceHeader* back_header = reinterpret_cast<BacktraceHeader*>(
+      g_dispatch->malloc(sizeof(BacktraceHeader) + backtrace_num_frames_ * sizeof(uintptr_t)));
+    if (back_header) {
+      back_header->num_frames = backtrace_get(&back_header->frames[0], backtrace_num_frames_);
+      backtraces_[header] = back_header;
+    }
+  }
+  list_.push_front(header);
+
+  pthread_mutex_unlock(&mutex_);
+}
+
+void FreeTrackData::VerifyAll(DebugData& debug) {
+  // Make sure the stl calls below don't call the debug_XXX functions.
+  ScopedDisableDebugCalls disable;
+
+  for (const auto& header : list_) {
+    VerifyAndFree(debug, header, debug.GetPointer(header));
+  }
+  list_.clear();
+}
+
+void FreeTrackData::LogBacktrace(const Header* header) {
+  ScopedDisableDebugCalls disable;
+
+  auto back_iter = backtraces_.find(header);
+  if (back_iter == backtraces_.end()) {
+    return;
+  }
+
+  error_log("Backtrace of original free:");
+  backtrace_log(&back_iter->second->frames[0], back_iter->second->num_frames);
+}
diff --git a/libc/malloc_debug/FreeTrackData.h b/libc/malloc_debug/FreeTrackData.h
new file mode 100644
index 0000000..804b5a6
--- /dev/null
+++ b/libc/malloc_debug/FreeTrackData.h
@@ -0,0 +1,71 @@
+/*
+ * Copyright (C) 2015 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 DEBUG_MALLOC_FREETRACKDATA_H
+#define DEBUG_MALLOC_FREETRACKDATA_H
+
+#include <stdint.h>
+#include <pthread.h>
+
+#include <deque>
+#include <unordered_map>
+#include <vector>
+
+#include <private/bionic_macros.h>
+
+// Forward declarations.
+struct Header;
+class DebugData;
+struct Config;
+struct BacktraceHeader;
+
+class FreeTrackData {
+ public:
+  FreeTrackData(const Config& config);
+  virtual ~FreeTrackData() = default;
+
+  void Add(DebugData& debug, const Header* header);
+
+  void VerifyAll(DebugData& debug);
+
+  void LogBacktrace(const Header* header);
+
+ private:
+  void LogFreeError(DebugData& debug, const Header* header, const uint8_t* pointer);
+  void VerifyAndFree(DebugData& debug, const Header* header, const void* pointer);
+
+  pthread_mutex_t mutex_ = PTHREAD_MUTEX_INITIALIZER;
+  std::deque<const Header*> list_;
+  std::vector<uint8_t> cmp_mem_;
+  std::unordered_map<const Header*, BacktraceHeader*> backtraces_;
+  size_t backtrace_num_frames_;
+
+  DISALLOW_COPY_AND_ASSIGN(FreeTrackData);
+};
+
+#endif // DEBUG_MALLOC_FREETRACKDATA_H
diff --git a/libc/malloc_debug/GuardData.cpp b/libc/malloc_debug/GuardData.cpp
new file mode 100644
index 0000000..97b16ff
--- /dev/null
+++ b/libc/malloc_debug/GuardData.cpp
@@ -0,0 +1,101 @@
+/*
+ * Copyright (C) 2015 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 <stdint.h>
+#include <string.h>
+
+#include <vector>
+
+#include "backtrace.h"
+#include "Config.h"
+#include "debug_disable.h"
+#include "debug_log.h"
+#include "DebugData.h"
+#include "malloc_debug.h"
+#include "GuardData.h"
+
+GuardData::GuardData(int init_value, size_t num_bytes) {
+  // Create a buffer for fast comparisons of the front guard.
+  cmp_mem_.resize(num_bytes);
+  memset(cmp_mem_.data(), init_value, cmp_mem_.size());
+}
+
+void GuardData::LogFailure(const Header* header, const void* pointer, const void* data) {
+  ScopedDisableDebugCalls disable;
+
+  error_log(LOG_DIVIDER);
+  error_log("+++ ALLOCATION %p SIZE %zu HAS A CORRUPTED %s GUARD", pointer,
+            header->real_size(), GetTypeName());
+
+  // Log all of the failing bytes.
+  const uint8_t* expected = cmp_mem_.data();
+  int pointer_idx = reinterpret_cast<uintptr_t>(data) - reinterpret_cast<uintptr_t>(pointer);
+  const uint8_t* real = reinterpret_cast<const uint8_t*>(data);
+  for (size_t i = 0; i < cmp_mem_.size(); i++, pointer_idx++) {
+    if (real[i] != expected[i]) {
+      error_log("  allocation[%d] = 0x%02x (expected 0x%02x)", pointer_idx, real[i], expected[i]);
+    }
+  }
+
+  error_log("Backtrace at time of failure:");
+  std::vector<uintptr_t> frames(64);
+  size_t frame_num = backtrace_get(frames.data(), frames.size());
+  frames.resize(frame_num);
+  backtrace_log(frames.data(), frames.size());
+  error_log(LOG_DIVIDER);
+}
+
+FrontGuardData::FrontGuardData(const Config& config, size_t* offset)
+   : GuardData(config.front_guard_value, config.front_guard_bytes) {
+  // Create a buffer for fast comparisons of the front guard.
+  cmp_mem_.resize(config.front_guard_bytes);
+  memset(cmp_mem_.data(), config.front_guard_value, cmp_mem_.size());
+  // Assumes that front_bytes is a multiple of MINIMUM_ALIGNMENT_BYTES.
+  offset_ = *offset;
+  *offset += config.front_guard_bytes;
+}
+
+bool FrontGuardData::Valid(DebugData& debug, const Header* header) {
+  return GuardData::Valid(debug.GetFrontGuard(header));
+}
+
+void FrontGuardData::LogFailure(DebugData& debug, const Header* header) {
+  GuardData::LogFailure(header, debug.GetPointer(header), debug.GetFrontGuard(header));
+}
+
+RearGuardData::RearGuardData(const Config& config)
+    : GuardData(config.rear_guard_value, config.rear_guard_bytes) {
+}
+
+bool RearGuardData::Valid(DebugData& debug, const Header* header) {
+  return GuardData::Valid(debug.GetRearGuard(header));
+}
+
+void RearGuardData::LogFailure(DebugData& debug, const Header* header) {
+  GuardData::LogFailure(header, debug.GetPointer(header), debug.GetRearGuard(header));
+}
diff --git a/libc/malloc_debug/GuardData.h b/libc/malloc_debug/GuardData.h
new file mode 100644
index 0000000..4de2702
--- /dev/null
+++ b/libc/malloc_debug/GuardData.h
@@ -0,0 +1,95 @@
+/*
+ * Copyright (C) 2015 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 DEBUG_MALLOC_GUARDDATA_H
+#define DEBUG_MALLOC_GUARDDATA_H
+
+#include <stdint.h>
+#include <string.h>
+
+#include <vector>
+
+#include <private/bionic_macros.h>
+
+// Forward declarations.
+class DebugData;
+struct Header;
+struct Config;
+
+class GuardData {
+ public:
+  GuardData(int init_value, size_t num_bytes);
+  virtual ~GuardData() = default;
+
+  bool Valid(void* data) { return memcmp(data, cmp_mem_.data(), cmp_mem_.size()) == 0; }
+
+  void LogFailure(const Header* header, const void* pointer, const void* data);
+
+ protected:
+  std::vector<uint8_t> cmp_mem_;
+
+  virtual const char* GetTypeName() = 0;
+
+  DISALLOW_COPY_AND_ASSIGN(GuardData);
+};
+
+class FrontGuardData : public GuardData {
+ public:
+  FrontGuardData(const Config& config, size_t* offset);
+  virtual ~FrontGuardData() = default;
+
+  bool Valid(DebugData& debug, const Header* header);
+
+  void LogFailure(DebugData& debug, const Header* header);
+
+  size_t offset() { return offset_; }
+
+ private:
+  const char* GetTypeName() override { return "FRONT"; }
+
+  size_t offset_ = 0;
+
+  DISALLOW_COPY_AND_ASSIGN(FrontGuardData);
+};
+
+class RearGuardData : public GuardData {
+ public:
+  RearGuardData(const Config& config);
+  virtual ~RearGuardData() = default;
+
+  bool Valid(DebugData& debug, const Header* header);
+
+  void LogFailure(DebugData& debug, const Header* header);
+
+ private:
+  const char* GetTypeName() override { return "REAR"; }
+
+  DISALLOW_COPY_AND_ASSIGN(RearGuardData);
+};
+
+#endif // DEBUG_MALLOC_GUARDDATA_H
diff --git a/libc/malloc_debug/MapData.cpp b/libc/malloc_debug/MapData.cpp
new file mode 100644
index 0000000..d57017e
--- /dev/null
+++ b/libc/malloc_debug/MapData.cpp
@@ -0,0 +1,168 @@
+/*
+ * Copyright (C) 2012 The Android Open Source Project
+ * All rights reserved.
+ *
+ * Redistribution and use in source and binary forms, with or without
+ * modification, are permitted provided that the following conditions
+ * are met:
+ *  * Redistributions of source code must retain the above copyright
+ *    notice, this list of conditions and the following disclaimer.
+ *  * Redistributions in binary form must reproduce the above copyright
+ *    notice, this list of conditions and the following disclaimer in
+ *    the documentation and/or other materials provided with the
+ *    distribution.
+ *
+ * THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS
+ * "AS IS" AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT
+ * LIMITED TO, THE IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS
+ * FOR A PARTICULAR PURPOSE ARE DISCLAIMED. IN NO EVENT SHALL THE
+ * COPYRIGHT OWNER OR CONTRIBUTORS BE LIABLE FOR ANY DIRECT, INDIRECT,
+ * INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING,
+ * BUT NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; LOSS
+ * OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED
+ * AND ON ANY THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY,
+ * OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT
+ * OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF
+ * SUCH DAMAGE.
+ */
+
+#include <ctype.h>
+#include <elf.h>
+#include <inttypes.h>
+#include <link.h>
+#include <stdio.h>
+#include <string.h>
+#include <stdlib.h>
+
+#include <vector>
+
+#include "MapData.h"
+
+// Format of /proc/<PID>/maps:
+//   6f000000-6f01e000 rwxp 00000000 00:0c 16389419   /system/lib/libcomposer.so
+static MapEntry* parse_line(char* line) {
+  uintptr_t start;
+  uintptr_t end;
+  uintptr_t offset;
+  char permissions[5];
+  int name_pos;
+  if (sscanf(line, "%" PRIxPTR "-%" PRIxPTR " %4s %" PRIxPTR " %*x:%*x %*d %n", &start,
+             &end, permissions, &offset, &name_pos) < 2) {
+    return nullptr;
+  }
+
+  const char* name = line + name_pos;
+  size_t name_len = strlen(name);
+  if (name_len && name[name_len - 1] == '\n') {
+    name_len -= 1;
+  }
+
+  MapEntry* entry = new MapEntry(start, end, offset, name, name_len);
+  if (permissions[0] != 'r') {
+    // Any unreadable map will just get a zero load base.
+    entry->load_base = 0;
+    entry->load_base_read = true;
+  }
+  return entry;
+}
+
+template<typename T>
+static inline bool get_val(MapEntry* entry, uintptr_t addr, T* store) {
+  if (addr < entry->start || addr + sizeof(T) > entry->end) {
+    return false;
+  }
+  // Make sure the address is aligned properly.
+  if (addr & (sizeof(T)-1)) {
+    return false;
+  }
+  *store = *reinterpret_cast<T*>(addr);
+  return true;
+}
+
+static void read_loadbase(MapEntry* entry) {
+  entry->load_base = 0;
+  entry->load_base_read = true;
+  uintptr_t addr = entry->start;
+  ElfW(Ehdr) ehdr;
+  if (!get_val<ElfW(Half)>(entry, addr + offsetof(ElfW(Ehdr), e_phnum), &ehdr.e_phnum)) {
+    return;
+  }
+  if (!get_val<ElfW(Off)>(entry, addr + offsetof(ElfW(Ehdr), e_phoff), &ehdr.e_phoff)) {
+    return;
+  }
+  addr += ehdr.e_phoff;
+  for (size_t i = 0; i < ehdr.e_phnum; i++) {
+    ElfW(Phdr) phdr;
+    if (!get_val<ElfW(Word)>(entry, addr + offsetof(ElfW(Phdr), p_type), &phdr.p_type)) {
+      return;
+    }
+    if (!get_val<ElfW(Off)>(entry, addr + offsetof(ElfW(Phdr), p_offset), &phdr.p_offset)) {
+      return;
+    }
+    if (phdr.p_type == PT_LOAD && phdr.p_offset == entry->offset) {
+      if (!get_val<ElfW(Addr)>(entry, addr + offsetof(ElfW(Phdr), p_vaddr), &phdr.p_vaddr)) {
+        return;
+      }
+      entry->load_base = phdr.p_vaddr;
+      return;
+    }
+    addr += sizeof(phdr);
+  }
+}
+
+bool MapData::ReadMaps() {
+  FILE* fp = fopen("/proc/self/maps", "re");
+  if (fp == nullptr) {
+    return false;
+  }
+
+  std::vector<char> buffer(1024);
+  while (fgets(buffer.data(), buffer.size(), fp) != nullptr) {
+    MapEntry* entry = parse_line(buffer.data());
+    if (entry == nullptr) {
+      fclose(fp);
+      return false;
+    }
+
+    auto it = entries_.find(entry);
+    if (it == entries_.end()) {
+      entries_.insert(entry);
+    } else {
+      delete entry;
+    }
+  }
+  fclose(fp);
+  return true;
+}
+
+MapData::~MapData() {
+  for (auto* entry : entries_) {
+    delete entry;
+  }
+  entries_.clear();
+}
+
+// Find the containing map info for the PC.
+const MapEntry* MapData::find(uintptr_t pc, uintptr_t* rel_pc) {
+  MapEntry pc_entry(pc);
+
+  std::lock_guard<std::mutex> lock(m_);
+
+  auto it = entries_.find(&pc_entry);
+  if (it == entries_.end()) {
+    ReadMaps();
+  }
+  it = entries_.find(&pc_entry);
+  if (it == entries_.end()) {
+    return nullptr;
+  }
+
+  MapEntry *entry = *it;
+  if (!entry->load_base_read) {
+    read_loadbase(entry);
+  }
+  if (rel_pc) {
+    *rel_pc = pc - entry->start + entry->load_base;
+  }
+  return entry;
+}
diff --git a/libc/bionic/debug_mapinfo.h b/libc/malloc_debug/MapData.h
similarity index 61%
rename from libc/bionic/debug_mapinfo.h
rename to libc/malloc_debug/MapData.h
index af7d05d..0238139 100644
--- a/libc/bionic/debug_mapinfo.h
+++ b/libc/malloc_debug/MapData.h
@@ -26,23 +26,53 @@
  * SUCH DAMAGE.
  */
 
-#ifndef DEBUG_MAPINFO_H
-#define DEBUG_MAPINFO_H
+#ifndef DEBUG_MALLOC_MAPDATA_H
+#define DEBUG_MALLOC_MAPDATA_H
 
 #include <sys/cdefs.h>
 
-struct mapinfo_t {
-  struct mapinfo_t* next;
+#include <mutex>
+#include <string>
+#include <set>
+
+#include <private/bionic_macros.h>
+
+struct MapEntry {
+  MapEntry(uintptr_t start, uintptr_t end, uintptr_t offset, const char* name, size_t name_len)
+      : start(start), end(end), offset(offset), name(name, name_len) {}
+
+  MapEntry(uintptr_t pc) : start(pc), end(pc) {}
+
   uintptr_t start;
   uintptr_t end;
   uintptr_t offset;
   uintptr_t load_base;
-  bool load_base_read;
-  char name[];
+  bool load_base_read = false;
+  std::string name;
 };
 
-__LIBC_HIDDEN__ mapinfo_t* mapinfo_create(pid_t pid);
-__LIBC_HIDDEN__ void mapinfo_destroy(mapinfo_t* mi);
-__LIBC_HIDDEN__ const mapinfo_t* mapinfo_find(mapinfo_t* mi, uintptr_t pc, uintptr_t* rel_pc);
 
-#endif /* DEBUG_MAPINFO_H */
+// Ordering comparator that returns equivalence for overlapping entries
+struct compare_entries {
+  bool operator()(const MapEntry* a, const MapEntry* b) const {
+    return a->end <= b->start;
+  }
+};
+
+class MapData {
+ public:
+  MapData() = default;
+  ~MapData();
+
+  const MapEntry* find(uintptr_t pc, uintptr_t* rel_pc = nullptr);
+
+ private:
+  bool ReadMaps();
+
+  std::mutex m_;
+  std::set<MapEntry*, compare_entries> entries_;
+
+  DISALLOW_COPY_AND_ASSIGN(MapData);
+};
+
+#endif  // DEBUG_MALLOC_MAPDATA_H
diff --git a/libc/malloc_debug/README.md b/libc/malloc_debug/README.md
new file mode 100644
index 0000000..3fc2305
--- /dev/null
+++ b/libc/malloc_debug/README.md
@@ -0,0 +1,330 @@
+Malloc Debug
+============
+
+Malloc debug is a method of debugging native memory problems. It can help
+detect memory corruption, memory leaks, and use after free issues.
+
+Currently, malloc debug requires root to enable. When it is enabled, it works
+by adding a shim layer that replaces the normal allocation calls. The replaced
+calls are:
+
+<pre>
+malloc
+free
+calloc
+realloc
+posix_memalign
+memalign
+malloc_usable_size
+</pre>
+
+On 32 bit systems, these two deprecated functions are also replaced:
+
+<pre>
+pvalloc
+valloc
+</pre>
+
+Any errors detected by the library are reported in the log.
+
+Controlling Malloc Debug Behavior
+---------------------------------
+Malloc debug is controlled by individual options. Each option can be enabled
+individually, or in a group of other options. Every single option can be
+combined with every other option.
+
+Option Descriptions
+-------------------
+### front\_guard[=SIZE\_BYTES]
+Enables a small buffer placed before the allocated data. This is an attempt
+to find memory corruption occuring to a region before the original allocation.
+On first allocation, this front guard is written with a specific pattern (0xaa).
+When the allocation is freed, the guard is checked to verify it has not been
+modified. If any part of the front guard is modified, an error will be reported
+in the log indicating what bytes changed.
+
+If the backtrace option is also enabled, then any error message will include
+the backtrace of the allocation site.
+
+If SIZE\_BYTES is present, it indicates the number of bytes in the guard.
+The default is 32 bytes, the max bytes is 16384. SIZE\_BYTES will be
+padded so that it is a multiple of 8 bytes on 32 bit systems and 16 bytes
+on 64 bit systems to make sure that the allocation returned is aligned
+properly.
+
+This option adds a special header to all allocations that contains the guard
+and information about the original allocation.
+
+Example error:
+
+<pre>
+04-10 12:00:45.621  7412  7412 E malloc_debug: +++ ALLOCATION 0x12345678 SIZE 100 HAS A CORRUPTED FRONT GUARD
+04-10 12:00:45.622  7412  7412 E malloc_debug:   allocation[-32] = 0x00 (expected 0xaa)
+04-10 12:00:45.622  7412  7412 E malloc_debug:   allocation[-15] = 0x02 (expected 0xaa)
+</pre>
+
+### rear\_guard[=SIZE\_BYTES]
+Enables a small buffer placed after the allocated data. This is an attempt
+to find memory corruption occuring to a region after the original allocation.
+On first allocation, this rear guard is written with a specific pattern (0xbb).
+When the allocation is freed, the guard is checked to verify it has not been
+modified. If any part of the rear guard is modified, an error will be reported
+in the log indicating what bytes changed.
+
+If SIZE\_BYTES is present, it indicates the number of bytes in the guard.
+The default is 32 bytes, the max bytes is 16384.
+
+This option adds a special header to all allocations that contains
+information about the original allocation.
+
+Example error:
+
+<pre>
+04-10 12:00:45.621  7412  7412 E malloc_debug: +++ ALLOCATION 0x12345678 SIZE 100 HAS A CORRUPTED REAR GUARD
+04-10 12:00:45.622  7412  7412 E malloc_debug:   allocation[130] = 0xbf (expected 0xbb)
+04-10 12:00:45.622  7412  7412 E malloc_debug:   allocation[131] = 0x00 (expected 0xbb)
+</pre>
+
+### guard[=SIZE\_BYTES]
+Enables both a front guard and a rear guard on all allocations.
+
+If SIZE\_BYTES is present, it indicates the number of bytes in both guards.
+The default is 32 bytes, the max bytes is 16384.
+
+### backtrace[=MAX\_FRAMES]
+Enable capturing the backtrace of each allocation site.
+This option will slow down allocations by an order of magnitude. If the
+system runs too slowly with this option enabled, decreasing the maximum number
+of frames captured will speed the allocations up.
+
+Note that any backtrace frames that occur within the malloc backtrace library
+itself are not recorded.
+
+If MAX\_FRAMES is present, it indicates the maximum number of frames to
+capture in a backtrace. The default is 16 frames, the maximumum value
+this can be set to is 256.
+
+This option adds a special header to all allocations that contains the
+backtrace and information about the original allocation.
+
+### backtrace\_enable\_on\_signal[=MAX\_FRAMES]
+Enable capturing the backtrace of each allocation site. If the
+backtrace capture is toggled when the process receives the signal
+SIGRTMAX - 19 (which is 45 on most Android devices). When this
+option is used alone, backtrace capture starts out disabled until the signal
+is received. If both this option and the backtrace option are set, then
+backtrace capture is enabled until the signal is received.
+
+If MAX\_FRAMES is present, it indicates the maximum number of frames to
+capture in a backtrace. The default is 16 frames, the maximumum value
+this can be set to is 256.
+
+This option adds a special header to all allocations that contains the
+backtrace and information about the original allocation.
+
+### fill\_on\_alloc[=MAX\_FILLED\_BYTES]
+Any allocation routine, other than calloc, will result in the allocation being
+filled with the value 0xeb. When doing a realloc to a larger size, the bytes
+above the original usable size will be set to 0xeb.
+
+If MAX\_FILLED\_BYTES is present, it will only fill up to the specified number
+of bytes in the allocation. The default is to fill the entire allocation.
+
+### fill\_on\_free[=MAX\_FILLED\_BYTES]
+When an allocation is freed, fill it with 0xef.
+
+If MAX\_FILLED\_BYTES is present, it will only fill up to the specified number
+of bytes in the allocation. The default is to fill the entire allocation.
+
+### fill[=MAX\_FILLED\_BYTES]
+This enables both the fill\_on\_alloc option and the fill\_on\_free option.
+
+If MAX\_FILLED\_BYTES is present, it will only fill up to the specified number
+of bytes in the allocation. The default is to fill the entire allocation.
+
+### expand\_alloc[=EXPAND\_BYTES]
+Add an extra amount to allocate for every allocation.
+
+If XX is present, it is the number of bytes to expand the allocation by.
+The default is 16 bytes, the max bytes is 16384.
+
+### free\_track[=ALLOCATION\_COUNT]
+When a pointer is freed, do not free the memory right away, but add it to
+a list of freed allocations. In addition to being added to the list, the
+entire allocation is filled with the value 0xef, and the backtrace at
+the time of the free is recorded. The backtrace recording is completely
+separate from the backtrace option, and happens automatically if this
+option is enabled. By default, a maximum of 16 frames will be recorded,
+but this value can be changed using the free\_track\_backtrace\_num\_frames
+option. It can also be completely disabled by setting the option to zero.
+See the full description of this option below.
+
+When the list is full, an allocation is removed from the list and is
+checked to make sure that none of the contents have been modified since
+being placed on the list. When the program terminates, all of the allocations
+left on the list are verified.
+
+If ALLOCATION\_COUNT is present, it indicates the total number of allocations
+in the list. The default is to record 100 freed allocations, the max
+allocations to record is 16384.
+
+This option adds a special header to all allocations that contains
+information about the original allocation.
+
+Example error:
+
+<pre>
+04-15 12:00:31.304  7412  7412 E malloc_debug: +++ ALLOCATION 0x12345678 USED AFTER FREE
+04-15 12:00:31.305  7412  7412 E malloc_debug:   allocation[20] = 0xaf (expected 0xef)
+04-15 12:00:31.305  7412  7412 E malloc_debug:   allocation[99] = 0x12 (expected 0xef)
+04-15 12:00:31.305  7412  7412 E malloc_debug: Backtrace at time of free:
+04-15 12:00:31.305  7412  7412 E malloc_debug:           #00  pc 00029310  /system/lib/libc.so
+04-15 12:00:31.305  7412  7412 E malloc_debug:           #01  pc 00021438  /system/lib/libc.so (newlocale+160)
+04-15 12:00:31.305  7412  7412 E malloc_debug:           #02  pc 000a9e38  /system/lib/libc++.so
+04-15 12:00:31.305  7412  7412 E malloc_debug:           #03  pc 000a28a8  /system/lib/libc++.so
+</pre>
+
+In addition, there is another type of error message that can occur if
+an allocation has a special header applied, and the header is corrupted
+before the verification occurs. This is the error message that will be found
+in the log:
+
+<pre>
++++ ALLOCATION 0x12345678 HAS CORRUPTED HEADER TAG 0x1cc7dc00 AFTER FREE
+</pre>
+
+### free\_track\_backtrace\_num\_frames[=MAX\_FRAMES]
+This option only has meaning if free\_track is set. It indicates how many
+backtrace frames to capture when an allocation is freed.
+
+If MAX\_FRAMES is present, it indicates the number of frames to capture.
+If the value is set to zero, then no backtrace will be captured when the
+allocation is freed. The default is to record 16 frames, the max number of
+frames to to record is 256.
+
+### leak\_track
+Track all live allocations. When the program terminates, all of the live
+allocations will be dumped to the log. If the backtrace option was enabled,
+then the log will include the backtrace of the leaked allocations. This
+option is not useful when enabled globally because a lot of programs do not
+free everything before the program terminates.
+
+This option adds a special header to all allocations that contains
+information about the original allocation.
+
+Example leak error found in the log:
+
+<pre>
+04-15 12:35:33.304  7412  7412 E malloc_debug: +++ APP leaked block of size 100 at 0x2be3b0b0 (leak 1 of 2)
+04-15 12:35:33.304  7412  7412 E malloc_debug: Backtrace at time of allocation:
+04-15 12:35:33.305  7412  7412 E malloc_debug:           #00  pc 00029310  /system/lib/libc.so
+04-15 12:35:33.305  7412  7412 E malloc_debug:           #01  pc 00021438  /system/lib/libc.so (newlocale+160)
+04-15 12:35:33.305  7412  7412 E malloc_debug:           #02  pc 000a9e38  /system/lib/libc++.so
+04-15 12:35:33.305  7412  7412 E malloc_debug:           #03  pc 000a28a8  /system/lib/libc++.so
+04-15 12:35:33.305  7412  7412 E malloc_debug: +++ APP leaked block of size 24 at 0x7be32380 (leak 2 of 2)
+04-15 12:35:33.305  7412  7412 E malloc_debug: Backtrace at time of allocation:
+04-15 12:35:33.305  7412  7412 E malloc_debug:           #00  pc 00029310  /system/lib/libc.so
+04-15 12:35:33.305  7412  7412 E malloc_debug:           #01  pc 00021438  /system/lib/libc.so (newlocale+160)
+04-15 12:35:33.305  7412  7412 E malloc_debug:           #02  pc 000a9e38  /system/lib/libc++.so
+04-15 12:35:33.305  7412  7412 E malloc_debug:           #03  pc 000a28a8  /system/lib/libc++.so
+</pre>
+
+Additional Errors
+-----------------
+There are a few other error messages that might appear in the log.
+
+### Use After Free
+<pre>
+04-15 12:00:31.304  7412  7412 E malloc_debug: +++ ALLOCATION 0x12345678 USED AFTER FREE (free)
+04-15 12:00:31.305  7412  7412 E malloc_debug: Backtrace of original free:
+04-15 12:00:31.305  7412  7412 E malloc_debug:           #00  pc 00029310  /system/lib/libc.so
+04-15 12:00:31.305  7412  7412 E malloc_debug:           #01  pc 00021438  /system/lib/libc.so (newlocale+160)
+04-15 12:00:31.305  7412  7412 E malloc_debug:           #02  pc 000a9e38  /system/lib/libc++.so
+04-15 12:00:31.305  7412  7412 E malloc_debug:           #03  pc 000a28a8  /system/lib/libc++.so
+04-15 12:00:31.305  7412  7412 E malloc_debug: Backtrace at time of failure:
+04-15 12:00:31.305  7412  7412 E malloc_debug:           #00  pc 00029310  /system/lib/libc.so
+04-15 12:00:31.305  7412  7412 E malloc_debug:           #01  pc 00021438  /system/lib/libc.so (newlocale+160)
+04-15 12:00:31.305  7412  7412 E malloc_debug:           #02  pc 000a9e38  /system/lib/libc++.so
+04-15 12:00:31.305  7412  7412 E malloc_debug:           #03  pc 000a28a8  /system/lib/libc++.so
+</pre>
+
+This indicates that code is attempting to free an already freed pointer. The
+name in parenthesis indicates that the application called the function
+<i>free</i> with the bad pointer.
+
+For example, this message:
+
+<pre>
+04-15 12:00:31.304  7412  7412 E malloc_debug: +++ ALLOCATION 0x12345678 USED AFTER FREE (realloc)
+</pre>
+
+Would indicate that the application called the <i>realloc</i> function
+with an already freed pointer.
+
+### Invalid Tag
+<pre>
+04-15 12:00:31.304  7412  7412 E malloc_debug: +++ ALLOCATION 0x12345678 HAS INVALID TAG 1ee7d000 (malloc_usable_size)
+04-15 12:00:31.305  7412  7412 E malloc_debug: Backtrace at time of failure:
+04-15 12:00:31.305  7412  7412 E malloc_debug:           #00  pc 00029310  /system/lib/libc.so
+04-15 12:00:31.305  7412  7412 E malloc_debug:           #01  pc 00021438  /system/lib/libc.so (newlocale+160)
+04-15 12:00:31.305  7412  7412 E malloc_debug:           #02  pc 000a9e38  /system/lib/libc++.so
+04-15 12:00:31.305  7412  7412 E malloc_debug:           #03  pc 000a28a8  /system/lib/libc++.so
+</pre>
+
+This indicates that a function (malloc\_usable\_size) was called with
+a pointer that is either not allocated memory, or that the memory of
+the pointer has been corrupted.
+
+As with the other error message, the function in parenthesis is the
+function that was called with the bad pointer.
+
+Examples
+========
+Enable backtrace tracking of all allocation for all processes:
+
+<pre>
+  adb shell stop
+  adb shell setprop libc.debug.malloc.options backtrace
+  adb shell start
+</pre>
+
+Enable backtrace tracking for a specific process (ls):
+
+<pre>
+  adb shell setprop libc.debug.malloc.options backtrace
+  adb shell setprop libc.debug.malloc.program ls
+  adb shell ls
+</pre>
+
+Enable backtrace tracking for the zygote and zygote based processes:
+
+<pre>
+  adb shell stop
+  adb shell setprop libc.debug.malloc.program app_process
+  adb shell setprop libc.debug.malloc.options backtrace
+  adb shell start
+</pre>
+
+Enable multiple options (backtrace and guards):
+
+<pre>
+  adb shell stop
+  adb shell setprop libc.debug.malloc.options "\"backtrace guards\""
+  adb shell start
+</pre>
+
+Enable malloc debug when multiple processes have the same name. This method
+can be used to enable malloc debug for only a very specific process if
+multiple processes have the same name.
+
+Note: The double quotes in the adb shell command are necessary. Otherwise,
+the setprop command will fail since the backtrace guards options will look
+like two arguments instead of one.
+
+<pre>
+  adb shell
+  # setprop libc.debug.malloc.env_enabled
+  # setprop libc.debug.malloc.options backtrace
+  # export LIBC_DEBUG_MALLOC_ENABLE 1
+  # ls
+</pre>
diff --git a/libc/malloc_debug/README_api.md b/libc/malloc_debug/README_api.md
new file mode 100644
index 0000000..cd04c32
--- /dev/null
+++ b/libc/malloc_debug/README_api.md
@@ -0,0 +1,64 @@
+Native Memory Tracking using libc Callbacks
+-------------------------------------------
+Malloc debug can be used to get information on all of the live allocations
+in a process. The libc library in Android exports two calls that can be
+used to gather this data from a process. This tracking can be enabled using
+either the backtrace option or the backtrace\_enabled\_on\_signal option.
+
+The function to gather the data:
+
+<pre>
+<b>
+extern "C" void get_malloc_leak_info(uint8_t** info, size_t* overall_size, size_t* info_size, size_t* total_memory, size_t* backtrace_size);
+</b>
+</pre>
+
+<i>info</i> is set to a buffer allocated by the call that contains all of
+the allocation information.
+<i>overall\_size</i> is set to the total size of the buffer returned. If this
+<i>info\_size</i>
+value is zero, then there are no allocation being tracked.
+<i>total\_memory</i> is set to the sum of all allocation sizes that are live at
+the point of the function call. This does not include the memory allocated
+by the malloc debug library itself.
+<i>backtrace\_size</i> is set to the maximum number of backtrace entries
+that are present for each allocation.
+
+In order to free the buffer allocated by the function, call:
+
+<pre>
+<b>
+extern "C" void free_malloc_leak_info(uint8_t* info);
+</b>
+</pre>
+
+### Format of info Buffer
+<pre>
+size_t size_of_original_allocation
+size_t num_backtrace_frames
+uintptr_t pc1
+uintptr_t pc2
+uintptr_t pc3
+.
+.
+.
+</pre>
+
+The number of <i>uintptr\_t</i> values is determined by the value
+<i>backtrace\_size</i> as returned by the original call to
+<i>get\_malloc\_leak\_info</i>. This value is not variable, it is the same
+for all the returned data. The value
+<i>num\_backtrace\_frames</i> contains the real number of frames found. The
+extra frames are set to zero. Each <i>uintptr\_t</i> is a pc of the callstack.
+The calls from within the malloc debug library are automatically removed.
+
+For 32 bit systems, <i>size\_t</i> and <i>uintptr\_t</i> are both 4 byte values.
+
+For 64 bit systems, <i>size\_t</i> and <i>uintptr\_t</i> are both 8 byte values.
+
+The total number of these structures returned in <i>info</i> is
+<i>overall\_size</i> divided by <i>info\_size</i>.
+
+Note, the size value in each allocation data structure will have bit 31 set
+if this allocation was created by the Zygote process. This helps to distinguish
+between native allocations created by the application.
diff --git a/libc/malloc_debug/TrackData.cpp b/libc/malloc_debug/TrackData.cpp
new file mode 100644
index 0000000..c9828d0
--- /dev/null
+++ b/libc/malloc_debug/TrackData.cpp
@@ -0,0 +1,146 @@
+/*
+ * Copyright (C) 2015 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 <pthread.h>
+#include <stdint.h>
+#include <stdlib.h>
+
+#include <algorithm>
+#include <vector>
+
+#include <private/ScopedPthreadMutexLocker.h>
+
+#include "backtrace.h"
+#include "BacktraceData.h"
+#include "Config.h"
+#include "DebugData.h"
+#include "debug_disable.h"
+#include "debug_log.h"
+#include "malloc_debug.h"
+#include "TrackData.h"
+
+void TrackData::GetList(std::vector<const Header*>* list) {
+  ScopedDisableDebugCalls disable;
+
+  for (const auto& header : headers_) {
+    list->push_back(header);
+  }
+
+  // Sort by the size of the allocation.
+  std::sort(list->begin(), list->end(), [](const Header* a, const Header* b) {
+    if (a->size == b->size) return a < b;
+    return a->size > b->size;
+  });
+}
+
+void TrackData::Add(const Header* header, bool backtrace_found) {
+  ScopedDisableDebugCalls disable;
+
+  pthread_mutex_lock(&mutex_);
+  if (backtrace_found) {
+    total_backtrace_allocs_++;
+  }
+  headers_.insert(header);
+  pthread_mutex_unlock(&mutex_);
+}
+
+void TrackData::Remove(const Header* header, bool backtrace_found) {
+  ScopedDisableDebugCalls disable;
+
+  pthread_mutex_lock(&mutex_);
+  headers_.erase(header);
+  if (backtrace_found) {
+    total_backtrace_allocs_--;
+  }
+  pthread_mutex_unlock(&mutex_);
+}
+
+bool TrackData::Contains(const Header* header) {
+  ScopedDisableDebugCalls disable;
+
+  pthread_mutex_lock(&mutex_);
+  bool found = headers_.count(header);
+  pthread_mutex_unlock(&mutex_);
+  return found;
+}
+
+void TrackData::DisplayLeaks(DebugData& debug) {
+  ScopedDisableDebugCalls disable;
+
+  std::vector<const Header*> list;
+  GetList(&list);
+
+  size_t track_count = 0;
+  for (const auto& header : list) {
+    error_log("+++ %s leaked block of size %zu at %p (leak %zu of %zu)", getprogname(),
+              header->real_size(), debug.GetPointer(header), ++track_count, list.size());
+    if (debug.config().options & BACKTRACE) {
+      BacktraceHeader* back_header = debug.GetAllocBacktrace(header);
+      if (back_header->num_frames > 0) {
+        error_log("Backtrace at time of allocation:");
+        backtrace_log(&back_header->frames[0], back_header->num_frames);
+      }
+    }
+    g_dispatch->free(header->orig_pointer);
+  }
+}
+
+void TrackData::GetInfo(DebugData& debug, uint8_t** info, size_t* overall_size,
+                        size_t* info_size, size_t* total_memory, size_t* backtrace_size) {
+  ScopedPthreadMutexLocker scoped(&mutex_);
+
+  if (headers_.size() == 0 || total_backtrace_allocs_ == 0) {
+    return;
+  }
+
+  *backtrace_size = debug.config().backtrace_frames;
+  *info_size = sizeof(size_t) * 2 + sizeof(uintptr_t) * *backtrace_size;
+  *info = reinterpret_cast<uint8_t*>(g_dispatch->calloc(*info_size, total_backtrace_allocs_));
+  if (*info == nullptr) {
+    return;
+  }
+  *overall_size = *info_size * total_backtrace_allocs_;
+
+  std::vector<const Header*> list;
+  GetList(&list);
+
+  uint8_t* data = *info;
+  for (const auto& header : list) {
+    BacktraceHeader* back_header = debug.GetAllocBacktrace(header);
+    if (back_header->num_frames > 0) {
+      memcpy(data, &header->size, sizeof(size_t));
+      memcpy(&data[sizeof(size_t)], &back_header->num_frames, sizeof(size_t));
+      memcpy(&data[2 * sizeof(size_t)], &back_header->frames[0],
+            back_header->num_frames * sizeof(uintptr_t));
+
+      *total_memory += header->real_size();
+
+      data += *info_size;
+    }
+  }
+}
diff --git a/libc/malloc_debug/TrackData.h b/libc/malloc_debug/TrackData.h
new file mode 100644
index 0000000..1234316
--- /dev/null
+++ b/libc/malloc_debug/TrackData.h
@@ -0,0 +1,75 @@
+/*
+ * Copyright (C) 2015 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 DEBUG_MALLOC_TRACKDATA_H
+#define DEBUG_MALLOC_TRACKDATA_H
+
+#include <stdint.h>
+#include <pthread.h>
+
+#include <vector>
+#include <unordered_set>
+
+#include <private/bionic_macros.h>
+
+// Forward declarations.
+struct Header;
+struct Config;
+class DebugData;
+
+class TrackData {
+ public:
+  TrackData() = default;
+  virtual ~TrackData() = default;
+
+  void GetList(std::vector<const Header*>* list);
+
+  void Add(const Header* header, bool backtrace_found);
+
+  void Remove(const Header* header, bool backtrace_found);
+
+  bool Contains(const Header *header);
+
+  void GetInfo(DebugData& debug, uint8_t** info, size_t* overall_size,
+               size_t* info_size, size_t* total_memory, size_t* backtrace_size);
+
+  void DisplayLeaks(DebugData& debug);
+
+  void PrepareFork() { pthread_mutex_lock(&mutex_); }
+  void PostForkParent() { pthread_mutex_unlock(&mutex_); }
+  void PostForkChild() { pthread_mutex_init(&mutex_, NULL); }
+
+ private:
+  pthread_mutex_t mutex_ = PTHREAD_MUTEX_INITIALIZER;
+  std::unordered_set<const Header*> headers_;
+  size_t total_backtrace_allocs_ = 0;
+
+  DISALLOW_COPY_AND_ASSIGN(TrackData);
+};
+
+#endif // DEBUG_MALLOC_TRACKDATA_H
diff --git a/libc/malloc_debug/backtrace.cpp b/libc/malloc_debug/backtrace.cpp
new file mode 100644
index 0000000..18ce8b8
--- /dev/null
+++ b/libc/malloc_debug/backtrace.cpp
@@ -0,0 +1,175 @@
+/*
+ * Copyright (C) 2012 The Android Open Source Project
+ * All rights reserved.
+ *
+ * Redistribution and use in source and binary forms, with or without
+ * modification, are permitted provided that the following conditions
+ * are met:
+ *  * Redistributions of source code must retain the above copyright
+ *    notice, this list of conditions and the following disclaimer.
+ *  * Redistributions in binary form must reproduce the above copyright
+ *    notice, this list of conditions and the following disclaimer in
+ *    the documentation and/or other materials provided with the
+ *    distribution.
+ *
+ * THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS
+ * "AS IS" AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT
+ * LIMITED TO, THE IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS
+ * FOR A PARTICULAR PURPOSE ARE DISCLAIMED. IN NO EVENT SHALL THE
+ * COPYRIGHT OWNER OR CONTRIBUTORS BE LIABLE FOR ANY DIRECT, INDIRECT,
+ * INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING,
+ * BUT NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; LOSS
+ * OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED
+ * AND ON ANY THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY,
+ * OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT
+ * OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF
+ * SUCH DAMAGE.
+ */
+
+#include <dlfcn.h>
+#include <errno.h>
+#include <inttypes.h>
+#include <malloc.h>
+#include <pthread.h>
+#include <string.h>
+#include <sys/types.h>
+#include <unistd.h>
+#include <unwind.h>
+
+#include "backtrace.h"
+#include "debug_log.h"
+#include "MapData.h"
+
+#if defined(__LP64__)
+#define PAD_PTR "016" PRIxPTR
+#else
+#define PAD_PTR "08" PRIxPTR
+#endif
+
+typedef struct _Unwind_Context __unwind_context;
+
+extern "C" char* __cxa_demangle(const char*, char*, size_t*, int*);
+
+static MapData g_map_data;
+static const MapEntry* g_current_code_map = nullptr;
+
+static _Unwind_Reason_Code find_current_map(__unwind_context* context, void*) {
+  uintptr_t ip = _Unwind_GetIP(context);
+
+  if (ip == 0) {
+    return _URC_END_OF_STACK;
+  }
+  g_current_code_map = g_map_data.find(ip);
+  return _URC_END_OF_STACK;
+}
+
+void backtrace_startup() {
+  _Unwind_Backtrace(find_current_map, nullptr);
+}
+
+void backtrace_shutdown() {
+}
+
+struct stack_crawl_state_t {
+  uintptr_t* frames;
+  size_t frame_count;
+  size_t cur_frame = 0;
+
+  stack_crawl_state_t(uintptr_t* frames, size_t frame_count)
+      : frames(frames), frame_count(frame_count) {}
+};
+
+static _Unwind_Reason_Code trace_function(__unwind_context* context, void* arg) {
+  stack_crawl_state_t* state = static_cast<stack_crawl_state_t*>(arg);
+
+  uintptr_t ip = _Unwind_GetIP(context);
+
+  // The instruction pointer is pointing at the instruction after the return
+  // call on all architectures.
+  // Modify the pc to point at the real function.
+  if (ip != 0) {
+#if defined(__arm__)
+    // If the ip is suspiciously low, do nothing to avoid a segfault trying
+    // to access this memory.
+    if (ip >= 4096) {
+      // Check bits [15:11] of the first halfword assuming the instruction
+      // is 32 bits long. If the bits are any of these values, then our
+      // assumption was correct:
+      //  b11101
+      //  b11110
+      //  b11111
+      // Otherwise, this is a 16 bit instruction.
+      uint16_t value = (*reinterpret_cast<uint16_t*>(ip - 2)) >> 11;
+      if (value == 0x1f || value == 0x1e || value == 0x1d) {
+        ip -= 4;
+      } else {
+        ip -= 2;
+      }
+    }
+#elif defined(__aarch64__)
+    // All instructions are 4 bytes long, skip back one instruction.
+    ip -= 4;
+#elif defined(__i386__) || defined(__x86_64__)
+    // It's difficult to decode exactly where the previous instruction is,
+    // so subtract 1 to estimate where the instruction lives.
+    ip--;
+#endif
+
+    // Do not record the frames that fall in our own shared library.
+    if (g_current_code_map && (ip >= g_current_code_map->start) && ip < g_current_code_map->end) {
+      return _URC_NO_REASON;
+    }
+  }
+
+  state->frames[state->cur_frame++] = ip;
+  return (state->cur_frame >= state->frame_count) ? _URC_END_OF_STACK : _URC_NO_REASON;
+}
+
+size_t backtrace_get(uintptr_t* frames, size_t frame_count) {
+  stack_crawl_state_t state(frames, frame_count);
+  _Unwind_Backtrace(trace_function, &state);
+  return state.cur_frame;
+}
+
+std::string backtrace_string(const uintptr_t* frames, size_t frame_count) {
+  std::string str;
+
+  for (size_t frame_num = 0; frame_num < frame_count; frame_num++) {
+    uintptr_t offset = 0;
+    const char* symbol = nullptr;
+
+    Dl_info info;
+    if (dladdr(reinterpret_cast<void*>(frames[frame_num]), &info) != 0) {
+      offset = reinterpret_cast<uintptr_t>(info.dli_saddr);
+      symbol = info.dli_sname;
+    }
+
+    uintptr_t rel_pc = offset;
+    const MapEntry* entry = g_map_data.find(frames[frame_num], &rel_pc);
+
+    const char* soname = (entry != nullptr) ? entry->name.c_str() : info.dli_fname;
+    if (soname == nullptr) {
+      soname = "<unknown>";
+    }
+    char buf[1024];
+    if (symbol != nullptr) {
+      char* demangled_symbol = __cxa_demangle(symbol, nullptr, nullptr, nullptr);
+      const char* best_name = (demangled_symbol != nullptr) ? demangled_symbol : symbol;
+
+      __libc_format_buffer(buf, sizeof(buf),
+          "          #%02zd  pc %" PAD_PTR "  %s (%s+%" PRIuPTR ")\n", frame_num,
+          rel_pc, soname, best_name, frames[frame_num] - offset);
+      free(demangled_symbol);
+    } else {
+      __libc_format_buffer(buf, sizeof(buf),
+          "          #%02zd  pc %" PAD_PTR "  %s\n", frame_num, rel_pc, soname);
+    }
+    str += buf;
+  }
+
+  return str;
+}
+
+void backtrace_log(const uintptr_t* frames, size_t frame_count) {
+  error_log_string(backtrace_string(frames, frame_count).c_str());
+}
diff --git a/libc/bionic/debug_stacktrace.h b/libc/malloc_debug/backtrace.h
similarity index 78%
rename from libc/bionic/debug_stacktrace.h
rename to libc/malloc_debug/backtrace.h
index 2cf8636..f570873 100644
--- a/libc/bionic/debug_stacktrace.h
+++ b/libc/malloc_debug/backtrace.h
@@ -26,15 +26,18 @@
  * SUCH DAMAGE.
  */
 
-#ifndef DEBUG_STACKTRACE_H
-#define DEBUG_STACKTRACE_H
+#ifndef MALLOC_DEBUG_BACKTRACE_H
+#define MALLOC_DEBUG_BACKTRACE_H
 
 #include <stdint.h>
 #include <sys/cdefs.h>
 
-__LIBC_HIDDEN__ void backtrace_startup();
-__LIBC_HIDDEN__ void backtrace_shutdown();
-__LIBC_HIDDEN__ int get_backtrace(uintptr_t* stack_frames, size_t max_depth);
-__LIBC_HIDDEN__ void log_backtrace(uintptr_t* stack_frames, size_t frame_count);
+#include <string>
 
-#endif /* DEBUG_STACKTRACE_H */
+void backtrace_startup();
+void backtrace_shutdown();
+size_t backtrace_get(uintptr_t* frames, size_t frame_count);
+void backtrace_log(const uintptr_t* frames, size_t frame_count);
+std::string backtrace_string(const uintptr_t* frames, size_t frame_count);
+
+#endif // MALLOC_DEBUG_BACKTRACE_H
diff --git a/libc/include/sys/shm.h b/libc/malloc_debug/debug_disable.cpp
similarity index 60%
copy from libc/include/sys/shm.h
copy to libc/malloc_debug/debug_disable.cpp
index c691c29..af0264b 100644
--- a/libc/include/sys/shm.h
+++ b/libc/malloc_debug/debug_disable.cpp
@@ -1,5 +1,5 @@
 /*
- * Copyright (C) 2014 The Android Open Source Project
+ * Copyright (C) 2015 The Android Open Source Project
  * All rights reserved.
  *
  * Redistribution and use in source and binary forms, with or without
@@ -26,9 +26,41 @@
  * SUCH DAMAGE.
  */
 
-#ifndef _SYS_SHM_H_
-#define _SYS_SHM_H_
+#include <pthread.h>
 
-#include <linux/shm.h>
+#include "DebugData.h"
+#include "debug_disable.h"
+#include "debug_log.h"
 
-#endif /* _SYS_SHM_H_ */
+extern DebugData* g_debug;
+pthread_key_t g_disable_key;
+
+bool DebugCallsDisabled() {
+  if (g_debug == nullptr || pthread_getspecific(g_disable_key) != nullptr) {
+    return true;
+  }
+  return false;
+}
+
+bool DebugDisableInitialize() {
+  int error = pthread_key_create(&g_disable_key, nullptr);
+  if (error != 0) {
+    error_log("pthread_key_create failed: %s", strerror(error));
+    return false;
+  }
+  pthread_setspecific(g_disable_key, nullptr);
+
+  return true;
+}
+
+void DebugDisableFinalize() {
+  pthread_key_delete(g_disable_key);
+}
+
+void DebugDisableSet(bool disable) {
+  if (disable) {
+    pthread_setspecific(g_disable_key, reinterpret_cast<void*>(1));
+  } else {
+    pthread_setspecific(g_disable_key, nullptr);
+  }
+}
diff --git a/libc/bionic/malloc_debug_disable.h b/libc/malloc_debug/debug_disable.h
similarity index 84%
rename from libc/bionic/malloc_debug_disable.h
rename to libc/malloc_debug/debug_disable.h
index 9503128..9edb4df 100644
--- a/libc/bionic/malloc_debug_disable.h
+++ b/libc/malloc_debug/debug_disable.h
@@ -29,29 +29,29 @@
 #ifndef MALLOC_DEBUG_DISABLE_H
 #define MALLOC_DEBUG_DISABLE_H
 
-#include <pthread.h>
+#include <sys/cdefs.h>
 
-#include "private/bionic_macros.h"
+#include <private/bionic_macros.h>
 
 // =============================================================================
 // Used to disable the debug allocation calls.
 // =============================================================================
-extern pthread_key_t g_debug_calls_disabled;
+bool DebugDisableInitialize();
+void DebugDisableFinalize();
 
-static inline bool DebugCallsDisabled() {
-  return pthread_getspecific(g_debug_calls_disabled) != NULL;
-}
+bool DebugCallsDisabled();
+void DebugDisableSet(bool disable);
 
 class ScopedDisableDebugCalls {
  public:
   ScopedDisableDebugCalls() : disabled_(DebugCallsDisabled()) {
     if (!disabled_) {
-      pthread_setspecific(g_debug_calls_disabled, reinterpret_cast<const void*>(1));
+      DebugDisableSet(true);
     }
   }
   ~ScopedDisableDebugCalls() {
     if (!disabled_) {
-      pthread_setspecific(g_debug_calls_disabled, NULL);
+      DebugDisableSet(false);
     }
   }
 
diff --git a/libc/bionic/malloc_debug_disable.h b/libc/malloc_debug/debug_log.h
similarity index 63%
copy from libc/bionic/malloc_debug_disable.h
copy to libc/malloc_debug/debug_log.h
index 9503128..4df0408 100644
--- a/libc/bionic/malloc_debug_disable.h
+++ b/libc/malloc_debug/debug_log.h
@@ -1,5 +1,5 @@
 /*
- * Copyright (C) 2014 The Android Open Source Project
+ * Copyright (C) 2009 The Android Open Source Project
  * All rights reserved.
  *
  * Redistribution and use in source and binary forms, with or without
@@ -26,39 +26,21 @@
  * SUCH DAMAGE.
  */
 
-#ifndef MALLOC_DEBUG_DISABLE_H
-#define MALLOC_DEBUG_DISABLE_H
+#ifndef MALLOC_DEBUG_LOG_H
+#define MALLOC_DEBUG_LOG_H
 
-#include <pthread.h>
-
-#include "private/bionic_macros.h"
+#include <private/libc_logging.h>
 
 // =============================================================================
-// Used to disable the debug allocation calls.
+// log functions
 // =============================================================================
-extern pthread_key_t g_debug_calls_disabled;
+#define debug_log(format, ...)  \
+    __libc_format_log(ANDROID_LOG_DEBUG, "malloc_debug", (format), ##__VA_ARGS__ )
+#define error_log(format, ...)  \
+    __libc_format_log(ANDROID_LOG_ERROR, "malloc_debug", (format), ##__VA_ARGS__ )
+#define error_log_string(str)  \
+    __libc_write_log(ANDROID_LOG_ERROR, "malloc_debug", (str))
+#define info_log(format, ...)  \
+    __libc_format_log(ANDROID_LOG_INFO, "malloc_debug", (format), ##__VA_ARGS__ )
 
-static inline bool DebugCallsDisabled() {
-  return pthread_getspecific(g_debug_calls_disabled) != NULL;
-}
-
-class ScopedDisableDebugCalls {
- public:
-  ScopedDisableDebugCalls() : disabled_(DebugCallsDisabled()) {
-    if (!disabled_) {
-      pthread_setspecific(g_debug_calls_disabled, reinterpret_cast<const void*>(1));
-    }
-  }
-  ~ScopedDisableDebugCalls() {
-    if (!disabled_) {
-      pthread_setspecific(g_debug_calls_disabled, NULL);
-    }
-  }
-
- private:
-  bool disabled_;
-
-  DISALLOW_COPY_AND_ASSIGN(ScopedDisableDebugCalls);
-};
-
-#endif  // MALLOC_DEBUG_DISABLE_H
+#endif  // MALLOC_DEBUG_LOG_H
diff --git a/libc/malloc_debug/exported32.map b/libc/malloc_debug/exported32.map
new file mode 100644
index 0000000..a985ef9
--- /dev/null
+++ b/libc/malloc_debug/exported32.map
@@ -0,0 +1,24 @@
+LIBC_MALLOC_DEBUG {
+  global:
+    debug_calloc;
+    debug_finalize;
+    debug_free;
+    debug_free_malloc_leak_info;
+    debug_get_malloc_leak_info;
+    debug_initialize;
+    debug_iterate;
+    debug_mallinfo;
+    debug_malloc;
+    debug_malloc_backtrace;
+    debug_malloc_disable;
+    debug_malloc_enable;
+    debug_malloc_usable_size;
+    debug_memalign;
+    debug_posix_memalign;
+    debug_pvalloc;
+    debug_realloc;
+    debug_valloc;
+
+  local:
+    *;
+};
diff --git a/libc/malloc_debug/exported64.map b/libc/malloc_debug/exported64.map
new file mode 100644
index 0000000..1a6b30f
--- /dev/null
+++ b/libc/malloc_debug/exported64.map
@@ -0,0 +1,22 @@
+LIBC_MALLOC_DEBUG {
+  global:
+    debug_calloc;
+    debug_finalize;
+    debug_free;
+    debug_free_malloc_leak_info;
+    debug_get_malloc_leak_info;
+    debug_initialize;
+    debug_iterate;
+    debug_mallinfo;
+    debug_malloc;
+    debug_malloc_backtrace;
+    debug_malloc_disable;
+    debug_malloc_enable;
+    debug_malloc_usable_size;
+    debug_memalign;
+    debug_posix_memalign;
+    debug_realloc;
+
+  local:
+    *;
+};
diff --git a/libc/malloc_debug/malloc_debug.cpp b/libc/malloc_debug/malloc_debug.cpp
new file mode 100644
index 0000000..1ee7689
--- /dev/null
+++ b/libc/malloc_debug/malloc_debug.cpp
@@ -0,0 +1,699 @@
+/*
+ * Copyright (C) 2012 The Android Open Source Project
+ * All rights reserved.
+ *
+ * Redistribution and use in source and binary forms, with or without
+ * modification, are permitted provided that the following conditions
+ * are met:
+ *  * Redistributions of source code must retain the above copyright
+ *    notice, this list of conditions and the following disclaimer.
+ *  * Redistributions in binary form must reproduce the above copyright
+ *    notice, this list of conditions and the following disclaimer in
+ *    the documentation and/or other materials provided with the
+ *    distribution.
+ *
+ * THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS
+ * "AS IS" AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT
+ * LIMITED TO, THE IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS
+ * FOR A PARTICULAR PURPOSE ARE DISCLAIMED. IN NO EVENT SHALL THE
+ * COPYRIGHT OWNER OR CONTRIBUTORS BE LIABLE FOR ANY DIRECT, INDIRECT,
+ * INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING,
+ * BUT NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; LOSS
+ * OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED
+ * AND ON ANY THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY,
+ * OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT
+ * OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF
+ * SUCH DAMAGE.
+ */
+
+#include <errno.h>
+#include <inttypes.h>
+#include <malloc.h>
+#include <string.h>
+#include <sys/cdefs.h>
+#include <sys/param.h>
+#include <unistd.h>
+
+#include <vector>
+
+#include <private/bionic_malloc_dispatch.h>
+
+#include "backtrace.h"
+#include "Config.h"
+#include "DebugData.h"
+#include "debug_disable.h"
+#include "debug_log.h"
+#include "malloc_debug.h"
+
+// ------------------------------------------------------------------------
+// Global Data
+// ------------------------------------------------------------------------
+DebugData* g_debug;
+
+int* g_malloc_zygote_child;
+
+const MallocDispatch* g_dispatch;
+// ------------------------------------------------------------------------
+
+// ------------------------------------------------------------------------
+// Use C style prototypes for all exported functions. This makes it easy
+// to do dlsym lookups during libc initialization when malloc debug
+// is enabled.
+// ------------------------------------------------------------------------
+__BEGIN_DECLS
+
+bool debug_initialize(const MallocDispatch* malloc_dispatch, int* malloc_zygote_child);
+void debug_finalize();
+void debug_get_malloc_leak_info(
+    uint8_t** info, size_t* overall_size, size_t* info_size, size_t* total_memory,
+    size_t* backtrace_size);
+ssize_t debug_malloc_backtrace(void* pointer, uintptr_t* frames, size_t frame_count);
+void debug_free_malloc_leak_info(uint8_t* info);
+size_t debug_malloc_usable_size(void* pointer);
+void* debug_malloc(size_t size);
+void debug_free(void* pointer);
+void* debug_memalign(size_t alignment, size_t bytes);
+void* debug_realloc(void* pointer, size_t bytes);
+void* debug_calloc(size_t nmemb, size_t bytes);
+struct mallinfo debug_mallinfo();
+int debug_posix_memalign(void** memptr, size_t alignment, size_t size);
+int debug_iterate(uintptr_t base, size_t size,
+    void (*callback)(uintptr_t base, size_t size, void* arg), void* arg);
+void debug_malloc_disable();
+void debug_malloc_enable();
+
+#if defined(HAVE_DEPRECATED_MALLOC_FUNCS)
+void* debug_pvalloc(size_t bytes);
+void* debug_valloc(size_t size);
+#endif
+
+__END_DECLS
+// ------------------------------------------------------------------------
+
+static void InitAtfork() {
+  static pthread_once_t atfork_init = PTHREAD_ONCE_INIT;
+  pthread_once(&atfork_init, [](){
+    pthread_atfork(
+        [](){
+          if (g_debug != nullptr) {
+            g_debug->PrepareFork();
+          }
+        },
+        [](){
+          if (g_debug != nullptr) {
+            g_debug->PostForkParent();
+          }
+        },
+        [](){
+          if (g_debug != nullptr) {
+            g_debug->PostForkChild();
+          }
+        }
+    );
+  });
+}
+
+static void LogTagError(const Header* header, const void* pointer, const char* name) {
+  ScopedDisableDebugCalls disable;
+
+  error_log(LOG_DIVIDER);
+  if (header->tag == DEBUG_FREE_TAG) {
+    error_log("+++ ALLOCATION %p USED AFTER FREE (%s)", pointer, name);
+    if (g_debug->config().options & FREE_TRACK) {
+      g_debug->free_track->LogBacktrace(header);
+    }
+  } else {
+    error_log("+++ ALLOCATION %p HAS INVALID TAG %" PRIx32 " (%s)", pointer, header->tag, name);
+  }
+  error_log("Backtrace at time of failure:");
+  std::vector<uintptr_t> frames(64);
+  size_t frame_num = backtrace_get(frames.data(), frames.size());
+  frames.resize(frame_num);
+  backtrace_log(frames.data(), frames.size());
+  error_log(LOG_DIVIDER);
+}
+
+static void* InitHeader(Header* header, void* orig_pointer, size_t size) {
+  header->tag = DEBUG_TAG;
+  header->orig_pointer = orig_pointer;
+  header->size = size;
+  if (*g_malloc_zygote_child) {
+    header->set_zygote();
+  }
+  header->usable_size = g_dispatch->malloc_usable_size(orig_pointer);
+  if (header->usable_size == 0) {
+    g_dispatch->free(orig_pointer);
+    return nullptr;
+  }
+  header->usable_size -= g_debug->pointer_offset() +
+      reinterpret_cast<uintptr_t>(header) - reinterpret_cast<uintptr_t>(orig_pointer);
+
+  if (g_debug->config().options & FRONT_GUARD) {
+    uint8_t* guard = g_debug->GetFrontGuard(header);
+    memset(guard, g_debug->config().front_guard_value, g_debug->config().front_guard_bytes);
+  }
+
+  if (g_debug->config().options & REAR_GUARD) {
+    uint8_t* guard = g_debug->GetRearGuard(header);
+    memset(guard, g_debug->config().rear_guard_value, g_debug->config().rear_guard_bytes);
+    // If the rear guard is enabled, set the usable size to the exact size
+    // of the allocation.
+    header->usable_size = header->real_size();
+  }
+
+  bool backtrace_found = false;
+  if (g_debug->config().options & BACKTRACE) {
+    BacktraceHeader* back_header = g_debug->GetAllocBacktrace(header);
+    if (g_debug->backtrace->enabled()) {
+      ScopedDisableDebugCalls disable;
+      back_header->num_frames = backtrace_get(
+          &back_header->frames[0], g_debug->config().backtrace_frames);
+      backtrace_found = back_header->num_frames > 0;
+    } else {
+      back_header->num_frames = 0;
+    }
+  }
+
+  if (g_debug->config().options & TRACK_ALLOCS) {
+    g_debug->track->Add(header, backtrace_found);
+  }
+
+  return g_debug->GetPointer(header);
+}
+
+bool debug_initialize(const MallocDispatch* malloc_dispatch, int* malloc_zygote_child) {
+  if (malloc_zygote_child == nullptr) {
+    return false;
+  }
+
+  InitAtfork();
+
+  g_malloc_zygote_child = malloc_zygote_child;
+
+  g_dispatch = malloc_dispatch;
+
+  if (!DebugDisableInitialize()) {
+    return false;
+  }
+
+  DebugData* debug = new DebugData();
+  if (!debug->Initialize()) {
+    delete debug;
+    DebugDisableFinalize();
+    return false;
+  }
+  g_debug = debug;
+
+  // Always enable the backtrace code since we will use it in a number
+  // of different error cases.
+  backtrace_startup();
+
+  return true;
+}
+
+void debug_finalize() {
+  if (g_debug == nullptr) {
+    return;
+  }
+
+  if (g_debug->config().options & FREE_TRACK) {
+    g_debug->free_track->VerifyAll(*g_debug);
+  }
+
+  if (g_debug->config().options & LEAK_TRACK) {
+    g_debug->track->DisplayLeaks(*g_debug);
+  }
+
+  DebugDisableSet(true);
+
+  backtrace_shutdown();
+
+  delete g_debug;
+  g_debug = nullptr;
+
+  DebugDisableFinalize();
+}
+
+void debug_get_malloc_leak_info(uint8_t** info, size_t* overall_size,
+    size_t* info_size, size_t* total_memory, size_t* backtrace_size) {
+  ScopedDisableDebugCalls disable;
+
+  // Verify the arguments.
+  if (info == nullptr || overall_size == nullptr || info_size == NULL ||
+      total_memory == nullptr || backtrace_size == nullptr) {
+    error_log("get_malloc_leak_info: At least one invalid parameter.");
+    return;
+  }
+
+  *info = nullptr;
+  *overall_size = 0;
+  *info_size = 0;
+  *total_memory = 0;
+  *backtrace_size = 0;
+
+  if (!(g_debug->config().options & BACKTRACE)) {
+    error_log("get_malloc_leak_info: Allocations not being tracked, to enable "
+              "set the option 'backtrace'.");
+    return;
+  }
+
+  g_debug->track->GetInfo(*g_debug, info, overall_size, info_size, total_memory, backtrace_size);
+}
+
+void debug_free_malloc_leak_info(uint8_t* info) {
+  g_dispatch->free(info);
+}
+
+size_t debug_malloc_usable_size(void* pointer) {
+  if (DebugCallsDisabled() || !g_debug->need_header() || pointer == nullptr) {
+    return g_dispatch->malloc_usable_size(pointer);
+  }
+
+  Header* header = g_debug->GetHeader(pointer);
+  if (header->tag != DEBUG_TAG) {
+    LogTagError(header, pointer, "malloc_usable_size");
+    return 0;
+  }
+
+  return header->usable_size;
+}
+
+void* debug_malloc(size_t size) {
+  if (DebugCallsDisabled()) {
+    return g_dispatch->malloc(size);
+  }
+
+  if (size == 0) {
+    size = 1;
+  }
+
+  size_t real_size = size + g_debug->extra_bytes();
+  if (real_size < size) {
+    // Overflow.
+    errno = ENOMEM;
+    return nullptr;
+  }
+
+  void* pointer;
+  if (g_debug->need_header()) {
+    if (size > Header::max_size()) {
+      errno = ENOMEM;
+      return nullptr;
+    }
+
+    Header* header = reinterpret_cast<Header*>(
+        g_dispatch->memalign(MINIMUM_ALIGNMENT_BYTES, real_size));
+    if (header == nullptr) {
+      return nullptr;
+    }
+    pointer = InitHeader(header, header, size);
+  } else {
+    pointer = g_dispatch->malloc(real_size);
+  }
+
+  if (pointer != nullptr && g_debug->config().options & FILL_ON_ALLOC) {
+    size_t bytes = debug_malloc_usable_size(pointer);
+    size_t fill_bytes = g_debug->config().fill_on_alloc_bytes;
+    bytes = (bytes < fill_bytes) ? bytes : fill_bytes;
+    memset(pointer, g_debug->config().fill_alloc_value, bytes);
+  }
+  return pointer;
+}
+
+void debug_free(void* pointer) {
+  if (DebugCallsDisabled() || pointer == nullptr) {
+    return g_dispatch->free(pointer);
+  }
+
+  void* free_pointer = pointer;
+  size_t bytes;
+  Header* header;
+  if (g_debug->need_header()) {
+    header = g_debug->GetHeader(pointer);
+    if (header->tag != DEBUG_TAG) {
+      LogTagError(header, pointer, "free");
+      return;
+    }
+    free_pointer = header->orig_pointer;
+
+    if (g_debug->config().options & FRONT_GUARD) {
+      if (!g_debug->front_guard->Valid(*g_debug, header)) {
+        g_debug->front_guard->LogFailure(*g_debug, header);
+      }
+    }
+    if (g_debug->config().options & REAR_GUARD) {
+      if (!g_debug->rear_guard->Valid(*g_debug, header)) {
+        g_debug->rear_guard->LogFailure(*g_debug, header);
+      }
+    }
+
+    if (g_debug->config().options & TRACK_ALLOCS) {
+      bool backtrace_found = false;
+      if (g_debug->config().options & BACKTRACE) {
+        BacktraceHeader* back_header = g_debug->GetAllocBacktrace(header);
+        backtrace_found = back_header->num_frames > 0;
+      }
+      g_debug->track->Remove(header, backtrace_found);
+    }
+    header->tag = DEBUG_FREE_TAG;
+
+    bytes = header->usable_size;
+  } else {
+    bytes = g_dispatch->malloc_usable_size(pointer);
+  }
+
+  if (g_debug->config().options & FILL_ON_FREE) {
+    size_t fill_bytes = g_debug->config().fill_on_free_bytes;
+    bytes = (bytes < fill_bytes) ? bytes : fill_bytes;
+    memset(pointer, g_debug->config().fill_free_value, bytes);
+  }
+
+  if (g_debug->config().options & FREE_TRACK) {
+    // Do not add the allocation until we are done modifying the pointer
+    // itself. This avoids a race if a lot of threads are all doing
+    // frees at the same time and we wind up trying to really free this
+    // pointer from another thread, while still trying to free it in
+    // this function.
+    g_debug->free_track->Add(*g_debug, header);
+  } else {
+    g_dispatch->free(free_pointer);
+  }
+}
+
+void* debug_memalign(size_t alignment, size_t bytes) {
+  if (DebugCallsDisabled()) {
+    return g_dispatch->memalign(alignment, bytes);
+  }
+
+  if (bytes == 0) {
+    bytes = 1;
+  }
+
+  void* pointer;
+  if (g_debug->need_header()) {
+    if (bytes > Header::max_size()) {
+      errno = ENOMEM;
+      return nullptr;
+    }
+
+    // Make the alignment a power of two.
+    if (!powerof2(alignment)) {
+      alignment = BIONIC_ROUND_UP_POWER_OF_2(alignment);
+    }
+    // Force the alignment to at least MINIMUM_ALIGNMENT_BYTES to guarantee
+    // that the header is aligned properly.
+    if (alignment < MINIMUM_ALIGNMENT_BYTES) {
+      alignment = MINIMUM_ALIGNMENT_BYTES;
+    }
+
+    // We don't have any idea what the natural alignment of
+    // the underlying native allocator is, so we always need to
+    // over allocate.
+    size_t real_size = alignment + bytes + g_debug->extra_bytes();
+    if (real_size < bytes) {
+      // Overflow.
+      errno = ENOMEM;
+      return nullptr;
+    }
+
+    pointer = g_dispatch->malloc(real_size);
+    if (pointer == nullptr) {
+      return nullptr;
+    }
+
+    uintptr_t value = reinterpret_cast<uintptr_t>(pointer) + g_debug->pointer_offset();
+    // Now align the pointer.
+    value += (-value % alignment);
+
+    Header* header = g_debug->GetHeader(reinterpret_cast<void*>(value));
+    pointer = InitHeader(header, pointer, bytes);
+  } else {
+    size_t real_size = bytes + g_debug->extra_bytes();
+    if (real_size < bytes) {
+      // Overflow.
+      errno = ENOMEM;
+      return nullptr;
+    }
+    pointer = g_dispatch->memalign(alignment, real_size);
+  }
+
+  if (pointer != nullptr && g_debug->config().options & FILL_ON_ALLOC) {
+    size_t bytes = debug_malloc_usable_size(pointer);
+    size_t fill_bytes = g_debug->config().fill_on_alloc_bytes;
+    bytes = (bytes < fill_bytes) ? bytes : fill_bytes;
+    memset(pointer, g_debug->config().fill_alloc_value, bytes);
+  }
+  return pointer;
+}
+
+void* debug_realloc(void* pointer, size_t bytes) {
+  if (DebugCallsDisabled()) {
+    return g_dispatch->realloc(pointer, bytes);
+  }
+
+  if (pointer == nullptr) {
+    return debug_malloc(bytes);
+  }
+
+  if (bytes == 0) {
+    debug_free(pointer);
+    return nullptr;
+  }
+
+  size_t real_size = bytes;
+  if (g_debug->config().options & EXPAND_ALLOC) {
+    real_size += g_debug->config().expand_alloc_bytes;
+    if (real_size < bytes) {
+      // Overflow.
+      errno = ENOMEM;
+      return nullptr;
+    }
+  }
+
+  void* new_pointer;
+  size_t prev_size;
+  if (g_debug->need_header()) {
+    if (bytes > Header::max_size()) {
+      errno = ENOMEM;
+      return nullptr;
+    }
+
+    Header* header = g_debug->GetHeader(pointer);
+    if (header->tag != DEBUG_TAG) {
+      LogTagError(header, pointer, "realloc");
+      return nullptr;
+    }
+
+    // Same size, do nothing.
+    if (real_size == header->real_size()) {
+      return pointer;
+    }
+
+    // Allocation is shrinking.
+    if (real_size < header->usable_size) {
+      header->size = real_size;
+      if (*g_malloc_zygote_child) {
+        header->set_zygote();
+      }
+      if (g_debug->config().options & REAR_GUARD) {
+        // Don't bother allocating a smaller pointer in this case, simply
+        // change the header usable_size and reset the rear guard.
+        header->usable_size = header->real_size();
+        memset(g_debug->GetRearGuard(header), g_debug->config().rear_guard_value,
+               g_debug->config().rear_guard_bytes);
+      }
+      return pointer;
+    }
+
+    // Allocate the new size.
+    new_pointer = debug_malloc(bytes);
+    if (new_pointer == nullptr) {
+      errno = ENOMEM;
+      return nullptr;
+    }
+
+    prev_size = header->usable_size;
+    memcpy(new_pointer, pointer, prev_size);
+    debug_free(pointer);
+  } else {
+    prev_size = g_dispatch->malloc_usable_size(pointer);
+    new_pointer = g_dispatch->realloc(pointer, real_size);
+    if (new_pointer == nullptr) {
+      return nullptr;
+    }
+  }
+
+  if (g_debug->config().options & FILL_ON_ALLOC) {
+    size_t bytes = debug_malloc_usable_size(new_pointer);
+    if (bytes > g_debug->config().fill_on_alloc_bytes) {
+      bytes = g_debug->config().fill_on_alloc_bytes;
+    }
+    if (bytes > prev_size) {
+      memset(reinterpret_cast<void*>(reinterpret_cast<uintptr_t>(new_pointer) + prev_size),
+             g_debug->config().fill_alloc_value, bytes - prev_size);
+    }
+  }
+
+  return new_pointer;
+}
+
+void* debug_calloc(size_t nmemb, size_t bytes) {
+  if (DebugCallsDisabled()) {
+    return g_dispatch->calloc(nmemb, bytes);
+  }
+
+  size_t size;
+  if (__builtin_mul_overflow(nmemb, bytes, &size)) {
+    // Overflow
+    errno = ENOMEM;
+    return nullptr;
+  }
+
+  if (size == 0) {
+    size = 1;
+  }
+
+  size_t real_size;
+  if (__builtin_add_overflow(size, g_debug->extra_bytes(), &real_size)) {
+    // Overflow.
+    errno = ENOMEM;
+    return nullptr;
+  }
+
+  if (g_debug->need_header()) {
+    // The above check will guarantee the multiply will not overflow.
+    if (size > Header::max_size()) {
+      errno = ENOMEM;
+      return nullptr;
+    }
+
+    // Need to guarantee the alignment of the header.
+    Header* header = reinterpret_cast<Header*>(
+        g_dispatch->memalign(MINIMUM_ALIGNMENT_BYTES, real_size));
+    if (header == nullptr) {
+      return nullptr;
+    }
+    memset(header, 0, g_dispatch->malloc_usable_size(header));
+    return InitHeader(header, header, size);
+  } else {
+    return g_dispatch->calloc(1, real_size);
+  }
+}
+
+struct mallinfo debug_mallinfo() {
+  return g_dispatch->mallinfo();
+}
+
+int debug_posix_memalign(void** memptr, size_t alignment, size_t size) {
+  if (DebugCallsDisabled()) {
+    return g_dispatch->posix_memalign(memptr, alignment, size);
+  }
+
+  if (!powerof2(alignment)) {
+    return EINVAL;
+  }
+  int saved_errno = errno;
+  *memptr = debug_memalign(alignment, size);
+  errno = saved_errno;
+  return (*memptr != nullptr) ? 0 : ENOMEM;
+}
+
+int debug_iterate(uintptr_t base, size_t size,
+    void (*callback)(uintptr_t base, size_t size, void* arg), void* arg) {
+  // Can't allocate, malloc is disabled
+  // Manual capture of the arguments to pass to the lambda below as void* arg
+  struct iterate_ctx {
+    decltype(callback) callback;
+    decltype(arg) arg;
+  } ctx = { callback, arg };
+
+  return g_dispatch->iterate(base, size,
+      [](uintptr_t base, size_t size, void* arg) {
+        const iterate_ctx* ctx = reinterpret_cast<iterate_ctx*>(arg);
+        const void* pointer = reinterpret_cast<void*>(base);
+        if (g_debug->need_header()) {
+          const Header* header = reinterpret_cast<const Header*>(pointer);
+          if (g_debug->config().options & TRACK_ALLOCS) {
+            if (g_debug->track->Contains(header)) {
+              // Return just the body of the allocation if we're sure the header exists
+              ctx->callback(reinterpret_cast<uintptr_t>(g_debug->GetPointer(header)),
+                  header->usable_size, ctx->arg);
+              return;
+            }
+          }
+        }
+        // Fall back to returning the whole allocation
+        ctx->callback(base, size, ctx->arg);
+      }, &ctx);
+}
+
+void debug_malloc_disable() {
+  g_dispatch->malloc_disable();
+  if (g_debug->track) {
+    g_debug->track->PrepareFork();
+  }
+}
+
+void debug_malloc_enable() {
+  if (g_debug->track) {
+    g_debug->track->PostForkParent();
+  }
+  g_dispatch->malloc_enable();
+}
+
+ssize_t debug_malloc_backtrace(void* pointer, uintptr_t* frames, size_t frame_count) {
+  if (DebugCallsDisabled() || pointer == nullptr) {
+    return 0;
+  }
+
+  if (g_debug->need_header()) {
+    Header* header;
+    if (g_debug->config().options & TRACK_ALLOCS) {
+      header = g_debug->GetHeader(pointer);
+      if (!g_debug->track->Contains(header)) {
+        return 0;
+      }
+    } else {
+      header = reinterpret_cast<Header*>(pointer);
+    }
+    if (header->tag != DEBUG_TAG) {
+      return 0;
+    }
+    if (g_debug->config().options & BACKTRACE) {
+      BacktraceHeader* back_header = g_debug->GetAllocBacktrace(header);
+      if (back_header->num_frames > 0) {
+        if (frame_count > back_header->num_frames) {
+          frame_count = back_header->num_frames;
+        }
+        memcpy(frames, &back_header->frames[0], frame_count * sizeof(uintptr_t));
+        return frame_count;
+      }
+    }
+  }
+
+  return 0;
+}
+
+#if defined(HAVE_DEPRECATED_MALLOC_FUNCS)
+void* debug_pvalloc(size_t bytes) {
+  if (DebugCallsDisabled()) {
+    return g_dispatch->pvalloc(bytes);
+  }
+
+  size_t pagesize = getpagesize();
+  size_t size = BIONIC_ALIGN(bytes, pagesize);
+  if (size < bytes) {
+    // Overflow
+    errno = ENOMEM;
+    return nullptr;
+  }
+  return debug_memalign(pagesize, size);
+}
+
+void* debug_valloc(size_t size) {
+  if (DebugCallsDisabled()) {
+    return g_dispatch->valloc(size);
+  }
+  return debug_memalign(getpagesize(), size);
+}
+#endif
diff --git a/libc/malloc_debug/malloc_debug.h b/libc/malloc_debug/malloc_debug.h
new file mode 100644
index 0000000..347fae2
--- /dev/null
+++ b/libc/malloc_debug/malloc_debug.h
@@ -0,0 +1,73 @@
+/*
+ * Copyright (C) 2015 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 MALLOC_DEBUG_H
+#define MALLOC_DEBUG_H
+
+#include <stdint.h>
+
+#include <private/bionic_malloc_dispatch.h>
+
+// Allocations that require a header include a variable length header.
+// This is the order that data structures will be found. If an optional
+// part of the header does not exist, the other parts of the header
+// will still be in this order.
+//   Header          (Required)
+//   BacktraceHeader (Optional: For the allocation backtrace)
+//   uint8_t data    (Optional: Front guard, will be a multiple of MINIMUM_ALIGNMENT_BYTES)
+//   allocation data
+//   uint8_t data    (Optional: End guard)
+//
+// If backtracing is enabled, then both BacktraceHeaders will be present.
+//
+// In the initialization function, offsets into the header will be set
+// for each different header location. The offsets are always from the
+// beginning of the Header section.
+struct Header {
+  uint32_t tag;
+  void* orig_pointer;
+  size_t size;
+  size_t usable_size;
+  size_t real_size() const { return size & ~(1U << 31); }
+  void set_zygote() { size |= 1U << 31; }
+  static size_t max_size() { return (1U << 31) - 1; }
+} __attribute__((packed));
+
+struct BacktraceHeader {
+  size_t num_frames;
+  uintptr_t frames[0];
+} __attribute__((packed));
+
+constexpr uint32_t DEBUG_TAG = 0x1ee7d00d;
+constexpr uint32_t DEBUG_FREE_TAG = 0x1cc7dccd;
+constexpr char LOG_DIVIDER[] = "*** *** *** *** *** *** *** *** *** *** *** *** *** *** *** ***";
+constexpr size_t FREE_TRACK_MEM_BUFFER_SIZE = 4096;
+
+extern const MallocDispatch* g_dispatch;
+
+#endif // MALLOC_DEBUG_H
diff --git a/libc/malloc_debug/tests/backtrace_fake.cpp b/libc/malloc_debug/tests/backtrace_fake.cpp
new file mode 100644
index 0000000..db542e5
--- /dev/null
+++ b/libc/malloc_debug/tests/backtrace_fake.cpp
@@ -0,0 +1,59 @@
+/*
+ * Copyright (C) 2015 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 <stdint.h>
+
+#include <deque>
+#include <vector>
+#include <utility>
+
+#include "backtrace.h"
+#include "backtrace_fake.h"
+#include "debug_log.h"
+
+static std::deque<std::vector<uintptr_t>> g_fake_backtrace;
+
+void backtrace_fake_clear_all() {
+  g_fake_backtrace.clear();
+}
+
+void backtrace_fake_add(const std::vector<uintptr_t>& ips) {
+  g_fake_backtrace.push_back(ips);
+}
+
+void backtrace_startup() {
+}
+
+void backtrace_shutdown() {
+}
+
+size_t backtrace_get(uintptr_t* frames, size_t frame_num) {
+  if (frame_num == 0 || g_fake_backtrace.size() == 0) {
+    return 0;
+  }
+
+  size_t ips_size = g_fake_backtrace[0].size();
+  size_t total_frames = (frame_num < ips_size) ? frame_num : ips_size;
+  memcpy(frames, g_fake_backtrace[0].data(), sizeof(uintptr_t) * total_frames);
+  g_fake_backtrace.pop_front();
+  return total_frames;
+}
+
+void backtrace_log(const uintptr_t* frames, size_t frame_count) {
+  for (size_t i = 0; i < frame_count; i++) {
+    error_log("  #%02zd pc %p", i, reinterpret_cast<void*>(frames[i]));
+  }
+}
diff --git a/libc/upstream-freebsd/android/include/spinlock.h b/libc/malloc_debug/tests/backtrace_fake.h
similarity index 63%
copy from libc/upstream-freebsd/android/include/spinlock.h
copy to libc/malloc_debug/tests/backtrace_fake.h
index f5c3785..f2aa7a0 100644
--- a/libc/upstream-freebsd/android/include/spinlock.h
+++ b/libc/malloc_debug/tests/backtrace_fake.h
@@ -1,5 +1,5 @@
 /*
- * Copyright (C) 2013 The Android Open Source Project
+ * Copyright (C) 2015 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,9 +14,14 @@
  * limitations under the License.
  */
 
-#ifndef _BIONIC_FREEBSD_SPINLOCK_H_included
-#define _BIONIC_FREEBSD_SPINLOCK_H_included
+#ifndef MALLOC_DEBUG_TESTS_BACKTRACE_FAKE_H
+#define MALLOC_DEBUG_TESTS_BACKTRACE_FAKE_H
 
-/* TODO: until we have the FreeBSD findfp.c, this is useless. */
+#include <stdint.h>
 
-#endif
+#include <vector>
+
+void backtrace_fake_clear_all();
+void backtrace_fake_add(const std::vector<uintptr_t>& ips);
+
+#endif // MALLOC_DEBUG_TESTS_BACKTRACE_FAKE_H
diff --git a/libc/upstream-freebsd/android/include/spinlock.h b/libc/malloc_debug/tests/libc_fake.cpp
similarity index 71%
copy from libc/upstream-freebsd/android/include/spinlock.h
copy to libc/malloc_debug/tests/libc_fake.cpp
index f5c3785..45ace4d 100644
--- a/libc/upstream-freebsd/android/include/spinlock.h
+++ b/libc/malloc_debug/tests/libc_fake.cpp
@@ -1,5 +1,5 @@
 /*
- * Copyright (C) 2013 The Android Open Source Project
+ * Copyright (C) 2015 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,9 +14,6 @@
  * limitations under the License.
  */
 
-#ifndef _BIONIC_FREEBSD_SPINLOCK_H_included
-#define _BIONIC_FREEBSD_SPINLOCK_H_included
-
-/* TODO: until we have the FreeBSD findfp.c, this is useless. */
-
-#endif
+extern "C" const char* getprogname() {
+  return "malloc_testing";
+}
diff --git a/libc/malloc_debug/tests/log_fake.cpp b/libc/malloc_debug/tests/log_fake.cpp
new file mode 100644
index 0000000..7350ea0
--- /dev/null
+++ b/libc/malloc_debug/tests/log_fake.cpp
@@ -0,0 +1,110 @@
+/*
+ * Copyright (C) 2015 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 <errno.h>
+#include <stdarg.h>
+
+#include <string>
+
+#include <android-base/stringprintf.h>
+#include <log/log.h>
+#include <log/logger.h>
+
+// Forward declarations.
+class Backtrace;
+struct EventTagMap;
+struct AndroidLogEntry;
+
+std::string g_fake_log_buf;
+
+std::string g_fake_log_print;
+
+void resetLogs() {
+  g_fake_log_buf = "";
+  g_fake_log_print = "";
+}
+
+std::string getFakeLogBuf() {
+  return g_fake_log_buf;
+}
+
+std::string getFakeLogPrint() {
+  return g_fake_log_print;
+}
+
+extern "C" int __libc_format_log(int priority, const char* tag, const char* format, ...) {
+  g_fake_log_print += std::to_string(priority) + ' ';
+  g_fake_log_print += tag;
+  g_fake_log_print += ' ';
+
+  va_list ap;
+  va_start(ap, format);
+  android::base::StringAppendV(&g_fake_log_print, format, ap);
+  va_end(ap);
+
+  g_fake_log_print += '\n';
+
+  return 0;
+}
+
+extern "C" int __android_log_buf_write(int bufId, int prio, const char* tag, const char* msg) {
+  g_fake_log_buf += std::to_string(bufId) + ' ' + std::to_string(prio) + ' ';
+  g_fake_log_buf += tag;
+  g_fake_log_buf += ' ';
+  g_fake_log_buf += msg;
+  return 1;
+}
+
+extern "C" int __android_log_print(int prio, const char* tag, const char* fmt, ...) {
+  g_fake_log_print += std::to_string(prio) + ' ';
+  g_fake_log_print += tag;
+  g_fake_log_print += ' ';
+
+  va_list ap;
+  va_start(ap, fmt);
+  android::base::StringAppendV(&g_fake_log_print, fmt, ap);
+  va_end(ap);
+
+  g_fake_log_print += '\n';
+
+  return 1;
+}
+
+extern "C" log_id_t android_name_to_log_id(const char*) {
+  return LOG_ID_SYSTEM;
+}
+
+extern "C" struct logger_list* android_logger_list_open(log_id_t, int, unsigned int, pid_t) {
+  errno = EACCES;
+  return nullptr;
+}
+
+extern "C" int android_logger_list_read(struct logger_list*, struct log_msg*) {
+  return 0;
+}
+
+extern "C" EventTagMap* android_openEventTagMap(const char*) {
+  return nullptr;
+}
+
+extern "C" int android_log_processBinaryLogBuffer(
+    struct logger_entry*,
+    AndroidLogEntry*, const EventTagMap*, char*, int) {
+  return 0;
+}
+
+extern "C" void android_logger_list_free(struct logger_list*) {
+}
diff --git a/benchmarks/utils.h b/libc/malloc_debug/tests/log_fake.h
similarity index 69%
rename from benchmarks/utils.h
rename to libc/malloc_debug/tests/log_fake.h
index c3c64ba..1ea72f8 100644
--- a/benchmarks/utils.h
+++ b/libc/malloc_debug/tests/log_fake.h
@@ -1,5 +1,5 @@
 /*
- * Copyright (C) 2012 The Android Open Source Project
+ * Copyright (C) 2015 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,13 +14,13 @@
  * limitations under the License.
  */
 
-#ifndef BENCHMARKS_UTILS_H
-#define BENCHMARKS_UTILS_H
+#ifndef MALLOC_DEBUG_TESTS_LOG_FAKE_H
+#define MALLOC_DEBUG_TESTS_LOG_FAKE_H
 
-#include <stddef.h>
 #include <string>
 
-int Round(int n);
-std::string PrettyInt(long value, size_t base);
+void resetLogs();
+std::string getFakeLogBuf();
+std::string getFakeLogPrint();
 
-#endif  // BENCHMARKS_UTILS_H
+#endif // MALLOC_DEBUG_TESTS_LOG_FAKE_H
diff --git a/libc/malloc_debug/tests/malloc_debug_config_tests.cpp b/libc/malloc_debug/tests/malloc_debug_config_tests.cpp
new file mode 100644
index 0000000..85d5cb5
--- /dev/null
+++ b/libc/malloc_debug/tests/malloc_debug_config_tests.cpp
@@ -0,0 +1,628 @@
+/*
+ * Copyright (C) 2015 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 <limits.h>
+
+#include <memory>
+#include <string>
+
+#include <gtest/gtest.h>
+
+#include "Config.h"
+
+#include "log_fake.h"
+
+extern "C" int property_set(const char*, const char*);
+
+class MallocDebugConfigTest : public ::testing::Test {
+ protected:
+  void SetUp() override {
+    resetLogs();
+  }
+
+  void TearDown() override {
+  }
+
+  std::unique_ptr<Config> config;
+
+  bool InitConfig(const char* property_value) {
+    config.reset(new Config);
+    property_set("libc.debug.malloc.options", property_value);
+    return config->SetFromProperties();
+  }
+};
+
+std::string usage_string(
+  "6 malloc_debug malloc debug options usage:\n"
+  "6 malloc_debug \n"
+  "6 malloc_debug   front_guard[=XX]\n"
+  "6 malloc_debug     Enables a front guard on all allocations. If XX is set\n"
+  "6 malloc_debug     it sets the number of bytes in the guard. The default is\n"
+  "6 malloc_debug     32 bytes, the max bytes is 16384.\n"
+  "6 malloc_debug \n"
+  "6 malloc_debug   rear_guard[=XX]\n"
+  "6 malloc_debug     Enables a rear guard on all allocations. If XX is set\n"
+  "6 malloc_debug     it sets the number of bytes in the guard. The default is\n"
+  "6 malloc_debug     32 bytes, the max bytes is 16384.\n"
+  "6 malloc_debug \n"
+  "6 malloc_debug   guard[=XX]\n"
+  "6 malloc_debug     Enables both a front guard and a rear guard on all allocations.\n"
+  "6 malloc_debug     If XX is set it sets the number of bytes in both guards.\n"
+  "6 malloc_debug     The default is 32 bytes, the max bytes is 16384.\n"
+  "6 malloc_debug \n"
+  "6 malloc_debug   backtrace[=XX]\n"
+  "6 malloc_debug     Enable capturing the backtrace at the point of allocation.\n"
+  "6 malloc_debug     If XX is set it sets the number of backtrace frames.\n"
+  "6 malloc_debug     The default is 16 frames, the max number of frames is 256.\n"
+  "6 malloc_debug \n"
+  "6 malloc_debug   backtrace_enable_on_signal[=XX]\n"
+  "6 malloc_debug     Enable capturing the backtrace at the point of allocation.\n"
+  "6 malloc_debug     The backtrace capture is not enabled until the process\n"
+  "6 malloc_debug     receives a signal. If XX is set it sets the number of backtrace\n"
+  "6 malloc_debug     frames. The default is 16 frames, the max number of frames is 256.\n"
+  "6 malloc_debug \n"
+  "6 malloc_debug   fill_on_alloc[=XX]\n"
+  "6 malloc_debug     On first allocation, fill with the value 0xeb.\n"
+  "6 malloc_debug     If XX is set it will only fill up to XX bytes of the\n"
+  "6 malloc_debug     allocation. The default is to fill the entire allocation.\n"
+  "6 malloc_debug \n"
+  "6 malloc_debug   fill_on_free[=XX]\n"
+  "6 malloc_debug     On free, fill with the value 0xef. If XX is set it will\n"
+  "6 malloc_debug     only fill up to XX bytes of the allocation. The default is to\n"
+  "6 malloc_debug     fill the entire allocation.\n"
+  "6 malloc_debug \n"
+  "6 malloc_debug   fill[=XX]\n"
+  "6 malloc_debug     On both first allocation free, fill with the value 0xeb on\n"
+  "6 malloc_debug     first allocation and the value 0xef. If XX is set, only fill\n"
+  "6 malloc_debug     up to XX bytes. The default is to fill the entire allocation.\n"
+  "6 malloc_debug \n"
+  "6 malloc_debug   expand_alloc[=XX]\n"
+  "6 malloc_debug     Allocate an extra number of bytes for every allocation call.\n"
+  "6 malloc_debug     If XX is set, that is the number of bytes to expand the\n"
+  "6 malloc_debug     allocation by. The default is 16 bytes, the max bytes is 16384.\n"
+  "6 malloc_debug \n"
+  "6 malloc_debug   free_track[=XX]\n"
+  "6 malloc_debug     When a pointer is freed, do not free the memory right away.\n"
+  "6 malloc_debug     Instead, keep XX of these allocations around and then verify\n"
+  "6 malloc_debug     that they have not been modified when the total number of freed\n"
+  "6 malloc_debug     allocations exceeds the XX amount. When the program terminates,\n"
+  "6 malloc_debug     the rest of these allocations are verified. When this option is\n"
+  "6 malloc_debug     enabled, it automatically records the backtrace at the time of the free.\n"
+  "6 malloc_debug     The default is to record 100 allocations, the max allocations\n"
+  "6 malloc_debug     to record is 16384.\n"
+  "6 malloc_debug \n"
+  "6 malloc_debug   free_track_backtrace_num_frames[=XX]\n"
+  "6 malloc_debug     This option only has meaning if free_track is set. This indicates\n"
+  "6 malloc_debug     how many backtrace frames to capture when an allocation is freed.\n"
+  "6 malloc_debug     If XX is set, that is the number of frames to capture. If XX\n"
+  "6 malloc_debug     is set to zero, then no backtrace will be captured.\n"
+  "6 malloc_debug     The default is to record 16 frames, the max number of frames is 256.\n"
+  "6 malloc_debug \n"
+  "6 malloc_debug   leak_track\n"
+  "6 malloc_debug     Enable the leak tracking of memory allocations.\n"
+);
+
+TEST_F(MallocDebugConfigTest, unknown_option) {
+
+  ASSERT_FALSE(InitConfig("unknown_option"));
+
+  ASSERT_STREQ("", getFakeLogBuf().c_str());
+  std::string log_msg("6 malloc_debug malloc_testing: unknown option unknown_option\n");
+  ASSERT_STREQ((log_msg + usage_string).c_str(), getFakeLogPrint().c_str());
+}
+
+TEST_F(MallocDebugConfigTest, good_option_and_bad_option) {
+  ASSERT_FALSE(InitConfig("backtrace unknown_option"));
+
+  ASSERT_STREQ("", getFakeLogBuf().c_str());
+  std::string log_msg("6 malloc_debug malloc_testing: unknown option unknown_option\n");
+  ASSERT_STREQ((log_msg + usage_string).c_str(), getFakeLogPrint().c_str());
+}
+
+TEST_F(MallocDebugConfigTest, unparseable_number) {
+  ASSERT_FALSE(InitConfig("backtrace=XXX"));
+
+  ASSERT_STREQ("", getFakeLogBuf().c_str());
+  std::string log_msg("6 malloc_debug malloc_testing: bad value for option 'backtrace'\n");
+  ASSERT_STREQ((log_msg + usage_string).c_str(), getFakeLogPrint().c_str());
+}
+
+TEST_F(MallocDebugConfigTest, illegal_value_zero) {
+  ASSERT_FALSE(InitConfig("backtrace=0"));
+
+  ASSERT_STREQ("", getFakeLogBuf().c_str());
+  std::string log_msg(
+      "6 malloc_debug malloc_testing: bad value for option 'backtrace', value must be >= 1: 0\n");
+  ASSERT_STREQ((log_msg + usage_string).c_str(), getFakeLogPrint().c_str());
+}
+
+TEST_F(MallocDebugConfigTest, no_space) {
+  ASSERT_FALSE(InitConfig("backtrace=10front_guard"));
+
+  ASSERT_STREQ("", getFakeLogBuf().c_str());
+  std::string log_msg(
+      "6 malloc_debug malloc_testing: bad value for option 'backtrace', "
+      "non space found after option: front_guard\n");
+  ASSERT_STREQ((log_msg + usage_string).c_str(), getFakeLogPrint().c_str());
+}
+
+TEST_F(MallocDebugConfigTest, illegal_value_negative) {
+  ASSERT_FALSE(InitConfig("backtrace=-1"));
+
+  ASSERT_STREQ("", getFakeLogBuf().c_str());
+  std::string log_msg(
+      "6 malloc_debug malloc_testing: bad value for option 'backtrace', "
+      "value cannot be negative: -1\n");
+  ASSERT_STREQ((log_msg + usage_string).c_str(), getFakeLogPrint().c_str());
+}
+
+TEST_F(MallocDebugConfigTest, overflow) {
+  ASSERT_FALSE(InitConfig("backtrace=99999999999999999999"));
+
+  ASSERT_STREQ("", getFakeLogBuf().c_str());
+  std::string log_msg(
+      "6 malloc_debug malloc_testing: bad value for option 'backtrace': "
+      "Math result not representable\n");
+  ASSERT_STREQ((log_msg + usage_string).c_str(), getFakeLogPrint().c_str());
+}
+
+TEST_F(MallocDebugConfigTest, set_value_error) {
+  ASSERT_FALSE(InitConfig("leak_track=12"));
+
+  ASSERT_STREQ("", getFakeLogBuf().c_str());
+  std::string log_msg(
+      "6 malloc_debug malloc_testing: value set for option 'leak_track' "
+      "which does not take a value\n");
+  ASSERT_STREQ((log_msg + usage_string).c_str(), getFakeLogPrint().c_str());
+}
+
+TEST_F(MallocDebugConfigTest, space_before_equal) {
+  ASSERT_TRUE(InitConfig("backtrace  =10"));
+  ASSERT_EQ(BACKTRACE | TRACK_ALLOCS, config->options);
+  ASSERT_EQ(10U, config->backtrace_frames);
+
+  ASSERT_STREQ("", getFakeLogBuf().c_str());
+  ASSERT_STREQ("", getFakeLogPrint().c_str());
+}
+
+TEST_F(MallocDebugConfigTest, space_after_equal) {
+  ASSERT_TRUE(InitConfig("backtrace=  10"));
+  ASSERT_EQ(BACKTRACE | TRACK_ALLOCS, config->options);
+  ASSERT_EQ(10U, config->backtrace_frames);
+
+  ASSERT_STREQ("", getFakeLogBuf().c_str());
+  ASSERT_STREQ("", getFakeLogPrint().c_str());
+}
+
+TEST_F(MallocDebugConfigTest, extra_space) {
+  ASSERT_TRUE(InitConfig("   backtrace=64   "));
+  ASSERT_EQ(BACKTRACE | TRACK_ALLOCS, config->options);
+  ASSERT_EQ(64U, config->backtrace_frames);
+
+  ASSERT_STREQ("", getFakeLogBuf().c_str());
+  ASSERT_STREQ("", getFakeLogPrint().c_str());
+}
+
+TEST_F(MallocDebugConfigTest, multiple_options) {
+  ASSERT_TRUE(InitConfig("  backtrace=64   front_guard=48"));
+  ASSERT_EQ(BACKTRACE | TRACK_ALLOCS | FRONT_GUARD, config->options);
+  ASSERT_EQ(64U, config->backtrace_frames);
+  ASSERT_EQ(48U, config->front_guard_bytes);
+
+  ASSERT_STREQ("", getFakeLogBuf().c_str());
+  ASSERT_STREQ("", getFakeLogPrint().c_str());
+}
+
+TEST_F(MallocDebugConfigTest, front_guard) {
+  ASSERT_TRUE(InitConfig("front_guard=48"));
+  ASSERT_EQ(FRONT_GUARD, config->options);
+  ASSERT_EQ(48U, config->front_guard_bytes);
+
+  ASSERT_TRUE(InitConfig("front_guard"));
+  ASSERT_EQ(FRONT_GUARD, config->options);
+  ASSERT_EQ(32U, config->front_guard_bytes);
+
+  ASSERT_TRUE(InitConfig("front_guard=39"));
+  ASSERT_EQ(FRONT_GUARD, config->options);
+#if defined(__LP64__)
+  ASSERT_EQ(48U, config->front_guard_bytes);
+#else
+  ASSERT_EQ(40U, config->front_guard_bytes);
+#endif
+
+  ASSERT_TRUE(InitConfig("front_guard=41"));
+  ASSERT_EQ(FRONT_GUARD, config->options);
+  ASSERT_EQ(48U, config->front_guard_bytes);
+
+  ASSERT_STREQ("", getFakeLogBuf().c_str());
+  ASSERT_STREQ("", getFakeLogPrint().c_str());
+}
+
+TEST_F(MallocDebugConfigTest, rear_guard) {
+  ASSERT_TRUE(InitConfig("rear_guard=50"));
+  ASSERT_EQ(REAR_GUARD, config->options);
+  ASSERT_EQ(50U, config->rear_guard_bytes);
+
+  ASSERT_TRUE(InitConfig("rear_guard"));
+  ASSERT_EQ(REAR_GUARD, config->options);
+  ASSERT_EQ(32U, config->rear_guard_bytes);
+
+  ASSERT_STREQ("", getFakeLogBuf().c_str());
+  ASSERT_STREQ("", getFakeLogPrint().c_str());
+}
+
+TEST_F(MallocDebugConfigTest, guard) {
+  ASSERT_TRUE(InitConfig("guard=32"));
+  ASSERT_EQ(FRONT_GUARD | REAR_GUARD, config->options);
+  ASSERT_EQ(32U, config->front_guard_bytes);
+  ASSERT_EQ(32U, config->rear_guard_bytes);
+
+  ASSERT_TRUE(InitConfig("guard"));
+  ASSERT_EQ(FRONT_GUARD | REAR_GUARD, config->options);
+  ASSERT_EQ(32U, config->front_guard_bytes);
+  ASSERT_EQ(32U, config->rear_guard_bytes);
+
+  ASSERT_STREQ("", getFakeLogBuf().c_str());
+  ASSERT_STREQ("", getFakeLogPrint().c_str());
+}
+
+TEST_F(MallocDebugConfigTest, backtrace) {
+  ASSERT_TRUE(InitConfig("backtrace=64"));
+  ASSERT_EQ(BACKTRACE | TRACK_ALLOCS, config->options);
+  ASSERT_EQ(64U, config->backtrace_frames);
+
+  ASSERT_TRUE(InitConfig("backtrace"));
+  ASSERT_EQ(BACKTRACE | TRACK_ALLOCS, config->options);
+  ASSERT_EQ(16U, config->backtrace_frames);
+
+  ASSERT_STREQ("", getFakeLogBuf().c_str());
+  ASSERT_STREQ("", getFakeLogPrint().c_str());
+}
+
+TEST_F(MallocDebugConfigTest, backtrace_enable_on_signal) {
+  ASSERT_TRUE(InitConfig("backtrace_enable_on_signal=64"));
+  ASSERT_EQ(BACKTRACE | TRACK_ALLOCS, config->options);
+  ASSERT_EQ(64U, config->backtrace_frames);
+
+  ASSERT_TRUE(InitConfig("backtrace_enable_on_signal"));
+  ASSERT_EQ(BACKTRACE | TRACK_ALLOCS, config->options);
+  ASSERT_EQ(16U, config->backtrace_frames);
+
+  ASSERT_STREQ("", getFakeLogBuf().c_str());
+  ASSERT_STREQ("", getFakeLogPrint().c_str());
+}
+
+TEST_F(MallocDebugConfigTest, fill_on_alloc) {
+  ASSERT_TRUE(InitConfig("fill_on_alloc=64"));
+  ASSERT_EQ(FILL_ON_ALLOC, config->options);
+  ASSERT_EQ(64U, config->fill_on_alloc_bytes);
+
+  ASSERT_TRUE(InitConfig("fill_on_alloc"));
+  ASSERT_EQ(FILL_ON_ALLOC, config->options);
+  ASSERT_EQ(SIZE_MAX, config->fill_on_alloc_bytes);
+
+  ASSERT_STREQ("", getFakeLogBuf().c_str());
+  ASSERT_STREQ("", getFakeLogPrint().c_str());
+}
+
+TEST_F(MallocDebugConfigTest, fill_on_free) {
+  ASSERT_TRUE(InitConfig("fill_on_free=64"));
+  ASSERT_EQ(FILL_ON_FREE, config->options);
+  ASSERT_EQ(64U, config->fill_on_free_bytes);
+
+  ASSERT_TRUE(InitConfig("fill_on_free"));
+  ASSERT_EQ(FILL_ON_FREE, config->options);
+  ASSERT_EQ(SIZE_MAX, config->fill_on_free_bytes);
+
+  ASSERT_STREQ("", getFakeLogBuf().c_str());
+  ASSERT_STREQ("", getFakeLogPrint().c_str());
+}
+
+TEST_F(MallocDebugConfigTest, fill) {
+  ASSERT_TRUE(InitConfig("fill=64"));
+  ASSERT_EQ(FILL_ON_ALLOC | FILL_ON_FREE, config->options);
+  ASSERT_EQ(64U, config->fill_on_alloc_bytes);
+  ASSERT_EQ(64U, config->fill_on_free_bytes);
+
+  ASSERT_TRUE(InitConfig("fill"));
+  ASSERT_EQ(FILL_ON_ALLOC | FILL_ON_FREE, config->options);
+  ASSERT_EQ(SIZE_MAX, config->fill_on_alloc_bytes);
+  ASSERT_EQ(SIZE_MAX, config->fill_on_free_bytes);
+
+  ASSERT_STREQ("", getFakeLogBuf().c_str());
+  ASSERT_STREQ("", getFakeLogPrint().c_str());
+}
+
+TEST_F(MallocDebugConfigTest, expand_alloc) {
+  ASSERT_TRUE(InitConfig("expand_alloc=1234"));
+  ASSERT_EQ(EXPAND_ALLOC, config->options);
+  ASSERT_EQ(1234U, config->expand_alloc_bytes);
+
+  ASSERT_TRUE(InitConfig("expand_alloc"));
+  ASSERT_EQ(EXPAND_ALLOC, config->options);
+  ASSERT_EQ(16U, config->expand_alloc_bytes);
+
+  ASSERT_STREQ("", getFakeLogBuf().c_str());
+  ASSERT_STREQ("", getFakeLogPrint().c_str());
+}
+
+TEST_F(MallocDebugConfigTest, free_track) {
+  ASSERT_TRUE(InitConfig("free_track=1234"));
+  ASSERT_EQ(FREE_TRACK | FILL_ON_FREE, config->options);
+  ASSERT_EQ(1234U, config->free_track_allocations);
+  ASSERT_EQ(SIZE_MAX, config->fill_on_free_bytes);
+  ASSERT_EQ(16U, config->free_track_backtrace_num_frames);
+
+  ASSERT_TRUE(InitConfig("free_track"));
+  ASSERT_EQ(FREE_TRACK | FILL_ON_FREE, config->options);
+  ASSERT_EQ(100U, config->free_track_allocations);
+  ASSERT_EQ(SIZE_MAX, config->fill_on_free_bytes);
+  ASSERT_EQ(16U, config->free_track_backtrace_num_frames);
+
+  ASSERT_STREQ("", getFakeLogBuf().c_str());
+  ASSERT_STREQ("", getFakeLogPrint().c_str());
+}
+
+TEST_F(MallocDebugConfigTest, free_track_and_fill_on_free) {
+  ASSERT_TRUE(InitConfig("free_track=1234 fill_on_free=32"));
+  ASSERT_EQ(FREE_TRACK | FILL_ON_FREE, config->options);
+  ASSERT_EQ(1234U, config->free_track_allocations);
+  ASSERT_EQ(32U, config->fill_on_free_bytes);
+  ASSERT_EQ(16U, config->free_track_backtrace_num_frames);
+
+  ASSERT_TRUE(InitConfig("free_track fill_on_free=60"));
+  ASSERT_EQ(FREE_TRACK | FILL_ON_FREE, config->options);
+  ASSERT_EQ(100U, config->free_track_allocations);
+  ASSERT_EQ(60U, config->fill_on_free_bytes);
+  ASSERT_EQ(16U, config->free_track_backtrace_num_frames);
+
+  ASSERT_STREQ("", getFakeLogBuf().c_str());
+  ASSERT_STREQ("", getFakeLogPrint().c_str());
+}
+
+TEST_F(MallocDebugConfigTest, free_track_backtrace_num_frames) {
+  ASSERT_TRUE(InitConfig("free_track_backtrace_num_frames=123"));
+
+  ASSERT_EQ(0U, config->options);
+  ASSERT_EQ(123U, config->free_track_backtrace_num_frames);
+
+  ASSERT_TRUE(InitConfig("free_track_backtrace_num_frames"));
+  ASSERT_EQ(0U, config->options);
+  ASSERT_EQ(16U, config->free_track_backtrace_num_frames);
+
+  ASSERT_STREQ("", getFakeLogBuf().c_str());
+  ASSERT_STREQ("", getFakeLogPrint().c_str());
+}
+
+TEST_F(MallocDebugConfigTest, free_track_backtrace_num_frames_zero) {
+  ASSERT_TRUE(InitConfig("free_track_backtrace_num_frames=0"));
+
+  ASSERT_EQ(0U, config->options);
+  ASSERT_EQ(0U, config->free_track_backtrace_num_frames);
+
+  ASSERT_STREQ("", getFakeLogBuf().c_str());
+  ASSERT_STREQ("", getFakeLogPrint().c_str());
+}
+
+TEST_F(MallocDebugConfigTest, free_track_backtrace_num_frames_and_free_track) {
+  ASSERT_TRUE(InitConfig("free_track free_track_backtrace_num_frames=123"));
+  ASSERT_EQ(FREE_TRACK | FILL_ON_FREE, config->options);
+  ASSERT_EQ(123U, config->free_track_backtrace_num_frames);
+
+  ASSERT_TRUE(InitConfig("free_track free_track_backtrace_num_frames"));
+  ASSERT_EQ(FREE_TRACK | FILL_ON_FREE, config->options);
+  ASSERT_EQ(16U, config->free_track_backtrace_num_frames);
+
+  ASSERT_STREQ("", getFakeLogBuf().c_str());
+  ASSERT_STREQ("", getFakeLogPrint().c_str());
+}
+
+TEST_F(MallocDebugConfigTest, leak_track) {
+  ASSERT_TRUE(InitConfig("leak_track"));
+  ASSERT_EQ(LEAK_TRACK | TRACK_ALLOCS, config->options);
+
+  ASSERT_STREQ("", getFakeLogBuf().c_str());
+  ASSERT_STREQ("", getFakeLogPrint().c_str());
+}
+
+TEST_F(MallocDebugConfigTest, leak_track_fail) {
+  ASSERT_FALSE(InitConfig("leak_track=100"));
+
+  ASSERT_STREQ("", getFakeLogBuf().c_str());
+  std::string log_msg(
+      "6 malloc_debug malloc_testing: value set for option 'leak_track' "
+      "which does not take a value\n");
+  ASSERT_STREQ((log_msg + usage_string).c_str(), getFakeLogPrint().c_str());
+}
+
+TEST_F(MallocDebugConfigTest, guard_min_error) {
+  ASSERT_FALSE(InitConfig("guard=0"));
+
+  ASSERT_STREQ("", getFakeLogBuf().c_str());
+  std::string log_msg(
+      "6 malloc_debug malloc_testing: bad value for option 'guard', value must be >= 1: 0\n");
+  ASSERT_STREQ((log_msg + usage_string).c_str(), getFakeLogPrint().c_str());
+}
+
+TEST_F(MallocDebugConfigTest, guard_max_error) {
+  ASSERT_FALSE(InitConfig("guard=20000"));
+
+  ASSERT_STREQ("", getFakeLogBuf().c_str());
+  std::string log_msg(
+      "6 malloc_debug malloc_testing: bad value for option 'guard', "
+      "value must be <= 16384: 20000\n");
+  ASSERT_STREQ((log_msg + usage_string).c_str(), getFakeLogPrint().c_str());
+}
+
+TEST_F(MallocDebugConfigTest, front_guard_min_error) {
+  ASSERT_FALSE(InitConfig("front_guard=0"));
+
+  ASSERT_STREQ("", getFakeLogBuf().c_str());
+  std::string log_msg(
+      "6 malloc_debug malloc_testing: bad value for option 'front_guard', "
+      "value must be >= 1: 0\n");
+  ASSERT_STREQ((log_msg + usage_string).c_str(), getFakeLogPrint().c_str());
+}
+
+TEST_F(MallocDebugConfigTest, front_guard_max_error) {
+  ASSERT_FALSE(InitConfig("front_guard=20000"));
+
+  ASSERT_STREQ("", getFakeLogBuf().c_str());
+  std::string log_msg(
+      "6 malloc_debug malloc_testing: bad value for option 'front_guard', "
+      "value must be <= 16384: 20000\n");
+  ASSERT_STREQ((log_msg + usage_string).c_str(), getFakeLogPrint().c_str());
+}
+
+TEST_F(MallocDebugConfigTest, rear_guard_min_error) {
+  ASSERT_FALSE(InitConfig("rear_guard=0"));
+
+  ASSERT_STREQ("", getFakeLogBuf().c_str());
+  std::string log_msg(
+      "6 malloc_debug malloc_testing: bad value for option 'rear_guard', "
+      "value must be >= 1: 0\n");
+  ASSERT_STREQ((log_msg + usage_string).c_str(), getFakeLogPrint().c_str());
+}
+
+TEST_F(MallocDebugConfigTest, rear_guard_max_error) {
+  ASSERT_FALSE(InitConfig("rear_guard=20000"));
+
+  ASSERT_STREQ("", getFakeLogBuf().c_str());
+  std::string log_msg(
+      "6 malloc_debug malloc_testing: bad value for option 'rear_guard', "
+      "value must be <= 16384: 20000\n");
+  ASSERT_STREQ((log_msg + usage_string).c_str(), getFakeLogPrint().c_str());
+}
+
+TEST_F(MallocDebugConfigTest, fill_min_error) {
+  ASSERT_FALSE(InitConfig("fill=0"));
+
+  ASSERT_STREQ("", getFakeLogBuf().c_str());
+  std::string log_msg(
+      "6 malloc_debug malloc_testing: bad value for option 'fill', "
+      "value must be >= 1: 0\n");
+  ASSERT_STREQ((log_msg + usage_string).c_str(), getFakeLogPrint().c_str());
+}
+
+TEST_F(MallocDebugConfigTest, fill_on_alloc_min_error) {
+  ASSERT_FALSE(InitConfig("fill_on_alloc=0"));
+
+  ASSERT_STREQ("", getFakeLogBuf().c_str());
+  std::string log_msg(
+      "6 malloc_debug malloc_testing: bad value for option 'fill_on_alloc', "
+      "value must be >= 1: 0\n");
+  ASSERT_STREQ((log_msg + usage_string).c_str(), getFakeLogPrint().c_str());
+}
+
+TEST_F(MallocDebugConfigTest, fill_on_free_min_error) {
+  ASSERT_FALSE(InitConfig("fill_on_free=0"));
+
+  ASSERT_STREQ("", getFakeLogBuf().c_str());
+  std::string log_msg(
+      "6 malloc_debug malloc_testing: bad value for option 'fill_on_free', "
+      "value must be >= 1: 0\n");
+  ASSERT_STREQ((log_msg + usage_string).c_str(), getFakeLogPrint().c_str());
+}
+
+TEST_F(MallocDebugConfigTest, backtrace_min_error) {
+  ASSERT_FALSE(InitConfig("backtrace=0"));
+
+  ASSERT_STREQ("", getFakeLogBuf().c_str());
+  std::string log_msg(
+      "6 malloc_debug malloc_testing: bad value for option 'backtrace', "
+      "value must be >= 1: 0\n");
+  ASSERT_STREQ((log_msg + usage_string).c_str(), getFakeLogPrint().c_str());
+}
+
+TEST_F(MallocDebugConfigTest, backtrace_max_error) {
+  ASSERT_FALSE(InitConfig("backtrace=300"));
+
+  ASSERT_STREQ("", getFakeLogBuf().c_str());
+  std::string log_msg(
+      "6 malloc_debug malloc_testing: bad value for option 'backtrace', "
+      "value must be <= 256: 300\n");
+  ASSERT_STREQ((log_msg + usage_string).c_str(), getFakeLogPrint().c_str());
+}
+
+TEST_F(MallocDebugConfigTest, backtrace_enable_on_signal_min_error) {
+  ASSERT_FALSE(InitConfig("backtrace_enable_on_signal=0"));
+
+  ASSERT_STREQ("", getFakeLogBuf().c_str());
+  std::string log_msg(
+      "6 malloc_debug malloc_testing: bad value for option 'backtrace_enable_on_signal', "
+      "value must be >= 1: 0\n");
+  ASSERT_STREQ((log_msg + usage_string).c_str(), getFakeLogPrint().c_str());
+}
+
+TEST_F(MallocDebugConfigTest, backtrace_enable_on_signal_max_error) {
+  ASSERT_FALSE(InitConfig("backtrace_enable_on_signal=300"));
+
+  ASSERT_STREQ("", getFakeLogBuf().c_str());
+  std::string log_msg(
+      "6 malloc_debug malloc_testing: bad value for option 'backtrace_enable_on_signal', "
+      "value must be <= 256: 300\n");
+  ASSERT_STREQ((log_msg + usage_string).c_str(), getFakeLogPrint().c_str());
+}
+
+TEST_F(MallocDebugConfigTest, expand_alloc_min_error) {
+  ASSERT_FALSE(InitConfig("expand_alloc=0"));
+
+  ASSERT_STREQ("", getFakeLogBuf().c_str());
+  std::string log_msg(
+      "6 malloc_debug malloc_testing: bad value for option 'expand_alloc', "
+      "value must be >= 1: 0\n");
+  ASSERT_STREQ((log_msg + usage_string).c_str(), getFakeLogPrint().c_str());
+}
+
+TEST_F(MallocDebugConfigTest, expand_alloc_max_error) {
+  ASSERT_FALSE(InitConfig("expand_alloc=21000"));
+
+  ASSERT_STREQ("", getFakeLogBuf().c_str());
+  std::string log_msg(
+      "6 malloc_debug malloc_testing: bad value for option 'expand_alloc', "
+      "value must be <= 16384: 21000\n");
+  ASSERT_STREQ((log_msg + usage_string).c_str(), getFakeLogPrint().c_str());
+}
+
+TEST_F(MallocDebugConfigTest, free_track_min_error) {
+  ASSERT_FALSE(InitConfig("free_track=0"));
+
+  ASSERT_STREQ("", getFakeLogBuf().c_str());
+  std::string log_msg(
+      "6 malloc_debug malloc_testing: bad value for option 'free_track', "
+      "value must be >= 1: 0\n");
+  ASSERT_STREQ((log_msg + usage_string).c_str(), getFakeLogPrint().c_str());
+}
+
+TEST_F(MallocDebugConfigTest, free_track_max_error) {
+  ASSERT_FALSE(InitConfig("free_track=21000"));
+
+  ASSERT_STREQ("", getFakeLogBuf().c_str());
+  std::string log_msg(
+      "6 malloc_debug malloc_testing: bad value for option 'free_track', "
+      "value must be <= 16384: 21000\n");
+  ASSERT_STREQ((log_msg + usage_string).c_str(), getFakeLogPrint().c_str());
+}
+
+TEST_F(MallocDebugConfigTest, free_track_backtrace_num_frames_max_error) {
+  ASSERT_FALSE(InitConfig("free_track_backtrace_num_frames=400"));
+
+  ASSERT_STREQ("", getFakeLogBuf().c_str());
+  std::string log_msg(
+      "6 malloc_debug malloc_testing: bad value for option 'free_track_backtrace_num_frames', "
+      "value must be <= 256: 400\n");
+  ASSERT_STREQ((log_msg + usage_string).c_str(), getFakeLogPrint().c_str());
+}
diff --git a/libc/malloc_debug/tests/malloc_debug_unit_tests.cpp b/libc/malloc_debug/tests/malloc_debug_unit_tests.cpp
new file mode 100644
index 0000000..014b913
--- /dev/null
+++ b/libc/malloc_debug/tests/malloc_debug_unit_tests.cpp
@@ -0,0 +1,1514 @@
+/*
+ * Copyright (C) 2015 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 <malloc.h>
+#include <signal.h>
+#include <stdlib.h>
+#include <string.h>
+#include <sys/cdefs.h>
+#include <sys/param.h>
+#include <sys/types.h>
+#include <unistd.h>
+
+#include <algorithm>
+#include <thread>
+#include <vector>
+#include <utility>
+
+#include <gtest/gtest.h>
+
+#include <android-base/stringprintf.h>
+
+#include <private/bionic_macros.h>
+#include <private/bionic_malloc_dispatch.h>
+
+#include "Config.h"
+#include "malloc_debug.h"
+
+#include "log_fake.h"
+#include "backtrace_fake.h"
+
+__BEGIN_DECLS
+
+int property_set(const char*, const char*);
+bool debug_initialize(const MallocDispatch*, int*);
+void debug_finalize();
+
+void* debug_malloc(size_t);
+void debug_free(void*);
+void* debug_calloc(size_t, size_t);
+void* debug_realloc(void*, size_t);
+int debug_posix_memalign(void**, size_t, size_t);
+void* debug_memalign(size_t, size_t);
+size_t debug_malloc_usable_size(void*);
+void debug_get_malloc_leak_info(uint8_t**, size_t*, size_t*, size_t*, size_t*);
+void debug_free_malloc_leak_info(uint8_t*);
+
+struct mallinfo debug_mallinfo();
+
+#if defined(HAVE_DEPRECATED_MALLOC_FUNCS)
+void* debug_pvalloc(size_t);
+void* debug_valloc(size_t);
+#endif
+
+__END_DECLS
+
+constexpr char DIVIDER[] =
+    "6 malloc_debug *** *** *** *** *** *** *** *** *** *** *** *** *** *** *** ***\n";
+
+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);
+  if (flags & BACKTRACE_HEADER) {
+    offset += BIONIC_ALIGN(sizeof(BacktraceHeader) + sizeof(uintptr_t) * backtrace_frames, MINIMUM_ALIGNMENT_BYTES);
+  }
+  return offset;
+}
+
+class MallocDebugTest : public ::testing::Test {
+ protected:
+  void SetUp() override {
+    initialized = false;
+    resetLogs();
+    backtrace_fake_clear_all();
+  }
+
+  void TearDown() override {
+    if (initialized) {
+      debug_finalize();
+    }
+  }
+
+  void Init(const char* property_value) {
+    property_set("libc.debug.malloc.options", property_value);
+    zygote = 0;
+    ASSERT_TRUE(debug_initialize(&dispatch, &zygote));
+    initialized = true;
+  }
+
+  bool initialized;
+
+  int zygote;
+
+  static MallocDispatch dispatch;
+};
+
+MallocDispatch MallocDebugTest::dispatch = {
+  calloc,
+  free,
+  mallinfo,
+  malloc,
+  malloc_usable_size,
+  memalign,
+  posix_memalign,
+#if defined(HAVE_DEPRECATED_MALLOC_FUNCS)
+  nullptr,
+#endif
+  realloc,
+#if defined(HAVE_DEPRECATED_MALLOC_FUNCS)
+  nullptr,
+#endif
+  nullptr,
+  nullptr,
+  nullptr,
+};
+
+void VerifyAllocCalls() {
+  size_t alloc_size = 1024;
+
+  // Verify debug_malloc.
+  uint8_t* pointer = reinterpret_cast<uint8_t*>(debug_malloc(alloc_size));
+  ASSERT_TRUE(pointer != nullptr);
+  for (size_t i = 0; i < debug_malloc_usable_size(pointer); i++) {
+    ASSERT_EQ(0xeb, pointer[i]);
+  }
+  debug_free(pointer);
+
+  // Verify debug_calloc.
+  pointer = reinterpret_cast<uint8_t*>(debug_calloc(1, alloc_size));
+  ASSERT_TRUE(pointer != nullptr);
+  for (size_t i = 0; i < debug_malloc_usable_size(pointer); i++) {
+    ASSERT_EQ(0, pointer[i]) << "Failed at byte " << i;
+  }
+  debug_free(pointer);
+
+  pointer = reinterpret_cast<uint8_t*>(debug_memalign(128, alloc_size));
+  ASSERT_TRUE(pointer != nullptr);
+  for (size_t i = 0; i < debug_malloc_usable_size(pointer); i++) {
+    ASSERT_EQ(0xeb, pointer[i]) << "Failed at byte " << i;
+  }
+  debug_free(pointer);
+
+  pointer = reinterpret_cast<uint8_t*>(debug_realloc(nullptr, alloc_size));
+  ASSERT_TRUE(pointer != nullptr);
+  for (size_t i = 0; i < debug_malloc_usable_size(pointer); i++) {
+    ASSERT_EQ(0xeb, pointer[i]) << "Failed at byte " << i;
+  }
+  memset(pointer, 0xff, alloc_size);
+  // Increase the size, verify the extra length is initialized to 0xeb,
+  // but the rest is 0xff.
+  pointer = reinterpret_cast<uint8_t*>(debug_realloc(pointer, alloc_size * 2));
+  ASSERT_TRUE(pointer != nullptr);
+  for (size_t i = 0; i < alloc_size; i++) {
+    ASSERT_EQ(0xff, pointer[i]) << "Failed at byte " << i;
+  }
+  for (size_t i = alloc_size; i < debug_malloc_usable_size(pointer); i++) {
+    ASSERT_EQ(0xeb, pointer[i]) << "Failed at byte " << i;
+  }
+  memset(pointer, 0xff, debug_malloc_usable_size(pointer));
+  // Shrink the size and verify nothing changes.
+  pointer = reinterpret_cast<uint8_t*>(debug_realloc(pointer, alloc_size));
+  ASSERT_TRUE(pointer != nullptr);
+  for (size_t i = 0; i < debug_malloc_usable_size(pointer); i++) {
+    ASSERT_EQ(0xff, pointer[i]) << "Failed at byte " << i;
+  }
+  // This should free the pointer.
+  pointer = reinterpret_cast<uint8_t*>(debug_realloc(pointer, 0));
+  ASSERT_TRUE(pointer == nullptr);
+
+  ASSERT_STREQ("", getFakeLogBuf().c_str());
+  ASSERT_STREQ("", getFakeLogPrint().c_str());
+}
+
+TEST_F(MallocDebugTest, fill_generic) {
+  Init("fill");
+  VerifyAllocCalls();
+}
+
+TEST_F(MallocDebugTest, fill_on_alloc_generic) {
+  Init("fill_on_alloc");
+  VerifyAllocCalls();
+}
+
+TEST_F(MallocDebugTest, fill_on_alloc_partial) {
+  Init("fill_on_alloc=25");
+
+  uint8_t* pointer = reinterpret_cast<uint8_t*>(debug_malloc(100));
+  ASSERT_TRUE(pointer != nullptr);
+  for (size_t i = 0; i < 25; i++) {
+    ASSERT_EQ(0xeb, pointer[i]) << "Failed at byte " << i;
+  }
+  debug_free(pointer);
+
+  ASSERT_STREQ("", getFakeLogBuf().c_str());
+  ASSERT_STREQ("", getFakeLogPrint().c_str());
+}
+
+TEST_F(MallocDebugTest, fill_on_free) {
+  Init("fill_on_free free_track free_track_backtrace_num_frames=0");
+
+  uint8_t* pointer = reinterpret_cast<uint8_t*>(debug_malloc(100));
+  ASSERT_TRUE(pointer != nullptr);
+  size_t usable_size = debug_malloc_usable_size(pointer);
+  memset(pointer, 0, usable_size);
+  debug_free(pointer);
+
+  for (size_t i = 0; i < usable_size; i++) {
+    ASSERT_EQ(0xef, pointer[i]) << "Failed at byte " << i;
+  }
+
+  ASSERT_STREQ("", getFakeLogBuf().c_str());
+  ASSERT_STREQ("", getFakeLogPrint().c_str());
+}
+
+TEST_F(MallocDebugTest, fill_on_free_partial) {
+  Init("fill_on_free=30 free_track free_track_backtrace_num_frames=0");
+
+  uint8_t* pointer = reinterpret_cast<uint8_t*>(debug_malloc(100));
+  ASSERT_TRUE(pointer != nullptr);
+  size_t usable_size = debug_malloc_usable_size(pointer);
+  memset(pointer, 0, usable_size);
+  debug_free(pointer);
+
+  for (size_t i = 0; i < 30; i++) {
+    ASSERT_EQ(0xef, pointer[i]) << "Failed to fill on free at byte " << i;
+  }
+  for (size_t i = 30; i < usable_size; i++) {
+    ASSERT_EQ(0, pointer[i]) << "Filled too much on byte " << i;
+  }
+
+  ASSERT_STREQ("", getFakeLogBuf().c_str());
+  ASSERT_STREQ("", getFakeLogPrint().c_str());
+}
+
+TEST_F(MallocDebugTest, free_track_partial) {
+  Init("fill_on_free=30 free_track free_track_backtrace_num_frames=0");
+
+  uint8_t* pointer = reinterpret_cast<uint8_t*>(debug_malloc(100));
+  ASSERT_TRUE(pointer != nullptr);
+  size_t usable_size = debug_malloc_usable_size(pointer);
+  memset(pointer, 0, usable_size);
+  debug_free(pointer);
+
+  for (size_t i = 0; i < 30; i++) {
+    ASSERT_EQ(0xef, pointer[i]) << "Failed to fill on free at byte " << i;
+  }
+  for (size_t i = 30; i < usable_size; i++) {
+    ASSERT_EQ(0, pointer[i]) << "Filled too much on byte " << i;
+  }
+
+  debug_finalize();
+  initialized = false;
+
+  ASSERT_STREQ("", getFakeLogBuf().c_str());
+  ASSERT_STREQ("", getFakeLogPrint().c_str());
+}
+
+TEST_F(MallocDebugTest, all_options) {
+  Init("guard backtrace fill expand_alloc free_track leak_track");
+  VerifyAllocCalls();
+}
+
+TEST_F(MallocDebugTest, expand_alloc) {
+  Init("expand_alloc=1024");
+
+  void* pointer = debug_malloc(10);
+  ASSERT_TRUE(pointer != nullptr);
+  ASSERT_LE(1034U, debug_malloc_usable_size(pointer));
+  debug_free(pointer);
+
+  pointer = debug_calloc(1, 20);
+  ASSERT_TRUE(pointer != nullptr);
+  ASSERT_LE(1044U, debug_malloc_usable_size(pointer));
+  debug_free(pointer);
+
+  pointer = debug_memalign(128, 15);
+  ASSERT_TRUE(pointer != nullptr);
+  ASSERT_LE(1039U, debug_malloc_usable_size(pointer));
+  debug_free(pointer);
+
+  pointer = debug_realloc(nullptr, 30);
+  ASSERT_TRUE(pointer != nullptr);
+  ASSERT_LE(1054U, debug_malloc_usable_size(pointer));
+  pointer = debug_realloc(pointer, 100);
+  ASSERT_LE(1124U, debug_malloc_usable_size(pointer));
+  debug_free(pointer);
+
+  ASSERT_STREQ("", getFakeLogBuf().c_str());
+  ASSERT_STREQ("", getFakeLogPrint().c_str());
+}
+
+TEST_F(MallocDebugTest, front_guard) {
+  Init("front_guard=32");
+
+  // Create a buffer for doing comparisons.
+  std::vector<uint8_t> buffer(32);
+  memset(buffer.data(), 0xaa, buffer.size());
+
+  uint8_t* pointer = reinterpret_cast<uint8_t*>(debug_malloc(100));
+  ASSERT_TRUE(pointer != nullptr);
+  ASSERT_TRUE(memcmp(buffer.data(), &pointer[-buffer.size()], buffer.size()) == 0);
+  memset(pointer, 0xff, 100);
+  debug_free(pointer);
+
+  // Loop through a bunch alignments.
+  for (size_t alignment = 1; alignment <= 256; alignment++) {
+    pointer = reinterpret_cast<uint8_t*>(debug_memalign(alignment, 100));
+    ASSERT_TRUE(pointer != nullptr);
+    ASSERT_TRUE(memcmp(buffer.data(), &pointer[-buffer.size()], buffer.size()) == 0);
+    size_t alignment_mask = alignment - 1;
+    if (!powerof2(alignment)) {
+      alignment_mask = BIONIC_ROUND_UP_POWER_OF_2(alignment) - 1;
+    }
+    ASSERT_EQ(0U, reinterpret_cast<uintptr_t>(pointer) & alignment_mask);
+    memset(pointer, 0xff, 100);
+    debug_free(pointer);
+  }
+
+  pointer = reinterpret_cast<uint8_t*>(debug_calloc(1, 100));
+  ASSERT_TRUE(pointer != nullptr);
+  ASSERT_TRUE(memcmp(buffer.data(), &pointer[-buffer.size()], buffer.size()) == 0);
+  for (size_t i = 0; i < 100; i++) {
+    ASSERT_EQ(0, pointer[i]) << "debug_calloc non-zero byte at " << i;
+  }
+  debug_free(pointer);
+
+  pointer = reinterpret_cast<uint8_t*>(debug_realloc(nullptr, 100));
+  ASSERT_TRUE(pointer != nullptr);
+  ASSERT_TRUE(memcmp(buffer.data(), &pointer[-buffer.size()], buffer.size()) == 0);
+  memset(pointer, 0xff, 100);
+  pointer = reinterpret_cast<uint8_t*>(debug_realloc(pointer, 200));
+  ASSERT_TRUE(memcmp(buffer.data(), &pointer[-buffer.size()], buffer.size()) == 0);
+  memset(pointer, 0xff, 200);
+  pointer = reinterpret_cast<uint8_t*>(debug_realloc(pointer, 0));
+  ASSERT_TRUE(pointer == nullptr);
+
+  ASSERT_STREQ("", getFakeLogBuf().c_str());
+  ASSERT_STREQ("", getFakeLogPrint().c_str());
+}
+
+TEST_F(MallocDebugTest, realloc_memalign_memory) {
+  Init("rear_guard");
+
+  void* pointer = debug_memalign(1024, 100);
+  ASSERT_TRUE(pointer != nullptr);
+  memset(pointer, 0, 100);
+
+  pointer = debug_realloc(pointer, 1024);
+  ASSERT_TRUE(pointer != nullptr);
+  ASSERT_EQ(1024U, debug_malloc_usable_size(pointer));
+  memset(pointer, 0, 1024);
+  debug_free(pointer);
+
+  ASSERT_STREQ("", getFakeLogBuf().c_str());
+  ASSERT_STREQ("", getFakeLogPrint().c_str());
+}
+
+TEST_F(MallocDebugTest, front_guard_corrupted) {
+  Init("front_guard=32");
+
+  backtrace_fake_add(std::vector<uintptr_t> {0x1, 0x2, 0x3});
+
+  uint8_t* pointer = reinterpret_cast<uint8_t*>(debug_malloc(100));
+  ASSERT_TRUE(pointer != nullptr);
+  pointer[-32] = 0x00;
+  pointer[-15] = 0x02;
+  debug_free(pointer);
+
+  std::string expected_log(DIVIDER);
+  expected_log += android::base::StringPrintf(
+      "6 malloc_debug +++ ALLOCATION %p SIZE 100 HAS A CORRUPTED FRONT GUARD\n", pointer);
+  expected_log += "6 malloc_debug   allocation[-32] = 0x00 (expected 0xaa)\n";
+  expected_log += "6 malloc_debug   allocation[-15] = 0x02 (expected 0xaa)\n";
+  expected_log += "6 malloc_debug Backtrace at time of failure:\n";
+  expected_log += "6 malloc_debug   #00 pc 0x1\n";
+  expected_log += "6 malloc_debug   #01 pc 0x2\n";
+  expected_log += "6 malloc_debug   #02 pc 0x3\n";
+  expected_log += DIVIDER;
+  ASSERT_STREQ("", getFakeLogBuf().c_str());
+  ASSERT_STREQ(expected_log.c_str(), getFakeLogPrint().c_str());
+}
+
+TEST_F(MallocDebugTest, rear_guard) {
+  Init("rear_guard=32");
+
+  // Create a buffer for doing comparisons.
+  std::vector<uint8_t> buffer(32);
+  memset(buffer.data(), 0xbb, buffer.size());
+
+  uint8_t* pointer = reinterpret_cast<uint8_t*>(debug_malloc(100));
+  ASSERT_TRUE(pointer != nullptr);
+  ASSERT_EQ(100U, debug_malloc_usable_size(pointer));
+  ASSERT_TRUE(memcmp(buffer.data(), &pointer[100], buffer.size()) == 0);
+  memset(pointer, 0xff, 100);
+  debug_free(pointer);
+
+  // Loop through a bunch alignments.
+  for (size_t alignment = 1; alignment <= 256; alignment++) {
+    pointer = reinterpret_cast<uint8_t*>(debug_memalign(alignment, 100));
+    ASSERT_TRUE(pointer != nullptr);
+    ASSERT_EQ(100U, debug_malloc_usable_size(pointer));
+    ASSERT_TRUE(memcmp(buffer.data(), &pointer[100], buffer.size()) == 0);
+    size_t alignment_mask = alignment - 1;
+    if (!powerof2(alignment)) {
+      alignment_mask = BIONIC_ROUND_UP_POWER_OF_2(alignment) - 1;
+    }
+    ASSERT_EQ(0U, reinterpret_cast<uintptr_t>(pointer) & alignment_mask)
+        << "Failed at alignment " << alignment << " mask " << alignment_mask;
+    memset(pointer, 0xff, 100);
+    debug_free(pointer);
+  }
+
+  pointer = reinterpret_cast<uint8_t*>(debug_calloc(1, 100));
+  ASSERT_TRUE(pointer != nullptr);
+  ASSERT_EQ(100U, debug_malloc_usable_size(pointer));
+  ASSERT_TRUE(memcmp(buffer.data(), &pointer[100], buffer.size()) == 0);
+  for (size_t i = 0; i < 100; i++) {
+    ASSERT_EQ(0, pointer[i]) << "debug_calloc non-zero byte at " << i;
+  }
+  debug_free(pointer);
+
+  pointer = reinterpret_cast<uint8_t*>(debug_realloc(nullptr, 100));
+  ASSERT_TRUE(pointer != nullptr);
+  ASSERT_TRUE(memcmp(buffer.data(), &pointer[100], buffer.size()) == 0);
+  memset(pointer, 0xff, 100);
+  pointer = reinterpret_cast<uint8_t*>(debug_realloc(pointer, 200));
+  ASSERT_TRUE(memcmp(buffer.data(), &pointer[200], buffer.size()) == 0);
+  for (size_t i = 0; i < 100; i++) {
+    ASSERT_EQ(0xff, pointer[i]) << "debug_realloc not copied byte at " << i;
+  }
+  memset(pointer, 0xff, 200);
+  pointer = reinterpret_cast<uint8_t*>(debug_realloc(pointer, 0));
+  ASSERT_TRUE(pointer == nullptr);
+
+  ASSERT_STREQ("", getFakeLogBuf().c_str());
+  ASSERT_STREQ("", getFakeLogPrint().c_str());
+}
+
+TEST_F(MallocDebugTest, rear_guard_corrupted) {
+  Init("rear_guard=32");
+
+  backtrace_fake_add(std::vector<uintptr_t> {0x100, 0x200, 0x300});
+
+  uint8_t* pointer = reinterpret_cast<uint8_t*>(debug_malloc(100));
+  ASSERT_TRUE(pointer != nullptr);
+  pointer[130] = 0xbf;
+  pointer[131] = 0x00;
+  debug_free(pointer);
+
+  std::string expected_log(DIVIDER);
+  expected_log += android::base::StringPrintf(
+      "6 malloc_debug +++ ALLOCATION %p SIZE 100 HAS A CORRUPTED REAR GUARD\n", pointer);
+  expected_log += "6 malloc_debug   allocation[130] = 0xbf (expected 0xbb)\n";
+  expected_log += "6 malloc_debug   allocation[131] = 0x00 (expected 0xbb)\n";
+  expected_log += "6 malloc_debug Backtrace at time of failure:\n";
+  expected_log += "6 malloc_debug   #00 pc 0x100\n";
+  expected_log += "6 malloc_debug   #01 pc 0x200\n";
+  expected_log += "6 malloc_debug   #02 pc 0x300\n";
+  expected_log += DIVIDER;
+
+  ASSERT_STREQ("", getFakeLogBuf().c_str());
+  ASSERT_STREQ(expected_log.c_str(), getFakeLogPrint().c_str());
+}
+
+TEST_F(MallocDebugTest, rear_guard_corrupted_after_realloc_shrink) {
+  Init("rear_guard=32");
+
+  backtrace_fake_add(std::vector<uintptr_t> {0x100, 0x200, 0x300});
+
+  void* pointer = debug_malloc(200);
+  ASSERT_TRUE(pointer != nullptr);
+  memset(pointer, 0, 200);
+
+  uint8_t* pointer_shrink = reinterpret_cast<uint8_t*>(debug_realloc(pointer, 100));
+  pointer_shrink[130] = 0xbf;
+  pointer_shrink[131] = 0x00;
+  debug_free(pointer);
+
+  // When shrinking sizes, the same pointer should be returned.
+  ASSERT_EQ(pointer, pointer_shrink);
+
+  std::string expected_log(DIVIDER);
+  expected_log += android::base::StringPrintf(
+      "6 malloc_debug +++ ALLOCATION %p SIZE 100 HAS A CORRUPTED REAR GUARD\n", pointer);
+  expected_log += "6 malloc_debug   allocation[130] = 0xbf (expected 0xbb)\n";
+  expected_log += "6 malloc_debug   allocation[131] = 0x00 (expected 0xbb)\n";
+  expected_log += "6 malloc_debug Backtrace at time of failure:\n";
+  expected_log += "6 malloc_debug   #00 pc 0x100\n";
+  expected_log += "6 malloc_debug   #01 pc 0x200\n";
+  expected_log += "6 malloc_debug   #02 pc 0x300\n";
+  expected_log += DIVIDER;
+
+  ASSERT_STREQ("", getFakeLogBuf().c_str());
+  ASSERT_STREQ(expected_log.c_str(), getFakeLogPrint().c_str());
+}
+
+TEST_F(MallocDebugTest, tag_corrupted) {
+  Init("rear_guard=32");
+
+  backtrace_fake_add(std::vector<uintptr_t> {0xa, 0xb, 0xc});
+
+  backtrace_fake_add(std::vector<uintptr_t> {0xaa, 0xbb, 0xcc});
+
+  backtrace_fake_add(std::vector<uintptr_t> {0xaaa, 0xbbb, 0xccc});
+
+  uint8_t* pointer = reinterpret_cast<uint8_t*>(debug_malloc(100));
+  ASSERT_TRUE(pointer != nullptr);
+  uint8_t saved = pointer[-get_tag_offset()];
+  pointer[-get_tag_offset()] = 0x00;
+  ASSERT_EQ(0U, debug_malloc_usable_size(pointer));
+  ASSERT_TRUE(debug_realloc(pointer, 200) == nullptr);
+  debug_free(pointer);
+
+  // Fix the pointer and really free it.
+  pointer[-get_tag_offset()] = saved;
+  debug_free(pointer);
+
+  std::string expected_log(DIVIDER);
+  expected_log += android::base::StringPrintf(
+      "6 malloc_debug +++ ALLOCATION %p HAS INVALID TAG 1ee7d000 (malloc_usable_size)\n",
+      pointer);
+  expected_log += "6 malloc_debug Backtrace at time of failure:\n";
+  expected_log += "6 malloc_debug   #00 pc 0xa\n";
+  expected_log += "6 malloc_debug   #01 pc 0xb\n";
+  expected_log += "6 malloc_debug   #02 pc 0xc\n";
+  expected_log += DIVIDER;
+
+  expected_log += DIVIDER;
+  expected_log += android::base::StringPrintf(
+      "6 malloc_debug +++ ALLOCATION %p HAS INVALID TAG 1ee7d000 (realloc)\n",
+      pointer);
+  expected_log += "6 malloc_debug Backtrace at time of failure:\n";
+  expected_log += "6 malloc_debug   #00 pc 0xaa\n";
+  expected_log += "6 malloc_debug   #01 pc 0xbb\n";
+  expected_log += "6 malloc_debug   #02 pc 0xcc\n";
+  expected_log += DIVIDER;
+
+  expected_log += DIVIDER;
+  expected_log += android::base::StringPrintf(
+      "6 malloc_debug +++ ALLOCATION %p HAS INVALID TAG 1ee7d000 (free)\n",
+      pointer);
+  expected_log += "6 malloc_debug Backtrace at time of failure:\n";
+  expected_log += "6 malloc_debug   #00 pc 0xaaa\n";
+  expected_log += "6 malloc_debug   #01 pc 0xbbb\n";
+  expected_log += "6 malloc_debug   #02 pc 0xccc\n";
+  expected_log += DIVIDER;
+
+  ASSERT_STREQ("", getFakeLogBuf().c_str());
+  ASSERT_STREQ(expected_log.c_str(), getFakeLogPrint().c_str());
+}
+
+TEST_F(MallocDebugTest, leak_track_no_frees) {
+  Init("leak_track");
+
+  void* pointer1 = debug_malloc(200);
+  ASSERT_TRUE(pointer1 != nullptr);
+  memset(pointer1, 0, 200);
+
+  void* pointer2 = debug_malloc(128);
+  ASSERT_TRUE(pointer2 != nullptr);
+  memset(pointer2, 0, 128);
+
+  void* pointer3 = debug_malloc(1024);
+  ASSERT_TRUE(pointer3 != nullptr);
+  memset(pointer3, 0, 1024);
+
+  debug_finalize();
+  initialized = false;
+
+  ASSERT_STREQ("", getFakeLogBuf().c_str());
+  std::string expected_log = android::base::StringPrintf(
+        "6 malloc_debug +++ malloc_testing leaked block of size 1024 at %p (leak 1 of 3)\n",
+      pointer3);
+  expected_log += android::base::StringPrintf(
+        "6 malloc_debug +++ malloc_testing leaked block of size 200 at %p (leak 2 of 3)\n",
+      pointer1);
+  expected_log += android::base::StringPrintf(
+        "6 malloc_debug +++ malloc_testing leaked block of size 128 at %p (leak 3 of 3)\n",
+      pointer2);
+  ASSERT_STREQ(expected_log.c_str(), getFakeLogPrint().c_str());
+}
+
+TEST_F(MallocDebugTest, leak_track_no_frees_with_backtrace) {
+  Init("leak_track backtrace");
+
+  backtrace_fake_add(std::vector<uintptr_t> {0x1000, 0x2000, 0x3000});
+
+  void* pointer1 = debug_malloc(100);
+  ASSERT_TRUE(pointer1 != nullptr);
+  memset(pointer1, 0, 100);
+
+  backtrace_fake_add(std::vector<uintptr_t> {0xa000, 0xb000, 0xc000, 0xd000});
+
+  void* pointer2 = debug_malloc(128);
+  ASSERT_TRUE(pointer2 != nullptr);
+  memset(pointer2, 0, 128);
+
+  backtrace_fake_add(std::vector<uintptr_t> {0xfe000, 0xde000, 0xce000, 0xbe000, 0xae000});
+
+  void* pointer3 = debug_malloc(1024);
+  ASSERT_TRUE(pointer3 != nullptr);
+  memset(pointer3, 0, 1024);
+
+  debug_finalize();
+  initialized = false;
+
+  ASSERT_STREQ("", getFakeLogBuf().c_str());
+  std::string expected_log = android::base::StringPrintf(
+      "6 malloc_debug +++ malloc_testing leaked block of size 1024 at %p (leak 1 of 3)\n",
+      pointer3);
+  expected_log += "6 malloc_debug Backtrace at time of allocation:\n";
+  expected_log += "6 malloc_debug   #00 pc 0xfe000\n";
+  expected_log += "6 malloc_debug   #01 pc 0xde000\n";
+  expected_log += "6 malloc_debug   #02 pc 0xce000\n";
+  expected_log += "6 malloc_debug   #03 pc 0xbe000\n";
+  expected_log += "6 malloc_debug   #04 pc 0xae000\n";
+
+  expected_log += android::base::StringPrintf(
+      "6 malloc_debug +++ malloc_testing leaked block of size 128 at %p (leak 2 of 3)\n",
+      pointer2);
+  expected_log += "6 malloc_debug Backtrace at time of allocation:\n";
+  expected_log += "6 malloc_debug   #00 pc 0xa000\n";
+  expected_log += "6 malloc_debug   #01 pc 0xb000\n";
+  expected_log += "6 malloc_debug   #02 pc 0xc000\n";
+  expected_log += "6 malloc_debug   #03 pc 0xd000\n";
+
+  expected_log += android::base::StringPrintf(
+      "6 malloc_debug +++ malloc_testing leaked block of size 100 at %p (leak 3 of 3)\n",
+      pointer1);
+  expected_log += "6 malloc_debug Backtrace at time of allocation:\n";
+  expected_log += "6 malloc_debug   #00 pc 0x1000\n";
+  expected_log += "6 malloc_debug   #01 pc 0x2000\n";
+  expected_log += "6 malloc_debug   #02 pc 0x3000\n";
+
+  ASSERT_STREQ(expected_log.c_str(), getFakeLogPrint().c_str());
+}
+
+TEST_F(MallocDebugTest, leak_track_frees) {
+  Init("leak_track");
+
+  void* pointer1 = debug_malloc(390);
+  ASSERT_TRUE(pointer1 != nullptr);
+  memset(pointer1, 0, 390);
+  debug_free(pointer1);
+
+  pointer1 = debug_malloc(100);
+  ASSERT_TRUE(pointer1 != nullptr);
+  memset(pointer1, 0, 100);
+
+  void* pointer2 = debug_malloc(250);
+  ASSERT_TRUE(pointer2 != nullptr);
+  memset(pointer2, 0, 250);
+  debug_free(pointer2);
+
+  pointer2 = debug_malloc(450);
+  ASSERT_TRUE(pointer2 != nullptr);
+  memset(pointer2, 0, 450);
+
+  void* pointer3 = debug_malloc(999);
+  ASSERT_TRUE(pointer3 != nullptr);
+  memset(pointer3, 0, 999);
+  debug_free(pointer2);
+
+  debug_finalize();
+  initialized = false;
+
+  ASSERT_STREQ("", getFakeLogBuf().c_str());
+  std::string expected_log = android::base::StringPrintf(
+      "6 malloc_debug +++ malloc_testing leaked block of size 999 at %p (leak 1 of 2)\n",
+      pointer3);
+  expected_log += android::base::StringPrintf(
+      "6 malloc_debug +++ malloc_testing leaked block of size 100 at %p (leak 2 of 2)\n",
+      pointer1);
+  ASSERT_STREQ(expected_log.c_str(), getFakeLogPrint().c_str());
+}
+
+TEST_F(MallocDebugTest, free_track) {
+  Init("free_track=5 free_track_backtrace_num_frames=0");
+
+  void* pointers[10];
+  for (size_t i = 0; i < sizeof(pointers) / sizeof(void*); i++) {
+    pointers[i] = debug_malloc(100 + i);
+    ASSERT_TRUE(pointers[i] != nullptr);
+    memset(pointers[i], 0, 100 + i);
+    debug_free(pointers[i]);
+  }
+
+  // Large allocations (> 4096) to verify large allocation checks.
+  void* pointer = debug_malloc(8192);
+  ASSERT_TRUE(pointer != nullptr);
+  memset(pointer, 0, 8192);
+  debug_free(pointer);
+
+  pointer = debug_malloc(9000);
+  ASSERT_TRUE(pointer != nullptr);
+  memset(pointer, 0, 9000);
+  debug_free(pointer);
+
+  ASSERT_STREQ("", getFakeLogBuf().c_str());
+  ASSERT_STREQ("", getFakeLogPrint().c_str());
+}
+
+TEST_F(MallocDebugTest, free_track_use_after_free) {
+  Init("free_track=5 free_track_backtrace_num_frames=0");
+
+  uint8_t* pointers[5];
+  for (size_t i = 0; i < sizeof(pointers) / sizeof(void*); i++) {
+    pointers[i] = reinterpret_cast<uint8_t*>(debug_malloc(100 + i));
+    ASSERT_TRUE(pointers[i] != nullptr);
+    memset(pointers[i], 0, 100 + i);
+    debug_free(pointers[i]);
+  }
+
+  // Stomp on the data.
+  pointers[0][20] = 0xaf;
+  pointers[0][99] = 0x12;
+
+  pointers[3][3] = 0x34;
+
+  // Large allocations (> 4096) to verify large allocation checks.
+  uint8_t* pointer1_large = reinterpret_cast<uint8_t*>(debug_malloc(8192));
+  ASSERT_TRUE(pointer1_large != nullptr);
+  memset(pointer1_large, 0, 8192);
+  debug_free(pointer1_large);
+
+  pointer1_large[4095] = 0x90;
+  pointer1_large[4100] = 0x56;
+  pointer1_large[8191] = 0x89;
+
+  uint8_t* pointer2_large = reinterpret_cast<uint8_t*>(debug_malloc(9000));
+  ASSERT_TRUE(pointer2_large != nullptr);
+  memset(pointer2_large, 0, 9000);
+  debug_free(pointer2_large);
+
+  pointer2_large[8200] = 0x78;
+
+  // Do a bunch of alloc and free to verify the above frees are checked.
+  for (size_t i = 0; i < 10; i++) {
+    void* flush_pointer = debug_malloc(100+i);
+    ASSERT_TRUE(flush_pointer != nullptr);
+    memset(flush_pointer, 0, 100 + i);
+    debug_free(flush_pointer);
+  }
+
+  ASSERT_STREQ("", getFakeLogBuf().c_str());
+  std::string expected_log(DIVIDER);
+  expected_log += android::base::StringPrintf("6 malloc_debug +++ ALLOCATION %p USED AFTER FREE\n", pointers[0]);
+  expected_log += "6 malloc_debug   allocation[20] = 0xaf (expected 0xef)\n";
+  expected_log += "6 malloc_debug   allocation[99] = 0x12 (expected 0xef)\n";
+  expected_log += DIVIDER;
+  expected_log += DIVIDER;
+  expected_log += android::base::StringPrintf("6 malloc_debug +++ ALLOCATION %p USED AFTER FREE\n", pointers[3]);
+  expected_log += "6 malloc_debug   allocation[3] = 0x34 (expected 0xef)\n";
+  expected_log += DIVIDER;
+  expected_log += DIVIDER;
+  expected_log += android::base::StringPrintf("6 malloc_debug +++ ALLOCATION %p USED AFTER FREE\n", pointer1_large);
+  expected_log += "6 malloc_debug   allocation[4095] = 0x90 (expected 0xef)\n";
+  expected_log += "6 malloc_debug   allocation[4100] = 0x56 (expected 0xef)\n";
+  expected_log += "6 malloc_debug   allocation[8191] = 0x89 (expected 0xef)\n";
+  expected_log += DIVIDER;
+  expected_log += DIVIDER;
+  expected_log += android::base::StringPrintf("6 malloc_debug +++ ALLOCATION %p USED AFTER FREE\n", pointer2_large);
+  expected_log += "6 malloc_debug   allocation[8200] = 0x78 (expected 0xef)\n";
+  expected_log += DIVIDER;
+  ASSERT_STREQ(expected_log.c_str(), getFakeLogPrint().c_str());
+}
+
+TEST_F(MallocDebugTest, free_track_use_after_free_finalize) {
+  Init("free_track=100 free_track_backtrace_num_frames=0");
+
+  uint8_t* pointer = reinterpret_cast<uint8_t*>(debug_malloc(100));
+  ASSERT_TRUE(pointer != nullptr);
+  memset(pointer, 0, 100);
+  debug_free(pointer);
+
+  pointer[56] = 0x91;
+
+  ASSERT_STREQ("", getFakeLogBuf().c_str());
+  ASSERT_STREQ("", getFakeLogPrint().c_str());
+
+  debug_finalize();
+  initialized = false;
+
+  ASSERT_STREQ("", getFakeLogBuf().c_str());
+  std::string expected_log(DIVIDER);
+  expected_log += android::base::StringPrintf("6 malloc_debug +++ ALLOCATION %p USED AFTER FREE\n", pointer);
+  expected_log += "6 malloc_debug   allocation[56] = 0x91 (expected 0xef)\n";
+  expected_log += DIVIDER;
+  ASSERT_STREQ(expected_log.c_str(), getFakeLogPrint().c_str());
+}
+
+TEST_F(MallocDebugTest, free_track_use_after_free_with_backtrace) {
+  Init("free_track=100");
+
+  // Free backtrace.
+  backtrace_fake_add(std::vector<uintptr_t> {0xfa, 0xeb, 0xdc});
+
+  uint8_t* pointer = reinterpret_cast<uint8_t*>(debug_malloc(200));
+  ASSERT_TRUE(pointer != nullptr);
+  memset(pointer, 0, 200);
+  debug_free(pointer);
+
+  pointer[101] = 0xab;
+
+  ASSERT_STREQ("", getFakeLogBuf().c_str());
+  ASSERT_STREQ("", getFakeLogPrint().c_str());
+
+  debug_finalize();
+  initialized = false;
+
+  ASSERT_STREQ("", getFakeLogBuf().c_str());
+  std::string expected_log(DIVIDER);
+  expected_log += android::base::StringPrintf("6 malloc_debug +++ ALLOCATION %p USED AFTER FREE\n", pointer);
+  expected_log += "6 malloc_debug   allocation[101] = 0xab (expected 0xef)\n";
+  expected_log += "6 malloc_debug Backtrace at time of free:\n";
+  expected_log += "6 malloc_debug   #00 pc 0xfa\n";
+  expected_log += "6 malloc_debug   #01 pc 0xeb\n";
+  expected_log += "6 malloc_debug   #02 pc 0xdc\n";
+  expected_log += DIVIDER;
+  ASSERT_STREQ(expected_log.c_str(), getFakeLogPrint().c_str());
+}
+
+TEST_F(MallocDebugTest, free_track_use_after_free_call_realloc) {
+  Init("free_track=100");
+
+  // Free backtrace.
+  backtrace_fake_add(std::vector<uintptr_t> {0xfa, 0xeb, 0xdc});
+  // Backtrace at realloc.
+  backtrace_fake_add(std::vector<uintptr_t> {0x12, 0x22, 0x32, 0x42});
+
+  void* pointer = debug_malloc(200);
+  ASSERT_TRUE(pointer != nullptr);
+  memset(pointer, 0, 200);
+  debug_free(pointer);
+
+  // Choose a size that should not trigger a realloc to verify tag is
+  // verified early.
+  ASSERT_TRUE(debug_realloc(pointer, 200) == nullptr);
+
+  ASSERT_STREQ("", getFakeLogBuf().c_str());
+  std::string expected_log(DIVIDER);
+  expected_log += android::base::StringPrintf(
+      "6 malloc_debug +++ ALLOCATION %p USED AFTER FREE (realloc)\n", pointer);
+  expected_log += "6 malloc_debug Backtrace of original free:\n";
+  expected_log += "6 malloc_debug   #00 pc 0xfa\n";
+  expected_log += "6 malloc_debug   #01 pc 0xeb\n";
+  expected_log += "6 malloc_debug   #02 pc 0xdc\n";
+  expected_log += "6 malloc_debug Backtrace at time of failure:\n";
+  expected_log += "6 malloc_debug   #00 pc 0x12\n";
+  expected_log += "6 malloc_debug   #01 pc 0x22\n";
+  expected_log += "6 malloc_debug   #02 pc 0x32\n";
+  expected_log += "6 malloc_debug   #03 pc 0x42\n";
+  expected_log += DIVIDER;
+  ASSERT_STREQ(expected_log.c_str(), getFakeLogPrint().c_str());
+}
+
+TEST_F(MallocDebugTest, free_track_use_after_free_call_free) {
+  Init("free_track=100");
+
+  // Free backtrace.
+  backtrace_fake_add(std::vector<uintptr_t> {0xfa, 0xeb, 0xdc});
+  // Backtrace at second free.
+  backtrace_fake_add(std::vector<uintptr_t> {0x12, 0x22, 0x32, 0x42});
+
+  void* pointer = debug_malloc(200);
+  ASSERT_TRUE(pointer != nullptr);
+  memset(pointer, 0, 200);
+  debug_free(pointer);
+
+  debug_free(pointer);
+
+  ASSERT_STREQ("", getFakeLogBuf().c_str());
+  std::string expected_log(DIVIDER);
+  expected_log += android::base::StringPrintf(
+      "6 malloc_debug +++ ALLOCATION %p USED AFTER FREE (free)\n", pointer);
+  expected_log += "6 malloc_debug Backtrace of original free:\n";
+  expected_log += "6 malloc_debug   #00 pc 0xfa\n";
+  expected_log += "6 malloc_debug   #01 pc 0xeb\n";
+  expected_log += "6 malloc_debug   #02 pc 0xdc\n";
+  expected_log += "6 malloc_debug Backtrace at time of failure:\n";
+  expected_log += "6 malloc_debug   #00 pc 0x12\n";
+  expected_log += "6 malloc_debug   #01 pc 0x22\n";
+  expected_log += "6 malloc_debug   #02 pc 0x32\n";
+  expected_log += "6 malloc_debug   #03 pc 0x42\n";
+  expected_log += DIVIDER;
+  ASSERT_STREQ(expected_log.c_str(), getFakeLogPrint().c_str());
+}
+
+TEST_F(MallocDebugTest, free_track_header_tag_corrupted) {
+  Init("free_track=100 free_track_backtrace_num_frames=0");
+
+  uint8_t* pointer = reinterpret_cast<uint8_t*>(debug_malloc(100));
+  ASSERT_TRUE(pointer != nullptr);
+  memset(pointer, 0, 100);
+  debug_free(pointer);
+
+  pointer[-get_tag_offset()] = 0x00;
+
+  ASSERT_STREQ("", getFakeLogBuf().c_str());
+  ASSERT_STREQ("", getFakeLogPrint().c_str());
+
+  debug_finalize();
+  initialized = false;
+
+  ASSERT_STREQ("", getFakeLogBuf().c_str());
+  std::string expected_log(DIVIDER);
+  expected_log += android::base::StringPrintf(
+      "6 malloc_debug +++ ALLOCATION %p HAS CORRUPTED HEADER TAG 0x1cc7dc00 AFTER FREE\n",
+      pointer);
+  expected_log += DIVIDER;
+  ASSERT_STREQ(expected_log.c_str(), getFakeLogPrint().c_str());
+}
+
+TEST_F(MallocDebugTest, free_track_multiple_thread) {
+  Init("free_track=10 free_track_backtrace_num_frames=0");
+
+  std::vector<std::thread*> threads(1000);
+  for (size_t i = 0; i < threads.size(); i++) {
+    threads[i] = new std::thread([](){
+      for (size_t j = 0; j < 100; j++) {
+        void* mem = debug_malloc(100);
+        write(0, mem, 0);
+        debug_free(mem);
+      }
+    });
+  }
+  for (size_t i = 0; i < threads.size(); i++) {
+    threads[i]->join();
+    delete threads[i];
+  }
+
+  ASSERT_STREQ("", getFakeLogBuf().c_str());
+  ASSERT_STREQ("", getFakeLogPrint().c_str());
+}
+
+TEST_F(MallocDebugTest, get_malloc_leak_info_invalid) {
+  Init("fill");
+
+  uint8_t* info;
+  size_t overall_size;
+  size_t info_size;
+  size_t total_memory;
+  size_t backtrace_size;
+
+  std::string expected_log("6 malloc_debug get_malloc_leak_info: At least one invalid parameter.\n");
+
+  debug_get_malloc_leak_info(nullptr, &overall_size, &info_size, &total_memory, &backtrace_size);
+  ASSERT_STREQ(expected_log.c_str(), getFakeLogPrint().c_str());
+
+  resetLogs();
+  debug_get_malloc_leak_info(&info, nullptr, &info_size, &total_memory, &backtrace_size);
+  ASSERT_STREQ(expected_log.c_str(), getFakeLogPrint().c_str());
+
+  resetLogs();
+  debug_get_malloc_leak_info(&info, &overall_size, nullptr, &total_memory, &backtrace_size);
+  ASSERT_STREQ(expected_log.c_str(), getFakeLogPrint().c_str());
+
+  resetLogs();
+  debug_get_malloc_leak_info(&info, &overall_size, &info_size, nullptr, &backtrace_size);
+  ASSERT_STREQ(expected_log.c_str(), getFakeLogPrint().c_str());
+
+  resetLogs();
+  debug_get_malloc_leak_info(&info, &overall_size, &info_size, &total_memory, nullptr);
+  ASSERT_STREQ(expected_log.c_str(), getFakeLogPrint().c_str());
+}
+
+TEST_F(MallocDebugTest, get_malloc_leak_info_not_enabled) {
+  Init("fill");
+
+  uint8_t* info;
+  size_t overall_size;
+  size_t info_size;
+  size_t total_memory;
+  size_t backtrace_size;
+
+  ASSERT_STREQ("", getFakeLogBuf().c_str());
+  debug_get_malloc_leak_info(&info, &overall_size, &info_size, &total_memory, &backtrace_size);
+  std::string expected_log(
+      "6 malloc_debug get_malloc_leak_info: Allocations not being tracked, to enable "
+      "set the option 'backtrace'.\n");
+  ASSERT_STREQ(expected_log.c_str(), getFakeLogPrint().c_str());
+}
+
+struct InfoEntry {
+  size_t size;
+  size_t num_frames;
+  uintptr_t frames[0];
+} __attribute__((packed));
+
+TEST_F(MallocDebugTest, get_malloc_leak_info_empty) {
+  Init("backtrace");
+
+  uint8_t* info;
+  size_t overall_size;
+  size_t info_size;
+  size_t total_memory;
+  size_t backtrace_size;
+
+  debug_get_malloc_leak_info(&info, &overall_size, &info_size, &total_memory, &backtrace_size);
+  ASSERT_TRUE(info == nullptr);
+  ASSERT_EQ(0U, overall_size);
+  ASSERT_EQ(0U, info_size);
+  ASSERT_EQ(0U, total_memory);
+  ASSERT_EQ(0U, backtrace_size);
+
+  ASSERT_STREQ("", getFakeLogBuf().c_str());
+  ASSERT_STREQ("", getFakeLogPrint().c_str());
+}
+
+TEST_F(MallocDebugTest, get_malloc_leak_info_single) {
+  Init("backtrace");
+
+  // Create the expected info buffer.
+  size_t individual_size = 2 * sizeof(size_t) + 16 * sizeof(uintptr_t);
+  std::vector<uint8_t> expected_info(individual_size);
+  memset(expected_info.data(), 0, individual_size);
+
+  InfoEntry* entry = reinterpret_cast<InfoEntry*>(expected_info.data());
+  entry->size = 200;
+  entry->num_frames = 3;
+  entry->frames[0] = 0xf;
+  entry->frames[1] = 0xe;
+  entry->frames[2] = 0xd;
+
+  backtrace_fake_add(std::vector<uintptr_t> {0xf, 0xe, 0xd});
+
+  uint8_t* pointer = reinterpret_cast<uint8_t*>(debug_malloc(entry->size));
+  ASSERT_TRUE(pointer != nullptr);
+  memset(pointer, 0, entry->size);
+
+  uint8_t* info;
+  size_t overall_size;
+  size_t info_size;
+  size_t total_memory;
+  size_t backtrace_size;
+
+  debug_get_malloc_leak_info(&info, &overall_size, &info_size, &total_memory, &backtrace_size);
+  ASSERT_TRUE(info != nullptr);
+  ASSERT_EQ(individual_size, overall_size);
+  ASSERT_EQ(individual_size, info_size);
+  ASSERT_EQ(200U, total_memory);
+  ASSERT_EQ(16U, backtrace_size);
+  ASSERT_TRUE(memcmp(expected_info.data(), info, overall_size) == 0);
+
+  debug_free_malloc_leak_info(info);
+
+  debug_free(pointer);
+
+  ASSERT_STREQ("", getFakeLogBuf().c_str());
+  ASSERT_STREQ("", getFakeLogPrint().c_str());
+}
+
+TEST_F(MallocDebugTest, get_malloc_leak_info_multi) {
+  Init("backtrace=16");
+
+  // Create the expected info buffer.
+  size_t individual_size = 2 * sizeof(size_t) + 16 * sizeof(uintptr_t);
+  std::vector<uint8_t> expected_info(individual_size * 3);
+  memset(expected_info.data(), 0, individual_size * 3);
+
+  InfoEntry* entry0 = reinterpret_cast<InfoEntry*>(expected_info.data());
+  InfoEntry* entry1 = reinterpret_cast<InfoEntry*>(
+      reinterpret_cast<uintptr_t>(entry0) + individual_size);
+  InfoEntry* entry2 = reinterpret_cast<InfoEntry*>(
+      reinterpret_cast<uintptr_t>(entry1) + individual_size);
+
+  // These values will be in the reverse order that we create.
+  entry2->size = 500;
+  entry2->num_frames = 4;
+  entry2->frames[0] = 0xf;
+  entry2->frames[1] = 0xe;
+  entry2->frames[2] = 0xd;
+  entry2->frames[3] = 0xc;
+
+  backtrace_fake_add(std::vector<uintptr_t> {0xf, 0xe, 0xd, 0xc});
+
+  uint8_t* pointers[3];
+
+  pointers[0] = reinterpret_cast<uint8_t*>(debug_malloc(entry2->size));
+  ASSERT_TRUE(pointers[0] != nullptr);
+  memset(pointers[0], 0, entry2->size);
+
+  entry1->size = 4100;
+  entry1->num_frames = 16;
+  for (size_t i = 0; i < 16; i++) {
+    entry1->frames[i] = 0xbc000 + i;
+  }
+
+  backtrace_fake_add(
+      std::vector<uintptr_t> {0xbc000, 0xbc001, 0xbc002, 0xbc003, 0xbc004, 0xbc005,
+                              0xbc006, 0xbc007, 0xbc008, 0xbc009, 0xbc00a, 0xbc00b,
+                              0xbc00c, 0xbc00d, 0xbc00e, 0xbc00f, 0xffff});
+
+  pointers[1] = reinterpret_cast<uint8_t*>(debug_malloc(entry1->size));
+  ASSERT_TRUE(pointers[1] != nullptr);
+  memset(pointers[1], 0, entry1->size);
+
+  entry0->size = 9000;
+  entry0->num_frames = 1;
+
+  entry0->frames[0] = 0x104;
+  backtrace_fake_add(std::vector<uintptr_t> {0x104});
+
+  pointers[2] = reinterpret_cast<uint8_t*>(debug_malloc(entry0->size));
+  ASSERT_TRUE(pointers[2] != nullptr);
+  memset(pointers[2], 0, entry0->size);
+
+  uint8_t* info;
+  size_t overall_size;
+  size_t info_size;
+  size_t total_memory;
+  size_t backtrace_size;
+
+  debug_get_malloc_leak_info(&info, &overall_size, &info_size, &total_memory, &backtrace_size);
+  ASSERT_TRUE(info != nullptr);
+  ASSERT_EQ(individual_size * 3, overall_size);
+  ASSERT_EQ(individual_size, info_size);
+  ASSERT_EQ(500U + 4100U + 9000U, total_memory);
+  ASSERT_EQ(16U, backtrace_size);
+  ASSERT_TRUE(memcmp(expected_info.data(), info, overall_size) == 0);
+
+  debug_free_malloc_leak_info(info);
+
+  debug_free(pointers[0]);
+  debug_free(pointers[1]);
+  debug_free(pointers[2]);
+
+  ASSERT_STREQ("", getFakeLogBuf().c_str());
+  ASSERT_STREQ("", getFakeLogPrint().c_str());
+}
+
+TEST_F(MallocDebugTest, get_malloc_leak_info_multi_skip_empty_backtrace) {
+  Init("backtrace=16");
+
+  // Create the expected info buffer.
+  size_t individual_size = 2 * sizeof(size_t) + 16 * sizeof(uintptr_t);
+  std::vector<uint8_t> expected_info(individual_size * 2);
+  memset(expected_info.data(), 0, individual_size * 2);
+
+  InfoEntry* entry0 = reinterpret_cast<InfoEntry*>(expected_info.data());
+  InfoEntry* entry1 = reinterpret_cast<InfoEntry*>(
+      reinterpret_cast<uintptr_t>(entry0) + individual_size);
+
+  // These values will be in the reverse order that we create.
+  entry1->size = 500;
+  entry1->num_frames = 4;
+  entry1->frames[0] = 0xf;
+  entry1->frames[1] = 0xe;
+  entry1->frames[2] = 0xd;
+  entry1->frames[3] = 0xc;
+
+  backtrace_fake_add(std::vector<uintptr_t> {0xf, 0xe, 0xd, 0xc});
+
+  uint8_t* pointers[3];
+
+  pointers[0] = reinterpret_cast<uint8_t*>(debug_malloc(entry1->size));
+  ASSERT_TRUE(pointers[0] != nullptr);
+  memset(pointers[0], 0, entry1->size);
+
+  entry0->size = 4100;
+  entry0->num_frames = 16;
+  for (size_t i = 0; i < 16; i++) {
+    entry0->frames[i] = 0xbc000 + i;
+  }
+
+  backtrace_fake_add(
+      std::vector<uintptr_t> {0xbc000, 0xbc001, 0xbc002, 0xbc003, 0xbc004, 0xbc005,
+                              0xbc006, 0xbc007, 0xbc008, 0xbc009, 0xbc00a, 0xbc00b,
+                              0xbc00c, 0xbc00d, 0xbc00e, 0xbc00f, 0xffff});
+
+  pointers[1] = reinterpret_cast<uint8_t*>(debug_malloc(entry0->size));
+  ASSERT_TRUE(pointers[1] != nullptr);
+  memset(pointers[1], 0, entry0->size);
+
+  pointers[2] = reinterpret_cast<uint8_t*>(debug_malloc(10000));
+  ASSERT_TRUE(pointers[2] != nullptr);
+  memset(pointers[2], 0, 10000);
+
+  uint8_t* info;
+  size_t overall_size;
+  size_t info_size;
+  size_t total_memory;
+  size_t backtrace_size;
+
+  debug_get_malloc_leak_info(&info, &overall_size, &info_size, &total_memory, &backtrace_size);
+  ASSERT_TRUE(info != nullptr);
+  ASSERT_EQ(individual_size * 2, overall_size);
+  ASSERT_EQ(individual_size, info_size);
+  ASSERT_EQ(500U + 4100U, total_memory);
+  ASSERT_EQ(16U, backtrace_size);
+  ASSERT_TRUE(memcmp(expected_info.data(), info, overall_size) == 0);
+
+  debug_free_malloc_leak_info(info);
+
+  debug_free(pointers[0]);
+  debug_free(pointers[1]);
+  debug_free(pointers[2]);
+
+  ASSERT_STREQ("", getFakeLogBuf().c_str());
+  ASSERT_STREQ("", getFakeLogPrint().c_str());
+}
+
+TEST_F(MallocDebugTest, realloc_usable_size) {
+  Init("front_guard");
+
+  // Verify that if the usable size > size of alloc, that realloc
+  // copies the bytes in the usable size not just the size.
+  // This assumes that an allocation of size 1 returns usable size > 1.
+  // If this isn't true, this test is not going to do anything.
+  uint8_t* pointer = reinterpret_cast<uint8_t*>(debug_malloc(1));
+  ASSERT_TRUE(pointer != nullptr);
+  size_t usable_size = debug_malloc_usable_size(pointer);
+  memset(pointer, 0xaa, usable_size);
+  pointer = reinterpret_cast<uint8_t*>(debug_realloc(pointer, usable_size + 10));
+  ASSERT_TRUE(pointer != nullptr);
+  ASSERT_LE(usable_size + 10, debug_malloc_usable_size(pointer));
+  for (size_t i = 0; i < usable_size; i++) {
+    ASSERT_EQ(0xaa, pointer[i]) << "Failed compare at byte " << i;
+  }
+  debug_free(pointer);
+
+  ASSERT_STREQ("", getFakeLogBuf().c_str());
+  ASSERT_STREQ("", getFakeLogPrint().c_str());
+}
+
+TEST_F(MallocDebugTest, backtrace_enable_on_signal) {
+  Init("backtrace_enable_on_signal=20");
+
+  size_t individual_size = 2 * sizeof(size_t) + 20 * sizeof(uintptr_t);
+
+  backtrace_fake_add(std::vector<uintptr_t> {0xbc000, 0xecd00, 0x12000});
+  backtrace_fake_add(std::vector<uintptr_t> {0x100, 0x200, 0x300, 0x400});
+  backtrace_fake_add(std::vector<uintptr_t> {0x500, 0xa00, 0xb00});
+
+  // First allocation should not actually attempt to get the backtrace.
+  void* pointer = debug_malloc(10);
+  ASSERT_TRUE(pointer != nullptr);
+
+  uint8_t* info;
+  size_t overall_size;
+  size_t info_size;
+  size_t total_memory;
+  size_t backtrace_size;
+
+  debug_get_malloc_leak_info(&info, &overall_size, &info_size, &total_memory, &backtrace_size);
+  ASSERT_TRUE(info == nullptr);
+  ASSERT_EQ(0U, overall_size);
+  ASSERT_EQ(0U, info_size);
+  ASSERT_EQ(0U, total_memory);
+  ASSERT_EQ(0U, backtrace_size);
+  debug_free(pointer);
+
+  debug_free_malloc_leak_info(info);
+
+  // Send the signal to enable.
+  ASSERT_TRUE(kill(getpid(), SIGRTMIN + 10) == 0);
+  sleep(1);
+
+  pointer = debug_malloc(100);
+  ASSERT_TRUE(pointer != nullptr);
+
+  debug_get_malloc_leak_info(&info, &overall_size, &info_size, &total_memory, &backtrace_size);
+  ASSERT_TRUE(info != nullptr);
+  ASSERT_EQ(individual_size, overall_size);
+  ASSERT_EQ(individual_size, info_size);
+  ASSERT_EQ(100U, total_memory);
+  ASSERT_EQ(20U, backtrace_size);
+  uintptr_t* ips = reinterpret_cast<uintptr_t*>(&info[2 * sizeof(size_t)]);
+  ASSERT_EQ(0xbc000U, ips[0]);
+  ASSERT_EQ(0xecd00U, ips[1]);
+  ASSERT_EQ(0x12000U, ips[2]);
+  for (size_t i = 3; i < 20; i++) {
+    ASSERT_EQ(0U, ips[i]);
+  }
+
+  debug_free(pointer);
+
+  debug_free_malloc_leak_info(info);
+
+  // Send the signal to disable.
+  ASSERT_TRUE(kill(getpid(), SIGRTMIN + 10) == 0);
+  sleep(1);
+
+  pointer = debug_malloc(200);
+  ASSERT_TRUE(pointer != nullptr);
+
+  debug_get_malloc_leak_info(&info, &overall_size, &info_size, &total_memory, &backtrace_size);
+  ASSERT_TRUE(info == nullptr);
+  ASSERT_EQ(0U, overall_size);
+  ASSERT_EQ(0U, info_size);
+  ASSERT_EQ(0U, total_memory);
+  ASSERT_EQ(0U, backtrace_size);
+
+  debug_free(pointer);
+
+  debug_free_malloc_leak_info(info);
+
+  ASSERT_STREQ("", getFakeLogBuf().c_str());
+  std::string expected_log = android::base::StringPrintf(
+      "4 malloc_debug malloc_testing: Run: 'kill -%d %d' to enable backtracing.\n",
+      SIGRTMIN + 10, getpid());
+  ASSERT_STREQ(expected_log.c_str(), getFakeLogPrint().c_str());
+}
+
+TEST_F(MallocDebugTest, overflow) {
+  Init("guard fill_on_free");
+
+  void* pointer = debug_malloc(SIZE_MAX);
+  ASSERT_TRUE(pointer == nullptr);
+  ASSERT_EQ(ENOMEM, errno);
+
+  pointer = debug_calloc(1, SIZE_MAX);
+  ASSERT_TRUE(pointer == nullptr);
+  ASSERT_EQ(ENOMEM, errno);
+
+  pointer = debug_calloc(SIZE_MAX, 1);
+  ASSERT_TRUE(pointer == nullptr);
+  ASSERT_EQ(ENOMEM, errno);
+
+  pointer = debug_calloc(SIZE_MAX/100, 100);
+  ASSERT_TRUE(pointer == nullptr);
+  ASSERT_EQ(ENOMEM, errno);
+
+  pointer = debug_calloc(100, SIZE_MAX/100);
+  ASSERT_TRUE(pointer == nullptr);
+  ASSERT_EQ(ENOMEM, errno);
+
+  const size_t size_t_bits = sizeof(size_t) * 8;
+  const size_t sqrt_size_t = 1ULL << (size_t_bits/2);
+  pointer = debug_calloc(sqrt_size_t + 1, sqrt_size_t);
+  ASSERT_TRUE(pointer == nullptr);
+  ASSERT_EQ(ENOMEM, errno);
+
+  pointer = debug_realloc(nullptr, SIZE_MAX);
+  ASSERT_TRUE(pointer == nullptr);
+  ASSERT_EQ(ENOMEM, errno);
+
+  pointer = debug_malloc(100);
+  ASSERT_TRUE(pointer != nullptr);
+  memset(pointer, 0xd0, 100);
+
+  void* realloc_pointer = debug_realloc(pointer, SIZE_MAX);
+  ASSERT_TRUE(realloc_pointer == nullptr);
+  // Verify the pointer was not freed.
+  for (size_t i = 0; i < 100; i++) {
+    ASSERT_EQ(0xd0, reinterpret_cast<uint8_t*>(pointer)[i]) << "Failed checking byte " << i;
+  }
+  debug_free(pointer);
+
+  ASSERT_STREQ("", getFakeLogBuf().c_str());
+  ASSERT_STREQ("", getFakeLogPrint().c_str());
+}
+
+static void VerifyZygoteSet(size_t memory_bytes) {
+  size_t expected_info_size = 2 * sizeof(size_t) + 16 * sizeof(uintptr_t);
+  std::vector<uint8_t> expected_info(expected_info_size);
+  memset(expected_info.data(), 0, expected_info_size);
+  InfoEntry* entry = reinterpret_cast<InfoEntry*>(expected_info.data());
+  entry->size = memory_bytes | (1U << 31);
+  entry->num_frames = 1;
+  entry->frames[0] = 0x1;
+
+  uint8_t* info;
+  size_t overall_size;
+  size_t info_size;
+  size_t total_memory;
+  size_t backtrace_size;
+
+  debug_get_malloc_leak_info(&info, &overall_size, &info_size, &total_memory, &backtrace_size);
+  ASSERT_EQ(expected_info_size, overall_size);
+  ASSERT_EQ(expected_info_size, info_size);
+  ASSERT_EQ(memory_bytes, total_memory);
+  ASSERT_EQ(16U, backtrace_size);
+  ASSERT_TRUE(memcmp(info, expected_info.data(), expected_info_size) == 0);
+
+  debug_free_malloc_leak_info(info);
+}
+
+TEST_F(MallocDebugTest, zygote_set) {
+  // Set all of the options.
+  Init("guard fill backtrace leak_track free_track=2");
+
+  zygote = 1;
+
+  backtrace_fake_add(std::vector<uintptr_t> {0x1});
+
+  void* pointer = debug_malloc(100);
+  ASSERT_TRUE(pointer != nullptr);
+  ASSERT_EQ(100U, debug_malloc_usable_size(pointer));
+  memset(pointer, 0, 100);
+  VerifyZygoteSet(100);
+  debug_free(pointer);
+
+  backtrace_fake_add(std::vector<uintptr_t> {0x1});
+  pointer = debug_calloc(10, 20);
+  ASSERT_TRUE(pointer != nullptr);
+  ASSERT_EQ(200U, debug_malloc_usable_size(pointer));
+  VerifyZygoteSet(200);
+  debug_free(pointer);
+
+  backtrace_fake_add(std::vector<uintptr_t> {0x1});
+  pointer = debug_memalign(128, 300);
+  ASSERT_TRUE(pointer != nullptr);
+  ASSERT_EQ(300U, debug_malloc_usable_size(pointer));
+  memset(pointer, 0, 300);
+  VerifyZygoteSet(300);
+  debug_free(pointer);
+
+  backtrace_fake_add(std::vector<uintptr_t> {0x1});
+  pointer = debug_malloc(500);
+  ASSERT_TRUE(pointer != nullptr);
+  ASSERT_EQ(500U, debug_malloc_usable_size(pointer));
+  memset(pointer, 0, 500);
+  VerifyZygoteSet(500);
+
+  backtrace_fake_add(std::vector<uintptr_t> {0x1});
+  pointer = debug_realloc(pointer, 300);
+  ASSERT_TRUE(pointer != nullptr);
+  ASSERT_EQ(300U, debug_malloc_usable_size(pointer));
+  VerifyZygoteSet(300);
+  debug_free(pointer);
+
+  ASSERT_STREQ("", getFakeLogBuf().c_str());
+  ASSERT_STREQ("", getFakeLogPrint().c_str());
+}
+
+TEST_F(MallocDebugTest, max_size) {
+  Init("guard");
+
+  void* pointer = debug_malloc(1U << 31);
+  ASSERT_TRUE(pointer == nullptr);
+
+  pointer = debug_calloc(1, 1U << 31);
+  ASSERT_TRUE(pointer == nullptr);
+
+  pointer = debug_calloc(1U << 31, 1);
+  ASSERT_TRUE(pointer == nullptr);
+
+  pointer = debug_memalign(16, 1U << 31);
+  ASSERT_TRUE(pointer == nullptr);
+
+  ASSERT_STREQ("", getFakeLogBuf().c_str());
+  ASSERT_STREQ("", getFakeLogPrint().c_str());
+}
+
+TEST_F(MallocDebugTest, debug_mallinfo) {
+  Init("guard");
+
+  void* pointer = debug_malloc(150);
+  ASSERT_TRUE(pointer != nullptr);
+
+  struct mallinfo mi = debug_mallinfo();
+  EXPECT_NE(0U, mi.uordblks);
+
+  debug_free(pointer);
+
+  ASSERT_STREQ("", getFakeLogBuf().c_str());
+  ASSERT_STREQ("", getFakeLogPrint().c_str());
+}
+
+TEST_F(MallocDebugTest, debug_posix_memalign) {
+  Init("guard");
+
+  void* pointer;
+  ASSERT_EQ(0, debug_posix_memalign(&pointer, 32, 300));
+  ASSERT_TRUE(pointer != nullptr);
+  debug_free(pointer);
+
+  ASSERT_EQ(EINVAL, debug_posix_memalign(&pointer, 11, 300));
+
+  ASSERT_EQ(ENOMEM, debug_posix_memalign(&pointer, 16, SIZE_MAX));
+
+  ASSERT_STREQ("", getFakeLogBuf().c_str());
+  ASSERT_STREQ("", getFakeLogPrint().c_str());
+}
+
+#if defined(HAVE_DEPRECATED_MALLOC_FUNCS)
+TEST_F(MallocDebugTest, debug_pvalloc) {
+  Init("guard");
+
+  size_t pagesize = getpagesize();
+  void* pointer = debug_pvalloc(1);
+  ASSERT_TRUE(pointer != nullptr);
+  ASSERT_EQ(pagesize, debug_malloc_usable_size(pointer));
+  uintptr_t value = reinterpret_cast<uintptr_t>(pointer) & (pagesize - 1);
+  ASSERT_EQ(0U, value);
+  debug_free(pointer);
+}
+
+TEST_F(MallocDebugTest, debug_valloc) {
+  Init("guard");
+
+  size_t pagesize = getpagesize();
+  void* pointer = debug_valloc(100);
+  ASSERT_TRUE(pointer != nullptr);
+  ASSERT_EQ(100U, debug_malloc_usable_size(pointer));
+  uintptr_t value = reinterpret_cast<uintptr_t>(pointer) & (pagesize - 1);
+  ASSERT_EQ(0U, value);
+  debug_free(pointer);
+}
+#endif
diff --git a/libc/malloc_debug/tests/property_fake.cpp b/libc/malloc_debug/tests/property_fake.cpp
new file mode 100644
index 0000000..d9f0ad8
--- /dev/null
+++ b/libc/malloc_debug/tests/property_fake.cpp
@@ -0,0 +1,55 @@
+/*
+ * Copyright (C) 2015 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 <string.h>
+
+#include <string>
+#include <unordered_map>
+
+#include <sys/system_properties.h>
+
+std::unordered_map<std::string, std::string> g_properties;
+
+extern "C" int property_set(const char* name, const char* value) {
+  if (g_properties.count(name) != 0) {
+    g_properties.erase(name);
+  }
+  g_properties[name] = value;
+  return 0;
+}
+
+extern "C" int property_get(const char* key, char* value, const char* default_value) {
+  if (g_properties.count(key) == 0) {
+    if (default_value == nullptr) {
+      return 0;
+    }
+    strncpy(value, default_value, PROP_VALUE_MAX-1);
+  } else {
+    strncpy(value, g_properties[key].c_str(), PROP_VALUE_MAX-1);
+  }
+  value[PROP_VALUE_MAX-1] = '\0';
+  return strlen(value);
+}
+
+extern "C" int __system_property_get(const char* key, char* value) {
+  if (g_properties.count(key) == 0) {
+    return 0;
+  } else {
+    strncpy(value, g_properties[key].c_str(), PROP_VALUE_MAX-1);
+  }
+  value[PROP_VALUE_MAX-1] = '\0';
+  return strlen(value);
+}
diff --git a/libc/private/KernelArgumentBlock.h b/libc/private/KernelArgumentBlock.h
index c8ea497..68d4999 100644
--- a/libc/private/KernelArgumentBlock.h
+++ b/libc/private/KernelArgumentBlock.h
@@ -38,32 +38,25 @@
     argv = reinterpret_cast<char**>(args + 1);
     envp = argv + argc + 1;
 
-    // Skip over all environment variable definitions to find aux vector.
-    // The end of the environment block is marked by two NULL pointers.
+    // Skip over all environment variable definitions to find the aux vector.
+    // The end of the environment block is marked by a NULL pointer.
     char** p = envp;
     while (*p != NULL) {
       ++p;
     }
-    ++p; // Skip second NULL;
+    ++p; // Skip the NULL itself.
 
     auxv = reinterpret_cast<ElfW(auxv_t)*>(p);
   }
 
   // Similar to ::getauxval but doesn't require the libc global variables to be set up,
-  // so it's safe to call this really early on. This function also lets you distinguish
-  // between the inability to find the given type and its value just happening to be 0.
-  unsigned long getauxval(unsigned long type, bool* found_match = NULL) {
+  // so it's safe to call this really early on.
+  unsigned long getauxval(unsigned long type) {
     for (ElfW(auxv_t)* v = auxv; v->a_type != AT_NULL; ++v) {
       if (v->a_type == type) {
-        if (found_match != NULL) {
-            *found_match = true;
-        }
         return v->a_un.a_val;
       }
     }
-    if (found_match != NULL) {
-      *found_match = false;
-    }
     return 0;
   }
 
diff --git a/libc/private/ScopedPthreadMutexLocker.h b/libc/private/ScopedPthreadMutexLocker.h
index 43dbdc1..58462e3 100644
--- a/libc/private/ScopedPthreadMutexLocker.h
+++ b/libc/private/ScopedPthreadMutexLocker.h
@@ -34,7 +34,7 @@
  private:
   pthread_mutex_t* mu_;
 
-  DISALLOW_COPY_AND_ASSIGN(ScopedPthreadMutexLocker);
+  DISALLOW_IMPLICIT_CONSTRUCTORS(ScopedPthreadMutexLocker);
 };
 
 #endif // SCOPED_PTHREAD_MUTEX_LOCKER_H
diff --git a/libc/private/ScopedReaddir.h b/libc/private/ScopedReaddir.h
index 84c1b93..3d77a40 100644
--- a/libc/private/ScopedReaddir.h
+++ b/libc/private/ScopedReaddir.h
@@ -23,8 +23,11 @@
 
 class ScopedReaddir {
  public:
-  ScopedReaddir(const char* path) {
-    dir_ = opendir(path);
+  ScopedReaddir(const char* path) : ScopedReaddir(opendir(path)) {
+  }
+
+  ScopedReaddir(DIR* dir) {
+    dir_ = dir;
   }
 
   ~ScopedReaddir() {
diff --git a/libc/private/WriteProtected.h b/libc/private/WriteProtected.h
new file mode 100644
index 0000000..1133e2a
--- /dev/null
+++ b/libc/private/WriteProtected.h
@@ -0,0 +1,86 @@
+/*
+ * Copyright (C) 2015 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 _PRIVATE_WRITEPROTECTED_H
+#define _PRIVATE_WRITEPROTECTED_H
+
+#include <errno.h>
+#include <string.h>
+#include <sys/cdefs.h>
+#include <sys/mman.h>
+#include <sys/user.h>
+
+#include "private/bionic_macros.h"
+#include "private/bionic_prctl.h"
+#include "private/libc_logging.h"
+
+template <typename T>
+union WriteProtectedContents {
+  T value;
+  char padding[PAGE_SIZE];
+
+  WriteProtectedContents() = default;
+  DISALLOW_COPY_AND_ASSIGN(WriteProtectedContents);
+} __attribute__((aligned(PAGE_SIZE)));
+
+// Write protected wrapper class that aligns its contents to a page boundary,
+// and sets the memory protection to be non-writable, except when being modified
+// explicitly.
+template <typename T>
+class WriteProtected {
+  static_assert(sizeof(T) < PAGE_SIZE,
+                "WriteProtected only supports contents up to PAGE_SIZE");
+  static_assert(__is_pod(T), "WriteProtected only supports POD contents");
+
+  WriteProtectedContents<T> contents;
+
+ public:
+  WriteProtected() = default;
+  DISALLOW_COPY_AND_ASSIGN(WriteProtected);
+
+  void initialize() {
+    // Not strictly necessary, but this will hopefully segfault if we initialize
+    // multiple times by accident.
+    memset(&contents, 0, sizeof(contents));
+
+    if (mprotect(&contents, PAGE_SIZE, PROT_READ)) {
+      __libc_fatal("failed to make WriteProtected nonwritable in initialize");
+    }
+  }
+
+  const T* operator->() {
+    return &contents.value;
+  }
+
+  const T& operator*() {
+    return contents.value;
+  }
+
+  template <typename Mutator>
+  void mutate(Mutator mutator) {
+    if (mprotect(&contents, PAGE_SIZE, PROT_READ | PROT_WRITE) != 0) {
+      __libc_fatal("failed to make WriteProtected writable in mutate: %s",
+                   strerror(errno));
+    }
+    mutator(&contents.value);
+    if (mprotect(&contents, PAGE_SIZE, PROT_READ) != 0) {
+      __libc_fatal("failed to make WriteProtected nonwritable in mutate: %s",
+                   strerror(errno));
+    }
+  }
+};
+
+#endif
diff --git a/libc/private/bionic_asm.h b/libc/private/bionic_asm.h
index 5fca222c..e2084d4 100644
--- a/libc/private/bionic_asm.h
+++ b/libc/private/bionic_asm.h
@@ -38,25 +38,36 @@
 
 #include <machine/asm.h>
 
-#define ENTRY(f) \
+#define ENTRY_NO_DWARF(f) \
     .text; \
     .globl f; \
     .align __bionic_asm_align; \
     .type f, __bionic_asm_function_type; \
     f: \
     __bionic_asm_custom_entry(f); \
+
+#define ENTRY(f) \
+    ENTRY_NO_DWARF(f) \
     .cfi_startproc \
 
+#define END_NO_DWARF(f) \
+    .size f, .-f; \
+    __bionic_asm_custom_end(f) \
+
 #define END(f) \
     .cfi_endproc; \
-    .size f, .-f; \
-    __bionic_asm_custom_end(f) \
+    END_NO_DWARF(f) \
 
 /* Like ENTRY, but with hidden visibility. */
 #define ENTRY_PRIVATE(f) \
     ENTRY(f); \
     .hidden f \
 
+/* Like ENTRY_NO_DWARF, but with hidden visibility. */
+#define ENTRY_PRIVATE_NO_DWARF(f) \
+    ENTRY_NO_DWARF(f); \
+    .hidden f \
+
 #define ALIAS_SYMBOL(alias, original) \
     .globl alias; \
     .equ alias, original
diff --git a/libc/private/bionic_futex.h b/libc/private/bionic_futex.h
index 401577a..946d9dd 100644
--- a/libc/private/bionic_futex.h
+++ b/libc/private/bionic_futex.h
@@ -40,10 +40,12 @@
 
 struct timespec;
 
-static inline __always_inline int __futex(volatile void* ftx, int op, int value, const struct timespec* timeout) {
+static inline __always_inline int __futex(volatile void* ftx, int op, int value,
+                                          const struct timespec* timeout,
+                                          int bitset) {
   // Our generated syscall assembler sets errno, but our callers (pthread functions) don't want to.
   int saved_errno = errno;
-  int result = syscall(__NR_futex, ftx, op, value, timeout);
+  int result = syscall(__NR_futex, ftx, op, value, timeout, NULL, bitset);
   if (__predict_false(result == -1)) {
     result = -errno;
     errno = saved_errno;
@@ -52,19 +54,22 @@
 }
 
 static inline int __futex_wake(volatile void* ftx, int count) {
-  return __futex(ftx, FUTEX_WAKE, count, NULL);
+  return __futex(ftx, FUTEX_WAKE, count, NULL, 0);
 }
 
 static inline int __futex_wake_ex(volatile void* ftx, bool shared, int count) {
-  return __futex(ftx, shared ? FUTEX_WAKE : FUTEX_WAKE_PRIVATE, count, NULL);
+  return __futex(ftx, shared ? FUTEX_WAKE : FUTEX_WAKE_PRIVATE, count, NULL, 0);
 }
 
 static inline int __futex_wait(volatile void* ftx, int value, const struct timespec* timeout) {
-  return __futex(ftx, FUTEX_WAIT, value, timeout);
+  return __futex(ftx, FUTEX_WAIT, value, timeout, 0);
 }
 
-static inline int __futex_wait_ex(volatile void* ftx, bool shared, int value, const struct timespec* timeout) {
-  return __futex(ftx, shared ? FUTEX_WAIT : FUTEX_WAIT_PRIVATE, value, timeout);
+static inline int __futex_wait_ex(volatile void* ftx, bool shared, int value,
+                                  bool use_realtime_clock, const struct timespec* abs_timeout) {
+  return __futex(ftx, (shared ? FUTEX_WAIT_BITSET : FUTEX_WAIT_BITSET_PRIVATE) |
+                 (use_realtime_clock ? FUTEX_CLOCK_REALTIME : 0), value, abs_timeout,
+                 FUTEX_BITSET_MATCH_ANY);
 }
 
 __END_DECLS
diff --git a/libc/private/bionic_globals.h b/libc/private/bionic_globals.h
new file mode 100644
index 0000000..b45c0c3
--- /dev/null
+++ b/libc/private/bionic_globals.h
@@ -0,0 +1,57 @@
+/*
+ * Copyright (C) 2015 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 _PRIVATE_BIONIC_GLOBALS_H
+#define _PRIVATE_BIONIC_GLOBALS_H
+
+#include <sys/cdefs.h>
+
+#include "private/bionic_malloc_dispatch.h"
+#include "private/bionic_vdso.h"
+#include "private/WriteProtected.h"
+
+struct libc_globals {
+  vdso_entry vdso[VDSO_END];
+  long setjmp_cookie;
+  MallocDispatch malloc_dispatch;
+};
+
+__LIBC_HIDDEN__ extern WriteProtected<libc_globals> __libc_globals;
+
+class KernelArgumentBlock;
+__LIBC_HIDDEN__ void __libc_init_global_stack_chk_guard(KernelArgumentBlock& args);
+__LIBC_HIDDEN__ void __libc_init_malloc(libc_globals* globals);
+__LIBC_HIDDEN__ void __libc_init_setjmp_cookie(libc_globals* globals, KernelArgumentBlock& args);
+__LIBC_HIDDEN__ void __libc_init_vdso(libc_globals* globals, KernelArgumentBlock& args);
+
+#if defined(__i386__)
+__LIBC_HIDDEN__ extern void* __libc_sysinfo;
+__LIBC_HIDDEN__ void __libc_init_sysinfo(KernelArgumentBlock& args);
+#endif
+
+#endif
diff --git a/libc/private/bionic_lock.h b/libc/private/bionic_lock.h
index 6a0fd06..3dbafe0 100644
--- a/libc/private/bionic_lock.h
+++ b/libc/private/bionic_lock.h
@@ -30,7 +30,10 @@
 
 #include <stdatomic.h>
 #include "private/bionic_futex.h"
+#include "private/bionic_macros.h"
 
+// Lock is used in places like pthread_rwlock_t, which can be initialized without calling
+// an initialization function. So make sure Lock can be initialized by setting its memory to 0.
 class Lock {
  private:
   enum LockState {
@@ -42,15 +45,17 @@
   bool process_shared;
 
  public:
-  Lock(bool process_shared = false) {
-    init(process_shared);
-  }
-
   void init(bool process_shared) {
     atomic_init(&state, Unlocked);
     this->process_shared = process_shared;
   }
 
+  bool trylock() {
+    LockState old_state = Unlocked;
+    return __predict_true(atomic_compare_exchange_strong_explicit(&state, &old_state,
+                        LockedWithoutWaiter, memory_order_acquire, memory_order_relaxed));
+  }
+
   void lock() {
     LockState old_state = Unlocked;
     if (__predict_true(atomic_compare_exchange_strong_explicit(&state, &old_state,
@@ -59,7 +64,7 @@
     }
     while (atomic_exchange_explicit(&state, LockedWithWaiter, memory_order_acquire) != Unlocked) {
       // TODO: As the critical section is brief, it is a better choice to spin a few times befor sleeping.
-      __futex_wait_ex(&state, process_shared, LockedWithWaiter, NULL);
+      __futex_wait_ex(&state, process_shared, LockedWithWaiter, false, nullptr);
     }
     return;
   }
diff --git a/libc/private/bionic_macros.h b/libc/private/bionic_macros.h
index 4f3cf89..4969bd9 100644
--- a/libc/private/bionic_macros.h
+++ b/libc/private/bionic_macros.h
@@ -42,8 +42,8 @@
   (((value) + (alignment) - 1) & ~((alignment) - 1))
 
 #define BIONIC_ROUND_UP_POWER_OF_2(value) \
-  (sizeof(value) == 8) \
+  ((sizeof(value) == 8) \
     ? (1UL << (64 - __builtin_clzl(static_cast<unsigned long>(value)))) \
-    : (1UL << (32 - __builtin_clz(static_cast<unsigned int>(value))))
+    : (1UL << (32 - __builtin_clz(static_cast<unsigned int>(value)))))
 
 #endif // _BIONIC_MACROS_H_
diff --git a/libc/private/bionic_malloc_dispatch.h b/libc/private/bionic_malloc_dispatch.h
new file mode 100644
index 0000000..02a092f
--- /dev/null
+++ b/libc/private/bionic_malloc_dispatch.h
@@ -0,0 +1,74 @@
+/*
+ * Copyright (C) 2015 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 _PRIVATE_BIONIC_MALLOC_DISPATCH_H
+#define _PRIVATE_BIONIC_MALLOC_DISPATCH_H
+
+#include <stddef.h>
+#include <stdint.h>
+#include <private/bionic_config.h>
+
+// Entry in malloc dispatch table.
+typedef void* (*MallocCalloc)(size_t, size_t);
+typedef void (*MallocFree)(void*);
+typedef struct mallinfo (*MallocMallinfo)();
+typedef void* (*MallocMalloc)(size_t);
+typedef size_t (*MallocMallocUsableSize)(const void*);
+typedef void* (*MallocMemalign)(size_t, size_t);
+typedef int (*MallocPosixMemalign)(void**, size_t, size_t);
+typedef void* (*MallocRealloc)(void*, size_t);
+typedef int (*MallocIterate)(uintptr_t, size_t, void (*)(uintptr_t, size_t, void*), void*);
+typedef void (*MallocMallocDisable)();
+typedef void (*MallocMallocEnable)();
+
+#if defined(HAVE_DEPRECATED_MALLOC_FUNCS)
+typedef void* (*MallocPvalloc)(size_t);
+typedef void* (*MallocValloc)(size_t);
+#endif
+
+struct MallocDispatch {
+  MallocCalloc calloc;
+  MallocFree free;
+  MallocMallinfo mallinfo;
+  MallocMalloc malloc;
+  MallocMallocUsableSize malloc_usable_size;
+  MallocMemalign memalign;
+  MallocPosixMemalign posix_memalign;
+#if defined(HAVE_DEPRECATED_MALLOC_FUNCS)
+  MallocPvalloc pvalloc;
+#endif
+  MallocRealloc realloc;
+#if defined(HAVE_DEPRECATED_MALLOC_FUNCS)
+  MallocValloc valloc;
+#endif
+  MallocIterate iterate;
+  MallocMallocDisable malloc_disable;
+  MallocMallocEnable malloc_enable;
+} __attribute__((aligned(32)));
+
+#endif
diff --git a/libc/private/bionic_page.h b/libc/private/bionic_page.h
new file mode 100644
index 0000000..0beb708
--- /dev/null
+++ b/libc/private/bionic_page.h
@@ -0,0 +1,33 @@
+/*
+ * Copyright (C) 2015 The Android Open Source Project
+ *
+ * Licensed under the Apache License, Version 2.0 (the "License");
+ * you may not use this file except in compliance with the License.
+ * You may obtain a copy of the License at
+ *
+ *      http://www.apache.org/licenses/LICENSE-2.0
+ *
+ * Unless required by applicable law or agreed to in writing, software
+ * distributed under the License is distributed on an "AS IS" BASIS,
+ * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
+ * See the License for the specific language governing permissions and
+ * limitations under the License.
+ */
+
+#ifndef _BIONIC_PAGE_H_
+#define _BIONIC_PAGE_H_
+
+// Get PAGE_SIZE and PAGE_MASK.
+#include <sys/user.h>
+
+// Returns the address of the page containing address 'x'.
+#define PAGE_START(x) ((x) & PAGE_MASK)
+
+// Returns the offset of address 'x' in its page.
+#define PAGE_OFFSET(x) ((x) & ~PAGE_MASK)
+
+// Returns the address of the next page after address 'x', unless 'x' is
+// itself at the start of a page.
+#define PAGE_END(x) PAGE_START((x) + (PAGE_SIZE-1))
+
+#endif // _BIONIC_PAGE_H_
diff --git a/libc/upstream-freebsd/android/include/spinlock.h b/libc/private/bionic_sdk_version.h
similarity index 71%
copy from libc/upstream-freebsd/android/include/spinlock.h
copy to libc/private/bionic_sdk_version.h
index f5c3785..871d25c 100644
--- a/libc/upstream-freebsd/android/include/spinlock.h
+++ b/libc/private/bionic_sdk_version.h
@@ -1,5 +1,5 @@
 /*
- * Copyright (C) 2013 The Android Open Source Project
+ * Copyright (C) 2016 The Android Open Source Project
  *
  * Licensed under the Apache License, Version 2.0 (the "License");
  * you may not use this file except in compliance with the License.
@@ -14,9 +14,11 @@
  * limitations under the License.
  */
 
-#ifndef _BIONIC_FREEBSD_SPINLOCK_H_included
-#define _BIONIC_FREEBSD_SPINLOCK_H_included
+#ifndef _BIONIC_SDK_VERSION_H_
+#define _BIONIC_SDK_VERSION_H_
 
-/* TODO: until we have the FreeBSD findfp.c, this is useless. */
+#include <stdint.h>
 
-#endif
+uint32_t bionic_get_application_target_sdk_version();
+
+#endif  // _BIONIC_SDK_VERSION_H_
diff --git a/libc/private/bionic_time_conversions.h b/libc/private/bionic_time_conversions.h
index cf0046a..a834843 100644
--- a/libc/private/bionic_time_conversions.h
+++ b/libc/private/bionic_time_conversions.h
@@ -29,9 +29,12 @@
 #ifndef _BIONIC_TIME_CONVERSIONS_H
 #define _BIONIC_TIME_CONVERSIONS_H
 
+#include <errno.h>
 #include <time.h>
 #include <sys/cdefs.h>
 
+#include "private/bionic_constants.h"
+
 __BEGIN_DECLS
 
 __LIBC_HIDDEN__ bool timespec_from_timeval(timespec& ts, const timeval& tv);
@@ -39,8 +42,24 @@
 
 __LIBC_HIDDEN__ void timeval_from_timespec(timeval& tv, const timespec& ts);
 
-__LIBC_HIDDEN__ bool timespec_from_absolute_timespec(timespec& ts, const timespec& abs_ts, clockid_t clock);
+__LIBC_HIDDEN__ void absolute_timespec_from_timespec(timespec& abs_ts, const timespec& ts,
+                                                     clockid_t clock);
 
 __END_DECLS
 
+static inline int check_timespec(const timespec* ts, bool null_allowed) {
+  if (null_allowed && ts == nullptr) {
+    return 0;
+  }
+  // glibc just segfaults if you pass a null timespec.
+  // That seems a lot more likely to catch bad code than returning EINVAL.
+  if (ts->tv_nsec < 0 || ts->tv_nsec >= NS_PER_S) {
+    return EINVAL;
+  }
+  if (ts->tv_sec < 0) {
+    return ETIMEDOUT;
+  }
+  return 0;
+}
+
 #endif
diff --git a/libc/private/bionic_tls.h b/libc/private/bionic_tls.h
index 30dc0eb..c61e2ff 100644
--- a/libc/private/bionic_tls.h
+++ b/libc/private/bionic_tls.h
@@ -30,7 +30,7 @@
 #define __BIONIC_PRIVATE_BIONIC_TLS_H_
 
 #include <sys/cdefs.h>
-#include <sys/limits.h>
+
 #include "bionic_macros.h"
 #include "__get_tls.h"
 
@@ -67,6 +67,13 @@
   TLS_SLOT_STACK_GUARD = 5, // GCC requires this specific slot for x86.
   TLS_SLOT_DLERROR,
 
+  // Fast storage for Thread::Current() in ART.
+  TLS_SLOT_ART_THREAD_SELF,
+
+  // Lets TSAN avoid using pthread_getspecific for finding the current thread
+  // state.
+  TLS_SLOT_TSAN,
+
   BIONIC_TLS_SLOTS // Must come last!
 };
 
@@ -96,13 +103,9 @@
 
 #define LIBC_PTHREAD_KEY_RESERVED_COUNT 12
 
-#if defined(USE_JEMALLOC)
 /* Internally, jemalloc uses a single key for per thread data. */
 #define JEMALLOC_PTHREAD_KEY_RESERVED_COUNT 1
 #define BIONIC_PTHREAD_KEY_RESERVED_COUNT (LIBC_PTHREAD_KEY_RESERVED_COUNT + JEMALLOC_PTHREAD_KEY_RESERVED_COUNT)
-#else
-#define BIONIC_PTHREAD_KEY_RESERVED_COUNT LIBC_PTHREAD_KEY_RESERVED_COUNT
-#endif
 
 /*
  * Maximum number of pthread keys allocated.
@@ -114,7 +117,7 @@
 
 #if defined(__cplusplus)
 class KernelArgumentBlock;
-extern __LIBC_HIDDEN__ void __libc_init_tls(KernelArgumentBlock& args);
+extern void __libc_init_main_thread(KernelArgumentBlock&);
 #endif
 
 #endif /* __BIONIC_PRIVATE_BIONIC_TLS_H_ */
diff --git a/libc/private/bionic_time.h b/libc/private/bionic_vdso.h
similarity index 66%
copy from libc/private/bionic_time.h
copy to libc/private/bionic_vdso.h
index 030dcfd..5400de5 100644
--- a/libc/private/bionic_time.h
+++ b/libc/private/bionic_vdso.h
@@ -1,5 +1,5 @@
 /*
- * Copyright (C) 2011 The Android Open Source Project
+ * Copyright (C) 2015 The Android Open Source Project
  * All rights reserved.
  *
  * Redistribution and use in source and binary forms, with or without
@@ -25,17 +25,31 @@
  * OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF
  * SUCH DAMAGE.
  */
-#ifndef _BIONIC_TIME_H
-#define _BIONIC_TIME_H
+#ifndef _PRIVATE_BIONIC_VDSO_H
+#define _PRIVATE_BIONIC_VDSO_H
 
 #include <time.h>
-#include <sys/cdefs.h>
 
-__BEGIN_DECLS
+#if defined(__aarch64__)
+#define VDSO_CLOCK_GETTIME_SYMBOL "__kernel_clock_gettime"
+#define VDSO_GETTIMEOFDAY_SYMBOL  "__kernel_gettimeofday"
+#elif defined(__x86_64__) || defined(__i386__)
+#define VDSO_CLOCK_GETTIME_SYMBOL "__vdso_clock_gettime"
+#define VDSO_GETTIMEOFDAY_SYMBOL  "__vdso_gettimeofday"
+#endif
 
-// We can't remove this (and this file) until we fix MtpUtils.cpp.
-time_t mktime_tz(struct tm* const, char const*);
+extern "C" int __clock_gettime(int, timespec*);
+extern "C" int __gettimeofday(timeval*, struct timezone*);
 
-__END_DECLS
+struct vdso_entry {
+  const char* name;
+  void* fn;
+};
 
-#endif /* _BIONIC_TIME_H */
+enum {
+  VDSO_CLOCK_GETTIME = 0,
+  VDSO_GETTIMEOFDAY,
+  VDSO_END
+};
+
+#endif  // _PRIVATE_BIONIC_VDSO_H
diff --git a/libc/include/sys/shm.h b/libc/private/get_cpu_count_from_string.h
similarity index 69%
copy from libc/include/sys/shm.h
copy to libc/private/get_cpu_count_from_string.h
index c691c29..a0cb95d 100644
--- a/libc/include/sys/shm.h
+++ b/libc/private/get_cpu_count_from_string.h
@@ -1,5 +1,5 @@
 /*
- * Copyright (C) 2014 The Android Open Source Project
+ * Copyright (C) 2015 The Android Open Source Project
  * All rights reserved.
  *
  * Redistribution and use in source and binary forms, with or without
@@ -26,9 +26,28 @@
  * SUCH DAMAGE.
  */
 
-#ifndef _SYS_SHM_H_
-#define _SYS_SHM_H_
+#include <ctype.h>
+#include <stdlib.h>
 
-#include <linux/shm.h>
-
-#endif /* _SYS_SHM_H_ */
+// Parse a string like: 0, 2-4, 6.
+static int GetCpuCountFromString(const char* s) {
+  int cpu_count = 0;
+  int last_cpu = -1;
+  while (*s != '\0') {
+    if (isdigit(*s)) {
+      int cpu = static_cast<int>(strtol(s, const_cast<char**>(&s), 10));
+      if (last_cpu != -1) {
+        cpu_count += cpu - last_cpu;
+      } else {
+        cpu_count++;
+      }
+      last_cpu = cpu;
+    } else {
+      if (*s == ',') {
+        last_cpu = -1;
+      }
+      s++;
+    }
+  }
+  return cpu_count;
+}
diff --git a/libc/private/libc_logging.h b/libc/private/libc_logging.h
index da2192b..e389565 100644
--- a/libc/private/libc_logging.h
+++ b/libc/private/libc_logging.h
@@ -101,6 +101,8 @@
 __LIBC_HIDDEN__ int __libc_format_log_va_list(int priority, const char* tag, const char* format,
                                               va_list ap);
 
+__LIBC_HIDDEN__ int __libc_write_log(int priority, const char* tag, const char* msg);
+
 //
 // Event logging.
 //
diff --git a/libc/stdio/fileext.h b/libc/stdio/fileext.h
deleted file mode 100644
index 6cacc0f..0000000
--- a/libc/stdio/fileext.h
+++ /dev/null
@@ -1,80 +0,0 @@
-/*	$OpenBSD: fileext.h,v 1.2 2005/06/17 20:40:32 espie Exp $	*/
-/* $NetBSD: fileext.h,v 1.5 2003/07/18 21:46:41 nathanw Exp $ */
-
-/*-
- * Copyright (c)2001 Citrus 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:
- * 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.
- *
- * $Citrus$
- */
-
-#ifndef _FILEEXT_H_
-#define _FILEEXT_H_
-
-#include <pthread.h>
-#include <stdbool.h>
-
-__BEGIN_DECLS
-
-/*
- * file extension
- */
-struct __sfileext {
-	struct	__sbuf _ub;		/* ungetc buffer */
-	struct wchar_io_data _wcio;	/* wide char io status */
-	pthread_mutex_t _lock;		/* file lock */
-	bool _stdio_handles_locking;	/* __fsetlocking support */
-};
-
-#if defined(__cplusplus)
-#define _EXT(fp) reinterpret_cast<__sfileext*>((fp)->_ext._base)
-#else
-#define _EXT(fp) ((struct __sfileext *)((fp)->_ext._base))
-#endif
-
-#define _UB(fp) _EXT(fp)->_ub
-#define _FLOCK(fp)  _EXT(fp)->_lock
-
-#define _FILEEXT_INIT(fp) \
-do { \
-	_UB(fp)._base = NULL; \
-	_UB(fp)._size = 0; \
-	WCIO_INIT(fp); \
-	pthread_mutexattr_t attr; \
-	pthread_mutexattr_init(&attr); \
-	pthread_mutexattr_settype(&attr, PTHREAD_MUTEX_RECURSIVE); \
-	pthread_mutex_init(&_FLOCK(fp), &attr); \
-	pthread_mutexattr_destroy(&attr); \
-	_EXT(fp)->_stdio_handles_locking = true; \
-} while (0)
-
-#define _FILEEXT_SETUP(f, fext) \
-do { \
-	(f)->_ext._base = (unsigned char *)(fext); \
-	_FILEEXT_INIT(f); \
-} while (0)
-
-__END_DECLS
-
-#endif /* _FILEEXT_H_ */
diff --git a/libc/stdio/findfp.c b/libc/stdio/findfp.c
deleted file mode 100644
index 5e51198..0000000
--- a/libc/stdio/findfp.c
+++ /dev/null
@@ -1,191 +0,0 @@
-/*	$OpenBSD: findfp.c,v 1.15 2013/12/17 16:33:27 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 <sys/param.h>
-#include <unistd.h>
-#include <stdio.h>
-#include <errno.h>
-#include <stdlib.h>
-#include <string.h>
-#include "local.h"
-#include "glue.h"
-#include "private/thread_private.h"
-
-#define ALIGNBYTES (sizeof(uintptr_t) - 1)
-#define ALIGN(p) (((uintptr_t)(p) + ALIGNBYTES) &~ ALIGNBYTES)
-
-int	__sdidinit;
-
-#define	NDYNAMIC 10		/* add ten more whenever necessary */
-
-#define	std(flags, file) \
-	{0,0,0,flags,file,{0,0},0,__sF+file,__sclose,__sread,__sseek,__swrite, \
-	    {(unsigned char *)(__sFext+file), 0},NULL,0,{0},{0},{0,0},0,0}
-
-				/* the usual - (stdin + stdout + stderr) */
-static FILE usual[FOPEN_MAX - 3];
-static struct __sfileext usualext[FOPEN_MAX - 3];
-static struct glue uglue = { 0, FOPEN_MAX - 3, usual };
-static struct glue *lastglue = &uglue;
-_THREAD_PRIVATE_MUTEX(__sfp_mutex);
-
-static struct __sfileext __sFext[3];
-FILE __sF[3] = {
-	std(__SRD, STDIN_FILENO),		/* stdin */
-	std(__SWR, STDOUT_FILENO),		/* stdout */
-	std(__SWR|__SNBF, STDERR_FILENO)	/* stderr */
-};
-FILE* stdin = &__sF[0];
-FILE* stdout = &__sF[1];
-FILE* stderr = &__sF[2];
-struct glue __sglue = { &uglue, 3, __sF };
-
-static struct glue *
-moreglue(int n)
-{
-	struct glue *g;
-	FILE *p;
-	struct __sfileext *pext;
-	static FILE empty;
-	char *data;
-
-	data = malloc(sizeof(*g) + ALIGNBYTES + n * sizeof(FILE)
-	    + n * sizeof(struct __sfileext));
-	if (data == NULL)
-		return (NULL);
-	g = (struct glue *)data;
-	p = (FILE *)ALIGN(data + sizeof(*g));
-	pext = (struct __sfileext *)
-	    (ALIGN(data + sizeof(*g)) + n * sizeof(FILE));
-	g->next = NULL;
-	g->niobs = n;
-	g->iobs = p;
-	while (--n >= 0) {
-		*p = empty;
-		_FILEEXT_SETUP(p, pext);
-		p++;
-		pext++;
-	}
-	return (g);
-}
-
-/*
- * Find a free FILE for fopen et al.
- */
-FILE *
-__sfp(void)
-{
-	FILE *fp;
-	int n;
-	struct glue *g;
-
-	if (!__sdidinit)
-		__sinit();
-
-	_THREAD_PRIVATE_MUTEX_LOCK(__sfp_mutex);
-	for (g = &__sglue; g != NULL; g = g->next) {
-		for (fp = g->iobs, n = g->niobs; --n >= 0; fp++)
-			if (fp->_flags == 0)
-				goto found;
-	}
-
-	/* release lock while mallocing */
-	_THREAD_PRIVATE_MUTEX_UNLOCK(__sfp_mutex);
-	if ((g = moreglue(NDYNAMIC)) == NULL)
-		return (NULL);
-	_THREAD_PRIVATE_MUTEX_LOCK(__sfp_mutex);
-	lastglue->next = g;
-	lastglue = g;
-	fp = g->iobs;
-found:
-	fp->_flags = 1;		/* reserve this slot; caller sets real flags */
-	_THREAD_PRIVATE_MUTEX_UNLOCK(__sfp_mutex);
-	fp->_p = NULL;		/* no current pointer */
-	fp->_w = 0;		/* nothing to read or write */
-	fp->_r = 0;
-	fp->_bf._base = NULL;	/* no buffer */
-	fp->_bf._size = 0;
-	fp->_lbfsize = 0;	/* not line buffered */
-	fp->_file = -1;		/* no file */
-/*	fp->_cookie = <any>; */	/* caller sets cookie, _read/_write etc */
-	fp->_lb._base = NULL;	/* no line buffer */
-	fp->_lb._size = 0;
-	_FILEEXT_INIT(fp);
-	return (fp);
-}
-
-/*
- * exit() and abort() call _cleanup() through the callback registered
- * with __atexit_register_cleanup(), set whenever we open or buffer a
- * file. This chicanery is done so that programs that do not use stdio
- * need not link it all in.
- *
- * The name `_cleanup' is, alas, fairly well known outside stdio.
- */
-void
-_cleanup(void)
-{
-	/* (void) _fwalk(fclose); */
-	(void) _fwalk(__sflush);		/* `cheating' */
-}
-
-/*
- * __sinit() is called whenever stdio's internal variables must be set up.
- */
-void
-__sinit(void)
-{
-	_THREAD_PRIVATE_MUTEX(__sinit_mutex);
-
-	_THREAD_PRIVATE_MUTEX_LOCK(__sinit_mutex);
-	if (__sdidinit) {
-		/* bail out if caller lost the race */
-		_THREAD_PRIVATE_MUTEX_UNLOCK(__sinit_mutex);
-		return;
-	}
-
-	/* Initialize stdin/stdout/stderr (for the recursive mutex). http://b/18208568. */
-	for (size_t i = 0; i < 3; ++i) {
-		_FILEEXT_SETUP(__sF+i, __sFext+i);
-	}
-	/* Initialize the pre-allocated (but initially unused) streams. */
-	for (size_t i = 0; i < FOPEN_MAX - 3; ++i) {
-		_FILEEXT_SETUP(usual+i, usualext+i);
-	}
-
-	/* make sure we clean up on exit */
-	__atexit_register_cleanup(_cleanup); /* conservative */
-	__sdidinit = 1;
-
-	_THREAD_PRIVATE_MUTEX_UNLOCK(__sinit_mutex);
-}
diff --git a/libc/stdio/glue.h b/libc/stdio/glue.h
index a9e5d10..cb1d182 100644
--- a/libc/stdio/glue.h
+++ b/libc/stdio/glue.h
@@ -47,6 +47,6 @@
 };
 
 /* This was referenced by a couple of different pieces of middleware and the Crystax NDK. */
-__LIBC64_HIDDEN__ extern struct glue __sglue;
+__LIBC32_LEGACY_PUBLIC__ extern struct glue __sglue;
 
 __END_DECLS
diff --git a/libc/stdio/local.h b/libc/stdio/local.h
index ce04141..7fe339a 100644
--- a/libc/stdio/local.h
+++ b/libc/stdio/local.h
@@ -32,48 +32,178 @@
  * SUCH DAMAGE.
  */
 
+#ifndef __BIONIC_STDIO_LOCAL_H__
+#define __BIONIC_STDIO_LOCAL_H__
+
+#include <pthread.h>
+#include <stdbool.h>
+#include <wchar.h>
+#include "wcio.h"
+
 /*
  * Information local to this implementation of stdio,
  * in particular, macros and private variables.
  */
 
-#include <wchar.h>
-#include "wcio.h"
-#include "fileext.h"
-
 __BEGIN_DECLS
 
+struct __sbuf {
+  unsigned char* _base;
+#if defined(__LP64__)
+  size_t _size;
+#else
+  int _size;
+#endif
+};
+
+struct __sFILE {
+	unsigned char *_p;	/* current position in (some) buffer */
+	int	_r;		/* read space left for getc() */
+	int	_w;		/* write space left for putc() */
+#if defined(__LP64__)
+	int	_flags;		/* flags, below; this FILE is free if 0 */
+	int	_file;		/* fileno, if Unix descriptor, else -1 */
+#else
+	short	_flags;		/* flags, below; this FILE is free if 0 */
+	short	_file;		/* fileno, if Unix descriptor, else -1 */
+#endif
+	struct	__sbuf _bf;	/* the buffer (at least 1 byte, if !NULL) */
+	int	_lbfsize;	/* 0 or -_bf._size, for inline putc */
+
+	// Function pointers used by `funopen`.
+	// Note that `_seek` is ignored if `_seek64` (in __sfileext) is set.
+	// TODO: NetBSD has `funopen2` which corrects the `int`s to `size_t`s.
+	// TODO: glibc has `fopencookie` which passes the function pointers in a struct.
+	void* _cookie;	/* cookie passed to io functions */
+	int (*_close)(void*);
+	int (*_read)(void*, char*, int);
+	fpos_t (*_seek)(void*, fpos_t, int);
+	int (*_write)(void*, const char*, int);
+
+	/* extension data, to avoid further ABI breakage */
+	struct	__sbuf _ext;
+	/* data for long sequences of ungetc() */
+	unsigned char *_up;	/* saved _p when _p is doing ungetc data */
+	int	_ur;		/* saved _r when _r is counting ungetc data */
+
+	/* tricks to meet minimum requirements even when malloc() fails */
+	unsigned char _ubuf[3];	/* guarantee an ungetc() buffer */
+	unsigned char _nbuf[1];	/* guarantee a getc() buffer */
+
+	/* separate buffer for fgetln() when line crosses buffer boundary */
+	struct	__sbuf _lb;	/* buffer for fgetln() */
+
+	/* Unix stdio files get aligned to block boundaries on fseek() */
+	int	_blksize;	/* stat.st_blksize (may be != _bf._size) */
+
+	fpos_t _unused_0; // This was the `_offset` field (see below).
+
+	// Do not add new fields here. (Or remove or change the size of any above.)
+	// Although bionic currently exports `stdin`, `stdout`, and `stderr` symbols,
+	// that still hasn't made it to the NDK. All NDK-built apps index directly
+	// into an array of this struct (which was in <stdio.h> historically), so if
+	// you need to make any changes, they need to be in the `__sfileext` struct
+	// below, and accessed via `_EXT`.
+};
+
+struct __sfileext {
+  // ungetc buffer.
+  struct __sbuf _ub;
+
+  // Wide char io status.
+  struct wchar_io_data _wcio;
+
+  // File lock.
+  pthread_mutex_t _lock;
+
+  // __fsetlocking support.
+  bool _caller_handles_locking;
+
+  // Equivalent to `_seek` but for _FILE_OFFSET_BITS=64.
+  // Callers should use this but fall back to `__sFILE::_seek`.
+  off64_t (*_seek64)(void*, off64_t, int);
+};
+
+// Values for `__sFILE::_flags`.
+#define __SLBF 0x0001  // Line buffered.
+#define __SNBF 0x0002  // Unbuffered.
+// RD and WR are never simultaneously asserted: use _SRW instead.
+#define __SRD  0x0004  // OK to read.
+#define __SWR  0x0008  // OK to write.
+#define __SRW  0x0010  // Open for reading & writing.
+#define __SEOF 0x0020  // Found EOF.
+#define __SERR 0x0040  // Found error.
+#define __SMBF 0x0080  // `_buf` is from malloc.
+#define __SAPP 0x0100  // fdopen()ed in append mode.
+#define __SSTR 0x0200  // This is an sprintf/snprintf string.
+// #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 __SALC 0x4000  // Allocate string space dynamically.
+#define __SIGN 0x8000  // Ignore this file in _fwalk.
+
+// TODO: remove remaining references to these obsolete flags.
+#define __SNPT 0
+#define __SOPT 0
+
+#if defined(__cplusplus)
+#define _EXT(fp) reinterpret_cast<__sfileext*>((fp)->_ext._base)
+#else
+#define _EXT(fp) ((struct __sfileext *)((fp)->_ext._base))
+#endif
+
+#define _UB(fp) _EXT(fp)->_ub
+#define _FLOCK(fp)  _EXT(fp)->_lock
+
+#define _FILEEXT_INIT(fp) \
+do { \
+	_UB(fp)._base = NULL; \
+	_UB(fp)._size = 0; \
+	WCIO_INIT(fp); \
+	pthread_mutexattr_t attr; \
+	pthread_mutexattr_init(&attr); \
+	pthread_mutexattr_settype(&attr, PTHREAD_MUTEX_RECURSIVE); \
+	pthread_mutex_init(&_FLOCK(fp), &attr); \
+	pthread_mutexattr_destroy(&attr); \
+	_EXT(fp)->_caller_handles_locking = false; \
+} while (0)
+
+#define _FILEEXT_SETUP(f, fext) \
+do { \
+	(f)->_ext._base = (unsigned char *)(fext); \
+	_FILEEXT_INIT(f); \
+} while (0)
+
 /*
  * Android <= KitKat had getc/putc macros in <stdio.h> that referred
  * to __srget/__swbuf, so those symbols need to be public for LP32
  * but can be hidden for LP64.
  */
-__LIBC64_HIDDEN__ int __srget(FILE*);
-__LIBC64_HIDDEN__ int __swbuf(int, FILE*);
-__LIBC64_HIDDEN__ int __srefill(FILE*);
+__LIBC32_LEGACY_PUBLIC__ int __srget(FILE*);
+__LIBC32_LEGACY_PUBLIC__ int __swbuf(int, FILE*);
+__LIBC32_LEGACY_PUBLIC__ int __srefill(FILE*);
 
 /* This was referenced by the apportable middleware for LP32. */
-__LIBC64_HIDDEN__ int __swsetup(FILE*);
+__LIBC32_LEGACY_PUBLIC__ int __swsetup(FILE*);
 
 /* These were referenced by a couple of different pieces of middleware and the Crystax NDK. */
-__LIBC64_HIDDEN__ extern int __sdidinit;
-__LIBC64_HIDDEN__ int __sflags(const char*, int*);
-__LIBC64_HIDDEN__ FILE* __sfp(void);
-__LIBC64_HIDDEN__ void __sinit(void);
-__LIBC64_HIDDEN__ void __smakebuf(FILE*);
+__LIBC32_LEGACY_PUBLIC__ int __sflags(const char*, int*);
+__LIBC32_LEGACY_PUBLIC__ FILE* __sfp(void);
+__LIBC32_LEGACY_PUBLIC__ void __smakebuf(FILE*);
 
 /* These are referenced by the Greed for Glory franchise. */
-__LIBC64_HIDDEN__ int __sflush(FILE *);
-__LIBC64_HIDDEN__ int __sread(void *, char *, int);
-__LIBC64_HIDDEN__ int __swrite(void *, const char *, int);
-__LIBC64_HIDDEN__ fpos_t __sseek(void *, fpos_t, int);
-__LIBC64_HIDDEN__ int __sclose(void *);
-__LIBC64_HIDDEN__ int _fwalk(int (*)(FILE *));
+__LIBC32_LEGACY_PUBLIC__ int __sflush(FILE *);
+__LIBC32_LEGACY_PUBLIC__ int __sread(void *, char *, int);
+__LIBC32_LEGACY_PUBLIC__ int __swrite(void *, const char *, int);
+__LIBC32_LEGACY_PUBLIC__ fpos_t __sseek(void *, fpos_t, int);
+__LIBC32_LEGACY_PUBLIC__ int __sclose(void *);
+__LIBC32_LEGACY_PUBLIC__ int _fwalk(int (*)(FILE *));
 
 #pragma GCC visibility push(hidden)
 
+off64_t __sseek64(void*, off64_t, int);
 int	__sflush_locked(FILE *);
-void	_cleanup(void);
 int	__swhatbuf(FILE *, size_t *, int *);
 wint_t __fgetwc_unlock(FILE *);
 wint_t	__ungetwc(wint_t, FILE *);
@@ -82,8 +212,6 @@
 int	__vfwprintf(FILE * __restrict, const wchar_t * __restrict, __va_list);
 int	__vfwscanf(FILE * __restrict, const wchar_t * __restrict, __va_list);
 
-extern void __atexit_register_cleanup(void (*)(void));
-
 /*
  * Return true if the given FILE cannot be written now.
  */
@@ -111,8 +239,8 @@
 	(fp)->_lb._base = NULL; \
 }
 
-#define FLOCKFILE(fp)   if (_EXT(fp)->_stdio_handles_locking) flockfile(fp)
-#define FUNLOCKFILE(fp) if (_EXT(fp)->_stdio_handles_locking) funlockfile(fp)
+#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
@@ -123,7 +251,6 @@
 #define __sfeof(p)     (((p)->_flags & __SEOF) != 0)
 #define __sferror(p)   (((p)->_flags & __SERR) != 0)
 #define __sclearerr(p) ((void)((p)->_flags &= ~(__SERR|__SEOF)))
-#define __sfileno(p)   ((p)->_file)
 #if !defined(__cplusplus)
 #define __sgetc(p) (--(p)->_r < 0 ? __srget(p) : (int)(*(p)->_p++))
 static __inline int __sputc(int _c, FILE* _p) {
@@ -140,6 +267,12 @@
 extern 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.
+#define __sdidinit 1
+
 #pragma GCC visibility pop
 
 __END_DECLS
+
+#endif
diff --git a/libc/upstream-openbsd/lib/libc/stdio/refill.c b/libc/stdio/refill.c
similarity index 97%
rename from libc/upstream-openbsd/lib/libc/stdio/refill.c
rename to libc/stdio/refill.c
index 165c72a..5b0811f 100644
--- a/libc/upstream-openbsd/lib/libc/stdio/refill.c
+++ b/libc/stdio/refill.c
@@ -51,16 +51,13 @@
 int
 __srefill(FILE *fp)
 {
-
-	/* make sure stdio is set up */
-	if (!__sdidinit)
-		__sinit();
-
 	fp->_r = 0;		/* largely a convenience for callers */
 
+#if !defined(__ANDROID__)
 	/* SysV does not make this test; take it out for compatibility */
 	if (fp->_flags & __SEOF)
 		return (EOF);
+#endif
 
 	/* if not already reading, have to be reading and writing */
 	if ((fp->_flags & __SRD) == 0) {
diff --git a/libc/stdio/stdio.c b/libc/stdio/stdio.c
deleted file mode 100644
index fc2115e..0000000
--- a/libc/stdio/stdio.c
+++ /dev/null
@@ -1,90 +0,0 @@
-/*	$OpenBSD: stdio.c,v 1.9 2005/08/08 08:05:36 espie 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 <fcntl.h>
-#include <unistd.h>
-#include <stdio.h>
-#include "local.h"
-
-/*
- * Small standard I/O/seek/close functions.
- * These maintain the `known seek offset' for seek optimisation.
- */
-int
-__sread(void *cookie, char *buf, int n)
-{
-	FILE *fp = cookie;
-	int ret;
-	
-	ret = TEMP_FAILURE_RETRY(read(fp->_file, buf, n));
-	/* if the read succeeded, update the current offset */
-	if (ret >= 0)
-		fp->_offset += ret;
-	else
-		fp->_flags &= ~__SOFF;	/* paranoia */
-	return (ret);
-}
-
-int
-__swrite(void *cookie, const char *buf, int n)
-{
-	FILE *fp = cookie;
-
-	if (fp->_flags & __SAPP)
-		(void) TEMP_FAILURE_RETRY(lseek(fp->_file, (off_t)0, SEEK_END));
-	fp->_flags &= ~__SOFF;	/* in case FAPPEND mode is set */
-	return TEMP_FAILURE_RETRY(write(fp->_file, buf, n));
-}
-
-fpos_t
-__sseek(void *cookie, fpos_t offset, int whence)
-{
-	FILE *fp = cookie;
-	off_t ret;
-	
-	ret = TEMP_FAILURE_RETRY(lseek(fp->_file, (off_t)offset, whence));
-	if (ret == (off_t)-1)
-		fp->_flags &= ~__SOFF;
-	else {
-		fp->_flags |= __SOFF;
-		fp->_offset = ret;
-	}
-	return (ret);
-}
-
-int
-__sclose(void *cookie)
-{
-	return close(((FILE *)cookie)->_file);
-}
diff --git a/libc/stdio/stdio.cpp b/libc/stdio/stdio.cpp
new file mode 100644
index 0000000..1c31a27
--- /dev/null
+++ b/libc/stdio/stdio.cpp
@@ -0,0 +1,600 @@
+/*	$OpenBSD: findfp.c,v 1.15 2013/12/17 16:33:27 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 <errno.h>
+#include <fcntl.h>
+#include <limits.h>
+#include <stdlib.h>
+#include <string.h>
+#include <sys/param.h>
+#include <sys/stat.h>
+#include <unistd.h>
+
+#include "local.h"
+#include "glue.h"
+#include "private/ErrnoRestorer.h"
+#include "private/thread_private.h"
+
+#define ALIGNBYTES (sizeof(uintptr_t) - 1)
+#define ALIGN(p) (((uintptr_t)(p) + ALIGNBYTES) &~ ALIGNBYTES)
+
+#define	NDYNAMIC 10		/* add ten more whenever necessary */
+
+#define std(flags, file) \
+    {0,0,0,flags,file,{0,0},0,__sF+file,__sclose,__sread,nullptr,__swrite, \
+    {(unsigned char *)(__sFext+file), 0},nullptr,0,{0},{0},{0,0},0,0}
+
+_THREAD_PRIVATE_MUTEX(__sfp_mutex);
+
+// TODO: when we no longer have to support both clang and GCC, we can simplify all this.
+#define SBUF_INIT {0,0}
+#if defined(__LP64__)
+#define MBSTATE_T_INIT {{0},{0}}
+#else
+#define MBSTATE_T_INIT {{0}}
+#endif
+#define WCHAR_IO_DATA_INIT {MBSTATE_T_INIT,MBSTATE_T_INIT,{0},0,0}
+
+static struct __sfileext __sFext[3] = {
+  { SBUF_INIT, WCHAR_IO_DATA_INIT, PTHREAD_RECURSIVE_MUTEX_INITIALIZER_NP, false, __sseek64 },
+  { SBUF_INIT, WCHAR_IO_DATA_INIT, PTHREAD_RECURSIVE_MUTEX_INITIALIZER_NP, false, __sseek64 },
+  { SBUF_INIT, WCHAR_IO_DATA_INIT, PTHREAD_RECURSIVE_MUTEX_INITIALIZER_NP, false, __sseek64 },
+};
+
+// __sF is exported for backwards compatibility. Until M, we didn't have symbols
+// for stdin/stdout/stderr; they were macros accessing __sF.
+FILE __sF[3] = {
+  std(__SRD, STDIN_FILENO),
+  std(__SWR, STDOUT_FILENO),
+  std(__SWR|__SNBF, STDERR_FILENO),
+};
+
+FILE* stdin = &__sF[0];
+FILE* stdout = &__sF[1];
+FILE* stderr = &__sF[2];
+
+struct glue __sglue = { NULL, 3, __sF };
+static struct glue* lastglue = &__sglue;
+
+class ScopedFileLock {
+ public:
+  ScopedFileLock(FILE* fp) : fp_(fp) {
+    FLOCKFILE(fp_);
+  }
+  ~ScopedFileLock() {
+    FUNLOCKFILE(fp_);
+  }
+
+ private:
+  FILE* fp_;
+};
+
+static glue* moreglue(int n) {
+  static FILE empty;
+
+  char* data = new char[sizeof(glue) + ALIGNBYTES + n * sizeof(FILE) + n * sizeof(__sfileext)];
+  if (data == nullptr) return nullptr;
+
+  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->niobs = n;
+  g->iobs = p;
+  while (--n >= 0) {
+    *p = empty;
+    _FILEEXT_SETUP(p, pext);
+    p++;
+    pext++;
+  }
+  return g;
+}
+
+/*
+ * Find a free FILE for fopen et al.
+ */
+FILE* __sfp(void) {
+	FILE *fp;
+	int n;
+	struct glue *g;
+
+	_THREAD_PRIVATE_MUTEX_LOCK(__sfp_mutex);
+	for (g = &__sglue; g != NULL; g = g->next) {
+		for (fp = g->iobs, n = g->niobs; --n >= 0; fp++)
+			if (fp->_flags == 0)
+				goto found;
+	}
+
+	/* release lock while mallocing */
+	_THREAD_PRIVATE_MUTEX_UNLOCK(__sfp_mutex);
+	if ((g = moreglue(NDYNAMIC)) == NULL)
+		return (NULL);
+	_THREAD_PRIVATE_MUTEX_LOCK(__sfp_mutex);
+	lastglue->next = g;
+	lastglue = g;
+	fp = g->iobs;
+found:
+	fp->_flags = 1;		/* reserve this slot; caller sets real flags */
+	_THREAD_PRIVATE_MUTEX_UNLOCK(__sfp_mutex);
+	fp->_p = NULL;		/* no current pointer */
+	fp->_w = 0;		/* nothing to read or write */
+	fp->_r = 0;
+	fp->_bf._base = NULL;	/* 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._size = 0;
+	_FILEEXT_INIT(fp);
+
+	// Caller sets cookie, _read/_write etc.
+	// We explicitly clear _seek and _seek64 to prevent subtle bugs.
+	fp->_seek = nullptr;
+	_EXT(fp)->_seek64 = nullptr;
+
+	return fp;
+}
+
+extern "C" __LIBC_HIDDEN__ void __libc_stdio_cleanup(void) {
+  // Equivalent to fflush(nullptr), but without all the locking since we're shutting down anyway.
+  _fwalk(__sflush);
+}
+
+static FILE* __fopen(int fd, int flags) {
+#if !defined(__LP64__)
+  if (fd > SHRT_MAX) {
+    errno = EMFILE;
+    return nullptr;
+  }
+#endif
+
+  FILE* fp = __sfp();
+  if (fp != nullptr) {
+    fp->_file = fd;
+    fp->_flags = flags;
+    fp->_cookie = fp;
+    fp->_read = __sread;
+    fp->_write = __swrite;
+    fp->_close = __sclose;
+    _EXT(fp)->_seek64 = __sseek64;
+  }
+  return fp;
+}
+
+FILE* fopen(const char* file, const char* mode) {
+  int oflags;
+  int flags = __sflags(mode, &oflags);
+  if (flags == 0) return nullptr;
+
+  int fd = open(file, oflags, DEFFILEMODE);
+  if (fd == -1) {
+    return nullptr;
+  }
+
+  FILE* fp = __fopen(fd, flags);
+  if (fp == nullptr) {
+    ErrnoRestorer errno_restorer;
+    close(fd);
+    return nullptr;
+  }
+
+  // When opening in append mode, even though we use O_APPEND,
+  // we need to seek to the end so that ftell() gets the right
+  // answer.  If the user then alters the seek pointer, or
+  // the file extends, this will fail, but there is not much
+  // we can do about this.  (We could set __SAPP and check in
+  // fseek and ftell.)
+  // TODO: check in __sseek instead.
+  if (oflags & O_APPEND) __sseek64(fp, 0, SEEK_END);
+
+  return fp;
+}
+__strong_alias(fopen64, fopen);
+
+FILE* fdopen(int fd, const char* mode) {
+  int oflags;
+  int flags = __sflags(mode, &oflags);
+  if (flags == 0) return nullptr;
+
+  // Make sure the mode the user wants is a subset of the actual mode.
+  int fdflags = fcntl(fd, F_GETFL, 0);
+  if (fdflags < 0) return nullptr;
+  int tmp = fdflags & O_ACCMODE;
+  if (tmp != O_RDWR && (tmp != (oflags & O_ACCMODE))) {
+    errno = EINVAL;
+    return nullptr;
+  }
+
+  // If opened for appending, but underlying descriptor does not have
+  // O_APPEND bit set, assert __SAPP so that __swrite() will lseek to
+  // end before each write.
+  // TODO: use fcntl(2) to set O_APPEND instead.
+  if ((oflags & O_APPEND) && !(fdflags & O_APPEND)) flags |= __SAPP;
+
+  // If close-on-exec was requested, then turn it on if not already.
+  if ((oflags & O_CLOEXEC) && !((tmp = fcntl(fd, F_GETFD)) & FD_CLOEXEC)) {
+    fcntl(fd, F_SETFD, tmp | FD_CLOEXEC);
+  }
+
+  return __fopen(fd, flags);
+}
+
+// Re-direct an existing, open (probably) file to some other file.
+// ANSI is written such that the original file gets closed if at
+// all possible, no matter what.
+// TODO: rewrite this mess completely.
+FILE* freopen(const char* file, const char* mode, FILE* fp) {
+  int oflags;
+  int flags = __sflags(mode, &oflags);
+  if (flags == 0) {
+    fclose(fp);
+    return nullptr;
+  }
+
+  ScopedFileLock sfl(fp);
+
+  // There are actually programs that depend on being able to "freopen"
+  // descriptors that weren't originally open.  Keep this from breaking.
+  // Remember whether the stream was open to begin with, and which file
+  // descriptor (if any) was associated with it.  If it was attached to
+  // a descriptor, defer closing it; freopen("/dev/stdin", "r", stdin)
+  // should work.  This is unnecessary if it was not a Unix file.
+  int isopen, wantfd;
+  if (fp->_flags == 0) {
+    fp->_flags = __SEOF; // Hold on to it.
+    isopen = 0;
+    wantfd = -1;
+  } else {
+    // 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 ((wantfd = fp->_file) < 0 && isopen) {
+        (*fp->_close)(fp->_cookie);
+        isopen = 0;
+    }
+  }
+
+  // Get a new descriptor to refer to the new file.
+  int fd = open(file, oflags, DEFFILEMODE);
+  if (fd < 0 && isopen) {
+    // If out of fd's close the old one and try again.
+    if (errno == ENFILE || errno == EMFILE) {
+      (*fp->_close)(fp->_cookie);
+      isopen = 0;
+      fd = open(file, oflags, DEFFILEMODE);
+    }
+  }
+
+  int sverrno = errno;
+
+  // Finish closing fp.  Even if the open succeeded above, we cannot
+  // keep fp->_base: it may be the wrong size.  This loses the effect
+  // of any setbuffer calls, but stdio has always done this before.
+  if (isopen && fd != wantfd) (*fp->_close)(fp->_cookie);
+  if (fp->_flags & __SMBF) free(fp->_bf._base);
+  fp->_w = 0;
+  fp->_r = 0;
+  fp->_p = NULL;
+  fp->_bf._base = NULL;
+  fp->_bf._size = 0;
+  fp->_lbfsize = 0;
+  if (HASUB(fp)) FREEUB(fp);
+  _UB(fp)._size = 0;
+  WCIO_FREE(fp);
+  if (HASLB(fp)) FREELB(fp);
+  fp->_lb._size = 0;
+
+  if (fd < 0) { // Did not get it after all.
+    fp->_flags = 0; // Release.
+    errno = sverrno; // Restore errno in case _close clobbered it.
+    return nullptr;
+  }
+
+  // If reopening something that was open before on a real file, try
+  // to maintain the descriptor.  Various C library routines (perror)
+  // assume stderr is always fd STDERR_FILENO, even if being freopen'd.
+  if (wantfd >= 0 && fd != wantfd) {
+    if (dup3(fd, wantfd, oflags & O_CLOEXEC) >= 0) {
+      close(fd);
+      fd = wantfd;
+    }
+  }
+
+  // _file is only a short.
+  if (fd > SHRT_MAX) {
+      fp->_flags = 0; // Release.
+      errno = EMFILE;
+      return nullptr;
+  }
+
+  fp->_flags = flags;
+  fp->_file = fd;
+  fp->_cookie = fp;
+  fp->_read = __sread;
+  fp->_write = __swrite;
+  fp->_close = __sclose;
+  _EXT(fp)->_seek64 = __sseek64;
+
+  // When opening in append mode, even though we use O_APPEND,
+  // we need to seek to the end so that ftell() gets the right
+  // answer.  If the user then alters the seek pointer, or
+  // the file extends, this will fail, but there is not much
+  // we can do about this.  (We could set __SAPP and check in
+  // fseek and ftell.)
+  if (oflags & O_APPEND) __sseek64(fp, 0, SEEK_END);
+  return fp;
+}
+__strong_alias(freopen64, freopen);
+
+int fclose(FILE* fp) {
+  if (fp->_flags == 0) {
+    // Already freed!
+    errno = EBADF;
+    return EOF;
+  }
+
+  ScopedFileLock sfl(fp);
+  WCIO_FREE(fp);
+  int r = fp->_flags & __SWR ? __sflush(fp) : 0;
+  if (fp->_close != NULL && (*fp->_close)(fp->_cookie) < 0) {
+    r = EOF;
+  }
+  if (fp->_flags & __SMBF) free(fp->_bf._base);
+  if (HASUB(fp)) FREEUB(fp);
+  if (HASLB(fp)) FREELB(fp);
+
+  // Poison this FILE so accesses after fclose will be obvious.
+  fp->_file = -1;
+  fp->_r = fp->_w = 0;
+
+  // Release this FILE for reuse.
+  fp->_flags = 0;
+  return r;
+}
+
+int fileno(FILE* fp) {
+  ScopedFileLock sfl(fp);
+  return fileno_unlocked(fp);
+}
+
+int __sread(void* cookie, char* buf, int n) {
+  FILE* fp = reinterpret_cast<FILE*>(cookie);
+  return TEMP_FAILURE_RETRY(read(fp->_file, buf, n));
+}
+
+int __swrite(void* cookie, const char* buf, int n) {
+  FILE* fp = reinterpret_cast<FILE*>(cookie);
+  if (fp->_flags & __SAPP) {
+    // The FILE* is in append mode, but the underlying fd doesn't have O_APPEND set.
+    // We need to seek manually.
+    // TODO: use fcntl(2) to set O_APPEND in fdopen(3) instead?
+    TEMP_FAILURE_RETRY(lseek64(fp->_file, 0, SEEK_END));
+  }
+  return TEMP_FAILURE_RETRY(write(fp->_file, buf, n));
+}
+
+fpos_t __sseek(void* cookie, fpos_t offset, int whence) {
+  FILE* fp = reinterpret_cast<FILE*>(cookie);
+  return TEMP_FAILURE_RETRY(lseek(fp->_file, offset, whence));
+}
+
+off64_t __sseek64(void* cookie, off64_t offset, int whence) {
+  FILE* fp = reinterpret_cast<FILE*>(cookie);
+  return TEMP_FAILURE_RETRY(lseek64(fp->_file, offset, whence));
+}
+
+int __sclose(void* cookie) {
+  FILE* fp = reinterpret_cast<FILE*>(cookie);
+  return close(fp->_file);
+}
+
+static off64_t __seek_unlocked(FILE* fp, off64_t offset, int whence) {
+  // Use `_seek64` if set, but fall back to `_seek`.
+  if (_EXT(fp)->_seek64 != nullptr) {
+    return (*_EXT(fp)->_seek64)(fp->_cookie, offset, whence);
+  } else if (fp->_seek != nullptr) {
+    off64_t result = (*fp->_seek)(fp->_cookie, offset, whence);
+#if !defined(__LP64__)
+    // Avoid sign extension if off64_t is larger than off_t.
+    if (result != -1) result &= 0xffffffff;
+#endif
+    return result;
+  } else {
+    errno = ESPIPE;
+    return -1;
+  }
+}
+
+static off64_t __ftello64_unlocked(FILE* fp) {
+  // Find offset of underlying I/O object, then adjust for buffered bytes.
+  __sflush(fp);  // May adjust seek offset on append stream.
+  off64_t result = __seek_unlocked(fp, 0, SEEK_CUR);
+  if (result == -1) {
+    return -1;
+  }
+
+  if (fp->_flags & __SRD) {
+    // Reading.  Any unread characters (including
+    // those from ungetc) cause the position to be
+    // smaller than that in the underlying object.
+    result -= fp->_r;
+    if (HASUB(fp)) result -= fp->_ur;
+  } else if (fp->_flags & __SWR && fp->_p != NULL) {
+    // Writing.  Any buffered characters cause the
+    // position to be greater than that in the
+    // underlying object.
+    result += fp->_p - fp->_bf._base;
+  }
+  return result;
+}
+
+int __fseeko64(FILE* fp, off64_t offset, int whence, int off_t_bits) {
+  ScopedFileLock sfl(fp);
+
+  // Change any SEEK_CUR to SEEK_SET, and check `whence` argument.
+  // After this, whence is either SEEK_SET or SEEK_END.
+  if (whence == SEEK_CUR) {
+    fpos64_t current_offset = __ftello64_unlocked(fp);
+    if (current_offset == -1) {
+      return -1;
+    }
+    offset += current_offset;
+    whence = SEEK_SET;
+  } else if (whence != SEEK_SET && whence != SEEK_END) {
+    errno = EINVAL;
+    return -1;
+  }
+
+  // If our caller has a 32-bit interface, refuse to go past a 32-bit file offset.
+  if (off_t_bits == 32 && offset > LONG_MAX) {
+    errno = EOVERFLOW;
+    return -1;
+  }
+
+  if (fp->_bf._base == NULL) __smakebuf(fp);
+
+  // Flush unwritten data and attempt the seek.
+  if (__sflush(fp) || __seek_unlocked(fp, offset, whence) == -1) {
+    return -1;
+  }
+
+  // Success: clear EOF indicator and discard ungetc() data.
+  if (HASUB(fp)) FREEUB(fp);
+  fp->_p = fp->_bf._base;
+  fp->_r = 0;
+  /* fp->_w = 0; */	/* unnecessary (I think...) */
+  fp->_flags &= ~__SEOF;
+  return 0;
+}
+
+int fseeko(FILE* fp, off_t offset, int whence) {
+  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));
+}
+
+int fsetpos(FILE* fp, const fpos_t* pos) {
+  return fseeko(fp, *pos, SEEK_SET);
+}
+
+int fsetpos64(FILE* fp, const fpos64_t* pos) {
+  return fseeko64(fp, *pos, SEEK_SET);
+}
+
+off_t ftello(FILE* fp) {
+  static_assert(sizeof(off_t) == sizeof(long), "sizeof(off_t) != sizeof(long)");
+  off64_t result = ftello64(fp);
+  if (result > LONG_MAX) {
+    errno = EOVERFLOW;
+    return -1;
+  }
+  return result;
+}
+__strong_alias(ftell, ftello);
+
+off64_t ftello64(FILE* fp) {
+  ScopedFileLock sfl(fp);
+  return __ftello64_unlocked(fp);
+}
+
+int fgetpos(FILE* fp, fpos_t* pos) {
+  *pos = ftello(fp);
+  return (*pos == -1) ? -1 : 0;
+}
+
+int fgetpos64(FILE* fp, fpos64_t* pos) {
+  *pos = ftello64(fp);
+  return (*pos == -1) ? -1 : 0;
+}
+
+static FILE* __funopen(const void* cookie,
+                       int (*read_fn)(void*, char*, int),
+                       int (*write_fn)(void*, const char*, int),
+                       int (*close_fn)(void*)) {
+  if (read_fn == nullptr && write_fn == nullptr) {
+    errno = EINVAL;
+    return nullptr;
+  }
+
+  FILE* fp = __sfp();
+  if (fp == nullptr) return nullptr;
+
+  if (read_fn != nullptr && write_fn != nullptr) {
+    fp->_flags = __SRW;
+  } else if (read_fn != nullptr) {
+    fp->_flags = __SRD;
+  } else if (write_fn != nullptr) {
+    fp->_flags = __SWR;
+  }
+
+  fp->_file = -1;
+  fp->_cookie = const_cast<void*>(cookie); // The funopen(3) API is incoherent.
+  fp->_read = read_fn;
+  fp->_write = write_fn;
+  fp->_close = close_fn;
+
+  return fp;
+}
+
+FILE* funopen(const void* cookie,
+              int (*read_fn)(void*, char*, int),
+              int (*write_fn)(void*, const char*, int),
+              fpos_t (*seek_fn)(void*, fpos_t, int),
+              int (*close_fn)(void*)) {
+  FILE* fp = __funopen(cookie, read_fn, write_fn, close_fn);
+  if (fp != nullptr) {
+    fp->_seek = seek_fn;
+  }
+  return fp;
+}
+
+FILE* funopen64(const void* cookie,
+                int (*read_fn)(void*, char*, int),
+                int (*write_fn)(void*, const char*, int),
+                fpos64_t (*seek_fn)(void*, fpos64_t, int),
+                int (*close_fn)(void*)) {
+  FILE* fp = __funopen(cookie, read_fn, write_fn, close_fn);
+  if (fp != nullptr) {
+    _EXT(fp)->_seek64 = seek_fn;
+  }
+  return fp;
+}
diff --git a/libc/stdio/stdio_ext.cpp b/libc/stdio/stdio_ext.cpp
index fea44f6..88e5951 100644
--- a/libc/stdio/stdio_ext.cpp
+++ b/libc/stdio/stdio_ext.cpp
@@ -27,6 +27,8 @@
  */
 
 #include <stdio_ext.h>
+
+#include <errno.h>
 #include <stdlib.h>
 
 #include "local.h"
@@ -74,7 +76,7 @@
 }
 
 int __fsetlocking(FILE* fp, int type) {
-  int old_state = _EXT(fp)->_stdio_handles_locking ? FSETLOCKING_INTERNAL : FSETLOCKING_BYCALLER;
+  int old_state = _EXT(fp)->_caller_handles_locking ? FSETLOCKING_BYCALLER : FSETLOCKING_INTERNAL;
   if (type == FSETLOCKING_QUERY) {
     return old_state;
   }
@@ -84,7 +86,7 @@
     __libc_fatal("Bad type (%d) passed to __fsetlocking", type);
   }
 
-  _EXT(fp)->_stdio_handles_locking = (type == FSETLOCKING_INTERNAL);
+  _EXT(fp)->_caller_handles_locking = (type == FSETLOCKING_BYCALLER);
   return old_state;
 }
 
@@ -99,3 +101,12 @@
 int ferror_unlocked(FILE* fp) {
   return __sferror(fp);
 }
+
+int fileno_unlocked(FILE* fp) {
+  int fd = fp->_file;
+  if (fd == -1) {
+    errno = EBADF;
+    return -1;
+  }
+  return fd;
+}
diff --git a/libc/stdlib/atexit.c b/libc/stdlib/atexit.c
index a6970dd..c817b63 100644
--- a/libc/stdlib/atexit.c
+++ b/libc/stdlib/atexit.c
@@ -37,6 +37,10 @@
 #include "atexit.h"
 #include "private/thread_private.h"
 
+/* BEGIN android-changed */
+#include "private/bionic_prctl.h"
+/* END android-changed */
+
 struct atexit {
 	struct atexit *next;		/* next in list */
 	int ind;			/* next index in this table */
@@ -95,6 +99,10 @@
 		    MAP_ANON | MAP_PRIVATE, -1, 0);
 		if (p == MAP_FAILED)
 			goto unlock;
+/* BEGIN android-changed */
+		prctl(PR_SET_VMA, PR_SET_VMA_ANON_NAME, p, pgsize,
+		    "atexit handlers");
+/* END android-changed */
 		if (__atexit == NULL) {
 			memset(&p->fns[0], 0, sizeof(p->fns[0]));
 			p->ind = 1;
@@ -177,47 +185,12 @@
 	}
 	_ATEXIT_UNLOCK();
 
+  extern void __libc_stdio_cleanup(void);
+  __libc_stdio_cleanup();
+
   /* BEGIN android-changed: call __unregister_atfork if dso is not null */
   if (dso != NULL) {
     __unregister_atfork(dso);
   }
   /* END android-changed */
 }
-
-/*
- * Register the cleanup function
- */
-void
-__atexit_register_cleanup(void (*func)(void))
-{
-	struct atexit *p;
-	size_t pgsize = getpagesize();
-
-	if (pgsize < sizeof(*p))
-		return;
-	_ATEXIT_LOCK();
-	p = __atexit;
-	while (p != NULL && p->next != NULL)
-		p = p->next;
-	if (p == NULL) {
-		p = mmap(NULL, pgsize, PROT_READ | PROT_WRITE,
-		    MAP_ANON | MAP_PRIVATE, -1, 0);
-		if (p == MAP_FAILED)
-			goto unlock;
-		p->ind = 1;
-		p->max = (pgsize - ((char *)&p->fns[0] - (char *)p)) /
-		    sizeof(p->fns[0]);
-		p->next = NULL;
-		__atexit = p;
-	} else {
-		if (mprotect(p, pgsize, PROT_READ | PROT_WRITE))
-			goto unlock;
-	}
-	p->fns[0].fn_ptr = (void (*)(void *))func;
-	p->fns[0].fn_arg = NULL;
-	p->fns[0].fn_dso = NULL;
-	mprotect(p, pgsize, PROT_READ);
-	restartloop = 1;
-unlock:
-	_ATEXIT_UNLOCK();
-}
diff --git a/libc/tools/check-symbols-glibc.py b/libc/tools/check-symbols-glibc.py
index 2c352b2..c5dbdcf 100755
--- a/libc/tools/check-symbols-glibc.py
+++ b/libc/tools/check-symbols-glibc.py
@@ -71,11 +71,15 @@
 
 # bionic includes various BSD symbols to ease porting other BSD-licensed code.
 bsd_stuff = set([
+  'arc4random',
+  'arc4random_buf',
+  'arc4random_uniform',
   'basename_r',
   'dirname_r',
   'fgetln',
   'fpurge',
   'funopen',
+  'funopen64',
   'gamma_r',
   'gammaf_r',
   'getprogname',
@@ -91,6 +95,11 @@
   '__FD_CLR_chk',
   '__FD_ISSET_chk',
   '__FD_SET_chk',
+  '__fwrite_chk',
+  '__memchr_chk',
+  '__memrchr_chk',
+  '__pwrite64_chk',
+  '__pwrite_chk',
   '__stack_chk_guard',
   '__stpncpy_chk2',
   '__strchr_chk',
@@ -100,6 +109,7 @@
   '__strncpy_chk2',
   '__strrchr_chk',
   '__umask_chk'
+  '__write_chk',
 ])
 # Some symbols are used to implement public macros.
 macro_stuff = set([
diff --git a/libc/tools/check-symbols.py b/libc/tools/check-symbols.py
index a217ff7..a6cf50c 100755
--- a/libc/tools/check-symbols.py
+++ b/libc/tools/check-symbols.py
@@ -13,9 +13,21 @@
 sys.stderr.write('Checking symbols for arch "%s"...\n' % arch)
 
 def GetSymbols(library, functions_or_variables):
+  global api
+  global arch
+
   api = '9'
   if library == 'libm' and arch == 'arm':
     api = '3'
+
+  # There were no 64-bit ABIs before API level 21.
+  if '64' in arch:
+    api = '21'
+
+  # What GCC calls aarch64, Android calls arm64.
+  if arch == 'aarch64':
+    arch = 'arm64'
+
   path = '%s/development/ndk/platforms/android-%s/arch-%s/symbols/%s.so.%s.txt' % (os.environ['ANDROID_BUILD_TOP'], api, arch, library, functions_or_variables)
   symbols = set()
   for line in open(path, 'r'):
@@ -26,7 +38,11 @@
 def CheckSymbols(library, functions_or_variables):
   expected_symbols = GetSymbols(library, functions_or_variables)
 
-  so_file = '%s/system/lib/%s.so' % (os.environ['ANDROID_PRODUCT_OUT'], library)
+  lib_dir = 'lib'
+  if '64' in arch:
+    lib_dir = 'lib64'
+
+  so_file = '%s/system/%s/%s.so' % (os.environ['ANDROID_PRODUCT_OUT'], lib_dir, library)
 
   # Example readelf output:
   #   264: 0001623c     4 FUNC    GLOBAL DEFAULT    8 cabsf
@@ -38,7 +54,7 @@
   r = re.compile(r' +\d+: [0-9a-f]+ +\d+ (FUNC|OBJECT) +\S+ +\S+ +\d+ (\S+)')
 
   actual_symbols = set()
-  for line in subprocess.check_output(['readelf', '--dyn-syms', so_file]).split('\n'):
+  for line in subprocess.check_output(['readelf', '-W', '--dyn-syms', so_file]).split('\n'):
     m = r.match(line)
     if m:
       symbol = string.split(m.group(2), '@')[0]
@@ -55,6 +71,12 @@
     for miss in sorted(missing):
       sys.stderr.write('  %s\n' % miss)
 
+  extra = actual_symbols - expected_symbols
+  if len(extra) > 0:
+    sys.stderr.write('%d extra %s in %s for %s:\n' % (len(extra), functions_or_variables, library, arch))
+    for s in sorted(extra):
+      sys.stderr.write('  %s\n' % s)
+
   return len(missing) == 0
 
 CheckSymbols("libc", "functions")
diff --git a/libc/tools/gensyscalls.py b/libc/tools/gensyscalls.py
index 4d0afe2..04ccf39 100755
--- a/libc/tools/gensyscalls.py
+++ b/libc/tools/gensyscalls.py
@@ -62,9 +62,11 @@
 
 arm_eabi_call_default = syscall_stub_header + """\
     mov     ip, r7
+    .cfi_register r7, ip
     ldr     r7, =%(__NR_name)s
     swi     #0
     mov     r7, ip
+    .cfi_restore r7
     cmn     r0, #(MAX_ERRNO + 1)
     bxls    lr
     neg     r0, r0
@@ -166,9 +168,20 @@
 
 x86_registers = [ "ebx", "ecx", "edx", "esi", "edi", "ebp" ]
 
+x86_call_prepare = """\
+
+    call    __kernel_syscall
+    pushl   %eax
+    .cfi_adjust_cfa_offset 4
+    .cfi_rel_offset eax, 0
+
+"""
+
 x86_call = """\
     movl    $%(__NR_name)s, %%eax
-    int     $0x80
+    call    *(%%esp)
+    addl    $4, %%esp
+
     cmpl    $-MAX_ERRNO, %%eax
     jb      1f
     negl    %%eax
@@ -311,7 +324,7 @@
     result     = syscall_stub_header % syscall
 
     numparams = count_generic_param_registers(syscall["params"])
-    stack_bias = numparams*4 + 4
+    stack_bias = numparams*4 + 8
     offset = 0
     mov_result = ""
     first_push = True
@@ -327,6 +340,7 @@
         mov_result += "    mov     %d(%%esp), %%%s\n" % (stack_bias+offset, register)
         offset += 4
 
+    result += x86_call_prepare
     result += mov_result
     result += x86_call % syscall
 
@@ -352,7 +366,9 @@
     result += "    pushl   %ecx\n"
     result += "    .cfi_adjust_cfa_offset 4\n"
     result += "    .cfi_rel_offset ecx, 0\n"
-    stack_bias = 12
+    stack_bias = 16
+
+    result += x86_call_prepare
 
     # set the call id (%ebx)
     result += "    mov     $%d, %%ebx\n" % syscall["socketcall_id"]
diff --git a/libc/tools/genversion-scripts.py b/libc/tools/genversion-scripts.py
new file mode 100755
index 0000000..e15c04e
--- /dev/null
+++ b/libc/tools/genversion-scripts.py
@@ -0,0 +1,63 @@
+#!/usr/bin/python
+
+# This tool is used to generate the version scripts for libc and libm
+# for every architecture.
+
+import atexit
+import os.path
+import shutil
+import tempfile
+
+
+all_arches = ["arm", "arm64", "mips", "mips64", "x86", "x86_64"]
+bionic_libc_root = os.path.join(os.environ["ANDROID_BUILD_TOP"], "bionic/libc")
+bionic_libm_root = os.path.join(os.environ["ANDROID_BUILD_TOP"], "bionic/libm")
+bionic_libdl_root = os.path.join(os.environ["ANDROID_BUILD_TOP"], "bionic/libdl")
+libc_script = os.path.join(bionic_libc_root, "libc.map.txt")
+libm_script = os.path.join(bionic_libm_root, "libm.map.txt")
+libdl_script = os.path.join(bionic_libdl_root, "libdl.map.txt")
+
+# TODO (dimity): generate architecture-specific version scripts as part of build
+
+# temp directory where we store all intermediate files
+bionic_temp = tempfile.mkdtemp(prefix="bionic_genversionscripts")
+# Make sure the directory is deleted when the script exits.
+atexit.register(shutil.rmtree, bionic_temp)
+
+bionic_libc_root = os.path.join(os.environ["ANDROID_BUILD_TOP"], "bionic/libc")
+
+warning = "Generated by genversionscripts.py. Do not edit."
+
+
+class VersionScriptGenerator(object):
+
+  def run(self):
+    for script in [libc_script, libm_script, libdl_script]:
+      basename = os.path.basename(script)
+      dirname = os.path.dirname(script)
+      for arch in all_arches:
+        for brillo in [False, True]:
+          has_nobrillo = False
+          name = basename.split(".")[0] + "." + arch + (".brillo" if brillo else "") + ".map"
+          tmp_path = os.path.join(bionic_temp, name)
+          dest_path = os.path.join(dirname, name)
+          with open(tmp_path, "w") as fout:
+            with open(script, "r") as fin:
+              fout.write("# %s\n" % warning)
+              for line in fin:
+                index = line.find("#")
+                if index != -1:
+                  tags = line[index+1:].split()
+                  if arch not in tags:
+                    continue
+                  if brillo and "nobrillo" in tags:
+                    has_nobrillo = True
+                    continue
+                fout.write(line)
+          if not brillo or has_nobrillo:
+            shutil.copyfile(tmp_path, dest_path)
+
+
+generator = VersionScriptGenerator()
+generator.run()
+
diff --git a/libc/tools/zoneinfo/ZoneCompactor.java b/libc/tools/zoneinfo/ZoneCompactor.java
deleted file mode 100644
index 2d598fe..0000000
--- a/libc/tools/zoneinfo/ZoneCompactor.java
+++ /dev/null
@@ -1,192 +0,0 @@
-
-import java.io.*;
-import java.util.*;
-
-// usage: java ZoneCompiler <setup file> <data directory> <output directory> <tzdata version>
-//
-// Compile a set of tzfile-formatted files into a single file containing an index.
-//
-// The compilation is controlled by a setup file, which is provided as a
-// command-line argument.  The setup file has the form:
-//
-// Link <toName> <fromName>
-// ...
-// <zone filename>
-// ...
-//
-// Note that the links must be declared prior to the zone names.
-// A zone name is a filename relative to the source directory such as
-// 'GMT', 'Africa/Dakar', or 'America/Argentina/Jujuy'.
-//
-// Use the 'zic' command-line tool to convert from flat files
-// (such as 'africa' or 'northamerica') to a directory
-// hierarchy suitable for this tool (containing files such as 'data/Africa/Abidjan').
-//
-
-public class ZoneCompactor {
-  // Maximum number of characters in a zone name, including '\0' terminator.
-  private static final int MAXNAME = 40;
-
-  // Zone name synonyms.
-  private Map<String,String> links = new HashMap<String,String>();
-
-  // File offsets by zone name.
-  private Map<String,Integer> offsets = new HashMap<String,Integer>();
-
-  // File lengths by zone name.
-  private Map<String,Integer> lengths = new HashMap<String,Integer>();
-
-  // Concatenate the contents of 'inFile' onto 'out'.
-  private static void copyFile(File inFile, OutputStream out) throws Exception {
-    byte[] ret = new byte[0];
-
-    InputStream in = new FileInputStream(inFile);
-    byte[] buf = new byte[8192];
-    while (true) {
-      int nbytes = in.read(buf);
-      if (nbytes == -1) {
-        break;
-      }
-      out.write(buf, 0, nbytes);
-
-      byte[] nret = new byte[ret.length + nbytes];
-      System.arraycopy(ret, 0, nret, 0, ret.length);
-      System.arraycopy(buf, 0, nret, ret.length, nbytes);
-      ret = nret;
-    }
-    out.flush();
-  }
-
-  public ZoneCompactor(String setupFile, String dataDirectory, String zoneTabFile, String outputDirectory, String version) throws Exception {
-    // Read the setup file and concatenate all the data.
-    ByteArrayOutputStream allData = new ByteArrayOutputStream();
-    BufferedReader reader = new BufferedReader(new FileReader(setupFile));
-    String s;
-    int offset = 0;
-    while ((s = reader.readLine()) != null) {
-      s = s.trim();
-      if (s.startsWith("Link")) {
-        StringTokenizer st = new StringTokenizer(s);
-        st.nextToken();
-        String to = st.nextToken();
-        String from = st.nextToken();
-        links.put(from, to);
-      } else {
-        String link = links.get(s);
-        if (link == null) {
-          File sourceFile = new File(dataDirectory, s);
-          long length = sourceFile.length();
-          offsets.put(s, offset);
-          lengths.put(s, (int) length);
-
-          offset += length;
-          copyFile(sourceFile, allData);
-        }
-      }
-    }
-    reader.close();
-
-    // Fill in fields for links.
-    Iterator<String> it = links.keySet().iterator();
-    while (it.hasNext()) {
-      String from = it.next();
-      String to = links.get(from);
-
-      offsets.put(from, offsets.get(to));
-      lengths.put(from, lengths.get(to));
-    }
-
-    // Create/truncate the destination file.
-    RandomAccessFile f = new RandomAccessFile(new File(outputDirectory, "tzdata"), "rw");
-    f.setLength(0);
-
-    // Write the header.
-
-    // byte[12] tzdata_version -- 'tzdata2012f\0'
-    // int index_offset -- so we can slip in extra header fields in a backwards-compatible way
-    // int data_offset
-    // int zonetab_offset
-
-    // tzdata_version
-    f.write(toAscii(new byte[12], version));
-
-    // Write dummy values for the three offsets, and remember where we need to seek back to later
-    // when we have the real values.
-    int index_offset_offset = (int) f.getFilePointer();
-    f.writeInt(0);
-    int data_offset_offset = (int) f.getFilePointer();
-    f.writeInt(0);
-    int zonetab_offset_offset = (int) f.getFilePointer();
-    f.writeInt(0);
-
-    int index_offset = (int) f.getFilePointer();
-
-    // Write the index.
-    ArrayList<String> sortedOlsonIds = new ArrayList<String>();
-    sortedOlsonIds.addAll(offsets.keySet());
-    Collections.sort(sortedOlsonIds);
-    it = sortedOlsonIds.iterator();
-    while (it.hasNext()) {
-      String zoneName = it.next();
-      if (zoneName.length() >= MAXNAME) {
-        throw new RuntimeException("zone filename too long: " + zoneName.length());
-      }
-
-      // Follow the chain of links to work out where the real data for this zone lives.
-      String actualZoneName = zoneName;
-      while (links.get(actualZoneName) != null) {
-        actualZoneName = links.get(actualZoneName);
-      }
-
-      f.write(toAscii(new byte[MAXNAME], zoneName));
-      f.writeInt(offsets.get(actualZoneName));
-      f.writeInt(lengths.get(actualZoneName));
-      f.writeInt(0); // Used to be raw GMT offset. No longer used.
-    }
-
-    int data_offset = (int) f.getFilePointer();
-
-    // Write the data.
-    f.write(allData.toByteArray());
-
-    int zonetab_offset = (int) f.getFilePointer();
-
-    // Copy the zone.tab.
-    reader = new BufferedReader(new FileReader(zoneTabFile));
-    while ((s = reader.readLine()) != null) {
-      if (!s.startsWith("#")) {
-        f.writeBytes(s);
-        f.write('\n');
-      }
-    }
-    reader.close();
-
-    // Go back and fix up the offsets in the header.
-    f.seek(index_offset_offset);
-    f.writeInt(index_offset);
-    f.seek(data_offset_offset);
-    f.writeInt(data_offset);
-    f.seek(zonetab_offset_offset);
-    f.writeInt(zonetab_offset);
-
-    f.close();
-  }
-
-  private static byte[] toAscii(byte[] dst, String src) {
-    for (int i = 0; i < src.length(); ++i) {
-      if (src.charAt(i) > '~') {
-        throw new RuntimeException("non-ASCII string: " + src);
-      }
-      dst[i] = (byte) src.charAt(i);
-    }
-    return dst;
-  }
-
-  public static void main(String[] args) throws Exception {
-    if (args.length != 5) {
-      System.err.println("usage: java ZoneCompactor <setup file> <data directory> <zone.tab file> <output directory> <tzdata version>");
-      System.exit(0);
-    }
-    new ZoneCompactor(args[0], args[1], args[2], args[3], args[4]);
-  }
-}
diff --git a/libc/tools/zoneinfo/update-tzdata.py b/libc/tools/zoneinfo/update-tzdata.py
deleted file mode 100755
index 68a5ff5..0000000
--- a/libc/tools/zoneinfo/update-tzdata.py
+++ /dev/null
@@ -1,262 +0,0 @@
-#!/usr/bin/python
-
-"""Updates the timezone data held in bionic and ICU."""
-
-import ftplib
-import glob
-import httplib
-import os
-import re
-import shutil
-import subprocess
-import sys
-import tarfile
-import tempfile
-
-regions = ['africa', 'antarctica', 'asia', 'australasia',
-           'etcetera', 'europe', 'northamerica', 'southamerica',
-           # These two deliberately come last so they override what came
-           # before (and each other).
-           'backward', 'backzone' ]
-
-def CheckDirExists(dir, dirname):
-  if not os.path.isdir(dir):
-    print "Couldn't find %s (%s)!" % (dirname, dir)
-    sys.exit(1)
-
-bionic_libc_tools_zoneinfo_dir = os.path.realpath(os.path.dirname(sys.argv[0]))
-
-# Find the bionic directory, searching upward from this script.
-bionic_dir = os.path.realpath('%s/../../..' % bionic_libc_tools_zoneinfo_dir)
-bionic_libc_zoneinfo_dir = '%s/libc/zoneinfo' % bionic_dir
-CheckDirExists(bionic_libc_zoneinfo_dir, 'bionic/libc/zoneinfo')
-CheckDirExists(bionic_libc_tools_zoneinfo_dir, 'bionic/libc/tools/zoneinfo')
-print 'Found bionic in %s ...' % bionic_dir
-
-# Find the icu directory.
-icu_dir = os.path.realpath('%s/../external/icu' % bionic_dir)
-icu4c_dir = os.path.realpath('%s/icu4c/source' % icu_dir)
-icu4j_dir = os.path.realpath('%s/icu4j' % icu_dir)
-CheckDirExists(icu4c_dir, 'external/icu/icu4c/source')
-CheckDirExists(icu4j_dir, 'external/icu/icu4j')
-print 'Found icu in %s ...' % icu_dir
-
-
-def GetCurrentTzDataVersion():
-  return open('%s/tzdata' % bionic_libc_zoneinfo_dir).read().split('\x00', 1)[0]
-
-
-def WriteSetupFile():
-  """Writes the list of zones that ZoneCompactor should process."""
-  links = []
-  zones = []
-  for region in regions:
-    for line in open('extracted/%s' % region):
-      fields = line.split()
-      if fields:
-        if fields[0] == 'Link':
-          links.append('%s %s %s' % (fields[0], fields[1], fields[2]))
-          zones.append(fields[2])
-        elif fields[0] == 'Zone':
-          zones.append(fields[1])
-  zones.sort()
-
-  setup = open('setup', 'w')
-  for link in sorted(set(links)):
-    setup.write('%s\n' % link)
-  for zone in sorted(set(zones)):
-    setup.write('%s\n' % zone)
-  setup.close()
-
-
-def SwitchToNewTemporaryDirectory():
-  tmp_dir = tempfile.mkdtemp('-tzdata')
-  os.chdir(tmp_dir)
-  print 'Created temporary directory "%s"...' % tmp_dir
-
-
-def FtpRetrieveFile(ftp, filename):
-  ftp.retrbinary('RETR %s' % filename, open(filename, 'wb').write)
-
-
-def FtpRetrieveFileAndSignature(ftp, data_filename):
-  """Downloads and repackages the given data from the given FTP server."""
-  print 'Downloading data...'
-  FtpRetrieveFile(ftp, data_filename)
-
-  print 'Downloading signature...'
-  signature_filename = '%s.asc' % data_filename
-  FtpRetrieveFile(ftp, signature_filename)
-
-
-def HttpRetrieveFile(http, path, output_filename):
-  http.request("GET", path)
-  f = open(output_filename, 'wb')
-  f.write(http.getresponse().read())
-  f.close()
-
-
-def HttpRetrieveFileAndSignature(http, data_filename):
-  """Downloads and repackages the given data from the given HTTP server."""
-  path = "/time-zones/repository/releases/%s" % data_filename
-
-  print 'Downloading data...'
-  HttpRetrieveFile(http, path, data_filename)
-
-  print 'Downloading signature...'
-  signature_filename = '%s.asc' % data_filename
-  HttpRetrievefile(http, "%s.asc" % path, signature_filename)
-
-
-def BuildIcuToolsAndData(data_filename):
-  # Keep track of the original cwd so we can go back to it at the end.
-  original_working_dir = os.getcwd()
-
-  # Create a directory to run 'make' from.
-  icu_working_dir = '%s/icu' % original_working_dir
-  os.mkdir(icu_working_dir)
-  os.chdir(icu_working_dir)
-
-  # Build the ICU tools.
-  print 'Configuring ICU tools...'
-  subprocess.check_call(['%s/runConfigureICU' % icu4c_dir, 'Linux'])
-
-  # Run the ICU tools.
-  os.chdir('tools/tzcode')
-
-  # The tz2icu tool only picks up icuregions and icuzones in they are in the CWD
-  for icu_data_file in [ 'icuregions', 'icuzones']:
-    icu_data_file_source = '%s/tools/tzcode/%s' % (icu4c_dir, icu_data_file)
-    icu_data_file_symlink = './%s' % icu_data_file
-    os.symlink(icu_data_file_source, icu_data_file_symlink)
-
-  shutil.copyfile('%s/%s' % (original_working_dir, data_filename), data_filename)
-  print 'Making ICU data...'
-  # The Makefile assumes the existence of the bin directory.
-  os.mkdir('%s/bin' % icu_working_dir)
-  subprocess.check_call(['make'])
-
-  # Copy the source file to its ultimate destination.
-  icu_txt_data_dir = '%s/data/misc' % icu4c_dir
-  print 'Copying zoneinfo64.txt to %s ...' % icu_txt_data_dir
-  shutil.copy('zoneinfo64.txt', icu_txt_data_dir)
-
-  # Regenerate the .dat file.
-  os.chdir(icu_working_dir)
-  subprocess.check_call(['make', 'INCLUDE_UNI_CORE_DATA=1', '-j32'])
-
-  # Copy the .dat file to its ultimate destination.
-  icu_dat_data_dir = '%s/stubdata' % icu4c_dir
-  datfiles = glob.glob('data/out/tmp/icudt??l.dat')
-  if len(datfiles) != 1:
-    print 'ERROR: Unexpectedly found %d .dat files (%s). Halting.' % (len(datfiles), datfiles)
-    sys.exit(1)
-  datfile = datfiles[0]
-  print 'Copying %s to %s ...' % (datfile, icu_dat_data_dir)
-  shutil.copy(datfile, icu_dat_data_dir)
-
-  # Generate the ICU4J .jar files
-  os.chdir('%s/data' % icu_working_dir)
-  subprocess.check_call(['make', 'icu4j-data'])
-
-  # Copy the ICU4J .jar files to their ultimate destination.
-  icu_jar_data_dir = '%s/main/shared/data' % icu4j_dir
-  jarfiles = glob.glob('out/icu4j/*.jar')
-  if len(jarfiles) != 2:
-    print 'ERROR: Unexpectedly found %d .jar files (%s). Halting.' % (len(jarfiles), jarfiles)
-    sys.exit(1)
-  for jarfile in jarfiles:
-    print 'Copying %s to %s ...' % (jarfile, icu_jar_data_dir)
-    shutil.copy(jarfile, icu_jar_data_dir)
-
-  # Switch back to the original working cwd.
-  os.chdir(original_working_dir)
-
-
-def CheckSignature(data_filename):
-  signature_filename = '%s.asc' % data_filename
-  print 'Verifying signature...'
-  # If this fails for you, you probably need to import Paul Eggert's public key:
-  # gpg --recv-keys ED97E90E62AA7E34
-  subprocess.check_call(['gpg', '--trusted-key=ED97E90E62AA7E34', '--verify',
-                         signature_filename, data_filename])
-
-
-def BuildBionicToolsAndData(data_filename):
-  new_version = re.search('(tzdata.+)\\.tar\\.gz', data_filename).group(1)
-
-  print 'Extracting...'
-  os.mkdir('extracted')
-  tar = tarfile.open(data_filename, 'r')
-  tar.extractall('extracted')
-
-  print 'Calling zic(1)...'
-  os.mkdir('data')
-  zic_inputs = [ 'extracted/%s' % x for x in regions ]
-  zic_cmd = ['zic', '-d', 'data' ]
-  zic_cmd.extend(zic_inputs)
-  subprocess.check_call(zic_cmd)
-
-  WriteSetupFile()
-
-  print 'Calling ZoneCompactor to update bionic to %s...' % new_version
-  subprocess.check_call(['javac', '-d', '.',
-                         '%s/ZoneCompactor.java' % bionic_libc_tools_zoneinfo_dir])
-  subprocess.check_call(['java', 'ZoneCompactor',
-                         'setup', 'data', 'extracted/zone.tab',
-                         bionic_libc_zoneinfo_dir, new_version])
-
-
-# Run with no arguments from any directory, with no special setup required.
-# See http://www.iana.org/time-zones/ for more about the source of this data.
-def main():
-  print 'Looking for new tzdata...'
-
-  tzdata_filenames = []
-
-  # The FTP server lets you download intermediate releases, and also lets you
-  # download the signatures for verification, so it's your best choice.
-  use_ftp = True
-
-  if use_ftp:
-    ftp = ftplib.FTP('ftp.iana.org')
-    ftp.login()
-    ftp.cwd('tz/releases')
-    for filename in ftp.nlst():
-      if filename.startswith('tzdata20') and filename.endswith('.tar.gz'):
-        tzdata_filenames.append(filename)
-    tzdata_filenames.sort()
-  else:
-    http = httplib.HTTPConnection('www.iana.org')
-    http.request("GET", "/time-zones")
-    index_lines = http.getresponse().read().split('\n')
-    for line in index_lines:
-      m = re.compile('.*href="/time-zones/repository/releases/(tzdata20\d\d\c\.tar\.gz)".*').match(line)
-      if m:
-        tzdata_filenames.append(m.group(1))
-
-  # If you're several releases behind, we'll walk you through the upgrades
-  # one by one.
-  current_version = GetCurrentTzDataVersion()
-  current_filename = '%s.tar.gz' % current_version
-  for filename in tzdata_filenames:
-    if filename > current_filename:
-      print 'Found new tzdata: %s' % filename
-      SwitchToNewTemporaryDirectory()
-      if use_ftp:
-        FtpRetrieveFileAndSignature(ftp, filename)
-      else:
-        HttpRetrieveFileAndSignature(http, filename)
-
-      CheckSignature(filename)
-      BuildIcuToolsAndData(filename)
-      BuildBionicToolsAndData(filename)
-      print 'Look in %s and %s for new data files' % (bionic_dir, icu_dir)
-      sys.exit(0)
-
-  print 'You already have the latest tzdata (%s)!' % current_version
-  sys.exit(0)
-
-
-if __name__ == '__main__':
-  main()
diff --git a/libc/tzcode/asctime.c b/libc/tzcode/asctime.c
index fea24e4..337a313 100644
--- a/libc/tzcode/asctime.c
+++ b/libc/tzcode/asctime.c
@@ -55,7 +55,7 @@
 ** ??? ???-2147483648 -2147483648:-2147483648:-2147483648     -2147483648\n
 ** (two three-character abbreviations, five strings denoting integers,
 ** seven explicit spaces, two explicit colons, a newline,
-** and a trailing ASCII nul).
+** and a trailing NUL byte).
 ** The values above are for systems where an int is 32 bits and are provided
 ** as an example; the define below calculates the maximum for the system at
 ** hand.
@@ -99,11 +99,11 @@
 	** Assume that strftime is unaffected by other out-of-range members
 	** (e.g., timeptr->tm_mday) when processing "%Y".
 	*/
-	(void) strftime(year, sizeof year, "%Y", timeptr);
+	strftime(year, sizeof year, "%Y", timeptr);
 	/*
 	** We avoid using snprintf since it's not available on all systems.
 	*/
-	(void) snprintf(result, sizeof(result), /* Android change: use snprintf. */
+	snprintf(result, sizeof(result), /* Android change: use snprintf. */
 		((strlen(year) <= 4) ? ASCTIME_FMT : ASCTIME_FMT_B),
 		wn, mn,
 		timeptr->tm_mday, timeptr->tm_hour,
@@ -112,11 +112,7 @@
 	if (strlen(result) < STD_ASCTIME_BUF_SIZE || buf == buf_asctime)
 		return strcpy(buf, result);
 	else {
-#ifdef EOVERFLOW
 		errno = EOVERFLOW;
-#else /* !defined EOVERFLOW */
-		errno = EINVAL;
-#endif /* !defined EOVERFLOW */
 		return NULL;
 	}
 }
diff --git a/libc/tzcode/difftime.c b/libc/tzcode/difftime.c
index 449cdf0..ba2fd03 100644
--- a/libc/tzcode/difftime.c
+++ b/libc/tzcode/difftime.c
@@ -7,42 +7,52 @@
 
 #include "private.h"	/* for time_t and TYPE_SIGNED */
 
+/* Return -X as a double.  Using this avoids casting to 'double'.  */
+static double
+dminus(double x)
+{
+  return -x;
+}
+
 double ATTRIBUTE_CONST
-difftime(const time_t time1, const time_t time0)
+difftime(time_t time1, time_t time0)
 {
 	/*
-	** If (sizeof (double) > sizeof (time_t)) simply convert and subtract
+	** If double is large enough, simply convert and subtract
 	** (assuming that the larger type has more precision).
 	*/
-	if (sizeof (double) > sizeof (time_t))
-		return (double) time1 - (double) time0;
-	if (!TYPE_SIGNED(time_t)) {
-		/*
-		** The difference of two unsigned values can't overflow
-		** if the minuend is greater than or equal to the subtrahend.
-		*/
-		if (time1 >= time0)
-			return            time1 - time0;
-		else	return -(double) (time0 - time1);
+	if (sizeof (time_t) < sizeof (double)) {
+	  double t1 = time1, t0 = time0;
+	  return t1 - t0;
 	}
+
+	/*
+	** The difference of two unsigned values can't overflow
+	** if the minuend is greater than or equal to the subtrahend.
+	*/
+	if (!TYPE_SIGNED(time_t))
+	  return time0 <= time1 ? time1 - time0 : dminus(time0 - time1);
+
+	/* Use uintmax_t if wide enough.  */
+	if (sizeof (time_t) <= sizeof (uintmax_t)) {
+	  uintmax_t t1 = time1, t0 = time0;
+	  return time0 <= time1 ? t1 - t0 : dminus(t0 - t1);
+	}
+
 	/*
 	** Handle cases where both time1 and time0 have the same sign
 	** (meaning that their difference cannot overflow).
 	*/
 	if ((time1 < 0) == (time0 < 0))
-		return time1 - time0;
+	  return time1 - time0;
+
 	/*
-	** time1 and time0 have opposite signs.
-	** Punt if uintmax_t is too narrow.
+	** The values have opposite signs and uintmax_t is too narrow.
 	** This suffers from double rounding; attempt to lessen that
 	** by using long double temporaries.
 	*/
-	if (sizeof (uintmax_t) < sizeof (time_t))
-		return (long double) time1 - (long double) time0;
-	/*
-	** Stay calm...decent optimizers will eliminate the complexity below.
-	*/
-	if (time1 >= 0 /* && time0 < 0 */)
-		return    (uintmax_t) time1 + (uintmax_t) (-1 - time0) + 1;
-	return -(double) ((uintmax_t) time0 + (uintmax_t) (-1 - time1) + 1);
+	{
+	  long double t1 = time1, t0 = time0;
+	  return t1 - t0;
+	}
 }
diff --git a/libc/tzcode/localtime.c b/libc/tzcode/localtime.c
index bf09c5e..f370e87 100644
--- a/libc/tzcode/localtime.c
+++ b/libc/tzcode/localtime.c
@@ -10,10 +10,30 @@
 
 /*LINTLIBRARY*/
 
+#define LOCALTIME_IMPLEMENTATION
 #include "private.h"
+
 #include "tzfile.h"
 #include "fcntl.h"
 
+#if THREAD_SAFE
+# include <pthread.h>
+static pthread_mutex_t locallock = PTHREAD_MUTEX_INITIALIZER;
+static int lock(void) { return pthread_mutex_lock(&locallock); }
+static void unlock(void) { pthread_mutex_unlock(&locallock); }
+#else
+static int lock(void) { return 0; }
+static void unlock(void) { }
+#endif
+
+/* NETBSD_INSPIRED_EXTERN functions are exported to callers if
+   NETBSD_INSPIRED is defined, and are private otherwise.  */
+#if NETBSD_INSPIRED
+# define NETBSD_INSPIRED_EXTERN
+#else
+# define NETBSD_INSPIRED_EXTERN static
+#endif
+
 #ifndef TZ_ABBR_MAX_LEN
 #define TZ_ABBR_MAX_LEN 16
 #endif /* !defined TZ_ABBR_MAX_LEN */
@@ -38,19 +58,6 @@
 #define OPEN_MODE   O_RDONLY
 #endif /* !defined O_BINARY */
 
-#if 0
-#  define  XLOG(xx)  printf xx , fflush(stdout)
-#else
-#  define  XLOG(x)   do{}while (0)
-#endif
-
-/* BEGIN android-added: thread-safety. */
-#include <pthread.h>
-static pthread_mutex_t _tzMutex = PTHREAD_MUTEX_INITIALIZER;
-static inline void _tzLock(void) { pthread_mutex_lock(&_tzMutex); }
-static inline void _tzUnlock(void) { pthread_mutex_unlock(&_tzMutex); }
-/* END android-added */
-
 #ifndef WILDABBR
 /*
 ** Someone might make incorrect use of a time zone abbreviation:
@@ -91,10 +98,10 @@
 
 struct ttinfo {              /* time type information */
     int_fast32_t tt_gmtoff;  /* UT offset in seconds */
-    int          tt_isdst;   /* used to set tm_isdst */
+    bool         tt_isdst;   /* used to set tm_isdst */
     int          tt_abbrind; /* abbreviation list index */
-    int          tt_ttisstd; /* TRUE if transition is std time */
-    int          tt_ttisgmt; /* TRUE if transition is UT */
+    bool         tt_ttisstd; /* transition is std time */
+    bool         tt_ttisgmt; /* transition is UT */
 };
 
 struct lsinfo {              /* leap second information */
@@ -102,6 +109,7 @@
     int_fast64_t ls_corr;    /* correction to apply */
 };
 
+#define SMALLEST(a, b)	(((a) < (b)) ? (a) : (b))
 #define BIGGEST(a, b)   (((a) > (b)) ? (a) : (b))
 
 #ifdef TZNAME_MAX
@@ -116,8 +124,8 @@
     int           timecnt;
     int           typecnt;
     int           charcnt;
-    int           goback;
-    int           goahead;
+    bool          goback;
+    bool          goahead;
     time_t        ats[TZ_MAX_TIMES];
     unsigned char types[TZ_MAX_TIMES];
     struct ttinfo ttis[TZ_MAX_TYPES];
@@ -127,74 +135,29 @@
     int           defaulttype; /* for early times or if no transitions */
 };
 
+enum r_type {
+  JULIAN_DAY,		/* Jn = Julian day */
+  DAY_OF_YEAR,		/* n = day of year */
+  MONTH_NTH_DAY_OF_WEEK	/* Mm.n.d = month, week, day of week */
+};
+
 struct rule {
-    int          r_type; /* type of rule; see below */
+	enum r_type	r_type;		/* type of rule */
     int          r_day;  /* day number of rule */
     int          r_week; /* week number of rule */
     int          r_mon;  /* month number of rule */
     int_fast32_t r_time; /* transition time of rule */
 };
 
-#define JULIAN_DAY             0       /* Jn = Julian day */
-#define DAY_OF_YEAR            1       /* n = day of year */
-#define MONTH_NTH_DAY_OF_WEEK  2       /* Mm.n.d = month, week, day of week */
-
-/*
-** Prototypes for static functions.
-*/
-
-/* NOTE: all internal functions assume that _tzLock() was already called */
-
-static int __bionic_open_tzdata(const char*, int*);
-static int_fast32_t detzcode(const char * codep);
-static int_fast64_t detzcode64(const char * codep);
-static int      differ_by_repeat(time_t t1, time_t t0);
-static const char * getzname(const char * strp) ATTRIBUTE_PURE;
-static const char * getqzname(const char * strp, const int delim)
-        ATTRIBUTE_PURE;
-static const char * getnum(const char * strp, int * nump, int min,
-                int max);
-static const char * getsecs(const char * strp, int_fast32_t * secsp);
-static const char * getoffset(const char * strp, int_fast32_t * offsetp);
-static const char * getrule(const char * strp, struct rule * rulep);
-static void     gmtload(struct state * sp);
-static struct tm *  gmtsub(const time_t * timep, int_fast32_t offset,
-                struct tm * tmp, struct state * sp); // android-changed: added sp.
-static struct tm *  localsub(const time_t * timep, int_fast32_t offset,
-                struct tm * tmp, struct state * sp); // android-changed: added sp.
-static int      increment_overflow(int * number, int delta);
-static int      leaps_thru_end_of(int y) ATTRIBUTE_PURE;
-static int      increment_overflow32(int_fast32_t * number, int delta);
-static int      increment_overflow_time(time_t *t, int_fast32_t delta);
-static int      normalize_overflow32(int_fast32_t * tensptr,
-                int * unitsptr, int base);
-static int      normalize_overflow(int * tensptr, int * unitsptr,
-                int base);
-static void     settzname(void);
-static time_t       time1(struct tm * tmp,
-                struct tm * (*funcp)(const time_t *,
-                int_fast32_t, struct tm *, struct state *), // android-changed: added state*.
-                int_fast32_t, struct state * sp); // android-changed: added sp.
-static time_t       time2(struct tm * tmp,
-                struct tm * (*funcp)(const time_t *,
-                int_fast32_t, struct tm*, struct state *), // android-changed: added state*.
-                int_fast32_t offset, int * okayp, struct state * sp); // android-changed: added sp.
-static time_t       time2sub(struct tm *tmp,
-                struct tm * (*funcp) (const time_t *,
-                int_fast32_t, struct tm*, struct state *), // android-changed: added state*.
-                int_fast32_t offset, int * okayp, int do_norm_secs, struct state * sp); // android-change: added sp.
-static struct tm *  timesub(const time_t * timep, int_fast32_t offset,
-                const struct state * sp, struct tm * tmp);
-static int      tmcomp(const struct tm * atmp,
-                const struct tm * btmp);
-static int_fast32_t transtime(int year, const struct rule * rulep,
-                int_fast32_t offset)
-        ATTRIBUTE_PURE;
-static int      typesequiv(const struct state * sp, int a, int b);
-static int      tzload(const char * name, struct state * sp,
-                int doextend);
-static int      tzparse(const char * name, struct state * sp,
-                int lastditch);
+static struct tm *gmtsub(struct state const *, time_t const *, int_fast32_t,
+			 struct tm *);
+static bool increment_overflow(int *, int);
+static bool increment_overflow_time(time_t *, int_fast32_t);
+static bool normalize_overflow32(int_fast32_t *, int *, int);
+static struct tm *timesub(time_t const *, int_fast32_t, struct state const *,
+			  struct tm *);
+static bool typesequiv(struct state const *, int, int);
+static bool tzparse(char const *, struct state *, bool);
 
 #ifdef ALL_STATE
 static struct state * lclptr;
@@ -214,7 +177,6 @@
 
 static char lcl_TZname[TZ_STRLEN_MAX + 1];
 static int  lcl_is_set;
-static int  gmt_is_set;
 
 char * tzname[2] = {
     (char *) wildabbr,
@@ -229,427 +191,539 @@
 ** Thanks to Paul Eggert for noting this.
 */
 
-static struct tm    tmGlobal;
+static struct tm	tm;
 
 #ifdef USG_COMPAT
-long                timezone = 0;
-int                 daylight = 0;
+long			timezone;
+int			daylight;
 #endif /* defined USG_COMPAT */
 
 #ifdef ALTZONE
-long                altzone = 0;
+long			altzone;
 #endif /* defined ALTZONE */
 
+/* Initialize *S to a value based on GMTOFF, ISDST, and ABBRIND.  */
+static void
+init_ttinfo(struct ttinfo *s, int_fast32_t gmtoff, bool isdst, int abbrind)
+{
+  s->tt_gmtoff = gmtoff;
+  s->tt_isdst = isdst;
+  s->tt_abbrind = abbrind;
+  s->tt_ttisstd = false;
+  s->tt_ttisgmt = false;
+}
+
 static int_fast32_t
 detzcode(const char *const codep)
 {
-    register int_fast32_t result;
-    register int          i;
+	register int_fast32_t	result;
+	register int		i;
+	int_fast32_t one = 1;
+	int_fast32_t halfmaxval = one << (32 - 2);
+	int_fast32_t maxval = halfmaxval - 1 + halfmaxval;
+	int_fast32_t minval = -1 - maxval;
 
-    result = (codep[0] & 0x80) ? -1 : 0;
-    for (i = 0; i < 4; ++i)
-        result = (result << 8) | (codep[i] & 0xff);
-    return result;
+	result = codep[0] & 0x7f;
+	for (i = 1; i < 4; ++i)
+		result = (result << 8) | (codep[i] & 0xff);
+
+	if (codep[0] & 0x80) {
+	  /* Do two's-complement negation even on non-two's-complement machines.
+	     If the result would be minval - 1, return minval.  */
+	  result -= !TWOS_COMPLEMENT(int_fast32_t) && result != 0;
+	  result += minval;
+	}
+	return result;
 }
 
 static int_fast64_t
 detzcode64(const char *const codep)
 {
-    register int_fast64_t result;
-    register int          i;
+	register uint_fast64_t result;
+	register int	i;
+	int_fast64_t one = 1;
+	int_fast64_t halfmaxval = one << (64 - 2);
+	int_fast64_t maxval = halfmaxval - 1 + halfmaxval;
+	int_fast64_t minval = -TWOS_COMPLEMENT(int_fast64_t) - maxval;
 
-    result = (codep[0] & 0x80) ? -1 : 0;
-    for (i = 0; i < 8; ++i)
-        result = (result << 8) | (codep[i] & 0xff);
-    return result;
+	result = codep[0] & 0x7f;
+	for (i = 1; i < 8; ++i)
+		result = (result << 8) | (codep[i] & 0xff);
+
+	if (codep[0] & 0x80) {
+	  /* Do two's-complement negation even on non-two's-complement machines.
+	     If the result would be minval - 1, return minval.  */
+	  result -= !TWOS_COMPLEMENT(int_fast64_t) && result != 0;
+	  result += minval;
+	}
+	return result;
+}
+
+static void
+update_tzname_etc(struct state const *sp, struct ttinfo const *ttisp)
+{
+  tzname[ttisp->tt_isdst] = (char *) &sp->chars[ttisp->tt_abbrind];
+#ifdef USG_COMPAT
+  if (!ttisp->tt_isdst)
+    timezone = - ttisp->tt_gmtoff;
+#endif
+#ifdef ALTZONE
+  if (ttisp->tt_isdst)
+    altzone = - ttisp->tt_gmtoff;
+#endif
 }
 
 static void
 settzname(void)
 {
-    register struct state * const sp = lclptr;
-    register int                  i;
+	register struct state * const	sp = lclptr;
+	register int			i;
 
-    tzname[0] = tzname[1] = (char *) wildabbr;
+	tzname[0] = tzname[1] = (char *) wildabbr;
 #ifdef USG_COMPAT
-    daylight = 0;
-    timezone = 0;
+	daylight = 0;
+	timezone = 0;
 #endif /* defined USG_COMPAT */
 #ifdef ALTZONE
-    altzone = 0;
+	altzone = 0;
 #endif /* defined ALTZONE */
-    if (sp == NULL) {
-        tzname[0] = tzname[1] = (char *) gmt;
-        return;
-    }
-    /*
-    ** And to get the latest zone names into tzname. . .
-    */
-    for (i = 0; i < sp->typecnt; ++i) {
-        register const struct ttinfo * const    ttisp = &sp->ttis[i];
-
-        tzname[ttisp->tt_isdst] = &sp->chars[ttisp->tt_abbrind];
-    }
-    for (i = 0; i < sp->timecnt; ++i) {
-        register const struct ttinfo * const    ttisp =
-                            &sp->ttis[
-                                sp->types[i]];
-
-        tzname[ttisp->tt_isdst] =
-            &sp->chars[ttisp->tt_abbrind];
+	if (sp == NULL) {
+		tzname[0] = tzname[1] = (char *) gmt;
+		return;
+	}
+	/*
+	** And to get the latest zone names into tzname. . .
+	*/
+	for (i = 0; i < sp->typecnt; ++i) {
+		register const struct ttinfo * const	ttisp = &sp->ttis[i];
+		update_tzname_etc(sp, ttisp);
+	}
+	for (i = 0; i < sp->timecnt; ++i) {
+		register const struct ttinfo * const	ttisp =
+							&sp->ttis[
+								sp->types[i]];
+		update_tzname_etc(sp, ttisp);
 #ifdef USG_COMPAT
-        if (ttisp->tt_isdst)
-            daylight = 1;
-        if (!ttisp->tt_isdst)
-            timezone = -(ttisp->tt_gmtoff);
+		if (ttisp->tt_isdst)
+			daylight = 1;
 #endif /* defined USG_COMPAT */
-#ifdef ALTZONE
-        if (ttisp->tt_isdst)
-            altzone = -(ttisp->tt_gmtoff);
-#endif /* defined ALTZONE */
-    }
-    /*
-    ** Finally, scrub the abbreviations.
-    ** First, replace bogus characters.
-    */
-    for (i = 0; i < sp->charcnt; ++i)
-        if (strchr(TZ_ABBR_CHAR_SET, sp->chars[i]) == NULL)
-            sp->chars[i] = TZ_ABBR_ERR_CHAR;
-    /*
-    ** Second, truncate long abbreviations.
-    */
-    for (i = 0; i < sp->typecnt; ++i) {
-        register const struct ttinfo * const    ttisp = &sp->ttis[i];
-        register char *             cp = &sp->chars[ttisp->tt_abbrind];
-
-        if (strlen(cp) > TZ_ABBR_MAX_LEN &&
-            strcmp(cp, GRANDPARENTED) != 0)
-                *(cp + TZ_ABBR_MAX_LEN) = '\0';
-    }
+	}
 }
 
-static int
-differ_by_repeat(const time_t t1 __unused, const time_t t0 __unused)
+static void
+scrub_abbrs(struct state *sp)
+{
+	int i;
+	/*
+	** First, replace bogus characters.
+	*/
+	for (i = 0; i < sp->charcnt; ++i)
+		if (strchr(TZ_ABBR_CHAR_SET, sp->chars[i]) == NULL)
+			sp->chars[i] = TZ_ABBR_ERR_CHAR;
+	/*
+	** Second, truncate long abbreviations.
+	*/
+	for (i = 0; i < sp->typecnt; ++i) {
+		register const struct ttinfo * const	ttisp = &sp->ttis[i];
+		register char *				cp = &sp->chars[ttisp->tt_abbrind];
+
+		if (strlen(cp) > TZ_ABBR_MAX_LEN &&
+			strcmp(cp, GRANDPARENTED) != 0)
+				*(cp + TZ_ABBR_MAX_LEN) = '\0';
+	}
+}
+
+static bool
+differ_by_repeat(const time_t t1, const time_t t0)
 {
     if (TYPE_BIT(time_t) - TYPE_SIGNED(time_t) < SECSPERREPEAT_BITS)
         return 0;
-#if defined(__LP64__) // 32-bit Android only has a signed 32-bit time_t; 64-bit Android is fixed.
+#if defined(__LP64__) // 32-bit Android/glibc has a signed 32-bit time_t; 64-bit doesn't.
     return t1 - t0 == SECSPERREPEAT;
 #endif
 }
 
-static int
-tzload(register const char* name, register struct state* const sp,
-       register const int doextend)
-{
-    register const char * p;
-    register int          i;
-    register int          fid;
-    register int          stored;
-    register int          nread;
-    typedef union {
-        struct tzhead tzhead;
-        char          buf[2 * sizeof(struct tzhead) +
-                      2 * sizeof *sp +
-                      4 * TZ_MAX_TIMES];
-    } u_t;
-    union local_storage {
-        /*
-        ** Section 4.9.1 of the C standard says that
-        ** "FILENAME_MAX expands to an integral constant expression
-        ** that is the size needed for an array of char large enough
-        ** to hold the longest file name string that the implementation
-        ** guarantees can be opened."
-        */
-        //char            fullname[FILENAME_MAX + 1];
+/* Input buffer for data read from a compiled tz file.  */
+union input_buffer {
+  /* The first part of the buffer, interpreted as a header.  */
+  struct tzhead tzhead;
 
-        /* The main part of the storage for this function.  */
-        struct {
-            u_t u;
-            struct state st;
-        } u;
-    };
-    //register char *fullname;
-    register u_t *up;
-    register union local_storage *lsp;
-#ifdef ALL_STATE
-    lsp = malloc(sizeof *lsp);
-    if (!lsp)
-        return -1;
-#else /* !defined ALL_STATE */
-    union local_storage ls;
-    lsp = &ls;
-#endif /* !defined ALL_STATE */
-    //fullname = lsp->fullname;
-    up = &lsp->u.u;
-
-    sp->goback = sp->goahead = FALSE;
-
-    if (! name) {
-        name = TZDEFAULT;
-        if (! name)
-            goto oops;
-    }
-
-    int toread;
-    fid = __bionic_open_tzdata(name, &toread);
-    if (fid < 0)
-        goto oops;
-
-    nread = read(fid, up->buf, sizeof up->buf);
-    if (close(fid) < 0 || nread <= 0)
-        goto oops;
-    for (stored = 4; stored <= 8; stored *= 2) {
-        int ttisstdcnt;
-        int ttisgmtcnt;
-        int timecnt;
-
-        ttisstdcnt = (int) detzcode(up->tzhead.tzh_ttisstdcnt);
-        ttisgmtcnt = (int) detzcode(up->tzhead.tzh_ttisgmtcnt);
-        sp->leapcnt = (int) detzcode(up->tzhead.tzh_leapcnt);
-        sp->timecnt = (int) detzcode(up->tzhead.tzh_timecnt);
-        sp->typecnt = (int) detzcode(up->tzhead.tzh_typecnt);
-        sp->charcnt = (int) detzcode(up->tzhead.tzh_charcnt);
-        p = up->tzhead.tzh_charcnt + sizeof up->tzhead.tzh_charcnt;
-        if (sp->leapcnt < 0 || sp->leapcnt > TZ_MAX_LEAPS ||
-            sp->typecnt <= 0 || sp->typecnt > TZ_MAX_TYPES ||
-            sp->timecnt < 0 || sp->timecnt > TZ_MAX_TIMES ||
-            sp->charcnt < 0 || sp->charcnt > TZ_MAX_CHARS ||
-            (ttisstdcnt != sp->typecnt && ttisstdcnt != 0) ||
-            (ttisgmtcnt != sp->typecnt && ttisgmtcnt != 0))
-                goto oops;
-        if (nread - (p - up->buf) <
-            sp->timecnt * stored +       /* ats */
-            sp->timecnt +                /* types */
-            sp->typecnt * 6 +            /* ttinfos */
-            sp->charcnt +                /* chars */
-            sp->leapcnt * (stored + 4) + /* lsinfos */
-            ttisstdcnt +                 /* ttisstds */
-            ttisgmtcnt)                  /* ttisgmts */
-                goto oops;
-        timecnt = 0;
-        for (i = 0; i < sp->timecnt; ++i) {
-            int_fast64_t at
-              = stored == 4 ? detzcode(p) : detzcode64(p);
-            sp->types[i] = ((TYPE_SIGNED(time_t)
-                     ? time_t_min <= at
-                     : 0 <= at)
-                    && at <= time_t_max);
-            if (sp->types[i]) {
-                if (i && !timecnt && at != time_t_min) {
-                    /*
-                    ** Keep the earlier record, but tweak
-                    ** it so that it starts with the
-                    ** minimum time_t value.
-                    */
-                    sp->types[i - 1] = 1;
-                    sp->ats[timecnt++] = time_t_min;
-                }
-                sp->ats[timecnt++] = at;
-            }
-            p += stored;
-        }
-        timecnt = 0;
-        for (i = 0; i < sp->timecnt; ++i) {
-            unsigned char typ = *p++;
-            if (sp->typecnt <= typ)
-                goto oops;
-            if (sp->types[i])
-                sp->types[timecnt++] = typ;
-        }
-        sp->timecnt = timecnt;
-        for (i = 0; i < sp->typecnt; ++i) {
-            register struct ttinfo *    ttisp;
-
-            ttisp = &sp->ttis[i];
-            ttisp->tt_gmtoff = detzcode(p);
-            p += 4;
-            ttisp->tt_isdst = (unsigned char) *p++;
-            if (ttisp->tt_isdst != 0 && ttisp->tt_isdst != 1)
-                goto oops;
-            ttisp->tt_abbrind = (unsigned char) *p++;
-            if (ttisp->tt_abbrind < 0 ||
-                ttisp->tt_abbrind > sp->charcnt)
-                    goto oops;
-        }
-        for (i = 0; i < sp->charcnt; ++i)
-            sp->chars[i] = *p++;
-        sp->chars[i] = '\0';    /* ensure '\0' at end */
-        for (i = 0; i < sp->leapcnt; ++i) {
-            register struct lsinfo *    lsisp;
-
-            lsisp = &sp->lsis[i];
-            lsisp->ls_trans = (stored == 4) ?
-                detzcode(p) : detzcode64(p);
-            p += stored;
-            lsisp->ls_corr = detzcode(p);
-            p += 4;
-        }
-        for (i = 0; i < sp->typecnt; ++i) {
-            register struct ttinfo *    ttisp;
-
-            ttisp = &sp->ttis[i];
-            if (ttisstdcnt == 0)
-                ttisp->tt_ttisstd = FALSE;
-            else {
-                ttisp->tt_ttisstd = *p++;
-                if (ttisp->tt_ttisstd != TRUE &&
-                    ttisp->tt_ttisstd != FALSE)
-                        goto oops;
-            }
-        }
-        for (i = 0; i < sp->typecnt; ++i) {
-            register struct ttinfo *    ttisp;
-
-            ttisp = &sp->ttis[i];
-            if (ttisgmtcnt == 0)
-                ttisp->tt_ttisgmt = FALSE;
-            else {
-                ttisp->tt_ttisgmt = *p++;
-                if (ttisp->tt_ttisgmt != TRUE &&
-                    ttisp->tt_ttisgmt != FALSE)
-                        goto oops;
-            }
-        }
-        /*
-        ** If this is an old file, we're done.
-        */
-        if (up->tzhead.tzh_version[0] == '\0')
-            break;
-        nread -= p - up->buf;
-        for (i = 0; i < nread; ++i)
-            up->buf[i] = p[i];
-        /*
-        ** If this is a signed narrow time_t system, we're done.
-        */
-        if (TYPE_SIGNED(time_t) && stored >= (int) sizeof(time_t))
-            break;
-    }
-    if (doextend && nread > 2 &&
-        up->buf[0] == '\n' && up->buf[nread - 1] == '\n' &&
-        sp->typecnt + 2 <= TZ_MAX_TYPES) {
-            struct state    *ts = &lsp->u.st;
-            register int result;
-
-            up->buf[nread - 1] = '\0';
-            result = tzparse(&up->buf[1], ts, FALSE);
-            if (result == 0 && ts->typecnt == 2 &&
-                sp->charcnt + ts->charcnt <= TZ_MAX_CHARS) {
-                    for (i = 0; i < 2; ++i)
-                        ts->ttis[i].tt_abbrind +=
-                            sp->charcnt;
-                    for (i = 0; i < ts->charcnt; ++i)
-                        sp->chars[sp->charcnt++] =
-                            ts->chars[i];
-                    i = 0;
-                    while (i < ts->timecnt &&
-                        ts->ats[i] <=
-                        sp->ats[sp->timecnt - 1])
-                            ++i;
-                    while (i < ts->timecnt &&
-                        sp->timecnt < TZ_MAX_TIMES) {
-                        sp->ats[sp->timecnt] =
-                            ts->ats[i];
-                        sp->types[sp->timecnt] =
-                            sp->typecnt +
-                            ts->types[i];
-                        ++sp->timecnt;
-                        ++i;
-                    }
-                    sp->ttis[sp->typecnt++] = ts->ttis[0];
-                    sp->ttis[sp->typecnt++] = ts->ttis[1];
-            }
-    }
-    if (sp->timecnt > 1) {
-        for (i = 1; i < sp->timecnt; ++i)
-            if (typesequiv(sp, sp->types[i], sp->types[0]) &&
-                    differ_by_repeat(sp->ats[i], sp->ats[0])) {
-                sp->goback = TRUE;
-                break;
-            }
-            for (i = sp->timecnt - 2; i >= 0; --i)
-                if (typesequiv(sp, sp->types[sp->timecnt - 1],
-                               sp->types[i]) &&
-                        differ_by_repeat(sp->ats[sp->timecnt - 1],
-                                         sp->ats[i])) {
-                    sp->goahead = TRUE;
-                    break;
-            }
-        }
-        /*
-        ** If type 0 is is unused in transitions,
-        ** it's the type to use for early times.
-        */
-        for (i = 0; i < sp->typecnt; ++i)
-            if (sp->types[i] == 0)
-                break;
-        i = (i >= sp->typecnt) ? 0 : -1;
-        /*
-        ** Absent the above,
-        ** if there are transition times
-        ** and the first transition is to a daylight time
-        ** find the standard type less than and closest to
-        ** the type of the first transition.
-        */
-        if (i < 0 && sp->timecnt > 0 && sp->ttis[sp->types[0]].tt_isdst) {
-            i = sp->types[0];
-            while (--i >= 0)
-                if (!sp->ttis[i].tt_isdst)
-                    break;
-        }
-        /*
-        ** If no result yet, find the first standard type.
-        ** If there is none, punt to type zero.
-        */
-        if (i < 0) {
-            i = 0;
-            while (sp->ttis[i].tt_isdst)
-                if (++i >= sp->typecnt) {
-                    i = 0;
-                    break;
-                }
-        }
-        sp->defaulttype = i;
-#ifdef ALL_STATE
-        free(up);
-#endif /* defined ALL_STATE */
-        return 0;
-oops:
-#ifdef ALL_STATE
-        free(up);
-#endif /* defined ALL_STATE */
-        return -1;
-}
-
-static int
-typesequiv(const struct state *const sp, const int a, const int b)
-{
-    register int result;
-
-    if (sp == NULL ||
-        a < 0 || a >= sp->typecnt ||
-        b < 0 || b >= sp->typecnt)
-            result = FALSE;
-    else {
-        register const struct ttinfo *  ap = &sp->ttis[a];
-        register const struct ttinfo *  bp = &sp->ttis[b];
-        result = ap->tt_gmtoff == bp->tt_gmtoff &&
-            ap->tt_isdst == bp->tt_isdst &&
-            ap->tt_ttisstd == bp->tt_ttisstd &&
-            ap->tt_ttisgmt == bp->tt_ttisgmt &&
-            strcmp(&sp->chars[ap->tt_abbrind],
-            &sp->chars[bp->tt_abbrind]) == 0;
-    }
-    return result;
-}
-
-static const int mon_lengths[2][MONSPERYEAR] = {
-    { 31, 28, 31, 30, 31, 30, 31, 31, 30, 31, 30, 31 },
-    { 31, 29, 31, 30, 31, 30, 31, 31, 30, 31, 30, 31 }
+  /* The entire buffer.  */
+  char buf[2 * sizeof(struct tzhead) + 2 * sizeof (struct state)
+	   + 4 * TZ_MAX_TIMES];
 };
 
-static const int year_lengths[2] = {
-    DAYSPERNYEAR, DAYSPERLYEAR
+/* Local storage needed for 'tzloadbody'.  */
+union local_storage {
+  /* The file name to be opened.  */
+  char fullname[FILENAME_MAX + 1];
+
+  /* The results of analyzing the file's contents after it is opened.  */
+  struct {
+    /* The input buffer.  */
+    union input_buffer u;
+
+    /* A temporary state used for parsing a TZ string in the file.  */
+    struct state st;
+  } u;
+};
+
+static int __bionic_open_tzdata(const char*);
+
+/* Load tz data from the file named NAME into *SP.  Read extended
+   format if DOEXTEND.  Use *LSP for temporary storage.  Return 0 on
+   success, an errno value on failure.  */
+static int
+tzloadbody(char const *name, struct state *sp, bool doextend,
+	   union local_storage *lsp)
+{
+	register int			i;
+	register int			fid;
+	register int			stored;
+	register ssize_t		nread;
+#if !defined(__ANDROID__)
+	register bool doaccess;
+	register char *fullname = lsp->fullname;
+#endif
+	register union input_buffer *up = &lsp->u.u;
+	register int tzheadsize = sizeof (struct tzhead);
+
+	sp->goback = sp->goahead = false;
+
+	if (! name) {
+		name = TZDEFAULT;
+		if (! name)
+		  return EINVAL;
+	}
+
+#if defined(__ANDROID__)
+	fid = __bionic_open_tzdata(name);
+#else
+	if (name[0] == ':')
+		++name;
+	doaccess = name[0] == '/';
+	if (!doaccess) {
+		char const *p = TZDIR;
+		if (! p)
+		  return EINVAL;
+		if (sizeof lsp->fullname - 1 <= strlen(p) + strlen(name))
+		  return ENAMETOOLONG;
+		strcpy(fullname, p);
+		strcat(fullname, "/");
+		strcat(fullname, name);
+		/* Set doaccess if '.' (as in "../") shows up in name.  */
+		if (strchr(name, '.'))
+			doaccess = true;
+		name = fullname;
+	}
+	if (doaccess && access(name, R_OK) != 0)
+	  return errno;
+	fid = open(name, OPEN_MODE);
+#endif
+	if (fid < 0)
+	  return errno;
+
+	nread = read(fid, up->buf, sizeof up->buf);
+	if (nread < tzheadsize) {
+	  int err = nread < 0 ? errno : EINVAL;
+	  close(fid);
+	  return err;
+	}
+	if (close(fid) < 0)
+	  return errno;
+	for (stored = 4; stored <= 8; stored *= 2) {
+		int_fast32_t ttisstdcnt = detzcode(up->tzhead.tzh_ttisstdcnt);
+		int_fast32_t ttisgmtcnt = detzcode(up->tzhead.tzh_ttisgmtcnt);
+		int_fast32_t leapcnt = detzcode(up->tzhead.tzh_leapcnt);
+		int_fast32_t timecnt = detzcode(up->tzhead.tzh_timecnt);
+		int_fast32_t typecnt = detzcode(up->tzhead.tzh_typecnt);
+		int_fast32_t charcnt = detzcode(up->tzhead.tzh_charcnt);
+		char const *p = up->buf + tzheadsize;
+		if (! (0 <= leapcnt && leapcnt < TZ_MAX_LEAPS
+		       && 0 < typecnt && typecnt < TZ_MAX_TYPES
+		       && 0 <= timecnt && timecnt < TZ_MAX_TIMES
+		       && 0 <= charcnt && charcnt < TZ_MAX_CHARS
+		       && (ttisstdcnt == typecnt || ttisstdcnt == 0)
+		       && (ttisgmtcnt == typecnt || ttisgmtcnt == 0)))
+		  return EINVAL;
+		if (nread
+		    < (tzheadsize		/* struct tzhead */
+		       + timecnt * stored	/* ats */
+		       + timecnt		/* types */
+		       + typecnt * 6		/* ttinfos */
+		       + charcnt		/* chars */
+		       + leapcnt * (stored + 4)	/* lsinfos */
+		       + ttisstdcnt		/* ttisstds */
+		       + ttisgmtcnt))		/* ttisgmts */
+		  return EINVAL;
+		sp->leapcnt = leapcnt;
+		sp->timecnt = timecnt;
+		sp->typecnt = typecnt;
+		sp->charcnt = charcnt;
+
+		/* Read transitions, discarding those out of time_t range.
+		   But pretend the last transition before time_t_min
+		   occurred at time_t_min.  */
+		timecnt = 0;
+		for (i = 0; i < sp->timecnt; ++i) {
+			int_fast64_t at
+			  = stored == 4 ? detzcode(p) : detzcode64(p);
+			sp->types[i] = at <= time_t_max;
+			if (sp->types[i]) {
+			  time_t attime
+			    = ((TYPE_SIGNED(time_t) ? at < time_t_min : at < 0)
+			       ? time_t_min : at);
+			  if (timecnt && attime <= sp->ats[timecnt - 1]) {
+			    if (attime < sp->ats[timecnt - 1])
+			      return EINVAL;
+			    sp->types[i - 1] = 0;
+			    timecnt--;
+			  }
+			  sp->ats[timecnt++] = attime;
+			}
+			p += stored;
+		}
+
+		timecnt = 0;
+		for (i = 0; i < sp->timecnt; ++i) {
+			unsigned char typ = *p++;
+			if (sp->typecnt <= typ)
+			  return EINVAL;
+			if (sp->types[i])
+				sp->types[timecnt++] = typ;
+		}
+		sp->timecnt = timecnt;
+		for (i = 0; i < sp->typecnt; ++i) {
+			register struct ttinfo *	ttisp;
+			unsigned char isdst, abbrind;
+
+			ttisp = &sp->ttis[i];
+			ttisp->tt_gmtoff = detzcode(p);
+			p += 4;
+			isdst = *p++;
+			if (! (isdst < 2))
+			  return EINVAL;
+			ttisp->tt_isdst = isdst;
+			abbrind = *p++;
+			if (! (abbrind < sp->charcnt))
+			  return EINVAL;
+			ttisp->tt_abbrind = abbrind;
+		}
+		for (i = 0; i < sp->charcnt; ++i)
+			sp->chars[i] = *p++;
+		sp->chars[i] = '\0';	/* ensure '\0' at end */
+
+		/* Read leap seconds, discarding those out of time_t range.  */
+		leapcnt = 0;
+		for (i = 0; i < sp->leapcnt; ++i) {
+		  int_fast64_t tr = stored == 4 ? detzcode(p) : detzcode64(p);
+		  int_fast32_t corr = detzcode(p + stored);
+		  p += stored + 4;
+		  if (tr <= time_t_max) {
+		    time_t trans
+		      = ((TYPE_SIGNED(time_t) ? tr < time_t_min : tr < 0)
+			 ? time_t_min : tr);
+		    if (leapcnt && trans <= sp->lsis[leapcnt - 1].ls_trans) {
+		      if (trans < sp->lsis[leapcnt - 1].ls_trans)
+			return EINVAL;
+		      leapcnt--;
+		    }
+		    sp->lsis[leapcnt].ls_trans = trans;
+		    sp->lsis[leapcnt].ls_corr = corr;
+		    leapcnt++;
+		  }
+		}
+		sp->leapcnt = leapcnt;
+
+		for (i = 0; i < sp->typecnt; ++i) {
+			register struct ttinfo *	ttisp;
+
+			ttisp = &sp->ttis[i];
+			if (ttisstdcnt == 0)
+				ttisp->tt_ttisstd = false;
+			else {
+				if (*p != true && *p != false)
+				  return EINVAL;
+				ttisp->tt_ttisstd = *p++;
+			}
+		}
+		for (i = 0; i < sp->typecnt; ++i) {
+			register struct ttinfo *	ttisp;
+
+			ttisp = &sp->ttis[i];
+			if (ttisgmtcnt == 0)
+				ttisp->tt_ttisgmt = false;
+			else {
+				if (*p != true && *p != false)
+						return EINVAL;
+				ttisp->tt_ttisgmt = *p++;
+			}
+		}
+		/*
+		** If this is an old file, we're done.
+		*/
+		if (up->tzhead.tzh_version[0] == '\0')
+			break;
+		nread -= p - up->buf;
+		memmove(up->buf, p, nread);
+	}
+	if (doextend && nread > 2 &&
+		up->buf[0] == '\n' && up->buf[nread - 1] == '\n' &&
+		sp->typecnt + 2 <= TZ_MAX_TYPES) {
+			struct state	*ts = &lsp->u.st;
+
+			up->buf[nread - 1] = '\0';
+			if (tzparse(&up->buf[1], ts, false)
+			    && ts->typecnt == 2) {
+
+			  /* Attempt to reuse existing abbreviations.
+			     Without this, America/Anchorage would stop
+			     working after 2037 when TZ_MAX_CHARS is 50, as
+			     sp->charcnt equals 42 (for LMT CAT CAWT CAPT AHST
+			     AHDT YST AKDT AKST) and ts->charcnt equals 10
+			     (for AKST AKDT).  Reusing means sp->charcnt can
+			     stay 42 in this example.  */
+			  int gotabbr = 0;
+			  int charcnt = sp->charcnt;
+			  for (i = 0; i < 2; i++) {
+			    char *tsabbr = ts->chars + ts->ttis[i].tt_abbrind;
+			    int j;
+			    for (j = 0; j < charcnt; j++)
+			      if (strcmp(sp->chars + j, tsabbr) == 0) {
+				ts->ttis[i].tt_abbrind = j;
+				gotabbr++;
+				break;
+			      }
+			    if (! (j < charcnt)) {
+			      int tsabbrlen = strlen(tsabbr);
+			      if (j + tsabbrlen < TZ_MAX_CHARS) {
+				strcpy(sp->chars + j, tsabbr);
+				charcnt = j + tsabbrlen + 1;
+				ts->ttis[i].tt_abbrind = j;
+				gotabbr++;
+			      }
+			    }
+			  }
+			  if (gotabbr == 2) {
+			    sp->charcnt = charcnt;
+			    for (i = 0; i < ts->timecnt; i++)
+			      if (sp->ats[sp->timecnt - 1] < ts->ats[i])
+				break;
+			    while (i < ts->timecnt
+				   && sp->timecnt < TZ_MAX_TIMES) {
+			      sp->ats[sp->timecnt] = ts->ats[i];
+			      sp->types[sp->timecnt] = (sp->typecnt
+							+ ts->types[i]);
+			      sp->timecnt++;
+			      i++;
+			    }
+			    sp->ttis[sp->typecnt++] = ts->ttis[0];
+			    sp->ttis[sp->typecnt++] = ts->ttis[1];
+			  }
+			}
+	}
+	if (sp->timecnt > 1) {
+		for (i = 1; i < sp->timecnt; ++i)
+			if (typesequiv(sp, sp->types[i], sp->types[0]) &&
+				differ_by_repeat(sp->ats[i], sp->ats[0])) {
+					sp->goback = true;
+					break;
+				}
+		for (i = sp->timecnt - 2; i >= 0; --i)
+			if (typesequiv(sp, sp->types[sp->timecnt - 1],
+				sp->types[i]) &&
+				differ_by_repeat(sp->ats[sp->timecnt - 1],
+				sp->ats[i])) {
+					sp->goahead = true;
+					break;
+		}
+	}
+	/*
+	** If type 0 is is unused in transitions,
+	** it's the type to use for early times.
+	*/
+	for (i = 0; i < sp->timecnt; ++i)
+		if (sp->types[i] == 0)
+			break;
+	i = i < sp->timecnt ? -1 : 0;
+	/*
+	** Absent the above,
+	** if there are transition times
+	** and the first transition is to a daylight time
+	** find the standard type less than and closest to
+	** the type of the first transition.
+	*/
+	if (i < 0 && sp->timecnt > 0 && sp->ttis[sp->types[0]].tt_isdst) {
+		i = sp->types[0];
+		while (--i >= 0)
+			if (!sp->ttis[i].tt_isdst)
+				break;
+	}
+	/*
+	** If no result yet, find the first standard type.
+	** If there is none, punt to type zero.
+	*/
+	if (i < 0) {
+		i = 0;
+		while (sp->ttis[i].tt_isdst)
+			if (++i >= sp->typecnt) {
+				i = 0;
+				break;
+			}
+	}
+	sp->defaulttype = i;
+	return 0;
+}
+
+/* Load tz data from the file named NAME into *SP.  Read extended
+   format if DOEXTEND.  Return 0 on success, an errno value on failure.  */
+static int
+tzload(char const *name, struct state *sp, bool doextend)
+{
+#ifdef ALL_STATE
+  union local_storage *lsp = malloc(sizeof *lsp);
+  if (!lsp)
+    return errno;
+  else {
+    int err = tzloadbody(name, sp, doextend, lsp);
+    free(lsp);
+    return err;
+  }
+#else
+  union local_storage ls;
+  return tzloadbody(name, sp, doextend, &ls);
+#endif
+}
+
+static bool
+typesequiv(const struct state *sp, int a, int b)
+{
+	register bool result;
+
+	if (sp == NULL ||
+		a < 0 || a >= sp->typecnt ||
+		b < 0 || b >= sp->typecnt)
+			result = false;
+	else {
+		register const struct ttinfo *	ap = &sp->ttis[a];
+		register const struct ttinfo *	bp = &sp->ttis[b];
+		result = ap->tt_gmtoff == bp->tt_gmtoff &&
+			ap->tt_isdst == bp->tt_isdst &&
+			ap->tt_ttisstd == bp->tt_ttisstd &&
+			ap->tt_ttisgmt == bp->tt_ttisgmt &&
+			strcmp(&sp->chars[ap->tt_abbrind],
+			&sp->chars[bp->tt_abbrind]) == 0;
+	}
+	return result;
+}
+
+static const int	mon_lengths[2][MONSPERYEAR] = {
+	{ 31, 28, 31, 30, 31, 30, 31, 31, 30, 31, 30, 31 },
+	{ 31, 29, 31, 30, 31, 30, 31, 31, 30, 31, 30, 31 }
+};
+
+static const int	year_lengths[2] = {
+	DAYSPERNYEAR, DAYSPERLYEAR
 };
 
 /*
@@ -658,15 +732,15 @@
 ** character.
 */
 
-static const char *
-getzname(register const char * strp)
+static const char * ATTRIBUTE_PURE
+getzname(register const char *strp)
 {
-    register char   c;
+	register char	c;
 
-    while ((c = *strp) != '\0' && !is_digit(c) && c != ',' && c != '-' &&
-        c != '+')
-            ++strp;
-    return strp;
+	while ((c = *strp) != '\0' && !is_digit(c) && c != ',' && c != '-' &&
+		c != '+')
+			++strp;
+	return strp;
 }
 
 /*
@@ -678,14 +752,14 @@
 ** We don't do any checking here; checking is done later in common-case code.
 */
 
-static const char *
+static const char * ATTRIBUTE_PURE
 getqzname(register const char *strp, const int delim)
 {
-    register int c;
+	register int	c;
 
-    while ((c = *strp) != '\0' && c != delim)
-        ++strp;
-    return strp;
+	while ((c = *strp) != '\0' && c != delim)
+		++strp;
+	return strp;
 }
 
 /*
@@ -696,24 +770,24 @@
 */
 
 static const char *
-getnum(register const char * strp, int * const nump, const int min, const int max)
+getnum(register const char *strp, int *const nump, const int min, const int max)
 {
-    register char c;
-    register int  num;
+	register char	c;
+	register int	num;
 
-    if (strp == NULL || !is_digit(c = *strp))
-        return NULL;
-    num = 0;
-    do {
-        num = num * 10 + (c - '0');
-        if (num > max)
-            return NULL;    /* illegal value */
-        c = *++strp;
-    } while (is_digit(c));
-    if (num < min)
-        return NULL;        /* illegal value */
-    *nump = num;
-    return strp;
+	if (strp == NULL || !is_digit(c = *strp))
+		return NULL;
+	num = 0;
+	do {
+		num = num * 10 + (c - '0');
+		if (num > max)
+			return NULL;	/* illegal value */
+		c = *++strp;
+	} while (is_digit(c));
+	if (num < min)
+		return NULL;		/* illegal value */
+	*nump = num;
+	return strp;
 }
 
 /*
@@ -727,34 +801,34 @@
 static const char *
 getsecs(register const char *strp, int_fast32_t *const secsp)
 {
-    int num;
+	int	num;
 
-    /*
-    ** 'HOURSPERDAY * DAYSPERWEEK - 1' allows quasi-Posix rules like
-    ** "M10.4.6/26", which does not conform to Posix,
-    ** but which specifies the equivalent of
-    ** "02:00 on the first Sunday on or after 23 Oct".
-    */
-    strp = getnum(strp, &num, 0, HOURSPERDAY * DAYSPERWEEK - 1);
-    if (strp == NULL)
-        return NULL;
-    *secsp = num * (int_fast32_t) SECSPERHOUR;
-    if (*strp == ':') {
-        ++strp;
-        strp = getnum(strp, &num, 0, MINSPERHOUR - 1);
-        if (strp == NULL)
-            return NULL;
-        *secsp += num * SECSPERMIN;
-        if (*strp == ':') {
-            ++strp;
-            /* 'SECSPERMIN' allows for leap seconds. */
-            strp = getnum(strp, &num, 0, SECSPERMIN);
-            if (strp == NULL)
-                return NULL;
-            *secsp += num;
-        }
-    }
-    return strp;
+	/*
+	** 'HOURSPERDAY * DAYSPERWEEK - 1' allows quasi-Posix rules like
+	** "M10.4.6/26", which does not conform to Posix,
+	** but which specifies the equivalent of
+	** "02:00 on the first Sunday on or after 23 Oct".
+	*/
+	strp = getnum(strp, &num, 0, HOURSPERDAY * DAYSPERWEEK - 1);
+	if (strp == NULL)
+		return NULL;
+	*secsp = num * (int_fast32_t) SECSPERHOUR;
+	if (*strp == ':') {
+		++strp;
+		strp = getnum(strp, &num, 0, MINSPERHOUR - 1);
+		if (strp == NULL)
+			return NULL;
+		*secsp += num * SECSPERMIN;
+		if (*strp == ':') {
+			++strp;
+			/* 'SECSPERMIN' allows for leap seconds.  */
+			strp = getnum(strp, &num, 0, SECSPERMIN);
+			if (strp == NULL)
+				return NULL;
+			*secsp += num;
+		}
+	}
+	return strp;
 }
 
 /*
@@ -767,19 +841,19 @@
 static const char *
 getoffset(register const char *strp, int_fast32_t *const offsetp)
 {
-    register int neg = 0;
+	register bool neg = false;
 
-    if (*strp == '-') {
-        neg = 1;
-        ++strp;
-    } else if (*strp == '+')
-        ++strp;
-    strp = getsecs(strp, offsetp);
-    if (strp == NULL)
-        return NULL;        /* illegal time */
-    if (neg)
-        *offsetp = -*offsetp;
-    return strp;
+	if (*strp == '-') {
+		neg = true;
+		++strp;
+	} else if (*strp == '+')
+		++strp;
+	strp = getsecs(strp, offsetp);
+	if (strp == NULL)
+		return NULL;		/* illegal time */
+	if (neg)
+		*offsetp = -*offsetp;
+	return strp;
 }
 
 /*
@@ -790,49 +864,49 @@
 */
 
 static const char *
-getrule(const char * strp, register struct rule * const rulep)
+getrule(const char *strp, register struct rule *const rulep)
 {
-    if (*strp == 'J') {
-        /*
-        ** Julian day.
-        */
-        rulep->r_type = JULIAN_DAY;
-        ++strp;
-        strp = getnum(strp, &rulep->r_day, 1, DAYSPERNYEAR);
-    } else if (*strp == 'M') {
-        /*
-        ** Month, week, day.
-        */
-        rulep->r_type = MONTH_NTH_DAY_OF_WEEK;
-        ++strp;
-        strp = getnum(strp, &rulep->r_mon, 1, MONSPERYEAR);
-        if (strp == NULL)
-            return NULL;
-        if (*strp++ != '.')
-            return NULL;
-        strp = getnum(strp, &rulep->r_week, 1, 5);
-        if (strp == NULL)
-            return NULL;
-        if (*strp++ != '.')
-            return NULL;
-        strp = getnum(strp, &rulep->r_day, 0, DAYSPERWEEK - 1);
-    } else if (is_digit(*strp)) {
-        /*
-        ** Day of year.
-        */
-        rulep->r_type = DAY_OF_YEAR;
-        strp = getnum(strp, &rulep->r_day, 0, DAYSPERLYEAR - 1);
-    } else  return NULL;        /* invalid format */
-    if (strp == NULL)
-        return NULL;
-    if (*strp == '/') {
-        /*
-        ** Time specified.
-        */
-        ++strp;
-        strp = getoffset(strp, &rulep->r_time);
-    } else  rulep->r_time = 2 * SECSPERHOUR;    /* default = 2:00:00 */
-    return strp;
+	if (*strp == 'J') {
+		/*
+		** Julian day.
+		*/
+		rulep->r_type = JULIAN_DAY;
+		++strp;
+		strp = getnum(strp, &rulep->r_day, 1, DAYSPERNYEAR);
+	} else if (*strp == 'M') {
+		/*
+		** Month, week, day.
+		*/
+		rulep->r_type = MONTH_NTH_DAY_OF_WEEK;
+		++strp;
+		strp = getnum(strp, &rulep->r_mon, 1, MONSPERYEAR);
+		if (strp == NULL)
+			return NULL;
+		if (*strp++ != '.')
+			return NULL;
+		strp = getnum(strp, &rulep->r_week, 1, 5);
+		if (strp == NULL)
+			return NULL;
+		if (*strp++ != '.')
+			return NULL;
+		strp = getnum(strp, &rulep->r_day, 0, DAYSPERWEEK - 1);
+	} else if (is_digit(*strp)) {
+		/*
+		** Day of year.
+		*/
+		rulep->r_type = DAY_OF_YEAR;
+		strp = getnum(strp, &rulep->r_day, 0, DAYSPERLYEAR - 1);
+	} else	return NULL;		/* invalid format */
+	if (strp == NULL)
+		return NULL;
+	if (*strp == '/') {
+		/*
+		** Time specified.
+		*/
+		++strp;
+		strp = getoffset(strp, &rulep->r_time);
+	} else	rulep->r_time = 2 * SECSPERHOUR;	/* default = 2:00:00 */
+	return strp;
 }
 
 /*
@@ -840,11 +914,11 @@
 ** effect, calculate the year-relative time that rule takes effect.
 */
 
-static int_fast32_t
+static int_fast32_t ATTRIBUTE_PURE
 transtime(const int year, register const struct rule *const rulep,
           const int_fast32_t offset)
 {
-    register int          leapyear;
+    register bool         leapyear;
     register int_fast32_t value;
     register int          i;
     int d, m1, yy0, yy1, yy2, dow;
@@ -931,457 +1005,542 @@
 ** appropriate.
 */
 
-static int
-tzparse(const char * name, register struct state * const sp,
-        const int lastditch)
+static bool
+tzparse(const char *name, struct state *sp, bool lastditch)
 {
-    const char *         stdname;
-    const char *         dstname;
-    size_t               stdlen;
-    size_t               dstlen;
-    int_fast32_t         stdoffset;
-    int_fast32_t         dstoffset;
-    register char *      cp;
-    register int         load_result;
-    static struct ttinfo zttinfo;
+	const char *			stdname;
+	const char *			dstname;
+	size_t				stdlen;
+	size_t				dstlen;
+	size_t				charcnt;
+	int_fast32_t			stdoffset;
+	int_fast32_t			dstoffset;
+	register char *			cp;
+	register bool			load_ok;
 
-    stdname = name;
-    if (lastditch) {
-        stdlen = strlen(name);  /* length of standard zone name */
-        name += stdlen;
-        if (stdlen >= sizeof sp->chars)
-            stdlen = (sizeof sp->chars) - 1;
-        stdoffset = 0;
-    } else {
-        if (*name == '<') {
-            name++;
-            stdname = name;
-            name = getqzname(name, '>');
-            if (*name != '>')
-                return (-1);
-            stdlen = name - stdname;
-            name++;
-        } else {
-            name = getzname(name);
-            stdlen = name - stdname;
-        }
-        if (*name == '\0')
-            return -1;
-        name = getoffset(name, &stdoffset);
-        if (name == NULL)
-            return -1;
-    }
-    load_result = tzload(TZDEFRULES, sp, FALSE);
-    if (load_result != 0)
-        sp->leapcnt = 0;        /* so, we're off a little */
-    if (*name != '\0') {
-        if (*name == '<') {
-            dstname = ++name;
-            name = getqzname(name, '>');
-            if (*name != '>')
-                return -1;
-            dstlen = name - dstname;
-            name++;
-        } else {
-            dstname = name;
-            name = getzname(name);
-            dstlen = name - dstname; /* length of DST zone name */
-        }
-        if (*name != '\0' && *name != ',' && *name != ';') {
-            name = getoffset(name, &dstoffset);
-            if (name == NULL)
-                return -1;
-        } else  dstoffset = stdoffset - SECSPERHOUR;
-        if (*name == '\0' && load_result != 0)
-            name = TZDEFRULESTRING;
-        if (*name == ',' || *name == ';') {
-            struct rule  start;
-            struct rule  end;
-            register int year;
-            register int yearlim;
-            register int timecnt;
-            time_t       janfirst;
+	stdname = name;
+	if (lastditch) {
+		stdlen = sizeof gmt - 1;
+		name += stdlen;
+		stdoffset = 0;
+	} else {
+		if (*name == '<') {
+			name++;
+			stdname = name;
+			name = getqzname(name, '>');
+			if (*name != '>')
+			  return false;
+			stdlen = name - stdname;
+			name++;
+		} else {
+			name = getzname(name);
+			stdlen = name - stdname;
+		}
+		if (!stdlen)
+		  return false;
+		name = getoffset(name, &stdoffset);
+		if (name == NULL)
+		  return false;
+	}
+	charcnt = stdlen + 1;
+	if (sizeof sp->chars < charcnt)
+	  return false;
+	load_ok = tzload(TZDEFRULES, sp, false) == 0;
+	if (!load_ok)
+		sp->leapcnt = 0;		/* so, we're off a little */
+	if (*name != '\0') {
+		if (*name == '<') {
+			dstname = ++name;
+			name = getqzname(name, '>');
+			if (*name != '>')
+			  return false;
+			dstlen = name - dstname;
+			name++;
+		} else {
+			dstname = name;
+			name = getzname(name);
+			dstlen = name - dstname; /* length of DST zone name */
+		}
+		if (!dstlen)
+		  return false;
+		charcnt += dstlen + 1;
+		if (sizeof sp->chars < charcnt)
+		  return false;
+		if (*name != '\0' && *name != ',' && *name != ';') {
+			name = getoffset(name, &dstoffset);
+			if (name == NULL)
+			  return false;
+		} else	dstoffset = stdoffset - SECSPERHOUR;
+		if (*name == '\0' && !load_ok)
+			name = TZDEFRULESTRING;
+		if (*name == ',' || *name == ';') {
+			struct rule	start;
+			struct rule	end;
+			register int	year;
+			register int	yearlim;
+			register int	timecnt;
+			time_t		janfirst;
 
-            ++name;
-            if ((name = getrule(name, &start)) == NULL)
-                return -1;
-            if (*name++ != ',')
-                return -1;
-            if ((name = getrule(name, &end)) == NULL)
-                return -1;
-            if (*name != '\0')
-                return -1;
-            sp->typecnt = 2;    /* standard time and DST */
-            /*
-            ** Two transitions per year, from EPOCH_YEAR forward.
-            */
-            sp->ttis[0] = sp->ttis[1] = zttinfo;
-            sp->ttis[0].tt_gmtoff = -dstoffset;
-            sp->ttis[0].tt_isdst = 1;
-            sp->ttis[0].tt_abbrind = stdlen + 1;
-            sp->ttis[1].tt_gmtoff = -stdoffset;
-            sp->ttis[1].tt_isdst = 0;
-            sp->ttis[1].tt_abbrind = 0;
-            sp->defaulttype = 0;
-            timecnt = 0;
-            janfirst = 0;
-            yearlim = EPOCH_YEAR + YEARSPERREPEAT;
-            for (year = EPOCH_YEAR; year < yearlim; year++) {
-                int_fast32_t
-                  starttime = transtime(year, &start, stdoffset),
-                  endtime = transtime(year, &end, dstoffset);
-                int_fast32_t
-                yearsecs = (year_lengths[isleap(year)]
-                            * SECSPERDAY);
-                int reversed = endtime < starttime;
-                if (reversed) {
-                    int_fast32_t swap = starttime;
-                    starttime = endtime;
-                    endtime = swap;
-                }
-                if (reversed
-                    || (starttime < endtime
-                        && (endtime - starttime
-                            < (yearsecs
-                               + (stdoffset - dstoffset))))) {
-                    if (TZ_MAX_TIMES - 2 < timecnt)
-                        break;
-                    yearlim = year + YEARSPERREPEAT + 1;
-                    sp->ats[timecnt] = janfirst;
-                    if (increment_overflow_time
-                        (&sp->ats[timecnt], starttime))
-                        break;
-                    sp->types[timecnt++] = reversed;
-                    sp->ats[timecnt] = janfirst;
-                    if (increment_overflow_time
-                        (&sp->ats[timecnt], endtime))
-                        break;
-                    sp->types[timecnt++] = !reversed;
-                    }
-                if (increment_overflow_time(&janfirst, yearsecs))
-                    break;
-            }
-            sp->timecnt = timecnt;
-            if (!timecnt)
-                sp->typecnt = 1;    /* Perpetual DST.  */
-        } else {
-            register int_fast32_t   theirstdoffset;
-            register int_fast32_t   theirdstoffset;
-            register int_fast32_t   theiroffset;
-            register int    isdst;
-            register int    i;
-            register int    j;
+			++name;
+			if ((name = getrule(name, &start)) == NULL)
+			  return false;
+			if (*name++ != ',')
+			  return false;
+			if ((name = getrule(name, &end)) == NULL)
+			  return false;
+			if (*name != '\0')
+			  return false;
+			sp->typecnt = 2;	/* standard time and DST */
+			/*
+			** Two transitions per year, from EPOCH_YEAR forward.
+			*/
+			init_ttinfo(&sp->ttis[0], -dstoffset, true, stdlen + 1);
+			init_ttinfo(&sp->ttis[1], -stdoffset, false, 0);
+			sp->defaulttype = 0;
+			timecnt = 0;
+			janfirst = 0;
+			yearlim = EPOCH_YEAR + YEARSPERREPEAT;
+			for (year = EPOCH_YEAR; year < yearlim; year++) {
+				int_fast32_t
+				  starttime = transtime(year, &start, stdoffset),
+				  endtime = transtime(year, &end, dstoffset);
+				int_fast32_t
+				  yearsecs = (year_lengths[isleap(year)]
+					      * SECSPERDAY);
+				bool reversed = endtime < starttime;
+				if (reversed) {
+					int_fast32_t swap = starttime;
+					starttime = endtime;
+					endtime = swap;
+				}
+				if (reversed
+				    || (starttime < endtime
+					&& (endtime - starttime
+					    < (yearsecs
+					       + (stdoffset - dstoffset))))) {
+					if (TZ_MAX_TIMES - 2 < timecnt)
+						break;
+					yearlim = year + YEARSPERREPEAT + 1;
+					sp->ats[timecnt] = janfirst;
+					if (increment_overflow_time
+					    (&sp->ats[timecnt], starttime))
+						break;
+					sp->types[timecnt++] = reversed;
+					sp->ats[timecnt] = janfirst;
+					if (increment_overflow_time
+					    (&sp->ats[timecnt], endtime))
+						break;
+					sp->types[timecnt++] = !reversed;
+				}
+				if (increment_overflow_time(&janfirst, yearsecs))
+					break;
+			}
+			sp->timecnt = timecnt;
+			if (!timecnt)
+				sp->typecnt = 1;	/* Perpetual DST.  */
+		} else {
+			register int_fast32_t	theirstdoffset;
+			register int_fast32_t	theirdstoffset;
+			register int_fast32_t	theiroffset;
+			register bool		isdst;
+			register int		i;
+			register int		j;
 
-            if (*name != '\0')
-                return -1;
-            /*
-            ** Initial values of theirstdoffset and theirdstoffset.
-            */
-            theirstdoffset = 0;
-            for (i = 0; i < sp->timecnt; ++i) {
-                j = sp->types[i];
-                if (!sp->ttis[j].tt_isdst) {
-                    theirstdoffset =
-                        -sp->ttis[j].tt_gmtoff;
-                    break;
-                }
-            }
-            theirdstoffset = 0;
-            for (i = 0; i < sp->timecnt; ++i) {
-                j = sp->types[i];
-                if (sp->ttis[j].tt_isdst) {
-                    theirdstoffset =
-                        -sp->ttis[j].tt_gmtoff;
-                    break;
-                }
-            }
-            /*
-            ** Initially we're assumed to be in standard time.
-            */
-            isdst = FALSE;
-            theiroffset = theirstdoffset;
-            /*
-            ** Now juggle transition times and types
-            ** tracking offsets as you do.
-            */
-            for (i = 0; i < sp->timecnt; ++i) {
-                j = sp->types[i];
-                sp->types[i] = sp->ttis[j].tt_isdst;
-                if (sp->ttis[j].tt_ttisgmt) {
-                    /* No adjustment to transition time */
-                } else {
-                    /*
-                    ** If summer time is in effect, and the
-                    ** transition time was not specified as
-                    ** standard time, add the summer time
-                    ** offset to the transition time;
-                    ** otherwise, add the standard time
-                    ** offset to the transition time.
-                    */
-                    /*
-                    ** Transitions from DST to DDST
-                    ** will effectively disappear since
-                    ** POSIX provides for only one DST
-                    ** offset.
-                    */
-                    if (isdst && !sp->ttis[j].tt_ttisstd) {
-                        sp->ats[i] += dstoffset -
-                            theirdstoffset;
-                    } else {
-                        sp->ats[i] += stdoffset -
-                            theirstdoffset;
-                    }
-                }
-                theiroffset = -sp->ttis[j].tt_gmtoff;
-                if (sp->ttis[j].tt_isdst)
-                    theirdstoffset = theiroffset;
-                else    theirstdoffset = theiroffset;
-            }
-            /*
-            ** Finally, fill in ttis.
-            */
-            sp->ttis[0] = sp->ttis[1] = zttinfo;
-            sp->ttis[0].tt_gmtoff = -stdoffset;
-            sp->ttis[0].tt_isdst = FALSE;
-            sp->ttis[0].tt_abbrind = 0;
-            sp->ttis[1].tt_gmtoff = -dstoffset;
-            sp->ttis[1].tt_isdst = TRUE;
-            sp->ttis[1].tt_abbrind = stdlen + 1;
-            sp->typecnt = 2;
-            sp->defaulttype = 0;
-        }
-    } else {
-        dstlen = 0;
-        sp->typecnt = 1;        /* only standard time */
-        sp->timecnt = 0;
-        sp->ttis[0] = zttinfo;
-        sp->ttis[0].tt_gmtoff = -stdoffset;
-        sp->ttis[0].tt_isdst = 0;
-        sp->ttis[0].tt_abbrind = 0;
-        sp->defaulttype = 0;
-    }
-    sp->charcnt = stdlen + 1;
-    if (dstlen != 0)
-        sp->charcnt += dstlen + 1;
-    if ((size_t) sp->charcnt > sizeof sp->chars)
-        return -1;
-    cp = sp->chars;
-    (void) strncpy(cp, stdname, stdlen);
-    cp += stdlen;
-    *cp++ = '\0';
-    if (dstlen != 0) {
-        (void) strncpy(cp, dstname, dstlen);
-        *(cp + dstlen) = '\0';
-    }
-    return 0;
+			if (*name != '\0')
+			  return false;
+			/*
+			** Initial values of theirstdoffset and theirdstoffset.
+			*/
+			theirstdoffset = 0;
+			for (i = 0; i < sp->timecnt; ++i) {
+				j = sp->types[i];
+				if (!sp->ttis[j].tt_isdst) {
+					theirstdoffset =
+						-sp->ttis[j].tt_gmtoff;
+					break;
+				}
+			}
+			theirdstoffset = 0;
+			for (i = 0; i < sp->timecnt; ++i) {
+				j = sp->types[i];
+				if (sp->ttis[j].tt_isdst) {
+					theirdstoffset =
+						-sp->ttis[j].tt_gmtoff;
+					break;
+				}
+			}
+			/*
+			** Initially we're assumed to be in standard time.
+			*/
+			isdst = false;
+			theiroffset = theirstdoffset;
+			/*
+			** Now juggle transition times and types
+			** tracking offsets as you do.
+			*/
+			for (i = 0; i < sp->timecnt; ++i) {
+				j = sp->types[i];
+				sp->types[i] = sp->ttis[j].tt_isdst;
+				if (sp->ttis[j].tt_ttisgmt) {
+					/* No adjustment to transition time */
+				} else {
+					/*
+					** If summer time is in effect, and the
+					** transition time was not specified as
+					** standard time, add the summer time
+					** offset to the transition time;
+					** otherwise, add the standard time
+					** offset to the transition time.
+					*/
+					/*
+					** Transitions from DST to DDST
+					** will effectively disappear since
+					** POSIX provides for only one DST
+					** offset.
+					*/
+					if (isdst && !sp->ttis[j].tt_ttisstd) {
+						sp->ats[i] += dstoffset -
+							theirdstoffset;
+					} else {
+						sp->ats[i] += stdoffset -
+							theirstdoffset;
+					}
+				}
+				theiroffset = -sp->ttis[j].tt_gmtoff;
+				if (sp->ttis[j].tt_isdst)
+					theirdstoffset = theiroffset;
+				else	theirstdoffset = theiroffset;
+			}
+			/*
+			** Finally, fill in ttis.
+			*/
+			init_ttinfo(&sp->ttis[0], -stdoffset, false, 0);
+			init_ttinfo(&sp->ttis[1], -dstoffset, true, stdlen + 1);
+			sp->typecnt = 2;
+			sp->defaulttype = 0;
+		}
+	} else {
+		dstlen = 0;
+		sp->typecnt = 1;		/* only standard time */
+		sp->timecnt = 0;
+		init_ttinfo(&sp->ttis[0], -stdoffset, false, 0);
+		sp->defaulttype = 0;
+	}
+	sp->charcnt = charcnt;
+	cp = sp->chars;
+	memcpy(cp, stdname, stdlen);
+	cp += stdlen;
+	*cp++ = '\0';
+	if (dstlen != 0) {
+		memcpy(cp, dstname, dstlen);
+		*(cp + dstlen) = '\0';
+	}
+	return true;
 }
 
 static void
-gmtload(struct state * const sp)
+gmtload(struct state *const sp)
 {
-    if (tzload(gmt, sp, TRUE) != 0)
-        (void) tzparse(gmt, sp, TRUE);
+	if (tzload(gmt, sp, true) != 0)
+		tzparse(gmt, sp, true);
 }
 
-#ifndef STD_INSPIRED
-/*
-** A non-static declaration of tzsetwall in a system header file
-** may cause a warning about this upcoming static declaration...
-*/
-static
-#endif /* !defined STD_INSPIRED */
+/* Initialize *SP to a value appropriate for the TZ setting NAME.
+   Return 0 on success, an errno value on failure.  */
+static int
+zoneinit(struct state *sp, char const *name)
+{
+  if (name && ! name[0]) {
+    /*
+    ** User wants it fast rather than right.
+    */
+    sp->leapcnt = 0;		/* so, we're off a little */
+    sp->timecnt = 0;
+    sp->typecnt = 0;
+    sp->charcnt = 0;
+    sp->goback = sp->goahead = false;
+    init_ttinfo(&sp->ttis[0], 0, false, 0);
+    strcpy(sp->chars, gmt);
+    sp->defaulttype = 0;
+    return 0;
+  } else {
+    int err = tzload(name, sp, true);
+    if (err != 0 && name && name[0] != ':' && tzparse(name, sp, false))
+      err = 0;
+    if (err == 0)
+      scrub_abbrs(sp);
+    return err;
+  }
+}
+
+static void
+tzsetlcl(char const *name)
+{
+  struct state *sp = lclptr;
+  int lcl = name ? strlen(name) < sizeof lcl_TZname : -1;
+  if (lcl < 0
+      ? lcl_is_set < 0
+      : 0 < lcl_is_set && strcmp(lcl_TZname, name) == 0)
+    return;
+#ifdef ALL_STATE
+  if (! sp)
+    lclptr = sp = malloc(sizeof *lclptr);
+#endif /* defined ALL_STATE */
+  if (sp) {
+    if (zoneinit(sp, name) != 0)
+      zoneinit(sp, "");
+    if (0 < lcl)
+      strcpy(lcl_TZname, name);
+  }
+  settzname();
+  lcl_is_set = lcl;
+}
+
+#ifdef STD_INSPIRED
 void
 tzsetwall(void)
 {
-    if (lcl_is_set < 0)
-        return;
-    lcl_is_set = -1;
-
-#ifdef ALL_STATE
-    if (lclptr == NULL) {
-        lclptr = malloc(sizeof *lclptr);
-        if (lclptr == NULL) {
-            settzname();    /* all we can do */
-            return;
-        }
-    }
-#endif /* defined ALL_STATE */
-    if (tzload(NULL, lclptr, TRUE) != 0)
-        gmtload(lclptr);
-    settzname();
+  if (lock() != 0)
+    return;
+  tzsetlcl(NULL);
+  unlock();
 }
+#endif
 
-#include <sys/system_properties.h> // For __system_property_get.
+#if defined(__ANDROID__)
+#define _REALLY_INCLUDE_SYS__SYSTEM_PROPERTIES_H_
+#include <sys/_system_properties.h> // For __system_property_serial.
+#endif
 
 static void
-tzset_locked(void)
+tzset_unlocked(void)
 {
-    register const char * name;
+#if defined(__ANDROID__)
+  // The TZ environment variable is meant to override the system-wide setting.
+  const char * name = getenv("TZ");
 
-    name = getenv("TZ");
+  // If that's not set, look at the "persist.sys.timezone" system property.
+  if (name == NULL) {
+    static const prop_info *pi;
 
-    // try the "persist.sys.timezone" system property first
-    static char buf[PROP_VALUE_MAX];
-    if (name == NULL && __system_property_get("persist.sys.timezone", buf) > 0) {
+    if (!pi) {
+      pi = __system_property_find("persist.sys.timezone");
+    }
+    if (pi) {
+      static char buf[PROP_VALUE_MAX];
+      static uint32_t s = -1;
+      static bool ok = false;
+      uint32_t serial = __system_property_serial(pi);
+      if (serial != s) {
+        ok = __system_property_read(pi, 0, buf) > 0;
+        s = serial;
+      }
+      if (ok) {
         name = buf;
+      }
     }
+  }
 
-    if (name == NULL) {
-        tzsetwall();
-        return;
-    }
+  // If that's not available (because you're running AOSP on a WiFi-only
+  // device, say), fall back to GMT.
+  if (name == NULL) name = gmt;
 
-    if (lcl_is_set > 0 && strcmp(lcl_TZname, name) == 0)
-        return;
-    lcl_is_set = strlen(name) < sizeof lcl_TZname;
-    if (lcl_is_set)
-        (void) strcpy(lcl_TZname, name);
-
-#ifdef ALL_STATE
-    if (lclptr == NULL) {
-        lclptr = malloc(sizeof *lclptr);
-        if (lclptr == NULL) {
-            settzname();    /* all we can do */
-            return;
-        }
-    }
-#endif /* defined ALL_STATE */
-    if (*name == '\0') {
-        /*
-        ** User wants it fast rather than right.
-        */
-        lclptr->leapcnt = 0;        /* so, we're off a little */
-        lclptr->timecnt = 0;
-        lclptr->typecnt = 0;
-        lclptr->ttis[0].tt_isdst = 0;
-        lclptr->ttis[0].tt_gmtoff = 0;
-        lclptr->ttis[0].tt_abbrind = 0;
-        (void) strcpy(lclptr->chars, gmt);
-        lclptr->defaulttype = 0;
-    } else if (tzload(name, lclptr, TRUE) != 0)
-        if (name[0] == ':' || tzparse(name, lclptr, FALSE) != 0)
-            (void) gmtload(lclptr);
-    settzname();
+  tzsetlcl(name);
+#else
+  tzsetlcl(getenv("TZ"));
+#endif
 }
 
 void
 tzset(void)
 {
-    _tzLock();
-    tzset_locked();
-    _tzUnlock();
+  if (lock() != 0)
+    return;
+  tzset_unlocked();
+  unlock();
+}
+
+static void
+gmtcheck(void)
+{
+  static bool gmt_is_set;
+  if (lock() != 0)
+    return;
+  if (! gmt_is_set) {
+#ifdef ALL_STATE
+    gmtptr = malloc(sizeof *gmtptr);
+#endif
+    if (gmtptr)
+      gmtload(gmtptr);
+    gmt_is_set = true;
+  }
+  unlock();
+}
+
+#if NETBSD_INSPIRED
+
+timezone_t
+tzalloc(char const *name)
+{
+  timezone_t sp = malloc(sizeof *sp);
+  if (sp) {
+    int err = zoneinit(sp, name);
+    if (err != 0) {
+      free(sp);
+      errno = err;
+      return NULL;
+    }
+  }
+  return sp;
+}
+
+void
+tzfree(timezone_t sp)
+{
+  free(sp);
 }
 
 /*
+** NetBSD 6.1.4 has ctime_rz, but omit it because POSIX says ctime and
+** ctime_r are obsolescent and have potential security problems that
+** ctime_rz would share.  Callers can instead use localtime_rz + strftime.
+**
+** NetBSD 6.1.4 has tzgetname, but omit it because it doesn't work
+** in zones with three or more time zone abbreviations.
+** Callers can instead use localtime_rz + strftime.
+*/
+
+#endif
+
+/*
 ** The easy way to behave "as if no library function calls" localtime
-** is to not call it--so we drop its guts into "localsub", which can be
-** freely called. (And no, the PANS doesn't require the above behavior--
+** is to not call it, so we drop its guts into "localsub", which can be
+** freely called. (And no, the PANS doesn't require the above behavior,
 ** but it *is* desirable.)
 **
-** The unused offset argument is for the benefit of mktime variants.
+** If successful and SETNAME is nonzero,
+** set the applicable parts of tzname, timezone and altzone;
+** however, it's OK to omit this step if the time zone is POSIX-compatible,
+** since in that case tzset should have already done this step correctly.
+** SETNAME's type is intfast32_t for compatibility with gmtsub,
+** but it is actually a boolean and its value should be 0 or 1.
 */
 
 /*ARGSUSED*/
 static struct tm *
-localsub(const time_t * const timep, const int_fast32_t offset,
-         struct tm * const tmp, struct state * sp) // android-changed: added sp.
+localsub(struct state const *sp, time_t const *timep, int_fast32_t setname,
+	 struct tm *const tmp)
 {
-    register const struct ttinfo * ttisp;
-    register int         i;
-    register struct tm * result;
-    const time_t         t = *timep;
+	register const struct ttinfo *	ttisp;
+	register int			i;
+	register struct tm *		result;
+	const time_t			t = *timep;
 
-    // BEGIN android-changed: support user-supplied sp.
-    if (sp == NULL) {
-        sp = lclptr;
-    }
-    // END android-changed
-    if (sp == NULL)
-        return gmtsub(timep, offset, tmp, sp); // android-changed: added sp.
-    if ((sp->goback && t < sp->ats[0]) ||
-        (sp->goahead && t > sp->ats[sp->timecnt - 1])) {
-            time_t          newt = t;
-            register time_t seconds;
-            register time_t years;
+	if (sp == NULL) {
+	  /* Don't bother to set tzname etc.; tzset has already done it.  */
+	  return gmtsub(gmtptr, timep, 0, tmp);
+	}
+	if ((sp->goback && t < sp->ats[0]) ||
+		(sp->goahead && t > sp->ats[sp->timecnt - 1])) {
+			time_t			newt = t;
+			register time_t		seconds;
+			register time_t		years;
 
-            if (t < sp->ats[0])
-                seconds = sp->ats[0] - t;
-            else    seconds = t - sp->ats[sp->timecnt - 1];
-            --seconds;
-            years = (seconds / SECSPERREPEAT + 1) * YEARSPERREPEAT;
-            seconds = years * AVGSECSPERYEAR;
-            if (t < sp->ats[0])
-                newt += seconds;
-            else    newt -= seconds;
-            if (newt < sp->ats[0] ||
-                newt > sp->ats[sp->timecnt - 1])
-                    return NULL;    /* "cannot happen" */
-            result = localsub(&newt, offset, tmp, sp); // android-changed: added sp.
-            if (result == tmp) {
-                register time_t newy;
+			if (t < sp->ats[0])
+				seconds = sp->ats[0] - t;
+			else	seconds = t - sp->ats[sp->timecnt - 1];
+			--seconds;
+			years = (seconds / SECSPERREPEAT + 1) * YEARSPERREPEAT;
+			seconds = years * AVGSECSPERYEAR;
+			if (t < sp->ats[0])
+				newt += seconds;
+			else	newt -= seconds;
+			if (newt < sp->ats[0] ||
+				newt > sp->ats[sp->timecnt - 1])
+					return NULL;	/* "cannot happen" */
+			result = localsub(sp, &newt, setname, tmp);
+			if (result) {
+				register int_fast64_t newy;
 
-                newy = tmp->tm_year;
-                if (t < sp->ats[0])
-                    newy -= years;
-                else    newy += years;
-                tmp->tm_year = newy;
-                if (tmp->tm_year != newy)
-                    return NULL;
-            }
-            return result;
-    }
-    if (sp->timecnt == 0 || t < sp->ats[0]) {
-        i = sp->defaulttype;
-    } else {
-        register int lo = 1;
-        register int hi = sp->timecnt;
+				newy = result->tm_year;
+				if (t < sp->ats[0])
+					newy -= years;
+				else	newy += years;
+				if (! (INT_MIN <= newy && newy <= INT_MAX))
+					return NULL;
+				result->tm_year = newy;
+			}
+			return result;
+	}
+	if (sp->timecnt == 0 || t < sp->ats[0]) {
+		i = sp->defaulttype;
+	} else {
+		register int	lo = 1;
+		register int	hi = sp->timecnt;
 
-        while (lo < hi) {
-            register int    mid = (lo + hi) >> 1;
+		while (lo < hi) {
+			register int	mid = (lo + hi) >> 1;
 
-            if (t < sp->ats[mid])
-                hi = mid;
-            else    lo = mid + 1;
-        }
-        i = (int) sp->types[lo - 1];
-    }
-    ttisp = &sp->ttis[i];
-    /*
-    ** To get (wrong) behavior that's compatible with System V Release 2.0
-    ** you'd replace the statement below with
-    **  t += ttisp->tt_gmtoff;
-    **  timesub(&t, 0L, sp, tmp);
-    */
-    result = timesub(&t, ttisp->tt_gmtoff, sp, tmp);
-    tmp->tm_isdst = ttisp->tt_isdst;
-    tzname[tmp->tm_isdst] = &sp->chars[ttisp->tt_abbrind];
+			if (t < sp->ats[mid])
+				hi = mid;
+			else	lo = mid + 1;
+		}
+		i = (int) sp->types[lo - 1];
+	}
+	ttisp = &sp->ttis[i];
+	/*
+	** To get (wrong) behavior that's compatible with System V Release 2.0
+	** you'd replace the statement below with
+	**	t += ttisp->tt_gmtoff;
+	**	timesub(&t, 0L, sp, tmp);
+	*/
+	result = timesub(&t, ttisp->tt_gmtoff, sp, tmp);
+	if (result) {
+	  result->tm_isdst = ttisp->tt_isdst;
 #ifdef TM_ZONE
-    tmp->TM_ZONE = &sp->chars[ttisp->tt_abbrind];
+	  result->TM_ZONE = (char *) &sp->chars[ttisp->tt_abbrind];
 #endif /* defined TM_ZONE */
-    return result;
+	  if (setname)
+	    update_tzname_etc(sp, ttisp);
+	}
+	return result;
+}
+
+#if NETBSD_INSPIRED
+
+struct tm *
+localtime_rz(struct state *sp, time_t const *timep, struct tm *tmp)
+{
+  return localsub(sp, timep, 0, tmp);
+}
+
+#endif
+
+static struct tm *
+localtime_tzset(time_t const *timep, struct tm *tmp, bool setname)
+{
+  int err = lock();
+  if (err) {
+    errno = err;
+    return NULL;
+  }
+  if (setname || !lcl_is_set)
+    tzset_unlocked();
+  tmp = localsub(lclptr, timep, setname, tmp);
+  unlock();
+  return tmp;
 }
 
 struct tm *
-localtime(const time_t * const timep)
+localtime(const time_t *timep)
 {
-    return localtime_r(timep, &tmGlobal);
+  return localtime_tzset(timep, &tm, true);
 }
 
-/*
-** Re-entrant version of localtime.
-*/
-
 struct tm *
-localtime_r(const time_t * const timep, struct tm * tmp)
+localtime_r(const time_t *timep, struct tm *tmp)
 {
-    struct tm* result;
-
-    _tzLock();
-    tzset_locked();
-    result = localsub(timep, 0L, tmp, NULL); // android-changed: extra parameter.
-    _tzUnlock();
-
-    return result;
+  return localtime_tzset(timep, tmp, false);
 }
 
 /*
@@ -1389,37 +1548,22 @@
 */
 
 static struct tm *
-gmtsub(const time_t * const timep, const int_fast32_t offset,
-       struct tm *const tmp, struct state * sp __unused) // android-changed: added sp.
+gmtsub(struct state const *sp, time_t const *timep, int_fast32_t offset,
+       struct tm *tmp)
 {
-    register struct tm * result;
+	register struct tm *	result;
 
-    if (!gmt_is_set) {
-#ifdef ALL_STATE
-        gmtptr = malloc(sizeof *gmtptr);
-        gmt_is_set = gmtptr != NULL;
-#else
-        gmt_is_set = TRUE;
-#endif /* defined ALL_STATE */
-        if (gmt_is_set)
-            gmtload(gmtptr);
-    }
-    result = timesub(timep, offset, gmtptr, tmp);
+	result = timesub(timep, offset, gmtptr, tmp);
 #ifdef TM_ZONE
-    /*
-    ** Could get fancy here and deliver something such as
-    ** "UT+xxxx" or "UT-xxxx" if offset is non-zero,
-    ** but this is no time for a treasure hunt.
-    */
-    tmp->TM_ZONE = offset ? wildabbr : gmtptr ? gmtptr->chars : gmt;
+	/*
+	** Could get fancy here and deliver something such as
+	** "UT+xxxx" or "UT-xxxx" if offset is non-zero,
+	** but this is no time for a treasure hunt.
+	*/
+	tmp->TM_ZONE = ((char *)
+			(offset ? wildabbr : gmtptr ? gmtptr->chars : gmt));
 #endif /* defined TM_ZONE */
-    return result;
-}
-
-struct tm *
-gmtime(const time_t * const timep)
-{
-    return gmtime_r(timep, &tmGlobal);
+	return result;
 }
 
 /*
@@ -1427,23 +1571,25 @@
 */
 
 struct tm *
-gmtime_r(const time_t * const timep, struct tm * tmp)
+gmtime_r(const time_t *timep, struct tm *tmp)
 {
-    struct tm* result;
+  gmtcheck();
+  return gmtsub(gmtptr, timep, 0, tmp);
+}
 
-    _tzLock();
-    result = gmtsub(timep, 0L, tmp, NULL); // android-changed: extra parameter.
-    _tzUnlock();
-
-    return result;
+struct tm *
+gmtime(const time_t *timep)
+{
+  return gmtime_r(timep, &tm);
 }
 
 #ifdef STD_INSPIRED
 
 struct tm *
-offtime(const time_t *const timep, const long offset)
+offtime(const time_t *timep, long offset)
 {
-    return gmtsub(timep, offset, &tmGlobal, NULL); // android-changed: extra parameter.
+  gmtcheck();
+  return gmtsub(gmtptr, timep, offset, &tm);
 }
 
 #endif /* defined STD_INSPIRED */
@@ -1453,597 +1599,610 @@
 ** where, to make the math easy, the answer for year zero is defined as zero.
 */
 
-static int
+static int ATTRIBUTE_PURE
 leaps_thru_end_of(register const int y)
 {
-    return (y >= 0) ? (y / 4 - y / 100 + y / 400) :
-        -(leaps_thru_end_of(-(y + 1)) + 1);
+	return (y >= 0) ? (y / 4 - y / 100 + y / 400) :
+		-(leaps_thru_end_of(-(y + 1)) + 1);
 }
 
 static struct tm *
-timesub(const time_t *const timep, const int_fast32_t offset,
-        register const struct state *const sp,
-        register struct tm *const tmp)
+timesub(const time_t *timep, int_fast32_t offset,
+	const struct state *sp, struct tm *tmp)
 {
-    register const struct lsinfo * lp;
-    register time_t       tdays;
-    register int          idays;  /* unsigned would be so 2003 */
-    register int_fast64_t rem;
-    int                   y;
-    register const int *  ip;
-    register int_fast64_t corr;
-    register int          hit;
-    register int          i;
+	register const struct lsinfo *	lp;
+	register time_t			tdays;
+	register int			idays;	/* unsigned would be so 2003 */
+	register int_fast64_t		rem;
+	int				y;
+	register const int *		ip;
+	register int_fast64_t		corr;
+	register bool			hit;
+	register int			i;
 
-    corr = 0;
-    hit = 0;
-    i = (sp == NULL) ? 0 : sp->leapcnt;
-    while (--i >= 0) {
-        lp = &sp->lsis[i];
-        if (*timep >= lp->ls_trans) {
-            if (*timep == lp->ls_trans) {
-                hit = ((i == 0 && lp->ls_corr > 0) ||
-                    lp->ls_corr > sp->lsis[i - 1].ls_corr);
-                if (hit)
-                    while (i > 0 &&
-                        sp->lsis[i].ls_trans ==
-                        sp->lsis[i - 1].ls_trans + 1 &&
-                        sp->lsis[i].ls_corr ==
-                        sp->lsis[i - 1].ls_corr + 1) {
-                            ++hit;
-                            --i;
-                    }
-            }
-            corr = lp->ls_corr;
-            break;
-        }
-    }
-    y = EPOCH_YEAR;
-    tdays = *timep / SECSPERDAY;
-    rem = *timep - tdays * SECSPERDAY;
-    while (tdays < 0 || tdays >= year_lengths[isleap(y)]) {
-        int     newy;
-        register time_t tdelta;
-        register int    idelta;
-        register int    leapdays;
+	corr = 0;
+	hit = false;
+	i = (sp == NULL) ? 0 : sp->leapcnt;
+	while (--i >= 0) {
+		lp = &sp->lsis[i];
+		if (*timep >= lp->ls_trans) {
+			if (*timep == lp->ls_trans) {
+				hit = ((i == 0 && lp->ls_corr > 0) ||
+					lp->ls_corr > sp->lsis[i - 1].ls_corr);
+				if (hit)
+					while (i > 0 &&
+						sp->lsis[i].ls_trans ==
+						sp->lsis[i - 1].ls_trans + 1 &&
+						sp->lsis[i].ls_corr ==
+						sp->lsis[i - 1].ls_corr + 1) {
+							++hit;
+							--i;
+					}
+			}
+			corr = lp->ls_corr;
+			break;
+		}
+	}
+	y = EPOCH_YEAR;
+	tdays = *timep / SECSPERDAY;
+	rem = *timep % SECSPERDAY;
+	while (tdays < 0 || tdays >= year_lengths[isleap(y)]) {
+		int		newy;
+		register time_t	tdelta;
+		register int	idelta;
+		register int	leapdays;
 
-        tdelta = tdays / DAYSPERLYEAR;
-        if (! ((! TYPE_SIGNED(time_t) || INT_MIN <= tdelta)
-               && tdelta <= INT_MAX))
-                return NULL;
-        idelta = tdelta;
-        if (idelta == 0)
-            idelta = (tdays < 0) ? -1 : 1;
-        newy = y;
-        if (increment_overflow(&newy, idelta))
-            return NULL;
-        leapdays = leaps_thru_end_of(newy - 1) -
-            leaps_thru_end_of(y - 1);
-        tdays -= ((time_t) newy - y) * DAYSPERNYEAR;
-        tdays -= leapdays;
-        y = newy;
-    }
-    {
-        register int_fast32_t   seconds;
-
-        seconds = tdays * SECSPERDAY;
-        tdays = seconds / SECSPERDAY;
-        rem += seconds - tdays * SECSPERDAY;
-    }
-    /*
-    ** Given the range, we can now fearlessly cast...
-    */
-    idays = tdays;
-    rem += offset - corr;
-    while (rem < 0) {
-        rem += SECSPERDAY;
-        --idays;
-    }
-    while (rem >= SECSPERDAY) {
-        rem -= SECSPERDAY;
-        ++idays;
-    }
-    while (idays < 0) {
-        if (increment_overflow(&y, -1))
-            return NULL;
-        idays += year_lengths[isleap(y)];
-    }
-    while (idays >= year_lengths[isleap(y)]) {
-        idays -= year_lengths[isleap(y)];
-        if (increment_overflow(&y, 1))
-            return NULL;
-    }
-    tmp->tm_year = y;
-    if (increment_overflow(&tmp->tm_year, -TM_YEAR_BASE))
-        return NULL;
-    tmp->tm_yday = idays;
-    /*
-    ** The "extra" mods below avoid overflow problems.
-    */
-    tmp->tm_wday = EPOCH_WDAY +
-        ((y - EPOCH_YEAR) % DAYSPERWEEK) *
-        (DAYSPERNYEAR % DAYSPERWEEK) +
-        leaps_thru_end_of(y - 1) -
-        leaps_thru_end_of(EPOCH_YEAR - 1) +
-        idays;
-    tmp->tm_wday %= DAYSPERWEEK;
-    if (tmp->tm_wday < 0)
-        tmp->tm_wday += DAYSPERWEEK;
-    tmp->tm_hour = (int) (rem / SECSPERHOUR);
-    rem %= SECSPERHOUR;
-    tmp->tm_min = (int) (rem / SECSPERMIN);
-    /*
-    ** A positive leap second requires a special
-    ** representation. This uses "... ??:59:60" et seq.
-    */
-    tmp->tm_sec = (int) (rem % SECSPERMIN) + hit;
-    ip = mon_lengths[isleap(y)];
-    for (tmp->tm_mon = 0; idays >= ip[tmp->tm_mon]; ++(tmp->tm_mon))
-        idays -= ip[tmp->tm_mon];
-    tmp->tm_mday = (int) (idays + 1);
-    tmp->tm_isdst = 0;
+		tdelta = tdays / DAYSPERLYEAR;
+		if (! ((! TYPE_SIGNED(time_t) || INT_MIN <= tdelta)
+		       && tdelta <= INT_MAX))
+		  goto out_of_range;
+		idelta = tdelta;
+		if (idelta == 0)
+			idelta = (tdays < 0) ? -1 : 1;
+		newy = y;
+		if (increment_overflow(&newy, idelta))
+		  goto out_of_range;
+		leapdays = leaps_thru_end_of(newy - 1) -
+			leaps_thru_end_of(y - 1);
+		tdays -= ((time_t) newy - y) * DAYSPERNYEAR;
+		tdays -= leapdays;
+		y = newy;
+	}
+	/*
+	** Given the range, we can now fearlessly cast...
+	*/
+	idays = tdays;
+	rem += offset - corr;
+	while (rem < 0) {
+		rem += SECSPERDAY;
+		--idays;
+	}
+	while (rem >= SECSPERDAY) {
+		rem -= SECSPERDAY;
+		++idays;
+	}
+	while (idays < 0) {
+		if (increment_overflow(&y, -1))
+		  goto out_of_range;
+		idays += year_lengths[isleap(y)];
+	}
+	while (idays >= year_lengths[isleap(y)]) {
+		idays -= year_lengths[isleap(y)];
+		if (increment_overflow(&y, 1))
+		  goto out_of_range;
+	}
+	tmp->tm_year = y;
+	if (increment_overflow(&tmp->tm_year, -TM_YEAR_BASE))
+	  goto out_of_range;
+	tmp->tm_yday = idays;
+	/*
+	** The "extra" mods below avoid overflow problems.
+	*/
+	tmp->tm_wday = EPOCH_WDAY +
+		((y - EPOCH_YEAR) % DAYSPERWEEK) *
+		(DAYSPERNYEAR % DAYSPERWEEK) +
+		leaps_thru_end_of(y - 1) -
+		leaps_thru_end_of(EPOCH_YEAR - 1) +
+		idays;
+	tmp->tm_wday %= DAYSPERWEEK;
+	if (tmp->tm_wday < 0)
+		tmp->tm_wday += DAYSPERWEEK;
+	tmp->tm_hour = (int) (rem / SECSPERHOUR);
+	rem %= SECSPERHOUR;
+	tmp->tm_min = (int) (rem / SECSPERMIN);
+	/*
+	** A positive leap second requires a special
+	** representation. This uses "... ??:59:60" et seq.
+	*/
+	tmp->tm_sec = (int) (rem % SECSPERMIN) + hit;
+	ip = mon_lengths[isleap(y)];
+	for (tmp->tm_mon = 0; idays >= ip[tmp->tm_mon]; ++(tmp->tm_mon))
+		idays -= ip[tmp->tm_mon];
+	tmp->tm_mday = (int) (idays + 1);
+	tmp->tm_isdst = 0;
 #ifdef TM_GMTOFF
-    tmp->TM_GMTOFF = offset;
+	tmp->TM_GMTOFF = offset;
 #endif /* defined TM_GMTOFF */
-    return tmp;
+	return tmp;
+
+ out_of_range:
+	errno = EOVERFLOW;
+	return NULL;
 }
 
 char *
-ctime(const time_t * const timep)
+ctime(const time_t *timep)
 {
 /*
 ** Section 4.12.3.2 of X3.159-1989 requires that
-**  The ctime function converts the calendar time pointed to by timer
-**  to local time in the form of a string. It is equivalent to
-**      asctime(localtime(timer))
+**	The ctime function converts the calendar time pointed to by timer
+**	to local time in the form of a string. It is equivalent to
+**		asctime(localtime(timer))
 */
-    return asctime(localtime(timep));
+  struct tm *tmp = localtime(timep);
+  return tmp ? asctime(tmp) : NULL;
 }
 
 char *
-ctime_r(const time_t * const timep, char * buf)
+ctime_r(const time_t *timep, char *buf)
 {
-    struct tm   mytm;
-
-    return asctime_r(localtime_r(timep, &mytm), buf);
+  struct tm mytm;
+  struct tm *tmp = localtime_r(timep, &mytm);
+  return tmp ? asctime_r(tmp, buf) : NULL;
 }
 
 /*
 ** Adapted from code provided by Robert Elz, who writes:
-**  The "best" way to do mktime I think is based on an idea of Bob
-**  Kridle's (so its said...) from a long time ago.
-**  It does a binary search of the time_t space. Since time_t's are
-**  just 32 bits, its a max of 32 iterations (even at 64 bits it
-**  would still be very reasonable).
+**	The "best" way to do mktime I think is based on an idea of Bob
+**	Kridle's (so its said...) from a long time ago.
+**	It does a binary search of the time_t space. Since time_t's are
+**	just 32 bits, its a max of 32 iterations (even at 64 bits it
+**	would still be very reasonable).
 */
 
 #ifndef WRONG
-#define WRONG   (-1)
+#define WRONG	(-1)
 #endif /* !defined WRONG */
 
 /*
 ** Normalize logic courtesy Paul Eggert.
 */
 
-static int
-increment_overflow(int *const ip, int j)
+static bool
+increment_overflow(int *ip, int j)
 {
-    register int const i = *ip;
+	register int const	i = *ip;
 
-    /*
-    ** If i >= 0 there can only be overflow if i + j > INT_MAX
-    ** or if j > INT_MAX - i; given i >= 0, INT_MAX - i cannot overflow.
-    ** If i < 0 there can only be overflow if i + j < INT_MIN
-    ** or if j < INT_MIN - i; given i < 0, INT_MIN - i cannot overflow.
-    */
-    if ((i >= 0) ? (j > INT_MAX - i) : (j < INT_MIN - i))
-        return TRUE;
-    *ip += j;
-    return FALSE;
+	/*
+	** If i >= 0 there can only be overflow if i + j > INT_MAX
+	** or if j > INT_MAX - i; given i >= 0, INT_MAX - i cannot overflow.
+	** If i < 0 there can only be overflow if i + j < INT_MIN
+	** or if j < INT_MIN - i; given i < 0, INT_MIN - i cannot overflow.
+	*/
+	if ((i >= 0) ? (j > INT_MAX - i) : (j < INT_MIN - i))
+		return true;
+	*ip += j;
+	return false;
 }
 
-static int
+static bool
 increment_overflow32(int_fast32_t *const lp, int const m)
 {
-    register int_fast32_t const l = *lp;
+	register int_fast32_t const	l = *lp;
 
-    if ((l >= 0) ? (m > INT_FAST32_MAX - l) : (m < INT_FAST32_MIN - l))
-        return TRUE;
-    *lp += m;
-    return FALSE;
+	if ((l >= 0) ? (m > INT_FAST32_MAX - l) : (m < INT_FAST32_MIN - l))
+		return true;
+	*lp += m;
+	return false;
 }
 
-static int
+static bool
 increment_overflow_time(time_t *tp, int_fast32_t j)
 {
-    /*
-    ** This is like
-    ** 'if (! (time_t_min <= *tp + j && *tp + j <= time_t_max)) ...',
-    ** except that it does the right thing even if *tp + j would overflow.
-    */
-    if (! (j < 0
-           ? (TYPE_SIGNED(time_t) ? time_t_min - j <= *tp : -1 - j < *tp)
-           : *tp <= time_t_max - j))
-        return TRUE;
-    *tp += j;
-    return FALSE;
+	/*
+	** This is like
+	** 'if (! (time_t_min <= *tp + j && *tp + j <= time_t_max)) ...',
+	** except that it does the right thing even if *tp + j would overflow.
+	*/
+	if (! (j < 0
+	       ? (TYPE_SIGNED(time_t) ? time_t_min - j <= *tp : -1 - j < *tp)
+	       : *tp <= time_t_max - j))
+		return true;
+	*tp += j;
+	return false;
 }
 
-static int
+static bool
 normalize_overflow(int *const tensptr, int *const unitsptr, const int base)
 {
-    register int tensdelta;
+	register int	tensdelta;
 
-    tensdelta = (*unitsptr >= 0) ?
-        (*unitsptr / base) :
-        (-1 - (-1 - *unitsptr) / base);
-    *unitsptr -= tensdelta * base;
-    return increment_overflow(tensptr, tensdelta);
+	tensdelta = (*unitsptr >= 0) ?
+		(*unitsptr / base) :
+		(-1 - (-1 - *unitsptr) / base);
+	*unitsptr -= tensdelta * base;
+	return increment_overflow(tensptr, tensdelta);
+}
+
+static bool
+normalize_overflow32(int_fast32_t *tensptr, int *unitsptr, int base)
+{
+	register int	tensdelta;
+
+	tensdelta = (*unitsptr >= 0) ?
+		(*unitsptr / base) :
+		(-1 - (-1 - *unitsptr) / base);
+	*unitsptr -= tensdelta * base;
+	return increment_overflow32(tensptr, tensdelta);
 }
 
 static int
-normalize_overflow32(int_fast32_t *const tensptr, int *const unitsptr,
-             const int base)
+tmcomp(register const struct tm *const atmp,
+       register const struct tm *const btmp)
 {
-    register int tensdelta;
+	register int	result;
 
-    tensdelta = (*unitsptr >= 0) ?
-        (*unitsptr / base) :
-        (-1 - (-1 - *unitsptr) / base);
-    *unitsptr -= tensdelta * base;
-    return increment_overflow32(tensptr, tensdelta);
-}
-
-static int
-tmcomp(register const struct tm * const atmp,
-       register const struct tm * const btmp)
-{
-    register int result;
-
-    if (atmp->tm_year != btmp->tm_year)
-        return atmp->tm_year < btmp->tm_year ? -1 : 1;
-    if ((result = (atmp->tm_mon - btmp->tm_mon)) == 0 &&
-        (result = (atmp->tm_mday - btmp->tm_mday)) == 0 &&
-        (result = (atmp->tm_hour - btmp->tm_hour)) == 0 &&
-        (result = (atmp->tm_min - btmp->tm_min)) == 0)
-            result = atmp->tm_sec - btmp->tm_sec;
-    return result;
+	if (atmp->tm_year != btmp->tm_year)
+		return atmp->tm_year < btmp->tm_year ? -1 : 1;
+	if ((result = (atmp->tm_mon - btmp->tm_mon)) == 0 &&
+		(result = (atmp->tm_mday - btmp->tm_mday)) == 0 &&
+		(result = (atmp->tm_hour - btmp->tm_hour)) == 0 &&
+		(result = (atmp->tm_min - btmp->tm_min)) == 0)
+			result = atmp->tm_sec - btmp->tm_sec;
+	return result;
 }
 
 static time_t
-time2sub(struct tm * const tmp,
-         struct tm *(*const funcp)(const time_t*, int_fast32_t, struct tm*, struct state*),
-         const int_fast32_t offset,
-         int * const okayp,
-         const int do_norm_secs, struct state * sp) // android-changed: added sp
+time2sub(struct tm *const tmp,
+	 struct tm *(*funcp)(struct state const *, time_t const *,
+			     int_fast32_t, struct tm *),
+	 struct state const *sp,
+	 const int_fast32_t offset,
+	 bool *okayp,
+	 bool do_norm_secs)
 {
-    register int          dir;
-    register int          i, j;
-    register int          saved_seconds;
-    register int_fast32_t li;
-    register time_t       lo;
-    register time_t       hi;
-    int_fast32_t          y;
-    time_t                newt;
-    time_t                t;
-    struct tm             yourtm, mytm;
+	register int			dir;
+	register int			i, j;
+	register int			saved_seconds;
+	register int_fast32_t		li;
+	register time_t			lo;
+	register time_t			hi;
+	int_fast32_t			y;
+	time_t				newt;
+	time_t				t;
+	struct tm			yourtm, mytm;
 
-    *okayp = FALSE;
-    yourtm = *tmp;
-    if (do_norm_secs) {
-        if (normalize_overflow(&yourtm.tm_min, &yourtm.tm_sec,
-            SECSPERMIN))
-                return WRONG;
-    }
-    if (normalize_overflow(&yourtm.tm_hour, &yourtm.tm_min, MINSPERHOUR))
-        return WRONG;
-    if (normalize_overflow(&yourtm.tm_mday, &yourtm.tm_hour, HOURSPERDAY))
-        return WRONG;
-    y = yourtm.tm_year;
-    if (normalize_overflow32(&y, &yourtm.tm_mon, MONSPERYEAR))
-        return WRONG;
-    /*
-    ** Turn y into an actual year number for now.
-    ** It is converted back to an offset from TM_YEAR_BASE later.
-    */
-    if (increment_overflow32(&y, TM_YEAR_BASE))
-        return WRONG;
-    while (yourtm.tm_mday <= 0) {
-        if (increment_overflow32(&y, -1))
-            return WRONG;
-        li = y + (1 < yourtm.tm_mon);
-        yourtm.tm_mday += year_lengths[isleap(li)];
-    }
-    while (yourtm.tm_mday > DAYSPERLYEAR) {
-        li = y + (1 < yourtm.tm_mon);
-        yourtm.tm_mday -= year_lengths[isleap(li)];
-        if (increment_overflow32(&y, 1))
-            return WRONG;
-    }
-    for ( ; ; ) {
-        i = mon_lengths[isleap(y)][yourtm.tm_mon];
-        if (yourtm.tm_mday <= i)
-            break;
-        yourtm.tm_mday -= i;
-        if (++yourtm.tm_mon >= MONSPERYEAR) {
-            yourtm.tm_mon = 0;
-            if (increment_overflow32(&y, 1))
-                return WRONG;
-        }
-    }
-    if (increment_overflow32(&y, -TM_YEAR_BASE))
-        return WRONG;
-    yourtm.tm_year = y;
-    if (yourtm.tm_year != y)
-        return WRONG;
-    if (yourtm.tm_sec >= 0 && yourtm.tm_sec < SECSPERMIN)
-        saved_seconds = 0;
-    else if (y + TM_YEAR_BASE < EPOCH_YEAR) {
-        /*
-        ** We can't set tm_sec to 0, because that might push the
-        ** time below the minimum representable time.
-        ** Set tm_sec to 59 instead.
-        ** This assumes that the minimum representable time is
-        ** not in the same minute that a leap second was deleted from,
-        ** which is a safer assumption than using 58 would be.
-        */
-        if (increment_overflow(&yourtm.tm_sec, 1 - SECSPERMIN))
-            return WRONG;
-        saved_seconds = yourtm.tm_sec;
-        yourtm.tm_sec = SECSPERMIN - 1;
-    } else {
-        saved_seconds = yourtm.tm_sec;
-        yourtm.tm_sec = 0;
-    }
-    /*
-    ** Do a binary search (this works whatever time_t's type is).
-    */
-    if (!TYPE_SIGNED(time_t)) {
-        lo = 0;
-        hi = lo - 1;
-    } else {
-        lo = 1;
-        for (i = 0; i < (int) TYPE_BIT(time_t) - 1; ++i)
-            lo *= 2;
-        hi = -(lo + 1);
-    }
-    for ( ; ; ) {
-        t = lo / 2 + hi / 2;
-        if (t < lo)
-            t = lo;
-        else if (t > hi)
-            t = hi;
-        if ((*funcp)(&t, offset, &mytm, sp) == NULL) { // android-changed: added sp.
-            /*
-            ** Assume that t is too extreme to be represented in
-            ** a struct tm; arrange things so that it is less
-            ** extreme on the next pass.
-            */
-            dir = (t > 0) ? 1 : -1;
-        } else  dir = tmcomp(&mytm, &yourtm);
-        if (dir != 0) {
-            if (t == lo) {
-                if (t == time_t_max)
-                    return WRONG;
-                ++t;
-                ++lo;
-            } else if (t == hi) {
-                if (t == time_t_min)
-                    return WRONG;
-                --t;
-                --hi;
-            }
-            if (lo > hi)
-                return WRONG;
-            if (dir > 0)
-                hi = t;
-            else    lo = t;
-            continue;
-        }
-        if (yourtm.tm_isdst < 0 || mytm.tm_isdst == yourtm.tm_isdst)
-            break;
-        /*
-        ** Right time, wrong type.
-        ** Hunt for right time, right type.
-        ** It's okay to guess wrong since the guess
-        ** gets checked.
-        */
-        // BEGIN android-changed: support user-supplied sp
-        if (sp == NULL) {
-            sp = (struct state *)
-                ((funcp == localsub) ? lclptr : gmtptr);
-        }
-        // END android-changed
-        if (sp == NULL)
-            return WRONG;
-        for (i = sp->typecnt - 1; i >= 0; --i) {
-            if (sp->ttis[i].tt_isdst != yourtm.tm_isdst)
-                continue;
-            for (j = sp->typecnt - 1; j >= 0; --j) {
-                if (sp->ttis[j].tt_isdst == yourtm.tm_isdst)
-                    continue;
-                newt = t + sp->ttis[j].tt_gmtoff -
-                    sp->ttis[i].tt_gmtoff;
-                if ((*funcp)(&newt, offset, &mytm, sp) == NULL) // android-changed: added sp.
-                    continue;
-                if (tmcomp(&mytm, &yourtm) != 0)
-                    continue;
-                if (mytm.tm_isdst != yourtm.tm_isdst)
-                    continue;
-                /*
-                ** We have a match.
-                */
-                t = newt;
-                goto label;
-            }
-        }
-        return WRONG;
-    }
+	*okayp = false;
+	yourtm = *tmp;
+	if (do_norm_secs) {
+		if (normalize_overflow(&yourtm.tm_min, &yourtm.tm_sec,
+			SECSPERMIN))
+				return WRONG;
+	}
+	if (normalize_overflow(&yourtm.tm_hour, &yourtm.tm_min, MINSPERHOUR))
+		return WRONG;
+	if (normalize_overflow(&yourtm.tm_mday, &yourtm.tm_hour, HOURSPERDAY))
+		return WRONG;
+	y = yourtm.tm_year;
+	if (normalize_overflow32(&y, &yourtm.tm_mon, MONSPERYEAR))
+		return WRONG;
+	/*
+	** Turn y into an actual year number for now.
+	** It is converted back to an offset from TM_YEAR_BASE later.
+	*/
+	if (increment_overflow32(&y, TM_YEAR_BASE))
+		return WRONG;
+	while (yourtm.tm_mday <= 0) {
+		if (increment_overflow32(&y, -1))
+			return WRONG;
+		li = y + (1 < yourtm.tm_mon);
+		yourtm.tm_mday += year_lengths[isleap(li)];
+	}
+	while (yourtm.tm_mday > DAYSPERLYEAR) {
+		li = y + (1 < yourtm.tm_mon);
+		yourtm.tm_mday -= year_lengths[isleap(li)];
+		if (increment_overflow32(&y, 1))
+			return WRONG;
+	}
+	for ( ; ; ) {
+		i = mon_lengths[isleap(y)][yourtm.tm_mon];
+		if (yourtm.tm_mday <= i)
+			break;
+		yourtm.tm_mday -= i;
+		if (++yourtm.tm_mon >= MONSPERYEAR) {
+			yourtm.tm_mon = 0;
+			if (increment_overflow32(&y, 1))
+				return WRONG;
+		}
+	}
+	if (increment_overflow32(&y, -TM_YEAR_BASE))
+		return WRONG;
+	if (! (INT_MIN <= y && y <= INT_MAX))
+		return WRONG;
+	yourtm.tm_year = y;
+	if (yourtm.tm_sec >= 0 && yourtm.tm_sec < SECSPERMIN)
+		saved_seconds = 0;
+	else if (y + TM_YEAR_BASE < EPOCH_YEAR) {
+		/*
+		** We can't set tm_sec to 0, because that might push the
+		** time below the minimum representable time.
+		** Set tm_sec to 59 instead.
+		** This assumes that the minimum representable time is
+		** not in the same minute that a leap second was deleted from,
+		** which is a safer assumption than using 58 would be.
+		*/
+		if (increment_overflow(&yourtm.tm_sec, 1 - SECSPERMIN))
+			return WRONG;
+		saved_seconds = yourtm.tm_sec;
+		yourtm.tm_sec = SECSPERMIN - 1;
+	} else {
+		saved_seconds = yourtm.tm_sec;
+		yourtm.tm_sec = 0;
+	}
+	/*
+	** Do a binary search (this works whatever time_t's type is).
+	*/
+	lo = time_t_min;
+	hi = time_t_max;
+	for ( ; ; ) {
+		t = lo / 2 + hi / 2;
+		if (t < lo)
+			t = lo;
+		else if (t > hi)
+			t = hi;
+		if (! funcp(sp, &t, offset, &mytm)) {
+			/*
+			** Assume that t is too extreme to be represented in
+			** a struct tm; arrange things so that it is less
+			** extreme on the next pass.
+			*/
+			dir = (t > 0) ? 1 : -1;
+		} else	dir = tmcomp(&mytm, &yourtm);
+		if (dir != 0) {
+			if (t == lo) {
+				if (t == time_t_max)
+					return WRONG;
+				++t;
+				++lo;
+			} else if (t == hi) {
+				if (t == time_t_min)
+					return WRONG;
+				--t;
+				--hi;
+			}
+			if (lo > hi)
+				return WRONG;
+			if (dir > 0)
+				hi = t;
+			else	lo = t;
+			continue;
+		}
+#if defined TM_GMTOFF && ! UNINIT_TRAP
+		if (mytm.TM_GMTOFF != yourtm.TM_GMTOFF
+		    && (yourtm.TM_GMTOFF < 0
+			? (-SECSPERDAY <= yourtm.TM_GMTOFF
+			   && (mytm.TM_GMTOFF <=
+			       (SMALLEST (INT_FAST32_MAX, LONG_MAX)
+				+ yourtm.TM_GMTOFF)))
+			: (yourtm.TM_GMTOFF <= SECSPERDAY
+			   && ((BIGGEST (INT_FAST32_MIN, LONG_MIN)
+				+ yourtm.TM_GMTOFF)
+			       <= mytm.TM_GMTOFF)))) {
+		  /* MYTM matches YOURTM except with the wrong UTC offset.
+		     YOURTM.TM_GMTOFF is plausible, so try it instead.
+		     It's OK if YOURTM.TM_GMTOFF contains uninitialized data,
+		     since the guess gets checked.  */
+		  time_t altt = t;
+		  int_fast32_t diff = mytm.TM_GMTOFF - yourtm.TM_GMTOFF;
+		  if (!increment_overflow_time(&altt, diff)) {
+		    struct tm alttm;
+		    if (funcp(sp, &altt, offset, &alttm)
+			&& alttm.tm_isdst == mytm.tm_isdst
+			&& alttm.TM_GMTOFF == yourtm.TM_GMTOFF
+			&& tmcomp(&alttm, &yourtm) == 0) {
+		      t = altt;
+		      mytm = alttm;
+		    }
+		  }
+		}
+#endif
+		if (yourtm.tm_isdst < 0 || mytm.tm_isdst == yourtm.tm_isdst)
+			break;
+		/*
+		** Right time, wrong type.
+		** Hunt for right time, right type.
+		** It's okay to guess wrong since the guess
+		** gets checked.
+		*/
+		if (sp == NULL)
+			return WRONG;
+		for (i = sp->typecnt - 1; i >= 0; --i) {
+			if (sp->ttis[i].tt_isdst != yourtm.tm_isdst)
+				continue;
+			for (j = sp->typecnt - 1; j >= 0; --j) {
+				if (sp->ttis[j].tt_isdst == yourtm.tm_isdst)
+					continue;
+				newt = t + sp->ttis[j].tt_gmtoff -
+					sp->ttis[i].tt_gmtoff;
+				if (! funcp(sp, &newt, offset, &mytm))
+					continue;
+				if (tmcomp(&mytm, &yourtm) != 0)
+					continue;
+				if (mytm.tm_isdst != yourtm.tm_isdst)
+					continue;
+				/*
+				** We have a match.
+				*/
+				t = newt;
+				goto label;
+			}
+		}
+		return WRONG;
+	}
 label:
-    newt = t + saved_seconds;
-    if ((newt < t) != (saved_seconds < 0))
-        return WRONG;
-    t = newt;
-    if ((*funcp)(&t, offset, tmp, sp)) // android-changed: added sp.
-        *okayp = TRUE;
-    return t;
+	newt = t + saved_seconds;
+	if ((newt < t) != (saved_seconds < 0))
+		return WRONG;
+	t = newt;
+	if (funcp(sp, &t, offset, tmp))
+		*okayp = true;
+	return t;
 }
 
 static time_t
-time2(struct tm * const tmp,
-      struct tm * (*const funcp)(const time_t *, int_fast32_t, struct tm *, struct state *), // android-changed: added sp.
+time2(struct tm * const	tmp,
+      struct tm *(*funcp)(struct state const *, time_t const *,
+			  int_fast32_t, struct tm *),
+      struct state const *sp,
       const int_fast32_t offset,
-      int *const okayp, struct state* sp) // android-changed: added sp.
+      bool *okayp)
 {
-    time_t t;
+	time_t	t;
 
-    /*
-    ** First try without normalization of seconds
-    ** (in case tm_sec contains a value associated with a leap second).
-    ** If that fails, try with normalization of seconds.
-    */
-    t = time2sub(tmp, funcp, offset, okayp, FALSE, sp);
-    return *okayp ? t : time2sub(tmp, funcp, offset, okayp, TRUE, sp);
+	/*
+	** First try without normalization of seconds
+	** (in case tm_sec contains a value associated with a leap second).
+	** If that fails, try with normalization of seconds.
+	*/
+	t = time2sub(tmp, funcp, sp, offset, okayp, false);
+	return *okayp ? t : time2sub(tmp, funcp, sp, offset, okayp, true);
 }
 
 static time_t
-time1(struct tm * const tmp,
-      struct tm * (* const funcp) (const time_t *, int_fast32_t, struct tm *, struct state *), // android-changed: added sp.
-      const int_fast32_t offset, struct state * sp) // android-changed: added sp.
+time1(struct tm *const tmp,
+      struct tm *(*funcp) (struct state const *, time_t const *,
+			   int_fast32_t, struct tm *),
+      struct state const *sp,
+      const int_fast32_t offset)
 {
-    register time_t t;
-    register int    samei, otheri;
-    register int    sameind, otherind;
-    register int    i;
-    register int    nseen;
-    char            seen[TZ_MAX_TYPES];
-    unsigned char   types[TZ_MAX_TYPES];
-    int             okay;
+	register time_t			t;
+	register int			samei, otheri;
+	register int			sameind, otherind;
+	register int			i;
+	register int			nseen;
+	char				seen[TZ_MAX_TYPES];
+	unsigned char			types[TZ_MAX_TYPES];
+	bool				okay;
 
-    if (tmp == NULL) {
-        errno = EINVAL;
-        return WRONG;
-    }
-    if (tmp->tm_isdst > 1)
-        tmp->tm_isdst = 1;
-    t = time2(tmp, funcp, offset, &okay, sp); // android-changed: added sp.
-    if (okay)
-        return t;
-    if (tmp->tm_isdst < 0)
+	if (tmp == NULL) {
+		errno = EINVAL;
+		return WRONG;
+	}
+	if (tmp->tm_isdst > 1)
+		tmp->tm_isdst = 1;
+	t = time2(tmp, funcp, sp, offset, &okay);
+	if (okay)
+		return t;
+	if (tmp->tm_isdst < 0)
 #ifdef PCTS
-        /*
-        ** POSIX Conformance Test Suite code courtesy Grant Sullivan.
-        */
-        tmp->tm_isdst = 0;  /* reset to std and try again */
+		/*
+		** POSIX Conformance Test Suite code courtesy Grant Sullivan.
+		*/
+		tmp->tm_isdst = 0;	/* reset to std and try again */
 #else
-        return t;
+		return t;
 #endif /* !defined PCTS */
-    /*
-    ** We're supposed to assume that somebody took a time of one type
-    ** and did some math on it that yielded a "struct tm" that's bad.
-    ** We try to divine the type they started from and adjust to the
-    ** type they need.
-    */
-    // BEGIN android-changed: support user-supplied sp.
-    if (sp == NULL) {
-        sp = (struct state *) ((funcp == localsub) ?  lclptr : gmtptr);
-    }
-    // BEGIN android-changed
-    if (sp == NULL)
-        return WRONG;
-    for (i = 0; i < sp->typecnt; ++i)
-        seen[i] = FALSE;
-    nseen = 0;
-    for (i = sp->timecnt - 1; i >= 0; --i)
-        if (!seen[sp->types[i]]) {
-            seen[sp->types[i]] = TRUE;
-            types[nseen++] = sp->types[i];
-        }
-    for (sameind = 0; sameind < nseen; ++sameind) {
-        samei = types[sameind];
-        if (sp->ttis[samei].tt_isdst != tmp->tm_isdst)
-            continue;
-        for (otherind = 0; otherind < nseen; ++otherind) {
-            otheri = types[otherind];
-            if (sp->ttis[otheri].tt_isdst == tmp->tm_isdst)
-                continue;
-            tmp->tm_sec += sp->ttis[otheri].tt_gmtoff -
-                    sp->ttis[samei].tt_gmtoff;
-            tmp->tm_isdst = !tmp->tm_isdst;
-            t = time2(tmp, funcp, offset, &okay, sp); // android-changed: added sp.
-            if (okay)
-                return t;
-            tmp->tm_sec -= sp->ttis[otheri].tt_gmtoff -
-                    sp->ttis[samei].tt_gmtoff;
-            tmp->tm_isdst = !tmp->tm_isdst;
-        }
-    }
-    return WRONG;
+	/*
+	** We're supposed to assume that somebody took a time of one type
+	** and did some math on it that yielded a "struct tm" that's bad.
+	** We try to divine the type they started from and adjust to the
+	** type they need.
+	*/
+	if (sp == NULL)
+		return WRONG;
+	for (i = 0; i < sp->typecnt; ++i)
+		seen[i] = false;
+	nseen = 0;
+	for (i = sp->timecnt - 1; i >= 0; --i)
+		if (!seen[sp->types[i]]) {
+			seen[sp->types[i]] = true;
+			types[nseen++] = sp->types[i];
+		}
+	for (sameind = 0; sameind < nseen; ++sameind) {
+		samei = types[sameind];
+		if (sp->ttis[samei].tt_isdst != tmp->tm_isdst)
+			continue;
+		for (otherind = 0; otherind < nseen; ++otherind) {
+			otheri = types[otherind];
+			if (sp->ttis[otheri].tt_isdst == tmp->tm_isdst)
+				continue;
+			tmp->tm_sec += sp->ttis[otheri].tt_gmtoff -
+					sp->ttis[samei].tt_gmtoff;
+			tmp->tm_isdst = !tmp->tm_isdst;
+			t = time2(tmp, funcp, sp, offset, &okay);
+			if (okay)
+				return t;
+			tmp->tm_sec -= sp->ttis[otheri].tt_gmtoff -
+					sp->ttis[samei].tt_gmtoff;
+			tmp->tm_isdst = !tmp->tm_isdst;
+		}
+	}
+	return WRONG;
 }
 
+static time_t
+mktime_tzname(struct state *sp, struct tm *tmp, bool setname)
+{
+  if (sp)
+    return time1(tmp, localsub, sp, setname);
+  else {
+    gmtcheck();
+    return time1(tmp, gmtsub, gmtptr, 0);
+  }
+}
+
+#if NETBSD_INSPIRED
+
 time_t
-mktime(struct tm * const tmp)
+mktime_z(struct state *sp, struct tm *tmp)
 {
-    _tzLock();
-    tzset_locked();
-    time_t result = time1(tmp, localsub, 0L, NULL); // android-changed: extra parameter.
-    _tzUnlock();
-    return result;
+  return mktime_tzname(sp, tmp, false);
+}
+
+#endif
+
+time_t
+mktime(struct tm *tmp)
+{
+  time_t t;
+  int err = lock();
+  if (err) {
+    errno = err;
+    return -1;
+  }
+  tzset_unlocked();
+  t = mktime_tzname(lclptr, tmp, true);
+  unlock();
+  return t;
 }
 
 #ifdef STD_INSPIRED
 
 time_t
-timelocal(struct tm * const tmp)
+timelocal(struct tm *tmp)
 {
-    if (tmp != NULL)
-        tmp->tm_isdst = -1; /* in case it wasn't initialized */
-    return mktime(tmp);
+	if (tmp != NULL)
+		tmp->tm_isdst = -1;	/* in case it wasn't initialized */
+	return mktime(tmp);
 }
 
 time_t
-timegm(struct tm * const tmp)
+timegm(struct tm *tmp)
 {
-    time_t result;
-
-    if (tmp != NULL)
-        tmp->tm_isdst = 0;
-    _tzLock();
-    result = time1(tmp, gmtsub, 0L, NULL); // android-changed: extra parameter.
-    _tzUnlock();
-
-    return result;
+  return timeoff(tmp, 0);
 }
 
 time_t
-timeoff(struct tm *const tmp, const long offset)
+timeoff(struct tm *tmp, long offset)
 {
-    if (tmp != NULL)
-        tmp->tm_isdst = 0;
-    return time1(tmp, gmtsub, offset, NULL); // android-changed: extra parameter.
+  if (tmp)
+    tmp->tm_isdst = 0;
+  gmtcheck();
+  return time1(tmp, gmtsub, gmtptr, offset);
 }
 
 #endif /* defined STD_INSPIRED */
 
-#ifdef CMUCS
-
-/*
-** The following is supplied for compatibility with
-** previous versions of the CMUCS runtime library.
-*/
-
-long
-gtime(struct tm * const tmp)
-{
-    const time_t t = mktime(tmp);
-
-    if (t == WRONG)
-        return -1;
-    return t;
-}
-
-#endif /* defined CMUCS */
-
 /*
 ** XXX--is the below the right way to conditionalize??
 */
@@ -2059,64 +2218,105 @@
 */
 
 static int_fast64_t
-leapcorr(time_t * timep)
+leapcorr(struct state const *sp, time_t t)
 {
-    register struct state *  sp;
-    register struct lsinfo * lp;
-    register int             i;
+	register struct lsinfo const *	lp;
+	register int			i;
 
-    sp = lclptr;
-    i = sp->leapcnt;
-    while (--i >= 0) {
-        lp = &sp->lsis[i];
-        if (*timep >= lp->ls_trans)
-            return lp->ls_corr;
-    }
-    return 0;
+	i = sp->leapcnt;
+	while (--i >= 0) {
+		lp = &sp->lsis[i];
+		if (t >= lp->ls_trans)
+			return lp->ls_corr;
+	}
+	return 0;
+}
+
+NETBSD_INSPIRED_EXTERN time_t ATTRIBUTE_PURE
+time2posix_z(struct state *sp, time_t t)
+{
+  return t - leapcorr(sp, t);
 }
 
 time_t
 time2posix(time_t t)
 {
-    tzset();
-    return t - leapcorr(&t);
+  int err = lock();
+  if (err) {
+    errno = err;
+    return -1;
+  }
+  if (!lcl_is_set)
+    tzset_unlocked();
+  if (lclptr)
+    t = time2posix_z(lclptr, t);
+  unlock();
+  return t;
+}
+
+NETBSD_INSPIRED_EXTERN time_t ATTRIBUTE_PURE
+posix2time_z(struct state *sp, time_t t)
+{
+	time_t	x;
+	time_t	y;
+	/*
+	** For a positive leap second hit, the result
+	** is not unique. For a negative leap second
+	** hit, the corresponding time doesn't exist,
+	** so we return an adjacent second.
+	*/
+	x = t + leapcorr(sp, t);
+	y = x - leapcorr(sp, x);
+	if (y < t) {
+		do {
+			x++;
+			y = x - leapcorr(sp, x);
+		} while (y < t);
+		x -= y != t;
+	} else if (y > t) {
+		do {
+			--x;
+			y = x - leapcorr(sp, x);
+		} while (y > t);
+		x += y != t;
+	}
+	return x;
 }
 
 time_t
 posix2time(time_t t)
 {
-    time_t x;
-    time_t y;
-
-    tzset();
-    /*
-    ** For a positive leap second hit, the result
-    ** is not unique. For a negative leap second
-    ** hit, the corresponding time doesn't exist,
-    ** so we return an adjacent second.
-    */
-    x = t + leapcorr(&t);
-    y = x - leapcorr(&x);
-    if (y < t) {
-        do {
-            x++;
-            y = x - leapcorr(&x);
-        } while (y < t);
-        if (t != y)
-            return x - 1;
-    } else if (y > t) {
-        do {
-            --x;
-            y = x - leapcorr(&x);
-        } while (y > t);
-        if (t != y)
-            return x + 1;
-    }
-    return x;
+  int err = lock();
+  if (err) {
+    errno = err;
+    return -1;
+  }
+  if (!lcl_is_set)
+    tzset_unlocked();
+  if (lclptr)
+    t = posix2time_z(lclptr, t);
+  unlock();
+  return t;
 }
 
 #endif /* defined STD_INSPIRED */
 
+#ifdef time_tz
+
+/* Convert from the underlying system's time_t to the ersatz time_tz,
+   which is called 'time_t' in this file.  */
+
+time_t
+time(time_t *p)
+{
+  time_t r = sys_time(0);
+  if (p)
+    *p = r;
+  return r;
+}
+
+#endif
+
 // BEGIN android-added
 
 #include <assert.h>
@@ -2124,7 +2324,7 @@
 #include <arpa/inet.h> // For ntohl(3).
 
 static int __bionic_open_tzdata_path(const char* path_prefix_variable, const char* path_suffix,
-                                     const char* olson_id, int* data_size) {
+                                     const char* olson_id) {
   const char* path_prefix = getenv(path_prefix_variable);
   if (path_prefix == NULL) {
     fprintf(stderr, "%s: %s not set!\n", __FUNCTION__, path_prefix_variable);
@@ -2139,7 +2339,6 @@
   snprintf(path, path_length, "%s/%s", path_prefix, path_suffix);
   int fd = TEMP_FAILURE_RETRY(open(path, OPEN_MODE));
   if (fd == -1) {
-    XLOG(("%s: could not open \"%s\": %s\n", __FUNCTION__, path, strerror(errno)));
     free(path);
     return -2; // Distinguish failure to find any data from failure to find a specific id.
   }
@@ -2223,7 +2422,6 @@
 
     if (strcmp(this_id, olson_id) == 0) {
       specific_zone_offset = ntohl(entry->start) + ntohl(header.data_offset);
-      *data_size = ntohl(entry->length);
       break;
     }
 
@@ -2232,7 +2430,6 @@
   free(index);
 
   if (specific_zone_offset == -1) {
-    XLOG(("%s: couldn't find zone \"%s\"\n", __FUNCTION__, olson_id));
     free(path);
     close(fd);
     return -1;
@@ -2252,10 +2449,10 @@
   return fd;
 }
 
-static int __bionic_open_tzdata(const char* olson_id, int* data_size) {
-  int fd = __bionic_open_tzdata_path("ANDROID_DATA", "/misc/zoneinfo/current/tzdata", olson_id, data_size);
+static int __bionic_open_tzdata(const char* olson_id) {
+  int fd = __bionic_open_tzdata_path("ANDROID_DATA", "/misc/zoneinfo/current/tzdata", olson_id);
   if (fd < 0) {
-    fd = __bionic_open_tzdata_path("ANDROID_ROOT", "/usr/share/zoneinfo/tzdata", olson_id, data_size);
+    fd = __bionic_open_tzdata_path("ANDROID_ROOT", "/usr/share/zoneinfo/tzdata", olson_id);
     if (fd == -2) {
       // The first thing that 'recovery' does is try to format the current time. It doesn't have
       // any tzdata available, so we must not abort here --- doing so breaks the recovery image!
@@ -2265,50 +2462,4 @@
   return fd;
 }
 
-// Caches the most recent timezone (http://b/8270865).
-static int __bionic_tzload_cached(const char* name, struct state* const sp, const int doextend) {
-  _tzLock();
-
-  // Our single-item cache.
-  static char* g_cached_time_zone_name;
-  static struct state g_cached_time_zone;
-
-  // Do we already have this timezone cached?
-  if (g_cached_time_zone_name != NULL && strcmp(name, g_cached_time_zone_name) == 0) {
-    *sp = g_cached_time_zone;
-    _tzUnlock();
-    return 0;
-  }
-
-  // Can we load it?
-  int rc = tzload(name, sp, doextend);
-  if (rc == 0) {
-    // Update the cache.
-    free(g_cached_time_zone_name);
-    g_cached_time_zone_name = strdup(name);
-    g_cached_time_zone = *sp;
-  }
-
-  _tzUnlock();
-  return rc;
-}
-
-// Non-standard API: mktime(3) but with an explicit timezone parameter.
-// This can't actually be hidden/removed until we fix MtpUtils.cpp
-__attribute__((visibility("default"))) time_t mktime_tz(struct tm* const tmp, const char* tz) {
-  struct state* st = malloc(sizeof(*st));
-  time_t return_value;
-
-  if (st == NULL)
-    return 0;
-  if (__bionic_tzload_cached(tz, st, TRUE) != 0) {
-    // TODO: not sure what's best here, but for now, we fall back to gmt.
-    gmtload(st);
-  }
-
-  return_value = time1(tmp, localsub, 0L, st);
-  free(st);
-  return return_value;
-}
-
 // END android-added
diff --git a/libc/tzcode/private.h b/libc/tzcode/private.h
index c30c711..1c176e6 100644
--- a/libc/tzcode/private.h
+++ b/libc/tzcode/private.h
@@ -19,13 +19,9 @@
 
 /*
 ** Defaults for preprocessor symbols.
-** You can override these in your C compiler options, e.g. '-DHAVE_ADJTIME=0'.
+** You can override these in your C compiler options, e.g. '-DHAVE_GETTEXT=1'.
 */
 
-#ifndef HAVE_ADJTIME
-#define HAVE_ADJTIME		1
-#endif /* !defined HAVE_ADJTIME */
-
 #ifndef HAVE_GETTEXT
 #define HAVE_GETTEXT		0
 #endif /* !defined HAVE_GETTEXT */
@@ -38,9 +34,9 @@
 #define HAVE_LINK		1
 #endif /* !defined HAVE_LINK */
 
-#ifndef HAVE_SETTIMEOFDAY
-#define HAVE_SETTIMEOFDAY	3
-#endif /* !defined HAVE_SETTIMEOFDAY */
+#ifndef HAVE_STRDUP
+#define HAVE_STRDUP 1
+#endif
 
 #ifndef HAVE_SYMLINK
 #define HAVE_SYMLINK		1
@@ -59,32 +55,61 @@
 #endif /* !defined HAVE_UNISTD_H */
 
 #ifndef HAVE_UTMPX_H
-#define HAVE_UTMPX_H		0
+#define HAVE_UTMPX_H		1
 #endif /* !defined HAVE_UTMPX_H */
 
-#if !defined(__ANDROID__)
-#ifndef LOCALE_HOME
-#define LOCALE_HOME		"/usr/lib/locale"
-#endif /* !defined LOCALE_HOME */
-#endif // __ANDROID__
+#ifndef NETBSD_INSPIRED
+# define NETBSD_INSPIRED 1
+#endif
 
 #if HAVE_INCOMPATIBLE_CTIME_R
 #define asctime_r _incompatible_asctime_r
 #define ctime_r _incompatible_ctime_r
 #endif /* HAVE_INCOMPATIBLE_CTIME_R */
 
+/* Enable tm_gmtoff and tm_zone on GNUish systems.  */
+#define _GNU_SOURCE 1
+/* Fix asctime_r on Solaris 10.  */
+#define _POSIX_PTHREAD_SEMANTICS 1
+/* Enable strtoimax on Solaris 10.  */
+#define __EXTENSIONS__ 1
+
 /*
 ** Nested includes
 */
 
+/* Avoid clashes with NetBSD by renaming NetBSD's declarations.  */
+#define localtime_rz sys_localtime_rz
+#define mktime_z sys_mktime_z
+#define posix2time_z sys_posix2time_z
+#define time2posix_z sys_time2posix_z
+#define timezone_t sys_timezone_t
+#define tzalloc sys_tzalloc
+#define tzfree sys_tzfree
+#include <time.h>
+#undef localtime_rz
+#undef mktime_z
+#undef posix2time_z
+#undef time2posix_z
+#undef timezone_t
+#undef tzalloc
+#undef tzfree
+
 #include "sys/types.h"	/* for time_t */
 #include "stdio.h"
-#include "errno.h"
 #include "string.h"
 #include "limits.h"	/* for CHAR_BIT et al. */
-#include "time.h"
 #include "stdlib.h"
 
+#include "errno.h"
+
+#ifndef ENAMETOOLONG
+# define ENAMETOOLONG EINVAL
+#endif
+#ifndef EOVERFLOW
+# define EOVERFLOW EINVAL
+#endif
+
 #if HAVE_GETTEXT
 #include "libintl.h"
 #endif /* HAVE_GETTEXT */
@@ -104,6 +129,14 @@
 #include "unistd.h"	/* for F_OK, R_OK, and other POSIX goodness */
 #endif /* HAVE_UNISTD_H */
 
+#ifndef HAVE_STRFTIME_L
+# if _POSIX_VERSION < 200809
+#  define HAVE_STRFTIME_L 0
+# else
+#  define HAVE_STRFTIME_L 1
+# endif
+#endif
+
 #ifndef F_OK
 #define F_OK	0
 #endif /* !defined F_OK */
@@ -138,65 +171,98 @@
 # include <inttypes.h>
 #endif
 
-#ifndef INT_FAST64_MAX
 /* Pre-C99 GCC compilers define __LONG_LONG_MAX__ instead of LLONG_MAX.  */
-#if defined LLONG_MAX || defined __LONG_LONG_MAX__
-typedef long long	int_fast64_t;
+#ifdef __LONG_LONG_MAX__
+# ifndef LLONG_MAX
+#  define LLONG_MAX __LONG_LONG_MAX__
+# endif
+# ifndef LLONG_MIN
+#  define LLONG_MIN (-1 - LLONG_MAX)
+# endif
+#endif
+
+#ifndef INT_FAST64_MAX
 # ifdef LLONG_MAX
+typedef long long	int_fast64_t;
 #  define INT_FAST64_MIN LLONG_MIN
 #  define INT_FAST64_MAX LLONG_MAX
 # else
-#  define INT_FAST64_MIN __LONG_LONG_MIN__
-#  define INT_FAST64_MAX __LONG_LONG_MAX__
-# endif
-# define SCNdFAST64 "lld"
-#else /* ! (defined LLONG_MAX || defined __LONG_LONG_MAX__) */
-#if (LONG_MAX >> 31) < 0xffffffff
+#  if LONG_MAX >> 31 < 0xffffffff
 Please use a compiler that supports a 64-bit integer type (or wider);
 you may need to compile with "-DHAVE_STDINT_H".
-#endif /* (LONG_MAX >> 31) < 0xffffffff */
+#  endif
 typedef long		int_fast64_t;
-# define INT_FAST64_MIN LONG_MIN
-# define INT_FAST64_MAX LONG_MAX
-# define SCNdFAST64 "ld"
-#endif /* ! (defined LLONG_MAX || defined __LONG_LONG_MAX__) */
-#endif /* !defined INT_FAST64_MAX */
+#  define INT_FAST64_MIN LONG_MIN
+#  define INT_FAST64_MAX LONG_MAX
+# endif
+#endif
+
+#ifndef SCNdFAST64
+# if INT_FAST64_MAX == LLONG_MAX
+#  define SCNdFAST64 "lld"
+# else
+#  define SCNdFAST64 "ld"
+# endif
+#endif
 
 #ifndef INT_FAST32_MAX
 # if INT_MAX >> 31 == 0
 typedef long int_fast32_t;
+#  define INT_FAST32_MAX LONG_MAX
+#  define INT_FAST32_MIN LONG_MIN
 # else
 typedef int int_fast32_t;
+#  define INT_FAST32_MAX INT_MAX
+#  define INT_FAST32_MIN INT_MIN
 # endif
 #endif
 
 #ifndef INTMAX_MAX
-# if defined LLONG_MAX || defined __LONG_LONG_MAX__
+# ifdef LLONG_MAX
 typedef long long intmax_t;
 #  define strtoimax strtoll
-#  define PRIdMAX "lld"
-#  ifdef LLONG_MAX
-#   define INTMAX_MAX LLONG_MAX
-#   define INTMAX_MIN LLONG_MIN
-#  else
-#   define INTMAX_MAX __LONG_LONG_MAX__
-#   define INTMAX_MIN __LONG_LONG_MIN__
-#  endif
+#  define INTMAX_MAX LLONG_MAX
+#  define INTMAX_MIN LLONG_MIN
 # else
 typedef long intmax_t;
 #  define strtoimax strtol
-#  define PRIdMAX "ld"
 #  define INTMAX_MAX LONG_MAX
 #  define INTMAX_MIN LONG_MIN
 # endif
 #endif
 
+#ifndef PRIdMAX
+# if INTMAX_MAX == LLONG_MAX
+#  define PRIdMAX "lld"
+# else
+#  define PRIdMAX "ld"
+# endif
+#endif
+
+#ifndef UINT_FAST64_MAX
+# if defined ULLONG_MAX || defined __LONG_LONG_MAX__
+typedef unsigned long long uint_fast64_t;
+# else
+#  if ULONG_MAX >> 31 >> 1 < 0xffffffff
+Please use a compiler that supports a 64-bit integer type (or wider);
+you may need to compile with "-DHAVE_STDINT_H".
+#  endif
+typedef unsigned long	uint_fast64_t;
+# endif
+#endif
+
 #ifndef UINTMAX_MAX
 # if defined ULLONG_MAX || defined __LONG_LONG_MAX__
 typedef unsigned long long uintmax_t;
-#  define PRIuMAX "llu"
 # else
 typedef unsigned long uintmax_t;
+# endif
+#endif
+
+#ifndef PRIuMAX
+# if defined ULLONG_MAX || defined __LONG_LONG_MAX__
+#  define PRIuMAX "llu"
+# else
 #  define PRIuMAX "lu"
 # endif
 #endif
@@ -239,16 +305,6 @@
 */
 
 /*
-** Some time.h implementations don't declare asctime_r.
-** Others might define it as a macro.
-** Fix the former without affecting the latter.
-*/
-
-#ifndef asctime_r
-extern char *	asctime_r(struct tm const *, char *);
-#endif
-
-/*
 ** Compile with -Dtime_tz=T to build the tz package with a private
 ** time_t type equivalent to T rather than the system-supplied time_t.
 ** This debugging feature can test unusual design decisions
@@ -256,7 +312,11 @@
 ** typical platforms.
 */
 #ifdef time_tz
+# ifdef LOCALTIME_IMPLEMENTATION
 static time_t sys_time(time_t *x) { return time(x); }
+# endif
+
+typedef time_tz tz_time_t;
 
 # undef  ctime
 # define ctime tz_ctime
@@ -272,14 +332,40 @@
 # define localtime tz_localtime
 # undef  localtime_r
 # define localtime_r tz_localtime_r
+# undef  localtime_rz
+# define localtime_rz tz_localtime_rz
 # undef  mktime
 # define mktime tz_mktime
+# undef  mktime_z
+# define mktime_z tz_mktime_z
+# undef  offtime
+# define offtime tz_offtime
+# undef  posix2time
+# define posix2time tz_posix2time
+# undef  posix2time_z
+# define posix2time_z tz_posix2time_z
 # undef  time
 # define time tz_time
+# undef  time2posix
+# define time2posix tz_time2posix
+# undef  time2posix_z
+# define time2posix_z tz_time2posix_z
 # undef  time_t
 # define time_t tz_time_t
-
-typedef time_tz time_t;
+# undef  timegm
+# define timegm tz_timegm
+# undef  timelocal
+# define timelocal tz_timelocal
+# undef  timeoff
+# define timeoff tz_timeoff
+# undef  tzalloc
+# define tzalloc tz_tzalloc
+# undef  tzfree
+# define tzfree tz_tzfree
+# undef  tzset
+# define tzset tz_tzset
+# undef  tzsetwall
+# define tzsetwall tz_tzsetwall
 
 char *ctime(time_t const *);
 char *ctime_r(time_t const *, char *);
@@ -289,36 +375,111 @@
 struct tm *localtime(time_t const *);
 struct tm *localtime_r(time_t const *restrict, struct tm *restrict);
 time_t mktime(struct tm *);
-
-static time_t
-time(time_t *p)
-{
-	time_t r = sys_time(0);
-	if (p)
-		*p = r;
-	return r;
-}
+time_t time(time_t *);
+void tzset(void);
 #endif
 
 /*
-** Private function declarations.
+** Some time.h implementations don't declare asctime_r.
+** Others might define it as a macro.
+** Fix the former without affecting the latter.
+** Similarly for timezone, daylight, and altzone.
 */
 
-char *		icatalloc(char * old, const char * new);
-char *		icpyalloc(const char * string);
-const char *	scheck(const char * string, const char * format);
+#ifndef asctime_r
+extern char *	asctime_r(struct tm const *restrict, char *restrict);
+#endif
+
+#ifdef USG_COMPAT
+# ifndef timezone
+extern long timezone;
+# endif
+# ifndef daylight
+extern int daylight;
+# endif
+#endif
+#if defined ALTZONE && !defined altzone
+extern long altzone;
+#endif
+
+/*
+** The STD_INSPIRED functions are similar, but most also need
+** declarations if time_tz is defined.
+*/
+
+#ifdef STD_INSPIRED
+# if !defined tzsetwall || defined time_tz
+void tzsetwall(void);
+# endif
+# if !defined offtime || defined time_tz
+struct tm *offtime(time_t const *, long);
+# endif
+# if !defined timegm || defined time_tz
+time_t timegm(struct tm *);
+# endif
+# if !defined timelocal || defined time_tz
+time_t timelocal(struct tm *);
+# endif
+# if !defined timeoff || defined time_tz
+time_t timeoff(struct tm *, long);
+# endif
+# if !defined time2posix || defined time_tz
+time_t time2posix(time_t);
+# endif
+# if !defined posix2time || defined time_tz
+time_t posix2time(time_t);
+# endif
+#endif
+
+/* Infer TM_ZONE on systems where this information is known, but suppress
+   guessing if NO_TM_ZONE is defined.  Similarly for TM_GMTOFF.  */
+#if (defined __GLIBC__ \
+     || defined __FreeBSD__ || defined __NetBSD__ || defined __OpenBSD__ \
+     || (defined __APPLE__ && defined __MACH__))
+# if !defined TM_GMTOFF && !defined NO_TM_GMTOFF
+#  define TM_GMTOFF tm_gmtoff
+# endif
+# if !defined TM_ZONE && !defined NO_TM_ZONE
+#  define TM_ZONE tm_zone
+# endif
+#endif
+
+/*
+** Define functions that are ABI compatible with NetBSD but have
+** better prototypes.  NetBSD 6.1.4 defines a pointer type timezone_t
+** and labors under the misconception that 'const timezone_t' is a
+** pointer to a constant.  This use of 'const' is ineffective, so it
+** is not done here.  What we call 'struct state' NetBSD calls
+** 'struct __state', but this is a private name so it doesn't matter.
+*/
+#if NETBSD_INSPIRED
+typedef struct state *timezone_t;
+struct tm *localtime_rz(timezone_t restrict, time_t const *restrict,
+			struct tm *restrict);
+time_t mktime_z(timezone_t restrict, struct tm *restrict);
+timezone_t tzalloc(char const *);
+void tzfree(timezone_t);
+# ifdef STD_INSPIRED
+#  if !defined posix2time_z || defined time_tz
+time_t posix2time_z(timezone_t, time_t) ATTRIBUTE_PURE;
+#  endif
+#  if !defined time2posix_z || defined time_tz
+time_t time2posix_z(timezone_t, time_t) ATTRIBUTE_PURE;
+#  endif
+# endif
+#endif
 
 /*
 ** Finally, some convenience items.
 */
 
-#ifndef TRUE
-#define TRUE	1
-#endif /* !defined TRUE */
-
-#ifndef FALSE
-#define FALSE	0
-#endif /* !defined FALSE */
+#if __STDC_VERSION__ < 199901
+# define true 1
+# define false 0
+# define bool int
+#else
+# include <stdbool.h>
+#endif
 
 #ifndef TYPE_BIT
 #define TYPE_BIT(type)	(sizeof (type) * CHAR_BIT)
@@ -328,15 +489,20 @@
 #define TYPE_SIGNED(type) (((type) -1) < 0)
 #endif /* !defined TYPE_SIGNED */
 
-/* The minimum and maximum finite time values.  */
-static time_t const time_t_min =
-  (TYPE_SIGNED(time_t)
-   ? (time_t) -1 << (CHAR_BIT * sizeof (time_t) - 1)
-   : 0);
-static time_t const time_t_max =
-  (TYPE_SIGNED(time_t)
-   ? - (~ 0 < 0) - ((time_t) -1 << (CHAR_BIT * sizeof (time_t) - 1))
-   : -1);
+#define TWOS_COMPLEMENT(t) ((t) ~ (t) 0 < 0)
+
+/* Max and min values of the integer type T, of which only the bottom
+   B bits are used, and where the highest-order used bit is considered
+   to be a sign bit if T is signed.  */
+#define MAXVAL(t, b)						\
+  ((t) (((t) 1 << ((b) - 1 - TYPE_SIGNED(t)))			\
+	- 1 + ((t) 1 << ((b) - 1 - TYPE_SIGNED(t)))))
+#define MINVAL(t, b)						\
+  ((t) (TYPE_SIGNED(t) ? - TWOS_COMPLEMENT(t) - MAXVAL(t, b) : 0))
+
+/* The minimum and maximum finite time values.  This assumes no padding.  */
+static time_t const time_t_min = MINVAL(time_t, TYPE_BIT(time_t));
+static time_t const time_t_max = MAXVAL(time_t, TYPE_BIT(time_t));
 
 #ifndef INT_STRLEN_MAXIMUM
 /*
@@ -360,6 +526,10 @@
 # define INITIALIZE(x)
 #endif
 
+#ifndef UNINIT_TRAP
+# define UNINIT_TRAP 0
+#endif
+
 /*
 ** For the benefit of GNU folk...
 ** '_(MSGID)' uses the current locale's message library string for MSGID.
@@ -374,7 +544,7 @@
 #endif /* !HAVE_GETTEXT */
 #endif /* !defined _ */
 
-#if !defined TZ_DOMAIN && defined TZ_DOMAINDIR
+#if !defined TZ_DOMAIN && defined HAVE_GETTEXT
 # define TZ_DOMAIN "tz"
 #endif
 
@@ -405,8 +575,4 @@
 #define SECSPERREPEAT_BITS	34	/* ceil(log2(SECSPERREPEAT)) */
 #endif /* !defined SECSPERREPEAT_BITS */
 
-/*
-** UNIX was a registered trademark of The Open Group in 2003.
-*/
-
 #endif /* !defined PRIVATE_H */
diff --git a/libc/tzcode/strftime.c b/libc/tzcode/strftime.c
index 4328b4c..4349cf6 100644
--- a/libc/tzcode/strftime.c
+++ b/libc/tzcode/strftime.c
@@ -55,15 +55,7 @@
     const char *    date_fmt;
 };
 
-#ifdef LOCALE_HOME
-#include "sys/stat.h"
-static struct lc_time_T                localebuf;
-static struct lc_time_T *      _loc(void);
-#define Locale _loc()
-#endif /* defined LOCALE_HOME */
-#ifndef LOCALE_HOME
 #define Locale  (&C_time_locale)
-#endif /* !defined LOCALE_HOME */
 
 static const struct lc_time_T   C_time_locale = {
     {
@@ -115,7 +107,7 @@
 static char *   _conv(int, const char *, char *, const char *);
 static char *   _fmt(const char *, const struct tm *, char *, const char *,
             int *);
-static char *   _yconv(int, int, int, int, char *, const char *, int);
+static char *   _yconv(int, int, bool, bool, char *, const char *, int);
 static char *   getformat(int, char *, char *, char *, char *);
 
 extern char *   tzname[];
@@ -132,32 +124,28 @@
 #define FORCE_LOWER_CASE 0x100
 
 size_t
-strftime(char * const s, const size_t maxsize, const char *const format,
-        const struct tm *const t)
+strftime(char *s, size_t maxsize, const char *format, const struct tm *t)
 {
     char *  p;
     int warn;
 
     tzset();
-#ifdef LOCALE_HOME
-    localebuf.mon[0] = 0;
-#endif /* defined LOCALE_HOME */
     warn = IN_NONE;
     p = _fmt(((format == NULL) ? "%c" : format), t, s, s + maxsize, &warn);
 #ifndef NO_RUN_TIME_WARNINGS_ABOUT_YEAR_2000_PROBLEMS_THANK_YOU
     if (warn != IN_NONE && getenv(YEAR_2000_NAME) != NULL) {
-        (void) fprintf(stderr, "\n");
+        fprintf(stderr, "\n");
         if (format == NULL)
-            (void) fprintf(stderr, "NULL strftime format ");
-        else    (void) fprintf(stderr, "strftime format \"%s\" ",
+            fprintf(stderr, "NULL strftime format ");
+        else    fprintf(stderr, "strftime format \"%s\" ",
                 format);
-        (void) fprintf(stderr, "yields only two digits of years in ");
+        fprintf(stderr, "yields only two digits of years in ");
         if (warn == IN_SOME)
-            (void) fprintf(stderr, "some locales");
+            fprintf(stderr, "some locales");
         else if (warn == IN_THIS)
-            (void) fprintf(stderr, "the current locale");
-        else    (void) fprintf(stderr, "all locales");
-        (void) fprintf(stderr, "\n");
+            fprintf(stderr, "the current locale");
+        else    fprintf(stderr, "all locales");
+        fprintf(stderr, "\n");
     }
 #endif /* !defined NO_RUN_TIME_WARNINGS_ABOUT_YEAR_2000_PROBLEMS_THANK_YOU */
     if (p == s + maxsize)
@@ -171,20 +159,17 @@
     switch (modifier) {
     case '_':
         return underscore;
-
     case '-':
         return dash;
-
     case '0':
         return zero;
     }
-
     return normal;
 }
 
 static char *
-_fmt(const char *format, const struct tm *const t, char * pt,
-        const char *const ptlim, int *warnp)
+_fmt(const char *format, const struct tm *t, char *pt,
+        const char *ptlim, int *warnp)
 {
     for ( ; *format; ++format) {
         if (*format == '%') {
@@ -227,8 +212,8 @@
                 ** something completely different.
                 ** (ado, 1993-05-24)
                 */
-                pt = _yconv(t->tm_year, TM_YEAR_BASE, 1, 0,
-                    pt, ptlim, modifier);
+                pt = _yconv(t->tm_year, TM_YEAR_BASE,
+                    true, false, pt, ptlim, modifier);
                 continue;
             case 'c':
                 {
@@ -245,10 +230,7 @@
                                 pt = _fmt("%m/%d/%y", t, pt, ptlim, warnp);
                 continue;
             case 'd':
-                                pt = _conv(t->tm_mday,
-                                           getformat(modifier, "%02d",
-                                                     "%2d", "%d", "%02d"),
-                                           pt, ptlim);
+                                pt = _conv(t->tm_mday, getformat(modifier, "%02d", "%2d", "%d", "%02d"), pt, ptlim);
                 continue;
             case 'E':
             case 'O':
@@ -270,31 +252,21 @@
                 modifier = *format;
                 goto label;
             case 'e':
-                pt = _conv(t->tm_mday,
-                                           getformat(modifier, "%2d",
-                                                     "%2d", "%d", "%02d"),
-                                           pt, ptlim);
+                pt = _conv(t->tm_mday, getformat(modifier, "%2d", "%2d", "%d", "%02d"), pt, ptlim);
                 continue;
             case 'F':
                 pt = _fmt("%Y-%m-%d", t, pt, ptlim, warnp);
                 continue;
             case 'H':
-                pt = _conv(t->tm_hour,
-                                           getformat(modifier, "%02d",
-                                                     "%2d", "%d", "%02d"),
-                                           pt, ptlim);
+                pt = _conv(t->tm_hour, getformat(modifier, "%02d", "%2d", "%d", "%02d"), pt, ptlim);
                 continue;
             case 'I':
                 pt = _conv((t->tm_hour % 12) ?
                     (t->tm_hour % 12) : 12,
-                    getformat(modifier, "%02d",
-                                                  "%2d", "%d", "%02d"),
-                                        pt, ptlim);
+                    getformat(modifier, "%02d", "%2d", "%d", "%02d"), pt, ptlim);
                 continue;
             case 'j':
-                pt = _conv(t->tm_yday + 1,
-                           getformat(modifier, "%03d", "%3d", "%d", "%03d"),
-                           pt, ptlim);
+                pt = _conv(t->tm_yday + 1, getformat(modifier, "%03d", "%3d", "%d", "%03d"), pt, ptlim);
                 continue;
             case 'k':
                 /*
@@ -307,10 +279,7 @@
                 ** "%l" have been swapped.
                 ** (ado, 1993-05-24)
                 */
-                pt = _conv(t->tm_hour,
-                                           getformat(modifier, "%2d",
-                                                     "%2d", "%d", "%02d"),
-                                           pt, ptlim);
+                pt = _conv(t->tm_hour, getformat(modifier, "%2d", "%2d", "%d", "%02d"), pt, ptlim);
                 continue;
 #ifdef KITCHEN_SINK
             case 'K':
@@ -332,36 +301,23 @@
                 */
                 pt = _conv((t->tm_hour % 12) ?
                     (t->tm_hour % 12) : 12,
-                    getformat(modifier, "%2d",
-                                                  "%2d", "%d", "%02d"),
-                                        pt, ptlim);
+                    getformat(modifier, "%2d", "%2d", "%d", "%02d"), pt, ptlim);
                 continue;
             case 'M':
-                pt = _conv(t->tm_min,
-                                           getformat(modifier, "%02d",
-                                                     "%2d", "%d", "%02d"),
-                                           pt, ptlim);
+                pt = _conv(t->tm_min, getformat(modifier, "%02d", "%2d", "%d", "%02d"), pt, ptlim);
                 continue;
             case 'm':
-                pt = _conv(t->tm_mon + 1,
-                                           getformat(modifier, "%02d",
-                                                     "%2d", "%d", "%02d"),
-                                           pt, ptlim);
+                pt = _conv(t->tm_mon + 1, getformat(modifier, "%02d", "%2d", "%d", "%02d"), pt, ptlim);
                 continue;
             case 'n':
                 pt = _add("\n", pt, ptlim, modifier);
                 continue;
+            case 'P':
             case 'p':
                 pt = _add((t->tm_hour >= (HOURSPERDAY / 2)) ?
                     Locale->pm :
                     Locale->am,
-                    pt, ptlim, modifier);
-                continue;
-            case 'P':
-                pt = _add((t->tm_hour >= (HOURSPERDAY / 2)) ?
-                    Locale->pm :
-                    Locale->am,
-                    pt, ptlim, FORCE_LOWER_CASE);
+                    pt, ptlim, (*format == 'P') ? FORCE_LOWER_CASE : modifier);
                 continue;
             case 'R':
                 pt = _fmt("%H:%M", t, pt, ptlim, warnp);
@@ -370,10 +326,7 @@
                 pt = _fmt("%I:%M:%S %p", t, pt, ptlim, warnp);
                 continue;
             case 'S':
-                pt = _conv(t->tm_sec,
-                                           getformat(modifier, "%02d",
-                                                     "%2d", "%d", "%02d"),
-                                           pt, ptlim);
+                pt = _conv(t->tm_sec, getformat(modifier, "%02d", "%2d", "%d", "%02d"), pt, ptlim);
                 continue;
             case 's':
                 {
@@ -385,10 +338,10 @@
                     tm = *t;
                     mkt = mktime64(&tm);
                     if (TYPE_SIGNED(time64_t))
-                        (void) snprintf(buf, sizeof(buf), "%lld",
-                            (long long) mkt);
-                    else    (void) snprintf(buf, sizeof(buf), "%llu",
-                            (unsigned long long) mkt);
+                        snprintf(buf, sizeof(buf), "%"PRIdMAX,
+                                 (intmax_t) mkt);
+                    else    snprintf(buf, sizeof(buf), "%"PRIuMAX,
+                                     (uintmax_t) mkt);
                     pt = _add(buf, pt, ptlim, modifier);
                 }
                 continue;
@@ -401,9 +354,7 @@
             case 'U':
                 pt = _conv((t->tm_yday + DAYSPERWEEK -
                     t->tm_wday) / DAYSPERWEEK,
-                    getformat(modifier, "%02d",
-                                                  "%2d", "%d", "%02d"),
-                                        pt, ptlim);
+                    getformat(modifier, "%02d", "%2d", "%d", "%02d"), pt, ptlim);
                 continue;
             case 'u':
                 /*
@@ -413,7 +364,8 @@
                 ** (ado, 1993-05-24)
                 */
                 pt = _conv((t->tm_wday == 0) ?
-                    DAYSPERWEEK : t->tm_wday, "%d", pt, ptlim);
+                    DAYSPERWEEK : t->tm_wday,
+                    "%d", pt, ptlim);
                 continue;
             case 'V':   /* ISO 8601 week number */
             case 'G':   /* ISO 8601 year (four digits) */
@@ -493,14 +445,15 @@
                             w = 53;
 #endif /* defined XPG4_1994_04_09 */
                     if (*format == 'V')
-                        pt = _conv(w,
-                                getformat(modifier, "%02d", "%2d", "%d", "%02d"),
+                        pt = _conv(w, getformat(modifier, "%02d", "%2d", "%d", "%02d"),
                                pt, ptlim);
                     else if (*format == 'g') {
                         *warnp = IN_ALL;
-                        pt = _yconv(year, base, 0, 1,
+                        pt = _yconv(year, base,
+                            false, true,
                             pt, ptlim, modifier);
-                    } else  pt = _yconv(year, base, 1, 1,
+                    } else  pt = _yconv(year, base,
+                            true, true,
                             pt, ptlim, modifier);
                 }
                 continue;
@@ -517,9 +470,7 @@
                     (t->tm_wday ?
                     (t->tm_wday - 1) :
                     (DAYSPERWEEK - 1))) / DAYSPERWEEK,
-                    getformat(modifier, "%02d",
-                                                  "%2d", "%d", "%02d"),
-                                        pt, ptlim);
+                    getformat(modifier, "%02d", "%2d", "%d", "%02d"), pt, ptlim);
                 continue;
             case 'w':
                 pt = _conv(t->tm_wday, "%d", pt, ptlim);
@@ -540,23 +491,39 @@
                 continue;
             case 'y':
                 *warnp = IN_ALL;
-                pt = _yconv(t->tm_year, TM_YEAR_BASE, 0, 1,
+                pt = _yconv(t->tm_year, TM_YEAR_BASE,
+                    false, true,
                     pt, ptlim, modifier);
                 continue;
             case 'Y':
-                pt = _yconv(t->tm_year, TM_YEAR_BASE, 1, 1,
+                pt = _yconv(t->tm_year, TM_YEAR_BASE,
+                    true, true,
                     pt, ptlim, modifier);
                 continue;
             case 'Z':
 #ifdef TM_ZONE
-                if (t->TM_ZONE != NULL)
-                    pt = _add(t->TM_ZONE, pt, ptlim,
-                                                  modifier);
-                else
-#endif /* defined TM_ZONE */
+                // BEGIN: Android-changed.
+                {
+                    const char* zone = t->TM_ZONE;
+                    if (!zone || !*zone) {
+                        // "The value of tm_isdst shall be positive if Daylight Savings Time is
+                        // in effect, 0 if Daylight Savings Time is not in effect, and negative
+                        // if the information is not available."
+                        if (t->tm_isdst == 0) zone = tzname[0];
+                        else if (t->tm_isdst > 0) zone = tzname[1];
+
+                        // "Replaced by the timezone name or abbreviation, or by no bytes if no
+                        // timezone information exists."
+                        if (!zone || !*zone) zone = "";
+                    }
+                    pt = _add(zone, pt, ptlim, modifier);
+                }
+                // END: Android-changed.
+#else
                 if (t->tm_isdst >= 0)
                     pt = _add(tzname[t->tm_isdst != 0],
-                        pt, ptlim, modifier);
+                        pt, ptlim);
+#endif
                 /*
                 ** C99 says that %Z must be replaced by the
                 ** empty string if the time zone is not
@@ -613,10 +580,7 @@
                 diff /= SECSPERMIN;
                 diff = (diff / MINSPERHOUR) * 100 +
                     (diff % MINSPERHOUR);
-                pt = _conv(diff,
-                                           getformat(modifier, "%04d",
-                                                     "%4d", "%d", "%04d"),
-                                           pt, ptlim);
+                pt = _conv(diff, getformat(modifier, "%04d", "%4d", "%d", "%04d"), pt, ptlim);
                 }
                 continue;
             case '+':
@@ -641,13 +605,12 @@
 }
 
 static char *
-_conv(const int n, const char *const format, char *const pt,
-        const char *const ptlim)
+_conv(int n, const char *format, char *pt, const char *ptlim)
 {
-    char    buf[INT_STRLEN_MAXIMUM(int) + 1];
+	char	buf[INT_STRLEN_MAXIMUM(int) + 1];
 
-    (void) snprintf(buf, sizeof(buf), format, n);
-    return _add(buf, pt, ptlim, 0);
+	snprintf(buf, sizeof(buf), format, n);
+	return _add(buf, pt, ptlim, 0);
 }
 
 static char *
@@ -699,8 +662,8 @@
 */
 
 static char *
-_yconv(const int a, const int b, const int convert_top, const int convert_yy,
-        char *pt, const char *const ptlim, int modifier)
+_yconv(int a, int b, bool convert_top, bool convert_yy,
+       char *pt, const char *ptlim, int modifier)
 {
     register int    lead;
     register int    trail;
diff --git a/libc/tzcode/tzfile.h b/libc/tzcode/tzfile.h
index 529650d..ebecd68 100644
--- a/libc/tzcode/tzfile.h
+++ b/libc/tzcode/tzfile.h
@@ -40,7 +40,7 @@
 struct tzhead {
 	char	tzh_magic[4];		/* TZ_MAGIC */
 	char	tzh_version[1];		/* '\0' or '2' or '3' as of 2013 */
-	char	tzh_reserved[15];	/* reserved--must be zero */
+	char	tzh_reserved[15];	/* reserved; must be zero */
 	char	tzh_ttisgmtcnt[4];	/* coded number of trans. time flags */
 	char	tzh_ttisstdcnt[4];	/* coded number of trans. time flags */
 	char	tzh_leapcnt[4];		/* coded number of leap seconds */
@@ -62,13 +62,13 @@
 **	tzh_leapcnt repetitions of
 **		one (char [4])		coded leap second transition times
 **		one (char [4])		total correction after above
-**	tzh_ttisstdcnt (char)s		indexed by type; if TRUE, transition
-**					time is standard time, if FALSE,
+**	tzh_ttisstdcnt (char)s		indexed by type; if 1, transition
+**					time is standard time, if 0,
 **					transition time is wall clock time
 **					if absent, transition times are
 **					assumed to be wall clock time
-**	tzh_ttisgmtcnt (char)s		indexed by type; if TRUE, transition
-**					time is UT, if FALSE,
+**	tzh_ttisgmtcnt (char)s		indexed by type; if 1, transition
+**					time is UT, if 0,
 **					transition time is local time
 **					if absent, transition times are
 **					assumed to be local time
@@ -97,7 +97,7 @@
 */
 
 #ifndef TZ_MAX_TIMES
-#define TZ_MAX_TIMES	1200
+#define TZ_MAX_TIMES	2000
 #endif /* !defined TZ_MAX_TIMES */
 
 #ifndef TZ_MAX_TYPES
diff --git a/libc/upstream-dlmalloc/README.txt b/libc/upstream-dlmalloc/README.txt
deleted file mode 100644
index 485704b..0000000
--- a/libc/upstream-dlmalloc/README.txt
+++ /dev/null
@@ -1,10 +0,0 @@
-This directory contains malloc/free routines implemented by Doug Lea
-(aka dlmalloc). You should not edit these files directly. Make fixes
-upstream and then pull down the new version of the file.
-
-This code is imported from: ftp://g.oswego.edu/pub/misc/
-It is currently version 2.8.6.
-
-Currently there are very minor modifications that are signified with:
-BEGIN android-changed: change description
-END android-changed
diff --git a/libc/upstream-dlmalloc/malloc.c b/libc/upstream-dlmalloc/malloc.c
deleted file mode 100644
index 3c9d36b..0000000
--- a/libc/upstream-dlmalloc/malloc.c
+++ /dev/null
@@ -1,6318 +0,0 @@
-/*
-  This is a version (aka dlmalloc) of malloc/free/realloc written by
-  Doug Lea and released to the public domain, as explained at
-  http://creativecommons.org/publicdomain/zero/1.0/ Send questions,
-  comments, complaints, performance data, etc to dl@cs.oswego.edu
-
-* Version 2.8.6 Wed Aug 29 06:57:58 2012  Doug Lea
-   Note: There may be an updated version of this malloc obtainable at
-           ftp://gee.cs.oswego.edu/pub/misc/malloc.c
-         Check before installing!
-
-* Quickstart
-
-  This library is all in one file to simplify the most common usage:
-  ftp it, compile it (-O3), and link it into another program. All of
-  the compile-time options default to reasonable values for use on
-  most platforms.  You might later want to step through various
-  compile-time and dynamic tuning options.
-
-  For convenience, an include file for code using this malloc is at:
-     ftp://gee.cs.oswego.edu/pub/misc/malloc-2.8.6.h
-  You don't really need this .h file unless you call functions not
-  defined in your system include files.  The .h file contains only the
-  excerpts from this file needed for using this malloc on ANSI C/C++
-  systems, so long as you haven't changed compile-time options about
-  naming and tuning parameters.  If you do, then you can create your
-  own malloc.h that does include all settings by cutting at the point
-  indicated below. Note that you may already by default be using a C
-  library containing a malloc that is based on some version of this
-  malloc (for example in linux). You might still want to use the one
-  in this file to customize settings or to avoid overheads associated
-  with library versions.
-
-* Vital statistics:
-
-  Supported pointer/size_t representation:       4 or 8 bytes
-       size_t MUST be an unsigned type of the same width as
-       pointers. (If you are using an ancient system that declares
-       size_t as a signed type, or need it to be a different width
-       than pointers, you can use a previous release of this malloc
-       (e.g. 2.7.2) supporting these.)
-
-  Alignment:                                     8 bytes (minimum)
-       This suffices for nearly all current machines and C compilers.
-       However, you can define MALLOC_ALIGNMENT to be wider than this
-       if necessary (up to 128bytes), at the expense of using more space.
-
-  Minimum overhead per allocated chunk:   4 or  8 bytes (if 4byte sizes)
-                                          8 or 16 bytes (if 8byte sizes)
-       Each malloced chunk has a hidden word of overhead holding size
-       and status information, and additional cross-check word
-       if FOOTERS is defined.
-
-  Minimum allocated size: 4-byte ptrs:  16 bytes    (including overhead)
-                          8-byte ptrs:  32 bytes    (including overhead)
-
-       Even a request for zero bytes (i.e., malloc(0)) returns a
-       pointer to something of the minimum allocatable size.
-       The maximum overhead wastage (i.e., number of extra bytes
-       allocated than were requested in malloc) is less than or equal
-       to the minimum size, except for requests >= mmap_threshold that
-       are serviced via mmap(), where the worst case wastage is about
-       32 bytes plus the remainder from a system page (the minimal
-       mmap unit); typically 4096 or 8192 bytes.
-
-  Security: static-safe; optionally more or less
-       The "security" of malloc refers to the ability of malicious
-       code to accentuate the effects of errors (for example, freeing
-       space that is not currently malloc'ed or overwriting past the
-       ends of chunks) in code that calls malloc.  This malloc
-       guarantees not to modify any memory locations below the base of
-       heap, i.e., static variables, even in the presence of usage
-       errors.  The routines additionally detect most improper frees
-       and reallocs.  All this holds as long as the static bookkeeping
-       for malloc itself is not corrupted by some other means.  This
-       is only one aspect of security -- these checks do not, and
-       cannot, detect all possible programming errors.
-
-       If FOOTERS is defined nonzero, then each allocated chunk
-       carries an additional check word to verify that it was malloced
-       from its space.  These check words are the same within each
-       execution of a program using malloc, but differ across
-       executions, so externally crafted fake chunks cannot be
-       freed. This improves security by rejecting frees/reallocs that
-       could corrupt heap memory, in addition to the checks preventing
-       writes to statics that are always on.  This may further improve
-       security at the expense of time and space overhead.  (Note that
-       FOOTERS may also be worth using with MSPACES.)
-
-       By default detected errors cause the program to abort (calling
-       "abort()"). You can override this to instead proceed past
-       errors by defining PROCEED_ON_ERROR.  In this case, a bad free
-       has no effect, and a malloc that encounters a bad address
-       caused by user overwrites will ignore the bad address by
-       dropping pointers and indices to all known memory. This may
-       be appropriate for programs that should continue if at all
-       possible in the face of programming errors, although they may
-       run out of memory because dropped memory is never reclaimed.
-
-       If you don't like either of these options, you can define
-       CORRUPTION_ERROR_ACTION and USAGE_ERROR_ACTION to do anything
-       else. And if if you are sure that your program using malloc has
-       no errors or vulnerabilities, you can define INSECURE to 1,
-       which might (or might not) provide a small performance improvement.
-
-       It is also possible to limit the maximum total allocatable
-       space, using malloc_set_footprint_limit. This is not
-       designed as a security feature in itself (calls to set limits
-       are not screened or privileged), but may be useful as one
-       aspect of a secure implementation.
-
-  Thread-safety: NOT thread-safe unless USE_LOCKS defined non-zero
-       When USE_LOCKS is defined, each public call to malloc, free,
-       etc is surrounded with a lock. By default, this uses a plain
-       pthread mutex, win32 critical section, or a spin-lock if if
-       available for the platform and not disabled by setting
-       USE_SPIN_LOCKS=0.  However, if USE_RECURSIVE_LOCKS is defined,
-       recursive versions are used instead (which are not required for
-       base functionality but may be needed in layered extensions).
-       Using a global lock is not especially fast, and can be a major
-       bottleneck.  It is designed only to provide minimal protection
-       in concurrent environments, and to provide a basis for
-       extensions.  If you are using malloc in a concurrent program,
-       consider instead using nedmalloc
-       (http://www.nedprod.com/programs/portable/nedmalloc/) or
-       ptmalloc (See http://www.malloc.de), which are derived from
-       versions of this malloc.
-
-  System requirements: Any combination of MORECORE and/or MMAP/MUNMAP
-       This malloc can use unix sbrk or any emulation (invoked using
-       the CALL_MORECORE macro) and/or mmap/munmap or any emulation
-       (invoked using CALL_MMAP/CALL_MUNMAP) to get and release system
-       memory.  On most unix systems, it tends to work best if both
-       MORECORE and MMAP are enabled.  On Win32, it uses emulations
-       based on VirtualAlloc. It also uses common C library functions
-       like memset.
-
-  Compliance: I believe it is compliant with the Single Unix Specification
-       (See http://www.unix.org). Also SVID/XPG, ANSI C, and probably
-       others as well.
-
-* Overview of algorithms
-
-  This is not the fastest, most space-conserving, most portable, or
-  most tunable malloc ever written. However it is among the fastest
-  while also being among the most space-conserving, portable and
-  tunable.  Consistent balance across these factors results in a good
-  general-purpose allocator for malloc-intensive programs.
-
-  In most ways, this malloc is a best-fit allocator. Generally, it
-  chooses the best-fitting existing chunk for a request, with ties
-  broken in approximately least-recently-used order. (This strategy
-  normally maintains low fragmentation.) However, for requests less
-  than 256bytes, it deviates from best-fit when there is not an
-  exactly fitting available chunk by preferring to use space adjacent
-  to that used for the previous small request, as well as by breaking
-  ties in approximately most-recently-used order. (These enhance
-  locality of series of small allocations.)  And for very large requests
-  (>= 256Kb by default), it relies on system memory mapping
-  facilities, if supported.  (This helps avoid carrying around and
-  possibly fragmenting memory used only for large chunks.)
-
-  All operations (except malloc_stats and mallinfo) have execution
-  times that are bounded by a constant factor of the number of bits in
-  a size_t, not counting any clearing in calloc or copying in realloc,
-  or actions surrounding MORECORE and MMAP that have times
-  proportional to the number of non-contiguous regions returned by
-  system allocation routines, which is often just 1. In real-time
-  applications, you can optionally suppress segment traversals using
-  NO_SEGMENT_TRAVERSAL, which assures bounded execution even when
-  system allocators return non-contiguous spaces, at the typical
-  expense of carrying around more memory and increased fragmentation.
-
-  The implementation is not very modular and seriously overuses
-  macros. Perhaps someday all C compilers will do as good a job
-  inlining modular code as can now be done by brute-force expansion,
-  but now, enough of them seem not to.
-
-  Some compilers issue a lot of warnings about code that is
-  dead/unreachable only on some platforms, and also about intentional
-  uses of negation on unsigned types. All known cases of each can be
-  ignored.
-
-  For a longer but out of date high-level description, see
-     http://gee.cs.oswego.edu/dl/html/malloc.html
-
-* MSPACES
-  If MSPACES is defined, then in addition to malloc, free, etc.,
-  this file also defines mspace_malloc, mspace_free, etc. These
-  are versions of malloc routines that take an "mspace" argument
-  obtained using create_mspace, to control all internal bookkeeping.
-  If ONLY_MSPACES is defined, only these versions are compiled.
-  So if you would like to use this allocator for only some allocations,
-  and your system malloc for others, you can compile with
-  ONLY_MSPACES and then do something like...
-    static mspace mymspace = create_mspace(0,0); // for example
-    #define mymalloc(bytes)  mspace_malloc(mymspace, bytes)
-
-  (Note: If you only need one instance of an mspace, you can instead
-  use "USE_DL_PREFIX" to relabel the global malloc.)
-
-  You can similarly create thread-local allocators by storing
-  mspaces as thread-locals. For example:
-    static __thread mspace tlms = 0;
-    void*  tlmalloc(size_t bytes) {
-      if (tlms == 0) tlms = create_mspace(0, 0);
-      return mspace_malloc(tlms, bytes);
-    }
-    void  tlfree(void* mem) { mspace_free(tlms, mem); }
-
-  Unless FOOTERS is defined, each mspace is completely independent.
-  You cannot allocate from one and free to another (although
-  conformance is only weakly checked, so usage errors are not always
-  caught). If FOOTERS is defined, then each chunk carries around a tag
-  indicating its originating mspace, and frees are directed to their
-  originating spaces. Normally, this requires use of locks.
-
- -------------------------  Compile-time options ---------------------------
-
-Be careful in setting #define values for numerical constants of type
-size_t. On some systems, literal values are not automatically extended
-to size_t precision unless they are explicitly casted. You can also
-use the symbolic values MAX_SIZE_T, SIZE_T_ONE, etc below.
-
-WIN32                    default: defined if _WIN32 defined
-  Defining WIN32 sets up defaults for MS environment and compilers.
-  Otherwise defaults are for unix. Beware that there seem to be some
-  cases where this malloc might not be a pure drop-in replacement for
-  Win32 malloc: Random-looking failures from Win32 GDI API's (eg;
-  SetDIBits()) may be due to bugs in some video driver implementations
-  when pixel buffers are malloc()ed, and the region spans more than
-  one VirtualAlloc()ed region. Because dlmalloc uses a small (64Kb)
-  default granularity, pixel buffers may straddle virtual allocation
-  regions more often than when using the Microsoft allocator.  You can
-  avoid this by using VirtualAlloc() and VirtualFree() for all pixel
-  buffers rather than using malloc().  If this is not possible,
-  recompile this malloc with a larger DEFAULT_GRANULARITY. Note:
-  in cases where MSC and gcc (cygwin) are known to differ on WIN32,
-  conditions use _MSC_VER to distinguish them.
-
-DLMALLOC_EXPORT       default: extern
-  Defines how public APIs are declared. If you want to export via a
-  Windows DLL, you might define this as
-    #define DLMALLOC_EXPORT extern  __declspec(dllexport)
-  If you want a POSIX ELF shared object, you might use
-    #define DLMALLOC_EXPORT extern __attribute__((visibility("default")))
-
-MALLOC_ALIGNMENT         default: (size_t)(2 * sizeof(void *))
-  Controls the minimum alignment for malloc'ed chunks.  It must be a
-  power of two and at least 8, even on machines for which smaller
-  alignments would suffice. It may be defined as larger than this
-  though. Note however that code and data structures are optimized for
-  the case of 8-byte alignment.
-
-MSPACES                  default: 0 (false)
-  If true, compile in support for independent allocation spaces.
-  This is only supported if HAVE_MMAP is true.
-
-ONLY_MSPACES             default: 0 (false)
-  If true, only compile in mspace versions, not regular versions.
-
-USE_LOCKS                default: 0 (false)
-  Causes each call to each public routine to be surrounded with
-  pthread or WIN32 mutex lock/unlock. (If set true, this can be
-  overridden on a per-mspace basis for mspace versions.) If set to a
-  non-zero value other than 1, locks are used, but their
-  implementation is left out, so lock functions must be supplied manually,
-  as described below.
-
-USE_SPIN_LOCKS           default: 1 iff USE_LOCKS and spin locks available
-  If true, uses custom spin locks for locking. This is currently
-  supported only gcc >= 4.1, older gccs on x86 platforms, and recent
-  MS compilers.  Otherwise, posix locks or win32 critical sections are
-  used.
-
-USE_RECURSIVE_LOCKS      default: not defined
-  If defined nonzero, uses recursive (aka reentrant) locks, otherwise
-  uses plain mutexes. This is not required for malloc proper, but may
-  be needed for layered allocators such as nedmalloc.
-
-LOCK_AT_FORK            default: not defined
-  If defined nonzero, performs pthread_atfork upon initialization
-  to initialize child lock while holding parent lock. The implementation
-  assumes that pthread locks (not custom locks) are being used. In other
-  cases, you may need to customize the implementation.
-
-FOOTERS                  default: 0
-  If true, provide extra checking and dispatching by placing
-  information in the footers of allocated chunks. This adds
-  space and time overhead.
-
-INSECURE                 default: 0
-  If true, omit checks for usage errors and heap space overwrites.
-
-USE_DL_PREFIX            default: NOT defined
-  Causes compiler to prefix all public routines with the string 'dl'.
-  This can be useful when you only want to use this malloc in one part
-  of a program, using your regular system malloc elsewhere.
-
-MALLOC_INSPECT_ALL       default: NOT defined
-  If defined, compiles malloc_inspect_all and mspace_inspect_all, that
-  perform traversal of all heap space.  Unless access to these
-  functions is otherwise restricted, you probably do not want to
-  include them in secure implementations.
-
-ABORT                    default: defined as abort()
-  Defines how to abort on failed checks.  On most systems, a failed
-  check cannot die with an "assert" or even print an informative
-  message, because the underlying print routines in turn call malloc,
-  which will fail again.  Generally, the best policy is to simply call
-  abort(). It's not very useful to do more than this because many
-  errors due to overwriting will show up as address faults (null, odd
-  addresses etc) rather than malloc-triggered checks, so will also
-  abort.  Also, most compilers know that abort() does not return, so
-  can better optimize code conditionally calling it.
-
-PROCEED_ON_ERROR           default: defined as 0 (false)
-  Controls whether detected bad addresses cause them to bypassed
-  rather than aborting. If set, detected bad arguments to free and
-  realloc are ignored. And all bookkeeping information is zeroed out
-  upon a detected overwrite of freed heap space, thus losing the
-  ability to ever return it from malloc again, but enabling the
-  application to proceed. If PROCEED_ON_ERROR is defined, the
-  static variable malloc_corruption_error_count is compiled in
-  and can be examined to see if errors have occurred. This option
-  generates slower code than the default abort policy.
-
-DEBUG                    default: NOT defined
-  The DEBUG setting is mainly intended for people trying to modify
-  this code or diagnose problems when porting to new platforms.
-  However, it may also be able to better isolate user errors than just
-  using runtime checks.  The assertions in the check routines spell
-  out in more detail the assumptions and invariants underlying the
-  algorithms.  The checking is fairly extensive, and will slow down
-  execution noticeably. Calling malloc_stats or mallinfo with DEBUG
-  set will attempt to check every non-mmapped allocated and free chunk
-  in the course of computing the summaries.
-
-ABORT_ON_ASSERT_FAILURE   default: defined as 1 (true)
-  Debugging assertion failures can be nearly impossible if your
-  version of the assert macro causes malloc to be called, which will
-  lead to a cascade of further failures, blowing the runtime stack.
-  ABORT_ON_ASSERT_FAILURE cause assertions failures to call abort(),
-  which will usually make debugging easier.
-
-MALLOC_FAILURE_ACTION     default: sets errno to ENOMEM, or no-op on win32
-  The action to take before "return 0" when malloc fails to be able to
-  return memory because there is none available.
-
-HAVE_MORECORE             default: 1 (true) unless win32 or ONLY_MSPACES
-  True if this system supports sbrk or an emulation of it.
-
-MORECORE                  default: sbrk
-  The name of the sbrk-style system routine to call to obtain more
-  memory.  See below for guidance on writing custom MORECORE
-  functions. The type of the argument to sbrk/MORECORE varies across
-  systems.  It cannot be size_t, because it supports negative
-  arguments, so it is normally the signed type of the same width as
-  size_t (sometimes declared as "intptr_t").  It doesn't much matter
-  though. Internally, we only call it with arguments less than half
-  the max value of a size_t, which should work across all reasonable
-  possibilities, although sometimes generating compiler warnings.
-
-MORECORE_CONTIGUOUS       default: 1 (true) if HAVE_MORECORE
-  If true, take advantage of fact that consecutive calls to MORECORE
-  with positive arguments always return contiguous increasing
-  addresses.  This is true of unix sbrk. It does not hurt too much to
-  set it true anyway, since malloc copes with non-contiguities.
-  Setting it false when definitely non-contiguous saves time
-  and possibly wasted space it would take to discover this though.
-
-MORECORE_CANNOT_TRIM      default: NOT defined
-  True if MORECORE cannot release space back to the system when given
-  negative arguments. This is generally necessary only if you are
-  using a hand-crafted MORECORE function that cannot handle negative
-  arguments.
-
-NO_SEGMENT_TRAVERSAL       default: 0
-  If non-zero, suppresses traversals of memory segments
-  returned by either MORECORE or CALL_MMAP. This disables
-  merging of segments that are contiguous, and selectively
-  releasing them to the OS if unused, but bounds execution times.
-
-HAVE_MMAP                 default: 1 (true)
-  True if this system supports mmap or an emulation of it.  If so, and
-  HAVE_MORECORE is not true, MMAP is used for all system
-  allocation. If set and HAVE_MORECORE is true as well, MMAP is
-  primarily used to directly allocate very large blocks. It is also
-  used as a backup strategy in cases where MORECORE fails to provide
-  space from system. Note: A single call to MUNMAP is assumed to be
-  able to unmap memory that may have be allocated using multiple calls
-  to MMAP, so long as they are adjacent.
-
-HAVE_MREMAP               default: 1 on linux, else 0
-  If true realloc() uses mremap() to re-allocate large blocks and
-  extend or shrink allocation spaces.
-
-MMAP_CLEARS               default: 1 except on WINCE.
-  True if mmap clears memory so calloc doesn't need to. This is true
-  for standard unix mmap using /dev/zero and on WIN32 except for WINCE.
-
-USE_BUILTIN_FFS            default: 0 (i.e., not used)
-  Causes malloc to use the builtin ffs() function to compute indices.
-  Some compilers may recognize and intrinsify ffs to be faster than the
-  supplied C version. Also, the case of x86 using gcc is special-cased
-  to an asm instruction, so is already as fast as it can be, and so
-  this setting has no effect. Similarly for Win32 under recent MS compilers.
-  (On most x86s, the asm version is only slightly faster than the C version.)
-
-malloc_getpagesize         default: derive from system includes, or 4096.
-  The system page size. To the extent possible, this malloc manages
-  memory from the system in page-size units.  This may be (and
-  usually is) a function rather than a constant. This is ignored
-  if WIN32, where page size is determined using getSystemInfo during
-  initialization.
-
-USE_DEV_RANDOM             default: 0 (i.e., not used)
-  Causes malloc to use /dev/random to initialize secure magic seed for
-  stamping footers. Otherwise, the current time is used.
-
-NO_MALLINFO                default: 0
-  If defined, don't compile "mallinfo". This can be a simple way
-  of dealing with mismatches between system declarations and
-  those in this file.
-
-MALLINFO_FIELD_TYPE        default: size_t
-  The type of the fields in the mallinfo struct. This was originally
-  defined as "int" in SVID etc, but is more usefully defined as
-  size_t. The value is used only if  HAVE_USR_INCLUDE_MALLOC_H is not set
-
-NO_MALLOC_STATS            default: 0
-  If defined, don't compile "malloc_stats". This avoids calls to
-  fprintf and bringing in stdio dependencies you might not want.
-
-REALLOC_ZERO_BYTES_FREES    default: not defined
-  This should be set if a call to realloc with zero bytes should
-  be the same as a call to free. Some people think it should. Otherwise,
-  since this malloc returns a unique pointer for malloc(0), so does
-  realloc(p, 0).
-
-LACKS_UNISTD_H, LACKS_FCNTL_H, LACKS_SYS_PARAM_H, LACKS_SYS_MMAN_H
-LACKS_STRINGS_H, LACKS_STRING_H, LACKS_SYS_TYPES_H,  LACKS_ERRNO_H
-LACKS_STDLIB_H LACKS_SCHED_H LACKS_TIME_H  default: NOT defined unless on WIN32
-  Define these if your system does not have these header files.
-  You might need to manually insert some of the declarations they provide.
-
-DEFAULT_GRANULARITY        default: page size if MORECORE_CONTIGUOUS,
-                                system_info.dwAllocationGranularity in WIN32,
-                                otherwise 64K.
-      Also settable using mallopt(M_GRANULARITY, x)
-  The unit for allocating and deallocating memory from the system.  On
-  most systems with contiguous MORECORE, there is no reason to
-  make this more than a page. However, systems with MMAP tend to
-  either require or encourage larger granularities.  You can increase
-  this value to prevent system allocation functions to be called so
-  often, especially if they are slow.  The value must be at least one
-  page and must be a power of two.  Setting to 0 causes initialization
-  to either page size or win32 region size.  (Note: In previous
-  versions of malloc, the equivalent of this option was called
-  "TOP_PAD")
-
-DEFAULT_TRIM_THRESHOLD    default: 2MB
-      Also settable using mallopt(M_TRIM_THRESHOLD, x)
-  The maximum amount of unused top-most memory to keep before
-  releasing via malloc_trim in free().  Automatic trimming is mainly
-  useful in long-lived programs using contiguous MORECORE.  Because
-  trimming via sbrk can be slow on some systems, and can sometimes be
-  wasteful (in cases where programs immediately afterward allocate
-  more large chunks) the value should be high enough so that your
-  overall system performance would improve by releasing this much
-  memory.  As a rough guide, you might set to a value close to the
-  average size of a process (program) running on your system.
-  Releasing this much memory would allow such a process to run in
-  memory.  Generally, it is worth tuning trim thresholds when a
-  program undergoes phases where several large chunks are allocated
-  and released in ways that can reuse each other's storage, perhaps
-  mixed with phases where there are no such chunks at all. The trim
-  value must be greater than page size to have any useful effect.  To
-  disable trimming completely, you can set to MAX_SIZE_T. Note that the trick
-  some people use of mallocing a huge space and then freeing it at
-  program startup, in an attempt to reserve system memory, doesn't
-  have the intended effect under automatic trimming, since that memory
-  will immediately be returned to the system.
-
-DEFAULT_MMAP_THRESHOLD       default: 256K
-      Also settable using mallopt(M_MMAP_THRESHOLD, x)
-  The request size threshold for using MMAP to directly service a
-  request. Requests of at least this size that cannot be allocated
-  using already-existing space will be serviced via mmap.  (If enough
-  normal freed space already exists it is used instead.)  Using mmap
-  segregates relatively large chunks of memory so that they can be
-  individually obtained and released from the host system. A request
-  serviced through mmap is never reused by any other request (at least
-  not directly; the system may just so happen to remap successive
-  requests to the same locations).  Segregating space in this way has
-  the benefits that: Mmapped space can always be individually released
-  back to the system, which helps keep the system level memory demands
-  of a long-lived program low.  Also, mapped memory doesn't become
-  `locked' between other chunks, as can happen with normally allocated
-  chunks, which means that even trimming via malloc_trim would not
-  release them.  However, it has the disadvantage that the space
-  cannot be reclaimed, consolidated, and then used to service later
-  requests, as happens with normal chunks.  The advantages of mmap
-  nearly always outweigh disadvantages for "large" chunks, but the
-  value of "large" may vary across systems.  The default is an
-  empirically derived value that works well in most systems. You can
-  disable mmap by setting to MAX_SIZE_T.
-
-MAX_RELEASE_CHECK_RATE   default: 4095 unless not HAVE_MMAP
-  The number of consolidated frees between checks to release
-  unused segments when freeing. When using non-contiguous segments,
-  especially with multiple mspaces, checking only for topmost space
-  doesn't always suffice to trigger trimming. To compensate for this,
-  free() will, with a period of MAX_RELEASE_CHECK_RATE (or the
-  current number of segments, if greater) try to release unused
-  segments to the OS when freeing chunks that result in
-  consolidation. The best value for this parameter is a compromise
-  between slowing down frees with relatively costly checks that
-  rarely trigger versus holding on to unused memory. To effectively
-  disable, set to MAX_SIZE_T. This may lead to a very slight speed
-  improvement at the expense of carrying around more memory.
-*/
-
-/* Version identifier to allow people to support multiple versions */
-#ifndef DLMALLOC_VERSION
-#define DLMALLOC_VERSION 20806
-#endif /* DLMALLOC_VERSION */
-
-#ifndef DLMALLOC_EXPORT
-#define DLMALLOC_EXPORT extern
-#endif
-
-#ifndef WIN32
-#ifdef _WIN32
-#define WIN32 1
-#endif  /* _WIN32 */
-#ifdef _WIN32_WCE
-#define LACKS_FCNTL_H
-#define WIN32 1
-#endif /* _WIN32_WCE */
-#endif  /* WIN32 */
-#ifdef WIN32
-#define WIN32_LEAN_AND_MEAN
-#include <windows.h>
-#include <tchar.h>
-#define HAVE_MMAP 1
-#define HAVE_MORECORE 0
-#define LACKS_UNISTD_H
-#define LACKS_SYS_PARAM_H
-#define LACKS_SYS_MMAN_H
-#define LACKS_STRING_H
-#define LACKS_STRINGS_H
-#define LACKS_SYS_TYPES_H
-#define LACKS_ERRNO_H
-#define LACKS_SCHED_H
-#ifndef MALLOC_FAILURE_ACTION
-#define MALLOC_FAILURE_ACTION
-#endif /* MALLOC_FAILURE_ACTION */
-#ifndef MMAP_CLEARS
-#ifdef _WIN32_WCE /* WINCE reportedly does not clear */
-#define MMAP_CLEARS 0
-#else
-#define MMAP_CLEARS 1
-#endif /* _WIN32_WCE */
-#endif /*MMAP_CLEARS */
-#endif  /* WIN32 */
-
-#if defined(DARWIN) || defined(_DARWIN)
-/* Mac OSX docs advise not to use sbrk; it seems better to use mmap */
-#ifndef HAVE_MORECORE
-#define HAVE_MORECORE 0
-#define HAVE_MMAP 1
-/* OSX allocators provide 16 byte alignment */
-#ifndef MALLOC_ALIGNMENT
-#define MALLOC_ALIGNMENT ((size_t)16U)
-#endif
-#endif  /* HAVE_MORECORE */
-#endif  /* DARWIN */
-
-#ifndef LACKS_SYS_TYPES_H
-#include <sys/types.h>  /* For size_t */
-#endif  /* LACKS_SYS_TYPES_H */
-
-/* The maximum possible size_t value has all bits set */
-#define MAX_SIZE_T           (~(size_t)0)
-
-#ifndef USE_LOCKS /* ensure true if spin or recursive locks set */
-#define USE_LOCKS  ((defined(USE_SPIN_LOCKS) && USE_SPIN_LOCKS != 0) || \
-                    (defined(USE_RECURSIVE_LOCKS) && USE_RECURSIVE_LOCKS != 0))
-#endif /* USE_LOCKS */
-
-#if USE_LOCKS /* Spin locks for gcc >= 4.1, older gcc on x86, MSC >= 1310 */
-#if ((defined(__GNUC__) &&                                              \
-      ((__GNUC__ > 4 || (__GNUC__ == 4 && __GNUC_MINOR__ >= 1)) ||      \
-       defined(__i386__) || defined(__x86_64__))) ||                    \
-     (defined(_MSC_VER) && _MSC_VER>=1310))
-#ifndef USE_SPIN_LOCKS
-#define USE_SPIN_LOCKS 1
-#endif /* USE_SPIN_LOCKS */
-#elif USE_SPIN_LOCKS
-#error "USE_SPIN_LOCKS defined without implementation"
-#endif /* ... locks available... */
-#elif !defined(USE_SPIN_LOCKS)
-#define USE_SPIN_LOCKS 0
-#endif /* USE_LOCKS */
-
-#ifndef ONLY_MSPACES
-#define ONLY_MSPACES 0
-#endif  /* ONLY_MSPACES */
-#ifndef MSPACES
-#if ONLY_MSPACES
-#define MSPACES 1
-#else   /* ONLY_MSPACES */
-#define MSPACES 0
-#endif  /* ONLY_MSPACES */
-#endif  /* MSPACES */
-#ifndef MALLOC_ALIGNMENT
-#define MALLOC_ALIGNMENT ((size_t)(2 * sizeof(void *)))
-#endif  /* MALLOC_ALIGNMENT */
-#ifndef FOOTERS
-#define FOOTERS 0
-#endif  /* FOOTERS */
-#ifndef ABORT
-#define ABORT  abort()
-#endif  /* ABORT */
-#ifndef ABORT_ON_ASSERT_FAILURE
-#define ABORT_ON_ASSERT_FAILURE 1
-#endif  /* ABORT_ON_ASSERT_FAILURE */
-#ifndef PROCEED_ON_ERROR
-#define PROCEED_ON_ERROR 0
-#endif  /* PROCEED_ON_ERROR */
-
-#ifndef INSECURE
-#define INSECURE 0
-#endif  /* INSECURE */
-#ifndef MALLOC_INSPECT_ALL
-#define MALLOC_INSPECT_ALL 0
-#endif  /* MALLOC_INSPECT_ALL */
-#ifndef HAVE_MMAP
-#define HAVE_MMAP 1
-#endif  /* HAVE_MMAP */
-#ifndef MMAP_CLEARS
-#define MMAP_CLEARS 1
-#endif  /* MMAP_CLEARS */
-#ifndef HAVE_MREMAP
-#ifdef linux
-#define HAVE_MREMAP 1
-#define _GNU_SOURCE /* Turns on mremap() definition */
-#else   /* linux */
-#define HAVE_MREMAP 0
-#endif  /* linux */
-#endif  /* HAVE_MREMAP */
-#ifndef MALLOC_FAILURE_ACTION
-#define MALLOC_FAILURE_ACTION  errno = ENOMEM;
-#endif  /* MALLOC_FAILURE_ACTION */
-#ifndef HAVE_MORECORE
-#if ONLY_MSPACES
-#define HAVE_MORECORE 0
-#else   /* ONLY_MSPACES */
-#define HAVE_MORECORE 1
-#endif  /* ONLY_MSPACES */
-#endif  /* HAVE_MORECORE */
-#if !HAVE_MORECORE
-#define MORECORE_CONTIGUOUS 0
-#else   /* !HAVE_MORECORE */
-#define MORECORE_DEFAULT sbrk
-#ifndef MORECORE_CONTIGUOUS
-#define MORECORE_CONTIGUOUS 1
-#endif  /* MORECORE_CONTIGUOUS */
-#endif  /* HAVE_MORECORE */
-#ifndef DEFAULT_GRANULARITY
-#if (MORECORE_CONTIGUOUS || defined(WIN32))
-#define DEFAULT_GRANULARITY (0)  /* 0 means to compute in init_mparams */
-#else   /* MORECORE_CONTIGUOUS */
-#define DEFAULT_GRANULARITY ((size_t)64U * (size_t)1024U)
-#endif  /* MORECORE_CONTIGUOUS */
-#endif  /* DEFAULT_GRANULARITY */
-#ifndef DEFAULT_TRIM_THRESHOLD
-#ifndef MORECORE_CANNOT_TRIM
-#define DEFAULT_TRIM_THRESHOLD ((size_t)2U * (size_t)1024U * (size_t)1024U)
-#else   /* MORECORE_CANNOT_TRIM */
-#define DEFAULT_TRIM_THRESHOLD MAX_SIZE_T
-#endif  /* MORECORE_CANNOT_TRIM */
-#endif  /* DEFAULT_TRIM_THRESHOLD */
-#ifndef DEFAULT_MMAP_THRESHOLD
-#if HAVE_MMAP
-#define DEFAULT_MMAP_THRESHOLD ((size_t)256U * (size_t)1024U)
-#else   /* HAVE_MMAP */
-#define DEFAULT_MMAP_THRESHOLD MAX_SIZE_T
-#endif  /* HAVE_MMAP */
-#endif  /* DEFAULT_MMAP_THRESHOLD */
-#ifndef MAX_RELEASE_CHECK_RATE
-#if HAVE_MMAP
-#define MAX_RELEASE_CHECK_RATE 4095
-#else
-#define MAX_RELEASE_CHECK_RATE MAX_SIZE_T
-#endif /* HAVE_MMAP */
-#endif /* MAX_RELEASE_CHECK_RATE */
-#ifndef USE_BUILTIN_FFS
-#define USE_BUILTIN_FFS 0
-#endif  /* USE_BUILTIN_FFS */
-#ifndef USE_DEV_RANDOM
-#define USE_DEV_RANDOM 0
-#endif  /* USE_DEV_RANDOM */
-#ifndef NO_MALLINFO
-#define NO_MALLINFO 0
-#endif  /* NO_MALLINFO */
-#ifndef MALLINFO_FIELD_TYPE
-#define MALLINFO_FIELD_TYPE size_t
-#endif  /* MALLINFO_FIELD_TYPE */
-#ifndef NO_MALLOC_STATS
-#define NO_MALLOC_STATS 0
-#endif  /* NO_MALLOC_STATS */
-#ifndef NO_SEGMENT_TRAVERSAL
-#define NO_SEGMENT_TRAVERSAL 0
-#endif /* NO_SEGMENT_TRAVERSAL */
-
-/*
-  mallopt tuning options.  SVID/XPG defines four standard parameter
-  numbers for mallopt, normally defined in malloc.h.  None of these
-  are used in this malloc, so setting them has no effect. But this
-  malloc does support the following options.
-*/
-
-#define M_TRIM_THRESHOLD     (-1)
-#define M_GRANULARITY        (-2)
-#define M_MMAP_THRESHOLD     (-3)
-
-/* ------------------------ Mallinfo declarations ------------------------ */
-
-#if !NO_MALLINFO
-/*
-  This version of malloc supports the standard SVID/XPG mallinfo
-  routine that returns a struct containing usage properties and
-  statistics. It should work on any system that has a
-  /usr/include/malloc.h defining struct mallinfo.  The main
-  declaration needed is the mallinfo struct that is returned (by-copy)
-  by mallinfo().  The malloinfo struct contains a bunch of fields that
-  are not even meaningful in this version of malloc.  These fields are
-  are instead filled by mallinfo() with other numbers that might be of
-  interest.
-
-  HAVE_USR_INCLUDE_MALLOC_H should be set if you have a
-  /usr/include/malloc.h file that includes a declaration of struct
-  mallinfo.  If so, it is included; else a compliant version is
-  declared below.  These must be precisely the same for mallinfo() to
-  work.  The original SVID version of this struct, defined on most
-  systems with mallinfo, declares all fields as ints. But some others
-  define as unsigned long. If your system defines the fields using a
-  type of different width than listed here, you MUST #include your
-  system version and #define HAVE_USR_INCLUDE_MALLOC_H.
-*/
-
-/* #define HAVE_USR_INCLUDE_MALLOC_H */
-
-#ifdef HAVE_USR_INCLUDE_MALLOC_H
-#include "/usr/include/malloc.h"
-#else /* HAVE_USR_INCLUDE_MALLOC_H */
-#ifndef STRUCT_MALLINFO_DECLARED
-/* HP-UX (and others?) redefines mallinfo unless _STRUCT_MALLINFO is defined */
-#define _STRUCT_MALLINFO
-#define STRUCT_MALLINFO_DECLARED 1
-struct mallinfo {
-  MALLINFO_FIELD_TYPE arena;    /* non-mmapped space allocated from system */
-  MALLINFO_FIELD_TYPE ordblks;  /* number of free chunks */
-  MALLINFO_FIELD_TYPE smblks;   /* always 0 */
-  MALLINFO_FIELD_TYPE hblks;    /* always 0 */
-  MALLINFO_FIELD_TYPE hblkhd;   /* space in mmapped regions */
-  MALLINFO_FIELD_TYPE usmblks;  /* maximum total allocated space */
-  MALLINFO_FIELD_TYPE fsmblks;  /* always 0 */
-  MALLINFO_FIELD_TYPE uordblks; /* total allocated space */
-  MALLINFO_FIELD_TYPE fordblks; /* total free space */
-  MALLINFO_FIELD_TYPE keepcost; /* releasable (via malloc_trim) space */
-};
-#endif /* STRUCT_MALLINFO_DECLARED */
-#endif /* HAVE_USR_INCLUDE_MALLOC_H */
-#endif /* NO_MALLINFO */
-
-/*
-  Try to persuade compilers to inline. The most critical functions for
-  inlining are defined as macros, so these aren't used for them.
-*/
-
-#ifndef FORCEINLINE
-  #if defined(__GNUC__)
-#define FORCEINLINE __inline __attribute__ ((always_inline))
-  #elif defined(_MSC_VER)
-    #define FORCEINLINE __forceinline
-  #endif
-#endif
-#ifndef NOINLINE
-  #if defined(__GNUC__)
-    #define NOINLINE __attribute__ ((noinline))
-  #elif defined(_MSC_VER)
-    #define NOINLINE __declspec(noinline)
-  #else
-    #define NOINLINE
-  #endif
-#endif
-
-#ifdef __cplusplus
-extern "C" {
-#ifndef FORCEINLINE
- #define FORCEINLINE inline
-#endif
-#endif /* __cplusplus */
-#ifndef FORCEINLINE
- #define FORCEINLINE
-#endif
-
-#if !ONLY_MSPACES
-
-/* ------------------- Declarations of public routines ------------------- */
-
-#ifndef USE_DL_PREFIX
-#define dlcalloc               calloc
-#define dlfree                 free
-#define dlmalloc               malloc
-#define dlmemalign             memalign
-#define dlposix_memalign       posix_memalign
-#define dlrealloc              realloc
-#define dlrealloc_in_place     realloc_in_place
-#define dlvalloc               valloc
-#define dlpvalloc              pvalloc
-#define dlmallinfo             mallinfo
-#define dlmallopt              mallopt
-#define dlmalloc_trim          malloc_trim
-#define dlmalloc_stats         malloc_stats
-#define dlmalloc_usable_size   malloc_usable_size
-#define dlmalloc_footprint     malloc_footprint
-#define dlmalloc_max_footprint malloc_max_footprint
-#define dlmalloc_footprint_limit malloc_footprint_limit
-#define dlmalloc_set_footprint_limit malloc_set_footprint_limit
-#define dlmalloc_inspect_all   malloc_inspect_all
-#define dlindependent_calloc   independent_calloc
-#define dlindependent_comalloc independent_comalloc
-#define dlbulk_free            bulk_free
-#endif /* USE_DL_PREFIX */
-
-/*
-  malloc(size_t n)
-  Returns a pointer to a newly allocated chunk of at least n bytes, or
-  null if no space is available, in which case errno is set to ENOMEM
-  on ANSI C systems.
-
-  If n is zero, malloc returns a minimum-sized chunk. (The minimum
-  size is 16 bytes on most 32bit systems, and 32 bytes on 64bit
-  systems.)  Note that size_t is an unsigned type, so calls with
-  arguments that would be negative if signed are interpreted as
-  requests for huge amounts of space, which will often fail. The
-  maximum supported value of n differs across systems, but is in all
-  cases less than the maximum representable value of a size_t.
-*/
-DLMALLOC_EXPORT void* dlmalloc(size_t);
-
-/*
-  free(void* p)
-  Releases the chunk of memory pointed to by p, that had been previously
-  allocated using malloc or a related routine such as realloc.
-  It has no effect if p is null. If p was not malloced or already
-  freed, free(p) will by default cause the current program to abort.
-*/
-DLMALLOC_EXPORT void  dlfree(void*);
-
-/*
-  calloc(size_t n_elements, size_t element_size);
-  Returns a pointer to n_elements * element_size bytes, with all locations
-  set to zero.
-*/
-DLMALLOC_EXPORT void* dlcalloc(size_t, size_t);
-
-/*
-  realloc(void* p, size_t n)
-  Returns a pointer to a chunk of size n that contains the same data
-  as does chunk p up to the minimum of (n, p's size) bytes, or null
-  if no space is available.
-
-  The returned pointer may or may not be the same as p. The algorithm
-  prefers extending p in most cases when possible, otherwise it
-  employs the equivalent of a malloc-copy-free sequence.
-
-  If p is null, realloc is equivalent to malloc.
-
-  If space is not available, realloc returns null, errno is set (if on
-  ANSI) and p is NOT freed.
-
-  if n is for fewer bytes than already held by p, the newly unused
-  space is lopped off and freed if possible.  realloc with a size
-  argument of zero (re)allocates a minimum-sized chunk.
-
-  The old unix realloc convention of allowing the last-free'd chunk
-  to be used as an argument to realloc is not supported.
-*/
-DLMALLOC_EXPORT void* dlrealloc(void*, size_t);
-
-/*
-  realloc_in_place(void* p, size_t n)
-  Resizes the space allocated for p to size n, only if this can be
-  done without moving p (i.e., only if there is adjacent space
-  available if n is greater than p's current allocated size, or n is
-  less than or equal to p's size). This may be used instead of plain
-  realloc if an alternative allocation strategy is needed upon failure
-  to expand space; for example, reallocation of a buffer that must be
-  memory-aligned or cleared. You can use realloc_in_place to trigger
-  these alternatives only when needed.
-
-  Returns p if successful; otherwise null.
-*/
-DLMALLOC_EXPORT void* dlrealloc_in_place(void*, size_t);
-
-/*
-  memalign(size_t alignment, size_t n);
-  Returns a pointer to a newly allocated chunk of n bytes, aligned
-  in accord with the alignment argument.
-
-  The alignment argument should be a power of two. If the argument is
-  not a power of two, the nearest greater power is used.
-  8-byte alignment is guaranteed by normal malloc calls, so don't
-  bother calling memalign with an argument of 8 or less.
-
-  Overreliance on memalign is a sure way to fragment space.
-*/
-DLMALLOC_EXPORT void* dlmemalign(size_t, size_t);
-
-/*
-  int posix_memalign(void** pp, size_t alignment, size_t n);
-  Allocates a chunk of n bytes, aligned in accord with the alignment
-  argument. Differs from memalign only in that it (1) assigns the
-  allocated memory to *pp rather than returning it, (2) fails and
-  returns EINVAL if the alignment is not a power of two (3) fails and
-  returns ENOMEM if memory cannot be allocated.
-*/
-DLMALLOC_EXPORT int dlposix_memalign(void**, size_t, size_t);
-
-/*
-  valloc(size_t n);
-  Equivalent to memalign(pagesize, n), where pagesize is the page
-  size of the system. If the pagesize is unknown, 4096 is used.
-*/
-DLMALLOC_EXPORT void* dlvalloc(size_t);
-
-/*
-  mallopt(int parameter_number, int parameter_value)
-  Sets tunable parameters The format is to provide a
-  (parameter-number, parameter-value) pair.  mallopt then sets the
-  corresponding parameter to the argument value if it can (i.e., so
-  long as the value is meaningful), and returns 1 if successful else
-  0.  To workaround the fact that mallopt is specified to use int,
-  not size_t parameters, the value -1 is specially treated as the
-  maximum unsigned size_t value.
-
-  SVID/XPG/ANSI defines four standard param numbers for mallopt,
-  normally defined in malloc.h.  None of these are use in this malloc,
-  so setting them has no effect. But this malloc also supports other
-  options in mallopt. See below for details.  Briefly, supported
-  parameters are as follows (listed defaults are for "typical"
-  configurations).
-
-  Symbol            param #  default    allowed param values
-  M_TRIM_THRESHOLD     -1   2*1024*1024   any   (-1 disables)
-  M_GRANULARITY        -2     page size   any power of 2 >= page size
-  M_MMAP_THRESHOLD     -3      256*1024   any   (or 0 if no MMAP support)
-*/
-DLMALLOC_EXPORT int dlmallopt(int, int);
-
-/*
-  malloc_footprint();
-  Returns the number of bytes obtained from the system.  The total
-  number of bytes allocated by malloc, realloc etc., is less than this
-  value. Unlike mallinfo, this function returns only a precomputed
-  result, so can be called frequently to monitor memory consumption.
-  Even if locks are otherwise defined, this function does not use them,
-  so results might not be up to date.
-*/
-DLMALLOC_EXPORT size_t dlmalloc_footprint(void);
-
-/*
-  malloc_max_footprint();
-  Returns the maximum number of bytes obtained from the system. This
-  value will be greater than current footprint if deallocated space
-  has been reclaimed by the system. The peak number of bytes allocated
-  by malloc, realloc etc., is less than this value. Unlike mallinfo,
-  this function returns only a precomputed result, so can be called
-  frequently to monitor memory consumption.  Even if locks are
-  otherwise defined, this function does not use them, so results might
-  not be up to date.
-*/
-DLMALLOC_EXPORT size_t dlmalloc_max_footprint(void);
-
-/*
-  malloc_footprint_limit();
-  Returns the number of bytes that the heap is allowed to obtain from
-  the system, returning the last value returned by
-  malloc_set_footprint_limit, or the maximum size_t value if
-  never set. The returned value reflects a permission. There is no
-  guarantee that this number of bytes can actually be obtained from
-  the system.
-*/
-DLMALLOC_EXPORT size_t dlmalloc_footprint_limit();
-
-/*
-  malloc_set_footprint_limit();
-  Sets the maximum number of bytes to obtain from the system, causing
-  failure returns from malloc and related functions upon attempts to
-  exceed this value. The argument value may be subject to page
-  rounding to an enforceable limit; this actual value is returned.
-  Using an argument of the maximum possible size_t effectively
-  disables checks. If the argument is less than or equal to the
-  current malloc_footprint, then all future allocations that require
-  additional system memory will fail. However, invocation cannot
-  retroactively deallocate existing used memory.
-*/
-DLMALLOC_EXPORT size_t dlmalloc_set_footprint_limit(size_t bytes);
-
-#if MALLOC_INSPECT_ALL
-/*
-  malloc_inspect_all(void(*handler)(void *start,
-                                    void *end,
-                                    size_t used_bytes,
-                                    void* callback_arg),
-                      void* arg);
-  Traverses the heap and calls the given handler for each managed
-  region, skipping all bytes that are (or may be) used for bookkeeping
-  purposes.  Traversal does not include include chunks that have been
-  directly memory mapped. Each reported region begins at the start
-  address, and continues up to but not including the end address.  The
-  first used_bytes of the region contain allocated data. If
-  used_bytes is zero, the region is unallocated. The handler is
-  invoked with the given callback argument. If locks are defined, they
-  are held during the entire traversal. It is a bad idea to invoke
-  other malloc functions from within the handler.
-
-  For example, to count the number of in-use chunks with size greater
-  than 1000, you could write:
-  static int count = 0;
-  void count_chunks(void* start, void* end, size_t used, void* arg) {
-    if (used >= 1000) ++count;
-  }
-  then:
-    malloc_inspect_all(count_chunks, NULL);
-
-  malloc_inspect_all is compiled only if MALLOC_INSPECT_ALL is defined.
-*/
-DLMALLOC_EXPORT void dlmalloc_inspect_all(void(*handler)(void*, void *, size_t, void*),
-                           void* arg);
-
-#endif /* MALLOC_INSPECT_ALL */
-
-#if !NO_MALLINFO
-/*
-  mallinfo()
-  Returns (by copy) a struct containing various summary statistics:
-
-  arena:     current total non-mmapped bytes allocated from system
-  ordblks:   the number of free chunks
-  smblks:    always zero.
-  hblks:     current number of mmapped regions
-  hblkhd:    total bytes held in mmapped regions
-  usmblks:   the maximum total allocated space. This will be greater
-                than current total if trimming has occurred.
-  fsmblks:   always zero
-  uordblks:  current total allocated space (normal or mmapped)
-  fordblks:  total free space
-  keepcost:  the maximum number of bytes that could ideally be released
-               back to system via malloc_trim. ("ideally" means that
-               it ignores page restrictions etc.)
-
-  Because these fields are ints, but internal bookkeeping may
-  be kept as longs, the reported values may wrap around zero and
-  thus be inaccurate.
-*/
-DLMALLOC_EXPORT struct mallinfo dlmallinfo(void);
-#endif /* NO_MALLINFO */
-
-/*
-  independent_calloc(size_t n_elements, size_t element_size, void* chunks[]);
-
-  independent_calloc is similar to calloc, but instead of returning a
-  single cleared space, it returns an array of pointers to n_elements
-  independent elements that can hold contents of size elem_size, each
-  of which starts out cleared, and can be independently freed,
-  realloc'ed etc. The elements are guaranteed to be adjacently
-  allocated (this is not guaranteed to occur with multiple callocs or
-  mallocs), which may also improve cache locality in some
-  applications.
-
-  The "chunks" argument is optional (i.e., may be null, which is
-  probably the most typical usage). If it is null, the returned array
-  is itself dynamically allocated and should also be freed when it is
-  no longer needed. Otherwise, the chunks array must be of at least
-  n_elements in length. It is filled in with the pointers to the
-  chunks.
-
-  In either case, independent_calloc returns this pointer array, or
-  null if the allocation failed.  If n_elements is zero and "chunks"
-  is null, it returns a chunk representing an array with zero elements
-  (which should be freed if not wanted).
-
-  Each element must be freed when it is no longer needed. This can be
-  done all at once using bulk_free.
-
-  independent_calloc simplifies and speeds up implementations of many
-  kinds of pools.  It may also be useful when constructing large data
-  structures that initially have a fixed number of fixed-sized nodes,
-  but the number is not known at compile time, and some of the nodes
-  may later need to be freed. For example:
-
-  struct Node { int item; struct Node* next; };
-
-  struct Node* build_list() {
-    struct Node** pool;
-    int n = read_number_of_nodes_needed();
-    if (n <= 0) return 0;
-    pool = (struct Node**)(independent_calloc(n, sizeof(struct Node), 0);
-    if (pool == 0) die();
-    // organize into a linked list...
-    struct Node* first = pool[0];
-    for (i = 0; i < n-1; ++i)
-      pool[i]->next = pool[i+1];
-    free(pool);     // Can now free the array (or not, if it is needed later)
-    return first;
-  }
-*/
-DLMALLOC_EXPORT void** dlindependent_calloc(size_t, size_t, void**);
-
-/*
-  independent_comalloc(size_t n_elements, size_t sizes[], void* chunks[]);
-
-  independent_comalloc allocates, all at once, a set of n_elements
-  chunks with sizes indicated in the "sizes" array.    It returns
-  an array of pointers to these elements, each of which can be
-  independently freed, realloc'ed etc. The elements are guaranteed to
-  be adjacently allocated (this is not guaranteed to occur with
-  multiple callocs or mallocs), which may also improve cache locality
-  in some applications.
-
-  The "chunks" argument is optional (i.e., may be null). If it is null
-  the returned array is itself dynamically allocated and should also
-  be freed when it is no longer needed. Otherwise, the chunks array
-  must be of at least n_elements in length. It is filled in with the
-  pointers to the chunks.
-
-  In either case, independent_comalloc returns this pointer array, or
-  null if the allocation failed.  If n_elements is zero and chunks is
-  null, it returns a chunk representing an array with zero elements
-  (which should be freed if not wanted).
-
-  Each element must be freed when it is no longer needed. This can be
-  done all at once using bulk_free.
-
-  independent_comallac differs from independent_calloc in that each
-  element may have a different size, and also that it does not
-  automatically clear elements.
-
-  independent_comalloc can be used to speed up allocation in cases
-  where several structs or objects must always be allocated at the
-  same time.  For example:
-
-  struct Head { ... }
-  struct Foot { ... }
-
-  void send_message(char* msg) {
-    int msglen = strlen(msg);
-    size_t sizes[3] = { sizeof(struct Head), msglen, sizeof(struct Foot) };
-    void* chunks[3];
-    if (independent_comalloc(3, sizes, chunks) == 0)
-      die();
-    struct Head* head = (struct Head*)(chunks[0]);
-    char*        body = (char*)(chunks[1]);
-    struct Foot* foot = (struct Foot*)(chunks[2]);
-    // ...
-  }
-
-  In general though, independent_comalloc is worth using only for
-  larger values of n_elements. For small values, you probably won't
-  detect enough difference from series of malloc calls to bother.
-
-  Overuse of independent_comalloc can increase overall memory usage,
-  since it cannot reuse existing noncontiguous small chunks that
-  might be available for some of the elements.
-*/
-DLMALLOC_EXPORT void** dlindependent_comalloc(size_t, size_t*, void**);
-
-/*
-  bulk_free(void* array[], size_t n_elements)
-  Frees and clears (sets to null) each non-null pointer in the given
-  array.  This is likely to be faster than freeing them one-by-one.
-  If footers are used, pointers that have been allocated in different
-  mspaces are not freed or cleared, and the count of all such pointers
-  is returned.  For large arrays of pointers with poor locality, it
-  may be worthwhile to sort this array before calling bulk_free.
-*/
-DLMALLOC_EXPORT size_t  dlbulk_free(void**, size_t n_elements);
-
-/*
-  pvalloc(size_t n);
-  Equivalent to valloc(minimum-page-that-holds(n)), that is,
-  round up n to nearest pagesize.
- */
-DLMALLOC_EXPORT void*  dlpvalloc(size_t);
-
-/*
-  malloc_trim(size_t pad);
-
-  If possible, gives memory back to the system (via negative arguments
-  to sbrk) if there is unused memory at the `high' end of the malloc
-  pool or in unused MMAP segments. You can call this after freeing
-  large blocks of memory to potentially reduce the system-level memory
-  requirements of a program. However, it cannot guarantee to reduce
-  memory. Under some allocation patterns, some large free blocks of
-  memory will be locked between two used chunks, so they cannot be
-  given back to the system.
-
-  The `pad' argument to malloc_trim represents the amount of free
-  trailing space to leave untrimmed. If this argument is zero, only
-  the minimum amount of memory to maintain internal data structures
-  will be left. Non-zero arguments can be supplied to maintain enough
-  trailing space to service future expected allocations without having
-  to re-obtain memory from the system.
-
-  Malloc_trim returns 1 if it actually released any memory, else 0.
-*/
-DLMALLOC_EXPORT int  dlmalloc_trim(size_t);
-
-/*
-  malloc_stats();
-  Prints on stderr the amount of space obtained from the system (both
-  via sbrk and mmap), the maximum amount (which may be more than
-  current if malloc_trim and/or munmap got called), and the current
-  number of bytes allocated via malloc (or realloc, etc) but not yet
-  freed. Note that this is the number of bytes allocated, not the
-  number requested. It will be larger than the number requested
-  because of alignment and bookkeeping overhead. Because it includes
-  alignment wastage as being in use, this figure may be greater than
-  zero even when no user-level chunks are allocated.
-
-  The reported current and maximum system memory can be inaccurate if
-  a program makes other calls to system memory allocation functions
-  (normally sbrk) outside of malloc.
-
-  malloc_stats prints only the most commonly interesting statistics.
-  More information can be obtained by calling mallinfo.
-*/
-DLMALLOC_EXPORT void  dlmalloc_stats(void);
-
-/*
-  malloc_usable_size(void* p);
-
-  Returns the number of bytes you can actually use in
-  an allocated chunk, which may be more than you requested (although
-  often not) due to alignment and minimum size constraints.
-  You can use this many bytes without worrying about
-  overwriting other allocated objects. This is not a particularly great
-  programming practice. malloc_usable_size can be more useful in
-  debugging and assertions, for example:
-
-  p = malloc(n);
-  assert(malloc_usable_size(p) >= 256);
-*/
-/* BEGIN android-changed: added const */
-size_t dlmalloc_usable_size(const void*);
-/* END android-change */
-
-#endif /* ONLY_MSPACES */
-
-#if MSPACES
-
-/*
-  mspace is an opaque type representing an independent
-  region of space that supports mspace_malloc, etc.
-*/
-typedef void* mspace;
-
-/*
-  create_mspace creates and returns a new independent space with the
-  given initial capacity, or, if 0, the default granularity size.  It
-  returns null if there is no system memory available to create the
-  space.  If argument locked is non-zero, the space uses a separate
-  lock to control access. The capacity of the space will grow
-  dynamically as needed to service mspace_malloc requests.  You can
-  control the sizes of incremental increases of this space by
-  compiling with a different DEFAULT_GRANULARITY or dynamically
-  setting with mallopt(M_GRANULARITY, value).
-*/
-DLMALLOC_EXPORT mspace create_mspace(size_t capacity, int locked);
-
-/*
-  destroy_mspace destroys the given space, and attempts to return all
-  of its memory back to the system, returning the total number of
-  bytes freed. After destruction, the results of access to all memory
-  used by the space become undefined.
-*/
-DLMALLOC_EXPORT size_t destroy_mspace(mspace msp);
-
-/*
-  create_mspace_with_base uses the memory supplied as the initial base
-  of a new mspace. Part (less than 128*sizeof(size_t) bytes) of this
-  space is used for bookkeeping, so the capacity must be at least this
-  large. (Otherwise 0 is returned.) When this initial space is
-  exhausted, additional memory will be obtained from the system.
-  Destroying this space will deallocate all additionally allocated
-  space (if possible) but not the initial base.
-*/
-DLMALLOC_EXPORT mspace create_mspace_with_base(void* base, size_t capacity, int locked);
-
-/*
-  mspace_track_large_chunks controls whether requests for large chunks
-  are allocated in their own untracked mmapped regions, separate from
-  others in this mspace. By default large chunks are not tracked,
-  which reduces fragmentation. However, such chunks are not
-  necessarily released to the system upon destroy_mspace.  Enabling
-  tracking by setting to true may increase fragmentation, but avoids
-  leakage when relying on destroy_mspace to release all memory
-  allocated using this space.  The function returns the previous
-  setting.
-*/
-DLMALLOC_EXPORT int mspace_track_large_chunks(mspace msp, int enable);
-
-
-/*
-  mspace_malloc behaves as malloc, but operates within
-  the given space.
-*/
-DLMALLOC_EXPORT void* mspace_malloc(mspace msp, size_t bytes);
-
-/*
-  mspace_free behaves as free, but operates within
-  the given space.
-
-  If compiled with FOOTERS==1, mspace_free is not actually needed.
-  free may be called instead of mspace_free because freed chunks from
-  any space are handled by their originating spaces.
-*/
-DLMALLOC_EXPORT void mspace_free(mspace msp, void* mem);
-
-/*
-  mspace_realloc behaves as realloc, but operates within
-  the given space.
-
-  If compiled with FOOTERS==1, mspace_realloc is not actually
-  needed.  realloc may be called instead of mspace_realloc because
-  realloced chunks from any space are handled by their originating
-  spaces.
-*/
-DLMALLOC_EXPORT void* mspace_realloc(mspace msp, void* mem, size_t newsize);
-
-/*
-  mspace_calloc behaves as calloc, but operates within
-  the given space.
-*/
-DLMALLOC_EXPORT void* mspace_calloc(mspace msp, size_t n_elements, size_t elem_size);
-
-/*
-  mspace_memalign behaves as memalign, but operates within
-  the given space.
-*/
-DLMALLOC_EXPORT void* mspace_memalign(mspace msp, size_t alignment, size_t bytes);
-
-/*
-  mspace_independent_calloc behaves as independent_calloc, but
-  operates within the given space.
-*/
-DLMALLOC_EXPORT void** mspace_independent_calloc(mspace msp, size_t n_elements,
-                                 size_t elem_size, void* chunks[]);
-
-/*
-  mspace_independent_comalloc behaves as independent_comalloc, but
-  operates within the given space.
-*/
-DLMALLOC_EXPORT void** mspace_independent_comalloc(mspace msp, size_t n_elements,
-                                   size_t sizes[], void* chunks[]);
-
-/*
-  mspace_footprint() returns the number of bytes obtained from the
-  system for this space.
-*/
-DLMALLOC_EXPORT size_t mspace_footprint(mspace msp);
-
-/*
-  mspace_max_footprint() returns the peak number of bytes obtained from the
-  system for this space.
-*/
-DLMALLOC_EXPORT size_t mspace_max_footprint(mspace msp);
-
-
-#if !NO_MALLINFO
-/*
-  mspace_mallinfo behaves as mallinfo, but reports properties of
-  the given space.
-*/
-DLMALLOC_EXPORT struct mallinfo mspace_mallinfo(mspace msp);
-#endif /* NO_MALLINFO */
-
-/*
-  malloc_usable_size(void* p) behaves the same as malloc_usable_size;
-*/
-DLMALLOC_EXPORT size_t mspace_usable_size(const void* mem);
-
-/*
-  mspace_malloc_stats behaves as malloc_stats, but reports
-  properties of the given space.
-*/
-DLMALLOC_EXPORT void mspace_malloc_stats(mspace msp);
-
-/*
-  mspace_trim behaves as malloc_trim, but
-  operates within the given space.
-*/
-DLMALLOC_EXPORT int mspace_trim(mspace msp, size_t pad);
-
-/*
-  An alias for mallopt.
-*/
-DLMALLOC_EXPORT int mspace_mallopt(int, int);
-
-#endif /* MSPACES */
-
-#ifdef __cplusplus
-}  /* end of extern "C" */
-#endif /* __cplusplus */
-
-/*
-  ========================================================================
-  To make a fully customizable malloc.h header file, cut everything
-  above this line, put into file malloc.h, edit to suit, and #include it
-  on the next line, as well as in programs that use this malloc.
-  ========================================================================
-*/
-
-/* #include "malloc.h" */
-
-/*------------------------------ internal #includes ---------------------- */
-
-#ifdef _MSC_VER
-#pragma warning( disable : 4146 ) /* no "unsigned" warnings */
-#endif /* _MSC_VER */
-#if !NO_MALLOC_STATS
-#include <stdio.h>       /* for printing in malloc_stats */
-#endif /* NO_MALLOC_STATS */
-#ifndef LACKS_ERRNO_H
-#include <errno.h>       /* for MALLOC_FAILURE_ACTION */
-#endif /* LACKS_ERRNO_H */
-#ifdef DEBUG
-#if ABORT_ON_ASSERT_FAILURE
-#undef assert
-#define assert(x) if(!(x)) ABORT
-#else /* ABORT_ON_ASSERT_FAILURE */
-#include <assert.h>
-#endif /* ABORT_ON_ASSERT_FAILURE */
-#else  /* DEBUG */
-#ifndef assert
-#define assert(x)
-#endif
-#define DEBUG 0
-#endif /* DEBUG */
-#if !defined(WIN32) && !defined(LACKS_TIME_H)
-#include <time.h>        /* for magic initialization */
-#endif /* WIN32 */
-#ifndef LACKS_STDLIB_H
-#include <stdlib.h>      /* for abort() */
-#endif /* LACKS_STDLIB_H */
-#ifndef LACKS_STRING_H
-#include <string.h>      /* for memset etc */
-#endif  /* LACKS_STRING_H */
-#if USE_BUILTIN_FFS
-#ifndef LACKS_STRINGS_H
-#include <strings.h>     /* for ffs */
-#endif /* LACKS_STRINGS_H */
-#endif /* USE_BUILTIN_FFS */
-#if HAVE_MMAP
-#ifndef LACKS_SYS_MMAN_H
-/* On some versions of linux, mremap decl in mman.h needs __USE_GNU set */
-#if (defined(linux) && !defined(__USE_GNU))
-#define __USE_GNU 1
-#include <sys/mman.h>    /* for mmap */
-#undef __USE_GNU
-#else
-#include <sys/mman.h>    /* for mmap */
-#endif /* linux */
-#endif /* LACKS_SYS_MMAN_H */
-#ifndef LACKS_FCNTL_H
-#include <fcntl.h>
-#endif /* LACKS_FCNTL_H */
-#endif /* HAVE_MMAP */
-#ifndef LACKS_UNISTD_H
-#include <unistd.h>     /* for sbrk, sysconf */
-#else /* LACKS_UNISTD_H */
-#if !defined(__FreeBSD__) && !defined(__OpenBSD__) && !defined(__NetBSD__)
-extern void*     sbrk(ptrdiff_t);
-#endif /* FreeBSD etc */
-#endif /* LACKS_UNISTD_H */
-
-/* Declarations for locking */
-#if USE_LOCKS
-#ifndef WIN32
-#if defined (__SVR4) && defined (__sun)  /* solaris */
-#include <thread.h>
-#elif !defined(LACKS_SCHED_H)
-#include <sched.h>
-#endif /* solaris or LACKS_SCHED_H */
-#if (defined(USE_RECURSIVE_LOCKS) && USE_RECURSIVE_LOCKS != 0) || !USE_SPIN_LOCKS
-#include <pthread.h>
-#endif /* USE_RECURSIVE_LOCKS ... */
-#elif defined(_MSC_VER)
-#ifndef _M_AMD64
-/* These are already defined on AMD64 builds */
-#ifdef __cplusplus
-extern "C" {
-#endif /* __cplusplus */
-LONG __cdecl _InterlockedCompareExchange(LONG volatile *Dest, LONG Exchange, LONG Comp);
-LONG __cdecl _InterlockedExchange(LONG volatile *Target, LONG Value);
-#ifdef __cplusplus
-}
-#endif /* __cplusplus */
-#endif /* _M_AMD64 */
-#pragma intrinsic (_InterlockedCompareExchange)
-#pragma intrinsic (_InterlockedExchange)
-#define interlockedcompareexchange _InterlockedCompareExchange
-#define interlockedexchange _InterlockedExchange
-#elif defined(WIN32) && defined(__GNUC__)
-#define interlockedcompareexchange(a, b, c) __sync_val_compare_and_swap(a, c, b)
-#define interlockedexchange __sync_lock_test_and_set
-#endif /* Win32 */
-#else /* USE_LOCKS */
-#endif /* USE_LOCKS */
-
-#ifndef LOCK_AT_FORK
-#define LOCK_AT_FORK 0
-#endif
-
-/* Declarations for bit scanning on win32 */
-#if defined(_MSC_VER) && _MSC_VER>=1300
-#ifndef BitScanForward /* Try to avoid pulling in WinNT.h */
-#ifdef __cplusplus
-extern "C" {
-#endif /* __cplusplus */
-unsigned char _BitScanForward(unsigned long *index, unsigned long mask);
-unsigned char _BitScanReverse(unsigned long *index, unsigned long mask);
-#ifdef __cplusplus
-}
-#endif /* __cplusplus */
-
-#define BitScanForward _BitScanForward
-#define BitScanReverse _BitScanReverse
-#pragma intrinsic(_BitScanForward)
-#pragma intrinsic(_BitScanReverse)
-#endif /* BitScanForward */
-#endif /* defined(_MSC_VER) && _MSC_VER>=1300 */
-
-#ifndef WIN32
-#ifndef malloc_getpagesize
-#  ifdef _SC_PAGESIZE         /* some SVR4 systems omit an underscore */
-#    ifndef _SC_PAGE_SIZE
-#      define _SC_PAGE_SIZE _SC_PAGESIZE
-#    endif
-#  endif
-#  ifdef _SC_PAGE_SIZE
-#    define malloc_getpagesize sysconf(_SC_PAGE_SIZE)
-#  else
-#    if defined(BSD) || defined(DGUX) || defined(HAVE_GETPAGESIZE)
-       extern size_t getpagesize();
-#      define malloc_getpagesize getpagesize()
-#    else
-#      ifdef WIN32 /* use supplied emulation of getpagesize */
-#        define malloc_getpagesize getpagesize()
-#      else
-#        ifndef LACKS_SYS_PARAM_H
-#          include <sys/param.h>
-#        endif
-#        ifdef EXEC_PAGESIZE
-#          define malloc_getpagesize EXEC_PAGESIZE
-#        else
-#          ifdef NBPG
-#            ifndef CLSIZE
-#              define malloc_getpagesize NBPG
-#            else
-#              define malloc_getpagesize (NBPG * CLSIZE)
-#            endif
-#          else
-#            ifdef NBPC
-#              define malloc_getpagesize NBPC
-#            else
-#              ifdef PAGESIZE
-#                define malloc_getpagesize PAGESIZE
-#              else /* just guess */
-#                define malloc_getpagesize ((size_t)4096U)
-#              endif
-#            endif
-#          endif
-#        endif
-#      endif
-#    endif
-#  endif
-#endif
-#endif
-
-/* ------------------- size_t and alignment properties -------------------- */
-
-/* The byte and bit size of a size_t */
-#define SIZE_T_SIZE         (sizeof(size_t))
-#define SIZE_T_BITSIZE      (sizeof(size_t) << 3)
-
-/* Some constants coerced to size_t */
-/* Annoying but necessary to avoid errors on some platforms */
-#define SIZE_T_ZERO         ((size_t)0)
-#define SIZE_T_ONE          ((size_t)1)
-#define SIZE_T_TWO          ((size_t)2)
-#define SIZE_T_FOUR         ((size_t)4)
-#define TWO_SIZE_T_SIZES    (SIZE_T_SIZE<<1)
-#define FOUR_SIZE_T_SIZES   (SIZE_T_SIZE<<2)
-#define SIX_SIZE_T_SIZES    (FOUR_SIZE_T_SIZES+TWO_SIZE_T_SIZES)
-#define HALF_MAX_SIZE_T     (MAX_SIZE_T / 2U)
-
-/* The bit mask value corresponding to MALLOC_ALIGNMENT */
-#define CHUNK_ALIGN_MASK    (MALLOC_ALIGNMENT - SIZE_T_ONE)
-
-/* True if address a has acceptable alignment */
-#define is_aligned(A)       (((size_t)((A)) & (CHUNK_ALIGN_MASK)) == 0)
-
-/* the number of bytes to offset an address to align it */
-#define align_offset(A)\
- ((((size_t)(A) & CHUNK_ALIGN_MASK) == 0)? 0 :\
-  ((MALLOC_ALIGNMENT - ((size_t)(A) & CHUNK_ALIGN_MASK)) & CHUNK_ALIGN_MASK))
-
-/* -------------------------- MMAP preliminaries ------------------------- */
-
-/*
-   If HAVE_MORECORE or HAVE_MMAP are false, we just define calls and
-   checks to fail so compiler optimizer can delete code rather than
-   using so many "#if"s.
-*/
-
-
-/* MORECORE and MMAP must return MFAIL on failure */
-#define MFAIL                ((void*)(MAX_SIZE_T))
-#define CMFAIL               ((char*)(MFAIL)) /* defined for convenience */
-
-#if HAVE_MMAP
-
-#ifndef WIN32
-#define MUNMAP_DEFAULT(a, s)  munmap((a), (s))
-#define MMAP_PROT            (PROT_READ|PROT_WRITE)
-#if !defined(MAP_ANONYMOUS) && defined(MAP_ANON)
-#define MAP_ANONYMOUS        MAP_ANON
-#endif /* MAP_ANON */
-#ifdef MAP_ANONYMOUS
-#define MMAP_FLAGS           (MAP_PRIVATE|MAP_ANONYMOUS)
-#define MMAP_DEFAULT(s)       mmap(0, (s), MMAP_PROT, MMAP_FLAGS, -1, 0)
-#else /* MAP_ANONYMOUS */
-/*
-   Nearly all versions of mmap support MAP_ANONYMOUS, so the following
-   is unlikely to be needed, but is supplied just in case.
-*/
-#define MMAP_FLAGS           (MAP_PRIVATE)
-static int dev_zero_fd = -1; /* Cached file descriptor for /dev/zero. */
-#define MMAP_DEFAULT(s) ((dev_zero_fd < 0) ? \
-           (dev_zero_fd = open("/dev/zero", O_RDWR), \
-            mmap(0, (s), MMAP_PROT, MMAP_FLAGS, dev_zero_fd, 0)) : \
-            mmap(0, (s), MMAP_PROT, MMAP_FLAGS, dev_zero_fd, 0))
-#endif /* MAP_ANONYMOUS */
-
-#define DIRECT_MMAP_DEFAULT(s) MMAP_DEFAULT(s)
-
-#else /* WIN32 */
-
-/* Win32 MMAP via VirtualAlloc */
-static FORCEINLINE void* win32mmap(size_t size) {
-  void* ptr = VirtualAlloc(0, size, MEM_RESERVE|MEM_COMMIT, PAGE_READWRITE);
-  return (ptr != 0)? ptr: MFAIL;
-}
-
-/* For direct MMAP, use MEM_TOP_DOWN to minimize interference */
-static FORCEINLINE void* win32direct_mmap(size_t size) {
-  void* ptr = VirtualAlloc(0, size, MEM_RESERVE|MEM_COMMIT|MEM_TOP_DOWN,
-                           PAGE_READWRITE);
-  return (ptr != 0)? ptr: MFAIL;
-}
-
-/* This function supports releasing coalesed segments */
-static FORCEINLINE int win32munmap(void* ptr, size_t size) {
-  MEMORY_BASIC_INFORMATION minfo;
-  char* cptr = (char*)ptr;
-  while (size) {
-    if (VirtualQuery(cptr, &minfo, sizeof(minfo)) == 0)
-      return -1;
-    if (minfo.BaseAddress != cptr || minfo.AllocationBase != cptr ||
-        minfo.State != MEM_COMMIT || minfo.RegionSize > size)
-      return -1;
-    if (VirtualFree(cptr, 0, MEM_RELEASE) == 0)
-      return -1;
-    cptr += minfo.RegionSize;
-    size -= minfo.RegionSize;
-  }
-  return 0;
-}
-
-#define MMAP_DEFAULT(s)             win32mmap(s)
-#define MUNMAP_DEFAULT(a, s)        win32munmap((a), (s))
-#define DIRECT_MMAP_DEFAULT(s)      win32direct_mmap(s)
-#endif /* WIN32 */
-#endif /* HAVE_MMAP */
-
-#if HAVE_MREMAP
-#ifndef WIN32
-#define MREMAP_DEFAULT(addr, osz, nsz, mv) mremap((addr), (osz), (nsz), (mv))
-#endif /* WIN32 */
-#endif /* HAVE_MREMAP */
-
-/**
- * Define CALL_MORECORE
- */
-#if HAVE_MORECORE
-    #ifdef MORECORE
-        #define CALL_MORECORE(S)    MORECORE(S)
-    #else  /* MORECORE */
-        #define CALL_MORECORE(S)    MORECORE_DEFAULT(S)
-    #endif /* MORECORE */
-#else  /* HAVE_MORECORE */
-    #define CALL_MORECORE(S)        MFAIL
-#endif /* HAVE_MORECORE */
-
-/**
- * Define CALL_MMAP/CALL_MUNMAP/CALL_DIRECT_MMAP
- */
-#if HAVE_MMAP
-    #define USE_MMAP_BIT            (SIZE_T_ONE)
-
-    #ifdef MMAP
-        #define CALL_MMAP(s)        MMAP(s)
-    #else /* MMAP */
-        #define CALL_MMAP(s)        MMAP_DEFAULT(s)
-    #endif /* MMAP */
-    #ifdef MUNMAP
-        #define CALL_MUNMAP(a, s)   MUNMAP((a), (s))
-    #else /* MUNMAP */
-        #define CALL_MUNMAP(a, s)   MUNMAP_DEFAULT((a), (s))
-    #endif /* MUNMAP */
-    #ifdef DIRECT_MMAP
-        #define CALL_DIRECT_MMAP(s) DIRECT_MMAP(s)
-    #else /* DIRECT_MMAP */
-        #define CALL_DIRECT_MMAP(s) DIRECT_MMAP_DEFAULT(s)
-    #endif /* DIRECT_MMAP */
-#else  /* HAVE_MMAP */
-    #define USE_MMAP_BIT            (SIZE_T_ZERO)
-
-    #define MMAP(s)                 MFAIL
-    #define MUNMAP(a, s)            (-1)
-    #define DIRECT_MMAP(s)          MFAIL
-    #define CALL_DIRECT_MMAP(s)     DIRECT_MMAP(s)
-    #define CALL_MMAP(s)            MMAP(s)
-    #define CALL_MUNMAP(a, s)       MUNMAP((a), (s))
-#endif /* HAVE_MMAP */
-
-/**
- * Define CALL_MREMAP
- */
-#if HAVE_MMAP && HAVE_MREMAP
-    #ifdef MREMAP
-        #define CALL_MREMAP(addr, osz, nsz, mv) MREMAP((addr), (osz), (nsz), (mv))
-    #else /* MREMAP */
-        #define CALL_MREMAP(addr, osz, nsz, mv) MREMAP_DEFAULT((addr), (osz), (nsz), (mv))
-    #endif /* MREMAP */
-#else  /* HAVE_MMAP && HAVE_MREMAP */
-    #define CALL_MREMAP(addr, osz, nsz, mv)     MFAIL
-#endif /* HAVE_MMAP && HAVE_MREMAP */
-
-/* mstate bit set if continguous morecore disabled or failed */
-#define USE_NONCONTIGUOUS_BIT (4U)
-
-/* segment bit set in create_mspace_with_base */
-#define EXTERN_BIT            (8U)
-
-
-/* --------------------------- Lock preliminaries ------------------------ */
-
-/*
-  When locks are defined, there is one global lock, plus
-  one per-mspace lock.
-
-  The global lock_ensures that mparams.magic and other unique
-  mparams values are initialized only once. It also protects
-  sequences of calls to MORECORE.  In many cases sys_alloc requires
-  two calls, that should not be interleaved with calls by other
-  threads.  This does not protect against direct calls to MORECORE
-  by other threads not using this lock, so there is still code to
-  cope the best we can on interference.
-
-  Per-mspace locks surround calls to malloc, free, etc.
-  By default, locks are simple non-reentrant mutexes.
-
-  Because lock-protected regions generally have bounded times, it is
-  OK to use the supplied simple spinlocks. Spinlocks are likely to
-  improve performance for lightly contended applications, but worsen
-  performance under heavy contention.
-
-  If USE_LOCKS is > 1, the definitions of lock routines here are
-  bypassed, in which case you will need to define the type MLOCK_T,
-  and at least INITIAL_LOCK, DESTROY_LOCK, ACQUIRE_LOCK, RELEASE_LOCK
-  and TRY_LOCK.  You must also declare a
-    static MLOCK_T malloc_global_mutex = { initialization values };.
-
-*/
-
-#if !USE_LOCKS
-#define USE_LOCK_BIT               (0U)
-#define INITIAL_LOCK(l)            (0)
-#define DESTROY_LOCK(l)            (0)
-#define ACQUIRE_MALLOC_GLOBAL_LOCK()
-#define RELEASE_MALLOC_GLOBAL_LOCK()
-
-#else
-#if USE_LOCKS > 1
-/* -----------------------  User-defined locks ------------------------ */
-/* Define your own lock implementation here */
-/* #define INITIAL_LOCK(lk)  ... */
-/* #define DESTROY_LOCK(lk)  ... */
-/* #define ACQUIRE_LOCK(lk)  ... */
-/* #define RELEASE_LOCK(lk)  ... */
-/* #define TRY_LOCK(lk) ... */
-/* static MLOCK_T malloc_global_mutex = ... */
-
-#elif USE_SPIN_LOCKS
-
-/* First, define CAS_LOCK and CLEAR_LOCK on ints */
-/* Note CAS_LOCK defined to return 0 on success */
-
-#if defined(__GNUC__)&& (__GNUC__ > 4 || (__GNUC__ == 4 && __GNUC_MINOR__ >= 1))
-#define CAS_LOCK(sl)     __sync_lock_test_and_set(sl, 1)
-#define CLEAR_LOCK(sl)   __sync_lock_release(sl)
-
-#elif (defined(__GNUC__) && (defined(__i386__) || defined(__x86_64__)))
-/* Custom spin locks for older gcc on x86 */
-static FORCEINLINE int x86_cas_lock(int *sl) {
-  int ret;
-  int val = 1;
-  int cmp = 0;
-  __asm__ __volatile__  ("lock; cmpxchgl %1, %2"
-                         : "=a" (ret)
-                         : "r" (val), "m" (*(sl)), "0"(cmp)
-                         : "memory", "cc");
-  return ret;
-}
-
-static FORCEINLINE void x86_clear_lock(int* sl) {
-  assert(*sl != 0);
-  int prev = 0;
-  int ret;
-  __asm__ __volatile__ ("lock; xchgl %0, %1"
-                        : "=r" (ret)
-                        : "m" (*(sl)), "0"(prev)
-                        : "memory");
-}
-
-#define CAS_LOCK(sl)     x86_cas_lock(sl)
-#define CLEAR_LOCK(sl)   x86_clear_lock(sl)
-
-#else /* Win32 MSC */
-#define CAS_LOCK(sl)     interlockedexchange(sl, (LONG)1)
-#define CLEAR_LOCK(sl)   interlockedexchange (sl, (LONG)0)
-
-#endif /* ... gcc spins locks ... */
-
-/* How to yield for a spin lock */
-#define SPINS_PER_YIELD       63
-#if defined(_MSC_VER)
-#define SLEEP_EX_DURATION     50 /* delay for yield/sleep */
-#define SPIN_LOCK_YIELD  SleepEx(SLEEP_EX_DURATION, FALSE)
-#elif defined (__SVR4) && defined (__sun) /* solaris */
-#define SPIN_LOCK_YIELD   thr_yield();
-#elif !defined(LACKS_SCHED_H)
-#define SPIN_LOCK_YIELD   sched_yield();
-#else
-#define SPIN_LOCK_YIELD
-#endif /* ... yield ... */
-
-#if !defined(USE_RECURSIVE_LOCKS) || USE_RECURSIVE_LOCKS == 0
-/* Plain spin locks use single word (embedded in malloc_states) */
-static int spin_acquire_lock(int *sl) {
-  int spins = 0;
-  while (*(volatile int *)sl != 0 || CAS_LOCK(sl)) {
-    if ((++spins & SPINS_PER_YIELD) == 0) {
-      SPIN_LOCK_YIELD;
-    }
-  }
-  return 0;
-}
-
-#define MLOCK_T               int
-#define TRY_LOCK(sl)          !CAS_LOCK(sl)
-#define RELEASE_LOCK(sl)      CLEAR_LOCK(sl)
-#define ACQUIRE_LOCK(sl)      (CAS_LOCK(sl)? spin_acquire_lock(sl) : 0)
-#define INITIAL_LOCK(sl)      (*sl = 0)
-#define DESTROY_LOCK(sl)      (0)
-static MLOCK_T malloc_global_mutex = 0;
-
-#else /* USE_RECURSIVE_LOCKS */
-/* types for lock owners */
-#ifdef WIN32
-#define THREAD_ID_T           DWORD
-#define CURRENT_THREAD        GetCurrentThreadId()
-#define EQ_OWNER(X,Y)         ((X) == (Y))
-#else
-/*
-  Note: the following assume that pthread_t is a type that can be
-  initialized to (casted) zero. If this is not the case, you will need to
-  somehow redefine these or not use spin locks.
-*/
-#define THREAD_ID_T           pthread_t
-#define CURRENT_THREAD        pthread_self()
-#define EQ_OWNER(X,Y)         pthread_equal(X, Y)
-#endif
-
-struct malloc_recursive_lock {
-  int sl;
-  unsigned int c;
-  THREAD_ID_T threadid;
-};
-
-#define MLOCK_T  struct malloc_recursive_lock
-static MLOCK_T malloc_global_mutex = { 0, 0, (THREAD_ID_T)0};
-
-static FORCEINLINE void recursive_release_lock(MLOCK_T *lk) {
-  assert(lk->sl != 0);
-  if (--lk->c == 0) {
-    CLEAR_LOCK(&lk->sl);
-  }
-}
-
-static FORCEINLINE int recursive_acquire_lock(MLOCK_T *lk) {
-  THREAD_ID_T mythreadid = CURRENT_THREAD;
-  int spins = 0;
-  for (;;) {
-    if (*((volatile int *)(&lk->sl)) == 0) {
-      if (!CAS_LOCK(&lk->sl)) {
-        lk->threadid = mythreadid;
-        lk->c = 1;
-        return 0;
-      }
-    }
-    else if (EQ_OWNER(lk->threadid, mythreadid)) {
-      ++lk->c;
-      return 0;
-    }
-    if ((++spins & SPINS_PER_YIELD) == 0) {
-      SPIN_LOCK_YIELD;
-    }
-  }
-}
-
-static FORCEINLINE int recursive_try_lock(MLOCK_T *lk) {
-  THREAD_ID_T mythreadid = CURRENT_THREAD;
-  if (*((volatile int *)(&lk->sl)) == 0) {
-    if (!CAS_LOCK(&lk->sl)) {
-      lk->threadid = mythreadid;
-      lk->c = 1;
-      return 1;
-    }
-  }
-  else if (EQ_OWNER(lk->threadid, mythreadid)) {
-    ++lk->c;
-    return 1;
-  }
-  return 0;
-}
-
-#define RELEASE_LOCK(lk)      recursive_release_lock(lk)
-#define TRY_LOCK(lk)          recursive_try_lock(lk)
-#define ACQUIRE_LOCK(lk)      recursive_acquire_lock(lk)
-#define INITIAL_LOCK(lk)      ((lk)->threadid = (THREAD_ID_T)0, (lk)->sl = 0, (lk)->c = 0)
-#define DESTROY_LOCK(lk)      (0)
-#endif /* USE_RECURSIVE_LOCKS */
-
-#elif defined(WIN32) /* Win32 critical sections */
-#define MLOCK_T               CRITICAL_SECTION
-#define ACQUIRE_LOCK(lk)      (EnterCriticalSection(lk), 0)
-#define RELEASE_LOCK(lk)      LeaveCriticalSection(lk)
-#define TRY_LOCK(lk)          TryEnterCriticalSection(lk)
-#define INITIAL_LOCK(lk)      (!InitializeCriticalSectionAndSpinCount((lk), 0x80000000|4000))
-#define DESTROY_LOCK(lk)      (DeleteCriticalSection(lk), 0)
-#define NEED_GLOBAL_LOCK_INIT
-
-static MLOCK_T malloc_global_mutex;
-static volatile LONG malloc_global_mutex_status;
-
-/* Use spin loop to initialize global lock */
-static void init_malloc_global_mutex() {
-  for (;;) {
-    long stat = malloc_global_mutex_status;
-    if (stat > 0)
-      return;
-    /* transition to < 0 while initializing, then to > 0) */
-    if (stat == 0 &&
-        interlockedcompareexchange(&malloc_global_mutex_status, (LONG)-1, (LONG)0) == 0) {
-      InitializeCriticalSection(&malloc_global_mutex);
-      interlockedexchange(&malloc_global_mutex_status, (LONG)1);
-      return;
-    }
-    SleepEx(0, FALSE);
-  }
-}
-
-#else /* pthreads-based locks */
-#define MLOCK_T               pthread_mutex_t
-#define ACQUIRE_LOCK(lk)      pthread_mutex_lock(lk)
-#define RELEASE_LOCK(lk)      pthread_mutex_unlock(lk)
-#define TRY_LOCK(lk)          (!pthread_mutex_trylock(lk))
-#define INITIAL_LOCK(lk)      pthread_init_lock(lk)
-#define DESTROY_LOCK(lk)      pthread_mutex_destroy(lk)
-
-#if defined(USE_RECURSIVE_LOCKS) && USE_RECURSIVE_LOCKS != 0 && defined(linux) && !defined(PTHREAD_MUTEX_RECURSIVE)
-/* Cope with old-style linux recursive lock initialization by adding */
-/* skipped internal declaration from pthread.h */
-extern int pthread_mutexattr_setkind_np __P ((pthread_mutexattr_t *__attr,
-                                              int __kind));
-#define PTHREAD_MUTEX_RECURSIVE PTHREAD_MUTEX_RECURSIVE_NP
-#define pthread_mutexattr_settype(x,y) pthread_mutexattr_setkind_np(x,y)
-#endif /* USE_RECURSIVE_LOCKS ... */
-
-static MLOCK_T malloc_global_mutex = PTHREAD_MUTEX_INITIALIZER;
-
-static int pthread_init_lock (MLOCK_T *lk) {
-  pthread_mutexattr_t attr;
-  if (pthread_mutexattr_init(&attr)) return 1;
-#if defined(USE_RECURSIVE_LOCKS) && USE_RECURSIVE_LOCKS != 0
-  if (pthread_mutexattr_settype(&attr, PTHREAD_MUTEX_RECURSIVE)) return 1;
-#endif
-  if (pthread_mutex_init(lk, &attr)) return 1;
-  if (pthread_mutexattr_destroy(&attr)) return 1;
-  return 0;
-}
-
-#endif /* ... lock types ... */
-
-/* Common code for all lock types */
-#define USE_LOCK_BIT               (2U)
-
-#ifndef ACQUIRE_MALLOC_GLOBAL_LOCK
-#define ACQUIRE_MALLOC_GLOBAL_LOCK()  ACQUIRE_LOCK(&malloc_global_mutex);
-#endif
-
-#ifndef RELEASE_MALLOC_GLOBAL_LOCK
-#define RELEASE_MALLOC_GLOBAL_LOCK()  RELEASE_LOCK(&malloc_global_mutex);
-#endif
-
-#endif /* USE_LOCKS */
-
-/* -----------------------  Chunk representations ------------------------ */
-
-/*
-  (The following includes lightly edited explanations by Colin Plumb.)
-
-  The malloc_chunk declaration below is misleading (but accurate and
-  necessary).  It declares a "view" into memory allowing access to
-  necessary fields at known offsets from a given base.
-
-  Chunks of memory are maintained using a `boundary tag' method as
-  originally described by Knuth.  (See the paper by Paul Wilson
-  ftp://ftp.cs.utexas.edu/pub/garbage/allocsrv.ps for a survey of such
-  techniques.)  Sizes of free chunks are stored both in the front of
-  each chunk and at the end.  This makes consolidating fragmented
-  chunks into bigger chunks fast.  The head fields also hold bits
-  representing whether chunks are free or in use.
-
-  Here are some pictures to make it clearer.  They are "exploded" to
-  show that the state of a chunk can be thought of as extending from
-  the high 31 bits of the head field of its header through the
-  prev_foot and PINUSE_BIT bit of the following chunk header.
-
-  A chunk that's in use looks like:
-
-   chunk-> +-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+
-           | Size of previous chunk (if P = 0)                             |
-           +-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+
-         +-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+ |P|
-         | Size of this chunk                                         1| +-+
-   mem-> +-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+
-         |                                                               |
-         +-                                                             -+
-         |                                                               |
-         +-                                                             -+
-         |                                                               :
-         +-      size - sizeof(size_t) available payload bytes          -+
-         :                                                               |
- chunk-> +-                                                             -+
-         |                                                               |
-         +-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+
-       +-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+ |1|
-       | Size of next chunk (may or may not be in use)               | +-+
- mem-> +-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+
-
-    And if it's free, it looks like this:
-
-   chunk-> +-                                                             -+
-           | User payload (must be in use, or we would have merged!)       |
-           +-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+
-         +-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+ |P|
-         | Size of this chunk                                         0| +-+
-   mem-> +-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+
-         | Next pointer                                                  |
-         +-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+
-         | Prev pointer                                                  |
-         +-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+
-         |                                                               :
-         +-      size - sizeof(struct chunk) unused bytes               -+
-         :                                                               |
- chunk-> +-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+
-         | Size of this chunk                                            |
-         +-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+
-       +-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+ |0|
-       | Size of next chunk (must be in use, or we would have merged)| +-+
- mem-> +-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+
-       |                                                               :
-       +- User payload                                                -+
-       :                                                               |
-       +-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+
-                                                                     |0|
-                                                                     +-+
-  Note that since we always merge adjacent free chunks, the chunks
-  adjacent to a free chunk must be in use.
-
-  Given a pointer to a chunk (which can be derived trivially from the
-  payload pointer) we can, in O(1) time, find out whether the adjacent
-  chunks are free, and if so, unlink them from the lists that they
-  are on and merge them with the current chunk.
-
-  Chunks always begin on even word boundaries, so the mem portion
-  (which is returned to the user) is also on an even word boundary, and
-  thus at least double-word aligned.
-
-  The P (PINUSE_BIT) bit, stored in the unused low-order bit of the
-  chunk size (which is always a multiple of two words), is an in-use
-  bit for the *previous* chunk.  If that bit is *clear*, then the
-  word before the current chunk size contains the previous chunk
-  size, and can be used to find the front of the previous chunk.
-  The very first chunk allocated always has this bit set, preventing
-  access to non-existent (or non-owned) memory. If pinuse is set for
-  any given chunk, then you CANNOT determine the size of the
-  previous chunk, and might even get a memory addressing fault when
-  trying to do so.
-
-  The C (CINUSE_BIT) bit, stored in the unused second-lowest bit of
-  the chunk size redundantly records whether the current chunk is
-  inuse (unless the chunk is mmapped). This redundancy enables usage
-  checks within free and realloc, and reduces indirection when freeing
-  and consolidating chunks.
-
-  Each freshly allocated chunk must have both cinuse and pinuse set.
-  That is, each allocated chunk borders either a previously allocated
-  and still in-use chunk, or the base of its memory arena. This is
-  ensured by making all allocations from the `lowest' part of any
-  found chunk.  Further, no free chunk physically borders another one,
-  so each free chunk is known to be preceded and followed by either
-  inuse chunks or the ends of memory.
-
-  Note that the `foot' of the current chunk is actually represented
-  as the prev_foot of the NEXT chunk. This makes it easier to
-  deal with alignments etc but can be very confusing when trying
-  to extend or adapt this code.
-
-  The exceptions to all this are
-
-     1. The special chunk `top' is the top-most available chunk (i.e.,
-        the one bordering the end of available memory). It is treated
-        specially.  Top is never included in any bin, is used only if
-        no other chunk is available, and is released back to the
-        system if it is very large (see M_TRIM_THRESHOLD).  In effect,
-        the top chunk is treated as larger (and thus less well
-        fitting) than any other available chunk.  The top chunk
-        doesn't update its trailing size field since there is no next
-        contiguous chunk that would have to index off it. However,
-        space is still allocated for it (TOP_FOOT_SIZE) to enable
-        separation or merging when space is extended.
-
-     3. Chunks allocated via mmap, have both cinuse and pinuse bits
-        cleared in their head fields.  Because they are allocated
-        one-by-one, each must carry its own prev_foot field, which is
-        also used to hold the offset this chunk has within its mmapped
-        region, which is needed to preserve alignment. Each mmapped
-        chunk is trailed by the first two fields of a fake next-chunk
-        for sake of usage checks.
-
-*/
-
-struct malloc_chunk {
-  size_t               prev_foot;  /* Size of previous chunk (if free).  */
-  size_t               head;       /* Size and inuse bits. */
-  struct malloc_chunk* fd;         /* double links -- used only if free. */
-  struct malloc_chunk* bk;
-};
-
-typedef struct malloc_chunk  mchunk;
-typedef struct malloc_chunk* mchunkptr;
-typedef struct malloc_chunk* sbinptr;  /* The type of bins of chunks */
-typedef unsigned int bindex_t;         /* Described below */
-typedef unsigned int binmap_t;         /* Described below */
-typedef unsigned int flag_t;           /* The type of various bit flag sets */
-
-/* ------------------- Chunks sizes and alignments ----------------------- */
-
-#define MCHUNK_SIZE         (sizeof(mchunk))
-
-#if FOOTERS
-#define CHUNK_OVERHEAD      (TWO_SIZE_T_SIZES)
-#else /* FOOTERS */
-#define CHUNK_OVERHEAD      (SIZE_T_SIZE)
-#endif /* FOOTERS */
-
-/* MMapped chunks need a second word of overhead ... */
-#define MMAP_CHUNK_OVERHEAD (TWO_SIZE_T_SIZES)
-/* ... and additional padding for fake next-chunk at foot */
-#define MMAP_FOOT_PAD       (FOUR_SIZE_T_SIZES)
-
-/* The smallest size we can malloc is an aligned minimal chunk */
-#define MIN_CHUNK_SIZE\
-  ((MCHUNK_SIZE + CHUNK_ALIGN_MASK) & ~CHUNK_ALIGN_MASK)
-
-/* conversion from malloc headers to user pointers, and back */
-#define chunk2mem(p)        ((void*)((char*)(p)       + TWO_SIZE_T_SIZES))
-#define mem2chunk(mem)      ((mchunkptr)((char*)(mem) - TWO_SIZE_T_SIZES))
-/* chunk associated with aligned address A */
-#define align_as_chunk(A)   (mchunkptr)((A) + align_offset(chunk2mem(A)))
-
-/* Bounds on request (not chunk) sizes. */
-#define MAX_REQUEST         ((-MIN_CHUNK_SIZE) << 2)
-#define MIN_REQUEST         (MIN_CHUNK_SIZE - CHUNK_OVERHEAD - SIZE_T_ONE)
-
-/* pad request bytes into a usable size */
-#define pad_request(req) \
-   (((req) + CHUNK_OVERHEAD + CHUNK_ALIGN_MASK) & ~CHUNK_ALIGN_MASK)
-
-/* pad request, checking for minimum (but not maximum) */
-#define request2size(req) \
-  (((req) < MIN_REQUEST)? MIN_CHUNK_SIZE : pad_request(req))
-
-
-/* ------------------ Operations on head and foot fields ----------------- */
-
-/*
-  The head field of a chunk is or'ed with PINUSE_BIT when previous
-  adjacent chunk in use, and or'ed with CINUSE_BIT if this chunk is in
-  use, unless mmapped, in which case both bits are cleared.
-
-  FLAG4_BIT is not used by this malloc, but might be useful in extensions.
-*/
-
-#define PINUSE_BIT          (SIZE_T_ONE)
-#define CINUSE_BIT          (SIZE_T_TWO)
-#define FLAG4_BIT           (SIZE_T_FOUR)
-#define INUSE_BITS          (PINUSE_BIT|CINUSE_BIT)
-#define FLAG_BITS           (PINUSE_BIT|CINUSE_BIT|FLAG4_BIT)
-
-/* Head value for fenceposts */
-#define FENCEPOST_HEAD      (INUSE_BITS|SIZE_T_SIZE)
-
-/* extraction of fields from head words */
-#define cinuse(p)           ((p)->head & CINUSE_BIT)
-#define pinuse(p)           ((p)->head & PINUSE_BIT)
-#define flag4inuse(p)       ((p)->head & FLAG4_BIT)
-#define is_inuse(p)         (((p)->head & INUSE_BITS) != PINUSE_BIT)
-#define is_mmapped(p)       (((p)->head & INUSE_BITS) == 0)
-
-#define chunksize(p)        ((p)->head & ~(FLAG_BITS))
-
-#define clear_pinuse(p)     ((p)->head &= ~PINUSE_BIT)
-#define set_flag4(p)        ((p)->head |= FLAG4_BIT)
-#define clear_flag4(p)      ((p)->head &= ~FLAG4_BIT)
-
-/* Treat space at ptr +/- offset as a chunk */
-#define chunk_plus_offset(p, s)  ((mchunkptr)(((char*)(p)) + (s)))
-#define chunk_minus_offset(p, s) ((mchunkptr)(((char*)(p)) - (s)))
-
-/* Ptr to next or previous physical malloc_chunk. */
-#define next_chunk(p) ((mchunkptr)( ((char*)(p)) + ((p)->head & ~FLAG_BITS)))
-#define prev_chunk(p) ((mchunkptr)( ((char*)(p)) - ((p)->prev_foot) ))
-
-/* extract next chunk's pinuse bit */
-#define next_pinuse(p)  ((next_chunk(p)->head) & PINUSE_BIT)
-
-/* Get/set size at footer */
-#define get_foot(p, s)  (((mchunkptr)((char*)(p) + (s)))->prev_foot)
-#define set_foot(p, s)  (((mchunkptr)((char*)(p) + (s)))->prev_foot = (s))
-
-/* Set size, pinuse bit, and foot */
-#define set_size_and_pinuse_of_free_chunk(p, s)\
-  ((p)->head = (s|PINUSE_BIT), set_foot(p, s))
-
-/* Set size, pinuse bit, foot, and clear next pinuse */
-#define set_free_with_pinuse(p, s, n)\
-  (clear_pinuse(n), set_size_and_pinuse_of_free_chunk(p, s))
-
-/* Get the internal overhead associated with chunk p */
-#define overhead_for(p)\
- (is_mmapped(p)? MMAP_CHUNK_OVERHEAD : CHUNK_OVERHEAD)
-
-/* Return true if malloced space is not necessarily cleared */
-#if MMAP_CLEARS
-#define calloc_must_clear(p) (!is_mmapped(p))
-#else /* MMAP_CLEARS */
-#define calloc_must_clear(p) (1)
-#endif /* MMAP_CLEARS */
-
-/* ---------------------- Overlaid data structures ----------------------- */
-
-/*
-  When chunks are not in use, they are treated as nodes of either
-  lists or trees.
-
-  "Small"  chunks are stored in circular doubly-linked lists, and look
-  like this:
-
-    chunk-> +-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+
-            |             Size of previous chunk                            |
-            +-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+
-    `head:' |             Size of chunk, in bytes                         |P|
-      mem-> +-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+
-            |             Forward pointer to next chunk in list             |
-            +-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+
-            |             Back pointer to previous chunk in list            |
-            +-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+
-            |             Unused space (may be 0 bytes long)                .
-            .                                                               .
-            .                                                               |
-nextchunk-> +-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+
-    `foot:' |             Size of chunk, in bytes                           |
-            +-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+
-
-  Larger chunks are kept in a form of bitwise digital trees (aka
-  tries) keyed on chunksizes.  Because malloc_tree_chunks are only for
-  free chunks greater than 256 bytes, their size doesn't impose any
-  constraints on user chunk sizes.  Each node looks like:
-
-    chunk-> +-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+
-            |             Size of previous chunk                            |
-            +-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+
-    `head:' |             Size of chunk, in bytes                         |P|
-      mem-> +-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+
-            |             Forward pointer to next chunk of same size        |
-            +-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+
-            |             Back pointer to previous chunk of same size       |
-            +-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+
-            |             Pointer to left child (child[0])                  |
-            +-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+
-            |             Pointer to right child (child[1])                 |
-            +-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+
-            |             Pointer to parent                                 |
-            +-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+
-            |             bin index of this chunk                           |
-            +-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+
-            |             Unused space                                      .
-            .                                                               |
-nextchunk-> +-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+
-    `foot:' |             Size of chunk, in bytes                           |
-            +-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+
-
-  Each tree holding treenodes is a tree of unique chunk sizes.  Chunks
-  of the same size are arranged in a circularly-linked list, with only
-  the oldest chunk (the next to be used, in our FIFO ordering)
-  actually in the tree.  (Tree members are distinguished by a non-null
-  parent pointer.)  If a chunk with the same size an an existing node
-  is inserted, it is linked off the existing node using pointers that
-  work in the same way as fd/bk pointers of small chunks.
-
-  Each tree contains a power of 2 sized range of chunk sizes (the
-  smallest is 0x100 <= x < 0x180), which is is divided in half at each
-  tree level, with the chunks in the smaller half of the range (0x100
-  <= x < 0x140 for the top nose) in the left subtree and the larger
-  half (0x140 <= x < 0x180) in the right subtree.  This is, of course,
-  done by inspecting individual bits.
-
-  Using these rules, each node's left subtree contains all smaller
-  sizes than its right subtree.  However, the node at the root of each
-  subtree has no particular ordering relationship to either.  (The
-  dividing line between the subtree sizes is based on trie relation.)
-  If we remove the last chunk of a given size from the interior of the
-  tree, we need to replace it with a leaf node.  The tree ordering
-  rules permit a node to be replaced by any leaf below it.
-
-  The smallest chunk in a tree (a common operation in a best-fit
-  allocator) can be found by walking a path to the leftmost leaf in
-  the tree.  Unlike a usual binary tree, where we follow left child
-  pointers until we reach a null, here we follow the right child
-  pointer any time the left one is null, until we reach a leaf with
-  both child pointers null. The smallest chunk in the tree will be
-  somewhere along that path.
-
-  The worst case number of steps to add, find, or remove a node is
-  bounded by the number of bits differentiating chunks within
-  bins. Under current bin calculations, this ranges from 6 up to 21
-  (for 32 bit sizes) or up to 53 (for 64 bit sizes). The typical case
-  is of course much better.
-*/
-
-struct malloc_tree_chunk {
-  /* The first four fields must be compatible with malloc_chunk */
-  size_t                    prev_foot;
-  size_t                    head;
-  struct malloc_tree_chunk* fd;
-  struct malloc_tree_chunk* bk;
-
-  struct malloc_tree_chunk* child[2];
-  struct malloc_tree_chunk* parent;
-  bindex_t                  index;
-};
-
-typedef struct malloc_tree_chunk  tchunk;
-typedef struct malloc_tree_chunk* tchunkptr;
-typedef struct malloc_tree_chunk* tbinptr; /* The type of bins of trees */
-
-/* A little helper macro for trees */
-#define leftmost_child(t) ((t)->child[0] != 0? (t)->child[0] : (t)->child[1])
-
-/* ----------------------------- Segments -------------------------------- */
-
-/*
-  Each malloc space may include non-contiguous segments, held in a
-  list headed by an embedded malloc_segment record representing the
-  top-most space. Segments also include flags holding properties of
-  the space. Large chunks that are directly allocated by mmap are not
-  included in this list. They are instead independently created and
-  destroyed without otherwise keeping track of them.
-
-  Segment management mainly comes into play for spaces allocated by
-  MMAP.  Any call to MMAP might or might not return memory that is
-  adjacent to an existing segment.  MORECORE normally contiguously
-  extends the current space, so this space is almost always adjacent,
-  which is simpler and faster to deal with. (This is why MORECORE is
-  used preferentially to MMAP when both are available -- see
-  sys_alloc.)  When allocating using MMAP, we don't use any of the
-  hinting mechanisms (inconsistently) supported in various
-  implementations of unix mmap, or distinguish reserving from
-  committing memory. Instead, we just ask for space, and exploit
-  contiguity when we get it.  It is probably possible to do
-  better than this on some systems, but no general scheme seems
-  to be significantly better.
-
-  Management entails a simpler variant of the consolidation scheme
-  used for chunks to reduce fragmentation -- new adjacent memory is
-  normally prepended or appended to an existing segment. However,
-  there are limitations compared to chunk consolidation that mostly
-  reflect the fact that segment processing is relatively infrequent
-  (occurring only when getting memory from system) and that we
-  don't expect to have huge numbers of segments:
-
-  * Segments are not indexed, so traversal requires linear scans.  (It
-    would be possible to index these, but is not worth the extra
-    overhead and complexity for most programs on most platforms.)
-  * New segments are only appended to old ones when holding top-most
-    memory; if they cannot be prepended to others, they are held in
-    different segments.
-
-  Except for the top-most segment of an mstate, each segment record
-  is kept at the tail of its segment. Segments are added by pushing
-  segment records onto the list headed by &mstate.seg for the
-  containing mstate.
-
-  Segment flags control allocation/merge/deallocation policies:
-  * If EXTERN_BIT set, then we did not allocate this segment,
-    and so should not try to deallocate or merge with others.
-    (This currently holds only for the initial segment passed
-    into create_mspace_with_base.)
-  * If USE_MMAP_BIT set, the segment may be merged with
-    other surrounding mmapped segments and trimmed/de-allocated
-    using munmap.
-  * If neither bit is set, then the segment was obtained using
-    MORECORE so can be merged with surrounding MORECORE'd segments
-    and deallocated/trimmed using MORECORE with negative arguments.
-*/
-
-struct malloc_segment {
-  char*        base;             /* base address */
-  size_t       size;             /* allocated size */
-  struct malloc_segment* next;   /* ptr to next segment */
-  flag_t       sflags;           /* mmap and extern flag */
-};
-
-#define is_mmapped_segment(S)  ((S)->sflags & USE_MMAP_BIT)
-#define is_extern_segment(S)   ((S)->sflags & EXTERN_BIT)
-
-typedef struct malloc_segment  msegment;
-typedef struct malloc_segment* msegmentptr;
-
-/* ---------------------------- malloc_state ----------------------------- */
-
-/*
-   A malloc_state holds all of the bookkeeping for a space.
-   The main fields are:
-
-  Top
-    The topmost chunk of the currently active segment. Its size is
-    cached in topsize.  The actual size of topmost space is
-    topsize+TOP_FOOT_SIZE, which includes space reserved for adding
-    fenceposts and segment records if necessary when getting more
-    space from the system.  The size at which to autotrim top is
-    cached from mparams in trim_check, except that it is disabled if
-    an autotrim fails.
-
-  Designated victim (dv)
-    This is the preferred chunk for servicing small requests that
-    don't have exact fits.  It is normally the chunk split off most
-    recently to service another small request.  Its size is cached in
-    dvsize. The link fields of this chunk are not maintained since it
-    is not kept in a bin.
-
-  SmallBins
-    An array of bin headers for free chunks.  These bins hold chunks
-    with sizes less than MIN_LARGE_SIZE bytes. Each bin contains
-    chunks of all the same size, spaced 8 bytes apart.  To simplify
-    use in double-linked lists, each bin header acts as a malloc_chunk
-    pointing to the real first node, if it exists (else pointing to
-    itself).  This avoids special-casing for headers.  But to avoid
-    waste, we allocate only the fd/bk pointers of bins, and then use
-    repositioning tricks to treat these as the fields of a chunk.
-
-  TreeBins
-    Treebins are pointers to the roots of trees holding a range of
-    sizes. There are 2 equally spaced treebins for each power of two
-    from TREE_SHIFT to TREE_SHIFT+16. The last bin holds anything
-    larger.
-
-  Bin maps
-    There is one bit map for small bins ("smallmap") and one for
-    treebins ("treemap).  Each bin sets its bit when non-empty, and
-    clears the bit when empty.  Bit operations are then used to avoid
-    bin-by-bin searching -- nearly all "search" is done without ever
-    looking at bins that won't be selected.  The bit maps
-    conservatively use 32 bits per map word, even if on 64bit system.
-    For a good description of some of the bit-based techniques used
-    here, see Henry S. Warren Jr's book "Hacker's Delight" (and
-    supplement at http://hackersdelight.org/). Many of these are
-    intended to reduce the branchiness of paths through malloc etc, as
-    well as to reduce the number of memory locations read or written.
-
-  Segments
-    A list of segments headed by an embedded malloc_segment record
-    representing the initial space.
-
-  Address check support
-    The least_addr field is the least address ever obtained from
-    MORECORE or MMAP. Attempted frees and reallocs of any address less
-    than this are trapped (unless INSECURE is defined).
-
-  Magic tag
-    A cross-check field that should always hold same value as mparams.magic.
-
-  Max allowed footprint
-    The maximum allowed bytes to allocate from system (zero means no limit)
-
-  Flags
-    Bits recording whether to use MMAP, locks, or contiguous MORECORE
-
-  Statistics
-    Each space keeps track of current and maximum system memory
-    obtained via MORECORE or MMAP.
-
-  Trim support
-    Fields holding the amount of unused topmost memory that should trigger
-    trimming, and a counter to force periodic scanning to release unused
-    non-topmost segments.
-
-  Locking
-    If USE_LOCKS is defined, the "mutex" lock is acquired and released
-    around every public call using this mspace.
-
-  Extension support
-    A void* pointer and a size_t field that can be used to help implement
-    extensions to this malloc.
-*/
-
-/* Bin types, widths and sizes */
-#define NSMALLBINS        (32U)
-#define NTREEBINS         (32U)
-#define SMALLBIN_SHIFT    (3U)
-#define SMALLBIN_WIDTH    (SIZE_T_ONE << SMALLBIN_SHIFT)
-#define TREEBIN_SHIFT     (8U)
-#define MIN_LARGE_SIZE    (SIZE_T_ONE << TREEBIN_SHIFT)
-#define MAX_SMALL_SIZE    (MIN_LARGE_SIZE - SIZE_T_ONE)
-#define MAX_SMALL_REQUEST (MAX_SMALL_SIZE - CHUNK_ALIGN_MASK - CHUNK_OVERHEAD)
-
-struct malloc_state {
-  binmap_t   smallmap;
-  binmap_t   treemap;
-  size_t     dvsize;
-  size_t     topsize;
-  char*      least_addr;
-  mchunkptr  dv;
-  mchunkptr  top;
-  size_t     trim_check;
-  size_t     release_checks;
-  size_t     magic;
-  mchunkptr  smallbins[(NSMALLBINS+1)*2];
-  tbinptr    treebins[NTREEBINS];
-  size_t     footprint;
-  size_t     max_footprint;
-  size_t     footprint_limit; /* zero means no limit */
-  flag_t     mflags;
-#if USE_LOCKS
-  MLOCK_T    mutex;     /* locate lock among fields that rarely change */
-#endif /* USE_LOCKS */
-  msegment   seg;
-  void*      extp;      /* Unused but available for extensions */
-  size_t     exts;
-};
-
-typedef struct malloc_state*    mstate;
-
-/* ------------- Global malloc_state and malloc_params ------------------- */
-
-/*
-  malloc_params holds global properties, including those that can be
-  dynamically set using mallopt. There is a single instance, mparams,
-  initialized in init_mparams. Note that the non-zeroness of "magic"
-  also serves as an initialization flag.
-*/
-
-struct malloc_params {
-  size_t magic;
-  size_t page_size;
-  size_t granularity;
-  size_t mmap_threshold;
-  size_t trim_threshold;
-  flag_t default_mflags;
-};
-
-static struct malloc_params mparams;
-
-/* Ensure mparams initialized */
-#define ensure_initialization() (void)(mparams.magic != 0 || init_mparams())
-
-#if !ONLY_MSPACES
-
-/* The global malloc_state used for all non-"mspace" calls */
-static struct malloc_state _gm_;
-#define gm                 (&_gm_)
-#define is_global(M)       ((M) == &_gm_)
-
-#endif /* !ONLY_MSPACES */
-
-#define is_initialized(M)  ((M)->top != 0)
-
-/* -------------------------- system alloc setup ------------------------- */
-
-/* Operations on mflags */
-
-#define use_lock(M)           ((M)->mflags &   USE_LOCK_BIT)
-#define enable_lock(M)        ((M)->mflags |=  USE_LOCK_BIT)
-#if USE_LOCKS
-#define disable_lock(M)       ((M)->mflags &= ~USE_LOCK_BIT)
-#else
-#define disable_lock(M)
-#endif
-
-#define use_mmap(M)           ((M)->mflags &   USE_MMAP_BIT)
-#define enable_mmap(M)        ((M)->mflags |=  USE_MMAP_BIT)
-#if HAVE_MMAP
-#define disable_mmap(M)       ((M)->mflags &= ~USE_MMAP_BIT)
-#else
-#define disable_mmap(M)
-#endif
-
-#define use_noncontiguous(M)  ((M)->mflags &   USE_NONCONTIGUOUS_BIT)
-#define disable_contiguous(M) ((M)->mflags |=  USE_NONCONTIGUOUS_BIT)
-
-#define set_lock(M,L)\
- ((M)->mflags = (L)?\
-  ((M)->mflags | USE_LOCK_BIT) :\
-  ((M)->mflags & ~USE_LOCK_BIT))
-
-/* page-align a size */
-#define page_align(S)\
- (((S) + (mparams.page_size - SIZE_T_ONE)) & ~(mparams.page_size - SIZE_T_ONE))
-
-/* granularity-align a size */
-#define granularity_align(S)\
-  (((S) + (mparams.granularity - SIZE_T_ONE))\
-   & ~(mparams.granularity - SIZE_T_ONE))
-
-
-/* For mmap, use granularity alignment on windows, else page-align */
-#ifdef WIN32
-#define mmap_align(S) granularity_align(S)
-#else
-#define mmap_align(S) page_align(S)
-#endif
-
-/* For sys_alloc, enough padding to ensure can malloc request on success */
-#define SYS_ALLOC_PADDING (TOP_FOOT_SIZE + MALLOC_ALIGNMENT)
-
-#define is_page_aligned(S)\
-   (((size_t)(S) & (mparams.page_size - SIZE_T_ONE)) == 0)
-#define is_granularity_aligned(S)\
-   (((size_t)(S) & (mparams.granularity - SIZE_T_ONE)) == 0)
-
-/*  True if segment S holds address A */
-#define segment_holds(S, A)\
-  ((char*)(A) >= S->base && (char*)(A) < S->base + S->size)
-
-/* Return segment holding given address */
-static msegmentptr segment_holding(mstate m, char* addr) {
-  msegmentptr sp = &m->seg;
-  for (;;) {
-    if (addr >= sp->base && addr < sp->base + sp->size)
-      return sp;
-    if ((sp = sp->next) == 0)
-      return 0;
-  }
-}
-
-/* Return true if segment contains a segment link */
-static int has_segment_link(mstate m, msegmentptr ss) {
-  msegmentptr sp = &m->seg;
-  for (;;) {
-    if ((char*)sp >= ss->base && (char*)sp < ss->base + ss->size)
-      return 1;
-    if ((sp = sp->next) == 0)
-      return 0;
-  }
-}
-
-#ifndef MORECORE_CANNOT_TRIM
-#define should_trim(M,s)  ((s) > (M)->trim_check)
-#else  /* MORECORE_CANNOT_TRIM */
-#define should_trim(M,s)  (0)
-#endif /* MORECORE_CANNOT_TRIM */
-
-/*
-  TOP_FOOT_SIZE is padding at the end of a segment, including space
-  that may be needed to place segment records and fenceposts when new
-  noncontiguous segments are added.
-*/
-#define TOP_FOOT_SIZE\
-  (align_offset(chunk2mem(0))+pad_request(sizeof(struct malloc_segment))+MIN_CHUNK_SIZE)
-
-
-/* -------------------------------  Hooks -------------------------------- */
-
-/*
-  PREACTION should be defined to return 0 on success, and nonzero on
-  failure. If you are not using locking, you can redefine these to do
-  anything you like.
-*/
-
-#if USE_LOCKS
-#define PREACTION(M)  ((use_lock(M))? ACQUIRE_LOCK(&(M)->mutex) : 0)
-#define POSTACTION(M) { if (use_lock(M)) RELEASE_LOCK(&(M)->mutex); }
-#else /* USE_LOCKS */
-
-#ifndef PREACTION
-#define PREACTION(M) (0)
-#endif  /* PREACTION */
-
-#ifndef POSTACTION
-#define POSTACTION(M)
-#endif  /* POSTACTION */
-
-#endif /* USE_LOCKS */
-
-/*
-  CORRUPTION_ERROR_ACTION is triggered upon detected bad addresses.
-  USAGE_ERROR_ACTION is triggered on detected bad frees and
-  reallocs. The argument p is an address that might have triggered the
-  fault. It is ignored by the two predefined actions, but might be
-  useful in custom actions that try to help diagnose errors.
-*/
-
-#if PROCEED_ON_ERROR
-
-/* A count of the number of corruption errors causing resets */
-int malloc_corruption_error_count;
-
-/* default corruption action */
-static void reset_on_error(mstate m);
-
-#define CORRUPTION_ERROR_ACTION(m)  reset_on_error(m)
-#define USAGE_ERROR_ACTION(m, p)
-
-#else /* PROCEED_ON_ERROR */
-
-#ifndef CORRUPTION_ERROR_ACTION
-#define CORRUPTION_ERROR_ACTION(m) ABORT
-#endif /* CORRUPTION_ERROR_ACTION */
-
-#ifndef USAGE_ERROR_ACTION
-#define USAGE_ERROR_ACTION(m,p) ABORT
-#endif /* USAGE_ERROR_ACTION */
-
-#endif /* PROCEED_ON_ERROR */
-
-
-/* -------------------------- Debugging setup ---------------------------- */
-
-#if ! DEBUG
-
-#define check_free_chunk(M,P)
-#define check_inuse_chunk(M,P)
-#define check_malloced_chunk(M,P,N)
-#define check_mmapped_chunk(M,P)
-#define check_malloc_state(M)
-#define check_top_chunk(M,P)
-
-#else /* DEBUG */
-#define check_free_chunk(M,P)       do_check_free_chunk(M,P)
-#define check_inuse_chunk(M,P)      do_check_inuse_chunk(M,P)
-#define check_top_chunk(M,P)        do_check_top_chunk(M,P)
-#define check_malloced_chunk(M,P,N) do_check_malloced_chunk(M,P,N)
-#define check_mmapped_chunk(M,P)    do_check_mmapped_chunk(M,P)
-#define check_malloc_state(M)       do_check_malloc_state(M)
-
-static void   do_check_any_chunk(mstate m, mchunkptr p);
-static void   do_check_top_chunk(mstate m, mchunkptr p);
-static void   do_check_mmapped_chunk(mstate m, mchunkptr p);
-static void   do_check_inuse_chunk(mstate m, mchunkptr p);
-static void   do_check_free_chunk(mstate m, mchunkptr p);
-static void   do_check_malloced_chunk(mstate m, void* mem, size_t s);
-static void   do_check_tree(mstate m, tchunkptr t);
-static void   do_check_treebin(mstate m, bindex_t i);
-static void   do_check_smallbin(mstate m, bindex_t i);
-static void   do_check_malloc_state(mstate m);
-static int    bin_find(mstate m, mchunkptr x);
-static size_t traverse_and_check(mstate m);
-#endif /* DEBUG */
-
-/* ---------------------------- Indexing Bins ---------------------------- */
-
-#define is_small(s)         (((s) >> SMALLBIN_SHIFT) < NSMALLBINS)
-#define small_index(s)      (bindex_t)((s)  >> SMALLBIN_SHIFT)
-#define small_index2size(i) ((i)  << SMALLBIN_SHIFT)
-#define MIN_SMALL_INDEX     (small_index(MIN_CHUNK_SIZE))
-
-/* addressing by index. See above about smallbin repositioning */
-/* BEGIN android-changed: strict aliasing change: char* cast to void* */
-#define smallbin_at(M, i)   ((sbinptr)((void*)&((M)->smallbins[(i)<<1])))
-/* END android-changed */
-#define treebin_at(M,i)     (&((M)->treebins[i]))
-
-/* assign tree index for size S to variable I. Use x86 asm if possible  */
-#if defined(__GNUC__) && (defined(__i386__) || defined(__x86_64__))
-#define compute_tree_index(S, I)\
-{\
-  unsigned int X = S >> TREEBIN_SHIFT;\
-  if (X == 0)\
-    I = 0;\
-  else if (X > 0xFFFF)\
-    I = NTREEBINS-1;\
-  else {\
-    unsigned int K = (unsigned) sizeof(X)*__CHAR_BIT__ - 1 - (unsigned) __builtin_clz(X); \
-    I =  (bindex_t)((K << 1) + ((S >> (K + (TREEBIN_SHIFT-1)) & 1)));\
-  }\
-}
-
-#elif defined (__INTEL_COMPILER)
-#define compute_tree_index(S, I)\
-{\
-  size_t X = S >> TREEBIN_SHIFT;\
-  if (X == 0)\
-    I = 0;\
-  else if (X > 0xFFFF)\
-    I = NTREEBINS-1;\
-  else {\
-    unsigned int K = _bit_scan_reverse (X); \
-    I =  (bindex_t)((K << 1) + ((S >> (K + (TREEBIN_SHIFT-1)) & 1)));\
-  }\
-}
-
-#elif defined(_MSC_VER) && _MSC_VER>=1300
-#define compute_tree_index(S, I)\
-{\
-  size_t X = S >> TREEBIN_SHIFT;\
-  if (X == 0)\
-    I = 0;\
-  else if (X > 0xFFFF)\
-    I = NTREEBINS-1;\
-  else {\
-    unsigned int K;\
-    _BitScanReverse((DWORD *) &K, (DWORD) X);\
-    I =  (bindex_t)((K << 1) + ((S >> (K + (TREEBIN_SHIFT-1)) & 1)));\
-  }\
-}
-
-#else /* GNUC */
-#define compute_tree_index(S, I)\
-{\
-  size_t X = S >> TREEBIN_SHIFT;\
-  if (X == 0)\
-    I = 0;\
-  else if (X > 0xFFFF)\
-    I = NTREEBINS-1;\
-  else {\
-    unsigned int Y = (unsigned int)X;\
-    unsigned int N = ((Y - 0x100) >> 16) & 8;\
-    unsigned int K = (((Y <<= N) - 0x1000) >> 16) & 4;\
-    N += K;\
-    N += K = (((Y <<= K) - 0x4000) >> 16) & 2;\
-    K = 14 - N + ((Y <<= K) >> 15);\
-    I = (K << 1) + ((S >> (K + (TREEBIN_SHIFT-1)) & 1));\
-  }\
-}
-#endif /* GNUC */
-
-/* Bit representing maximum resolved size in a treebin at i */
-#define bit_for_tree_index(i) \
-   (i == NTREEBINS-1)? (SIZE_T_BITSIZE-1) : (((i) >> 1) + TREEBIN_SHIFT - 2)
-
-/* Shift placing maximum resolved bit in a treebin at i as sign bit */
-#define leftshift_for_tree_index(i) \
-   ((i == NTREEBINS-1)? 0 : \
-    ((SIZE_T_BITSIZE-SIZE_T_ONE) - (((i) >> 1) + TREEBIN_SHIFT - 2)))
-
-/* The size of the smallest chunk held in bin with index i */
-#define minsize_for_tree_index(i) \
-   ((SIZE_T_ONE << (((i) >> 1) + TREEBIN_SHIFT)) |  \
-   (((size_t)((i) & SIZE_T_ONE)) << (((i) >> 1) + TREEBIN_SHIFT - 1)))
-
-
-/* ------------------------ Operations on bin maps ----------------------- */
-
-/* bit corresponding to given index */
-#define idx2bit(i)              ((binmap_t)(1) << (i))
-
-/* Mark/Clear bits with given index */
-#define mark_smallmap(M,i)      ((M)->smallmap |=  idx2bit(i))
-#define clear_smallmap(M,i)     ((M)->smallmap &= ~idx2bit(i))
-#define smallmap_is_marked(M,i) ((M)->smallmap &   idx2bit(i))
-
-#define mark_treemap(M,i)       ((M)->treemap  |=  idx2bit(i))
-#define clear_treemap(M,i)      ((M)->treemap  &= ~idx2bit(i))
-#define treemap_is_marked(M,i)  ((M)->treemap  &   idx2bit(i))
-
-/* isolate the least set bit of a bitmap */
-#define least_bit(x)         ((x) & -(x))
-
-/* mask with all bits to left of least bit of x on */
-#define left_bits(x)         ((x<<1) | -(x<<1))
-
-/* mask with all bits to left of or equal to least bit of x on */
-#define same_or_left_bits(x) ((x) | -(x))
-
-/* index corresponding to given bit. Use x86 asm if possible */
-
-#if defined(__GNUC__) && (defined(__i386__) || defined(__x86_64__))
-#define compute_bit2idx(X, I)\
-{\
-  unsigned int J;\
-  J = __builtin_ctz(X); \
-  I = (bindex_t)J;\
-}
-
-#elif defined (__INTEL_COMPILER)
-#define compute_bit2idx(X, I)\
-{\
-  unsigned int J;\
-  J = _bit_scan_forward (X); \
-  I = (bindex_t)J;\
-}
-
-#elif defined(_MSC_VER) && _MSC_VER>=1300
-#define compute_bit2idx(X, I)\
-{\
-  unsigned int J;\
-  _BitScanForward((DWORD *) &J, X);\
-  I = (bindex_t)J;\
-}
-
-#elif USE_BUILTIN_FFS
-#define compute_bit2idx(X, I) I = ffs(X)-1
-
-#else
-#define compute_bit2idx(X, I)\
-{\
-  unsigned int Y = X - 1;\
-  unsigned int K = Y >> (16-4) & 16;\
-  unsigned int N = K;        Y >>= K;\
-  N += K = Y >> (8-3) &  8;  Y >>= K;\
-  N += K = Y >> (4-2) &  4;  Y >>= K;\
-  N += K = Y >> (2-1) &  2;  Y >>= K;\
-  N += K = Y >> (1-0) &  1;  Y >>= K;\
-  I = (bindex_t)(N + Y);\
-}
-#endif /* GNUC */
-
-
-/* ----------------------- Runtime Check Support ------------------------- */
-
-/*
-  For security, the main invariant is that malloc/free/etc never
-  writes to a static address other than malloc_state, unless static
-  malloc_state itself has been corrupted, which cannot occur via
-  malloc (because of these checks). In essence this means that we
-  believe all pointers, sizes, maps etc held in malloc_state, but
-  check all of those linked or offsetted from other embedded data
-  structures.  These checks are interspersed with main code in a way
-  that tends to minimize their run-time cost.
-
-  When FOOTERS is defined, in addition to range checking, we also
-  verify footer fields of inuse chunks, which can be used guarantee
-  that the mstate controlling malloc/free is intact.  This is a
-  streamlined version of the approach described by William Robertson
-  et al in "Run-time Detection of Heap-based Overflows" LISA'03
-  http://www.usenix.org/events/lisa03/tech/robertson.html The footer
-  of an inuse chunk holds the xor of its mstate and a random seed,
-  that is checked upon calls to free() and realloc().  This is
-  (probabalistically) unguessable from outside the program, but can be
-  computed by any code successfully malloc'ing any chunk, so does not
-  itself provide protection against code that has already broken
-  security through some other means.  Unlike Robertson et al, we
-  always dynamically check addresses of all offset chunks (previous,
-  next, etc). This turns out to be cheaper than relying on hashes.
-*/
-
-#if !INSECURE
-/* Check if address a is at least as high as any from MORECORE or MMAP */
-#define ok_address(M, a) ((char*)(a) >= (M)->least_addr)
-/* Check if address of next chunk n is higher than base chunk p */
-#define ok_next(p, n)    ((char*)(p) < (char*)(n))
-/* Check if p has inuse status */
-#define ok_inuse(p)     is_inuse(p)
-/* Check if p has its pinuse bit on */
-#define ok_pinuse(p)     pinuse(p)
-
-#else /* !INSECURE */
-#define ok_address(M, a) (1)
-#define ok_next(b, n)    (1)
-#define ok_inuse(p)      (1)
-#define ok_pinuse(p)     (1)
-#endif /* !INSECURE */
-
-#if (FOOTERS && !INSECURE)
-/* Check if (alleged) mstate m has expected magic field */
-#define ok_magic(M)      ((M)->magic == mparams.magic)
-#else  /* (FOOTERS && !INSECURE) */
-#define ok_magic(M)      (1)
-#endif /* (FOOTERS && !INSECURE) */
-
-/* In gcc, use __builtin_expect to minimize impact of checks */
-#if !INSECURE
-#if defined(__GNUC__) && __GNUC__ >= 3
-#define RTCHECK(e)  __builtin_expect(e, 1)
-#else /* GNUC */
-#define RTCHECK(e)  (e)
-#endif /* GNUC */
-#else /* !INSECURE */
-#define RTCHECK(e)  (1)
-#endif /* !INSECURE */
-
-/* macros to set up inuse chunks with or without footers */
-
-#if !FOOTERS
-
-#define mark_inuse_foot(M,p,s)
-
-/* Macros for setting head/foot of non-mmapped chunks */
-
-/* Set cinuse bit and pinuse bit of next chunk */
-#define set_inuse(M,p,s)\
-  ((p)->head = (((p)->head & PINUSE_BIT)|s|CINUSE_BIT),\
-  ((mchunkptr)(((char*)(p)) + (s)))->head |= PINUSE_BIT)
-
-/* Set cinuse and pinuse of this chunk and pinuse of next chunk */
-#define set_inuse_and_pinuse(M,p,s)\
-  ((p)->head = (s|PINUSE_BIT|CINUSE_BIT),\
-  ((mchunkptr)(((char*)(p)) + (s)))->head |= PINUSE_BIT)
-
-/* Set size, cinuse and pinuse bit of this chunk */
-#define set_size_and_pinuse_of_inuse_chunk(M, p, s)\
-  ((p)->head = (s|PINUSE_BIT|CINUSE_BIT))
-
-#else /* FOOTERS */
-
-/* Set foot of inuse chunk to be xor of mstate and seed */
-#define mark_inuse_foot(M,p,s)\
-  (((mchunkptr)((char*)(p) + (s)))->prev_foot = ((size_t)(M) ^ mparams.magic))
-
-#define get_mstate_for(p)\
-  ((mstate)(((mchunkptr)((char*)(p) +\
-    (chunksize(p))))->prev_foot ^ mparams.magic))
-
-#define set_inuse(M,p,s)\
-  ((p)->head = (((p)->head & PINUSE_BIT)|s|CINUSE_BIT),\
-  (((mchunkptr)(((char*)(p)) + (s)))->head |= PINUSE_BIT), \
-  mark_inuse_foot(M,p,s))
-
-#define set_inuse_and_pinuse(M,p,s)\
-  ((p)->head = (s|PINUSE_BIT|CINUSE_BIT),\
-  (((mchunkptr)(((char*)(p)) + (s)))->head |= PINUSE_BIT),\
- mark_inuse_foot(M,p,s))
-
-#define set_size_and_pinuse_of_inuse_chunk(M, p, s)\
-  ((p)->head = (s|PINUSE_BIT|CINUSE_BIT),\
-  mark_inuse_foot(M, p, s))
-
-#endif /* !FOOTERS */
-
-/* ---------------------------- setting mparams -------------------------- */
-
-#if LOCK_AT_FORK
-static void pre_fork(void)         { ACQUIRE_LOCK(&(gm)->mutex); }
-static void post_fork_parent(void) { RELEASE_LOCK(&(gm)->mutex); }
-static void post_fork_child(void)  { INITIAL_LOCK(&(gm)->mutex); }
-#endif /* LOCK_AT_FORK */
-
-/* Initialize mparams */
-static int init_mparams(void) {
-  /* BEGIN android-added: move pthread_atfork outside of lock */
-  int first_run = 0;
-  /* END android-added */
-#ifdef NEED_GLOBAL_LOCK_INIT
-  if (malloc_global_mutex_status <= 0)
-    init_malloc_global_mutex();
-#endif
-
-  ACQUIRE_MALLOC_GLOBAL_LOCK();
-  if (mparams.magic == 0) {
-    size_t magic;
-    size_t psize;
-    size_t gsize;
-    /* BEGIN android-added: move pthread_atfork outside of lock */
-    first_run = 1;
-    /* END android-added */
-
-#ifndef WIN32
-    psize = malloc_getpagesize;
-    gsize = ((DEFAULT_GRANULARITY != 0)? DEFAULT_GRANULARITY : psize);
-#else /* WIN32 */
-    {
-      SYSTEM_INFO system_info;
-      GetSystemInfo(&system_info);
-      psize = system_info.dwPageSize;
-      gsize = ((DEFAULT_GRANULARITY != 0)?
-               DEFAULT_GRANULARITY : system_info.dwAllocationGranularity);
-    }
-#endif /* WIN32 */
-
-    /* Sanity-check configuration:
-       size_t must be unsigned and as wide as pointer type.
-       ints must be at least 4 bytes.
-       alignment must be at least 8.
-       Alignment, min chunk size, and page size must all be powers of 2.
-    */
-    if ((sizeof(size_t) != sizeof(char*)) ||
-        (MAX_SIZE_T < MIN_CHUNK_SIZE)  ||
-        (sizeof(int) < 4)  ||
-        (MALLOC_ALIGNMENT < (size_t)8U) ||
-        ((MALLOC_ALIGNMENT & (MALLOC_ALIGNMENT-SIZE_T_ONE)) != 0) ||
-        ((MCHUNK_SIZE      & (MCHUNK_SIZE-SIZE_T_ONE))      != 0) ||
-        ((gsize            & (gsize-SIZE_T_ONE))            != 0) ||
-        ((psize            & (psize-SIZE_T_ONE))            != 0))
-      ABORT;
-    mparams.granularity = gsize;
-    mparams.page_size = psize;
-    mparams.mmap_threshold = DEFAULT_MMAP_THRESHOLD;
-    mparams.trim_threshold = DEFAULT_TRIM_THRESHOLD;
-#if MORECORE_CONTIGUOUS
-    mparams.default_mflags = USE_LOCK_BIT|USE_MMAP_BIT;
-#else  /* MORECORE_CONTIGUOUS */
-    mparams.default_mflags = USE_LOCK_BIT|USE_MMAP_BIT|USE_NONCONTIGUOUS_BIT;
-#endif /* MORECORE_CONTIGUOUS */
-
-#if !ONLY_MSPACES
-    /* Set up lock for main malloc area */
-    gm->mflags = mparams.default_mflags;
-    (void)INITIAL_LOCK(&gm->mutex);
-#endif
-    /* BEGIN android-removed: move pthread_atfork outside of lock */
-#if 0 && LOCK_AT_FORK
-    pthread_atfork(&pre_fork, &post_fork_parent, &post_fork_child);
-#endif
-    /* END android-removed */
-
-    {
-#if USE_DEV_RANDOM
-      int fd;
-      unsigned char buf[sizeof(size_t)];
-      /* Try to use /dev/urandom, else fall back on using time */
-      if ((fd = open("/dev/urandom", O_RDONLY)) >= 0 &&
-          read(fd, buf, sizeof(buf)) == sizeof(buf)) {
-        magic = *((size_t *) buf);
-        close(fd);
-      }
-      else
-#endif /* USE_DEV_RANDOM */
-#ifdef WIN32
-      magic = (size_t)(GetTickCount() ^ (size_t)0x55555555U);
-#elif defined(LACKS_TIME_H)
-      magic = (size_t)&magic ^ (size_t)0x55555555U;
-#else
-      magic = (size_t)(time(0) ^ (size_t)0x55555555U);
-#endif
-      magic |= (size_t)8U;    /* ensure nonzero */
-      magic &= ~(size_t)7U;   /* improve chances of fault for bad values */
-      /* Until memory modes commonly available, use volatile-write */
-      (*(volatile size_t *)(&(mparams.magic))) = magic;
-    }
-  }
-
-  RELEASE_MALLOC_GLOBAL_LOCK();
-  /* BEGIN android-added: move pthread_atfork outside of lock */
-  if (first_run != 0) {
-#if LOCK_AT_FORK
-    pthread_atfork(&pre_fork, &post_fork_parent, &post_fork_child);
-#endif
-  }
-  /* END android-added */
-  return 1;
-}
-
-/* support for mallopt */
-static int change_mparam(int param_number, int value) {
-  size_t val;
-  ensure_initialization();
-  val = (value == -1)? MAX_SIZE_T : (size_t)value;
-  switch(param_number) {
-  case M_TRIM_THRESHOLD:
-    mparams.trim_threshold = val;
-    return 1;
-  case M_GRANULARITY:
-    if (val >= mparams.page_size && ((val & (val-1)) == 0)) {
-      mparams.granularity = val;
-      return 1;
-    }
-    else
-      return 0;
-  case M_MMAP_THRESHOLD:
-    mparams.mmap_threshold = val;
-    return 1;
-  default:
-    return 0;
-  }
-}
-
-#if DEBUG
-/* ------------------------- Debugging Support --------------------------- */
-
-/* Check properties of any chunk, whether free, inuse, mmapped etc  */
-static void do_check_any_chunk(mstate m, mchunkptr p) {
-  assert((is_aligned(chunk2mem(p))) || (p->head == FENCEPOST_HEAD));
-  assert(ok_address(m, p));
-}
-
-/* Check properties of top chunk */
-static void do_check_top_chunk(mstate m, mchunkptr p) {
-  msegmentptr sp = segment_holding(m, (char*)p);
-  size_t  sz = p->head & ~INUSE_BITS; /* third-lowest bit can be set! */
-  assert(sp != 0);
-  assert((is_aligned(chunk2mem(p))) || (p->head == FENCEPOST_HEAD));
-  assert(ok_address(m, p));
-  assert(sz == m->topsize);
-  assert(sz > 0);
-  assert(sz == ((sp->base + sp->size) - (char*)p) - TOP_FOOT_SIZE);
-  assert(pinuse(p));
-  assert(!pinuse(chunk_plus_offset(p, sz)));
-}
-
-/* Check properties of (inuse) mmapped chunks */
-static void do_check_mmapped_chunk(mstate m, mchunkptr p) {
-  size_t  sz = chunksize(p);
-  size_t len = (sz + (p->prev_foot) + MMAP_FOOT_PAD);
-  assert(is_mmapped(p));
-  assert(use_mmap(m));
-  assert((is_aligned(chunk2mem(p))) || (p->head == FENCEPOST_HEAD));
-  assert(ok_address(m, p));
-  assert(!is_small(sz));
-  assert((len & (mparams.page_size-SIZE_T_ONE)) == 0);
-  assert(chunk_plus_offset(p, sz)->head == FENCEPOST_HEAD);
-  assert(chunk_plus_offset(p, sz+SIZE_T_SIZE)->head == 0);
-}
-
-/* Check properties of inuse chunks */
-static void do_check_inuse_chunk(mstate m, mchunkptr p) {
-  do_check_any_chunk(m, p);
-  assert(is_inuse(p));
-  assert(next_pinuse(p));
-  /* If not pinuse and not mmapped, previous chunk has OK offset */
-  assert(is_mmapped(p) || pinuse(p) || next_chunk(prev_chunk(p)) == p);
-  if (is_mmapped(p))
-    do_check_mmapped_chunk(m, p);
-}
-
-/* Check properties of free chunks */
-static void do_check_free_chunk(mstate m, mchunkptr p) {
-  size_t sz = chunksize(p);
-  mchunkptr next = chunk_plus_offset(p, sz);
-  do_check_any_chunk(m, p);
-  assert(!is_inuse(p));
-  assert(!next_pinuse(p));
-  assert (!is_mmapped(p));
-  if (p != m->dv && p != m->top) {
-    if (sz >= MIN_CHUNK_SIZE) {
-      assert((sz & CHUNK_ALIGN_MASK) == 0);
-      assert(is_aligned(chunk2mem(p)));
-      assert(next->prev_foot == sz);
-      assert(pinuse(p));
-      assert (next == m->top || is_inuse(next));
-      assert(p->fd->bk == p);
-      assert(p->bk->fd == p);
-    }
-    else  /* markers are always of size SIZE_T_SIZE */
-      assert(sz == SIZE_T_SIZE);
-  }
-}
-
-/* Check properties of malloced chunks at the point they are malloced */
-static void do_check_malloced_chunk(mstate m, void* mem, size_t s) {
-  if (mem != 0) {
-    mchunkptr p = mem2chunk(mem);
-    size_t sz = p->head & ~INUSE_BITS;
-    do_check_inuse_chunk(m, p);
-    assert((sz & CHUNK_ALIGN_MASK) == 0);
-    assert(sz >= MIN_CHUNK_SIZE);
-    assert(sz >= s);
-    /* unless mmapped, size is less than MIN_CHUNK_SIZE more than request */
-    assert(is_mmapped(p) || sz < (s + MIN_CHUNK_SIZE));
-  }
-}
-
-/* Check a tree and its subtrees.  */
-static void do_check_tree(mstate m, tchunkptr t) {
-  tchunkptr head = 0;
-  tchunkptr u = t;
-  bindex_t tindex = t->index;
-  size_t tsize = chunksize(t);
-  bindex_t idx;
-  compute_tree_index(tsize, idx);
-  assert(tindex == idx);
-  assert(tsize >= MIN_LARGE_SIZE);
-  assert(tsize >= minsize_for_tree_index(idx));
-  assert((idx == NTREEBINS-1) || (tsize < minsize_for_tree_index((idx+1))));
-
-  do { /* traverse through chain of same-sized nodes */
-    do_check_any_chunk(m, ((mchunkptr)u));
-    assert(u->index == tindex);
-    assert(chunksize(u) == tsize);
-    assert(!is_inuse(u));
-    assert(!next_pinuse(u));
-    assert(u->fd->bk == u);
-    assert(u->bk->fd == u);
-    if (u->parent == 0) {
-      assert(u->child[0] == 0);
-      assert(u->child[1] == 0);
-    }
-    else {
-      assert(head == 0); /* only one node on chain has parent */
-      head = u;
-      assert(u->parent != u);
-      assert (u->parent->child[0] == u ||
-              u->parent->child[1] == u ||
-              *((tbinptr*)(u->parent)) == u);
-      if (u->child[0] != 0) {
-        assert(u->child[0]->parent == u);
-        assert(u->child[0] != u);
-        do_check_tree(m, u->child[0]);
-      }
-      if (u->child[1] != 0) {
-        assert(u->child[1]->parent == u);
-        assert(u->child[1] != u);
-        do_check_tree(m, u->child[1]);
-      }
-      if (u->child[0] != 0 && u->child[1] != 0) {
-        assert(chunksize(u->child[0]) < chunksize(u->child[1]));
-      }
-    }
-    u = u->fd;
-  } while (u != t);
-  assert(head != 0);
-}
-
-/*  Check all the chunks in a treebin.  */
-static void do_check_treebin(mstate m, bindex_t i) {
-  tbinptr* tb = treebin_at(m, i);
-  tchunkptr t = *tb;
-  int empty = (m->treemap & (1U << i)) == 0;
-  if (t == 0)
-    assert(empty);
-  if (!empty)
-    do_check_tree(m, t);
-}
-
-/*  Check all the chunks in a smallbin.  */
-static void do_check_smallbin(mstate m, bindex_t i) {
-  sbinptr b = smallbin_at(m, i);
-  mchunkptr p = b->bk;
-  unsigned int empty = (m->smallmap & (1U << i)) == 0;
-  if (p == b)
-    assert(empty);
-  if (!empty) {
-    for (; p != b; p = p->bk) {
-      size_t size = chunksize(p);
-      mchunkptr q;
-      /* each chunk claims to be free */
-      do_check_free_chunk(m, p);
-      /* chunk belongs in bin */
-      assert(small_index(size) == i);
-      assert(p->bk == b || chunksize(p->bk) == chunksize(p));
-      /* chunk is followed by an inuse chunk */
-      q = next_chunk(p);
-      if (q->head != FENCEPOST_HEAD)
-        do_check_inuse_chunk(m, q);
-    }
-  }
-}
-
-/* Find x in a bin. Used in other check functions. */
-static int bin_find(mstate m, mchunkptr x) {
-  size_t size = chunksize(x);
-  if (is_small(size)) {
-    bindex_t sidx = small_index(size);
-    sbinptr b = smallbin_at(m, sidx);
-    if (smallmap_is_marked(m, sidx)) {
-      mchunkptr p = b;
-      do {
-        if (p == x)
-          return 1;
-      } while ((p = p->fd) != b);
-    }
-  }
-  else {
-    bindex_t tidx;
-    compute_tree_index(size, tidx);
-    if (treemap_is_marked(m, tidx)) {
-      tchunkptr t = *treebin_at(m, tidx);
-      size_t sizebits = size << leftshift_for_tree_index(tidx);
-      while (t != 0 && chunksize(t) != size) {
-        t = t->child[(sizebits >> (SIZE_T_BITSIZE-SIZE_T_ONE)) & 1];
-        sizebits <<= 1;
-      }
-      if (t != 0) {
-        tchunkptr u = t;
-        do {
-          if (u == (tchunkptr)x)
-            return 1;
-        } while ((u = u->fd) != t);
-      }
-    }
-  }
-  return 0;
-}
-
-/* Traverse each chunk and check it; return total */
-static size_t traverse_and_check(mstate m) {
-  size_t sum = 0;
-  if (is_initialized(m)) {
-    msegmentptr s = &m->seg;
-    sum += m->topsize + TOP_FOOT_SIZE;
-    while (s != 0) {
-      mchunkptr q = align_as_chunk(s->base);
-      mchunkptr lastq = 0;
-      assert(pinuse(q));
-      while (segment_holds(s, q) &&
-             q != m->top && q->head != FENCEPOST_HEAD) {
-        sum += chunksize(q);
-        if (is_inuse(q)) {
-          assert(!bin_find(m, q));
-          do_check_inuse_chunk(m, q);
-        }
-        else {
-          assert(q == m->dv || bin_find(m, q));
-          assert(lastq == 0 || is_inuse(lastq)); /* Not 2 consecutive free */
-          do_check_free_chunk(m, q);
-        }
-        lastq = q;
-        q = next_chunk(q);
-      }
-      s = s->next;
-    }
-  }
-  return sum;
-}
-
-
-/* Check all properties of malloc_state. */
-static void do_check_malloc_state(mstate m) {
-  bindex_t i;
-  size_t total;
-  /* check bins */
-  for (i = 0; i < NSMALLBINS; ++i)
-    do_check_smallbin(m, i);
-  for (i = 0; i < NTREEBINS; ++i)
-    do_check_treebin(m, i);
-
-  if (m->dvsize != 0) { /* check dv chunk */
-    do_check_any_chunk(m, m->dv);
-    assert(m->dvsize == chunksize(m->dv));
-    assert(m->dvsize >= MIN_CHUNK_SIZE);
-    assert(bin_find(m, m->dv) == 0);
-  }
-
-  if (m->top != 0) {   /* check top chunk */
-    do_check_top_chunk(m, m->top);
-    /*assert(m->topsize == chunksize(m->top)); redundant */
-    assert(m->topsize > 0);
-    assert(bin_find(m, m->top) == 0);
-  }
-
-  total = traverse_and_check(m);
-  assert(total <= m->footprint);
-  assert(m->footprint <= m->max_footprint);
-}
-#endif /* DEBUG */
-
-/* ----------------------------- statistics ------------------------------ */
-
-#if !NO_MALLINFO
-static struct mallinfo internal_mallinfo(mstate m) {
-  struct mallinfo nm = { 0, 0, 0, 0, 0, 0, 0, 0, 0, 0 };
-  ensure_initialization();
-  if (!PREACTION(m)) {
-    check_malloc_state(m);
-    if (is_initialized(m)) {
-      size_t nfree = SIZE_T_ONE; /* top always free */
-      size_t mfree = m->topsize + TOP_FOOT_SIZE;
-      size_t sum = mfree;
-      msegmentptr s = &m->seg;
-      while (s != 0) {
-        mchunkptr q = align_as_chunk(s->base);
-        while (segment_holds(s, q) &&
-               q != m->top && q->head != FENCEPOST_HEAD) {
-          size_t sz = chunksize(q);
-          sum += sz;
-          if (!is_inuse(q)) {
-            mfree += sz;
-            ++nfree;
-          }
-          q = next_chunk(q);
-        }
-        s = s->next;
-      }
-
-      nm.arena    = sum;
-      nm.ordblks  = nfree;
-      nm.hblkhd   = m->footprint - sum;
-      /* BEGIN android-changed: usmblks set to footprint from max_footprint */
-      nm.usmblks  = m->footprint;
-      /* END android-changed */
-      nm.uordblks = m->footprint - mfree;
-      nm.fordblks = mfree;
-      nm.keepcost = m->topsize;
-    }
-
-    POSTACTION(m);
-  }
-  return nm;
-}
-#endif /* !NO_MALLINFO */
-
-#if !NO_MALLOC_STATS
-static void internal_malloc_stats(mstate m) {
-  ensure_initialization();
-  if (!PREACTION(m)) {
-    size_t maxfp = 0;
-    size_t fp = 0;
-    size_t used = 0;
-    check_malloc_state(m);
-    if (is_initialized(m)) {
-      msegmentptr s = &m->seg;
-      maxfp = m->max_footprint;
-      fp = m->footprint;
-      used = fp - (m->topsize + TOP_FOOT_SIZE);
-
-      while (s != 0) {
-        mchunkptr q = align_as_chunk(s->base);
-        while (segment_holds(s, q) &&
-               q != m->top && q->head != FENCEPOST_HEAD) {
-          if (!is_inuse(q))
-            used -= chunksize(q);
-          q = next_chunk(q);
-        }
-        s = s->next;
-      }
-    }
-    POSTACTION(m); /* drop lock */
-    fprintf(stderr, "max system bytes = %10lu\n", (unsigned long)(maxfp));
-    fprintf(stderr, "system bytes     = %10lu\n", (unsigned long)(fp));
-    fprintf(stderr, "in use bytes     = %10lu\n", (unsigned long)(used));
-  }
-}
-#endif /* NO_MALLOC_STATS */
-
-/* ----------------------- Operations on smallbins ----------------------- */
-
-/*
-  Various forms of linking and unlinking are defined as macros.  Even
-  the ones for trees, which are very long but have very short typical
-  paths.  This is ugly but reduces reliance on inlining support of
-  compilers.
-*/
-
-/* Link a free chunk into a smallbin  */
-#define insert_small_chunk(M, P, S) {\
-  bindex_t I  = small_index(S);\
-  mchunkptr B = smallbin_at(M, I);\
-  mchunkptr F = B;\
-  assert(S >= MIN_CHUNK_SIZE);\
-  if (!smallmap_is_marked(M, I))\
-    mark_smallmap(M, I);\
-  else if (RTCHECK(ok_address(M, B->fd)))\
-    F = B->fd;\
-  else {\
-    CORRUPTION_ERROR_ACTION(M);\
-  }\
-  B->fd = P;\
-  F->bk = P;\
-  P->fd = F;\
-  P->bk = B;\
-}
-
-/* Unlink a chunk from a smallbin  */
-#define unlink_small_chunk(M, P, S) {\
-  mchunkptr F = P->fd;\
-  mchunkptr B = P->bk;\
-  bindex_t I = small_index(S);\
-  assert(P != B);\
-  assert(P != F);\
-  assert(chunksize(P) == small_index2size(I));\
-  if (RTCHECK(F == smallbin_at(M,I) || (ok_address(M, F) && F->bk == P))) { \
-    if (B == F) {\
-      clear_smallmap(M, I);\
-    }\
-    else if (RTCHECK(B == smallbin_at(M,I) ||\
-                     (ok_address(M, B) && B->fd == P))) {\
-      F->bk = B;\
-      B->fd = F;\
-    }\
-    else {\
-      CORRUPTION_ERROR_ACTION(M);\
-    }\
-  }\
-  else {\
-    CORRUPTION_ERROR_ACTION(M);\
-  }\
-}
-
-/* Unlink the first chunk from a smallbin */
-#define unlink_first_small_chunk(M, B, P, I) {\
-  mchunkptr F = P->fd;\
-  assert(P != B);\
-  assert(P != F);\
-  assert(chunksize(P) == small_index2size(I));\
-  if (B == F) {\
-    clear_smallmap(M, I);\
-  }\
-  else if (RTCHECK(ok_address(M, F) && F->bk == P)) {\
-    F->bk = B;\
-    B->fd = F;\
-  }\
-  else {\
-    CORRUPTION_ERROR_ACTION(M);\
-  }\
-}
-
-/* Replace dv node, binning the old one */
-/* Used only when dvsize known to be small */
-#define replace_dv(M, P, S) {\
-  size_t DVS = M->dvsize;\
-  assert(is_small(DVS));\
-  if (DVS != 0) {\
-    mchunkptr DV = M->dv;\
-    insert_small_chunk(M, DV, DVS);\
-  }\
-  M->dvsize = S;\
-  M->dv = P;\
-}
-
-/* ------------------------- Operations on trees ------------------------- */
-
-/* Insert chunk into tree */
-#define insert_large_chunk(M, X, S) {\
-  tbinptr* H;\
-  bindex_t I;\
-  compute_tree_index(S, I);\
-  H = treebin_at(M, I);\
-  X->index = I;\
-  X->child[0] = X->child[1] = 0;\
-  if (!treemap_is_marked(M, I)) {\
-    mark_treemap(M, I);\
-    *H = X;\
-    X->parent = (tchunkptr)H;\
-    X->fd = X->bk = X;\
-  }\
-  else {\
-    tchunkptr T = *H;\
-    size_t K = S << leftshift_for_tree_index(I);\
-    for (;;) {\
-      if (chunksize(T) != S) {\
-        tchunkptr* C = &(T->child[(K >> (SIZE_T_BITSIZE-SIZE_T_ONE)) & 1]);\
-        K <<= 1;\
-        if (*C != 0)\
-          T = *C;\
-        else if (RTCHECK(ok_address(M, C))) {\
-          *C = X;\
-          X->parent = T;\
-          X->fd = X->bk = X;\
-          break;\
-        }\
-        else {\
-          CORRUPTION_ERROR_ACTION(M);\
-          break;\
-        }\
-      }\
-      else {\
-        tchunkptr F = T->fd;\
-        if (RTCHECK(ok_address(M, T) && ok_address(M, F))) {\
-          T->fd = F->bk = X;\
-          X->fd = F;\
-          X->bk = T;\
-          X->parent = 0;\
-          break;\
-        }\
-        else {\
-          CORRUPTION_ERROR_ACTION(M);\
-          break;\
-        }\
-      }\
-    }\
-  }\
-}
-
-/*
-  Unlink steps:
-
-  1. If x is a chained node, unlink it from its same-sized fd/bk links
-     and choose its bk node as its replacement.
-  2. If x was the last node of its size, but not a leaf node, it must
-     be replaced with a leaf node (not merely one with an open left or
-     right), to make sure that lefts and rights of descendents
-     correspond properly to bit masks.  We use the rightmost descendent
-     of x.  We could use any other leaf, but this is easy to locate and
-     tends to counteract removal of leftmosts elsewhere, and so keeps
-     paths shorter than minimally guaranteed.  This doesn't loop much
-     because on average a node in a tree is near the bottom.
-  3. If x is the base of a chain (i.e., has parent links) relink
-     x's parent and children to x's replacement (or null if none).
-*/
-
-#define unlink_large_chunk(M, X) {\
-  tchunkptr XP = X->parent;\
-  tchunkptr R;\
-  if (X->bk != X) {\
-    tchunkptr F = X->fd;\
-    R = X->bk;\
-    if (RTCHECK(ok_address(M, F) && F->bk == X && R->fd == X)) {\
-      F->bk = R;\
-      R->fd = F;\
-    }\
-    else {\
-      CORRUPTION_ERROR_ACTION(M);\
-    }\
-  }\
-  else {\
-    tchunkptr* RP;\
-    if (((R = *(RP = &(X->child[1]))) != 0) ||\
-        ((R = *(RP = &(X->child[0]))) != 0)) {\
-      tchunkptr* CP;\
-      while ((*(CP = &(R->child[1])) != 0) ||\
-             (*(CP = &(R->child[0])) != 0)) {\
-        R = *(RP = CP);\
-      }\
-      if (RTCHECK(ok_address(M, RP)))\
-        *RP = 0;\
-      else {\
-        CORRUPTION_ERROR_ACTION(M);\
-      }\
-    }\
-  }\
-  if (XP != 0) {\
-    tbinptr* H = treebin_at(M, X->index);\
-    if (X == *H) {\
-      if ((*H = R) == 0) \
-        clear_treemap(M, X->index);\
-    }\
-    else if (RTCHECK(ok_address(M, XP))) {\
-      if (XP->child[0] == X) \
-        XP->child[0] = R;\
-      else \
-        XP->child[1] = R;\
-    }\
-    else\
-      CORRUPTION_ERROR_ACTION(M);\
-    if (R != 0) {\
-      if (RTCHECK(ok_address(M, R))) {\
-        tchunkptr C0, C1;\
-        R->parent = XP;\
-        if ((C0 = X->child[0]) != 0) {\
-          if (RTCHECK(ok_address(M, C0))) {\
-            R->child[0] = C0;\
-            C0->parent = R;\
-          }\
-          else\
-            CORRUPTION_ERROR_ACTION(M);\
-        }\
-        if ((C1 = X->child[1]) != 0) {\
-          if (RTCHECK(ok_address(M, C1))) {\
-            R->child[1] = C1;\
-            C1->parent = R;\
-          }\
-          else\
-            CORRUPTION_ERROR_ACTION(M);\
-        }\
-      }\
-      else\
-        CORRUPTION_ERROR_ACTION(M);\
-    }\
-  }\
-}
-
-/* Relays to large vs small bin operations */
-
-#define insert_chunk(M, P, S)\
-  if (is_small(S)) insert_small_chunk(M, P, S)\
-  else { tchunkptr TP = (tchunkptr)(P); insert_large_chunk(M, TP, S); }
-
-#define unlink_chunk(M, P, S)\
-  if (is_small(S)) unlink_small_chunk(M, P, S)\
-  else { tchunkptr TP = (tchunkptr)(P); unlink_large_chunk(M, TP); }
-
-
-/* Relays to internal calls to malloc/free from realloc, memalign etc */
-
-#if ONLY_MSPACES
-#define internal_malloc(m, b) mspace_malloc(m, b)
-#define internal_free(m, mem) mspace_free(m,mem);
-#else /* ONLY_MSPACES */
-#if MSPACES
-#define internal_malloc(m, b)\
-  ((m == gm)? dlmalloc(b) : mspace_malloc(m, b))
-#define internal_free(m, mem)\
-   if (m == gm) dlfree(mem); else mspace_free(m,mem);
-#else /* MSPACES */
-#define internal_malloc(m, b) dlmalloc(b)
-#define internal_free(m, mem) dlfree(mem)
-#endif /* MSPACES */
-#endif /* ONLY_MSPACES */
-
-/* -----------------------  Direct-mmapping chunks ----------------------- */
-
-/*
-  Directly mmapped chunks are set up with an offset to the start of
-  the mmapped region stored in the prev_foot field of the chunk. This
-  allows reconstruction of the required argument to MUNMAP when freed,
-  and also allows adjustment of the returned chunk to meet alignment
-  requirements (especially in memalign).
-*/
-
-/* Malloc using mmap */
-static void* mmap_alloc(mstate m, size_t nb) {
-  size_t mmsize = mmap_align(nb + SIX_SIZE_T_SIZES + CHUNK_ALIGN_MASK);
-  if (m->footprint_limit != 0) {
-    size_t fp = m->footprint + mmsize;
-    if (fp <= m->footprint || fp > m->footprint_limit)
-      return 0;
-  }
-  if (mmsize > nb) {     /* Check for wrap around 0 */
-    char* mm = (char*)(CALL_DIRECT_MMAP(mmsize));
-    if (mm != CMFAIL) {
-      size_t offset = align_offset(chunk2mem(mm));
-      size_t psize = mmsize - offset - MMAP_FOOT_PAD;
-      mchunkptr p = (mchunkptr)(mm + offset);
-      p->prev_foot = offset;
-      p->head = psize;
-      mark_inuse_foot(m, p, psize);
-      chunk_plus_offset(p, psize)->head = FENCEPOST_HEAD;
-      chunk_plus_offset(p, psize+SIZE_T_SIZE)->head = 0;
-
-      if (m->least_addr == 0 || mm < m->least_addr)
-        m->least_addr = mm;
-      if ((m->footprint += mmsize) > m->max_footprint)
-        m->max_footprint = m->footprint;
-      assert(is_aligned(chunk2mem(p)));
-      check_mmapped_chunk(m, p);
-      return chunk2mem(p);
-    }
-  }
-  return 0;
-}
-
-/* Realloc using mmap */
-static mchunkptr mmap_resize(mstate m, mchunkptr oldp, size_t nb, int flags) {
-  size_t oldsize = chunksize(oldp);
-  (void)flags; /* placate people compiling -Wunused */
-  if (is_small(nb)) /* Can't shrink mmap regions below small size */
-    return 0;
-  /* Keep old chunk if big enough but not too big */
-  if (oldsize >= nb + SIZE_T_SIZE &&
-      (oldsize - nb) <= (mparams.granularity << 1))
-    return oldp;
-  else {
-    size_t offset = oldp->prev_foot;
-    size_t oldmmsize = oldsize + offset + MMAP_FOOT_PAD;
-    size_t newmmsize = mmap_align(nb + SIX_SIZE_T_SIZES + CHUNK_ALIGN_MASK);
-    char* cp = (char*)CALL_MREMAP((char*)oldp - offset,
-                                  oldmmsize, newmmsize, flags);
-    if (cp != CMFAIL) {
-      mchunkptr newp = (mchunkptr)(cp + offset);
-      size_t psize = newmmsize - offset - MMAP_FOOT_PAD;
-      newp->head = psize;
-      mark_inuse_foot(m, newp, psize);
-      chunk_plus_offset(newp, psize)->head = FENCEPOST_HEAD;
-      chunk_plus_offset(newp, psize+SIZE_T_SIZE)->head = 0;
-
-      if (cp < m->least_addr)
-        m->least_addr = cp;
-      if ((m->footprint += newmmsize - oldmmsize) > m->max_footprint)
-        m->max_footprint = m->footprint;
-      check_mmapped_chunk(m, newp);
-      return newp;
-    }
-  }
-  return 0;
-}
-
-
-/* -------------------------- mspace management -------------------------- */
-
-/* Initialize top chunk and its size */
-static void init_top(mstate m, mchunkptr p, size_t psize) {
-  /* Ensure alignment */
-  size_t offset = align_offset(chunk2mem(p));
-  p = (mchunkptr)((char*)p + offset);
-  psize -= offset;
-
-  m->top = p;
-  m->topsize = psize;
-  p->head = psize | PINUSE_BIT;
-  /* set size of fake trailing chunk holding overhead space only once */
-  chunk_plus_offset(p, psize)->head = TOP_FOOT_SIZE;
-  m->trim_check = mparams.trim_threshold; /* reset on each update */
-}
-
-/* Initialize bins for a new mstate that is otherwise zeroed out */
-static void init_bins(mstate m) {
-  /* Establish circular links for smallbins */
-  bindex_t i;
-  for (i = 0; i < NSMALLBINS; ++i) {
-    sbinptr bin = smallbin_at(m,i);
-    bin->fd = bin->bk = bin;
-  }
-}
-
-#if PROCEED_ON_ERROR
-
-/* default corruption action */
-static void reset_on_error(mstate m) {
-  int i;
-  ++malloc_corruption_error_count;
-  /* Reinitialize fields to forget about all memory */
-  m->smallmap = m->treemap = 0;
-  m->dvsize = m->topsize = 0;
-  m->seg.base = 0;
-  m->seg.size = 0;
-  m->seg.next = 0;
-  m->top = m->dv = 0;
-  for (i = 0; i < NTREEBINS; ++i)
-    *treebin_at(m, i) = 0;
-  init_bins(m);
-}
-#endif /* PROCEED_ON_ERROR */
-
-/* Allocate chunk and prepend remainder with chunk in successor base. */
-static void* prepend_alloc(mstate m, char* newbase, char* oldbase,
-                           size_t nb) {
-  mchunkptr p = align_as_chunk(newbase);
-  mchunkptr oldfirst = align_as_chunk(oldbase);
-  size_t psize = (char*)oldfirst - (char*)p;
-  mchunkptr q = chunk_plus_offset(p, nb);
-  size_t qsize = psize - nb;
-  set_size_and_pinuse_of_inuse_chunk(m, p, nb);
-
-  assert((char*)oldfirst > (char*)q);
-  assert(pinuse(oldfirst));
-  assert(qsize >= MIN_CHUNK_SIZE);
-
-  /* consolidate remainder with first chunk of old base */
-  if (oldfirst == m->top) {
-    size_t tsize = m->topsize += qsize;
-    m->top = q;
-    q->head = tsize | PINUSE_BIT;
-    check_top_chunk(m, q);
-  }
-  else if (oldfirst == m->dv) {
-    size_t dsize = m->dvsize += qsize;
-    m->dv = q;
-    set_size_and_pinuse_of_free_chunk(q, dsize);
-  }
-  else {
-    if (!is_inuse(oldfirst)) {
-      size_t nsize = chunksize(oldfirst);
-      unlink_chunk(m, oldfirst, nsize);
-      oldfirst = chunk_plus_offset(oldfirst, nsize);
-      qsize += nsize;
-    }
-    set_free_with_pinuse(q, qsize, oldfirst);
-    insert_chunk(m, q, qsize);
-    check_free_chunk(m, q);
-  }
-
-  check_malloced_chunk(m, chunk2mem(p), nb);
-  return chunk2mem(p);
-}
-
-/* Add a segment to hold a new noncontiguous region */
-static void add_segment(mstate m, char* tbase, size_t tsize, flag_t mmapped) {
-  /* Determine locations and sizes of segment, fenceposts, old top */
-  char* old_top = (char*)m->top;
-  msegmentptr oldsp = segment_holding(m, old_top);
-  char* old_end = oldsp->base + oldsp->size;
-  size_t ssize = pad_request(sizeof(struct malloc_segment));
-  char* rawsp = old_end - (ssize + FOUR_SIZE_T_SIZES + CHUNK_ALIGN_MASK);
-  size_t offset = align_offset(chunk2mem(rawsp));
-  char* asp = rawsp + offset;
-  char* csp = (asp < (old_top + MIN_CHUNK_SIZE))? old_top : asp;
-  mchunkptr sp = (mchunkptr)csp;
-  msegmentptr ss = (msegmentptr)(chunk2mem(sp));
-  mchunkptr tnext = chunk_plus_offset(sp, ssize);
-  mchunkptr p = tnext;
-  int nfences = 0;
-
-  /* reset top to new space */
-  init_top(m, (mchunkptr)tbase, tsize - TOP_FOOT_SIZE);
-
-  /* Set up segment record */
-  assert(is_aligned(ss));
-  set_size_and_pinuse_of_inuse_chunk(m, sp, ssize);
-  *ss = m->seg; /* Push current record */
-  m->seg.base = tbase;
-  m->seg.size = tsize;
-  m->seg.sflags = mmapped;
-  m->seg.next = ss;
-
-  /* Insert trailing fenceposts */
-  for (;;) {
-    mchunkptr nextp = chunk_plus_offset(p, SIZE_T_SIZE);
-    p->head = FENCEPOST_HEAD;
-    ++nfences;
-    if ((char*)(&(nextp->head)) < old_end)
-      p = nextp;
-    else
-      break;
-  }
-  assert(nfences >= 2);
-
-  /* Insert the rest of old top into a bin as an ordinary free chunk */
-  if (csp != old_top) {
-    mchunkptr q = (mchunkptr)old_top;
-    size_t psize = csp - old_top;
-    mchunkptr tn = chunk_plus_offset(q, psize);
-    set_free_with_pinuse(q, psize, tn);
-    insert_chunk(m, q, psize);
-  }
-
-  check_top_chunk(m, m->top);
-}
-
-/* -------------------------- System allocation -------------------------- */
-
-/* Get memory from system using MORECORE or MMAP */
-static void* sys_alloc(mstate m, size_t nb) {
-  char* tbase = CMFAIL;
-  size_t tsize = 0;
-  flag_t mmap_flag = 0;
-  size_t asize; /* allocation size */
-
-  ensure_initialization();
-
-  /* Directly map large chunks, but only if already initialized */
-  if (use_mmap(m) && nb >= mparams.mmap_threshold && m->topsize != 0) {
-    void* mem = mmap_alloc(m, nb);
-    if (mem != 0)
-      return mem;
-  }
-
-  asize = granularity_align(nb + SYS_ALLOC_PADDING);
-  if (asize <= nb) {
-    /* BEGIN android-added: set errno */
-    MALLOC_FAILURE_ACTION;
-    /* END android-added */
-    return 0; /* wraparound */
-  }
-  if (m->footprint_limit != 0) {
-    size_t fp = m->footprint + asize;
-    if (fp <= m->footprint || fp > m->footprint_limit) {
-      /* BEGIN android-added: set errno */
-      MALLOC_FAILURE_ACTION;
-      /* END android-added */
-      return 0;
-    }
-  }
-
-  /*
-    Try getting memory in any of three ways (in most-preferred to
-    least-preferred order):
-    1. A call to MORECORE that can normally contiguously extend memory.
-       (disabled if not MORECORE_CONTIGUOUS or not HAVE_MORECORE or
-       or main space is mmapped or a previous contiguous call failed)
-    2. A call to MMAP new space (disabled if not HAVE_MMAP).
-       Note that under the default settings, if MORECORE is unable to
-       fulfill a request, and HAVE_MMAP is true, then mmap is
-       used as a noncontiguous system allocator. This is a useful backup
-       strategy for systems with holes in address spaces -- in this case
-       sbrk cannot contiguously expand the heap, but mmap may be able to
-       find space.
-    3. A call to MORECORE that cannot usually contiguously extend memory.
-       (disabled if not HAVE_MORECORE)
-
-   In all cases, we need to request enough bytes from system to ensure
-   we can malloc nb bytes upon success, so pad with enough space for
-   top_foot, plus alignment-pad to make sure we don't lose bytes if
-   not on boundary, and round this up to a granularity unit.
-  */
-
-  if (MORECORE_CONTIGUOUS && !use_noncontiguous(m)) {
-    char* br = CMFAIL;
-    size_t ssize = asize; /* sbrk call size */
-    msegmentptr ss = (m->top == 0)? 0 : segment_holding(m, (char*)m->top);
-    ACQUIRE_MALLOC_GLOBAL_LOCK();
-
-    if (ss == 0) {  /* First time through or recovery */
-      char* base = (char*)CALL_MORECORE(0);
-      if (base != CMFAIL) {
-        size_t fp;
-        /* Adjust to end on a page boundary */
-        if (!is_page_aligned(base))
-          ssize += (page_align((size_t)base) - (size_t)base);
-        fp = m->footprint + ssize; /* recheck limits */
-        if (ssize > nb && ssize < HALF_MAX_SIZE_T &&
-            (m->footprint_limit == 0 ||
-             (fp > m->footprint && fp <= m->footprint_limit)) &&
-            (br = (char*)(CALL_MORECORE(ssize))) == base) {
-          tbase = base;
-          tsize = ssize;
-        }
-      }
-    }
-    else {
-      /* Subtract out existing available top space from MORECORE request. */
-      ssize = granularity_align(nb - m->topsize + SYS_ALLOC_PADDING);
-      /* Use mem here only if it did continuously extend old space */
-      if (ssize < HALF_MAX_SIZE_T &&
-          (br = (char*)(CALL_MORECORE(ssize))) == ss->base+ss->size) {
-        tbase = br;
-        tsize = ssize;
-      }
-    }
-
-    if (tbase == CMFAIL) {    /* Cope with partial failure */
-      if (br != CMFAIL) {    /* Try to use/extend the space we did get */
-        if (ssize < HALF_MAX_SIZE_T &&
-            ssize < nb + SYS_ALLOC_PADDING) {
-          size_t esize = granularity_align(nb + SYS_ALLOC_PADDING - ssize);
-          if (esize < HALF_MAX_SIZE_T) {
-            char* end = (char*)CALL_MORECORE(esize);
-            if (end != CMFAIL)
-              ssize += esize;
-            else {            /* Can't use; try to release */
-              (void) CALL_MORECORE(-ssize);
-              br = CMFAIL;
-            }
-          }
-        }
-      }
-      if (br != CMFAIL) {    /* Use the space we did get */
-        tbase = br;
-        tsize = ssize;
-      }
-      else
-        disable_contiguous(m); /* Don't try contiguous path in the future */
-    }
-
-    RELEASE_MALLOC_GLOBAL_LOCK();
-  }
-
-  if (HAVE_MMAP && tbase == CMFAIL) {  /* Try MMAP */
-    char* mp = (char*)(CALL_MMAP(asize));
-    if (mp != CMFAIL) {
-      tbase = mp;
-      tsize = asize;
-      mmap_flag = USE_MMAP_BIT;
-    }
-  }
-
-  if (HAVE_MORECORE && tbase == CMFAIL) { /* Try noncontiguous MORECORE */
-    if (asize < HALF_MAX_SIZE_T) {
-      char* br = CMFAIL;
-      char* end = CMFAIL;
-      ACQUIRE_MALLOC_GLOBAL_LOCK();
-      br = (char*)(CALL_MORECORE(asize));
-      end = (char*)(CALL_MORECORE(0));
-      RELEASE_MALLOC_GLOBAL_LOCK();
-      if (br != CMFAIL && end != CMFAIL && br < end) {
-        size_t ssize = end - br;
-        if (ssize > nb + TOP_FOOT_SIZE) {
-          tbase = br;
-          tsize = ssize;
-        }
-      }
-    }
-  }
-
-  if (tbase != CMFAIL) {
-
-    if ((m->footprint += tsize) > m->max_footprint)
-      m->max_footprint = m->footprint;
-
-    if (!is_initialized(m)) { /* first-time initialization */
-      if (m->least_addr == 0 || tbase < m->least_addr)
-        m->least_addr = tbase;
-      m->seg.base = tbase;
-      m->seg.size = tsize;
-      m->seg.sflags = mmap_flag;
-      m->magic = mparams.magic;
-      m->release_checks = MAX_RELEASE_CHECK_RATE;
-      init_bins(m);
-#if !ONLY_MSPACES
-      if (is_global(m))
-        init_top(m, (mchunkptr)tbase, tsize - TOP_FOOT_SIZE);
-      else
-#endif
-      {
-        /* Offset top by embedded malloc_state */
-        mchunkptr mn = next_chunk(mem2chunk(m));
-        init_top(m, mn, (size_t)((tbase + tsize) - (char*)mn) -TOP_FOOT_SIZE);
-      }
-    }
-
-    else {
-      /* Try to merge with an existing segment */
-      msegmentptr sp = &m->seg;
-      /* Only consider most recent segment if traversal suppressed */
-      while (sp != 0 && tbase != sp->base + sp->size)
-        sp = (NO_SEGMENT_TRAVERSAL) ? 0 : sp->next;
-      if (sp != 0 &&
-          !is_extern_segment(sp) &&
-          (sp->sflags & USE_MMAP_BIT) == mmap_flag &&
-          segment_holds(sp, m->top)) { /* append */
-        sp->size += tsize;
-        init_top(m, m->top, m->topsize + tsize);
-      }
-      else {
-        if (tbase < m->least_addr)
-          m->least_addr = tbase;
-        sp = &m->seg;
-        while (sp != 0 && sp->base != tbase + tsize)
-          sp = (NO_SEGMENT_TRAVERSAL) ? 0 : sp->next;
-        if (sp != 0 &&
-            !is_extern_segment(sp) &&
-            (sp->sflags & USE_MMAP_BIT) == mmap_flag) {
-          char* oldbase = sp->base;
-          sp->base = tbase;
-          sp->size += tsize;
-          return prepend_alloc(m, tbase, oldbase, nb);
-        }
-        else
-          add_segment(m, tbase, tsize, mmap_flag);
-      }
-    }
-
-    if (nb < m->topsize) { /* Allocate from new or extended top space */
-      size_t rsize = m->topsize -= nb;
-      mchunkptr p = m->top;
-      mchunkptr r = m->top = chunk_plus_offset(p, nb);
-      r->head = rsize | PINUSE_BIT;
-      set_size_and_pinuse_of_inuse_chunk(m, p, nb);
-      check_top_chunk(m, m->top);
-      check_malloced_chunk(m, chunk2mem(p), nb);
-      return chunk2mem(p);
-    }
-  }
-
-  MALLOC_FAILURE_ACTION;
-  return 0;
-}
-
-/* -----------------------  system deallocation -------------------------- */
-
-/* Unmap and unlink any mmapped segments that don't contain used chunks */
-static size_t release_unused_segments(mstate m) {
-  size_t released = 0;
-  int nsegs = 0;
-  msegmentptr pred = &m->seg;
-  msegmentptr sp = pred->next;
-  while (sp != 0) {
-    char* base = sp->base;
-    size_t size = sp->size;
-    msegmentptr next = sp->next;
-    ++nsegs;
-    if (is_mmapped_segment(sp) && !is_extern_segment(sp)) {
-      mchunkptr p = align_as_chunk(base);
-      size_t psize = chunksize(p);
-      /* Can unmap if first chunk holds entire segment and not pinned */
-      if (!is_inuse(p) && (char*)p + psize >= base + size - TOP_FOOT_SIZE) {
-        tchunkptr tp = (tchunkptr)p;
-        assert(segment_holds(sp, (char*)sp));
-        if (p == m->dv) {
-          m->dv = 0;
-          m->dvsize = 0;
-        }
-        else {
-          unlink_large_chunk(m, tp);
-        }
-        if (CALL_MUNMAP(base, size) == 0) {
-          released += size;
-          m->footprint -= size;
-          /* unlink obsoleted record */
-          sp = pred;
-          sp->next = next;
-        }
-        else { /* back out if cannot unmap */
-          insert_large_chunk(m, tp, psize);
-        }
-      }
-    }
-    if (NO_SEGMENT_TRAVERSAL) /* scan only first segment */
-      break;
-    pred = sp;
-    sp = next;
-  }
-  /* Reset check counter */
-  m->release_checks = (((size_t) nsegs > (size_t) MAX_RELEASE_CHECK_RATE)?
-                       (size_t) nsegs : (size_t) MAX_RELEASE_CHECK_RATE);
-  return released;
-}
-
-static int sys_trim(mstate m, size_t pad) {
-  size_t released = 0;
-  ensure_initialization();
-  if (pad < MAX_REQUEST && is_initialized(m)) {
-    pad += TOP_FOOT_SIZE; /* ensure enough room for segment overhead */
-
-    if (m->topsize > pad) {
-      /* Shrink top space in granularity-size units, keeping at least one */
-      size_t unit = mparams.granularity;
-      size_t extra = ((m->topsize - pad + (unit - SIZE_T_ONE)) / unit -
-                      SIZE_T_ONE) * unit;
-      msegmentptr sp = segment_holding(m, (char*)m->top);
-
-      if (!is_extern_segment(sp)) {
-        if (is_mmapped_segment(sp)) {
-          if (HAVE_MMAP &&
-              sp->size >= extra &&
-              !has_segment_link(m, sp)) { /* can't shrink if pinned */
-            size_t newsize = sp->size - extra;
-            (void)newsize; /* placate people compiling -Wunused-variable */
-            /* Prefer mremap, fall back to munmap */
-            if ((CALL_MREMAP(sp->base, sp->size, newsize, 0) != MFAIL) ||
-                (CALL_MUNMAP(sp->base + newsize, extra) == 0)) {
-              released = extra;
-            }
-          }
-        }
-        else if (HAVE_MORECORE) {
-          if (extra >= HALF_MAX_SIZE_T) /* Avoid wrapping negative */
-            extra = (HALF_MAX_SIZE_T) + SIZE_T_ONE - unit;
-          ACQUIRE_MALLOC_GLOBAL_LOCK();
-          {
-            /* Make sure end of memory is where we last set it. */
-            char* old_br = (char*)(CALL_MORECORE(0));
-            if (old_br == sp->base + sp->size) {
-              char* rel_br = (char*)(CALL_MORECORE(-extra));
-              char* new_br = (char*)(CALL_MORECORE(0));
-              if (rel_br != CMFAIL && new_br < old_br)
-                released = old_br - new_br;
-            }
-          }
-          RELEASE_MALLOC_GLOBAL_LOCK();
-        }
-      }
-
-      if (released != 0) {
-        sp->size -= released;
-        m->footprint -= released;
-        init_top(m, m->top, m->topsize - released);
-        check_top_chunk(m, m->top);
-      }
-    }
-
-    /* Unmap any unused mmapped segments */
-    if (HAVE_MMAP)
-      released += release_unused_segments(m);
-
-    /* On failure, disable autotrim to avoid repeated failed future calls */
-    if (released == 0 && m->topsize > m->trim_check)
-      m->trim_check = MAX_SIZE_T;
-  }
-
-  return (released != 0)? 1 : 0;
-}
-
-/* Consolidate and bin a chunk. Differs from exported versions
-   of free mainly in that the chunk need not be marked as inuse.
-*/
-static void dispose_chunk(mstate m, mchunkptr p, size_t psize) {
-  mchunkptr next = chunk_plus_offset(p, psize);
-  if (!pinuse(p)) {
-    mchunkptr prev;
-    size_t prevsize = p->prev_foot;
-    if (is_mmapped(p)) {
-      psize += prevsize + MMAP_FOOT_PAD;
-      if (CALL_MUNMAP((char*)p - prevsize, psize) == 0)
-        m->footprint -= psize;
-      return;
-    }
-    prev = chunk_minus_offset(p, prevsize);
-    psize += prevsize;
-    p = prev;
-    if (RTCHECK(ok_address(m, prev))) { /* consolidate backward */
-      if (p != m->dv) {
-        unlink_chunk(m, p, prevsize);
-      }
-      else if ((next->head & INUSE_BITS) == INUSE_BITS) {
-        m->dvsize = psize;
-        set_free_with_pinuse(p, psize, next);
-        return;
-      }
-    }
-    else {
-      CORRUPTION_ERROR_ACTION(m);
-      return;
-    }
-  }
-  if (RTCHECK(ok_address(m, next))) {
-    if (!cinuse(next)) {  /* consolidate forward */
-      if (next == m->top) {
-        size_t tsize = m->topsize += psize;
-        m->top = p;
-        p->head = tsize | PINUSE_BIT;
-        if (p == m->dv) {
-          m->dv = 0;
-          m->dvsize = 0;
-        }
-        return;
-      }
-      else if (next == m->dv) {
-        size_t dsize = m->dvsize += psize;
-        m->dv = p;
-        set_size_and_pinuse_of_free_chunk(p, dsize);
-        return;
-      }
-      else {
-        size_t nsize = chunksize(next);
-        psize += nsize;
-        unlink_chunk(m, next, nsize);
-        set_size_and_pinuse_of_free_chunk(p, psize);
-        if (p == m->dv) {
-          m->dvsize = psize;
-          return;
-        }
-      }
-    }
-    else {
-      set_free_with_pinuse(p, psize, next);
-    }
-    insert_chunk(m, p, psize);
-  }
-  else {
-    CORRUPTION_ERROR_ACTION(m);
-  }
-}
-
-/* ---------------------------- malloc --------------------------- */
-
-/* allocate a large request from the best fitting chunk in a treebin */
-static void* tmalloc_large(mstate m, size_t nb) {
-  tchunkptr v = 0;
-  size_t rsize = -nb; /* Unsigned negation */
-  tchunkptr t;
-  bindex_t idx;
-  compute_tree_index(nb, idx);
-  if ((t = *treebin_at(m, idx)) != 0) {
-    /* Traverse tree for this bin looking for node with size == nb */
-    size_t sizebits = nb << leftshift_for_tree_index(idx);
-    tchunkptr rst = 0;  /* The deepest untaken right subtree */
-    for (;;) {
-      tchunkptr rt;
-      size_t trem = chunksize(t) - nb;
-      if (trem < rsize) {
-        v = t;
-        if ((rsize = trem) == 0)
-          break;
-      }
-      rt = t->child[1];
-      t = t->child[(sizebits >> (SIZE_T_BITSIZE-SIZE_T_ONE)) & 1];
-      if (rt != 0 && rt != t)
-        rst = rt;
-      if (t == 0) {
-        t = rst; /* set t to least subtree holding sizes > nb */
-        break;
-      }
-      sizebits <<= 1;
-    }
-  }
-  if (t == 0 && v == 0) { /* set t to root of next non-empty treebin */
-    binmap_t leftbits = left_bits(idx2bit(idx)) & m->treemap;
-    if (leftbits != 0) {
-      bindex_t i;
-      binmap_t leastbit = least_bit(leftbits);
-      compute_bit2idx(leastbit, i);
-      t = *treebin_at(m, i);
-    }
-  }
-
-  while (t != 0) { /* find smallest of tree or subtree */
-    size_t trem = chunksize(t) - nb;
-    if (trem < rsize) {
-      rsize = trem;
-      v = t;
-    }
-    t = leftmost_child(t);
-  }
-
-  /*  If dv is a better fit, return 0 so malloc will use it */
-  if (v != 0 && rsize < (size_t)(m->dvsize - nb)) {
-    if (RTCHECK(ok_address(m, v))) { /* split */
-      mchunkptr r = chunk_plus_offset(v, nb);
-      assert(chunksize(v) == rsize + nb);
-      if (RTCHECK(ok_next(v, r))) {
-        unlink_large_chunk(m, v);
-        if (rsize < MIN_CHUNK_SIZE)
-          set_inuse_and_pinuse(m, v, (rsize + nb));
-        else {
-          set_size_and_pinuse_of_inuse_chunk(m, v, nb);
-          set_size_and_pinuse_of_free_chunk(r, rsize);
-          insert_chunk(m, r, rsize);
-        }
-        return chunk2mem(v);
-      }
-    }
-    CORRUPTION_ERROR_ACTION(m);
-  }
-  return 0;
-}
-
-/* allocate a small request from the best fitting chunk in a treebin */
-static void* tmalloc_small(mstate m, size_t nb) {
-  tchunkptr t, v;
-  size_t rsize;
-  bindex_t i;
-  binmap_t leastbit = least_bit(m->treemap);
-  compute_bit2idx(leastbit, i);
-  v = t = *treebin_at(m, i);
-  rsize = chunksize(t) - nb;
-
-  while ((t = leftmost_child(t)) != 0) {
-    size_t trem = chunksize(t) - nb;
-    if (trem < rsize) {
-      rsize = trem;
-      v = t;
-    }
-  }
-
-  if (RTCHECK(ok_address(m, v))) {
-    mchunkptr r = chunk_plus_offset(v, nb);
-    assert(chunksize(v) == rsize + nb);
-    if (RTCHECK(ok_next(v, r))) {
-      unlink_large_chunk(m, v);
-      if (rsize < MIN_CHUNK_SIZE)
-        set_inuse_and_pinuse(m, v, (rsize + nb));
-      else {
-        set_size_and_pinuse_of_inuse_chunk(m, v, nb);
-        set_size_and_pinuse_of_free_chunk(r, rsize);
-        replace_dv(m, r, rsize);
-      }
-      return chunk2mem(v);
-    }
-  }
-
-  CORRUPTION_ERROR_ACTION(m);
-  return 0;
-}
-
-#if !ONLY_MSPACES
-
-void* dlmalloc(size_t bytes) {
-  /*
-     Basic algorithm:
-     If a small request (< 256 bytes minus per-chunk overhead):
-       1. If one exists, use a remainderless chunk in associated smallbin.
-          (Remainderless means that there are too few excess bytes to
-          represent as a chunk.)
-       2. If it is big enough, use the dv chunk, which is normally the
-          chunk adjacent to the one used for the most recent small request.
-       3. If one exists, split the smallest available chunk in a bin,
-          saving remainder in dv.
-       4. If it is big enough, use the top chunk.
-       5. If available, get memory from system and use it
-     Otherwise, for a large request:
-       1. Find the smallest available binned chunk that fits, and use it
-          if it is better fitting than dv chunk, splitting if necessary.
-       2. If better fitting than any binned chunk, use the dv chunk.
-       3. If it is big enough, use the top chunk.
-       4. If request size >= mmap threshold, try to directly mmap this chunk.
-       5. If available, get memory from system and use it
-
-     The ugly goto's here ensure that postaction occurs along all paths.
-  */
-
-#if USE_LOCKS
-  ensure_initialization(); /* initialize in sys_alloc if not using locks */
-#endif
-
-  if (!PREACTION(gm)) {
-    void* mem;
-    size_t nb;
-    if (bytes <= MAX_SMALL_REQUEST) {
-      bindex_t idx;
-      binmap_t smallbits;
-      nb = (bytes < MIN_REQUEST)? MIN_CHUNK_SIZE : pad_request(bytes);
-      idx = small_index(nb);
-      smallbits = gm->smallmap >> idx;
-
-      if ((smallbits & 0x3U) != 0) { /* Remainderless fit to a smallbin. */
-        mchunkptr b, p;
-        idx += ~smallbits & 1;       /* Uses next bin if idx empty */
-        b = smallbin_at(gm, idx);
-        p = b->fd;
-        assert(chunksize(p) == small_index2size(idx));
-        unlink_first_small_chunk(gm, b, p, idx);
-        set_inuse_and_pinuse(gm, p, small_index2size(idx));
-        mem = chunk2mem(p);
-        check_malloced_chunk(gm, mem, nb);
-        goto postaction;
-      }
-
-      else if (nb > gm->dvsize) {
-        if (smallbits != 0) { /* Use chunk in next nonempty smallbin */
-          mchunkptr b, p, r;
-          size_t rsize;
-          bindex_t i;
-          binmap_t leftbits = (smallbits << idx) & left_bits(idx2bit(idx));
-          binmap_t leastbit = least_bit(leftbits);
-          compute_bit2idx(leastbit, i);
-          b = smallbin_at(gm, i);
-          p = b->fd;
-          assert(chunksize(p) == small_index2size(i));
-          unlink_first_small_chunk(gm, b, p, i);
-          rsize = small_index2size(i) - nb;
-          /* Fit here cannot be remainderless if 4byte sizes */
-          if (SIZE_T_SIZE != 4 && rsize < MIN_CHUNK_SIZE)
-            set_inuse_and_pinuse(gm, p, small_index2size(i));
-          else {
-            set_size_and_pinuse_of_inuse_chunk(gm, p, nb);
-            r = chunk_plus_offset(p, nb);
-            set_size_and_pinuse_of_free_chunk(r, rsize);
-            replace_dv(gm, r, rsize);
-          }
-          mem = chunk2mem(p);
-          check_malloced_chunk(gm, mem, nb);
-          goto postaction;
-        }
-
-        else if (gm->treemap != 0 && (mem = tmalloc_small(gm, nb)) != 0) {
-          check_malloced_chunk(gm, mem, nb);
-          goto postaction;
-        }
-      }
-    }
-    else if (bytes >= MAX_REQUEST)
-      nb = MAX_SIZE_T; /* Too big to allocate. Force failure (in sys alloc) */
-    else {
-      nb = pad_request(bytes);
-      if (gm->treemap != 0 && (mem = tmalloc_large(gm, nb)) != 0) {
-        check_malloced_chunk(gm, mem, nb);
-        goto postaction;
-      }
-    }
-
-    if (nb <= gm->dvsize) {
-      size_t rsize = gm->dvsize - nb;
-      mchunkptr p = gm->dv;
-      if (rsize >= MIN_CHUNK_SIZE) { /* split dv */
-        mchunkptr r = gm->dv = chunk_plus_offset(p, nb);
-        gm->dvsize = rsize;
-        set_size_and_pinuse_of_free_chunk(r, rsize);
-        set_size_and_pinuse_of_inuse_chunk(gm, p, nb);
-      }
-      else { /* exhaust dv */
-        size_t dvs = gm->dvsize;
-        gm->dvsize = 0;
-        gm->dv = 0;
-        set_inuse_and_pinuse(gm, p, dvs);
-      }
-      mem = chunk2mem(p);
-      check_malloced_chunk(gm, mem, nb);
-      goto postaction;
-    }
-
-    else if (nb < gm->topsize) { /* Split top */
-      size_t rsize = gm->topsize -= nb;
-      mchunkptr p = gm->top;
-      mchunkptr r = gm->top = chunk_plus_offset(p, nb);
-      r->head = rsize | PINUSE_BIT;
-      set_size_and_pinuse_of_inuse_chunk(gm, p, nb);
-      mem = chunk2mem(p);
-      check_top_chunk(gm, gm->top);
-      check_malloced_chunk(gm, mem, nb);
-      goto postaction;
-    }
-
-    mem = sys_alloc(gm, nb);
-
-  postaction:
-    POSTACTION(gm);
-    return mem;
-  }
-
-  return 0;
-}
-
-/* ---------------------------- free --------------------------- */
-
-void dlfree(void* mem) {
-  /*
-     Consolidate freed chunks with preceeding or succeeding bordering
-     free chunks, if they exist, and then place in a bin.  Intermixed
-     with special cases for top, dv, mmapped chunks, and usage errors.
-  */
-
-  if (mem != 0) {
-    mchunkptr p  = mem2chunk(mem);
-#if FOOTERS
-    mstate fm = get_mstate_for(p);
-    if (!ok_magic(fm)) {
-      USAGE_ERROR_ACTION(fm, p);
-      return;
-    }
-#else /* FOOTERS */
-#define fm gm
-#endif /* FOOTERS */
-    if (!PREACTION(fm)) {
-      check_inuse_chunk(fm, p);
-      if (RTCHECK(ok_address(fm, p) && ok_inuse(p))) {
-        size_t psize = chunksize(p);
-        mchunkptr next = chunk_plus_offset(p, psize);
-        if (!pinuse(p)) {
-          size_t prevsize = p->prev_foot;
-          if (is_mmapped(p)) {
-            psize += prevsize + MMAP_FOOT_PAD;
-            if (CALL_MUNMAP((char*)p - prevsize, psize) == 0)
-              fm->footprint -= psize;
-            goto postaction;
-          }
-          else {
-            mchunkptr prev = chunk_minus_offset(p, prevsize);
-            psize += prevsize;
-            p = prev;
-            if (RTCHECK(ok_address(fm, prev))) { /* consolidate backward */
-              if (p != fm->dv) {
-                unlink_chunk(fm, p, prevsize);
-              }
-              else if ((next->head & INUSE_BITS) == INUSE_BITS) {
-                fm->dvsize = psize;
-                set_free_with_pinuse(p, psize, next);
-                goto postaction;
-              }
-            }
-            else
-              goto erroraction;
-          }
-        }
-
-        if (RTCHECK(ok_next(p, next) && ok_pinuse(next))) {
-          if (!cinuse(next)) {  /* consolidate forward */
-            if (next == fm->top) {
-              size_t tsize = fm->topsize += psize;
-              fm->top = p;
-              p->head = tsize | PINUSE_BIT;
-              if (p == fm->dv) {
-                fm->dv = 0;
-                fm->dvsize = 0;
-              }
-              if (should_trim(fm, tsize))
-                sys_trim(fm, 0);
-              goto postaction;
-            }
-            else if (next == fm->dv) {
-              size_t dsize = fm->dvsize += psize;
-              fm->dv = p;
-              set_size_and_pinuse_of_free_chunk(p, dsize);
-              goto postaction;
-            }
-            else {
-              size_t nsize = chunksize(next);
-              psize += nsize;
-              unlink_chunk(fm, next, nsize);
-              set_size_and_pinuse_of_free_chunk(p, psize);
-              if (p == fm->dv) {
-                fm->dvsize = psize;
-                goto postaction;
-              }
-            }
-          }
-          else
-            set_free_with_pinuse(p, psize, next);
-
-          if (is_small(psize)) {
-            insert_small_chunk(fm, p, psize);
-            check_free_chunk(fm, p);
-          }
-          else {
-            tchunkptr tp = (tchunkptr)p;
-            insert_large_chunk(fm, tp, psize);
-            check_free_chunk(fm, p);
-            if (--fm->release_checks == 0)
-              release_unused_segments(fm);
-          }
-          goto postaction;
-        }
-      }
-    erroraction:
-      USAGE_ERROR_ACTION(fm, p);
-    postaction:
-      POSTACTION(fm);
-    }
-  }
-#if !FOOTERS
-#undef fm
-#endif /* FOOTERS */
-}
-
-void* dlcalloc(size_t n_elements, size_t elem_size) {
-  void* mem;
-  size_t req = 0;
-  if (n_elements != 0) {
-    req = n_elements * elem_size;
-    if (((n_elements | elem_size) & ~(size_t)0xffff) &&
-        (req / n_elements != elem_size))
-      req = MAX_SIZE_T; /* force downstream failure on overflow */
-  }
-  mem = dlmalloc(req);
-  if (mem != 0 && calloc_must_clear(mem2chunk(mem)))
-    memset(mem, 0, req);
-  return mem;
-}
-
-#endif /* !ONLY_MSPACES */
-
-/* ------------ Internal support for realloc, memalign, etc -------------- */
-
-/* Try to realloc; only in-place unless can_move true */
-static mchunkptr try_realloc_chunk(mstate m, mchunkptr p, size_t nb,
-                                   int can_move) {
-  mchunkptr newp = 0;
-  size_t oldsize = chunksize(p);
-  mchunkptr next = chunk_plus_offset(p, oldsize);
-  if (RTCHECK(ok_address(m, p) && ok_inuse(p) &&
-              ok_next(p, next) && ok_pinuse(next))) {
-    if (is_mmapped(p)) {
-      newp = mmap_resize(m, p, nb, can_move);
-    }
-    else if (oldsize >= nb) {             /* already big enough */
-      size_t rsize = oldsize - nb;
-      if (rsize >= MIN_CHUNK_SIZE) {      /* split off remainder */
-        mchunkptr r = chunk_plus_offset(p, nb);
-        set_inuse(m, p, nb);
-        set_inuse(m, r, rsize);
-        dispose_chunk(m, r, rsize);
-      }
-      newp = p;
-    }
-    else if (next == m->top) {  /* extend into top */
-      if (oldsize + m->topsize > nb) {
-        size_t newsize = oldsize + m->topsize;
-        size_t newtopsize = newsize - nb;
-        mchunkptr newtop = chunk_plus_offset(p, nb);
-        set_inuse(m, p, nb);
-        newtop->head = newtopsize |PINUSE_BIT;
-        m->top = newtop;
-        m->topsize = newtopsize;
-        newp = p;
-      }
-    }
-    else if (next == m->dv) { /* extend into dv */
-      size_t dvs = m->dvsize;
-      if (oldsize + dvs >= nb) {
-        size_t dsize = oldsize + dvs - nb;
-        if (dsize >= MIN_CHUNK_SIZE) {
-          mchunkptr r = chunk_plus_offset(p, nb);
-          mchunkptr n = chunk_plus_offset(r, dsize);
-          set_inuse(m, p, nb);
-          set_size_and_pinuse_of_free_chunk(r, dsize);
-          clear_pinuse(n);
-          m->dvsize = dsize;
-          m->dv = r;
-        }
-        else { /* exhaust dv */
-          size_t newsize = oldsize + dvs;
-          set_inuse(m, p, newsize);
-          m->dvsize = 0;
-          m->dv = 0;
-        }
-        newp = p;
-      }
-    }
-    else if (!cinuse(next)) { /* extend into next free chunk */
-      size_t nextsize = chunksize(next);
-      if (oldsize + nextsize >= nb) {
-        size_t rsize = oldsize + nextsize - nb;
-        unlink_chunk(m, next, nextsize);
-        if (rsize < MIN_CHUNK_SIZE) {
-          size_t newsize = oldsize + nextsize;
-          set_inuse(m, p, newsize);
-        }
-        else {
-          mchunkptr r = chunk_plus_offset(p, nb);
-          set_inuse(m, p, nb);
-          set_inuse(m, r, rsize);
-          dispose_chunk(m, r, rsize);
-        }
-        newp = p;
-      }
-    }
-  }
-  else {
-    USAGE_ERROR_ACTION(m, chunk2mem(p));
-  }
-  return newp;
-}
-
-static void* internal_memalign(mstate m, size_t alignment, size_t bytes) {
-  void* mem = 0;
-  if (alignment <  MIN_CHUNK_SIZE) /* must be at least a minimum chunk size */
-    alignment = MIN_CHUNK_SIZE;
-  if ((alignment & (alignment-SIZE_T_ONE)) != 0) {/* Ensure a power of 2 */
-    size_t a = MALLOC_ALIGNMENT << 1;
-    while (a < alignment) a <<= 1;
-    alignment = a;
-  }
-  if (bytes >= MAX_REQUEST - alignment) {
-    if (m != 0)  { /* Test isn't needed but avoids compiler warning */
-      MALLOC_FAILURE_ACTION;
-    }
-  }
-  else {
-    size_t nb = request2size(bytes);
-    size_t req = nb + alignment + MIN_CHUNK_SIZE - CHUNK_OVERHEAD;
-    mem = internal_malloc(m, req);
-    if (mem != 0) {
-      mchunkptr p = mem2chunk(mem);
-      if (PREACTION(m))
-        return 0;
-      if ((((size_t)(mem)) & (alignment - 1)) != 0) { /* misaligned */
-        /*
-          Find an aligned spot inside chunk.  Since we need to give
-          back leading space in a chunk of at least MIN_CHUNK_SIZE, if
-          the first calculation places us at a spot with less than
-          MIN_CHUNK_SIZE leader, we can move to the next aligned spot.
-          We've allocated enough total room so that this is always
-          possible.
-        */
-        char* br = (char*)mem2chunk((size_t)(((size_t)((char*)mem + alignment -
-                                                       SIZE_T_ONE)) &
-                                             -alignment));
-        char* pos = ((size_t)(br - (char*)(p)) >= MIN_CHUNK_SIZE)?
-          br : br+alignment;
-        mchunkptr newp = (mchunkptr)pos;
-        size_t leadsize = pos - (char*)(p);
-        size_t newsize = chunksize(p) - leadsize;
-
-        if (is_mmapped(p)) { /* For mmapped chunks, just adjust offset */
-          newp->prev_foot = p->prev_foot + leadsize;
-          newp->head = newsize;
-        }
-        else { /* Otherwise, give back leader, use the rest */
-          set_inuse(m, newp, newsize);
-          set_inuse(m, p, leadsize);
-          dispose_chunk(m, p, leadsize);
-        }
-        p = newp;
-      }
-
-      /* Give back spare room at the end */
-      if (!is_mmapped(p)) {
-        size_t size = chunksize(p);
-        if (size > nb + MIN_CHUNK_SIZE) {
-          size_t remainder_size = size - nb;
-          mchunkptr remainder = chunk_plus_offset(p, nb);
-          set_inuse(m, p, nb);
-          set_inuse(m, remainder, remainder_size);
-          dispose_chunk(m, remainder, remainder_size);
-        }
-      }
-
-      mem = chunk2mem(p);
-      assert (chunksize(p) >= nb);
-      assert(((size_t)mem & (alignment - 1)) == 0);
-      check_inuse_chunk(m, p);
-      POSTACTION(m);
-    }
-  }
-  return mem;
-}
-
-/*
-  Common support for independent_X routines, handling
-    all of the combinations that can result.
-  The opts arg has:
-    bit 0 set if all elements are same size (using sizes[0])
-    bit 1 set if elements should be zeroed
-*/
-static void** ialloc(mstate m,
-                     size_t n_elements,
-                     size_t* sizes,
-                     int opts,
-                     void* chunks[]) {
-
-  size_t    element_size;   /* chunksize of each element, if all same */
-  size_t    contents_size;  /* total size of elements */
-  size_t    array_size;     /* request size of pointer array */
-  void*     mem;            /* malloced aggregate space */
-  mchunkptr p;              /* corresponding chunk */
-  size_t    remainder_size; /* remaining bytes while splitting */
-  void**    marray;         /* either "chunks" or malloced ptr array */
-  mchunkptr array_chunk;    /* chunk for malloced ptr array */
-  flag_t    was_enabled;    /* to disable mmap */
-  size_t    size;
-  size_t    i;
-
-  ensure_initialization();
-  /* compute array length, if needed */
-  if (chunks != 0) {
-    if (n_elements == 0)
-      return chunks; /* nothing to do */
-    marray = chunks;
-    array_size = 0;
-  }
-  else {
-    /* if empty req, must still return chunk representing empty array */
-    if (n_elements == 0)
-      return (void**)internal_malloc(m, 0);
-    marray = 0;
-    array_size = request2size(n_elements * (sizeof(void*)));
-  }
-
-  /* compute total element size */
-  if (opts & 0x1) { /* all-same-size */
-    element_size = request2size(*sizes);
-    contents_size = n_elements * element_size;
-  }
-  else { /* add up all the sizes */
-    element_size = 0;
-    contents_size = 0;
-    for (i = 0; i != n_elements; ++i)
-      contents_size += request2size(sizes[i]);
-  }
-
-  size = contents_size + array_size;
-
-  /*
-     Allocate the aggregate chunk.  First disable direct-mmapping so
-     malloc won't use it, since we would not be able to later
-     free/realloc space internal to a segregated mmap region.
-  */
-  was_enabled = use_mmap(m);
-  disable_mmap(m);
-  mem = internal_malloc(m, size - CHUNK_OVERHEAD);
-  if (was_enabled)
-    enable_mmap(m);
-  if (mem == 0)
-    return 0;
-
-  if (PREACTION(m)) return 0;
-  p = mem2chunk(mem);
-  remainder_size = chunksize(p);
-
-  assert(!is_mmapped(p));
-
-  if (opts & 0x2) {       /* optionally clear the elements */
-    memset((size_t*)mem, 0, remainder_size - SIZE_T_SIZE - array_size);
-  }
-
-  /* If not provided, allocate the pointer array as final part of chunk */
-  if (marray == 0) {
-    size_t  array_chunk_size;
-    array_chunk = chunk_plus_offset(p, contents_size);
-    array_chunk_size = remainder_size - contents_size;
-    marray = (void**) (chunk2mem(array_chunk));
-    set_size_and_pinuse_of_inuse_chunk(m, array_chunk, array_chunk_size);
-    remainder_size = contents_size;
-  }
-
-  /* split out elements */
-  for (i = 0; ; ++i) {
-    marray[i] = chunk2mem(p);
-    if (i != n_elements-1) {
-      if (element_size != 0)
-        size = element_size;
-      else
-        size = request2size(sizes[i]);
-      remainder_size -= size;
-      set_size_and_pinuse_of_inuse_chunk(m, p, size);
-      p = chunk_plus_offset(p, size);
-    }
-    else { /* the final element absorbs any overallocation slop */
-      set_size_and_pinuse_of_inuse_chunk(m, p, remainder_size);
-      break;
-    }
-  }
-
-#if DEBUG
-  if (marray != chunks) {
-    /* final element must have exactly exhausted chunk */
-    if (element_size != 0) {
-      assert(remainder_size == element_size);
-    }
-    else {
-      assert(remainder_size == request2size(sizes[i]));
-    }
-    check_inuse_chunk(m, mem2chunk(marray));
-  }
-  for (i = 0; i != n_elements; ++i)
-    check_inuse_chunk(m, mem2chunk(marray[i]));
-
-#endif /* DEBUG */
-
-  POSTACTION(m);
-  return marray;
-}
-
-/* Try to free all pointers in the given array.
-   Note: this could be made faster, by delaying consolidation,
-   at the price of disabling some user integrity checks, We
-   still optimize some consolidations by combining adjacent
-   chunks before freeing, which will occur often if allocated
-   with ialloc or the array is sorted.
-*/
-static size_t internal_bulk_free(mstate m, void* array[], size_t nelem) {
-  size_t unfreed = 0;
-  if (!PREACTION(m)) {
-    void** a;
-    void** fence = &(array[nelem]);
-    for (a = array; a != fence; ++a) {
-      void* mem = *a;
-      if (mem != 0) {
-        mchunkptr p = mem2chunk(mem);
-        size_t psize = chunksize(p);
-#if FOOTERS
-        if (get_mstate_for(p) != m) {
-          ++unfreed;
-          continue;
-        }
-#endif
-        check_inuse_chunk(m, p);
-        *a = 0;
-        if (RTCHECK(ok_address(m, p) && ok_inuse(p))) {
-          void ** b = a + 1; /* try to merge with next chunk */
-          mchunkptr next = next_chunk(p);
-          if (b != fence && *b == chunk2mem(next)) {
-            size_t newsize = chunksize(next) + psize;
-            set_inuse(m, p, newsize);
-            *b = chunk2mem(p);
-          }
-          else
-            dispose_chunk(m, p, psize);
-        }
-        else {
-          CORRUPTION_ERROR_ACTION(m);
-          break;
-        }
-      }
-    }
-    if (should_trim(m, m->topsize))
-      sys_trim(m, 0);
-    POSTACTION(m);
-  }
-  return unfreed;
-}
-
-/* Traversal */
-#if MALLOC_INSPECT_ALL
-static void internal_inspect_all(mstate m,
-                                 void(*handler)(void *start,
-                                                void *end,
-                                                size_t used_bytes,
-                                                void* callback_arg),
-                                 void* arg) {
-  if (is_initialized(m)) {
-    mchunkptr top = m->top;
-    msegmentptr s;
-    for (s = &m->seg; s != 0; s = s->next) {
-      mchunkptr q = align_as_chunk(s->base);
-      while (segment_holds(s, q) && q->head != FENCEPOST_HEAD) {
-        mchunkptr next = next_chunk(q);
-        size_t sz = chunksize(q);
-        size_t used;
-        void* start;
-        if (is_inuse(q)) {
-          used = sz - CHUNK_OVERHEAD; /* must not be mmapped */
-          start = chunk2mem(q);
-        }
-        else {
-          used = 0;
-          if (is_small(sz)) {     /* offset by possible bookkeeping */
-            start = (void*)((char*)q + sizeof(struct malloc_chunk));
-          }
-          else {
-            start = (void*)((char*)q + sizeof(struct malloc_tree_chunk));
-          }
-        }
-        if (start < (void*)next)  /* skip if all space is bookkeeping */
-          handler(start, next, used, arg);
-        if (q == top)
-          break;
-        q = next;
-      }
-    }
-  }
-}
-#endif /* MALLOC_INSPECT_ALL */
-
-/* ------------------ Exported realloc, memalign, etc -------------------- */
-
-#if !ONLY_MSPACES
-
-void* dlrealloc(void* oldmem, size_t bytes) {
-  void* mem = 0;
-  if (oldmem == 0) {
-    mem = dlmalloc(bytes);
-  }
-  else if (bytes >= MAX_REQUEST) {
-    MALLOC_FAILURE_ACTION;
-  }
-#ifdef REALLOC_ZERO_BYTES_FREES
-  else if (bytes == 0) {
-    dlfree(oldmem);
-  }
-#endif /* REALLOC_ZERO_BYTES_FREES */
-  else {
-    size_t nb = request2size(bytes);
-    mchunkptr oldp = mem2chunk(oldmem);
-#if ! FOOTERS
-    mstate m = gm;
-#else /* FOOTERS */
-    mstate m = get_mstate_for(oldp);
-    if (!ok_magic(m)) {
-      USAGE_ERROR_ACTION(m, oldmem);
-      return 0;
-    }
-#endif /* FOOTERS */
-    if (!PREACTION(m)) {
-      mchunkptr newp = try_realloc_chunk(m, oldp, nb, 1);
-      POSTACTION(m);
-      if (newp != 0) {
-        check_inuse_chunk(m, newp);
-        mem = chunk2mem(newp);
-      }
-      else {
-        mem = internal_malloc(m, bytes);
-        if (mem != 0) {
-          size_t oc = chunksize(oldp) - overhead_for(oldp);
-          memcpy(mem, oldmem, (oc < bytes)? oc : bytes);
-          internal_free(m, oldmem);
-        }
-      }
-    }
-  }
-  return mem;
-}
-
-void* dlrealloc_in_place(void* oldmem, size_t bytes) {
-  void* mem = 0;
-  if (oldmem != 0) {
-    if (bytes >= MAX_REQUEST) {
-      MALLOC_FAILURE_ACTION;
-    }
-    else {
-      size_t nb = request2size(bytes);
-      mchunkptr oldp = mem2chunk(oldmem);
-#if ! FOOTERS
-      mstate m = gm;
-#else /* FOOTERS */
-      mstate m = get_mstate_for(oldp);
-      if (!ok_magic(m)) {
-        USAGE_ERROR_ACTION(m, oldmem);
-        return 0;
-      }
-#endif /* FOOTERS */
-      if (!PREACTION(m)) {
-        mchunkptr newp = try_realloc_chunk(m, oldp, nb, 0);
-        POSTACTION(m);
-        if (newp == oldp) {
-          check_inuse_chunk(m, newp);
-          mem = oldmem;
-        }
-      }
-    }
-  }
-  return mem;
-}
-
-void* dlmemalign(size_t alignment, size_t bytes) {
-  if (alignment <= MALLOC_ALIGNMENT) {
-    return dlmalloc(bytes);
-  }
-  return internal_memalign(gm, alignment, bytes);
-}
-
-int dlposix_memalign(void** pp, size_t alignment, size_t bytes) {
-  void* mem = 0;
-  if (alignment == MALLOC_ALIGNMENT)
-    mem = dlmalloc(bytes);
-  else {
-    size_t d = alignment / sizeof(void*);
-    size_t r = alignment % sizeof(void*);
-    if (r != 0 || d == 0 || (d & (d-SIZE_T_ONE)) != 0)
-      return EINVAL;
-    else if (bytes <= MAX_REQUEST - alignment) {
-      if (alignment <  MIN_CHUNK_SIZE)
-        alignment = MIN_CHUNK_SIZE;
-      mem = internal_memalign(gm, alignment, bytes);
-    }
-  }
-  if (mem == 0)
-    return ENOMEM;
-  else {
-    *pp = mem;
-    return 0;
-  }
-}
-
-void* dlvalloc(size_t bytes) {
-  size_t pagesz;
-  ensure_initialization();
-  pagesz = mparams.page_size;
-  return dlmemalign(pagesz, bytes);
-}
-
-/* BEGIN android-changed: added overflow check */
-void* dlpvalloc(size_t bytes) {
-  size_t pagesz;
-  size_t size;
-  ensure_initialization();
-  pagesz = mparams.page_size;
-  size = (bytes + pagesz - SIZE_T_ONE) & ~(pagesz - SIZE_T_ONE);
-  if (size < bytes) {
-    return NULL;
-  }
-  return dlmemalign(pagesz, size);
-}
-/* END android-change */
-
-void** dlindependent_calloc(size_t n_elements, size_t elem_size,
-                            void* chunks[]) {
-  size_t sz = elem_size; /* serves as 1-element array */
-  return ialloc(gm, n_elements, &sz, 3, chunks);
-}
-
-void** dlindependent_comalloc(size_t n_elements, size_t sizes[],
-                              void* chunks[]) {
-  return ialloc(gm, n_elements, sizes, 0, chunks);
-}
-
-size_t dlbulk_free(void* array[], size_t nelem) {
-  return internal_bulk_free(gm, array, nelem);
-}
-
-#if MALLOC_INSPECT_ALL
-void dlmalloc_inspect_all(void(*handler)(void *start,
-                                         void *end,
-                                         size_t used_bytes,
-                                         void* callback_arg),
-                          void* arg) {
-  ensure_initialization();
-  if (!PREACTION(gm)) {
-    internal_inspect_all(gm, handler, arg);
-    POSTACTION(gm);
-  }
-}
-#endif /* MALLOC_INSPECT_ALL */
-
-int dlmalloc_trim(size_t pad) {
-  int result = 0;
-  ensure_initialization();
-  if (!PREACTION(gm)) {
-    result = sys_trim(gm, pad);
-    POSTACTION(gm);
-  }
-  return result;
-}
-
-size_t dlmalloc_footprint(void) {
-  return gm->footprint;
-}
-
-size_t dlmalloc_max_footprint(void) {
-  return gm->max_footprint;
-}
-
-size_t dlmalloc_footprint_limit(void) {
-  size_t maf = gm->footprint_limit;
-  return maf == 0 ? MAX_SIZE_T : maf;
-}
-
-size_t dlmalloc_set_footprint_limit(size_t bytes) {
-  size_t result;  /* invert sense of 0 */
-  if (bytes == 0)
-    result = granularity_align(1); /* Use minimal size */
-  if (bytes == MAX_SIZE_T)
-    result = 0;                    /* disable */
-  else
-    result = granularity_align(bytes);
-  return gm->footprint_limit = result;
-}
-
-#if !NO_MALLINFO
-struct mallinfo dlmallinfo(void) {
-  return internal_mallinfo(gm);
-}
-#endif /* NO_MALLINFO */
-
-#if !NO_MALLOC_STATS
-void dlmalloc_stats() {
-  internal_malloc_stats(gm);
-}
-#endif /* NO_MALLOC_STATS */
-
-int dlmallopt(int param_number, int value) {
-  return change_mparam(param_number, value);
-}
-
-/* BEGIN android-changed: added const */
-size_t dlmalloc_usable_size(const void* mem) {
-/* END android-change */
-  if (mem != 0) {
-    mchunkptr p = mem2chunk(mem);
-    if (is_inuse(p))
-      return chunksize(p) - overhead_for(p);
-  }
-  return 0;
-}
-
-#endif /* !ONLY_MSPACES */
-
-/* ----------------------------- user mspaces ---------------------------- */
-
-#if MSPACES
-
-static mstate init_user_mstate(char* tbase, size_t tsize) {
-  size_t msize = pad_request(sizeof(struct malloc_state));
-  mchunkptr mn;
-  mchunkptr msp = align_as_chunk(tbase);
-  mstate m = (mstate)(chunk2mem(msp));
-  memset(m, 0, msize);
-  (void)INITIAL_LOCK(&m->mutex);
-  msp->head = (msize|INUSE_BITS);
-  m->seg.base = m->least_addr = tbase;
-  m->seg.size = m->footprint = m->max_footprint = tsize;
-  m->magic = mparams.magic;
-  m->release_checks = MAX_RELEASE_CHECK_RATE;
-  m->mflags = mparams.default_mflags;
-  m->extp = 0;
-  m->exts = 0;
-  disable_contiguous(m);
-  init_bins(m);
-  mn = next_chunk(mem2chunk(m));
-  init_top(m, mn, (size_t)((tbase + tsize) - (char*)mn) - TOP_FOOT_SIZE);
-  check_top_chunk(m, m->top);
-  return m;
-}
-
-mspace create_mspace(size_t capacity, int locked) {
-  mstate m = 0;
-  size_t msize;
-  ensure_initialization();
-  msize = pad_request(sizeof(struct malloc_state));
-  if (capacity < (size_t) -(msize + TOP_FOOT_SIZE + mparams.page_size)) {
-    size_t rs = ((capacity == 0)? mparams.granularity :
-                 (capacity + TOP_FOOT_SIZE + msize));
-    size_t tsize = granularity_align(rs);
-    char* tbase = (char*)(CALL_MMAP(tsize));
-    if (tbase != CMFAIL) {
-      m = init_user_mstate(tbase, tsize);
-      m->seg.sflags = USE_MMAP_BIT;
-      set_lock(m, locked);
-    }
-  }
-  return (mspace)m;
-}
-
-mspace create_mspace_with_base(void* base, size_t capacity, int locked) {
-  mstate m = 0;
-  size_t msize;
-  ensure_initialization();
-  msize = pad_request(sizeof(struct malloc_state));
-  if (capacity > msize + TOP_FOOT_SIZE &&
-      capacity < (size_t) -(msize + TOP_FOOT_SIZE + mparams.page_size)) {
-    m = init_user_mstate((char*)base, capacity);
-    m->seg.sflags = EXTERN_BIT;
-    set_lock(m, locked);
-  }
-  return (mspace)m;
-}
-
-int mspace_track_large_chunks(mspace msp, int enable) {
-  int ret = 0;
-  mstate ms = (mstate)msp;
-  if (!PREACTION(ms)) {
-    if (!use_mmap(ms)) {
-      ret = 1;
-    }
-    if (!enable) {
-      enable_mmap(ms);
-    } else {
-      disable_mmap(ms);
-    }
-    POSTACTION(ms);
-  }
-  return ret;
-}
-
-size_t destroy_mspace(mspace msp) {
-  size_t freed = 0;
-  mstate ms = (mstate)msp;
-  if (ok_magic(ms)) {
-    msegmentptr sp = &ms->seg;
-    (void)DESTROY_LOCK(&ms->mutex); /* destroy before unmapped */
-    while (sp != 0) {
-      char* base = sp->base;
-      size_t size = sp->size;
-      flag_t flag = sp->sflags;
-      (void)base; /* placate people compiling -Wunused-variable */
-      sp = sp->next;
-      if ((flag & USE_MMAP_BIT) && !(flag & EXTERN_BIT) &&
-          CALL_MUNMAP(base, size) == 0)
-        freed += size;
-    }
-  }
-  else {
-    USAGE_ERROR_ACTION(ms,ms);
-  }
-  return freed;
-}
-
-/*
-  mspace versions of routines are near-clones of the global
-  versions. This is not so nice but better than the alternatives.
-*/
-
-void* mspace_malloc(mspace msp, size_t bytes) {
-  mstate ms = (mstate)msp;
-  if (!ok_magic(ms)) {
-    USAGE_ERROR_ACTION(ms,ms);
-    return 0;
-  }
-  if (!PREACTION(ms)) {
-    void* mem;
-    size_t nb;
-    if (bytes <= MAX_SMALL_REQUEST) {
-      bindex_t idx;
-      binmap_t smallbits;
-      nb = (bytes < MIN_REQUEST)? MIN_CHUNK_SIZE : pad_request(bytes);
-      idx = small_index(nb);
-      smallbits = ms->smallmap >> idx;
-
-      if ((smallbits & 0x3U) != 0) { /* Remainderless fit to a smallbin. */
-        mchunkptr b, p;
-        idx += ~smallbits & 1;       /* Uses next bin if idx empty */
-        b = smallbin_at(ms, idx);
-        p = b->fd;
-        assert(chunksize(p) == small_index2size(idx));
-        unlink_first_small_chunk(ms, b, p, idx);
-        set_inuse_and_pinuse(ms, p, small_index2size(idx));
-        mem = chunk2mem(p);
-        check_malloced_chunk(ms, mem, nb);
-        goto postaction;
-      }
-
-      else if (nb > ms->dvsize) {
-        if (smallbits != 0) { /* Use chunk in next nonempty smallbin */
-          mchunkptr b, p, r;
-          size_t rsize;
-          bindex_t i;
-          binmap_t leftbits = (smallbits << idx) & left_bits(idx2bit(idx));
-          binmap_t leastbit = least_bit(leftbits);
-          compute_bit2idx(leastbit, i);
-          b = smallbin_at(ms, i);
-          p = b->fd;
-          assert(chunksize(p) == small_index2size(i));
-          unlink_first_small_chunk(ms, b, p, i);
-          rsize = small_index2size(i) - nb;
-          /* Fit here cannot be remainderless if 4byte sizes */
-          if (SIZE_T_SIZE != 4 && rsize < MIN_CHUNK_SIZE)
-            set_inuse_and_pinuse(ms, p, small_index2size(i));
-          else {
-            set_size_and_pinuse_of_inuse_chunk(ms, p, nb);
-            r = chunk_plus_offset(p, nb);
-            set_size_and_pinuse_of_free_chunk(r, rsize);
-            replace_dv(ms, r, rsize);
-          }
-          mem = chunk2mem(p);
-          check_malloced_chunk(ms, mem, nb);
-          goto postaction;
-        }
-
-        else if (ms->treemap != 0 && (mem = tmalloc_small(ms, nb)) != 0) {
-          check_malloced_chunk(ms, mem, nb);
-          goto postaction;
-        }
-      }
-    }
-    else if (bytes >= MAX_REQUEST)
-      nb = MAX_SIZE_T; /* Too big to allocate. Force failure (in sys alloc) */
-    else {
-      nb = pad_request(bytes);
-      if (ms->treemap != 0 && (mem = tmalloc_large(ms, nb)) != 0) {
-        check_malloced_chunk(ms, mem, nb);
-        goto postaction;
-      }
-    }
-
-    if (nb <= ms->dvsize) {
-      size_t rsize = ms->dvsize - nb;
-      mchunkptr p = ms->dv;
-      if (rsize >= MIN_CHUNK_SIZE) { /* split dv */
-        mchunkptr r = ms->dv = chunk_plus_offset(p, nb);
-        ms->dvsize = rsize;
-        set_size_and_pinuse_of_free_chunk(r, rsize);
-        set_size_and_pinuse_of_inuse_chunk(ms, p, nb);
-      }
-      else { /* exhaust dv */
-        size_t dvs = ms->dvsize;
-        ms->dvsize = 0;
-        ms->dv = 0;
-        set_inuse_and_pinuse(ms, p, dvs);
-      }
-      mem = chunk2mem(p);
-      check_malloced_chunk(ms, mem, nb);
-      goto postaction;
-    }
-
-    else if (nb < ms->topsize) { /* Split top */
-      size_t rsize = ms->topsize -= nb;
-      mchunkptr p = ms->top;
-      mchunkptr r = ms->top = chunk_plus_offset(p, nb);
-      r->head = rsize | PINUSE_BIT;
-      set_size_and_pinuse_of_inuse_chunk(ms, p, nb);
-      mem = chunk2mem(p);
-      check_top_chunk(ms, ms->top);
-      check_malloced_chunk(ms, mem, nb);
-      goto postaction;
-    }
-
-    mem = sys_alloc(ms, nb);
-
-  postaction:
-    POSTACTION(ms);
-    return mem;
-  }
-
-  return 0;
-}
-
-void mspace_free(mspace msp, void* mem) {
-  if (mem != 0) {
-    mchunkptr p  = mem2chunk(mem);
-#if FOOTERS
-    mstate fm = get_mstate_for(p);
-    (void)msp; /* placate people compiling -Wunused */
-#else /* FOOTERS */
-    mstate fm = (mstate)msp;
-#endif /* FOOTERS */
-    if (!ok_magic(fm)) {
-      USAGE_ERROR_ACTION(fm, p);
-      return;
-    }
-    if (!PREACTION(fm)) {
-      check_inuse_chunk(fm, p);
-      if (RTCHECK(ok_address(fm, p) && ok_inuse(p))) {
-        size_t psize = chunksize(p);
-        mchunkptr next = chunk_plus_offset(p, psize);
-        if (!pinuse(p)) {
-          size_t prevsize = p->prev_foot;
-          if (is_mmapped(p)) {
-            psize += prevsize + MMAP_FOOT_PAD;
-            if (CALL_MUNMAP((char*)p - prevsize, psize) == 0)
-              fm->footprint -= psize;
-            goto postaction;
-          }
-          else {
-            mchunkptr prev = chunk_minus_offset(p, prevsize);
-            psize += prevsize;
-            p = prev;
-            if (RTCHECK(ok_address(fm, prev))) { /* consolidate backward */
-              if (p != fm->dv) {
-                unlink_chunk(fm, p, prevsize);
-              }
-              else if ((next->head & INUSE_BITS) == INUSE_BITS) {
-                fm->dvsize = psize;
-                set_free_with_pinuse(p, psize, next);
-                goto postaction;
-              }
-            }
-            else
-              goto erroraction;
-          }
-        }
-
-        if (RTCHECK(ok_next(p, next) && ok_pinuse(next))) {
-          if (!cinuse(next)) {  /* consolidate forward */
-            if (next == fm->top) {
-              size_t tsize = fm->topsize += psize;
-              fm->top = p;
-              p->head = tsize | PINUSE_BIT;
-              if (p == fm->dv) {
-                fm->dv = 0;
-                fm->dvsize = 0;
-              }
-              if (should_trim(fm, tsize))
-                sys_trim(fm, 0);
-              goto postaction;
-            }
-            else if (next == fm->dv) {
-              size_t dsize = fm->dvsize += psize;
-              fm->dv = p;
-              set_size_and_pinuse_of_free_chunk(p, dsize);
-              goto postaction;
-            }
-            else {
-              size_t nsize = chunksize(next);
-              psize += nsize;
-              unlink_chunk(fm, next, nsize);
-              set_size_and_pinuse_of_free_chunk(p, psize);
-              if (p == fm->dv) {
-                fm->dvsize = psize;
-                goto postaction;
-              }
-            }
-          }
-          else
-            set_free_with_pinuse(p, psize, next);
-
-          if (is_small(psize)) {
-            insert_small_chunk(fm, p, psize);
-            check_free_chunk(fm, p);
-          }
-          else {
-            tchunkptr tp = (tchunkptr)p;
-            insert_large_chunk(fm, tp, psize);
-            check_free_chunk(fm, p);
-            if (--fm->release_checks == 0)
-              release_unused_segments(fm);
-          }
-          goto postaction;
-        }
-      }
-    erroraction:
-      USAGE_ERROR_ACTION(fm, p);
-    postaction:
-      POSTACTION(fm);
-    }
-  }
-}
-
-void* mspace_calloc(mspace msp, size_t n_elements, size_t elem_size) {
-  void* mem;
-  size_t req = 0;
-  mstate ms = (mstate)msp;
-  if (!ok_magic(ms)) {
-    USAGE_ERROR_ACTION(ms,ms);
-    return 0;
-  }
-  if (n_elements != 0) {
-    req = n_elements * elem_size;
-    if (((n_elements | elem_size) & ~(size_t)0xffff) &&
-        (req / n_elements != elem_size))
-      req = MAX_SIZE_T; /* force downstream failure on overflow */
-  }
-  mem = internal_malloc(ms, req);
-  if (mem != 0 && calloc_must_clear(mem2chunk(mem)))
-    memset(mem, 0, req);
-  return mem;
-}
-
-void* mspace_realloc(mspace msp, void* oldmem, size_t bytes) {
-  void* mem = 0;
-  if (oldmem == 0) {
-    mem = mspace_malloc(msp, bytes);
-  }
-  else if (bytes >= MAX_REQUEST) {
-    MALLOC_FAILURE_ACTION;
-  }
-#ifdef REALLOC_ZERO_BYTES_FREES
-  else if (bytes == 0) {
-    mspace_free(msp, oldmem);
-  }
-#endif /* REALLOC_ZERO_BYTES_FREES */
-  else {
-    size_t nb = request2size(bytes);
-    mchunkptr oldp = mem2chunk(oldmem);
-#if ! FOOTERS
-    mstate m = (mstate)msp;
-#else /* FOOTERS */
-    mstate m = get_mstate_for(oldp);
-    if (!ok_magic(m)) {
-      USAGE_ERROR_ACTION(m, oldmem);
-      return 0;
-    }
-#endif /* FOOTERS */
-    if (!PREACTION(m)) {
-      mchunkptr newp = try_realloc_chunk(m, oldp, nb, 1);
-      POSTACTION(m);
-      if (newp != 0) {
-        check_inuse_chunk(m, newp);
-        mem = chunk2mem(newp);
-      }
-      else {
-        mem = mspace_malloc(m, bytes);
-        if (mem != 0) {
-          size_t oc = chunksize(oldp) - overhead_for(oldp);
-          memcpy(mem, oldmem, (oc < bytes)? oc : bytes);
-          mspace_free(m, oldmem);
-        }
-      }
-    }
-  }
-  return mem;
-}
-
-void* mspace_realloc_in_place(mspace msp, void* oldmem, size_t bytes) {
-  void* mem = 0;
-  if (oldmem != 0) {
-    if (bytes >= MAX_REQUEST) {
-      MALLOC_FAILURE_ACTION;
-    }
-    else {
-      size_t nb = request2size(bytes);
-      mchunkptr oldp = mem2chunk(oldmem);
-#if ! FOOTERS
-      mstate m = (mstate)msp;
-#else /* FOOTERS */
-      mstate m = get_mstate_for(oldp);
-      (void)msp; /* placate people compiling -Wunused */
-      if (!ok_magic(m)) {
-        USAGE_ERROR_ACTION(m, oldmem);
-        return 0;
-      }
-#endif /* FOOTERS */
-      if (!PREACTION(m)) {
-        mchunkptr newp = try_realloc_chunk(m, oldp, nb, 0);
-        POSTACTION(m);
-        if (newp == oldp) {
-          check_inuse_chunk(m, newp);
-          mem = oldmem;
-        }
-      }
-    }
-  }
-  return mem;
-}
-
-void* mspace_memalign(mspace msp, size_t alignment, size_t bytes) {
-  mstate ms = (mstate)msp;
-  if (!ok_magic(ms)) {
-    USAGE_ERROR_ACTION(ms,ms);
-    return 0;
-  }
-  if (alignment <= MALLOC_ALIGNMENT)
-    return mspace_malloc(msp, bytes);
-  return internal_memalign(ms, alignment, bytes);
-}
-
-void** mspace_independent_calloc(mspace msp, size_t n_elements,
-                                 size_t elem_size, void* chunks[]) {
-  size_t sz = elem_size; /* serves as 1-element array */
-  mstate ms = (mstate)msp;
-  if (!ok_magic(ms)) {
-    USAGE_ERROR_ACTION(ms,ms);
-    return 0;
-  }
-  return ialloc(ms, n_elements, &sz, 3, chunks);
-}
-
-void** mspace_independent_comalloc(mspace msp, size_t n_elements,
-                                   size_t sizes[], void* chunks[]) {
-  mstate ms = (mstate)msp;
-  if (!ok_magic(ms)) {
-    USAGE_ERROR_ACTION(ms,ms);
-    return 0;
-  }
-  return ialloc(ms, n_elements, sizes, 0, chunks);
-}
-
-size_t mspace_bulk_free(mspace msp, void* array[], size_t nelem) {
-  return internal_bulk_free((mstate)msp, array, nelem);
-}
-
-#if MALLOC_INSPECT_ALL
-void mspace_inspect_all(mspace msp,
-                        void(*handler)(void *start,
-                                       void *end,
-                                       size_t used_bytes,
-                                       void* callback_arg),
-                        void* arg) {
-  mstate ms = (mstate)msp;
-  if (ok_magic(ms)) {
-    if (!PREACTION(ms)) {
-      internal_inspect_all(ms, handler, arg);
-      POSTACTION(ms);
-    }
-  }
-  else {
-    USAGE_ERROR_ACTION(ms,ms);
-  }
-}
-#endif /* MALLOC_INSPECT_ALL */
-
-int mspace_trim(mspace msp, size_t pad) {
-  int result = 0;
-  mstate ms = (mstate)msp;
-  if (ok_magic(ms)) {
-    if (!PREACTION(ms)) {
-      result = sys_trim(ms, pad);
-      POSTACTION(ms);
-    }
-  }
-  else {
-    USAGE_ERROR_ACTION(ms,ms);
-  }
-  return result;
-}
-
-#if !NO_MALLOC_STATS
-void mspace_malloc_stats(mspace msp) {
-  mstate ms = (mstate)msp;
-  if (ok_magic(ms)) {
-    internal_malloc_stats(ms);
-  }
-  else {
-    USAGE_ERROR_ACTION(ms,ms);
-  }
-}
-#endif /* NO_MALLOC_STATS */
-
-size_t mspace_footprint(mspace msp) {
-  size_t result = 0;
-  mstate ms = (mstate)msp;
-  if (ok_magic(ms)) {
-    result = ms->footprint;
-  }
-  else {
-    USAGE_ERROR_ACTION(ms,ms);
-  }
-  return result;
-}
-
-size_t mspace_max_footprint(mspace msp) {
-  size_t result = 0;
-  mstate ms = (mstate)msp;
-  if (ok_magic(ms)) {
-    result = ms->max_footprint;
-  }
-  else {
-    USAGE_ERROR_ACTION(ms,ms);
-  }
-  return result;
-}
-
-size_t mspace_footprint_limit(mspace msp) {
-  size_t result = 0;
-  mstate ms = (mstate)msp;
-  if (ok_magic(ms)) {
-    size_t maf = ms->footprint_limit;
-    result = (maf == 0) ? MAX_SIZE_T : maf;
-  }
-  else {
-    USAGE_ERROR_ACTION(ms,ms);
-  }
-  return result;
-}
-
-size_t mspace_set_footprint_limit(mspace msp, size_t bytes) {
-  size_t result = 0;
-  mstate ms = (mstate)msp;
-  if (ok_magic(ms)) {
-    if (bytes == 0)
-      result = granularity_align(1); /* Use minimal size */
-    if (bytes == MAX_SIZE_T)
-      result = 0;                    /* disable */
-    else
-      result = granularity_align(bytes);
-    ms->footprint_limit = result;
-  }
-  else {
-    USAGE_ERROR_ACTION(ms,ms);
-  }
-  return result;
-}
-
-#if !NO_MALLINFO
-struct mallinfo mspace_mallinfo(mspace msp) {
-  mstate ms = (mstate)msp;
-  if (!ok_magic(ms)) {
-    USAGE_ERROR_ACTION(ms,ms);
-  }
-  return internal_mallinfo(ms);
-}
-#endif /* NO_MALLINFO */
-
-size_t mspace_usable_size(const void* mem) {
-  if (mem != 0) {
-    mchunkptr p = mem2chunk(mem);
-    if (is_inuse(p))
-      return chunksize(p) - overhead_for(p);
-  }
-  return 0;
-}
-
-int mspace_mallopt(int param_number, int value) {
-  return change_mparam(param_number, value);
-}
-
-#endif /* MSPACES */
-
-
-/* -------------------- Alternative MORECORE functions ------------------- */
-
-/*
-  Guidelines for creating a custom version of MORECORE:
-
-  * For best performance, MORECORE should allocate in multiples of pagesize.
-  * MORECORE may allocate more memory than requested. (Or even less,
-      but this will usually result in a malloc failure.)
-  * MORECORE must not allocate memory when given argument zero, but
-      instead return one past the end address of memory from previous
-      nonzero call.
-  * For best performance, consecutive calls to MORECORE with positive
-      arguments should return increasing addresses, indicating that
-      space has been contiguously extended.
-  * Even though consecutive calls to MORECORE need not return contiguous
-      addresses, it must be OK for malloc'ed chunks to span multiple
-      regions in those cases where they do happen to be contiguous.
-  * MORECORE need not handle negative arguments -- it may instead
-      just return MFAIL when given negative arguments.
-      Negative arguments are always multiples of pagesize. MORECORE
-      must not misinterpret negative args as large positive unsigned
-      args. You can suppress all such calls from even occurring by defining
-      MORECORE_CANNOT_TRIM,
-
-  As an example alternative MORECORE, here is a custom allocator
-  kindly contributed for pre-OSX macOS.  It uses virtually but not
-  necessarily physically contiguous non-paged memory (locked in,
-  present and won't get swapped out).  You can use it by uncommenting
-  this section, adding some #includes, and setting up the appropriate
-  defines above:
-
-      #define MORECORE osMoreCore
-
-  There is also a shutdown routine that should somehow be called for
-  cleanup upon program exit.
-
-  #define MAX_POOL_ENTRIES 100
-  #define MINIMUM_MORECORE_SIZE  (64 * 1024U)
-  static int next_os_pool;
-  void *our_os_pools[MAX_POOL_ENTRIES];
-
-  void *osMoreCore(int size)
-  {
-    void *ptr = 0;
-    static void *sbrk_top = 0;
-
-    if (size > 0)
-    {
-      if (size < MINIMUM_MORECORE_SIZE)
-         size = MINIMUM_MORECORE_SIZE;
-      if (CurrentExecutionLevel() == kTaskLevel)
-         ptr = PoolAllocateResident(size + RM_PAGE_SIZE, 0);
-      if (ptr == 0)
-      {
-        return (void *) MFAIL;
-      }
-      // save ptrs so they can be freed during cleanup
-      our_os_pools[next_os_pool] = ptr;
-      next_os_pool++;
-      ptr = (void *) ((((size_t) ptr) + RM_PAGE_MASK) & ~RM_PAGE_MASK);
-      sbrk_top = (char *) ptr + size;
-      return ptr;
-    }
-    else if (size < 0)
-    {
-      // we don't currently support shrink behavior
-      return (void *) MFAIL;
-    }
-    else
-    {
-      return sbrk_top;
-    }
-  }
-
-  // cleanup any allocated memory pools
-  // called as last thing before shutting down driver
-
-  void osCleanupMem(void)
-  {
-    void **ptr;
-
-    for (ptr = our_os_pools; ptr < &our_os_pools[MAX_POOL_ENTRIES]; ptr++)
-      if (*ptr)
-      {
-         PoolDeallocate(*ptr);
-         *ptr = 0;
-      }
-  }
-
-*/
-
-
-/* -----------------------------------------------------------------------
-History:
-    v2.8.6 Wed Aug 29 06:57:58 2012  Doug Lea
-      * fix bad comparison in dlposix_memalign
-      * don't reuse adjusted asize in sys_alloc
-      * add LOCK_AT_FORK -- thanks to Kirill Artamonov for the suggestion
-      * reduce compiler warnings -- thanks to all who reported/suggested these
-
-    v2.8.5 Sun May 22 10:26:02 2011  Doug Lea  (dl at gee)
-      * Always perform unlink checks unless INSECURE
-      * Add posix_memalign.
-      * Improve realloc to expand in more cases; expose realloc_in_place.
-        Thanks to Peter Buhr for the suggestion.
-      * Add footprint_limit, inspect_all, bulk_free. Thanks
-        to Barry Hayes and others for the suggestions.
-      * Internal refactorings to avoid calls while holding locks
-      * Use non-reentrant locks by default. Thanks to Roland McGrath
-        for the suggestion.
-      * Small fixes to mspace_destroy, reset_on_error.
-      * Various configuration extensions/changes. Thanks
-         to all who contributed these.
-
-    V2.8.4a Thu Apr 28 14:39:43 2011 (dl at gee.cs.oswego.edu)
-      * Update Creative Commons URL
-
-    V2.8.4 Wed May 27 09:56:23 2009  Doug Lea  (dl at gee)
-      * Use zeros instead of prev foot for is_mmapped
-      * Add mspace_track_large_chunks; thanks to Jean Brouwers
-      * Fix set_inuse in internal_realloc; thanks to Jean Brouwers
-      * Fix insufficient sys_alloc padding when using 16byte alignment
-      * Fix bad error check in mspace_footprint
-      * Adaptations for ptmalloc; thanks to Wolfram Gloger.
-      * Reentrant spin locks; thanks to Earl Chew and others
-      * Win32 improvements; thanks to Niall Douglas and Earl Chew
-      * Add NO_SEGMENT_TRAVERSAL and MAX_RELEASE_CHECK_RATE options
-      * Extension hook in malloc_state
-      * Various small adjustments to reduce warnings on some compilers
-      * Various configuration extensions/changes for more platforms. Thanks
-         to all who contributed these.
-
-    V2.8.3 Thu Sep 22 11:16:32 2005  Doug Lea  (dl at gee)
-      * Add max_footprint functions
-      * Ensure all appropriate literals are size_t
-      * Fix conditional compilation problem for some #define settings
-      * Avoid concatenating segments with the one provided
-        in create_mspace_with_base
-      * Rename some variables to avoid compiler shadowing warnings
-      * Use explicit lock initialization.
-      * Better handling of sbrk interference.
-      * Simplify and fix segment insertion, trimming and mspace_destroy
-      * Reinstate REALLOC_ZERO_BYTES_FREES option from 2.7.x
-      * Thanks especially to Dennis Flanagan for help on these.
-
-    V2.8.2 Sun Jun 12 16:01:10 2005  Doug Lea  (dl at gee)
-      * Fix memalign brace error.
-
-    V2.8.1 Wed Jun  8 16:11:46 2005  Doug Lea  (dl at gee)
-      * Fix improper #endif nesting in C++
-      * Add explicit casts needed for C++
-
-    V2.8.0 Mon May 30 14:09:02 2005  Doug Lea  (dl at gee)
-      * Use trees for large bins
-      * Support mspaces
-      * Use segments to unify sbrk-based and mmap-based system allocation,
-        removing need for emulation on most platforms without sbrk.
-      * Default safety checks
-      * Optional footer checks. Thanks to William Robertson for the idea.
-      * Internal code refactoring
-      * Incorporate suggestions and platform-specific changes.
-        Thanks to Dennis Flanagan, Colin Plumb, Niall Douglas,
-        Aaron Bachmann,  Emery Berger, and others.
-      * Speed up non-fastbin processing enough to remove fastbins.
-      * Remove useless cfree() to avoid conflicts with other apps.
-      * Remove internal memcpy, memset. Compilers handle builtins better.
-      * Remove some options that no one ever used and rename others.
-
-    V2.7.2 Sat Aug 17 09:07:30 2002  Doug Lea  (dl at gee)
-      * Fix malloc_state bitmap array misdeclaration
-
-    V2.7.1 Thu Jul 25 10:58:03 2002  Doug Lea  (dl at gee)
-      * Allow tuning of FIRST_SORTED_BIN_SIZE
-      * Use PTR_UINT as type for all ptr->int casts. Thanks to John Belmonte.
-      * Better detection and support for non-contiguousness of MORECORE.
-        Thanks to Andreas Mueller, Conal Walsh, and Wolfram Gloger
-      * Bypass most of malloc if no frees. Thanks To Emery Berger.
-      * Fix freeing of old top non-contiguous chunk im sysmalloc.
-      * Raised default trim and map thresholds to 256K.
-      * Fix mmap-related #defines. Thanks to Lubos Lunak.
-      * Fix copy macros; added LACKS_FCNTL_H. Thanks to Neal Walfield.
-      * Branch-free bin calculation
-      * Default trim and mmap thresholds now 256K.
-
-    V2.7.0 Sun Mar 11 14:14:06 2001  Doug Lea  (dl at gee)
-      * Introduce independent_comalloc and independent_calloc.
-        Thanks to Michael Pachos for motivation and help.
-      * Make optional .h file available
-      * Allow > 2GB requests on 32bit systems.
-      * new WIN32 sbrk, mmap, munmap, lock code from <Walter@GeNeSys-e.de>.
-        Thanks also to Andreas Mueller <a.mueller at paradatec.de>,
-        and Anonymous.
-      * Allow override of MALLOC_ALIGNMENT (Thanks to Ruud Waij for
-        helping test this.)
-      * memalign: check alignment arg
-      * realloc: don't try to shift chunks backwards, since this
-        leads to  more fragmentation in some programs and doesn't
-        seem to help in any others.
-      * Collect all cases in malloc requiring system memory into sysmalloc
-      * Use mmap as backup to sbrk
-      * Place all internal state in malloc_state
-      * Introduce fastbins (although similar to 2.5.1)
-      * Many minor tunings and cosmetic improvements
-      * Introduce USE_PUBLIC_MALLOC_WRAPPERS, USE_MALLOC_LOCK
-      * Introduce MALLOC_FAILURE_ACTION, MORECORE_CONTIGUOUS
-        Thanks to Tony E. Bennett <tbennett@nvidia.com> and others.
-      * Include errno.h to support default failure action.
-
-    V2.6.6 Sun Dec  5 07:42:19 1999  Doug Lea  (dl at gee)
-      * return null for negative arguments
-      * Added Several WIN32 cleanups from Martin C. Fong <mcfong at yahoo.com>
-         * Add 'LACKS_SYS_PARAM_H' for those systems without 'sys/param.h'
-          (e.g. WIN32 platforms)
-         * Cleanup header file inclusion for WIN32 platforms
-         * Cleanup code to avoid Microsoft Visual C++ compiler complaints
-         * Add 'USE_DL_PREFIX' to quickly allow co-existence with existing
-           memory allocation routines
-         * Set 'malloc_getpagesize' for WIN32 platforms (needs more work)
-         * Use 'assert' rather than 'ASSERT' in WIN32 code to conform to
-           usage of 'assert' in non-WIN32 code
-         * Improve WIN32 'sbrk()' emulation's 'findRegion()' routine to
-           avoid infinite loop
-      * Always call 'fREe()' rather than 'free()'
-
-    V2.6.5 Wed Jun 17 15:57:31 1998  Doug Lea  (dl at gee)
-      * Fixed ordering problem with boundary-stamping
-
-    V2.6.3 Sun May 19 08:17:58 1996  Doug Lea  (dl at gee)
-      * Added pvalloc, as recommended by H.J. Liu
-      * Added 64bit pointer support mainly from Wolfram Gloger
-      * Added anonymously donated WIN32 sbrk emulation
-      * Malloc, calloc, getpagesize: add optimizations from Raymond Nijssen
-      * malloc_extend_top: fix mask error that caused wastage after
-        foreign sbrks
-      * Add linux mremap support code from HJ Liu
-
-    V2.6.2 Tue Dec  5 06:52:55 1995  Doug Lea  (dl at gee)
-      * Integrated most documentation with the code.
-      * Add support for mmap, with help from
-        Wolfram Gloger (Gloger@lrz.uni-muenchen.de).
-      * Use last_remainder in more cases.
-      * Pack bins using idea from  colin@nyx10.cs.du.edu
-      * Use ordered bins instead of best-fit threshhold
-      * Eliminate block-local decls to simplify tracing and debugging.
-      * Support another case of realloc via move into top
-      * Fix error occuring when initial sbrk_base not word-aligned.
-      * Rely on page size for units instead of SBRK_UNIT to
-        avoid surprises about sbrk alignment conventions.
-      * Add mallinfo, mallopt. Thanks to Raymond Nijssen
-        (raymond@es.ele.tue.nl) for the suggestion.
-      * Add `pad' argument to malloc_trim and top_pad mallopt parameter.
-      * More precautions for cases where other routines call sbrk,
-        courtesy of Wolfram Gloger (Gloger@lrz.uni-muenchen.de).
-      * Added macros etc., allowing use in linux libc from
-        H.J. Lu (hjl@gnu.ai.mit.edu)
-      * Inverted this history list
-
-    V2.6.1 Sat Dec  2 14:10:57 1995  Doug Lea  (dl at gee)
-      * Re-tuned and fixed to behave more nicely with V2.6.0 changes.
-      * Removed all preallocation code since under current scheme
-        the work required to undo bad preallocations exceeds
-        the work saved in good cases for most test programs.
-      * No longer use return list or unconsolidated bins since
-        no scheme using them consistently outperforms those that don't
-        given above changes.
-      * Use best fit for very large chunks to prevent some worst-cases.
-      * Added some support for debugging
-
-    V2.6.0 Sat Nov  4 07:05:23 1995  Doug Lea  (dl at gee)
-      * Removed footers when chunks are in use. Thanks to
-        Paul Wilson (wilson@cs.texas.edu) for the suggestion.
-
-    V2.5.4 Wed Nov  1 07:54:51 1995  Doug Lea  (dl at gee)
-      * Added malloc_trim, with help from Wolfram Gloger
-        (wmglo@Dent.MED.Uni-Muenchen.DE).
-
-    V2.5.3 Tue Apr 26 10:16:01 1994  Doug Lea  (dl at g)
-
-    V2.5.2 Tue Apr  5 16:20:40 1994  Doug Lea  (dl at g)
-      * realloc: try to expand in both directions
-      * malloc: swap order of clean-bin strategy;
-      * realloc: only conditionally expand backwards
-      * Try not to scavenge used bins
-      * Use bin counts as a guide to preallocation
-      * Occasionally bin return list chunks in first scan
-      * Add a few optimizations from colin@nyx10.cs.du.edu
-
-    V2.5.1 Sat Aug 14 15:40:43 1993  Doug Lea  (dl at g)
-      * faster bin computation & slightly different binning
-      * merged all consolidations to one part of malloc proper
-         (eliminating old malloc_find_space & malloc_clean_bin)
-      * Scan 2 returns chunks (not just 1)
-      * Propagate failure in realloc if malloc returns 0
-      * Add stuff to allow compilation on non-ANSI compilers
-          from kpv@research.att.com
-
-    V2.5 Sat Aug  7 07:41:59 1993  Doug Lea  (dl at g.oswego.edu)
-      * removed potential for odd address access in prev_chunk
-      * removed dependency on getpagesize.h
-      * misc cosmetics and a bit more internal documentation
-      * anticosmetics: mangled names in macros to evade debugger strangeness
-      * tested on sparc, hp-700, dec-mips, rs6000
-          with gcc & native cc (hp, dec only) allowing
-          Detlefs & Zorn comparison study (in SIGPLAN Notices.)
-
-    Trial version Fri Aug 28 13:14:29 1992  Doug Lea  (dl at g.oswego.edu)
-      * Based loosely on libg++-1.2X malloc. (It retains some of the overall
-         structure of old version,  but most details differ.)
-
-*/
diff --git a/libc/upstream-dlmalloc/malloc.h b/libc/upstream-dlmalloc/malloc.h
deleted file mode 100644
index e52c9e5..0000000
--- a/libc/upstream-dlmalloc/malloc.h
+++ /dev/null
@@ -1,620 +0,0 @@
-/*
-  Default header file for malloc-2.8.x, written by Doug Lea
-  and released to the public domain, as explained at
-  http://creativecommons.org/publicdomain/zero/1.0/ 
- 
-  This header is for ANSI C/C++ only.  You can set any of
-  the following #defines before including:
-
-  * If USE_DL_PREFIX is defined, it is assumed that malloc.c 
-    was also compiled with this option, so all routines
-    have names starting with "dl".
-
-  * If HAVE_USR_INCLUDE_MALLOC_H is defined, it is assumed that this
-    file will be #included AFTER <malloc.h>. This is needed only if
-    your system defines a struct mallinfo that is incompatible with the
-    standard one declared here.  Otherwise, you can include this file
-    INSTEAD of your system system <malloc.h>.  At least on ANSI, all
-    declarations should be compatible with system versions
-
-  * If MSPACES is defined, declarations for mspace versions are included.
-*/
-
-#ifndef MALLOC_280_H
-#define MALLOC_280_H
-
-#ifdef __cplusplus
-extern "C" {
-#endif
-
-#include <stddef.h>   /* for size_t */
-
-#ifndef ONLY_MSPACES
-#define ONLY_MSPACES 0     /* define to a value */
-#elif ONLY_MSPACES != 0
-#define ONLY_MSPACES 1
-#endif  /* ONLY_MSPACES */
-#ifndef NO_MALLINFO
-#define NO_MALLINFO 0
-#endif  /* NO_MALLINFO */
-
-#ifndef MSPACES
-#if ONLY_MSPACES
-#define MSPACES 1
-#else   /* ONLY_MSPACES */
-#define MSPACES 0
-#endif  /* ONLY_MSPACES */
-#endif  /* MSPACES */
-
-#if !ONLY_MSPACES
-
-#ifndef USE_DL_PREFIX
-#define dlcalloc               calloc
-#define dlfree                 free
-#define dlmalloc               malloc
-#define dlmemalign             memalign
-#define dlposix_memalign       posix_memalign
-#define dlrealloc              realloc
-#define dlvalloc               valloc
-#define dlpvalloc              pvalloc
-#define dlmallinfo             mallinfo
-#define dlmallopt              mallopt
-#define dlmalloc_trim          malloc_trim
-#define dlmalloc_stats         malloc_stats
-#define dlmalloc_usable_size   malloc_usable_size
-#define dlmalloc_footprint     malloc_footprint
-#define dlmalloc_max_footprint malloc_max_footprint
-#define dlmalloc_footprint_limit malloc_footprint_limit
-#define dlmalloc_set_footprint_limit malloc_set_footprint_limit
-#define dlmalloc_inspect_all   malloc_inspect_all
-#define dlindependent_calloc   independent_calloc
-#define dlindependent_comalloc independent_comalloc
-#define dlbulk_free            bulk_free
-#endif /* USE_DL_PREFIX */
-
-#if !NO_MALLINFO 
-#ifndef HAVE_USR_INCLUDE_MALLOC_H
-#ifndef _MALLOC_H
-#ifndef MALLINFO_FIELD_TYPE
-#define MALLINFO_FIELD_TYPE size_t
-#endif /* MALLINFO_FIELD_TYPE */
-#ifndef STRUCT_MALLINFO_DECLARED
-#define STRUCT_MALLINFO_DECLARED 1
-struct mallinfo {
-  MALLINFO_FIELD_TYPE arena;    /* non-mmapped space allocated from system */
-  MALLINFO_FIELD_TYPE ordblks;  /* number of free chunks */
-  MALLINFO_FIELD_TYPE smblks;   /* always 0 */
-  MALLINFO_FIELD_TYPE hblks;    /* always 0 */
-  MALLINFO_FIELD_TYPE hblkhd;   /* space in mmapped regions */
-  MALLINFO_FIELD_TYPE usmblks;  /* maximum total allocated space */
-  MALLINFO_FIELD_TYPE fsmblks;  /* always 0 */
-  MALLINFO_FIELD_TYPE uordblks; /* total allocated space */
-  MALLINFO_FIELD_TYPE fordblks; /* total free space */
-  MALLINFO_FIELD_TYPE keepcost; /* releasable (via malloc_trim) space */
-};
-#endif /* STRUCT_MALLINFO_DECLARED */
-#endif  /* _MALLOC_H */
-#endif  /* HAVE_USR_INCLUDE_MALLOC_H */
-#endif  /* !NO_MALLINFO */
-
-/*
-  malloc(size_t n)
-  Returns a pointer to a newly allocated chunk of at least n bytes, or
-  null if no space is available, in which case errno is set to ENOMEM
-  on ANSI C systems.
-
-  If n is zero, malloc returns a minimum-sized chunk. (The minimum
-  size is 16 bytes on most 32bit systems, and 32 bytes on 64bit
-  systems.)  Note that size_t is an unsigned type, so calls with
-  arguments that would be negative if signed are interpreted as
-  requests for huge amounts of space, which will often fail. The
-  maximum supported value of n differs across systems, but is in all
-  cases less than the maximum representable value of a size_t.
-*/
-void* dlmalloc(size_t);
-
-/*
-  free(void* p)
-  Releases the chunk of memory pointed to by p, that had been previously
-  allocated using malloc or a related routine such as realloc.
-  It has no effect if p is null. If p was not malloced or already
-  freed, free(p) will by default cuase the current program to abort.
-*/
-void  dlfree(void*);
-
-/*
-  calloc(size_t n_elements, size_t element_size);
-  Returns a pointer to n_elements * element_size bytes, with all locations
-  set to zero.
-*/
-void* dlcalloc(size_t, size_t);
-
-/*
-  realloc(void* p, size_t n)
-  Returns a pointer to a chunk of size n that contains the same data
-  as does chunk p up to the minimum of (n, p's size) bytes, or null
-  if no space is available.
-
-  The returned pointer may or may not be the same as p. The algorithm
-  prefers extending p in most cases when possible, otherwise it
-  employs the equivalent of a malloc-copy-free sequence.
-
-  If p is null, realloc is equivalent to malloc.
-
-  If space is not available, realloc returns null, errno is set (if on
-  ANSI) and p is NOT freed.
-
-  if n is for fewer bytes than already held by p, the newly unused
-  space is lopped off and freed if possible.  realloc with a size
-  argument of zero (re)allocates a minimum-sized chunk.
-
-  The old unix realloc convention of allowing the last-free'd chunk
-  to be used as an argument to realloc is not supported.
-*/
-void* dlrealloc(void*, size_t);
-
-/*
-  realloc_in_place(void* p, size_t n)
-  Resizes the space allocated for p to size n, only if this can be
-  done without moving p (i.e., only if there is adjacent space
-  available if n is greater than p's current allocated size, or n is
-  less than or equal to p's size). This may be used instead of plain
-  realloc if an alternative allocation strategy is needed upon failure
-  to expand space; for example, reallocation of a buffer that must be
-  memory-aligned or cleared. You can use realloc_in_place to trigger
-  these alternatives only when needed.
-
-  Returns p if successful; otherwise null.
-*/
-void* dlrealloc_in_place(void*, size_t);
-
-/*
-  memalign(size_t alignment, size_t n);
-  Returns a pointer to a newly allocated chunk of n bytes, aligned
-  in accord with the alignment argument.
-
-  The alignment argument should be a power of two. If the argument is
-  not a power of two, the nearest greater power is used.
-  8-byte alignment is guaranteed by normal malloc calls, so don't
-  bother calling memalign with an argument of 8 or less.
-
-  Overreliance on memalign is a sure way to fragment space.
-*/
-void* dlmemalign(size_t, size_t);
-
-/*
-  int posix_memalign(void** pp, size_t alignment, size_t n);
-  Allocates a chunk of n bytes, aligned in accord with the alignment
-  argument. Differs from memalign only in that it (1) assigns the
-  allocated memory to *pp rather than returning it, (2) fails and
-  returns EINVAL if the alignment is not a power of two (3) fails and
-  returns ENOMEM if memory cannot be allocated.
-*/
-int dlposix_memalign(void**, size_t, size_t);
-
-/*
-  valloc(size_t n);
-  Equivalent to memalign(pagesize, n), where pagesize is the page
-  size of the system. If the pagesize is unknown, 4096 is used.
-*/
-void* dlvalloc(size_t);
-
-/*
-  mallopt(int parameter_number, int parameter_value)
-  Sets tunable parameters The format is to provide a
-  (parameter-number, parameter-value) pair.  mallopt then sets the
-  corresponding parameter to the argument value if it can (i.e., so
-  long as the value is meaningful), and returns 1 if successful else
-  0.  SVID/XPG/ANSI defines four standard param numbers for mallopt,
-  normally defined in malloc.h.  None of these are use in this malloc,
-  so setting them has no effect. But this malloc also supports other
-  options in mallopt:
-
-  Symbol            param #  default    allowed param values
-  M_TRIM_THRESHOLD     -1   2*1024*1024   any   (-1U disables trimming)
-  M_GRANULARITY        -2     page size   any power of 2 >= page size
-  M_MMAP_THRESHOLD     -3      256*1024   any   (or 0 if no MMAP support)
-*/
-int dlmallopt(int, int);
-
-#define M_TRIM_THRESHOLD     (-1)
-#define M_GRANULARITY        (-2)
-#define M_MMAP_THRESHOLD     (-3)
-
-
-/*
-  malloc_footprint();
-  Returns the number of bytes obtained from the system.  The total
-  number of bytes allocated by malloc, realloc etc., is less than this
-  value. Unlike mallinfo, this function returns only a precomputed
-  result, so can be called frequently to monitor memory consumption.
-  Even if locks are otherwise defined, this function does not use them,
-  so results might not be up to date.
-*/
-size_t dlmalloc_footprint(void);
-
-/*
-  malloc_max_footprint();
-  Returns the maximum number of bytes obtained from the system. This
-  value will be greater than current footprint if deallocated space
-  has been reclaimed by the system. The peak number of bytes allocated
-  by malloc, realloc etc., is less than this value. Unlike mallinfo,
-  this function returns only a precomputed result, so can be called
-  frequently to monitor memory consumption.  Even if locks are
-  otherwise defined, this function does not use them, so results might
-  not be up to date.
-*/
-size_t dlmalloc_max_footprint(void);
-
-/*
-  malloc_footprint_limit();
-  Returns the number of bytes that the heap is allowed to obtain from
-  the system, returning the last value returned by
-  malloc_set_footprint_limit, or the maximum size_t value if
-  never set. The returned value reflects a permission. There is no
-  guarantee that this number of bytes can actually be obtained from
-  the system.  
-*/
-size_t dlmalloc_footprint_limit(void);
-
-/*
-  malloc_set_footprint_limit();
-  Sets the maximum number of bytes to obtain from the system, causing
-  failure returns from malloc and related functions upon attempts to
-  exceed this value. The argument value may be subject to page
-  rounding to an enforceable limit; this actual value is returned.
-  Using an argument of the maximum possible size_t effectively
-  disables checks. If the argument is less than or equal to the
-  current malloc_footprint, then all future allocations that require
-  additional system memory will fail. However, invocation cannot
-  retroactively deallocate existing used memory.
-*/
-size_t dlmalloc_set_footprint_limit(size_t bytes);
-
-/*
-  malloc_inspect_all(void(*handler)(void *start,
-                                    void *end,
-                                    size_t used_bytes,
-                                    void* callback_arg),
-                      void* arg);
-  Traverses the heap and calls the given handler for each managed
-  region, skipping all bytes that are (or may be) used for bookkeeping
-  purposes.  Traversal does not include include chunks that have been
-  directly memory mapped. Each reported region begins at the start
-  address, and continues up to but not including the end address.  The
-  first used_bytes of the region contain allocated data. If
-  used_bytes is zero, the region is unallocated. The handler is
-  invoked with the given callback argument. If locks are defined, they
-  are held during the entire traversal. It is a bad idea to invoke
-  other malloc functions from within the handler.
-
-  For example, to count the number of in-use chunks with size greater
-  than 1000, you could write:
-  static int count = 0;
-  void count_chunks(void* start, void* end, size_t used, void* arg) {
-    if (used >= 1000) ++count;
-  }
-  then:
-    malloc_inspect_all(count_chunks, NULL);
-
-  malloc_inspect_all is compiled only if MALLOC_INSPECT_ALL is defined.
-*/
-void dlmalloc_inspect_all(void(*handler)(void*, void *, size_t, void*),
-                           void* arg);
-
-#if !NO_MALLINFO
-/*
-  mallinfo()
-  Returns (by copy) a struct containing various summary statistics:
-
-  arena:     current total non-mmapped bytes allocated from system
-  ordblks:   the number of free chunks
-  smblks:    always zero.
-  hblks:     current number of mmapped regions
-  hblkhd:    total bytes held in mmapped regions
-  usmblks:   the maximum total allocated space. This will be greater
-                than current total if trimming has occurred.
-  fsmblks:   always zero
-  uordblks:  current total allocated space (normal or mmapped)
-  fordblks:  total free space
-  keepcost:  the maximum number of bytes that could ideally be released
-               back to system via malloc_trim. ("ideally" means that
-               it ignores page restrictions etc.)
-
-  Because these fields are ints, but internal bookkeeping may
-  be kept as longs, the reported values may wrap around zero and
-  thus be inaccurate.
-*/
-
-struct mallinfo dlmallinfo(void);
-#endif  /* NO_MALLINFO */
-
-/*
-  independent_calloc(size_t n_elements, size_t element_size, void* chunks[]);
-
-  independent_calloc is similar to calloc, but instead of returning a
-  single cleared space, it returns an array of pointers to n_elements
-  independent elements that can hold contents of size elem_size, each
-  of which starts out cleared, and can be independently freed,
-  realloc'ed etc. The elements are guaranteed to be adjacently
-  allocated (this is not guaranteed to occur with multiple callocs or
-  mallocs), which may also improve cache locality in some
-  applications.
-
-  The "chunks" argument is optional (i.e., may be null, which is
-  probably the most typical usage). If it is null, the returned array
-  is itself dynamically allocated and should also be freed when it is
-  no longer needed. Otherwise, the chunks array must be of at least
-  n_elements in length. It is filled in with the pointers to the
-  chunks.
-
-  In either case, independent_calloc returns this pointer array, or
-  null if the allocation failed.  If n_elements is zero and "chunks"
-  is null, it returns a chunk representing an array with zero elements
-  (which should be freed if not wanted).
-
-  Each element must be freed when it is no longer needed. This can be
-  done all at once using bulk_free.
-
-  independent_calloc simplifies and speeds up implementations of many
-  kinds of pools.  It may also be useful when constructing large data
-  structures that initially have a fixed number of fixed-sized nodes,
-  but the number is not known at compile time, and some of the nodes
-  may later need to be freed. For example:
-
-  struct Node { int item; struct Node* next; };
-
-  struct Node* build_list() {
-    struct Node** pool;
-    int n = read_number_of_nodes_needed();
-    if (n <= 0) return 0;
-    pool = (struct Node**)(independent_calloc(n, sizeof(struct Node), 0);
-    if (pool == 0) die();
-    // organize into a linked list...
-    struct Node* first = pool[0];
-    for (i = 0; i < n-1; ++i)
-      pool[i]->next = pool[i+1];
-    free(pool);     // Can now free the array (or not, if it is needed later)
-    return first;
-  }
-*/
-void** dlindependent_calloc(size_t, size_t, void**);
-
-/*
-  independent_comalloc(size_t n_elements, size_t sizes[], void* chunks[]);
-
-  independent_comalloc allocates, all at once, a set of n_elements
-  chunks with sizes indicated in the "sizes" array.    It returns
-  an array of pointers to these elements, each of which can be
-  independently freed, realloc'ed etc. The elements are guaranteed to
-  be adjacently allocated (this is not guaranteed to occur with
-  multiple callocs or mallocs), which may also improve cache locality
-  in some applications.
-
-  The "chunks" argument is optional (i.e., may be null). If it is null
-  the returned array is itself dynamically allocated and should also
-  be freed when it is no longer needed. Otherwise, the chunks array
-  must be of at least n_elements in length. It is filled in with the
-  pointers to the chunks.
-
-  In either case, independent_comalloc returns this pointer array, or
-  null if the allocation failed.  If n_elements is zero and chunks is
-  null, it returns a chunk representing an array with zero elements
-  (which should be freed if not wanted).
-
-  Each element must be freed when it is no longer needed. This can be
-  done all at once using bulk_free.
-
-  independent_comallac differs from independent_calloc in that each
-  element may have a different size, and also that it does not
-  automatically clear elements.
-
-  independent_comalloc can be used to speed up allocation in cases
-  where several structs or objects must always be allocated at the
-  same time.  For example:
-
-  struct Head { ... }
-  struct Foot { ... }
-
-  void send_message(char* msg) {
-    int msglen = strlen(msg);
-    size_t sizes[3] = { sizeof(struct Head), msglen, sizeof(struct Foot) };
-    void* chunks[3];
-    if (independent_comalloc(3, sizes, chunks) == 0)
-      die();
-    struct Head* head = (struct Head*)(chunks[0]);
-    char*        body = (char*)(chunks[1]);
-    struct Foot* foot = (struct Foot*)(chunks[2]);
-    // ...
-  }
-
-  In general though, independent_comalloc is worth using only for
-  larger values of n_elements. For small values, you probably won't
-  detect enough difference from series of malloc calls to bother.
-
-  Overuse of independent_comalloc can increase overall memory usage,
-  since it cannot reuse existing noncontiguous small chunks that
-  might be available for some of the elements.
-*/
-void** dlindependent_comalloc(size_t, size_t*, void**);
-
-/*
-  bulk_free(void* array[], size_t n_elements)
-  Frees and clears (sets to null) each non-null pointer in the given
-  array.  This is likely to be faster than freeing them one-by-one.
-  If footers are used, pointers that have been allocated in different
-  mspaces are not freed or cleared, and the count of all such pointers
-  is returned.  For large arrays of pointers with poor locality, it
-  may be worthwhile to sort this array before calling bulk_free.
-*/
-size_t  dlbulk_free(void**, size_t n_elements);
-
-/*
-  pvalloc(size_t n);
-  Equivalent to valloc(minimum-page-that-holds(n)), that is,
-  round up n to nearest pagesize.
- */
-void*  dlpvalloc(size_t);
-
-/*
-  malloc_trim(size_t pad);
-
-  If possible, gives memory back to the system (via negative arguments
-  to sbrk) if there is unused memory at the `high' end of the malloc
-  pool or in unused MMAP segments. You can call this after freeing
-  large blocks of memory to potentially reduce the system-level memory
-  requirements of a program. However, it cannot guarantee to reduce
-  memory. Under some allocation patterns, some large free blocks of
-  memory will be locked between two used chunks, so they cannot be
-  given back to the system.
-
-  The `pad' argument to malloc_trim represents the amount of free
-  trailing space to leave untrimmed. If this argument is zero, only
-  the minimum amount of memory to maintain internal data structures
-  will be left. Non-zero arguments can be supplied to maintain enough
-  trailing space to service future expected allocations without having
-  to re-obtain memory from the system.
-
-  Malloc_trim returns 1 if it actually released any memory, else 0.
-*/
-int  dlmalloc_trim(size_t);
-
-/*
-  malloc_stats();
-  Prints on stderr the amount of space obtained from the system (both
-  via sbrk and mmap), the maximum amount (which may be more than
-  current if malloc_trim and/or munmap got called), and the current
-  number of bytes allocated via malloc (or realloc, etc) but not yet
-  freed. Note that this is the number of bytes allocated, not the
-  number requested. It will be larger than the number requested
-  because of alignment and bookkeeping overhead. Because it includes
-  alignment wastage as being in use, this figure may be greater than
-  zero even when no user-level chunks are allocated.
-
-  The reported current and maximum system memory can be inaccurate if
-  a program makes other calls to system memory allocation functions
-  (normally sbrk) outside of malloc.
-
-  malloc_stats prints only the most commonly interesting statistics.
-  More information can be obtained by calling mallinfo.
-  
-  malloc_stats is not compiled if NO_MALLOC_STATS is defined.
-*/
-void  dlmalloc_stats(void);
-
-#endif /* !ONLY_MSPACES */
-
-/*
-  malloc_usable_size(void* p);
-
-  Returns the number of bytes you can actually use in
-  an allocated chunk, which may be more than you requested (although
-  often not) due to alignment and minimum size constraints.
-  You can use this many bytes without worrying about
-  overwriting other allocated objects. This is not a particularly great
-  programming practice. malloc_usable_size can be more useful in
-  debugging and assertions, for example:
-
-  p = malloc(n);
-  assert(malloc_usable_size(p) >= 256);
-*/
-size_t dlmalloc_usable_size(const void*);
-
-#if MSPACES
-
-/*
-  mspace is an opaque type representing an independent
-  region of space that supports mspace_malloc, etc.
-*/
-typedef void* mspace;
-
-/*
-  create_mspace creates and returns a new independent space with the
-  given initial capacity, or, if 0, the default granularity size.  It
-  returns null if there is no system memory available to create the
-  space.  If argument locked is non-zero, the space uses a separate
-  lock to control access. The capacity of the space will grow
-  dynamically as needed to service mspace_malloc requests.  You can
-  control the sizes of incremental increases of this space by
-  compiling with a different DEFAULT_GRANULARITY or dynamically
-  setting with mallopt(M_GRANULARITY, value).
-*/
-mspace create_mspace(size_t capacity, int locked);
-
-/*
-  destroy_mspace destroys the given space, and attempts to return all
-  of its memory back to the system, returning the total number of
-  bytes freed. After destruction, the results of access to all memory
-  used by the space become undefined.
-*/
-size_t destroy_mspace(mspace msp);
-
-/*
-  create_mspace_with_base uses the memory supplied as the initial base
-  of a new mspace. Part (less than 128*sizeof(size_t) bytes) of this
-  space is used for bookkeeping, so the capacity must be at least this
-  large. (Otherwise 0 is returned.) When this initial space is
-  exhausted, additional memory will be obtained from the system.
-  Destroying this space will deallocate all additionally allocated
-  space (if possible) but not the initial base.
-*/
-mspace create_mspace_with_base(void* base, size_t capacity, int locked);
-
-/*
-  mspace_track_large_chunks controls whether requests for large chunks
-  are allocated in their own untracked mmapped regions, separate from
-  others in this mspace. By default large chunks are not tracked,
-  which reduces fragmentation. However, such chunks are not
-  necessarily released to the system upon destroy_mspace.  Enabling
-  tracking by setting to true may increase fragmentation, but avoids
-  leakage when relying on destroy_mspace to release all memory
-  allocated using this space.  The function returns the previous
-  setting.
-*/
-int mspace_track_large_chunks(mspace msp, int enable);
-
-#if !NO_MALLINFO
-/*
-  mspace_mallinfo behaves as mallinfo, but reports properties of
-  the given space.
-*/
-struct mallinfo mspace_mallinfo(mspace msp);
-#endif /* NO_MALLINFO */
-
-/*
-  An alias for mallopt.
-*/
-int mspace_mallopt(int, int);
-
-/*
-  The following operate identically to their malloc counterparts
-  but operate only for the given mspace argument
-*/
-void* mspace_malloc(mspace msp, size_t bytes);
-void mspace_free(mspace msp, void* mem);
-void* mspace_calloc(mspace msp, size_t n_elements, size_t elem_size);
-void* mspace_realloc(mspace msp, void* mem, size_t newsize);
-void* mspace_realloc_in_place(mspace msp, void* mem, size_t newsize);
-void* mspace_memalign(mspace msp, size_t alignment, size_t bytes);
-void** mspace_independent_calloc(mspace msp, size_t n_elements,
-                                 size_t elem_size, void* chunks[]);
-void** mspace_independent_comalloc(mspace msp, size_t n_elements,
-                                   size_t sizes[], void* chunks[]);
-size_t mspace_bulk_free(mspace msp, void**, size_t n_elements);
-size_t mspace_usable_size(const void* mem);
-void mspace_malloc_stats(mspace msp);
-int mspace_trim(mspace msp, size_t pad);
-size_t mspace_footprint(mspace msp);
-size_t mspace_max_footprint(mspace msp);
-size_t mspace_footprint_limit(mspace msp);
-size_t mspace_set_footprint_limit(mspace msp, size_t bytes);
-void mspace_inspect_all(mspace msp, 
-                        void(*handler)(void *, void *, size_t, void*),
-                        void* arg);
-#endif  /* MSPACES */
-
-#ifdef __cplusplus
-};  /* end of extern "C" */
-#endif
-
-#endif /* MALLOC_280_H */
diff --git a/libc/upstream-freebsd/lib/libc/stdlib/imaxabs.c b/libc/upstream-freebsd/lib/libc/stdlib/imaxabs.c
deleted file mode 100644
index 35e3dee..0000000
--- a/libc/upstream-freebsd/lib/libc/stdlib/imaxabs.c
+++ /dev/null
@@ -1,36 +0,0 @@
-/*-
- * Copyright (c) 2001 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.
- */
-
-#include <sys/cdefs.h>
-__FBSDID("$FreeBSD$");
-
-#include <inttypes.h>
-
-intmax_t
-imaxabs(intmax_t j)
-{
-	return (j < 0 ? -j : j);
-}
diff --git a/libc/upstream-freebsd/lib/libc/stdlib/imaxdiv.c b/libc/upstream-freebsd/lib/libc/stdlib/imaxdiv.c
deleted file mode 100644
index 7dae467..0000000
--- a/libc/upstream-freebsd/lib/libc/stdlib/imaxdiv.c
+++ /dev/null
@@ -1,45 +0,0 @@
-/*-
- * Copyright (c) 2001 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.
- */
-
-#include <sys/cdefs.h>
-__FBSDID("$FreeBSD$");
-
-#include <inttypes.h>
-
-/* See comments in div.c for implementation details. */
-imaxdiv_t
-imaxdiv(intmax_t numer, intmax_t denom)
-{
-	imaxdiv_t retval;
-
-	retval.quot = numer / denom;
-	retval.rem = numer % denom;
-	if (numer >= 0 && retval.rem < 0) {
-		retval.quot++;
-		retval.rem -= denom;
-	}
-	return (retval);
-}
diff --git a/libc/upstream-freebsd/lib/libc/stdlib/llabs.c b/libc/upstream-freebsd/lib/libc/stdlib/llabs.c
deleted file mode 100644
index 2bfbada..0000000
--- a/libc/upstream-freebsd/lib/libc/stdlib/llabs.c
+++ /dev/null
@@ -1,36 +0,0 @@
-/*-
- * Copyright (c) 2001 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.
- */
-
-#include <sys/cdefs.h>
-__FBSDID("$FreeBSD$");
-
-#include <stdlib.h>
-
-long long
-llabs(long long j)
-{
-	return (j < 0 ? -j : j);
-}
diff --git a/libc/upstream-netbsd/android/include/netbsd-compat.h b/libc/upstream-netbsd/android/include/netbsd-compat.h
index 8d1c46b..bfd0401 100644
--- a/libc/upstream-netbsd/android/include/netbsd-compat.h
+++ b/libc/upstream-netbsd/android/include/netbsd-compat.h
@@ -20,18 +20,17 @@
 #define _BSD_SOURCE
 #define _GNU_SOURCE
 
-// NetBSD uses _DIAGASSERT to null-check arguments and the like.
-#include <assert.h>
-#define _DIAGASSERT(e) ((e) ? (void) 0 : __assert2(__FILE__, __LINE__, __func__, #e))
-
-// TODO: update our <sys/cdefs.h> to support this properly.
-#define __type_fit(t, a) (0 == 0)
+// NetBSD uses _DIAGASSERT to null-check arguments and the like,
+// but it's clear from the number of mistakes in their assertions
+// that they don't actually test or ship with this.
+#define _DIAGASSERT(e) /* nothing */
 
 // TODO: we don't yet have thread-safe environment variables.
 #define __readlockenv() 0
 #define __unlockenv() 0
 
+#include <sys/cdefs.h>
 #include <stddef.h>
-__LIBC_HIDDEN__ int reallocarr(void*, size_t, size_t);
+int reallocarr(void*, size_t, size_t);
 
 #endif
diff --git a/libc/upstream-openbsd/android/include/arc4random.h b/libc/upstream-openbsd/android/include/arc4random.h
index c07257d..96d9c9a 100644
--- a/libc/upstream-openbsd/android/include/arc4random.h
+++ b/libc/upstream-openbsd/android/include/arc4random.h
@@ -27,6 +27,8 @@
 #include <pthread.h>
 #include <signal.h>
 
+#include "private/bionic_prctl.h"
+
 // Android gets these from "thread_private.h".
 #include "thread_private.h"
 //static pthread_mutex_t arc4random_mtx = PTHREAD_MUTEX_INITIALIZER;
@@ -76,12 +78,18 @@
 	    MAP_ANON|MAP_PRIVATE, -1, 0)) == MAP_FAILED)
 		return (-1);
 
+	prctl(PR_SET_VMA, PR_SET_VMA_ANON_NAME, *rsp, sizeof(**rsp),
+	    "arc4random _rs structure");
+
 	if ((*rsxp = mmap(NULL, sizeof(**rsxp), PROT_READ|PROT_WRITE,
 	    MAP_ANON|MAP_PRIVATE, -1, 0)) == MAP_FAILED) {
 		munmap(*rsxp, sizeof(**rsxp));
 		return (-1);
 	}
 
+	prctl(PR_SET_VMA, PR_SET_VMA_ANON_NAME, *rsxp, sizeof(**rsxp),
+	    "arc4random _rsx structure");
+
 	_ARC4_ATFORK(_rs_forkhandler);
 	return (0);
 }
diff --git a/libc/upstream-openbsd/android/include/openbsd-compat.h b/libc/upstream-openbsd/android/include/openbsd-compat.h
index 47bacc3..caea45a 100644
--- a/libc/upstream-openbsd/android/include/openbsd-compat.h
+++ b/libc/upstream-openbsd/android/include/openbsd-compat.h
@@ -32,8 +32,9 @@
 #define _warn warn
 #define _warnx warnx
 
-/* Ignore all __weak_alias in OpenBSD. */
-#define __weak_alias(alias,sym)
+/* Ignore all DEF_STRONG/DEF_WEAK in OpenBSD. */
+#define DEF_STRONG(sym)
+#define DEF_WEAK(sym)
 
 /* Ignore all __warn_references in OpenBSD. */
 #define __warn_references(sym,msg)
@@ -71,8 +72,8 @@
 __LIBC_HIDDEN__ void* reallocarray(void*, size_t, size_t);
 
 /* LP32 NDK ctype.h contained references to these. */
-__LIBC64_HIDDEN__ extern const short* _tolower_tab_;
-__LIBC64_HIDDEN__ extern const short* _toupper_tab_;
+__LIBC32_LEGACY_PUBLIC__ extern const short* _tolower_tab_;
+__LIBC32_LEGACY_PUBLIC__ extern const short* _toupper_tab_;
 
 __LIBC_HIDDEN__ extern const char _C_ctype_[];
 __LIBC_HIDDEN__ extern const short _C_toupper_[];
diff --git a/libc/upstream-openbsd/lib/libc/gen/err.c b/libc/upstream-openbsd/lib/libc/gen/err.c
index e7ec29d..15e1b97 100644
--- a/libc/upstream-openbsd/lib/libc/gen/err.c
+++ b/libc/upstream-openbsd/lib/libc/gen/err.c
@@ -1,4 +1,4 @@
-/*	$OpenBSD: err.c,v 1.11 2012/12/05 23:19:59 deraadt Exp $ */
+/*	$OpenBSD: err.c,v 1.12 2015/08/31 02:53:57 guenther Exp $ */
 /*-
  * Copyright (c) 1993
  *	The Regents of the University of California.  All rights reserved.
@@ -31,17 +31,13 @@
 #include <err.h>
 #include <stdarg.h>
 
-/* PRINTFLIKE2 */
 __dead void
-_err(int eval, const char *fmt, ...)
+err(int eval, const char *fmt, ...)
 {
 	va_list ap;
 
 	va_start(ap, fmt);
-	_verr(eval, fmt, ap);
+	verr(eval, fmt, ap);
 	va_end(ap);
 }
-
-/* PRINTFLIKE2 */
-__weak_alias(err, _err);
-
+DEF_WEAK(err);
diff --git a/libc/upstream-openbsd/lib/libc/gen/errx.c b/libc/upstream-openbsd/lib/libc/gen/errx.c
index d213435..e6b5d23 100644
--- a/libc/upstream-openbsd/lib/libc/gen/errx.c
+++ b/libc/upstream-openbsd/lib/libc/gen/errx.c
@@ -1,4 +1,4 @@
-/*	$OpenBSD: errx.c,v 1.10 2012/12/05 23:19:59 deraadt Exp $ */
+/*	$OpenBSD: errx.c,v 1.11 2015/08/31 02:53:57 guenther Exp $ */
 /*-
  * Copyright (c) 1993
  *	The Regents of the University of California.  All rights reserved.
@@ -31,17 +31,13 @@
 #include <err.h>
 #include <stdarg.h>
 
-/* PRINTFLIKE2 */
 __dead void
-_errx(int eval, const char *fmt, ...)
+errx(int eval, const char *fmt, ...)
 {
 	va_list ap;
 
 	va_start(ap, fmt);
-	_verrx(eval, fmt, ap);
+	verrx(eval, fmt, ap);
 	va_end(ap);
 }
-
-/* PRINTFLIKE2 */
-__weak_alias(errx, _errx);
-
+DEF_WEAK(errx);
diff --git a/libc/upstream-openbsd/lib/libc/gen/fnmatch.c b/libc/upstream-openbsd/lib/libc/gen/fnmatch.c
index 2c860f7..0d0f18f 100644
--- a/libc/upstream-openbsd/lib/libc/gen/fnmatch.c
+++ b/libc/upstream-openbsd/lib/libc/gen/fnmatch.c
@@ -1,4 +1,4 @@
-/*	$OpenBSD: fnmatch.c,v 1.17 2013/11/24 23:51:29 deraadt Exp $	*/
+/*	$OpenBSD: fnmatch.c,v 1.19 2015/08/01 18:11:08 millert Exp $	*/
 
 /* Copyright (c) 2011, VMware, Inc.
  * All rights reserved.
@@ -88,7 +88,6 @@
 #include <fnmatch.h>
 #include <string.h>
 #include <ctype.h>
-#include <limits.h>
 
 #include "charclass.h"
 
@@ -193,6 +192,8 @@
                 result = 0;
                 continue;
             }
+            if (!**pattern)
+                break;
 
 leadingclosebrace:
             /* Look at only well-formed range patterns; 
@@ -294,10 +295,6 @@
     const char *mismatch = NULL;
     int matchlen = 0;
 
-    if (strnlen(pattern, PATH_MAX) == PATH_MAX ||
-        strnlen(string, PATH_MAX) == PATH_MAX)
-            return (FNM_NOMATCH);
-
     if (*pattern == '*')
         goto firstsegment;
 
diff --git a/libc/upstream-openbsd/lib/libc/gen/time.c b/libc/upstream-openbsd/lib/libc/gen/time.c
index 3a57500..6fcf1cd 100644
--- a/libc/upstream-openbsd/lib/libc/gen/time.c
+++ b/libc/upstream-openbsd/lib/libc/gen/time.c
@@ -1,4 +1,4 @@
-/*	$OpenBSD: time.c,v 1.5 2005/08/08 08:05:34 espie Exp $ */
+/*	$OpenBSD: time.c,v 1.7 2015/10/29 03:58:55 mmcc Exp $ */
 /*
  * Copyright (c) 1983, 1993
  *	The Regents of the University of California.  All rights reserved.
@@ -28,17 +28,18 @@
  * SUCH DAMAGE.
  */
 
-#include <sys/types.h>
 #include <sys/time.h>
+#include <time.h>
 
 time_t
 time(time_t *t)
 {
 	struct timeval tt;
 
-	if (gettimeofday(&tt, (struct timezone *)0) < 0)
+	if (gettimeofday(&tt, NULL) < 0)
 		return (-1);
 	if (t)
 		*t = (time_t)tt.tv_sec;
 	return (tt.tv_sec);
 }
+DEF_STRONG(time);
diff --git a/libc/upstream-openbsd/lib/libc/gen/verr.c b/libc/upstream-openbsd/lib/libc/gen/verr.c
index dcd8edc..8f4722b 100644
--- a/libc/upstream-openbsd/lib/libc/gen/verr.c
+++ b/libc/upstream-openbsd/lib/libc/gen/verr.c
@@ -1,4 +1,4 @@
-/*	$OpenBSD: verr.c,v 1.9 2012/12/05 23:20:00 deraadt Exp $ */
+/*	$OpenBSD: verr.c,v 1.10 2015/08/31 02:53:57 guenther Exp $ */
 /*-
  * Copyright (c) 1993
  *	The Regents of the University of California.  All rights reserved.
@@ -38,7 +38,7 @@
 extern char *__progname;		/* Program name, from crt0. */
 
 __dead void
-_verr(int eval, const char *fmt, va_list ap)
+verr(int eval, const char *fmt, va_list ap)
 {
 	int sverrno;
 
@@ -51,6 +51,4 @@
 	(void)fprintf(stderr, "%s\n", strerror(sverrno));
 	exit(eval);
 }
-
-__weak_alias(verr, _verr);
-
+DEF_WEAK(verr);
diff --git a/libc/upstream-openbsd/lib/libc/gen/verrx.c b/libc/upstream-openbsd/lib/libc/gen/verrx.c
index 60da062..f0186b6 100644
--- a/libc/upstream-openbsd/lib/libc/gen/verrx.c
+++ b/libc/upstream-openbsd/lib/libc/gen/verrx.c
@@ -1,4 +1,4 @@
-/*	$OpenBSD: verrx.c,v 1.9 2012/12/05 23:20:00 deraadt Exp $ */
+/*	$OpenBSD: verrx.c,v 1.10 2015/08/31 02:53:57 guenther Exp $ */
 /*-
  * Copyright (c) 1993
  *	The Regents of the University of California.  All rights reserved.
@@ -36,7 +36,7 @@
 extern char *__progname;		/* Program name, from crt0. */
 
 __dead void
-_verrx(int eval, const char *fmt, va_list ap)
+verrx(int eval, const char *fmt, va_list ap)
 {
 	(void)fprintf(stderr, "%s: ", __progname);
 	if (fmt != NULL)
@@ -44,6 +44,4 @@
 	(void)fprintf(stderr, "\n");
 	exit(eval);
 }
-
-__weak_alias(verrx, _verrx);
-
+DEF_WEAK(verrx);
diff --git a/libc/upstream-openbsd/lib/libc/gen/vwarn.c b/libc/upstream-openbsd/lib/libc/gen/vwarn.c
index 26b60f3..44d8be4 100644
--- a/libc/upstream-openbsd/lib/libc/gen/vwarn.c
+++ b/libc/upstream-openbsd/lib/libc/gen/vwarn.c
@@ -1,4 +1,4 @@
-/*	$OpenBSD: vwarn.c,v 1.9 2012/12/05 23:20:00 deraadt Exp $ */
+/*	$OpenBSD: vwarn.c,v 1.10 2015/08/31 02:53:57 guenther Exp $ */
 /*-
  * Copyright (c) 1993
  *	The Regents of the University of California.  All rights reserved.
@@ -37,7 +37,7 @@
 extern char *__progname;		/* Program name, from crt0. */
 
 void
-_vwarn(const char *fmt, va_list ap)
+vwarn(const char *fmt, va_list ap)
 {
 	int sverrno;
 
@@ -49,6 +49,4 @@
 	}
 	(void)fprintf(stderr, "%s\n", strerror(sverrno));
 }
-
-__weak_alias(vwarn, _vwarn);
-
+DEF_WEAK(vwarn);
diff --git a/libc/upstream-openbsd/lib/libc/gen/vwarnx.c b/libc/upstream-openbsd/lib/libc/gen/vwarnx.c
index e6b1957..67d8f5b 100644
--- a/libc/upstream-openbsd/lib/libc/gen/vwarnx.c
+++ b/libc/upstream-openbsd/lib/libc/gen/vwarnx.c
@@ -1,4 +1,4 @@
-/*	$OpenBSD: vwarnx.c,v 1.9 2012/12/05 23:20:00 deraadt Exp $ */
+/*	$OpenBSD: vwarnx.c,v 1.10 2015/08/31 02:53:57 guenther Exp $ */
 /*-
  * Copyright (c) 1993
  *	The Regents of the University of California.  All rights reserved.
@@ -35,13 +35,11 @@
 extern char *__progname;		/* Program name, from crt0. */
 
 void
-_vwarnx(const char *fmt, va_list ap)
+vwarnx(const char *fmt, va_list ap)
 {
 	(void)fprintf(stderr, "%s: ", __progname);
 	if (fmt != NULL)
 		(void)vfprintf(stderr, fmt, ap);
 	(void)fprintf(stderr, "\n");
 }
-
-__weak_alias(vwarnx, _vwarnx);
-
+DEF_WEAK(vwarnx);
diff --git a/libc/upstream-openbsd/lib/libc/gen/warn.c b/libc/upstream-openbsd/lib/libc/gen/warn.c
index c1b47a6..6784cf6 100644
--- a/libc/upstream-openbsd/lib/libc/gen/warn.c
+++ b/libc/upstream-openbsd/lib/libc/gen/warn.c
@@ -1,4 +1,4 @@
-/*	$OpenBSD: warn.c,v 1.10 2012/12/05 23:20:00 deraadt Exp $ */
+/*	$OpenBSD: warn.c,v 1.11 2015/08/31 02:53:57 guenther Exp $ */
 /*-
  * Copyright (c) 1993
  *	The Regents of the University of California.  All rights reserved.
@@ -31,17 +31,13 @@
 #include <err.h>
 #include <stdarg.h>
 
-/* PRINTFLIKE1 */
 void
-_warn(const char *fmt, ...)
+warn(const char *fmt, ...)
 {
 	va_list ap;
 
 	va_start(ap, fmt);
-	_vwarn(fmt, ap);
+	vwarn(fmt, ap);
 	va_end(ap);
 }
-
-/* PRINTFLIKE1 */
-__weak_alias(warn, _warn);
-
+DEF_WEAK(warn);
diff --git a/libc/upstream-openbsd/lib/libc/gen/warnx.c b/libc/upstream-openbsd/lib/libc/gen/warnx.c
index af2ab66..723bc0d 100644
--- a/libc/upstream-openbsd/lib/libc/gen/warnx.c
+++ b/libc/upstream-openbsd/lib/libc/gen/warnx.c
@@ -1,4 +1,4 @@
-/*	$OpenBSD: warnx.c,v 1.9 2012/12/05 23:20:00 deraadt Exp $ */
+/*	$OpenBSD: warnx.c,v 1.10 2015/08/31 02:53:57 guenther Exp $ */
 /*-
  * Copyright (c) 1993
  *	The Regents of the University of California.  All rights reserved.
@@ -31,17 +31,13 @@
 #include <err.h>
 #include <stdarg.h>
 
-/* PRINTFLIKE1 */
 void
-_warnx(const char *fmt, ...)
+warnx(const char *fmt, ...)
 {
 	va_list ap;
 
 	va_start(ap, fmt);
-	_vwarnx(fmt, ap);
+	vwarnx(fmt, ap);
 	va_end(ap);
 }
-
-/* PRINTFLIKE1 */
-__weak_alias(warnx, _warnx);
-
+DEF_WEAK(warnx);
diff --git a/libc/upstream-openbsd/lib/libc/net/inet_addr.c b/libc/upstream-openbsd/lib/libc/net/inet_addr.c
deleted file mode 100644
index 18762ab..0000000
--- a/libc/upstream-openbsd/lib/libc/net/inet_addr.c
+++ /dev/null
@@ -1,175 +0,0 @@
-/*	$OpenBSD: inet_addr.c,v 1.10 2013/11/24 23:51:28 deraadt Exp $	*/
-
-/*
- * ++Copyright++ 1983, 1990, 1993
- * -
- * Copyright (c) 1983, 1990, 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.
- * -
- * Portions Copyright (c) 1993 by Digital Equipment Corporation.
- * 
- * Permission to use, copy, modify, and distribute this software for any
- * purpose with or without fee is hereby granted, provided that the above
- * copyright notice and this permission notice appear in all copies, and that
- * the name of Digital Equipment Corporation not be used in advertising or
- * publicity pertaining to distribution of the document or software without
- * specific, written prior permission.
- * 
- * THE SOFTWARE IS PROVIDED "AS IS" AND DIGITAL EQUIPMENT CORP. DISCLAIMS ALL
- * WARRANTIES WITH REGARD TO THIS SOFTWARE, INCLUDING ALL IMPLIED WARRANTIES
- * OF MERCHANTABILITY AND FITNESS.   IN NO EVENT SHALL DIGITAL EQUIPMENT
- * CORPORATION BE LIABLE FOR ANY SPECIAL, DIRECT, INDIRECT, OR CONSEQUENTIAL
- * DAMAGES OR ANY DAMAGES WHATSOEVER RESULTING FROM LOSS OF USE, DATA OR
- * PROFITS, WHETHER IN AN ACTION OF CONTRACT, NEGLIGENCE OR OTHER TORTIOUS
- * ACTION, ARISING OUT OF OR IN CONNECTION WITH THE USE OR PERFORMANCE OF THIS
- * SOFTWARE.
- * -
- * --Copyright--
- */
-
-#include <sys/types.h>
-#include <sys/param.h>
-#include <netinet/in.h>
-#include <arpa/inet.h>
-#include <ctype.h>
-
-/*
- * Ascii internet address interpretation routine.
- * The value returned is in network order.
- */
-in_addr_t
-inet_addr(const char *cp)
-{
-	struct in_addr val;
-
-	if (inet_aton(cp, &val))
-		return (val.s_addr);
-	return (INADDR_NONE);
-}
-
-/* 
- * Check whether "cp" is a valid ascii representation
- * of an Internet address and convert to a binary address.
- * Returns 1 if the address is valid, 0 if not.
- * This replaces inet_addr, the return value from which
- * cannot distinguish between failure and a local broadcast address.
- */
-int
-inet_aton(const char *cp, struct in_addr *addr)
-{
-	in_addr_t val;
-	int base, n;
-	char c;
-	u_int parts[4];
-	u_int *pp = parts;
-
-	c = *cp;
-	for (;;) {
-		/*
-		 * Collect number up to ``.''.
-		 * Values are specified as for C:
-		 * 0x=hex, 0=octal, isdigit=decimal.
-		 */
-		if (!isdigit((unsigned char)c))
-			return (0);
-		val = 0; base = 10;
-		if (c == '0') {
-			c = *++cp;
-			if (c == 'x' || c == 'X')
-				base = 16, c = *++cp;
-			else
-				base = 8;
-		}
-		for (;;) {
-			if (isascii((unsigned char)c) &&
-			    isdigit((unsigned char)c)) {
-				val = (val * base) + (c - '0');
-				c = *++cp;
-			} else if (base == 16 &&
-			    isascii((unsigned char)c) &&
-			    isxdigit((unsigned char)c)) {
-				val = (val << 4) |
-				    (c + 10 - (islower((unsigned char)c) ? 'a' : 'A'));
-				c = *++cp;
-			} else
-				break;
-		}
-		if (c == '.') {
-			/*
-			 * Internet format:
-			 *	a.b.c.d
-			 *	a.b.c	(with c treated as 16 bits)
-			 *	a.b	(with b treated as 24 bits)
-			 */
-			if (pp >= parts + 3)
-				return (0);
-			*pp++ = val;
-			c = *++cp;
-		} else
-			break;
-	}
-	/*
-	 * Check for trailing characters.
-	 */
-	if (c != '\0' &&
-	    (!isascii((unsigned char)c) || !isspace((unsigned char)c)))
-		return (0);
-	/*
-	 * Concoct the address according to
-	 * the number of parts specified.
-	 */
-	n = pp - parts + 1;
-	switch (n) {
-
-	case 0:
-		return (0);		/* initial nondigit */
-
-	case 1:				/* a -- 32 bits */
-		break;
-
-	case 2:				/* a.b -- 8.24 bits */
-		if ((val > 0xffffff) || (parts[0] > 0xff))
-			return (0);
-		val |= parts[0] << 24;
-		break;
-
-	case 3:				/* a.b.c -- 8.8.16 bits */
-		if ((val > 0xffff) || (parts[0] > 0xff) || (parts[1] > 0xff))
-			return (0);
-		val |= (parts[0] << 24) | (parts[1] << 16);
-		break;
-
-	case 4:				/* a.b.c.d -- 8.8.8.8 bits */
-		if ((val > 0xff) || (parts[0] > 0xff) || (parts[1] > 0xff) || (parts[2] > 0xff))
-			return (0);
-		val |= (parts[0] << 24) | (parts[1] << 16) | (parts[2] << 8);
-		break;
-	}
-	if (addr)
-		addr->s_addr = htonl(val);
-	return (1);
-}
diff --git a/libc/upstream-openbsd/lib/libc/net/inet_network.c b/libc/upstream-openbsd/lib/libc/net/inet_network.c
deleted file mode 100644
index ecf554e..0000000
--- a/libc/upstream-openbsd/lib/libc/net/inet_network.c
+++ /dev/null
@@ -1,84 +0,0 @@
-/*	$OpenBSD: inet_network.c,v 1.11 2013/11/25 17:29:19 deraadt Exp $ */
-/*
- * Copyright (c) 1983, 1993
- *	The Regents of the University of California.  All rights reserved.
- *
- * Redistribution and use in source and binary forms, with or without
- * modification, are permitted provided that the following conditions
- * are met:
- * 1. Redistributions of source code must retain the above copyright
- *    notice, this list of conditions and the following disclaimer.
- * 2. Redistributions in binary form must reproduce the above copyright
- *    notice, this list of conditions and the following disclaimer in the
- *    documentation and/or other materials provided with the distribution.
- * 3. Neither the name of the University nor the names of its contributors
- *    may be used to endorse or promote products derived from this software
- *    without specific prior written permission.
- *
- * THIS SOFTWARE IS PROVIDED BY THE REGENTS AND CONTRIBUTORS ``AS IS'' AND
- * ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE
- * IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE
- * ARE DISCLAIMED.  IN NO EVENT SHALL THE REGENTS OR CONTRIBUTORS BE LIABLE
- * FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL
- * DAMAGES (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS
- * OR SERVICES; LOSS OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION)
- * HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT
- * LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY
- * OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF
- * SUCH DAMAGE.
- */
-
-#include <sys/types.h>
-#include <netinet/in.h>
-#include <arpa/inet.h>
-#include <ctype.h>
-
-/*
- * Internet network address interpretation routine.
- * The library routines call this routine to interpret
- * network numbers.
- */
-in_addr_t
-inet_network(const char *cp)
-{
-	in_addr_t val, base, n;
-	u_char c;
-	in_addr_t parts[4], *pp = parts;
-	int i;
-
-again:
-	val = 0; base = 10;
-	if (*cp == '0')
-		base = 8, cp++;
-	if (*cp == 'x' || *cp == 'X')
-		base = 16, cp++;
-	while ((c = *cp)) {
-		if (isdigit(c)) {
-			val = (val * base) + (c - '0');
-			cp++;
-			continue;
-		}
-		if (base == 16 && isxdigit(c)) {
-			val = (val << 4) + (c + 10 - (islower(c) ? 'a' : 'A'));
-			cp++;
-			continue;
-		}
-		break;
-	}
-	if (*cp == '.') {
-		if (pp >= parts + 3)
-			return (INADDR_NONE);
-		*pp++ = val, cp++;
-		goto again;
-	}
-	if (*cp && !isspace(*cp))
-		return (INADDR_NONE);
-	*pp++ = val;
-	n = pp - parts;
-	for (val = 0, i = 0; i < 4; i++) {
-		val <<= 8;
-		if (i < n)
-			val |= parts[i] & 0xff;
-	}
-	return (val);
-}
diff --git a/libc/upstream-openbsd/lib/libc/net/res_random.c b/libc/upstream-openbsd/lib/libc/net/res_random.c
index f28692f..72b9c41 100644
--- a/libc/upstream-openbsd/lib/libc/net/res_random.c
+++ b/libc/upstream-openbsd/lib/libc/net/res_random.c
@@ -1,4 +1,4 @@
-/* $OpenBSD: res_random.c,v 1.21 2014/07/20 04:22:34 guenther Exp $ */
+/* $OpenBSD: res_random.c,v 1.23 2015/10/05 02:57:16 guenther Exp $ */
 
 /*
  * Copyright 1997 Niels Provos <provos@physnet.uni-hamburg.de>
@@ -101,6 +101,7 @@
 static u_int16_t ru_msb = 0;
 static struct prf_ctx *ru_prf = NULL;
 static time_t ru_reseed;
+static pid_t ru_pid;
 
 static u_int16_t pmod(u_int16_t, u_int16_t, u_int16_t);
 static void res_initid(void);
@@ -224,18 +225,22 @@
 }
 
 u_int
-res_randomid(void)
+__res_randomid(void)
 {
 	struct timespec ts;
+	pid_t pid;
 	u_int r;
 	_THREAD_PRIVATE_MUTEX(random);
 
 	clock_gettime(CLOCK_MONOTONIC, &ts);
+	pid = getpid();
 
 	_THREAD_PRIVATE_MUTEX_LOCK(random);
 
-	if (ru_counter >= RU_MAX || ts.tv_sec > ru_reseed)
+	if (ru_counter >= RU_MAX || ts.tv_sec > ru_reseed || pid != ru_pid) {
 		res_initid();
+		ru_pid = pid;
+	}
 
 	/* Linear Congruential Generator */
 	ru_x = (ru_a * ru_x + ru_b) % RU_M;
@@ -247,6 +252,7 @@
 
 	return (r);
 }
+DEF_STRONG(__res_randomid);
 
 #if 0
 int
diff --git a/libc/upstream-openbsd/lib/libc/stdio/asprintf.c b/libc/upstream-openbsd/lib/libc/stdio/asprintf.c
index 5424c90..4823677 100644
--- a/libc/upstream-openbsd/lib/libc/stdio/asprintf.c
+++ b/libc/upstream-openbsd/lib/libc/stdio/asprintf.c
@@ -1,4 +1,4 @@
-/*	$OpenBSD: asprintf.c,v 1.19 2011/05/30 18:48:33 martynas Exp $	*/
+/*	$OpenBSD: asprintf.c,v 1.22 2015/12/28 22:08:18 mmcc Exp $	*/
 
 /*
  * Copyright (c) 1997 Todd C. Miller <Todd.Miller@courtesan.com>
@@ -23,7 +23,6 @@
 #include <stdarg.h>
 #include "local.h"
 
-/* PRINTFLIKE2 */
 int
 asprintf(char **str, const char *fmt, ...)
 {
@@ -36,7 +35,7 @@
 	_FILEEXT_SETUP(&f, &fext);
 	f._file = -1;
 	f._flags = __SWR | __SSTR | __SALC;
-	f._bf._base = f._p = (unsigned char *)malloc(128);
+	f._bf._base = f._p = malloc(128);
 	if (f._bf._base == NULL)
 		goto err;
 	f._bf._size = f._w = 127;		/* Leave room for the NUL */
@@ -53,11 +52,10 @@
 	return (ret);
 
 err:
-	if (f._bf._base) {
-		free(f._bf._base);
-		f._bf._base = NULL;
-	}
+	free(f._bf._base);
+	f._bf._base = NULL;
 	*str = NULL;
 	errno = ENOMEM;
 	return (-1);
 }
+DEF_WEAK(asprintf);
diff --git a/libc/upstream-openbsd/lib/libc/stdio/fclose.c b/libc/upstream-openbsd/lib/libc/stdio/fclose.c
deleted file mode 100644
index c72af54..0000000
--- a/libc/upstream-openbsd/lib/libc/stdio/fclose.c
+++ /dev/null
@@ -1,63 +0,0 @@
-/*	$OpenBSD: fclose.c,v 1.9 2009/11/09 00:18:27 kurt 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 <stdlib.h>
-#include "local.h"
-
-int
-fclose(FILE *fp)
-{
-	int r;
-
-	if (fp->_flags == 0) {	/* not open! */
-		errno = EBADF;
-		return (EOF);
-	}
-	FLOCKFILE(fp);
-	WCIO_FREE(fp);
-	r = fp->_flags & __SWR ? __sflush(fp) : 0;
-	if (fp->_close != NULL && (*fp->_close)(fp->_cookie) < 0)
-		r = EOF;
-	if (fp->_flags & __SMBF)
-		free((char *)fp->_bf._base);
-	if (HASUB(fp))
-		FREEUB(fp);
-	if (HASLB(fp))
-		FREELB(fp);
-	fp->_r = fp->_w = 0;	/* Mess up if reaccessed. */
-	fp->_flags = 0;		/* Release this FILE for reuse. */
-	FUNLOCKFILE(fp);
-	return (r);
-}
diff --git a/libc/upstream-openbsd/lib/libc/stdio/fdopen.c b/libc/upstream-openbsd/lib/libc/stdio/fdopen.c
deleted file mode 100644
index 1c0c813..0000000
--- a/libc/upstream-openbsd/lib/libc/stdio/fdopen.c
+++ /dev/null
@@ -1,91 +0,0 @@
-/*	$OpenBSD: fdopen.c,v 1.7 2014/08/31 02:21:18 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 <sys/types.h>
-#include <fcntl.h>
-#include <limits.h>
-#include <unistd.h>
-#include <stdio.h>
-#include <errno.h>
-#include "local.h"
-
-FILE *
-fdopen(int fd, const char *mode)
-{
-	FILE *fp;
-	int flags, oflags, fdflags, tmp;
-
-	/* _file is only a short */
-	if (fd > SHRT_MAX) {
-		errno = EMFILE;
-		return (NULL);
-	}
-
-	if ((flags = __sflags(mode, &oflags)) == 0)
-		return (NULL);
-
-	/* Make sure the mode the user wants is a subset of the actual mode. */
-	if ((fdflags = fcntl(fd, F_GETFL, 0)) < 0)
-		return (NULL);
-	tmp = fdflags & O_ACCMODE;
-	if (tmp != O_RDWR && (tmp != (oflags & O_ACCMODE))) {
-		errno = EINVAL;
-		return (NULL);
-	}
-
-	if ((fp = __sfp()) == NULL)
-		return (NULL);
-	fp->_flags = flags;
-
-	/*
-	 * If opened for appending, but underlying descriptor does not have
-	 * O_APPEND bit set, assert __SAPP so that __swrite() will lseek to
-	 * end before each write.
-	 */
-	if ((oflags & O_APPEND) && !(fdflags & O_APPEND))
-		fp->_flags |= __SAPP;
-
-	/*
-	 * If close-on-exec was requested, then turn it on if not already
-	 */
-	if ((oflags & O_CLOEXEC) && !((tmp = fcntl(fd, F_GETFD)) & FD_CLOEXEC))
-		fcntl(fd, F_SETFD, tmp | FD_CLOEXEC);
-
-	fp->_file = fd;
-	fp->_cookie = fp;
-	fp->_read = __sread;
-	fp->_write = __swrite;
-	fp->_seek = __sseek;
-	fp->_close = __sclose;
-	return (fp);
-}
diff --git a/libc/upstream-openbsd/lib/libc/stdio/fgetpos.c b/libc/upstream-openbsd/lib/libc/stdio/fgetpos.c
deleted file mode 100644
index e6188e5..0000000
--- a/libc/upstream-openbsd/lib/libc/stdio/fgetpos.c
+++ /dev/null
@@ -1,43 +0,0 @@
-/*	$OpenBSD: fgetpos.c,v 1.6 2005/08/08 08:05:36 espie 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>
-
-/*
- * fgetpos: like ftello.
- */
-int
-fgetpos(FILE *fp, fpos_t *pos)
-{
-	return((*pos = ftello(fp)) == (fpos_t)-1);
-}
diff --git a/libc/upstream-openbsd/lib/libc/stdio/fgetwc.c b/libc/upstream-openbsd/lib/libc/stdio/fgetwc.c
index c16ffaf..2e69191 100644
--- a/libc/upstream-openbsd/lib/libc/stdio/fgetwc.c
+++ b/libc/upstream-openbsd/lib/libc/stdio/fgetwc.c
@@ -1,4 +1,4 @@
-/*	$OpenBSD: fgetwc.c,v 1.4 2009/11/09 00:18:27 kurt Exp $	*/
+/*	$OpenBSD: fgetwc.c,v 1.6 2015/12/24 19:55:39 schwarze Exp $	*/
 /* $NetBSD: fgetwc.c,v 1.3 2003/03/07 07:11:36 tshiozak Exp $ */
 
 /*-
@@ -69,7 +69,7 @@
 		c = ch;
 		size = mbrtowc(&wc, &c, 1, st);
 		if (size == (size_t)-1) {
-			errno = EILSEQ;
+			fp->_flags |= __SERR;
 			return WEOF;
 		}
 	} while (size == (size_t)-2);
@@ -88,3 +88,4 @@
 
 	return (r);
 }
+DEF_STRONG(fgetwc);
diff --git a/libc/upstream-openbsd/lib/libc/stdio/fgetws.c b/libc/upstream-openbsd/lib/libc/stdio/fgetws.c
index e8cd249..d02ccd5 100644
--- a/libc/upstream-openbsd/lib/libc/stdio/fgetws.c
+++ b/libc/upstream-openbsd/lib/libc/stdio/fgetws.c
@@ -1,4 +1,4 @@
-/*	$OpenBSD: fgetws.c,v 1.6 2009/11/09 00:18:27 kurt Exp $	*/
+/*	$OpenBSD: fgetws.c,v 1.8 2016/01/04 16:14:19 schwarze Exp $	*/
 /* $NetBSD: fgetws.c,v 1.1 2003/03/07 07:11:37 tshiozak Exp $ */
 
 /*-
@@ -52,9 +52,9 @@
 
 	wsp = ws;
 	while (n-- > 1) {
-		if ((wc = __fgetwc_unlock(fp)) == WEOF && errno == EILSEQ) {
+		if ((wc = __fgetwc_unlock(fp)) == WEOF &&
+		    ferror(fp) && errno == EILSEQ)
 			goto error;
-		}
 		if (wc == WEOF) {
 			if (wsp == ws) {
 				/* EOF/error, no characters read yet. */
@@ -77,3 +77,4 @@
 	FUNLOCKFILE(fp);
 	return (NULL);
 }
+DEF_STRONG(fgetws);
diff --git a/libc/upstream-openbsd/lib/libc/stdio/fopen.c b/libc/upstream-openbsd/lib/libc/stdio/fopen.c
deleted file mode 100644
index 1465052..0000000
--- a/libc/upstream-openbsd/lib/libc/stdio/fopen.c
+++ /dev/null
@@ -1,86 +0,0 @@
-/*	$OpenBSD: fopen.c,v 1.7 2008/05/03 18:46:41 chl 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 <sys/types.h>
-#include <sys/stat.h>
-#include <fcntl.h>
-#include <limits.h>
-#include <stdio.h>
-#include <errno.h>
-#include <unistd.h>
-#include "local.h"
-
-FILE *
-fopen(const char *file, const char *mode)
-{
-	FILE *fp;
-	int f;
-	int flags, oflags;
-
-	if ((flags = __sflags(mode, &oflags)) == 0)
-		return (NULL);
-	if ((fp = __sfp()) == NULL)
-		return (NULL);
-	if ((f = open(file, oflags, DEFFILEMODE)) < 0) {
-		fp->_flags = 0;			/* release */
-		return (NULL);
-	}
-
-	/* _file is only a short */
-	if (f > SHRT_MAX) {
-		fp->_flags = 0;			/* release */
-		close(f);
-		errno = EMFILE;
-		return (NULL);
-	}
-
-	fp->_file = f;
-	fp->_flags = flags;
-	fp->_cookie = fp;
-	fp->_read = __sread;
-	fp->_write = __swrite;
-	fp->_seek = __sseek;
-	fp->_close = __sclose;
-
-	/*
-	 * When opening in append mode, even though we use O_APPEND,
-	 * we need to seek to the end so that ftell() gets the right
-	 * answer.  If the user then alters the seek pointer, or
-	 * the file extends, this will fail, but there is not much
-	 * we can do about this.  (We could set __SAPP and check in
-	 * fseek and ftell.)
-	 */
-	if (oflags & O_APPEND)
-		(void) __sseek((void *)fp, (fpos_t)0, SEEK_END);
-	return (fp);
-}
diff --git a/libc/upstream-openbsd/lib/libc/stdio/fputwc.c b/libc/upstream-openbsd/lib/libc/stdio/fputwc.c
index 9db70d0..829c22c 100644
--- a/libc/upstream-openbsd/lib/libc/stdio/fputwc.c
+++ b/libc/upstream-openbsd/lib/libc/stdio/fputwc.c
@@ -1,4 +1,4 @@
-/*	$OpenBSD: fputwc.c,v 1.4 2009/11/09 00:18:27 kurt Exp $	*/
+/*	$OpenBSD: fputwc.c,v 1.6 2015/10/01 02:32:07 guenther Exp $	*/
 /* $NetBSD: fputwc.c,v 1.3 2003/03/07 07:11:37 tshiozak Exp $ */
 
 /*-
@@ -46,8 +46,7 @@
 	struct __suio uio;
 	struct __siov iov;
 
-	/* LINTED we don't play with buf */
-	iov.iov_base = (void *)buf;
+	iov.iov_base = buf;
 	uio.uio_iov = &iov;
 	uio.uio_iovcnt = 1;
 
@@ -86,3 +85,4 @@
 
 	return (r);
 }
+DEF_STRONG(fputwc);
diff --git a/libc/upstream-openbsd/lib/libc/stdio/freopen.c b/libc/upstream-openbsd/lib/libc/stdio/freopen.c
deleted file mode 100644
index 82717b1..0000000
--- a/libc/upstream-openbsd/lib/libc/stdio/freopen.c
+++ /dev/null
@@ -1,171 +0,0 @@
-/*	$OpenBSD: freopen.c,v 1.14 2014/08/31 02:21:18 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 <sys/types.h>
-#include <sys/stat.h>
-#include <fcntl.h>
-#include <errno.h>
-#include <limits.h>
-#include <unistd.h>
-#include <stdio.h>
-#include <stdlib.h>
-#include "local.h"
-
-/* 
- * Re-direct an existing, open (probably) file to some other file. 
- * ANSI is written such that the original file gets closed if at
- * all possible, no matter what.
- */
-FILE *
-freopen(const char *file, const char *mode, FILE *fp)
-{
-	int f;
-	int flags, isopen, oflags, sverrno, wantfd;
-
-	if ((flags = __sflags(mode, &oflags)) == 0) {
-		(void) fclose(fp);
-		return (NULL);
-	}
-
-	if (!__sdidinit)
-		__sinit();
-
-	FLOCKFILE(fp);
-
-	/*
-	 * There are actually programs that depend on being able to "freopen"
-	 * descriptors that weren't originally open.  Keep this from breaking.
-	 * Remember whether the stream was open to begin with, and which file
-	 * descriptor (if any) was associated with it.  If it was attached to
-	 * a descriptor, defer closing it; freopen("/dev/stdin", "r", stdin)
-	 * should work.  This is unnecessary if it was not a Unix file.
-	 */
-	if (fp->_flags == 0) {
-		fp->_flags = __SEOF;	/* hold on to it */
-		isopen = 0;
-		wantfd = -1;
-	} else {
-		/* flush the stream; ANSI doesn't require this. */
-		if (fp->_flags & __SWR)
-			(void) __sflush(fp);
-		/* if close is NULL, closing is a no-op, hence pointless */
-		isopen = fp->_close != NULL;
-		if ((wantfd = fp->_file) < 0 && isopen) {
-			(void) (*fp->_close)(fp->_cookie);
-			isopen = 0;
-		}
-	}
-
-	/* Get a new descriptor to refer to the new file. */
-	f = open(file, oflags, DEFFILEMODE);
-	if (f < 0 && isopen) {
-		/* If out of fd's close the old one and try again. */
-		if (errno == ENFILE || errno == EMFILE) {
-			(void) (*fp->_close)(fp->_cookie);
-			isopen = 0;
-			f = open(file, oflags, DEFFILEMODE);
-		}
-	}
-	sverrno = errno;
-
-	/*
-	 * Finish closing fp.  Even if the open succeeded above, we cannot
-	 * keep fp->_base: it may be the wrong size.  This loses the effect
-	 * of any setbuffer calls, but stdio has always done this before.
-	 */
-	if (isopen && f != wantfd)
-		(void) (*fp->_close)(fp->_cookie);
-	if (fp->_flags & __SMBF)
-		free((char *)fp->_bf._base);
-	fp->_w = 0;
-	fp->_r = 0;
-	fp->_p = NULL;
-	fp->_bf._base = NULL;
-	fp->_bf._size = 0;
-	fp->_lbfsize = 0;
-	if (HASUB(fp))
-		FREEUB(fp);
-	_UB(fp)._size = 0;
-	WCIO_FREE(fp);
-	if (HASLB(fp))
-		FREELB(fp);
-	fp->_lb._size = 0;
-
-	if (f < 0) {			/* did not get it after all */
-		fp->_flags = 0;		/* set it free */
-		FUNLOCKFILE(fp);
-		errno = sverrno;	/* restore in case _close clobbered */
-		return (NULL);
-	}
-
-	/*
-	 * If reopening something that was open before on a real file, try
-	 * to maintain the descriptor.  Various C library routines (perror)
-	 * assume stderr is always fd STDERR_FILENO, even if being freopen'd.
-	 */
-	if (wantfd >= 0 && f != wantfd) {
-		if (dup3(f, wantfd, oflags & O_CLOEXEC) >= 0) {
-			(void) close(f);
-			f = wantfd;
-		}
-	}
-
-	/* _file is only a short */
-	if (f > SHRT_MAX) {
-		fp->_flags = 0;		/* set it free */
-		FUNLOCKFILE(fp);
-		errno = EMFILE;
-		return (NULL);
-	}
-
-	fp->_flags = flags;
-	fp->_file = f;
-	fp->_cookie = fp;
-	fp->_read = __sread;
-	fp->_write = __swrite;
-	fp->_seek = __sseek;
-	fp->_close = __sclose;
-
-	/*
-	 * When opening in append mode, even though we use O_APPEND,
-	 * we need to seek to the end so that ftell() gets the right
-	 * answer.  If the user then alters the seek pointer, or
-	 * the file extends, this will fail, but there is not much
-	 * we can do about this.  (We could set __SAPP and check in
-	 * fseek and ftell.)
-	 */
-	if (oflags & O_APPEND)
-		(void) __sseek((void *)fp, (fpos_t)0, SEEK_END);
-	FUNLOCKFILE(fp);
-	return (fp);
-}
diff --git a/libc/upstream-openbsd/lib/libc/stdio/fseek.c b/libc/upstream-openbsd/lib/libc/stdio/fseek.c
deleted file mode 100644
index cdd40b6..0000000
--- a/libc/upstream-openbsd/lib/libc/stdio/fseek.c
+++ /dev/null
@@ -1,251 +0,0 @@
-/*	$OpenBSD: fseek.c,v 1.11 2012/05/21 22:24:19 matthew 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 <sys/types.h>
-#include <sys/stat.h>
-#include <fcntl.h>
-#include <stdio.h>
-#include <stdlib.h>
-#include <errno.h>
-#include "local.h"
-
-#define	POS_ERR	(-(fpos_t)1)
-
-/*
- * Seek the given file to the given offset.
- * `Whence' must be one of the three SEEK_* macros.
- */
-int
-fseeko(FILE *fp, off_t offset, int whence)
-{
-	fpos_t (*seekfn)(void *, fpos_t, int);
-	fpos_t target, curoff;
-	size_t n;
-	struct stat st;
-	int havepos;
-
-	/* make sure stdio is set up */
-	if (!__sdidinit)
-		__sinit();
-
-	/*
-	 * Have to be able to seek.
-	 */
-	if ((seekfn = fp->_seek) == NULL) {
-		errno = ESPIPE;			/* historic practice */
-		return (EOF);
-	}
-
-	/*
-	 * Change any SEEK_CUR to SEEK_SET, and check `whence' argument.
-	 * After this, whence is either SEEK_SET or SEEK_END.
-	 */
-	FLOCKFILE(fp);
-	switch (whence) {
-
-	case SEEK_CUR:
-		/*
-		 * In order to seek relative to the current stream offset,
-		 * we have to first find the current stream offset a la
-		 * ftell (see ftell for details).
-		 */
-		__sflush(fp);	/* may adjust seek offset on append stream */
-		if (fp->_flags & __SOFF)
-			curoff = fp->_offset;
-		else {
-			curoff = (*seekfn)(fp->_cookie, (fpos_t)0, SEEK_CUR);
-			if (curoff == (fpos_t)-1) {
-				FUNLOCKFILE(fp);
-				return (EOF);
-			}
-		}
-		if (fp->_flags & __SRD) {
-			curoff -= fp->_r;
-			if (HASUB(fp))
-				curoff -= fp->_ur;
-		} else if (fp->_flags & __SWR && fp->_p != NULL)
-			curoff += fp->_p - fp->_bf._base;
-
-		offset += curoff;
-		whence = SEEK_SET;
-		havepos = 1;
-		break;
-
-	case SEEK_SET:
-	case SEEK_END:
-		curoff = 0;		/* XXX just to keep gcc quiet */
-		havepos = 0;
-		break;
-
-	default:
-		FUNLOCKFILE(fp);
-		errno = EINVAL;
-		return (EOF);
-	}
-
-	/*
-	 * Can only optimise if:
-	 *	reading (and not reading-and-writing);
-	 *	not unbuffered; and
-	 *	this is a `regular' Unix file (and hence seekfn==__sseek).
-	 * We must check __NBF first, because it is possible to have __NBF
-	 * and __SOPT both set.
-	 */
-	if (fp->_bf._base == NULL)
-		__smakebuf(fp);
-	if (fp->_flags & (__SWR | __SRW | __SNBF | __SNPT))
-		goto dumb;
-	if ((fp->_flags & __SOPT) == 0) {
-		if (seekfn != __sseek ||
-		    fp->_file < 0 || fstat(fp->_file, &st) ||
-		    (st.st_mode & S_IFMT) != S_IFREG) {
-			fp->_flags |= __SNPT;
-			goto dumb;
-		}
-		fp->_blksize = st.st_blksize;
-		fp->_flags |= __SOPT;
-	}
-
-	/*
-	 * We are reading; we can try to optimise.
-	 * Figure out where we are going and where we are now.
-	 */
-	if (whence == SEEK_SET)
-		target = offset;
-	else {
-		if (fstat(fp->_file, &st))
-			goto dumb;
-		target = st.st_size + offset;
-	}
-
-	if (!havepos) {
-		if (fp->_flags & __SOFF)
-			curoff = fp->_offset;
-		else {
-			curoff = (*seekfn)(fp->_cookie, (fpos_t)0, SEEK_CUR);
-			if (curoff == POS_ERR)
-				goto dumb;
-		}
-		curoff -= fp->_r;
-		if (HASUB(fp))
-			curoff -= fp->_ur;
-	}
-
-	/*
-	 * Compute the number of bytes in the input buffer (pretending
-	 * that any ungetc() input has been discarded).  Adjust current
-	 * offset backwards by this count so that it represents the
-	 * file offset for the first byte in the current input buffer.
-	 */
-	if (HASUB(fp)) {
-		curoff += fp->_r;	/* kill off ungetc */
-		n = fp->_up - fp->_bf._base;
-		curoff -= n;
-		n += fp->_ur;
-	} else {
-		n = fp->_p - fp->_bf._base;
-		curoff -= n;
-		n += fp->_r;
-	}
-
-	/*
-	 * If the target offset is within the current buffer,
-	 * simply adjust the pointers, clear EOF, undo ungetc(),
-	 * and return.  (If the buffer was modified, we have to
-	 * skip this; see fgetln.c.)
-	 */
-	if ((fp->_flags & __SMOD) == 0 &&
-	    target >= curoff && target < curoff + n) {
-		int o = target - curoff;
-
-		fp->_p = fp->_bf._base + o;
-		fp->_r = n - o;
-		if (HASUB(fp))
-			FREEUB(fp);
-		fp->_flags &= ~__SEOF;
-		FUNLOCKFILE(fp);
-		return (0);
-	}
-
-	/*
-	 * The place we want to get to is not within the current buffer,
-	 * but we can still be kind to the kernel copyout mechanism.
-	 * By aligning the file offset to a block boundary, we can let
-	 * the kernel use the VM hardware to map pages instead of
-	 * copying bytes laboriously.  Using a block boundary also
-	 * ensures that we only read one block, rather than two.
-	 */
-	curoff = target & ~(fp->_blksize - 1);
-	if ((*seekfn)(fp->_cookie, curoff, SEEK_SET) == POS_ERR)
-		goto dumb;
-	fp->_r = 0;
- 	fp->_p = fp->_bf._base;
-	if (HASUB(fp))
-		FREEUB(fp);
-	fp->_flags &= ~__SEOF;
-	n = target - curoff;
-	if (n) {
-		if (__srefill(fp) || fp->_r < n)
-			goto dumb;
-		fp->_p += n;
-		fp->_r -= n;
-	}
-	FUNLOCKFILE(fp);
-	return (0);
-
-	/*
-	 * We get here if we cannot optimise the seek ... just
-	 * do it.  Allow the seek function to change fp->_bf._base.
-	 */
-dumb:
-	if (__sflush(fp) ||
-	    (*seekfn)(fp->_cookie, (fpos_t)offset, whence) == POS_ERR) {
-		FUNLOCKFILE(fp);
-		return (EOF);
-	}
-	/* success: clear EOF indicator and discard ungetc() data */
-	if (HASUB(fp))
-		FREEUB(fp);
-	fp->_p = fp->_bf._base;
-	fp->_r = 0;
-	/* fp->_w = 0; */	/* unnecessary (I think...) */
-	fp->_flags &= ~__SEOF;
-	FUNLOCKFILE(fp);
-	return (0);
-}
-
-int
-fseek(FILE *fp, long offset, int whence)
-{
-	return (fseeko(fp, offset, whence));
-}
diff --git a/libc/upstream-openbsd/lib/libc/stdio/fsetpos.c b/libc/upstream-openbsd/lib/libc/stdio/fsetpos.c
deleted file mode 100644
index 9624fe5..0000000
--- a/libc/upstream-openbsd/lib/libc/stdio/fsetpos.c
+++ /dev/null
@@ -1,43 +0,0 @@
-/*	$OpenBSD: fsetpos.c,v 1.6 2005/08/08 08:05:36 espie 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>
-
-/*
- * fsetpos: like fseeko.
- */
-int
-fsetpos(FILE *iop, const fpos_t *pos)
-{
-	return (fseeko(iop, (off_t)*pos, SEEK_SET));
-}
diff --git a/libc/upstream-openbsd/lib/libc/stdio/ftell.c b/libc/upstream-openbsd/lib/libc/stdio/ftell.c
deleted file mode 100644
index 0a2016c..0000000
--- a/libc/upstream-openbsd/lib/libc/stdio/ftell.c
+++ /dev/null
@@ -1,96 +0,0 @@
-/*	$OpenBSD: ftell.c,v 1.10 2012/05/21 22:24:19 matthew 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 <errno.h>
-#include <limits.h>
-#include "local.h"
-
-/*
- * ftello: return current offset.
- */
-off_t
-ftello(FILE *fp)
-{
-	fpos_t pos;
-
-	if (fp->_seek == NULL) {
-		errno = ESPIPE;			/* historic practice */
-		pos = -1;
-		goto out;
-	}
-
-	/*
-	 * Find offset of underlying I/O object, then
-	 * adjust for buffered bytes.
-	 */
-	FLOCKFILE(fp);
-	__sflush(fp);		/* may adjust seek offset on append stream */
-	if (fp->_flags & __SOFF)
-		pos = fp->_offset;
-	else {
-		pos = (*fp->_seek)(fp->_cookie, (fpos_t)0, SEEK_CUR);
-		if (pos == -1)
-			goto out;
-	}
-	if (fp->_flags & __SRD) {
-		/*
-		 * Reading.  Any unread characters (including
-		 * those from ungetc) cause the position to be
-		 * smaller than that in the underlying object.
-		 */
-		pos -= fp->_r;
-		if (HASUB(fp))
-			pos -= fp->_ur;
-	} else if (fp->_flags & __SWR && fp->_p != NULL) {
-		/*
-		 * Writing.  Any buffered characters cause the
-		 * position to be greater than that in the
-		 * underlying object.
-		 */
-		pos += fp->_p - fp->_bf._base;
-	}
-out:	FUNLOCKFILE(fp);
-	return (pos);
-}
-
-long
-ftell(FILE *fp)
-{
-	off_t offset = ftello(fp);
-	if (offset > LONG_MAX) {
-		errno = EOVERFLOW;
-		return (-1);
-	}
-	return ((long)offset);
-}
diff --git a/libc/upstream-openbsd/lib/libc/stdio/funopen.c b/libc/upstream-openbsd/lib/libc/stdio/funopen.c
deleted file mode 100644
index b85ee96..0000000
--- a/libc/upstream-openbsd/lib/libc/stdio/funopen.c
+++ /dev/null
@@ -1,68 +0,0 @@
-/*	$OpenBSD: funopen.c,v 1.8 2005/08/08 08:05:36 espie 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 <errno.h>
-#include "local.h"
-
-FILE *
-funopen(const void *cookie, int (*readfn)(void *, char *, int),
-	int (*writefn)(void *, const char *, int),
-	fpos_t (*seekfn)(void *, fpos_t, int), int (*closefn)(void *))
-{
-	FILE *fp;
-	int flags;
-
-	if (readfn == NULL) {
-		if (writefn == NULL) {		/* illegal */
-			errno = EINVAL;
-			return (NULL);
-		} else
-			flags = __SWR;		/* write only */
-	} else {
-		if (writefn == NULL)
-			flags = __SRD;		/* read only */
-		else
-			flags = __SRW;		/* read-write */
-	}
-	if ((fp = __sfp()) == NULL)
-		return (NULL);
-	fp->_flags = flags;
-	fp->_file = -1;
-	fp->_cookie = (void *)cookie;		/* SAFE: cookie not modified */
-	fp->_read = readfn;
-	fp->_write = writefn;
-	fp->_seek = seekfn;
-	fp->_close = closefn;
-	return (fp);
-}
diff --git a/libc/upstream-openbsd/lib/libc/stdio/getdelim.c b/libc/upstream-openbsd/lib/libc/stdio/getdelim.c
index 5e583cb..58ff0a1 100644
--- a/libc/upstream-openbsd/lib/libc/stdio/getdelim.c
+++ b/libc/upstream-openbsd/lib/libc/stdio/getdelim.c
@@ -1,4 +1,4 @@
-/*	$OpenBSD: getdelim.c,v 1.2 2014/10/16 17:31:51 millert Exp $	*/
+/*	$OpenBSD: getdelim.c,v 1.4 2015/08/31 02:53:57 guenther Exp $	*/
 /* $NetBSD: getdelim.c,v 1.13 2011/07/22 23:12:30 joerg Exp $ */
 
 /*
@@ -30,6 +30,7 @@
 
 #include <errno.h>
 #include <limits.h>
+#include <stdint.h>
 #include <stdio.h>
 #include <stdlib.h>
 #include <string.h>
@@ -96,7 +97,7 @@
 				newlen |= newlen >> 4;
 				newlen |= newlen >> 8;
 				newlen |= newlen >> 16;
-#if SIZE_T_MAX > 0xffffffffU
+#if SIZE_MAX > 0xffffffffU
 				newlen |= newlen >> 32;
 #endif
 				newlen++;
@@ -131,3 +132,4 @@
 	FUNLOCKFILE(fp);
 	return -1;
 }
+DEF_WEAK(getdelim);
diff --git a/libc/upstream-openbsd/lib/libc/stdio/open_memstream.c b/libc/upstream-openbsd/lib/libc/stdio/open_memstream.c
index 4610535..f708acc 100644
--- a/libc/upstream-openbsd/lib/libc/stdio/open_memstream.c
+++ b/libc/upstream-openbsd/lib/libc/stdio/open_memstream.c
@@ -1,4 +1,4 @@
-/*	$OpenBSD: open_memstream.c,v 1.3 2013/04/03 03:11:53 guenther Exp $	*/
+/*	$OpenBSD: open_memstream.c,v 1.6 2015/08/31 02:53:57 guenther Exp $	*/
 
 /*
  * Copyright (c) 2011 Martin Pieuchot <mpi@openbsd.org>
@@ -16,16 +16,16 @@
  * OR IN CONNECTION WITH THE USE OR PERFORMANCE OF THIS SOFTWARE.
  */
 
-#include <sys/param.h>
-
 #include <errno.h>
 #include <fcntl.h>
-#include <limits.h>
+#include <stdint.h>
 #include <stdio.h>
 #include <stdlib.h>
 #include <string.h>
 #include "local.h"
 
+#define	MINIMUM(a, b)	(((a) < (b)) ? (a) : (b))
+
 struct state {
 	char		 *string;	/* actual stream */
 	char		**pbuf;		/* point to the stream */
@@ -95,7 +95,7 @@
 	}
 
 	st->pos = base + off;
-	*st->psize = MIN(st->pos, st->len);
+	*st->psize = MINIMUM(st->pos, st->len);
 
 	return (st->pos);
 }
@@ -156,3 +156,4 @@
 
 	return (fp);
 }
+DEF_WEAK(open_memstream);
diff --git a/libc/upstream-openbsd/lib/libc/stdio/open_wmemstream.c b/libc/upstream-openbsd/lib/libc/stdio/open_wmemstream.c
index 391a944..aceef35 100644
--- a/libc/upstream-openbsd/lib/libc/stdio/open_wmemstream.c
+++ b/libc/upstream-openbsd/lib/libc/stdio/open_wmemstream.c
@@ -1,4 +1,4 @@
-/*	$OpenBSD: open_wmemstream.c,v 1.4 2014/10/08 05:28:19 deraadt Exp $	*/
+/*	$OpenBSD: open_wmemstream.c,v 1.8 2015/09/12 16:23:14 guenther Exp $	*/
 
 /*
  * Copyright (c) 2011 Martin Pieuchot <mpi@openbsd.org>
@@ -16,17 +16,17 @@
  * OR IN CONNECTION WITH THE USE OR PERFORMANCE OF THIS SOFTWARE.
  */
 
-#include <sys/param.h>
-
 #include <errno.h>
 #include <fcntl.h>
-#include <limits.h>
 #include <stdio.h>
+#include <stdint.h>
 #include <stdlib.h>
 #include <string.h>
 #include <wchar.h>
 #include "local.h"
 
+#define	MINIMUM(a, b)	(((a) < (b)) ? (a) : (b))
+
 struct state {
 	wchar_t		 *string;	/* actual stream */
 	wchar_t		**pbuf;		/* point to the stream */
@@ -105,7 +105,7 @@
 	bzero(&st->mbs, sizeof(st->mbs));
 
 	st->pos = base + off;
-	*st->psize = MIN(st->pos, st->len);
+	*st->psize = MINIMUM(st->pos, st->len);
 
 	return (st->pos);
 }
diff --git a/libc/upstream-openbsd/lib/libc/stdio/tempnam.c b/libc/upstream-openbsd/lib/libc/stdio/tempnam.c
index e3f2ab6..854b871 100644
--- a/libc/upstream-openbsd/lib/libc/stdio/tempnam.c
+++ b/libc/upstream-openbsd/lib/libc/stdio/tempnam.c
@@ -1,4 +1,4 @@
-/*	$OpenBSD: tempnam.c,v 1.17 2013/09/30 12:02:35 millert Exp $ */
+/*	$OpenBSD: tempnam.c,v 1.19 2015/08/31 02:53:57 guenther Exp $ */
 /*
  * Copyright (c) 1988, 1993
  *	The Regents of the University of California.  All rights reserved.
@@ -39,8 +39,6 @@
 __warn_references(tempnam,
     "warning: tempnam() possibly used unsafely; consider using mkstemp()");
 
-extern char *_mktemp(char *);
-
 char *
 tempnam(const char *dir, const char *pfx)
 {
@@ -58,7 +56,7 @@
 		    f[strlen(f) - 1] == '/' ? "" : "/", pfx);
 		if (len < 0 || len >= PATH_MAX) {
 			errno = ENAMETOOLONG;
-			return(NULL);
+			goto fail;
 		}
 		if ((f = _mktemp(name)))
 			return(f);
@@ -70,7 +68,7 @@
 		    f[strlen(f) - 1] == '/' ? "" : "/", pfx);
 		if (len < 0 || len >= PATH_MAX) {
 			errno = ENAMETOOLONG;
-			return(NULL);
+			goto fail;
 		}
 		if ((f = _mktemp(name)))
 			return(f);
@@ -80,7 +78,7 @@
 	len = snprintf(name, PATH_MAX, "%s%sXXXXXXXXX", f, pfx);
 	if (len < 0 || len >= PATH_MAX) {
 		errno = ENAMETOOLONG;
-		return(NULL);
+		goto fail;
 	}
 	if ((f = _mktemp(name)))
 		return(f);
@@ -89,11 +87,12 @@
 	len = snprintf(name, PATH_MAX, "%s%sXXXXXXXXX", f, pfx);
 	if (len < 0 || len >= PATH_MAX) {
 		errno = ENAMETOOLONG;
-		return(NULL);
+		goto fail;
 	}
 	if ((f = _mktemp(name)))
 		return(f);
 
+fail:
 	sverrno = errno;
 	free(name);
 	errno = sverrno;
diff --git a/libc/upstream-openbsd/lib/libc/stdio/vasprintf.c b/libc/upstream-openbsd/lib/libc/stdio/vasprintf.c
index 8fe7c5b..98cdb45 100644
--- a/libc/upstream-openbsd/lib/libc/stdio/vasprintf.c
+++ b/libc/upstream-openbsd/lib/libc/stdio/vasprintf.c
@@ -1,4 +1,4 @@
-/*	$OpenBSD: vasprintf.c,v 1.16 2009/11/09 00:18:27 kurt Exp $	*/
+/*	$OpenBSD: vasprintf.c,v 1.19 2015/12/28 22:08:18 mmcc Exp $	*/
 
 /*
  * Copyright (c) 1997 Todd C. Miller <Todd.Miller@courtesan.com>
@@ -33,7 +33,7 @@
 	_FILEEXT_SETUP(&f, &fext);
 	f._file = -1;
 	f._flags = __SWR | __SSTR | __SALC;
-	f._bf._base = f._p = (unsigned char *)malloc(128);
+	f._bf._base = f._p = malloc(128);
 	if (f._bf._base == NULL)
 		goto err;
 	f._bf._size = f._w = 127;		/* Leave room for the NUL */
@@ -48,11 +48,10 @@
 	return (ret);
 
 err:
-	if (f._bf._base) {
-		free(f._bf._base);
-		f._bf._base = NULL;
-	}
+	free(f._bf._base);
+	f._bf._base = NULL;
 	*str = NULL;
 	errno = ENOMEM;
 	return (-1);
 }
+DEF_WEAK(vasprintf);
diff --git a/libc/upstream-openbsd/lib/libc/stdio/vfprintf.c b/libc/upstream-openbsd/lib/libc/stdio/vfprintf.c
index 5f4fb7f..3d7d41e 100644
--- a/libc/upstream-openbsd/lib/libc/stdio/vfprintf.c
+++ b/libc/upstream-openbsd/lib/libc/stdio/vfprintf.c
@@ -1,4 +1,4 @@
-/*	$OpenBSD: vfprintf.c,v 1.67 2014/12/21 00:23:30 daniel Exp $	*/
+/*	$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.
@@ -165,10 +165,8 @@
 		memset(&mbs, 0, sizeof(mbs));
 		p = wcsarg;
 		nbytes = wcsrtombs(NULL, (const wchar_t **)&p, 0, &mbs);
-		if (nbytes == (size_t)-1) {
-			errno = EILSEQ;
+		if (nbytes == (size_t)-1)
 			return (NULL);
-		}
 	} else {
 		/*
 		 * Optimisation: if the output precision is small enough,
@@ -188,10 +186,8 @@
 					break;
 				nbytes += clen;
 			}
-			if (clen == (size_t)-1) {
-				errno = EILSEQ;
+			if (clen == (size_t)-1)
 				return (NULL);
-			}
 		}
 	}
 	if ((convbuf = malloc(nbytes + 1)) == NULL)
@@ -203,7 +199,6 @@
 	if ((nbytes = wcsrtombs(convbuf, (const wchar_t **)&p,
 	    nbytes, &mbs)) == (size_t)-1) {
 		free(convbuf);
-		errno = EILSEQ;
 		return (NULL);
 	}
 	convbuf[nbytes] = '\0';
@@ -268,6 +263,7 @@
 	FUNLOCKFILE(fp);
 	return (ret);
 }
+DEF_STRONG(vfprintf);
 
 int
 __vfprintf(FILE *fp, const char *fmt0, __va_list ap)
@@ -437,7 +433,11 @@
 		int hold = nextarg; \
 		if (argtable == NULL) { \
 			argtable = statargtable; \
-			__find_arguments(fmt0, orgap, &argtable, &argtablesiz); \
+			if (__find_arguments(fmt0, orgap, &argtable, \
+			    &argtablesiz) == -1) { \
+				ret = -1; \
+				goto error; \
+			} \
 		} \
 		nextarg = n2; \
 		val = GETARG(int); \
@@ -493,6 +493,10 @@
 				break;
 			}
 		}
+		if (n < 0) {
+			ret = -1;
+			goto error;
+		}
 		if (fmt != cp) {
 			ptrdiff_t m = fmt - cp;
 			if (m < 0 || m > INT_MAX - ret)
@@ -500,7 +504,7 @@
 			PRINT(cp, m);
 			ret += m;
 		}
-		if (n <= 0)
+		if (n == 0)
 			goto done;
 		fmt++;		/* skip over '%' */
 
@@ -563,8 +567,11 @@
 				nextarg = n;
 				if (argtable == NULL) {
 					argtable = statargtable;
-					__find_arguments(fmt0, orgap,
-					    &argtable, &argtablesiz);
+					if (__find_arguments(fmt0, orgap,
+					    &argtable, &argtablesiz) == -1) {
+						ret = -1;
+						goto error;
+					}
 				}
 				goto rflag;
 			}
@@ -589,8 +596,11 @@
 				nextarg = n;
 				if (argtable == NULL) {
 					argtable = statargtable;
-					__find_arguments(fmt0, orgap,
-					    &argtable, &argtablesiz);
+					if (__find_arguments(fmt0, orgap,
+					    &argtable, &argtablesiz) == -1) {
+						ret = -1;
+						goto error;
+					}
 				}
 				goto rflag;
 			}
@@ -639,8 +649,7 @@
 				mbseqlen = wcrtomb(buf,
 				    (wchar_t)GETARG(wint_t), &mbs);
 				if (mbseqlen == (size_t)-1) {
-					fp->_flags |= __SERR;
-					errno = EILSEQ;
+					ret = -1;
 					goto error;
 				}
 				cp = buf;
@@ -835,7 +844,6 @@
 			 * defined manner.''
 			 *	-- ANSI X3J11
 			 */
-			/* NOSTRICT */
 			_umax = (u_long)GETARG(void *);
 			base = HEX;
 			xdigs = xdigs_lower;
@@ -846,16 +854,14 @@
 			if (flags & LONGINT) {
 				wchar_t *wcp;
 
-				if (convbuf != NULL) {
-					free(convbuf);
-					convbuf = NULL;
-				}
+				free(convbuf);
+				convbuf = NULL;
 				if ((wcp = GETARG(wchar_t *)) == NULL) {
 					cp = "(null)";
 				} else {
 					convbuf = __wcsconv(wcp, prec);
 					if (convbuf == NULL) {
-						fp->_flags = __SERR;
+						ret = -1;
 						goto error;
 					}
 					cp = convbuf;
@@ -1075,8 +1081,7 @@
 
 finish:
 #ifdef PRINTF_WIDE_CHAR
-	if (convbuf)
-		free(convbuf);
+	free(convbuf);
 #endif
 #ifdef FLOATING_POINT
 	if (dtoaresult)
@@ -1214,7 +1219,9 @@
 				break;
 			}
 		}
-		if (n <= 0)
+		if (n < 0)
+			return (-1);
+		if (n == 0)
 			goto done;
 		fmt++;		/* skip over '%' */
 
diff --git a/libc/upstream-openbsd/lib/libc/stdio/vfwprintf.c b/libc/upstream-openbsd/lib/libc/stdio/vfwprintf.c
index a6f4123..520c8bc 100644
--- a/libc/upstream-openbsd/lib/libc/stdio/vfwprintf.c
+++ b/libc/upstream-openbsd/lib/libc/stdio/vfwprintf.c
@@ -1,4 +1,4 @@
-/*	$OpenBSD: vfwprintf.c,v 1.12 2014/12/21 00:23:30 daniel Exp $ */
+/*	$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.
@@ -667,10 +667,7 @@
 				prec = dtoaend - dtoaresult;
 			if (expt == INT_MAX)
 				ox[1] = '\0';
-			if (convbuf) {
-				free(convbuf);
-				convbuf = NULL;
-			}
+			free(convbuf);
 			cp = convbuf = __mbsconv(dtoaresult, -1);
 			if (cp == NULL)
 				goto error;
@@ -719,10 +716,7 @@
 				if (expt == 9999)
 					expt = INT_MAX;
  			}
-			if (convbuf) {
-				free(convbuf);
-				convbuf = NULL;
-			}
+			free(convbuf);
 			cp = convbuf = __mbsconv(dtoaresult, -1);
 			if (cp == NULL)
 				goto error;
@@ -812,7 +806,6 @@
 			 * defined manner.''
 			 *	-- ANSI X3J11
 			 */
-			/* NOSTRICT */
 			_umax = (u_long)GETARG(void *);
 			base = HEX;
 			xdigs = xdigs_lower;
@@ -829,10 +822,7 @@
 				char *mbsarg;
 				if ((mbsarg = GETARG(char *)) == NULL)
 					mbsarg = "(null)";
-				if (convbuf) {
-					free(convbuf);
-					convbuf = NULL;
-				}
+				free(convbuf);
 				convbuf = __mbsconv(mbsarg, prec);
 				if (convbuf == NULL) {
 					fp->_flags |= __SERR;
@@ -1048,8 +1038,7 @@
 	ret = -1;
 
 finish:
-	if (convbuf)
-		free(convbuf);
+	free(convbuf);
 #ifdef FLOATING_POINT
 	if (dtoaresult)
 		__freedtoa(dtoaresult);
@@ -1072,6 +1061,7 @@
 
 	return (r);
 }
+DEF_STRONG(vfwprintf);
 
 /*
  * Type ids for argument type table.
diff --git a/libc/upstream-openbsd/lib/libc/stdio/vswprintf.c b/libc/upstream-openbsd/lib/libc/stdio/vswprintf.c
index da7c4de..641db4a 100644
--- a/libc/upstream-openbsd/lib/libc/stdio/vswprintf.c
+++ b/libc/upstream-openbsd/lib/libc/stdio/vswprintf.c
@@ -1,4 +1,4 @@
-/*	$OpenBSD: vswprintf.c,v 1.4 2012/12/05 23:20:01 deraadt Exp $	*/
+/*	$OpenBSD: vswprintf.c,v 1.6 2015/08/31 02:53:57 guenther Exp $	*/
 /*	$NetBSD: vswprintf.c,v 1.1 2005/05/14 23:51:02 christos Exp $	*/
 
 /*
@@ -55,7 +55,7 @@
 	_FILEEXT_SETUP(&f, &fext);
 	f._file = -1;
 	f._flags = __SWR | __SSTR | __SALC;
-	f._bf._base = f._p = (unsigned char *)malloc(128);
+	f._bf._base = f._p = malloc(128);
 	if (f._bf._base == NULL) {
 		errno = ENOMEM;
 		return (-1);
@@ -94,3 +94,4 @@
 
 	return (ret);
 }
+DEF_STRONG(vswprintf);
diff --git a/libc/upstream-freebsd/lib/libc/stdlib/labs.c b/libc/upstream-openbsd/lib/libc/stdlib/abs.c
similarity index 83%
rename from libc/upstream-freebsd/lib/libc/stdlib/labs.c
rename to libc/upstream-openbsd/lib/libc/stdlib/abs.c
index 816370e..5d2fbae 100644
--- a/libc/upstream-freebsd/lib/libc/stdlib/labs.c
+++ b/libc/upstream-openbsd/lib/libc/stdlib/abs.c
@@ -1,6 +1,7 @@
+/*	$OpenBSD: abs.c,v 1.5 2005/08/08 08:05:36 espie Exp $ */
 /*-
- * Copyright (c) 1990, 1993
- *	The Regents of the University of California.  All rights reserved.
+ * Copyright (c) 1990 The Regents of the University of California.
+ * All rights reserved.
  *
  * Redistribution and use in source and binary forms, with or without
  * modification, are permitted provided that the following conditions
@@ -27,17 +28,10 @@
  * SUCH DAMAGE.
  */
 
-#if defined(LIBC_SCCS) && !defined(lint)
-static char sccsid[] = "@(#)labs.c	8.1 (Berkeley) 6/4/93";
-#endif /* LIBC_SCCS and not lint */
-#include <sys/cdefs.h>
-__FBSDID("$FreeBSD$");
-
 #include <stdlib.h>
 
-long
-labs(j)
-	long j;
+int
+abs(int j)
 {
 	return(j < 0 ? -j : j);
 }
diff --git a/libc/upstream-freebsd/lib/libc/stdlib/abs.c b/libc/upstream-openbsd/lib/libc/stdlib/imaxabs.c
similarity index 81%
rename from libc/upstream-freebsd/lib/libc/stdlib/abs.c
rename to libc/upstream-openbsd/lib/libc/stdlib/imaxabs.c
index 8758947..b7e910e 100644
--- a/libc/upstream-freebsd/lib/libc/stdlib/abs.c
+++ b/libc/upstream-openbsd/lib/libc/stdlib/imaxabs.c
@@ -1,6 +1,8 @@
+/*	$OpenBSD: imaxabs.c,v 1.1 2006/01/13 17:58:09 millert Exp $	*/
+
 /*-
- * Copyright (c) 1990, 1993
- *	The Regents of the University of California.  All rights reserved.
+ * Copyright (c) 1990 The Regents of the University of California.
+ * All rights reserved.
  *
  * Redistribution and use in source and binary forms, with or without
  * modification, are permitted provided that the following conditions
@@ -27,17 +29,10 @@
  * SUCH DAMAGE.
  */
 
-#if defined(LIBC_SCCS) && !defined(lint)
-static char sccsid[] = "@(#)abs.c	8.1 (Berkeley) 6/4/93";
-#endif /* LIBC_SCCS and not lint */
-#include <sys/cdefs.h>
-__FBSDID("$FreeBSD$");
+#include <inttypes.h>
 
-#include <stdlib.h>
-
-int
-abs(j)
-	int j;
+intmax_t
+imaxabs(intmax_t j)
 {
-	return(j < 0 ? -j : j);
+	return (j < 0 ? -j : j);
 }
diff --git a/libc/upstream-openbsd/lib/libc/stdio/fileno.c b/libc/upstream-openbsd/lib/libc/stdlib/imaxdiv.c
similarity index 79%
rename from libc/upstream-openbsd/lib/libc/stdio/fileno.c
rename to libc/upstream-openbsd/lib/libc/stdlib/imaxdiv.c
index 58628da..0515a94 100644
--- a/libc/upstream-openbsd/lib/libc/stdio/fileno.c
+++ b/libc/upstream-openbsd/lib/libc/stdlib/imaxdiv.c
@@ -1,7 +1,7 @@
-/*	$OpenBSD: fileno.c,v 1.8 2009/11/09 00:18:27 kurt Exp $ */
-/*-
- * Copyright (c) 1990, 1993
- *	The Regents of the University of California.  All rights reserved.
+/*	$OpenBSD: imaxdiv.c,v 1.1 2006/01/13 17:58:09 millert Exp $	*/
+/*
+ * Copyright (c) 1990 Regents of the University of California.
+ * All rights reserved.
  *
  * This code is derived from software contributed to Berkeley by
  * Chris Torek.
@@ -31,21 +31,20 @@
  * SUCH DAMAGE.
  */
 
-#include <stdio.h>
-#include "local.h"
+#include <inttypes.h>		/* imaxdiv_t */
 
-/*
- * A subroutine version of the macro fileno.
- */
-#undef fileno
-
-int
-fileno(FILE *fp)
+imaxdiv_t
+imaxdiv(intmax_t num, intmax_t denom)
 {
-	int     ret;
+	imaxdiv_t r;
 
-	FLOCKFILE(fp);
-	ret = __sfileno(fp);
-	FUNLOCKFILE(fp);
-	return (ret);
+	/* see div.c for comments */
+
+	r.quot = num / denom;
+	r.rem = num % denom;
+	if (num >= 0 && r.rem < 0) {
+		r.quot++;
+		r.rem -= denom;
+	}
+	return (r);
 }
diff --git a/libc/upstream-freebsd/lib/libc/stdlib/labs.c b/libc/upstream-openbsd/lib/libc/stdlib/labs.c
similarity index 83%
copy from libc/upstream-freebsd/lib/libc/stdlib/labs.c
copy to libc/upstream-openbsd/lib/libc/stdlib/labs.c
index 816370e..ca60b9a 100644
--- a/libc/upstream-freebsd/lib/libc/stdlib/labs.c
+++ b/libc/upstream-openbsd/lib/libc/stdlib/labs.c
@@ -1,6 +1,7 @@
+/*	$OpenBSD: labs.c,v 1.5 2005/08/08 08:05:36 espie Exp $ */
 /*-
- * Copyright (c) 1990, 1993
- *	The Regents of the University of California.  All rights reserved.
+ * Copyright (c) 1990 The Regents of the University of California.
+ * All rights reserved.
  *
  * Redistribution and use in source and binary forms, with or without
  * modification, are permitted provided that the following conditions
@@ -27,17 +28,10 @@
  * SUCH DAMAGE.
  */
 
-#if defined(LIBC_SCCS) && !defined(lint)
-static char sccsid[] = "@(#)labs.c	8.1 (Berkeley) 6/4/93";
-#endif /* LIBC_SCCS and not lint */
-#include <sys/cdefs.h>
-__FBSDID("$FreeBSD$");
-
 #include <stdlib.h>
 
 long
-labs(j)
-	long j;
+labs(long j)
 {
 	return(j < 0 ? -j : j);
 }
diff --git a/libc/upstream-freebsd/lib/libc/stdlib/labs.c b/libc/upstream-openbsd/lib/libc/stdlib/llabs.c
similarity index 82%
copy from libc/upstream-freebsd/lib/libc/stdlib/labs.c
copy to libc/upstream-openbsd/lib/libc/stdlib/llabs.c
index 816370e..fc2cd82 100644
--- a/libc/upstream-freebsd/lib/libc/stdlib/labs.c
+++ b/libc/upstream-openbsd/lib/libc/stdlib/llabs.c
@@ -1,6 +1,8 @@
+/*	$OpenBSD: llabs.c,v 1.3 2007/01/08 19:39:25 deraadt Exp $	*/
+
 /*-
- * Copyright (c) 1990, 1993
- *	The Regents of the University of California.  All rights reserved.
+ * Copyright (c) 1990 The Regents of the University of California.
+ * All rights reserved.
  *
  * Redistribution and use in source and binary forms, with or without
  * modification, are permitted provided that the following conditions
@@ -27,17 +29,10 @@
  * SUCH DAMAGE.
  */
 
-#if defined(LIBC_SCCS) && !defined(lint)
-static char sccsid[] = "@(#)labs.c	8.1 (Berkeley) 6/4/93";
-#endif /* LIBC_SCCS and not lint */
-#include <sys/cdefs.h>
-__FBSDID("$FreeBSD$");
-
 #include <stdlib.h>
 
-long
-labs(j)
-	long j;
+long long
+llabs(long long j)
 {
-	return(j < 0 ? -j : j);
+	return (j < 0 ? -j : j);
 }
diff --git a/libc/upstream-openbsd/lib/libc/stdlib/reallocarray.c b/libc/upstream-openbsd/lib/libc/stdlib/reallocarray.c
index 7accd99..baea252 100644
--- a/libc/upstream-openbsd/lib/libc/stdlib/reallocarray.c
+++ b/libc/upstream-openbsd/lib/libc/stdlib/reallocarray.c
@@ -1,4 +1,4 @@
-/*	$OpenBSD: reallocarray.c,v 1.1 2014/05/08 21:43:49 deraadt Exp $	*/
+/*	$OpenBSD: reallocarray.c,v 1.3 2015/09/13 08:31:47 guenther Exp $	*/
 /*
  * Copyright (c) 2008 Otto Moerbeek <otto@drijf.net>
  *
@@ -24,7 +24,7 @@
  * This is sqrt(SIZE_MAX+1), as s1*s2 <= SIZE_MAX
  * if both s1 < MUL_NO_OVERFLOW and s2 < MUL_NO_OVERFLOW
  */
-#define MUL_NO_OVERFLOW	(1UL << (sizeof(size_t) * 4))
+#define MUL_NO_OVERFLOW	((size_t)1 << (sizeof(size_t) * 4))
 
 void *
 reallocarray(void *optr, size_t nmemb, size_t size)
@@ -36,3 +36,4 @@
 	}
 	return realloc(optr, size * nmemb);
 }
+DEF_WEAK(reallocarray);
diff --git a/libc/upstream-openbsd/lib/libc/stdlib/setenv.c b/libc/upstream-openbsd/lib/libc/stdlib/setenv.c
index 9060fdb..e55a1fe 100644
--- a/libc/upstream-openbsd/lib/libc/stdlib/setenv.c
+++ b/libc/upstream-openbsd/lib/libc/stdlib/setenv.c
@@ -1,4 +1,4 @@
-/*	$OpenBSD: setenv.c,v 1.14 2012/09/23 16:08:04 jeremy Exp $ */
+/*	$OpenBSD: setenv.c,v 1.16 2015/09/13 08:31:47 guenther Exp $ */
 /*
  * Copyright (c) 1987 Regents of the University of California.
  * All rights reserved.
@@ -32,8 +32,6 @@
 #include <stdlib.h>
 #include <string.h>
 
-char *__findenv(const char *name, int len, int *offset);
-
 extern char **environ;
 static char **lastenv;				/* last value of environ */
 
@@ -71,7 +69,7 @@
 	for (P = environ; *P != NULL; P++)
 		;
 	cnt = P - environ;
-	P = (char **)realloc(lastenv, sizeof(char *) * (cnt + 2));
+	P = reallocarray(lastenv, cnt + 2, sizeof(char *));
 	if (!P)
 		return (-1);
 	if (lastenv != environ)
@@ -81,6 +79,7 @@
 	environ[cnt + 1] = NULL;
 	return (0);
 }
+DEF_WEAK(putenv);
 
 /*
  * setenv --
@@ -129,7 +128,7 @@
 		for (P = environ; *P != NULL; P++)
 			;
 		cnt = P - environ;
-		P = (char **)realloc(lastenv, sizeof(char *) * (cnt + 2));
+		P = reallocarray(lastenv, cnt + 2, sizeof(char *));
 		if (!P)
 			return (-1);
 		if (lastenv != environ)
@@ -147,6 +146,7 @@
 		;
 	return (0);
 }
+DEF_WEAK(setenv);
 
 /*
  * unsetenv(name) --
@@ -178,3 +178,4 @@
 	}
 	return (0);
 }
+DEF_WEAK(unsetenv);
diff --git a/libc/upstream-openbsd/lib/libc/stdlib/system.c b/libc/upstream-openbsd/lib/libc/stdlib/system.c
index 14ddcae..de32d43 100644
--- a/libc/upstream-openbsd/lib/libc/stdlib/system.c
+++ b/libc/upstream-openbsd/lib/libc/stdlib/system.c
@@ -1,4 +1,4 @@
-/*	$OpenBSD: system.c,v 1.8 2005/08/08 08:05:37 espie Exp $ */
+/*	$OpenBSD: system.c,v 1.11 2015/10/23 04:44:41 guenther Exp $ */
 /*
  * Copyright (c) 1988 The Regents of the University of California.
  * All rights reserved.
@@ -30,6 +30,7 @@
 
 #include <sys/types.h>
 #include <sys/wait.h>
+#include <errno.h>
 #include <signal.h>
 #include <stdlib.h>
 #include <unistd.h>
@@ -40,8 +41,8 @@
 int
 system(const char *command)
 {
-	pid_t pid;
-	sig_t intsave, quitsave;
+	pid_t pid, cpid;
+	struct sigaction intsave, quitsave;
 	sigset_t mask, omask;
 	int pstat;
 	char *argp[] = {"sh", "-c", NULL, NULL};
@@ -54,7 +55,7 @@
 	sigemptyset(&mask);
 	sigaddset(&mask, SIGCHLD);
 	sigprocmask(SIG_BLOCK, &mask, &omask);
-	switch (pid = vfork()) {
+	switch (cpid = vfork()) {
 	case -1:			/* error */
 		sigprocmask(SIG_SETMASK, &omask, NULL);
 		return(-1);
@@ -64,11 +65,14 @@
 		_exit(127);
 	}
 
-	intsave = signal(SIGINT, SIG_IGN);
-	quitsave = signal(SIGQUIT, SIG_IGN);
-	pid = waitpid(pid, (int *)&pstat, 0);
+	sigaction(SIGINT, NULL, &intsave);
+	sigaction(SIGQUIT, NULL, &quitsave);
+	do {
+		pid = waitpid(cpid, &pstat, 0);
+	} while (pid == -1 && errno == EINTR);
 	sigprocmask(SIG_SETMASK, &omask, NULL);
-	(void)signal(SIGINT, intsave);
-	(void)signal(SIGQUIT, quitsave);
+	sigaction(SIGINT, &intsave, NULL);
+	sigaction(SIGQUIT, &quitsave, NULL);
 	return (pid == -1 ? -1 : pstat);
 }
+DEF_STRONG(system);
diff --git a/libc/upstream-openbsd/lib/libc/string/strlcat.c b/libc/upstream-openbsd/lib/libc/string/strlcat.c
index ceab094..073b0d4 100644
--- a/libc/upstream-openbsd/lib/libc/string/strlcat.c
+++ b/libc/upstream-openbsd/lib/libc/string/strlcat.c
@@ -1,7 +1,7 @@
-/*	$OpenBSD: strlcat.c,v 1.13 2005/08/08 08:05:37 espie Exp $	*/
+/*	$OpenBSD: strlcat.c,v 1.16 2015/08/31 02:53:57 guenther Exp $	*/
 
 /*
- * Copyright (c) 1998 Todd C. Miller <Todd.Miller@courtesan.com>
+ * Copyright (c) 1998, 2015 Todd C. Miller <Todd.Miller@courtesan.com>
  *
  * Permission to use, copy, modify, and distribute this software for any
  * purpose with or without fee is hereby granted, provided that the above
@@ -20,36 +20,37 @@
 #include <string.h>
 
 /*
- * Appends src to string dst of size siz (unlike strncat, siz is the
- * full size of dst, not space left).  At most siz-1 characters
- * will be copied.  Always NUL terminates (unless siz <= strlen(dst)).
- * Returns strlen(src) + MIN(siz, strlen(initial dst)).
- * If retval >= siz, truncation occurred.
+ * Appends src to string dst of size dsize (unlike strncat, dsize is the
+ * full size of dst, not space left).  At most dsize-1 characters
+ * will be copied.  Always NUL terminates (unless dsize <= strlen(dst)).
+ * Returns strlen(src) + MIN(dsize, strlen(initial dst)).
+ * If retval >= dsize, truncation occurred.
  */
 size_t
-strlcat(char *dst, const char *src, size_t siz)
+strlcat(char *dst, const char *src, size_t dsize)
 {
-	char *d = dst;
-	const char *s = src;
-	size_t n = siz;
+	const char *odst = dst;
+	const char *osrc = src;
+	size_t n = dsize;
 	size_t dlen;
 
-	/* Find the end of dst and adjust bytes left but don't go past end */
-	while (n-- != 0 && *d != '\0')
-		d++;
-	dlen = d - dst;
-	n = siz - dlen;
+	/* Find the end of dst and adjust bytes left but don't go past end. */
+	while (n-- != 0 && *dst != '\0')
+		dst++;
+	dlen = dst - odst;
+	n = dsize - dlen;
 
-	if (n == 0)
-		return(dlen + strlen(s));
-	while (*s != '\0') {
-		if (n != 1) {
-			*d++ = *s;
+	if (n-- == 0)
+		return(dlen + strlen(src));
+	while (*src != '\0') {
+		if (n != 0) {
+			*dst++ = *src;
 			n--;
 		}
-		s++;
+		src++;
 	}
-	*d = '\0';
+	*dst = '\0';
 
-	return(dlen + (s - src));	/* count does not include NUL */
+	return(dlen + (src - osrc));	/* count does not include NUL */
 }
+DEF_WEAK(strlcat);
diff --git a/libc/upstream-openbsd/lib/libc/string/strlcpy.c b/libc/upstream-openbsd/lib/libc/string/strlcpy.c
index d32b659..5fcf084 100644
--- a/libc/upstream-openbsd/lib/libc/string/strlcpy.c
+++ b/libc/upstream-openbsd/lib/libc/string/strlcpy.c
@@ -1,7 +1,7 @@
-/*	$OpenBSD: strlcpy.c,v 1.11 2006/05/05 15:27:38 millert Exp $	*/
+/*	$OpenBSD: strlcpy.c,v 1.13 2015/08/31 02:53:57 guenther Exp $	*/
 
 /*
- * Copyright (c) 1998 Todd C. Miller <Todd.Miller@courtesan.com>
+ * Copyright (c) 1998, 2015 Todd C. Miller <Todd.Miller@courtesan.com>
  *
  * Permission to use, copy, modify, and distribute this software for any
  * purpose with or without fee is hereby granted, provided that the above
@@ -20,32 +20,32 @@
 #include <string.h>
 
 /*
- * Copy src to string dst of size siz.  At most siz-1 characters
- * will be copied.  Always NUL terminates (unless siz == 0).
- * Returns strlen(src); if retval >= siz, truncation occurred.
+ * Copy string src to buffer dst of size dsize.  At most dsize-1
+ * chars will be copied.  Always NUL terminates (unless dsize == 0).
+ * Returns strlen(src); if retval >= dsize, truncation occurred.
  */
 size_t
-strlcpy(char *dst, const char *src, size_t siz)
+strlcpy(char *dst, const char *src, size_t dsize)
 {
-	char *d = dst;
-	const char *s = src;
-	size_t n = siz;
+	const char *osrc = src;
+	size_t nleft = dsize;
 
-	/* Copy as many bytes as will fit */
-	if (n != 0) {
-		while (--n != 0) {
-			if ((*d++ = *s++) == '\0')
+	/* Copy as many bytes as will fit. */
+	if (nleft != 0) {
+		while (--nleft != 0) {
+			if ((*dst++ = *src++) == '\0')
 				break;
 		}
 	}
 
-	/* Not enough room in dst, add NUL and traverse rest of src */
-	if (n == 0) {
-		if (siz != 0)
-			*d = '\0';		/* NUL-terminate dst */
-		while (*s++)
+	/* Not enough room in dst, add NUL and traverse rest of src. */
+	if (nleft == 0) {
+		if (dsize != 0)
+			*dst = '\0';		/* NUL-terminate dst */
+		while (*src++)
 			;
 	}
 
-	return(s - src - 1);	/* count does not include NUL */
+	return(src - osrc - 1);	/* count does not include NUL */
 }
+DEF_WEAK(strlcpy);
diff --git a/libc/upstream-openbsd/lib/libc/string/strtok.c b/libc/upstream-openbsd/lib/libc/string/strtok.c
index 4e963a0..c576575 100644
--- a/libc/upstream-openbsd/lib/libc/string/strtok.c
+++ b/libc/upstream-openbsd/lib/libc/string/strtok.c
@@ -36,15 +36,15 @@
 
 	return strtok_r(s, delim, &last);
 }
+DEF_STRONG(strtok);
 
 char *
 strtok_r(char *s, const char *delim, char **last)
 {
-	char *spanp;
+	const char *spanp;
 	int c, sc;
 	char *tok;
 
-
 	if (s == NULL && (s = *last) == NULL)
 		return (NULL);
 
@@ -53,7 +53,7 @@
 	 */
 cont:
 	c = *s++;
-	for (spanp = (char *)delim; (sc = *spanp++) != 0;) {
+	for (spanp = delim; (sc = *spanp++) != 0;) {
 		if (c == sc)
 			goto cont;
 	}
@@ -70,13 +70,13 @@
 	 */
 	for (;;) {
 		c = *s++;
-		spanp = (char *)delim;
+		spanp = delim;
 		do {
 			if ((sc = *spanp++) == c) {
 				if (c == 0)
 					s = NULL;
 				else
-					s[-1] = 0;
+					s[-1] = '\0';
 				*last = s;
 				return (tok);
 			}
@@ -84,3 +84,4 @@
 	}
 	/* NOTREACHED */
 }
+DEF_WEAK(strtok_r);
diff --git a/libc/upstream-openbsd/lib/libc/string/wcslcpy.c b/libc/upstream-openbsd/lib/libc/string/wcslcpy.c
index f49936a..36a544a 100644
--- a/libc/upstream-openbsd/lib/libc/string/wcslcpy.c
+++ b/libc/upstream-openbsd/lib/libc/string/wcslcpy.c
@@ -1,8 +1,7 @@
-/*	$OpenBSD: wcslcpy.c,v 1.5 2011/07/24 15:21:28 millert Exp $	*/
-/*	$NetBSD: wcslcpy.c,v 1.2 2001/01/03 14:33:02 lukem Exp $	*/
+/*	$OpenBSD: wcslcpy.c,v 1.7 2015/09/12 16:23:14 guenther Exp $	*/
 
 /*
- * Copyright (c) 1998 Todd C. Miller <Todd.Miller@courtesan.com>
+ * Copyright (c) 1998, 2015 Todd C. Miller <Todd.Miller@courtesan.com>
  *
  * Permission to use, copy, modify, and distribute this software for any
  * purpose with or without fee is hereby granted, provided that the above
@@ -21,32 +20,32 @@
 #include <wchar.h>
 
 /*
- * Copy src to string dst of size siz.  At most siz-1 characters
- * will be copied.  Always NUL terminates (unless siz == 0).
- * Returns wcslen(src); if retval >= siz, truncation occurred.
+ * Copy string src to buffer dst of size dsize.  At most dsize-1
+ * chars will be copied.  Always NUL terminates (unless dsize == 0).
+ * Returns wcslen(src); if retval >= dsize, truncation occurred.
  */
 size_t
-wcslcpy(wchar_t *dst, const wchar_t *src, size_t siz)
+wcslcpy(wchar_t *dst, const wchar_t *src, size_t dsize)
 {
-	wchar_t *d = dst;
-	const wchar_t *s = src;
-	size_t n = siz;
+	const wchar_t *osrc = src;
+	size_t nleft = dsize;
 
-	/* Copy as many bytes as will fit */
-	if (n != 0) {
-		while (--n != 0) {
-			if ((*d++ = *s++) == '\0')
+	/* Copy as many bytes as will fit. */
+	if (nleft != 0) {
+		while (--nleft != 0) {
+			if ((*dst++ = *src++) == L'\0')
 				break;
 		}
 	}
 
-	/* Not enough room in dst, add NUL and traverse rest of src */
-	if (n == 0) {
-		if (siz != 0)
-			*d = '\0';		/* NUL-terminate dst */
-		while (*s++)
+	/* Not enough room in dst, add NUL and traverse rest of src. */
+	if (nleft == 0) {
+		if (dsize != 0)
+			*dst = L'\0';		/* NUL-terminate dst */
+		while (*src++)
 			;
 	}
 
-	return(s - src - 1);	/* count does not include NUL */
+	return(src - osrc - 1);	/* count does not include NUL */
 }
+DEF_WEAK(wcslcpy);
diff --git a/libc/upstream-openbsd/lib/libc/time/wcsftime.c b/libc/upstream-openbsd/lib/libc/time/wcsftime.c
index 21ccac7..0678404 100644
--- a/libc/upstream-openbsd/lib/libc/time/wcsftime.c
+++ b/libc/upstream-openbsd/lib/libc/time/wcsftime.c
@@ -1,6 +1,4 @@
-/*	$OpenBSD: wcsftime.c,v 1.3 2014/05/06 15:49:45 tedu Exp $ */
-#include "private.h"
-
+/*	$OpenBSD: wcsftime.c,v 1.6 2015/02/09 14:52:28 tedu Exp $ */
 /*
 ** Based on the UCB version with the ID appearing below.
 ** This is ANSIish only when "multibyte character == plain character".
@@ -33,11 +31,13 @@
 ** SUCH DAMAGE.
 */
 
-#include "tzfile.h"
-#include "fcntl.h"
+#include <fcntl.h>
 #include <locale.h>
 #include <wchar.h>
 
+#include "private.h"
+#include "tzfile.h"
+
 struct lc_time_T {
 	const wchar_t *	mon[MONSPERYEAR];
 	const wchar_t *	month[MONSPERYEAR];
@@ -292,14 +292,9 @@
 
 				tm = *t;
 				mkt = mktime(&tm);
-				if (TYPE_SIGNED(time_t))
-					(void) swprintf(buf, 
-					    sizeof buf/sizeof buf[0],
-					    L"%ld", (long) mkt);
-				else	
-					(void) swprintf(buf, 
-					    sizeof buf/sizeof buf[0],
-					    L"%lu", (unsigned long) mkt);
+				(void) swprintf(buf, 
+				    sizeof buf/sizeof buf[0],
+				    L"%ld", (long) mkt);
 				pt = _add(buf, pt, ptlim);
 			}
 			continue;
@@ -529,8 +524,8 @@
 _yconv(int a, int b, int convert_top, int convert_yy, wchar_t *pt, 
     const wchar_t *ptlim)
 {
-	register int	lead;
-	register int	trail;
+	int	lead;
+	int	trail;
 
 #define DIVISOR	100
 	trail = a % DIVISOR + b % DIVISOR;
diff --git a/libdl/Android.bp b/libdl/Android.bp
new file mode 100644
index 0000000..2aa9b68
--- /dev/null
+++ b/libdl/Android.bp
@@ -0,0 +1,60 @@
+//
+// libdl
+//
+cc_library {
+
+    // NOTE: --exclude-libs=libgcc.a makes sure that any symbols libdl.so pulls from
+    // libgcc.a are made static to libdl.so.  This in turn ensures that libraries that
+    // a) pull symbols from libgcc.a and b) depend on libdl.so will not rely on libdl.so
+    // to provide those symbols, but will instead pull them from libgcc.a.  Specifically,
+    // we use this property to make sure libc.so has its own copy of the code from
+    // libgcc.a it uses.
+    //
+    // DO NOT REMOVE --exclude-libs!
+
+    ldflags: ["-Wl,--exclude-libs=libgcc.a"],
+
+    // for x86, exclude libgcc_eh.a for the same reasons as above
+    arch: {
+        arm: {
+            version_script: "libdl.arm.map",
+        },
+        arm64: {
+            version_script: "libdl.arm64.map",
+        },
+        mips: {
+            version_script: "libdl.mips.map",
+        },
+        mips64: {
+            version_script: "libdl.mips64.map",
+        },
+        x86: {
+            ldflags: ["-Wl,--exclude-libs=libgcc_eh.a"],
+            version_script: "libdl.x86.map",
+        },
+        x86_64: {
+            ldflags: ["-Wl,--exclude-libs=libgcc_eh.a"],
+            version_script: "libdl.x86_64.map",
+        },
+    },
+    srcs: ["libdl.c"],
+    cflags: [
+        "-Wall",
+        "-Wextra",
+        "-Wunused",
+        "-Werror",
+    ],
+    stl: "none",
+
+    name: "libdl",
+
+    // NOTE: libdl needs __aeabi_unwind_cpp_pr0 from libgcc.a but libgcc.a needs a
+    // few symbols from libc. Using --no-undefined here results in having to link
+    // against libc creating a circular dependency which is removed and we end up
+    // with missing symbols. Since this library is just a bunch of stubs, we set
+    // LOCAL_ALLOW_UNDEFINED_SYMBOLS to remove --no-undefined from the linker flags.
+    allow_undefined_symbols: true,
+    system_shared_libs: [],
+
+    sanitize: ["never"],
+}
diff --git a/libdl/Android.mk b/libdl/Android.mk
index 7b97dc4..1ea5dc7 100644
--- a/libdl/Android.mk
+++ b/libdl/Android.mk
@@ -15,18 +15,31 @@
 #
 # DO NOT REMOVE --exclude-libs!
 
-LOCAL_LDFLAGS := -Wl,--exclude-libs=libgcc.a -Wl,--version-script=$(LOCAL_PATH)/libdl.map
+LOCAL_LDFLAGS := -Wl,--exclude-libs=libgcc.a
 
 # for x86, exclude libgcc_eh.a for the same reasons as above
 LOCAL_LDFLAGS_x86 := -Wl,--exclude-libs=libgcc_eh.a
 LOCAL_LDFLAGS_x86_64 := $(LOCAL_LDFLAGS_x86)
 
+LOCAL_LDFLAGS_arm    += -Wl,--version-script=$(LOCAL_PATH)/libdl.arm.map
+LOCAL_LDFLAGS_arm64  += -Wl,--version-script=$(LOCAL_PATH)/libdl.arm64.map
+LOCAL_LDFLAGS_mips   += -Wl,--version-script=$(LOCAL_PATH)/libdl.mips.map
+LOCAL_LDFLAGS_mips64 += -Wl,--version-script=$(LOCAL_PATH)/libdl.mips64.map
+LOCAL_LDFLAGS_x86    += -Wl,--version-script=$(LOCAL_PATH)/libdl.x86.map
+LOCAL_LDFLAGS_x86_64 += -Wl,--version-script=$(LOCAL_PATH)/libdl.x86_64.map
+
 LOCAL_SRC_FILES:= libdl.c
 LOCAL_CFLAGS := -Wall -Wextra -Wunused -Werror
 LOCAL_CXX_STL := none
 
 LOCAL_MODULE := libdl
-LOCAL_ADDITIONAL_DEPENDENCIES := $(LOCAL_PATH)/Android.mk
+LOCAL_ADDITIONAL_DEPENDENCIES := $(LOCAL_PATH)/Android.mk \
+                                 $(LOCAL_PATH)/libdl.arm.map \
+                                 $(LOCAL_PATH)/libdl.arm64.map \
+                                 $(LOCAL_PATH)/libdl.mips.map \
+                                 $(LOCAL_PATH)/libdl.mips64.map \
+                                 $(LOCAL_PATH)/libdl.x86.map \
+                                 $(LOCAL_PATH)/libdl.x86_64.map \
 
 # NOTE: libdl needs __aeabi_unwind_cpp_pr0 from libgcc.a but libgcc.a needs a
 # few symbols from libc. Using --no-undefined here results in having to link
@@ -36,7 +49,7 @@
 LOCAL_ALLOW_UNDEFINED_SYMBOLS := true
 LOCAL_SYSTEM_SHARED_LIBRARIES :=
 
-LOCAL_ADDRESS_SANITIZER := false
+LOCAL_SANITIZE := never
 include $(BUILD_SHARED_LIBRARY)
 
 # A dummy libdl.a. Need for static executables using the LLVM unwinder. Most
@@ -49,5 +62,5 @@
 
 LOCAL_MODULE := libdl
 LOCAL_ADDITIONAL_DEPENDENCIES := $(LOCAL_PATH)/Android.mk
-LOCAL_ADDRESS_SANITIZER := false
+LOCAL_SANITIZE := never
 include $(BUILD_STATIC_LIBRARY)
diff --git a/libdl/libdl.arm.map b/libdl/libdl.arm.map
new file mode 100644
index 0000000..2821509
--- /dev/null
+++ b/libdl/libdl.arm.map
@@ -0,0 +1,31 @@
+# Generated by genversionscripts.py. Do not edit.
+
+LIBC {
+  global:
+    android_dlopen_ext;
+    dl_iterate_phdr;
+    dl_unwind_find_exidx; # arm
+    dladdr;
+    dlclose;
+    dlerror;
+    dlopen;
+    dlsym;
+  local:
+    *;
+};
+
+LIBC_N {
+  global:
+    dlvsym;
+} LIBC;
+
+LIBC_PLATFORM {
+  global:
+    android_dlwarning;
+    android_get_application_target_sdk_version;
+    android_set_application_target_sdk_version;
+    android_get_LD_LIBRARY_PATH;
+    android_update_LD_LIBRARY_PATH;
+    android_init_namespaces;
+    android_create_namespace;
+} LIBC_N;
diff --git a/libdl/libdl.arm64.map b/libdl/libdl.arm64.map
new file mode 100644
index 0000000..f21859c
--- /dev/null
+++ b/libdl/libdl.arm64.map
@@ -0,0 +1,30 @@
+# Generated by genversionscripts.py. Do not edit.
+
+LIBC {
+  global:
+    android_dlopen_ext;
+    dl_iterate_phdr;
+    dladdr;
+    dlclose;
+    dlerror;
+    dlopen;
+    dlsym;
+  local:
+    *;
+};
+
+LIBC_N {
+  global:
+    dlvsym;
+} LIBC;
+
+LIBC_PLATFORM {
+  global:
+    android_dlwarning;
+    android_get_application_target_sdk_version;
+    android_set_application_target_sdk_version;
+    android_get_LD_LIBRARY_PATH;
+    android_update_LD_LIBRARY_PATH;
+    android_init_namespaces;
+    android_create_namespace;
+} LIBC_N;
diff --git a/libdl/libdl.c b/libdl/libdl.c
index 9a858a3..b62ee5c 100644
--- a/libdl/libdl.c
+++ b/libdl/libdl.c
@@ -24,21 +24,50 @@
 // in the dynamic linker and hijacked at runtime.
 
 void* dlopen(const char* filename __unused, int flag __unused) { return 0; }
+
 const char* dlerror(void) { return 0; }
+
 void* dlsym(void* handle __unused, const char* symbol __unused) { return 0; }
+
+void* dlvsym(void* handle __unused, const char* symbol __unused, const char* version __unused) {
+  return 0;
+}
+
 int dladdr(const void* addr __unused, Dl_info* info __unused) { return 0; }
+
 int dlclose(void* handle __unused) { return 0; }
 
 #if defined(__arm__)
 _Unwind_Ptr dl_unwind_find_exidx(_Unwind_Ptr pc __unused, int* pcount __unused) { return 0; }
 #endif
 
-int dl_iterate_phdr(int (*cb)(struct dl_phdr_info* info, size_t size, void* data) __unused, void* data __unused) { return 0; }
+int dl_iterate_phdr(int (*cb)(struct dl_phdr_info* info, size_t size, void* data) __unused,
+                    void* data __unused) {
+  return 0;
+}
 
 void android_get_LD_LIBRARY_PATH(char* buffer __unused, size_t buffer_size __unused) { }
 void android_update_LD_LIBRARY_PATH(const char* ld_library_path __unused) { }
 
-void* android_dlopen_ext(const char* filename __unused, int flag __unused, const android_dlextinfo* extinfo __unused) { return 0; }
+void* android_dlopen_ext(const char* filename __unused, int flag __unused,
+                         const android_dlextinfo* extinfo __unused) {
+  return 0;
+}
 
 void android_set_application_target_sdk_version(uint32_t target __unused) { }
 uint32_t android_get_application_target_sdk_version() { return 0; }
+
+bool android_init_namespaces(const char* public_ns_sonames __unused,
+                             const char* anon_ns_library_path __unused) {
+  return false;
+}
+
+struct android_namespace_t* android_create_namespace(const char* name __unused,
+                                                     const char* ld_library_path __unused,
+                                                     const char* default_library_path __unused,
+                                                     uint64_t type __unused,
+                                                     const char* permitted_when_isolated_path __unused) {
+  return 0;
+}
+
+void android_dlwarning(void* obj, void (*f)(void*, const char*)) { f(obj, 0); }
diff --git a/libdl/libdl.map b/libdl/libdl.map.txt
similarity index 84%
rename from libdl/libdl.map
rename to libdl/libdl.map.txt
index a911cb6..962692e 100644
--- a/libdl/libdl.map
+++ b/libdl/libdl.map.txt
@@ -18,9 +18,7 @@
   global:
     android_dlopen_ext;
     dl_iterate_phdr;
-# begin arm-only
-    dl_unwind_find_exidx;
-# end arm-only
+    dl_unwind_find_exidx; # arm
     dladdr;
     dlclose;
     dlerror;
@@ -30,10 +28,18 @@
     *;
 };
 
-LIBC_PRIVATE {
+LIBC_N {
   global:
+    dlvsym;
+} LIBC;
+
+LIBC_PLATFORM {
+  global:
+    android_dlwarning;
     android_get_application_target_sdk_version;
     android_set_application_target_sdk_version;
     android_get_LD_LIBRARY_PATH;
     android_update_LD_LIBRARY_PATH;
-} LIBC;
+    android_init_namespaces;
+    android_create_namespace;
+} LIBC_N;
diff --git a/libdl/libdl.mips.map b/libdl/libdl.mips.map
new file mode 100644
index 0000000..f21859c
--- /dev/null
+++ b/libdl/libdl.mips.map
@@ -0,0 +1,30 @@
+# Generated by genversionscripts.py. Do not edit.
+
+LIBC {
+  global:
+    android_dlopen_ext;
+    dl_iterate_phdr;
+    dladdr;
+    dlclose;
+    dlerror;
+    dlopen;
+    dlsym;
+  local:
+    *;
+};
+
+LIBC_N {
+  global:
+    dlvsym;
+} LIBC;
+
+LIBC_PLATFORM {
+  global:
+    android_dlwarning;
+    android_get_application_target_sdk_version;
+    android_set_application_target_sdk_version;
+    android_get_LD_LIBRARY_PATH;
+    android_update_LD_LIBRARY_PATH;
+    android_init_namespaces;
+    android_create_namespace;
+} LIBC_N;
diff --git a/libdl/libdl.mips64.map b/libdl/libdl.mips64.map
new file mode 100644
index 0000000..f21859c
--- /dev/null
+++ b/libdl/libdl.mips64.map
@@ -0,0 +1,30 @@
+# Generated by genversionscripts.py. Do not edit.
+
+LIBC {
+  global:
+    android_dlopen_ext;
+    dl_iterate_phdr;
+    dladdr;
+    dlclose;
+    dlerror;
+    dlopen;
+    dlsym;
+  local:
+    *;
+};
+
+LIBC_N {
+  global:
+    dlvsym;
+} LIBC;
+
+LIBC_PLATFORM {
+  global:
+    android_dlwarning;
+    android_get_application_target_sdk_version;
+    android_set_application_target_sdk_version;
+    android_get_LD_LIBRARY_PATH;
+    android_update_LD_LIBRARY_PATH;
+    android_init_namespaces;
+    android_create_namespace;
+} LIBC_N;
diff --git a/libdl/libdl.x86.map b/libdl/libdl.x86.map
new file mode 100644
index 0000000..f21859c
--- /dev/null
+++ b/libdl/libdl.x86.map
@@ -0,0 +1,30 @@
+# Generated by genversionscripts.py. Do not edit.
+
+LIBC {
+  global:
+    android_dlopen_ext;
+    dl_iterate_phdr;
+    dladdr;
+    dlclose;
+    dlerror;
+    dlopen;
+    dlsym;
+  local:
+    *;
+};
+
+LIBC_N {
+  global:
+    dlvsym;
+} LIBC;
+
+LIBC_PLATFORM {
+  global:
+    android_dlwarning;
+    android_get_application_target_sdk_version;
+    android_set_application_target_sdk_version;
+    android_get_LD_LIBRARY_PATH;
+    android_update_LD_LIBRARY_PATH;
+    android_init_namespaces;
+    android_create_namespace;
+} LIBC_N;
diff --git a/libdl/libdl.x86_64.map b/libdl/libdl.x86_64.map
new file mode 100644
index 0000000..f21859c
--- /dev/null
+++ b/libdl/libdl.x86_64.map
@@ -0,0 +1,30 @@
+# Generated by genversionscripts.py. Do not edit.
+
+LIBC {
+  global:
+    android_dlopen_ext;
+    dl_iterate_phdr;
+    dladdr;
+    dlclose;
+    dlerror;
+    dlopen;
+    dlsym;
+  local:
+    *;
+};
+
+LIBC_N {
+  global:
+    dlvsym;
+} LIBC;
+
+LIBC_PLATFORM {
+  global:
+    android_dlwarning;
+    android_get_application_target_sdk_version;
+    android_set_application_target_sdk_version;
+    android_get_LD_LIBRARY_PATH;
+    android_update_LD_LIBRARY_PATH;
+    android_init_namespaces;
+    android_create_namespace;
+} LIBC_N;
diff --git a/libm/Android.bp b/libm/Android.bp
new file mode 100644
index 0000000..081a139
--- /dev/null
+++ b/libm/Android.bp
@@ -0,0 +1,520 @@
+// ANDROIDMK TRANSLATION ERROR: unsupported directive
+// ifneq ($(TARGET_USE_PRIVATE_LIBM),true)
+
+bionic_coverage = false
+
+libm_common_src_files = [
+    "upstream-freebsd/lib/msun/bsdsrc/b_exp.c",
+    "upstream-freebsd/lib/msun/bsdsrc/b_log.c",
+    "upstream-freebsd/lib/msun/bsdsrc/b_tgamma.c",
+    "upstream-freebsd/lib/msun/src/catrig.c",
+    "upstream-freebsd/lib/msun/src/catrigf.c",
+    "upstream-freebsd/lib/msun/src/e_acos.c",
+    "upstream-freebsd/lib/msun/src/e_acosf.c",
+    "upstream-freebsd/lib/msun/src/e_acosh.c",
+    "upstream-freebsd/lib/msun/src/e_acoshf.c",
+    "upstream-freebsd/lib/msun/src/e_asin.c",
+    "upstream-freebsd/lib/msun/src/e_asinf.c",
+    "upstream-freebsd/lib/msun/src/e_atan2.c",
+    "upstream-freebsd/lib/msun/src/e_atan2f.c",
+    "upstream-freebsd/lib/msun/src/e_atanh.c",
+    "upstream-freebsd/lib/msun/src/e_atanhf.c",
+    "upstream-freebsd/lib/msun/src/e_cosh.c",
+    "upstream-freebsd/lib/msun/src/e_coshf.c",
+    "upstream-freebsd/lib/msun/src/e_exp.c",
+    "upstream-freebsd/lib/msun/src/e_expf.c",
+    "upstream-freebsd/lib/msun/src/e_fmod.c",
+    "upstream-freebsd/lib/msun/src/e_fmodf.c",
+    "upstream-freebsd/lib/msun/src/e_gamma.c",
+    "upstream-freebsd/lib/msun/src/e_gammaf.c",
+    "upstream-freebsd/lib/msun/src/e_gammaf_r.c",
+    "upstream-freebsd/lib/msun/src/e_gamma_r.c",
+    "upstream-freebsd/lib/msun/src/e_hypot.c",
+    "upstream-freebsd/lib/msun/src/e_hypotf.c",
+    "upstream-freebsd/lib/msun/src/e_j0.c",
+    "upstream-freebsd/lib/msun/src/e_j0f.c",
+    "upstream-freebsd/lib/msun/src/e_j1.c",
+    "upstream-freebsd/lib/msun/src/e_j1f.c",
+    "upstream-freebsd/lib/msun/src/e_jn.c",
+    "upstream-freebsd/lib/msun/src/e_jnf.c",
+    "upstream-freebsd/lib/msun/src/e_lgamma.c",
+    "upstream-freebsd/lib/msun/src/e_lgammaf.c",
+    "upstream-freebsd/lib/msun/src/e_lgammaf_r.c",
+    "upstream-freebsd/lib/msun/src/e_lgamma_r.c",
+    "upstream-freebsd/lib/msun/src/e_log10.c",
+    "upstream-freebsd/lib/msun/src/e_log10f.c",
+    "upstream-freebsd/lib/msun/src/e_log2.c",
+    "upstream-freebsd/lib/msun/src/e_log2f.c",
+    "upstream-freebsd/lib/msun/src/e_log.c",
+    "upstream-freebsd/lib/msun/src/e_logf.c",
+    "upstream-freebsd/lib/msun/src/e_pow.c",
+    "upstream-freebsd/lib/msun/src/e_powf.c",
+    "upstream-freebsd/lib/msun/src/e_remainder.c",
+    "upstream-freebsd/lib/msun/src/e_remainderf.c",
+    "upstream-freebsd/lib/msun/src/e_rem_pio2.c",
+    "upstream-freebsd/lib/msun/src/e_rem_pio2f.c",
+    "upstream-freebsd/lib/msun/src/e_scalb.c",
+    "upstream-freebsd/lib/msun/src/e_scalbf.c",
+    "upstream-freebsd/lib/msun/src/e_sinh.c",
+    "upstream-freebsd/lib/msun/src/e_sinhf.c",
+    "upstream-freebsd/lib/msun/src/e_sqrt.c",
+    "upstream-freebsd/lib/msun/src/e_sqrtf.c",
+    "upstream-freebsd/lib/msun/src/imprecise.c",
+    "upstream-freebsd/lib/msun/src/k_cos.c",
+    "upstream-freebsd/lib/msun/src/k_cosf.c",
+    "upstream-freebsd/lib/msun/src/k_exp.c",
+    "upstream-freebsd/lib/msun/src/k_expf.c",
+    "upstream-freebsd/lib/msun/src/k_rem_pio2.c",
+    "upstream-freebsd/lib/msun/src/k_sin.c",
+    "upstream-freebsd/lib/msun/src/k_sinf.c",
+    "upstream-freebsd/lib/msun/src/k_tan.c",
+    "upstream-freebsd/lib/msun/src/k_tanf.c",
+    "upstream-freebsd/lib/msun/src/s_asinh.c",
+    "upstream-freebsd/lib/msun/src/s_asinhf.c",
+    "upstream-freebsd/lib/msun/src/s_atan.c",
+    "upstream-freebsd/lib/msun/src/s_atanf.c",
+    "upstream-freebsd/lib/msun/src/s_carg.c",
+    "upstream-freebsd/lib/msun/src/s_cargf.c",
+    "upstream-freebsd/lib/msun/src/s_cargl.c",
+    "upstream-freebsd/lib/msun/src/s_cbrt.c",
+    "upstream-freebsd/lib/msun/src/s_cbrtf.c",
+    "upstream-freebsd/lib/msun/src/s_ccosh.c",
+    "upstream-freebsd/lib/msun/src/s_ccoshf.c",
+    "upstream-freebsd/lib/msun/src/s_ceil.c",
+    "upstream-freebsd/lib/msun/src/s_ceilf.c",
+    "upstream-freebsd/lib/msun/src/s_cexp.c",
+    "upstream-freebsd/lib/msun/src/s_cexpf.c",
+    "upstream-freebsd/lib/msun/src/s_cimag.c",
+    "upstream-freebsd/lib/msun/src/s_cimagf.c",
+    "upstream-freebsd/lib/msun/src/s_cimagl.c",
+    "upstream-freebsd/lib/msun/src/s_conj.c",
+    "upstream-freebsd/lib/msun/src/s_conjf.c",
+    "upstream-freebsd/lib/msun/src/s_conjl.c",
+    "upstream-freebsd/lib/msun/src/s_copysign.c",
+    "upstream-freebsd/lib/msun/src/s_copysignf.c",
+    "upstream-freebsd/lib/msun/src/s_cos.c",
+    "upstream-freebsd/lib/msun/src/s_cosf.c",
+    "upstream-freebsd/lib/msun/src/s_cproj.c",
+    "upstream-freebsd/lib/msun/src/s_cprojf.c",
+    "upstream-freebsd/lib/msun/src/s_cprojl.c",
+    "upstream-freebsd/lib/msun/src/s_creal.c",
+    "upstream-freebsd/lib/msun/src/s_crealf.c",
+    "upstream-freebsd/lib/msun/src/s_creall.c",
+    "upstream-freebsd/lib/msun/src/s_csinh.c",
+    "upstream-freebsd/lib/msun/src/s_csinhf.c",
+    "upstream-freebsd/lib/msun/src/s_csqrt.c",
+    "upstream-freebsd/lib/msun/src/s_csqrtf.c",
+    "upstream-freebsd/lib/msun/src/s_csqrtl.c",
+    "upstream-freebsd/lib/msun/src/s_ctanh.c",
+    "upstream-freebsd/lib/msun/src/s_ctanhf.c",
+    "upstream-freebsd/lib/msun/src/s_erf.c",
+    "upstream-freebsd/lib/msun/src/s_erff.c",
+    "upstream-freebsd/lib/msun/src/s_exp2.c",
+    "upstream-freebsd/lib/msun/src/s_exp2f.c",
+    "upstream-freebsd/lib/msun/src/s_expm1.c",
+    "upstream-freebsd/lib/msun/src/s_expm1f.c",
+    "upstream-freebsd/lib/msun/src/s_fdim.c",
+    "upstream-freebsd/lib/msun/src/s_finite.c",
+    "upstream-freebsd/lib/msun/src/s_finitef.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_frexp.c",
+    "upstream-freebsd/lib/msun/src/s_frexpf.c",
+    "upstream-freebsd/lib/msun/src/s_ilogb.c",
+    "upstream-freebsd/lib/msun/src/s_ilogbf.c",
+    "upstream-freebsd/lib/msun/src/s_llrint.c",
+    "upstream-freebsd/lib/msun/src/s_llrintf.c",
+    "upstream-freebsd/lib/msun/src/s_llround.c",
+    "upstream-freebsd/lib/msun/src/s_llroundf.c",
+    "upstream-freebsd/lib/msun/src/s_log1p.c",
+    "upstream-freebsd/lib/msun/src/s_log1pf.c",
+    "upstream-freebsd/lib/msun/src/s_logb.c",
+    "upstream-freebsd/lib/msun/src/s_logbf.c",
+    "upstream-freebsd/lib/msun/src/s_lrint.c",
+    "upstream-freebsd/lib/msun/src/s_lrintf.c",
+    "upstream-freebsd/lib/msun/src/s_lround.c",
+    "upstream-freebsd/lib/msun/src/s_lroundf.c",
+    "upstream-freebsd/lib/msun/src/s_modf.c",
+    "upstream-freebsd/lib/msun/src/s_modff.c",
+    "upstream-freebsd/lib/msun/src/s_nan.c",
+    "upstream-freebsd/lib/msun/src/s_nearbyint.c",
+    "upstream-freebsd/lib/msun/src/s_nextafter.c",
+    "upstream-freebsd/lib/msun/src/s_nextafterf.c",
+    "upstream-freebsd/lib/msun/src/s_remquo.c",
+    "upstream-freebsd/lib/msun/src/s_remquof.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_scalbln.c",
+    "upstream-freebsd/lib/msun/src/s_scalbn.c",
+    "upstream-freebsd/lib/msun/src/s_scalbnf.c",
+    "upstream-freebsd/lib/msun/src/s_signgam.c",
+    "upstream-freebsd/lib/msun/src/s_significand.c",
+    "upstream-freebsd/lib/msun/src/s_significandf.c",
+    "upstream-freebsd/lib/msun/src/s_sin.c",
+    "upstream-freebsd/lib/msun/src/s_sinf.c",
+    "upstream-freebsd/lib/msun/src/s_tan.c",
+    "upstream-freebsd/lib/msun/src/s_tanf.c",
+    "upstream-freebsd/lib/msun/src/s_tanh.c",
+    "upstream-freebsd/lib/msun/src/s_tanhf.c",
+    "upstream-freebsd/lib/msun/src/s_tgammaf.c",
+    "upstream-freebsd/lib/msun/src/s_trunc.c",
+    "upstream-freebsd/lib/msun/src/s_truncf.c",
+    "upstream-freebsd/lib/msun/src/w_cabs.c",
+    "upstream-freebsd/lib/msun/src/w_cabsf.c",
+    "upstream-freebsd/lib/msun/src/w_cabsl.c",
+    "upstream-freebsd/lib/msun/src/w_drem.c",
+    "upstream-freebsd/lib/msun/src/w_dremf.c",
+]
+
+libm_common_src_files += [
+    // TODO: this comes from from upstream's libc, not libm, but it's an
+    // implementation detail that should have hidden visibility, so it needs
+    // to be in whatever library the math code is in.
+    "digittoint.c",
+
+    // Functionality not in the BSDs.
+    "significandl.c",
+    "sincos.c",
+
+    // Modified versions of BSD code.
+    "signbit.c",
+
+    // Home-grown stuff.
+    "fabs.cpp",
+]
+
+libm_ld128_src_files = [
+    "upstream-freebsd/lib/msun/src/e_acosl.c",
+    "upstream-freebsd/lib/msun/src/e_acoshl.c",
+    "upstream-freebsd/lib/msun/src/e_asinl.c",
+    "upstream-freebsd/lib/msun/src/e_atan2l.c",
+    "upstream-freebsd/lib/msun/src/e_atanhl.c",
+    "upstream-freebsd/lib/msun/src/e_fmodl.c",
+    "upstream-freebsd/lib/msun/src/e_hypotl.c",
+    "upstream-freebsd/lib/msun/src/e_lgammal.c",
+    "upstream-freebsd/lib/msun/src/e_remainderl.c",
+    "upstream-freebsd/lib/msun/src/e_sqrtl.c",
+    "upstream-freebsd/lib/msun/src/s_asinhl.c",
+    "upstream-freebsd/lib/msun/src/s_atanl.c",
+    "upstream-freebsd/lib/msun/src/s_cbrtl.c",
+    "upstream-freebsd/lib/msun/src/s_ceill.c",
+    "upstream-freebsd/lib/msun/src/s_copysignl.c",
+    "upstream-freebsd/lib/msun/src/e_coshl.c",
+    "upstream-freebsd/lib/msun/src/s_cosl.c",
+    "upstream-freebsd/lib/msun/src/s_floorl.c",
+    "upstream-freebsd/lib/msun/src/s_fmal.c",
+    "upstream-freebsd/lib/msun/src/s_fmaxl.c",
+    "upstream-freebsd/lib/msun/src/s_fminl.c",
+    "upstream-freebsd/lib/msun/src/s_modfl.c",
+    "upstream-freebsd/lib/msun/src/s_frexpl.c",
+    "upstream-freebsd/lib/msun/src/s_ilogbl.c",
+    "upstream-freebsd/lib/msun/src/s_llrintl.c",
+    "upstream-freebsd/lib/msun/src/s_llroundl.c",
+    "upstream-freebsd/lib/msun/src/s_logbl.c",
+    "upstream-freebsd/lib/msun/src/s_lrintl.c",
+    "upstream-freebsd/lib/msun/src/s_lroundl.c",
+    "upstream-freebsd/lib/msun/src/s_nextafterl.c",
+    "upstream-freebsd/lib/msun/src/s_nexttoward.c",
+    "upstream-freebsd/lib/msun/src/s_nexttowardf.c",
+    "upstream-freebsd/lib/msun/src/s_remquol.c",
+    "upstream-freebsd/lib/msun/src/s_rintl.c",
+    "upstream-freebsd/lib/msun/src/s_roundl.c",
+    "upstream-freebsd/lib/msun/src/s_scalbnl.c",
+    "upstream-freebsd/lib/msun/src/e_sinhl.c",
+    "upstream-freebsd/lib/msun/src/s_sinl.c",
+    "upstream-freebsd/lib/msun/src/s_tanhl.c",
+    "upstream-freebsd/lib/msun/src/s_tanl.c",
+    "upstream-freebsd/lib/msun/src/s_truncl.c",
+]
+
+libm_ld128_src_files += [
+    "upstream-freebsd/lib/msun/ld128/invtrig.c",
+    "upstream-freebsd/lib/msun/ld128/e_lgammal_r.c",
+    "upstream-freebsd/lib/msun/ld128/k_cosl.c",
+    "upstream-freebsd/lib/msun/ld128/k_sinl.c",
+    "upstream-freebsd/lib/msun/ld128/k_tanl.c",
+    "upstream-freebsd/lib/msun/ld128/s_erfl.c",
+    "upstream-freebsd/lib/msun/ld128/s_exp2l.c",
+    "upstream-freebsd/lib/msun/ld128/s_expl.c",
+    "upstream-freebsd/lib/msun/ld128/s_logl.c",
+    "upstream-freebsd/lib/msun/ld128/s_nanl.c",
+]
+
+// TODO: re-enable i387/e_sqrtf.S for x86, and maybe others.
+
+libm_common_cflags = [
+    "-D__BIONIC_NO_MATH_INLINES",
+    "-DFLT_EVAL_METHOD=0",
+    "-include freebsd-compat.h",
+    "-Werror",
+    "-Wno-missing-braces",
+    "-Wno-parentheses",
+    "-Wno-sign-compare",
+    "-Wno-uninitialized",
+    "-Wno-unknown-pragmas",
+    "-fvisibility=hidden",
+]
+
+// Workaround the GCC "(long)fn -> lfn" optimization bug which will result in
+// self recursions for lrint, lrintf, and lrintl.
+// BUG: 14225968
+libm_common_cflags += [
+    "-fno-builtin-rint",
+    "-fno-builtin-rintf",
+    "-fno-builtin-rintl",
+]
+
+libm_common_local_includes = ["upstream-freebsd/lib/msun/src/"]
+
+libm_ld_local_includes = ["upstream-freebsd/lib/msun/ld128/"]
+
+//
+// libm.so and libm.a for target.
+//
+cc_library {
+    name: "libm",
+
+    cflags: libm_common_cflags,
+    include_dirs: ["bionic/libc"],
+    local_include_dirs: libm_common_local_includes,
+    srcs: libm_common_src_files,
+    system_shared_libs: ["libc"],
+
+    native_coverage: bionic_coverage,
+    sanitize: ["never"],
+
+    multilib: {
+        lib32: {
+            srcs: ["fake_long_double.c"],
+        },
+        lib64: {
+            srcs: libm_ld128_src_files,
+            local_include_dirs: libm_ld_local_includes,
+            // We'd really like to do this for all architectures, but since this wasn't done
+            // before, these symbols must continue to be exported on LP32 for binary
+            // compatibility.
+            ldflags: ["-Wl,--exclude-libs,libgcc.a"],
+        },
+    },
+
+    // arch-specific settings
+    arch: {
+        arm: {
+            srcs: [
+                "arm/fenv.c",
+            ],
+            armv7_a_neon: {
+                srcs: [
+                    "arm/sqrt.S",
+                    "arm/floor.S",
+                ],
+                exclude_srcs: [
+                    "upstream-freebsd/lib/msun/src/e_sqrt.c",
+                    "upstream-freebsd/lib/msun/src/e_sqrtf.c",
+                    "upstream-freebsd/lib/msun/src/s_floor.c",
+                ],
+            },
+            instruction_set: "arm",
+            ldflags: ["-Wl,--hash-style=both"],
+            version_script: "libm.arm.map",
+        },
+
+        arm64: {
+            srcs: [
+                "arm64/ceil.S",
+                "arm64/fenv.c",
+                "arm64/fma.S",
+                "arm64/floor.S",
+                "arm64/lrint.S",
+                "arm64/rint.S",
+                "arm64/sqrt.S",
+                "arm64/trunc.S",
+            ],
+            exclude_srcs: [
+                "upstream-freebsd/lib/msun/src/e_sqrt.c",
+                "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_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_trunc.c",
+                "upstream-freebsd/lib/msun/src/s_truncf.c",
+            ],
+            version_script: "libm.arm64.map",
+        },
+
+        mips: {
+            srcs: ["mips/fenv.c"],
+            version_script: "libm.mips.map",
+        },
+
+        mips64: {
+            srcs: ["mips/fenv.c"],
+            version_script: "libm.mips64.map",
+        },
+
+        x86: {
+            srcs: [
+                "i387/fenv.c",
+                "x86/sqrt.S",
+                "x86/sqrtf.S",
+                "x86/e_acos.S",
+                "x86/e_asin.S",
+                "x86/e_atan2.S",
+                "x86/e_cosh.S",
+                "x86/e_exp.S",
+                "x86/e_hypot.S",
+                "x86/e_log10.S",
+                "x86/e_log.S",
+                "x86/e_pow.S",
+                "x86/e_sinh.S",
+                "x86/libm_reduce_pi04l.S",
+                "x86/libm_sincos_huge.S",
+                "x86/libm_tancot_huge.S",
+                "x86/s_atan.S",
+                "x86/s_cbrt.S",
+                "x86/s_cos.S",
+                "x86/s_expm1.S",
+                "x86/s_log1p.S",
+                "x86/s_sin.S",
+                "x86/s_tanh.S",
+                "x86/s_tan.S",
+            ],
+            exclude_srcs: [
+                "upstream-freebsd/lib/msun/src/e_acos.c",
+                "upstream-freebsd/lib/msun/src/e_asin.c",
+                "upstream-freebsd/lib/msun/src/e_atan2.c",
+                "upstream-freebsd/lib/msun/src/e_cosh.c",
+                "upstream-freebsd/lib/msun/src/e_exp.c",
+                "upstream-freebsd/lib/msun/src/e_hypot.c",
+                "upstream-freebsd/lib/msun/src/e_log.c",
+                "upstream-freebsd/lib/msun/src/e_log10.c",
+                "upstream-freebsd/lib/msun/src/e_pow.c",
+                "upstream-freebsd/lib/msun/src/e_sinh.c",
+                "upstream-freebsd/lib/msun/src/e_sqrt.c",
+                "upstream-freebsd/lib/msun/src/e_sqrtf.c",
+                "upstream-freebsd/lib/msun/src/s_atan.c",
+                "upstream-freebsd/lib/msun/src/s_cbrt.c",
+                "upstream-freebsd/lib/msun/src/s_cos.c",
+                "upstream-freebsd/lib/msun/src/s_expm1.c",
+                "upstream-freebsd/lib/msun/src/s_log1p.c",
+                "upstream-freebsd/lib/msun/src/s_sin.c",
+                "upstream-freebsd/lib/msun/src/s_tan.c",
+                "upstream-freebsd/lib/msun/src/s_tanh.c",
+            ],
+            sse4_1: {
+                srcs: [
+                    "x86/ceil.S",
+                    "x86/ceilf.S",
+                    "x86/floor.S",
+                    "x86/floorf.S",
+                    "x86/trunc.S",
+                    "x86/truncf.S",
+                ],
+                exclude_srcs: [
+                    "upstream-freebsd/lib/msun/src/s_ceil.c",
+                    "upstream-freebsd/lib/msun/src/s_ceilf.c",
+                    "upstream-freebsd/lib/msun/src/s_floor.c",
+                    "upstream-freebsd/lib/msun/src/s_floorf.c",
+                    "upstream-freebsd/lib/msun/src/s_trunc.c",
+                    "upstream-freebsd/lib/msun/src/s_truncf.c",
+                ],
+            },
+            local_include_dirs: ["i387"],
+            // Clang has wrong long double sizes for x86.
+            clang: false,
+            ldflags: ["-Wl,--hash-style=both"],
+            version_script: "libm.x86.map",
+        },
+
+        x86_64: {
+            srcs: [
+                "amd64/fenv.c",
+                "x86_64/sqrt.S",
+                "x86_64/sqrtf.S",
+                "x86_64/e_acos.S",
+                "x86_64/e_asin.S",
+                "x86_64/e_atan2.S",
+                "x86_64/e_cosh.S",
+                "x86_64/e_exp.S",
+                "x86_64/e_hypot.S",
+                "x86_64/e_log10.S",
+                "x86_64/e_log.S",
+                "x86_64/e_pow.S",
+                "x86_64/e_sinh.S",
+                "x86_64/s_atan.S",
+                "x86_64/s_cbrt.S",
+                "x86_64/s_cos.S",
+                "x86_64/s_expm1.S",
+                "x86_64/s_log1p.S",
+                "x86_64/s_sin.S",
+                "x86_64/s_tanh.S",
+                "x86_64/s_tan.S",
+            ],
+            exclude_srcs: [
+                "upstream-freebsd/lib/msun/src/e_acos.c",
+                "upstream-freebsd/lib/msun/src/e_asin.c",
+                "upstream-freebsd/lib/msun/src/e_atan2.c",
+                "upstream-freebsd/lib/msun/src/e_cosh.c",
+                "upstream-freebsd/lib/msun/src/e_exp.c",
+                "upstream-freebsd/lib/msun/src/e_hypot.c",
+                "upstream-freebsd/lib/msun/src/e_log.c",
+                "upstream-freebsd/lib/msun/src/e_log10.c",
+                "upstream-freebsd/lib/msun/src/e_pow.c",
+                "upstream-freebsd/lib/msun/src/e_sinh.c",
+                "upstream-freebsd/lib/msun/src/e_sqrt.c",
+                "upstream-freebsd/lib/msun/src/e_sqrtf.c",
+                "upstream-freebsd/lib/msun/src/s_atan.c",
+                "upstream-freebsd/lib/msun/src/s_cbrt.c",
+                "upstream-freebsd/lib/msun/src/s_cos.c",
+                "upstream-freebsd/lib/msun/src/s_expm1.c",
+                "upstream-freebsd/lib/msun/src/s_log1p.c",
+                "upstream-freebsd/lib/msun/src/s_sin.c",
+                "upstream-freebsd/lib/msun/src/s_tan.c",
+                "upstream-freebsd/lib/msun/src/s_tanh.c",
+            ],
+            sse4_1: {
+                srcs: [
+                    "x86_64/ceil.S",
+                    "x86_64/ceilf.S",
+                    "x86_64/floor.S",
+                    "x86_64/floorf.S",
+                    "x86_64/trunc.S",
+                    "x86_64/truncf.S",
+                ],
+                exclude_srcs: [
+                    "upstream-freebsd/lib/msun/src/s_ceil.c",
+                    "upstream-freebsd/lib/msun/src/s_ceilf.c",
+                    "upstream-freebsd/lib/msun/src/s_floor.c",
+                    "upstream-freebsd/lib/msun/src/s_floorf.c",
+                    "upstream-freebsd/lib/msun/src/s_trunc.c",
+                    "upstream-freebsd/lib/msun/src/s_truncf.c",
+                ],
+            },
+            // Clang has wrong long double sizes for x86.
+            clang: false,
+            version_script: "libm.x86_64.map",
+        },
+    },
+
+    stl: "none",
+}
+
+// ANDROIDMK TRANSLATION ERROR: unsupported directive
+// endif
diff --git a/libm/Android.mk b/libm/Android.mk
index e919129..6575e1e 100644
--- a/libm/Android.mk
+++ b/libm/Android.mk
@@ -3,8 +3,9 @@
 
 bionic_coverage := false
 
-ifneq (,$(filter $(TARGET_ARCH),x86 x86_64))
-# Clang has wrong long double sizes for x86.
+# Clang/llvm has incompatible long double (fp128) for x86_64.
+# https://llvm.org/bugs/show_bug.cgi?id=23897
+ifeq ($(TARGET_ARCH),x86_64)
 libm_clang := false
 endif
 
@@ -21,14 +22,19 @@
     upstream-freebsd/lib/msun/bsdsrc/b_tgamma.c \
     upstream-freebsd/lib/msun/src/catrig.c \
     upstream-freebsd/lib/msun/src/catrigf.c \
+    upstream-freebsd/lib/msun/src/e_acos.c \
     upstream-freebsd/lib/msun/src/e_acosf.c \
     upstream-freebsd/lib/msun/src/e_acosh.c \
     upstream-freebsd/lib/msun/src/e_acoshf.c \
+    upstream-freebsd/lib/msun/src/e_asin.c \
     upstream-freebsd/lib/msun/src/e_asinf.c \
+    upstream-freebsd/lib/msun/src/e_atan2.c \
     upstream-freebsd/lib/msun/src/e_atan2f.c \
     upstream-freebsd/lib/msun/src/e_atanh.c \
     upstream-freebsd/lib/msun/src/e_atanhf.c \
+    upstream-freebsd/lib/msun/src/e_cosh.c \
     upstream-freebsd/lib/msun/src/e_coshf.c \
+    upstream-freebsd/lib/msun/src/e_exp.c \
     upstream-freebsd/lib/msun/src/e_expf.c \
     upstream-freebsd/lib/msun/src/e_fmod.c \
     upstream-freebsd/lib/msun/src/e_fmodf.c \
@@ -36,6 +42,7 @@
     upstream-freebsd/lib/msun/src/e_gammaf.c \
     upstream-freebsd/lib/msun/src/e_gammaf_r.c \
     upstream-freebsd/lib/msun/src/e_gamma_r.c \
+    upstream-freebsd/lib/msun/src/e_hypot.c \
     upstream-freebsd/lib/msun/src/e_hypotf.c \
     upstream-freebsd/lib/msun/src/e_j0.c \
     upstream-freebsd/lib/msun/src/e_j0f.c \
@@ -47,10 +54,13 @@
     upstream-freebsd/lib/msun/src/e_lgammaf.c \
     upstream-freebsd/lib/msun/src/e_lgammaf_r.c \
     upstream-freebsd/lib/msun/src/e_lgamma_r.c \
+    upstream-freebsd/lib/msun/src/e_log10.c \
     upstream-freebsd/lib/msun/src/e_log10f.c \
     upstream-freebsd/lib/msun/src/e_log2.c \
     upstream-freebsd/lib/msun/src/e_log2f.c \
+    upstream-freebsd/lib/msun/src/e_log.c \
     upstream-freebsd/lib/msun/src/e_logf.c \
+    upstream-freebsd/lib/msun/src/e_pow.c \
     upstream-freebsd/lib/msun/src/e_powf.c \
     upstream-freebsd/lib/msun/src/e_remainder.c \
     upstream-freebsd/lib/msun/src/e_remainderf.c \
@@ -58,7 +68,10 @@
     upstream-freebsd/lib/msun/src/e_rem_pio2f.c \
     upstream-freebsd/lib/msun/src/e_scalb.c \
     upstream-freebsd/lib/msun/src/e_scalbf.c \
+    upstream-freebsd/lib/msun/src/e_sinh.c \
     upstream-freebsd/lib/msun/src/e_sinhf.c \
+    upstream-freebsd/lib/msun/src/e_sqrt.c \
+    upstream-freebsd/lib/msun/src/e_sqrtf.c \
     upstream-freebsd/lib/msun/src/imprecise.c \
     upstream-freebsd/lib/msun/src/k_cos.c \
     upstream-freebsd/lib/msun/src/k_cosf.c \
@@ -71,13 +84,17 @@
     upstream-freebsd/lib/msun/src/k_tanf.c \
     upstream-freebsd/lib/msun/src/s_asinh.c \
     upstream-freebsd/lib/msun/src/s_asinhf.c \
+    upstream-freebsd/lib/msun/src/s_atan.c \
     upstream-freebsd/lib/msun/src/s_atanf.c \
     upstream-freebsd/lib/msun/src/s_carg.c \
     upstream-freebsd/lib/msun/src/s_cargf.c \
     upstream-freebsd/lib/msun/src/s_cargl.c \
+    upstream-freebsd/lib/msun/src/s_cbrt.c \
     upstream-freebsd/lib/msun/src/s_cbrtf.c \
     upstream-freebsd/lib/msun/src/s_ccosh.c \
     upstream-freebsd/lib/msun/src/s_ccoshf.c \
+    upstream-freebsd/lib/msun/src/s_ceil.c \
+    upstream-freebsd/lib/msun/src/s_ceilf.c \
     upstream-freebsd/lib/msun/src/s_cexp.c \
     upstream-freebsd/lib/msun/src/s_cexpf.c \
     upstream-freebsd/lib/msun/src/s_cimag.c \
@@ -88,6 +105,7 @@
     upstream-freebsd/lib/msun/src/s_conjl.c \
     upstream-freebsd/lib/msun/src/s_copysign.c \
     upstream-freebsd/lib/msun/src/s_copysignf.c \
+    upstream-freebsd/lib/msun/src/s_cos.c \
     upstream-freebsd/lib/msun/src/s_cosf.c \
     upstream-freebsd/lib/msun/src/s_cproj.c \
     upstream-freebsd/lib/msun/src/s_cprojf.c \
@@ -106,12 +124,15 @@
     upstream-freebsd/lib/msun/src/s_erff.c \
     upstream-freebsd/lib/msun/src/s_exp2.c \
     upstream-freebsd/lib/msun/src/s_exp2f.c \
+    upstream-freebsd/lib/msun/src/s_expm1.c \
     upstream-freebsd/lib/msun/src/s_expm1f.c \
-    upstream-freebsd/lib/msun/src/s_fabs.c \
-    upstream-freebsd/lib/msun/src/s_fabsf.c \
     upstream-freebsd/lib/msun/src/s_fdim.c \
     upstream-freebsd/lib/msun/src/s_finite.c \
     upstream-freebsd/lib/msun/src/s_finitef.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 \
@@ -120,11 +141,16 @@
     upstream-freebsd/lib/msun/src/s_frexpf.c \
     upstream-freebsd/lib/msun/src/s_ilogb.c \
     upstream-freebsd/lib/msun/src/s_ilogbf.c \
+    upstream-freebsd/lib/msun/src/s_llrint.c \
+    upstream-freebsd/lib/msun/src/s_llrintf.c \
     upstream-freebsd/lib/msun/src/s_llround.c \
     upstream-freebsd/lib/msun/src/s_llroundf.c \
+    upstream-freebsd/lib/msun/src/s_log1p.c \
     upstream-freebsd/lib/msun/src/s_log1pf.c \
     upstream-freebsd/lib/msun/src/s_logb.c \
     upstream-freebsd/lib/msun/src/s_logbf.c \
+    upstream-freebsd/lib/msun/src/s_lrint.c \
+    upstream-freebsd/lib/msun/src/s_lrintf.c \
     upstream-freebsd/lib/msun/src/s_lround.c \
     upstream-freebsd/lib/msun/src/s_lroundf.c \
     upstream-freebsd/lib/msun/src/s_modf.c \
@@ -135,6 +161,8 @@
     upstream-freebsd/lib/msun/src/s_nextafterf.c \
     upstream-freebsd/lib/msun/src/s_remquo.c \
     upstream-freebsd/lib/msun/src/s_remquof.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_scalbln.c \
@@ -143,10 +171,15 @@
     upstream-freebsd/lib/msun/src/s_signgam.c \
     upstream-freebsd/lib/msun/src/s_significand.c \
     upstream-freebsd/lib/msun/src/s_significandf.c \
+    upstream-freebsd/lib/msun/src/s_sin.c \
     upstream-freebsd/lib/msun/src/s_sinf.c \
+    upstream-freebsd/lib/msun/src/s_tan.c \
     upstream-freebsd/lib/msun/src/s_tanf.c \
+    upstream-freebsd/lib/msun/src/s_tanh.c \
     upstream-freebsd/lib/msun/src/s_tanhf.c \
     upstream-freebsd/lib/msun/src/s_tgammaf.c \
+    upstream-freebsd/lib/msun/src/s_trunc.c \
+    upstream-freebsd/lib/msun/src/s_truncf.c \
     upstream-freebsd/lib/msun/src/w_cabs.c \
     upstream-freebsd/lib/msun/src/w_cabsf.c \
     upstream-freebsd/lib/msun/src/w_cabsl.c \
@@ -174,7 +207,6 @@
     upstream-freebsd/lib/msun/src/s_copysignl.c \
     upstream-freebsd/lib/msun/src/e_coshl.c \
     upstream-freebsd/lib/msun/src/s_cosl.c \
-    upstream-freebsd/lib/msun/src/s_fabsl.c \
     upstream-freebsd/lib/msun/src/s_floorl.c \
     upstream-freebsd/lib/msun/src/s_fmal.c \
     upstream-freebsd/lib/msun/src/s_fmaxl.c \
@@ -227,6 +259,10 @@
 LOCAL_SRC_FILES += \
     signbit.c \
 
+# Home-grown stuff.
+LOCAL_SRC_FILES += \
+    fabs.cpp \
+
 # Arch specific optimizations.
 
 # -----------------------------------------------------------------------------
@@ -234,37 +270,6 @@
 # -----------------------------------------------------------------------------
 LOCAL_SRC_FILES_arm += \
     arm/fenv.c \
-    upstream-freebsd/lib/msun/src/e_acos.c \
-    upstream-freebsd/lib/msun/src/e_asin.c \
-    upstream-freebsd/lib/msun/src/e_atan2.c \
-    upstream-freebsd/lib/msun/src/e_cosh.c \
-    upstream-freebsd/lib/msun/src/e_exp.c \
-    upstream-freebsd/lib/msun/src/e_hypot.c \
-    upstream-freebsd/lib/msun/src/e_log.c \
-    upstream-freebsd/lib/msun/src/e_log10.c \
-    upstream-freebsd/lib/msun/src/e_pow.c \
-    upstream-freebsd/lib/msun/src/e_sinh.c \
-    upstream-freebsd/lib/msun/src/s_atan.c \
-    upstream-freebsd/lib/msun/src/s_cbrt.c \
-    upstream-freebsd/lib/msun/src/s_ceil.c \
-    upstream-freebsd/lib/msun/src/s_ceilf.c \
-    upstream-freebsd/lib/msun/src/s_cos.c \
-    upstream-freebsd/lib/msun/src/s_fma.c \
-    upstream-freebsd/lib/msun/src/s_fmaf.c \
-    upstream-freebsd/lib/msun/src/s_floorf.c \
-    upstream-freebsd/lib/msun/src/s_expm1.c \
-    upstream-freebsd/lib/msun/src/s_llrint.c \
-    upstream-freebsd/lib/msun/src/s_llrintf.c \
-    upstream-freebsd/lib/msun/src/s_log1p.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_sin.c \
-    upstream-freebsd/lib/msun/src/s_tan.c \
-    upstream-freebsd/lib/msun/src/s_tanh.c \
-    upstream-freebsd/lib/msun/src/s_trunc.c \
-    upstream-freebsd/lib/msun/src/s_truncf.c \
 
 # s_floor.S requires neon instructions.
 ifdef TARGET_2ND_ARCH
@@ -274,18 +279,16 @@
 endif
 
 # Use the C version on armv7-a since it doesn't support neon instructions.
-ifeq ($(arch_variant),armv7-a)
+ifneq ($(arch_variant),armv7-a)
 LOCAL_SRC_FILES_arm += \
+    arm/sqrt.S \
+    arm/floor.S \
+
+LOCAL_SRC_FILES_EXCLUDE_arm += \
     upstream-freebsd/lib/msun/src/e_sqrt.c \
     upstream-freebsd/lib/msun/src/e_sqrtf.c \
     upstream-freebsd/lib/msun/src/s_floor.c \
 
-else
-LOCAL_SRC_FILES_arm += \
-    arm/e_sqrt.S \
-    arm/e_sqrtf.S \
-    arm/s_floor.S \
-
 endif
 
 # -----------------------------------------------------------------------------
@@ -300,64 +303,30 @@
     arm64/rint.S \
     arm64/sqrt.S \
     arm64/trunc.S \
-    upstream-freebsd/lib/msun/src/e_acos.c \
-    upstream-freebsd/lib/msun/src/e_asin.c \
-    upstream-freebsd/lib/msun/src/e_atan2.c \
-    upstream-freebsd/lib/msun/src/e_cosh.c \
-    upstream-freebsd/lib/msun/src/e_exp.c \
-    upstream-freebsd/lib/msun/src/e_hypot.c \
-    upstream-freebsd/lib/msun/src/e_log.c \
-    upstream-freebsd/lib/msun/src/e_log10.c \
-    upstream-freebsd/lib/msun/src/e_pow.c \
-    upstream-freebsd/lib/msun/src/e_sinh.c \
-    upstream-freebsd/lib/msun/src/s_atan.c \
-    upstream-freebsd/lib/msun/src/s_cbrt.c \
-    upstream-freebsd/lib/msun/src/s_cos.c \
-    upstream-freebsd/lib/msun/src/s_expm1.c \
-    upstream-freebsd/lib/msun/src/s_log1p.c \
-    upstream-freebsd/lib/msun/src/s_sin.c \
-    upstream-freebsd/lib/msun/src/s_tan.c \
-    upstream-freebsd/lib/msun/src/s_tanh.c \
+
+LOCAL_SRC_FILES_EXCLUDE_arm64 += \
+    upstream-freebsd/lib/msun/src/e_sqrt.c \
+    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_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_trunc.c \
+    upstream-freebsd/lib/msun/src/s_truncf.c \
 
 # -----------------------------------------------------------------------------
 # mips
 # -----------------------------------------------------------------------------
 libm_mips_arch_files := \
     mips/fenv.c \
-    upstream-freebsd/lib/msun/src/e_acos.c \
-    upstream-freebsd/lib/msun/src/e_asin.c \
-    upstream-freebsd/lib/msun/src/e_atan2.c \
-    upstream-freebsd/lib/msun/src/e_cosh.c \
-    upstream-freebsd/lib/msun/src/e_exp.c \
-    upstream-freebsd/lib/msun/src/e_hypot.c \
-    upstream-freebsd/lib/msun/src/e_log.c \
-    upstream-freebsd/lib/msun/src/e_log10.c \
-    upstream-freebsd/lib/msun/src/e_pow.c \
-    upstream-freebsd/lib/msun/src/e_sinh.c \
-    upstream-freebsd/lib/msun/src/e_sqrt.c \
-    upstream-freebsd/lib/msun/src/e_sqrtf.c \
-    upstream-freebsd/lib/msun/src/s_atan.c \
-    upstream-freebsd/lib/msun/src/s_cbrt.c \
-    upstream-freebsd/lib/msun/src/s_ceil.c \
-    upstream-freebsd/lib/msun/src/s_ceilf.c \
-    upstream-freebsd/lib/msun/src/s_cos.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_expm1.c \
-    upstream-freebsd/lib/msun/src/s_llrint.c \
-    upstream-freebsd/lib/msun/src/s_llrintf.c \
-    upstream-freebsd/lib/msun/src/s_log1p.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_sin.c \
-    upstream-freebsd/lib/msun/src/s_tan.c \
-    upstream-freebsd/lib/msun/src/s_tanh.c \
-    upstream-freebsd/lib/msun/src/s_trunc.c \
-    upstream-freebsd/lib/msun/src/s_truncf.c \
 
 LOCAL_SRC_FILES_mips += $(libm_mips_arch_files)
 LOCAL_SRC_FILES_mips64 += $(libm_mips_arch_files)
@@ -367,14 +336,6 @@
 # -----------------------------------------------------------------------------
 LOCAL_SRC_FILES_x86 += \
     i387/fenv.c \
-    upstream-freebsd/lib/msun/src/s_fma.c \
-    upstream-freebsd/lib/msun/src/s_fmaf.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 \
     x86/sqrt.S \
     x86/sqrtf.S \
     x86/e_acos.S \
@@ -390,6 +351,8 @@
     x86/libm_reduce_pi04l.S \
     x86/libm_sincos_huge.S \
     x86/libm_tancot_huge.S \
+    x86/lrint.S \
+    x86/lrintf.S \
     x86/s_atan.S \
     x86/s_cbrt.S \
     x86/s_cos.S \
@@ -399,21 +362,48 @@
     x86/s_tanh.S \
     x86/s_tan.S \
 
+LOCAL_SRC_FILES_EXCLUDE_x86 += \
+    upstream-freebsd/lib/msun/src/e_acos.c \
+    upstream-freebsd/lib/msun/src/e_asin.c \
+    upstream-freebsd/lib/msun/src/e_atan2.c \
+    upstream-freebsd/lib/msun/src/e_cosh.c \
+    upstream-freebsd/lib/msun/src/e_exp.c \
+    upstream-freebsd/lib/msun/src/e_hypot.c \
+    upstream-freebsd/lib/msun/src/e_log.c \
+    upstream-freebsd/lib/msun/src/e_log10.c \
+    upstream-freebsd/lib/msun/src/e_pow.c \
+    upstream-freebsd/lib/msun/src/e_sinh.c \
+    upstream-freebsd/lib/msun/src/e_sqrt.c \
+    upstream-freebsd/lib/msun/src/e_sqrtf.c \
+    upstream-freebsd/lib/msun/src/s_atan.c \
+    upstream-freebsd/lib/msun/src/s_cbrt.c \
+    upstream-freebsd/lib/msun/src/s_cos.c \
+    upstream-freebsd/lib/msun/src/s_expm1.c \
+    upstream-freebsd/lib/msun/src/s_log1p.c \
+    upstream-freebsd/lib/msun/src/s_lrint.c \
+    upstream-freebsd/lib/msun/src/s_lrintf.c \
+    upstream-freebsd/lib/msun/src/s_sin.c \
+    upstream-freebsd/lib/msun/src/s_tan.c \
+    upstream-freebsd/lib/msun/src/s_tanh.c \
+
 ifeq ($(ARCH_X86_HAVE_SSE4_1),true)
 LOCAL_SRC_FILES_x86 += \
     x86/ceil.S \
     x86/ceilf.S \
     x86/floor.S \
     x86/floorf.S \
+    x86/rint.S \
+    x86/rintf.S \
     x86/trunc.S \
     x86/truncf.S \
 
-else
-LOCAL_SRC_FILES_x86 += \
+LOCAL_SRC_FILES_EXCLUDE_x86 += \
     upstream-freebsd/lib/msun/src/s_ceil.c \
     upstream-freebsd/lib/msun/src/s_ceilf.c \
     upstream-freebsd/lib/msun/src/s_floor.c \
     upstream-freebsd/lib/msun/src/s_floorf.c \
+    upstream-freebsd/lib/msun/src/s_rint.c \
+    upstream-freebsd/lib/msun/src/s_rintf.c \
     upstream-freebsd/lib/msun/src/s_trunc.c \
     upstream-freebsd/lib/msun/src/s_truncf.c \
 
@@ -424,14 +414,6 @@
 # -----------------------------------------------------------------------------
 LOCAL_SRC_FILES_x86_64 += \
     amd64/fenv.c \
-    upstream-freebsd/lib/msun/src/s_fma.c \
-    upstream-freebsd/lib/msun/src/s_fmaf.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 \
     x86_64/sqrt.S \
     x86_64/sqrtf.S \
     x86_64/e_acos.S \
@@ -444,6 +426,8 @@
     x86_64/e_log.S \
     x86_64/e_pow.S \
     x86_64/e_sinh.S \
+    x86_64/lrint.S \
+    x86_64/lrintf.S \
     x86_64/s_atan.S \
     x86_64/s_cbrt.S \
     x86_64/s_cos.S \
@@ -453,21 +437,50 @@
     x86_64/s_tanh.S \
     x86_64/s_tan.S \
 
+LOCAL_SRC_FILES_EXCLUDE_x86_64 += \
+    upstream-freebsd/lib/msun/src/e_acos.c \
+    upstream-freebsd/lib/msun/src/e_asin.c \
+    upstream-freebsd/lib/msun/src/e_atan2.c \
+    upstream-freebsd/lib/msun/src/e_cosh.c \
+    upstream-freebsd/lib/msun/src/e_exp.c \
+    upstream-freebsd/lib/msun/src/e_hypot.c \
+    upstream-freebsd/lib/msun/src/e_log.c \
+    upstream-freebsd/lib/msun/src/e_log10.c \
+    upstream-freebsd/lib/msun/src/e_pow.c \
+    upstream-freebsd/lib/msun/src/e_sinh.c \
+    upstream-freebsd/lib/msun/src/e_sqrt.c \
+    upstream-freebsd/lib/msun/src/e_sqrtf.c \
+    upstream-freebsd/lib/msun/src/s_atan.c \
+    upstream-freebsd/lib/msun/src/s_cbrt.c \
+    upstream-freebsd/lib/msun/src/s_cos.c \
+    upstream-freebsd/lib/msun/src/s_expm1.c \
+    upstream-freebsd/lib/msun/src/s_log1p.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_sin.c \
+    upstream-freebsd/lib/msun/src/s_tan.c \
+    upstream-freebsd/lib/msun/src/s_tanh.c \
+
 ifeq ($(ARCH_X86_HAVE_SSE4_1),true)
 LOCAL_SRC_FILES_x86_64 += \
     x86_64/ceil.S \
     x86_64/ceilf.S \
     x86_64/floor.S \
     x86_64/floorf.S \
+    x86_64/rint.S \
+    x86_64/rintf.S \
     x86_64/trunc.S \
     x86_64/truncf.S \
 
-else
-LOCAL_SRC_FILES_x86_64 += \
+LOCAL_SRC_FILES_EXCLUDE_x86_64 += \
     upstream-freebsd/lib/msun/src/s_ceil.c \
     upstream-freebsd/lib/msun/src/s_ceilf.c \
     upstream-freebsd/lib/msun/src/s_floor.c \
     upstream-freebsd/lib/msun/src/s_floorf.c \
+    upstream-freebsd/lib/msun/src/s_rint.c \
+    upstream-freebsd/lib/msun/src/s_rintf.c \
     upstream-freebsd/lib/msun/src/s_trunc.c \
     upstream-freebsd/lib/msun/src/s_truncf.c \
 
@@ -481,8 +494,10 @@
 LOCAL_CLANG := $(libm_clang)
 LOCAL_ARM_MODE := arm
 LOCAL_CFLAGS := \
+    -D__BIONIC_NO_MATH_INLINES \
     -DFLT_EVAL_METHOD=0 \
     -include $(LOCAL_PATH)/freebsd-compat.h \
+    -Werror \
     -Wno-missing-braces \
     -Wno-parentheses \
     -Wno-sign-compare \
@@ -501,11 +516,8 @@
     -fno-builtin-rintf \
     -fno-builtin-rintl \
 
-LOCAL_CONLY_FLAGS := \
-    -std=c99 \
-
 LOCAL_NATIVE_COVERAGE := $(bionic_coverage)
-LOCAL_ADDRESS_SANITIZER := false
+LOCAL_SANITIZE := never
 include $(BUILD_STATIC_LIBRARY)
 
 # -----------------------------------------------------------------------------
@@ -513,13 +525,25 @@
 # -----------------------------------------------------------------------------
 include $(CLEAR_VARS)
 
-LOCAL_ADDITIONAL_DEPENDENCIES := $(LOCAL_PATH)/libm.map
+LOCAL_ADDITIONAL_DEPENDENCIES := \
+    $(LOCAL_PATH)/libm.arm.map \
+    $(LOCAL_PATH)/libm.arm64.map \
+    $(LOCAL_PATH)/libm.mips.map \
+    $(LOCAL_PATH)/libm.mips64.map \
+    $(LOCAL_PATH)/libm.x86.map \
+    $(LOCAL_PATH)/libm.x86_64.map \
 
-# TODO: This is to work around b/19059885. Remove after root cause is fixed
+# TODO: This is to work around b/24465209. Remove after root cause is fixed
 LOCAL_LDFLAGS_arm := -Wl,--hash-style=both
 LOCAL_LDFLAGS_x86 := -Wl,--hash-style=both
 
-LOCAL_LDFLAGS := -Wl,--version-script,$(LOCAL_PATH)/libm.map
+LOCAL_LDFLAGS_arm    += -Wl,--version-script,$(LOCAL_PATH)/libm.arm.map
+LOCAL_LDFLAGS_arm64  += -Wl,--version-script,$(LOCAL_PATH)/libm.arm64.map
+LOCAL_LDFLAGS_mips   += -Wl,--version-script,$(LOCAL_PATH)/libm.mips.map
+LOCAL_LDFLAGS_mips64 += -Wl,--version-script,$(LOCAL_PATH)/libm.mips64.map
+LOCAL_LDFLAGS_x86    += -Wl,--version-script,$(LOCAL_PATH)/libm.x86.map
+LOCAL_LDFLAGS_x86_64 += -Wl,--version-script,$(LOCAL_PATH)/libm.x86_64.map
+
 
 LOCAL_MODULE := libm
 LOCAL_CLANG := $(libm_clang)
@@ -527,7 +551,7 @@
 LOCAL_WHOLE_STATIC_LIBRARIES := libm
 
 LOCAL_NATIVE_COVERAGE := $(bionic_coverage)
-LOCAL_ADDRESS_SANITIZER := false
+LOCAL_SANITIZE := never
 
 LOCAL_CXX_STL := none
 
diff --git a/libm/NOTICE b/libm/NOTICE
index a2cfad3..c254c08 100644
--- a/libm/NOTICE
+++ b/libm/NOTICE
@@ -181,6 +181,22 @@
 
 -------------------------------------------------------------------
 
+Copyright (C) 2015 The Android Open Source Project
+
+Licensed under the Apache License, Version 2.0 (the "License");
+you may not use this file except in compliance with the License.
+You may obtain a copy of the License at
+
+     http://www.apache.org/licenses/LICENSE-2.0
+
+Unless required by applicable law or agreed to in writing, software
+distributed under the License is distributed on an "AS IS" BASIS,
+WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
+See the License for the specific language governing permissions and
+limitations under the License.
+
+-------------------------------------------------------------------
+
 Copyright (c) 1985, 1993
    The Regents of the University of California.  All rights reserved.
 
@@ -1003,37 +1019,6 @@
 -------------------------------------------------------------------
 
 Copyright (c) 2013-2014, NVIDIA Corporation.  All rights reserved.
-Johhnny Qiu <joqiu@nvidia.com>
-Shu Zhang <chazhang@nvidia.com>
-
-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 Linux 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 "AS IS" AND ANY EXPRESS OR IMPLIED
-WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE IMPLIED WARRANTIES OF
-MERCHANTABILITY, FITNESS FOR A PARTICULAR PURPOSE AND NON-INFRINGEMENT
-ARE DISCLAIMED.  IN NO EVENT SHALL THE COPYRIGHT OWNER OR CONTRIBUTORS
-BE LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR
-CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF
-SUBSTITUTE GOODS OR SERVICES; LOSS OF USE, DATA, OR PROFITS; OR
-BUSINESS INTERRUPTION) HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY,
-WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT (INCLUDING NEGLIGENCE
-OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE OF THIS SOFTWARE, EVEN
-IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE.
-
--------------------------------------------------------------------
-
-Copyright (c) 2013-2014, NVIDIA Corporation.  All rights reserved.
 Johnny Qiu <joqiu@nvidia.com>
 Shu Zhang <chazhang@nvidia.com>
 
diff --git a/libm/arm/e_sqrtf.S b/libm/arm/e_sqrtf.S
deleted file mode 100644
index ddefb22..0000000
--- a/libm/arm/e_sqrtf.S
+++ /dev/null
@@ -1,39 +0,0 @@
-/*
- * Copyright (c) 2013-2014, NVIDIA Corporation.  All rights reserved.
- * Johhnny Qiu <joqiu@nvidia.com>
- * Shu Zhang <chazhang@nvidia.com>
- *
- * 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 Linux 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 "AS IS" AND ANY EXPRESS OR IMPLIED
- * WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE IMPLIED WARRANTIES OF
- * MERCHANTABILITY, FITNESS FOR A PARTICULAR PURPOSE AND NON-INFRINGEMENT
- * 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 <private/bionic_asm.h>
-
-ENTRY(sqrtf)
-    vmov.f32    s0, r0
-    vsqrt.f32   s0, s0
-    vmov.f32    r0, s0
-    bx          lr
-END(sqrtf)
diff --git a/libm/arm/s_floor.S b/libm/arm/floor.S
similarity index 100%
rename from libm/arm/s_floor.S
rename to libm/arm/floor.S
diff --git a/libm/arm/e_sqrt.S b/libm/arm/sqrt.S
similarity index 94%
rename from libm/arm/e_sqrt.S
rename to libm/arm/sqrt.S
index 17312f5..f2981f4 100644
--- a/libm/arm/e_sqrt.S
+++ b/libm/arm/sqrt.S
@@ -39,4 +39,11 @@
     bx          lr
 END(sqrt)
 
+ENTRY(sqrtf)
+    vmov.f32    s0, r0
+    vsqrt.f32   s0, s0
+    vmov.f32    r0, s0
+    bx          lr
+END(sqrtf)
+
 ALIAS_SYMBOL(sqrtl, sqrt);
diff --git a/libm/arm64/fenv.c b/libm/arm64/fenv.c
index ce560a7..19a2393 100644
--- a/libm/arm64/fenv.c
+++ b/libm/arm64/fenv.c
@@ -26,6 +26,7 @@
  * $FreeBSD: libm/aarch64/fenv.c $
  */
 
+#include <stdint.h>
 #include <fenv.h>
 
 #define FPCR_EXCEPT_SHIFT 8
@@ -38,10 +39,20 @@
 typedef __uint32_t fpu_control_t;   // FPCR, Floating-point Control Register.
 typedef __uint32_t fpu_status_t;    // FPSR, Floating-point Status Register.
 
-#define __get_fpcr(__fpcr) __asm__ __volatile__("mrs %0,fpcr" : "=r" (__fpcr))
-#define __get_fpsr(__fpsr) __asm__ __volatile__("mrs %0,fpsr" : "=r" (__fpsr))
-#define __set_fpcr(__fpcr) __asm__ __volatile__("msr fpcr,%0" : :"ri" (__fpcr))
-#define __set_fpsr(__fpsr) __asm__ __volatile__("msr fpsr,%0" : :"ri" (__fpsr))
+#define __get(REGISTER, __value) { \
+  uint64_t __value64; \
+  __asm__ __volatile__("mrs %0," REGISTER : "=r" (__value64)); \
+  __value = (__uint32_t) __value64; \
+}
+#define __get_fpcr(__fpcr) __get("fpcr", __fpcr)
+#define __get_fpsr(__fpsr) __get("fpsr", __fpsr)
+
+#define __set(REGISTER, __value) { \
+  uint64_t __value64 = __value; \
+  __asm__ __volatile__("msr " REGISTER ",%0" : : "ri" (__value64)); \
+}
+#define __set_fpcr(__fpcr) __set("fpcr", __fpcr)
+#define __set_fpsr(__fpsr) __set("fpsr", __fpsr)
 
 int fegetenv(fenv_t* envp) {
   __get_fpcr(envp->__control);
diff --git a/libm/fabs.cpp b/libm/fabs.cpp
new file mode 100644
index 0000000..add73fe
--- /dev/null
+++ b/libm/fabs.cpp
@@ -0,0 +1,46 @@
+/*
+ * Copyright (C) 2015 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 <math.h>
+
+#include "fpmath.h"
+
+double fabs(double x) {
+#if __arm__
+  // Both Clang and GCC insist on moving r0/r1 into a double register
+  // and using fabs where bit-twiddling would be a better choice.
+  // They get fabsf right, but we need to be careful in fabsl too.
+  IEEEd2bits u;
+  u.d = x;
+  u.bits.sign = 0;
+  return u.d;
+#else
+  return __builtin_fabs(x);
+#endif
+}
+
+float fabsf(float x) {
+  return __builtin_fabsf(x);
+}
+
+#if defined(__LP64__)
+long double fabsl(long double x) { return __builtin_fabsl(x); }
+#else
+long double fabsl(long double x) {
+  // Don't use __builtin_fabs here because of ARM. (See fabs above.)
+  return fabs(x);
+}
+#endif
diff --git a/libm/fake_long_double.c b/libm/fake_long_double.c
index 317a115..20148a3 100644
--- a/libm/fake_long_double.c
+++ b/libm/fake_long_double.c
@@ -25,13 +25,14 @@
  */
 
 long double copysignl(long double a1, long double a2) { return copysign(a1, a2); }
-long double fabsl(long double a1) { return fabs(a1); }
 long double fmaxl(long double a1, long double a2) { return fmax(a1, a2); }
 long double fmodl(long double a1, long double a2) { return fmod(a1, a2); }
 long double fminl(long double a1, long double a2) { return fmin(a1, a2); }
 int ilogbl(long double a1) { return ilogb(a1); }
 long long llrintl(long double a1) { return llrint(a1); }
+#if !defined(__i386__) // x86 has an assembler lrint/lrintl.
 long lrintl(long double a1) { return lrint(a1); }
+#endif
 long long llroundl(long double a1) { return llround(a1); }
 long lroundl(long double a1) { return lround(a1); }
 long double modfl(long double a1, long double* a2) { double i; double f = modf(a1, &i); *a2 = i; return f; }
diff --git a/libm/include/math.h b/libm/include/math.h
index 1542374..ce8e3b2 100644
--- a/libm/include/math.h
+++ b/libm/include/math.h
@@ -15,116 +15,70 @@
  */
 
 #ifndef _MATH_H_
-#define	_MATH_H_
+#define _MATH_H_
 
 #include <sys/cdefs.h>
 #include <limits.h>
 
+#if !defined(__BIONIC_NO_MATH_INLINES)
+#define __BIONIC_MATH_INLINE(__def) extern __inline__ __always_inline __attribute__((gnu_inline)) __attribute__((__artificial__)) __def
+#else
+#define __BIONIC_MATH_INLINE(__def)
+#endif
+
 __BEGIN_DECLS
 #pragma GCC visibility push(default)
 
-/*
- * ANSI/POSIX
- */
-extern const union __infinity_un {
-	unsigned char	__uc[8];
-	double		__ud;
-} __infinity;
-
-extern const union __nan_un {
-	unsigned char	__uc[sizeof(float)];
-	float		__uf;
-} __nan;
-
-#if __GNUC_PREREQ(3, 3) || (defined(__INTEL_COMPILER) && __INTEL_COMPILER >= 800)
-#define	__MATH_BUILTIN_CONSTANTS
-#endif
-
-#if __GNUC_PREREQ(3, 0) && !defined(__INTEL_COMPILER)
-#define	__MATH_BUILTIN_RELOPS
-#endif
-
-#ifdef __MATH_BUILTIN_CONSTANTS
-#define	HUGE_VAL	__builtin_huge_val()
-#else
-#define	HUGE_VAL	(__infinity.__ud)
-#endif
+#define HUGE_VAL	__builtin_huge_val()
 
 #if __ISO_C_VISIBLE >= 1999
-#define	FP_ILOGB0	(-INT_MAX) /* Android-changed */
-#define	FP_ILOGBNAN	INT_MAX /* Android-changed */
+#define FP_ILOGB0	(-INT_MAX)
+#define FP_ILOGBNAN	INT_MAX
 
-#ifdef __MATH_BUILTIN_CONSTANTS
-#define	HUGE_VALF	__builtin_huge_valf()
-#define	HUGE_VALL	__builtin_huge_vall()
-#define	INFINITY	__builtin_inff()
-#define	NAN		__builtin_nanf("")
-#else
-#define	HUGE_VALF	(float)HUGE_VAL
-#define	HUGE_VALL	(long double)HUGE_VAL
-#define	INFINITY	HUGE_VALF
-#define	NAN		(__nan.__uf)
-#endif /* __MATH_BUILTIN_CONSTANTS */
+#define HUGE_VALF	__builtin_huge_valf()
+#define HUGE_VALL	__builtin_huge_vall()
+#define INFINITY	__builtin_inff()
+#define NAN		__builtin_nanf("")
 
-#define	MATH_ERRNO	1
-#define	MATH_ERREXCEPT	2
-#define	math_errhandling	MATH_ERREXCEPT
+#define MATH_ERRNO	1
+#define MATH_ERREXCEPT	2
+#define math_errhandling	MATH_ERREXCEPT
 
-#define	FP_FAST_FMAF	1
-#ifdef __ia64__
-#define	FP_FAST_FMA	1
-#define	FP_FAST_FMAL	1
+#if defined(__FP_FAST_FMA)
+#define FP_FAST_FMA 1
+#endif
+#if defined(__FP_FAST_FMAF)
+#define FP_FAST_FMAF 1
+#endif
+#if defined(__FP_FAST_FMAL)
+#define FP_FAST_FMAL 1
 #endif
 
 /* Symbolic constants to classify floating point numbers. */
-#define	FP_INFINITE	0x01
-#define	FP_NAN		0x02
-#define	FP_NORMAL	0x04
-#define	FP_SUBNORMAL	0x08
-#define	FP_ZERO		0x10
-#define	fpclassify(x) \
-    ((sizeof (x) == sizeof (float)) ? __fpclassifyf(x) \
-    : (sizeof (x) == sizeof (double)) ? __fpclassifyd(x) \
-    : __fpclassifyl(x))
+#define FP_INFINITE	0x01
+#define FP_NAN		0x02
+#define FP_NORMAL	0x04
+#define FP_SUBNORMAL	0x08
+#define FP_ZERO		0x10
+#define fpclassify(x) \
+    __builtin_fpclassify(FP_NAN, FP_INFINITE, FP_NORMAL, FP_SUBNORMAL, FP_ZERO, x)
 
-#define	isfinite(x)					\
-    ((sizeof (x) == sizeof (float)) ? __isfinitef(x)	\
-    : (sizeof (x) == sizeof (double)) ? __isfinite(x)	\
-    : __isfinitel(x))
-#define	isinf(x)					\
-    ((sizeof (x) == sizeof (float)) ? __isinff(x)	\
-    : (sizeof (x) == sizeof (double)) ? isinf(x)	\
-    : __isinfl(x))
-#define	isnan(x)					\
-    ((sizeof (x) == sizeof (float)) ? __isnanf(x)	\
-    : (sizeof (x) == sizeof (double)) ? isnan(x)	\
-    : __isnanl(x))
-#define	isnormal(x)					\
-    ((sizeof (x) == sizeof (float)) ? __isnormalf(x)	\
-    : (sizeof (x) == sizeof (double)) ? __isnormal(x)	\
-    : __isnormall(x))
+#define isfinite(x) __builtin_isfinite(x)
+#define isinf(x) __builtin_isinf(x)
+#define isnan(x) __builtin_isnan(x)
+#define isnormal(x) __builtin_isnormal(x)
 
-#ifdef __MATH_BUILTIN_RELOPS
-#define	isgreater(x, y)		__builtin_isgreater((x), (y))
-#define	isgreaterequal(x, y)	__builtin_isgreaterequal((x), (y))
-#define	isless(x, y)		__builtin_isless((x), (y))
-#define	islessequal(x, y)	__builtin_islessequal((x), (y))
-#define	islessgreater(x, y)	__builtin_islessgreater((x), (y))
-#define	isunordered(x, y)	__builtin_isunordered((x), (y))
-#else
-#define	isgreater(x, y)		(!isunordered((x), (y)) && (x) > (y))
-#define	isgreaterequal(x, y)	(!isunordered((x), (y)) && (x) >= (y))
-#define	isless(x, y)		(!isunordered((x), (y)) && (x) < (y))
-#define	islessequal(x, y)	(!isunordered((x), (y)) && (x) <= (y))
-#define	islessgreater(x, y)	(!isunordered((x), (y)) && \
-					((x) > (y) || (y) > (x)))
-#define	isunordered(x, y)	(isnan(x) || isnan(y))
-#endif /* __MATH_BUILTIN_RELOPS */
+#define isgreater(x, y) __builtin_isgreater((x), (y))
+#define isgreaterequal(x, y) __builtin_isgreaterequal((x), (y))
+#define isless(x, y) __builtin_isless((x), (y))
+#define islessequal(x, y) __builtin_islessequal((x), (y))
+#define islessgreater(x, y) __builtin_islessgreater((x), (y))
+#define isunordered(x, y) __builtin_isunordered((x), (y))
 
-#define	signbit(x)					\
-    ((sizeof (x) == sizeof (float)) ? __signbitf(x)	\
-    : (sizeof (x) == sizeof (double)) ? __signbit(x)	\
-    : __signbitl(x))
+#define signbit(x) \
+    ((sizeof(x) == sizeof(float)) ? __builtin_signbitf(x) \
+    : (sizeof(x) == sizeof(double)) ? __builtin_signbit(x) \
+    : __builtin_signbitl(x))
 
 typedef double __double_t;
 typedef __double_t double_t;
@@ -213,6 +167,7 @@
 
 double	ceil(double);
 double	fabs(double) __pure2;
+__BIONIC_MATH_INLINE(double fabs(double x) { return __builtin_fabs(x); })
 double	floor(double);
 double	fmod(double, double);
 
@@ -331,6 +286,7 @@
 
 float	ceilf(float);
 float	fabsf(float) __pure2;
+__BIONIC_MATH_INLINE(float fabsf(float x) { return __builtin_fabsf(x); })
 float	floorf(float);
 float	fmodf(float, float);
 float	roundf(float);
@@ -418,6 +374,7 @@
 long double	expl(long double);
 long double	expm1l(long double);
 long double	fabsl(long double) __pure2;
+__BIONIC_MATH_INLINE(long double fabsl(long double x) { return __builtin_fabsl(x); })
 long double	fdiml(long double, long double);
 long double	floorl(long double);
 long double	fmal(long double, long double, long double);
diff --git a/libm/libm.map b/libm/libm.arm.map
similarity index 97%
copy from libm/libm.map
copy to libm/libm.arm.map
index 7f02f42..e781f2d 100644
--- a/libm/libm.map
+++ b/libm/libm.arm.map
@@ -1,3 +1,4 @@
+# Generated by genversionscripts.py. Do not edit.
 LIBC {
   global:
     __fe_dfl_env;
@@ -271,8 +272,8 @@
     *;
 };
 
-LIBC_PRIVATE {
-  global:
+LIBC_PRIVATE { # arm mips
+  global: # arm mips
     ___Unwind_Backtrace; # arm
     ___Unwind_ForcedUnwind; # arm
     ___Unwind_RaiseException; # arm
@@ -353,7 +354,6 @@
     __lesf2; # arm
     __ltdf2; # arm
     __ltsf2; # arm
-    __muldc3; # arm x86 mips
     __muldf3; # arm
     __nedf2; # arm
     __nesf2; # arm
@@ -375,4 +375,4 @@
     _Unwind_VRS_Pop; # arm
     _Unwind_VRS_Set; # arm
     restore_core_regs; # arm
-} LIBC;
+} LIBC; # arm mips
diff --git a/libm/libm.arm64.map b/libm/libm.arm64.map
new file mode 100644
index 0000000..1623ea0
--- /dev/null
+++ b/libm/libm.arm64.map
@@ -0,0 +1,274 @@
+# Generated by genversionscripts.py. Do not edit.
+LIBC {
+  global:
+    __fe_dfl_env;
+    __signbit;
+    __signbitf;
+    __signbitl;
+    acos;
+    acosf;
+    acosh;
+    acoshf;
+    acoshl;
+    acosl;
+    asin;
+    asinf;
+    asinh;
+    asinhf;
+    asinhl;
+    asinl;
+    atan;
+    atan2;
+    atan2f;
+    atan2l;
+    atanf;
+    atanh;
+    atanhf;
+    atanhl;
+    atanl;
+    cabs;
+    cabsf;
+    cabsl;
+    cacos;
+    cacosf;
+    cacosh;
+    cacoshf;
+    carg;
+    cargf;
+    cargl;
+    casin;
+    casinf;
+    casinh;
+    casinhf;
+    catan;
+    catanf;
+    catanh;
+    catanhf;
+    cbrt;
+    cbrtf;
+    cbrtl;
+    ccos;
+    ccosf;
+    ccosh;
+    ccoshf;
+    ceil;
+    ceilf;
+    ceill;
+    cexp;
+    cexpf;
+    cimag;
+    cimagf;
+    cimagl;
+    conj;
+    conjf;
+    conjl;
+    copysign;
+    copysignf;
+    copysignl;
+    cos;
+    cosf;
+    cosh;
+    coshf;
+    coshl;
+    cosl;
+    cproj;
+    cprojf;
+    cprojl;
+    creal;
+    crealf;
+    creall;
+    csin;
+    csinf;
+    csinh;
+    csinhf;
+    csqrt;
+    csqrtf;
+    csqrtl;
+    ctan;
+    ctanf;
+    ctanh;
+    ctanhf;
+    drem;
+    dremf;
+    erf;
+    erfc;
+    erfcf;
+    erfcl;
+    erff;
+    erfl;
+    exp;
+    exp2;
+    exp2f;
+    exp2l;
+    expf;
+    expl;
+    expm1;
+    expm1f;
+    expm1l;
+    fabs;
+    fabsf;
+    fabsl;
+    fdim;
+    fdimf;
+    fdiml;
+    feclearexcept;
+    fedisableexcept;
+    feenableexcept;
+    fegetenv;
+    fegetexcept;
+    fegetexceptflag;
+    fegetround;
+    feholdexcept;
+    feraiseexcept;
+    fesetenv;
+    fesetexceptflag;
+    fesetround;
+    fetestexcept;
+    feupdateenv;
+    finite;
+    finitef;
+    floor;
+    floorf;
+    floorl;
+    fma;
+    fmaf;
+    fmal;
+    fmax;
+    fmaxf;
+    fmaxl;
+    fmin;
+    fminf;
+    fminl;
+    fmod;
+    fmodf;
+    fmodl;
+    frexp;
+    frexpf;
+    frexpl;
+    gamma;
+    gamma_r;
+    gammaf;
+    gammaf_r;
+    hypot;
+    hypotf;
+    hypotl;
+    ilogb;
+    ilogbf;
+    ilogbl;
+    j0;
+    j0f;
+    j1;
+    j1f;
+    jn;
+    jnf;
+    ldexpf;
+    ldexpl;
+    lgamma;
+    lgamma_r;
+    lgammaf;
+    lgammaf_r;
+    lgammal;
+    lgammal_r;
+    llrint;
+    llrintf;
+    llrintl;
+    llround;
+    llroundf;
+    llroundl;
+    log;
+    log10;
+    log10f;
+    log10l;
+    log1p;
+    log1pf;
+    log1pl;
+    log2;
+    log2f;
+    log2l;
+    logb;
+    logbf;
+    logbl;
+    logf;
+    logl;
+    lrint;
+    lrintf;
+    lrintl;
+    lround;
+    lroundf;
+    lroundl;
+    modf;
+    modff;
+    modfl;
+    nan;
+    nanf;
+    nanl;
+    nearbyint;
+    nearbyintf;
+    nearbyintl;
+    nextafter;
+    nextafterf;
+    nextafterl;
+    nexttoward;
+    nexttowardf;
+    nexttowardl;
+    pow;
+    powf;
+    powl;
+    remainder;
+    remainderf;
+    remainderl;
+    remquo;
+    remquof;
+    remquol;
+    rint;
+    rintf;
+    rintl;
+    round;
+    roundf;
+    roundl;
+    scalb;
+    scalbf;
+    scalbln;
+    scalblnf;
+    scalblnl;
+    scalbn;
+    scalbnf;
+    scalbnl;
+    signgam;
+    significand;
+    significandf;
+    significandl;
+    sin;
+    sincos;
+    sincosf;
+    sincosl;
+    sinf;
+    sinh;
+    sinhf;
+    sinhl;
+    sinl;
+    sqrt;
+    sqrtf;
+    sqrtl;
+    tan;
+    tanf;
+    tanh;
+    tanhf;
+    tanhl;
+    tanl;
+    tgamma;
+    tgammaf;
+    tgammal;
+    trunc;
+    truncf;
+    truncl;
+    y0;
+    y0f;
+    y1;
+    y1f;
+    yn;
+    ynf;
+  local:
+    *;
+};
+
diff --git a/libm/libm.map b/libm/libm.map.txt
similarity index 98%
rename from libm/libm.map
rename to libm/libm.map.txt
index 7f02f42..075ebd5 100644
--- a/libm/libm.map
+++ b/libm/libm.map.txt
@@ -271,8 +271,8 @@
     *;
 };
 
-LIBC_PRIVATE {
-  global:
+LIBC_PRIVATE { # arm mips
+  global: # arm mips
     ___Unwind_Backtrace; # arm
     ___Unwind_ForcedUnwind; # arm
     ___Unwind_RaiseException; # arm
@@ -353,7 +353,6 @@
     __lesf2; # arm
     __ltdf2; # arm
     __ltsf2; # arm
-    __muldc3; # arm x86 mips
     __muldf3; # arm
     __nedf2; # arm
     __nesf2; # arm
@@ -375,4 +374,4 @@
     _Unwind_VRS_Pop; # arm
     _Unwind_VRS_Set; # arm
     restore_core_regs; # arm
-} LIBC;
+} LIBC; # arm mips
diff --git a/libm/libm.mips.map b/libm/libm.mips.map
new file mode 100644
index 0000000..476c6ad
--- /dev/null
+++ b/libm/libm.mips.map
@@ -0,0 +1,281 @@
+# Generated by genversionscripts.py. Do not edit.
+LIBC {
+  global:
+    __fe_dfl_env;
+    __signbit;
+    __signbitf;
+    __signbitl;
+    acos;
+    acosf;
+    acosh;
+    acoshf;
+    acoshl;
+    acosl;
+    asin;
+    asinf;
+    asinh;
+    asinhf;
+    asinhl;
+    asinl;
+    atan;
+    atan2;
+    atan2f;
+    atan2l;
+    atanf;
+    atanh;
+    atanhf;
+    atanhl;
+    atanl;
+    cabs;
+    cabsf;
+    cabsl;
+    cacos;
+    cacosf;
+    cacosh;
+    cacoshf;
+    carg;
+    cargf;
+    cargl;
+    casin;
+    casinf;
+    casinh;
+    casinhf;
+    catan;
+    catanf;
+    catanh;
+    catanhf;
+    cbrt;
+    cbrtf;
+    cbrtl;
+    ccos;
+    ccosf;
+    ccosh;
+    ccoshf;
+    ceil;
+    ceilf;
+    ceill;
+    cexp;
+    cexpf;
+    cimag;
+    cimagf;
+    cimagl;
+    conj;
+    conjf;
+    conjl;
+    copysign;
+    copysignf;
+    copysignl;
+    cos;
+    cosf;
+    cosh;
+    coshf;
+    coshl;
+    cosl;
+    cproj;
+    cprojf;
+    cprojl;
+    creal;
+    crealf;
+    creall;
+    csin;
+    csinf;
+    csinh;
+    csinhf;
+    csqrt;
+    csqrtf;
+    csqrtl;
+    ctan;
+    ctanf;
+    ctanh;
+    ctanhf;
+    drem;
+    dremf;
+    erf;
+    erfc;
+    erfcf;
+    erfcl;
+    erff;
+    erfl;
+    exp;
+    exp2;
+    exp2f;
+    exp2l;
+    expf;
+    expl;
+    expm1;
+    expm1f;
+    expm1l;
+    fabs;
+    fabsf;
+    fabsl;
+    fdim;
+    fdimf;
+    fdiml;
+    feclearexcept;
+    fedisableexcept;
+    feenableexcept;
+    fegetenv;
+    fegetexcept;
+    fegetexceptflag;
+    fegetround;
+    feholdexcept;
+    feraiseexcept;
+    fesetenv;
+    fesetexceptflag;
+    fesetround;
+    fetestexcept;
+    feupdateenv;
+    finite;
+    finitef;
+    floor;
+    floorf;
+    floorl;
+    fma;
+    fmaf;
+    fmal;
+    fmax;
+    fmaxf;
+    fmaxl;
+    fmin;
+    fminf;
+    fminl;
+    fmod;
+    fmodf;
+    fmodl;
+    frexp;
+    frexpf;
+    frexpl;
+    gamma;
+    gamma_r;
+    gammaf;
+    gammaf_r;
+    hypot;
+    hypotf;
+    hypotl;
+    ilogb;
+    ilogbf;
+    ilogbl;
+    j0;
+    j0f;
+    j1;
+    j1f;
+    jn;
+    jnf;
+    ldexpf;
+    ldexpl;
+    lgamma;
+    lgamma_r;
+    lgammaf;
+    lgammaf_r;
+    lgammal;
+    lgammal_r;
+    llrint;
+    llrintf;
+    llrintl;
+    llround;
+    llroundf;
+    llroundl;
+    log;
+    log10;
+    log10f;
+    log10l;
+    log1p;
+    log1pf;
+    log1pl;
+    log2;
+    log2f;
+    log2l;
+    logb;
+    logbf;
+    logbl;
+    logf;
+    logl;
+    lrint;
+    lrintf;
+    lrintl;
+    lround;
+    lroundf;
+    lroundl;
+    modf;
+    modff;
+    modfl;
+    nan;
+    nanf;
+    nanl;
+    nearbyint;
+    nearbyintf;
+    nearbyintl;
+    nextafter;
+    nextafterf;
+    nextafterl;
+    nexttoward;
+    nexttowardf;
+    nexttowardl;
+    pow;
+    powf;
+    powl;
+    remainder;
+    remainderf;
+    remainderl;
+    remquo;
+    remquof;
+    remquol;
+    rint;
+    rintf;
+    rintl;
+    round;
+    roundf;
+    roundl;
+    scalb;
+    scalbf;
+    scalbln;
+    scalblnf;
+    scalblnl;
+    scalbn;
+    scalbnf;
+    scalbnl;
+    signgam;
+    significand;
+    significandf;
+    significandl;
+    sin;
+    sincos;
+    sincosf;
+    sincosl;
+    sinf;
+    sinh;
+    sinhf;
+    sinhl;
+    sinl;
+    sqrt;
+    sqrtf;
+    sqrtl;
+    tan;
+    tanf;
+    tanh;
+    tanhf;
+    tanhl;
+    tanl;
+    tgamma;
+    tgammaf;
+    tgammal;
+    trunc;
+    truncf;
+    truncl;
+    y0;
+    y0f;
+    y1;
+    y1f;
+    yn;
+    ynf;
+  local:
+    *;
+};
+
+LIBC_PRIVATE { # arm mips
+  global: # arm mips
+    __fixdfdi; # arm mips
+    __fixsfdi; # arm mips
+    __fixunsdfdi; # arm mips
+    __fixunssfdi; # arm mips
+} LIBC; # arm mips
diff --git a/libm/libm.mips64.map b/libm/libm.mips64.map
new file mode 100644
index 0000000..1623ea0
--- /dev/null
+++ b/libm/libm.mips64.map
@@ -0,0 +1,274 @@
+# Generated by genversionscripts.py. Do not edit.
+LIBC {
+  global:
+    __fe_dfl_env;
+    __signbit;
+    __signbitf;
+    __signbitl;
+    acos;
+    acosf;
+    acosh;
+    acoshf;
+    acoshl;
+    acosl;
+    asin;
+    asinf;
+    asinh;
+    asinhf;
+    asinhl;
+    asinl;
+    atan;
+    atan2;
+    atan2f;
+    atan2l;
+    atanf;
+    atanh;
+    atanhf;
+    atanhl;
+    atanl;
+    cabs;
+    cabsf;
+    cabsl;
+    cacos;
+    cacosf;
+    cacosh;
+    cacoshf;
+    carg;
+    cargf;
+    cargl;
+    casin;
+    casinf;
+    casinh;
+    casinhf;
+    catan;
+    catanf;
+    catanh;
+    catanhf;
+    cbrt;
+    cbrtf;
+    cbrtl;
+    ccos;
+    ccosf;
+    ccosh;
+    ccoshf;
+    ceil;
+    ceilf;
+    ceill;
+    cexp;
+    cexpf;
+    cimag;
+    cimagf;
+    cimagl;
+    conj;
+    conjf;
+    conjl;
+    copysign;
+    copysignf;
+    copysignl;
+    cos;
+    cosf;
+    cosh;
+    coshf;
+    coshl;
+    cosl;
+    cproj;
+    cprojf;
+    cprojl;
+    creal;
+    crealf;
+    creall;
+    csin;
+    csinf;
+    csinh;
+    csinhf;
+    csqrt;
+    csqrtf;
+    csqrtl;
+    ctan;
+    ctanf;
+    ctanh;
+    ctanhf;
+    drem;
+    dremf;
+    erf;
+    erfc;
+    erfcf;
+    erfcl;
+    erff;
+    erfl;
+    exp;
+    exp2;
+    exp2f;
+    exp2l;
+    expf;
+    expl;
+    expm1;
+    expm1f;
+    expm1l;
+    fabs;
+    fabsf;
+    fabsl;
+    fdim;
+    fdimf;
+    fdiml;
+    feclearexcept;
+    fedisableexcept;
+    feenableexcept;
+    fegetenv;
+    fegetexcept;
+    fegetexceptflag;
+    fegetround;
+    feholdexcept;
+    feraiseexcept;
+    fesetenv;
+    fesetexceptflag;
+    fesetround;
+    fetestexcept;
+    feupdateenv;
+    finite;
+    finitef;
+    floor;
+    floorf;
+    floorl;
+    fma;
+    fmaf;
+    fmal;
+    fmax;
+    fmaxf;
+    fmaxl;
+    fmin;
+    fminf;
+    fminl;
+    fmod;
+    fmodf;
+    fmodl;
+    frexp;
+    frexpf;
+    frexpl;
+    gamma;
+    gamma_r;
+    gammaf;
+    gammaf_r;
+    hypot;
+    hypotf;
+    hypotl;
+    ilogb;
+    ilogbf;
+    ilogbl;
+    j0;
+    j0f;
+    j1;
+    j1f;
+    jn;
+    jnf;
+    ldexpf;
+    ldexpl;
+    lgamma;
+    lgamma_r;
+    lgammaf;
+    lgammaf_r;
+    lgammal;
+    lgammal_r;
+    llrint;
+    llrintf;
+    llrintl;
+    llround;
+    llroundf;
+    llroundl;
+    log;
+    log10;
+    log10f;
+    log10l;
+    log1p;
+    log1pf;
+    log1pl;
+    log2;
+    log2f;
+    log2l;
+    logb;
+    logbf;
+    logbl;
+    logf;
+    logl;
+    lrint;
+    lrintf;
+    lrintl;
+    lround;
+    lroundf;
+    lroundl;
+    modf;
+    modff;
+    modfl;
+    nan;
+    nanf;
+    nanl;
+    nearbyint;
+    nearbyintf;
+    nearbyintl;
+    nextafter;
+    nextafterf;
+    nextafterl;
+    nexttoward;
+    nexttowardf;
+    nexttowardl;
+    pow;
+    powf;
+    powl;
+    remainder;
+    remainderf;
+    remainderl;
+    remquo;
+    remquof;
+    remquol;
+    rint;
+    rintf;
+    rintl;
+    round;
+    roundf;
+    roundl;
+    scalb;
+    scalbf;
+    scalbln;
+    scalblnf;
+    scalblnl;
+    scalbn;
+    scalbnf;
+    scalbnl;
+    signgam;
+    significand;
+    significandf;
+    significandl;
+    sin;
+    sincos;
+    sincosf;
+    sincosl;
+    sinf;
+    sinh;
+    sinhf;
+    sinhl;
+    sinl;
+    sqrt;
+    sqrtf;
+    sqrtl;
+    tan;
+    tanf;
+    tanh;
+    tanhf;
+    tanhl;
+    tanl;
+    tgamma;
+    tgammaf;
+    tgammal;
+    trunc;
+    truncf;
+    truncl;
+    y0;
+    y0f;
+    y1;
+    y1f;
+    yn;
+    ynf;
+  local:
+    *;
+};
+
diff --git a/libm/libm.x86.map b/libm/libm.x86.map
new file mode 100644
index 0000000..1623ea0
--- /dev/null
+++ b/libm/libm.x86.map
@@ -0,0 +1,274 @@
+# Generated by genversionscripts.py. Do not edit.
+LIBC {
+  global:
+    __fe_dfl_env;
+    __signbit;
+    __signbitf;
+    __signbitl;
+    acos;
+    acosf;
+    acosh;
+    acoshf;
+    acoshl;
+    acosl;
+    asin;
+    asinf;
+    asinh;
+    asinhf;
+    asinhl;
+    asinl;
+    atan;
+    atan2;
+    atan2f;
+    atan2l;
+    atanf;
+    atanh;
+    atanhf;
+    atanhl;
+    atanl;
+    cabs;
+    cabsf;
+    cabsl;
+    cacos;
+    cacosf;
+    cacosh;
+    cacoshf;
+    carg;
+    cargf;
+    cargl;
+    casin;
+    casinf;
+    casinh;
+    casinhf;
+    catan;
+    catanf;
+    catanh;
+    catanhf;
+    cbrt;
+    cbrtf;
+    cbrtl;
+    ccos;
+    ccosf;
+    ccosh;
+    ccoshf;
+    ceil;
+    ceilf;
+    ceill;
+    cexp;
+    cexpf;
+    cimag;
+    cimagf;
+    cimagl;
+    conj;
+    conjf;
+    conjl;
+    copysign;
+    copysignf;
+    copysignl;
+    cos;
+    cosf;
+    cosh;
+    coshf;
+    coshl;
+    cosl;
+    cproj;
+    cprojf;
+    cprojl;
+    creal;
+    crealf;
+    creall;
+    csin;
+    csinf;
+    csinh;
+    csinhf;
+    csqrt;
+    csqrtf;
+    csqrtl;
+    ctan;
+    ctanf;
+    ctanh;
+    ctanhf;
+    drem;
+    dremf;
+    erf;
+    erfc;
+    erfcf;
+    erfcl;
+    erff;
+    erfl;
+    exp;
+    exp2;
+    exp2f;
+    exp2l;
+    expf;
+    expl;
+    expm1;
+    expm1f;
+    expm1l;
+    fabs;
+    fabsf;
+    fabsl;
+    fdim;
+    fdimf;
+    fdiml;
+    feclearexcept;
+    fedisableexcept;
+    feenableexcept;
+    fegetenv;
+    fegetexcept;
+    fegetexceptflag;
+    fegetround;
+    feholdexcept;
+    feraiseexcept;
+    fesetenv;
+    fesetexceptflag;
+    fesetround;
+    fetestexcept;
+    feupdateenv;
+    finite;
+    finitef;
+    floor;
+    floorf;
+    floorl;
+    fma;
+    fmaf;
+    fmal;
+    fmax;
+    fmaxf;
+    fmaxl;
+    fmin;
+    fminf;
+    fminl;
+    fmod;
+    fmodf;
+    fmodl;
+    frexp;
+    frexpf;
+    frexpl;
+    gamma;
+    gamma_r;
+    gammaf;
+    gammaf_r;
+    hypot;
+    hypotf;
+    hypotl;
+    ilogb;
+    ilogbf;
+    ilogbl;
+    j0;
+    j0f;
+    j1;
+    j1f;
+    jn;
+    jnf;
+    ldexpf;
+    ldexpl;
+    lgamma;
+    lgamma_r;
+    lgammaf;
+    lgammaf_r;
+    lgammal;
+    lgammal_r;
+    llrint;
+    llrintf;
+    llrintl;
+    llround;
+    llroundf;
+    llroundl;
+    log;
+    log10;
+    log10f;
+    log10l;
+    log1p;
+    log1pf;
+    log1pl;
+    log2;
+    log2f;
+    log2l;
+    logb;
+    logbf;
+    logbl;
+    logf;
+    logl;
+    lrint;
+    lrintf;
+    lrintl;
+    lround;
+    lroundf;
+    lroundl;
+    modf;
+    modff;
+    modfl;
+    nan;
+    nanf;
+    nanl;
+    nearbyint;
+    nearbyintf;
+    nearbyintl;
+    nextafter;
+    nextafterf;
+    nextafterl;
+    nexttoward;
+    nexttowardf;
+    nexttowardl;
+    pow;
+    powf;
+    powl;
+    remainder;
+    remainderf;
+    remainderl;
+    remquo;
+    remquof;
+    remquol;
+    rint;
+    rintf;
+    rintl;
+    round;
+    roundf;
+    roundl;
+    scalb;
+    scalbf;
+    scalbln;
+    scalblnf;
+    scalblnl;
+    scalbn;
+    scalbnf;
+    scalbnl;
+    signgam;
+    significand;
+    significandf;
+    significandl;
+    sin;
+    sincos;
+    sincosf;
+    sincosl;
+    sinf;
+    sinh;
+    sinhf;
+    sinhl;
+    sinl;
+    sqrt;
+    sqrtf;
+    sqrtl;
+    tan;
+    tanf;
+    tanh;
+    tanhf;
+    tanhl;
+    tanl;
+    tgamma;
+    tgammaf;
+    tgammal;
+    trunc;
+    truncf;
+    truncl;
+    y0;
+    y0f;
+    y1;
+    y1f;
+    yn;
+    ynf;
+  local:
+    *;
+};
+
diff --git a/libm/libm.x86_64.map b/libm/libm.x86_64.map
new file mode 100644
index 0000000..1623ea0
--- /dev/null
+++ b/libm/libm.x86_64.map
@@ -0,0 +1,274 @@
+# Generated by genversionscripts.py. Do not edit.
+LIBC {
+  global:
+    __fe_dfl_env;
+    __signbit;
+    __signbitf;
+    __signbitl;
+    acos;
+    acosf;
+    acosh;
+    acoshf;
+    acoshl;
+    acosl;
+    asin;
+    asinf;
+    asinh;
+    asinhf;
+    asinhl;
+    asinl;
+    atan;
+    atan2;
+    atan2f;
+    atan2l;
+    atanf;
+    atanh;
+    atanhf;
+    atanhl;
+    atanl;
+    cabs;
+    cabsf;
+    cabsl;
+    cacos;
+    cacosf;
+    cacosh;
+    cacoshf;
+    carg;
+    cargf;
+    cargl;
+    casin;
+    casinf;
+    casinh;
+    casinhf;
+    catan;
+    catanf;
+    catanh;
+    catanhf;
+    cbrt;
+    cbrtf;
+    cbrtl;
+    ccos;
+    ccosf;
+    ccosh;
+    ccoshf;
+    ceil;
+    ceilf;
+    ceill;
+    cexp;
+    cexpf;
+    cimag;
+    cimagf;
+    cimagl;
+    conj;
+    conjf;
+    conjl;
+    copysign;
+    copysignf;
+    copysignl;
+    cos;
+    cosf;
+    cosh;
+    coshf;
+    coshl;
+    cosl;
+    cproj;
+    cprojf;
+    cprojl;
+    creal;
+    crealf;
+    creall;
+    csin;
+    csinf;
+    csinh;
+    csinhf;
+    csqrt;
+    csqrtf;
+    csqrtl;
+    ctan;
+    ctanf;
+    ctanh;
+    ctanhf;
+    drem;
+    dremf;
+    erf;
+    erfc;
+    erfcf;
+    erfcl;
+    erff;
+    erfl;
+    exp;
+    exp2;
+    exp2f;
+    exp2l;
+    expf;
+    expl;
+    expm1;
+    expm1f;
+    expm1l;
+    fabs;
+    fabsf;
+    fabsl;
+    fdim;
+    fdimf;
+    fdiml;
+    feclearexcept;
+    fedisableexcept;
+    feenableexcept;
+    fegetenv;
+    fegetexcept;
+    fegetexceptflag;
+    fegetround;
+    feholdexcept;
+    feraiseexcept;
+    fesetenv;
+    fesetexceptflag;
+    fesetround;
+    fetestexcept;
+    feupdateenv;
+    finite;
+    finitef;
+    floor;
+    floorf;
+    floorl;
+    fma;
+    fmaf;
+    fmal;
+    fmax;
+    fmaxf;
+    fmaxl;
+    fmin;
+    fminf;
+    fminl;
+    fmod;
+    fmodf;
+    fmodl;
+    frexp;
+    frexpf;
+    frexpl;
+    gamma;
+    gamma_r;
+    gammaf;
+    gammaf_r;
+    hypot;
+    hypotf;
+    hypotl;
+    ilogb;
+    ilogbf;
+    ilogbl;
+    j0;
+    j0f;
+    j1;
+    j1f;
+    jn;
+    jnf;
+    ldexpf;
+    ldexpl;
+    lgamma;
+    lgamma_r;
+    lgammaf;
+    lgammaf_r;
+    lgammal;
+    lgammal_r;
+    llrint;
+    llrintf;
+    llrintl;
+    llround;
+    llroundf;
+    llroundl;
+    log;
+    log10;
+    log10f;
+    log10l;
+    log1p;
+    log1pf;
+    log1pl;
+    log2;
+    log2f;
+    log2l;
+    logb;
+    logbf;
+    logbl;
+    logf;
+    logl;
+    lrint;
+    lrintf;
+    lrintl;
+    lround;
+    lroundf;
+    lroundl;
+    modf;
+    modff;
+    modfl;
+    nan;
+    nanf;
+    nanl;
+    nearbyint;
+    nearbyintf;
+    nearbyintl;
+    nextafter;
+    nextafterf;
+    nextafterl;
+    nexttoward;
+    nexttowardf;
+    nexttowardl;
+    pow;
+    powf;
+    powl;
+    remainder;
+    remainderf;
+    remainderl;
+    remquo;
+    remquof;
+    remquol;
+    rint;
+    rintf;
+    rintl;
+    round;
+    roundf;
+    roundl;
+    scalb;
+    scalbf;
+    scalbln;
+    scalblnf;
+    scalblnl;
+    scalbn;
+    scalbnf;
+    scalbnl;
+    signgam;
+    significand;
+    significandf;
+    significandl;
+    sin;
+    sincos;
+    sincosf;
+    sincosl;
+    sinf;
+    sinh;
+    sinhf;
+    sinhl;
+    sinl;
+    sqrt;
+    sqrtf;
+    sqrtl;
+    tan;
+    tanf;
+    tanh;
+    tanhf;
+    tanhl;
+    tanl;
+    tgamma;
+    tgammaf;
+    tgammal;
+    trunc;
+    truncf;
+    truncl;
+    y0;
+    y0f;
+    y1;
+    y1f;
+    yn;
+    ynf;
+  local:
+    *;
+};
+
diff --git a/libm/upstream-freebsd/lib/msun/ld128/k_expl.h b/libm/upstream-freebsd/lib/msun/ld128/k_expl.h
index a5668fd..e843d43 100644
--- a/libm/upstream-freebsd/lib/msun/ld128/k_expl.h
+++ b/libm/upstream-freebsd/lib/msun/ld128/k_expl.h
@@ -29,7 +29,7 @@
  */
 
 #include <sys/cdefs.h>
-__FBSDID("$FreeBSD$");
+__FBSDID("$FreeBSD: head/lib/msun/ld128/k_expl.h 275819 2014-12-16 09:21:56Z ed $");
 
 /*
  * ld128 version of k_expl.h.  See ../ld80/s_expl.c for most comments.
@@ -322,7 +322,7 @@
 	scale2 = 1;
 	SET_LDBL_EXPSIGN(scale1, BIAS + expt - half_expt);
 
-	return (cpackl(cos(y) * exp_x * scale1 * scale2,
+	return (CMPLXL(cos(y) * exp_x * scale1 * scale2,
 	    sinl(y) * exp_x * scale1 * scale2));
 }
 #endif /* _COMPLEX_H */
diff --git a/libm/upstream-freebsd/lib/msun/src/catrig.c b/libm/upstream-freebsd/lib/msun/src/catrig.c
index 200977c..050a88b 100644
--- a/libm/upstream-freebsd/lib/msun/src/catrig.c
+++ b/libm/upstream-freebsd/lib/msun/src/catrig.c
@@ -25,7 +25,7 @@
  */
 
 #include <sys/cdefs.h>
-__FBSDID("$FreeBSD$");
+__FBSDID("$FreeBSD: head/lib/msun/src/catrig.c 275819 2014-12-16 09:21:56Z ed $");
 
 #include <complex.h>
 #include <float.h>
@@ -286,19 +286,19 @@
 	if (isnan(x) || isnan(y)) {
 		/* casinh(+-Inf + I*NaN) = +-Inf + I*NaN */
 		if (isinf(x))
-			return (cpack(x, y + y));
+			return (CMPLX(x, y + y));
 		/* casinh(NaN + I*+-Inf) = opt(+-)Inf + I*NaN */
 		if (isinf(y))
-			return (cpack(y, x + x));
+			return (CMPLX(y, x + x));
 		/* casinh(NaN + I*0) = NaN + I*0 */
 		if (y == 0)
-			return (cpack(x + x, y));
+			return (CMPLX(x + x, y));
 		/*
 		 * All other cases involving NaN return NaN + I*NaN.
 		 * C99 leaves it optional whether to raise invalid if one of
 		 * the arguments is not NaN, so we opt not to raise it.
 		 */
-		return (cpack(x + 0.0L + (y + 0), x + 0.0L + (y + 0)));
+		return (CMPLX(x + 0.0L + (y + 0), x + 0.0L + (y + 0)));
 	}
 
 	if (ax > RECIP_EPSILON || ay > RECIP_EPSILON) {
@@ -307,7 +307,7 @@
 			w = clog_for_large_values(z) + m_ln2;
 		else
 			w = clog_for_large_values(-z) + m_ln2;
-		return (cpack(copysign(creal(w), x), copysign(cimag(w), y)));
+		return (CMPLX(copysign(creal(w), x), copysign(cimag(w), y)));
 	}
 
 	/* Avoid spuriously raising inexact for z = 0. */
@@ -325,7 +325,7 @@
 		ry = asin(B);
 	else
 		ry = atan2(new_y, sqrt_A2my2);
-	return (cpack(copysign(rx, x), copysign(ry, y)));
+	return (CMPLX(copysign(rx, x), copysign(ry, y)));
 }
 
 /*
@@ -335,9 +335,9 @@
 double complex
 casin(double complex z)
 {
-	double complex w = casinh(cpack(cimag(z), creal(z)));
+	double complex w = casinh(CMPLX(cimag(z), creal(z)));
 
-	return (cpack(cimag(w), creal(w)));
+	return (CMPLX(cimag(w), creal(w)));
 }
 
 /*
@@ -370,19 +370,19 @@
 	if (isnan(x) || isnan(y)) {
 		/* cacos(+-Inf + I*NaN) = NaN + I*opt(-)Inf */
 		if (isinf(x))
-			return (cpack(y + y, -INFINITY));
+			return (CMPLX(y + y, -INFINITY));
 		/* cacos(NaN + I*+-Inf) = NaN + I*-+Inf */
 		if (isinf(y))
-			return (cpack(x + x, -y));
+			return (CMPLX(x + x, -y));
 		/* cacos(0 + I*NaN) = PI/2 + I*NaN with inexact */
 		if (x == 0)
-			return (cpack(pio2_hi + pio2_lo, y + y));
+			return (CMPLX(pio2_hi + pio2_lo, y + y));
 		/*
 		 * All other cases involving NaN return NaN + I*NaN.
 		 * C99 leaves it optional whether to raise invalid if one of
 		 * the arguments is not NaN, so we opt not to raise it.
 		 */
-		return (cpack(x + 0.0L + (y + 0), x + 0.0L + (y + 0)));
+		return (CMPLX(x + 0.0L + (y + 0), x + 0.0L + (y + 0)));
 	}
 
 	if (ax > RECIP_EPSILON || ay > RECIP_EPSILON) {
@@ -392,18 +392,18 @@
 		ry = creal(w) + m_ln2;
 		if (sy == 0)
 			ry = -ry;
-		return (cpack(rx, ry));
+		return (CMPLX(rx, ry));
 	}
 
 	/* Avoid spuriously raising inexact for z = 1. */
 	if (x == 1 && y == 0)
-		return (cpack(0, -y));
+		return (CMPLX(0, -y));
 
 	/* All remaining cases are inexact. */
 	raise_inexact();
 
 	if (ax < SQRT_6_EPSILON / 4 && ay < SQRT_6_EPSILON / 4)
-		return (cpack(pio2_hi - (x - pio2_lo), -y));
+		return (CMPLX(pio2_hi - (x - pio2_lo), -y));
 
 	do_hard_work(ay, ax, &ry, &B_is_usable, &B, &sqrt_A2mx2, &new_x);
 	if (B_is_usable) {
@@ -419,7 +419,7 @@
 	}
 	if (sy == 0)
 		ry = -ry;
-	return (cpack(rx, ry));
+	return (CMPLX(rx, ry));
 }
 
 /*
@@ -437,15 +437,15 @@
 	ry = cimag(w);
 	/* cacosh(NaN + I*NaN) = NaN + I*NaN */
 	if (isnan(rx) && isnan(ry))
-		return (cpack(ry, rx));
+		return (CMPLX(ry, rx));
 	/* cacosh(NaN + I*+-Inf) = +Inf + I*NaN */
 	/* cacosh(+-Inf + I*NaN) = +Inf + I*NaN */
 	if (isnan(rx))
-		return (cpack(fabs(ry), rx));
+		return (CMPLX(fabs(ry), rx));
 	/* cacosh(0 + I*NaN) = NaN + I*NaN */
 	if (isnan(ry))
-		return (cpack(ry, ry));
-	return (cpack(fabs(ry), copysign(rx, cimag(z))));
+		return (CMPLX(ry, ry));
+	return (CMPLX(fabs(ry), copysign(rx, cimag(z))));
 }
 
 /*
@@ -475,16 +475,16 @@
 	 * this method is still poor since it is uneccessarily slow.
 	 */
 	if (ax > DBL_MAX / 2)
-		return (cpack(log(hypot(x / m_e, y / m_e)) + 1, atan2(y, x)));
+		return (CMPLX(log(hypot(x / m_e, y / m_e)) + 1, atan2(y, x)));
 
 	/*
 	 * Avoid overflow when x or y is large.  Avoid underflow when x or
 	 * y is small.
 	 */
 	if (ax > QUARTER_SQRT_MAX || ay < SQRT_MIN)
-		return (cpack(log(hypot(x, y)), atan2(y, x)));
+		return (CMPLX(log(hypot(x, y)), atan2(y, x)));
 
-	return (cpack(log(ax * ax + ay * ay) / 2, atan2(y, x)));
+	return (CMPLX(log(ax * ax + ay * ay) / 2, atan2(y, x)));
 }
 
 /*
@@ -575,30 +575,30 @@
 
 	/* This helps handle many cases. */
 	if (y == 0 && ax <= 1)
-		return (cpack(atanh(x), y));
+		return (CMPLX(atanh(x), y));
 
 	/* To ensure the same accuracy as atan(), and to filter out z = 0. */
 	if (x == 0)
-		return (cpack(x, atan(y)));
+		return (CMPLX(x, atan(y)));
 
 	if (isnan(x) || isnan(y)) {
 		/* catanh(+-Inf + I*NaN) = +-0 + I*NaN */
 		if (isinf(x))
-			return (cpack(copysign(0, x), y + y));
+			return (CMPLX(copysign(0, x), y + y));
 		/* catanh(NaN + I*+-Inf) = sign(NaN)0 + I*+-PI/2 */
 		if (isinf(y))
-			return (cpack(copysign(0, x),
+			return (CMPLX(copysign(0, x),
 			    copysign(pio2_hi + pio2_lo, y)));
 		/*
 		 * All other cases involving NaN return NaN + I*NaN.
 		 * C99 leaves it optional whether to raise invalid if one of
 		 * the arguments is not NaN, so we opt not to raise it.
 		 */
-		return (cpack(x + 0.0L + (y + 0), x + 0.0L + (y + 0)));
+		return (CMPLX(x + 0.0L + (y + 0), x + 0.0L + (y + 0)));
 	}
 
 	if (ax > RECIP_EPSILON || ay > RECIP_EPSILON)
-		return (cpack(real_part_reciprocal(x, y),
+		return (CMPLX(real_part_reciprocal(x, y),
 		    copysign(pio2_hi + pio2_lo, y)));
 
 	if (ax < SQRT_3_EPSILON / 2 && ay < SQRT_3_EPSILON / 2) {
@@ -623,7 +623,7 @@
 	else
 		ry = atan2(2 * ay, (1 - ax) * (1 + ax) - ay * ay) / 2;
 
-	return (cpack(copysign(rx, x), copysign(ry, y)));
+	return (CMPLX(copysign(rx, x), copysign(ry, y)));
 }
 
 /*
@@ -633,7 +633,7 @@
 double complex
 catan(double complex z)
 {
-	double complex w = catanh(cpack(cimag(z), creal(z)));
+	double complex w = catanh(CMPLX(cimag(z), creal(z)));
 
-	return (cpack(cimag(w), creal(w)));
+	return (CMPLX(cimag(w), creal(w)));
 }
diff --git a/libm/upstream-freebsd/lib/msun/src/catrigf.c b/libm/upstream-freebsd/lib/msun/src/catrigf.c
index 08ebef7..e057d31 100644
--- a/libm/upstream-freebsd/lib/msun/src/catrigf.c
+++ b/libm/upstream-freebsd/lib/msun/src/catrigf.c
@@ -39,7 +39,7 @@
  */
 
 #include <sys/cdefs.h>
-__FBSDID("$FreeBSD$");
+__FBSDID("$FreeBSD: head/lib/msun/src/catrigf.c 275819 2014-12-16 09:21:56Z ed $");
 
 #include <complex.h>
 #include <float.h>
@@ -156,12 +156,12 @@
 
 	if (isnan(x) || isnan(y)) {
 		if (isinf(x))
-			return (cpackf(x, y + y));
+			return (CMPLXF(x, y + y));
 		if (isinf(y))
-			return (cpackf(y, x + x));
+			return (CMPLXF(y, x + x));
 		if (y == 0)
-			return (cpackf(x + x, y));
-		return (cpackf(x + 0.0L + (y + 0), x + 0.0L + (y + 0)));
+			return (CMPLXF(x + x, y));
+		return (CMPLXF(x + 0.0L + (y + 0), x + 0.0L + (y + 0)));
 	}
 
 	if (ax > RECIP_EPSILON || ay > RECIP_EPSILON) {
@@ -169,7 +169,7 @@
 			w = clog_for_large_values(z) + m_ln2;
 		else
 			w = clog_for_large_values(-z) + m_ln2;
-		return (cpackf(copysignf(crealf(w), x),
+		return (CMPLXF(copysignf(crealf(w), x),
 		    copysignf(cimagf(w), y)));
 	}
 
@@ -186,15 +186,15 @@
 		ry = asinf(B);
 	else
 		ry = atan2f(new_y, sqrt_A2my2);
-	return (cpackf(copysignf(rx, x), copysignf(ry, y)));
+	return (CMPLXF(copysignf(rx, x), copysignf(ry, y)));
 }
 
 float complex
 casinf(float complex z)
 {
-	float complex w = casinhf(cpackf(cimagf(z), crealf(z)));
+	float complex w = casinhf(CMPLXF(cimagf(z), crealf(z)));
 
-	return (cpackf(cimagf(w), crealf(w)));
+	return (CMPLXF(cimagf(w), crealf(w)));
 }
 
 float complex
@@ -214,12 +214,12 @@
 
 	if (isnan(x) || isnan(y)) {
 		if (isinf(x))
-			return (cpackf(y + y, -INFINITY));
+			return (CMPLXF(y + y, -INFINITY));
 		if (isinf(y))
-			return (cpackf(x + x, -y));
+			return (CMPLXF(x + x, -y));
 		if (x == 0)
-			return (cpackf(pio2_hi + pio2_lo, y + y));
-		return (cpackf(x + 0.0L + (y + 0), x + 0.0L + (y + 0)));
+			return (CMPLXF(pio2_hi + pio2_lo, y + y));
+		return (CMPLXF(x + 0.0L + (y + 0), x + 0.0L + (y + 0)));
 	}
 
 	if (ax > RECIP_EPSILON || ay > RECIP_EPSILON) {
@@ -228,16 +228,16 @@
 		ry = crealf(w) + m_ln2;
 		if (sy == 0)
 			ry = -ry;
-		return (cpackf(rx, ry));
+		return (CMPLXF(rx, ry));
 	}
 
 	if (x == 1 && y == 0)
-		return (cpackf(0, -y));
+		return (CMPLXF(0, -y));
 
 	raise_inexact();
 
 	if (ax < SQRT_6_EPSILON / 4 && ay < SQRT_6_EPSILON / 4)
-		return (cpackf(pio2_hi - (x - pio2_lo), -y));
+		return (CMPLXF(pio2_hi - (x - pio2_lo), -y));
 
 	do_hard_work(ay, ax, &ry, &B_is_usable, &B, &sqrt_A2mx2, &new_x);
 	if (B_is_usable) {
@@ -253,7 +253,7 @@
 	}
 	if (sy == 0)
 		ry = -ry;
-	return (cpackf(rx, ry));
+	return (CMPLXF(rx, ry));
 }
 
 float complex
@@ -266,12 +266,12 @@
 	rx = crealf(w);
 	ry = cimagf(w);
 	if (isnan(rx) && isnan(ry))
-		return (cpackf(ry, rx));
+		return (CMPLXF(ry, rx));
 	if (isnan(rx))
-		return (cpackf(fabsf(ry), rx));
+		return (CMPLXF(fabsf(ry), rx));
 	if (isnan(ry))
-		return (cpackf(ry, ry));
-	return (cpackf(fabsf(ry), copysignf(rx, cimagf(z))));
+		return (CMPLXF(ry, ry));
+	return (CMPLXF(fabsf(ry), copysignf(rx, cimagf(z))));
 }
 
 static float complex
@@ -291,13 +291,13 @@
 	}
 
 	if (ax > FLT_MAX / 2)
-		return (cpackf(logf(hypotf(x / m_e, y / m_e)) + 1,
+		return (CMPLXF(logf(hypotf(x / m_e, y / m_e)) + 1,
 		    atan2f(y, x)));
 
 	if (ax > QUARTER_SQRT_MAX || ay < SQRT_MIN)
-		return (cpackf(logf(hypotf(x, y)), atan2f(y, x)));
+		return (CMPLXF(logf(hypotf(x, y)), atan2f(y, x)));
 
-	return (cpackf(logf(ax * ax + ay * ay) / 2, atan2f(y, x)));
+	return (CMPLXF(logf(ax * ax + ay * ay) / 2, atan2f(y, x)));
 }
 
 static inline float
@@ -346,22 +346,22 @@
 	ay = fabsf(y);
 
 	if (y == 0 && ax <= 1)
-		return (cpackf(atanhf(x), y));
+		return (CMPLXF(atanhf(x), y));
 
 	if (x == 0)
-		return (cpackf(x, atanf(y)));
+		return (CMPLXF(x, atanf(y)));
 
 	if (isnan(x) || isnan(y)) {
 		if (isinf(x))
-			return (cpackf(copysignf(0, x), y + y));
+			return (CMPLXF(copysignf(0, x), y + y));
 		if (isinf(y))
-			return (cpackf(copysignf(0, x),
+			return (CMPLXF(copysignf(0, x),
 			    copysignf(pio2_hi + pio2_lo, y)));
-		return (cpackf(x + 0.0L + (y + 0), x + 0.0L + (y + 0)));
+		return (CMPLXF(x + 0.0L + (y + 0), x + 0.0L + (y + 0)));
 	}
 
 	if (ax > RECIP_EPSILON || ay > RECIP_EPSILON)
-		return (cpackf(real_part_reciprocal(x, y),
+		return (CMPLXF(real_part_reciprocal(x, y),
 		    copysignf(pio2_hi + pio2_lo, y)));
 
 	if (ax < SQRT_3_EPSILON / 2 && ay < SQRT_3_EPSILON / 2) {
@@ -381,13 +381,13 @@
 	else
 		ry = atan2f(2 * ay, (1 - ax) * (1 + ax) - ay * ay) / 2;
 
-	return (cpackf(copysignf(rx, x), copysignf(ry, y)));
+	return (CMPLXF(copysignf(rx, x), copysignf(ry, y)));
 }
 
 float complex
 catanf(float complex z)
 {
-	float complex w = catanhf(cpackf(cimagf(z), crealf(z)));
+	float complex w = catanhf(CMPLXF(cimagf(z), crealf(z)));
 
-	return (cpackf(cimagf(w), crealf(w)));
+	return (CMPLXF(cimagf(w), crealf(w)));
 }
diff --git a/libm/upstream-freebsd/lib/msun/src/e_j0.c b/libm/upstream-freebsd/lib/msun/src/e_j0.c
index 8320f25..36e72c2 100644
--- a/libm/upstream-freebsd/lib/msun/src/e_j0.c
+++ b/libm/upstream-freebsd/lib/msun/src/e_j0.c
@@ -12,7 +12,7 @@
  */
 
 #include <sys/cdefs.h>
-__FBSDID("$FreeBSD$");
+__FBSDID("$FreeBSD: head/lib/msun/src/e_j0.c 283032 2015-05-17 16:27:06Z kargl $");
 
 /* __ieee754_j0(x), __ieee754_y0(x)
  * Bessel function of the first and second kinds of order zero.
@@ -62,7 +62,9 @@
 #include "math.h"
 #include "math_private.h"
 
-static double pzero(double), qzero(double);
+static __inline double pzero(double), qzero(double);
+
+static const volatile double vone = 1, vzero = 0;
 
 static const double
 huge 	= 1e300,
@@ -115,7 +117,7 @@
 	if(ix<0x3f200000) {	/* |x| < 2**-13 */
 	    if(huge+x>one) {	/* raise inexact if x != 0 */
 	        if(ix<0x3e400000) return one;	/* |x|<2**-27 */
-	        else 	      return one - 0.25*x*x;
+	        else 	      return one - x*x/4;
 	    }
 	}
 	z = x*x;
@@ -150,10 +152,16 @@
 
 	EXTRACT_WORDS(hx,lx,x);
         ix = 0x7fffffff&hx;
-    /* Y0(NaN) is NaN, y0(-inf) is Nan, y0(inf) is 0  */
-	if(ix>=0x7ff00000) return  one/(x+x*x); 
-        if((ix|lx)==0) return -one/zero;
-        if(hx<0) return zero/zero;
+	/*
+	 * y0(NaN) = NaN.
+	 * y0(Inf) = 0.
+	 * y0(-Inf) = NaN and raise invalid exception.
+	 */
+	if(ix>=0x7ff00000) return vone/(x+x*x); 
+	/* y0(+-0) = -inf and raise divide-by-zero exception. */
+	if((ix|lx)==0) return -one/vzero;
+	/* y0(x<0) = NaN and raise invalid exception. */
+	if(hx<0) return vzero/vzero;
         if(ix >= 0x40000000) {  /* |x| >= 2.0 */
         /* y0(x) = sqrt(2/(pi*x))*(p0(x)*sin(x0)+q0(x)*cos(x0))
          * where x0 = x-pi/4
@@ -268,7 +276,8 @@
   1.46576176948256193810e+01, /* 0x402D50B3, 0x44391809 */
 };
 
-	static double pzero(double x)
+static __inline double
+pzero(double x)
 {
 	const double *p,*q;
 	double z,r,s;
@@ -278,7 +287,7 @@
 	if(ix>=0x40200000)     {p = pR8; q= pS8;}
 	else if(ix>=0x40122E8B){p = pR5; q= pS5;}
 	else if(ix>=0x4006DB6D){p = pR3; q= pS3;}
-	else if(ix>=0x40000000){p = pR2; q= pS2;}
+	else                   {p = pR2; q= pS2;}	/* ix>=0x40000000 */
 	z = one/(x*x);
 	r = p[0]+z*(p[1]+z*(p[2]+z*(p[3]+z*(p[4]+z*p[5]))));
 	s = one+z*(q[0]+z*(q[1]+z*(q[2]+z*(q[3]+z*q[4]))));
@@ -363,7 +372,8 @@
  -5.31095493882666946917e+00, /* 0xC0153E6A, 0xF8B32931 */
 };
 
-	static double qzero(double x)
+static __inline double
+qzero(double x)
 {
 	const double *p,*q;
 	double s,r,z;
@@ -373,7 +383,7 @@
 	if(ix>=0x40200000)     {p = qR8; q= qS8;}
 	else if(ix>=0x40122E8B){p = qR5; q= qS5;}
 	else if(ix>=0x4006DB6D){p = qR3; q= qS3;}
-	else if(ix>=0x40000000){p = qR2; q= qS2;}
+	else                   {p = qR2; q= qS2;}	/* ix>=0x40000000 */
 	z = one/(x*x);
 	r = p[0]+z*(p[1]+z*(p[2]+z*(p[3]+z*(p[4]+z*p[5]))));
 	s = one+z*(q[0]+z*(q[1]+z*(q[2]+z*(q[3]+z*(q[4]+z*q[5])))));
diff --git a/libm/upstream-freebsd/lib/msun/src/e_j0f.c b/libm/upstream-freebsd/lib/msun/src/e_j0f.c
index c45faf3..e53b218 100644
--- a/libm/upstream-freebsd/lib/msun/src/e_j0f.c
+++ b/libm/upstream-freebsd/lib/msun/src/e_j0f.c
@@ -14,12 +14,18 @@
  */
 
 #include <sys/cdefs.h>
-__FBSDID("$FreeBSD$");
+__FBSDID("$FreeBSD: head/lib/msun/src/e_j0f.c 283032 2015-05-17 16:27:06Z kargl $");
+
+/*
+ * See e_j0.c for complete comments.
+ */
 
 #include "math.h"
 #include "math_private.h"
 
-static float pzerof(float), qzerof(float);
+static __inline float pzerof(float), qzerof(float);
+
+static const volatile float vone = 1,  vzero = 0;
 
 static const float
 huge 	= 1e30,
@@ -62,17 +68,17 @@
 	 * j0(x) = 1/sqrt(pi) * (P(0,x)*cc - Q(0,x)*ss) / sqrt(x)
 	 * y0(x) = 1/sqrt(pi) * (P(0,x)*ss + Q(0,x)*cc) / sqrt(x)
 	 */
-		if(ix>0x80000000) z = (invsqrtpi*cc)/sqrtf(x);
+		if(ix>0x58000000) z = (invsqrtpi*cc)/sqrtf(x); /* |x|>2**49 */
 		else {
 		    u = pzerof(x); v = qzerof(x);
 		    z = invsqrtpi*(u*cc-v*ss)/sqrtf(x);
 		}
 		return z;
 	}
-	if(ix<0x39000000) {	/* |x| < 2**-13 */
+	if(ix<0x3b000000) {	/* |x| < 2**-9 */
 	    if(huge+x>one) {	/* raise inexact if x != 0 */
-	        if(ix<0x32000000) return one;	/* |x|<2**-27 */
-	        else 	      return one - (float)0.25*x*x;
+	        if(ix<0x39800000) return one;	/* |x|<2**-12 */
+	        else 	      return one - x*x/4;
 	    }
 	}
 	z = x*x;
@@ -107,10 +113,9 @@
 
 	GET_FLOAT_WORD(hx,x);
         ix = 0x7fffffff&hx;
-    /* Y0(NaN) is NaN, y0(-inf) is Nan, y0(inf) is 0  */
-	if(ix>=0x7f800000) return  one/(x+x*x);
-        if(ix==0) return -one/zero;
-        if(hx<0) return zero/zero;
+	if(ix>=0x7f800000) return  vone/(x+x*x);
+	if(ix==0) return -one/vzero;
+	if(hx<0) return vzero/vzero;
         if(ix >= 0x40000000) {  /* |x| >= 2.0 */
         /* y0(x) = sqrt(2/(pi*x))*(p0(x)*sin(x0)+q0(x)*cos(x0))
          * where x0 = x-pi/4
@@ -136,14 +141,14 @@
                     if ((s*c)<zero) cc = z/ss;
                     else            ss = z/cc;
                 }
-                if(ix>0x80000000) z = (invsqrtpi*ss)/sqrtf(x);
+                if(ix>0x58000000) z = (invsqrtpi*ss)/sqrtf(x); /* |x|>2**49 */
                 else {
                     u = pzerof(x); v = qzerof(x);
                     z = invsqrtpi*(u*ss+v*cc)/sqrtf(x);
                 }
                 return z;
 	}
-	if(ix<=0x32000000) {	/* x < 2**-27 */
+	if(ix<=0x39000000) {	/* x < 2**-13 */
 	    return(u00 + tpi*__ieee754_logf(x));
 	}
 	z = x*x;
@@ -224,7 +229,8 @@
   1.4657617569e+01, /* 0x416a859a */
 };
 
-	static float pzerof(float x)
+static __inline float
+pzerof(float x)
 {
 	const float *p,*q;
 	float z,r,s;
@@ -232,9 +238,9 @@
 	GET_FLOAT_WORD(ix,x);
 	ix &= 0x7fffffff;
 	if(ix>=0x41000000)     {p = pR8; q= pS8;}
-	else if(ix>=0x40f71c58){p = pR5; q= pS5;}
-	else if(ix>=0x4036db68){p = pR3; q= pS3;}
-	else if(ix>=0x40000000){p = pR2; q= pS2;}
+	else if(ix>=0x409173eb){p = pR5; q= pS5;}
+	else if(ix>=0x4036d917){p = pR3; q= pS3;}
+	else                   {p = pR2; q= pS2;}	/* ix>=0x40000000 */
 	z = one/(x*x);
 	r = p[0]+z*(p[1]+z*(p[2]+z*(p[3]+z*(p[4]+z*p[5]))));
 	s = one+z*(q[0]+z*(q[1]+z*(q[2]+z*(q[3]+z*q[4]))));
@@ -319,7 +325,8 @@
  -5.3109550476e+00, /* 0xc0a9f358 */
 };
 
-	static float qzerof(float x)
+static __inline float
+qzerof(float x)
 {
 	const float *p,*q;
 	float s,r,z;
@@ -327,9 +334,9 @@
 	GET_FLOAT_WORD(ix,x);
 	ix &= 0x7fffffff;
 	if(ix>=0x41000000)     {p = qR8; q= qS8;}
-	else if(ix>=0x40f71c58){p = qR5; q= qS5;}
-	else if(ix>=0x4036db68){p = qR3; q= qS3;}
-	else if(ix>=0x40000000){p = qR2; q= qS2;}
+	else if(ix>=0x409173eb){p = qR5; q= qS5;}
+	else if(ix>=0x4036d917){p = qR3; q= qS3;}
+	else                   {p = qR2; q= qS2;}	/* ix>=0x40000000 */
 	z = one/(x*x);
 	r = p[0]+z*(p[1]+z*(p[2]+z*(p[3]+z*(p[4]+z*p[5]))));
 	s = one+z*(q[0]+z*(q[1]+z*(q[2]+z*(q[3]+z*(q[4]+z*q[5])))));
diff --git a/libm/upstream-freebsd/lib/msun/src/e_j1.c b/libm/upstream-freebsd/lib/msun/src/e_j1.c
index 63800ad..b11ac2d 100644
--- a/libm/upstream-freebsd/lib/msun/src/e_j1.c
+++ b/libm/upstream-freebsd/lib/msun/src/e_j1.c
@@ -12,7 +12,7 @@
  */
 
 #include <sys/cdefs.h>
-__FBSDID("$FreeBSD$");
+__FBSDID("$FreeBSD: head/lib/msun/src/e_j1.c 283032 2015-05-17 16:27:06Z kargl $");
 
 /* __ieee754_j1(x), __ieee754_y1(x)
  * Bessel function of the first and second kinds of order zero.
@@ -62,7 +62,9 @@
 #include "math.h"
 #include "math_private.h"
 
-static double pone(double), qone(double);
+static __inline double pone(double), qone(double);
+
+static const volatile double vone = 1, vzero = 0;
 
 static const double
 huge    = 1e300,
@@ -147,10 +149,16 @@
 
 	EXTRACT_WORDS(hx,lx,x);
         ix = 0x7fffffff&hx;
-    /* if Y1(NaN) is NaN, Y1(-inf) is NaN, Y1(inf) is 0 */
-	if(ix>=0x7ff00000) return  one/(x+x*x); 
-        if((ix|lx)==0) return -one/zero;
-        if(hx<0) return zero/zero;
+	/*
+	 * y1(NaN) = NaN.
+	 * y1(Inf) = 0.
+	 * y1(-Inf) = NaN and raise invalid exception.
+	 */
+	if(ix>=0x7ff00000) return  vone/(x+x*x); 
+	/* y1(+-0) = -inf and raise divide-by-zero exception. */
+        if((ix|lx)==0) return -one/vzero;
+	/* y1(x<0) = NaN and raise invalid exception. */
+        if(hx<0) return vzero/vzero;
         if(ix >= 0x40000000) {  /* |x| >= 2.0 */
                 s = sin(x);
                 c = cos(x);
@@ -262,7 +270,8 @@
   8.36463893371618283368e+00, /* 0x4020BAB1, 0xF44E5192 */
 };
 
-	static double pone(double x)
+static __inline double
+pone(double x)
 {
 	const double *p,*q;
 	double z,r,s;
@@ -272,7 +281,7 @@
         if(ix>=0x40200000)     {p = pr8; q= ps8;}
         else if(ix>=0x40122E8B){p = pr5; q= ps5;}
         else if(ix>=0x4006DB6D){p = pr3; q= ps3;}
-        else if(ix>=0x40000000){p = pr2; q= ps2;}
+	else                   {p = pr2; q= ps2;}	/* ix>=0x40000000 */
         z = one/(x*x);
         r = p[0]+z*(p[1]+z*(p[2]+z*(p[3]+z*(p[4]+z*p[5]))));
         s = one+z*(q[0]+z*(q[1]+z*(q[2]+z*(q[3]+z*q[4]))));
@@ -358,7 +367,8 @@
  -4.95949898822628210127e+00, /* 0xC013D686, 0xE71BE86B */
 };
 
-	static double qone(double x)
+static __inline double
+qone(double x)
 {
 	const double *p,*q;
 	double  s,r,z;
@@ -368,7 +378,7 @@
 	if(ix>=0x40200000)     {p = qr8; q= qs8;}
 	else if(ix>=0x40122E8B){p = qr5; q= qs5;}
 	else if(ix>=0x4006DB6D){p = qr3; q= qs3;}
-	else if(ix>=0x40000000){p = qr2; q= qs2;}
+	else                   {p = qr2; q= qs2;}	/* ix>=0x40000000 */
 	z = one/(x*x);
 	r = p[0]+z*(p[1]+z*(p[2]+z*(p[3]+z*(p[4]+z*p[5]))));
 	s = one+z*(q[0]+z*(q[1]+z*(q[2]+z*(q[3]+z*(q[4]+z*q[5])))));
diff --git a/libm/upstream-freebsd/lib/msun/src/e_j1f.c b/libm/upstream-freebsd/lib/msun/src/e_j1f.c
index 88e2d83..0cca823 100644
--- a/libm/upstream-freebsd/lib/msun/src/e_j1f.c
+++ b/libm/upstream-freebsd/lib/msun/src/e_j1f.c
@@ -14,12 +14,18 @@
  */
 
 #include <sys/cdefs.h>
-__FBSDID("$FreeBSD$");
+__FBSDID("$FreeBSD: head/lib/msun/src/e_j1f.c 283032 2015-05-17 16:27:06Z kargl $");
+
+/*
+ * See e_j1.c for complete comments.
+ */
 
 #include "math.h"
 #include "math_private.h"
 
-static float ponef(float), qonef(float);
+static __inline float ponef(float), qonef(float);
+
+static const volatile float vone = 1, vzero = 0;
 
 static const float
 huge    = 1e30,
@@ -63,7 +69,7 @@
 	 * j1(x) = 1/sqrt(pi) * (P(1,x)*cc - Q(1,x)*ss) / sqrt(x)
 	 * y1(x) = 1/sqrt(pi) * (P(1,x)*ss + Q(1,x)*cc) / sqrt(x)
 	 */
-		if(ix>0x80000000) z = (invsqrtpi*cc)/sqrtf(y);
+		if(ix>0x58000000) z = (invsqrtpi*cc)/sqrtf(y); /* |x|>2**49 */
 		else {
 		    u = ponef(y); v = qonef(y);
 		    z = invsqrtpi*(u*cc-v*ss)/sqrtf(y);
@@ -71,7 +77,7 @@
 		if(hx<0) return -z;
 		else  	 return  z;
 	}
-	if(ix<0x32000000) {	/* |x|<2**-27 */
+	if(ix<0x39000000) {	/* |x|<2**-13 */
 	    if(huge+x>one) return (float)0.5*x;/* inexact if x!=0 necessary */
 	}
 	z = x*x;
@@ -104,10 +110,9 @@
 
 	GET_FLOAT_WORD(hx,x);
         ix = 0x7fffffff&hx;
-    /* if Y1(NaN) is NaN, Y1(-inf) is NaN, Y1(inf) is 0 */
-	if(ix>=0x7f800000) return  one/(x+x*x);
-        if(ix==0) return -one/zero;
-        if(hx<0) return zero/zero;
+	if(ix>=0x7f800000) return  vone/(x+x*x);
+	if(ix==0) return -one/vzero;
+	if(hx<0) return vzero/vzero;
         if(ix >= 0x40000000) {  /* |x| >= 2.0 */
                 s = sinf(x);
                 c = cosf(x);
@@ -129,14 +134,14 @@
          *              sin(x) +- cos(x) = -cos(2x)/(sin(x) -+ cos(x))
          * to compute the worse one.
          */
-                if(ix>0x48000000) z = (invsqrtpi*ss)/sqrtf(x);
+                if(ix>0x58000000) z = (invsqrtpi*ss)/sqrtf(x); /* |x|>2**49 */
                 else {
                     u = ponef(x); v = qonef(x);
                     z = invsqrtpi*(u*ss+v*cc)/sqrtf(x);
                 }
                 return z;
         }
-        if(ix<=0x24800000) {    /* x < 2**-54 */
+        if(ix<=0x33000000) {    /* x < 2**-25 */
             return(-tpi/x);
         }
         z = x*x;
@@ -219,7 +224,8 @@
   8.3646392822e+00, /* 0x4105d590 */
 };
 
-	static float ponef(float x)
+static __inline float
+ponef(float x)
 {
 	const float *p,*q;
 	float z,r,s;
@@ -227,9 +233,9 @@
 	GET_FLOAT_WORD(ix,x);
 	ix &= 0x7fffffff;
         if(ix>=0x41000000)     {p = pr8; q= ps8;}
-        else if(ix>=0x40f71c58){p = pr5; q= ps5;}
-        else if(ix>=0x4036db68){p = pr3; q= ps3;}
-        else if(ix>=0x40000000){p = pr2; q= ps2;}
+        else if(ix>=0x409173eb){p = pr5; q= ps5;}
+        else if(ix>=0x4036d917){p = pr3; q= ps3;}
+	else                   {p = pr2; q= ps2;}	/* ix>=0x40000000 */
         z = one/(x*x);
         r = p[0]+z*(p[1]+z*(p[2]+z*(p[3]+z*(p[4]+z*p[5]))));
         s = one+z*(q[0]+z*(q[1]+z*(q[2]+z*(q[3]+z*q[4]))));
@@ -315,17 +321,18 @@
  -4.9594988823e+00, /* 0xc09eb437 */
 };
 
-	static float qonef(float x)
+static __inline float
+qonef(float x)
 {
 	const float *p,*q;
 	float  s,r,z;
 	int32_t ix;
 	GET_FLOAT_WORD(ix,x);
 	ix &= 0x7fffffff;
-	if(ix>=0x40200000)     {p = qr8; q= qs8;}
-	else if(ix>=0x40f71c58){p = qr5; q= qs5;}
-	else if(ix>=0x4036db68){p = qr3; q= qs3;}
-	else if(ix>=0x40000000){p = qr2; q= qs2;}
+	if(ix>=0x41000000)     {p = qr8; q= qs8;}
+	else if(ix>=0x409173eb){p = qr5; q= qs5;}
+	else if(ix>=0x4036d917){p = qr3; q= qs3;}
+	else                   {p = qr2; q= qs2;}	/* ix>=0x40000000 */
 	z = one/(x*x);
 	r = p[0]+z*(p[1]+z*(p[2]+z*(p[3]+z*(p[4]+z*p[5]))));
 	s = one+z*(q[0]+z*(q[1]+z*(q[2]+z*(q[3]+z*(q[4]+z*q[5])))));
diff --git a/libm/upstream-freebsd/lib/msun/src/e_jn.c b/libm/upstream-freebsd/lib/msun/src/e_jn.c
index 8b0bc62..a1130c5 100644
--- a/libm/upstream-freebsd/lib/msun/src/e_jn.c
+++ b/libm/upstream-freebsd/lib/msun/src/e_jn.c
@@ -12,7 +12,7 @@
  */
 
 #include <sys/cdefs.h>
-__FBSDID("$FreeBSD$");
+__FBSDID("$FreeBSD: head/lib/msun/src/e_jn.c 279856 2015-03-10 17:10:54Z kargl $");
 
 /*
  * __ieee754_jn(n, x), __ieee754_yn(n, x)
@@ -43,6 +43,8 @@
 #include "math.h"
 #include "math_private.h"
 
+static const volatile double vone = 1, vzero = 0;
+
 static const double
 invsqrtpi=  5.64189583547756279280e-01, /* 0x3FE20DD7, 0x50429B6D */
 two   =  2.00000000000000000000e+00, /* 0x40000000, 0x00000000 */
@@ -220,10 +222,12 @@
 
 	EXTRACT_WORDS(hx,lx,x);
 	ix = 0x7fffffff&hx;
-    /* if Y(n,NaN) is NaN */
+	/* yn(n,NaN) = NaN */
 	if((ix|((u_int32_t)(lx|-lx))>>31)>0x7ff00000) return x+x;
-	if((ix|lx)==0) return -one/zero;
-	if(hx<0) return zero/zero;
+	/* yn(n,+-0) = -inf and raise divide-by-zero exception. */
+	if((ix|lx)==0) return -one/vzero;
+	/* yn(n,x<0) = NaN and raise invalid exception. */
+	if(hx<0) return vzero/vzero;
 	sign = 1;
 	if(n<0){
 		n = -n;
diff --git a/libm/upstream-freebsd/lib/msun/src/e_jnf.c b/libm/upstream-freebsd/lib/msun/src/e_jnf.c
index f564aec..c82d5cf 100644
--- a/libm/upstream-freebsd/lib/msun/src/e_jnf.c
+++ b/libm/upstream-freebsd/lib/msun/src/e_jnf.c
@@ -14,11 +14,17 @@
  */
 
 #include <sys/cdefs.h>
-__FBSDID("$FreeBSD$");
+__FBSDID("$FreeBSD: head/lib/msun/src/e_jnf.c 279856 2015-03-10 17:10:54Z kargl $");
+
+/*
+ * See e_jn.c for complete comments.
+ */
 
 #include "math.h"
 #include "math_private.h"
 
+static const volatile float vone = 1, vzero = 0;
+
 static const float
 two   =  2.0000000000e+00, /* 0x40000000 */
 one   =  1.0000000000e+00; /* 0x3F800000 */
@@ -172,10 +178,9 @@
 
 	GET_FLOAT_WORD(hx,x);
 	ix = 0x7fffffff&hx;
-    /* if Y(n,NaN) is NaN */
 	if(ix>0x7f800000) return x+x;
-	if(ix==0) return -one/zero;
-	if(hx<0) return zero/zero;
+	if(ix==0) return -one/vzero;
+	if(hx<0) return vzero/vzero;
 	sign = 1;
 	if(n<0){
 		n = -n;
diff --git a/libm/upstream-freebsd/lib/msun/src/k_exp.c b/libm/upstream-freebsd/lib/msun/src/k_exp.c
index f592f69..5aa3ef3 100644
--- a/libm/upstream-freebsd/lib/msun/src/k_exp.c
+++ b/libm/upstream-freebsd/lib/msun/src/k_exp.c
@@ -25,7 +25,7 @@
  */
 
 #include <sys/cdefs.h>
-__FBSDID("$FreeBSD$");
+__FBSDID("$FreeBSD: head/lib/msun/src/k_exp.c 275819 2014-12-16 09:21:56Z ed $");
 
 #include <complex.h>
 
@@ -103,6 +103,6 @@
 	half_expt = expt - half_expt;
 	INSERT_WORDS(scale2, (0x3ff + half_expt) << 20, 0);
 
-	return (cpack(cos(y) * exp_x * scale1 * scale2,
+	return (CMPLX(cos(y) * exp_x * scale1 * scale2,
 	    sin(y) * exp_x * scale1 * scale2));
 }
diff --git a/libm/upstream-freebsd/lib/msun/src/k_expf.c b/libm/upstream-freebsd/lib/msun/src/k_expf.c
index 548a008..8fe8c46 100644
--- a/libm/upstream-freebsd/lib/msun/src/k_expf.c
+++ b/libm/upstream-freebsd/lib/msun/src/k_expf.c
@@ -25,7 +25,7 @@
  */
 
 #include <sys/cdefs.h>
-__FBSDID("$FreeBSD$");
+__FBSDID("$FreeBSD: head/lib/msun/src/k_expf.c 275819 2014-12-16 09:21:56Z ed $");
 
 #include <complex.h>
 
@@ -82,6 +82,6 @@
 	half_expt = expt - half_expt;
 	SET_FLOAT_WORD(scale2, (0x7f + half_expt) << 23);
 
-	return (cpackf(cosf(y) * exp_x * scale1 * scale2,
+	return (CMPLXF(cosf(y) * exp_x * scale1 * scale2,
 	    sinf(y) * exp_x * scale1 * scale2));
 }
diff --git a/libm/upstream-freebsd/lib/msun/src/math_private.h b/libm/upstream-freebsd/lib/msun/src/math_private.h
index 8af2c65..1f10e8b 100644
--- a/libm/upstream-freebsd/lib/msun/src/math_private.h
+++ b/libm/upstream-freebsd/lib/msun/src/math_private.h
@@ -11,7 +11,7 @@
 
 /*
  * from: @(#)fdlibm.h 5.1 93/09/24
- * $FreeBSD$
+ * $FreeBSD: head/lib/msun/src/math_private.h 276176 2014-12-24 10:13:53Z ed $
  */
 
 #ifndef _MATH_PRIVATE_H_
@@ -454,9 +454,15 @@
  * (0.0+I)*(y+0.0*I) and laboriously computing the full complex product.
  * In particular, I*Inf is corrupted to NaN+I*Inf, and I*-0 is corrupted
  * to -0.0+I*0.0.
+ *
+ * The C11 standard introduced the macros CMPLX(), CMPLXF() and CMPLXL()
+ * to construct complex values.  Compilers that conform to the C99
+ * standard require the following functions to avoid the above issues.
  */
+
+#ifndef CMPLXF
 static __inline float complex
-cpackf(float x, float y)
+CMPLXF(float x, float y)
 {
 	float_complex z;
 
@@ -464,9 +470,11 @@
 	IMAGPART(z) = y;
 	return (z.f);
 }
+#endif
 
+#ifndef CMPLX
 static __inline double complex
-cpack(double x, double y)
+CMPLX(double x, double y)
 {
 	double_complex z;
 
@@ -474,9 +482,11 @@
 	IMAGPART(z) = y;
 	return (z.f);
 }
+#endif
 
+#ifndef CMPLXL
 static __inline long double complex
-cpackl(long double x, long double y)
+CMPLXL(long double x, long double y)
 {
 	long_double_complex z;
 
@@ -484,6 +494,8 @@
 	IMAGPART(z) = y;
 	return (z.f);
 }
+#endif
+
 #endif /* _COMPLEX_H */
  
 #ifdef __GNUCLIKE_ASM
diff --git a/libm/upstream-freebsd/lib/msun/src/s_ccosh.c b/libm/upstream-freebsd/lib/msun/src/s_ccosh.c
index 9ea962b..e544e91 100644
--- a/libm/upstream-freebsd/lib/msun/src/s_ccosh.c
+++ b/libm/upstream-freebsd/lib/msun/src/s_ccosh.c
@@ -32,10 +32,12 @@
  *
  * Exceptional values are noted in the comments within the source code.
  * These values and the return value were taken from n1124.pdf.
+ * The sign of the result for some exceptional values is unspecified but
+ * must satisfy both cosh(conj(z)) == conj(cosh(z)) and cosh(-z) == cosh(z).
  */
 
 #include <sys/cdefs.h>
-__FBSDID("$FreeBSD$");
+__FBSDID("$FreeBSD: head/lib/msun/src/s_ccosh.c 284423 2015-06-15 20:11:06Z tijl $");
 
 #include <complex.h>
 #include <math.h>
@@ -62,49 +64,48 @@
 	/* Handle the nearly-non-exceptional cases where x and y are finite. */
 	if (ix < 0x7ff00000 && iy < 0x7ff00000) {
 		if ((iy | ly) == 0)
-			return (cpack(cosh(x), x * y));
-		if (ix < 0x40360000)	/* small x: normal case */
-			return (cpack(cosh(x) * cos(y), sinh(x) * sin(y)));
+			return (CMPLX(cosh(x), x * y));
+		if (ix < 0x40360000)	/* |x| < 22: normal case */
+			return (CMPLX(cosh(x) * cos(y), sinh(x) * sin(y)));
 
 		/* |x| >= 22, so cosh(x) ~= exp(|x|) */
 		if (ix < 0x40862e42) {
 			/* x < 710: exp(|x|) won't overflow */
 			h = exp(fabs(x)) * 0.5;
-			return (cpack(h * cos(y), copysign(h, x) * sin(y)));
+			return (CMPLX(h * cos(y), copysign(h, x) * sin(y)));
 		} else if (ix < 0x4096bbaa) {
 			/* x < 1455: scale to avoid overflow */
-			z = __ldexp_cexp(cpack(fabs(x), y), -1);
-			return (cpack(creal(z), cimag(z) * copysign(1, x)));
+			z = __ldexp_cexp(CMPLX(fabs(x), y), -1);
+			return (CMPLX(creal(z), cimag(z) * copysign(1, x)));
 		} else {
 			/* x >= 1455: the result always overflows */
 			h = huge * x;
-			return (cpack(h * h * cos(y), h * sin(y)));
+			return (CMPLX(h * h * cos(y), h * sin(y)));
 		}
 	}
 
 	/*
-	 * cosh(+-0 +- I Inf) = dNaN + I sign(d(+-0, dNaN))0.
-	 * The sign of 0 in the result is unspecified.  Choice = normally
-	 * the same as dNaN.  Raise the invalid floating-point exception.
+	 * cosh(+-0 +- I Inf) = dNaN + I (+-)(+-)0.
+	 * The sign of 0 in the result is unspecified.  Choice = product
+	 * of the signs of the argument.  Raise the invalid floating-point
+	 * exception.
 	 *
-	 * cosh(+-0 +- I NaN) = d(NaN) + I sign(d(+-0, NaN))0.
-	 * The sign of 0 in the result is unspecified.  Choice = normally
-	 * the same as d(NaN).
+	 * cosh(+-0 +- I NaN) = d(NaN) + I (+-)(+-)0.
+	 * The sign of 0 in the result is unspecified.  Choice = product
+	 * of the signs of the argument.
 	 */
-	if ((ix | lx) == 0 && iy >= 0x7ff00000)
-		return (cpack(y - y, copysign(0, x * (y - y))));
+	if ((ix | lx) == 0)		/* && iy >= 0x7ff00000 */
+		return (CMPLX(y - y, x * copysign(0, y)));
 
 	/*
 	 * cosh(+-Inf +- I 0) = +Inf + I (+-)(+-)0.
 	 *
-	 * cosh(NaN +- I 0)   = d(NaN) + I sign(d(NaN, +-0))0.
-	 * The sign of 0 in the result is unspecified.
+	 * cosh(NaN +- I 0)   = d(NaN) + I (+-)(+-)0.
+	 * The sign of 0 in the result is unspecified.  Choice = product
+	 * of the signs of the argument.
 	 */
-	if ((iy | ly) == 0 && ix >= 0x7ff00000) {
-		if (((hx & 0xfffff) | lx) == 0)
-			return (cpack(x * x, copysign(0, x) * y));
-		return (cpack(x * x, copysign(0, (x + x) * y)));
-	}
+	if ((iy | ly) == 0)		/* && ix >= 0x7ff00000 */
+		return (CMPLX(x * x, copysign(0, x) * y));
 
 	/*
 	 * cosh(x +- I Inf) = dNaN + I dNaN.
@@ -114,8 +115,8 @@
 	 * Optionally raises the invalid floating-point exception for finite
 	 * nonzero x.  Choice = don't raise (except for signaling NaNs).
 	 */
-	if (ix < 0x7ff00000 && iy >= 0x7ff00000)
-		return (cpack(y - y, x * (y - y)));
+	if (ix < 0x7ff00000)		/* && iy >= 0x7ff00000 */
+		return (CMPLX(y - y, x * (y - y)));
 
 	/*
 	 * cosh(+-Inf + I NaN)  = +Inf + I d(NaN).
@@ -126,10 +127,10 @@
 	 *
 	 * cosh(+-Inf + I y)   = +Inf cos(y) +- I Inf sin(y)
 	 */
-	if (ix >= 0x7ff00000 && ((hx & 0xfffff) | lx) == 0) {
+	if (ix == 0x7ff00000 && lx == 0) {
 		if (iy >= 0x7ff00000)
-			return (cpack(x * x, x * (y - y)));
-		return (cpack((x * x) * cos(y), x * sin(y)));
+			return (CMPLX(INFINITY, x * (y - y)));
+		return (CMPLX(INFINITY * cos(y), x * sin(y)));
 	}
 
 	/*
@@ -143,7 +144,7 @@
 	 * Optionally raises the invalid floating-point exception for finite
 	 * nonzero y.  Choice = don't raise (except for signaling NaNs).
 	 */
-	return (cpack((x * x) * (y - y), (x + x) * (y - y)));
+	return (CMPLX((x * x) * (y - y), (x + x) * (y - y)));
 }
 
 double complex
@@ -151,5 +152,5 @@
 {
 
 	/* ccos(z) = ccosh(I * z) */
-	return (ccosh(cpack(-cimag(z), creal(z))));
+	return (ccosh(CMPLX(-cimag(z), creal(z))));
 }
diff --git a/libm/upstream-freebsd/lib/msun/src/s_ccoshf.c b/libm/upstream-freebsd/lib/msun/src/s_ccoshf.c
index 1de9ad4..e33840a 100644
--- a/libm/upstream-freebsd/lib/msun/src/s_ccoshf.c
+++ b/libm/upstream-freebsd/lib/msun/src/s_ccoshf.c
@@ -25,11 +25,11 @@
  */
 
 /*
- * Hyperbolic cosine of a complex argument.  See s_ccosh.c for details.
+ * Float version of ccosh().  See s_ccosh.c for details.
  */
 
 #include <sys/cdefs.h>
-__FBSDID("$FreeBSD$");
+__FBSDID("$FreeBSD: head/lib/msun/src/s_ccoshf.c 284423 2015-06-15 20:11:06Z tijl $");
 
 #include <complex.h>
 #include <math.h>
@@ -55,50 +55,47 @@
 
 	if (ix < 0x7f800000 && iy < 0x7f800000) {
 		if (iy == 0)
-			return (cpackf(coshf(x), x * y));
-		if (ix < 0x41100000)	/* small x: normal case */
-			return (cpackf(coshf(x) * cosf(y), sinhf(x) * sinf(y)));
+			return (CMPLXF(coshf(x), x * y));
+		if (ix < 0x41100000)	/* |x| < 9: normal case */
+			return (CMPLXF(coshf(x) * cosf(y), sinhf(x) * sinf(y)));
 
 		/* |x| >= 9, so cosh(x) ~= exp(|x|) */
 		if (ix < 0x42b17218) {
 			/* x < 88.7: expf(|x|) won't overflow */
-			h = expf(fabsf(x)) * 0.5f;
-			return (cpackf(h * cosf(y), copysignf(h, x) * sinf(y)));
+			h = expf(fabsf(x)) * 0.5F;
+			return (CMPLXF(h * cosf(y), copysignf(h, x) * sinf(y)));
 		} else if (ix < 0x4340b1e7) {
 			/* x < 192.7: scale to avoid overflow */
-			z = __ldexp_cexpf(cpackf(fabsf(x), y), -1);
-			return (cpackf(crealf(z), cimagf(z) * copysignf(1, x)));
+			z = __ldexp_cexpf(CMPLXF(fabsf(x), y), -1);
+			return (CMPLXF(crealf(z), cimagf(z) * copysignf(1, x)));
 		} else {
 			/* x >= 192.7: the result always overflows */
 			h = huge * x;
-			return (cpackf(h * h * cosf(y), h * sinf(y)));
+			return (CMPLXF(h * h * cosf(y), h * sinf(y)));
 		}
 	}
 
-	if (ix == 0 && iy >= 0x7f800000)
-		return (cpackf(y - y, copysignf(0, x * (y - y))));
+	if (ix == 0)			/* && iy >= 0x7f800000 */
+		return (CMPLXF(y - y, x * copysignf(0, y)));
 
-	if (iy == 0 && ix >= 0x7f800000) {
-		if ((hx & 0x7fffff) == 0)
-			return (cpackf(x * x, copysignf(0, x) * y));
-		return (cpackf(x * x, copysignf(0, (x + x) * y)));
-	}
+	if (iy == 0)			/* && ix >= 0x7f800000 */
+		return (CMPLXF(x * x, copysignf(0, x) * y));
 
-	if (ix < 0x7f800000 && iy >= 0x7f800000)
-		return (cpackf(y - y, x * (y - y)));
+	if (ix < 0x7f800000)		/* && iy >= 0x7f800000 */
+		return (CMPLXF(y - y, x * (y - y)));
 
-	if (ix >= 0x7f800000 && (hx & 0x7fffff) == 0) {
+	if (ix == 0x7f800000) {
 		if (iy >= 0x7f800000)
-			return (cpackf(x * x, x * (y - y)));
-		return (cpackf((x * x) * cosf(y), x * sinf(y)));
+			return (CMPLXF(INFINITY, x * (y - y)));
+		return (CMPLXF(INFINITY * cosf(y), x * sinf(y)));
 	}
 
-	return (cpackf((x * x) * (y - y), (x + x) * (y - y)));
+	return (CMPLXF((x * x) * (y - y), (x + x) * (y - y)));
 }
 
 float complex
 ccosf(float complex z)
 {
 
-	return (ccoshf(cpackf(-cimagf(z), crealf(z))));
+	return (ccoshf(CMPLXF(-cimagf(z), crealf(z))));
 }
diff --git a/libm/upstream-freebsd/lib/msun/src/s_cexp.c b/libm/upstream-freebsd/lib/msun/src/s_cexp.c
index abe178f..660a68d 100644
--- a/libm/upstream-freebsd/lib/msun/src/s_cexp.c
+++ b/libm/upstream-freebsd/lib/msun/src/s_cexp.c
@@ -25,7 +25,7 @@
  */
 
 #include <sys/cdefs.h>
-__FBSDID("$FreeBSD$");
+__FBSDID("$FreeBSD: head/lib/msun/src/s_cexp.c 275819 2014-12-16 09:21:56Z ed $");
 
 #include <complex.h>
 #include <math.h>
@@ -50,22 +50,22 @@
 
 	/* cexp(x + I 0) = exp(x) + I 0 */
 	if ((hy | ly) == 0)
-		return (cpack(exp(x), y));
+		return (CMPLX(exp(x), y));
 	EXTRACT_WORDS(hx, lx, x);
 	/* cexp(0 + I y) = cos(y) + I sin(y) */
 	if (((hx & 0x7fffffff) | lx) == 0)
-		return (cpack(cos(y), sin(y)));
+		return (CMPLX(cos(y), sin(y)));
 
 	if (hy >= 0x7ff00000) {
 		if (lx != 0 || (hx & 0x7fffffff) != 0x7ff00000) {
 			/* cexp(finite|NaN +- I Inf|NaN) = NaN + I NaN */
-			return (cpack(y - y, y - y));
+			return (CMPLX(y - y, y - y));
 		} else if (hx & 0x80000000) {
 			/* cexp(-Inf +- I Inf|NaN) = 0 + I 0 */
-			return (cpack(0.0, 0.0));
+			return (CMPLX(0.0, 0.0));
 		} else {
 			/* cexp(+Inf +- I Inf|NaN) = Inf + I NaN */
-			return (cpack(x, y - y));
+			return (CMPLX(x, y - y));
 		}
 	}
 
@@ -84,6 +84,6 @@
 		 *  -  x = NaN (spurious inexact exception from y)
 		 */
 		exp_x = exp(x);
-		return (cpack(exp_x * cos(y), exp_x * sin(y)));
+		return (CMPLX(exp_x * cos(y), exp_x * sin(y)));
 	}
 }
diff --git a/libm/upstream-freebsd/lib/msun/src/s_cexpf.c b/libm/upstream-freebsd/lib/msun/src/s_cexpf.c
index 0e30d08..709ad47 100644
--- a/libm/upstream-freebsd/lib/msun/src/s_cexpf.c
+++ b/libm/upstream-freebsd/lib/msun/src/s_cexpf.c
@@ -25,7 +25,7 @@
  */
 
 #include <sys/cdefs.h>
-__FBSDID("$FreeBSD$");
+__FBSDID("$FreeBSD: head/lib/msun/src/s_cexpf.c 275819 2014-12-16 09:21:56Z ed $");
 
 #include <complex.h>
 #include <math.h>
@@ -50,22 +50,22 @@
 
 	/* cexp(x + I 0) = exp(x) + I 0 */
 	if (hy == 0)
-		return (cpackf(expf(x), y));
+		return (CMPLXF(expf(x), y));
 	GET_FLOAT_WORD(hx, x);
 	/* cexp(0 + I y) = cos(y) + I sin(y) */
 	if ((hx & 0x7fffffff) == 0)
-		return (cpackf(cosf(y), sinf(y)));
+		return (CMPLXF(cosf(y), sinf(y)));
 
 	if (hy >= 0x7f800000) {
 		if ((hx & 0x7fffffff) != 0x7f800000) {
 			/* cexp(finite|NaN +- I Inf|NaN) = NaN + I NaN */
-			return (cpackf(y - y, y - y));
+			return (CMPLXF(y - y, y - y));
 		} else if (hx & 0x80000000) {
 			/* cexp(-Inf +- I Inf|NaN) = 0 + I 0 */
-			return (cpackf(0.0, 0.0));
+			return (CMPLXF(0.0, 0.0));
 		} else {
 			/* cexp(+Inf +- I Inf|NaN) = Inf + I NaN */
-			return (cpackf(x, y - y));
+			return (CMPLXF(x, y - y));
 		}
 	}
 
@@ -84,6 +84,6 @@
 		 *  -  x = NaN (spurious inexact exception from y)
 		 */
 		exp_x = expf(x);
-		return (cpackf(exp_x * cosf(y), exp_x * sinf(y)));
+		return (CMPLXF(exp_x * cosf(y), exp_x * sinf(y)));
 	}
 }
diff --git a/libm/upstream-freebsd/lib/msun/src/s_conj.c b/libm/upstream-freebsd/lib/msun/src/s_conj.c
index 5770c29..61fac63 100644
--- a/libm/upstream-freebsd/lib/msun/src/s_conj.c
+++ b/libm/upstream-freebsd/lib/msun/src/s_conj.c
@@ -23,7 +23,7 @@
  * OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF
  * SUCH DAMAGE.
  *
- * $FreeBSD$
+ * $FreeBSD: head/lib/msun/src/s_conj.c 275819 2014-12-16 09:21:56Z ed $
  */
 
 #include <complex.h>
@@ -34,5 +34,5 @@
 conj(double complex z)
 {
 
-	return (cpack(creal(z), -cimag(z)));
+	return (CMPLX(creal(z), -cimag(z)));
 }
diff --git a/libm/upstream-freebsd/lib/msun/src/s_conjf.c b/libm/upstream-freebsd/lib/msun/src/s_conjf.c
index b090760..83c9ef0 100644
--- a/libm/upstream-freebsd/lib/msun/src/s_conjf.c
+++ b/libm/upstream-freebsd/lib/msun/src/s_conjf.c
@@ -23,7 +23,7 @@
  * OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF
  * SUCH DAMAGE.
  *
- * $FreeBSD$
+ * $FreeBSD: head/lib/msun/src/s_conjf.c 275819 2014-12-16 09:21:56Z ed $
  */
 
 #include <complex.h>
@@ -34,5 +34,5 @@
 conjf(float complex z)
 {
 
-	return (cpackf(crealf(z), -cimagf(z)));
+	return (CMPLXF(crealf(z), -cimagf(z)));
 }
diff --git a/libm/upstream-freebsd/lib/msun/src/s_conjl.c b/libm/upstream-freebsd/lib/msun/src/s_conjl.c
index 0e431ef..d9e6a16 100644
--- a/libm/upstream-freebsd/lib/msun/src/s_conjl.c
+++ b/libm/upstream-freebsd/lib/msun/src/s_conjl.c
@@ -23,7 +23,7 @@
  * OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF
  * SUCH DAMAGE.
  *
- * $FreeBSD$
+ * $FreeBSD: head/lib/msun/src/s_conjl.c 275819 2014-12-16 09:21:56Z ed $
  */
 
 #include <complex.h>
@@ -34,5 +34,5 @@
 conjl(long double complex z)
 {
 
-	return (cpackl(creall(z), -cimagl(z)));
+	return (CMPLXL(creall(z), -cimagl(z)));
 }
diff --git a/libm/upstream-freebsd/lib/msun/src/s_cproj.c b/libm/upstream-freebsd/lib/msun/src/s_cproj.c
index 8e9404c..ec2266e 100644
--- a/libm/upstream-freebsd/lib/msun/src/s_cproj.c
+++ b/libm/upstream-freebsd/lib/msun/src/s_cproj.c
@@ -25,7 +25,7 @@
  */
 
 #include <sys/cdefs.h>
-__FBSDID("$FreeBSD$");
+__FBSDID("$FreeBSD: head/lib/msun/src/s_cproj.c 275819 2014-12-16 09:21:56Z ed $");
 
 #include <complex.h>
 #include <math.h>
@@ -39,7 +39,7 @@
 	if (!isinf(creal(z)) && !isinf(cimag(z)))
 		return (z);
 	else
-		return (cpack(INFINITY, copysign(0.0, cimag(z))));
+		return (CMPLX(INFINITY, copysign(0.0, cimag(z))));
 }
 
 #if LDBL_MANT_DIG == 53
diff --git a/libm/upstream-freebsd/lib/msun/src/s_cprojf.c b/libm/upstream-freebsd/lib/msun/src/s_cprojf.c
index 68ea77b..63af75f 100644
--- a/libm/upstream-freebsd/lib/msun/src/s_cprojf.c
+++ b/libm/upstream-freebsd/lib/msun/src/s_cprojf.c
@@ -25,7 +25,7 @@
  */
 
 #include <sys/cdefs.h>
-__FBSDID("$FreeBSD$");
+__FBSDID("$FreeBSD: head/lib/msun/src/s_cprojf.c 275819 2014-12-16 09:21:56Z ed $");
 
 #include <complex.h>
 #include <math.h>
@@ -39,5 +39,5 @@
 	if (!isinf(crealf(z)) && !isinf(cimagf(z)))
 		return (z);
 	else
-		return (cpackf(INFINITY, copysignf(0.0, cimagf(z))));
+		return (CMPLXF(INFINITY, copysignf(0.0, cimagf(z))));
 }
diff --git a/libm/upstream-freebsd/lib/msun/src/s_cprojl.c b/libm/upstream-freebsd/lib/msun/src/s_cprojl.c
index 07385bc..8386f81 100644
--- a/libm/upstream-freebsd/lib/msun/src/s_cprojl.c
+++ b/libm/upstream-freebsd/lib/msun/src/s_cprojl.c
@@ -25,7 +25,7 @@
  */
 
 #include <sys/cdefs.h>
-__FBSDID("$FreeBSD$");
+__FBSDID("$FreeBSD: head/lib/msun/src/s_cprojl.c 275819 2014-12-16 09:21:56Z ed $");
 
 #include <complex.h>
 #include <math.h>
@@ -39,5 +39,5 @@
 	if (!isinf(creall(z)) && !isinf(cimagl(z)))
 		return (z);
 	else
-		return (cpackl(INFINITY, copysignl(0.0, cimagl(z))));
+		return (CMPLXL(INFINITY, copysignl(0.0, cimagl(z))));
 }
diff --git a/libm/upstream-freebsd/lib/msun/src/s_csinh.c b/libm/upstream-freebsd/lib/msun/src/s_csinh.c
index c192f30..cff1402 100644
--- a/libm/upstream-freebsd/lib/msun/src/s_csinh.c
+++ b/libm/upstream-freebsd/lib/msun/src/s_csinh.c
@@ -32,10 +32,12 @@
  *
  * Exceptional values are noted in the comments within the source code.
  * These values and the return value were taken from n1124.pdf.
+ * The sign of the result for some exceptional values is unspecified but
+ * must satisfy both sinh(conj(z)) == conj(sinh(z)) and sinh(-z) == -sinh(z).
  */
 
 #include <sys/cdefs.h>
-__FBSDID("$FreeBSD$");
+__FBSDID("$FreeBSD: head/lib/msun/src/s_csinh.c 284426 2015-06-15 20:16:53Z tijl $");
 
 #include <complex.h>
 #include <math.h>
@@ -62,48 +64,45 @@
 	/* Handle the nearly-non-exceptional cases where x and y are finite. */
 	if (ix < 0x7ff00000 && iy < 0x7ff00000) {
 		if ((iy | ly) == 0)
-			return (cpack(sinh(x), y));
-		if (ix < 0x40360000)	/* small x: normal case */
-			return (cpack(sinh(x) * cos(y), cosh(x) * sin(y)));
+			return (CMPLX(sinh(x), y));
+		if (ix < 0x40360000)	/* |x| < 22: normal case */
+			return (CMPLX(sinh(x) * cos(y), cosh(x) * sin(y)));
 
 		/* |x| >= 22, so cosh(x) ~= exp(|x|) */
 		if (ix < 0x40862e42) {
 			/* x < 710: exp(|x|) won't overflow */
 			h = exp(fabs(x)) * 0.5;
-			return (cpack(copysign(h, x) * cos(y), h * sin(y)));
+			return (CMPLX(copysign(h, x) * cos(y), h * sin(y)));
 		} else if (ix < 0x4096bbaa) {
 			/* x < 1455: scale to avoid overflow */
-			z = __ldexp_cexp(cpack(fabs(x), y), -1);
-			return (cpack(creal(z) * copysign(1, x), cimag(z)));
+			z = __ldexp_cexp(CMPLX(fabs(x), y), -1);
+			return (CMPLX(creal(z) * copysign(1, x), cimag(z)));
 		} else {
 			/* x >= 1455: the result always overflows */
 			h = huge * x;
-			return (cpack(h * cos(y), h * h * sin(y)));
+			return (CMPLX(h * cos(y), h * h * sin(y)));
 		}
 	}
 
 	/*
-	 * sinh(+-0 +- I Inf) = sign(d(+-0, dNaN))0 + I dNaN.
-	 * The sign of 0 in the result is unspecified.  Choice = normally
-	 * the same as dNaN.  Raise the invalid floating-point exception.
+	 * sinh(+-0 +- I Inf) = +-0 + I dNaN.
+	 * The sign of 0 in the result is unspecified.  Choice = same sign
+	 * as the argument.  Raise the invalid floating-point exception.
 	 *
-	 * sinh(+-0 +- I NaN) = sign(d(+-0, NaN))0 + I d(NaN).
-	 * The sign of 0 in the result is unspecified.  Choice = normally
-	 * the same as d(NaN).
+	 * sinh(+-0 +- I NaN) = +-0 + I d(NaN).
+	 * The sign of 0 in the result is unspecified.  Choice = same sign
+	 * as the argument.
 	 */
-	if ((ix | lx) == 0 && iy >= 0x7ff00000)
-		return (cpack(copysign(0, x * (y - y)), y - y));
+	if ((ix | lx) == 0)		/* && iy >= 0x7ff00000 */
+		return (CMPLX(x, y - y));
 
 	/*
 	 * sinh(+-Inf +- I 0) = +-Inf + I +-0.
 	 *
 	 * sinh(NaN +- I 0)   = d(NaN) + I +-0.
 	 */
-	if ((iy | ly) == 0 && ix >= 0x7ff00000) {
-		if (((hx & 0xfffff) | lx) == 0)
-			return (cpack(x, y));
-		return (cpack(x, copysign(0, y)));
-	}
+	if ((iy | ly) == 0)		/* && ix >= 0x7ff00000 */
+		return (CMPLX(x + x, y));
 
 	/*
 	 * sinh(x +- I Inf) = dNaN + I dNaN.
@@ -113,45 +112,45 @@
 	 * Optionally raises the invalid floating-point exception for finite
 	 * nonzero x.  Choice = don't raise (except for signaling NaNs).
 	 */
-	if (ix < 0x7ff00000 && iy >= 0x7ff00000)
-		return (cpack(y - y, x * (y - y)));
+	if (ix < 0x7ff00000)		/* && iy >= 0x7ff00000 */
+		return (CMPLX(y - y, y - y));
 
 	/*
 	 * sinh(+-Inf + I NaN)  = +-Inf + I d(NaN).
-	 * The sign of Inf in the result is unspecified.  Choice = normally
-	 * the same as d(NaN).
+	 * The sign of Inf in the result is unspecified.  Choice = same sign
+	 * as the argument.
 	 *
-	 * sinh(+-Inf +- I Inf) = +Inf + I dNaN.
-	 * The sign of Inf in the result is unspecified.  Choice = always +.
-	 * Raise the invalid floating-point exception.
+	 * sinh(+-Inf +- I Inf) = +-Inf + I dNaN.
+	 * The sign of Inf in the result is unspecified.  Choice = same sign
+	 * as the argument.  Raise the invalid floating-point exception.
 	 *
 	 * sinh(+-Inf + I y)   = +-Inf cos(y) + I Inf sin(y)
 	 */
-	if (ix >= 0x7ff00000 && ((hx & 0xfffff) | lx) == 0) {
+	if (ix == 0x7ff00000 && lx == 0) {
 		if (iy >= 0x7ff00000)
-			return (cpack(x * x, x * (y - y)));
-		return (cpack(x * cos(y), INFINITY * sin(y)));
+			return (CMPLX(x, y - y));
+		return (CMPLX(x * cos(y), INFINITY * sin(y)));
 	}
 
 	/*
-	 * sinh(NaN + I NaN)  = d(NaN) + I d(NaN).
+	 * sinh(NaN1 + I NaN2) = d(NaN1, NaN2) + I d(NaN1, NaN2).
 	 *
-	 * sinh(NaN +- I Inf) = d(NaN) + I d(NaN).
+	 * sinh(NaN +- I Inf)  = d(NaN, dNaN) + I d(NaN, dNaN).
 	 * Optionally raises the invalid floating-point exception.
 	 * Choice = raise.
 	 *
-	 * sinh(NaN + I y)    = d(NaN) + I d(NaN).
+	 * sinh(NaN + I y)     = d(NaN) + I d(NaN).
 	 * Optionally raises the invalid floating-point exception for finite
 	 * nonzero y.  Choice = don't raise (except for signaling NaNs).
 	 */
-	return (cpack((x * x) * (y - y), (x + x) * (y - y)));
+	return (CMPLX((x + x) * (y - y), (x * x) * (y - y)));
 }
 
 double complex
 csin(double complex z)
 {
 
-	/* csin(z) = -I * csinh(I * z) */
-	z = csinh(cpack(-cimag(z), creal(z)));
-	return (cpack(cimag(z), -creal(z)));
+	/* csin(z) = -I * csinh(I * z) = I * conj(csinh(I * conj(z))). */
+	z = csinh(CMPLX(cimag(z), creal(z)));
+	return (CMPLX(cimag(z), creal(z)));
 }
diff --git a/libm/upstream-freebsd/lib/msun/src/s_csinhf.c b/libm/upstream-freebsd/lib/msun/src/s_csinhf.c
index c523125..f050890 100644
--- a/libm/upstream-freebsd/lib/msun/src/s_csinhf.c
+++ b/libm/upstream-freebsd/lib/msun/src/s_csinhf.c
@@ -25,11 +25,11 @@
  */
 
 /*
- * Hyperbolic sine of a complex argument z.  See s_csinh.c for details.
+ * Float version of csinh().  See s_csinh.c for details.
  */
 
 #include <sys/cdefs.h>
-__FBSDID("$FreeBSD$");
+__FBSDID("$FreeBSD: head/lib/msun/src/s_csinhf.c 284426 2015-06-15 20:16:53Z tijl $");
 
 #include <complex.h>
 #include <math.h>
@@ -55,51 +55,48 @@
 
 	if (ix < 0x7f800000 && iy < 0x7f800000) {
 		if (iy == 0)
-			return (cpackf(sinhf(x), y));
-		if (ix < 0x41100000)	/* small x: normal case */
-			return (cpackf(sinhf(x) * cosf(y), coshf(x) * sinf(y)));
+			return (CMPLXF(sinhf(x), y));
+		if (ix < 0x41100000)	/* |x| < 9: normal case */
+			return (CMPLXF(sinhf(x) * cosf(y), coshf(x) * sinf(y)));
 
 		/* |x| >= 9, so cosh(x) ~= exp(|x|) */
 		if (ix < 0x42b17218) {
 			/* x < 88.7: expf(|x|) won't overflow */
-			h = expf(fabsf(x)) * 0.5f;
-			return (cpackf(copysignf(h, x) * cosf(y), h * sinf(y)));
+			h = expf(fabsf(x)) * 0.5F;
+			return (CMPLXF(copysignf(h, x) * cosf(y), h * sinf(y)));
 		} else if (ix < 0x4340b1e7) {
 			/* x < 192.7: scale to avoid overflow */
-			z = __ldexp_cexpf(cpackf(fabsf(x), y), -1);
-			return (cpackf(crealf(z) * copysignf(1, x), cimagf(z)));
+			z = __ldexp_cexpf(CMPLXF(fabsf(x), y), -1);
+			return (CMPLXF(crealf(z) * copysignf(1, x), cimagf(z)));
 		} else {
 			/* x >= 192.7: the result always overflows */
 			h = huge * x;
-			return (cpackf(h * cosf(y), h * h * sinf(y)));
+			return (CMPLXF(h * cosf(y), h * h * sinf(y)));
 		}
 	}
 
-	if (ix == 0 && iy >= 0x7f800000)
-		return (cpackf(copysignf(0, x * (y - y)), y - y));
+	if (ix == 0)			/* && iy >= 0x7f800000 */
+		return (CMPLXF(x, y - y));
 
-	if (iy == 0 && ix >= 0x7f800000) {
-		if ((hx & 0x7fffff) == 0)
-			return (cpackf(x, y));
-		return (cpackf(x, copysignf(0, y)));
-	}
+	if (iy == 0)			/* && ix >= 0x7f800000 */
+		return (CMPLXF(x + x, y));
 
-	if (ix < 0x7f800000 && iy >= 0x7f800000)
-		return (cpackf(y - y, x * (y - y)));
+	if (ix < 0x7f800000)		/* && iy >= 0x7f800000 */
+		return (CMPLXF(y - y, y - y));
 
-	if (ix >= 0x7f800000 && (hx & 0x7fffff) == 0) {
+	if (ix == 0x7f800000) {
 		if (iy >= 0x7f800000)
-			return (cpackf(x * x, x * (y - y)));
-		return (cpackf(x * cosf(y), INFINITY * sinf(y)));
+			return (CMPLXF(x, y - y));
+		return (CMPLXF(x * cosf(y), INFINITY * sinf(y)));
 	}
 
-	return (cpackf((x * x) * (y - y), (x + x) * (y - y)));
+	return (CMPLXF((x + x) * (y - y), (x * x) * (y - y)));
 }
 
 float complex
 csinf(float complex z)
 {
 
-	z = csinhf(cpackf(-cimagf(z), crealf(z)));
-	return (cpackf(cimagf(z), -crealf(z)));
+	z = csinhf(CMPLXF(cimagf(z), crealf(z)));
+	return (CMPLXF(cimagf(z), crealf(z)));
 }
diff --git a/libm/upstream-freebsd/lib/msun/src/s_csqrt.c b/libm/upstream-freebsd/lib/msun/src/s_csqrt.c
index 18a7ae3..c908a2d 100644
--- a/libm/upstream-freebsd/lib/msun/src/s_csqrt.c
+++ b/libm/upstream-freebsd/lib/msun/src/s_csqrt.c
@@ -25,7 +25,7 @@
  */
 
 #include <sys/cdefs.h>
-__FBSDID("$FreeBSD$");
+__FBSDID("$FreeBSD: head/lib/msun/src/s_csqrt.c 275819 2014-12-16 09:21:56Z ed $");
 
 #include <complex.h>
 #include <float.h>
@@ -58,12 +58,12 @@
 
 	/* Handle special cases. */
 	if (z == 0)
-		return (cpack(0, b));
+		return (CMPLX(0, b));
 	if (isinf(b))
-		return (cpack(INFINITY, b));
+		return (CMPLX(INFINITY, b));
 	if (isnan(a)) {
 		t = (b - b) / (b - b);	/* raise invalid if b is not a NaN */
-		return (cpack(a, t));	/* return NaN + NaN i */
+		return (CMPLX(a, t));	/* return NaN + NaN i */
 	}
 	if (isinf(a)) {
 		/*
@@ -73,9 +73,9 @@
 		 * csqrt(-inf + y i)   = 0   +  inf i
 		 */
 		if (signbit(a))
-			return (cpack(fabs(b - b), copysign(a, b)));
+			return (CMPLX(fabs(b - b), copysign(a, b)));
 		else
-			return (cpack(a, copysign(b - b, b)));
+			return (CMPLX(a, copysign(b - b, b)));
 	}
 	/*
 	 * The remaining special case (b is NaN) is handled just fine by
@@ -94,10 +94,10 @@
 	/* Algorithm 312, CACM vol 10, Oct 1967. */
 	if (a >= 0) {
 		t = sqrt((a + hypot(a, b)) * 0.5);
-		result = cpack(t, b / (2 * t));
+		result = CMPLX(t, b / (2 * t));
 	} else {
 		t = sqrt((-a + hypot(a, b)) * 0.5);
-		result = cpack(fabs(b) / (2 * t), copysign(t, b));
+		result = CMPLX(fabs(b) / (2 * t), copysign(t, b));
 	}
 
 	/* Rescale. */
diff --git a/libm/upstream-freebsd/lib/msun/src/s_csqrtf.c b/libm/upstream-freebsd/lib/msun/src/s_csqrtf.c
index da7fe18..12a894f 100644
--- a/libm/upstream-freebsd/lib/msun/src/s_csqrtf.c
+++ b/libm/upstream-freebsd/lib/msun/src/s_csqrtf.c
@@ -25,7 +25,7 @@
  */
 
 #include <sys/cdefs.h>
-__FBSDID("$FreeBSD$");
+__FBSDID("$FreeBSD: head/lib/msun/src/s_csqrtf.c 275819 2014-12-16 09:21:56Z ed $");
 
 #include <complex.h>
 #include <math.h>
@@ -49,12 +49,12 @@
 
 	/* Handle special cases. */
 	if (z == 0)
-		return (cpackf(0, b));
+		return (CMPLXF(0, b));
 	if (isinf(b))
-		return (cpackf(INFINITY, b));
+		return (CMPLXF(INFINITY, b));
 	if (isnan(a)) {
 		t = (b - b) / (b - b);	/* raise invalid if b is not a NaN */
-		return (cpackf(a, t));	/* return NaN + NaN i */
+		return (CMPLXF(a, t));	/* return NaN + NaN i */
 	}
 	if (isinf(a)) {
 		/*
@@ -64,9 +64,9 @@
 		 * csqrtf(-inf + y i)   = 0   +  inf i
 		 */
 		if (signbit(a))
-			return (cpackf(fabsf(b - b), copysignf(a, b)));
+			return (CMPLXF(fabsf(b - b), copysignf(a, b)));
 		else
-			return (cpackf(a, copysignf(b - b, b)));
+			return (CMPLXF(a, copysignf(b - b, b)));
 	}
 	/*
 	 * The remaining special case (b is NaN) is handled just fine by
@@ -80,9 +80,9 @@
 	 */
 	if (a >= 0) {
 		t = sqrt((a + hypot(a, b)) * 0.5);
-		return (cpackf(t, b / (2.0 * t)));
+		return (CMPLXF(t, b / (2.0 * t)));
 	} else {
 		t = sqrt((-a + hypot(a, b)) * 0.5);
-		return (cpackf(fabsf(b) / (2.0 * t), copysignf(t, b)));
+		return (CMPLXF(fabsf(b) / (2.0 * t), copysignf(t, b)));
 	}
 }
diff --git a/libm/upstream-freebsd/lib/msun/src/s_csqrtl.c b/libm/upstream-freebsd/lib/msun/src/s_csqrtl.c
index dd18e1e..7bcff59 100644
--- a/libm/upstream-freebsd/lib/msun/src/s_csqrtl.c
+++ b/libm/upstream-freebsd/lib/msun/src/s_csqrtl.c
@@ -25,7 +25,7 @@
  */
 
 #include <sys/cdefs.h>
-__FBSDID("$FreeBSD$");
+__FBSDID("$FreeBSD: head/lib/msun/src/s_csqrtl.c 275819 2014-12-16 09:21:56Z ed $");
 
 #include <complex.h>
 #include <float.h>
@@ -58,12 +58,12 @@
 
 	/* Handle special cases. */
 	if (z == 0)
-		return (cpackl(0, b));
+		return (CMPLXL(0, b));
 	if (isinf(b))
-		return (cpackl(INFINITY, b));
+		return (CMPLXL(INFINITY, b));
 	if (isnan(a)) {
 		t = (b - b) / (b - b);	/* raise invalid if b is not a NaN */
-		return (cpackl(a, t));	/* return NaN + NaN i */
+		return (CMPLXL(a, t));	/* return NaN + NaN i */
 	}
 	if (isinf(a)) {
 		/*
@@ -73,9 +73,9 @@
 		 * csqrt(-inf + y i)   = 0   +  inf i
 		 */
 		if (signbit(a))
-			return (cpackl(fabsl(b - b), copysignl(a, b)));
+			return (CMPLXL(fabsl(b - b), copysignl(a, b)));
 		else
-			return (cpackl(a, copysignl(b - b, b)));
+			return (CMPLXL(a, copysignl(b - b, b)));
 	}
 	/*
 	 * The remaining special case (b is NaN) is handled just fine by
@@ -94,10 +94,10 @@
 	/* Algorithm 312, CACM vol 10, Oct 1967. */
 	if (a >= 0) {
 		t = sqrtl((a + hypotl(a, b)) * 0.5);
-		result = cpackl(t, b / (2 * t));
+		result = CMPLXL(t, b / (2 * t));
 	} else {
 		t = sqrtl((-a + hypotl(a, b)) * 0.5);
-		result = cpackl(fabsl(b) / (2 * t), copysignl(t, b));
+		result = CMPLXL(fabsl(b) / (2 * t), copysignl(t, b));
 	}
 
 	/* Rescale. */
diff --git a/libm/upstream-freebsd/lib/msun/src/s_ctanh.c b/libm/upstream-freebsd/lib/msun/src/s_ctanh.c
index d427e28..e5973c3 100644
--- a/libm/upstream-freebsd/lib/msun/src/s_ctanh.c
+++ b/libm/upstream-freebsd/lib/msun/src/s_ctanh.c
@@ -25,7 +25,7 @@
  */
 
 /*
- * Hyperbolic tangent of a complex argument z = x + i y.
+ * Hyperbolic tangent of a complex argument z = x + I y.
  *
  * The algorithm is from:
  *
@@ -44,15 +44,15 @@
  *
  *   tanh(z) = sinh(z) / cosh(z)
  *
- *             sinh(x) cos(y) + i cosh(x) sin(y)
+ *             sinh(x) cos(y) + I cosh(x) sin(y)
  *           = ---------------------------------
- *             cosh(x) cos(y) + i sinh(x) sin(y)
+ *             cosh(x) cos(y) + I sinh(x) sin(y)
  *
- *             cosh(x) sinh(x) / cos^2(y) + i tan(y)
+ *             cosh(x) sinh(x) / cos^2(y) + I tan(y)
  *           = -------------------------------------
  *                    1 + sinh^2(x) / cos^2(y)
  *
- *             beta rho s + i t
+ *             beta rho s + I t
  *           = ----------------
  *               1 + beta s^2
  *
@@ -64,7 +64,7 @@
  */
 
 #include <sys/cdefs.h>
-__FBSDID("$FreeBSD$");
+__FBSDID("$FreeBSD: head/lib/msun/src/s_ctanh.c 284427 2015-06-15 20:40:44Z tijl $");
 
 #include <complex.h>
 #include <math.h>
@@ -85,16 +85,16 @@
 	ix = hx & 0x7fffffff;
 
 	/*
-	 * ctanh(NaN + i 0) = NaN + i 0
+	 * ctanh(NaN +- I 0) = d(NaN) +- I 0
 	 *
-	 * ctanh(NaN + i y) = NaN + i NaN		for y != 0
+	 * ctanh(NaN + I y) = d(NaN,y) + I d(NaN,y)	for y != 0
 	 *
 	 * The imaginary part has the sign of x*sin(2*y), but there's no
 	 * special effort to get this right.
 	 *
-	 * ctanh(+-Inf +- i Inf) = +-1 +- 0
+	 * ctanh(+-Inf +- I Inf) = +-1 +- I 0
 	 *
-	 * ctanh(+-Inf + i y) = +-1 + 0 sin(2y)		for y finite
+	 * ctanh(+-Inf + I y) = +-1 + I 0 sin(2y)	for y finite
 	 *
 	 * The imaginary part of the sign is unspecified.  This special
 	 * case is only needed to avoid a spurious invalid exception when
@@ -102,26 +102,27 @@
 	 */
 	if (ix >= 0x7ff00000) {
 		if ((ix & 0xfffff) | lx)	/* x is NaN */
-			return (cpack(x, (y == 0 ? y : x * y)));
+			return (CMPLX((x + 0) * (y + 0),
+			    y == 0 ? y : (x + 0) * (y + 0)));
 		SET_HIGH_WORD(x, hx - 0x40000000);	/* x = copysign(1, x) */
-		return (cpack(x, copysign(0, isinf(y) ? y : sin(y) * cos(y))));
+		return (CMPLX(x, copysign(0, isinf(y) ? y : sin(y) * cos(y))));
 	}
 
 	/*
-	 * ctanh(x + i NAN) = NaN + i NaN
-	 * ctanh(x +- i Inf) = NaN + i NaN
+	 * ctanh(x + I NaN) = d(NaN) + I d(NaN)
+	 * ctanh(x +- I Inf) = dNaN + I dNaN
 	 */
 	if (!isfinite(y))
-		return (cpack(y - y, y - y));
+		return (CMPLX(y - y, y - y));
 
 	/*
-	 * ctanh(+-huge + i +-y) ~= +-1 +- i 2sin(2y)/exp(2x), using the
+	 * ctanh(+-huge +- I y) ~= +-1 +- I 2sin(2y)/exp(2x), using the
 	 * approximation sinh^2(huge) ~= exp(2*huge) / 4.
 	 * We use a modified formula to avoid spurious overflow.
 	 */
-	if (ix >= 0x40360000) {	/* x >= 22 */
+	if (ix >= 0x40360000) {	/* |x| >= 22 */
 		double exp_mx = exp(-fabs(x));
-		return (cpack(copysign(1, x),
+		return (CMPLX(copysign(1, x),
 		    4 * sin(y) * cos(y) * exp_mx * exp_mx));
 	}
 
@@ -131,14 +132,14 @@
 	s = sinh(x);
 	rho = sqrt(1 + s * s);	/* = cosh(x) */
 	denom = 1 + beta * s * s;
-	return (cpack((beta * rho * s) / denom, t / denom));
+	return (CMPLX((beta * rho * s) / denom, t / denom));
 }
 
 double complex
 ctan(double complex z)
 {
 
-	/* ctan(z) = -I * ctanh(I * z) */
-	z = ctanh(cpack(-cimag(z), creal(z)));
-	return (cpack(cimag(z), -creal(z)));
+	/* ctan(z) = -I * ctanh(I * z) = I * conj(ctanh(I * conj(z))) */
+	z = ctanh(CMPLX(cimag(z), creal(z)));
+	return (CMPLX(cimag(z), creal(z)));
 }
diff --git a/libm/upstream-freebsd/lib/msun/src/s_ctanhf.c b/libm/upstream-freebsd/lib/msun/src/s_ctanhf.c
index 4be28d8..e9826c0 100644
--- a/libm/upstream-freebsd/lib/msun/src/s_ctanhf.c
+++ b/libm/upstream-freebsd/lib/msun/src/s_ctanhf.c
@@ -29,7 +29,7 @@
  */
 
 #include <sys/cdefs.h>
-__FBSDID("$FreeBSD$");
+__FBSDID("$FreeBSD: head/lib/msun/src/s_ctanhf.c 284428 2015-06-15 20:47:26Z tijl $");
 
 #include <complex.h>
 #include <math.h>
@@ -51,18 +51,19 @@
 
 	if (ix >= 0x7f800000) {
 		if (ix & 0x7fffff)
-			return (cpackf(x, (y == 0 ? y : x * y)));
+			return (CMPLXF((x + 0) * (y + 0),
+			    y == 0 ? y : (x + 0) * (y + 0)));
 		SET_FLOAT_WORD(x, hx - 0x40000000);
-		return (cpackf(x,
+		return (CMPLXF(x,
 		    copysignf(0, isinf(y) ? y : sinf(y) * cosf(y))));
 	}
 
 	if (!isfinite(y))
-		return (cpackf(y - y, y - y));
+		return (CMPLXF(y - y, y - y));
 
-	if (ix >= 0x41300000) {	/* x >= 11 */
+	if (ix >= 0x41300000) {	/* |x| >= 11 */
 		float exp_mx = expf(-fabsf(x));
-		return (cpackf(copysignf(1, x),
+		return (CMPLXF(copysignf(1, x),
 		    4 * sinf(y) * cosf(y) * exp_mx * exp_mx));
 	}
 
@@ -71,14 +72,14 @@
 	s = sinhf(x);
 	rho = sqrtf(1 + s * s);
 	denom = 1 + beta * s * s;
-	return (cpackf((beta * rho * s) / denom, t / denom));
+	return (CMPLXF((beta * rho * s) / denom, t / denom));
 }
 
 float complex
 ctanf(float complex z)
 {
 
-	z = ctanhf(cpackf(-cimagf(z), crealf(z)));
-	return (cpackf(cimagf(z), -crealf(z)));
+	z = ctanhf(CMPLXF(cimagf(z), crealf(z)));
+	return (CMPLXF(cimagf(z), crealf(z)));
 }
 
diff --git a/libm/upstream-freebsd/lib/msun/src/s_exp2.c b/libm/upstream-freebsd/lib/msun/src/s_exp2.c
index fde11c2..dbef729 100644
--- a/libm/upstream-freebsd/lib/msun/src/s_exp2.c
+++ b/libm/upstream-freebsd/lib/msun/src/s_exp2.c
@@ -25,7 +25,7 @@
  */
 
 #include <sys/cdefs.h>
-__FBSDID("$FreeBSD$");
+__FBSDID("$FreeBSD: head/lib/msun/src/s_exp2.c 286515 2015-08-09 10:00:13Z dim $");
 
 #include <float.h>
 
@@ -376,14 +376,14 @@
 	/* Compute r = exp2(y) = exp2t[i0] * p(z - eps[i]). */
 	t = tbl[i0];		/* exp2t[i0] */
 	z -= tbl[i0 + 1];	/* eps[i0]   */
-	if (k >= -1021 << 20)
+	if (k >= -(1021 << 20))
 		INSERT_WORDS(twopk, 0x3ff00000 + k, 0);
 	else
 		INSERT_WORDS(twopkp1000, 0x3ff00000 + k + (1000 << 20), 0);
 	r = t + t * z * (P1 + z * (P2 + z * (P3 + z * (P4 + z * P5))));
 
 	/* Scale by 2**(k>>20). */
-	if(k >= -1021 << 20) {
+	if(k >= -(1021 << 20)) {
 		if (k == 1024 << 20)
 			return (r * 2.0 * 0x1p1023);
 		return (r * twopk);
diff --git a/libm/upstream-freebsd/lib/msun/src/s_fabs.c b/libm/upstream-freebsd/lib/msun/src/s_fabs.c
deleted file mode 100644
index 15529e5..0000000
--- a/libm/upstream-freebsd/lib/msun/src/s_fabs.c
+++ /dev/null
@@ -1,31 +0,0 @@
-/* @(#)s_fabs.c 5.1 93/09/24 */
-/*
- * ====================================================
- * Copyright (C) 1993 by Sun Microsystems, Inc. All rights reserved.
- *
- * Developed at SunPro, a Sun Microsystems, Inc. business.
- * Permission to use, copy, modify, and distribute this
- * software is freely granted, provided that this notice
- * is preserved.
- * ====================================================
- */
-
-#ifndef lint
-static char rcsid[] = "$FreeBSD$";
-#endif
-
-/*
- * fabs(x) returns the absolute value of x.
- */
-
-#include "math.h"
-#include "math_private.h"
-
-double
-fabs(double x)
-{
-	u_int32_t high;
-	GET_HIGH_WORD(high,x);
-	SET_HIGH_WORD(x,high&0x7fffffff);
-        return x;
-}
diff --git a/libm/upstream-freebsd/lib/msun/src/s_fabsf.c b/libm/upstream-freebsd/lib/msun/src/s_fabsf.c
deleted file mode 100644
index e9383d0..0000000
--- a/libm/upstream-freebsd/lib/msun/src/s_fabsf.c
+++ /dev/null
@@ -1,33 +0,0 @@
-/* s_fabsf.c -- float version of s_fabs.c.
- * Conversion to float by Ian Lance Taylor, Cygnus Support, ian@cygnus.com.
- */
-
-/*
- * ====================================================
- * Copyright (C) 1993 by Sun Microsystems, Inc. All rights reserved.
- *
- * Developed at SunPro, a Sun Microsystems, Inc. business.
- * Permission to use, copy, modify, and distribute this
- * software is freely granted, provided that this notice
- * is preserved.
- * ====================================================
- */
-
-#include <sys/cdefs.h>
-__FBSDID("$FreeBSD$");
-
-/*
- * fabsf(x) returns the absolute value of x.
- */
-
-#include "math.h"
-#include "math_private.h"
-
-float
-fabsf(float x)
-{
-	u_int32_t ix;
-	GET_FLOAT_WORD(ix,x);
-	SET_FLOAT_WORD(x,ix&0x7fffffff);
-        return x;
-}
diff --git a/libm/upstream-freebsd/lib/msun/src/s_scalbln.c b/libm/upstream-freebsd/lib/msun/src/s_scalbln.c
index d609d4e..8e61377 100644
--- a/libm/upstream-freebsd/lib/msun/src/s_scalbln.c
+++ b/libm/upstream-freebsd/lib/msun/src/s_scalbln.c
@@ -25,52 +25,30 @@
  */
 
 #include <sys/cdefs.h>
-__FBSDID("$FreeBSD$");
+__FBSDID("$FreeBSD: head/lib/msun/src/s_scalbln.c 278339 2015-02-07 00:38:18Z kargl $");
 
-#include <limits.h>
 #include <math.h>
 
-double
-scalbln (double x, long n)
-{
-	int in;
+#define	NMAX	65536
+#define	NMIN	-65536
 
-	in = (int)n;
-	if (in != n) {
-		if (n > 0)
-			in = INT_MAX;
-		else
-			in = INT_MIN;
-	}
-	return (scalbn(x, in));
+double
+scalbln(double x, long n)
+{
+
+	return (scalbn(x, (n > NMAX) ? NMAX : (n < NMIN) ? NMIN : (int)n));
 }
 
 float
-scalblnf (float x, long n)
+scalblnf(float x, long n)
 {
-	int in;
 
-	in = (int)n;
-	if (in != n) {
-		if (n > 0)
-			in = INT_MAX;
-		else
-			in = INT_MIN;
-	}
-	return (scalbnf(x, in));
+	return (scalbnf(x, (n > NMAX) ? NMAX : (n < NMIN) ? NMIN : (int)n));
 }
 
 long double
-scalblnl (long double x, long n)
+scalblnl(long double x, long n)
 {
-	int in;
 
-	in = (int)n;
-	if (in != n) {
-		if (n > 0)
-			in = INT_MAX;
-		else
-			in = INT_MIN;
-	}
-	return (scalbnl(x, (int)n));
+	return (scalbnl(x, (n > NMAX) ? NMAX : (n < NMIN) ? NMIN : (int)n));
 }
diff --git a/libm/x86/lrint.S b/libm/x86/lrint.S
new file mode 100644
index 0000000..48d71dd
--- /dev/null
+++ b/libm/x86/lrint.S
@@ -0,0 +1,36 @@
+/*
+Copyright (c) 2014, Intel Corporation
+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 Intel Corporation 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 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 <private/bionic_asm.h>
+
+ENTRY(lrint)
+  // LP32 sizeof(long) == 4.
+  movsd     0x4(%esp),%xmm0
+  cvtsd2si  %xmm0, %eax
+  ret
+END(lrint)
+
+// LP32 sizeof(long double) == sizeof(double).
+ALIAS_SYMBOL(lrintl, lrint);
diff --git a/libm/x86/lrintf.S b/libm/x86/lrintf.S
new file mode 100644
index 0000000..bc8fcb3
--- /dev/null
+++ b/libm/x86/lrintf.S
@@ -0,0 +1,33 @@
+/*
+Copyright (c) 2014, Intel Corporation
+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 Intel Corporation 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 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 <private/bionic_asm.h>
+
+ENTRY(lrintf)
+  // LP32 sizeof(long) == 4.
+  movss     0x4(%esp),%xmm0
+  cvtss2si  %xmm0, %eax
+  ret
+END(lrintf)
diff --git a/libm/x86/rint.S b/libm/x86/rint.S
new file mode 100644
index 0000000..85635f2
--- /dev/null
+++ b/libm/x86/rint.S
@@ -0,0 +1,39 @@
+/*
+Copyright (c) 2014, Intel Corporation
+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 Intel Corporation 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 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 <private/bionic_asm.h>
+
+ENTRY(rint)
+  subl    $12,%esp
+  movsd   16(%esp),%xmm0
+  roundsd $4,%xmm0,%xmm0
+  movsd   %xmm0,(%esp)
+  fldl    (%esp)
+  addl    $12,%esp
+  ret
+END(rint)
+
+// LP32 sizeof(long double) == sizeof(double).
+ALIAS_SYMBOL(rintl, rint);
diff --git a/libm/x86/rintf.S b/libm/x86/rintf.S
new file mode 100644
index 0000000..9f82400
--- /dev/null
+++ b/libm/x86/rintf.S
@@ -0,0 +1,36 @@
+/*
+Copyright (c) 2014, Intel Corporation
+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 Intel Corporation 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 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 <private/bionic_asm.h>
+
+ENTRY(rintf)
+  subl    $12,%esp
+  movss   16(%esp),%xmm0
+  roundss $4,%xmm0,%xmm0
+  movss   %xmm0,(%esp)
+  flds    (%esp)
+  add     $12,%esp
+  ret
+END(rintf)
diff --git a/libm/x86_64/lrint.S b/libm/x86_64/lrint.S
new file mode 100644
index 0000000..f809a1f
--- /dev/null
+++ b/libm/x86_64/lrint.S
@@ -0,0 +1,35 @@
+/*
+Copyright (c) 2014, Intel Corporation
+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 Intel Corporation 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 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 <private/bionic_asm.h>
+
+ENTRY(lrint)
+  // LP64 sizeof(long) == 8.
+  cvtsd2si  %xmm0, %rax
+  ret
+END(lrint)
+
+// LP64 sizeof(long long) == sizeof(long).
+ALIAS_SYMBOL(llrint, lrint);
diff --git a/libm/x86_64/lrintf.S b/libm/x86_64/lrintf.S
new file mode 100644
index 0000000..a661cbc
--- /dev/null
+++ b/libm/x86_64/lrintf.S
@@ -0,0 +1,35 @@
+/*
+Copyright (c) 2014, Intel Corporation
+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 Intel Corporation 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 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 <private/bionic_asm.h>
+
+ENTRY(lrintf)
+  // LP64 sizeof(long) == 8.
+  cvtss2si  %xmm0, %rax
+  ret
+END(lrintf)
+
+// LP64 sizeof(long long) == sizeof(long).
+ALIAS_SYMBOL(llrintf, lrintf);
diff --git a/libm/x86_64/rint.S b/libm/x86_64/rint.S
new file mode 100644
index 0000000..098fdc5
--- /dev/null
+++ b/libm/x86_64/rint.S
@@ -0,0 +1,31 @@
+/*
+Copyright (c) 2014, Intel Corporation
+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 Intel Corporation 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 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 <private/bionic_asm.h>
+
+ENTRY(rint)
+  roundsd $0x4,%xmm0,%xmm0
+  retq
+END(rint)
diff --git a/libm/x86_64/rintf.S b/libm/x86_64/rintf.S
new file mode 100644
index 0000000..09f5e9c
--- /dev/null
+++ b/libm/x86_64/rintf.S
@@ -0,0 +1,31 @@
+/*
+Copyright (c) 2014, Intel Corporation
+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 Intel Corporation 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 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 <private/bionic_asm.h>
+
+ENTRY(rintf)
+  roundss $0x4,%xmm0,%xmm0
+  retq
+END(rintf)
diff --git a/linker/Android.mk b/linker/Android.mk
index 7a9b5d9..4a4ca5c 100644
--- a/linker/Android.mk
+++ b/linker/Android.mk
@@ -2,16 +2,22 @@
 
 include $(CLEAR_VARS)
 
-LOCAL_SRC_FILES:= \
+LOCAL_CLANG := true
+
+LOCAL_SRC_FILES := \
     debugger.cpp \
     dlfcn.cpp \
     linker.cpp \
     linker_allocator.cpp \
-    linker_sdk_versions.cpp \
     linker_block_allocator.cpp \
+    linker_dlwarning.cpp \
+    linker_gdb_support.cpp \
     linker_libc_support.c \
+    linker_mapped_file_fragment.cpp \
     linker_memory.cpp \
     linker_phdr.cpp \
+    linker_sdk_versions.cpp \
+    linker_utils.cpp \
     rt.cpp \
 
 LOCAL_SRC_FILES_arm     := arch/arm/begin.S
@@ -35,14 +41,13 @@
     -fvisibility=hidden \
     -Wall -Wextra -Wunused -Werror \
 
-LOCAL_CFLAGS_arm += -D__work_around_b_19059885__
-LOCAL_CFLAGS_x86 += -D__work_around_b_19059885__
+LOCAL_CFLAGS_arm += -D__work_around_b_24465209__
+LOCAL_CFLAGS_x86 += -D__work_around_b_24465209__
 
 LOCAL_CONLYFLAGS += \
     -std=gnu99 \
 
 LOCAL_CPPFLAGS += \
-    -std=gnu++11 \
     -Wold-style-cast \
 
 ifeq ($(TARGET_IS_64_BIT),true)
@@ -60,7 +65,7 @@
 
 LOCAL_ADDITIONAL_DEPENDENCIES := $(LOCAL_PATH)/Android.mk
 
-LOCAL_STATIC_LIBRARIES := libc_nomalloc libziparchive libutils libz liblog
+LOCAL_STATIC_LIBRARIES := libc_nomalloc libziparchive libutils libbase libz liblog
 
 LOCAL_FORCE_STATIC_EXECUTABLE := true
 
@@ -83,4 +88,20 @@
 
 include $(BUILD_EXECUTABLE)
 
+
+define add-linker-symlink
+$(eval _from := $(TARGET_OUT)/bin/$(1))
+$(eval _to:=$(2))
+$(_from): $(LOCAL_MODULE_MAKEFILE)
+	@echo "Symlink: $$@ -> $(_to)"
+	@mkdir -p $$(dir $$@)
+	@rm -rf $$@
+	$(hide) ln -sf $(_to) $$@
+endef
+
+$(eval $(call add-linker-symlink,linker_asan,linker))
+ifeq ($(TARGET_IS_64_BIT),true)
+$(eval $(call add-linker-symlink,linker_asan64,linker64))
+endif
+
 include $(call first-makefiles-under,$(LOCAL_PATH))
diff --git a/linker/NOTICE b/linker/NOTICE
index 139b26e..2c70ab8 100644
--- a/linker/NOTICE
+++ b/linker/NOTICE
@@ -42,34 +42,6 @@
 
 -------------------------------------------------------------------
 
-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.
-
--------------------------------------------------------------------
-
 Copyright (C) 2012 The Android Open Source Project
 All rights reserved.
 
diff --git a/linker/debugger.cpp b/linker/debugger.cpp
index 46c97af..d4c7928 100644
--- a/linker/debugger.cpp
+++ b/linker/debugger.cpp
@@ -27,6 +27,7 @@
  */
 
 #include "linker.h"
+#include "linker_gdb_support.h"
 
 #include <errno.h>
 #include <inttypes.h>
@@ -38,6 +39,7 @@
 #include <sys/mman.h>
 #include <sys/prctl.h>
 #include <sys/socket.h>
+#include <sys/syscall.h>
 #include <sys/un.h>
 #include <unistd.h>
 
@@ -60,7 +62,9 @@
   DEBUGGER_ACTION_DUMP_BACKTRACE,
 };
 
-/* message sent over the socket */
+// Message sent over the socket.
+// NOTE: Any changes to this structure must also be reflected in
+//       system/core/include/cutils/debugger.h.
 struct __attribute__((packed)) debugger_msg_t {
   int32_t action;
   pid_t tid;
@@ -135,9 +139,6 @@
       signal_name = "SIGILL";
       has_address = true;
       break;
-    case SIGPIPE:
-      signal_name = "SIGPIPE";
-      break;
     case SIGSEGV:
       signal_name = "SIGSEGV";
       has_address = true;
@@ -269,27 +270,32 @@
 
   send_debuggerd_packet(info);
 
-  // Remove our net so we fault for real when we return.
+  // We need to return from the signal handler so that debuggerd can dump the
+  // thread that crashed, but returning here does not guarantee that the signal
+  // will be thrown again, even for SIGSEGV and friends, since the signal could
+  // have been sent manually. Resend the signal with rt_tgsigqueueinfo(2) to
+  // preserve the SA_SIGINFO contents.
   signal(signal_number, SIG_DFL);
 
-  // These signals are not re-thrown when we resume.  This means that
-  // crashing due to (say) SIGPIPE doesn't work the way you'd expect it
-  // to.  We work around this by throwing them manually.  We don't want
-  // to do this for *all* signals because it'll screw up the si_addr for
-  // faults like SIGSEGV. It does screw up the si_code, which is why we
-  // passed that to debuggerd above.
-  switch (signal_number) {
-    case SIGABRT:
-    case SIGFPE:
-    case SIGPIPE:
-#if defined(SIGSTKFLT)
-    case SIGSTKFLT:
-#endif
-    case SIGTRAP:
-      tgkill(getpid(), gettid(), signal_number);
-      break;
-    default:    // SIGILL, SIGBUS, SIGSEGV
-      break;
+  struct siginfo si;
+  if (!info) {
+    memset(&si, 0, sizeof(si));
+    si.si_code = SI_USER;
+    si.si_pid = getpid();
+    si.si_uid = getuid();
+    info = &si;
+  } else if (info->si_code >= 0 || info->si_code == SI_TKILL) {
+    // rt_tgsigqueueinfo(2)'s documentation appears to be incorrect on kernels
+    // that contain commit 66dd34a (3.9+). The manpage claims to only allow
+    // negative si_code values that are not SI_TKILL, but 66dd34a changed the
+    // check to allow all si_code values in calls coming from inside the house.
+  }
+
+  int rc = syscall(SYS_rt_tgsigqueueinfo, getpid(), gettid(), signal_number, info);
+  if (rc != 0) {
+    __libc_format_log(ANDROID_LOG_FATAL, "libc", "failed to resend signal during crash: %s",
+                      strerror(errno));
+    _exit(0);
   }
 }
 
@@ -307,7 +313,6 @@
   sigaction(SIGBUS, &action, nullptr);
   sigaction(SIGFPE, &action, nullptr);
   sigaction(SIGILL, &action, nullptr);
-  sigaction(SIGPIPE, &action, nullptr);
   sigaction(SIGSEGV, &action, nullptr);
 #if defined(SIGSTKFLT)
   sigaction(SIGSTKFLT, &action, nullptr);
diff --git a/linker/dlfcn.cpp b/linker/dlfcn.cpp
index ef454ab..12dd039 100644
--- a/linker/dlfcn.cpp
+++ b/linker/dlfcn.cpp
@@ -15,13 +15,12 @@
  */
 
 #include "linker.h"
+#include "linker_dlwarning.h"
 
-#include <dlfcn.h>
 #include <pthread.h>
 #include <stdio.h>
 #include <stdlib.h>
 #include <string.h>
-#include <android/dlext.h>
 #include <android/api-level.h>
 
 #include <bionic/pthread_internal.h>
@@ -67,9 +66,10 @@
   do_android_update_LD_LIBRARY_PATH(ld_library_path);
 }
 
-static void* dlopen_ext(const char* filename, int flags, const android_dlextinfo* extinfo) {
+static void* dlopen_ext(const char* filename, int flags,
+                        const android_dlextinfo* extinfo, void* caller_addr) {
   ScopedPthreadMutexLocker locker(&g_dl_mutex);
-  soinfo* result = do_dlopen(filename, flags, extinfo);
+  void* result = do_dlopen(filename, flags, extinfo, caller_addr);
   if (result == nullptr) {
     __bionic_format_dlerror("dlopen failed", linker_get_error_buffer());
     return nullptr;
@@ -78,84 +78,48 @@
 }
 
 void* android_dlopen_ext(const char* filename, int flags, const android_dlextinfo* extinfo) {
-  return dlopen_ext(filename, flags, extinfo);
+  void* caller_addr = __builtin_return_address(0);
+  return dlopen_ext(filename, flags, extinfo, caller_addr);
 }
 
 void* dlopen(const char* filename, int flags) {
-  return dlopen_ext(filename, flags, nullptr);
+  void* caller_addr = __builtin_return_address(0);
+  return dlopen_ext(filename, flags, nullptr, caller_addr);
+}
+
+void* dlsym_impl(void* handle, const char* symbol, const char* version, void* caller_addr) {
+  ScopedPthreadMutexLocker locker(&g_dl_mutex);
+  void* result;
+  if (!do_dlsym(handle, symbol, version, caller_addr, &result)) {
+    __bionic_format_dlerror(linker_get_error_buffer(), nullptr);
+    return nullptr;
+  }
+
+  return result;
 }
 
 void* dlsym(void* handle, const char* symbol) {
-  ScopedPthreadMutexLocker locker(&g_dl_mutex);
-
-#if !defined(__LP64__)
-  if (handle == nullptr) {
-    __bionic_format_dlerror("dlsym library handle is null", nullptr);
-    return nullptr;
-  }
-#endif
-
-  if (symbol == nullptr) {
-    __bionic_format_dlerror("dlsym symbol name is null", nullptr);
-    return nullptr;
-  }
-
-  soinfo* found = nullptr;
-  const ElfW(Sym)* sym = nullptr;
   void* caller_addr = __builtin_return_address(0);
-  soinfo* caller = find_containing_library(caller_addr);
+  return dlsym_impl(handle, symbol, nullptr, caller_addr);
+}
 
-  if (handle == RTLD_DEFAULT || handle == RTLD_NEXT) {
-    sym = dlsym_linear_lookup(symbol, &found, caller, handle);
-  } else {
-    sym = dlsym_handle_lookup(reinterpret_cast<soinfo*>(handle), &found, symbol);
-  }
-
-  if (sym != nullptr) {
-    unsigned bind = ELF_ST_BIND(sym->st_info);
-
-    if ((bind == STB_GLOBAL || bind == STB_WEAK) && sym->st_shndx != 0) {
-      return reinterpret_cast<void*>(found->resolve_symbol_address(sym));
-    }
-
-    __bionic_format_dlerror("symbol found but not global", symbol);
-    return nullptr;
-  } else {
-    __bionic_format_dlerror("undefined symbol", symbol);
-    return nullptr;
-  }
+void* dlvsym(void* handle, const char* symbol, const char* version) {
+  void* caller_addr = __builtin_return_address(0);
+  return dlsym_impl(handle, symbol, version, caller_addr);
 }
 
 int dladdr(const void* addr, Dl_info* info) {
   ScopedPthreadMutexLocker locker(&g_dl_mutex);
-
-  // Determine if this address can be found in any library currently mapped.
-  soinfo* si = find_containing_library(addr);
-  if (si == nullptr) {
-    return 0;
-  }
-
-  memset(info, 0, sizeof(Dl_info));
-
-  info->dli_fname = si->get_realpath();
-  // Address at which the shared object is loaded.
-  info->dli_fbase = reinterpret_cast<void*>(si->base);
-
-  // Determine if any symbol in the library contains the specified address.
-  ElfW(Sym)* sym = si->find_symbol_by_address(addr);
-  if (sym != nullptr) {
-    info->dli_sname = si->get_string(sym->st_name);
-    info->dli_saddr = reinterpret_cast<void*>(si->resolve_symbol_address(sym));
-  }
-
-  return 1;
+  return do_dladdr(addr, info);
 }
 
 int dlclose(void* handle) {
   ScopedPthreadMutexLocker locker(&g_dl_mutex);
-  do_dlclose(reinterpret_cast<soinfo*>(handle));
-  // dlclose has no defined errors.
-  return 0;
+  int result = do_dlclose(handle);
+  if (result != 0) {
+    __bionic_format_dlerror("dlclose failed", linker_get_error_buffer());
+  }
+  return result;
 }
 
 int dl_iterate_phdr(int (*cb)(dl_phdr_info* info, size_t size, void* data), void* data) {
@@ -173,6 +137,46 @@
   return get_application_target_sdk_version();
 }
 
+void android_dlwarning(void* obj, void (*f)(void*, const char*)) {
+  ScopedPthreadMutexLocker locker(&g_dl_mutex);
+  get_dlwarning(obj, f);
+}
+
+bool android_init_namespaces(const char* public_ns_sonames,
+                             const char* anon_ns_library_path) {
+  ScopedPthreadMutexLocker locker(&g_dl_mutex);
+  bool success = init_namespaces(public_ns_sonames, anon_ns_library_path);
+  if (!success) {
+    __bionic_format_dlerror("android_init_namespaces failed", linker_get_error_buffer());
+  }
+
+  return success;
+}
+
+android_namespace_t* android_create_namespace(const char* name,
+                                              const char* ld_library_path,
+                                              const char* default_library_path,
+                                              uint64_t type,
+                                              const char* permitted_when_isolated_path,
+                                              android_namespace_t* parent_namespace) {
+  void* caller_addr = __builtin_return_address(0);
+  ScopedPthreadMutexLocker locker(&g_dl_mutex);
+
+  android_namespace_t* result = create_namespace(caller_addr,
+                                                 name,
+                                                 ld_library_path,
+                                                 default_library_path,
+                                                 type,
+                                                 permitted_when_isolated_path,
+                                                 parent_namespace);
+
+  if (result == nullptr) {
+    __bionic_format_dlerror("android_create_namespace failed", linker_get_error_buffer());
+  }
+
+  return result;
+}
+
 // name_offset: starting index of the name in libdl_info.strtab
 #define ELF32_SYM_INITIALIZER(name_offset, value, shndx) \
     { name_offset, \
@@ -199,11 +203,11 @@
   // 00000000001 1111111112222222222 3333333333444444444455555555556666666666777 777777788888888889999999999
   // 01234567890 1234567890123456789 0123456789012345678901234567890123456789012 345678901234567890123456789
     "erate_phdr\0android_dlopen_ext\0android_set_application_target_sdk_version\0android_get_application_tar"
-  // 0000000000111111
-  // 0123456789012345
-    "get_sdk_version\0"
+  // 0000000000111111 111122222222223333333333 4444444444555555555566666 6666677 777777778888888888
+  // 0123456789012345 678901234567890123456789 0123456789012345678901234 5678901 234567890123456789
+    "get_sdk_version\0android_init_namespaces\0android_create_namespace\0dlvsym\0android_dlwarning\0"
 #if defined(__arm__)
-  // 216
+  // 290
     "dl_unwind_find_exidx\0"
 #endif
     ;
@@ -225,8 +229,12 @@
   ELFW(SYM_INITIALIZER)(111, &android_dlopen_ext, 1),
   ELFW(SYM_INITIALIZER)(130, &android_set_application_target_sdk_version, 1),
   ELFW(SYM_INITIALIZER)(173, &android_get_application_target_sdk_version, 1),
+  ELFW(SYM_INITIALIZER)(216, &android_init_namespaces, 1),
+  ELFW(SYM_INITIALIZER)(240, &android_create_namespace, 1),
+  ELFW(SYM_INITIALIZER)(265, &dlvsym, 1),
+  ELFW(SYM_INITIALIZER)(272, &android_dlwarning, 1),
 #if defined(__arm__)
-  ELFW(SYM_INITIALIZER)(216, &dl_unwind_find_exidx, 1),
+  ELFW(SYM_INITIALIZER)(290, &dl_unwind_find_exidx, 1),
 #endif
 };
 
@@ -243,18 +251,20 @@
 // Note that adding any new symbols here requires stubbing them out in libdl.
 static unsigned g_libdl_buckets[1] = { 1 };
 #if defined(__arm__)
-static unsigned g_libdl_chains[] = { 0, 2, 3, 4, 5, 6, 7, 8, 9, 10, 11, 12, 0 };
+static unsigned g_libdl_chains[] = { 0, 2, 3, 4, 5, 6, 7, 8, 9, 10, 11, 12, 13, 14, 15, 16, 0 };
 #else
-static unsigned g_libdl_chains[] = { 0, 2, 3, 4, 5, 6, 7, 8, 9, 10, 11, 0 };
+static unsigned g_libdl_chains[] = { 0, 2, 3, 4, 5, 6, 7, 8, 9, 10, 11, 12, 13, 14, 15, 0 };
 #endif
 
 static uint8_t __libdl_info_buf[sizeof(soinfo)] __attribute__((aligned(8)));
 static soinfo* __libdl_info = nullptr;
 
+extern android_namespace_t g_default_namespace;
+
 // This is used by the dynamic linker. Every process gets these symbols for free.
 soinfo* get_libdl_info() {
   if (__libdl_info == nullptr) {
-    __libdl_info = new (__libdl_info_buf) soinfo("libdl.so", nullptr, 0, RTLD_GLOBAL);
+    __libdl_info = new (__libdl_info_buf) soinfo(&g_default_namespace, "libdl.so", nullptr, 0, RTLD_GLOBAL);
     __libdl_info->flags_ |= FLAG_LINKED;
     __libdl_info->strtab_ = ANDROID_LIBDL_STRTAB;
     __libdl_info->symtab_ = g_libdl_symtab;
@@ -267,7 +277,8 @@
     __libdl_info->local_group_root_ = __libdl_info;
     __libdl_info->soname_ = "libdl.so";
     __libdl_info->target_sdk_version_ = __ANDROID_API__;
-#if defined(__arm__)
+    __libdl_info->generate_handle();
+#if defined(__work_around_b_24465209__)
     strlcpy(__libdl_info->old_name_, __libdl_info->soname_, sizeof(__libdl_info->old_name_));
 #endif
   }
diff --git a/linker/linked_list.h b/linker/linked_list.h
index 8003dbf..092e831 100644
--- a/linker/linked_list.h
+++ b/linker/linked_list.h
@@ -25,12 +25,49 @@
   T* element;
 };
 
+// ForwardInputIterator
+template<typename T>
+class LinkedListIterator {
+ public:
+  LinkedListIterator() : entry_(nullptr) {}
+  LinkedListIterator(const LinkedListIterator<T>& that) : entry_(that.entry_) {}
+  explicit LinkedListIterator(LinkedListEntry<T>* entry) : entry_(entry) {}
+
+  LinkedListIterator<T>& operator=(const LinkedListIterator<T>& that) {
+    entry_ = that.entry_;
+    return *this;
+  }
+
+  LinkedListIterator<T>& operator++() {
+    entry_ = entry_->next;
+    return *this;
+  }
+
+  T* const operator*() {
+    return entry_->element;
+  }
+
+  bool operator==(const LinkedListIterator<T>& that) const {
+    return entry_ == that.entry_;
+  }
+
+  bool operator!=(const LinkedListIterator<T>& that) const {
+    return entry_ != that.entry_;
+  }
+
+ private:
+  LinkedListEntry<T> *entry_;
+};
+
 /*
  * Represents linked list of objects of type T
  */
 template<typename T, typename Allocator>
 class LinkedList {
  public:
+  typedef LinkedListIterator<T> iterator;
+  typedef T* value_type;
+
   LinkedList() : head_(nullptr), tail_(nullptr) {}
   ~LinkedList() {
     clear();
@@ -127,7 +164,13 @@
         } else {
           p->next = next;
         }
+
+        if (tail_ == e) {
+          tail_ = p;
+        }
+
         Allocator::free(e);
+
         e = next;
       } else {
         p = e;
@@ -147,6 +190,24 @@
     return nullptr;
   }
 
+  iterator begin() const {
+    return iterator(head_);
+  }
+
+  iterator end() const {
+    return iterator(nullptr);
+  }
+
+  iterator find(T* value) const {
+    for (LinkedListEntry<T>* e = head_; e != nullptr; e = e->next) {
+      if (e->element == value) {
+        return iterator(e);
+      }
+    }
+
+    return end();
+  }
+
   size_t copy_to_array(T* array[], size_t array_length) const {
     size_t sz = 0;
     for (LinkedListEntry<T>* e = head_; sz < array_length && e != nullptr; e = e->next) {
diff --git a/linker/linker.cpp b/linker/linker.cpp
index d3ac1d0..39aa2ca 100644
--- a/linker/linker.cpp
+++ b/linker/linker.cpp
@@ -27,7 +27,6 @@
  */
 
 #include <android/api-level.h>
-#include <dlfcn.h>
 #include <errno.h>
 #include <fcntl.h>
 #include <inttypes.h>
@@ -37,67 +36,241 @@
 #include <string.h>
 #include <sys/mman.h>
 #include <sys/param.h>
-#include <sys/prctl.h>
 #include <unistd.h>
 
 #include <new>
 #include <string>
+#include <unordered_map>
 #include <vector>
 
 // Private C library headers.
+#include "private/bionic_globals.h"
 #include "private/bionic_tls.h"
 #include "private/KernelArgumentBlock.h"
 #include "private/ScopedPthreadMutexLocker.h"
 #include "private/ScopeGuard.h"
-#include "private/UniquePtr.h"
 
 #include "linker.h"
 #include "linker_block_allocator.h"
+#include "linker_gdb_support.h"
 #include "linker_debug.h"
+#include "linker_dlwarning.h"
 #include "linker_sleb128.h"
 #include "linker_phdr.h"
 #include "linker_relocs.h"
 #include "linker_reloc_iterators.h"
+#include "linker_utils.h"
+
+#include "android-base/strings.h"
 #include "ziparchive/zip_archive.h"
 
+extern void __libc_init_globals(KernelArgumentBlock&);
 extern void __libc_init_AT_SECURE(KernelArgumentBlock&);
 
+extern "C" void _start();
+
 // Override macros to use C++ style casts.
 #undef ELF_ST_TYPE
 #define ELF_ST_TYPE(x) (static_cast<uint32_t>(x) & 0xf)
 
+struct android_namespace_t {
+ public:
+  android_namespace_t() : name_(nullptr), is_isolated_(false) {}
+
+  const char* get_name() const { return name_; }
+  void set_name(const char* name) { name_ = name; }
+
+  bool is_isolated() const { return is_isolated_; }
+  void set_isolated(bool isolated) { is_isolated_ = isolated; }
+
+  const std::vector<std::string>& get_ld_library_paths() const {
+    return ld_library_paths_;
+  }
+  void set_ld_library_paths(std::vector<std::string>&& library_paths) {
+    ld_library_paths_ = library_paths;
+  }
+
+  const std::vector<std::string>& get_default_library_paths() const {
+    return default_library_paths_;
+  }
+  void set_default_library_paths(std::vector<std::string>&& library_paths) {
+    default_library_paths_ = library_paths;
+  }
+
+  const std::vector<std::string>& get_permitted_paths() const {
+    return permitted_paths_;
+  }
+  void set_permitted_paths(std::vector<std::string>&& permitted_paths) {
+    permitted_paths_ = permitted_paths;
+  }
+
+  void add_soinfo(soinfo* si) {
+    soinfo_list_.push_back(si);
+  }
+
+  void add_soinfos(const soinfo::soinfo_list_t& soinfos) {
+    for (auto si : soinfos) {
+      add_soinfo(si);
+      si->add_secondary_namespace(this);
+    }
+  }
+
+  void remove_soinfo(soinfo* si) {
+    soinfo_list_.remove_if([&](soinfo* candidate) {
+      return si == candidate;
+    });
+  }
+
+  const soinfo::soinfo_list_t& soinfo_list() const { return soinfo_list_; }
+
+  // For isolated namespaces - checks if the file is on the search path;
+  // always returns true for not isolated namespace.
+  bool is_accessible(const std::string& path);
+
+ private:
+  const char* name_;
+  bool is_isolated_;
+  std::vector<std::string> ld_library_paths_;
+  std::vector<std::string> default_library_paths_;
+  std::vector<std::string> permitted_paths_;
+  soinfo::soinfo_list_t soinfo_list_;
+
+  DISALLOW_COPY_AND_ASSIGN(android_namespace_t);
+};
+
+android_namespace_t g_default_namespace;
+
+static std::unordered_map<uintptr_t, soinfo*> g_soinfo_handles_map;
+static android_namespace_t* g_anonymous_namespace = &g_default_namespace;
+
 static ElfW(Addr) get_elf_exec_load_bias(const ElfW(Ehdr)* elf);
 
 static LinkerTypeAllocator<soinfo> g_soinfo_allocator;
 static LinkerTypeAllocator<LinkedListEntry<soinfo>> g_soinfo_links_allocator;
 
+static LinkerTypeAllocator<android_namespace_t> g_namespace_allocator;
+static LinkerTypeAllocator<LinkedListEntry<android_namespace_t>> g_namespace_list_allocator;
+
 static soinfo* solist;
 static soinfo* sonext;
 static soinfo* somain; // main process, always the one after libdl_info
 
 static const char* const kDefaultLdPaths[] = {
 #if defined(__LP64__)
-  "/vendor/lib64",
   "/system/lib64",
+  "/vendor/lib64",
 #else
-  "/vendor/lib",
   "/system/lib",
+  "/vendor/lib",
 #endif
   nullptr
 };
 
+static const char* const kAsanDefaultLdPaths[] = {
+#if defined(__LP64__)
+  "/data/lib64",
+  "/system/lib64",
+  "/data/vendor/lib64",
+  "/vendor/lib64",
+#else
+  "/data/lib",
+  "/system/lib",
+  "/data/vendor/lib",
+  "/vendor/lib",
+#endif
+  nullptr
+};
+
+static bool is_system_library(const std::string& realpath) {
+  for (const auto& dir : g_default_namespace.get_default_library_paths()) {
+    if (file_is_in_dir(realpath, dir)) {
+      return true;
+    }
+  }
+  return false;
+}
+
+#if defined(__LP64__)
+static const char* const kSystemLibDir = "/system/lib64";
+#else
+static const char* const kSystemLibDir = "/system/lib";
+#endif
+
+static std::string dirname(const char *path);
+
+// TODO(dimitry): The grey-list is a workaround for http://b/26394120 ---
+// gradually remove libraries from this list until it is gone.
+static bool is_greylisted(const char* name, const soinfo* needed_by) {
+  static const char* const kLibraryGreyList[] = {
+    "libandroid_runtime.so",
+    "libbinder.so",
+    "libcrypto.so",
+    "libcutils.so",
+    "libexpat.so",
+    "libgui.so",
+    "libmedia.so",
+    "libnativehelper.so",
+    "libskia.so",
+    "libssl.so",
+    "libstagefright.so",
+    "libsqlite.so",
+    "libui.so",
+    "libutils.so",
+    "libvorbisidec.so",
+    nullptr
+  };
+
+  // limit greylisting to apps targeting sdk version 23 and below
+  if (get_application_target_sdk_version() > 23) {
+    return false;
+  }
+
+  // if the library needed by a system library - implicitly assume it
+  // is greylisted
+
+  if (needed_by != nullptr && is_system_library(needed_by->get_realpath())) {
+    return true;
+  }
+
+  // if this is an absolute path - make sure it points to /system/lib(64)
+  if (name[0] == '/' && dirname(name) == kSystemLibDir) {
+    // and reduce the path to basename
+    name = basename(name);
+  }
+
+  for (size_t i = 0; kLibraryGreyList[i] != nullptr; ++i) {
+    if (strcmp(name, kLibraryGreyList[i]) == 0) {
+      return true;
+    }
+  }
+
+  return false;
+}
+// END OF WORKAROUND
+
 static const ElfW(Versym) kVersymNotNeeded = 0;
 static const ElfW(Versym) kVersymGlobal = 1;
 
-static std::vector<std::string> g_ld_library_paths;
+static const char* const* g_default_ld_paths;
 static std::vector<std::string> g_ld_preload_names;
 
 static std::vector<soinfo*> g_ld_preloads;
 
+static bool g_public_namespace_initialized;
+static soinfo::soinfo_list_t g_public_namespace;
+
 __LIBC_HIDDEN__ int g_ld_debug_verbosity;
 
 __LIBC_HIDDEN__ abort_msg_t* g_abort_message = nullptr; // For debuggerd.
 
+static std::string dirname(const char *path) {
+  const char* last_slash = strrchr(path, '/');
+  if (last_slash == path) return "/";
+  else if (last_slash == nullptr) return ".";
+  else
+    return std::string(path, last_slash - path);
+}
+
 #if STATS
 struct linker_stats_t {
   int count[kRelocMax];
@@ -127,95 +300,53 @@
   return sizeof(__linker_dl_err_buf);
 }
 
-// This function is an empty stub where GDB locates a breakpoint to get notified
-// about linker activity.
-extern "C"
-void __attribute__((noinline)) __attribute__((visibility("default"))) rtld_db_dlactivity();
+static void notify_gdb_of_load(soinfo* info) {
+  if (info->is_linker() || info->is_main_executable()) {
+    // gdb already knows about the linker and the main executable.
+    return;
+  }
 
-static pthread_mutex_t g__r_debug_mutex = PTHREAD_MUTEX_INITIALIZER;
-static r_debug _r_debug =
-    {1, nullptr, reinterpret_cast<uintptr_t>(&rtld_db_dlactivity), r_debug::RT_CONSISTENT, 0};
-
-static link_map* r_debug_tail = 0;
-
-static void insert_soinfo_into_debug_map(soinfo* info) {
-  // Copy the necessary fields into the debug structure.
   link_map* map = &(info->link_map_head);
+
   map->l_addr = info->load_bias;
   // link_map l_name field is not const.
   map->l_name = const_cast<char*>(info->get_realpath());
   map->l_ld = info->dynamic;
 
-  // Stick the new library at the end of the list.
-  // gdb tends to care more about libc than it does
-  // about leaf libraries, and ordering it this way
-  // reduces the back-and-forth over the wire.
-  if (r_debug_tail) {
-    r_debug_tail->l_next = map;
-    map->l_prev = r_debug_tail;
-    map->l_next = 0;
-  } else {
-    _r_debug.r_map = map;
-    map->l_prev = 0;
-    map->l_next = 0;
-  }
-  r_debug_tail = map;
-}
+  CHECK(map->l_name != nullptr);
+  CHECK(map->l_name[0] != '\0');
 
-static void remove_soinfo_from_debug_map(soinfo* info) {
-  link_map* map = &(info->link_map_head);
-
-  if (r_debug_tail == map) {
-    r_debug_tail = map->l_prev;
-  }
-
-  if (map->l_prev) {
-    map->l_prev->l_next = map->l_next;
-  }
-  if (map->l_next) {
-    map->l_next->l_prev = map->l_prev;
-  }
-}
-
-static void notify_gdb_of_load(soinfo* info) {
-  if (info->is_main_executable()) {
-    // GDB already knows about the main executable
-    return;
-  }
-
-  ScopedPthreadMutexLocker locker(&g__r_debug_mutex);
-
-  _r_debug.r_state = r_debug::RT_ADD;
-  rtld_db_dlactivity();
-
-  insert_soinfo_into_debug_map(info);
-
-  _r_debug.r_state = r_debug::RT_CONSISTENT;
-  rtld_db_dlactivity();
+  notify_gdb_of_load(map);
 }
 
 static void notify_gdb_of_unload(soinfo* info) {
-  if (info->is_main_executable()) {
-    // GDB already knows about the main executable
-    return;
-  }
-
-  ScopedPthreadMutexLocker locker(&g__r_debug_mutex);
-
-  _r_debug.r_state = r_debug::RT_DELETE;
-  rtld_db_dlactivity();
-
-  remove_soinfo_from_debug_map(info);
-
-  _r_debug.r_state = r_debug::RT_CONSISTENT;
-  rtld_db_dlactivity();
+  notify_gdb_of_unload(&(info->link_map_head));
 }
 
-void notify_gdb_of_libraries() {
-  _r_debug.r_state = r_debug::RT_ADD;
-  rtld_db_dlactivity();
-  _r_debug.r_state = r_debug::RT_CONSISTENT;
-  rtld_db_dlactivity();
+bool android_namespace_t::is_accessible(const std::string& file) {
+  if (!is_isolated_) {
+    return true;
+  }
+
+  for (const auto& dir : ld_library_paths_) {
+    if (file_is_in_dir(file, dir)) {
+      return true;
+    }
+  }
+
+  for (const auto& dir : default_library_paths_) {
+    if (file_is_in_dir(file, dir)) {
+      return true;
+    }
+  }
+
+  for (const auto& dir : permitted_paths_) {
+    if (file_is_under_dir(file, dir)) {
+      return true;
+    }
+  }
+
+  return false;
 }
 
 LinkedListEntry<soinfo>* SoinfoListAllocator::alloc() {
@@ -226,18 +357,31 @@
   g_soinfo_links_allocator.free(entry);
 }
 
-static soinfo* soinfo_alloc(const char* name, struct stat* file_stat,
-                            off64_t file_offset, uint32_t rtld_flags) {
+LinkedListEntry<android_namespace_t>* NamespaceListAllocator::alloc() {
+  return g_namespace_list_allocator.alloc();
+}
+
+void NamespaceListAllocator::free(LinkedListEntry<android_namespace_t>* entry) {
+  g_namespace_list_allocator.free(entry);
+}
+
+static soinfo* soinfo_alloc(android_namespace_t* ns, const char* name,
+                            struct stat* file_stat, off64_t file_offset,
+                            uint32_t rtld_flags) {
   if (strlen(name) >= PATH_MAX) {
     DL_ERR("library name \"%s\" too long", name);
     return nullptr;
   }
 
-  soinfo* si = new (g_soinfo_allocator.alloc()) soinfo(name, file_stat, file_offset, rtld_flags);
+  soinfo* si = new (g_soinfo_allocator.alloc()) soinfo(ns, name, file_stat,
+                                                       file_offset, rtld_flags);
 
   sonext->next = si;
   sonext = si;
 
+  si->generate_handle();
+  ns->add_soinfo(si);
+
   TRACE("name %s: allocated soinfo @ %p", name, si);
   return si;
 }
@@ -248,7 +392,13 @@
   }
 
   if (si->base != 0 && si->size != 0) {
-    munmap(reinterpret_cast<void*>(si->base), si->size);
+    if (!si->is_mapped_by_caller()) {
+      munmap(reinterpret_cast<void*>(si->base), si->size);
+    } else {
+      // remap the region as PROT_NONE, MAP_ANONYMOUS | MAP_NORESERVE
+      mmap(reinterpret_cast<void*>(si->base), si->size, PROT_NONE,
+           MAP_FIXED | MAP_PRIVATE | MAP_ANONYMOUS | MAP_NORESERVE, -1, 0);
+    }
   }
 
   soinfo *prev = nullptr, *trav;
@@ -282,55 +432,132 @@
   g_soinfo_allocator.free(si);
 }
 
-static void parse_path(const char* path, const char* delimiters,
+// For every path element this function checks of it exists, and is a directory,
+// and normalizes it:
+// 1. For regular path it converts it to realpath()
+// 2. For path in a zip file it uses realpath on the zipfile
+//    normalizes entry name by calling normalize_path function.
+static void resolve_paths(std::vector<std::string>& paths,
+                          std::vector<std::string>* resolved_paths) {
+  resolved_paths->clear();
+  for (const auto& path : paths) {
+    char resolved_path[PATH_MAX];
+    const char* original_path = path.c_str();
+    if (realpath(original_path, resolved_path) != nullptr) {
+      struct stat s;
+      if (stat(resolved_path, &s) == 0) {
+        if (S_ISDIR(s.st_mode)) {
+          resolved_paths->push_back(resolved_path);
+        } else {
+          DL_WARN("Warning: \"%s\" is not a directory (excluding from path)", resolved_path);
+          continue;
+        }
+      } else {
+        DL_WARN("Warning: cannot stat file \"%s\": %s", resolved_path, strerror(errno));
+        continue;
+      }
+    } else {
+      std::string zip_path;
+      std::string entry_path;
+
+      std::string normalized_path;
+
+      if (!normalize_path(original_path, &normalized_path)) {
+        DL_WARN("Warning: unable to normalize \"%s\"", original_path);
+        continue;
+      }
+
+      if (parse_zip_path(normalized_path.c_str(), &zip_path, &entry_path)) {
+        if (realpath(zip_path.c_str(), resolved_path) == nullptr) {
+          DL_WARN("Warning: unable to resolve \"%s\": %s", zip_path.c_str(), strerror(errno));
+          continue;
+        }
+
+        resolved_paths->push_back(std::string(resolved_path) + kZipFileSeparator + entry_path);
+      }
+    }
+  }
+}
+
+static void split_path(const char* path, const char* delimiters,
                        std::vector<std::string>* paths) {
-  if (path == nullptr) {
-    return;
+  if (path != nullptr && path[0] != 0) {
+    *paths = android::base::Split(path, delimiters);
   }
+}
 
-  paths->clear();
-
-  for (const char *p = path; ; ++p) {
-    size_t len = strcspn(p, delimiters);
-    // skip empty tokens
-    if (len == 0) {
-      continue;
-    }
-
-    paths->push_back(std::string(p, len));
-    p += len;
-
-    if (*p == '\0') {
-      break;
-    }
-  }
+static void parse_path(const char* path, const char* delimiters,
+                       std::vector<std::string>* resolved_paths) {
+  std::vector<std::string> paths;
+  split_path(path, delimiters, &paths);
+  resolve_paths(paths, resolved_paths);
 }
 
 static void parse_LD_LIBRARY_PATH(const char* path) {
-  parse_path(path, ":", &g_ld_library_paths);
+  std::vector<std::string> ld_libary_paths;
+  parse_path(path, ":", &ld_libary_paths);
+  g_default_namespace.set_ld_library_paths(std::move(ld_libary_paths));
+}
+
+void soinfo::set_dt_runpath(const char* path) {
+  if (!has_min_version(3)) {
+    return;
+  }
+
+  std::vector<std::string> runpaths;
+
+  split_path(path, ":", &runpaths);
+
+  std::string origin = dirname(get_realpath());
+  // FIXME: add $LIB and $PLATFORM.
+  std::pair<std::string, std::string> substs[] = {{"ORIGIN", origin}};
+  for (auto&& s : runpaths) {
+    size_t pos = 0;
+    while (pos < s.size()) {
+      pos = s.find("$", pos);
+      if (pos == std::string::npos) break;
+      for (const auto& subst : substs) {
+        const std::string& token = subst.first;
+        const std::string& replacement = subst.second;
+        if (s.substr(pos + 1, token.size()) == token) {
+          s.replace(pos, token.size() + 1, replacement);
+          // -1 to compensate for the ++pos below.
+          pos += replacement.size() - 1;
+          break;
+        } else if (s.substr(pos + 1, token.size() + 2) == "{" + token + "}") {
+          s.replace(pos, token.size() + 3, replacement);
+          pos += replacement.size() - 1;
+          break;
+        }
+      }
+      // Skip $ in case it did not match any of the known substitutions.
+      ++pos;
+    }
+  }
+
+  resolve_paths(runpaths, &dt_runpath_);
 }
 
 static void parse_LD_PRELOAD(const char* path) {
-  // We have historically supported ':' as well as ' ' in LD_PRELOAD.
-  parse_path(path, " :", &g_ld_preload_names);
+  g_ld_preload_names.clear();
+  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(); });
+  }
 }
 
 static bool realpath_fd(int fd, std::string* realpath) {
   std::vector<char> buf(PATH_MAX), proc_self_fd(PATH_MAX);
-  snprintf(&proc_self_fd[0], proc_self_fd.size(), "/proc/self/fd/%d", fd);
-  // set DUMPABLE to 1 to access /proc/self/fd
-  int dumpable = prctl(PR_GET_DUMPABLE, 0, 0, 0, 0);
-  prctl(PR_SET_DUMPABLE, 1, 0, 0, 0);
-  auto guard = make_scope_guard([&]() {
-    // restore dumpable
-    prctl(PR_SET_DUMPABLE, dumpable, 0, 0, 0);
-  });
+  __libc_format_buffer(&proc_self_fd[0], proc_self_fd.size(), "/proc/self/fd/%d", fd);
   if (readlink(&proc_self_fd[0], &buf[0], buf.size()) == -1) {
-    PRINT("readlink('%s') failed: %s [fd=%d]", &proc_self_fd[0], strerror(errno), fd);
+    PRINT("readlink(\"%s\") failed: %s [fd=%d]", &proc_self_fd[0], strerror(errno), fd);
     return false;
   }
 
-  *realpath = std::string(&buf[0]);
+  *realpath = &buf[0];
   return true;
 }
 
@@ -507,8 +734,8 @@
       ELF_ST_BIND(s->st_info) == STB_WEAK) {
     return s->st_shndx != SHN_UNDEF;
   } else if (ELF_ST_BIND(s->st_info) != STB_LOCAL) {
-    DL_WARN("unexpected ST_BIND value: %d for '%s' in '%s'",
-        ELF_ST_BIND(s->st_info), si->get_string(s->st_name), si->get_realpath());
+    DL_WARN("unexpected ST_BIND value: %d for \"%s\" in \"%s\"",
+            ELF_ST_BIND(s->st_info), si->get_string(s->st_name), si->get_realpath());
   }
 
   return false;
@@ -640,8 +867,9 @@
   return true;
 }
 
-soinfo::soinfo(const char* realpath, const struct stat* file_stat,
-               off64_t file_offset, int rtld_flags) {
+soinfo::soinfo(android_namespace_t* ns, const char* realpath,
+               const struct stat* file_stat, off64_t file_offset,
+               int rtld_flags) {
   memset(this, 0, sizeof(*this));
 
   if (realpath != nullptr) {
@@ -658,22 +886,30 @@
   }
 
   this->rtld_flags_ = rtld_flags;
+  this->primary_namespace_ = ns;
 }
 
+soinfo::~soinfo() {
+  g_soinfo_handles_map.erase(handle_);
+}
+
+static uint32_t calculate_elf_hash(const char* name) {
+  const uint8_t* name_bytes = reinterpret_cast<const uint8_t*>(name);
+  uint32_t h = 0, g;
+
+  while (*name_bytes) {
+    h = (h << 4) + *name_bytes++;
+    g = h & 0xf0000000;
+    h ^= g;
+    h ^= g >> 24;
+  }
+
+  return h;
+}
 
 uint32_t SymbolName::elf_hash() {
   if (!has_elf_hash_) {
-    const uint8_t* name = reinterpret_cast<const uint8_t*>(name_);
-    uint32_t h = 0, g;
-
-    while (*name) {
-      h = (h << 4) + *name++;
-      g = h & 0xf0000000;
-      h ^= g;
-      h ^= g >> 24;
-    }
-
-    elf_hash_ = h;
+    elf_hash_ = calculate_elf_hash(name_);
     has_elf_hash_ = true;
   }
 
@@ -809,6 +1045,8 @@
   void protect_data(int protection) {
     g_soinfo_allocator.protect_all(protection);
     g_soinfo_links_allocator.protect_all(protection);
+    g_namespace_allocator.protect_all(protection);
+    g_namespace_list_allocator.protect_all(protection);
   }
 
   static size_t ref_count_;
@@ -851,17 +1089,17 @@
  public:
   struct deleter_t {
     void operator()(LoadTask* t) {
+      t->~LoadTask();
       TypeBasedAllocator<LoadTask>::free(t);
     }
   };
 
-  typedef UniquePtr<LoadTask, deleter_t> unique_ptr;
-
   static deleter_t deleter;
 
-  static LoadTask* create(const char* name, soinfo* needed_by) {
+  static LoadTask* create(const char* name, soinfo* needed_by,
+                          std::unordered_map<const soinfo*, ElfReader>* readers_map) {
     LoadTask* ptr = TypeBasedAllocator<LoadTask>::alloc();
-    return new (ptr) LoadTask(name, needed_by);
+    return new (ptr) LoadTask(name, needed_by, readers_map);
   }
 
   const char* get_name() const {
@@ -871,12 +1109,107 @@
   soinfo* get_needed_by() const {
     return needed_by_;
   }
+
+  soinfo* get_soinfo() const {
+    return si_;
+  }
+
+  void set_soinfo(soinfo* si) {
+    si_ = si;
+  }
+
+  off64_t get_file_offset() const {
+    return file_offset_;
+  }
+
+  void set_file_offset(off64_t offset) {
+    file_offset_ = offset;
+  }
+
+  int get_fd() const {
+    return fd_;
+  }
+
+  void set_fd(int fd, bool assume_ownership) {
+    fd_ = fd;
+    close_fd_ = assume_ownership;
+  }
+
+  const android_dlextinfo* get_extinfo() const {
+    return extinfo_;
+  }
+
+  void set_extinfo(const android_dlextinfo* extinfo) {
+    extinfo_ = extinfo;
+  }
+
+  bool is_dt_needed() const {
+    return is_dt_needed_;
+  }
+
+  void set_dt_needed(bool is_dt_needed) {
+    is_dt_needed_ = is_dt_needed;
+  }
+
+  const ElfReader& get_elf_reader() const {
+    CHECK(si_ != nullptr);
+    return (*elf_readers_map_)[si_];
+  }
+
+  ElfReader& get_elf_reader() {
+    CHECK(si_ != nullptr);
+    return (*elf_readers_map_)[si_];
+  }
+
+  std::unordered_map<const soinfo*, ElfReader>* get_readers_map() {
+    return elf_readers_map_;
+  }
+
+  bool read(const char* realpath, off64_t file_size) {
+    ElfReader& elf_reader = get_elf_reader();
+    return elf_reader.Read(realpath, fd_, file_offset_, file_size);
+  }
+
+  bool load() {
+    ElfReader& elf_reader = get_elf_reader();
+    if (!elf_reader.Load(extinfo_)) {
+      return false;
+    }
+
+    si_->base = elf_reader.load_start();
+    si_->size = elf_reader.load_size();
+    si_->set_mapped_by_caller(elf_reader.is_mapped_by_caller());
+    si_->load_bias = elf_reader.load_bias();
+    si_->phnum = elf_reader.phdr_count();
+    si_->phdr = elf_reader.loaded_phdr();
+
+    return true;
+  }
+
  private:
-  LoadTask(const char* name, soinfo* needed_by)
-    : name_(name), needed_by_(needed_by) {}
+  LoadTask(const char* name, soinfo* needed_by,
+           std::unordered_map<const soinfo*, ElfReader>* readers_map)
+    : name_(name), needed_by_(needed_by), si_(nullptr),
+      fd_(-1), close_fd_(false), file_offset_(0), elf_readers_map_(readers_map),
+      is_dt_needed_(false) {}
+
+  ~LoadTask() {
+    if (fd_ != -1 && close_fd_) {
+      close(fd_);
+    }
+  }
 
   const char* name_;
   soinfo* needed_by_;
+  soinfo* si_;
+  const android_dlextinfo* extinfo_;
+  int fd_;
+  bool close_fd_;
+  off64_t file_offset_;
+  std::unordered_map<const soinfo*, ElfReader>* elf_readers_map_;
+  // TODO(dimitry): needed by workaround for http://b/26394120 (the grey-list)
+  bool is_dt_needed_;
+  // END OF WORKAROUND
 
   DISALLOW_IMPLICIT_CONSTRUCTORS(LoadTask);
 };
@@ -888,7 +1221,7 @@
 
 typedef linked_list_t<soinfo> SoinfoLinkedList;
 typedef linked_list_t<const char> StringLinkedList;
-typedef linked_list_t<LoadTask> LoadTaskList;
+typedef std::vector<LoadTask*> LoadTaskList;
 
 
 // This function walks down the tree of soinfo dependencies
@@ -929,7 +1262,8 @@
 
 
 static const ElfW(Sym)* dlsym_handle_lookup(soinfo* root, soinfo* skip_until,
-                                            soinfo** found, SymbolName& symbol_name) {
+                                            soinfo** found, SymbolName& symbol_name,
+                                            const version_info* vi) {
   const ElfW(Sym)* result = nullptr;
   bool skip_lookup = skip_until != nullptr;
 
@@ -939,7 +1273,7 @@
       return true;
     }
 
-    if (!current_soinfo->find_symbol_by_name(symbol_name, nullptr, &result)) {
+    if (!current_soinfo->find_symbol_by_name(symbol_name, vi, &result)) {
       result = nullptr;
       return false;
     }
@@ -955,9 +1289,17 @@
   return result;
 }
 
+static const ElfW(Sym)* dlsym_linear_lookup(android_namespace_t* ns,
+                                            const char* name,
+                                            const version_info* vi,
+                                            soinfo** found,
+                                            soinfo* caller,
+                                            void* handle);
+
 // This is used by dlsym(3).  It performs symbol lookup only within the
 // specified soinfo object and its dependencies in breadth first order.
-const ElfW(Sym)* dlsym_handle_lookup(soinfo* si, soinfo** found, const char* name) {
+static const ElfW(Sym)* dlsym_handle_lookup(soinfo* si, soinfo** found,
+                                            const char* name, const version_info* vi) {
   // According to man dlopen(3) and posix docs in the case when si is handle
   // of the main executable we need to search not only in the executable and its
   // dependencies but also in all libraries loaded with RTLD_GLOBAL.
@@ -966,11 +1308,11 @@
   // libraries and they are loaded in breath-first (correct) order we can just execute
   // dlsym(RTLD_DEFAULT, ...); instead of doing two stage lookup.
   if (si == somain) {
-    return dlsym_linear_lookup(name, found, nullptr, RTLD_DEFAULT);
+    return dlsym_linear_lookup(&g_default_namespace, name, vi, found, nullptr, RTLD_DEFAULT);
   }
 
   SymbolName symbol_name(name);
-  return dlsym_handle_lookup(si, nullptr, found, symbol_name);
+  return dlsym_handle_lookup(si, nullptr, found, symbol_name, vi);
 }
 
 /* This is used by dlsym(3) to performs a global symbol lookup. If the
@@ -978,24 +1320,30 @@
    beginning of the global solist. Otherwise the search starts at the
    specified soinfo (for RTLD_NEXT).
  */
-const ElfW(Sym)* dlsym_linear_lookup(const char* name,
-                                     soinfo** found,
-                                     soinfo* caller,
-                                     void* handle) {
+static const ElfW(Sym)* dlsym_linear_lookup(android_namespace_t* ns,
+                                            const char* name,
+                                            const version_info* vi,
+                                            soinfo** found,
+                                            soinfo* caller,
+                                            void* handle) {
   SymbolName symbol_name(name);
 
-  soinfo* start = solist;
+  auto& soinfo_list = ns->soinfo_list();
+  auto start = soinfo_list.begin();
 
   if (handle == RTLD_NEXT) {
     if (caller == nullptr) {
       return nullptr;
     } else {
-      start = caller->next;
+      auto it = soinfo_list.find(caller);
+      CHECK (it != soinfo_list.end());
+      start = ++it;
     }
   }
 
   const ElfW(Sym)* s = nullptr;
-  for (soinfo* si = start; si != nullptr; si = si->next) {
+  for (auto it = start, end = soinfo_list.end(); it != end; ++it) {
+    soinfo* si = *it;
     // Do not skip RTLD_LOCAL libraries in dlsym(RTLD_DEFAULT, ...)
     // if the library is opened by application with target api level <= 22
     // See http://b/21565766
@@ -1003,7 +1351,7 @@
       continue;
     }
 
-    if (!si->find_symbol_by_name(symbol_name, nullptr, &s)) {
+    if (!si->find_symbol_by_name(symbol_name, vi, &s)) {
       return nullptr;
     }
 
@@ -1019,7 +1367,7 @@
   if (s == nullptr && caller != nullptr &&
       (caller->get_rtld_flags() & RTLD_GLOBAL) == 0) {
     return dlsym_handle_lookup(caller->get_local_group_root(),
-        (handle == RTLD_NEXT) ? caller : nullptr, found, symbol_name);
+        (handle == RTLD_NEXT) ? caller : nullptr, found, symbol_name, vi);
   }
 
   if (s != nullptr) {
@@ -1086,15 +1434,65 @@
   return nullptr;
 }
 
-static int open_library_in_zipfile(const char* const path,
-                                   off64_t* file_offset) {
-  TRACE("Trying zip file open from path '%s'", path);
+class ZipArchiveCache {
+ public:
+  ZipArchiveCache() {}
+  ~ZipArchiveCache();
+
+  bool get_or_open(const char* zip_path, ZipArchiveHandle* handle);
+ private:
+  DISALLOW_COPY_AND_ASSIGN(ZipArchiveCache);
+
+  std::unordered_map<std::string, ZipArchiveHandle> cache_;
+};
+
+bool ZipArchiveCache::get_or_open(const char* zip_path, ZipArchiveHandle* handle) {
+  std::string key(zip_path);
+
+  auto it = cache_.find(key);
+  if (it != cache_.end()) {
+    *handle = it->second;
+    return true;
+  }
+
+  int fd = TEMP_FAILURE_RETRY(open(zip_path, O_RDONLY | O_CLOEXEC));
+  if (fd == -1) {
+    return false;
+  }
+
+  if (OpenArchiveFd(fd, "", handle) != 0) {
+    // invalid zip-file (?)
+    CloseArchive(handle);
+    close(fd);
+    return false;
+  }
+
+  cache_[key] = *handle;
+  return true;
+}
+
+ZipArchiveCache::~ZipArchiveCache() {
+  for (const auto& it : cache_) {
+    CloseArchive(it.second);
+  }
+}
+
+static int open_library_in_zipfile(ZipArchiveCache* zip_archive_cache,
+                                   const char* const input_path,
+                                   off64_t* file_offset, std::string* realpath) {
+  std::string normalized_path;
+  if (!normalize_path(input_path, &normalized_path)) {
+    return -1;
+  }
+
+  const char* const path = normalized_path.c_str();
+  TRACE("Trying zip file open from path \"%s\" -> normalized \"%s\"", input_path, path);
 
   // Treat an '!/' separator inside a path as the separator between the name
   // of the zip file on disk and the subdirectory to search within it.
   // For example, if path is "foo.zip!/bar/bas/x.so", then we search for
   // "bar/bas/x.so" within "foo.zip".
-  const char* separator = strstr(path, "!/");
+  const char* const separator = strstr(path, kZipFileSeparator);
   if (separator == nullptr) {
     return -1;
   }
@@ -1115,19 +1513,15 @@
   }
 
   ZipArchiveHandle handle;
-  if (OpenArchiveFd(fd, "", &handle, false) != 0) {
+  if (!zip_archive_cache->get_or_open(zip_path, &handle)) {
     // invalid zip-file (?)
     close(fd);
     return -1;
   }
 
-  auto archive_guard = make_scope_guard([&]() {
-    CloseArchive(handle);
-  });
-
   ZipEntry entry;
 
-  if (FindEntry(handle, ZipEntryName(file_path), &entry) != 0) {
+  if (FindEntry(handle, ZipString(file_path), &entry) != 0) {
     // Entry was not found.
     close(fd);
     return -1;
@@ -1140,6 +1534,15 @@
   }
 
   *file_offset = entry.offset;
+
+  if (realpath_fd(fd, realpath)) {
+    *realpath += separator;
+  } else {
+    PRINT("warning: unable to get realpath for the library \"%s\". Will use given path.",
+          normalized_path.c_str());
+    *realpath = normalized_path;
+  }
+
   return fd;
 }
 
@@ -1153,40 +1556,29 @@
   return true;
 }
 
-static int open_library_on_default_path(const char* name, off64_t* file_offset) {
-  for (size_t i = 0; kDefaultLdPaths[i] != nullptr; ++i) {
+static int open_library_on_paths(ZipArchiveCache* zip_archive_cache,
+                                 const char* name, off64_t* file_offset,
+                                 const std::vector<std::string>& paths,
+                                 std::string* realpath) {
+  for (const auto& path : paths) {
     char buf[512];
-    if (!format_path(buf, sizeof(buf), kDefaultLdPaths[i], name)) {
-      continue;
-    }
-
-    int fd = TEMP_FAILURE_RETRY(open(buf, O_RDONLY | O_CLOEXEC));
-    if (fd != -1) {
-      *file_offset = 0;
-      return fd;
-    }
-  }
-
-  return -1;
-}
-
-static int open_library_on_ld_library_path(const char* name, off64_t* file_offset) {
-  for (const auto& path_str : g_ld_library_paths) {
-    char buf[512];
-    const char* const path = path_str.c_str();
-    if (!format_path(buf, sizeof(buf), path, name)) {
+    if (!format_path(buf, sizeof(buf), path.c_str(), name)) {
       continue;
     }
 
     int fd = -1;
-    if (strchr(buf, '!') != nullptr) {
-      fd = open_library_in_zipfile(buf, file_offset);
+    if (strstr(buf, kZipFileSeparator) != nullptr) {
+      fd = open_library_in_zipfile(zip_archive_cache, buf, file_offset, realpath);
     }
 
     if (fd == -1) {
       fd = TEMP_FAILURE_RETRY(open(buf, O_RDONLY | O_CLOEXEC));
       if (fd != -1) {
         *file_offset = 0;
+        if (!realpath_fd(fd, realpath)) {
+          PRINT("warning: unable to get realpath for the library \"%s\". Will use given path.", buf);
+          *realpath = buf;
+        }
       }
     }
 
@@ -1198,30 +1590,56 @@
   return -1;
 }
 
-static int open_library(const char* name, off64_t* file_offset) {
+static int open_library(android_namespace_t* ns,
+                        ZipArchiveCache* zip_archive_cache,
+                        const char* name, soinfo *needed_by,
+                        off64_t* file_offset, std::string* realpath) {
   TRACE("[ opening %s ]", name);
 
   // If the name contains a slash, we should attempt to open it directly and not search the paths.
   if (strchr(name, '/') != nullptr) {
-    if (strchr(name, '!') != nullptr) {
-      int fd = open_library_in_zipfile(name, file_offset);
+    int fd = -1;
+
+    if (strstr(name, kZipFileSeparator) != nullptr) {
+      fd = open_library_in_zipfile(zip_archive_cache, name, file_offset, realpath);
+    }
+
+    if (fd == -1) {
+      fd = TEMP_FAILURE_RETRY(open(name, O_RDONLY | O_CLOEXEC));
       if (fd != -1) {
-        return fd;
+        *file_offset = 0;
+        if (!realpath_fd(fd, realpath)) {
+          PRINT("warning: unable to get realpath for the library \"%s\". Will use given path.", name);
+          *realpath = name;
+        }
       }
     }
 
-    int fd = TEMP_FAILURE_RETRY(open(name, O_RDONLY | O_CLOEXEC));
-    if (fd != -1) {
-      *file_offset = 0;
-    }
     return fd;
   }
 
-  // Otherwise we try LD_LIBRARY_PATH first, and fall back to the built-in well known paths.
-  int fd = open_library_on_ld_library_path(name, file_offset);
-  if (fd == -1) {
-    fd = open_library_on_default_path(name, file_offset);
+  // Otherwise we try LD_LIBRARY_PATH first, and fall back to the default library path
+  int fd = open_library_on_paths(zip_archive_cache, name, file_offset, ns->get_ld_library_paths(), realpath);
+  if (fd == -1 && needed_by != nullptr) {
+    fd = open_library_on_paths(zip_archive_cache, name, file_offset, needed_by->get_dt_runpath(), realpath);
+    // Check if the library is accessible
+    if (fd != -1 && !ns->is_accessible(*realpath)) {
+      fd = -1;
+    }
   }
+
+  if (fd == -1) {
+    fd = open_library_on_paths(zip_archive_cache, name, file_offset, ns->get_default_library_paths(), realpath);
+  }
+
+  // TODO(dimitry): workaround for http://b/26394120 (the grey-list)
+  if (fd == -1 && ns != &g_default_namespace && is_greylisted(name, needed_by)) {
+    // try searching for it on default_namespace default_library_path
+    fd = open_library_on_paths(zip_archive_cache, name, file_offset,
+                               g_default_namespace.get_default_library_paths(), realpath);
+  }
+  // END OF WORKAROUND
+
   return fd;
 }
 
@@ -1231,7 +1649,8 @@
   if (get_application_target_sdk_version() <= 22) {
     const char* bname = basename(dt_needed);
     if (bname != dt_needed) {
-      DL_WARN("'%s' library has invalid DT_NEEDED entry '%s'", sopath, dt_needed);
+      DL_WARN("library \"%s\" has invalid DT_NEEDED entry \"%s\"", sopath, dt_needed);
+      add_dlwarning(sopath, "invalid DT_NEEDED entry",  dt_needed);
     }
 
     return bname;
@@ -1242,120 +1661,204 @@
 
 template<typename F>
 static void for_each_dt_needed(const soinfo* si, F action) {
-  for (ElfW(Dyn)* d = si->dynamic; d->d_tag != DT_NULL; ++d) {
+  for (const ElfW(Dyn)* d = si->dynamic; d->d_tag != DT_NULL; ++d) {
     if (d->d_tag == DT_NEEDED) {
       action(fix_dt_needed(si->get_string(d->d_un.d_val), si->get_realpath()));
     }
   }
 }
 
-static soinfo* load_library(int fd, off64_t file_offset,
-                            LoadTaskList& load_tasks,
-                            const char* name, int rtld_flags,
-                            const android_dlextinfo* extinfo) {
+template<typename F>
+static void for_each_dt_needed(const ElfReader& elf_reader, F action) {
+  for (const ElfW(Dyn)* d = elf_reader.dynamic(); d->d_tag != DT_NULL; ++d) {
+    if (d->d_tag == DT_NEEDED) {
+      action(fix_dt_needed(elf_reader.get_string(d->d_un.d_val), elf_reader.name()));
+    }
+  }
+}
+
+static bool load_library(android_namespace_t* ns,
+                         LoadTask* task,
+                         LoadTaskList* load_tasks,
+                         int rtld_flags,
+                         const std::string& realpath) {
+  off64_t file_offset = task->get_file_offset();
+  const char* name = task->get_name();
+  const android_dlextinfo* extinfo = task->get_extinfo();
+
   if ((file_offset % PAGE_SIZE) != 0) {
     DL_ERR("file offset for the library \"%s\" is not page-aligned: %" PRId64, name, file_offset);
-    return nullptr;
+    return false;
   }
   if (file_offset < 0) {
     DL_ERR("file offset for the library \"%s\" is negative: %" PRId64, name, file_offset);
-    return nullptr;
+    return false;
   }
 
   struct stat file_stat;
-  if (TEMP_FAILURE_RETRY(fstat(fd, &file_stat)) != 0) {
+  if (TEMP_FAILURE_RETRY(fstat(task->get_fd(), &file_stat)) != 0) {
     DL_ERR("unable to stat file for the library \"%s\": %s", name, strerror(errno));
-    return nullptr;
+    return false;
   }
   if (file_offset >= file_stat.st_size) {
     DL_ERR("file offset for the library \"%s\" >= file size: %" PRId64 " >= %" PRId64,
         name, file_offset, file_stat.st_size);
-    return nullptr;
+    return false;
   }
 
   // Check for symlink and other situations where
   // file can have different names, unless ANDROID_DLEXT_FORCE_LOAD is set
   if (extinfo == nullptr || (extinfo->flags & ANDROID_DLEXT_FORCE_LOAD) == 0) {
-    for (soinfo* si = solist; si != nullptr; si = si->next) {
-      if (si->get_st_dev() != 0 &&
-          si->get_st_ino() != 0 &&
-          si->get_st_dev() == file_stat.st_dev &&
-          si->get_st_ino() == file_stat.st_ino &&
-          si->get_file_offset() == file_offset) {
-        TRACE("library \"%s\" is already loaded under different name/path \"%s\" - "
-            "will return existing soinfo", name, si->get_realpath());
-        return si;
+    auto predicate = [&](soinfo* si) {
+      return si->get_st_dev() != 0 &&
+             si->get_st_ino() != 0 &&
+             si->get_st_dev() == file_stat.st_dev &&
+             si->get_st_ino() == file_stat.st_ino &&
+             si->get_file_offset() == file_offset;
+    };
+
+    soinfo* si = ns->soinfo_list().find_if(predicate);
+
+    // check public namespace
+    if (si == nullptr) {
+      si = g_public_namespace.find_if(predicate);
+      if (si != nullptr) {
+        ns->add_soinfo(si);
       }
     }
+
+    if (si != nullptr) {
+      TRACE("library \"%s\" is already loaded under different name/path \"%s\" - "
+            "will return existing soinfo", name, si->get_realpath());
+      task->set_soinfo(si);
+      return true;
+    }
   }
 
   if ((rtld_flags & RTLD_NOLOAD) != 0) {
     DL_ERR("library \"%s\" wasn't loaded and RTLD_NOLOAD prevented it", name);
-    return nullptr;
+    return false;
   }
 
-  std::string realpath = name;
-  if (!realpath_fd(fd, &realpath)) {
-    PRINT("warning: unable to get realpath for the library \"%s\". Will use given name.", name);
-    realpath = name;
+  if (!ns->is_accessible(realpath)) {
+    // TODO(dimitry): workaround for http://b/26394120 - the grey-list
+    const soinfo* needed_by = task->is_dt_needed() ? task->get_needed_by() : nullptr;
+    if (is_greylisted(name, needed_by)) {
+      // print warning only if needed by non-system library
+      if (needed_by == nullptr || !is_system_library(needed_by->get_realpath())) {
+        const soinfo* needed_or_dlopened_by = task->get_needed_by();
+        const char* sopath = needed_or_dlopened_by == nullptr ? "(unknown)" :
+                                                      needed_or_dlopened_by->get_realpath();
+        DL_WARN("library \"%s\" (\"%s\") needed or dlopened by \"%s\" is not accessible for the namespace \"%s\""
+                " - the access is temporarily granted as a workaround for http://b/26394120, note that the access"
+                " will be removed in future releases of Android.",
+                name, realpath.c_str(), sopath, ns->get_name());
+        add_dlwarning(sopath, "unauthorized access to",  name);
+      }
+    } else {
+      // do not load libraries if they are not accessible for the specified namespace.
+      const char* needed_or_dlopened_by = task->get_needed_by() == nullptr ?
+                                          "(unknown)" :
+                                          task->get_needed_by()->get_realpath();
+
+      DL_ERR("library \"%s\" needed or dlopened by \"%s\" is not accessible for the namespace \"%s\"",
+             name, needed_or_dlopened_by, ns->get_name());
+
+      PRINT("library \"%s\" (\"%s\") needed or dlopened by \"%s\" is not accessible for the"
+            " namespace: [name=\"%s\", ld_library_paths=\"%s\", default_library_paths=\"%s\","
+            " permitted_paths=\"%s\"]",
+            name, realpath.c_str(),
+            needed_or_dlopened_by,
+            ns->get_name(),
+            android::base::Join(ns->get_ld_library_paths(), ':').c_str(),
+            android::base::Join(ns->get_default_library_paths(), ':').c_str(),
+            android::base::Join(ns->get_permitted_paths(), ':').c_str());
+      return false;
+    }
   }
 
-  // Read the ELF header and load the segments.
-  ElfReader elf_reader(realpath.c_str(), fd, file_offset, file_stat.st_size);
-  if (!elf_reader.Load(extinfo)) {
-    return nullptr;
-  }
-
-  soinfo* si = soinfo_alloc(realpath.c_str(), &file_stat, file_offset, rtld_flags);
+  soinfo* si = soinfo_alloc(ns, realpath.c_str(), &file_stat, file_offset, rtld_flags);
   if (si == nullptr) {
-    return nullptr;
+    return false;
   }
-  si->base = elf_reader.load_start();
-  si->size = elf_reader.load_size();
-  si->load_bias = elf_reader.load_bias();
-  si->phnum = elf_reader.phdr_count();
-  si->phdr = elf_reader.loaded_phdr();
 
-  if (!si->prelink_image()) {
+  task->set_soinfo(si);
+
+  // Read the ELF header and some of the segments.
+  if (!task->read(realpath.c_str(), file_stat.st_size)) {
     soinfo_free(si);
-    return nullptr;
+    task->set_soinfo(nullptr);
+    return false;
   }
 
-  for_each_dt_needed(si, [&] (const char* name) {
-    load_tasks.push_back(LoadTask::create(name, si));
+  // find and set DT_RUNPATH and dt_soname
+  // Note that these field values are temporary and are
+  // going to be overwritten on soinfo::prelink_image
+  // with values from PT_LOAD segments.
+  const ElfReader& elf_reader = task->get_elf_reader();
+  for (const ElfW(Dyn)* d = elf_reader.dynamic(); d->d_tag != DT_NULL; ++d) {
+    if (d->d_tag == DT_RUNPATH) {
+      si->set_dt_runpath(elf_reader.get_string(d->d_un.d_val));
+    }
+    if (d->d_tag == DT_SONAME) {
+      si->set_soname(elf_reader.get_string(d->d_un.d_val));
+    }
+  }
+
+  for_each_dt_needed(task->get_elf_reader(), [&](const char* name) {
+    load_tasks->push_back(LoadTask::create(name, si, task->get_readers_map()));
   });
 
-  return si;
+  return true;
 }
 
-static soinfo* load_library(LoadTaskList& load_tasks,
-                            const char* name, int rtld_flags,
-                            const android_dlextinfo* extinfo) {
+static bool load_library(android_namespace_t* ns,
+                         LoadTask* task,
+                         ZipArchiveCache* zip_archive_cache,
+                         LoadTaskList* load_tasks,
+                         int rtld_flags) {
+  const char* name = task->get_name();
+  soinfo* needed_by = task->get_needed_by();
+  const android_dlextinfo* extinfo = task->get_extinfo();
+
+  off64_t file_offset;
+  std::string realpath;
   if (extinfo != nullptr && (extinfo->flags & ANDROID_DLEXT_USE_LIBRARY_FD) != 0) {
-    off64_t file_offset = 0;
+    file_offset = 0;
     if ((extinfo->flags & ANDROID_DLEXT_USE_LIBRARY_FD_OFFSET) != 0) {
       file_offset = extinfo->library_fd_offset;
     }
-    return load_library(extinfo->library_fd, file_offset, load_tasks, name, rtld_flags, extinfo);
+
+    if (!realpath_fd(extinfo->library_fd, &realpath)) {
+      PRINT("warning: unable to get realpath for the library \"%s\" by extinfo->library_fd. "
+            "Will use given name.", name);
+      realpath = name;
+    }
+
+    task->set_fd(extinfo->library_fd, false);
+    task->set_file_offset(file_offset);
+    return load_library(ns, task, load_tasks, rtld_flags, realpath);
   }
 
   // Open the file.
-  off64_t file_offset;
-  int fd = open_library(name, &file_offset);
+  int fd = open_library(ns, zip_archive_cache, name, needed_by, &file_offset, &realpath);
   if (fd == -1) {
     DL_ERR("library \"%s\" not found", name);
-    return nullptr;
+    return false;
   }
-  soinfo* result = load_library(fd, file_offset, load_tasks, name, rtld_flags, extinfo);
-  close(fd);
-  return result;
+
+  task->set_fd(fd, true);
+  task->set_file_offset(file_offset);
+
+  return load_library(ns, task, load_tasks, rtld_flags, realpath);
 }
 
 // Returns true if library was found and false in 2 cases
-// 1. The library was found but loaded under different target_sdk_version
-//    (*candidate != nullptr)
+// 1. (for default namespace only) The library was found but loaded under different
+//    target_sdk_version (*candidate != nullptr)
 // 2. The library was not found by soname (*candidate is nullptr)
-static bool find_loaded_library_by_soname(const char* name, soinfo** candidate) {
+static bool find_loaded_library_by_soname(android_namespace_t* ns,
+                                          const char* name, soinfo** candidate) {
   *candidate = nullptr;
 
   // Ignore filename with path.
@@ -1365,7 +1868,7 @@
 
   uint32_t target_sdk_version = get_application_target_sdk_version();
 
-  for (soinfo* si = solist; si != nullptr; si = si->next) {
+  return !ns->soinfo_list().visit([&](soinfo* si) {
     const char* soname = si->get_soname();
     if (soname != nullptr && (strcmp(name, soname) == 0)) {
       // If the library was opened under different target sdk version
@@ -1375,45 +1878,68 @@
       // in any case.
       bool is_libdl = si == solist;
       if (is_libdl || (si->get_dt_flags_1() & DF_1_GLOBAL) != 0 ||
-          !si->is_linked() || si->get_target_sdk_version() == target_sdk_version) {
+          !si->is_linked() || si->get_target_sdk_version() == target_sdk_version ||
+          ns != &g_default_namespace) {
         *candidate = si;
-        return true;
+        return false;
       } else if (*candidate == nullptr) {
-        // for the different sdk version - remember the first library.
+        // for the different sdk version in the default namespace
+        // remember the first library.
         *candidate = si;
       }
     }
+
+    return true;
+  });
+}
+
+static bool find_library_internal(android_namespace_t* ns,
+                                  LoadTask* task,
+                                  ZipArchiveCache* zip_archive_cache,
+                                  LoadTaskList* load_tasks,
+                                  int rtld_flags) {
+  soinfo* candidate;
+
+  if (find_loaded_library_by_soname(ns, task->get_name(), &candidate)) {
+    task->set_soinfo(candidate);
+    return true;
+  }
+
+  if (ns != &g_default_namespace) {
+    // check public namespace
+    candidate = g_public_namespace.find_if([&](soinfo* si) {
+      return strcmp(task->get_name(), si->get_soname()) == 0;
+    });
+
+    if (candidate != nullptr) {
+      ns->add_soinfo(candidate);
+      task->set_soinfo(candidate);
+      return true;
+    }
+  }
+
+  // Library might still be loaded, the accurate detection
+  // of this fact is done by load_library.
+  TRACE("[ \"%s\" find_loaded_library_by_soname failed (*candidate=%s@%p). Trying harder...]",
+      task->get_name(), candidate == nullptr ? "n/a" : candidate->get_realpath(), candidate);
+
+  if (load_library(ns, task, zip_archive_cache, load_tasks, rtld_flags)) {
+    return true;
+  } else {
+    // In case we were unable to load the library but there
+    // is a candidate loaded under the same soname but different
+    // sdk level - return it anyways.
+    if (candidate != nullptr) {
+      task->set_soinfo(candidate);
+      return true;
+    }
   }
 
   return false;
 }
 
-static soinfo* find_library_internal(LoadTaskList& load_tasks, const char* name,
-                                     int rtld_flags, const android_dlextinfo* extinfo) {
-  soinfo* candidate;
-
-  if (find_loaded_library_by_soname(name, &candidate)) {
-    return candidate;
-  }
-
-  // Library might still be loaded, the accurate detection
-  // of this fact is done by load_library.
-  TRACE("[ '%s' find_loaded_library_by_soname returned false (*candidate=%s@%p). Trying harder...]",
-      name, candidate == nullptr ? "n/a" : candidate->get_realpath(), candidate);
-
-  soinfo* si = load_library(load_tasks, name, rtld_flags, extinfo);
-
-  // In case we were unable to load the library but there
-  // is a candidate loaded under the same soname but different
-  // sdk level - return it anyways.
-  if (si == nullptr && candidate != nullptr) {
-    si = candidate;
-  }
-
-  return si;
-}
-
 static void soinfo_unload(soinfo* si);
+static void soinfo_unload(soinfo* soinfos[], size_t count);
 
 // TODO: this is slightly unusual way to construct
 // the global group for relocation. Not every RTLD_GLOBAL
@@ -1422,29 +1948,68 @@
 //
 // This group consists of the main executable, LD_PRELOADs
 // and libraries with the DF_1_GLOBAL flag set.
-static soinfo::soinfo_list_t make_global_group() {
+static soinfo::soinfo_list_t make_global_group(android_namespace_t* ns) {
   soinfo::soinfo_list_t global_group;
-  for (soinfo* si = somain; si != nullptr; si = si->next) {
+  ns->soinfo_list().for_each([&](soinfo* si) {
     if ((si->get_dt_flags_1() & DF_1_GLOBAL) != 0) {
       global_group.push_back(si);
     }
-  }
+  });
 
   return global_group;
 }
 
-static bool find_libraries(soinfo* start_with, const char* const library_names[],
-      size_t library_names_count, soinfo* soinfos[], std::vector<soinfo*>* ld_preloads,
-      size_t ld_preloads_count, int rtld_flags, const android_dlextinfo* extinfo) {
+// This function provides a list of libraries to be shared
+// by the namespace. For the default namespace this is the global
+// group (see make_global_group). For all others this is a group
+// of RTLD_GLOBAL libraries (which includes the global group from
+// the default namespace).
+static soinfo::soinfo_list_t get_shared_group(android_namespace_t* ns) {
+  if (ns == &g_default_namespace) {
+    return make_global_group(ns);
+  }
+
+  soinfo::soinfo_list_t shared_group;
+  ns->soinfo_list().for_each([&](soinfo* si) {
+    if ((si->get_rtld_flags() & RTLD_GLOBAL) != 0) {
+      shared_group.push_back(si);
+    }
+  });
+
+  return shared_group;
+}
+
+static void shuffle(std::vector<LoadTask*>* v) {
+  for (size_t i = 0, size = v->size(); i < size; ++i) {
+    size_t n = size - i;
+    size_t r = arc4random_uniform(n);
+    std::swap((*v)[n-1], (*v)[r]);
+  }
+}
+
+// add_as_children - add first-level loaded libraries (i.e. library_names[], but
+// not their transitive dependencies) as children of the start_with library.
+// This is false when find_libraries is called for dlopen(), when newly loaded
+// libraries must form a disjoint tree.
+static bool find_libraries(android_namespace_t* ns,
+                           soinfo* start_with,
+                           const char* const library_names[],
+                           size_t library_names_count, soinfo* soinfos[],
+                           std::vector<soinfo*>* ld_preloads,
+                           size_t ld_preloads_count, int rtld_flags,
+                           const android_dlextinfo* extinfo,
+                           bool add_as_children) {
   // Step 0: prepare.
   LoadTaskList load_tasks;
+  std::unordered_map<const soinfo*, ElfReader> readers_map;
+
   for (size_t i = 0; i < library_names_count; ++i) {
     const char* name = library_names[i];
-    load_tasks.push_back(LoadTask::create(name, start_with));
+    load_tasks.push_back(LoadTask::create(name, start_with, &readers_map));
   }
 
   // Construct global_group.
-  soinfo::soinfo_list_t global_group = make_global_group();
+  soinfo::soinfo_list_t global_group = make_global_group(ns);
 
   // If soinfos array is null allocate one on stack.
   // The array is needed in case of failure; for example
@@ -1462,29 +2027,36 @@
   // list of libraries to link - see step 2.
   size_t soinfos_count = 0;
 
-  auto failure_guard = make_scope_guard([&]() {
-    // Housekeeping
-    load_tasks.for_each([] (LoadTask* t) {
+  auto scope_guard = make_scope_guard([&]() {
+    for (LoadTask* t : load_tasks) {
       LoadTask::deleter(t);
-    });
-
-    for (size_t i = 0; i<soinfos_count; ++i) {
-      soinfo_unload(soinfos[i]);
     }
   });
 
-  // Step 1: load and pre-link all DT_NEEDED libraries in breadth first order.
-  for (LoadTask::unique_ptr task(load_tasks.pop_front());
-      task.get() != nullptr; task.reset(load_tasks.pop_front())) {
+  auto failure_guard = make_scope_guard([&]() {
+    // Housekeeping
+    soinfo_unload(soinfos, soinfos_count);
+  });
+
+  ZipArchiveCache zip_archive_cache;
+
+  // Step 1: expand the list of load_tasks to include
+  // all DT_NEEDED libraries (do not load them just yet)
+  for (size_t i = 0; i<load_tasks.size(); ++i) {
+    LoadTask* task = load_tasks[i];
     soinfo* needed_by = task->get_needed_by();
 
-    soinfo* si = find_library_internal(load_tasks, task->get_name(),
-                                       rtld_flags, needed_by == nullptr ? extinfo : nullptr);
-    if (si == nullptr) {
+    bool is_dt_needed = needed_by != nullptr && (needed_by != start_with || add_as_children);
+    task->set_extinfo(is_dt_needed ? nullptr : extinfo);
+    task->set_dt_needed(is_dt_needed);
+
+    if(!find_library_internal(ns, task, &zip_archive_cache, &load_tasks, rtld_flags)) {
       return false;
     }
 
-    if (needed_by != nullptr) {
+    soinfo* si = task->get_soinfo();
+
+    if (is_dt_needed) {
       needed_by->add_child(si);
     }
 
@@ -1495,11 +2067,6 @@
     // When ld_preloads is not null, the first
     // ld_preloads_count libs are in fact ld_preloads.
     if (ld_preloads != nullptr && soinfos_count < ld_preloads_count) {
-      // Add LD_PRELOADed libraries to the global group for future runs.
-      // There is no need to explicitly add them to the global group
-      // for this run because they are going to appear in the local
-      // group in the correct order.
-      si->set_dt_flags_1(si->get_dt_flags_1() | DF_1_GLOBAL);
       ld_preloads->push_back(si);
     }
 
@@ -1508,11 +2075,51 @@
     }
   }
 
-  // Step 2: link libraries.
+  // Step 2: Load libraries in random order (see b/24047022)
+  LoadTaskList load_list;
+  for (auto&& task : load_tasks) {
+    soinfo* si = task->get_soinfo();
+    auto pred = [&](const LoadTask* t) {
+      return t->get_soinfo() == si;
+    };
+
+    if (!si->is_linked() &&
+        std::find_if(load_list.begin(), load_list.end(), pred) == load_list.end() ) {
+      load_list.push_back(task);
+    }
+  }
+  shuffle(&load_list);
+
+  for (auto&& task : load_list) {
+    if (!task->load()) {
+      return false;
+    }
+  }
+
+  // Step 3: pre-link all DT_NEEDED libraries in breadth first order.
+  for (auto&& task : load_tasks) {
+    soinfo* si = task->get_soinfo();
+    if (!si->is_linked() && !si->prelink_image()) {
+      return false;
+    }
+  }
+
+  // Step 4: Add LD_PRELOADed libraries to the global group for
+  // future runs. There is no need to explicitly add them to
+  // the global group for this run because they are going to
+  // appear in the local group in the correct order.
+  if (ld_preloads != nullptr) {
+    for (auto&& si : *ld_preloads) {
+      si->set_dt_flags_1(si->get_dt_flags_1() | DF_1_GLOBAL);
+    }
+  }
+
+
+  // Step 5: link libraries.
   soinfo::soinfo_list_t local_group;
   walk_dependencies_tree(
-      start_with == nullptr ? soinfos : &start_with,
-      start_with == nullptr ? soinfos_count : 1,
+      (start_with != nullptr && add_as_children) ? &start_with : soinfos,
+      (start_with != nullptr && add_as_children) ? 1 : soinfos_count,
       [&] (soinfo* si) {
     local_group.push_back(si);
     return true;
@@ -1527,13 +2134,18 @@
       if (!si->link_image(global_group, local_group, extinfo)) {
         return false;
       }
-      si->set_linked();
     }
 
     return true;
   });
 
   if (linked) {
+    local_group.for_each([](soinfo* si) {
+      if (!si->is_linked()) {
+        si->set_linked();
+      }
+    });
+
     failure_guard.disable();
   }
 
@@ -1544,12 +2156,16 @@
   return linked;
 }
 
-static soinfo* find_library(const char* name, int rtld_flags, const android_dlextinfo* extinfo) {
+static soinfo* find_library(android_namespace_t* ns,
+                            const char* name, int rtld_flags,
+                            const android_dlextinfo* extinfo,
+                            soinfo* needed_by) {
   soinfo* si;
 
   if (name == nullptr) {
     si = somain;
-  } else if (!find_libraries(nullptr, &name, 1, &si, nullptr, 0, rtld_flags, extinfo)) {
+  } else if (!find_libraries(ns, needed_by, &name, 1, &si, nullptr, 0, rtld_flags,
+                             extinfo, /* add_as_children */ false)) {
     return nullptr;
   }
 
@@ -1557,98 +2173,134 @@
 }
 
 static void soinfo_unload(soinfo* root) {
+  if (root->is_linked()) {
+    root = root->get_local_group_root();
+  }
+
+  if (!root->can_unload()) {
+    TRACE("not unloading \"%s\" - the binary is flagged with NODELETE", root->get_realpath());
+    return;
+  }
+
+  soinfo_unload(&root, 1);
+}
+
+static void soinfo_unload(soinfo* soinfos[], size_t count) {
   // Note that the library can be loaded but not linked;
   // in which case there is no root but we still need
   // to walk the tree and unload soinfos involved.
   //
   // This happens on unsuccessful dlopen, when one of
   // the DT_NEEDED libraries could not be linked/found.
-  if (root->is_linked()) {
-    root = root->get_local_group_root();
-  }
-
-  if (!root->can_unload()) {
-    TRACE("not unloading '%s' - the binary is flagged with NODELETE", root->get_realpath());
+  if (count == 0) {
     return;
   }
 
-  size_t ref_count = root->is_linked() ? root->decrement_ref_count() : 0;
+  soinfo::soinfo_list_t unload_list;
+  for (size_t i = 0; i < count; ++i) {
+    soinfo* si = soinfos[i];
 
-  if (ref_count == 0) {
-    soinfo::soinfo_list_t local_unload_list;
-    soinfo::soinfo_list_t external_unload_list;
-    soinfo::soinfo_list_t depth_first_list;
-    depth_first_list.push_back(root);
-    soinfo* si = nullptr;
-
-    while ((si = depth_first_list.pop_front()) != nullptr) {
-      if (local_unload_list.contains(si)) {
-        continue;
-      }
-
-      local_unload_list.push_back(si);
-
-      if (si->has_min_version(0)) {
-        soinfo* child = nullptr;
-        while ((child = si->get_children().pop_front()) != nullptr) {
-          TRACE("%s@%p needs to unload %s@%p", si->get_realpath(), si,
-              child->get_realpath(), child);
-
-          if (local_unload_list.contains(child)) {
-            continue;
-          } else if (child->is_linked() && child->get_local_group_root() != root) {
-            external_unload_list.push_back(child);
-          } else {
-            depth_first_list.push_front(child);
-          }
-        }
+    if (si->can_unload()) {
+      size_t ref_count = si->is_linked() ? si->decrement_ref_count() : 0;
+      if (ref_count == 0) {
+        unload_list.push_back(si);
       } else {
-#if !defined(__work_around_b_19059885__)
-        __libc_fatal("soinfo for \"%s\"@%p has no version", si->get_realpath(), si);
-#else
-        PRINT("warning: soinfo for \"%s\"@%p has no version", si->get_realpath(), si);
-        for_each_dt_needed(si, [&] (const char* library_name) {
-          TRACE("deprecated (old format of soinfo): %s needs to unload %s",
-              si->get_realpath(), library_name);
-
-          soinfo* needed = find_library(library_name, RTLD_NOLOAD, nullptr);
-          if (needed != nullptr) {
-            // Not found: for example if symlink was deleted between dlopen and dlclose
-            // Since we cannot really handle errors at this point - print and continue.
-            PRINT("warning: couldn't find %s needed by %s on unload.",
-                library_name, si->get_realpath());
-            return;
-          } else if (local_unload_list.contains(needed)) {
-            // already visited
-            return;
-          } else if (needed->is_linked() && needed->get_local_group_root() != root) {
-            // external group
-            external_unload_list.push_back(needed);
-          } else {
-            // local group
-            depth_first_list.push_front(needed);
-          }
-        });
-#endif
+        TRACE("not unloading '%s' group, decrementing ref_count to %zd",
+            si->get_realpath(), ref_count);
       }
+    } else {
+      TRACE("not unloading '%s' - the binary is flagged with NODELETE", si->get_realpath());
+      return;
     }
-
-    local_unload_list.for_each([](soinfo* si) {
-      si->call_destructors();
-    });
-
-    while ((si = local_unload_list.pop_front()) != nullptr) {
-      notify_gdb_of_unload(si);
-      soinfo_free(si);
-    }
-
-    while ((si = external_unload_list.pop_front()) != nullptr) {
-      soinfo_unload(si);
-    }
-  } else {
-    TRACE("not unloading '%s' group, decrementing ref_count to %zd",
-        root->get_realpath(), ref_count);
   }
+
+  // This is used to identify soinfos outside of the load-group
+  // note that we cannot have > 1 in the array and have any of them
+  // linked. This is why we can safely use the first one.
+  soinfo* root = soinfos[0];
+
+  soinfo::soinfo_list_t local_unload_list;
+  soinfo::soinfo_list_t external_unload_list;
+  soinfo* si = nullptr;
+
+  while ((si = unload_list.pop_front()) != nullptr) {
+    if (local_unload_list.contains(si)) {
+      continue;
+    }
+
+    local_unload_list.push_back(si);
+
+    if (si->has_min_version(0)) {
+      soinfo* child = nullptr;
+      while ((child = si->get_children().pop_front()) != nullptr) {
+        TRACE("%s@%p needs to unload %s@%p", si->get_realpath(), si,
+            child->get_realpath(), child);
+
+        if (local_unload_list.contains(child)) {
+          continue;
+        } else if (child->is_linked() && child->get_local_group_root() != root) {
+          external_unload_list.push_back(child);
+        } else {
+          unload_list.push_front(child);
+        }
+      }
+    } else {
+#if !defined(__work_around_b_24465209__)
+      __libc_fatal("soinfo for \"%s\"@%p has no version", si->get_realpath(), si);
+#else
+      PRINT("warning: soinfo for \"%s\"@%p has no version", si->get_realpath(), si);
+      for_each_dt_needed(si, [&] (const char* library_name) {
+        TRACE("deprecated (old format of soinfo): %s needs to unload %s",
+            si->get_realpath(), library_name);
+
+        soinfo* needed = find_library(si->get_primary_namespace(),
+                                      library_name, RTLD_NOLOAD, nullptr, nullptr);
+
+        if (needed != nullptr) {
+          // Not found: for example if symlink was deleted between dlopen and dlclose
+          // Since we cannot really handle errors at this point - print and continue.
+          PRINT("warning: couldn't find %s needed by %s on unload.",
+              library_name, si->get_realpath());
+          return;
+        } else if (local_unload_list.contains(needed)) {
+          // already visited
+          return;
+        } else if (needed->is_linked() && needed->get_local_group_root() != root) {
+          // external group
+          external_unload_list.push_back(needed);
+        } else {
+          // local group
+          unload_list.push_front(needed);
+        }
+      });
+#endif
+    }
+  }
+
+  local_unload_list.for_each([](soinfo* si) {
+    si->call_destructors();
+  });
+
+  while ((si = local_unload_list.pop_front()) != nullptr) {
+    notify_gdb_of_unload(si);
+    soinfo_free(si);
+  }
+
+  while ((si = external_unload_list.pop_front()) != nullptr) {
+    soinfo_unload(si);
+  }
+}
+
+static std::string symbol_display_name(const char* sym_name, const char* sym_ver) {
+  if (sym_ver == nullptr) {
+    return sym_name;
+  }
+
+  return std::string(sym_name) + ", version " + sym_ver;
+}
+
+static android_namespace_t* get_caller_namespace(soinfo* caller) {
+  return caller != nullptr ? caller->get_primary_namespace() : g_anonymous_namespace;
 }
 
 void do_android_get_LD_LIBRARY_PATH(char* buffer, size_t buffer_size) {
@@ -1659,49 +2311,273 @@
   // See b/17302493 for further details.
   // Once the above bug is fixed, this code can be modified to use
   // snprintf again.
-  size_t required_len = strlen(kDefaultLdPaths[0]) + strlen(kDefaultLdPaths[1]) + 2;
+  size_t required_len = 0;
+  for (size_t i = 0; g_default_ld_paths[i] != nullptr; ++i) {
+    required_len += strlen(g_default_ld_paths[i]) + 1;
+  }
   if (buffer_size < required_len) {
     __libc_fatal("android_get_LD_LIBRARY_PATH failed, buffer too small: "
                  "buffer len %zu, required len %zu", buffer_size, required_len);
   }
-  char* end = stpcpy(buffer, kDefaultLdPaths[0]);
-  *end = ':';
-  strcpy(end + 1, kDefaultLdPaths[1]);
+  char* end = buffer;
+  for (size_t i = 0; g_default_ld_paths[i] != nullptr; ++i) {
+    if (i > 0) *end++ = ':';
+    end = stpcpy(end, g_default_ld_paths[i]);
+  }
 }
 
 void do_android_update_LD_LIBRARY_PATH(const char* ld_library_path) {
   parse_LD_LIBRARY_PATH(ld_library_path);
 }
 
-soinfo* do_dlopen(const char* name, int flags, const android_dlextinfo* extinfo) {
+void* do_dlopen(const char* name, int flags, const android_dlextinfo* extinfo,
+                  void* caller_addr) {
+  soinfo* const caller = find_containing_library(caller_addr);
+
   if ((flags & ~(RTLD_NOW|RTLD_LAZY|RTLD_LOCAL|RTLD_GLOBAL|RTLD_NODELETE|RTLD_NOLOAD)) != 0) {
     DL_ERR("invalid flags to dlopen: %x", flags);
     return nullptr;
   }
+
+  android_namespace_t* ns = get_caller_namespace(caller);
+
   if (extinfo != nullptr) {
     if ((extinfo->flags & ~(ANDROID_DLEXT_VALID_FLAG_BITS)) != 0) {
       DL_ERR("invalid extended flags to android_dlopen_ext: 0x%" PRIx64, extinfo->flags);
       return nullptr;
     }
+
     if ((extinfo->flags & ANDROID_DLEXT_USE_LIBRARY_FD) == 0 &&
         (extinfo->flags & ANDROID_DLEXT_USE_LIBRARY_FD_OFFSET) != 0) {
       DL_ERR("invalid extended flag combination (ANDROID_DLEXT_USE_LIBRARY_FD_OFFSET without "
           "ANDROID_DLEXT_USE_LIBRARY_FD): 0x%" PRIx64, extinfo->flags);
       return nullptr;
     }
+
+    if ((extinfo->flags & ANDROID_DLEXT_LOAD_AT_FIXED_ADDRESS) != 0 &&
+        (extinfo->flags & (ANDROID_DLEXT_RESERVED_ADDRESS | ANDROID_DLEXT_RESERVED_ADDRESS_HINT)) != 0) {
+      DL_ERR("invalid extended flag combination: ANDROID_DLEXT_LOAD_AT_FIXED_ADDRESS is not "
+             "compatible with ANDROID_DLEXT_RESERVED_ADDRESS/ANDROID_DLEXT_RESERVED_ADDRESS_HINT");
+      return nullptr;
+    }
+
+    if ((extinfo->flags & ANDROID_DLEXT_USE_NAMESPACE) != 0) {
+      if (extinfo->library_namespace == nullptr) {
+        DL_ERR("ANDROID_DLEXT_USE_NAMESPACE is set but extinfo->library_namespace is null");
+        return nullptr;
+      }
+      ns = extinfo->library_namespace;
+    }
   }
 
   ProtectedDataGuard guard;
-  soinfo* si = find_library(name, flags, extinfo);
+  soinfo* si = find_library(ns, name, flags, extinfo, caller);
   if (si != nullptr) {
     si->call_constructors();
+    return si->to_handle();
   }
-  return si;
+
+  return nullptr;
 }
 
-void do_dlclose(soinfo* si) {
+int do_dladdr(const void* addr, Dl_info* info) {
+  // Determine if this address can be found in any library currently mapped.
+  soinfo* si = find_containing_library(addr);
+  if (si == nullptr) {
+    return 0;
+  }
+
+  memset(info, 0, sizeof(Dl_info));
+
+  info->dli_fname = si->get_realpath();
+  // Address at which the shared object is loaded.
+  info->dli_fbase = reinterpret_cast<void*>(si->base);
+
+  // Determine if any symbol in the library contains the specified address.
+  ElfW(Sym)* sym = si->find_symbol_by_address(addr);
+  if (sym != nullptr) {
+    info->dli_sname = si->get_string(sym->st_name);
+    info->dli_saddr = reinterpret_cast<void*>(si->resolve_symbol_address(sym));
+  }
+
+  return 1;
+}
+
+static soinfo* soinfo_from_handle(void* handle) {
+  if ((reinterpret_cast<uintptr_t>(handle) & 1) != 0) {
+    auto it = g_soinfo_handles_map.find(reinterpret_cast<uintptr_t>(handle));
+    if (it == g_soinfo_handles_map.end()) {
+      return nullptr;
+    } else {
+      return it->second;
+    }
+  }
+
+  return static_cast<soinfo*>(handle);
+}
+
+bool do_dlsym(void* handle, const char* sym_name, const char* sym_ver,
+              void* caller_addr, void** symbol) {
+#if !defined(__LP64__)
+  if (handle == nullptr) {
+    DL_ERR("dlsym failed: library handle is null");
+    return false;
+  }
+#endif
+
+  if (sym_name == nullptr) {
+    DL_ERR("dlsym failed: symbol name is null");
+    return false;
+  }
+
+  soinfo* found = nullptr;
+  const ElfW(Sym)* sym = nullptr;
+  soinfo* caller = find_containing_library(caller_addr);
+  android_namespace_t* ns = get_caller_namespace(caller);
+
+  version_info vi_instance;
+  version_info* vi = nullptr;
+
+  if (sym_ver != nullptr) {
+    vi_instance.name = sym_ver;
+    vi_instance.elf_hash = calculate_elf_hash(sym_ver);
+    vi = &vi_instance;
+  }
+
+  if (handle == RTLD_DEFAULT || handle == RTLD_NEXT) {
+    sym = dlsym_linear_lookup(ns, sym_name, vi, &found, caller, handle);
+  } else {
+    soinfo* si = soinfo_from_handle(handle);
+    if (si == nullptr) {
+      DL_ERR("dlsym failed: invalid handle: %p", handle);
+      return false;
+    }
+    sym = dlsym_handle_lookup(si, &found, sym_name, vi);
+  }
+
+  if (sym != nullptr) {
+    uint32_t bind = ELF_ST_BIND(sym->st_info);
+
+    if ((bind == STB_GLOBAL || bind == STB_WEAK) && sym->st_shndx != 0) {
+      *symbol = reinterpret_cast<void*>(found->resolve_symbol_address(sym));
+      return true;
+    }
+
+    DL_ERR("symbol \"%s\" found but not global", symbol_display_name(sym_name, sym_ver).c_str());
+    return false;
+  }
+
+  DL_ERR("undefined symbol: %s", symbol_display_name(sym_name, sym_ver).c_str());
+  return false;
+}
+
+int do_dlclose(void* handle) {
   ProtectedDataGuard guard;
+  soinfo* si = soinfo_from_handle(handle);
+  if (si == nullptr) {
+    DL_ERR("invalid handle: %p", handle);
+    return -1;
+  }
+
   soinfo_unload(si);
+  return 0;
+}
+
+bool init_namespaces(const char* public_ns_sonames, const char* anon_ns_library_path) {
+  CHECK(public_ns_sonames != nullptr);
+  if (g_public_namespace_initialized) {
+    DL_ERR("public namespace has already been initialized.");
+    return false;
+  }
+
+  std::vector<std::string> sonames = android::base::Split(public_ns_sonames, ":");
+
+  ProtectedDataGuard guard;
+
+  auto failure_guard = make_scope_guard([&]() {
+    g_public_namespace.clear();
+  });
+
+  for (const auto& soname : sonames) {
+    soinfo* candidate = nullptr;
+
+    find_loaded_library_by_soname(&g_default_namespace, soname.c_str(), &candidate);
+
+    if (candidate == nullptr) {
+      DL_ERR("error initializing public namespace: \"%s\" was not found"
+             " in the default namespace", soname.c_str());
+      return false;
+    }
+
+    candidate->set_nodelete();
+    g_public_namespace.push_back(candidate);
+  }
+
+  g_public_namespace_initialized = true;
+
+  // create anonymous namespace
+  // When the caller is nullptr - create_namespace will take global group
+  // from the anonymous namespace, which is fine because anonymous namespace
+  // is still pointing to the default one.
+  android_namespace_t* anon_ns =
+      create_namespace(nullptr, "(anonymous)", nullptr, anon_ns_library_path,
+                       ANDROID_NAMESPACE_TYPE_REGULAR, nullptr, &g_default_namespace);
+
+  if (anon_ns == nullptr) {
+    g_public_namespace_initialized = false;
+    return false;
+  }
+  g_anonymous_namespace = anon_ns;
+  failure_guard.disable();
+  return true;
+}
+
+android_namespace_t* create_namespace(const void* caller_addr,
+                                      const char* name,
+                                      const char* ld_library_path,
+                                      const char* default_library_path,
+                                      uint64_t type,
+                                      const char* permitted_when_isolated_path,
+                                      android_namespace_t* parent_namespace) {
+  if (!g_public_namespace_initialized) {
+    DL_ERR("cannot create namespace: public namespace is not initialized.");
+    return nullptr;
+  }
+
+  if (parent_namespace == nullptr) {
+    // if parent_namespace is nullptr -> set it to the caller namespace
+    soinfo* caller_soinfo = find_containing_library(caller_addr);
+
+    parent_namespace = caller_soinfo != nullptr ?
+                       caller_soinfo->get_primary_namespace() :
+                       g_anonymous_namespace;
+  }
+
+  ProtectedDataGuard guard;
+  std::vector<std::string> ld_library_paths;
+  std::vector<std::string> default_library_paths;
+  std::vector<std::string> permitted_paths;
+
+  parse_path(ld_library_path, ":", &ld_library_paths);
+  parse_path(default_library_path, ":", &default_library_paths);
+  parse_path(permitted_when_isolated_path, ":", &permitted_paths);
+
+  android_namespace_t* ns = new (g_namespace_allocator.alloc()) android_namespace_t();
+  ns->set_name(name);
+  ns->set_isolated((type & ANDROID_NAMESPACE_TYPE_ISOLATED) != 0);
+  ns->set_ld_library_paths(std::move(ld_library_paths));
+  ns->set_default_library_paths(std::move(default_library_paths));
+  ns->set_permitted_paths(std::move(permitted_paths));
+
+  if ((type & ANDROID_NAMESPACE_TYPE_SHARED) != 0) {
+    // If shared - clone the parent namespace
+    ns->add_soinfos(parent_namespace->soinfo_list());
+  } else {
+    // If not shared - copy only the shared group
+    ns->add_soinfos(get_shared_group(parent_namespace));
+  }
+
+  return ns;
 }
 
 static ElfW(Addr) call_ifunc_resolver(ElfW(Addr) resolver_addr) {
@@ -1854,7 +2730,7 @@
     const char* sym_name = nullptr;
     ElfW(Addr) addend = get_addend(rel, reloc);
 
-    DEBUG("Processing '%s' relocation at index %zd", get_realpath(), idx);
+    DEBUG("Processing \"%s\" relocation at index %zd", get_realpath(), idx);
     if (type == R_GENERIC_NONE) {
       continue;
     }
@@ -2025,24 +2901,23 @@
         count_relocation(kRelocAbsolute);
         MARK(rel->r_offset);
         TRACE_TYPE(RELO, "RELO ABS64 %16llx <- %16llx %s\n",
-                   reloc, (sym_addr + addend), sym_name);
-        *reinterpret_cast<ElfW(Addr)*>(reloc) += (sym_addr + addend);
+                   reloc, sym_addr + addend, sym_name);
+        *reinterpret_cast<ElfW(Addr)*>(reloc) = sym_addr + addend;
         break;
       case R_AARCH64_ABS32:
         count_relocation(kRelocAbsolute);
         MARK(rel->r_offset);
         TRACE_TYPE(RELO, "RELO ABS32 %16llx <- %16llx %s\n",
-                   reloc, (sym_addr + addend), sym_name);
+                   reloc, sym_addr + addend, sym_name);
         {
-          const ElfW(Addr) reloc_value = *reinterpret_cast<ElfW(Addr)*>(reloc);
           const ElfW(Addr) min_value = static_cast<ElfW(Addr)>(INT32_MIN);
           const ElfW(Addr) max_value = static_cast<ElfW(Addr)>(UINT32_MAX);
-          if ((min_value <= (reloc_value + (sym_addr + addend))) &&
-              ((reloc_value + (sym_addr + addend)) <= max_value)) {
-            *reinterpret_cast<ElfW(Addr)*>(reloc) += (sym_addr + addend);
+          if ((min_value <= (sym_addr + addend)) &&
+              ((sym_addr + addend) <= max_value)) {
+            *reinterpret_cast<ElfW(Addr)*>(reloc) = sym_addr + addend;
           } else {
             DL_ERR("0x%016llx out of range 0x%016llx to 0x%016llx",
-                   (reloc_value + (sym_addr + addend)), min_value, max_value);
+                   sym_addr + addend, min_value, max_value);
             return false;
           }
         }
@@ -2051,17 +2926,16 @@
         count_relocation(kRelocAbsolute);
         MARK(rel->r_offset);
         TRACE_TYPE(RELO, "RELO ABS16 %16llx <- %16llx %s\n",
-                   reloc, (sym_addr + addend), sym_name);
+                   reloc, sym_addr + addend, sym_name);
         {
-          const ElfW(Addr) reloc_value = *reinterpret_cast<ElfW(Addr)*>(reloc);
           const ElfW(Addr) min_value = static_cast<ElfW(Addr)>(INT16_MIN);
           const ElfW(Addr) max_value = static_cast<ElfW(Addr)>(UINT16_MAX);
-          if ((min_value <= (reloc_value + (sym_addr + addend))) &&
-              ((reloc_value + (sym_addr + addend)) <= max_value)) {
-            *reinterpret_cast<ElfW(Addr)*>(reloc) += (sym_addr + addend);
+          if ((min_value <= (sym_addr + addend)) &&
+              ((sym_addr + addend) <= max_value)) {
+            *reinterpret_cast<ElfW(Addr)*>(reloc) = (sym_addr + addend);
           } else {
             DL_ERR("0x%016llx out of range 0x%016llx to 0x%016llx",
-                   reloc_value + (sym_addr + addend), min_value, max_value);
+                   sym_addr + addend, min_value, max_value);
             return false;
           }
         }
@@ -2070,24 +2944,23 @@
         count_relocation(kRelocRelative);
         MARK(rel->r_offset);
         TRACE_TYPE(RELO, "RELO REL64 %16llx <- %16llx - %16llx %s\n",
-                   reloc, (sym_addr + addend), rel->r_offset, sym_name);
-        *reinterpret_cast<ElfW(Addr)*>(reloc) += (sym_addr + addend) - rel->r_offset;
+                   reloc, sym_addr + addend, rel->r_offset, sym_name);
+        *reinterpret_cast<ElfW(Addr)*>(reloc) = sym_addr + addend - rel->r_offset;
         break;
       case R_AARCH64_PREL32:
         count_relocation(kRelocRelative);
         MARK(rel->r_offset);
         TRACE_TYPE(RELO, "RELO REL32 %16llx <- %16llx - %16llx %s\n",
-                   reloc, (sym_addr + addend), rel->r_offset, sym_name);
+                   reloc, sym_addr + addend, rel->r_offset, sym_name);
         {
-          const ElfW(Addr) reloc_value = *reinterpret_cast<ElfW(Addr)*>(reloc);
           const ElfW(Addr) min_value = static_cast<ElfW(Addr)>(INT32_MIN);
           const ElfW(Addr) max_value = static_cast<ElfW(Addr)>(UINT32_MAX);
-          if ((min_value <= (reloc_value + ((sym_addr + addend) - rel->r_offset))) &&
-              ((reloc_value + ((sym_addr + addend) - rel->r_offset)) <= max_value)) {
-            *reinterpret_cast<ElfW(Addr)*>(reloc) += ((sym_addr + addend) - rel->r_offset);
+          if ((min_value <= (sym_addr + addend - rel->r_offset)) &&
+              ((sym_addr + addend - rel->r_offset) <= max_value)) {
+            *reinterpret_cast<ElfW(Addr)*>(reloc) = sym_addr + addend - rel->r_offset;
           } else {
             DL_ERR("0x%016llx out of range 0x%016llx to 0x%016llx",
-                   reloc_value + ((sym_addr + addend) - rel->r_offset), min_value, max_value);
+                   sym_addr + addend - rel->r_offset, min_value, max_value);
             return false;
           }
         }
@@ -2096,17 +2969,16 @@
         count_relocation(kRelocRelative);
         MARK(rel->r_offset);
         TRACE_TYPE(RELO, "RELO REL16 %16llx <- %16llx - %16llx %s\n",
-                   reloc, (sym_addr + addend), rel->r_offset, sym_name);
+                   reloc, sym_addr + addend, rel->r_offset, sym_name);
         {
-          const ElfW(Addr) reloc_value = *reinterpret_cast<ElfW(Addr)*>(reloc);
           const ElfW(Addr) min_value = static_cast<ElfW(Addr)>(INT16_MIN);
           const ElfW(Addr) max_value = static_cast<ElfW(Addr)>(UINT16_MAX);
-          if ((min_value <= (reloc_value + ((sym_addr + addend) - rel->r_offset))) &&
-              ((reloc_value + ((sym_addr + addend) - rel->r_offset)) <= max_value)) {
-            *reinterpret_cast<ElfW(Addr)*>(reloc) += ((sym_addr + addend) - rel->r_offset);
+          if ((min_value <= (sym_addr + addend - rel->r_offset)) &&
+              ((sym_addr + addend - rel->r_offset) <= max_value)) {
+            *reinterpret_cast<ElfW(Addr)*>(reloc) = sym_addr + addend - rel->r_offset;
           } else {
             DL_ERR("0x%016llx out of range 0x%016llx to 0x%016llx",
-                   reloc_value + ((sym_addr + addend) - rel->r_offset), min_value, max_value);
+                   sym_addr + addend - rel->r_offset, min_value, max_value);
             return false;
           }
         }
@@ -2138,14 +3010,14 @@
         MARK(rel->r_offset);
         TRACE_TYPE(RELO, "RELO R_X86_64_32 %08zx <- +%08zx %s", static_cast<size_t>(reloc),
                    static_cast<size_t>(sym_addr), sym_name);
-        *reinterpret_cast<ElfW(Addr)*>(reloc) = sym_addr + addend;
+        *reinterpret_cast<Elf32_Addr*>(reloc) = sym_addr + addend;
         break;
       case R_X86_64_64:
         count_relocation(kRelocRelative);
         MARK(rel->r_offset);
         TRACE_TYPE(RELO, "RELO R_X86_64_64 %08zx <- +%08zx %s", static_cast<size_t>(reloc),
                    static_cast<size_t>(sym_addr), sym_name);
-        *reinterpret_cast<ElfW(Addr)*>(reloc) = sym_addr + addend;
+        *reinterpret_cast<Elf64_Addr*>(reloc) = sym_addr + addend;
         break;
       case R_X86_64_PC32:
         count_relocation(kRelocRelative);
@@ -2153,7 +3025,7 @@
         TRACE_TYPE(RELO, "RELO R_X86_64_PC32 %08zx <- +%08zx (%08zx - %08zx) %s",
                    static_cast<size_t>(reloc), static_cast<size_t>(sym_addr - reloc),
                    static_cast<size_t>(sym_addr), static_cast<size_t>(reloc), sym_name);
-        *reinterpret_cast<ElfW(Addr)*>(reloc) = sym_addr + addend - reloc;
+        *reinterpret_cast<Elf32_Addr*>(reloc) = sym_addr + addend - reloc;
         break;
 #elif defined(__arm__)
       case R_ARM_ABS32:
@@ -2211,7 +3083,7 @@
     return;
   }
 
-  TRACE("[ Calling %s (size %zd) @ %p for '%s' ]", array_name, count, functions, get_realpath());
+  TRACE("[ Calling %s (size %zd) @ %p for \"%s\" ]", array_name, count, functions, get_realpath());
 
   int begin = reverse ? (count - 1) : 0;
   int end = reverse ? -1 : count;
@@ -2222,7 +3094,7 @@
     call_function("function", functions[i]);
   }
 
-  TRACE("[ Done calling %s for '%s' ]", array_name, get_realpath());
+  TRACE("[ Done calling %s for \"%s\" ]", array_name, get_realpath());
 }
 
 void soinfo::call_function(const char* function_name __unused, linker_function_t function) {
@@ -2230,9 +3102,9 @@
     return;
   }
 
-  TRACE("[ Calling %s @ %p for '%s' ]", function_name, function, get_realpath());
+  TRACE("[ Calling %s @ %p for \"%s\" ]", function_name, function, get_realpath());
   function();
-  TRACE("[ Done calling %s @ %p for '%s' ]", function_name, function, get_realpath());
+  TRACE("[ Done calling %s @ %p for \"%s\" ]", function_name, function, get_realpath());
 }
 
 void soinfo::call_pre_init_constructors() {
@@ -2260,8 +3132,7 @@
 
   if (!is_main_executable() && preinit_array_ != nullptr) {
     // The GNU dynamic linker silently ignores these, but we warn the developer.
-    PRINT("\"%s\": ignoring %zd-entry DT_PREINIT_ARRAY in shared library!",
-          get_realpath(), preinit_array_count_);
+    PRINT("\"%s\": ignoring DT_PREINIT_ARRAY in shared library!", get_realpath());
   }
 
   get_children().for_each([] (soinfo* si) {
@@ -2317,9 +3188,20 @@
     });
   });
 
-  // 2. Once everything untied - clear local lists.
+  // 2. Remove from the primary namespace
+  primary_namespace_->remove_soinfo(this);
+  primary_namespace_ = nullptr;
+
+  // 3. Remove from secondary namespaces
+  secondary_namespaces_.for_each([&](android_namespace_t* ns) {
+    ns->remove_soinfo(this);
+  });
+
+
+  // 4. Once everything untied - clear local lists.
   parents_.clear();
   children_.clear();
+  secondary_namespaces_.clear();
 }
 
 dev_t soinfo::get_st_dev() const {
@@ -2376,8 +3258,12 @@
   }
 }
 
+void soinfo::set_nodelete() {
+  rtld_flags_ |= RTLD_NODELETE;
+}
+
 const char* soinfo::get_realpath() const {
-#if defined(__work_around_b_19059885__)
+#if defined(__work_around_b_24465209__)
   if (has_min_version(2)) {
     return realpath_.c_str();
   } else {
@@ -2388,8 +3274,19 @@
 #endif
 }
 
+void soinfo::set_soname(const char* soname) {
+#if defined(__work_around_b_24465209__)
+  if (has_min_version(2)) {
+    soname_ = soname;
+  }
+  strlcpy(old_name_, soname_, sizeof(old_name_));
+#else
+  soname_ = soname;
+#endif
+}
+
 const char* soinfo::get_soname() const {
-#if defined(__work_around_b_19059885__)
+#if defined(__work_around_b_24465209__)
   if (has_min_version(2)) {
     return soname_;
   } else {
@@ -2428,6 +3325,29 @@
   return g_empty_list;
 }
 
+static std::vector<std::string> g_empty_runpath;
+
+const std::vector<std::string>& soinfo::get_dt_runpath() const {
+  if (has_min_version(3)) {
+    return dt_runpath_;
+  }
+
+  return g_empty_runpath;
+}
+
+android_namespace_t* soinfo::get_primary_namespace() {
+  if (has_min_version(3)) {
+    return primary_namespace_;
+  }
+
+  return &g_default_namespace;
+}
+
+void soinfo::add_secondary_namespace(android_namespace_t* secondary_ns) {
+  CHECK(has_min_version(3));
+  secondary_namespaces_.push_back(secondary_ns);
+}
+
 ElfW(Addr) soinfo::resolve_symbol_address(const ElfW(Sym)* s) const {
   if (ELF_ST_TYPE(s->st_info) == STT_GNU_IFUNC) {
     return call_ifunc_resolver(s->st_value + load_bias);
@@ -2450,7 +3370,7 @@
 }
 
 bool soinfo::can_unload() const {
-  return (get_rtld_flags() & (RTLD_NODELETE | RTLD_GLOBAL)) == 0;
+  return !is_linked() || ((get_rtld_flags() & (RTLD_NODELETE | RTLD_GLOBAL)) == 0);
 }
 
 bool soinfo::is_linked() const {
@@ -2461,6 +3381,10 @@
   return (flags_ & FLAG_EXE) != 0;
 }
 
+bool soinfo::is_linker() const {
+  return (flags_ & FLAG_LINKER) != 0;
+}
+
 void soinfo::set_linked() {
   flags_ |= FLAG_LINKED;
 }
@@ -2485,6 +3409,19 @@
   return local_group_root_;
 }
 
+
+void soinfo::set_mapped_by_caller(bool mapped_by_caller) {
+  if (mapped_by_caller) {
+    flags_ |= FLAG_MAPPED_BY_CALLER;
+  } else {
+    flags_ &= ~FLAG_MAPPED_BY_CALLER;
+  }
+}
+
+bool soinfo::is_mapped_by_caller() const {
+  return (flags_ & FLAG_MAPPED_BY_CALLER) != 0;
+}
+
 // This function returns api-level at the time of
 // dlopen/load. Note that libraries opened by system
 // will always have 'current' api level.
@@ -2496,6 +3433,39 @@
   return local_group_root_->target_sdk_version_;
 }
 
+uintptr_t soinfo::get_handle() const {
+  CHECK(has_min_version(3));
+  CHECK(handle_ != 0);
+  return handle_;
+}
+
+void* soinfo::to_handle() {
+  if (get_application_target_sdk_version() <= 23 || !has_min_version(3)) {
+    return this;
+  }
+
+  return reinterpret_cast<void*>(get_handle());
+}
+
+void soinfo::generate_handle() {
+  CHECK(has_min_version(3));
+  CHECK(handle_ == 0); // Make sure this is the first call
+
+  // Make sure the handle is unique and does not collide
+  // with special values which are RTLD_DEFAULT and RTLD_NEXT.
+  do {
+    arc4random_buf(&handle_, sizeof(handle_));
+    // the least significant bit for the handle is always 1
+    // making it easy to test the type of handle passed to
+    // dl* functions.
+    handle_ = handle_ | 1;
+  } while (handle_ == reinterpret_cast<uintptr_t>(RTLD_DEFAULT) ||
+           handle_ == reinterpret_cast<uintptr_t>(RTLD_NEXT) ||
+           g_soinfo_handles_map.find(handle_) != g_soinfo_handles_map.end());
+
+  g_soinfo_handles_map[handle_] = this;
+}
+
 bool soinfo::prelink_image() {
   /* Extract dynamic section */
   ElfW(Word) dynamic_flags = 0;
@@ -2504,7 +3474,7 @@
   /* We can't log anything until the linker is relocated */
   bool relocating_linker = (flags_ & FLAG_LINKER) != 0;
   if (!relocating_linker) {
-    INFO("[ linking %s ]", get_realpath());
+    INFO("[ Linking \"%s\" ]", get_realpath());
     DEBUG("si->base = %p si->flags = 0x%08x", reinterpret_cast<void*>(base), flags_);
   }
 
@@ -2864,6 +3834,10 @@
         verneed_cnt_ = d->d_un.d_val;
         break;
 
+      case DT_RUNPATH:
+        // this is parsed after we have strtab initialized (see below).
+        break;
+
       default:
         if (!relocating_linker) {
           DL_WARN("%s: unused DT entry: type %p arg %p", get_realpath(),
@@ -2873,6 +3847,12 @@
     }
   }
 
+#if defined(__mips__) && !defined(__LP64__)
+  if (!mips_check_and_adjust_fp_modes()) {
+    return false;
+  }
+#endif
+
   DEBUG("si->base = %p, si->strtab = %p, si->symtab = %p",
         reinterpret_cast<void*>(base), strtab_, symtab_);
 
@@ -2897,12 +3877,13 @@
 
   // second pass - parse entries relying on strtab
   for (ElfW(Dyn)* d = dynamic; d->d_tag != DT_NULL; ++d) {
-    if (d->d_tag == DT_SONAME) {
-      soname_ = get_string(d->d_un.d_val);
-#if defined(__work_around_b_19059885__)
-      strlcpy(old_name_, soname_, sizeof(old_name_));
-#endif
-      break;
+    switch (d->d_tag) {
+      case DT_SONAME:
+        set_soname(get_string(d->d_un.d_val));
+        break;
+      case DT_RUNPATH:
+        set_dt_runpath(get_string(d->d_un.d_val));
+        break;
     }
   }
 
@@ -2917,6 +3898,7 @@
     soname_ = basename(realpath_.c_str());
     DL_WARN("%s: is missing DT_SONAME will use basename as a replacement: \"%s\"",
         get_realpath(), soname_);
+    // Don't call add_dlwarning because a missing DT_SONAME isn't important enough to show in the UI
   }
   return true;
 }
@@ -2942,17 +3924,16 @@
 #if !defined(__LP64__)
   if (has_text_relocations) {
     // Fail if app is targeting sdk version > 22
-    // TODO (dimitry): remove != __ANDROID_API__ check once http://b/20020312 is fixed
-    if (get_application_target_sdk_version() != __ANDROID_API__
-        && get_application_target_sdk_version() > 22) {
+    if (get_application_target_sdk_version() > 22) {
       PRINT("%s: has text relocations", get_realpath());
       DL_ERR("%s: has text relocations", get_realpath());
       return false;
     }
     // Make segments writable to allow text relocations to work properly. We will later call
-    // phdr_table_protect_segments() after all of them are applied and all constructors are run.
+    // phdr_table_protect_segments() after all of them are applied.
     DL_WARN("%s has text relocations. This is wasting memory and prevents "
             "security hardening. Please fix.", get_realpath());
+    add_dlwarning(get_realpath(), "text relocations");
     if (phdr_table_unprotect_segments(phdr, phnum, load_bias) < 0) {
       DL_ERR("can't unprotect loadable segments for \"%s\": %s",
              get_realpath(), strerror(errno));
@@ -3040,10 +4021,9 @@
   }
 #endif
 
-  /* We can also turn on GNU RELRO protection */
-  if (phdr_table_protect_gnu_relro(phdr, phnum, load_bias) < 0) {
-    DL_ERR("can't enable GNU RELRO protection for \"%s\": %s",
-           get_realpath(), strerror(errno));
+  // We can also turn on GNU RELRO protection if we're not linking the dynamic linker
+  // itself --- it can't make system calls yet, and will have to call protect_relro later.
+  if (!is_linker() && !protect_relro()) {
     return false;
   }
 
@@ -3068,6 +4048,15 @@
   return true;
 }
 
+bool soinfo::protect_relro() {
+  if (phdr_table_protect_gnu_relro(phdr, phnum, load_bias) < 0) {
+    DL_ERR("can't enable GNU RELRO protection for \"%s\": %s",
+           get_realpath(), strerror(errno));
+    return false;
+  }
+  return true;
+}
+
 /*
  * This function add vdso to internal dso list.
  * It helps to stack unwinding through signal handlers.
@@ -3080,7 +4069,7 @@
     return;
   }
 
-  soinfo* si = soinfo_alloc("[vdso]", nullptr, 0, 0);
+  soinfo* si = soinfo_alloc(&g_default_namespace, "[vdso]", nullptr, 0, 0);
 
   si->phdr = reinterpret_cast<ElfW(Phdr)*>(reinterpret_cast<char*>(ehdr_vdso) + ehdr_vdso->e_phoff);
   si->phnum = ehdr_vdso->e_phnum;
@@ -3093,32 +4082,22 @@
 #endif
 }
 
-/*
- * This is linker soinfo for GDB. See details below.
- */
-#if defined(__LP64__)
-#define LINKER_PATH "/system/bin/linker64"
-#else
-#define LINKER_PATH "/system/bin/linker"
-#endif
-
-// This is done to avoid calling c-tor prematurely
-// because soinfo c-tor needs memory allocator
-// which might be initialized after global variables.
-static uint8_t linker_soinfo_for_gdb_buf[sizeof(soinfo)] __attribute__((aligned(8)));
-static soinfo* linker_soinfo_for_gdb = nullptr;
-
 /* gdb expects the linker to be in the debug shared object list.
  * Without this, gdb has trouble locating the linker's ".text"
  * and ".plt" sections. Gdb could also potentially use this to
  * relocate the offset of our exported 'rtld_db_dlactivity' symbol.
- * Don't use soinfo_alloc(), because the linker shouldn't
- * be on the soinfo list.
+ * Note that the linker shouldn't be on the soinfo list.
  */
 static void init_linker_info_for_gdb(ElfW(Addr) linker_base) {
-  linker_soinfo_for_gdb = new (linker_soinfo_for_gdb_buf) soinfo(LINKER_PATH, nullptr, 0, 0);
+  static link_map linker_link_map_for_gdb;
+#if defined(__LP64__)
+  static char kLinkerPath[] = "/system/bin/linker64";
+#else
+  static char kLinkerPath[] = "/system/bin/linker";
+#endif
 
-  linker_soinfo_for_gdb->load_bias = linker_base;
+  linker_link_map_for_gdb.l_addr = linker_base;
+  linker_link_map_for_gdb.l_name = kLinkerPath;
 
   /*
    * Set the dynamic field in the link map otherwise gdb will complain with
@@ -3129,12 +4108,48 @@
   ElfW(Ehdr)* elf_hdr = reinterpret_cast<ElfW(Ehdr)*>(linker_base);
   ElfW(Phdr)* phdr = reinterpret_cast<ElfW(Phdr)*>(linker_base + elf_hdr->e_phoff);
   phdr_table_get_dynamic_section(phdr, elf_hdr->e_phnum, linker_base,
-                                 &linker_soinfo_for_gdb->dynamic, nullptr);
-  insert_soinfo_into_debug_map(linker_soinfo_for_gdb);
+                                 &linker_link_map_for_gdb.l_ld, nullptr);
+
+  insert_link_map_into_debug_map(&linker_link_map_for_gdb);
 }
 
+static void init_default_namespace() {
+  g_default_namespace.set_name("(default)");
+  g_default_namespace.set_isolated(false);
+
+  const char *interp = phdr_table_get_interpreter_name(somain->phdr, somain->phnum,
+                                                       somain->load_bias);
+  const char* bname = basename(interp);
+  if (bname && (strcmp(bname, "linker_asan") == 0 || strcmp(bname, "linker_asan64") == 0)) {
+    g_default_ld_paths = kAsanDefaultLdPaths;
+  } else {
+    g_default_ld_paths = kDefaultLdPaths;
+  }
+
+  std::vector<std::string> ld_default_paths;
+  for (size_t i = 0; g_default_ld_paths[i] != nullptr; ++i) {
+    ld_default_paths.push_back(g_default_ld_paths[i]);
+  }
+
+  g_default_namespace.set_default_library_paths(std::move(ld_default_paths));
+};
+
 extern "C" int __system_properties_init(void);
 
+static const char* get_executable_path() {
+  static std::string executable_path;
+  if (executable_path.empty()) {
+    char path[PATH_MAX];
+    ssize_t path_len = readlink("/proc/self/exe", path, sizeof(path));
+    if (path_len == -1 || path_len >= static_cast<ssize_t>(sizeof(path))) {
+      __libc_fatal("readlink('/proc/self/exe') failed: %s", strerror(errno));
+    }
+    executable_path = std::string(path, path_len);
+  }
+
+  return executable_path.c_str();
+}
+
 /*
  * This code is called after the linker has linked itself and
  * fixed it's own GOT. It is safe to make references to externs
@@ -3160,34 +4175,48 @@
     g_ld_debug_verbosity = atoi(LD_DEBUG);
   }
 
+#if defined(__LP64__)
+  INFO("[ Android dynamic linker (64-bit) ]");
+#else
+  INFO("[ Android dynamic linker (32-bit) ]");
+#endif
+
   // These should have been sanitized by __libc_init_AT_SECURE, but the test
   // doesn't cost us anything.
   const char* ldpath_env = nullptr;
   const char* ldpreload_env = nullptr;
   if (!getauxval(AT_SECURE)) {
     ldpath_env = getenv("LD_LIBRARY_PATH");
+    if (ldpath_env != nullptr) {
+      INFO("[ LD_LIBRARY_PATH set to \"%s\" ]", ldpath_env);
+    }
     ldpreload_env = getenv("LD_PRELOAD");
+    if (ldpreload_env != nullptr) {
+      INFO("[ LD_PRELOAD set to \"%s\" ]", ldpreload_env);
+    }
   }
 
-  INFO("[ android linker & debugger ]");
+  const char* executable_path = get_executable_path();
+  struct stat file_stat;
+  if (TEMP_FAILURE_RETRY(stat(executable_path, &file_stat)) != 0) {
+    __libc_fatal("unable to stat file for the executable \"%s\": %s", executable_path, strerror(errno));
+  }
 
-  soinfo* si = soinfo_alloc(args.argv[0], nullptr, 0, RTLD_GLOBAL);
+  soinfo* si = soinfo_alloc(&g_default_namespace, executable_path, &file_stat, 0, RTLD_GLOBAL);
   if (si == nullptr) {
-    exit(EXIT_FAILURE);
+    __libc_fatal("Couldn't allocate soinfo: out of memory?");
   }
 
   /* bootstrap the link map, the main exe always needs to be first */
   si->set_main_executable();
   link_map* map = &(si->link_map_head);
 
+  // Register the main executable and the linker upfront to have
+  // gdb aware of them before loading the rest of the dependency
+  // tree.
   map->l_addr = 0;
-  map->l_name = args.argv[0];
-  map->l_prev = nullptr;
-  map->l_next = nullptr;
-
-  _r_debug.r_map = map;
-  r_debug_tail = map;
-
+  map->l_name = const_cast<char*>(executable_path);
+  insert_link_map_into_debug_map(map);
   init_linker_info_for_gdb(linker_base);
 
   // Extract information passed from the kernel.
@@ -3213,8 +4242,8 @@
 
   ElfW(Ehdr)* elf_hdr = reinterpret_cast<ElfW(Ehdr)*>(si->base);
   if (elf_hdr->e_type != ET_DYN) {
-    __libc_format_fd(2, "error: only position independent executables (PIE) are supported.\n");
-    exit(EXIT_FAILURE);
+    __libc_fatal("\"%s\": error: only position independent executables (PIE) are supported.",
+                 args.argv[0]);
   }
 
   // Use LD_LIBRARY_PATH and LD_PRELOAD (but only if we aren't setuid/setgid).
@@ -3223,9 +4252,10 @@
 
   somain = si;
 
+  init_default_namespace();
+
   if (!si->prelink_image()) {
-    __libc_format_fd(2, "CANNOT LINK EXECUTABLE: %s\n", linker_get_error_buffer());
-    exit(EXIT_FAILURE);
+    __libc_fatal("CANNOT LINK EXECUTABLE \"%s\": %s", args.argv[0], linker_get_error_buffer());
   }
 
   // add somain to global group
@@ -3253,14 +4283,13 @@
   needed_library_name_list.copy_to_array(needed_library_names, needed_libraries_count);
 
   if (needed_libraries_count > 0 &&
-      !find_libraries(si, needed_library_names, needed_libraries_count, nullptr,
-          &g_ld_preloads, ld_preloads_count, RTLD_GLOBAL, nullptr)) {
-    __libc_format_fd(2, "CANNOT LINK EXECUTABLE: %s\n", linker_get_error_buffer());
-    exit(EXIT_FAILURE);
+      !find_libraries(&g_default_namespace, si, needed_library_names, needed_libraries_count,
+                      nullptr, &g_ld_preloads, ld_preloads_count, RTLD_GLOBAL, nullptr,
+                      /* add_as_children */ true)) {
+    __libc_fatal("CANNOT LINK EXECUTABLE \"%s\": %s", args.argv[0], linker_get_error_buffer());
   } else if (needed_libraries_count == 0) {
     if (!si->link_image(g_empty_list, soinfo::soinfo_list_t::make_list(si), nullptr)) {
-      __libc_format_fd(2, "CANNOT LINK EXECUTABLE: %s\n", linker_get_error_buffer());
-      exit(EXIT_FAILURE);
+      __libc_fatal("CANNOT LINK EXECUTABLE \"%s\": %s", args.argv[0], linker_get_error_buffer());
     }
     si->increment_ref_count();
   }
@@ -3322,7 +4351,7 @@
   fflush(stdout);
 #endif
 
-  TRACE("[ Ready to execute '%s' @ %p ]", si->get_realpath(), reinterpret_cast<void*>(si->entry));
+  TRACE("[ Ready to execute \"%s\" @ %p ]", si->get_realpath(), reinterpret_cast<void*>(si->entry));
   return si->entry;
 }
 
@@ -3350,7 +4379,9 @@
   return 0;
 }
 
-extern "C" void _start();
+static void __linker_cannot_link(KernelArgumentBlock& args) {
+  __libc_fatal("CANNOT LINK EXECUTABLE \"%s\": %s", args.argv[0], linker_get_error_buffer());
+}
 
 /*
  * This is the entry point for the linker, called from begin.S. This
@@ -3369,7 +4400,7 @@
   ElfW(Ehdr)* elf_hdr = reinterpret_cast<ElfW(Ehdr)*>(linker_addr);
   ElfW(Phdr)* phdr = reinterpret_cast<ElfW(Phdr)*>(linker_addr + elf_hdr->e_phoff);
 
-  soinfo linker_so(nullptr, nullptr, 0, 0);
+  soinfo linker_so(nullptr, nullptr, nullptr, 0, 0);
 
   // If the linker is not acting as PT_INTERP entry_point is equal to
   // _start. Which means that the linker is running as an executable and
@@ -3378,7 +4409,10 @@
   // This happens when user tries to run 'adb shell /system/bin/linker'
   // see also https://code.google.com/p/android/issues/detail?id=63174
   if (reinterpret_cast<ElfW(Addr)>(&_start) == entry_point) {
-    __libc_fatal("This is %s, the helper program for shared library executables.\n", args.argv[0]);
+    __libc_format_fd(STDOUT_FILENO,
+                     "This is %s, the helper program for shared library executables.\n",
+                     args.argv[0]);
+    exit(0);
   }
 
   linker_so.base = linker_addr;
@@ -3389,25 +4423,35 @@
   linker_so.phnum = elf_hdr->e_phnum;
   linker_so.set_linker_flag();
 
+  // Prelink the linker so we can access linker globals.
+  if (!linker_so.prelink_image()) __linker_cannot_link(args);
+
   // This might not be obvious... The reasons why we pass g_empty_list
   // in place of local_group here are (1) we do not really need it, because
   // linker is built with DT_SYMBOLIC and therefore relocates its symbols against
   // itself without having to look into local_group and (2) allocators
   // are not yet initialized, and therefore we cannot use linked_list.push_*
   // functions at this point.
-  if (!(linker_so.prelink_image() && linker_so.link_image(g_empty_list, g_empty_list, nullptr))) {
-    // It would be nice to print an error message, but if the linker
-    // can't link itself, there's no guarantee that we'll be able to
-    // call write() (because it involves a GOT reference). We may as
-    // well try though...
-    const char* msg = "CANNOT LINK EXECUTABLE: ";
-    write(2, msg, strlen(msg));
-    write(2, __linker_dl_err_buf, strlen(__linker_dl_err_buf));
-    write(2, "\n", 1);
-    _exit(EXIT_FAILURE);
-  }
+  if (!linker_so.link_image(g_empty_list, g_empty_list, nullptr)) __linker_cannot_link(args);
 
-  __libc_init_tls(args);
+#if defined(__i386__)
+  // On x86, we can't make system calls before this point.
+  // We can't move this up because this needs to assign to a global.
+  // Note that until we call __libc_init_main_thread below we have
+  // no TLS, so you shouldn't make a system call that can fail, because
+  // it will SEGV when it tries to set errno.
+  __libc_init_sysinfo(args);
+#endif
+
+  // Initialize the main thread (including TLS, so system calls really work).
+  __libc_init_main_thread(args);
+
+  // We didn't protect the linker's RELRO pages in link_image because we
+  // couldn't make system calls on x86 at that point, but we can now...
+  if (!linker_so.protect_relro()) __linker_cannot_link(args);
+
+  // Initialize the linker's static libc's globals
+  __libc_init_globals(args);
 
   // Initialize the linker's own global variables
   linker_so.call_constructors();
@@ -3417,13 +4461,14 @@
   // before get_libdl_info().
   solist = get_libdl_info();
   sonext = get_libdl_info();
+  g_default_namespace.add_soinfo(get_libdl_info());
 
   // We have successfully fixed our own relocations. It's safe to run
   // the main part of the linker now.
   args.abort_message_ptr = &g_abort_message;
   ElfW(Addr) start_address = __linker_init_post_relocation(args, linker_addr);
 
-  INFO("[ jumping to _start ]");
+  INFO("[ Jumping to _start (%p)... ]", reinterpret_cast<void*>(start_address));
 
   // Return the address that the calling assembly stub should jump to.
   return start_address;
diff --git a/linker/linker.h b/linker/linker.h
index 023b672..3ea601f 100644
--- a/linker/linker.h
+++ b/linker/linker.h
@@ -29,13 +29,15 @@
 #ifndef _LINKER_H_
 #define _LINKER_H_
 
+#include <dlfcn.h>
+#include <android/dlext.h>
 #include <elf.h>
 #include <inttypes.h>
 #include <link.h>
-#include <unistd.h>
-#include <android/dlext.h>
 #include <sys/stat.h>
+#include <unistd.h>
 
+#include "private/bionic_page.h"
 #include "private/libc_logging.h"
 #include "linked_list.h"
 
@@ -77,27 +79,19 @@
 #define ELF64_R_TYPE(info)  (((info) >> 56) & 0xff)
 #endif
 
-// Returns the address of the page containing address 'x'.
-#define PAGE_START(x)  ((x) & PAGE_MASK)
-
-// Returns the offset of address 'x' in its page.
-#define PAGE_OFFSET(x) ((x) & ~PAGE_MASK)
-
-// Returns the address of the next page after address 'x', unless 'x' is
-// itself at the start of a page.
-#define PAGE_END(x)    PAGE_START((x) + (PAGE_SIZE-1))
-
-#define FLAG_LINKED     0x00000001
-#define FLAG_EXE        0x00000004 // The main executable
-#define FLAG_LINKER     0x00000010 // The linker itself
-#define FLAG_GNU_HASH   0x00000040 // uses gnu hash
-#define FLAG_NEW_SOINFO 0x40000000 // new soinfo format
+#define FLAG_LINKED           0x00000001
+#define FLAG_EXE              0x00000004 // The main executable
+#define FLAG_LINKER           0x00000010 // The linker itself
+#define FLAG_GNU_HASH         0x00000040 // uses gnu hash
+#define FLAG_MAPPED_BY_CALLER 0x00000080 // the map is reserved by the caller
+                                         // and should not be unmapped
+#define FLAG_NEW_SOINFO       0x40000000 // new soinfo format
 
 #define SUPPORTED_DT_FLAGS_1 (DF_1_NOW | DF_1_GLOBAL | DF_1_NODELETE)
 
-#define SOINFO_VERSION 2
+#define SOINFO_VERSION 3
 
-#if defined(__work_around_b_19059885__)
+#if defined(__work_around_b_24465209__)
 #define SOINFO_NAME_LEN 128
 #endif
 
@@ -120,6 +114,16 @@
   DISALLOW_IMPLICIT_CONSTRUCTORS(SoinfoListAllocator);
 };
 
+class NamespaceListAllocator {
+ public:
+  static LinkedListEntry<android_namespace_t>* alloc();
+  static void free(LinkedListEntry<android_namespace_t>* entry);
+
+ private:
+  // unconstructable
+  DISALLOW_IMPLICIT_CONSTRUCTORS(NamespaceListAllocator);
+};
+
 class SymbolName {
  public:
   explicit SymbolName(const char* name)
@@ -144,7 +148,7 @@
 };
 
 struct version_info {
-  version_info() : elf_hash(0), name(nullptr), target_si(nullptr) {}
+  constexpr version_info() : elf_hash(0), name(nullptr), target_si(nullptr) {}
 
   uint32_t elf_hash;
   const char* name;
@@ -172,7 +176,8 @@
 struct soinfo {
  public:
   typedef LinkedList<soinfo, SoinfoListAllocator> soinfo_list_t;
-#if defined(__work_around_b_19059885__)
+  typedef LinkedList<android_namespace_t, NamespaceListAllocator> android_namespace_list_t;
+#if defined(__work_around_b_24465209__)
  private:
   char old_name_[SOINFO_NAME_LEN];
 #endif
@@ -183,13 +188,13 @@
   ElfW(Addr) base;
   size_t size;
 
-#if defined(__work_around_b_19059885__)
+#if defined(__work_around_b_24465209__)
   uint32_t unused1;  // DO NOT USE, maintained for compatibility.
 #endif
 
   ElfW(Dyn)* dynamic;
 
-#if defined(__work_around_b_19059885__)
+#if defined(__work_around_b_24465209__)
   uint32_t unused2; // DO NOT USE, maintained for compatibility
   uint32_t unused3; // DO NOT USE, maintained for compatibility
 #endif
@@ -250,7 +255,9 @@
   bool mips_relocate_got(const VersionTracker& version_tracker,
                          const soinfo_list_t& global_group,
                          const soinfo_list_t& local_group);
-
+#if !defined(__LP64__)
+  bool mips_check_and_adjust_fp_modes();
+#endif
 #endif
   size_t ref_count_;
  public:
@@ -268,7 +275,9 @@
   bool has_DT_SYMBOLIC;
 
  public:
-  soinfo(const char* name, const struct stat* file_stat, off64_t file_offset, int rtld_flags);
+  soinfo(android_namespace_t* ns, const char* name, const struct stat* file_stat,
+         off64_t file_offset, int rtld_flags);
+  ~soinfo();
 
   void call_constructors();
   void call_destructors();
@@ -276,6 +285,7 @@
   bool prelink_image();
   bool link_image(const soinfo_list_t& global_group, const soinfo_list_t& local_group,
                   const android_dlextinfo* extinfo);
+  bool protect_relro();
 
   void add_child(soinfo* child);
   void remove_all_links();
@@ -305,7 +315,7 @@
   bool is_gnu_hash() const;
 
   bool inline has_min_version(uint32_t min_version __unused) const {
-#if defined(__work_around_b_19059885__)
+#if defined(__work_around_b_24465209__)
     return (flags_ & FLAG_NEW_SOINFO) != 0 && version_ >= min_version;
 #else
     return true;
@@ -313,17 +323,20 @@
   }
 
   bool is_linked() const;
+  bool is_linker() const;
   bool is_main_executable() const;
 
   void set_linked();
   void set_linker_flag();
   void set_main_executable();
+  void set_nodelete();
 
   void increment_ref_count();
   size_t decrement_ref_count();
 
   soinfo* get_local_group_root() const;
 
+  void set_soname(const char* soname);
   const char* get_soname() const;
   const char* get_realpath() const;
   const ElfW(Versym)* get_versym(size_t n) const;
@@ -336,6 +349,18 @@
 
   uint32_t get_target_sdk_version() const;
 
+  void set_dt_runpath(const char *);
+  const std::vector<std::string>& get_dt_runpath() const;
+  android_namespace_t* get_primary_namespace();
+  void add_secondary_namespace(android_namespace_t* secondary_ns);
+
+  void set_mapped_by_caller(bool reserved_map);
+  bool is_mapped_by_caller() const;
+
+  uintptr_t get_handle() const;
+  void generate_handle();
+  void* to_handle();
+
  private:
   bool elf_lookup(SymbolName& symbol_name, const version_info* vi, uint32_t* symbol_index) const;
   ElfW(Sym)* elf_addr_lookup(const void* addr);
@@ -397,6 +422,12 @@
 
   uint32_t target_sdk_version_;
 
+  // version >= 3
+  std::vector<std::string> dt_runpath_;
+  android_namespace_t* primary_namespace_;
+  android_namespace_list_t secondary_namespaces_;
+  uintptr_t handle_;
+
   friend soinfo* get_libdl_info();
 };
 
@@ -418,19 +449,18 @@
 
 void do_android_get_LD_LIBRARY_PATH(char*, size_t);
 void do_android_update_LD_LIBRARY_PATH(const char* ld_library_path);
-soinfo* do_dlopen(const char* name, int flags, const android_dlextinfo* extinfo);
-void do_dlclose(soinfo* si);
+void* do_dlopen(const char* name, int flags, const android_dlextinfo* extinfo, void* caller_addr);
+int do_dlclose(void* handle);
 
 int do_dl_iterate_phdr(int (*cb)(dl_phdr_info* info, size_t size, void* data), void* data);
 
-const ElfW(Sym)* dlsym_linear_lookup(const char* name, soinfo** found, soinfo* caller, void* handle);
-soinfo* find_containing_library(const void* addr);
+bool do_dlsym(void* handle, const char* sym_name, const char* sym_ver,
+              void* caller_addr, void** symbol);
 
-const ElfW(Sym)* dlsym_handle_lookup(soinfo* si, soinfo** found, const char* name);
+int do_dladdr(const void* addr, Dl_info* info);
 
 void debuggerd_init();
 extern "C" abort_msg_t* g_abort_message;
-extern "C" void notify_gdb_of_libraries();
 
 char* linker_get_error_buffer();
 size_t linker_get_error_buffer_size();
@@ -438,4 +468,39 @@
 void set_application_target_sdk_version(uint32_t target);
 uint32_t get_application_target_sdk_version();
 
+enum {
+  /* A regular namespace is the namespace with a custom search path that does
+   * not impose any restrictions on the location of native libraries.
+   */
+  ANDROID_NAMESPACE_TYPE_REGULAR = 0,
+
+  /* An isolated namespace requires all the libraries to be on the search path
+   * or under permitted_when_isolated_path. The search path is the union of
+   * ld_library_path and default_library_path.
+   */
+  ANDROID_NAMESPACE_TYPE_ISOLATED = 1,
+
+  /* The shared namespace clones the list of libraries of the caller namespace upon creation
+   * which means that they are shared between namespaces - the caller namespace and the new one
+   * will use the same copy of a library if it was loaded prior to android_create_namespace call.
+   *
+   * Note that libraries loaded after the namespace is created will not be shared.
+   *
+   * Shared namespaces can be isolated or regular. Note that they do not inherit the search path nor
+   * permitted_path from the caller's namespace.
+   */
+  ANDROID_NAMESPACE_TYPE_SHARED = 2,
+  ANDROID_NAMESPACE_TYPE_SHARED_ISOLATED = ANDROID_NAMESPACE_TYPE_SHARED |
+                                           ANDROID_NAMESPACE_TYPE_ISOLATED,
+};
+
+bool init_namespaces(const char* public_ns_sonames, const char* anon_ns_library_path);
+android_namespace_t* create_namespace(const void* caller_addr,
+                                      const char* name,
+                                      const char* ld_library_path,
+                                      const char* default_library_path,
+                                      uint64_t type,
+                                      const char* permitted_when_isolated_path,
+                                      android_namespace_t* parent_namespace);
+
 #endif
diff --git a/linker/linker_allocator.cpp b/linker/linker_allocator.cpp
index 1b16cf1..57811d8 100644
--- a/linker/linker_allocator.cpp
+++ b/linker/linker_allocator.cpp
@@ -70,7 +70,7 @@
 }
 
 LinkerSmallObjectAllocator::LinkerSmallObjectAllocator()
-    : type_(0), name_(nullptr), block_size_(0), free_pages_cnt_(0), free_blocks_list_(nullptr) {}
+    : type_(0), block_size_(0), free_pages_cnt_(0), free_blocks_list_(nullptr) {}
 
 void* LinkerSmallObjectAllocator::alloc() {
   if (free_blocks_list_ == nullptr) {
@@ -156,10 +156,9 @@
   }
 }
 
-void LinkerSmallObjectAllocator::init(uint32_t type, size_t block_size, const char* name) {
+void LinkerSmallObjectAllocator::init(uint32_t type, size_t block_size) {
   type_ = type;
   block_size_ = block_size;
-  name_ = name;
 }
 
 linker_vector_t::iterator LinkerSmallObjectAllocator::find_page_record(void* ptr) {
@@ -189,13 +188,15 @@
 }
 
 void LinkerSmallObjectAllocator::alloc_page() {
+  static_assert(sizeof(page_info) % 16 == 0,
+                "sizeof(page_info) is not multiple of 16");
   void* map_ptr = mmap(nullptr, PAGE_SIZE,
       PROT_READ|PROT_WRITE, MAP_PRIVATE|MAP_ANONYMOUS, 0, 0);
   if (map_ptr == MAP_FAILED) {
     __libc_fatal("mmap failed");
   }
 
-  prctl(PR_SET_VMA, PR_SET_VMA_ANON_NAME, map_ptr, PAGE_SIZE, name_);
+  prctl(PR_SET_VMA, PR_SET_VMA_ANON_NAME, map_ptr, PAGE_SIZE, "linker_alloc_small_objects");
 
   memset(map_ptr, 0, PAGE_SIZE);
 
@@ -218,19 +219,9 @@
 
 
 LinkerMemoryAllocator::LinkerMemoryAllocator() {
-  static const char* allocator_names[kSmallObjectAllocatorsCount] = {
-    "linker_alloc_16", // 2^4
-    "linker_alloc_32", // 2^5
-    "linker_alloc_64", // and so on...
-    "linker_alloc_128",
-    "linker_alloc_256",
-    "linker_alloc_512",
-    "linker_alloc_1024", // 2^10
-  };
-
   for (size_t i = 0; i < kSmallObjectAllocatorsCount; ++i) {
     uint32_t type = i + kSmallObjectMinSizeLog2;
-    allocators_[i].init(type, 1 << type, allocator_names[i]);
+    allocators_[i].init(type, 1 << type);
   }
 }
 
diff --git a/linker/linker_allocator.h b/linker/linker_allocator.h
index 2adad56..22a337a 100644
--- a/linker/linker_allocator.h
+++ b/linker/linker_allocator.h
@@ -45,7 +45,7 @@
     // and allocator_addr for small ones.
     LinkerSmallObjectAllocator* allocator_addr;
   };
-};
+} __attribute__((aligned(16)));
 
 struct small_object_page_record {
   void* page_addr;
@@ -101,7 +101,7 @@
 class LinkerSmallObjectAllocator {
  public:
   LinkerSmallObjectAllocator();
-  void init(uint32_t type, size_t block_size, const char* name);
+  void init(uint32_t type, size_t block_size);
   void* alloc();
   void free(void* ptr);
 
@@ -113,7 +113,6 @@
   void create_page_record(void* page_addr, size_t free_blocks_cnt);
 
   uint32_t type_;
-  const char* name_;
   size_t block_size_;
 
   size_t free_pages_cnt_;
diff --git a/linker/linker_block_allocator.cpp b/linker/linker_block_allocator.cpp
index fc9a75b..23298a4 100644
--- a/linker/linker_block_allocator.cpp
+++ b/linker/linker_block_allocator.cpp
@@ -22,9 +22,14 @@
 
 #include "private/bionic_prctl.h"
 
+// the multiplier should be power of 2
+static constexpr size_t round_up(size_t size, size_t multiplier) {
+  return (size + (multiplier - 1)) & ~(multiplier-1);
+}
+
 struct LinkerBlockAllocatorPage {
   LinkerBlockAllocatorPage* next;
-  uint8_t bytes[PAGE_SIZE-sizeof(LinkerBlockAllocatorPage*)];
+  uint8_t bytes[PAGE_SIZE - 16] __attribute__((aligned(16)));
 };
 
 struct FreeBlockInfo {
@@ -33,7 +38,8 @@
 };
 
 LinkerBlockAllocator::LinkerBlockAllocator(size_t block_size)
-  : block_size_(block_size < sizeof(FreeBlockInfo) ? sizeof(FreeBlockInfo) : block_size),
+  : block_size_(
+      round_up(block_size < sizeof(FreeBlockInfo) ? sizeof(FreeBlockInfo) : block_size, 16)),
     page_list_(nullptr),
     free_block_list_(nullptr)
 {}
@@ -95,6 +101,9 @@
 }
 
 void LinkerBlockAllocator::create_new_page() {
+  static_assert(sizeof(LinkerBlockAllocatorPage) == PAGE_SIZE,
+                "Invalid sizeof(LinkerBlockAllocatorPage)");
+
   LinkerBlockAllocatorPage* page = reinterpret_cast<LinkerBlockAllocatorPage*>(
       mmap(nullptr, PAGE_SIZE, PROT_READ|PROT_WRITE, MAP_PRIVATE|MAP_ANONYMOUS, 0, 0));
 
diff --git a/linker/linker_debug.h b/linker/linker_debug.h
index 51f8d4c..5af9929 100644
--- a/linker/linker_debug.h
+++ b/linker/linker_debug.h
@@ -55,9 +55,17 @@
  *********************************************************************/
 
 #include "private/libc_logging.h"
+#include <unistd.h>
 
 __LIBC_HIDDEN__ extern int g_ld_debug_verbosity;
 
+#define CHECK(predicate) { \
+    if (!(predicate)) { \
+      __libc_fatal("%s:%d: %s CHECK '" #predicate "' failed", \
+          __FILE__, __LINE__, __FUNCTION__); \
+    } \
+  }
+
 #if LINKER_DEBUG_TO_LOG
 #define _PRINTVF(v, x...) \
     do { \
diff --git a/linker/linker_dlwarning.cpp b/linker/linker_dlwarning.cpp
new file mode 100644
index 0000000..c53ad66
--- /dev/null
+++ b/linker/linker_dlwarning.cpp
@@ -0,0 +1,47 @@
+/*
+ * Copyright (C) 2015 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 "linker_dlwarning.h"
+
+#include <strings.h>
+
+#include <string>
+
+static std::string current_msg;
+
+void add_dlwarning(const char* sopath, const char* message, const char* value) {
+  if (!current_msg.empty()) {
+    current_msg += '\n';
+  }
+
+  current_msg = current_msg + basename(sopath) + ": " + message;
+
+  if (value != nullptr) {
+    current_msg = current_msg + " \"" + value + "\"";
+  }
+}
+
+// Resets the current one (like dlerror but instead of
+// being thread-local it is process-local).
+void get_dlwarning(void* obj, void (*f)(void*, const char*)) {
+  if (current_msg.empty()) {
+    f(obj, nullptr);
+  } else {
+    std::string msg = current_msg;
+    current_msg.clear();
+    f(obj, msg.c_str());
+  }
+}
diff --git a/linker/linker_dlwarning.h b/linker/linker_dlwarning.h
new file mode 100644
index 0000000..0263c72
--- /dev/null
+++ b/linker/linker_dlwarning.h
@@ -0,0 +1,28 @@
+/*
+ * Copyright (C) 2016 The Android Open Source Project
+ *
+ * Licensed under the Apache License, Version 2.0 (the "License");
+ * you may not use this file except in compliance with the License.
+ * You may obtain a copy of the License at
+ *
+ *      http://www.apache.org/licenses/LICENSE-2.0
+ *
+ * Unless required by applicable law or agreed to in writing, software
+ * distributed under the License is distributed on an "AS IS" BASIS,
+ * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
+ * See the License for the specific language governing permissions and
+ * limitations under the License.
+ */
+
+#ifndef __LINKER_DLWARNING_H
+#define __LINKER_DLWARNING_H
+
+void add_dlwarning(const char* sopath, const char* message, const char* value = nullptr);
+
+// Resets the current one (like dlerror but instead of
+// being thread-local it is process-local). The user_data
+// is used to avoid forcing user into saving the message
+// to a global variable.
+void get_dlwarning(void* user_data, void (*f)(void*, const char*));
+
+#endif  /* __LINKER_DLWARNING_H */
diff --git a/linker/linker_gdb_support.cpp b/linker/linker_gdb_support.cpp
new file mode 100644
index 0000000..de74087
--- /dev/null
+++ b/linker/linker_gdb_support.cpp
@@ -0,0 +1,94 @@
+/*
+ * Copyright (C) 2016 The Android Open Source Project
+ *
+ * Licensed under the Apache License, Version 2.0 (the "License");
+ * you may not use this file except in compliance with the License.
+ * You may obtain a copy of the License at
+ *
+ *      http://www.apache.org/licenses/LICENSE-2.0
+ *
+ * Unless required by applicable law or agreed to in writing, software
+ * distributed under the License is distributed on an "AS IS" BASIS,
+ * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
+ * See the License for the specific language governing permissions and
+ * limitations under the License.
+ */
+
+#include "linker_gdb_support.h"
+
+#include <pthread.h>
+
+#include "private/ScopedPthreadMutexLocker.h"
+
+// This function is an empty stub where GDB locates a breakpoint to get notified
+// about linker activity.
+extern "C"
+void __attribute__((noinline)) __attribute__((visibility("default"))) rtld_db_dlactivity();
+
+r_debug _r_debug =
+    {1, nullptr, reinterpret_cast<uintptr_t>(&rtld_db_dlactivity), r_debug::RT_CONSISTENT, 0};
+
+static pthread_mutex_t g__r_debug_mutex = PTHREAD_MUTEX_INITIALIZER;
+static link_map* r_debug_tail = nullptr;
+
+void insert_link_map_into_debug_map(link_map* map) {
+  // Stick the new library at the end of the list.
+  // gdb tends to care more about libc than it does
+  // about leaf libraries, and ordering it this way
+  // reduces the back-and-forth over the wire.
+  if (r_debug_tail != nullptr) {
+    r_debug_tail->l_next = map;
+    map->l_prev = r_debug_tail;
+    map->l_next = nullptr;
+  } else {
+    _r_debug.r_map = map;
+    map->l_prev = nullptr;
+    map->l_next = nullptr;
+  }
+  r_debug_tail = map;
+}
+
+void remove_link_map_from_debug_map(link_map* map) {
+  if (r_debug_tail == map) {
+    r_debug_tail = map->l_prev;
+  }
+
+  if (map->l_prev) {
+    map->l_prev->l_next = map->l_next;
+  }
+  if (map->l_next) {
+    map->l_next->l_prev = map->l_prev;
+  }
+}
+
+void notify_gdb_of_load(link_map* map) {
+  ScopedPthreadMutexLocker locker(&g__r_debug_mutex);
+
+  _r_debug.r_state = r_debug::RT_ADD;
+  rtld_db_dlactivity();
+
+  insert_link_map_into_debug_map(map);
+
+  _r_debug.r_state = r_debug::RT_CONSISTENT;
+  rtld_db_dlactivity();
+}
+
+void notify_gdb_of_unload(link_map* map) {
+  ScopedPthreadMutexLocker locker(&g__r_debug_mutex);
+
+  _r_debug.r_state = r_debug::RT_DELETE;
+  rtld_db_dlactivity();
+
+  remove_link_map_from_debug_map(map);
+
+  _r_debug.r_state = r_debug::RT_CONSISTENT;
+  rtld_db_dlactivity();
+}
+
+void notify_gdb_of_libraries() {
+  _r_debug.r_state = r_debug::RT_ADD;
+  rtld_db_dlactivity();
+  _r_debug.r_state = r_debug::RT_CONSISTENT;
+  rtld_db_dlactivity();
+}
+
diff --git a/linker/linker_gdb_support.h b/linker/linker_gdb_support.h
new file mode 100644
index 0000000..2a590ba
--- /dev/null
+++ b/linker/linker_gdb_support.h
@@ -0,0 +1,34 @@
+/*
+ * Copyright (C) 2016 The Android Open Source Project
+ *
+ * Licensed under the Apache License, Version 2.0 (the "License");
+ * you may not use this file except in compliance with the License.
+ * You may obtain a copy of the License at
+ *
+ *      http://www.apache.org/licenses/LICENSE-2.0
+ *
+ * Unless required by applicable law or agreed to in writing, software
+ * distributed under the License is distributed on an "AS IS" BASIS,
+ * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
+ * See the License for the specific language governing permissions and
+ * limitations under the License.
+ */
+#ifndef __LINKER_GDB_SUPPORT_H
+#define __LINKER_GDB_SUPPORT_H
+
+#include <link.h>
+#include <sys/cdefs.h>
+
+__BEGIN_DECLS
+
+void insert_link_map_into_debug_map(link_map* map);
+void remove_link_map_from_debug_map(link_map* map);
+void notify_gdb_of_load(link_map* map);
+void notify_gdb_of_unload(link_map* map);
+void notify_gdb_of_libraries();
+
+extern struct r_debug _r_debug;
+
+__END_DECLS
+
+#endif
diff --git a/linker/linker_libc_support.c b/linker/linker_libc_support.c
index 4c49384..77a0252 100644
--- a/linker/linker_libc_support.c
+++ b/linker/linker_libc_support.c
@@ -15,7 +15,9 @@
  */
 
 #include "../libc/arch-common/bionic/__dso_handle.h"
+#include "../libc/arch-common/bionic/pthread_atfork.h"
 
 int atexit(void (*function)(void) __attribute__((__unused__))) {
   return -1;
 }
+
diff --git a/linker/linker_mapped_file_fragment.cpp b/linker/linker_mapped_file_fragment.cpp
new file mode 100644
index 0000000..27c1c69
--- /dev/null
+++ b/linker/linker_mapped_file_fragment.cpp
@@ -0,0 +1,63 @@
+/*
+ * Copyright (C) 2015 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 "linker_mapped_file_fragment.h"
+#include "linker_debug.h"
+#include "linker_utils.h"
+
+#include <inttypes.h>
+#include <stdlib.h>
+#include <sys/mman.h>
+#include <unistd.h>
+
+MappedFileFragment::MappedFileFragment() : map_start_(nullptr), map_size_(0),
+                                           data_(nullptr), size_ (0)
+{ }
+
+MappedFileFragment::~MappedFileFragment() {
+  if (map_start_ != nullptr) {
+    munmap(map_start_, map_size_);
+  }
+}
+
+bool MappedFileFragment::Map(int fd, off64_t base_offset, size_t elf_offset, size_t size) {
+  off64_t offset;
+  CHECK(safe_add(&offset, base_offset, elf_offset));
+
+  off64_t page_min = page_start(offset);
+  off64_t end_offset;
+
+  CHECK(safe_add(&end_offset, offset, size));
+  CHECK(safe_add(&end_offset, end_offset, page_offset(offset)));
+
+  size_t map_size = static_cast<size_t>(end_offset - page_min);
+  CHECK(map_size >= size);
+
+  uint8_t* map_start = static_cast<uint8_t*>(
+                          mmap64(nullptr, map_size, PROT_READ, MAP_PRIVATE, fd, page_min));
+
+  if (map_start == MAP_FAILED) {
+    return false;
+  }
+
+  map_start_ = map_start;
+  map_size_ = map_size;
+
+  data_ = map_start + page_offset(offset);
+  size_ = size;
+
+  return true;
+}
diff --git a/linker/linker_mapped_file_fragment.h b/linker/linker_mapped_file_fragment.h
new file mode 100644
index 0000000..91bd077
--- /dev/null
+++ b/linker/linker_mapped_file_fragment.h
@@ -0,0 +1,41 @@
+/*
+ * Copyright (C) 2015 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 LINKER_MAPPED_FILE_FRAGMENT_H
+#define LINKER_MAPPED_FILE_FRAGMENT_H
+
+#include <unistd.h>
+
+#include "private/bionic_macros.h"
+
+class MappedFileFragment {
+ public:
+  MappedFileFragment();
+  ~MappedFileFragment();
+
+  bool Map(int fd, off64_t base_offset, size_t elf_offset, size_t size);
+
+  void* data() const { return data_; }
+  size_t size() const { return size_; }
+ private:
+  void* map_start_;
+  size_t map_size_;
+  void* data_;
+  size_t size_;
+
+  DISALLOW_COPY_AND_ASSIGN(MappedFileFragment);
+};
+
+#endif /* LINKER_MAPPED_FILE_FRAGMENT_H */
diff --git a/linker/linker_mips.cpp b/linker/linker_mips.cpp
index a7a4bc0..2d565d7 100644
--- a/linker/linker_mips.cpp
+++ b/linker/linker_mips.cpp
@@ -26,8 +26,13 @@
  * SUCH DAMAGE.
  */
 
+#if !defined(__LP64__) && __mips_isa_rev >= 5
+#include <sys/prctl.h>
+#endif
+
 #include "linker.h"
 #include "linker_debug.h"
+#include "linker_phdr.h"
 #include "linker_relocs.h"
 #include "linker_reloc_iterators.h"
 #include "linker_sleb128.h"
@@ -62,7 +67,7 @@
     ElfW(Addr) sym_addr = 0;
     const char* sym_name = nullptr;
 
-    DEBUG("Processing '%s' relocation at index %zd", get_soname(), idx);
+    DEBUG("Processing \"%s\" relocation at index %zd", get_realpath(), idx);
     if (type == R_GENERIC_NONE) {
       continue;
     }
@@ -84,7 +89,8 @@
 
       if (s == nullptr) {
         // mips does not support relocation with weak-undefined symbols
-        DL_ERR("cannot locate symbol \"%s\" referenced by \"%s\"...", sym_name, get_soname());
+        DL_ERR("cannot locate symbol \"%s\" referenced by \"%s\"...",
+               sym_name, get_realpath());
         return false;
       } else {
         // We got a definition.
@@ -171,20 +177,22 @@
       }
     } else if (st_visibility == STV_PROTECTED) {
       if (local_sym->st_value == 0) {
-        DL_ERR("%s: invalid symbol \"%s\" (PROTECTED/UNDEFINED) ", get_soname(), sym_name);
+        DL_ERR("%s: invalid symbol \"%s\" (PROTECTED/UNDEFINED) ",
+               get_realpath(), sym_name);
         return false;
       }
       s = local_sym;
       lsi = this;
     } else {
-      DL_ERR("%s: invalid symbol \"%s\" visibility: 0x%x", get_soname(), sym_name, st_visibility);
+      DL_ERR("%s: invalid symbol \"%s\" visibility: 0x%x",
+             get_realpath(), sym_name, st_visibility);
       return false;
     }
 
     if (s == nullptr) {
       // We only allow an undefined symbol if this is a weak reference.
       if (ELF_ST_BIND(local_sym->st_info) != STB_WEAK) {
-        DL_ERR("%s: cannot locate \"%s\"...", get_soname(), sym_name);
+        DL_ERR("%s: cannot locate \"%s\"...", get_realpath(), sym_name);
         return false;
       }
       *got = 0;
@@ -198,3 +206,134 @@
   return true;
 }
 
+#if !defined(__LP64__)
+
+// Checks for mips32's various floating point abis.
+// (Mips64 Android has a single floating point abi and doesn't need any checks)
+
+// Linux kernel has declarations similar to the following
+//   in <linux>/arch/mips/include/asm/elf.h,
+// but that non-uapi internal header file will never be imported
+// into bionic's kernel headers.
+
+#define PT_MIPS_ABIFLAGS  0x70000003	// is .MIPS.abiflags segment
+
+struct mips_elf_abiflags_v0 {
+  uint16_t version;  // version of this structure
+  uint8_t  isa_level, isa_rev, gpr_size, cpr1_size, cpr2_size;
+  uint8_t  fp_abi;  // mips32 ABI variants for floating point
+  uint32_t isa_ext, ases, flags1, flags2;
+};
+
+// Bits of flags1:
+#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_DOUBLE 1  // -mdouble-float
+#define MIPS_ABI_FP_XX     5  // -mfpxx
+#define MIPS_ABI_FP_64A    7  // -mips32r* -mfp64 -mno-odd-spreg
+
+#if __mips_isa_rev >= 5
+static bool mips_fre_mode_on = false;  // have set FRE=1 mode for process
+#endif
+
+bool soinfo::mips_check_and_adjust_fp_modes() {
+  mips_elf_abiflags_v0* abiflags = nullptr;
+  int mips_fpabi;
+
+  // Find soinfo's optional .MIPS.abiflags segment
+  for (size_t i = 0; i<phnum; ++i) {
+    const ElfW(Phdr)& ph = phdr[i];
+    if (ph.p_type == PT_MIPS_ABIFLAGS) {
+      if (ph.p_filesz < sizeof (mips_elf_abiflags_v0)) {
+        DL_ERR("Corrupt PT_MIPS_ABIFLAGS header found \"%s\"", get_realpath());
+        return false;
+      }
+      abiflags = reinterpret_cast<mips_elf_abiflags_v0*>(ph.p_vaddr + load_bias);
+      break;
+    }
+  }
+
+  // FP ABI-variant compatibility checks for MIPS o32 ABI
+  if (abiflags == nullptr) {
+    // Old compilers and some translators don't emit the new abiflags section.
+    const char* filename = get_realpath();
+    size_t len = strlen(filename);
+    if (len > 4 && (strcmp(filename+len-4, ".dex") == 0 ||
+                    strcmp(filename+len-4, ".oat") == 0   )) {
+      // Assume dex2oat is compatible with target
+      mips_fpabi = MIPS_ABI_FP_XX;
+    } else {
+      // Old Android compilers used -mfp32 -mdouble-float -modd-spreg defaults,
+      //   ie FP32 aka DOUBLE, using FR=0 mode fpregs & odd single-prec fpregs
+      mips_fpabi = MIPS_ABI_FP_DOUBLE;
+    }
+  } else {
+    mips_fpabi = abiflags->fp_abi;
+    if ( (abiflags->flags1 & MIPS_AFL_FLAGS1_ODDSPREG)
+         && (mips_fpabi == MIPS_ABI_FP_XX ||
+             mips_fpabi == MIPS_ABI_FP_64A   ) ) {
+      // Android supports fewer cases than Linux
+      DL_ERR("Unsupported odd-single-prec FloatPt reg uses in \"%s\"",
+             get_realpath());
+      return false;
+    }
+  }
+  if (!(mips_fpabi == MIPS_ABI_FP_DOUBLE ||
+#if __mips_isa_rev >= 5
+        mips_fpabi == MIPS_ABI_FP_64A    ||
+#endif
+        mips_fpabi == MIPS_ABI_FP_XX       )) {
+    DL_ERR("Unsupported MIPS32 FloatPt ABI %d found in \"%s\"",
+           mips_fpabi, get_realpath());
+    return false;
+  }
+
+#if __mips_isa_rev >= 5
+  // Adjust process's FR Emulation mode, if needed
+  //
+  // On Mips R5 & R6, Android runs continuously in FR=1 64bit-fpreg mode.
+  // NDK mips32 apps compiled with old compilers generate FP32 code
+  //   which expects FR=0 32-bit fp registers.
+  // NDK mips32 apps compiled with newer compilers generate modeless
+  //   FPXX code which runs on both FR=0 and FR=1 modes.
+  // Android itself is compiled in FP64A which requires FR=1 mode.
+  // FP32, FPXX, and FP64A all interlink okay, without dynamic FR mode
+  //   changes during calls.  For details, see
+  //   http://dmz-portal.mips.com/wiki/MIPS_O32_ABI_-_FR0_and_FR1_Interlinking
+  // Processes containing FR32 FR=0 code are run via kernel software assist,
+  //   which maps all odd-numbered single-precision reg refs onto the
+  //   upper half of the paired even-numbered double-precision reg.
+  // FRE=1 triggers traps to the kernel's emulator on every single-precision
+  //   fp op (for both odd and even-numbered registers).
+  // Turning on FRE=1 traps is done at most once per process, simultanously
+  //   for all threads of that process, when dlopen discovers FP32 code.
+  // The kernel repacks threads' registers when FRE mode is turn on or off.
+  //   These asynchronous adjustments are wrong if any thread was executing
+  //   FPXX code using odd-numbered single-precision regs.
+  // Current Android compilers default to the -mno-oddspreg option,
+  //   and this requirement is checked by Android's dlopen.
+  //   So FRE can always be safely turned on for FP32, anytime.
+  // Deferred enhancement: Allow loading of odd-spreg FPXX modules.
+
+  if (mips_fpabi == MIPS_ABI_FP_DOUBLE && !mips_fre_mode_on) {
+    // Turn on FRE mode, which emulates mode-sensitive FR=0 code on FR=1
+    //   register files, by trapping to kernel on refs to single-precision regs
+    if (prctl(PR_SET_FP_MODE, PR_FP_MODE_FR|PR_FP_MODE_FRE)) {
+      DL_ERR("Kernel or cpu failed to set FRE mode required for running \"%s\"",
+             get_realpath());
+      return false;
+    }
+    DL_WARN("Using FRE=1 mode to run \"%s\"", get_realpath());
+    mips_fre_mode_on = true;  // Avoid future redundant mode-switch calls
+    // FRE mode is never turned back off.
+    // Deferred enhancement:
+    //   Reset FRE mode when dlclose() removes all FP32 modules
+  }
+#else
+  // Android runs continuously in FR=0 32bit-fpreg mode.
+#endif  // __mips_isa_rev
+  return true;
+}
+
+#endif  // __LP64___
diff --git a/linker/linker_phdr.cpp b/linker/linker_phdr.cpp
index 30118e3..136e432 100644
--- a/linker/linker_phdr.cpp
+++ b/linker/linker_phdr.cpp
@@ -37,6 +37,9 @@
 
 #include "linker.h"
 #include "linker_debug.h"
+#include "linker_utils.h"
+
+#include "private/bionic_prctl.h"
 
 static int GetTargetElfMachine() {
 #if defined(__arm__)
@@ -133,37 +136,60 @@
                                       MAYBE_MAP_FLAG((x), PF_R, PROT_READ) | \
                                       MAYBE_MAP_FLAG((x), PF_W, PROT_WRITE))
 
-ElfReader::ElfReader(const char* name, int fd, off64_t file_offset, off64_t file_size)
-    : name_(name), fd_(fd), file_offset_(file_offset), file_size_(file_size),
-      phdr_num_(0), phdr_mmap_(nullptr), phdr_table_(nullptr), phdr_size_(0),
-      load_start_(nullptr), load_size_(0), load_bias_(0),
-      loaded_phdr_(nullptr) {
+ElfReader::ElfReader()
+    : did_read_(false), did_load_(false), fd_(-1), file_offset_(0), file_size_(0), phdr_num_(0),
+      phdr_table_(nullptr), shdr_table_(nullptr), shdr_num_(0), dynamic_(nullptr), strtab_(nullptr),
+      strtab_size_(0), load_start_(nullptr), load_size_(0), load_bias_(0), loaded_phdr_(nullptr),
+      mapped_by_caller_(false) {
 }
 
-ElfReader::~ElfReader() {
-  if (phdr_mmap_ != nullptr) {
-    munmap(phdr_mmap_, phdr_size_);
+bool ElfReader::Read(const char* name, int fd, off64_t file_offset, off64_t file_size) {
+  CHECK(!did_read_);
+  CHECK(!did_load_);
+  name_ = name;
+  fd_ = fd;
+  file_offset_ = file_offset;
+  file_size_ = file_size;
+
+  if (ReadElfHeader() &&
+      VerifyElfHeader() &&
+      ReadProgramHeaders() &&
+      ReadSectionHeaders() &&
+      ReadDynamicSection()) {
+    did_read_ = true;
   }
+
+  return did_read_;
 }
 
 bool ElfReader::Load(const android_dlextinfo* extinfo) {
-  return ReadElfHeader() &&
-         VerifyElfHeader() &&
-         ReadProgramHeader() &&
-         ReserveAddressSpace(extinfo) &&
-         LoadSegments() &&
-         FindPhdr();
+  CHECK(did_read_);
+  CHECK(!did_load_);
+  if (ReserveAddressSpace(extinfo) &&
+      LoadSegments() &&
+      FindPhdr()) {
+    did_load_ = true;
+  }
+
+  return did_load_;
+}
+
+const char* ElfReader::get_string(ElfW(Word) index) const {
+  CHECK(strtab_ != nullptr);
+  CHECK(index < strtab_size_);
+
+  return strtab_ + index;
 }
 
 bool ElfReader::ReadElfHeader() {
   ssize_t rc = TEMP_FAILURE_RETRY(pread64(fd_, &header_, sizeof(header_), file_offset_));
   if (rc < 0) {
-    DL_ERR("can't read file \"%s\": %s", name_, strerror(errno));
+    DL_ERR("can't read file \"%s\": %s", name_.c_str(), strerror(errno));
     return false;
   }
 
   if (rc != sizeof(header_)) {
-    DL_ERR("\"%s\" is too small to be an ELF executable: only found %zd bytes", name_,
+    DL_ERR("\"%s\" is too small to be an ELF executable: only found %zd bytes", name_.c_str(),
            static_cast<size_t>(rc));
     return false;
   }
@@ -172,7 +198,7 @@
 
 bool ElfReader::VerifyElfHeader() {
   if (memcmp(header_.e_ident, ELFMAG, SELFMAG) != 0) {
-    DL_ERR("\"%s\" has bad ELF magic", name_);
+    DL_ERR("\"%s\" has bad ELF magic", name_.c_str());
     return false;
   }
 
@@ -182,73 +208,161 @@
 #if defined(__LP64__)
   if (elf_class != ELFCLASS64) {
     if (elf_class == ELFCLASS32) {
-      DL_ERR("\"%s\" is 32-bit instead of 64-bit", name_);
+      DL_ERR("\"%s\" is 32-bit instead of 64-bit", name_.c_str());
     } else {
-      DL_ERR("\"%s\" has unknown ELF class: %d", name_, elf_class);
+      DL_ERR("\"%s\" has unknown ELF class: %d", name_.c_str(), elf_class);
     }
     return false;
   }
 #else
   if (elf_class != ELFCLASS32) {
     if (elf_class == ELFCLASS64) {
-      DL_ERR("\"%s\" is 64-bit instead of 32-bit", name_);
+      DL_ERR("\"%s\" is 64-bit instead of 32-bit", name_.c_str());
     } else {
-      DL_ERR("\"%s\" has unknown ELF class: %d", name_, elf_class);
+      DL_ERR("\"%s\" has unknown ELF class: %d", name_.c_str(), elf_class);
     }
     return false;
   }
 #endif
 
   if (header_.e_ident[EI_DATA] != ELFDATA2LSB) {
-    DL_ERR("\"%s\" not little-endian: %d", name_, header_.e_ident[EI_DATA]);
+    DL_ERR("\"%s\" not little-endian: %d", name_.c_str(), header_.e_ident[EI_DATA]);
     return false;
   }
 
   if (header_.e_type != ET_DYN) {
-    DL_ERR("\"%s\" has unexpected e_type: %d", name_, header_.e_type);
+    DL_ERR("\"%s\" has unexpected e_type: %d", name_.c_str(), header_.e_type);
     return false;
   }
 
   if (header_.e_version != EV_CURRENT) {
-    DL_ERR("\"%s\" has unexpected e_version: %d", name_, header_.e_version);
+    DL_ERR("\"%s\" has unexpected e_version: %d", name_.c_str(), header_.e_version);
     return false;
   }
 
   if (header_.e_machine != GetTargetElfMachine()) {
-    DL_ERR("\"%s\" has unexpected e_machine: %d", name_, header_.e_machine);
+    DL_ERR("\"%s\" has unexpected e_machine: %d", name_.c_str(), header_.e_machine);
     return false;
   }
 
   return true;
 }
 
+bool ElfReader::CheckFileRange(ElfW(Addr) offset, size_t size) {
+  off64_t range_start;
+  off64_t range_end;
+
+  return safe_add(&range_start, file_offset_, offset) &&
+         safe_add(&range_end, range_start, size) &&
+         range_start < file_size_ &&
+         range_end <= file_size_;
+}
+
 // Loads the program header table from an ELF file into a read-only private
 // anonymous mmap-ed block.
-bool ElfReader::ReadProgramHeader() {
+bool ElfReader::ReadProgramHeaders() {
   phdr_num_ = header_.e_phnum;
 
   // Like the kernel, we only accept program header tables that
   // are smaller than 64KiB.
   if (phdr_num_ < 1 || phdr_num_ > 65536/sizeof(ElfW(Phdr))) {
-    DL_ERR("\"%s\" has invalid e_phnum: %zd", name_, phdr_num_);
+    DL_ERR("\"%s\" has invalid e_phnum: %zd", name_.c_str(), phdr_num_);
     return false;
   }
 
-  ElfW(Addr) page_min = PAGE_START(header_.e_phoff);
-  ElfW(Addr) page_max = PAGE_END(header_.e_phoff + (phdr_num_ * sizeof(ElfW(Phdr))));
-  ElfW(Addr) page_offset = PAGE_OFFSET(header_.e_phoff);
-
-  phdr_size_ = page_max - page_min;
-
-  void* mmap_result =
-      mmap64(nullptr, phdr_size_, PROT_READ, MAP_PRIVATE, fd_, file_offset_ + page_min);
-  if (mmap_result == MAP_FAILED) {
-    DL_ERR("\"%s\" phdr mmap failed: %s", name_, strerror(errno));
+  // Boundary checks
+  size_t size = phdr_num_ * sizeof(ElfW(Phdr));
+  if (!CheckFileRange(header_.e_phoff, size)) {
+    DL_ERR("\"%s\" has invalid phdr offset/size", name_.c_str());
     return false;
   }
 
-  phdr_mmap_ = mmap_result;
-  phdr_table_ = reinterpret_cast<ElfW(Phdr)*>(reinterpret_cast<char*>(mmap_result) + page_offset);
+  if (!phdr_fragment_.Map(fd_, file_offset_, header_.e_phoff, size)) {
+    DL_ERR("\"%s\" phdr mmap failed: %s", name_.c_str(), strerror(errno));
+    return false;
+  }
+
+  phdr_table_ = static_cast<ElfW(Phdr)*>(phdr_fragment_.data());
+  return true;
+}
+
+bool ElfReader::ReadSectionHeaders() {
+  shdr_num_ = header_.e_shnum;
+
+  if (shdr_num_ == 0) {
+    DL_ERR("\"%s\" has no section headers", name_.c_str());
+    return false;
+  }
+
+  size_t size = shdr_num_ * sizeof(ElfW(Shdr));
+  if (!CheckFileRange(header_.e_shoff, size)) {
+    DL_ERR("\"%s\" has invalid shdr offset/size", name_.c_str());
+    return false;
+  }
+
+  if (!shdr_fragment_.Map(fd_, file_offset_, header_.e_shoff, size)) {
+    DL_ERR("\"%s\" shdr mmap failed: %s", name_.c_str(), strerror(errno));
+    return false;
+  }
+
+  shdr_table_ = static_cast<const ElfW(Shdr)*>(shdr_fragment_.data());
+  return true;
+}
+
+bool ElfReader::ReadDynamicSection() {
+  // 1. Find .dynamic section (in section headers)
+  const ElfW(Shdr)* dynamic_shdr = nullptr;
+  for (size_t i = 0; i < shdr_num_; ++i) {
+    if (shdr_table_[i].sh_type == SHT_DYNAMIC) {
+      dynamic_shdr = &shdr_table_ [i];
+      break;
+    }
+  }
+
+  if (dynamic_shdr == nullptr) {
+    DL_ERR("\"%s\" .dynamic section header was not found", name_.c_str());
+    return false;
+  }
+
+  if (dynamic_shdr->sh_link >= shdr_num_) {
+    DL_ERR("\"%s\" .dynamic section has invalid sh_link: %d", name_.c_str(), dynamic_shdr->sh_link);
+    return false;
+  }
+
+  const ElfW(Shdr)* strtab_shdr = &shdr_table_[dynamic_shdr->sh_link];
+
+  if (strtab_shdr->sh_type != SHT_STRTAB) {
+    DL_ERR("\"%s\" .dynamic section has invalid link(%d) sh_type: %d (expected SHT_STRTAB)",
+           name_.c_str(), dynamic_shdr->sh_link, strtab_shdr->sh_type);
+    return false;
+  }
+
+  if (!CheckFileRange(dynamic_shdr->sh_offset, dynamic_shdr->sh_size)) {
+    DL_ERR("\"%s\" has invalid offset/size of .dynamic section", name_.c_str());
+    PRINT("\"%s\" has invalid offset/size of .dynamic section", name_.c_str());
+    return false;
+  }
+
+  if (!dynamic_fragment_.Map(fd_, file_offset_, dynamic_shdr->sh_offset, dynamic_shdr->sh_size)) {
+    DL_ERR("\"%s\" dynamic section mmap failed: %s", name_.c_str(), strerror(errno));
+    return false;
+  }
+
+  dynamic_ = static_cast<const ElfW(Dyn)*>(dynamic_fragment_.data());
+
+  if (!CheckFileRange(strtab_shdr->sh_offset, strtab_shdr->sh_size)) {
+    DL_ERR("\"%s\" has invalid offset/size of the .strtab section linked from .dynamic section",
+           name_.c_str());
+    return false;
+  }
+
+  if (!strtab_fragment_.Map(fd_, file_offset_, strtab_shdr->sh_offset, strtab_shdr->sh_size)) {
+    DL_ERR("\"%s\" strtab section mmap failed: %s", name_.c_str(), strerror(errno));
+    return false;
+  }
+
+  strtab_ = static_cast<const char*>(strtab_fragment_.data());
+  strtab_size_ = strtab_fragment_.size();
   return true;
 }
 
@@ -308,7 +422,7 @@
   ElfW(Addr) min_vaddr;
   load_size_ = phdr_table_get_load_size(phdr_table_, phdr_num_, &min_vaddr);
   if (load_size_ == 0) {
-    DL_ERR("\"%s\" has no loadable segments", name_);
+    DL_ERR("\"%s\" has no loadable segments", name_.c_str());
     return false;
   }
 
@@ -316,8 +430,9 @@
   void* start;
   size_t reserved_size = 0;
   bool reserved_hint = true;
+  bool strict_hint = false;
   // Assume position independent executable by default.
-  uint8_t* mmap_hint = nullptr;
+  void* mmap_hint = nullptr;
 
   if (extinfo != nullptr) {
     if (extinfo->flags & ANDROID_DLEXT_RESERVED_ADDRESS) {
@@ -327,25 +442,35 @@
       reserved_size = extinfo->reserved_size;
     }
 
-    if ((extinfo->flags & ANDROID_DLEXT_FORCE_FIXED_VADDR) != 0) {
+    if (addr != nullptr && (extinfo->flags & ANDROID_DLEXT_FORCE_FIXED_VADDR) != 0) {
       mmap_hint = addr;
+    } else if ((extinfo->flags & ANDROID_DLEXT_LOAD_AT_FIXED_ADDRESS) != 0) {
+      mmap_hint = extinfo->reserved_addr;
+      strict_hint = true;
     }
   }
 
   if (load_size_ > reserved_size) {
     if (!reserved_hint) {
       DL_ERR("reserved address space %zd smaller than %zd bytes needed for \"%s\"",
-             reserved_size - load_size_, load_size_, name_);
+             reserved_size - load_size_, load_size_, name_.c_str());
       return false;
     }
     int mmap_flags = MAP_PRIVATE | MAP_ANONYMOUS;
     start = mmap(mmap_hint, load_size_, PROT_NONE, mmap_flags, -1, 0);
     if (start == MAP_FAILED) {
-      DL_ERR("couldn't reserve %zd bytes of address space for \"%s\"", load_size_, name_);
+      DL_ERR("couldn't reserve %zd bytes of address space for \"%s\"", load_size_, name_.c_str());
+      return false;
+    }
+    if (strict_hint && (start != mmap_hint)) {
+      munmap(start, load_size_);
+      DL_ERR("couldn't reserve %zd bytes of address space at %p for \"%s\"",
+             load_size_, mmap_hint, name_.c_str());
       return false;
     }
   } else {
     start = extinfo->reserved_addr;
+    mapped_by_caller_ = true;
   }
 
   load_start_ = start;
@@ -378,14 +503,14 @@
     ElfW(Addr) file_length = file_end - file_page_start;
 
     if (file_size_ <= 0) {
-      DL_ERR("\"%s\" invalid file size: %" PRId64, name_, file_size_);
+      DL_ERR("\"%s\" invalid file size: %" PRId64, name_.c_str(), file_size_);
       return false;
     }
 
-    if (file_end >= static_cast<size_t>(file_size_)) {
+    if (file_end > static_cast<size_t>(file_size_)) {
       DL_ERR("invalid ELF file \"%s\" load segment[%zd]:"
           " p_offset (%p) + p_filesz (%p) ( = %p) past end of file (0x%" PRIx64 ")",
-          name_, i, reinterpret_cast<void*>(phdr->p_offset),
+          name_.c_str(), i, reinterpret_cast<void*>(phdr->p_offset),
           reinterpret_cast<void*>(phdr->p_filesz),
           reinterpret_cast<void*>(file_end), file_size_);
       return false;
@@ -399,7 +524,7 @@
                             fd_,
                             file_offset_ + file_page_start);
       if (seg_addr == MAP_FAILED) {
-        DL_ERR("couldn't map \"%s\" segment %zd: %s", name_, i, strerror(errno));
+        DL_ERR("couldn't map \"%s\" segment %zd: %s", name_.c_str(), i, strerror(errno));
         return false;
       }
     }
@@ -417,16 +542,19 @@
     // between them. This is done by using a private anonymous
     // map for all extra pages.
     if (seg_page_end > seg_file_end) {
+      size_t zeromap_size = seg_page_end - seg_file_end;
       void* zeromap = mmap(reinterpret_cast<void*>(seg_file_end),
-                           seg_page_end - seg_file_end,
+                           zeromap_size,
                            PFLAGS_TO_PROT(phdr->p_flags),
                            MAP_FIXED|MAP_ANONYMOUS|MAP_PRIVATE,
                            -1,
                            0);
       if (zeromap == MAP_FAILED) {
-        DL_ERR("couldn't zero fill \"%s\" gap: %s", name_, strerror(errno));
+        DL_ERR("couldn't zero fill \"%s\" gap: %s", name_.c_str(), strerror(errno));
         return false;
       }
+
+      prctl(PR_SET_VMA, PR_SET_VMA_ANON_NAME, zeromap, zeromap_size, ".bss");
     }
   }
   return true;
@@ -771,6 +899,26 @@
   }
 }
 
+/* Return the program interpreter string, or nullptr if missing.
+ *
+ * Input:
+ *   phdr_table  -> program header table
+ *   phdr_count  -> number of entries in tables
+ *   load_bias   -> load bias
+ * Return:
+ *   pointer to the program interpreter string.
+ */
+const char* phdr_table_get_interpreter_name(const ElfW(Phdr) * phdr_table, size_t phdr_count,
+                                            ElfW(Addr) load_bias) {
+  for (size_t i = 0; i<phdr_count; ++i) {
+    const ElfW(Phdr)& phdr = phdr_table[i];
+    if (phdr.p_type == PT_INTERP) {
+      return reinterpret_cast<const char*>(load_bias + phdr.p_vaddr);
+    }
+  }
+  return nullptr;
+}
+
 // Sets loaded_phdr_ to the address of the program header table as it appears
 // in the loaded segments in memory. This is in contrast with phdr_table_,
 // which is temporary and will be released before the library is relocated.
@@ -799,7 +947,7 @@
     }
   }
 
-  DL_ERR("can't find loaded phdr for \"%s\"", name_);
+  DL_ERR("can't find loaded phdr for \"%s\"", name_.c_str());
   return false;
 }
 
@@ -809,7 +957,7 @@
 bool ElfReader::CheckPhdr(ElfW(Addr) loaded) {
   const ElfW(Phdr)* phdr_limit = phdr_table_ + phdr_num_;
   ElfW(Addr) loaded_end = loaded + (phdr_num_ * sizeof(ElfW(Phdr)));
-  for (ElfW(Phdr)* phdr = phdr_table_; phdr < phdr_limit; ++phdr) {
+  for (const ElfW(Phdr)* phdr = phdr_table_; phdr < phdr_limit; ++phdr) {
     if (phdr->p_type != PT_LOAD) {
       continue;
     }
@@ -820,6 +968,7 @@
       return true;
     }
   }
-  DL_ERR("\"%s\" loaded phdr %p not in loadable segment", name_, reinterpret_cast<void*>(loaded));
+  DL_ERR("\"%s\" loaded phdr %p not in loadable segment",
+         name_.c_str(), reinterpret_cast<void*>(loaded));
   return false;
 }
diff --git a/linker/linker_phdr.h b/linker/linker_phdr.h
index 3affa66..89ec094 100644
--- a/linker/linker_phdr.h
+++ b/linker/linker_phdr.h
@@ -36,30 +36,40 @@
  */
 
 #include "linker.h"
+#include "linker_mapped_file_fragment.h"
 
 class ElfReader {
  public:
-  ElfReader(const char* name, int fd, off64_t file_offset, off64_t file_size);
-  ~ElfReader();
+  ElfReader();
 
+  bool Read(const char* name, int fd, off64_t file_offset, off64_t file_size);
   bool Load(const android_dlextinfo* extinfo);
 
-  size_t phdr_count() { return phdr_num_; }
-  ElfW(Addr) load_start() { return reinterpret_cast<ElfW(Addr)>(load_start_); }
-  size_t load_size() { return load_size_; }
-  ElfW(Addr) load_bias() { return load_bias_; }
-  const ElfW(Phdr)* loaded_phdr() { return loaded_phdr_; }
+  const char* name() const { return name_.c_str(); }
+  size_t phdr_count() const { return phdr_num_; }
+  ElfW(Addr) load_start() const { return reinterpret_cast<ElfW(Addr)>(load_start_); }
+  size_t load_size() const { return load_size_; }
+  ElfW(Addr) load_bias() const { return load_bias_; }
+  const ElfW(Phdr)* loaded_phdr() const { return loaded_phdr_; }
+  const ElfW(Dyn)* dynamic() const { return dynamic_; }
+  const char* get_string(ElfW(Word) index) const;
+  bool is_mapped_by_caller() const { return mapped_by_caller_; }
 
  private:
   bool ReadElfHeader();
   bool VerifyElfHeader();
-  bool ReadProgramHeader();
+  bool ReadProgramHeaders();
+  bool ReadSectionHeaders();
+  bool ReadDynamicSection();
   bool ReserveAddressSpace(const android_dlextinfo* extinfo);
   bool LoadSegments();
   bool FindPhdr();
   bool CheckPhdr(ElfW(Addr));
+  bool CheckFileRange(ElfW(Addr) offset, size_t size);
 
-  const char* name_;
+  bool did_read_;
+  bool did_load_;
+  std::string name_;
   int fd_;
   off64_t file_offset_;
   off64_t file_size_;
@@ -67,9 +77,19 @@
   ElfW(Ehdr) header_;
   size_t phdr_num_;
 
-  void* phdr_mmap_;
-  ElfW(Phdr)* phdr_table_;
-  ElfW(Addr) phdr_size_;
+  MappedFileFragment phdr_fragment_;
+  const ElfW(Phdr)* phdr_table_;
+
+  MappedFileFragment shdr_fragment_;
+  const ElfW(Shdr)* shdr_table_;
+  size_t shdr_num_;
+
+  MappedFileFragment dynamic_fragment_;
+  const ElfW(Dyn)* dynamic_;
+
+  MappedFileFragment strtab_fragment_;
+  const char* strtab_;
+  size_t strtab_size_;
 
   // First page of reserved address space.
   void* load_start_;
@@ -80,6 +100,9 @@
 
   // Loaded phdr.
   const ElfW(Phdr)* loaded_phdr_;
+
+  // Is map owned by the caller
+  bool mapped_by_caller_;
 };
 
 size_t phdr_table_get_load_size(const ElfW(Phdr)* phdr_table, size_t phdr_count,
@@ -109,4 +132,7 @@
                                     ElfW(Addr) load_bias, ElfW(Dyn)** dynamic,
                                     ElfW(Word)* dynamic_flags);
 
+const char* phdr_table_get_interpreter_name(const ElfW(Phdr) * phdr_table, size_t phdr_count,
+                                            ElfW(Addr) load_bias);
+
 #endif /* LINKER_PHDR_H */
diff --git a/linker/linker_utils.cpp b/linker/linker_utils.cpp
new file mode 100644
index 0000000..fb070ee
--- /dev/null
+++ b/linker/linker_utils.cpp
@@ -0,0 +1,136 @@
+/*
+ * Copyright (C) 2015 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 "linker_utils.h"
+#include "linker_debug.h"
+
+bool normalize_path(const char* path, std::string* normalized_path) {
+  // Input should be an absolute path
+  if (path[0] != '/') {
+    PRINT("normalize_path - invalid input: \"%s\", the input path should be absolute", path);
+    return false;
+  }
+
+  const size_t len = strlen(path) + 1;
+  char buf[len];
+
+  const char* in_ptr = path;
+  char* out_ptr = buf;
+
+  while (*in_ptr != 0) {
+    if (*in_ptr == '/') {
+      char c1 = in_ptr[1];
+      if (c1 == '.') {
+        char c2 = in_ptr[2];
+        if (c2 == '/') {
+          in_ptr += 2;
+          continue;
+        } else if (c2 == '.' && (in_ptr[3] == '/' || in_ptr[3] == 0)) {
+          in_ptr += 3;
+          while (out_ptr > buf && *--out_ptr != '/') {
+          }
+          if (in_ptr[0] == 0) {
+            // retain '/'
+            out_ptr++;
+          }
+          continue;
+        }
+      } else if (c1 == '/') {
+        ++in_ptr;
+        continue;
+      }
+    }
+    *out_ptr++ = *in_ptr++;
+  }
+
+  *out_ptr = 0;
+  *normalized_path = buf;
+  return true;
+}
+
+bool file_is_in_dir(const std::string& file, const std::string& dir) {
+  const char* needle = dir.c_str();
+  const char* haystack = file.c_str();
+  size_t needle_len = strlen(needle);
+
+  return strncmp(haystack, needle, needle_len) == 0 &&
+         haystack[needle_len] == '/' &&
+         strchr(haystack + needle_len + 1, '/') == nullptr;
+}
+
+bool file_is_under_dir(const std::string& file, const std::string& dir) {
+  const char* needle = dir.c_str();
+  const char* haystack = file.c_str();
+  size_t needle_len = strlen(needle);
+
+  return strncmp(haystack, needle, needle_len) == 0 &&
+         haystack[needle_len] == '/';
+}
+
+const char* const kZipFileSeparator = "!/";
+
+bool parse_zip_path(const char* input_path, std::string* zip_path, std::string* entry_path) {
+  std::string normalized_path;
+  if (!normalize_path(input_path, &normalized_path)) {
+    return false;
+  }
+
+  const char* const path = normalized_path.c_str();
+  TRACE("Trying zip file open from path \"%s\" -> normalized \"%s\"", input_path, path);
+
+  // Treat an '!/' separator inside a path as the separator between the name
+  // of the zip file on disk and the subdirectory to search within it.
+  // For example, if path is "foo.zip!/bar/bas/x.so", then we search for
+  // "bar/bas/x.so" within "foo.zip".
+  const char* const separator = strstr(path, kZipFileSeparator);
+  if (separator == nullptr) {
+    return false;
+  }
+
+  char buf[512];
+  if (strlcpy(buf, path, sizeof(buf)) >= sizeof(buf)) {
+    PRINT("Warning: ignoring very long library path: %s", path);
+    return false;
+  }
+
+  buf[separator - path] = '\0';
+
+  *zip_path = buf;
+  *entry_path = &buf[separator - path + 2];
+
+  return true;
+}
+
+constexpr off64_t kPageMask = ~static_cast<off64_t>(PAGE_SIZE-1);
+
+off64_t page_start(off64_t offset) {
+  return offset & kPageMask;
+}
+
+bool safe_add(off64_t* out, off64_t a, size_t b) {
+  CHECK(a >= 0);
+  if (static_cast<uint64_t>(INT64_MAX - a) < b) {
+    return false;
+  }
+
+  *out = a + b;
+  return true;
+}
+
+size_t page_offset(off64_t offset) {
+  return static_cast<size_t>(offset & (PAGE_SIZE-1));
+}
+
diff --git a/linker/linker_utils.h b/linker/linker_utils.h
new file mode 100644
index 0000000..987eabd
--- /dev/null
+++ b/linker/linker_utils.h
@@ -0,0 +1,32 @@
+/*
+ * Copyright (C) 2015 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 __LINKER_UTILS_H
+#define __LINKER_UTILS_H
+
+#include <string>
+
+extern const char* const kZipFileSeparator;
+
+bool normalize_path(const char* path, std::string* normalized_path);
+bool file_is_in_dir(const std::string& file, const std::string& dir);
+bool file_is_under_dir(const std::string& file, const std::string& dir);
+bool parse_zip_path(const char* input_path, std::string* zip_path, std::string* entry_path);
+
+off64_t page_start(off64_t offset);
+size_t page_offset(off64_t offset);
+bool safe_add(off64_t* out, off64_t a, size_t b);
+
+#endif
diff --git a/linker/tests/Android.mk b/linker/tests/Android.mk
index 35992c5..a061877 100644
--- a/linker/tests/Android.mk
+++ b/linker/tests/Android.mk
@@ -23,15 +23,18 @@
 
 LOCAL_ADDITIONAL_DEPENDENCIES := $(LOCAL_PATH)/Android.mk
 
-LOCAL_CFLAGS += -g -Wall -Wextra -Wunused -Werror -std=gnu++11
+LOCAL_CFLAGS += -g -Wall -Wextra -Wunused -Werror
 LOCAL_C_INCLUDES := $(LOCAL_PATH)/../../libc/
 
 LOCAL_SRC_FILES := \
+  linker_globals.cpp \
   linked_list_test.cpp \
   linker_block_allocator_test.cpp \
   ../linker_block_allocator.cpp \
   linker_memory_allocator_test.cpp \
-  ../linker_allocator.cpp
+  ../linker_allocator.cpp \
+  linker_utils_test.cpp \
+  ../linker_utils.cpp
 
 # for __libc_fatal
 LOCAL_SRC_FILES += ../../libc/bionic/libc_logging.cpp
diff --git a/linker/tests/linked_list_test.cpp b/linker/tests/linked_list_test.cpp
index 09ad687..12348d9 100644
--- a/linker/tests/linked_list_test.cpp
+++ b/linker/tests/linked_list_test.cpp
@@ -133,6 +133,23 @@
   ASSERT_TRUE(list.pop_front() == nullptr);
 }
 
+TEST(linked_list, remove_if_last_then_push_back) {
+  test_list_t list;
+
+  list.push_back("a");
+  list.push_back("b");
+  list.push_back("c");
+  list.push_back("d");
+
+  list.remove_if([](const char* c) {
+    return *c == 'c' || *c == 'd';
+  });
+
+  ASSERT_EQ("ab", test_list_to_string(list));
+  list.push_back("d");
+  ASSERT_EQ("abd", test_list_to_string(list));
+}
+
 TEST(linked_list, copy_to_array) {
   test_list_t list;
   const size_t max_size = 128;
diff --git a/linker/tests/linker_block_allocator_test.cpp b/linker/tests/linker_block_allocator_test.cpp
index 3ef0f36..5adc425 100644
--- a/linker/tests/linker_block_allocator_test.cpp
+++ b/linker/tests/linker_block_allocator_test.cpp
@@ -53,10 +53,12 @@
 
   test_struct_nominal* ptr1 = allocator.alloc();
   ASSERT_TRUE(ptr1 != nullptr);
+  ASSERT_EQ(0U, reinterpret_cast<uintptr_t>(ptr1) % 16);
   test_struct_nominal* ptr2 = allocator.alloc();
+  ASSERT_EQ(0U, reinterpret_cast<uintptr_t>(ptr2) % 16);
   ASSERT_TRUE(ptr2 != nullptr);
   // they should be next to each other.
-  ASSERT_EQ(ptr1+1, ptr2);
+  ASSERT_EQ(reinterpret_cast<uint8_t*>(ptr1)+16, reinterpret_cast<uint8_t*>(ptr2));
 
   ptr1->value = 42;
 
@@ -71,8 +73,10 @@
   char* ptr2 = reinterpret_cast<char*>(allocator.alloc());
 
   ASSERT_TRUE(ptr1 != nullptr);
+  ASSERT_EQ(0U, reinterpret_cast<uintptr_t>(ptr1) % 16);
   ASSERT_TRUE(ptr2 != nullptr);
-  ASSERT_EQ(ptr1+2*sizeof(void*), ptr2);
+  ASSERT_EQ(0U, reinterpret_cast<uintptr_t>(ptr2) % 16);
+  ASSERT_EQ(ptr1+16, ptr2); // aligned to 16
 }
 
 TEST(linker_allocator, test_larger) {
@@ -82,9 +86,11 @@
   test_struct_larger* ptr2 = allocator.alloc();
 
   ASSERT_TRUE(ptr1 != nullptr);
+  ASSERT_EQ(0U, reinterpret_cast<uintptr_t>(ptr1) % 16);
   ASSERT_TRUE(ptr2 != nullptr);
+  ASSERT_EQ(0U, reinterpret_cast<uintptr_t>(ptr2) % 16);
 
-  ASSERT_EQ(ptr1+1, ptr2);
+  ASSERT_EQ(reinterpret_cast<uint8_t*>(ptr1) + 1024, reinterpret_cast<uint8_t*>(ptr2));
 
   // lets allocate until we reach next page.
   size_t n = kPageSize/sizeof(test_struct_larger) + 1 - 2;
diff --git a/libc/upstream-freebsd/android/include/spinlock.h b/linker/tests/linker_globals.cpp
similarity index 78%
rename from libc/upstream-freebsd/android/include/spinlock.h
rename to linker/tests/linker_globals.cpp
index f5c3785..7762a87 100644
--- a/libc/upstream-freebsd/android/include/spinlock.h
+++ b/linker/tests/linker_globals.cpp
@@ -14,9 +14,6 @@
  * limitations under the License.
  */
 
-#ifndef _BIONIC_FREEBSD_SPINLOCK_H_included
-#define _BIONIC_FREEBSD_SPINLOCK_H_included
+// To enable logging
+int g_ld_debug_verbosity = 0;
 
-/* TODO: until we have the FreeBSD findfp.c, this is useless. */
-
-#endif
diff --git a/linker/tests/linker_memory_allocator_test.cpp b/linker/tests/linker_memory_allocator_test.cpp
index f002a0d..5b85536 100644
--- a/linker/tests/linker_memory_allocator_test.cpp
+++ b/linker/tests/linker_memory_allocator_test.cpp
@@ -53,7 +53,7 @@
   LinkerMemoryAllocator allocator;
   void* ptr = allocator.alloc(0);
   ASSERT_TRUE(ptr != nullptr);
-  free(ptr);
+  allocator.free(ptr);
 }
 
 TEST(linker_memory, test_free_nullptr) {
@@ -96,6 +96,7 @@
 
   ASSERT_TRUE(reallocated_ptr != nullptr);
   ASSERT_TRUE(reallocated_ptr != array);
+  ASSERT_EQ(0U, reinterpret_cast<uintptr_t>(reallocated_ptr) % 16);
 
   ASSERT_TRUE(memcmp(reallocated_ptr, model, array_size * 2) == 0);
 
@@ -107,10 +108,11 @@
 
   ASSERT_TRUE(reallocated_ptr != nullptr);
   ASSERT_TRUE(reallocated_ptr != array);
+  ASSERT_EQ(0U, reinterpret_cast<uintptr_t>(reallocated_ptr) % 16);
 
   ASSERT_TRUE(memcmp(reallocated_ptr, model, 4000) == 0);
 
-  ASSERT_EQ(nullptr, realloc(reallocated_ptr, 0));
+  ASSERT_EQ(nullptr, allocator.realloc(reallocated_ptr, 0));
 }
 
 TEST(linker_memory, test_small_smoke) {
@@ -125,7 +127,10 @@
       reinterpret_cast<test_struct_small*>(allocator.alloc(sizeof(test_struct_small)));
 
   ASSERT_TRUE(ptr1 != nullptr);
+  ASSERT_EQ(0U, reinterpret_cast<uintptr_t>(ptr1) % 16);
   ASSERT_TRUE(ptr2 != nullptr);
+  ASSERT_EQ(0U, reinterpret_cast<uintptr_t>(ptr2) % 16);
+
   ASSERT_EQ(reinterpret_cast<uintptr_t>(ptr1)+16, reinterpret_cast<uintptr_t>(ptr2));
   ASSERT_TRUE(memcmp(ptr1, zeros, 16) == 0);
 
@@ -143,7 +148,9 @@
       reinterpret_cast<test_struct_huge*>(allocator.alloc(sizeof(test_struct_huge)));
 
   ASSERT_TRUE(ptr1 != nullptr);
+  ASSERT_EQ(0U, reinterpret_cast<uintptr_t>(ptr1) % 16);
   ASSERT_TRUE(ptr2 != nullptr);
+  ASSERT_EQ(0U, reinterpret_cast<uintptr_t>(ptr2) % 16);
 
   ASSERT_TRUE(
       reinterpret_cast<uintptr_t>(ptr1)/kPageSize != reinterpret_cast<uintptr_t>(ptr2)/kPageSize);
@@ -160,7 +167,9 @@
       reinterpret_cast<test_struct_large*>(allocator.alloc(1024));
 
   ASSERT_TRUE(ptr1 != nullptr);
+  ASSERT_EQ(0U, reinterpret_cast<uintptr_t>(ptr1) % 16);
   ASSERT_TRUE(ptr2 != nullptr);
+  ASSERT_EQ(0U, reinterpret_cast<uintptr_t>(ptr2) % 16);
 
   ASSERT_EQ(reinterpret_cast<uintptr_t>(ptr1) + 1024, reinterpret_cast<uintptr_t>(ptr2));
 
@@ -179,6 +188,7 @@
       reinterpret_cast<test_struct_large*>(allocator.alloc(sizeof(test_struct_large)));
 
   ASSERT_TRUE(ptr_to_free != nullptr);
+  ASSERT_EQ(0U, reinterpret_cast<uintptr_t>(ptr_to_free) % 16);
 
   allocator.free(ptr1);
 
diff --git a/linker/tests/linker_utils_test.cpp b/linker/tests/linker_utils_test.cpp
new file mode 100644
index 0000000..fd749fa
--- /dev/null
+++ b/linker/tests/linker_utils_test.cpp
@@ -0,0 +1,104 @@
+/*
+ * Copyright (C) 2013 The Android Open Source Project
+ *
+ * Licensed under the Apache License, Version 2.0 (the "License");
+ * you may not use this file except in compliance with the License.
+ * You may obtain a copy of the License at
+ *
+ *      http://www.apache.org/licenses/LICENSE-2.0
+ *
+ * Unless required by applicable law or agreed to in writing, software
+ * distributed under the License is distributed on an "AS IS" BASIS,
+ * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
+ * See the License for the specific language governing permissions and
+ * limitations under the License.
+ */
+
+#include <stdlib.h>
+#include <string.h>
+#include <sys/mman.h>
+
+#include <gtest/gtest.h>
+
+#include "../linker_utils.h"
+
+TEST(linker_utils, normalize_path_smoke) {
+  std::string output;
+  ASSERT_TRUE(normalize_path("/../root///dir/.///dir2/somedir/../zipfile!/dir/dir9//..///afile", &output));
+  ASSERT_EQ("/root/dir/dir2/zipfile!/dir/afile", output);
+
+  ASSERT_TRUE(normalize_path("/../root///dir/.///dir2/somedir/.../zipfile!/.dir/dir9//..///afile", &output));
+  ASSERT_EQ("/root/dir/dir2/somedir/.../zipfile!/.dir/afile", output);
+
+  ASSERT_TRUE(normalize_path("/root/..", &output));
+  ASSERT_EQ("/", output);
+
+  ASSERT_TRUE(normalize_path("/root/notroot/..", &output));
+  ASSERT_EQ("/root/", output);
+
+  ASSERT_TRUE(normalize_path("/a/../../b", &output));
+  ASSERT_EQ("/b", output);
+
+  output = "unchanged";
+  ASSERT_FALSE(normalize_path("root///dir/.///dir2/somedir/../zipfile!/dir/dir9//..///afile", &output));
+  ASSERT_EQ("unchanged", output);
+}
+
+TEST(linker_utils, file_is_in_dir_smoke) {
+  ASSERT_TRUE(file_is_in_dir("/foo/bar/file", "/foo/bar"));
+  ASSERT_FALSE(file_is_in_dir("/foo/bar/file", "/foo"));
+
+  ASSERT_FALSE(file_is_in_dir("/foo/bar/file", "/bar/foo"));
+
+  ASSERT_TRUE(file_is_in_dir("/file", ""));
+  ASSERT_FALSE(file_is_in_dir("/file", "/"));
+}
+
+TEST(linker_utils, file_is_under_dir_smoke) {
+  ASSERT_TRUE(file_is_under_dir("/foo/bar/file", "/foo/bar"));
+  ASSERT_TRUE(file_is_under_dir("/foo/bar/file", "/foo"));
+
+  ASSERT_FALSE(file_is_under_dir("/foo/bar/file", "/bar/foo"));
+
+  ASSERT_TRUE(file_is_under_dir("/file", ""));
+  ASSERT_TRUE(file_is_under_dir("/foo/bar/file", ""));
+  ASSERT_FALSE(file_is_under_dir("/file", "/"));
+  ASSERT_FALSE(file_is_under_dir("/foo/bar/file", "/"));
+}
+
+TEST(linker_utils, parse_zip_path_smoke) {
+  std::string zip_path;
+  std::string entry_path;
+
+  ASSERT_FALSE(parse_zip_path("/not/a/zip/path/file.zip", &zip_path, &entry_path));
+  ASSERT_FALSE(parse_zip_path("/not/a/zip/path/file.zip!path/in/zip", &zip_path, &entry_path));
+  ASSERT_TRUE(parse_zip_path("/zip/path/file.zip!/path/in/zip", &zip_path, &entry_path));
+  ASSERT_EQ("/zip/path/file.zip", zip_path);
+  ASSERT_EQ("path/in/zip", entry_path);
+
+  ASSERT_TRUE(parse_zip_path("/zip/path/file2.zip!/", &zip_path, &entry_path));
+  ASSERT_EQ("/zip/path/file2.zip", zip_path);
+  ASSERT_EQ("", entry_path);
+}
+
+TEST(linker_utils, page_start) {
+  ASSERT_EQ(0x0001000, page_start(0x0001000));
+  ASSERT_EQ(0x3002000, page_start(0x300222f));
+  ASSERT_EQ(0x6001000, page_start(0x6001fff));
+}
+
+TEST(linker_utils, page_offset) {
+  ASSERT_EQ(0x0U, page_offset(0x0001000));
+  ASSERT_EQ(0x22fU, page_offset(0x300222f));
+  ASSERT_EQ(0xfffU, page_offset(0x6001fff));
+}
+
+TEST(linker_utils, safe_add) {
+  int64_t val = 42;
+  ASSERT_FALSE(safe_add(&val, INT64_MAX-20, 21U));
+  ASSERT_EQ(42, val);
+  ASSERT_TRUE(safe_add(&val, INT64_MAX-42, 42U));
+  ASSERT_EQ(INT64_MAX, val);
+  ASSERT_TRUE(safe_add(&val, 2000, 42U));
+  ASSERT_EQ(2042, val);
+}
diff --git a/tests/Android.build.mk b/tests/Android.build.mk
index 5b2b417..740c2f4 100644
--- a/tests/Android.build.mk
+++ b/tests/Android.build.mk
@@ -28,16 +28,24 @@
     LOCAL_MODULE_STEM_32 := $(module)32
     LOCAL_MODULE_STEM_64 := $(module)64
 else
+
+ifneq ($($(module)_install_to_out_data_dir),)
+  $(module)_install_to_out_data := true
+endif
+
 ifeq ($($(module)_install_to_out_data),true)
-    LOCAL_MODULE_PATH_32 := $($(TARGET_2ND_ARCH_VAR_PREFIX)TARGET_OUT_DATA_NATIVE_TESTS)/$(module)
-    LOCAL_MODULE_PATH_64 := $(TARGET_OUT_DATA_NATIVE_TESTS)/$(module)
+    ifeq ($($(module)_install_to_out_data_dir),)
+      $(module)_install_to_out_data_dir := $(module)
+    endif
+    LOCAL_MODULE_PATH_32 := $($(TARGET_2ND_ARCH_VAR_PREFIX)TARGET_OUT_DATA_NATIVE_TESTS)/$($(module)_install_to_out_data_dir)
+    LOCAL_MODULE_PATH_64 := $(TARGET_OUT_DATA_NATIVE_TESTS)/$($(module)_install_to_out_data_dir)
 endif
 endif
 
 LOCAL_CLANG := $($(module)_clang_$(build_type))
 
 ifneq ($($(module)_allow_asan),true)
-LOCAL_ADDRESS_SANITIZER := false
+LOCAL_SANITIZE := never
 endif
 
 LOCAL_FORCE_STATIC_EXECUTABLE := $($(module)_force_static_executable)
@@ -48,6 +56,10 @@
     LOCAL_MULTILIB := $($(module)_multilib)
 endif
 
+ifneq ($($(module)_relative_path),)
+    LOCAL_MODULE_RELATIVE_PATH := $($(module)_relative_path)
+endif
+
 LOCAL_CFLAGS := \
     $(common_cflags) \
     $($(module)_cflags) \
diff --git a/tests/Android.mk b/tests/Android.mk
index dc2e410..956b76f 100644
--- a/tests/Android.mk
+++ b/tests/Android.mk
@@ -40,18 +40,12 @@
 
 test_cflags += -D__STDC_LIMIT_MACROS  # For glibc.
 
-ifeq ($(MALLOC_IMPL),dlmalloc)
-test_cflags += -DUSE_DLMALLOC
-else
-test_cflags += -DUSE_JEMALLOC
-endif
-
-test_cppflags = \
-    -std=gnu++11 \
+test_cppflags := \
 
 libBionicStandardTests_src_files := \
     arpa_inet_test.cpp \
     buffer_tests.cpp \
+    bug_26110743_test.cpp \
     complex_test.cpp \
     ctype_test.cpp \
     dirent_test.cpp \
@@ -62,14 +56,19 @@
     ftw_test.cpp \
     getauxval_test.cpp \
     getcwd_test.cpp \
+    ifaddrs_test.cpp \
     inttypes_test.cpp \
     libc_logging_test.cpp \
+    libgen_basename_test.cpp \
     libgen_test.cpp \
     locale_test.cpp \
     malloc_test.cpp \
     math_test.cpp \
     mntent_test.cpp \
     netdb_test.cpp \
+    net_if_test.cpp \
+    netinet_in_test.cpp \
+    netinet_udp_test.cpp \
     pthread_test.cpp \
     pty_test.cpp \
     regex_test.cpp \
@@ -79,20 +78,25 @@
     setjmp_test.cpp \
     signal_test.cpp \
     stack_protector_test.cpp \
+    stack_protector_test_helper.cpp \
     stack_unwinding_test.cpp \
     stdatomic_test.cpp \
     stdint_test.cpp \
+    stdio_nofortify_test.cpp \
     stdio_test.cpp \
     stdio_ext_test.cpp \
     stdlib_test.cpp \
+    string_nofortify_test.cpp \
     string_test.cpp \
     string_posix_strerror_r_test.cpp \
+    strings_nofortify_test.cpp \
     strings_test.cpp \
     stubs_test.cpp \
     sstream_test.cpp \
     sys_epoll_test.cpp \
     sys_mman_test.cpp \
     sys_personality_test.cpp \
+    sys_prctl_test.cpp \
     sys_procfs_test.cpp \
     sys_resource_test.cpp \
     sys_select_test.cpp \
@@ -102,7 +106,9 @@
     sys_statvfs_test.cpp \
     sys_syscall_test.cpp \
     sys_sysinfo_test.cpp \
+    sys_sysmacros_test.cpp \
     sys_time_test.cpp \
+    sys_timex_test.cpp \
     sys_types_test.cpp \
     sys_uio_test.cpp \
     sys_vfs_test.cpp \
@@ -111,6 +117,7 @@
     time_test.cpp \
     uchar_test.cpp \
     uniqueptr_test.cpp \
+    unistd_nofortify_test.cpp \
     unistd_test.cpp \
     utmp_test.cpp \
     wchar_test.cpp \
@@ -118,12 +125,6 @@
 libBionicStandardTests_cflags := \
     $(test_cflags) \
 
-ifeq ($(MALLOC_IMPL),dlmalloc)
-  libBionicStandardTests_cflags += -DUSE_DLMALLOC
-else
-  libBionicStandardTests_cflags += -DUSE_JEMALLOC
-endif
-
 libBionicStandardTests_cppflags := \
     $(test_cppflags) \
 
@@ -137,6 +138,13 @@
 libBionicStandardTests_ldlibs_host := \
     -lrt \
 
+# Clang/llvm has incompatible long double (fp128) for x86_64.
+# https://llvm.org/bugs/show_bug.cgi?id=23897
+# This affects most of math_test.cpp.
+ifeq ($(TARGET_ARCH),$(filter $(TARGET_ARCH),x86_64))
+libBionicStandardTests_clang_target := false
+endif
+
 module := libBionicStandardTests
 module_tag := optional
 build_type := target
@@ -157,11 +165,12 @@
       -D_FORTIFY_SOURCE=$(test) \
       -DTEST_NAME=Fortify$(test)_$(compiler)); \
     $(eval fortify$(test)-tests-$(compiler)_src_files := \
-      fortify_test.cpp); \
+      fortify_test_main.cpp); \
     $(eval fortify_libs += fortify$(test)-tests-$(compiler)); \
   ) \
 )
 
+fortify1-tests-gcc_clang_target := false
 module := fortify1-tests-gcc
 module_tag := optional
 build_type := target
@@ -170,6 +179,7 @@
 build_type := host
 include $(LOCAL_PATH)/Android.build.mk
 
+fortify2-tests-gcc_clang_target := false
 module := fortify2-tests-gcc
 module_tag := optional
 build_type := target
@@ -231,7 +241,13 @@
 build_target := STATIC_TEST_LIBRARY
 include $(LOCAL_PATH)/Android.build.mk
 build_type := host
+
+ifeq ($(HOST_OS),$(filter $(HOST_OS),linux darwin))
+saved_build_host := $(build_host)
+build_host := true
 include $(LOCAL_PATH)/Android.build.mk
+build_host := $(saved_build_host)
+endif
 
 # -----------------------------------------------------------------------------
 # Library of bionic customized gtest main function, with normal gtest output format,
@@ -243,11 +259,6 @@
 
 libBionicCtsGtestMain_cppflags := $(test_cppflags) -DUSING_GTEST_OUTPUT_FORMAT \
 
-# Temporarily fix the job count to 1 for CTS since on some devices the
-# number of online cores is incorrectly read as the total number of cores
-# in the system. When b/24376925 is fixed, this should be removed.
-libBionicCtsGtestMain_cppflags += -DJOB_COUNT_FIXED=1
-
 module := libBionicCtsGtestMain
 module_tag := optional
 build_type := target
@@ -260,18 +271,20 @@
 # Tests for the device using bionic's .so. Run with:
 #   adb shell /data/nativetest/bionic-unit-tests/bionic-unit-tests32
 #   adb shell /data/nativetest/bionic-unit-tests/bionic-unit-tests64
+#   adb shell /data/nativetest/bionic-unit-tests/bionic-unit-tests-gcc32
+#   adb shell /data/nativetest/bionic-unit-tests/bionic-unit-tests-gcc64
 # -----------------------------------------------------------------------------
-bionic-unit-tests_whole_static_libraries := \
+common_bionic-unit-tests_whole_static_libraries := \
     libBionicTests \
     libBionicGtestMain \
 
-bionic-unit-tests_static_libraries := \
+common_bionic-unit-tests_static_libraries := \
     libtinyxml2 \
     liblog \
     libbase \
 
 # TODO: Include __cxa_thread_atexit_test.cpp to glibc tests once it is upgraded (glibc 2.18+)
-bionic-unit-tests_src_files := \
+common_bionic-unit-tests_src_files := \
     atexit_test.cpp \
     dl_test.cpp \
     dlext_test.cpp \
@@ -279,38 +292,66 @@
     dlfcn_test.cpp \
     libdl_test.cpp \
     pthread_dlfcn_test.cpp \
+    thread_local_test.cpp \
 
-bionic-unit-tests_cflags := $(test_cflags)
+common_bionic-unit-tests_cflags := $(test_cflags)
 
-bionic-unit-tests_conlyflags := \
+common_bionic-unit-tests_conlyflags := \
     -fexceptions \
     -fnon-call-exceptions \
 
-bionic-unit-tests_cppflags := $(test_cppflags)
+common_bionic-unit-tests_cppflags := $(test_cppflags)
 
-bionic-unit-tests_ldflags := \
+common_bionic-unit-tests_ldflags := \
     -Wl,--export-dynamic
 
-bionic-unit-tests_c_includes := \
+common_bionic-unit-tests_c_includes := \
     bionic/libc \
-    $(call include-path-for, libpagemap) \
 
-bionic-unit-tests_shared_libraries_target := \
+common_bionic-unit-tests_shared_libraries_target := \
     libdl \
     libpagemap \
     libdl_preempt_test_1 \
-    libdl_preempt_test_2
+    libdl_preempt_test_2 \
+    libdl_test_df_1_global \
 
-# TODO: clang support for thread_local on arm is done via __aeabi_read_tp()
-# which bionic does not support. Reenable this once this question is resolved.
-bionic-unit-tests_clang_target := false
+# The order of these libraries matters, do not shuffle them.
+common_bionic-unit-tests_static_libraries_target := \
+    libbase \
+    libziparchive \
+    libz \
+    libutils \
 
-bionic-unit-tests_shared_libraries_target += libdl_test_df_1_global
-
-module := bionic-unit-tests
 module_tag := optional
 build_type := target
 build_target := NATIVE_TEST
+
+module := bionic-unit-tests
+bionic-unit-tests_clang_target := true
+bionic-unit-tests_whole_static_libraries := $(common_bionic-unit-tests_whole_static_libraries)
+bionic-unit-tests_static_libraries := $(common_bionic-unit-tests_static_libraries)
+bionic-unit-tests_src_files := $(common_bionic-unit-tests_src_files)
+bionic-unit-tests_cflags := $(common_bionic-unit-tests_cflags)
+bionic-unit-tests_conlyflags := $(common_bionic-unit-tests_conlyflags)
+bionic-unit-tests_cppflags := $(common_bionic-unit-tests_cppflags)
+bionic-unit-tests_ldflags := $(common_bionic-unit-tests_ldflags)
+bionic-unit-tests_c_includes := $(common_bionic-unit-tests_c_includes)
+bionic-unit-tests_shared_libraries_target := $(common_bionic-unit-tests_shared_libraries_target)
+bionic-unit-tests_static_libraries_target := $(common_bionic-unit-tests_static_libraries_target)
+include $(LOCAL_PATH)/Android.build.mk
+
+module := bionic-unit-tests-gcc
+bionic-unit-tests-gcc_clang_target := false
+bionic-unit-tests-gcc_whole_static_libraries := $(common_bionic-unit-tests_whole_static_libraries)
+bionic-unit-tests-gcc_static_libraries := $(common_bionic-unit-tests_static_libraries)
+bionic-unit-tests-gcc_src_files := $(common_bionic-unit-tests_src_files)
+bionic-unit-tests-gcc_cflags := $(common_bionic-unit-tests_cflags)
+bionic-unit-tests-gcc_conlyflags := $(common_bionic-unit-tests_conlyflags)
+bionic-unit-tests-gcc_cppflags := $(common_bionic-unit-tests_cppflags)
+bionic-unit-tests-gcc_ldflags := $(common_bionic-unit-tests_ldflags)
+bionic-unit-tests-gcc_c_includes := $(common_bionic-unit-tests_c_includes)
+bionic-unit-tests-gcc_shared_libraries_target := $(common_bionic-unit-tests_shared_libraries_target)
+bionic-unit-tests-gcc_static_libraries_target := $(common_bionic-unit-tests_static_libraries_target)
 include $(LOCAL_PATH)/Android.build.mk
 
 # -----------------------------------------------------------------------------
@@ -413,6 +454,8 @@
 LOCAL_CLANG := false
 LOCAL_MODULE := bionic-compile-time-tests-g++
 LOCAL_CPPFLAGS := -Wall
+# Disable color diagnostics so the warnings output matches the source
+LOCAL_CPPFLAGS +=  -fdiagnostics-color=never
 LOCAL_SRC_FILES := fortify_compilation_test.cpp
 include $(BUILD_STATIC_LIBRARY)
 
@@ -430,6 +473,8 @@
 LOCAL_CLANG := true
 LOCAL_MODULE := bionic-compile-time-tests-clang++
 LOCAL_CPPFLAGS := -Wall
+# Disable color diagnostics so the warnings output matches the source
+LOCAL_CPPFLAGS += -fno-color-diagnostics
 # FileCheck will error if there aren't any CLANG: lines in the file, but there
 # don't appear to be any cases where clang _does_ emit warnings for sn?printf :(
 LOCAL_SRC_FILES :=
@@ -443,6 +488,7 @@
 # Make sure to create ANDROID_DATA/local/tmp if doesn't exist.
 # Use the current target out directory as ANDROID_DATA.
 # BIONIC_TEST_FLAGS is either empty or it comes from the user.
+.PHONY: bionic-unit-tests-glibc-run
 bionic-unit-tests-glibc-run: bionic-unit-tests-glibc
 	mkdir -p $(TARGET_OUT_DATA)/local/tmp
 	ANDROID_DATA=$(TARGET_OUT_DATA) \
@@ -460,6 +506,7 @@
 TEST_TIMEOUT := 0
 
 # BIONIC_TEST_FLAGS is either empty or it comes from the user.
+.PHONY: bionic-unit-tests-run-on-host32
 bionic-unit-tests-run-on-host32: bionic-unit-tests bionic-prepare-run-on-host
 	ANDROID_DATA=$(TARGET_OUT_DATA) \
 	ANDROID_DNS_MODE=local \
@@ -469,6 +516,7 @@
 
 ifeq ($(TARGET_IS_64_BIT),true)
 # add target to run lp64 tests
+.PHONY: bionic-unit-tests-run-on-host64
 bionic-unit-tests-run-on-host64: bionic-unit-tests bionic-prepare-run-on-host
 	ANDROID_DATA=$(TARGET_OUT_DATA) \
 	ANDROID_DNS_MODE=local \
diff --git a/tests/__cxa_thread_atexit_test.cpp b/tests/__cxa_thread_atexit_test.cpp
index e388f3b..1432968 100644
--- a/tests/__cxa_thread_atexit_test.cpp
+++ b/tests/__cxa_thread_atexit_test.cpp
@@ -35,7 +35,12 @@
   std::string message;
 };
 
+#if defined(__clang__) && defined(__aarch64__)
+// b/25642296, aarch64 clang compiled "thread_local" does not link.
+static ClassWithDtor class_with_dtor;
+#else
 static thread_local ClassWithDtor class_with_dtor;
+#endif
 
 static void* thread_nop(void* arg) {
   class_with_dtor.set_message(*static_cast<std::string*>(arg));
@@ -47,7 +52,12 @@
   pthread_t t;
   ASSERT_EQ(0, pthread_create(&t, nullptr, thread_nop, &msg));
   ASSERT_EQ(0, pthread_join(t, nullptr));
+#if defined(__clang__) && defined(__aarch64__)
+  GTEST_LOG_(INFO) << "Skipping test, b/25642296, "
+                   << "thread_local does not work with aarch64 clang/llvm.\n";
+#else
   ASSERT_EQ("dtor called.", class_with_dtor_output);
+#endif
 }
 
 class ClassWithDtorForMainThread {
@@ -64,7 +74,13 @@
 };
 
 static void thread_atexit_main() {
+#if defined(__clang__) && defined(__aarch64__)
+  static ClassWithDtorForMainThread class_with_dtor_for_main_thread;
+  GTEST_LOG_(INFO) << "Skipping test, b/25642296, "
+                   << "thread_local does not work with aarch64 clang/llvm.\n";
+#else
   static thread_local ClassWithDtorForMainThread class_with_dtor_for_main_thread;
+#endif
   class_with_dtor_for_main_thread.set_message("d-tor for main thread called.");
   exit(0);
 }
diff --git a/tests/arpa_inet_test.cpp b/tests/arpa_inet_test.cpp
index 5e53337..a368b8f 100644
--- a/tests/arpa_inet_test.cpp
+++ b/tests/arpa_inet_test.cpp
@@ -24,8 +24,85 @@
 
 TEST(arpa_inet, inet_aton) {
   in_addr a;
-  ASSERT_EQ(1, inet_aton("127.0.0.1", &a));
+
+  // a.b.c.d
+  a.s_addr = 0;
+  ASSERT_EQ(1, inet_aton("127.1.2.3", &a));
+  ASSERT_EQ((htonl)(0x7f010203), a.s_addr);
+
+  // a.b.c
+  a.s_addr = 0;
+  ASSERT_EQ(1, inet_aton("127.1.2", &a));
+  ASSERT_EQ((htonl)(0x7f010002), a.s_addr);
+
+  // a.b
+  a.s_addr = 0;
+  ASSERT_EQ(1, inet_aton("127.1", &a));
   ASSERT_EQ((htonl)(0x7f000001), a.s_addr);
+
+  // a
+  a.s_addr = 0;
+  ASSERT_EQ(1, inet_aton("0x7f000001", &a));
+  ASSERT_EQ((htonl)(0x7f000001), a.s_addr);
+
+  // Hex (0x) and mixed-case hex digits.
+  a.s_addr = 0;
+  ASSERT_EQ(1, inet_aton("0xFf.0.0.1", &a));
+  ASSERT_EQ((htonl)(0xff000001), a.s_addr);
+
+  // Hex (0X) and mixed-case hex digits.
+  a.s_addr = 0;
+  ASSERT_EQ(1, inet_aton("0XfF.0.0.1", &a));
+  ASSERT_EQ((htonl)(0xff000001), a.s_addr);
+
+  // Octal.
+  a.s_addr = 0;
+  ASSERT_EQ(1, inet_aton("0177.0.0.1", &a));
+  ASSERT_EQ((htonl)(0x7f000001), a.s_addr);
+
+  a.s_addr = 0;
+  ASSERT_EQ(1, inet_aton("036", &a));
+  ASSERT_EQ((htonl)(036U), a.s_addr);
+}
+
+TEST(arpa_inet, inet_aton_nullptr) {
+  ASSERT_EQ(0, inet_aton("", nullptr));
+  ASSERT_EQ(1, inet_aton("127.0.0.1", nullptr));
+}
+
+TEST(arpa_inet, inet_aton_invalid) {
+  ASSERT_EQ(0, inet_aton("", nullptr)); // Empty.
+  ASSERT_EQ(0, inet_aton("x", nullptr)); // Leading junk.
+  ASSERT_EQ(0, inet_aton("127.0.0.1x", nullptr)); // Trailing junk.
+  ASSERT_EQ(0, inet_aton("09.0.0.1", nullptr)); // Invalid octal.
+  ASSERT_EQ(0, inet_aton("0xg.0.0.1", nullptr)); // Invalid hex.
+
+  ASSERT_EQ(0, inet_aton("1.2.3.4.5", nullptr)); // Too many dots.
+  ASSERT_EQ(0, inet_aton("1.2.3.4.", nullptr)); // Trailing dot.
+
+  // Out of range a.b.c.d form.
+  ASSERT_EQ(0, inet_aton("999.0.0.1", nullptr));
+  ASSERT_EQ(0, inet_aton("0.999.0.1", nullptr));
+  ASSERT_EQ(0, inet_aton("0.0.999.1", nullptr));
+  ASSERT_EQ(0, inet_aton("0.0.0.999", nullptr));
+
+  // Out of range a.b.c form.
+  ASSERT_EQ(0, inet_aton("256.0.0", nullptr));
+  ASSERT_EQ(0, inet_aton("0.256.0", nullptr));
+  ASSERT_EQ(0, inet_aton("0.0.0x10000", nullptr));
+
+  // Out of range a.b form.
+  ASSERT_EQ(0, inet_aton("256.0", nullptr));
+  ASSERT_EQ(0, inet_aton("0.0x1000000", nullptr));
+
+  // Out of range a form.
+  ASSERT_EQ(0, inet_aton("0x100000000", nullptr));
+
+  // 64-bit overflow.
+  ASSERT_EQ(0, inet_aton("0x10000000000000000", nullptr));
+
+  // Out of range octal.
+  ASSERT_EQ(0, inet_aton("0400.0.0.1", nullptr));
 }
 
 TEST(arpa_inet, inet_lnaof) {
@@ -45,6 +122,8 @@
 
 TEST(arpa_inet, inet_network) {
   ASSERT_EQ(0x7f000001U, inet_network("127.0.0.1"));
+  ASSERT_EQ(0x7fU, inet_network("0x7f"));
+  ASSERT_EQ(~0U, inet_network(""));
 }
 
 TEST(arpa_inet, inet_ntoa) {
diff --git a/tests/atexit_test.cpp b/tests/atexit_test.cpp
index e92889d..67fbfd2 100644
--- a/tests/atexit_test.cpp
+++ b/tests/atexit_test.cpp
@@ -14,7 +14,17 @@
  * limitations under the License.
  */
 
+// To work around b/25643775, we disable clang optimization so that
+//   VTT for std::__1::basic_stringstream<char, std::__1::char_traits<char>,
+//   std::__1::allocator<char> >
+// will be correctly kept for other module's references.
+#if defined(__clang__) && (defined(__arm__) || defined(__aarch64__))
+#pragma clang optimize off
+#endif
 #include <gtest/gtest.h>
+#if defined(__clang__) && (defined(__arm__) || defined(__aarch64__))
+#pragma clang optimize on
+#endif
 
 #include <dlfcn.h>
 #include <libgen.h>
diff --git a/tests/buffer_tests.cpp b/tests/buffer_tests.cpp
index 4967382..a5a0c2a 100644
--- a/tests/buffer_tests.cpp
+++ b/tests/buffer_tests.cpp
@@ -256,7 +256,7 @@
       VerifyFencepost(&buf_align[len]);
     }
   }
-  delete buf;
+  delete[] buf;
 }
 
 void RunSrcDstBufferAlignTest(
@@ -292,8 +292,8 @@
       VerifyFencepost(&dst_align[len]);
     }
   }
-  delete src;
-  delete dst;
+  delete[] src;
+  delete[] dst;
 }
 
 void RunCmpBufferAlignTest(
@@ -344,8 +344,8 @@
       }
     }
   }
-  delete buf1;
-  delete buf2;
+  delete[] buf1;
+  delete[] buf2;
 }
 
 void RunSingleBufferOverreadTest(void (*test_func)(uint8_t*, size_t)) {
@@ -381,15 +381,19 @@
   // Make the second page unreadable and unwritable.
   ASSERT_TRUE(mprotect(&memory[pagesize], pagesize, PROT_NONE) == 0);
 
-  uint8_t* dst = new uint8_t[pagesize];
-  for (size_t i = 0; i < pagesize; i++) {
-    uint8_t* src = &memory[pagesize-i];
+  uint8_t* dst_buffer = new uint8_t[2*pagesize];
+  // Change the dst alignment as we change the source.
+  for (size_t i = 0; i < 16; i++) {
+    uint8_t* dst = &dst_buffer[i];
+    for (size_t j = 0; j < pagesize; j++) {
+      uint8_t* src = &memory[pagesize-j];
 
-    test_func(src, dst, i);
+      test_func(src, dst, j);
+    }
   }
   ASSERT_TRUE(mprotect(&memory[pagesize], pagesize, PROT_READ | PROT_WRITE) == 0);
   free(memory);
-  delete dst;
+  delete[] dst_buffer;
 }
 
 void RunCmpBufferOverreadTest(
diff --git a/tests/bug_26110743_test.cpp b/tests/bug_26110743_test.cpp
new file mode 100644
index 0000000..c49a9dc
--- /dev/null
+++ b/tests/bug_26110743_test.cpp
@@ -0,0 +1,113 @@
+/*
+ * Copyright (C) 2015 The Android Open Source Project
+ *
+ * Licensed under the Apache License, Version 2.0 (the "License");
+ * you may not use this file except in compliance with the License.
+ * You may obtain a copy of the License at
+ *
+ *      http://www.apache.org/licenses/LICENSE-2.0
+ *
+ * Unless required by applicable law or agreed to in writing, software
+ * distributed under the License is distributed on an "AS IS" BASIS,
+ * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
+ * See the License for the specific language governing permissions and
+ * limitations under the License.
+ */
+
+#include <gtest/gtest.h>
+#include <pthread.h>
+#include <fcntl.h>
+#include <unistd.h>
+#include <sys/types.h>
+#include <sys/stat.h>
+#include <sys/prctl.h>
+
+#include "private/ScopeGuard.h"
+
+extern "C" pid_t gettid();
+
+static void ProcSelfReadlinkBody() {
+  char buf[100];
+  char buf2[1024];
+  int fd = open("/dev/null", O_RDWR | O_CLOEXEC);
+  ASSERT_NE(-1, fd);
+  snprintf(buf, sizeof(buf), "/proc/self/fd/%d", fd);
+  const char* ERRORMSG = "Please apply the following two kernel patches:\n"
+    "* https://git.kernel.org/cgit/linux/kernel/git/torvalds/linux.git/commit/?id=73af963f9f3036dffed55c3a2898598186db1045\n"
+    "* https://git.kernel.org/cgit/linux/kernel/git/torvalds/linux.git/commit/?id=96d0df79f2644fc823f26c06491e182d87a90c2a\n";
+  ASSERT_NE(-1, readlink(buf, buf2, sizeof(buf2))) << ERRORMSG;
+  ASSERT_STREQ("/dev/null", buf2);
+  close(fd);
+}
+
+static void* ProcSelfReadlink(void*) {
+  ProcSelfReadlinkBody();
+  return NULL;
+}
+
+TEST(bug_26110743, ProcSelfReadlink) {
+  pthread_t t;
+  ASSERT_EQ(0, pthread_create(&t, NULL, ProcSelfReadlink, NULL));
+  void* result;
+  ASSERT_EQ(0, pthread_join(t, &result));
+  ASSERT_EQ(NULL, result);
+}
+
+TEST(bug_26110743, ProcSelfReadlink_NotDumpable) {
+  int dumpable = prctl(PR_GET_DUMPABLE, 0, 0, 0, 0);
+  prctl(PR_SET_DUMPABLE, 0, 0, 0, 0);
+  auto guard = make_scope_guard([&]() {
+    // restore dumpable
+    prctl(PR_SET_DUMPABLE, dumpable, 0, 0, 0);
+  });
+
+  pthread_t t;
+  ASSERT_EQ(0, pthread_create(&t, NULL, ProcSelfReadlink, NULL));
+  void* result;
+  ASSERT_EQ(0, pthread_join(t, &result));
+  ASSERT_EQ(NULL, result);
+}
+
+static void ProcTaskFdReadlinkBody() {
+  char buf[200];
+  char buf2[1024];
+  int fd = open("/dev/null", O_RDWR | O_CLOEXEC);
+  ASSERT_NE(-1, fd);
+  pid_t mypid = getpid();
+  pid_t mytid = gettid();
+  ASSERT_NE(mypid, mytid);
+  snprintf(buf, sizeof(buf), "/proc/%d/task/%d/fd/%d", mypid, mytid, fd);
+  const char* ERRORMSG = "Please apply the following kernel patch:\n"
+    "* https://git.kernel.org/cgit/linux/kernel/git/torvalds/linux.git/commit/?id=54708d2858e79a2bdda10bf8a20c80eb96c20613\n";
+  ASSERT_NE(-1, readlink(buf, buf2, sizeof(buf2))) << ERRORMSG;
+  ASSERT_STREQ("/dev/null", buf2);
+  close(fd);
+}
+
+static void* ProcTaskFdReadlink(void*) {
+  ProcTaskFdReadlinkBody();
+  return NULL;
+}
+
+TEST(bug_26110743, ProcTaskFdReadlink) {
+  pthread_t t;
+  ASSERT_EQ(0, pthread_create(&t, NULL, ProcTaskFdReadlink, NULL));
+  void* result;
+  ASSERT_EQ(0, pthread_join(t, &result));
+  ASSERT_EQ(NULL, result);
+}
+
+TEST(bug_26110743, ProcTaskFdReadlink_NotDumpable) {
+  int dumpable = prctl(PR_GET_DUMPABLE, 0, 0, 0, 0);
+  prctl(PR_SET_DUMPABLE, 0, 0, 0, 0);
+  auto guard = make_scope_guard([&]() {
+    // restore dumpable
+    prctl(PR_SET_DUMPABLE, dumpable, 0, 0, 0);
+  });
+
+  pthread_t t;
+  ASSERT_EQ(0, pthread_create(&t, NULL, ProcTaskFdReadlink, NULL));
+  void* result;
+  ASSERT_EQ(0, pthread_join(t, &result));
+  ASSERT_EQ(NULL, result);
+}
diff --git a/tests/dirent_test.cpp b/tests/dirent_test.cpp
index 214dd78..fa05ca1 100644
--- a/tests/dirent_test.cpp
+++ b/tests/dirent_test.cpp
@@ -81,6 +81,72 @@
   CheckProcSelf(name_set);
 }
 
+TEST(dirent, scandirat_scandirat64) {
+  // Get everything from /proc/self...
+  dirent** entries;
+  int entry_count = scandir("/proc/self", &entries, NULL, alphasort);
+  ASSERT_GE(entry_count, 0);
+
+  int proc_fd = open("/proc", O_DIRECTORY);
+  ASSERT_NE(-1, proc_fd);
+
+  dirent** entries_at;
+  int entry_count_at = scandirat(proc_fd, "self", &entries_at, NULL, alphasort);
+  ASSERT_EQ(entry_count, entry_count_at);
+
+  dirent64** entries_at64;
+  int entry_count_at64 = scandirat64(proc_fd, "self", &entries_at64, NULL, alphasort64);
+  ASSERT_EQ(entry_count, entry_count_at64);
+
+  close(proc_fd);
+
+  // scandirat and scandirat64 should return the same results as scandir.
+  std::set<std::string> name_set, name_set_at, name_set_at64;
+  std::vector<std::string> unsorted_name_list, unsorted_name_list_at, unsorted_name_list_at64;
+  ScanEntries(entries, entry_count, name_set, unsorted_name_list);
+  ScanEntries(entries_at, entry_count_at, name_set_at, unsorted_name_list_at);
+  ScanEntries(entries_at64, entry_count_at64, name_set_at64, unsorted_name_list_at64);
+
+  ASSERT_EQ(name_set, name_set_at);
+  ASSERT_EQ(name_set, name_set_at64);
+  ASSERT_EQ(unsorted_name_list, unsorted_name_list_at);
+  ASSERT_EQ(unsorted_name_list, unsorted_name_list_at64);
+}
+
+TEST(dirent, scandir_ENOENT) {
+  dirent** entries;
+  errno = 0;
+  ASSERT_EQ(-1, scandir("/does-not-exist", &entries, nullptr, nullptr));
+  ASSERT_EQ(ENOENT, errno);
+}
+
+TEST(dirent, scandir64_ENOENT) {
+  dirent64** entries;
+  errno = 0;
+  ASSERT_EQ(-1, scandir64("/does-not-exist", &entries, nullptr, nullptr));
+  ASSERT_EQ(ENOENT, errno);
+}
+
+TEST(dirent, scandirat_ENOENT) {
+  int root_fd = open("/", O_DIRECTORY | O_RDONLY);
+  ASSERT_NE(-1, root_fd);
+  dirent** entries;
+  errno = 0;
+  ASSERT_EQ(-1, scandirat(root_fd, "does-not-exist", &entries, nullptr, nullptr));
+  ASSERT_EQ(ENOENT, errno);
+  close(root_fd);
+}
+
+TEST(dirent, scandirat64_ENOENT) {
+  int root_fd = open("/", O_DIRECTORY | O_RDONLY);
+  ASSERT_NE(-1, root_fd);
+  dirent64** entries;
+  errno = 0;
+  ASSERT_EQ(-1, scandirat64(root_fd, "does-not-exist", &entries, nullptr, nullptr));
+  ASSERT_EQ(ENOENT, errno);
+  close(root_fd);
+}
+
 TEST(dirent, fdopendir_invalid) {
   ASSERT_TRUE(fdopendir(-1) == NULL);
   ASSERT_EQ(EBADF, errno);
diff --git a/tests/dlext_private.h b/tests/dlext_private.h
new file mode 100644
index 0000000..049db91
--- /dev/null
+++ b/tests/dlext_private.h
@@ -0,0 +1,93 @@
+/*
+ * Copyright (C) 2016 The Android Open Source Project
+ *
+ * Licensed under the Apache License, Version 2.0 (the "License");
+ * you may not use this file except in compliance with the License.
+ * You may obtain a copy of the License at
+ *
+ *      http://www.apache.org/licenses/LICENSE-2.0
+ *
+ * Unless required by applicable law or agreed to in writing, software
+ * distributed under the License is distributed on an "AS IS" BASIS,
+ * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
+ * See the License for the specific language governing permissions and
+ * limitations under the License.
+ */
+
+#ifndef __ANDROID_DLEXT_NAMESPACES_H__
+#define __ANDROID_DLEXT_NAMESPACES_H__
+
+#include <android/dlext.h>
+
+__BEGIN_DECLS
+
+/*
+ * Initializes public and anonymous namespaces. The public_ns_sonames is the list of sonames
+ * to be included into public namespace separated by colon. Example: "libc.so:libm.so:libdl.so".
+ * The libraries in this list should be loaded prior to this call.
+ *
+ * The anon_ns_library_path is the search path for anonymous namespace. The anonymous namespace
+ * is used in the case when linker cannot identify the caller of dlopen/dlsym. This happens
+ * for the code not loaded by dynamic linker; for example calls from the mono-compiled code.
+ */
+extern bool android_init_namespaces(const char* public_ns_sonames,
+                                    const char* anon_ns_library_path);
+
+
+enum {
+  /* A regular namespace is the namespace with a custom search path that does
+   * not impose any restrictions on the location of native libraries.
+   */
+  ANDROID_NAMESPACE_TYPE_REGULAR = 0,
+
+  /* An isolated namespace requires all the libraries to be on the search path
+   * or under permitted_when_isolated_path. The search path is the union of
+   * ld_library_path and default_library_path.
+   */
+  ANDROID_NAMESPACE_TYPE_ISOLATED = 1,
+
+  /* The shared namespace clones the list of libraries of the caller namespace upon creation
+   * which means that they are shared between namespaces - the caller namespace and the new one
+   * will use the same copy of a library if it was loaded prior to android_create_namespace call.
+   *
+   * Note that libraries loaded after the namespace is created will not be shared.
+   *
+   * Shared namespaces can be isolated or regular. Note that they do not inherit the search path nor
+   * permitted_path from the caller's namespace.
+   */
+  ANDROID_NAMESPACE_TYPE_SHARED = 2,
+  ANDROID_NAMESPACE_TYPE_SHARED_ISOLATED = ANDROID_NAMESPACE_TYPE_SHARED |
+                                           ANDROID_NAMESPACE_TYPE_ISOLATED,
+};
+
+/*
+ * Creates new linker namespace.
+ * ld_library_path and default_library_path represent the search path
+ * for the libraries in the namespace.
+ *
+ * The libraries in the namespace are searched by folowing order:
+ * 1. ld_library_path (Think of this as namespace-local LD_LIBRARY_PATH)
+ * 2. In directories specified by DT_RUNPATH of the "needed by" binary.
+ * 3. deault_library_path (This of this as namespace-local default library path)
+ *
+ * When type is ANDROID_NAMESPACE_TYPE_ISOLATED the resulting namespace requires all of
+ * the libraries to be on the search path or under the permitted_when_isolated_path;
+ * the search_path is ld_library_path:default_library_path. Note that the
+ * permitted_when_isolated_path path is not part of the search_path and
+ * does not affect the search order. It is a way to allow loading libraries from specific
+ * locations when using absolute path.
+ * If a library or any of its dependencies are outside of the permitted_when_isolated_path
+ * and search_path, and it is not part of the public namespace dlopen will fail.
+ */
+extern struct android_namespace_t* android_create_namespace(const char* name,
+                                                            const char* ld_library_path,
+                                                            const char* default_library_path,
+                                                            uint64_t type,
+                                                            const char* permitted_when_isolated_path,
+                                                            android_namespace_t* parent);
+
+extern void android_set_application_target_sdk_version(uint32_t target);
+
+__END_DECLS
+
+#endif /* __ANDROID_DLEXT_NAMESPACES_H__ */
diff --git a/tests/dlext_test.cpp b/tests/dlext_test.cpp
index f901708..ee61d5f 100644
--- a/tests/dlext_test.cpp
+++ b/tests/dlext_test.cpp
@@ -30,8 +30,11 @@
 #include <sys/wait.h>
 
 #include <pagemap/pagemap.h>
+#include <ziparchive/zip_archive.h>
 
 #include "TemporaryFile.h"
+#include "utils.h"
+#include "dlext_private.h"
 
 #define ASSERT_DL_NOTNULL(ptr) \
     ASSERT_TRUE(ptr != nullptr) << "dlerror: " << dlerror()
@@ -52,15 +55,15 @@
 #define LIBSIZE 1024*1024 // how much address space to reserve for it
 
 #if defined(__LP64__)
-#define LIBPATH_PREFIX "/nativetest64/libdlext_test_fd/"
+#define NATIVE_TESTS_PATH "/nativetest64"
 #else
-#define LIBPATH_PREFIX "/nativetest/libdlext_test_fd/"
+#define NATIVE_TESTS_PATH "/nativetest"
 #endif
 
-#define LIBPATH LIBPATH_PREFIX "libdlext_test_fd.so"
-#define LIBZIPPATH LIBPATH_PREFIX "libdlext_test_fd_zipaligned.zip"
-
-#define LIBZIP_OFFSET 2*PAGE_SIZE
+#define LIBPATH NATIVE_TESTS_PATH "/libdlext_test_fd/libdlext_test_fd.so"
+#define LIBZIPPATH NATIVE_TESTS_PATH "/libdlext_test_zip/libdlext_test_zip_zipaligned.zip"
+#define LIBZIPPATH_WITH_RUNPATH NATIVE_TESTS_PATH "/libdlext_test_runpath_zip/libdlext_test_runpath_zip_zipaligned.zip"
+#define LIBZIP_SIMPLE_ZIP "libdir/libatest_simple_zip.so"
 
 class DlExtTest : public ::testing::Test {
 protected:
@@ -114,6 +117,10 @@
   fn f = reinterpret_cast<fn>(dlsym(handle_, "getRandomNumber"));
   ASSERT_DL_NOTNULL(f);
   EXPECT_EQ(4, f());
+
+  uint32_t* taxicab_number = reinterpret_cast<uint32_t*>(dlsym(handle_, "dlopen_testlib_taxicab_number"));
+  ASSERT_DL_NOTNULL(taxicab_number);
+  EXPECT_EQ(1729U, *taxicab_number);
 }
 
 TEST_F(DlExtTest, ExtInfoUseFdWithOffset) {
@@ -122,14 +129,24 @@
   android_dlextinfo extinfo;
   extinfo.flags = ANDROID_DLEXT_USE_LIBRARY_FD | ANDROID_DLEXT_USE_LIBRARY_FD_OFFSET;
   extinfo.library_fd = TEMP_FAILURE_RETRY(open(lib_path.c_str(), O_RDONLY | O_CLOEXEC));
-  extinfo.library_fd_offset = LIBZIP_OFFSET;
+
+  // Find the offset of the shared library in the zip.
+  ZipArchiveHandle handle;
+  ASSERT_EQ(0, OpenArchive(lib_path.c_str(), &handle));
+  ZipEntry zip_entry;
+  ZipString zip_name;
+  zip_name.name = reinterpret_cast<const uint8_t*>(LIBZIP_SIMPLE_ZIP);
+  zip_name.name_length = sizeof(LIBZIP_SIMPLE_ZIP) - 1;
+  ASSERT_EQ(0, FindEntry(handle, zip_name, &zip_entry));
+  extinfo.library_fd_offset = zip_entry.offset;
+  CloseArchive(handle);
 
   handle_ = android_dlopen_ext(lib_path.c_str(), RTLD_NOW, &extinfo);
   ASSERT_DL_NOTNULL(handle_);
 
-  fn f = reinterpret_cast<fn>(dlsym(handle_, "getRandomNumber"));
-  ASSERT_DL_NOTNULL(f);
-  EXPECT_EQ(4, f());
+  uint32_t* taxicab_number = reinterpret_cast<uint32_t*>(dlsym(handle_, "dlopen_testlib_taxicab_number"));
+  ASSERT_DL_NOTNULL(taxicab_number);
+  EXPECT_EQ(1729U, *taxicab_number);
 }
 
 TEST_F(DlExtTest, ExtInfoUseFdWithInvalidOffset) {
@@ -159,18 +176,24 @@
   ASSERT_TRUE(handle_ == nullptr);
   ASSERT_SUBSTR("dlopen failed: file offset for the library \"libname_placeholder\" is negative", dlerror());
 
-  extinfo.library_fd_offset = PAGE_SIZE;
+  extinfo.library_fd_offset = 0;
   handle_ = android_dlopen_ext("libname_ignored", RTLD_NOW, &extinfo);
   ASSERT_TRUE(handle_ == nullptr);
   ASSERT_EQ("dlopen failed: \"" + lib_realpath + "\" has bad ELF magic", dlerror());
 
+  // Check if dlsym works after unsuccessful dlopen().
+  // Supply non-exiting one to make linker visit every soinfo.
+  void* sym = dlsym(RTLD_DEFAULT, "this_symbol_does_not_exist___");
+  ASSERT_TRUE(sym == nullptr);
+
   close(extinfo.library_fd);
 }
 
-TEST_F(DlExtTest, ExtInfoUseOffsetWihtoutFd) {
+TEST_F(DlExtTest, ExtInfoUseOffsetWithoutFd) {
   android_dlextinfo extinfo;
   extinfo.flags = ANDROID_DLEXT_USE_LIBRARY_FD_OFFSET;
-  extinfo.library_fd_offset = LIBZIP_OFFSET;
+  // This offset will not be used, so it doesn't matter.
+  extinfo.library_fd_offset = 0;
 
   handle_ = android_dlopen_ext("/some/lib/that/does_not_exist", RTLD_NOW, &extinfo);
   ASSERT_TRUE(handle_ == nullptr);
@@ -214,17 +237,34 @@
 TEST(dlfcn, dlopen_from_zip_absolute_path) {
   const std::string lib_path = std::string(getenv("ANDROID_DATA")) + LIBZIPPATH;
 
-  void* handle = dlopen((lib_path + "!/libdir/libdlext_test_fd.so").c_str(), RTLD_NOW);
+  void* handle = dlopen((lib_path + "!/libdir/libatest_simple_zip.so").c_str(), RTLD_NOW);
   ASSERT_TRUE(handle != nullptr) << dlerror();
 
-  int (*fn)(void);
-  fn = reinterpret_cast<int (*)(void)>(dlsym(handle, "getRandomNumber"));
-  ASSERT_TRUE(fn != nullptr);
-  EXPECT_EQ(4, fn());
+  uint32_t* taxicab_number = reinterpret_cast<uint32_t*>(dlsym(handle, "dlopen_testlib_taxicab_number"));
+  ASSERT_DL_NOTNULL(taxicab_number);
+  EXPECT_EQ(1729U, *taxicab_number);
 
   dlclose(handle);
 }
 
+TEST(dlfcn, dlopen_from_zip_with_dt_runpath) {
+  const std::string lib_path = std::string(getenv("ANDROID_DATA")) + LIBZIPPATH_WITH_RUNPATH;
+
+  void* handle = dlopen((lib_path + "!/libdir/libtest_dt_runpath_d_zip.so").c_str(), RTLD_NOW);
+
+  ASSERT_TRUE(handle != nullptr) << dlerror();
+
+  typedef void *(* dlopen_b_fn)();
+  dlopen_b_fn fn = (dlopen_b_fn)dlsym(handle, "dlopen_b");
+  ASSERT_TRUE(fn != nullptr) << dlerror();
+
+  void *p = fn();
+  ASSERT_TRUE(p != nullptr) << dlerror();
+
+  dlclose(p);
+  dlclose(handle);
+}
+
 TEST(dlfcn, dlopen_from_zip_ld_library_path) {
   const std::string lib_path = std::string(getenv("ANDROID_DATA")) + LIBZIPPATH + "!/libdir";
 
@@ -234,12 +274,12 @@
 
   ASSERT_TRUE(android_update_LD_LIBRARY_PATH != nullptr) << dlerror();
 
-  void* handle = dlopen("libdlext_test_fd.so", RTLD_NOW);
+  void* handle = dlopen("libdlext_test_zip.so", RTLD_NOW);
   ASSERT_TRUE(handle == nullptr);
 
   android_update_LD_LIBRARY_PATH(lib_path.c_str());
 
-  handle = dlopen("libdlext_test_fd.so", RTLD_NOW);
+  handle = dlopen("libdlext_test_zip.so", RTLD_NOW);
   ASSERT_TRUE(handle != nullptr) << dlerror();
 
   int (*fn)(void);
@@ -247,13 +287,17 @@
   ASSERT_TRUE(fn != nullptr);
   EXPECT_EQ(4, fn());
 
+  uint32_t* taxicab_number =
+          reinterpret_cast<uint32_t*>(dlsym(handle, "dlopen_testlib_taxicab_number"));
+  ASSERT_DL_NOTNULL(taxicab_number);
+  EXPECT_EQ(1729U, *taxicab_number);
+
   dlclose(handle);
 }
 
 
 TEST_F(DlExtTest, Reserved) {
-  void* start = mmap(nullptr, LIBSIZE, PROT_NONE, MAP_PRIVATE | MAP_ANONYMOUS,
-                     -1, 0);
+  void* start = mmap(nullptr, LIBSIZE, PROT_NONE, MAP_PRIVATE | MAP_ANONYMOUS, -1, 0);
   ASSERT_TRUE(start != MAP_FAILED);
   android_dlextinfo extinfo;
   extinfo.flags = ANDROID_DLEXT_RESERVED_ADDRESS;
@@ -267,11 +311,17 @@
   EXPECT_LT(reinterpret_cast<void*>(f),
             reinterpret_cast<char*>(start) + LIBSIZE);
   EXPECT_EQ(4, f());
+
+  // Check that after dlclose reserved address space is unmapped (and can be reused)
+  dlclose(handle_);
+  handle_ = nullptr;
+
+  void* new_start = mmap(start, PAGE_SIZE, PROT_NONE, MAP_PRIVATE | MAP_ANONYMOUS, -1, 0);
+  ASSERT_NE(start, new_start) << "dlclose unmapped reserved space";
 }
 
 TEST_F(DlExtTest, ReservedTooSmall) {
-  void* start = mmap(nullptr, PAGE_SIZE, PROT_NONE, MAP_PRIVATE | MAP_ANONYMOUS,
-                     -1, 0);
+  void* start = mmap(nullptr, PAGE_SIZE, PROT_NONE, MAP_PRIVATE | MAP_ANONYMOUS, -1, 0);
   ASSERT_TRUE(start != MAP_FAILED);
   android_dlextinfo extinfo;
   extinfo.flags = ANDROID_DLEXT_RESERVED_ADDRESS;
@@ -282,8 +332,7 @@
 }
 
 TEST_F(DlExtTest, ReservedHint) {
-  void* start = mmap(nullptr, LIBSIZE, PROT_NONE, MAP_PRIVATE | MAP_ANONYMOUS,
-                     -1, 0);
+  void* start = mmap(nullptr, LIBSIZE, PROT_NONE, MAP_PRIVATE | MAP_ANONYMOUS, -1, 0);
   ASSERT_TRUE(start != MAP_FAILED);
   android_dlextinfo extinfo;
   extinfo.flags = ANDROID_DLEXT_RESERVED_ADDRESS_HINT;
@@ -300,8 +349,7 @@
 }
 
 TEST_F(DlExtTest, ReservedHintTooSmall) {
-  void* start = mmap(nullptr, PAGE_SIZE, PROT_NONE, MAP_PRIVATE | MAP_ANONYMOUS,
-                     -1, 0);
+  void* start = mmap(nullptr, PAGE_SIZE, PROT_NONE, MAP_PRIVATE | MAP_ANONYMOUS, -1, 0);
   ASSERT_TRUE(start != MAP_FAILED);
   android_dlextinfo extinfo;
   extinfo.flags = ANDROID_DLEXT_RESERVED_ADDRESS_HINT;
@@ -317,12 +365,53 @@
   EXPECT_EQ(4, f());
 }
 
+TEST_F(DlExtTest, LoadAtFixedAddress) {
+  void* start = mmap(nullptr, LIBSIZE, PROT_NONE, MAP_PRIVATE | MAP_ANONYMOUS, -1, 0);
+  ASSERT_TRUE(start != MAP_FAILED);
+  munmap(start, LIBSIZE);
+
+  android_dlextinfo extinfo;
+  extinfo.flags = ANDROID_DLEXT_LOAD_AT_FIXED_ADDRESS;
+  extinfo.reserved_addr = start;
+
+  handle_ = android_dlopen_ext(LIBNAME, RTLD_NOW, &extinfo);
+  ASSERT_DL_NOTNULL(handle_);
+  fn f = reinterpret_cast<fn>(dlsym(handle_, "getRandomNumber"));
+  ASSERT_DL_NOTNULL(f);
+  EXPECT_GE(reinterpret_cast<void*>(f), start);
+  EXPECT_LT(reinterpret_cast<void*>(f), reinterpret_cast<char*>(start) + LIBSIZE);
+
+  EXPECT_EQ(4, f());
+  dlclose(handle_);
+  handle_ = nullptr;
+
+  // Check that dlclose unmapped the file
+  void* addr = mmap(start, LIBSIZE, PROT_NONE, MAP_PRIVATE | MAP_ANONYMOUS, -1, 0);
+  ASSERT_EQ(start, addr) << "dlclose did not unmap the memory";
+}
+
+TEST_F(DlExtTest, LoadAtFixedAddressTooSmall) {
+  void* start = mmap(nullptr, LIBSIZE + PAGE_SIZE, PROT_NONE,
+                         MAP_PRIVATE | MAP_ANONYMOUS, -1, 0);
+  ASSERT_TRUE(start != MAP_FAILED);
+  munmap(start, LIBSIZE + PAGE_SIZE);
+  void* new_addr = mmap(reinterpret_cast<uint8_t*>(start) + PAGE_SIZE, LIBSIZE, PROT_NONE,
+                        MAP_PRIVATE | MAP_ANONYMOUS, -1, 0);
+  ASSERT_TRUE(new_addr != MAP_FAILED);
+
+  android_dlextinfo extinfo;
+  extinfo.flags = ANDROID_DLEXT_LOAD_AT_FIXED_ADDRESS;
+  extinfo.reserved_addr = start;
+
+  handle_ = android_dlopen_ext(LIBNAME, RTLD_NOW, &extinfo);
+  ASSERT_TRUE(handle_ == nullptr);
+}
+
 class DlExtRelroSharingTest : public DlExtTest {
 protected:
   virtual void SetUp() {
     DlExtTest::SetUp();
-    void* start = mmap(nullptr, LIBSIZE, PROT_NONE, MAP_PRIVATE | MAP_ANONYMOUS,
-                       -1, 0);
+    void* start = mmap(nullptr, LIBSIZE, PROT_NONE, MAP_PRIVATE | MAP_ANONYMOUS, -1, 0);
     ASSERT_TRUE(start != MAP_FAILED);
     extinfo_.flags = ANDROID_DLEXT_RESERVED_ADDRESS;
     extinfo_.reserved_addr = start;
@@ -354,10 +443,7 @@
     // continuing in parent
     ASSERT_NOERROR(close(relro_fd));
     ASSERT_NOERROR(pid);
-    int status;
-    ASSERT_EQ(pid, waitpid(pid, &status, 0));
-    ASSERT_TRUE(WIFEXITED(status));
-    ASSERT_EQ(0, WEXITSTATUS(status));
+    AssertChildExited(pid, 0);
 
     // reopen file for reading so it can be used
     relro_fd = open(relro_file, O_RDONLY);
@@ -372,6 +458,11 @@
     fn f = reinterpret_cast<fn>(dlsym(handle_, "getRandomNumber"));
     ASSERT_DL_NOTNULL(f);
     EXPECT_EQ(4, f());
+
+    uint32_t* taxicab_number =
+            reinterpret_cast<uint32_t*>(dlsym(handle_, "dlopen_testlib_taxicab_number"));
+    ASSERT_DL_NOTNULL(taxicab_number);
+    EXPECT_EQ(1729U, *taxicab_number);
   }
 
   void SpawnChildrenAndMeasurePss(const char* lib, bool share_relro, size_t* pss_out);
@@ -461,7 +552,7 @@
   const int CHILDREN = 20;
 
   // Create children
-  pid_t childpid[CHILDREN];
+  pid_t child_pids[CHILDREN];
   int childpipe[CHILDREN];
   for (int i=0; i<CHILDREN; ++i) {
     char read_buf;
@@ -506,7 +597,7 @@
     close(child_done_pipe[0]);
 
     // save the child's pid and the parent_done_pipe
-    childpid[i] = child;
+    child_pids[i] = child;
     childpipe[i] = parent_done_pipe[1];
   }
 
@@ -514,7 +605,7 @@
   size_t total_pss = 0;
   for (int i=0; i<CHILDREN; ++i) {
     size_t child_pss;
-    ASSERT_NO_FATAL_FAILURE(getPss(childpid[i], &child_pss));
+    ASSERT_NO_FATAL_FAILURE(getPss(child_pids[i], &child_pss));
     total_pss += child_pss;
   }
   *pss_out = total_pss;
@@ -523,10 +614,596 @@
   for (int i=0; i<CHILDREN; ++i) {
     ASSERT_NOERROR(close(childpipe[i]));
   }
-  for (int i=0; i<CHILDREN; ++i) {
-    int status;
-    ASSERT_EQ(childpid[i], waitpid(childpid[i], &status, 0));
-    ASSERT_TRUE(WIFEXITED(status));
-    ASSERT_EQ(0, WEXITSTATUS(status));
+  for (int i = 0; i < CHILDREN; ++i) {
+    AssertChildExited(child_pids[i], 0);
   }
 }
+
+// Testing namespaces
+static const char* g_public_lib = "libnstest_public.so";
+
+TEST(dlext, ns_smoke) {
+  static const char* root_lib = "libnstest_root.so";
+  std::string path = std::string("libc.so:libc++.so:libdl.so:libm.so:") + g_public_lib;
+
+  ASSERT_FALSE(android_init_namespaces(path.c_str(), nullptr));
+  ASSERT_STREQ("android_init_namespaces failed: error initializing public namespace: "
+               "\"libnstest_public.so\" was not found in the default namespace", dlerror());
+
+  const std::string lib_path = std::string(getenv("ANDROID_DATA")) + NATIVE_TESTS_PATH;
+
+  const std::string lib_public_path = lib_path + "/public_namespace_libs/" + g_public_lib;
+  void* handle_public = dlopen(lib_public_path.c_str(), RTLD_NOW);
+  ASSERT_TRUE(handle_public != nullptr) << dlerror();
+
+  ASSERT_TRUE(android_init_namespaces(path.c_str(), nullptr)) << dlerror();
+
+  // Check that libraries added to public namespace are NODELETE
+  dlclose(handle_public);
+  handle_public = dlopen((lib_path + "/public_namespace_libs/" + g_public_lib).c_str(),
+                         RTLD_NOW | RTLD_NOLOAD);
+
+  ASSERT_TRUE(handle_public != nullptr) << dlerror();
+
+  android_namespace_t* ns1 =
+          android_create_namespace("private", nullptr,
+                                   (lib_path + "/private_namespace_libs").c_str(),
+                                   ANDROID_NAMESPACE_TYPE_REGULAR, nullptr, nullptr);
+  ASSERT_TRUE(ns1 != nullptr) << dlerror();
+
+  android_namespace_t* ns2 =
+          android_create_namespace("private_isolated", nullptr,
+                                   (lib_path + "/private_namespace_libs").c_str(),
+                                   ANDROID_NAMESPACE_TYPE_ISOLATED, nullptr, nullptr);
+  ASSERT_TRUE(ns2 != nullptr) << dlerror();
+
+  // This should not have affect search path for default namespace:
+  ASSERT_TRUE(dlopen(root_lib, RTLD_NOW) == nullptr);
+  void* handle = dlopen(g_public_lib, RTLD_NOW);
+  ASSERT_TRUE(handle != nullptr) << dlerror();
+  dlclose(handle);
+
+  android_dlextinfo extinfo;
+  extinfo.flags = ANDROID_DLEXT_USE_NAMESPACE;
+  extinfo.library_namespace = ns1;
+
+  void* handle1 = android_dlopen_ext(root_lib, RTLD_NOW, &extinfo);
+  ASSERT_TRUE(handle1 != nullptr) << dlerror();
+
+  extinfo.library_namespace = ns2;
+  void* handle2 = android_dlopen_ext(root_lib, RTLD_NOW, &extinfo);
+  ASSERT_TRUE(handle2 != nullptr) << dlerror();
+
+  ASSERT_TRUE(handle1 != handle2);
+
+  // dlopen for a public library using an absolute path should work for isolated namespaces
+  extinfo.library_namespace = ns2;
+  handle = android_dlopen_ext(lib_public_path.c_str(), RTLD_NOW, &extinfo);
+  ASSERT_TRUE(handle != nullptr) << dlerror();
+  ASSERT_TRUE(handle == handle_public);
+
+  dlclose(handle);
+
+  typedef const char* (*fn_t)();
+
+  fn_t ns_get_local_string1 = reinterpret_cast<fn_t>(dlsym(handle1, "ns_get_local_string"));
+  ASSERT_TRUE(ns_get_local_string1 != nullptr) << dlerror();
+  fn_t ns_get_local_string2 = reinterpret_cast<fn_t>(dlsym(handle2, "ns_get_local_string"));
+  ASSERT_TRUE(ns_get_local_string2 != nullptr) << dlerror();
+
+  EXPECT_STREQ("This string is local to root library", ns_get_local_string1());
+  EXPECT_STREQ("This string is local to root library", ns_get_local_string2());
+
+  ASSERT_TRUE(ns_get_local_string1() != ns_get_local_string2());
+
+  fn_t ns_get_private_extern_string1 =
+          reinterpret_cast<fn_t>(dlsym(handle1, "ns_get_private_extern_string"));
+  ASSERT_TRUE(ns_get_private_extern_string1 != nullptr) << dlerror();
+  fn_t ns_get_private_extern_string2 =
+          reinterpret_cast<fn_t>(dlsym(handle2, "ns_get_private_extern_string"));
+  ASSERT_TRUE(ns_get_private_extern_string2 != nullptr) << dlerror();
+
+  EXPECT_STREQ("This string is from private namespace", ns_get_private_extern_string1());
+  EXPECT_STREQ("This string is from private namespace", ns_get_private_extern_string2());
+
+  ASSERT_TRUE(ns_get_private_extern_string1() != ns_get_private_extern_string2());
+
+  fn_t ns_get_public_extern_string1 =
+          reinterpret_cast<fn_t>(dlsym(handle1, "ns_get_public_extern_string"));
+  ASSERT_TRUE(ns_get_public_extern_string1 != nullptr) << dlerror();
+  fn_t ns_get_public_extern_string2 =
+          reinterpret_cast<fn_t>(dlsym(handle2, "ns_get_public_extern_string"));
+  ASSERT_TRUE(ns_get_public_extern_string2 != nullptr) << dlerror();
+
+  EXPECT_STREQ("This string is from public namespace", ns_get_public_extern_string1());
+  ASSERT_TRUE(ns_get_public_extern_string1() == ns_get_public_extern_string2());
+
+  // and now check that dlopen() does the right thing in terms of preserving namespace
+  fn_t ns_get_dlopened_string1 = reinterpret_cast<fn_t>(dlsym(handle1, "ns_get_dlopened_string"));
+  ASSERT_TRUE(ns_get_dlopened_string1 != nullptr) << dlerror();
+  fn_t ns_get_dlopened_string2 = reinterpret_cast<fn_t>(dlsym(handle2, "ns_get_dlopened_string"));
+  ASSERT_TRUE(ns_get_dlopened_string2 != nullptr) << dlerror();
+
+  EXPECT_STREQ("This string is from private namespace (dlopened library)", ns_get_dlopened_string1());
+  EXPECT_STREQ("This string is from private namespace (dlopened library)", ns_get_dlopened_string2());
+
+  ASSERT_TRUE(ns_get_dlopened_string1() != ns_get_dlopened_string2());
+
+  dlclose(handle1);
+
+  // Check if handle2 is still alive (and well)
+  ASSERT_STREQ("This string is local to root library", ns_get_local_string2());
+  ASSERT_STREQ("This string is from private namespace", ns_get_private_extern_string2());
+  ASSERT_STREQ("This string is from public namespace", ns_get_public_extern_string2());
+  ASSERT_STREQ("This string is from private namespace (dlopened library)", ns_get_dlopened_string2());
+
+  dlclose(handle2);
+}
+
+TEST(dlext, ns_isolated) {
+  static const char* root_lib = "libnstest_root_not_isolated.so";
+  std::string path = std::string("libc.so:libc++.so:libdl.so:libm.so:") + g_public_lib;
+
+  const std::string lib_path = std::string(getenv("ANDROID_DATA")) + NATIVE_TESTS_PATH;
+  const std::string lib_public_path = lib_path + "/public_namespace_libs/" + g_public_lib;
+  void* handle_public = dlopen(lib_public_path.c_str(), RTLD_NOW);
+  ASSERT_TRUE(handle_public != nullptr) << dlerror();
+
+  android_set_application_target_sdk_version(42U); // something > 23
+
+  ASSERT_TRUE(android_init_namespaces(path.c_str(), nullptr)) << dlerror();
+
+  android_namespace_t* ns_not_isolated =
+          android_create_namespace("private", nullptr,
+                                   (lib_path + "/private_namespace_libs").c_str(),
+                                   ANDROID_NAMESPACE_TYPE_REGULAR, nullptr, nullptr);
+  ASSERT_TRUE(ns_not_isolated != nullptr) << dlerror();
+
+  android_namespace_t* ns_isolated =
+          android_create_namespace("private_isolated1",
+                                   nullptr,
+                                   (lib_path + "/private_namespace_libs").c_str(),
+                                   ANDROID_NAMESPACE_TYPE_ISOLATED,
+                                   nullptr,
+                                   nullptr);
+  ASSERT_TRUE(ns_isolated != nullptr) << dlerror();
+
+  android_namespace_t* ns_isolated2 =
+          android_create_namespace("private_isolated2",
+                                   (lib_path + "/private_namespace_libs").c_str(),
+                                   nullptr,
+                                   ANDROID_NAMESPACE_TYPE_ISOLATED,
+                                   lib_path.c_str(),
+                                   nullptr);
+  ASSERT_TRUE(ns_isolated2 != nullptr) << dlerror();
+
+  ASSERT_TRUE(dlopen(root_lib, RTLD_NOW) == nullptr);
+  ASSERT_STREQ("dlopen failed: library \"libnstest_root_not_isolated.so\" not found", dlerror());
+
+  std::string lib_private_external_path =
+      lib_path + "/private_namespace_libs_external/libnstest_private_external.so";
+
+  // Load lib_private_external_path to default namespace
+  // (it should remain invisible for the isolated namespaces after this)
+  void* handle = dlopen(lib_private_external_path.c_str(), RTLD_NOW);
+  ASSERT_TRUE(handle != nullptr) << dlerror();
+
+  android_dlextinfo extinfo;
+  extinfo.flags = ANDROID_DLEXT_USE_NAMESPACE;
+  extinfo.library_namespace = ns_not_isolated;
+
+  void* handle1 = android_dlopen_ext(root_lib, RTLD_NOW, &extinfo);
+  ASSERT_TRUE(handle1 != nullptr) << dlerror();
+
+  extinfo.library_namespace = ns_isolated;
+
+  void* handle2 = android_dlopen_ext(root_lib, RTLD_NOW, &extinfo);
+  ASSERT_TRUE(handle2 == nullptr);
+  ASSERT_STREQ("dlopen failed: library \"libnstest_private_external.so\" not found", dlerror());
+
+  // Check dlopen by absolute path
+  handle2 = android_dlopen_ext(lib_private_external_path.c_str(), RTLD_NOW, &extinfo);
+  ASSERT_TRUE(handle2 == nullptr);
+  ASSERT_EQ("dlopen failed: library \"" + lib_private_external_path + "\" needed"
+            " or dlopened by \"" + get_executable_path() +  "\" is not accessible"
+            " for the namespace \"private_isolated1\"", dlerror());
+
+  extinfo.library_namespace = ns_isolated2;
+
+  // this should work because isolation_path for private_isolated2 includes lib_path
+  handle2 = android_dlopen_ext(root_lib, RTLD_NOW, &extinfo);
+  ASSERT_TRUE(handle2 != nullptr) << dlerror();
+  dlclose(handle2);
+
+  // Check dlopen by absolute path
+  handle2 = android_dlopen_ext(lib_private_external_path.c_str(), RTLD_NOW, &extinfo);
+  ASSERT_TRUE(handle2 != nullptr) << dlerror();
+  dlclose(handle2);
+
+  typedef const char* (*fn_t)();
+  fn_t ns_get_local_string = reinterpret_cast<fn_t>(dlsym(handle1, "ns_get_local_string"));
+  ASSERT_TRUE(ns_get_local_string != nullptr) << dlerror();
+
+  ASSERT_STREQ("This string is local to root library", ns_get_local_string());
+
+  fn_t ns_get_private_extern_string =
+          reinterpret_cast<fn_t>(dlsym(handle1, "ns_get_private_extern_string"));
+  ASSERT_TRUE(ns_get_private_extern_string != nullptr) << dlerror();
+
+  ASSERT_STREQ("This string is from private namespace", ns_get_private_extern_string());
+
+  fn_t ns_get_public_extern_string =
+          reinterpret_cast<fn_t>(dlsym(handle1, "ns_get_public_extern_string"));
+  ASSERT_TRUE(ns_get_public_extern_string != nullptr) << dlerror();
+
+  ASSERT_STREQ("This string is from public namespace", ns_get_public_extern_string());
+
+  fn_t ns_get_dlopened_string = reinterpret_cast<fn_t>(dlsym(handle1, "ns_get_dlopened_string"));
+  ASSERT_TRUE(ns_get_dlopened_string != nullptr) << dlerror();
+
+  ASSERT_STREQ("This string is from private namespace (dlopened library)", ns_get_dlopened_string());
+
+  dlclose(handle1);
+}
+
+TEST(dlext, ns_shared) {
+  static const char* root_lib = "libnstest_root_not_isolated.so";
+  static const char* root_lib_isolated = "libnstest_root.so";
+  std::string path = std::string("libc.so:libc++.so:libdl.so:libm.so:") + g_public_lib;
+
+  const std::string lib_path = std::string(getenv("ANDROID_DATA")) + NATIVE_TESTS_PATH;
+  const std::string lib_public_path = lib_path + "/public_namespace_libs/" + g_public_lib;
+  void* handle_public = dlopen(lib_public_path.c_str(), RTLD_NOW);
+  ASSERT_TRUE(handle_public != nullptr) << dlerror();
+
+  android_set_application_target_sdk_version(42U); // something > 23
+
+  ASSERT_TRUE(android_init_namespaces(path.c_str(), nullptr)) << dlerror();
+
+  // preload this library to the default namespace to check if it
+  // is shared later on.
+  void* handle_dlopened =
+          dlopen((lib_path + "/private_namespace_libs/libnstest_dlopened.so").c_str(), RTLD_NOW);
+  ASSERT_TRUE(handle_dlopened != nullptr) << dlerror();
+
+  android_namespace_t* ns_not_isolated =
+          android_create_namespace("private", nullptr,
+                                   (lib_path + "/private_namespace_libs").c_str(),
+                                   ANDROID_NAMESPACE_TYPE_REGULAR, nullptr, nullptr);
+  ASSERT_TRUE(ns_not_isolated != nullptr) << dlerror();
+
+  android_namespace_t* ns_isolated_shared =
+          android_create_namespace("private_isolated_shared", nullptr,
+                                   (lib_path + "/private_namespace_libs").c_str(),
+                                   ANDROID_NAMESPACE_TYPE_ISOLATED | ANDROID_NAMESPACE_TYPE_SHARED,
+                                   nullptr, nullptr);
+  ASSERT_TRUE(ns_isolated_shared != nullptr) << dlerror();
+
+  ASSERT_TRUE(dlopen(root_lib, RTLD_NOW) == nullptr);
+  ASSERT_STREQ("dlopen failed: library \"libnstest_root_not_isolated.so\" not found", dlerror());
+
+  std::string lib_private_external_path =
+      lib_path + "/private_namespace_libs_external/libnstest_private_external.so";
+
+  // Load lib_private_external_path to default namespace
+  // (it should remain invisible for the isolated namespaces after this)
+  void* handle = dlopen(lib_private_external_path.c_str(), RTLD_NOW);
+  ASSERT_TRUE(handle != nullptr) << dlerror();
+
+  android_dlextinfo extinfo;
+  extinfo.flags = ANDROID_DLEXT_USE_NAMESPACE;
+  extinfo.library_namespace = ns_not_isolated;
+
+  void* handle1 = android_dlopen_ext(root_lib, RTLD_NOW, &extinfo);
+  ASSERT_TRUE(handle1 != nullptr) << dlerror();
+
+  extinfo.library_namespace = ns_isolated_shared;
+
+  void* handle2 = android_dlopen_ext(root_lib, RTLD_NOW, &extinfo);
+  ASSERT_TRUE(handle2 == nullptr);
+  ASSERT_STREQ("dlopen failed: library \"libnstest_private_external.so\" not found", dlerror());
+
+  // Check dlopen by absolute path
+  handle2 = android_dlopen_ext(lib_private_external_path.c_str(), RTLD_NOW, &extinfo);
+  ASSERT_TRUE(handle2 == nullptr);
+  ASSERT_EQ("dlopen failed: library \"" + lib_private_external_path + "\" needed"
+            " or dlopened by \"" + get_executable_path() + "\" is not accessible"
+            " for the namespace \"private_isolated_shared\"", dlerror());
+
+  // load libnstest_root.so to shared namespace in order to check that everything is different
+  // except shared libnstest_dlopened.so
+
+  handle2 = android_dlopen_ext(root_lib_isolated, RTLD_NOW, &extinfo);
+
+  typedef const char* (*fn_t)();
+  fn_t ns_get_local_string = reinterpret_cast<fn_t>(dlsym(handle1, "ns_get_local_string"));
+  ASSERT_TRUE(ns_get_local_string != nullptr) << dlerror();
+  fn_t ns_get_local_string_shared = reinterpret_cast<fn_t>(dlsym(handle2, "ns_get_local_string"));
+  ASSERT_TRUE(ns_get_local_string_shared != nullptr) << dlerror();
+
+  ASSERT_STREQ("This string is local to root library", ns_get_local_string());
+  ASSERT_STREQ("This string is local to root library", ns_get_local_string_shared());
+  ASSERT_TRUE(ns_get_local_string() != ns_get_local_string_shared());
+
+  fn_t ns_get_private_extern_string =
+          reinterpret_cast<fn_t>(dlsym(handle1, "ns_get_private_extern_string"));
+  ASSERT_TRUE(ns_get_private_extern_string != nullptr) << dlerror();
+  fn_t ns_get_private_extern_string_shared =
+          reinterpret_cast<fn_t>(dlsym(handle2, "ns_get_private_extern_string"));
+  ASSERT_TRUE(ns_get_private_extern_string_shared() != nullptr) << dlerror();
+
+  ASSERT_STREQ("This string is from private namespace", ns_get_private_extern_string());
+  ASSERT_STREQ("This string is from private namespace", ns_get_private_extern_string_shared());
+  ASSERT_TRUE(ns_get_private_extern_string() != ns_get_private_extern_string_shared());
+
+  fn_t ns_get_public_extern_string =
+          reinterpret_cast<fn_t>(dlsym(handle1, "ns_get_public_extern_string"));
+  ASSERT_TRUE(ns_get_public_extern_string != nullptr) << dlerror();
+  fn_t ns_get_public_extern_string_shared =
+          reinterpret_cast<fn_t>(dlsym(handle2, "ns_get_public_extern_string"));
+  ASSERT_TRUE(ns_get_public_extern_string_shared != nullptr) << dlerror();
+
+  ASSERT_STREQ("This string is from public namespace", ns_get_public_extern_string());
+  ASSERT_STREQ("This string is from public namespace", ns_get_public_extern_string_shared());
+  ASSERT_TRUE(ns_get_public_extern_string() == ns_get_public_extern_string_shared());
+
+  fn_t ns_get_dlopened_string = reinterpret_cast<fn_t>(dlsym(handle1, "ns_get_dlopened_string"));
+  ASSERT_TRUE(ns_get_dlopened_string != nullptr) << dlerror();
+  fn_t ns_get_dlopened_string_shared = reinterpret_cast<fn_t>(dlsym(handle2, "ns_get_dlopened_string"));
+  ASSERT_TRUE(ns_get_dlopened_string_shared != nullptr) << dlerror();
+  const char** ns_dlopened_string = static_cast<const char**>(dlsym(handle_dlopened, "g_private_dlopened_string"));
+  ASSERT_TRUE(ns_dlopened_string != nullptr) << dlerror();
+
+  ASSERT_STREQ("This string is from private namespace (dlopened library)", ns_get_dlopened_string());
+  ASSERT_STREQ("This string is from private namespace (dlopened library)", *ns_dlopened_string);
+  ASSERT_STREQ("This string is from private namespace (dlopened library)", ns_get_dlopened_string_shared());
+  ASSERT_TRUE(ns_get_dlopened_string() != ns_get_dlopened_string_shared());
+  ASSERT_TRUE(*ns_dlopened_string == ns_get_dlopened_string_shared());
+
+  dlclose(handle1);
+  dlclose(handle2);
+}
+
+TEST(dlext, ns_shared_dlclose) {
+  std::string path = "libc.so:libc++.so:libdl.so:libm.so";
+
+  const std::string lib_path = std::string(getenv("ANDROID_DATA")) + NATIVE_TESTS_PATH;
+
+  android_set_application_target_sdk_version(42U); // something > 23
+
+  ASSERT_TRUE(android_init_namespaces(path.c_str(), nullptr)) << dlerror();
+
+  // preload this library to the default namespace to check if it
+  // is shared later on.
+  void* handle_dlopened =
+          dlopen((lib_path + "/private_namespace_libs/libnstest_dlopened.so").c_str(), RTLD_NOW);
+  ASSERT_TRUE(handle_dlopened != nullptr) << dlerror();
+
+  android_namespace_t* ns_isolated_shared =
+          android_create_namespace("private_isolated_shared", nullptr,
+                                   (lib_path + "/private_namespace_libs").c_str(),
+                                   ANDROID_NAMESPACE_TYPE_ISOLATED | ANDROID_NAMESPACE_TYPE_SHARED,
+                                   nullptr, nullptr);
+  ASSERT_TRUE(ns_isolated_shared != nullptr) << dlerror();
+
+  // Check if "libnstest_dlopened.so" is loaded (and the same)
+  android_dlextinfo extinfo;
+  extinfo.flags = ANDROID_DLEXT_USE_NAMESPACE;
+  extinfo.library_namespace = ns_isolated_shared;
+
+  void* handle = android_dlopen_ext("libnstest_dlopened.so", RTLD_NOW | RTLD_NOLOAD, &extinfo);
+  ASSERT_TRUE(handle != nullptr) << dlerror();
+  ASSERT_TRUE(handle == handle_dlopened);
+  dlclose(handle);
+  dlclose(handle_dlopened);
+
+  // And now check that the library cannot be found by soname (and is no longer loaded)
+  handle = android_dlopen_ext("libnstest_dlopened.so", RTLD_NOW | RTLD_NOLOAD, &extinfo);
+  ASSERT_TRUE(handle == nullptr)
+      << "Error: libnstest_dlopened.so is still accessible in shared namespace";
+
+  handle = android_dlopen_ext((lib_path + "/private_namespace_libs/libnstest_dlopened.so").c_str(),
+                              RTLD_NOW | RTLD_NOLOAD, &extinfo);
+  ASSERT_TRUE(handle == nullptr)
+      << "Error: libnstest_dlopened.so is still accessible in shared namespace";
+
+  handle = dlopen("libnstest_dlopened.so", RTLD_NOW | RTLD_NOLOAD);
+  ASSERT_TRUE(handle == nullptr)
+      << "Error: libnstest_dlopened.so is still accessible in default namespace";
+
+  handle = dlopen((lib_path + "/private_namespace_libs/libnstest_dlopened.so").c_str(),
+                  RTLD_NOW | RTLD_NOLOAD);
+  ASSERT_TRUE(handle == nullptr)
+      << "Error: libnstest_dlopened.so is still accessible in default namespace";
+
+  // Now lets see if the soinfo area gets reused in the wrong way:
+  // load a library to default namespace.
+  const std::string lib_public_path = lib_path + "/public_namespace_libs/" + g_public_lib;
+  void* handle_public = dlopen(lib_public_path.c_str(), RTLD_NOW);
+  ASSERT_TRUE(handle_public != nullptr) << dlerror();
+
+  // try to find it in shared namespace
+  handle = android_dlopen_ext(g_public_lib, RTLD_NOW | RTLD_NOLOAD, &extinfo);
+  ASSERT_TRUE(handle == nullptr)
+      << "Error: " << g_public_lib << " is accessible in shared namespace";
+}
+
+TEST(dlext, ns_isolated_rtld_global) {
+  static const char* root_lib = "libnstest_root.so";
+  std::string path = "libc.so:libc++.so:libdl.so:libm.so";
+
+  ASSERT_TRUE(android_init_namespaces(path.c_str(), nullptr));
+
+  const std::string lib_path = std::string(getenv("ANDROID_DATA")) + NATIVE_TESTS_PATH;
+
+  const std::string lib_public_path = lib_path + "/public_namespace_libs";
+
+  android_namespace_t* ns1 =
+          android_create_namespace("isolated1",
+                                   nullptr,
+                                   (lib_path + "/private_namespace_libs").c_str(),
+                                   ANDROID_NAMESPACE_TYPE_ISOLATED,
+                                   lib_public_path.c_str(),
+                                   nullptr);
+  ASSERT_TRUE(ns1 != nullptr) << dlerror();
+
+  android_namespace_t* ns2 =
+          android_create_namespace("isolated2",
+                                   nullptr,
+                                   (lib_path + "/private_namespace_libs").c_str(),
+                                   ANDROID_NAMESPACE_TYPE_ISOLATED,
+                                   lib_public_path.c_str(),
+                                   nullptr);
+  ASSERT_TRUE(ns2 != nullptr) << dlerror();
+
+  android_dlextinfo extinfo;
+  extinfo.flags = ANDROID_DLEXT_USE_NAMESPACE;
+  extinfo.library_namespace = ns1;
+
+  void* handle_global = android_dlopen_ext((lib_public_path + "/" + g_public_lib).c_str(),
+                                           RTLD_GLOBAL,
+                                           &extinfo);
+
+  ASSERT_TRUE(handle_global != nullptr) << dlerror();
+
+  android_namespace_t* ns1_child =
+        android_create_namespace("isolated1_child",
+                                 nullptr,
+                                 (lib_path + "/private_namespace_libs").c_str(),
+                                 ANDROID_NAMESPACE_TYPE_ISOLATED,
+                                 nullptr,
+                                 ns1);
+
+  // Now - only ns1 and ns1 child should be able to dlopen root_lib
+  // attempt to use ns2 should result in dlerror()
+
+  // Check ns1_child first.
+  extinfo.flags = ANDROID_DLEXT_USE_NAMESPACE;
+  extinfo.library_namespace = ns1_child;
+
+  void* handle1 = android_dlopen_ext(root_lib, RTLD_NOW, &extinfo);
+  ASSERT_TRUE(handle1 != nullptr) << dlerror();
+
+  // now ns1
+  extinfo.flags = ANDROID_DLEXT_USE_NAMESPACE;
+  extinfo.library_namespace = ns1;
+
+  handle1 = android_dlopen_ext(root_lib, RTLD_NOW, &extinfo);
+  ASSERT_TRUE(handle1 != nullptr) << dlerror();
+
+  // and ns2 should fail
+  extinfo.flags = ANDROID_DLEXT_USE_NAMESPACE;
+  extinfo.library_namespace = ns2;
+
+  handle1 = android_dlopen_ext(root_lib, RTLD_NOW, &extinfo);
+  ASSERT_TRUE(handle1 == nullptr);
+  ASSERT_STREQ("dlopen failed: library \"libnstest_public.so\" not found", dlerror());
+}
+
+TEST(dlext, ns_anonymous) {
+  static const char* root_lib = "libnstest_root.so";
+  std::string path = std::string("libc.so:libc++.so:libdl.so:libm.so:") + g_public_lib;
+
+  const std::string lib_path = std::string(getenv("ANDROID_DATA")) + NATIVE_TESTS_PATH;
+
+  const std::string lib_public_path = lib_path + "/public_namespace_libs/" + g_public_lib;
+  void* handle_public = dlopen(lib_public_path.c_str(), RTLD_NOW);
+
+  ASSERT_TRUE(handle_public != nullptr) << dlerror();
+
+  ASSERT_TRUE(android_init_namespaces(path.c_str(), (lib_path + "/private_namespace_libs").c_str()))
+      << dlerror();
+
+  android_namespace_t* ns = android_create_namespace(
+                                "private", nullptr,
+                                (lib_path + "/private_namespace_libs").c_str(),
+                                ANDROID_NAMESPACE_TYPE_REGULAR, nullptr, nullptr);
+
+  ASSERT_TRUE(ns != nullptr) << dlerror();
+
+  std::string private_library_absolute_path = lib_path + "/private_namespace_libs/" + root_lib;
+
+  android_dlextinfo extinfo;
+  extinfo.flags = ANDROID_DLEXT_USE_NAMESPACE;
+  extinfo.library_namespace = ns;
+
+  // we are going to copy this library to anonymous mmap and call the copy of ns_get_dlopened_string
+  void* handle = android_dlopen_ext(private_library_absolute_path.c_str(), RTLD_NOW, &extinfo);
+  ASSERT_TRUE(handle != nullptr) << dlerror();
+
+  uintptr_t ns_get_dlopened_string_addr =
+      reinterpret_cast<uintptr_t>(dlsym(handle, "ns_get_dlopened_string"));
+  ASSERT_TRUE(ns_get_dlopened_string_addr != 0) << dlerror();
+  typedef const char* (*fn_t)();
+  fn_t ns_get_dlopened_string_private = reinterpret_cast<fn_t>(ns_get_dlopened_string_addr);
+
+  std::vector<map_record> maps;
+  Maps::parse_maps(&maps);
+
+  uintptr_t addr_start = 0;
+  uintptr_t addr_end = 0;
+  std::vector<map_record> maps_to_copy;
+
+  for (const auto& rec : maps) {
+    if (rec.pathname == private_library_absolute_path) {
+      if (addr_start == 0) {
+        addr_start = rec.addr_start;
+      }
+      addr_end = rec.addr_end;
+
+      maps_to_copy.push_back(rec);
+    }
+  }
+
+  // some sanity checks..
+  ASSERT_TRUE(addr_start > 0);
+  ASSERT_TRUE(addr_end > 0);
+  ASSERT_EQ(3U, maps_to_copy.size());
+  ASSERT_TRUE(ns_get_dlopened_string_addr > addr_start);
+  ASSERT_TRUE(ns_get_dlopened_string_addr < addr_end);
+
+  // copy
+  uintptr_t reserved_addr = reinterpret_cast<uintptr_t>(mmap(nullptr, addr_end - addr_start,
+                                                             PROT_NONE, MAP_ANON | MAP_PRIVATE,
+                                                             -1, 0));
+  ASSERT_TRUE(reinterpret_cast<void*>(reserved_addr) != MAP_FAILED);
+
+  for (const auto& rec : maps_to_copy) {
+    uintptr_t offset = rec.addr_start - addr_start;
+    size_t size = rec.addr_end - rec.addr_start;
+    void* addr = reinterpret_cast<void*>(reserved_addr + offset);
+    void* map = mmap(addr, size, PROT_READ | PROT_WRITE,
+                     MAP_ANON | MAP_PRIVATE | MAP_FIXED, -1, 0);
+    ASSERT_TRUE(map != MAP_FAILED);
+    memcpy(map, reinterpret_cast<void*>(rec.addr_start), size);
+    mprotect(map, size, rec.perms);
+  }
+
+  // call the function copy
+  uintptr_t ns_get_dlopened_string_offset  = ns_get_dlopened_string_addr - addr_start;
+  fn_t ns_get_dlopened_string_anon = reinterpret_cast<fn_t>(reserved_addr + ns_get_dlopened_string_offset);
+  ASSERT_STREQ("This string is from private namespace (dlopened library)",
+               ns_get_dlopened_string_anon());
+
+  // They should belong to different namespaces (private and anonymous)
+  ASSERT_STREQ("This string is from private namespace (dlopened library)",
+               ns_get_dlopened_string_private());
+
+  ASSERT_TRUE(ns_get_dlopened_string_anon() != ns_get_dlopened_string_private());
+}
+
+TEST(dlext, dlopen_handle_value_platform) {
+  void* handle = dlopen("libtest_dlsym_from_this.so", RTLD_NOW | RTLD_LOCAL);
+  ASSERT_TRUE((reinterpret_cast<uintptr_t>(handle) & 1) != 0)
+          << "dlopen should return odd value for the handle";
+  dlclose(handle);
+}
+
+TEST(dlext, dlopen_handle_value_app_compat) {
+  android_set_application_target_sdk_version(23);
+  void* handle = dlopen("libtest_dlsym_from_this.so", RTLD_NOW | RTLD_LOCAL);
+  ASSERT_TRUE(reinterpret_cast<uintptr_t>(handle) % sizeof(uintptr_t) == 0)
+          << "dlopen should return valid pointer";
+  dlclose(handle);
+}
+
diff --git a/tests/dlfcn_test.cpp b/tests/dlfcn_test.cpp
index 3c9b8e3..f842c66 100644
--- a/tests/dlfcn_test.cpp
+++ b/tests/dlfcn_test.cpp
@@ -51,12 +51,12 @@
 
 TEST(dlfcn, dlsym_in_executable) {
   dlerror(); // Clear any pending errors.
-  void* self = dlopen(NULL, RTLD_NOW);
-  ASSERT_TRUE(self != NULL);
-  ASSERT_TRUE(dlerror() == NULL);
+  void* self = dlopen(nullptr, RTLD_NOW);
+  ASSERT_TRUE(self != nullptr);
+  ASSERT_TRUE(dlerror() == nullptr);
 
   void* sym = dlsym(self, "DlSymTestFunction");
-  ASSERT_TRUE(sym != NULL);
+  ASSERT_TRUE(sym != nullptr);
 
   void (*function)() = reinterpret_cast<void(*)()>(sym);
 
@@ -175,11 +175,11 @@
 
 TEST(dlfcn, dlopen_noload) {
   void* handle = dlopen("libtest_simple.so", RTLD_NOW | RTLD_NOLOAD);
-  ASSERT_TRUE(handle == NULL);
+  ASSERT_TRUE(handle == nullptr);
   handle = dlopen("libtest_simple.so", RTLD_NOW);
   void* handle2 = dlopen("libtest_simple.so", RTLD_NOW | RTLD_NOLOAD);
-  ASSERT_TRUE(handle != NULL);
-  ASSERT_TRUE(handle2 != NULL);
+  ASSERT_TRUE(handle != nullptr);
+  ASSERT_TRUE(handle2 != nullptr);
   ASSERT_TRUE(handle == handle2);
   ASSERT_EQ(0, dlclose(handle));
   ASSERT_EQ(0, dlclose(handle2));
@@ -220,11 +220,11 @@
   // first check the set case
   setenv("IFUNC_CHOICE", "set", 1);
   void* handle = dlopen("libtest_ifunc.so", RTLD_NOW);
-  ASSERT_TRUE(handle != NULL);
+  ASSERT_TRUE(handle != nullptr);
   fn_ptr foo_ptr = reinterpret_cast<fn_ptr>(dlsym(handle, "foo"));
   fn_ptr foo_library_ptr = reinterpret_cast<fn_ptr>(dlsym(handle, "foo_library"));
-  ASSERT_TRUE(foo_ptr != NULL);
-  ASSERT_TRUE(foo_library_ptr != NULL);
+  ASSERT_TRUE(foo_ptr != nullptr);
+  ASSERT_TRUE(foo_library_ptr != nullptr);
   ASSERT_EQ(strncmp("set", foo_ptr(), 3), 0);
   ASSERT_EQ(strncmp("set", foo_library_ptr(), 3), 0);
   dlclose(handle);
@@ -232,11 +232,11 @@
   // then check the unset case
   unsetenv("IFUNC_CHOICE");
   handle = dlopen("libtest_ifunc.so", RTLD_NOW);
-  ASSERT_TRUE(handle != NULL);
+  ASSERT_TRUE(handle != nullptr);
   foo_ptr = reinterpret_cast<fn_ptr>(dlsym(handle, "foo"));
   foo_library_ptr = reinterpret_cast<fn_ptr>(dlsym(handle, "foo_library"));
-  ASSERT_TRUE(foo_ptr != NULL);
-  ASSERT_TRUE(foo_library_ptr != NULL);
+  ASSERT_TRUE(foo_ptr != nullptr);
+  ASSERT_TRUE(foo_library_ptr != nullptr);
   ASSERT_EQ(strncmp("unset", foo_ptr(), 5), 0);
   ASSERT_EQ(strncmp("unset", foo_library_ptr(), 3), 0);
   dlclose(handle);
@@ -315,9 +315,9 @@
   typedef int (*fn_t) (void);
   fn_t fn, fn2;
   fn = reinterpret_cast<fn_t>(dlsym(RTLD_DEFAULT, "check_order_dlsym_get_answer"));
-  ASSERT_TRUE(fn != NULL) << dlerror();
+  ASSERT_TRUE(fn != nullptr) << dlerror();
   fn2 = reinterpret_cast<fn_t>(dlsym(RTLD_DEFAULT, "check_order_dlsym_get_answer2"));
-  ASSERT_TRUE(fn2 != NULL) << dlerror();
+  ASSERT_TRUE(fn2 != nullptr) << dlerror();
 
   ASSERT_EQ(42, fn());
   ASSERT_EQ(43, fn2());
@@ -624,8 +624,10 @@
   handle = dlopen("libtest_with_dependency_loop.so", RTLD_NOW | RTLD_NOLOAD);
   ASSERT_TRUE(handle == nullptr);
 #ifdef __BIONIC__
-  // TODO: glibc returns nullptr on dlerror() here. Is it bug?
   ASSERT_STREQ("dlopen failed: library \"libtest_with_dependency_loop.so\" wasn't loaded and RTLD_NOLOAD prevented it", dlerror());
+#else
+  // TODO: glibc returns nullptr on dlerror() here. Is it bug?
+  ASSERT_TRUE(dlerror() == nullptr);
 #endif
 
   handle = dlopen("libtest_with_dependency_a.so", RTLD_NOW | RTLD_NOLOAD);
@@ -718,7 +720,7 @@
 
 TEST(dlfcn, dlopen_failure) {
   void* self = dlopen("/does/not/exist", RTLD_NOW);
-  ASSERT_TRUE(self == NULL);
+  ASSERT_TRUE(self == nullptr);
 #if defined(__BIONIC__)
   ASSERT_STREQ("dlopen failed: library \"/does/not/exist\" not found", dlerror());
 #else
@@ -737,7 +739,7 @@
   ASSERT_SUBSTR("/main/thread", main_thread_error);
 
   pthread_t t;
-  ASSERT_EQ(0, pthread_create(&t, NULL, ConcurrentDlErrorFn, NULL));
+  ASSERT_EQ(0, pthread_create(&t, nullptr, ConcurrentDlErrorFn, nullptr));
   void* result;
   ASSERT_EQ(0, pthread_join(t, &result));
   char* child_thread_error = static_cast<char*>(result);
@@ -749,31 +751,23 @@
 
 TEST(dlfcn, dlsym_failures) {
   dlerror(); // Clear any pending errors.
-  void* self = dlopen(NULL, RTLD_NOW);
-  ASSERT_TRUE(self != NULL);
-  ASSERT_TRUE(dlerror() == NULL);
+  void* self = dlopen(nullptr, RTLD_NOW);
+  ASSERT_TRUE(self != nullptr);
+  ASSERT_TRUE(dlerror() == nullptr);
 
   void* sym;
 
 #if defined(__BIONIC__) && !defined(__LP64__)
   // RTLD_DEFAULT in lp32 bionic is not (void*)0
   // so it can be distinguished from the NULL handle.
-  sym = dlsym(NULL, "test");
-  ASSERT_TRUE(sym == NULL);
-  ASSERT_SUBSTR("dlsym library handle is null", dlerror());
-#endif
-
-  // NULL symbol name.
-#if defined(__BIONIC__)
-  // glibc marks this parameter non-null and SEGVs if you cheat.
-  sym = dlsym(self, NULL);
-  ASSERT_TRUE(sym == NULL);
-  ASSERT_SUBSTR("", dlerror());
+  sym = dlsym(nullptr, "test");
+  ASSERT_TRUE(sym == nullptr);
+  ASSERT_STREQ("dlsym failed: library handle is null", dlerror());
 #endif
 
   // Symbol that doesn't exist.
   sym = dlsym(self, "ThisSymbolDoesNotExist");
-  ASSERT_TRUE(sym == NULL);
+  ASSERT_TRUE(sym == nullptr);
   ASSERT_SUBSTR("undefined symbol: ThisSymbolDoesNotExist", dlerror());
 
   ASSERT_EQ(0, dlclose(self));
@@ -781,12 +775,12 @@
 
 TEST(dlfcn, dladdr_executable) {
   dlerror(); // Clear any pending errors.
-  void* self = dlopen(NULL, RTLD_NOW);
-  ASSERT_TRUE(self != NULL);
-  ASSERT_TRUE(dlerror() == NULL);
+  void* self = dlopen(nullptr, RTLD_NOW);
+  ASSERT_TRUE(self != nullptr);
+  ASSERT_TRUE(dlerror() == nullptr);
 
   void* sym = dlsym(self, "DlSymTestFunction");
-  ASSERT_TRUE(sym != NULL);
+  ASSERT_TRUE(sym != nullptr);
 
   // Deliberately ask dladdr for an address inside a symbol, rather than the symbol base address.
   void* addr = reinterpret_cast<void*>(reinterpret_cast<uintptr_t>(sym) + 2);
@@ -796,15 +790,12 @@
   ASSERT_NE(rc, 0); // Zero on error, non-zero on success.
 
   // Get the name of this executable.
-  char executable_path[PATH_MAX];
-  rc = readlink("/proc/self/exe", executable_path, sizeof(executable_path));
-  ASSERT_NE(rc, -1);
-  executable_path[rc] = '\0';
+  const std::string& executable_path = get_executable_path();
 
   // The filename should be that of this executable.
   char dli_realpath[PATH_MAX];
   ASSERT_TRUE(realpath(info.dli_fname, dli_realpath) != nullptr);
-  ASSERT_STREQ(executable_path, dli_realpath);
+  ASSERT_STREQ(executable_path.c_str(), dli_realpath);
 
   // The symbol name should be the symbol we looked up.
   ASSERT_STREQ(info.dli_sname, "DlSymTestFunction");
@@ -829,11 +820,28 @@
   ASSERT_EQ(0, dlclose(self));
 }
 
-#if defined(__LP64__)
-#define BIONIC_PATH_TO_LIBC "/system/lib64/libc.so"
+TEST(dlfcn, dlopen_executable_by_absolute_path) {
+  void* handle1 = dlopen(nullptr, RTLD_NOW);
+  ASSERT_TRUE(handle1 != nullptr) << dlerror();
+
+  void* handle2 = dlopen(get_executable_path().c_str(), RTLD_NOW);
+  ASSERT_TRUE(handle2 != nullptr) << dlerror();
+
+#if defined(__BIONIC__)
+  ASSERT_EQ(handle1, handle2);
 #else
-#define BIONIC_PATH_TO_LIBC "/system/lib/libc.so"
+  GTEST_LOG_(INFO) << "Skipping ASSERT_EQ(handle1, handle2) for glibc: "
+                      "it loads a separate copy of the main executable "
+                      "on dlopen by absolute path.";
 #endif
+}
+
+#if defined(__LP64__)
+#define PATH_TO_SYSTEM_LIB "/system/lib64/"
+#else
+#define PATH_TO_SYSTEM_LIB "/system/lib/"
+#endif
+#define PATH_TO_LIBC PATH_TO_SYSTEM_LIB "libc.so"
 
 TEST(dlfcn, dladdr_libc) {
 #if defined(__BIONIC__)
@@ -843,7 +851,7 @@
 
   // /system/lib is symlink when this test is executed on host.
   char libc_realpath[PATH_MAX];
-  ASSERT_TRUE(realpath(BIONIC_PATH_TO_LIBC, libc_realpath) == libc_realpath);
+  ASSERT_TRUE(realpath(PATH_TO_LIBC, libc_realpath) == libc_realpath);
 
   ASSERT_STREQ(libc_realpath, info.dli_fname);
   // TODO: add check for dfi_fbase
@@ -861,12 +869,12 @@
   dlerror(); // Clear any pending errors.
 
   // No symbol corresponding to NULL.
-  ASSERT_EQ(dladdr(NULL, &info), 0); // Zero on error, non-zero on success.
-  ASSERT_TRUE(dlerror() == NULL); // dladdr(3) doesn't set dlerror(3).
+  ASSERT_EQ(dladdr(nullptr, &info), 0); // Zero on error, non-zero on success.
+  ASSERT_TRUE(dlerror() == nullptr); // dladdr(3) doesn't set dlerror(3).
 
   // No symbol corresponding to a stack address.
   ASSERT_EQ(dladdr(&info, &info), 0); // Zero on error, non-zero on success.
-  ASSERT_TRUE(dlerror() == NULL); // dladdr(3) doesn't set dlerror(3).
+  ASSERT_TRUE(dlerror() == nullptr); // dladdr(3) doesn't set dlerror(3).
 }
 
 // GNU-style ELF hash tables are incompatible with the MIPS ABI.
@@ -922,49 +930,49 @@
 
 #if defined(__GLIBC__)
   // glibc was smart enough not to define RTLD_NOW as 0, so it can detect missing flags.
-  handle = dlopen(NULL, 0);
-  ASSERT_TRUE(handle == NULL);
+  handle = dlopen(nullptr, 0);
+  ASSERT_TRUE(handle == nullptr);
   ASSERT_SUBSTR("invalid", dlerror());
 #endif
 
-  handle = dlopen(NULL, 0xffffffff);
-  ASSERT_TRUE(handle == NULL);
+  handle = dlopen(nullptr, 0xffffffff);
+  ASSERT_TRUE(handle == nullptr);
   ASSERT_SUBSTR("invalid", dlerror());
 
   // glibc actually allows you to choose both RTLD_NOW and RTLD_LAZY at the same time, and so do we.
-  handle = dlopen(NULL, RTLD_NOW|RTLD_LAZY);
-  ASSERT_TRUE(handle != NULL);
-  ASSERT_SUBSTR(NULL, dlerror());
+  handle = dlopen(nullptr, RTLD_NOW|RTLD_LAZY);
+  ASSERT_TRUE(handle != nullptr);
+  ASSERT_SUBSTR(nullptr, dlerror());
 }
 
 TEST(dlfcn, rtld_default_unknown_symbol) {
   void* addr = dlsym(RTLD_DEFAULT, "ANY_UNKNOWN_SYMBOL_NAME");
-  ASSERT_TRUE(addr == NULL);
+  ASSERT_TRUE(addr == nullptr);
 }
 
 TEST(dlfcn, rtld_default_known_symbol) {
   void* addr = dlsym(RTLD_DEFAULT, "fopen");
-  ASSERT_TRUE(addr != NULL);
+  ASSERT_TRUE(addr != nullptr);
 }
 
 TEST(dlfcn, rtld_next_unknown_symbol) {
   void* addr = dlsym(RTLD_NEXT, "ANY_UNKNOWN_SYMBOL_NAME");
-  ASSERT_TRUE(addr == NULL);
+  ASSERT_TRUE(addr == nullptr);
 }
 
 TEST(dlfcn, rtld_next_known_symbol) {
   void* addr = dlsym(RTLD_NEXT, "fopen");
-  ASSERT_TRUE(addr != NULL);
+  ASSERT_TRUE(addr != nullptr);
 }
 
 TEST(dlfcn, dlsym_weak_func) {
   dlerror();
   void* handle = dlopen("libtest_dlsym_weak_func.so", RTLD_NOW);
-  ASSERT_TRUE(handle != NULL);
+  ASSERT_TRUE(handle != nullptr);
 
   int (*weak_func)();
   weak_func = reinterpret_cast<int (*)()>(dlsym(handle, "weak_func"));
-  ASSERT_TRUE(weak_func != NULL) << "dlerror: " << dlerror();
+  ASSERT_TRUE(weak_func != nullptr) << "dlerror: " << dlerror();
   EXPECT_EQ(42, weak_func());
   dlclose(handle);
 }
@@ -982,8 +990,8 @@
 TEST(dlfcn, dlopen_symlink) {
   void* handle1 = dlopen("libdlext_test.so", RTLD_NOW);
   void* handle2 = dlopen("libdlext_test_v2.so", RTLD_NOW);
-  ASSERT_TRUE(handle1 != NULL);
-  ASSERT_TRUE(handle2 != NULL);
+  ASSERT_TRUE(handle1 != nullptr);
+  ASSERT_TRUE(handle2 != nullptr);
   ASSERT_EQ(handle1, handle2);
   dlclose(handle1);
   dlclose(handle2);
@@ -1053,6 +1061,26 @@
   dlclose(handle);
 }
 
+TEST(dlfcn, dlvsym_smoke) {
+  void* handle = dlopen("libtest_versioned_lib.so", RTLD_NOW);
+  ASSERT_TRUE(handle != nullptr) << dlerror();
+  typedef int (*fn_t)();
+
+  {
+    fn_t fn = reinterpret_cast<fn_t>(dlvsym(handle, "versioned_function", "nonversion"));
+    ASSERT_TRUE(fn == nullptr);
+    ASSERT_SUBSTR("undefined symbol: versioned_function, version nonversion", dlerror());
+  }
+
+  {
+    fn_t fn = reinterpret_cast<fn_t>(dlvsym(handle, "versioned_function", "TESTLIB_V2"));
+    ASSERT_TRUE(fn != nullptr) << dlerror();
+    ASSERT_EQ(2, fn());
+  }
+
+  dlclose(handle);
+}
+
 // This preempts the implementation from libtest_versioned_lib.so
 extern "C" int version_zero_function() {
   return 0;
@@ -1062,3 +1090,31 @@
 extern "C" int version_zero_function2() {
   return 0;
 }
+
+TEST(dlfcn, dt_runpath_smoke) {
+  void* handle = dlopen("libtest_dt_runpath_d.so", RTLD_NOW);
+  ASSERT_TRUE(handle != nullptr) << dlerror();
+
+  typedef void *(* dlopen_b_fn)();
+  dlopen_b_fn fn = (dlopen_b_fn)dlsym(handle, "dlopen_b");
+  ASSERT_TRUE(fn != nullptr) << dlerror();
+
+  void *p = fn();
+  ASSERT_TRUE(p != nullptr);
+
+  dlclose(handle);
+}
+
+TEST(dlfcn, dt_runpath_absolute_path) {
+  void* handle = dlopen(PATH_TO_SYSTEM_LIB "libtest_dt_runpath_d.so", RTLD_NOW);
+  ASSERT_TRUE(handle != nullptr) << dlerror();
+
+  typedef void *(* dlopen_b_fn)();
+  dlopen_b_fn fn = (dlopen_b_fn)dlsym(handle, "dlopen_b");
+  ASSERT_TRUE(fn != nullptr) << dlerror();
+
+  void *p = fn();
+  ASSERT_TRUE(p != nullptr);
+
+  dlclose(handle);
+}
diff --git a/tests/file-check-cxx b/tests/file-check-cxx
index 8ece835..d3bc5f7 100755
--- a/tests/file-check-cxx
+++ b/tests/file-check-cxx
@@ -2,10 +2,10 @@
 FILECHECK=$1
 CXX=$2
 PREFIX=$3
-ARGS=${*:4}
-SOURCE=$(echo $ARGS | grep -oP '\S+\.cpp\b')
-OBJ=$(echo $ARGS | grep -oP '\S+\.o\b')
-$CXX $ARGS 2>&1 | $FILECHECK -check-prefix=$PREFIX $SOURCE
+shift 3
+SOURCE=$(echo "$@" | grep -oP '\S+\.cpp\b')
+OBJ=$(echo "$@" | grep -oP '\S+\.o\b')
+$CXX "$@" -Wno-error 2>&1 | $FILECHECK -check-prefix=$PREFIX $SOURCE
 if [ "$?" -eq 0 ]; then
   touch $OBJ
 else
diff --git a/tests/fortify_compilation_test.cpp b/tests/fortify_compilation_test.cpp
index 537b341..1326597 100644
--- a/tests/fortify_compilation_test.cpp
+++ b/tests/fortify_compilation_test.cpp
@@ -21,6 +21,7 @@
 #include <poll.h>
 #include <stdarg.h>
 #include <stdio.h>
+#include <stdlib.h>
 #include <string.h>
 #include <sys/socket.h>
 #include <sys/stat.h>
@@ -230,3 +231,67 @@
   // clang should emit a warning, but doesn't
   ppoll(fds, 2, &timeout, NULL);
 }
+
+void test_fread_overflow() {
+  char buf[4];
+  // NOLINTNEXTLINE(whitespace/line_length)
+  // GCC: error: call to '__fread_overflow' declared with attribute error: fread called with overflowing size * count
+  // clang should emit a warning, but doesn't
+  fread(buf, 2, (size_t)-1, stdin);
+}
+
+void test_fread_too_big() {
+  char buf[4];
+  // NOLINTNEXTLINE(whitespace/line_length)
+  // GCC: error: call to '__fread_too_big_error' declared with attribute error: fread called with size * count bigger than buffer
+  // clang should emit a warning, but doesn't
+  fread(buf, 1, 5, stdin);
+}
+
+void test_fwrite_overflow() {
+  char buf[4] = {0};
+  // NOLINTNEXTLINE(whitespace/line_length)
+  // GCC: error: call to '__fwrite_overflow' declared with attribute error: fwrite called with overflowing size * count
+  // clang should emit a warning, but doesn't
+  fwrite(buf, 2, (size_t)-1, stdout);
+}
+
+void test_fwrite_too_big() {
+  char buf[4] = {0};
+  // NOLINTNEXTLINE(whitespace/line_length)
+  // GCC: error: call to '__fwrite_too_big_error' declared with attribute error: fwrite called with size * count bigger than buffer
+  // clang should emit a warning, but doesn't
+  fwrite(buf, 1, 5, stdout);
+}
+
+void test_getcwd() {
+  char buf[4];
+  // NOLINTNEXTLINE(whitespace/line_length)
+  // GCC: error: call to '__getcwd_dest_size_error' declared with attribute error: getcwd called with size bigger than destination
+  // clang should emit a warning, but doesn't
+  getcwd(buf, 5);
+}
+
+void test_pwrite64_size() {
+  char buf[4] = {0};
+  // NOLINTNEXTLINE(whitespace/line_length)
+  // GCC: error: call to '__pwrite64_dest_size_error' declared with attribute error: pwrite64 called with size bigger than destination
+  // clang should emit a warning, but doesn't
+  pwrite64(STDOUT_FILENO, buf, 5, 0);
+}
+
+void test_pwrite64_too_big() {
+  void *buf = calloc(atoi("5"), 1);
+  // NOLINTNEXTLINE(whitespace/line_length)
+  // GCC: error: call to '__pwrite64_count_toobig_error' declared with attribute error: pwrite64 called with count > SSIZE_MAX
+  // clang should emit a warning, but doesn't
+  pwrite64(STDOUT_FILENO, buf, SIZE_MAX, 0);
+}
+
+void test_write_size() {
+  char buf[4] = {0};
+  // NOLINTNEXTLINE(whitespace/line_length)
+  // GCC: error: call to '__write_dest_size_error' declared with attribute error: write called with size bigger than destination
+  // clang should emit a warning, but doesn't
+  write(STDOUT_FILENO, buf, 5);
+}
diff --git a/tests/fortify_test.cpp b/tests/fortify_test.cpp
index 4faccb4..4ffd5f9 100644
--- a/tests/fortify_test.cpp
+++ b/tests/fortify_test.cpp
@@ -14,6 +14,14 @@
  * limitations under the License.
  */
 
+// -Werror is on whether we like it or not, and we're intentionally doing awful
+// things in this file. GCC is dumb and doesn't have a specific error class for
+// the fortify failures (it's just -Werror), so we can't use anything more
+// constrained than disabling all the warnings in the file :( It also won't let
+// us use system_header in a .cpp file, so we have to #include this from
+// fortify_test_main.cpp.
+#pragma GCC system_header
+
 #include <gtest/gtest.h>
 #include "BionicDeathTest.h"
 
@@ -623,6 +631,12 @@
   ASSERT_FORTIFY(FD_ISSET(0, set));
 }
 
+TEST_F(DEATHTEST, getcwd_fortified) {
+  char buf[1];
+  size_t ct = atoi("2"); // prevent optimizations
+  ASSERT_FORTIFY(getcwd(buf, ct));
+}
+
 TEST_F(DEATHTEST, pread_fortified) {
   char buf[1];
   size_t ct = atoi("2"); // prevent optimizations
@@ -639,6 +653,22 @@
   close(fd);
 }
 
+TEST_F(DEATHTEST, pwrite_fortified) {
+  char buf[1] = {0};
+  size_t ct = atoi("2"); // prevent optimizations
+  int fd = open("/dev/null", O_WRONLY);
+  ASSERT_FORTIFY(pwrite(fd, buf, ct, 0));
+  close(fd);
+}
+
+TEST_F(DEATHTEST, pwrite64_fortified) {
+  char buf[1] = {0};
+  size_t ct = atoi("2"); // prevent optimizations
+  int fd = open("/dev/null", O_WRONLY);
+  ASSERT_FORTIFY(pwrite64(fd, buf, ct, 0));
+  close(fd);
+}
+
 TEST_F(DEATHTEST, read_fortified) {
   char buf[1];
   size_t ct = atoi("2"); // prevent optimizations
@@ -647,6 +677,30 @@
   close(fd);
 }
 
+TEST_F(DEATHTEST, write_fortified) {
+  char buf[1] = {0};
+  size_t ct = atoi("2"); // prevent optimizations
+  int fd = open("/dev/null", O_WRONLY);
+  ASSERT_EXIT(write(fd, buf, ct), testing::KilledBySignal(SIGABRT), "");
+  close(fd);
+}
+
+TEST_F(DEATHTEST, fread_fortified) {
+  char buf[1];
+  size_t ct = atoi("2"); // prevent optimizations
+  FILE* fp = fopen("/dev/null", "r");
+  ASSERT_FORTIFY(fread(buf, 1, ct, fp));
+  fclose(fp);
+}
+
+TEST_F(DEATHTEST, fwrite_fortified) {
+  char buf[1] = {0};
+  size_t ct = atoi("2"); // prevent optimizations
+  FILE* fp = fopen("/dev/null", "w");
+  ASSERT_FORTIFY(fwrite(buf, 1, ct, fp));
+  fclose(fp);
+}
+
 TEST_F(DEATHTEST, readlink_fortified) {
   char buf[1];
   size_t ct = atoi("2"); // prevent optimizations
diff --git a/libc/upstream-freebsd/android/include/spinlock.h b/tests/fortify_test_main.cpp
similarity index 71%
copy from libc/upstream-freebsd/android/include/spinlock.h
copy to tests/fortify_test_main.cpp
index f5c3785..8e52d42 100644
--- a/libc/upstream-freebsd/android/include/spinlock.h
+++ b/tests/fortify_test_main.cpp
@@ -1,5 +1,5 @@
 /*
- * Copyright (C) 2013 The Android Open Source Project
+ * Copyright (C) 2015 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,9 +14,4 @@
  * limitations under the License.
  */
 
-#ifndef _BIONIC_FREEBSD_SPINLOCK_H_included
-#define _BIONIC_FREEBSD_SPINLOCK_H_included
-
-/* TODO: until we have the FreeBSD findfp.c, this is useless. */
-
-#endif
+#include "fortify_test.cpp"
diff --git a/tests/getauxval_test.cpp b/tests/getauxval_test.cpp
index 6ce00f1..63bc963 100644
--- a/tests/getauxval_test.cpp
+++ b/tests/getauxval_test.cpp
@@ -16,6 +16,7 @@
 
 #include <errno.h>
 #include <sys/cdefs.h>
+#include <sys/utsname.h>
 #include <gtest/gtest.h>
 
 // getauxval() was only added as of glibc version 2.16.
@@ -36,28 +37,51 @@
 
 TEST(getauxval, expected_values) {
 #if defined(GETAUXVAL_CAN_COMPILE)
-  ASSERT_EQ((unsigned long int) 0, getauxval(AT_SECURE));
+  ASSERT_EQ(0UL, getauxval(AT_SECURE));
   ASSERT_EQ(getuid(), getauxval(AT_UID));
   ASSERT_EQ(geteuid(), getauxval(AT_EUID));
   ASSERT_EQ(getgid(), getauxval(AT_GID));
   ASSERT_EQ(getegid(), getauxval(AT_EGID));
-  ASSERT_EQ((unsigned long int) getpagesize(), getauxval(AT_PAGESZ));
+  ASSERT_EQ(static_cast<unsigned long>(getpagesize()), getauxval(AT_PAGESZ));
 
-  ASSERT_NE((unsigned long int) 0, getauxval(AT_PHDR));
-  ASSERT_NE((unsigned long int) 0, getauxval(AT_PHNUM));
-  ASSERT_NE((unsigned long int) 0, getauxval(AT_ENTRY));
-  ASSERT_NE((unsigned long int) 0, getauxval(AT_PAGESZ));
+  ASSERT_NE(0UL, getauxval(AT_PHDR));
+  ASSERT_NE(0UL, getauxval(AT_PHNUM));
+  ASSERT_NE(0UL, getauxval(AT_ENTRY));
+  ASSERT_NE(0UL, getauxval(AT_PAGESZ));
 #else
-  GTEST_LOG_(INFO) << "This test does nothing.\n";
+  GTEST_LOG_(INFO) << "This test requires a C library with getauxval.\n";
 #endif
 }
 
 TEST(getauxval, unexpected_values) {
 #if defined(GETAUXVAL_CAN_COMPILE)
   errno = 0;
-  ASSERT_EQ((unsigned long int) 0, getauxval(0xdeadbeef));
+  ASSERT_EQ(0UL, getauxval(0xdeadbeef));
   ASSERT_EQ(ENOENT, errno);
 #else
-  GTEST_LOG_(INFO) << "This test does nothing.\n";
+  GTEST_LOG_(INFO) << "This test requires a C library with getauxval.\n";
 #endif
 }
+
+TEST(getauxval, arm_has_AT_HWCAP2) {
+#if defined(__arm__)
+  // There are no known 32-bit processors that implement any of these instructions, so rather
+  // than require that OEMs backport kernel patches, let's just ignore old hardware. Strictly
+  // speaking this would be fooled by someone choosing to ship a 32-bit kernel on 64-bit hardware,
+  // but that doesn't seem very likely in 2016.
+  utsname u;
+  ASSERT_EQ(0, uname(&u));
+  if (strcmp(u.machine, "aarch64") == 0) {
+    // If this test fails, apps that use getauxval to decide at runtime whether crypto hardware is
+    // available will incorrectly assume that it isn't, and will have really bad performance.
+    // If this test fails, ensure that you've enabled COMPAT_BINFMT_ELF in your kernel configuration.
+    // Note that 0 ("I don't support any of these things") is a legitimate response --- we need
+    // to check errno to see whether we got a "true" 0 or a "not found" 0.
+    errno = 0;
+    getauxval(AT_HWCAP2);
+    ASSERT_EQ(0, errno) << "64-bit kernel not reporting AT_HWCAP2 to 32-bit ARM process";
+    return;
+  }
+#endif
+  GTEST_LOG_(INFO) << "This test is only meaningful for 32-bit ARM code on 64-bit devices.\n";
+}
diff --git a/tests/gtest_main.cpp b/tests/gtest_main.cpp
index 5d25a4c..2b58646 100644
--- a/tests/gtest_main.cpp
+++ b/tests/gtest_main.cpp
@@ -26,15 +26,31 @@
 #include <stdio.h>
 #include <string.h>
 #include <sys/wait.h>
-#include <time.h>
 #include <unistd.h>
 
+#include <chrono>
 #include <string>
 #include <tuple>
 #include <utility>
 #include <vector>
 
-#include "BionicDeathTest.h" // For selftest.
+#ifndef TEMP_FAILURE_RETRY
+
+/* Used to retry syscalls that can return EINTR. */
+#define TEMP_FAILURE_RETRY(exp) ({         \
+    __typeof__(exp) _rc;                   \
+    do {                                   \
+        _rc = (exp);                       \
+    } while (_rc == -1 && errno == EINTR); \
+    _rc; })
+
+#endif
+
+static std::string g_executable_path;
+
+const std::string& get_executable_path() {
+  return g_executable_path;
+}
 
 namespace testing {
 namespace internal {
@@ -90,7 +106,7 @@
          "      Don't use isolation mode, run all tests in a single process.\n"
          "  --deadline=[TIME_IN_MS]\n"
          "      Run each test in no longer than [TIME_IN_MS] time.\n"
-         "      It takes effect only in isolation mode. Deafult deadline is 60000 ms.\n"
+         "      It takes effect only in isolation mode. Deafult deadline is 90000 ms.\n"
          "  --warnline=[TIME_IN_MS]\n"
          "      Test running longer than [TIME_IN_MS] will be warned.\n"
          "      It takes effect only in isolation mode. Default warnline is 2000 ms.\n"
@@ -221,10 +237,8 @@
 }
 
 static int64_t NanoTime() {
-  struct timespec t;
-  t.tv_sec = t.tv_nsec = 0;
-  clock_gettime(CLOCK_MONOTONIC, &t);
-  return static_cast<int64_t>(t.tv_sec) * 1000000000LL + t.tv_nsec;
+  std::chrono::nanoseconds duration(std::chrono::steady_clock::now().time_since_epoch());
+  return static_cast<int64_t>(duration.count());
 }
 
 static bool EnumerateTests(int argc, char** argv, std::vector<TestCase>& testcase_list) {
@@ -256,7 +270,7 @@
     while (*p != '\0' && isspace(*p)) {
       ++p;
     }
-    if (*p != '\0') {
+    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;
@@ -434,6 +448,36 @@
   fflush(stdout);
 }
 
+std::string XmlEscape(const std::string& xml) {
+  std::string escaped;
+  escaped.reserve(xml.size());
+
+  for (auto c : xml) {
+    switch (c) {
+    case '<':
+      escaped.append("&lt;");
+      break;
+    case '>':
+      escaped.append("&gt;");
+      break;
+    case '&':
+      escaped.append("&amp;");
+      break;
+    case '\'':
+      escaped.append("&apos;");
+      break;
+    case '"':
+      escaped.append("&quot;");
+      break;
+    default:
+      escaped.append(1, c);
+      break;
+    }
+  }
+
+  return escaped;
+}
+
 // Output xml file when --gtest_output is used, write this function as we can't reuse
 // gtest.cc:XmlUnitTestResultPrinter. The reason is XmlUnitTestResultPrinter is totally
 // defined in gtest.cc and not expose to outside. What's more, as we don't run gtest in
@@ -489,7 +533,8 @@
       } else {
         fputs(">\n", fp);
         const std::string& test_output = testcase.GetTest(j).GetTestOutput();
-        fprintf(fp, "      <failure message=\"%s\" type=\"\">\n", test_output.c_str());
+        const std::string escaped_test_output = XmlEscape(test_output);
+        fprintf(fp, "      <failure message=\"%s\" type=\"\">\n", escaped_test_output.c_str());
         fputs("      </failure>\n", fp);
         fputs("    </testcase>\n", fp);
       }
@@ -501,6 +546,43 @@
   fclose(fp);
 }
 
+static bool sigint_flag;
+static bool sigquit_flag;
+
+static void signal_handler(int sig) {
+  if (sig == SIGINT) {
+    sigint_flag = true;
+  } else if (sig == SIGQUIT) {
+    sigquit_flag = true;
+  }
+}
+
+static bool RegisterSignalHandler() {
+  sigint_flag = false;
+  sigquit_flag = false;
+  sig_t ret = signal(SIGINT, signal_handler);
+  if (ret != SIG_ERR) {
+    ret = signal(SIGQUIT, signal_handler);
+  }
+  if (ret == SIG_ERR) {
+    perror("RegisterSignalHandler");
+    return false;
+  }
+  return true;
+}
+
+static bool UnregisterSignalHandler() {
+  sig_t ret = signal(SIGINT, SIG_DFL);
+  if (ret != SIG_ERR) {
+    ret = signal(SIGQUIT, SIG_DFL);
+  }
+  if (ret == SIG_ERR) {
+    perror("UnregisterSignalHandler");
+    return false;
+  }
+  return true;
+}
+
 struct ChildProcInfo {
   pid_t pid;
   int64_t start_time_ns;
@@ -531,11 +613,14 @@
 }
 
 static ChildProcInfo RunChildProcess(const std::string& test_name, int testcase_id, int test_id,
-                                     sigset_t sigmask, int argc, char** argv) {
+                                     int argc, char** argv) {
   int pipefd[2];
-  int ret = pipe2(pipefd, O_NONBLOCK);
-  if (ret == -1) {
-    perror("pipe2 in RunTestInSeparateProc");
+  if (pipe(pipefd) == -1) {
+    perror("pipe in RunTestInSeparateProc");
+    exit(1);
+  }
+  if (fcntl(pipefd[0], F_SETFL, O_NONBLOCK) == -1) {
+    perror("fcntl in RunTestInSeparateProc");
     exit(1);
   }
   pid_t pid = fork();
@@ -550,8 +635,7 @@
     dup2(pipefd[1], STDOUT_FILENO);
     dup2(pipefd[1], STDERR_FILENO);
 
-    if (sigprocmask(SIG_SETMASK, &sigmask, NULL) == -1) {
-      perror("sigprocmask SIG_SETMASK");
+    if (!UnregisterSignalHandler()) {
       exit(1);
     }
     ChildProcessFn(argc, argv, test_name);
@@ -572,42 +656,29 @@
 
 static void HandleSignals(std::vector<TestCase>& testcase_list,
                             std::vector<ChildProcInfo>& child_proc_list) {
-  sigset_t waiting_mask;
-  sigemptyset(&waiting_mask);
-  sigaddset(&waiting_mask, SIGINT);
-  sigaddset(&waiting_mask, SIGQUIT);
-  timespec timeout;
-  timeout.tv_sec = timeout.tv_nsec = 0;
-  while (true) {
-    int signo = TEMP_FAILURE_RETRY(sigtimedwait(&waiting_mask, NULL, &timeout));
-    if (signo == -1) {
-      if (errno == EAGAIN) {
-        return; // Timeout, no pending signals.
+  if (sigquit_flag) {
+    sigquit_flag = false;
+    // Print current running tests.
+    printf("List of current running tests:\n");
+    for (const auto& child_proc : child_proc_list) {
+      if (child_proc.pid != 0) {
+        std::string test_name = testcase_list[child_proc.testcase_id].GetTestName(child_proc.test_id);
+        int64_t current_time_ns = NanoTime();
+        int64_t run_time_ms = (current_time_ns - child_proc.start_time_ns) / 1000000;
+        printf("  %s (%" PRId64 " ms)\n", test_name.c_str(), run_time_ms);
       }
-      perror("sigtimedwait");
-      exit(1);
-    } else if (signo == SIGQUIT) {
-      // Print current running tests.
-      printf("List of current running tests:\n");
-      for (auto& child_proc : child_proc_list) {
-        if (child_proc.pid != 0) {
-          std::string test_name = testcase_list[child_proc.testcase_id].GetTestName(child_proc.test_id);
-          int64_t current_time_ns = NanoTime();
-          int64_t run_time_ms = (current_time_ns - child_proc.start_time_ns) / 1000000;
-          printf("  %s (%" PRId64 " ms)\n", test_name.c_str(), run_time_ms);
-        }
-      }
-    } else if (signo == SIGINT) {
-      // Kill current running tests.
-      for (auto& child_proc : child_proc_list) {
-        if (child_proc.pid != 0) {
-          // Send SIGKILL to ensure the child process can be killed unconditionally.
-          kill(child_proc.pid, SIGKILL);
-        }
-      }
-      // SIGINT kills the parent process as well.
-      exit(1);
     }
+  } else if (sigint_flag) {
+    sigint_flag = false;
+    // Kill current running tests.
+    for (const auto& child_proc : child_proc_list) {
+      if (child_proc.pid != 0) {
+        // Send SIGKILL to ensure the child process can be killed unconditionally.
+        kill(child_proc.pid, SIGKILL);
+      }
+    }
+    // SIGINT kills the parent process as well.
+    exit(1);
   }
 }
 
@@ -639,6 +710,30 @@
   return timeout_child_count;
 }
 
+static void ReadChildProcOutput(std::vector<TestCase>& testcase_list,
+                                std::vector<ChildProcInfo>& child_proc_list) {
+  for (const auto& child_proc : child_proc_list) {
+    TestCase& testcase = testcase_list[child_proc.testcase_id];
+    int test_id = child_proc.test_id;
+    while (true) {
+      char buf[1024];
+      ssize_t bytes_read = TEMP_FAILURE_RETRY(read(child_proc.child_read_fd, buf, sizeof(buf) - 1));
+      if (bytes_read > 0) {
+        buf[bytes_read] = '\0';
+        testcase.GetTest(test_id).AppendTestOutput(buf);
+      } else if (bytes_read == 0) {
+        break; // Read end.
+      } else {
+        if (errno == EAGAIN) {
+          break;
+        }
+        perror("failed to read child_read_fd");
+        exit(1);
+      }
+    }
+  }
+}
+
 static void WaitChildProcs(std::vector<TestCase>& testcase_list,
                            std::vector<ChildProcInfo>& child_proc_list) {
   size_t finished_child_count = 0;
@@ -663,6 +758,7 @@
       finished_child_count += CheckChildProcTimeout(child_proc_list);
     }
 
+    ReadChildProcOutput(testcase_list, child_proc_list);
     if (finished_child_count > 0) {
       return;
     }
@@ -696,26 +792,6 @@
     kill(child_proc.pid, SIGKILL);
     WaitForOneChild(child_proc.pid);
   }
-
-  while (true) {
-    char buf[1024];
-    ssize_t bytes_read = TEMP_FAILURE_RETRY(read(child_proc.child_read_fd, buf, sizeof(buf) - 1));
-    if (bytes_read > 0) {
-      buf[bytes_read] = '\0';
-      testcase.GetTest(test_id).AppendTestOutput(buf);
-    } else if (bytes_read == 0) {
-      break; // Read end.
-    } else {
-      if (errno == EAGAIN) {
-        // No data is available. This rarely happens, only when the child process created other
-        // processes which have not exited so far. But the child process has already exited or
-        // been killed, so the test has finished, and we shouldn't wait further.
-        break;
-      }
-      perror("read child_read_fd in RunTestInSeparateProc");
-      exit(1);
-    }
-  }
   close(child_proc.child_read_fd);
 
   if (child_proc.timed_out) {
@@ -734,8 +810,14 @@
     testcase.GetTest(test_id).AppendTestOutput(buf);
 
   } else {
-    testcase.SetTestResult(test_id, WEXITSTATUS(child_proc.exit_status) == 0 ?
-                           TEST_SUCCESS : TEST_FAILED);
+    int exitcode = WEXITSTATUS(child_proc.exit_status);
+    testcase.SetTestResult(test_id, exitcode == 0 ? TEST_SUCCESS : TEST_FAILED);
+    if (exitcode != 0) {
+      char buf[1024];
+      snprintf(buf, sizeof(buf), "%s exited with exitcode %d.\n",
+               testcase.GetTestName(test_id).c_str(), exitcode);
+      testcase.GetTest(test_id).AppendTestOutput(buf);
+    }
   }
 }
 
@@ -750,13 +832,7 @@
                         testing::UnitTest::GetInstance()->listeners().default_result_printer());
   testing::UnitTest::GetInstance()->listeners().Append(new TestResultPrinter);
 
-  // Signals are blocked here as we want to handle them in HandleSignals() later.
-  sigset_t block_mask, orig_mask;
-  sigemptyset(&block_mask);
-  sigaddset(&block_mask, SIGINT);
-  sigaddset(&block_mask, SIGQUIT);
-  if (sigprocmask(SIG_BLOCK, &block_mask, &orig_mask) == -1) {
-    perror("sigprocmask SIG_BLOCK");
+  if (!RegisterSignalHandler()) {
     exit(1);
   }
 
@@ -785,7 +861,7 @@
       while (child_proc_list.size() < job_count && next_testcase_id < testcase_list.size()) {
         std::string test_name = testcase_list[next_testcase_id].GetTestName(next_test_id);
         ChildProcInfo child_proc = RunChildProcess(test_name, next_testcase_id, next_test_id,
-                                                   orig_mask, argc, argv);
+                                                   argc, argv);
         child_proc_list.push_back(child_proc);
         if (++next_test_id == testcase_list[next_testcase_id].TestCount()) {
           next_test_id = 0;
@@ -830,9 +906,7 @@
     }
   }
 
-  // Restore signal mask.
-  if (sigprocmask(SIG_SETMASK, &orig_mask, NULL) == -1) {
-    perror("sigprocmask SIG_SETMASK");
+  if (!UnregisterSignalHandler()) {
     exit(1);
   }
 
@@ -840,11 +914,7 @@
 }
 
 static size_t GetDefaultJobCount() {
-#if defined(JOB_COUNT_FIXED)
-  return JOB_COUNT_FIXED;
-#else
   return static_cast<size_t>(sysconf(_SC_NPROCESSORS_ONLN));
-#endif
 }
 
 static void AddPathSeparatorInTestProgramPath(std::vector<char*>& args) {
@@ -853,15 +923,8 @@
   // The reason is that gtest uses clone() + execve() to run DeathTest in threadsafe mode,
   // and execve() doesn't read environment variable PATH, so execve() will not success
   // until we specify the absolute path or relative path of the test program directly.
-  if (strchr(args[0], '/') == NULL) {
-    char path[PATH_MAX];
-    ssize_t path_len = readlink("/proc/self/exe", path, sizeof(path));
-    if (path_len <= 0 || path_len >= static_cast<ssize_t>(sizeof(path))) {
-      perror("readlink");
-      exit(1);
-    }
-    path[path_len] = '\0';
-    args[0] = strdup(path);
+  if (strchr(args[0], '/') == nullptr) {
+    args[0] = strdup(g_executable_path.c_str());
   }
 }
 
@@ -1048,7 +1111,19 @@
   return true;
 }
 
+static std::string get_proc_self_exe() {
+  char path[PATH_MAX];
+  ssize_t path_len = readlink("/proc/self/exe", path, sizeof(path));
+  if (path_len <= 0 || path_len >= static_cast<ssize_t>(sizeof(path))) {
+    perror("readlink");
+    exit(1);
+  }
+
+  return std::string(path, path_len);
+}
+
 int main(int argc, char** argv) {
+  g_executable_path = get_proc_self_exe();
   std::vector<char*> arg_list;
   for (int i = 0; i < argc; ++i) {
     arg_list.push_back(argv[i]);
@@ -1107,7 +1182,12 @@
   *p = 3;
 }
 
-class bionic_selftest_DeathTest : public BionicDeathTest {};
+class bionic_selftest_DeathTest : public ::testing::Test {
+ protected:
+  virtual void SetUp() {
+    ::testing::FLAGS_gtest_death_test_style = "threadsafe";
+  }
+};
 
 static void deathtest_helper_success() {
   ASSERT_EQ(1, 1);
diff --git a/tests/ifaddrs_test.cpp b/tests/ifaddrs_test.cpp
new file mode 100644
index 0000000..9f01619
--- /dev/null
+++ b/tests/ifaddrs_test.cpp
@@ -0,0 +1,269 @@
+/*
+ * Copyright (C) 2015 The Android Open Source Project
+ *
+ * Licensed under the Apache License, Version 2.0 (the "License");
+ * you may not use this file except in compliance with the License.
+ * You may obtain a copy of the License at
+ *
+ *      http://www.apache.org/licenses/LICENSE-2.0
+ *
+ * Unless required by applicable law or agreed to in writing, software
+ * distributed under the License is distributed on an "AS IS" BASIS,
+ * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
+ * See the License for the specific language governing permissions and
+ * limitations under the License.
+ */
+
+#include <gtest/gtest.h>
+
+#include <ifaddrs.h>
+
+#include <dirent.h>
+#include <linux/if_packet.h>
+#include <net/ethernet.h>
+#include <net/if.h>
+#include <netdb.h>
+#include <netinet/in.h>
+#include <sys/ioctl.h>
+
+#include <algorithm>
+#include <map>
+#include <vector>
+
+TEST(ifaddrs, freeifaddrs_null) {
+  freeifaddrs(nullptr);
+}
+
+// We can't statically say much about what network interfaces are available, but we can be pretty
+// sure there's a loopback interface, and that it has IPv4, IPv6, and AF_PACKET entries.
+TEST(ifaddrs, getifaddrs_lo) {
+  ifaddrs* addrs = nullptr;
+
+  ASSERT_EQ(0, getifaddrs(&addrs));
+  ASSERT_TRUE(addrs != nullptr);
+
+  ifaddrs* lo_inet4 = nullptr;
+  ifaddrs* lo_inet6 = nullptr;
+  ifaddrs* lo_packet = nullptr;
+  for (ifaddrs* addr = addrs; addr != nullptr; addr = addr->ifa_next) {
+    if (addr->ifa_name && strcmp(addr->ifa_name, "lo") == 0) {
+      if (addr->ifa_addr && addr->ifa_addr->sa_family == AF_INET) lo_inet4 = addr;
+      else if (addr->ifa_addr && addr->ifa_addr->sa_family == AF_INET6) lo_inet6 = addr;
+      else if (addr->ifa_addr && addr->ifa_addr->sa_family == AF_PACKET) lo_packet = addr;
+    }
+  }
+
+  // Does the IPv4 entry look right?
+  ASSERT_TRUE(lo_inet4 != nullptr);
+  const sockaddr_in* sa_inet4 = reinterpret_cast<const sockaddr_in*>(lo_inet4->ifa_addr);
+  ASSERT_TRUE(ntohl(sa_inet4->sin_addr.s_addr) == INADDR_LOOPBACK);
+
+  // Does the IPv6 entry look right?
+  ASSERT_TRUE(lo_inet6 != nullptr);
+  const sockaddr_in6* sa_inet6 = reinterpret_cast<const sockaddr_in6*>(lo_inet6->ifa_addr);
+  ASSERT_TRUE(IN6_IS_ADDR_LOOPBACK(&sa_inet6->sin6_addr));
+
+  // Does the AF_PACKET entry look right?
+  ASSERT_TRUE(lo_packet != nullptr);
+  const sockaddr_ll* sa_ll = reinterpret_cast<const sockaddr_ll*>(lo_packet->ifa_addr);
+  ASSERT_EQ(6, sa_ll->sll_halen);
+
+  freeifaddrs(addrs);
+}
+
+// Check that getifaddrs sees the same list of interfaces as /sys/class/net.
+TEST(ifaddrs, getifaddrs_interfaces) {
+  std::vector<std::string> ifaddrs_socks;
+  {
+    ifaddrs* addrs;
+    ASSERT_EQ(0, getifaddrs(&addrs));
+
+    for (ifaddrs* addr = addrs; addr != nullptr; addr = addr->ifa_next) {
+      int family = addr->ifa_addr ? addr->ifa_addr->sa_family :
+          addr->ifa_broadaddr ? addr->ifa_broadaddr->sa_family :
+          AF_UNSPEC;
+
+      if (family == AF_PACKET || family == AF_UNSPEC) {
+        ifaddrs_socks.push_back(std::string(addr->ifa_name));
+      }
+    }
+
+    freeifaddrs(addrs);
+  }
+
+  std::vector<std::string> sys_class_net;
+  {
+    std::unique_ptr<DIR, decltype(&closedir)> d(opendir("/sys/class/net"), closedir);
+    ASSERT_TRUE(d != nullptr);
+    dirent* dir;
+    while ((dir = readdir(d.get())) != nullptr) {
+      if (dir->d_type == DT_LNK) {
+        sys_class_net.push_back(std::string(dir->d_name));
+      }
+    }
+  }
+
+  ASSERT_TRUE(std::is_permutation(ifaddrs_socks.begin(), ifaddrs_socks.end(),
+                                  sys_class_net.begin()));
+}
+
+static void CheckAddressIsInSet(const std::string& if_name, bool unicast,
+                                const std::set<in_addr_t>& addrs) {
+  ifreq ifr;
+  memset(&ifr, 0, sizeof(ifr));
+  ifr.ifr_addr.sa_family = AF_INET;
+  if_name.copy(ifr.ifr_name, IFNAMSIZ - 1);
+
+  int fd = socket(AF_INET, SOCK_DGRAM, 0);
+  ASSERT_TRUE(fd != -1);
+
+  int request = SIOCGIFADDR;
+  if (!unicast) {
+    // For non-unicast, the specific ioctl to use depends on whether the IFF_BROADCAST flag is set.
+    ASSERT_EQ(0, ioctl(fd, SIOCGIFFLAGS, &ifr)) << if_name << ' ' << strerror(errno);
+    request = ((ifr.ifr_flags & IFF_BROADCAST) != 0) ? SIOCGIFBRDADDR : SIOCGIFDSTADDR;
+  }
+
+  ASSERT_EQ(0, ioctl(fd, request, &ifr)) << if_name << ' ' << strerror(errno);
+  close(fd);
+
+  sockaddr_in* sock = reinterpret_cast<sockaddr_in*>(&ifr.ifr_addr);
+  in_addr_t addr = sock->sin_addr.s_addr;
+
+  EXPECT_TRUE(addrs.find(addr) != addrs.end()) << if_name << ' ' << std::hex << ntohl(addr);
+}
+
+TEST(ifaddrs, getifaddrs_INET) {
+  std::map<std::string, std::set<in_addr_t>> inet_addrs;
+  std::map<std::string, std::set<in_addr_t>> broad_addrs;
+
+  // Collect the IPv4 addresses for each interface.
+  ifaddrs* addrs;
+  ASSERT_EQ(0, getifaddrs(&addrs));
+  for (ifaddrs* addr = addrs; addr != nullptr; addr = addr->ifa_next) {
+    if (addr->ifa_name && addr->ifa_addr && addr->ifa_addr->sa_family == AF_INET) {
+      auto sock = reinterpret_cast<sockaddr_in*>(addr->ifa_addr);
+      inet_addrs[addr->ifa_name].insert(sock->sin_addr.s_addr);
+    }
+    if (addr->ifa_name && addr->ifa_broadaddr && addr->ifa_broadaddr->sa_family == AF_INET) {
+      auto sock = reinterpret_cast<sockaddr_in*>(addr->ifa_broadaddr);
+      broad_addrs[addr->ifa_name].insert(sock->sin_addr.s_addr);
+    }
+  }
+  freeifaddrs(addrs);
+
+  // Check that the addresses returned by the SIOCGIFADDR and SIOCGIFBRDADDR/SIOCGIFDSTADDR ioctls
+  // are in our collections.
+  for (const auto& it : inet_addrs) CheckAddressIsInSet(it.first, true, it.second);
+  for (const auto& it : broad_addrs) CheckAddressIsInSet(it.first, false, it.second);
+}
+
+static void print_sockaddr_ll(const char* what, const sockaddr* p) {
+  const sockaddr_ll* s = reinterpret_cast<const sockaddr_ll*>(p);
+  printf("\t\t%s\t", what);
+  for (int i = 0; i < s->sll_halen; ++i) {
+    if (i > 0) printf(":");
+    printf("%02X", s->sll_addr[i]);
+  }
+  printf(" (%d bytes)\n", s->sll_halen);
+}
+
+static void print_sockaddr_inet(const char* what, const sockaddr* addr) {
+  char host[NI_MAXHOST];
+  int family = addr->sa_family;
+  int error = getnameinfo(addr,
+                          (family == AF_INET) ? sizeof(sockaddr_in) : sizeof(sockaddr_in6),
+                          host, NI_MAXHOST, nullptr, 0, NI_NUMERICHOST);
+  if (error != 0) {
+    printf("%d getnameinfo() failed: %s\n", family, gai_strerror(error));
+    strcpy(host, "???");
+  }
+  printf("\t\t%s: <%s>\n", what, host);
+}
+
+static const char* FamilyToName(int family) {
+  if (family == AF_INET) return "AF_INET";
+  if (family == AF_INET6) return "AF_INET6";
+  if (family == AF_PACKET) return "AF_PACKET";
+  if (family == AF_UNSPEC) return "AF_UNSPEC";
+  return "?";
+}
+
+static std::string FlagsToString(short flags) {
+  std::string result;
+  if ((flags & IFF_UP) != 0) result += " UP";
+  if ((flags & IFF_BROADCAST) != 0) result += " BROADCAST";
+  if ((flags & IFF_DEBUG) != 0) result += " DEBUG";
+  if ((flags & IFF_LOOPBACK) != 0) result += " LOOPBACK";
+  if ((flags & IFF_POINTOPOINT) != 0) result += " POINTOPOINT";
+  if ((flags & IFF_NOTRAILERS) != 0) result += " NOTRAILERS";
+  if ((flags & IFF_RUNNING) != 0) result += " RUNNING";
+  if ((flags & IFF_NOARP) != 0) result += " NOARP";
+  if ((flags & IFF_PROMISC) != 0) result += " PROMISC";
+  if ((flags & IFF_ALLMULTI) != 0) result += " ALLMULTI";
+  if ((flags & IFF_MASTER) != 0) result += " MASTER";
+  if ((flags & IFF_SLAVE) != 0) result += " SLAVE";
+  if ((flags & IFF_MULTICAST) != 0) result += " MULTICAST";
+  if ((flags & IFF_PORTSEL) != 0) result += " PORTSEL";
+  if ((flags & IFF_AUTOMEDIA) != 0) result += " AUTOMEDIA";
+  if ((flags & IFF_DYNAMIC) != 0) result += " DYNAMIC";
+#if defined(IFF_LOWER_UP)
+  if ((flags & IFF_LOWER_UP) != 0) result += " LOWER_UP";
+#endif
+#if defined(IFF_DORMANT)
+  if ((flags & IFF_DORMANT) != 0) result += " DORMANT";
+#endif
+#if defined(IFF_ECHO)
+  if ((flags & IFF_ECHO) != 0) result += " ECHO";
+#endif
+  return result;
+}
+
+// Not really a test, but a useful debugging tool.
+TEST(ifaddrs, dump) {
+  ifaddrs* addrs;
+  ASSERT_EQ(0, getifaddrs(&addrs));
+
+  for (ifaddrs* ifa = addrs; ifa != nullptr; ifa = ifa->ifa_next) {
+    int family = ifa->ifa_addr ? ifa->ifa_addr->sa_family :
+                                 ifa->ifa_broadaddr ? ifa->ifa_broadaddr->sa_family : AF_UNSPEC;
+
+    printf("\t%s\n"
+           "\t\t%s (%d) flags=%#x%s\n",
+           ifa->ifa_name, FamilyToName(family), family,
+           ifa->ifa_flags, FlagsToString(ifa->ifa_flags).c_str());
+
+    if (family == AF_PACKET) {
+      if (ifa->ifa_addr) print_sockaddr_ll("hwaddr", ifa->ifa_addr);
+      if (ifa->ifa_broadaddr) print_sockaddr_ll("hwbroad", ifa->ifa_addr);
+    } else if (family == AF_INET || family == AF_INET6) {
+      if (ifa->ifa_addr) print_sockaddr_inet("address", ifa->ifa_addr);
+      if (ifa->ifa_broadaddr && (ifa->ifa_flags & (IFF_BROADCAST | IFF_POINTOPOINT)) != 0) {
+        print_sockaddr_inet((ifa->ifa_flags & IFF_BROADCAST) ? "broadcast" : "destination",
+                            ifa->ifa_broadaddr);
+      }
+    }
+
+    fflush(stdout);
+  }
+
+  freeifaddrs(addrs);
+}
+
+TEST(ifaddrs, inet6_scope_ids) {
+  ifaddrs* addrs;
+  ASSERT_EQ(0, getifaddrs(&addrs));
+
+  for (ifaddrs* ifa = addrs; ifa != nullptr; ifa = ifa->ifa_next) {
+    if (ifa->ifa_addr && ifa->ifa_addr->sa_family == AF_INET6) {
+      sockaddr_in6* sa6 = reinterpret_cast<sockaddr_in6*>(ifa->ifa_addr);
+      // Any link-local IPv6 address should have a scope id. (http://b/27219454.)
+      // 0 isn't a valid interface index, so that would mean the scope id wasn't set.
+      if (IN6_IS_ADDR_LINKLOCAL(&sa6->sin6_addr) || IN6_IS_ADDR_MC_LINKLOCAL(&sa6->sin6_addr)) {
+        ASSERT_NE(sa6->sin6_scope_id, 0U);
+      }
+    }
+  }
+
+  freeifaddrs(addrs);
+}
diff --git a/tests/libgen_basename_test.cpp b/tests/libgen_basename_test.cpp
new file mode 100644
index 0000000..d97e0da
--- /dev/null
+++ b/tests/libgen_basename_test.cpp
@@ -0,0 +1,90 @@
+/*
+ * Copyright (C) 2012 The Android Open Source Project
+ *
+ * Licensed under the Apache License, Version 2.0 (the "License");
+ * you may not use this file except in compliance with the License.
+ * You may obtain a copy of the License at
+ *
+ *      http://www.apache.org/licenses/LICENSE-2.0
+ *
+ * Unless required by applicable law or agreed to in writing, software
+ * distributed under the License is distributed on an "AS IS" BASIS,
+ * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
+ * See the License for the specific language governing permissions and
+ * limitations under the License.
+ */
+
+#ifndef _GNU_SOURCE
+  #define _GNU_SOURCE 1
+#endif
+
+#include <string.h>
+
+#if defined(basename)
+  #error basename should not be defined at this point
+#endif
+
+static const char* gnu_basename(const char* in) {
+  return basename(in);
+}
+
+#include <libgen.h>
+
+#if !defined(basename)
+  #error basename should be defined at this point
+#endif
+
+static char* posix_basename(char* in) {
+  return basename(in);
+}
+
+#include <errno.h>
+#include <gtest/gtest.h>
+
+static void __TestGnuBasename(const char* in, const char* expected_out, int line) {
+  errno = 0;
+  const char* out = gnu_basename(in);
+  ASSERT_STREQ(expected_out, out) << "(" << line << "): " << in << std::endl;
+  ASSERT_EQ(0, errno) << "(" << line << "): " << in << std::endl;
+}
+
+static void __TestPosixBasename(const char* in, const char* expected_out, int line) {
+  char* writable_in = (in != NULL) ? strdup(in) : NULL;
+  errno = 0;
+  const char* out = posix_basename(&writable_in[0]);
+  ASSERT_STREQ(expected_out, out) << "(" << line << "): " << in << std::endl;
+  ASSERT_EQ(0, errno) << "(" << line << "): " << in << std::endl;
+  free(writable_in);
+}
+
+#define TestGnuBasename(in, expected) __TestGnuBasename(in, expected, __LINE__)
+#define TestPosixBasename(in, expected) __TestPosixBasename(in, expected, __LINE__)
+
+TEST(libgen_basename, gnu_basename) {
+  // GNU's basename doesn't accept NULL
+  // TestGnuBasename(NULL, ".");
+  TestGnuBasename("", "");
+  TestGnuBasename("/usr/lib", "lib");
+  TestGnuBasename("/system/bin/sh/", "");
+  TestGnuBasename("/usr/", "");
+  TestGnuBasename("usr", "usr");
+  TestGnuBasename("/", "");
+  TestGnuBasename(".", ".");
+  TestGnuBasename("..", "..");
+  TestGnuBasename("///", "");
+  TestGnuBasename("//usr//lib//", "");
+}
+
+TEST(libgen_basename, posix_basename) {
+  TestPosixBasename(NULL, ".");
+  TestPosixBasename("", ".");
+  TestPosixBasename("/usr/lib", "lib");
+  TestPosixBasename("/system/bin/sh/", "sh");
+  TestPosixBasename("/usr/", "usr");
+  TestPosixBasename("usr", "usr");
+  TestPosixBasename("/", "/");
+  TestPosixBasename(".", ".");
+  TestPosixBasename("..", "..");
+  TestPosixBasename("///", "/");
+  TestPosixBasename("//usr//lib//", "lib");
+}
diff --git a/tests/libgen_test.cpp b/tests/libgen_test.cpp
index e9a5d5c..8a37a3f 100644
--- a/tests/libgen_test.cpp
+++ b/tests/libgen_test.cpp
@@ -19,15 +19,6 @@
 #include <errno.h>
 #include <gtest/gtest.h>
 
-static void TestBasename(const char* in, const char* expected_out) {
-  char* writable_in = (in != NULL) ? strdup(in) : NULL;
-  errno = 0;
-  const char* out = basename(&writable_in[0]);
-  ASSERT_STREQ(expected_out, out) << in;
-  ASSERT_EQ(0, errno) << in;
-  free(writable_in);
-}
-
 static void TestDirname(const char* in, const char* expected_out) {
   char* writable_in = (in != NULL) ? strdup(in) : NULL;
   errno = 0;
@@ -37,21 +28,6 @@
   free(writable_in);
 }
 
-// Do not use basename as the test name, it's defined to another value in glibc
-// so leads to a differently named test on host versus target architectures.
-TEST(libgen, posix_basename) {
-  TestBasename(NULL, ".");
-  TestBasename("", ".");
-  TestBasename("/usr/lib", "lib");
-  TestBasename("/usr/", "usr");
-  TestBasename("usr", "usr");
-  TestBasename("/", "/");
-  TestBasename(".", ".");
-  TestBasename("..", "..");
-  TestBasename("///", "/");
-  TestBasename("//usr//lib//", "lib");
-}
-
 TEST(libgen, dirname) {
   TestDirname(NULL, ".");
   TestDirname("", ".");
diff --git a/tests/libs/Android.build.dlext_testzip.mk b/tests/libs/Android.build.dlext_testzip.mk
index 7cc0dae..56be1e2 100644
--- a/tests/libs/Android.build.dlext_testzip.mk
+++ b/tests/libs/Android.build.dlext_testzip.mk
@@ -18,24 +18,67 @@
 # Library used by dlext tests - zipped and aligned
 # -----------------------------------------------------------------------------
 
+BIONIC_TESTS_ZIPALIGN := $(HOST_OUT_EXECUTABLES)/bionic_tests_zipalign
+
 include $(CLEAR_VARS)
 
 LOCAL_MODULE_CLASS := SHARED_LIBRARIES
-LOCAL_MODULE := libdlext_test_fd_zipaligned
+LOCAL_MODULE := libdlext_test_zip_zipaligned
 LOCAL_MODULE_SUFFIX := .zip
 LOCAL_MODULE_TAGS := tests
-LOCAL_MODULE_PATH := $($(bionic_2nd_arch_prefix)TARGET_OUT_DATA_NATIVE_TESTS)/libdlext_test_fd
+LOCAL_MODULE_PATH := $($(bionic_2nd_arch_prefix)TARGET_OUT_DATA_NATIVE_TESTS)/libdlext_test_zip
 LOCAL_2ND_ARCH_VAR_PREFIX := $(bionic_2nd_arch_prefix)
 
 include $(BUILD_SYSTEM)/base_rules.mk
 
 my_shared_libs := \
-  $($(bionic_2nd_arch_prefix)TARGET_OUT_INTERMEDIATE_LIBRARIES)/libdlext_test_fd.so
+  $($(bionic_2nd_arch_prefix)TARGET_OUT_INTERMEDIATE_LIBRARIES)/libdlext_test_zip.so \
+  $($(bionic_2nd_arch_prefix)TARGET_OUT_INTERMEDIATE_LIBRARIES)/libatest_simple_zip.so
 
-$(LOCAL_BUILT_MODULE): PRIVATE_ALIGNMENT := 4096 # PAGE_SIZE
-$(LOCAL_BUILT_MODULE) : $(my_shared_libs) | $(ZIPALIGN)
-	@echo "Zipalign $(PRIVATE_ALIGNMENT): $@"
+$(LOCAL_BUILT_MODULE) : $(my_shared_libs) | $(BIONIC_TESTS_ZIPALIGN)
+	@echo "Aligning zip: $@"
 	$(hide) rm -rf $(dir $@) && mkdir -p $(dir $@)/libdir
 	$(hide) cp $^ $(dir $@)/libdir
-	$(hide) (cd $(dir $@) && touch empty_file.txt && zip -rD0 $(notdir $@).unaligned empty_file.txt libdir/*.so)
-	$(hide) $(ZIPALIGN) $(PRIVATE_ALIGNMENT) $@.unaligned $@
+	$(hide) (cd $(dir $@) && touch empty_file.txt && zip -qrD0 $(notdir $@).unaligned empty_file.txt libdir/*.so)
+	$(hide) $(BIONIC_TESTS_ZIPALIGN) 4096 $@.unaligned $@
+
+include $(CLEAR_VARS)
+
+LOCAL_MODULE_CLASS := SHARED_LIBRARIES
+LOCAL_MODULE := libdlext_test_runpath_zip_zipaligned
+LOCAL_MODULE_SUFFIX := .zip
+LOCAL_MODULE_TAGS := tests
+LOCAL_MODULE_PATH := $($(bionic_2nd_arch_prefix)TARGET_OUT_DATA_NATIVE_TESTS)/libdlext_test_runpath_zip
+LOCAL_2ND_ARCH_VAR_PREFIX := $(bionic_2nd_arch_prefix)
+
+include $(BUILD_SYSTEM)/base_rules.mk
+my_shared_libs := \
+  $($(bionic_2nd_arch_prefix)TARGET_OUT_INTERMEDIATE_LIBRARIES)/libtest_dt_runpath_d_zip.so \
+  $($(bionic_2nd_arch_prefix)TARGET_OUT_INTERMEDIATE_LIBRARIES)/libtest_dt_runpath_b.so \
+  $($(bionic_2nd_arch_prefix)TARGET_OUT_INTERMEDIATE_LIBRARIES)/libtest_dt_runpath_a.so \
+  $($(bionic_2nd_arch_prefix)TARGET_OUT_INTERMEDIATE_LIBRARIES)/libtest_dt_runpath_c.so \
+  $($(bionic_2nd_arch_prefix)TARGET_OUT_INTERMEDIATE_LIBRARIES)/libtest_dt_runpath_x.so
+
+
+$(LOCAL_BUILT_MODULE) : PRIVATE_LIB_D := \
+  $($(bionic_2nd_arch_prefix)TARGET_OUT_INTERMEDIATE_LIBRARIES)/libtest_dt_runpath_d_zip.so
+$(LOCAL_BUILT_MODULE) : PRIVATE_LIB_A := \
+  $($(bionic_2nd_arch_prefix)TARGET_OUT_INTERMEDIATE_LIBRARIES)/libtest_dt_runpath_a.so
+$(LOCAL_BUILT_MODULE) : PRIVATE_LIB_B := \
+  $($(bionic_2nd_arch_prefix)TARGET_OUT_INTERMEDIATE_LIBRARIES)/libtest_dt_runpath_b.so
+$(LOCAL_BUILT_MODULE) : PRIVATE_LIB_C := \
+  $($(bionic_2nd_arch_prefix)TARGET_OUT_INTERMEDIATE_LIBRARIES)/libtest_dt_runpath_c.so
+$(LOCAL_BUILT_MODULE) : PRIVATE_LIB_X := \
+  $($(bionic_2nd_arch_prefix)TARGET_OUT_INTERMEDIATE_LIBRARIES)/libtest_dt_runpath_x.so
+$(LOCAL_BUILT_MODULE) : $(my_shared_libs) | $(BIONIC_TESTS_ZIPALIGN)
+	@echo "Aligning zip: $@"
+	$(hide) rm -rf $(dir $@) && mkdir -p $(dir $@)/libdir && \
+    mkdir -p $(dir $@)/libdir/dt_runpath_a && mkdir -p $(dir $@)/libdir/dt_runpath_b_c_x
+	$(hide) cp $(PRIVATE_LIB_D) $(dir $@)/libdir
+	$(hide) cp $(PRIVATE_LIB_A) $(dir $@)/libdir/dt_runpath_a
+	$(hide) cp $(PRIVATE_LIB_B) $(dir $@)/libdir/dt_runpath_b_c_x
+	$(hide) cp $(PRIVATE_LIB_C) $(dir $@)/libdir/dt_runpath_b_c_x
+	$(hide) cp $(PRIVATE_LIB_X) $(dir $@)/libdir/dt_runpath_b_c_x
+	$(hide) (cd $(dir $@) && touch empty_file.txt && zip -qrD0 $(notdir $@).unaligned empty_file.txt libdir)
+	$(hide) $(BIONIC_TESTS_ZIPALIGN) 4096 $@.unaligned $@
+
diff --git a/tests/libs/Android.build.dt_runpath.mk b/tests/libs/Android.build.dt_runpath.mk
new file mode 100644
index 0000000..4544bb1
--- /dev/null
+++ b/tests/libs/Android.build.dt_runpath.mk
@@ -0,0 +1,94 @@
+#
+# Copyright (C) 2012 The Android Open Source Project
+#
+# Licensed under the Apache License, Version 2.0 (the "License");
+# you may not use this file except in compliance with the License.
+# You may obtain a copy of the License at
+#
+#      http://www.apache.org/licenses/LICENSE-2.0
+#
+# Unless required by applicable law or agreed to in writing, software
+# distributed under the License is distributed on an "AS IS" BASIS,
+# WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
+# See the License for the specific language governing permissions and
+# limitations under the License.
+#
+
+# -----------------------------------------------------------------------------
+# Libraries used by dt_runpath tests.
+# -----------------------------------------------------------------------------
+
+#
+# Dependencies
+#
+# libtest_dt_runpath_d.so                       runpath: ${ORIGIN}/dt_runpath_b_c_x
+# |-> dt_runpath_b_c_x/libtest_dt_runpath_b.so  runpath: ${ORIGIN}/../dt_runpath_a
+# |   |-> dt_runpath_a/libtest_dt_runpath_a.so
+# |-> dt_runpath_b_c_x/libtest_dt_runpath_c.so  runpath: ${ORIGIN}/invalid_dt_runpath
+# |   |-> libtest_dt_runpath_a.so (soname)
+#
+# This one is used to test dlopen
+# dt_runpath_b_c_x/libtest_dt_runpath_x.so
+#
+
+# A leaf library in a non-standard directory.
+libtest_dt_runpath_a_src_files := \
+    empty.cpp
+
+libtest_dt_runpath_a_relative_path := dt_runpath_a
+module := libtest_dt_runpath_a
+include $(LOCAL_PATH)/Android.build.testlib.mk
+
+# Depends on library A with a DT_RUNPATH
+libtest_dt_runpath_b_src_files := \
+    empty.cpp
+
+libtest_dt_runpath_b_shared_libraries := libtest_dt_runpath_a
+libtest_dt_runpath_b_ldflags := -Wl,--rpath,\$${ORIGIN}/../dt_runpath_a -Wl,--enable-new-dtags
+libtest_dt_runpath_b_relative_path := dt_runpath_b_c_x
+module := libtest_dt_runpath_b
+include $(LOCAL_PATH)/Android.build.testlib.mk
+
+# Depends on library A with an incorrect DT_RUNPATH. This does not matter
+# because B is the first in the D (below) dependency order, and library A
+# is already loaded using the correct DT_RUNPATH from library B.
+libtest_dt_runpath_c_src_files := \
+    empty.cpp
+
+libtest_dt_runpath_c_shared_libraries := libtest_dt_runpath_a
+libtest_dt_runpath_c_ldflags := -Wl,--rpath,\$${ORIGIN}/invalid_dt_runpath -Wl,--enable-new-dtags
+libtest_dt_runpath_c_relative_path := dt_runpath_b_c_x
+module := libtest_dt_runpath_c
+include $(LOCAL_PATH)/Android.build.testlib.mk
+
+# D depends on B and C with DT_RUNPATH.
+libtest_dt_runpath_d_src_files := \
+    dlopen_b.cpp
+
+libtest_dt_runpath_d_shared_libraries := libtest_dt_runpath_b libtest_dt_runpath_c
+libtest_dt_runpath_d_ldflags := -Wl,--rpath,\$${ORIGIN}/dt_runpath_b_c_x -Wl,--enable-new-dtags
+module := libtest_dt_runpath_d
+include $(LOCAL_PATH)/Android.build.testlib.mk
+
+# D version for open-from-zip test with runpath
+libtest_dt_runpath_d_zip_src_files := \
+    dlopen_b.cpp
+
+libtest_dt_runpath_d_zip_shared_libraries := libtest_dt_runpath_b libtest_dt_runpath_c
+libtest_dt_runpath_d_zip_ldflags := -Wl,--rpath,\$${ORIGIN}/dt_runpath_b_c_x -Wl,--enable-new-dtags
+libtest_dt_runpath_d_zip_install_to_out_data := true
+module := libtest_dt_runpath_d_zip
+module_tag := optional
+build_type := target
+build_target := SHARED_LIBRARY
+include $(TEST_PATH)/Android.build.mk
+
+
+# A leaf library in a directory library D has DT_RUNPATH for.
+libtest_dt_runpath_x_src_files := \
+    empty.cpp
+
+libtest_dt_runpath_x_relative_path := dt_runpath_b_c_x
+module := libtest_dt_runpath_x
+include $(LOCAL_PATH)/Android.build.testlib.mk
+
diff --git a/tests/libs/Android.build.linker_namespaces.mk b/tests/libs/Android.build.linker_namespaces.mk
new file mode 100644
index 0000000..f913780
--- /dev/null
+++ b/tests/libs/Android.build.linker_namespaces.mk
@@ -0,0 +1,84 @@
+#
+# Copyright (C) 2015 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.
+#
+
+# -----------------------------------------------------------------------------
+# This set of libraries are used to verify linker namespaces.
+# -----------------------------------------------------------------------------
+
+# -----------------------------------------------------------------------------
+# Test cases
+# 1. Check that private libraries loaded in different namespaces are
+#    different. Check that dlsym does not confuse them.
+# 2. Check that public libraries loaded in different namespaces are shared
+#    between them.
+# 3. Check that namespace sticks on dlopen
+#
+# Dependency tree (visibility)
+# libnstest_root.so (this should be local to the namespace)
+# +-> libnstest_public.so
+# +-> libnstest_private.so
+#
+# libnstest_dlopened.so (library in private namespace dlopened from libnstest_root.so)
+# -----------------------------------------------------------------------------
+libnstest_root_src_files := namespaces_root.cpp
+libnstest_root_shared_libraries := libnstest_public libnstest_private
+libnstest_root_install_to_out_data_dir := private_namespace_libs
+module := libnstest_root
+include $(LOCAL_PATH)/Android.build.target.testlib.mk
+
+libnstest_public_src_files := namespaces_public.cpp
+module := libnstest_public
+libnstest_public_install_to_out_data_dir := public_namespace_libs
+include $(LOCAL_PATH)/Android.build.target.testlib.mk
+
+libnstest_private_src_files := namespaces_private.cpp
+libnstest_private_install_to_out_data_dir := private_namespace_libs
+module := libnstest_private
+include $(LOCAL_PATH)/Android.build.target.testlib.mk
+
+libnstest_dlopened_src_files := namespaces_dlopened.cpp
+libnstest_dlopened_install_to_out_data_dir := private_namespace_libs
+module := libnstest_dlopened
+include $(LOCAL_PATH)/Android.build.target.testlib.mk
+
+# -----------------------------------------------------------------------------
+# This set of libraries is to test isolated namespaces
+#
+# Isolated namespaces do not allow loading of the library outside of
+# the search paths.
+#
+# This library cannot be loaded in isolated namespace because one of DT_NEEDED
+# libraries is outside of the search paths.
+#
+# libnstest_root_not_isolated.so (DT_RUNPATH = $ORIGIN/../private_namespace_libs_external/)
+# +-> libnstest_public.so
+# +-> libnstest_private_external.so (located in $ORIGIN/../private_namespace_libs_external/)
+#
+# Search path: $NATIVE_TESTS/private_namespace_libs/
+# -----------------------------------------------------------------------------
+libnstest_root_not_isolated_src_files := namespaces_root.cpp
+libnstest_root_not_isolated_shared_libraries := libnstest_public libnstest_private_external
+libnstest_root_not_isolated_install_to_out_data_dir := private_namespace_libs
+libnstest_root_not_isolated_ldflags := -Wl,--rpath,\$$ORIGIN/../private_namespace_libs_external \
+                                       -Wl,--enable-new-dtags
+
+module := libnstest_root_not_isolated
+include $(LOCAL_PATH)/Android.build.target.testlib.mk
+
+libnstest_private_external_src_files := namespaces_private.cpp
+libnstest_private_external_install_to_out_data_dir := private_namespace_libs_external
+module := libnstest_private_external
+include $(LOCAL_PATH)/Android.build.target.testlib.mk
diff --git a/tests/libs/Android.build.target.testlib.mk b/tests/libs/Android.build.target.testlib.mk
new file mode 100644
index 0000000..1e767c2
--- /dev/null
+++ b/tests/libs/Android.build.target.testlib.mk
@@ -0,0 +1,20 @@
+#
+# Copyright (C) 2015 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.
+#
+
+build_target := SHARED_LIBRARY
+build_type := target
+include $(TEST_PATH)/Android.build.mk
+
diff --git a/tests/libs/Android.mk b/tests/libs/Android.mk
index 5b96306..506d6f2 100644
--- a/tests/libs/Android.mk
+++ b/tests/libs/Android.mk
@@ -17,14 +17,16 @@
 LOCAL_PATH := $(call my-dir)
 TEST_PATH := $(LOCAL_PATH)/..
 
-common_cppflags += -std=gnu++11
+common_cppflags :=
 common_additional_dependencies := \
     $(LOCAL_PATH)/Android.mk \
+    $(LOCAL_PATH)/Android.build.dt_runpath.mk \
     $(LOCAL_PATH)/Android.build.dlext_testzip.mk \
     $(LOCAL_PATH)/Android.build.dlopen_2_parents_reloc.mk \
     $(LOCAL_PATH)/Android.build.dlopen_check_order_dlsym.mk \
     $(LOCAL_PATH)/Android.build.dlopen_check_order_reloc_siblings.mk \
     $(LOCAL_PATH)/Android.build.dlopen_check_order_reloc_main_executable.mk \
+    $(LOCAL_PATH)/Android.build.linker_namespaces.mk \
     $(LOCAL_PATH)/Android.build.pthread_atfork.mk \
     $(LOCAL_PATH)/Android.build.testlib.mk \
     $(LOCAL_PATH)/Android.build.versioned_lib.mk \
@@ -102,6 +104,8 @@
 libdlext_test_norelro_ldflags := \
     -Wl,-z,norelro \
 
+libdlext_test_norelro_shared_libraries := libtest_simple
+
 module := libdlext_test_norelro
 module_tag := optional
 build_type := target
@@ -114,6 +118,8 @@
 libdlext_test_fd_src_files := \
     dlext_test_library.cpp \
 
+libdlext_test_fd_shared_libraries := libtest_simple
+
 libdlext_test_fd_install_to_out_data := true
 module := libdlext_test_fd
 module_tag := optional
@@ -121,6 +127,32 @@
 build_target := SHARED_LIBRARY
 include $(TEST_PATH)/Android.build.mk
 
+
+# -----------------------------------------------------------------------------
+# Libraries used by dlext tests for open from a zip-file
+# -----------------------------------------------------------------------------
+libdlext_test_zip_src_files := \
+    dlext_test_library.cpp \
+
+libdlext_test_zip_shared_libraries := libatest_simple_zip
+
+libdlext_test_zip_install_to_out_data := true
+module := libdlext_test_zip
+module_tag := optional
+build_type := target
+build_target := SHARED_LIBRARY
+include $(TEST_PATH)/Android.build.mk
+
+libatest_simple_zip_src_files := \
+    dlopen_testlib_simple.cpp
+
+libatest_simple_zip_install_to_out_data := true
+module := libatest_simple_zip
+module_tag := optional
+build_type := target
+build_target := SHARED_LIBRARY
+include $(TEST_PATH)/Android.build.mk
+
 # ----------------------------------------------------------------------------
 # Library with soname which does not match filename
 # ----------------------------------------------------------------------------
@@ -182,6 +214,16 @@
 include $(LOCAL_PATH)/Android.build.testlib.mk
 
 # -----------------------------------------------------------------------------
+# Build test helper libraries for linker namespaces
+# -----------------------------------------------------------------------------
+include $(LOCAL_PATH)/Android.build.linker_namespaces.mk
+
+# -----------------------------------------------------------------------------
+# Build DT_RUNPATH test helper libraries
+# -----------------------------------------------------------------------------
+include $(LOCAL_PATH)/Android.build.dt_runpath.mk
+
+# -----------------------------------------------------------------------------
 # Build library with two parents
 # -----------------------------------------------------------------------------
 include $(LOCAL_PATH)/Android.build.dlopen_2_parents_reloc.mk
@@ -444,3 +486,18 @@
 
 module := libtest_dlopen_from_ctor_main
 include $(LOCAL_PATH)/Android.build.testlib.mk
+
+# -----------------------------------------------------------------------------
+# Tool to use to align the shared libraries in a zip file.
+# -----------------------------------------------------------------------------
+include $(CLEAR_VARS)
+
+LOCAL_SRC_FILES := bionic_tests_zipalign.cpp
+LOCAL_MODULE := bionic_tests_zipalign
+LOCAL_CFLAGS := -Wall -Werror
+
+LOCAL_STATIC_LIBRARIES := libziparchive-host liblog libbase libz libutils
+
+LOCAL_MODULE_HOST_OS := darwin linux windows
+
+include $(BUILD_HOST_EXECUTABLE)
diff --git a/tests/libs/bionic_tests_zipalign.cpp b/tests/libs/bionic_tests_zipalign.cpp
new file mode 100644
index 0000000..a72820f
--- /dev/null
+++ b/tests/libs/bionic_tests_zipalign.cpp
@@ -0,0 +1,158 @@
+/*
+ * Copyright (C) 2015 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 <errno.h>
+#include <stdio.h>
+#include <stdlib.h>
+
+#include <algorithm>
+#include <string>
+#include <vector>
+
+#include <ziparchive/zip_archive.h>
+#include <ziparchive/zip_archive_stream_entry.h>
+#include <ziparchive/zip_writer.h>
+
+static void usage() {
+  fprintf(stderr, "usage: bionic_tests_zipalign ALIGNMENT INPUT_ZIP_FILE OUTPUT_ZIP_FILE\n");
+  fprintf(stderr, "  ALIGNMENT:\n");
+  fprintf(stderr, "    The new alignment of all entries in the new zip file.\n");
+  fprintf(stderr, "  INPUT_ZIP_FILE:\n");
+  fprintf(stderr, "    The input zip file that will be read but left unmodified.\n");
+  fprintf(stderr, "  OUTPUT_ZIP_FILE:\n");
+  fprintf(stderr, "    The output zip file that will be created from the input file.\n");
+}
+
+typedef std::pair<ZipEntry*, ZipString*> ZipData;
+
+static bool GetEntries(ZipArchiveHandle handle, std::vector<ZipData>* entries) {
+  void* cookie;
+  int32_t return_value = StartIteration(handle, &cookie, nullptr, nullptr);
+  if (return_value != 0) {
+    fprintf(stderr, "Unable to iterate over entries: %s\n", ErrorCodeString(return_value));
+    return false;
+  }
+
+  ZipEntry entry;
+  ZipString name;
+  while ((return_value = Next(cookie, &entry, &name)) == 0) {
+    entries->push_back(std::make_pair(new ZipEntry(entry), new ZipString(name)));
+  }
+  if (return_value != -1) {
+    fprintf(stderr, "Error while iterating over zip entries: %s\n", ErrorCodeString(return_value));
+  } else {
+    // Sort by offset.
+    std::sort(entries->begin(), entries->end(),
+              [](ZipData a, ZipData b) { return a.first->offset < b.first->offset; });
+  }
+
+  EndIteration(cookie);
+  return return_value == -1;
+}
+
+static bool CreateAlignedZip(ZipArchiveHandle& handle, FILE* zip_dst, uint32_t alignment) {
+  std::vector<ZipData> entries;
+  // We will not free the memory created in entries since the program
+  // terminates right after this function is called.
+  if (!GetEntries(handle, &entries)) {
+    return false;
+  }
+
+  ZipWriter writer(zip_dst);
+
+  int32_t error;
+  for (auto& entry : entries) {
+    ZipEntry* zip_entry = entry.first;
+    ZipString* zip_str = entry.second;
+
+    size_t flags = 0;
+    if ((zip_entry->method & kCompressDeflated) != 0) {
+      flags |= ZipWriter::kCompress;
+    }
+    std::string zip_name(reinterpret_cast<const char*>(zip_str->name), zip_str->name_length);
+    error = writer.StartAlignedEntry(zip_name.c_str(), flags, alignment);
+    if (error != 0) {
+      fprintf(stderr, "StartAlignedEntry failed: %s\n", ZipWriter::ErrorCodeString(error));
+      return false;
+    }
+    std::unique_ptr<ZipArchiveStreamEntry> stream(
+        ZipArchiveStreamEntry::Create(handle, *zip_entry));
+    const std::vector<uint8_t>* data;
+    while ((data = stream->Read()) != nullptr) {
+      error = writer.WriteBytes(data->data(), data->size());
+      if (error != 0) {
+        fprintf(stderr, "WriteBytes failed: %s\n", ZipWriter::ErrorCodeString(error));
+        return false;
+      }
+    }
+    if (!stream->Verify()) {
+      fprintf(stderr, "Failed to verify zip stream writer entry.\n");
+      return false;
+    }
+    error = writer.FinishEntry();
+    if (error != 0) {
+      fprintf(stderr, "FinishEntry failed: %s\n", ZipWriter::ErrorCodeString(error));
+    }
+  }
+
+  error = writer.Finish();
+  if (error != 0) {
+    fprintf(stderr, "Finish failed: %s\n", ZipWriter::ErrorCodeString(error));
+    return false;
+  }
+  return true;
+}
+
+int main(int argc, char* argv[]) {
+  if (argc != 4) {
+    usage();
+    return 1;
+  }
+
+  char* end;
+  unsigned long int alignment = strtoul(argv[1], &end, 10);
+  if ((alignment == ULONG_MAX && errno == ERANGE) || *end != '\0') {
+    fprintf(stderr, "ALIGNMENT value is not a valid number: %s\n", argv[1]);
+    usage();
+    return 1;
+  }
+  if (((alignment - 1) & alignment) != 0) {
+    fprintf(stderr, "ALIGNMENT value is not a power of 2: %s\n", argv[1]);
+    return 1;
+  }
+
+  ZipArchiveHandle handle;
+
+  int32_t return_value = OpenArchive(argv[2], &handle);
+  if (return_value != 0) {
+    CloseArchive(handle);
+    fprintf(stderr, "Unable to open '%s': %s\n", argv[2], ErrorCodeString(return_value));
+    return false;
+  }
+
+  FILE* zip_dst = fopen(argv[3], "we");
+  if (zip_dst == nullptr) {
+    fprintf(stderr, "Unable to create '%s': %s\n", argv[3], strerror(errno));
+    return 1;
+  }
+
+  bool success = CreateAlignedZip(handle, zip_dst, static_cast<uint32_t>(alignment));
+
+  CloseArchive(handle);
+  fclose(zip_dst);
+
+  return success ? 0 : 1;
+}
diff --git a/tests/libs/dlopen_b.cpp b/tests/libs/dlopen_b.cpp
new file mode 100644
index 0000000..cd81e16
--- /dev/null
+++ b/tests/libs/dlopen_b.cpp
@@ -0,0 +1,16 @@
+#include <dlfcn.h>
+extern "C" void *dlopen_b() {
+  // TODO (dimitry): this is to work around http://b/20049306
+  // remove once it is fixed
+  static int dummy = 0;
+
+  // This is supposed to succeed because this library has DT_RUNPATH
+  // for libtest_dt_runpath_x.so which should be taken into account
+  // by dlopen.
+  void *handle = dlopen("libtest_dt_runpath_x.so", RTLD_NOW);
+  if (handle != nullptr) {
+    dummy++;
+    return handle;
+  }
+  return nullptr;
+}
diff --git a/libc/upstream-freebsd/android/include/spinlock.h b/tests/libs/namespaces_dlopened.cpp
similarity index 71%
copy from libc/upstream-freebsd/android/include/spinlock.h
copy to tests/libs/namespaces_dlopened.cpp
index f5c3785..9d11689 100644
--- a/libc/upstream-freebsd/android/include/spinlock.h
+++ b/tests/libs/namespaces_dlopened.cpp
@@ -1,5 +1,5 @@
 /*
- * Copyright (C) 2013 The Android Open Source Project
+ * Copyright (C) 2015 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,9 +14,6 @@
  * limitations under the License.
  */
 
-#ifndef _BIONIC_FREEBSD_SPINLOCK_H_included
-#define _BIONIC_FREEBSD_SPINLOCK_H_included
+const char* g_private_dlopened_string = "This string is from private namespace "
+                                        "(dlopened library)";
 
-/* TODO: until we have the FreeBSD findfp.c, this is useless. */
-
-#endif
diff --git a/libc/upstream-freebsd/android/include/spinlock.h b/tests/libs/namespaces_private.cpp
similarity index 71%
copy from libc/upstream-freebsd/android/include/spinlock.h
copy to tests/libs/namespaces_private.cpp
index f5c3785..07cab70 100644
--- a/libc/upstream-freebsd/android/include/spinlock.h
+++ b/tests/libs/namespaces_private.cpp
@@ -1,5 +1,5 @@
 /*
- * Copyright (C) 2013 The Android Open Source Project
+ * Copyright (C) 2015 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,9 +14,5 @@
  * limitations under the License.
  */
 
-#ifndef _BIONIC_FREEBSD_SPINLOCK_H_included
-#define _BIONIC_FREEBSD_SPINLOCK_H_included
+const char* g_private_extern_string = "This string is from private namespace";
 
-/* TODO: until we have the FreeBSD findfp.c, this is useless. */
-
-#endif
diff --git a/libc/upstream-freebsd/android/include/spinlock.h b/tests/libs/namespaces_public.cpp
similarity index 71%
copy from libc/upstream-freebsd/android/include/spinlock.h
copy to tests/libs/namespaces_public.cpp
index f5c3785..bb2a8de 100644
--- a/libc/upstream-freebsd/android/include/spinlock.h
+++ b/tests/libs/namespaces_public.cpp
@@ -1,5 +1,5 @@
 /*
- * Copyright (C) 2013 The Android Open Source Project
+ * Copyright (C) 2015 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,9 +14,5 @@
  * limitations under the License.
  */
 
-#ifndef _BIONIC_FREEBSD_SPINLOCK_H_included
-#define _BIONIC_FREEBSD_SPINLOCK_H_included
+const char* g_public_extern_string = "This string is from public namespace";
 
-/* TODO: until we have the FreeBSD findfp.c, this is useless. */
-
-#endif
diff --git a/tests/libs/namespaces_root.cpp b/tests/libs/namespaces_root.cpp
new file mode 100644
index 0000000..b0006c7
--- /dev/null
+++ b/tests/libs/namespaces_root.cpp
@@ -0,0 +1,51 @@
+/*
+ * Copyright (C) 2015 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 <dlfcn.h>
+
+static const char* g_local_string = "This string is local to root library";
+extern "C" const char* g_private_extern_string;
+extern "C" const char* g_public_extern_string;
+
+bool g_dlopened = false;
+
+extern "C" const char* ns_get_local_string() {
+  return g_local_string;
+}
+
+extern "C" const char* ns_get_private_extern_string() {
+  return g_private_extern_string;
+}
+
+extern "C" const char* ns_get_public_extern_string() {
+  return g_public_extern_string;
+}
+
+extern "C" const char* ns_get_dlopened_string() {
+  void* handle = dlopen("libnstest_dlopened.so", RTLD_NOW | RTLD_GLOBAL);
+  if (handle == nullptr) {
+    return nullptr;
+  }
+
+  const char** result = static_cast<const char**>(dlsym(handle, "g_private_dlopened_string"));
+  if (result == nullptr) {
+    return nullptr;
+  } else {
+    g_dlopened = true;
+  }
+
+  return *result;
+}
diff --git a/tests/malloc_test.cpp b/tests/malloc_test.cpp
index b76625a..8fba1c4 100644
--- a/tests/malloc_test.cpp
+++ b/tests/malloc_test.cpp
@@ -372,3 +372,131 @@
   }
 #endif
 }
+
+TEST(malloc, calloc_usable_size) {
+  for (size_t size = 1; size <= 2048; size++) {
+    void* pointer = malloc(size);
+    ASSERT_TRUE(pointer != nullptr);
+    memset(pointer, 0xeb, malloc_usable_size(pointer));
+    free(pointer);
+
+    // We should get a previous pointer that has been set to non-zero.
+    // If calloc does not zero out all of the data, this will fail.
+    uint8_t* zero_mem = reinterpret_cast<uint8_t*>(calloc(1, size));
+    ASSERT_TRUE(pointer != nullptr);
+    size_t usable_size = malloc_usable_size(zero_mem);
+    for (size_t i = 0; i < usable_size; i++) {
+      ASSERT_EQ(0, zero_mem[i]) << "Failed at allocation size " << size << " at byte " << i;
+    }
+    free(zero_mem);
+  }
+}
+
+TEST(malloc, malloc_0) {
+  void* p = malloc(0);
+  ASSERT_TRUE(p != nullptr);
+  free(p);
+}
+
+TEST(malloc, calloc_0_0) {
+  void* p = calloc(0, 0);
+  ASSERT_TRUE(p != nullptr);
+  free(p);
+}
+
+TEST(malloc, calloc_0_1) {
+  void* p = calloc(0, 1);
+  ASSERT_TRUE(p != nullptr);
+  free(p);
+}
+
+TEST(malloc, calloc_1_0) {
+  void* p = calloc(1, 0);
+  ASSERT_TRUE(p != nullptr);
+  free(p);
+}
+
+TEST(malloc, realloc_nullptr_0) {
+  // realloc(nullptr, size) is actually malloc(size).
+  void* p = realloc(nullptr, 0);
+  ASSERT_TRUE(p != nullptr);
+  free(p);
+}
+
+TEST(malloc, realloc_0) {
+  void* p = malloc(1024);
+  ASSERT_TRUE(p != nullptr);
+  // realloc(p, 0) is actually free(p).
+  void* p2 = realloc(p, 0);
+  ASSERT_TRUE(p2 == nullptr);
+}
+
+constexpr size_t MAX_LOOPS = 200;
+
+// Make sure that memory returned by malloc is aligned to allow these data types.
+TEST(malloc, verify_alignment) {
+  uint32_t** values_32 = new uint32_t*[MAX_LOOPS];
+  uint64_t** values_64 = new uint64_t*[MAX_LOOPS];
+  long double** values_ldouble = new long double*[MAX_LOOPS];
+  // Use filler to attempt to force the allocator to get potentially bad alignments.
+  void** filler = new void*[MAX_LOOPS];
+
+  for (size_t i = 0; i < MAX_LOOPS; i++) {
+    // Check uint32_t pointers.
+    filler[i] = malloc(1);
+    ASSERT_TRUE(filler[i] != nullptr);
+
+    values_32[i] = reinterpret_cast<uint32_t*>(malloc(sizeof(uint32_t)));
+    ASSERT_TRUE(values_32[i] != nullptr);
+    *values_32[i] = i;
+    ASSERT_EQ(*values_32[i], i);
+    ASSERT_EQ(0U, reinterpret_cast<uintptr_t>(values_32[i]) & (sizeof(uint32_t) - 1));
+
+    free(filler[i]);
+  }
+
+  for (size_t i = 0; i < MAX_LOOPS; i++) {
+    // Check uint64_t pointers.
+    filler[i] = malloc(1);
+    ASSERT_TRUE(filler[i] != nullptr);
+
+    values_64[i] = reinterpret_cast<uint64_t*>(malloc(sizeof(uint64_t)));
+    ASSERT_TRUE(values_64[i] != nullptr);
+    *values_64[i] = 0x1000 + i;
+    ASSERT_EQ(*values_64[i], 0x1000 + i);
+    ASSERT_EQ(0U, reinterpret_cast<uintptr_t>(values_64[i]) & (sizeof(uint64_t) - 1));
+
+    free(filler[i]);
+  }
+
+  for (size_t i = 0; i < MAX_LOOPS; i++) {
+    // Check long double pointers.
+    filler[i] = malloc(1);
+    ASSERT_TRUE(filler[i] != nullptr);
+
+    values_ldouble[i] = reinterpret_cast<long double*>(malloc(sizeof(long double)));
+    ASSERT_TRUE(values_ldouble[i] != nullptr);
+    *values_ldouble[i] = 5.5 + i;
+    ASSERT_DOUBLE_EQ(*values_ldouble[i], 5.5 + i);
+    // 32 bit glibc has a long double size of 12 bytes, so hardcode the
+    // required alignment to 0x7.
+#if !defined(__BIONIC__) && !defined(__LP64__)
+    ASSERT_EQ(0U, reinterpret_cast<uintptr_t>(values_ldouble[i]) & 0x7);
+#else
+    ASSERT_EQ(0U, reinterpret_cast<uintptr_t>(values_ldouble[i]) & (sizeof(long double) - 1));
+#endif
+
+    free(filler[i]);
+  }
+
+  for (size_t i = 0; i < MAX_LOOPS; i++) {
+    free(values_32[i]);
+    free(values_64[i]);
+    free(values_ldouble[i]);
+  }
+
+  delete[] filler;
+  delete[] values_32;
+  delete[] values_64;
+  delete[] values_ldouble;
+}
diff --git a/tests/math_data/llrint_intel_data.h b/tests/math_data/llrint_intel_data.h
new file mode 100644
index 0000000..a6861c2
--- /dev/null
+++ b/tests/math_data/llrint_intel_data.h
@@ -0,0 +1,1242 @@
+/*
+ * Copyright (C) 2016 The Android Open Source Project
+ *
+ * Licensed under the Apache License, Version 2.0 (the "License");
+ * you may not use this file except in compliance with the License.
+ * You may obtain a copy of the License at
+ *
+ *      http://www.apache.org/licenses/LICENSE-2.0
+ *
+ * Unless required by applicable law or agreed to in writing, software
+ * distributed under the License is distributed on an "AS IS" BASIS,
+ * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
+ * See the License for the specific language governing permissions and
+ * limitations under the License.
+ */
+
+static data_llong_1_t<double> g_llrint_intel_data[] = {
+  { // Entry 0
+    (long long int)0.0,
+    -0x1.0p-1074
+  },
+  { // Entry 1
+    (long long int)0.0,
+    -0.0
+  },
+  { // Entry 2
+    (long long int)0.0,
+    0x1.0p-1074
+  },
+  { // Entry 3
+    (long long int)0.0,
+    0x1.fffffffffffffp-2
+  },
+  { // Entry 4
+    (long long int)0.0,
+    0x1.0p-1
+  },
+  { // Entry 5
+    (long long int)0x1.p0,
+    0x1.0000000000001p-1
+  },
+  { // Entry 6
+    (long long int)0x1.p0,
+    0x1.fffffffffffffp-1
+  },
+  { // Entry 7
+    (long long int)0x1.p0,
+    0x1.0p0
+  },
+  { // Entry 8
+    (long long int)0x1.p0,
+    0x1.0000000000001p0
+  },
+  { // Entry 9
+    (long long int)0x1.p0,
+    0x1.7ffffffffffffp0
+  },
+  { // Entry 10
+    (long long int)0x1.p1,
+    0x1.8p0
+  },
+  { // Entry 11
+    (long long int)0x1.p1,
+    0x1.8000000000001p0
+  },
+  { // Entry 12
+    (long long int)0x1.p1,
+    0x1.fffffffffffffp0
+  },
+  { // Entry 13
+    (long long int)0x1.p1,
+    0x1.0p1
+  },
+  { // Entry 14
+    (long long int)0x1.p1,
+    0x1.0000000000001p1
+  },
+  { // Entry 15
+    (long long int)0x1.p1,
+    0x1.3ffffffffffffp1
+  },
+  { // Entry 16
+    (long long int)0x1.p1,
+    0x1.4p1
+  },
+  { // Entry 17
+    (long long int)0x1.80p1,
+    0x1.4000000000001p1
+  },
+  { // Entry 18
+    (long long int)0x1.90p6,
+    0x1.8ffffffffffffp6
+  },
+  { // Entry 19
+    (long long int)0x1.90p6,
+    0x1.9p6
+  },
+  { // Entry 20
+    (long long int)0x1.90p6,
+    0x1.9000000000001p6
+  },
+  { // Entry 21
+    (long long int)0x1.90p6,
+    0x1.91fffffffffffp6
+  },
+  { // Entry 22
+    (long long int)0x1.90p6,
+    0x1.920p6
+  },
+  { // Entry 23
+    (long long int)0x1.94p6,
+    0x1.9200000000001p6
+  },
+  { // Entry 24
+    (long long int)0x1.f4p9,
+    0x1.f3fffffffffffp9
+  },
+  { // Entry 25
+    (long long int)0x1.f4p9,
+    0x1.f40p9
+  },
+  { // Entry 26
+    (long long int)0x1.f4p9,
+    0x1.f400000000001p9
+  },
+  { // Entry 27
+    (long long int)0x1.f4p9,
+    0x1.f43ffffffffffp9
+  },
+  { // Entry 28
+    (long long int)0x1.f4p9,
+    0x1.f44p9
+  },
+  { // Entry 29
+    (long long int)0x1.f480p9,
+    0x1.f440000000001p9
+  },
+  { // Entry 30
+    (long long int)0x1.p50,
+    0x1.fffffffffffffp49
+  },
+  { // Entry 31
+    (long long int)0x1.p50,
+    0x1.0p50
+  },
+  { // Entry 32
+    (long long int)0x1.p50,
+    0x1.0000000000001p50
+  },
+  { // Entry 33
+    (long long int)0x1.p51,
+    0x1.fffffffffffffp50
+  },
+  { // Entry 34
+    (long long int)0x1.p51,
+    0x1.0p51
+  },
+  { // Entry 35
+    (long long int)0x1.p51,
+    0x1.0000000000001p51
+  },
+  { // Entry 36
+    (long long int)0x1.p52,
+    0x1.fffffffffffffp51
+  },
+  { // Entry 37
+    (long long int)0x1.p52,
+    0x1.0p52
+  },
+  { // Entry 38
+    (long long int)0x1.00000000000010p52,
+    0x1.0000000000001p52
+  },
+  { // Entry 39
+    (long long int)0x1.fffffffffffff0p52,
+    0x1.fffffffffffffp52
+  },
+  { // Entry 40
+    (long long int)0x1.p53,
+    0x1.0p53
+  },
+  { // Entry 41
+    (long long int)0x1.00000000000010p53,
+    0x1.0000000000001p53
+  },
+  { // Entry 42
+    (long long int)0x1.fffffffffffff0p53,
+    0x1.fffffffffffffp53
+  },
+  { // Entry 43
+    (long long int)0x1.p54,
+    0x1.0p54
+  },
+  { // Entry 44
+    (long long int)0x1.00000000000010p54,
+    0x1.0000000000001p54
+  },
+  { // Entry 45
+    (long long int)-0x1.p0,
+    -0x1.0000000000001p-1
+  },
+  { // Entry 46
+    (long long int)0.0,
+    -0x1.0p-1
+  },
+  { // Entry 47
+    (long long int)0.0,
+    -0x1.fffffffffffffp-2
+  },
+  { // Entry 48
+    (long long int)-0x1.p0,
+    -0x1.0000000000001p0
+  },
+  { // Entry 49
+    (long long int)-0x1.p0,
+    -0x1.0p0
+  },
+  { // Entry 50
+    (long long int)-0x1.p0,
+    -0x1.fffffffffffffp-1
+  },
+  { // Entry 51
+    (long long int)-0x1.p1,
+    -0x1.8000000000001p0
+  },
+  { // Entry 52
+    (long long int)-0x1.p1,
+    -0x1.8p0
+  },
+  { // Entry 53
+    (long long int)-0x1.p0,
+    -0x1.7ffffffffffffp0
+  },
+  { // Entry 54
+    (long long int)-0x1.p1,
+    -0x1.0000000000001p1
+  },
+  { // Entry 55
+    (long long int)-0x1.p1,
+    -0x1.0p1
+  },
+  { // Entry 56
+    (long long int)-0x1.p1,
+    -0x1.fffffffffffffp0
+  },
+  { // Entry 57
+    (long long int)-0x1.80p1,
+    -0x1.4000000000001p1
+  },
+  { // Entry 58
+    (long long int)-0x1.p1,
+    -0x1.4p1
+  },
+  { // Entry 59
+    (long long int)-0x1.p1,
+    -0x1.3ffffffffffffp1
+  },
+  { // Entry 60
+    (long long int)-0x1.90p6,
+    -0x1.9000000000001p6
+  },
+  { // Entry 61
+    (long long int)-0x1.90p6,
+    -0x1.9p6
+  },
+  { // Entry 62
+    (long long int)-0x1.90p6,
+    -0x1.8ffffffffffffp6
+  },
+  { // Entry 63
+    (long long int)-0x1.94p6,
+    -0x1.9200000000001p6
+  },
+  { // Entry 64
+    (long long int)-0x1.90p6,
+    -0x1.920p6
+  },
+  { // Entry 65
+    (long long int)-0x1.90p6,
+    -0x1.91fffffffffffp6
+  },
+  { // Entry 66
+    (long long int)-0x1.f4p9,
+    -0x1.f400000000001p9
+  },
+  { // Entry 67
+    (long long int)-0x1.f4p9,
+    -0x1.f40p9
+  },
+  { // Entry 68
+    (long long int)-0x1.f4p9,
+    -0x1.f3fffffffffffp9
+  },
+  { // Entry 69
+    (long long int)-0x1.f480p9,
+    -0x1.f440000000001p9
+  },
+  { // Entry 70
+    (long long int)-0x1.f4p9,
+    -0x1.f44p9
+  },
+  { // Entry 71
+    (long long int)-0x1.f4p9,
+    -0x1.f43ffffffffffp9
+  },
+  { // Entry 72
+    (long long int)-0x1.p50,
+    -0x1.0000000000001p50
+  },
+  { // Entry 73
+    (long long int)-0x1.p50,
+    -0x1.0p50
+  },
+  { // Entry 74
+    (long long int)-0x1.p50,
+    -0x1.fffffffffffffp49
+  },
+  { // Entry 75
+    (long long int)-0x1.p51,
+    -0x1.0000000000001p51
+  },
+  { // Entry 76
+    (long long int)-0x1.p51,
+    -0x1.0p51
+  },
+  { // Entry 77
+    (long long int)-0x1.p51,
+    -0x1.fffffffffffffp50
+  },
+  { // Entry 78
+    (long long int)-0x1.00000000000010p52,
+    -0x1.0000000000001p52
+  },
+  { // Entry 79
+    (long long int)-0x1.p52,
+    -0x1.0p52
+  },
+  { // Entry 80
+    (long long int)-0x1.p52,
+    -0x1.fffffffffffffp51
+  },
+  { // Entry 81
+    (long long int)-0x1.00000000000010p53,
+    -0x1.0000000000001p53
+  },
+  { // Entry 82
+    (long long int)-0x1.p53,
+    -0x1.0p53
+  },
+  { // Entry 83
+    (long long int)-0x1.fffffffffffff0p52,
+    -0x1.fffffffffffffp52
+  },
+  { // Entry 84
+    (long long int)-0x1.00000000000010p54,
+    -0x1.0000000000001p54
+  },
+  { // Entry 85
+    (long long int)-0x1.p54,
+    -0x1.0p54
+  },
+  { // Entry 86
+    (long long int)-0x1.fffffffffffff0p53,
+    -0x1.fffffffffffffp53
+  },
+  { // Entry 87
+    (long long int)0x1.p30,
+    0x1.fffffffffffffp29
+  },
+  { // Entry 88
+    (long long int)0x1.p30,
+    0x1.0p30
+  },
+  { // Entry 89
+    (long long int)0x1.p30,
+    0x1.0000000000001p30
+  },
+  { // Entry 90
+    (long long int)0x1.fffffff8p30,
+    0x1.fffffff7ffffep30
+  },
+  { // Entry 91
+    (long long int)0x1.fffffff8p30,
+    0x1.fffffff7fffffp30
+  },
+  { // Entry 92
+    (long long int)0x1.fffffff8p30,
+    0x1.fffffff80p30
+  },
+  { // Entry 93
+    (long long int)0x1.fffffff8p30,
+    0x1.fffffff800001p30
+  },
+  { // Entry 94
+    (long long int)0x1.fffffff8p30,
+    0x1.fffffff800002p30
+  },
+  { // Entry 95
+    (long long int)0x1.fffffff8p30,
+    0x1.fffffff9ffffep30
+  },
+  { // Entry 96
+    (long long int)0x1.fffffff8p30,
+    0x1.fffffff9fffffp30
+  },
+  { // Entry 97
+    (long long int)0x1.fffffff8p30,
+    0x1.fffffffa0p30
+  },
+  { // Entry 98
+    (long long int)0x1.fffffffcp30,
+    0x1.fffffffa00001p30
+  },
+  { // Entry 99
+    (long long int)0x1.fffffffcp30,
+    0x1.fffffffa00002p30
+  },
+  { // Entry 100
+    (long long int)0x1.fffffffcp30,
+    0x1.fffffffbffffep30
+  },
+  { // Entry 101
+    (long long int)0x1.fffffffcp30,
+    0x1.fffffffbfffffp30
+  },
+  { // Entry 102
+    (long long int)0x1.fffffffcp30,
+    0x1.fffffffc0p30
+  },
+  { // Entry 103
+    (long long int)0x1.fffffffcp30,
+    0x1.fffffffc00001p30
+  },
+  { // Entry 104
+    (long long int)0x1.fffffffcp30,
+    0x1.fffffffc00002p30
+  },
+  { // Entry 105
+    (long long int)0x1.fffffffcp30,
+    0x1.fffffffdffffep30
+  },
+  { // Entry 106
+    (long long int)0x1.fffffffcp30,
+    0x1.fffffffdfffffp30
+  },
+  { // Entry 107
+    (long long int)0x1.p31,
+    0x1.fffffffe0p30
+  },
+  { // Entry 108
+    (long long int)0x1.p31,
+    0x1.fffffffe00001p30
+  },
+  { // Entry 109
+    (long long int)0x1.p31,
+    0x1.fffffffe00002p30
+  },
+  { // Entry 110
+    (long long int)0x1.p31,
+    0x1.ffffffffffffep30
+  },
+  { // Entry 111
+    (long long int)0x1.p31,
+    0x1.fffffffffffffp30
+  },
+  { // Entry 112
+    (long long int)0x1.p31,
+    0x1.0p31
+  },
+  { // Entry 113
+    (long long int)0x1.p31,
+    0x1.0000000000001p31
+  },
+  { // Entry 114
+    (long long int)0x1.p31,
+    0x1.0000000000002p31
+  },
+  { // Entry 115
+    (long long int)0x1.p31,
+    0x1.00000000ffffep31
+  },
+  { // Entry 116
+    (long long int)0x1.p31,
+    0x1.00000000fffffp31
+  },
+  { // Entry 117
+    (long long int)0x1.p31,
+    0x1.000000010p31
+  },
+  { // Entry 118
+    (long long int)0x1.00000002p31,
+    0x1.0000000100001p31
+  },
+  { // Entry 119
+    (long long int)0x1.00000002p31,
+    0x1.0000000100002p31
+  },
+  { // Entry 120
+    (long long int)0x1.ffffffe0p30,
+    0x1.ffffffep30
+  },
+  { // Entry 121
+    (long long int)0x1.ffffffe4p30,
+    0x1.ffffffe40p30
+  },
+  { // Entry 122
+    (long long int)0x1.ffffffe8p30,
+    0x1.ffffffe80p30
+  },
+  { // Entry 123
+    (long long int)0x1.ffffffecp30,
+    0x1.ffffffec0p30
+  },
+  { // Entry 124
+    (long long int)0x1.fffffff0p30,
+    0x1.fffffffp30
+  },
+  { // Entry 125
+    (long long int)0x1.fffffff4p30,
+    0x1.fffffff40p30
+  },
+  { // Entry 126
+    (long long int)0x1.fffffff8p30,
+    0x1.fffffff80p30
+  },
+  { // Entry 127
+    (long long int)0x1.fffffffcp30,
+    0x1.fffffffc0p30
+  },
+  { // Entry 128
+    (long long int)0x1.p31,
+    0x1.0p31
+  },
+  { // Entry 129
+    (long long int)0x1.00000002p31,
+    0x1.000000020p31
+  },
+  { // Entry 130
+    (long long int)-0x1.p30,
+    -0x1.0000000000001p30
+  },
+  { // Entry 131
+    (long long int)-0x1.p30,
+    -0x1.0p30
+  },
+  { // Entry 132
+    (long long int)-0x1.p30,
+    -0x1.fffffffffffffp29
+  },
+  { // Entry 133
+    (long long int)-0x1.fffffff8p30,
+    -0x1.fffffff800002p30
+  },
+  { // Entry 134
+    (long long int)-0x1.fffffff8p30,
+    -0x1.fffffff800001p30
+  },
+  { // Entry 135
+    (long long int)-0x1.fffffff8p30,
+    -0x1.fffffff80p30
+  },
+  { // Entry 136
+    (long long int)-0x1.fffffff8p30,
+    -0x1.fffffff7fffffp30
+  },
+  { // Entry 137
+    (long long int)-0x1.fffffff8p30,
+    -0x1.fffffff7ffffep30
+  },
+  { // Entry 138
+    (long long int)-0x1.fffffffcp30,
+    -0x1.fffffffa00002p30
+  },
+  { // Entry 139
+    (long long int)-0x1.fffffffcp30,
+    -0x1.fffffffa00001p30
+  },
+  { // Entry 140
+    (long long int)-0x1.fffffff8p30,
+    -0x1.fffffffa0p30
+  },
+  { // Entry 141
+    (long long int)-0x1.fffffff8p30,
+    -0x1.fffffff9fffffp30
+  },
+  { // Entry 142
+    (long long int)-0x1.fffffff8p30,
+    -0x1.fffffff9ffffep30
+  },
+  { // Entry 143
+    (long long int)-0x1.fffffffcp30,
+    -0x1.fffffffc00002p30
+  },
+  { // Entry 144
+    (long long int)-0x1.fffffffcp30,
+    -0x1.fffffffc00001p30
+  },
+  { // Entry 145
+    (long long int)-0x1.fffffffcp30,
+    -0x1.fffffffc0p30
+  },
+  { // Entry 146
+    (long long int)-0x1.fffffffcp30,
+    -0x1.fffffffbfffffp30
+  },
+  { // Entry 147
+    (long long int)-0x1.fffffffcp30,
+    -0x1.fffffffbffffep30
+  },
+  { // Entry 148
+    (long long int)-0x1.p31,
+    -0x1.fffffffe00002p30
+  },
+  { // Entry 149
+    (long long int)-0x1.p31,
+    -0x1.fffffffe00001p30
+  },
+  { // Entry 150
+    (long long int)-0x1.p31,
+    -0x1.fffffffe0p30
+  },
+  { // Entry 151
+    (long long int)-0x1.fffffffcp30,
+    -0x1.fffffffdfffffp30
+  },
+  { // Entry 152
+    (long long int)-0x1.fffffffcp30,
+    -0x1.fffffffdffffep30
+  },
+  { // Entry 153
+    (long long int)-0x1.p31,
+    -0x1.0000000000002p31
+  },
+  { // Entry 154
+    (long long int)-0x1.p31,
+    -0x1.0000000000001p31
+  },
+  { // Entry 155
+    (long long int)-0x1.p31,
+    -0x1.0p31
+  },
+  { // Entry 156
+    (long long int)-0x1.p31,
+    -0x1.fffffffffffffp30
+  },
+  { // Entry 157
+    (long long int)-0x1.p31,
+    -0x1.ffffffffffffep30
+  },
+  { // Entry 158
+    (long long int)-0x1.00000002p31,
+    -0x1.0000000100002p31
+  },
+  { // Entry 159
+    (long long int)-0x1.00000002p31,
+    -0x1.0000000100001p31
+  },
+  { // Entry 160
+    (long long int)-0x1.p31,
+    -0x1.000000010p31
+  },
+  { // Entry 161
+    (long long int)-0x1.p31,
+    -0x1.00000000fffffp31
+  },
+  { // Entry 162
+    (long long int)-0x1.p31,
+    -0x1.00000000ffffep31
+  },
+  { // Entry 163
+    (long long int)-0x1.ffffffe0p30,
+    -0x1.ffffffep30
+  },
+  { // Entry 164
+    (long long int)-0x1.ffffffe0p30,
+    -0x1.ffffffep30
+  },
+  { // Entry 165
+    (long long int)-0x1.ffffffe0p30,
+    -0x1.ffffffep30
+  },
+  { // Entry 166
+    (long long int)-0x1.ffffffe0p30,
+    -0x1.ffffffep30
+  },
+  { // Entry 167
+    (long long int)-0x1.ffffffe0p30,
+    -0x1.ffffffep30
+  },
+  { // Entry 168
+    (long long int)-0x1.ffffffe0p30,
+    -0x1.ffffffep30
+  },
+  { // Entry 169
+    (long long int)-0x1.ffffffe0p30,
+    -0x1.ffffffep30
+  },
+  { // Entry 170
+    (long long int)-0x1.ffffffe0p30,
+    -0x1.ffffffep30
+  },
+  { // Entry 171
+    (long long int)-0x1.ffffffe0p30,
+    -0x1.ffffffep30
+  },
+  { // Entry 172
+    (long long int)-0x1.ffffffe0p30,
+    -0x1.ffffffep30
+  },
+  { // Entry 173
+    (long long int)0x1.ffffffffffffe0p61,
+    0x1.ffffffffffffep61
+  },
+  { // Entry 174
+    (long long int)0x1.fffffffffffff0p61,
+    0x1.fffffffffffffp61
+  },
+  { // Entry 175
+    (long long int)0x1.p62,
+    0x1.0p62
+  },
+  { // Entry 176
+    (long long int)0x1.00000000000010p62,
+    0x1.0000000000001p62
+  },
+  { // Entry 177
+    (long long int)0x1.00000000000020p62,
+    0x1.0000000000002p62
+  },
+  { // Entry 178
+    (long long int)0x1.ffffffffffffe0p62,
+    0x1.ffffffffffffep62
+  },
+  { // Entry 179
+    (long long int)0x1.fffffffffffff0p62,
+    0x1.fffffffffffffp62
+  },
+  { // Entry 180
+    (long long int)-0x1.00000000000020p62,
+    -0x1.0000000000002p62
+  },
+  { // Entry 181
+    (long long int)-0x1.00000000000010p62,
+    -0x1.0000000000001p62
+  },
+  { // Entry 182
+    (long long int)-0x1.p62,
+    -0x1.0p62
+  },
+  { // Entry 183
+    (long long int)-0x1.fffffffffffff0p61,
+    -0x1.fffffffffffffp61
+  },
+  { // Entry 184
+    (long long int)-0x1.ffffffffffffe0p61,
+    -0x1.ffffffffffffep61
+  },
+  { // Entry 185
+    (long long int)-0x1.p63,
+    -0x1.0p63
+  },
+  { // Entry 186
+    (long long int)-0x1.fffffffffffff0p62,
+    -0x1.fffffffffffffp62
+  },
+  { // Entry 187
+    (long long int)-0x1.ffffffffffffe0p62,
+    -0x1.ffffffffffffep62
+  },
+  { // Entry 188
+    (long long int)0x1.p62,
+    0x1.0p62
+  },
+  { // Entry 189
+    (long long int)-0x1.p62,
+    -0x1.0p62
+  },
+  { // Entry 190
+    (long long int)-0x1.p63,
+    -0x1.0p63
+  },
+  { // Entry 191
+    (long long int)0x1.fffffffcp30,
+    0x1.fffffffbfffffp30
+  },
+  { // Entry 192
+    (long long int)0x1.fffffffcp30,
+    0x1.fffffffc0p30
+  },
+  { // Entry 193
+    (long long int)0x1.fffffffcp30,
+    0x1.fffffffc00001p30
+  },
+  { // Entry 194
+    (long long int)-0x1.p31,
+    -0x1.0000000000001p31
+  },
+  { // Entry 195
+    (long long int)-0x1.p31,
+    -0x1.0p31
+  },
+  { // Entry 196
+    (long long int)-0x1.p31,
+    -0x1.fffffffffffffp30
+  },
+  { // Entry 197
+    (long long int)0x1.p2,
+    0x1.fffffffffffffp1
+  },
+  { // Entry 198
+    (long long int)0x1.p2,
+    0x1.0p2
+  },
+  { // Entry 199
+    (long long int)0x1.p2,
+    0x1.0000000000001p2
+  },
+  { // Entry 200
+    (long long int)0x1.p3,
+    0x1.fffffffffffffp2
+  },
+  { // Entry 201
+    (long long int)0x1.p3,
+    0x1.0p3
+  },
+  { // Entry 202
+    (long long int)0x1.p3,
+    0x1.0000000000001p3
+  },
+  { // Entry 203
+    (long long int)0x1.p4,
+    0x1.fffffffffffffp3
+  },
+  { // Entry 204
+    (long long int)0x1.p4,
+    0x1.0p4
+  },
+  { // Entry 205
+    (long long int)0x1.p4,
+    0x1.0000000000001p4
+  },
+  { // Entry 206
+    (long long int)0x1.p5,
+    0x1.fffffffffffffp4
+  },
+  { // Entry 207
+    (long long int)0x1.p5,
+    0x1.0p5
+  },
+  { // Entry 208
+    (long long int)0x1.p5,
+    0x1.0000000000001p5
+  },
+  { // Entry 209
+    (long long int)0x1.p6,
+    0x1.fffffffffffffp5
+  },
+  { // Entry 210
+    (long long int)0x1.p6,
+    0x1.0p6
+  },
+  { // Entry 211
+    (long long int)0x1.p6,
+    0x1.0000000000001p6
+  },
+  { // Entry 212
+    (long long int)0x1.p7,
+    0x1.fffffffffffffp6
+  },
+  { // Entry 213
+    (long long int)0x1.p7,
+    0x1.0p7
+  },
+  { // Entry 214
+    (long long int)0x1.p7,
+    0x1.0000000000001p7
+  },
+  { // Entry 215
+    (long long int)0x1.p8,
+    0x1.fffffffffffffp7
+  },
+  { // Entry 216
+    (long long int)0x1.p8,
+    0x1.0p8
+  },
+  { // Entry 217
+    (long long int)0x1.p8,
+    0x1.0000000000001p8
+  },
+  { // Entry 218
+    (long long int)0x1.p9,
+    0x1.fffffffffffffp8
+  },
+  { // Entry 219
+    (long long int)0x1.p9,
+    0x1.0p9
+  },
+  { // Entry 220
+    (long long int)0x1.p9,
+    0x1.0000000000001p9
+  },
+  { // Entry 221
+    (long long int)0x1.p10,
+    0x1.fffffffffffffp9
+  },
+  { // Entry 222
+    (long long int)0x1.p10,
+    0x1.0p10
+  },
+  { // Entry 223
+    (long long int)0x1.p10,
+    0x1.0000000000001p10
+  },
+  { // Entry 224
+    (long long int)0x1.p11,
+    0x1.fffffffffffffp10
+  },
+  { // Entry 225
+    (long long int)0x1.p11,
+    0x1.0p11
+  },
+  { // Entry 226
+    (long long int)0x1.p11,
+    0x1.0000000000001p11
+  },
+  { // Entry 227
+    (long long int)0x1.p12,
+    0x1.fffffffffffffp11
+  },
+  { // Entry 228
+    (long long int)0x1.p12,
+    0x1.0p12
+  },
+  { // Entry 229
+    (long long int)0x1.p12,
+    0x1.0000000000001p12
+  },
+  { // Entry 230
+    (long long int)0x1.p2,
+    0x1.1ffffffffffffp2
+  },
+  { // Entry 231
+    (long long int)0x1.p2,
+    0x1.2p2
+  },
+  { // Entry 232
+    (long long int)0x1.40p2,
+    0x1.2000000000001p2
+  },
+  { // Entry 233
+    (long long int)0x1.p3,
+    0x1.0ffffffffffffp3
+  },
+  { // Entry 234
+    (long long int)0x1.p3,
+    0x1.1p3
+  },
+  { // Entry 235
+    (long long int)0x1.20p3,
+    0x1.1000000000001p3
+  },
+  { // Entry 236
+    (long long int)0x1.p4,
+    0x1.07fffffffffffp4
+  },
+  { // Entry 237
+    (long long int)0x1.p4,
+    0x1.080p4
+  },
+  { // Entry 238
+    (long long int)0x1.10p4,
+    0x1.0800000000001p4
+  },
+  { // Entry 239
+    (long long int)0x1.p5,
+    0x1.03fffffffffffp5
+  },
+  { // Entry 240
+    (long long int)0x1.p5,
+    0x1.040p5
+  },
+  { // Entry 241
+    (long long int)0x1.08p5,
+    0x1.0400000000001p5
+  },
+  { // Entry 242
+    (long long int)0x1.p6,
+    0x1.01fffffffffffp6
+  },
+  { // Entry 243
+    (long long int)0x1.p6,
+    0x1.020p6
+  },
+  { // Entry 244
+    (long long int)0x1.04p6,
+    0x1.0200000000001p6
+  },
+  { // Entry 245
+    (long long int)0x1.p7,
+    0x1.00fffffffffffp7
+  },
+  { // Entry 246
+    (long long int)0x1.p7,
+    0x1.010p7
+  },
+  { // Entry 247
+    (long long int)0x1.02p7,
+    0x1.0100000000001p7
+  },
+  { // Entry 248
+    (long long int)0x1.p8,
+    0x1.007ffffffffffp8
+  },
+  { // Entry 249
+    (long long int)0x1.p8,
+    0x1.008p8
+  },
+  { // Entry 250
+    (long long int)0x1.01p8,
+    0x1.0080000000001p8
+  },
+  { // Entry 251
+    (long long int)0x1.p9,
+    0x1.003ffffffffffp9
+  },
+  { // Entry 252
+    (long long int)0x1.p9,
+    0x1.004p9
+  },
+  { // Entry 253
+    (long long int)0x1.0080p9,
+    0x1.0040000000001p9
+  },
+  { // Entry 254
+    (long long int)0x1.p10,
+    0x1.001ffffffffffp10
+  },
+  { // Entry 255
+    (long long int)0x1.p10,
+    0x1.002p10
+  },
+  { // Entry 256
+    (long long int)0x1.0040p10,
+    0x1.0020000000001p10
+  },
+  { // Entry 257
+    (long long int)0x1.0040p10,
+    0x1.005ffffffffffp10
+  },
+  { // Entry 258
+    (long long int)0x1.0080p10,
+    0x1.006p10
+  },
+  { // Entry 259
+    (long long int)0x1.0080p10,
+    0x1.0060000000001p10
+  },
+  { // Entry 260
+    (long long int)0x1.p11,
+    0x1.000ffffffffffp11
+  },
+  { // Entry 261
+    (long long int)0x1.p11,
+    0x1.001p11
+  },
+  { // Entry 262
+    (long long int)0x1.0020p11,
+    0x1.0010000000001p11
+  },
+  { // Entry 263
+    (long long int)0x1.p12,
+    0x1.0007fffffffffp12
+  },
+  { // Entry 264
+    (long long int)0x1.p12,
+    0x1.00080p12
+  },
+  { // Entry 265
+    (long long int)0x1.0010p12,
+    0x1.0008000000001p12
+  },
+  { // Entry 266
+    (long long int)0x1.80p1,
+    0x1.921fb54442d18p1
+  },
+  { // Entry 267
+    (long long int)-0x1.80p1,
+    -0x1.921fb54442d18p1
+  },
+  { // Entry 268
+    (long long int)0x1.p1,
+    0x1.921fb54442d18p0
+  },
+  { // Entry 269
+    (long long int)-0x1.p1,
+    -0x1.921fb54442d18p0
+  },
+  { // Entry 270
+    (long long int)0x1.p0,
+    0x1.0000000000001p0
+  },
+  { // Entry 271
+    (long long int)-0x1.p0,
+    -0x1.0000000000001p0
+  },
+  { // Entry 272
+    (long long int)0x1.p0,
+    0x1.0p0
+  },
+  { // Entry 273
+    (long long int)-0x1.p0,
+    -0x1.0p0
+  },
+  { // Entry 274
+    (long long int)0x1.p0,
+    0x1.fffffffffffffp-1
+  },
+  { // Entry 275
+    (long long int)-0x1.p0,
+    -0x1.fffffffffffffp-1
+  },
+  { // Entry 276
+    (long long int)0x1.p0,
+    0x1.921fb54442d18p-1
+  },
+  { // Entry 277
+    (long long int)-0x1.p0,
+    -0x1.921fb54442d18p-1
+  },
+  { // Entry 278
+    (long long int)0.0,
+    0x1.0000000000001p-1022
+  },
+  { // Entry 279
+    (long long int)0.0,
+    -0x1.0000000000001p-1022
+  },
+  { // Entry 280
+    (long long int)0.0,
+    0x1.0p-1022
+  },
+  { // Entry 281
+    (long long int)0.0,
+    -0x1.0p-1022
+  },
+  { // Entry 282
+    (long long int)0.0,
+    0x1.ffffffffffffep-1023
+  },
+  { // Entry 283
+    (long long int)0.0,
+    -0x1.ffffffffffffep-1023
+  },
+  { // Entry 284
+    (long long int)0.0,
+    0x1.ffffffffffffcp-1023
+  },
+  { // Entry 285
+    (long long int)0.0,
+    -0x1.ffffffffffffcp-1023
+  },
+  { // Entry 286
+    (long long int)0.0,
+    0x1.0p-1073
+  },
+  { // Entry 287
+    (long long int)0.0,
+    -0x1.0p-1073
+  },
+  { // Entry 288
+    (long long int)0.0,
+    0x1.0p-1074
+  },
+  { // Entry 289
+    (long long int)0.0,
+    -0x1.0p-1074
+  },
+  { // Entry 290
+    (long long int)0.0,
+    0.0
+  },
+  { // Entry 291
+    (long long int)0.0,
+    -0.0
+  },
+  { // Entry 292
+    (long long int)0x1.p1,
+    0x1.8p0
+  },
+  { // Entry 293
+    (long long int)-0x1.p1,
+    -0x1.8p0
+  },
+  { // Entry 294
+    (long long int)0x1.p1,
+    0x1.4p1
+  },
+  { // Entry 295
+    (long long int)-0x1.p1,
+    -0x1.4p1
+  },
+  { // Entry 296
+    (long long int)0.0,
+    0x1.fffffp-2
+  },
+  { // Entry 297
+    (long long int)0.0,
+    0x1.0p-1
+  },
+  { // Entry 298
+    (long long int)0x1.p0,
+    0x1.00001p-1
+  },
+  { // Entry 299
+    (long long int)0.0,
+    -0x1.fffffp-2
+  },
+  { // Entry 300
+    (long long int)0.0,
+    -0x1.0p-1
+  },
+  { // Entry 301
+    (long long int)-0x1.p0,
+    -0x1.00001p-1
+  },
+  { // Entry 302
+    (long long int)0x1.p1,
+    0x1.80001p0
+  },
+  { // Entry 303
+    (long long int)0x1.p0,
+    0x1.7ffffp0
+  },
+  { // Entry 304
+    (long long int)-0x1.p1,
+    -0x1.80001p0
+  },
+  { // Entry 305
+    (long long int)-0x1.p0,
+    -0x1.7ffffp0
+  }
+};
\ No newline at end of file
diff --git a/tests/math_data/llrintf_intel_data.h b/tests/math_data/llrintf_intel_data.h
new file mode 100644
index 0000000..ecb22da
--- /dev/null
+++ b/tests/math_data/llrintf_intel_data.h
@@ -0,0 +1,1242 @@
+/*
+ * Copyright (C) 2016 The Android Open Source Project
+ *
+ * Licensed under the Apache License, Version 2.0 (the "License");
+ * you may not use this file except in compliance with the License.
+ * You may obtain a copy of the License at
+ *
+ *      http://www.apache.org/licenses/LICENSE-2.0
+ *
+ * Unless required by applicable law or agreed to in writing, software
+ * distributed under the License is distributed on an "AS IS" BASIS,
+ * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
+ * See the License for the specific language governing permissions and
+ * limitations under the License.
+ */
+
+static data_llong_1_t<float> g_llrintf_intel_data[] = {
+  { // Entry 0
+    (long long int)0.0,
+    -0x1.p-149
+  },
+  { // Entry 1
+    (long long int)0.0,
+    0.0
+  },
+  { // Entry 2
+    (long long int)0.0,
+    0x1.p-149
+  },
+  { // Entry 3
+    (long long int)0.0,
+    0x1.fffffep-2
+  },
+  { // Entry 4
+    (long long int)0.0,
+    0x1.p-1
+  },
+  { // Entry 5
+    (long long int)0x1.p0,
+    0x1.000002p-1
+  },
+  { // Entry 6
+    (long long int)0x1.p0,
+    0x1.fffffep-1
+  },
+  { // Entry 7
+    (long long int)0x1.p0,
+    0x1.p0
+  },
+  { // Entry 8
+    (long long int)0x1.p0,
+    0x1.000002p0
+  },
+  { // Entry 9
+    (long long int)0x1.p0,
+    0x1.7ffffep0
+  },
+  { // Entry 10
+    (long long int)0x1.p1,
+    0x1.80p0
+  },
+  { // Entry 11
+    (long long int)0x1.p1,
+    0x1.800002p0
+  },
+  { // Entry 12
+    (long long int)0x1.p1,
+    0x1.fffffep0
+  },
+  { // Entry 13
+    (long long int)0x1.p1,
+    0x1.p1
+  },
+  { // Entry 14
+    (long long int)0x1.p1,
+    0x1.000002p1
+  },
+  { // Entry 15
+    (long long int)0x1.p1,
+    0x1.3ffffep1
+  },
+  { // Entry 16
+    (long long int)0x1.p1,
+    0x1.40p1
+  },
+  { // Entry 17
+    (long long int)0x1.80p1,
+    0x1.400002p1
+  },
+  { // Entry 18
+    (long long int)0x1.90p6,
+    0x1.8ffffep6
+  },
+  { // Entry 19
+    (long long int)0x1.90p6,
+    0x1.90p6
+  },
+  { // Entry 20
+    (long long int)0x1.90p6,
+    0x1.900002p6
+  },
+  { // Entry 21
+    (long long int)0x1.90p6,
+    0x1.91fffep6
+  },
+  { // Entry 22
+    (long long int)0x1.90p6,
+    0x1.92p6
+  },
+  { // Entry 23
+    (long long int)0x1.94p6,
+    0x1.920002p6
+  },
+  { // Entry 24
+    (long long int)0x1.f4p9,
+    0x1.f3fffep9
+  },
+  { // Entry 25
+    (long long int)0x1.f4p9,
+    0x1.f4p9
+  },
+  { // Entry 26
+    (long long int)0x1.f4p9,
+    0x1.f40002p9
+  },
+  { // Entry 27
+    (long long int)0x1.f4p9,
+    0x1.f43ffep9
+  },
+  { // Entry 28
+    (long long int)0x1.f4p9,
+    0x1.f440p9
+  },
+  { // Entry 29
+    (long long int)0x1.f480p9,
+    0x1.f44002p9
+  },
+  { // Entry 30
+    (long long int)0x1.p21,
+    0x1.fffffep20
+  },
+  { // Entry 31
+    (long long int)0x1.p21,
+    0x1.p21
+  },
+  { // Entry 32
+    (long long int)0x1.p21,
+    0x1.000002p21
+  },
+  { // Entry 33
+    (long long int)0x1.p22,
+    0x1.fffffep21
+  },
+  { // Entry 34
+    (long long int)0x1.p22,
+    0x1.p22
+  },
+  { // Entry 35
+    (long long int)0x1.p22,
+    0x1.000002p22
+  },
+  { // Entry 36
+    (long long int)0x1.p23,
+    0x1.fffffep22
+  },
+  { // Entry 37
+    (long long int)0x1.p23,
+    0x1.p23
+  },
+  { // Entry 38
+    (long long int)0x1.000002p23,
+    0x1.000002p23
+  },
+  { // Entry 39
+    (long long int)0x1.fffffep23,
+    0x1.fffffep23
+  },
+  { // Entry 40
+    (long long int)0x1.p24,
+    0x1.p24
+  },
+  { // Entry 41
+    (long long int)0x1.000002p24,
+    0x1.000002p24
+  },
+  { // Entry 42
+    (long long int)0x1.fffffep24,
+    0x1.fffffep24
+  },
+  { // Entry 43
+    (long long int)0x1.p25,
+    0x1.p25
+  },
+  { // Entry 44
+    (long long int)0x1.000002p25,
+    0x1.000002p25
+  },
+  { // Entry 45
+    (long long int)-0x1.p0,
+    -0x1.000002p-1
+  },
+  { // Entry 46
+    (long long int)0.0,
+    -0x1.p-1
+  },
+  { // Entry 47
+    (long long int)0.0,
+    -0x1.fffffep-2
+  },
+  { // Entry 48
+    (long long int)-0x1.p0,
+    -0x1.000002p0
+  },
+  { // Entry 49
+    (long long int)-0x1.p0,
+    -0x1.p0
+  },
+  { // Entry 50
+    (long long int)-0x1.p0,
+    -0x1.fffffep-1
+  },
+  { // Entry 51
+    (long long int)-0x1.p1,
+    -0x1.800002p0
+  },
+  { // Entry 52
+    (long long int)-0x1.p1,
+    -0x1.80p0
+  },
+  { // Entry 53
+    (long long int)-0x1.p0,
+    -0x1.7ffffep0
+  },
+  { // Entry 54
+    (long long int)-0x1.p1,
+    -0x1.000002p1
+  },
+  { // Entry 55
+    (long long int)-0x1.p1,
+    -0x1.p1
+  },
+  { // Entry 56
+    (long long int)-0x1.p1,
+    -0x1.fffffep0
+  },
+  { // Entry 57
+    (long long int)-0x1.80p1,
+    -0x1.400002p1
+  },
+  { // Entry 58
+    (long long int)-0x1.p1,
+    -0x1.40p1
+  },
+  { // Entry 59
+    (long long int)-0x1.p1,
+    -0x1.3ffffep1
+  },
+  { // Entry 60
+    (long long int)-0x1.90p6,
+    -0x1.900002p6
+  },
+  { // Entry 61
+    (long long int)-0x1.90p6,
+    -0x1.90p6
+  },
+  { // Entry 62
+    (long long int)-0x1.90p6,
+    -0x1.8ffffep6
+  },
+  { // Entry 63
+    (long long int)-0x1.94p6,
+    -0x1.920002p6
+  },
+  { // Entry 64
+    (long long int)-0x1.90p6,
+    -0x1.92p6
+  },
+  { // Entry 65
+    (long long int)-0x1.90p6,
+    -0x1.91fffep6
+  },
+  { // Entry 66
+    (long long int)-0x1.f4p9,
+    -0x1.f40002p9
+  },
+  { // Entry 67
+    (long long int)-0x1.f4p9,
+    -0x1.f4p9
+  },
+  { // Entry 68
+    (long long int)-0x1.f4p9,
+    -0x1.f3fffep9
+  },
+  { // Entry 69
+    (long long int)-0x1.f480p9,
+    -0x1.f44002p9
+  },
+  { // Entry 70
+    (long long int)-0x1.f4p9,
+    -0x1.f440p9
+  },
+  { // Entry 71
+    (long long int)-0x1.f4p9,
+    -0x1.f43ffep9
+  },
+  { // Entry 72
+    (long long int)-0x1.p21,
+    -0x1.000002p21
+  },
+  { // Entry 73
+    (long long int)-0x1.p21,
+    -0x1.p21
+  },
+  { // Entry 74
+    (long long int)-0x1.p21,
+    -0x1.fffffep20
+  },
+  { // Entry 75
+    (long long int)-0x1.p22,
+    -0x1.000002p22
+  },
+  { // Entry 76
+    (long long int)-0x1.p22,
+    -0x1.p22
+  },
+  { // Entry 77
+    (long long int)-0x1.p22,
+    -0x1.fffffep21
+  },
+  { // Entry 78
+    (long long int)-0x1.000002p23,
+    -0x1.000002p23
+  },
+  { // Entry 79
+    (long long int)-0x1.p23,
+    -0x1.p23
+  },
+  { // Entry 80
+    (long long int)-0x1.p23,
+    -0x1.fffffep22
+  },
+  { // Entry 81
+    (long long int)-0x1.000002p24,
+    -0x1.000002p24
+  },
+  { // Entry 82
+    (long long int)-0x1.p24,
+    -0x1.p24
+  },
+  { // Entry 83
+    (long long int)-0x1.fffffep23,
+    -0x1.fffffep23
+  },
+  { // Entry 84
+    (long long int)-0x1.000002p25,
+    -0x1.000002p25
+  },
+  { // Entry 85
+    (long long int)-0x1.p25,
+    -0x1.p25
+  },
+  { // Entry 86
+    (long long int)-0x1.fffffep24,
+    -0x1.fffffep24
+  },
+  { // Entry 87
+    (long long int)0x1.fffffep29,
+    0x1.fffffep29
+  },
+  { // Entry 88
+    (long long int)0x1.p30,
+    0x1.p30
+  },
+  { // Entry 89
+    (long long int)0x1.000002p30,
+    0x1.000002p30
+  },
+  { // Entry 90
+    (long long int)0x1.fffffcp30,
+    0x1.fffffcp30
+  },
+  { // Entry 91
+    (long long int)0x1.fffffep30,
+    0x1.fffffep30
+  },
+  { // Entry 92
+    (long long int)0x1.p31,
+    0x1.p31
+  },
+  { // Entry 93
+    (long long int)0x1.000002p31,
+    0x1.000002p31
+  },
+  { // Entry 94
+    (long long int)0x1.000004p31,
+    0x1.000004p31
+  },
+  { // Entry 95
+    (long long int)0x1.fffffcp30,
+    0x1.fffffcp30
+  },
+  { // Entry 96
+    (long long int)0x1.fffffep30,
+    0x1.fffffep30
+  },
+  { // Entry 97
+    (long long int)0x1.p31,
+    0x1.p31
+  },
+  { // Entry 98
+    (long long int)0x1.000002p31,
+    0x1.000002p31
+  },
+  { // Entry 99
+    (long long int)0x1.000004p31,
+    0x1.000004p31
+  },
+  { // Entry 100
+    (long long int)0x1.fffffcp30,
+    0x1.fffffcp30
+  },
+  { // Entry 101
+    (long long int)0x1.fffffep30,
+    0x1.fffffep30
+  },
+  { // Entry 102
+    (long long int)0x1.p31,
+    0x1.p31
+  },
+  { // Entry 103
+    (long long int)0x1.000002p31,
+    0x1.000002p31
+  },
+  { // Entry 104
+    (long long int)0x1.000004p31,
+    0x1.000004p31
+  },
+  { // Entry 105
+    (long long int)0x1.fffffcp30,
+    0x1.fffffcp30
+  },
+  { // Entry 106
+    (long long int)0x1.fffffep30,
+    0x1.fffffep30
+  },
+  { // Entry 107
+    (long long int)0x1.p31,
+    0x1.p31
+  },
+  { // Entry 108
+    (long long int)0x1.000002p31,
+    0x1.000002p31
+  },
+  { // Entry 109
+    (long long int)0x1.000004p31,
+    0x1.000004p31
+  },
+  { // Entry 110
+    (long long int)0x1.fffffcp30,
+    0x1.fffffcp30
+  },
+  { // Entry 111
+    (long long int)0x1.fffffep30,
+    0x1.fffffep30
+  },
+  { // Entry 112
+    (long long int)0x1.p31,
+    0x1.p31
+  },
+  { // Entry 113
+    (long long int)0x1.000002p31,
+    0x1.000002p31
+  },
+  { // Entry 114
+    (long long int)0x1.000004p31,
+    0x1.000004p31
+  },
+  { // Entry 115
+    (long long int)0x1.fffffcp30,
+    0x1.fffffcp30
+  },
+  { // Entry 116
+    (long long int)0x1.fffffep30,
+    0x1.fffffep30
+  },
+  { // Entry 117
+    (long long int)0x1.p31,
+    0x1.p31
+  },
+  { // Entry 118
+    (long long int)0x1.000002p31,
+    0x1.000002p31
+  },
+  { // Entry 119
+    (long long int)0x1.000004p31,
+    0x1.000004p31
+  },
+  { // Entry 120
+    (long long int)0x1.p31,
+    0x1.p31
+  },
+  { // Entry 121
+    (long long int)0x1.p31,
+    0x1.p31
+  },
+  { // Entry 122
+    (long long int)0x1.p31,
+    0x1.p31
+  },
+  { // Entry 123
+    (long long int)0x1.p31,
+    0x1.p31
+  },
+  { // Entry 124
+    (long long int)0x1.p31,
+    0x1.p31
+  },
+  { // Entry 125
+    (long long int)0x1.p31,
+    0x1.p31
+  },
+  { // Entry 126
+    (long long int)0x1.p31,
+    0x1.p31
+  },
+  { // Entry 127
+    (long long int)0x1.p31,
+    0x1.p31
+  },
+  { // Entry 128
+    (long long int)0x1.p31,
+    0x1.p31
+  },
+  { // Entry 129
+    (long long int)0x1.p31,
+    0x1.p31
+  },
+  { // Entry 130
+    (long long int)-0x1.000002p30,
+    -0x1.000002p30
+  },
+  { // Entry 131
+    (long long int)-0x1.p30,
+    -0x1.p30
+  },
+  { // Entry 132
+    (long long int)-0x1.fffffep29,
+    -0x1.fffffep29
+  },
+  { // Entry 133
+    (long long int)-0x1.000004p31,
+    -0x1.000004p31
+  },
+  { // Entry 134
+    (long long int)-0x1.000002p31,
+    -0x1.000002p31
+  },
+  { // Entry 135
+    (long long int)-0x1.p31,
+    -0x1.p31
+  },
+  { // Entry 136
+    (long long int)-0x1.fffffep30,
+    -0x1.fffffep30
+  },
+  { // Entry 137
+    (long long int)-0x1.fffffcp30,
+    -0x1.fffffcp30
+  },
+  { // Entry 138
+    (long long int)-0x1.000004p31,
+    -0x1.000004p31
+  },
+  { // Entry 139
+    (long long int)-0x1.000002p31,
+    -0x1.000002p31
+  },
+  { // Entry 140
+    (long long int)-0x1.p31,
+    -0x1.p31
+  },
+  { // Entry 141
+    (long long int)-0x1.fffffep30,
+    -0x1.fffffep30
+  },
+  { // Entry 142
+    (long long int)-0x1.fffffcp30,
+    -0x1.fffffcp30
+  },
+  { // Entry 143
+    (long long int)-0x1.000004p31,
+    -0x1.000004p31
+  },
+  { // Entry 144
+    (long long int)-0x1.000002p31,
+    -0x1.000002p31
+  },
+  { // Entry 145
+    (long long int)-0x1.p31,
+    -0x1.p31
+  },
+  { // Entry 146
+    (long long int)-0x1.fffffep30,
+    -0x1.fffffep30
+  },
+  { // Entry 147
+    (long long int)-0x1.fffffcp30,
+    -0x1.fffffcp30
+  },
+  { // Entry 148
+    (long long int)-0x1.000004p31,
+    -0x1.000004p31
+  },
+  { // Entry 149
+    (long long int)-0x1.000002p31,
+    -0x1.000002p31
+  },
+  { // Entry 150
+    (long long int)-0x1.p31,
+    -0x1.p31
+  },
+  { // Entry 151
+    (long long int)-0x1.fffffep30,
+    -0x1.fffffep30
+  },
+  { // Entry 152
+    (long long int)-0x1.fffffcp30,
+    -0x1.fffffcp30
+  },
+  { // Entry 153
+    (long long int)-0x1.000004p31,
+    -0x1.000004p31
+  },
+  { // Entry 154
+    (long long int)-0x1.000002p31,
+    -0x1.000002p31
+  },
+  { // Entry 155
+    (long long int)-0x1.p31,
+    -0x1.p31
+  },
+  { // Entry 156
+    (long long int)-0x1.fffffep30,
+    -0x1.fffffep30
+  },
+  { // Entry 157
+    (long long int)-0x1.fffffcp30,
+    -0x1.fffffcp30
+  },
+  { // Entry 158
+    (long long int)-0x1.000004p31,
+    -0x1.000004p31
+  },
+  { // Entry 159
+    (long long int)-0x1.000002p31,
+    -0x1.000002p31
+  },
+  { // Entry 160
+    (long long int)-0x1.p31,
+    -0x1.p31
+  },
+  { // Entry 161
+    (long long int)-0x1.fffffep30,
+    -0x1.fffffep30
+  },
+  { // Entry 162
+    (long long int)-0x1.fffffcp30,
+    -0x1.fffffcp30
+  },
+  { // Entry 163
+    (long long int)-0x1.p31,
+    -0x1.p31
+  },
+  { // Entry 164
+    (long long int)-0x1.p31,
+    -0x1.p31
+  },
+  { // Entry 165
+    (long long int)-0x1.p31,
+    -0x1.p31
+  },
+  { // Entry 166
+    (long long int)-0x1.p31,
+    -0x1.p31
+  },
+  { // Entry 167
+    (long long int)-0x1.p31,
+    -0x1.p31
+  },
+  { // Entry 168
+    (long long int)-0x1.p31,
+    -0x1.p31
+  },
+  { // Entry 169
+    (long long int)-0x1.p31,
+    -0x1.p31
+  },
+  { // Entry 170
+    (long long int)-0x1.p31,
+    -0x1.p31
+  },
+  { // Entry 171
+    (long long int)-0x1.p31,
+    -0x1.p31
+  },
+  { // Entry 172
+    (long long int)-0x1.p31,
+    -0x1.p31
+  },
+  { // Entry 173
+    (long long int)0x1.fffffcp61,
+    0x1.fffffcp61
+  },
+  { // Entry 174
+    (long long int)0x1.fffffep61,
+    0x1.fffffep61
+  },
+  { // Entry 175
+    (long long int)0x1.p62,
+    0x1.p62
+  },
+  { // Entry 176
+    (long long int)0x1.000002p62,
+    0x1.000002p62
+  },
+  { // Entry 177
+    (long long int)0x1.000004p62,
+    0x1.000004p62
+  },
+  { // Entry 178
+    (long long int)0x1.fffffcp62,
+    0x1.fffffcp62
+  },
+  { // Entry 179
+    (long long int)0x1.fffffep62,
+    0x1.fffffep62
+  },
+  { // Entry 180
+    (long long int)-0x1.000004p62,
+    -0x1.000004p62
+  },
+  { // Entry 181
+    (long long int)-0x1.000002p62,
+    -0x1.000002p62
+  },
+  { // Entry 182
+    (long long int)-0x1.p62,
+    -0x1.p62
+  },
+  { // Entry 183
+    (long long int)-0x1.fffffep61,
+    -0x1.fffffep61
+  },
+  { // Entry 184
+    (long long int)-0x1.fffffcp61,
+    -0x1.fffffcp61
+  },
+  { // Entry 185
+    (long long int)-0x1.p63,
+    -0x1.p63
+  },
+  { // Entry 186
+    (long long int)-0x1.fffffep62,
+    -0x1.fffffep62
+  },
+  { // Entry 187
+    (long long int)-0x1.fffffcp62,
+    -0x1.fffffcp62
+  },
+  { // Entry 188
+    (long long int)0x1.p62,
+    0x1.p62
+  },
+  { // Entry 189
+    (long long int)-0x1.p62,
+    -0x1.p62
+  },
+  { // Entry 190
+    (long long int)-0x1.p63,
+    -0x1.p63
+  },
+  { // Entry 191
+    (long long int)0x1.fffffcp30,
+    0x1.fffffcp30
+  },
+  { // Entry 192
+    (long long int)0x1.fffffep30,
+    0x1.fffffep30
+  },
+  { // Entry 193
+    (long long int)0x1.p31,
+    0x1.p31
+  },
+  { // Entry 194
+    (long long int)-0x1.000002p31,
+    -0x1.000002p31
+  },
+  { // Entry 195
+    (long long int)-0x1.p31,
+    -0x1.p31
+  },
+  { // Entry 196
+    (long long int)-0x1.fffffep30,
+    -0x1.fffffep30
+  },
+  { // Entry 197
+    (long long int)0x1.p2,
+    0x1.fffffep1
+  },
+  { // Entry 198
+    (long long int)0x1.p2,
+    0x1.p2
+  },
+  { // Entry 199
+    (long long int)0x1.p2,
+    0x1.000002p2
+  },
+  { // Entry 200
+    (long long int)0x1.p3,
+    0x1.fffffep2
+  },
+  { // Entry 201
+    (long long int)0x1.p3,
+    0x1.p3
+  },
+  { // Entry 202
+    (long long int)0x1.p3,
+    0x1.000002p3
+  },
+  { // Entry 203
+    (long long int)0x1.p4,
+    0x1.fffffep3
+  },
+  { // Entry 204
+    (long long int)0x1.p4,
+    0x1.p4
+  },
+  { // Entry 205
+    (long long int)0x1.p4,
+    0x1.000002p4
+  },
+  { // Entry 206
+    (long long int)0x1.p5,
+    0x1.fffffep4
+  },
+  { // Entry 207
+    (long long int)0x1.p5,
+    0x1.p5
+  },
+  { // Entry 208
+    (long long int)0x1.p5,
+    0x1.000002p5
+  },
+  { // Entry 209
+    (long long int)0x1.p6,
+    0x1.fffffep5
+  },
+  { // Entry 210
+    (long long int)0x1.p6,
+    0x1.p6
+  },
+  { // Entry 211
+    (long long int)0x1.p6,
+    0x1.000002p6
+  },
+  { // Entry 212
+    (long long int)0x1.p7,
+    0x1.fffffep6
+  },
+  { // Entry 213
+    (long long int)0x1.p7,
+    0x1.p7
+  },
+  { // Entry 214
+    (long long int)0x1.p7,
+    0x1.000002p7
+  },
+  { // Entry 215
+    (long long int)0x1.p8,
+    0x1.fffffep7
+  },
+  { // Entry 216
+    (long long int)0x1.p8,
+    0x1.p8
+  },
+  { // Entry 217
+    (long long int)0x1.p8,
+    0x1.000002p8
+  },
+  { // Entry 218
+    (long long int)0x1.p9,
+    0x1.fffffep8
+  },
+  { // Entry 219
+    (long long int)0x1.p9,
+    0x1.p9
+  },
+  { // Entry 220
+    (long long int)0x1.p9,
+    0x1.000002p9
+  },
+  { // Entry 221
+    (long long int)0x1.p10,
+    0x1.fffffep9
+  },
+  { // Entry 222
+    (long long int)0x1.p10,
+    0x1.p10
+  },
+  { // Entry 223
+    (long long int)0x1.p10,
+    0x1.000002p10
+  },
+  { // Entry 224
+    (long long int)0x1.p11,
+    0x1.fffffep10
+  },
+  { // Entry 225
+    (long long int)0x1.p11,
+    0x1.p11
+  },
+  { // Entry 226
+    (long long int)0x1.p11,
+    0x1.000002p11
+  },
+  { // Entry 227
+    (long long int)0x1.p12,
+    0x1.fffffep11
+  },
+  { // Entry 228
+    (long long int)0x1.p12,
+    0x1.p12
+  },
+  { // Entry 229
+    (long long int)0x1.p12,
+    0x1.000002p12
+  },
+  { // Entry 230
+    (long long int)0x1.p2,
+    0x1.1ffffep2
+  },
+  { // Entry 231
+    (long long int)0x1.p2,
+    0x1.20p2
+  },
+  { // Entry 232
+    (long long int)0x1.40p2,
+    0x1.200002p2
+  },
+  { // Entry 233
+    (long long int)0x1.p3,
+    0x1.0ffffep3
+  },
+  { // Entry 234
+    (long long int)0x1.p3,
+    0x1.10p3
+  },
+  { // Entry 235
+    (long long int)0x1.20p3,
+    0x1.100002p3
+  },
+  { // Entry 236
+    (long long int)0x1.p4,
+    0x1.07fffep4
+  },
+  { // Entry 237
+    (long long int)0x1.p4,
+    0x1.08p4
+  },
+  { // Entry 238
+    (long long int)0x1.10p4,
+    0x1.080002p4
+  },
+  { // Entry 239
+    (long long int)0x1.p5,
+    0x1.03fffep5
+  },
+  { // Entry 240
+    (long long int)0x1.p5,
+    0x1.04p5
+  },
+  { // Entry 241
+    (long long int)0x1.08p5,
+    0x1.040002p5
+  },
+  { // Entry 242
+    (long long int)0x1.p6,
+    0x1.01fffep6
+  },
+  { // Entry 243
+    (long long int)0x1.p6,
+    0x1.02p6
+  },
+  { // Entry 244
+    (long long int)0x1.04p6,
+    0x1.020002p6
+  },
+  { // Entry 245
+    (long long int)0x1.p7,
+    0x1.00fffep7
+  },
+  { // Entry 246
+    (long long int)0x1.p7,
+    0x1.01p7
+  },
+  { // Entry 247
+    (long long int)0x1.02p7,
+    0x1.010002p7
+  },
+  { // Entry 248
+    (long long int)0x1.p8,
+    0x1.007ffep8
+  },
+  { // Entry 249
+    (long long int)0x1.p8,
+    0x1.0080p8
+  },
+  { // Entry 250
+    (long long int)0x1.01p8,
+    0x1.008002p8
+  },
+  { // Entry 251
+    (long long int)0x1.p9,
+    0x1.003ffep9
+  },
+  { // Entry 252
+    (long long int)0x1.p9,
+    0x1.0040p9
+  },
+  { // Entry 253
+    (long long int)0x1.0080p9,
+    0x1.004002p9
+  },
+  { // Entry 254
+    (long long int)0x1.p10,
+    0x1.001ffep10
+  },
+  { // Entry 255
+    (long long int)0x1.p10,
+    0x1.0020p10
+  },
+  { // Entry 256
+    (long long int)0x1.0040p10,
+    0x1.002002p10
+  },
+  { // Entry 257
+    (long long int)0x1.0040p10,
+    0x1.005ffep10
+  },
+  { // Entry 258
+    (long long int)0x1.0080p10,
+    0x1.0060p10
+  },
+  { // Entry 259
+    (long long int)0x1.0080p10,
+    0x1.006002p10
+  },
+  { // Entry 260
+    (long long int)0x1.p11,
+    0x1.000ffep11
+  },
+  { // Entry 261
+    (long long int)0x1.p11,
+    0x1.0010p11
+  },
+  { // Entry 262
+    (long long int)0x1.0020p11,
+    0x1.001002p11
+  },
+  { // Entry 263
+    (long long int)0x1.p12,
+    0x1.0007fep12
+  },
+  { // Entry 264
+    (long long int)0x1.p12,
+    0x1.0008p12
+  },
+  { // Entry 265
+    (long long int)0x1.0010p12,
+    0x1.000802p12
+  },
+  { // Entry 266
+    (long long int)0x1.80p1,
+    0x1.921fb6p1
+  },
+  { // Entry 267
+    (long long int)-0x1.80p1,
+    -0x1.921fb6p1
+  },
+  { // Entry 268
+    (long long int)0x1.p1,
+    0x1.921fb6p0
+  },
+  { // Entry 269
+    (long long int)-0x1.p1,
+    -0x1.921fb6p0
+  },
+  { // Entry 270
+    (long long int)0x1.p0,
+    0x1.000002p0
+  },
+  { // Entry 271
+    (long long int)-0x1.p0,
+    -0x1.000002p0
+  },
+  { // Entry 272
+    (long long int)0x1.p0,
+    0x1.p0
+  },
+  { // Entry 273
+    (long long int)-0x1.p0,
+    -0x1.p0
+  },
+  { // Entry 274
+    (long long int)0x1.p0,
+    0x1.fffffep-1
+  },
+  { // Entry 275
+    (long long int)-0x1.p0,
+    -0x1.fffffep-1
+  },
+  { // Entry 276
+    (long long int)0x1.p0,
+    0x1.921fb6p-1
+  },
+  { // Entry 277
+    (long long int)-0x1.p0,
+    -0x1.921fb6p-1
+  },
+  { // Entry 278
+    (long long int)0.0,
+    0x1.000002p-126
+  },
+  { // Entry 279
+    (long long int)0.0,
+    -0x1.000002p-126
+  },
+  { // Entry 280
+    (long long int)0.0,
+    0x1.p-126
+  },
+  { // Entry 281
+    (long long int)0.0,
+    -0x1.p-126
+  },
+  { // Entry 282
+    (long long int)0.0,
+    0x1.fffffcp-127
+  },
+  { // Entry 283
+    (long long int)0.0,
+    -0x1.fffffcp-127
+  },
+  { // Entry 284
+    (long long int)0.0,
+    0x1.fffff8p-127
+  },
+  { // Entry 285
+    (long long int)0.0,
+    -0x1.fffff8p-127
+  },
+  { // Entry 286
+    (long long int)0.0,
+    0x1.p-148
+  },
+  { // Entry 287
+    (long long int)0.0,
+    -0x1.p-148
+  },
+  { // Entry 288
+    (long long int)0.0,
+    0x1.p-149
+  },
+  { // Entry 289
+    (long long int)0.0,
+    -0x1.p-149
+  },
+  { // Entry 290
+    (long long int)0.0,
+    0.0f
+  },
+  { // Entry 291
+    (long long int)0.0,
+    -0.0f
+  },
+  { // Entry 292
+    (long long int)0x1.p1,
+    0x1.80p0
+  },
+  { // Entry 293
+    (long long int)-0x1.p1,
+    -0x1.80p0
+  },
+  { // Entry 294
+    (long long int)0x1.p1,
+    0x1.40p1
+  },
+  { // Entry 295
+    (long long int)-0x1.p1,
+    -0x1.40p1
+  },
+  { // Entry 296
+    (long long int)0.0,
+    0x1.fffff0p-2
+  },
+  { // Entry 297
+    (long long int)0.0,
+    0x1.p-1
+  },
+  { // Entry 298
+    (long long int)0x1.p0,
+    0x1.000010p-1
+  },
+  { // Entry 299
+    (long long int)0.0,
+    -0x1.fffff0p-2
+  },
+  { // Entry 300
+    (long long int)0.0,
+    -0x1.p-1
+  },
+  { // Entry 301
+    (long long int)-0x1.p0,
+    -0x1.000010p-1
+  },
+  { // Entry 302
+    (long long int)0x1.p1,
+    0x1.800010p0
+  },
+  { // Entry 303
+    (long long int)0x1.p0,
+    0x1.7ffff0p0
+  },
+  { // Entry 304
+    (long long int)-0x1.p1,
+    -0x1.800010p0
+  },
+  { // Entry 305
+    (long long int)-0x1.p0,
+    -0x1.7ffff0p0
+  }
+};
\ No newline at end of file
diff --git a/tests/math_data/lrint_intel_data.h b/tests/math_data/lrint_intel_data.h
new file mode 100644
index 0000000..a034be4
--- /dev/null
+++ b/tests/math_data/lrint_intel_data.h
@@ -0,0 +1,982 @@
+/*
+ * Copyright (C) 2016 The Android Open Source Project
+ *
+ * Licensed under the Apache License, Version 2.0 (the "License");
+ * you may not use this file except in compliance with the License.
+ * You may obtain a copy of the License at
+ *
+ *      http://www.apache.org/licenses/LICENSE-2.0
+ *
+ * Unless required by applicable law or agreed to in writing, software
+ * distributed under the License is distributed on an "AS IS" BASIS,
+ * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
+ * See the License for the specific language governing permissions and
+ * limitations under the License.
+ */
+
+static data_long_1_t<double> g_lrint_intel_data[] = {
+  { // Entry 0
+    (long int)0.0,
+    -0x1.0p-1074
+  },
+  { // Entry 1
+    (long int)0.0,
+    -0.0
+  },
+  { // Entry 2
+    (long int)0.0,
+    0x1.0p-1074
+  },
+  { // Entry 3
+    (long int)0.0,
+    0x1.fffffffffffffp-2
+  },
+  { // Entry 4
+    (long int)0.0,
+    0x1.0p-1
+  },
+  { // Entry 5
+    (long int)0x1.p0,
+    0x1.0000000000001p-1
+  },
+  { // Entry 6
+    (long int)0x1.p0,
+    0x1.fffffffffffffp-1
+  },
+  { // Entry 7
+    (long int)0x1.p0,
+    0x1.0p0
+  },
+  { // Entry 8
+    (long int)0x1.p0,
+    0x1.0000000000001p0
+  },
+  { // Entry 9
+    (long int)0x1.p0,
+    0x1.7ffffffffffffp0
+  },
+  { // Entry 10
+    (long int)0x1.p1,
+    0x1.8p0
+  },
+  { // Entry 11
+    (long int)0x1.p1,
+    0x1.8000000000001p0
+  },
+  { // Entry 12
+    (long int)0x1.p1,
+    0x1.fffffffffffffp0
+  },
+  { // Entry 13
+    (long int)0x1.p1,
+    0x1.0p1
+  },
+  { // Entry 14
+    (long int)0x1.p1,
+    0x1.0000000000001p1
+  },
+  { // Entry 15
+    (long int)0x1.p1,
+    0x1.3ffffffffffffp1
+  },
+  { // Entry 16
+    (long int)0x1.p1,
+    0x1.4p1
+  },
+  { // Entry 17
+    (long int)0x1.80p1,
+    0x1.4000000000001p1
+  },
+  { // Entry 18
+    (long int)0x1.90p6,
+    0x1.8ffffffffffffp6
+  },
+  { // Entry 19
+    (long int)0x1.90p6,
+    0x1.9p6
+  },
+  { // Entry 20
+    (long int)0x1.90p6,
+    0x1.9000000000001p6
+  },
+  { // Entry 21
+    (long int)0x1.90p6,
+    0x1.91fffffffffffp6
+  },
+  { // Entry 22
+    (long int)0x1.90p6,
+    0x1.920p6
+  },
+  { // Entry 23
+    (long int)0x1.94p6,
+    0x1.9200000000001p6
+  },
+  { // Entry 24
+    (long int)0x1.f4p9,
+    0x1.f3fffffffffffp9
+  },
+  { // Entry 25
+    (long int)0x1.f4p9,
+    0x1.f40p9
+  },
+  { // Entry 26
+    (long int)0x1.f4p9,
+    0x1.f400000000001p9
+  },
+  { // Entry 27
+    (long int)0x1.f4p9,
+    0x1.f43ffffffffffp9
+  },
+  { // Entry 28
+    (long int)0x1.f4p9,
+    0x1.f44p9
+  },
+  { // Entry 29
+    (long int)0x1.f480p9,
+    0x1.f440000000001p9
+  },
+  { // Entry 30
+    (long int)-0x1.p0,
+    -0x1.0000000000001p-1
+  },
+  { // Entry 31
+    (long int)0.0,
+    -0x1.0p-1
+  },
+  { // Entry 32
+    (long int)0.0,
+    -0x1.fffffffffffffp-2
+  },
+  { // Entry 33
+    (long int)-0x1.p0,
+    -0x1.0000000000001p0
+  },
+  { // Entry 34
+    (long int)-0x1.p0,
+    -0x1.0p0
+  },
+  { // Entry 35
+    (long int)-0x1.p0,
+    -0x1.fffffffffffffp-1
+  },
+  { // Entry 36
+    (long int)-0x1.p1,
+    -0x1.8000000000001p0
+  },
+  { // Entry 37
+    (long int)-0x1.p1,
+    -0x1.8p0
+  },
+  { // Entry 38
+    (long int)-0x1.p0,
+    -0x1.7ffffffffffffp0
+  },
+  { // Entry 39
+    (long int)-0x1.p1,
+    -0x1.0000000000001p1
+  },
+  { // Entry 40
+    (long int)-0x1.p1,
+    -0x1.0p1
+  },
+  { // Entry 41
+    (long int)-0x1.p1,
+    -0x1.fffffffffffffp0
+  },
+  { // Entry 42
+    (long int)-0x1.80p1,
+    -0x1.4000000000001p1
+  },
+  { // Entry 43
+    (long int)-0x1.p1,
+    -0x1.4p1
+  },
+  { // Entry 44
+    (long int)-0x1.p1,
+    -0x1.3ffffffffffffp1
+  },
+  { // Entry 45
+    (long int)-0x1.90p6,
+    -0x1.9000000000001p6
+  },
+  { // Entry 46
+    (long int)-0x1.90p6,
+    -0x1.9p6
+  },
+  { // Entry 47
+    (long int)-0x1.90p6,
+    -0x1.8ffffffffffffp6
+  },
+  { // Entry 48
+    (long int)-0x1.94p6,
+    -0x1.9200000000001p6
+  },
+  { // Entry 49
+    (long int)-0x1.90p6,
+    -0x1.920p6
+  },
+  { // Entry 50
+    (long int)-0x1.90p6,
+    -0x1.91fffffffffffp6
+  },
+  { // Entry 51
+    (long int)-0x1.f4p9,
+    -0x1.f400000000001p9
+  },
+  { // Entry 52
+    (long int)-0x1.f4p9,
+    -0x1.f40p9
+  },
+  { // Entry 53
+    (long int)-0x1.f4p9,
+    -0x1.f3fffffffffffp9
+  },
+  { // Entry 54
+    (long int)-0x1.f480p9,
+    -0x1.f440000000001p9
+  },
+  { // Entry 55
+    (long int)-0x1.f4p9,
+    -0x1.f44p9
+  },
+  { // Entry 56
+    (long int)-0x1.f4p9,
+    -0x1.f43ffffffffffp9
+  },
+  { // Entry 57
+    (long int)0x1.p30,
+    0x1.fffffffffffffp29
+  },
+  { // Entry 58
+    (long int)0x1.p30,
+    0x1.0p30
+  },
+  { // Entry 59
+    (long int)0x1.p30,
+    0x1.0000000000001p30
+  },
+  { // Entry 60
+    (long int)0x1.fffffff8p30,
+    0x1.fffffff7ffffep30
+  },
+  { // Entry 61
+    (long int)0x1.fffffff8p30,
+    0x1.fffffff7fffffp30
+  },
+  { // Entry 62
+    (long int)0x1.fffffff8p30,
+    0x1.fffffff80p30
+  },
+  { // Entry 63
+    (long int)0x1.fffffff8p30,
+    0x1.fffffff800001p30
+  },
+  { // Entry 64
+    (long int)0x1.fffffff8p30,
+    0x1.fffffff800002p30
+  },
+  { // Entry 65
+    (long int)0x1.fffffff8p30,
+    0x1.fffffff9ffffep30
+  },
+  { // Entry 66
+    (long int)0x1.fffffff8p30,
+    0x1.fffffff9fffffp30
+  },
+  { // Entry 67
+    (long int)0x1.fffffff8p30,
+    0x1.fffffffa0p30
+  },
+  { // Entry 68
+    (long int)0x1.fffffffcp30,
+    0x1.fffffffa00001p30
+  },
+  { // Entry 69
+    (long int)0x1.fffffffcp30,
+    0x1.fffffffa00002p30
+  },
+  { // Entry 70
+    (long int)0x1.fffffffcp30,
+    0x1.fffffffbffffep30
+  },
+  { // Entry 71
+    (long int)0x1.fffffffcp30,
+    0x1.fffffffbfffffp30
+  },
+  { // Entry 72
+    (long int)0x1.fffffffcp30,
+    0x1.fffffffc0p30
+  },
+  { // Entry 73
+    (long int)0x1.fffffffcp30,
+    0x1.fffffffc00001p30
+  },
+  { // Entry 74
+    (long int)0x1.fffffffcp30,
+    0x1.fffffffc00002p30
+  },
+  { // Entry 75
+    (long int)0x1.fffffffcp30,
+    0x1.fffffffdffffep30
+  },
+  { // Entry 76
+    (long int)0x1.fffffffcp30,
+    0x1.fffffffdfffffp30
+  },
+  { // Entry 77
+    (long int)0x1.ffffffe0p30,
+    0x1.ffffffep30
+  },
+  { // Entry 78
+    (long int)0x1.ffffffe4p30,
+    0x1.ffffffe40p30
+  },
+  { // Entry 79
+    (long int)0x1.ffffffe8p30,
+    0x1.ffffffe80p30
+  },
+  { // Entry 80
+    (long int)0x1.ffffffecp30,
+    0x1.ffffffec0p30
+  },
+  { // Entry 81
+    (long int)0x1.fffffff0p30,
+    0x1.fffffffp30
+  },
+  { // Entry 82
+    (long int)0x1.fffffff4p30,
+    0x1.fffffff40p30
+  },
+  { // Entry 83
+    (long int)0x1.fffffff8p30,
+    0x1.fffffff80p30
+  },
+  { // Entry 84
+    (long int)0x1.fffffffcp30,
+    0x1.fffffffc0p30
+  },
+  { // Entry 85
+    (long int)-0x1.p30,
+    -0x1.0000000000001p30
+  },
+  { // Entry 86
+    (long int)-0x1.p30,
+    -0x1.0p30
+  },
+  { // Entry 87
+    (long int)-0x1.p30,
+    -0x1.fffffffffffffp29
+  },
+  { // Entry 88
+    (long int)-0x1.fffffff8p30,
+    -0x1.fffffff800002p30
+  },
+  { // Entry 89
+    (long int)-0x1.fffffff8p30,
+    -0x1.fffffff800001p30
+  },
+  { // Entry 90
+    (long int)-0x1.fffffff8p30,
+    -0x1.fffffff80p30
+  },
+  { // Entry 91
+    (long int)-0x1.fffffff8p30,
+    -0x1.fffffff7fffffp30
+  },
+  { // Entry 92
+    (long int)-0x1.fffffff8p30,
+    -0x1.fffffff7ffffep30
+  },
+  { // Entry 93
+    (long int)-0x1.fffffffcp30,
+    -0x1.fffffffa00002p30
+  },
+  { // Entry 94
+    (long int)-0x1.fffffffcp30,
+    -0x1.fffffffa00001p30
+  },
+  { // Entry 95
+    (long int)-0x1.fffffff8p30,
+    -0x1.fffffffa0p30
+  },
+  { // Entry 96
+    (long int)-0x1.fffffff8p30,
+    -0x1.fffffff9fffffp30
+  },
+  { // Entry 97
+    (long int)-0x1.fffffff8p30,
+    -0x1.fffffff9ffffep30
+  },
+  { // Entry 98
+    (long int)-0x1.fffffffcp30,
+    -0x1.fffffffc00002p30
+  },
+  { // Entry 99
+    (long int)-0x1.fffffffcp30,
+    -0x1.fffffffc00001p30
+  },
+  { // Entry 100
+    (long int)-0x1.fffffffcp30,
+    -0x1.fffffffc0p30
+  },
+  { // Entry 101
+    (long int)-0x1.fffffffcp30,
+    -0x1.fffffffbfffffp30
+  },
+  { // Entry 102
+    (long int)-0x1.fffffffcp30,
+    -0x1.fffffffbffffep30
+  },
+  { // Entry 103
+    (long int)-0x1.p31,
+    -0x1.fffffffe00002p30
+  },
+  { // Entry 104
+    (long int)-0x1.p31,
+    -0x1.fffffffe00001p30
+  },
+  { // Entry 105
+    (long int)-0x1.p31,
+    -0x1.fffffffe0p30
+  },
+  { // Entry 106
+    (long int)-0x1.fffffffcp30,
+    -0x1.fffffffdfffffp30
+  },
+  { // Entry 107
+    (long int)-0x1.fffffffcp30,
+    -0x1.fffffffdffffep30
+  },
+  { // Entry 108
+    (long int)-0x1.p31,
+    -0x1.0000000000002p31
+  },
+  { // Entry 109
+    (long int)-0x1.p31,
+    -0x1.0000000000001p31
+  },
+  { // Entry 110
+    (long int)-0x1.p31,
+    -0x1.0p31
+  },
+  { // Entry 111
+    (long int)-0x1.p31,
+    -0x1.fffffffffffffp30
+  },
+  { // Entry 112
+    (long int)-0x1.p31,
+    -0x1.ffffffffffffep30
+  },
+  { // Entry 113
+    (long int)-0x1.p31,
+    -0x1.000000010p31
+  },
+  { // Entry 114
+    (long int)-0x1.p31,
+    -0x1.00000000fffffp31
+  },
+  { // Entry 115
+    (long int)-0x1.p31,
+    -0x1.00000000ffffep31
+  },
+  { // Entry 116
+    (long int)-0x1.ffffffe0p30,
+    -0x1.ffffffep30
+  },
+  { // Entry 117
+    (long int)-0x1.ffffffe0p30,
+    -0x1.ffffffep30
+  },
+  { // Entry 118
+    (long int)-0x1.ffffffe0p30,
+    -0x1.ffffffep30
+  },
+  { // Entry 119
+    (long int)-0x1.ffffffe0p30,
+    -0x1.ffffffep30
+  },
+  { // Entry 120
+    (long int)-0x1.ffffffe0p30,
+    -0x1.ffffffep30
+  },
+  { // Entry 121
+    (long int)-0x1.ffffffe0p30,
+    -0x1.ffffffep30
+  },
+  { // Entry 122
+    (long int)-0x1.ffffffe0p30,
+    -0x1.ffffffep30
+  },
+  { // Entry 123
+    (long int)-0x1.ffffffe0p30,
+    -0x1.ffffffep30
+  },
+  { // Entry 124
+    (long int)-0x1.ffffffe0p30,
+    -0x1.ffffffep30
+  },
+  { // Entry 125
+    (long int)-0x1.ffffffe0p30,
+    -0x1.ffffffep30
+  },
+  { // Entry 126
+    (long int)0x1.fffffffcp30,
+    0x1.fffffffbfffffp30
+  },
+  { // Entry 127
+    (long int)0x1.fffffffcp30,
+    0x1.fffffffc0p30
+  },
+  { // Entry 128
+    (long int)0x1.fffffffcp30,
+    0x1.fffffffc00001p30
+  },
+  { // Entry 129
+    (long int)-0x1.p31,
+    -0x1.0000000000001p31
+  },
+  { // Entry 130
+    (long int)-0x1.p31,
+    -0x1.0p31
+  },
+  { // Entry 131
+    (long int)-0x1.p31,
+    -0x1.fffffffffffffp30
+  },
+  { // Entry 132
+    (long int)0x1.p2,
+    0x1.fffffffffffffp1
+  },
+  { // Entry 133
+    (long int)0x1.p2,
+    0x1.0p2
+  },
+  { // Entry 134
+    (long int)0x1.p2,
+    0x1.0000000000001p2
+  },
+  { // Entry 135
+    (long int)0x1.p3,
+    0x1.fffffffffffffp2
+  },
+  { // Entry 136
+    (long int)0x1.p3,
+    0x1.0p3
+  },
+  { // Entry 137
+    (long int)0x1.p3,
+    0x1.0000000000001p3
+  },
+  { // Entry 138
+    (long int)0x1.p4,
+    0x1.fffffffffffffp3
+  },
+  { // Entry 139
+    (long int)0x1.p4,
+    0x1.0p4
+  },
+  { // Entry 140
+    (long int)0x1.p4,
+    0x1.0000000000001p4
+  },
+  { // Entry 141
+    (long int)0x1.p5,
+    0x1.fffffffffffffp4
+  },
+  { // Entry 142
+    (long int)0x1.p5,
+    0x1.0p5
+  },
+  { // Entry 143
+    (long int)0x1.p5,
+    0x1.0000000000001p5
+  },
+  { // Entry 144
+    (long int)0x1.p6,
+    0x1.fffffffffffffp5
+  },
+  { // Entry 145
+    (long int)0x1.p6,
+    0x1.0p6
+  },
+  { // Entry 146
+    (long int)0x1.p6,
+    0x1.0000000000001p6
+  },
+  { // Entry 147
+    (long int)0x1.p7,
+    0x1.fffffffffffffp6
+  },
+  { // Entry 148
+    (long int)0x1.p7,
+    0x1.0p7
+  },
+  { // Entry 149
+    (long int)0x1.p7,
+    0x1.0000000000001p7
+  },
+  { // Entry 150
+    (long int)0x1.p8,
+    0x1.fffffffffffffp7
+  },
+  { // Entry 151
+    (long int)0x1.p8,
+    0x1.0p8
+  },
+  { // Entry 152
+    (long int)0x1.p8,
+    0x1.0000000000001p8
+  },
+  { // Entry 153
+    (long int)0x1.p9,
+    0x1.fffffffffffffp8
+  },
+  { // Entry 154
+    (long int)0x1.p9,
+    0x1.0p9
+  },
+  { // Entry 155
+    (long int)0x1.p9,
+    0x1.0000000000001p9
+  },
+  { // Entry 156
+    (long int)0x1.p10,
+    0x1.fffffffffffffp9
+  },
+  { // Entry 157
+    (long int)0x1.p10,
+    0x1.0p10
+  },
+  { // Entry 158
+    (long int)0x1.p10,
+    0x1.0000000000001p10
+  },
+  { // Entry 159
+    (long int)0x1.p11,
+    0x1.fffffffffffffp10
+  },
+  { // Entry 160
+    (long int)0x1.p11,
+    0x1.0p11
+  },
+  { // Entry 161
+    (long int)0x1.p11,
+    0x1.0000000000001p11
+  },
+  { // Entry 162
+    (long int)0x1.p12,
+    0x1.fffffffffffffp11
+  },
+  { // Entry 163
+    (long int)0x1.p12,
+    0x1.0p12
+  },
+  { // Entry 164
+    (long int)0x1.p12,
+    0x1.0000000000001p12
+  },
+  { // Entry 165
+    (long int)0x1.p2,
+    0x1.1ffffffffffffp2
+  },
+  { // Entry 166
+    (long int)0x1.p2,
+    0x1.2p2
+  },
+  { // Entry 167
+    (long int)0x1.40p2,
+    0x1.2000000000001p2
+  },
+  { // Entry 168
+    (long int)0x1.p3,
+    0x1.0ffffffffffffp3
+  },
+  { // Entry 169
+    (long int)0x1.p3,
+    0x1.1p3
+  },
+  { // Entry 170
+    (long int)0x1.20p3,
+    0x1.1000000000001p3
+  },
+  { // Entry 171
+    (long int)0x1.p4,
+    0x1.07fffffffffffp4
+  },
+  { // Entry 172
+    (long int)0x1.p4,
+    0x1.080p4
+  },
+  { // Entry 173
+    (long int)0x1.10p4,
+    0x1.0800000000001p4
+  },
+  { // Entry 174
+    (long int)0x1.p5,
+    0x1.03fffffffffffp5
+  },
+  { // Entry 175
+    (long int)0x1.p5,
+    0x1.040p5
+  },
+  { // Entry 176
+    (long int)0x1.08p5,
+    0x1.0400000000001p5
+  },
+  { // Entry 177
+    (long int)0x1.p6,
+    0x1.01fffffffffffp6
+  },
+  { // Entry 178
+    (long int)0x1.p6,
+    0x1.020p6
+  },
+  { // Entry 179
+    (long int)0x1.04p6,
+    0x1.0200000000001p6
+  },
+  { // Entry 180
+    (long int)0x1.p7,
+    0x1.00fffffffffffp7
+  },
+  { // Entry 181
+    (long int)0x1.p7,
+    0x1.010p7
+  },
+  { // Entry 182
+    (long int)0x1.02p7,
+    0x1.0100000000001p7
+  },
+  { // Entry 183
+    (long int)0x1.p8,
+    0x1.007ffffffffffp8
+  },
+  { // Entry 184
+    (long int)0x1.p8,
+    0x1.008p8
+  },
+  { // Entry 185
+    (long int)0x1.01p8,
+    0x1.0080000000001p8
+  },
+  { // Entry 186
+    (long int)0x1.p9,
+    0x1.003ffffffffffp9
+  },
+  { // Entry 187
+    (long int)0x1.p9,
+    0x1.004p9
+  },
+  { // Entry 188
+    (long int)0x1.0080p9,
+    0x1.0040000000001p9
+  },
+  { // Entry 189
+    (long int)0x1.p10,
+    0x1.001ffffffffffp10
+  },
+  { // Entry 190
+    (long int)0x1.p10,
+    0x1.002p10
+  },
+  { // Entry 191
+    (long int)0x1.0040p10,
+    0x1.0020000000001p10
+  },
+  { // Entry 192
+    (long int)0x1.0040p10,
+    0x1.005ffffffffffp10
+  },
+  { // Entry 193
+    (long int)0x1.0080p10,
+    0x1.006p10
+  },
+  { // Entry 194
+    (long int)0x1.0080p10,
+    0x1.0060000000001p10
+  },
+  { // Entry 195
+    (long int)0x1.p11,
+    0x1.000ffffffffffp11
+  },
+  { // Entry 196
+    (long int)0x1.p11,
+    0x1.001p11
+  },
+  { // Entry 197
+    (long int)0x1.0020p11,
+    0x1.0010000000001p11
+  },
+  { // Entry 198
+    (long int)0x1.p12,
+    0x1.0007fffffffffp12
+  },
+  { // Entry 199
+    (long int)0x1.p12,
+    0x1.00080p12
+  },
+  { // Entry 200
+    (long int)0x1.0010p12,
+    0x1.0008000000001p12
+  },
+  { // Entry 201
+    (long int)0x1.80p1,
+    0x1.921fb54442d18p1
+  },
+  { // Entry 202
+    (long int)-0x1.80p1,
+    -0x1.921fb54442d18p1
+  },
+  { // Entry 203
+    (long int)0x1.p1,
+    0x1.921fb54442d18p0
+  },
+  { // Entry 204
+    (long int)-0x1.p1,
+    -0x1.921fb54442d18p0
+  },
+  { // Entry 205
+    (long int)0x1.p0,
+    0x1.0000000000001p0
+  },
+  { // Entry 206
+    (long int)-0x1.p0,
+    -0x1.0000000000001p0
+  },
+  { // Entry 207
+    (long int)0x1.p0,
+    0x1.0p0
+  },
+  { // Entry 208
+    (long int)-0x1.p0,
+    -0x1.0p0
+  },
+  { // Entry 209
+    (long int)0x1.p0,
+    0x1.fffffffffffffp-1
+  },
+  { // Entry 210
+    (long int)-0x1.p0,
+    -0x1.fffffffffffffp-1
+  },
+  { // Entry 211
+    (long int)0x1.p0,
+    0x1.921fb54442d18p-1
+  },
+  { // Entry 212
+    (long int)-0x1.p0,
+    -0x1.921fb54442d18p-1
+  },
+  { // Entry 213
+    (long int)0.0,
+    0x1.0000000000001p-1022
+  },
+  { // Entry 214
+    (long int)0.0,
+    -0x1.0000000000001p-1022
+  },
+  { // Entry 215
+    (long int)0.0,
+    0x1.0p-1022
+  },
+  { // Entry 216
+    (long int)0.0,
+    -0x1.0p-1022
+  },
+  { // Entry 217
+    (long int)0.0,
+    0x1.ffffffffffffep-1023
+  },
+  { // Entry 218
+    (long int)0.0,
+    -0x1.ffffffffffffep-1023
+  },
+  { // Entry 219
+    (long int)0.0,
+    0x1.ffffffffffffcp-1023
+  },
+  { // Entry 220
+    (long int)0.0,
+    -0x1.ffffffffffffcp-1023
+  },
+  { // Entry 221
+    (long int)0.0,
+    0x1.0p-1073
+  },
+  { // Entry 222
+    (long int)0.0,
+    -0x1.0p-1073
+  },
+  { // Entry 223
+    (long int)0.0,
+    0x1.0p-1074
+  },
+  { // Entry 224
+    (long int)0.0,
+    -0x1.0p-1074
+  },
+  { // Entry 225
+    (long int)0.0,
+    0.0
+  },
+  { // Entry 226
+    (long int)0.0,
+    -0.0
+  },
+  { // Entry 227
+    (long int)0x1.p1,
+    0x1.8p0
+  },
+  { // Entry 228
+    (long int)-0x1.p1,
+    -0x1.8p0
+  },
+  { // Entry 229
+    (long int)0x1.p1,
+    0x1.4p1
+  },
+  { // Entry 230
+    (long int)-0x1.p1,
+    -0x1.4p1
+  },
+  { // Entry 231
+    (long int)0.0,
+    0x1.fffffp-2
+  },
+  { // Entry 232
+    (long int)0.0,
+    0x1.0p-1
+  },
+  { // Entry 233
+    (long int)0x1.p0,
+    0x1.00001p-1
+  },
+  { // Entry 234
+    (long int)0.0,
+    -0x1.fffffp-2
+  },
+  { // Entry 235
+    (long int)0.0,
+    -0x1.0p-1
+  },
+  { // Entry 236
+    (long int)-0x1.p0,
+    -0x1.00001p-1
+  },
+  { // Entry 237
+    (long int)0x1.p1,
+    0x1.80001p0
+  },
+  { // Entry 238
+    (long int)0x1.p0,
+    0x1.7ffffp0
+  },
+  { // Entry 239
+    (long int)-0x1.p1,
+    -0x1.80001p0
+  },
+  { // Entry 240
+    (long int)-0x1.p0,
+    -0x1.7ffffp0
+  }
+};
\ No newline at end of file
diff --git a/tests/math_data/lrintf_intel_data.h b/tests/math_data/lrintf_intel_data.h
new file mode 100644
index 0000000..bd771b2
--- /dev/null
+++ b/tests/math_data/lrintf_intel_data.h
@@ -0,0 +1,1002 @@
+/*
+ * Copyright (C) 2016 The Android Open Source Project
+ *
+ * Licensed under the Apache License, Version 2.0 (the "License");
+ * you may not use this file except in compliance with the License.
+ * You may obtain a copy of the License at
+ *
+ *      http://www.apache.org/licenses/LICENSE-2.0
+ *
+ * Unless required by applicable law or agreed to in writing, software
+ * distributed under the License is distributed on an "AS IS" BASIS,
+ * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
+ * See the License for the specific language governing permissions and
+ * limitations under the License.
+ */
+
+static data_long_1_t<float> g_lrintf_intel_data[] = {
+  { // Entry 0
+    (long int)0.0,
+    -0x1.p-149
+  },
+  { // Entry 1
+    (long int)0.0,
+    0.0
+  },
+  { // Entry 2
+    (long int)0.0,
+    0x1.p-149
+  },
+  { // Entry 3
+    (long int)0.0,
+    0x1.fffffep-2
+  },
+  { // Entry 4
+    (long int)0.0,
+    0x1.p-1
+  },
+  { // Entry 5
+    (long int)0x1.p0,
+    0x1.000002p-1
+  },
+  { // Entry 6
+    (long int)0x1.p0,
+    0x1.fffffep-1
+  },
+  { // Entry 7
+    (long int)0x1.p0,
+    0x1.p0
+  },
+  { // Entry 8
+    (long int)0x1.p0,
+    0x1.000002p0
+  },
+  { // Entry 9
+    (long int)0x1.p0,
+    0x1.7ffffep0
+  },
+  { // Entry 10
+    (long int)0x1.p1,
+    0x1.80p0
+  },
+  { // Entry 11
+    (long int)0x1.p1,
+    0x1.800002p0
+  },
+  { // Entry 12
+    (long int)0x1.p1,
+    0x1.fffffep0
+  },
+  { // Entry 13
+    (long int)0x1.p1,
+    0x1.p1
+  },
+  { // Entry 14
+    (long int)0x1.p1,
+    0x1.000002p1
+  },
+  { // Entry 15
+    (long int)0x1.p1,
+    0x1.3ffffep1
+  },
+  { // Entry 16
+    (long int)0x1.p1,
+    0x1.40p1
+  },
+  { // Entry 17
+    (long int)0x1.80p1,
+    0x1.400002p1
+  },
+  { // Entry 18
+    (long int)0x1.90p6,
+    0x1.8ffffep6
+  },
+  { // Entry 19
+    (long int)0x1.90p6,
+    0x1.90p6
+  },
+  { // Entry 20
+    (long int)0x1.90p6,
+    0x1.900002p6
+  },
+  { // Entry 21
+    (long int)0x1.90p6,
+    0x1.91fffep6
+  },
+  { // Entry 22
+    (long int)0x1.90p6,
+    0x1.92p6
+  },
+  { // Entry 23
+    (long int)0x1.94p6,
+    0x1.920002p6
+  },
+  { // Entry 24
+    (long int)0x1.f4p9,
+    0x1.f3fffep9
+  },
+  { // Entry 25
+    (long int)0x1.f4p9,
+    0x1.f4p9
+  },
+  { // Entry 26
+    (long int)0x1.f4p9,
+    0x1.f40002p9
+  },
+  { // Entry 27
+    (long int)0x1.f4p9,
+    0x1.f43ffep9
+  },
+  { // Entry 28
+    (long int)0x1.f4p9,
+    0x1.f440p9
+  },
+  { // Entry 29
+    (long int)0x1.f480p9,
+    0x1.f44002p9
+  },
+  { // Entry 30
+    (long int)0x1.p21,
+    0x1.fffffep20
+  },
+  { // Entry 31
+    (long int)0x1.p21,
+    0x1.p21
+  },
+  { // Entry 32
+    (long int)0x1.p21,
+    0x1.000002p21
+  },
+  { // Entry 33
+    (long int)0x1.p22,
+    0x1.fffffep21
+  },
+  { // Entry 34
+    (long int)0x1.p22,
+    0x1.p22
+  },
+  { // Entry 35
+    (long int)0x1.p22,
+    0x1.000002p22
+  },
+  { // Entry 36
+    (long int)0x1.p23,
+    0x1.fffffep22
+  },
+  { // Entry 37
+    (long int)0x1.p23,
+    0x1.p23
+  },
+  { // Entry 38
+    (long int)0x1.000002p23,
+    0x1.000002p23
+  },
+  { // Entry 39
+    (long int)0x1.fffffep23,
+    0x1.fffffep23
+  },
+  { // Entry 40
+    (long int)0x1.p24,
+    0x1.p24
+  },
+  { // Entry 41
+    (long int)0x1.000002p24,
+    0x1.000002p24
+  },
+  { // Entry 42
+    (long int)0x1.fffffep24,
+    0x1.fffffep24
+  },
+  { // Entry 43
+    (long int)0x1.p25,
+    0x1.p25
+  },
+  { // Entry 44
+    (long int)0x1.000002p25,
+    0x1.000002p25
+  },
+  { // Entry 45
+    (long int)-0x1.p0,
+    -0x1.000002p-1
+  },
+  { // Entry 46
+    (long int)0.0,
+    -0x1.p-1
+  },
+  { // Entry 47
+    (long int)0.0,
+    -0x1.fffffep-2
+  },
+  { // Entry 48
+    (long int)-0x1.p0,
+    -0x1.000002p0
+  },
+  { // Entry 49
+    (long int)-0x1.p0,
+    -0x1.p0
+  },
+  { // Entry 50
+    (long int)-0x1.p0,
+    -0x1.fffffep-1
+  },
+  { // Entry 51
+    (long int)-0x1.p1,
+    -0x1.800002p0
+  },
+  { // Entry 52
+    (long int)-0x1.p1,
+    -0x1.80p0
+  },
+  { // Entry 53
+    (long int)-0x1.p0,
+    -0x1.7ffffep0
+  },
+  { // Entry 54
+    (long int)-0x1.p1,
+    -0x1.000002p1
+  },
+  { // Entry 55
+    (long int)-0x1.p1,
+    -0x1.p1
+  },
+  { // Entry 56
+    (long int)-0x1.p1,
+    -0x1.fffffep0
+  },
+  { // Entry 57
+    (long int)-0x1.80p1,
+    -0x1.400002p1
+  },
+  { // Entry 58
+    (long int)-0x1.p1,
+    -0x1.40p1
+  },
+  { // Entry 59
+    (long int)-0x1.p1,
+    -0x1.3ffffep1
+  },
+  { // Entry 60
+    (long int)-0x1.90p6,
+    -0x1.900002p6
+  },
+  { // Entry 61
+    (long int)-0x1.90p6,
+    -0x1.90p6
+  },
+  { // Entry 62
+    (long int)-0x1.90p6,
+    -0x1.8ffffep6
+  },
+  { // Entry 63
+    (long int)-0x1.94p6,
+    -0x1.920002p6
+  },
+  { // Entry 64
+    (long int)-0x1.90p6,
+    -0x1.92p6
+  },
+  { // Entry 65
+    (long int)-0x1.90p6,
+    -0x1.91fffep6
+  },
+  { // Entry 66
+    (long int)-0x1.f4p9,
+    -0x1.f40002p9
+  },
+  { // Entry 67
+    (long int)-0x1.f4p9,
+    -0x1.f4p9
+  },
+  { // Entry 68
+    (long int)-0x1.f4p9,
+    -0x1.f3fffep9
+  },
+  { // Entry 69
+    (long int)-0x1.f480p9,
+    -0x1.f44002p9
+  },
+  { // Entry 70
+    (long int)-0x1.f4p9,
+    -0x1.f440p9
+  },
+  { // Entry 71
+    (long int)-0x1.f4p9,
+    -0x1.f43ffep9
+  },
+  { // Entry 72
+    (long int)-0x1.p21,
+    -0x1.000002p21
+  },
+  { // Entry 73
+    (long int)-0x1.p21,
+    -0x1.p21
+  },
+  { // Entry 74
+    (long int)-0x1.p21,
+    -0x1.fffffep20
+  },
+  { // Entry 75
+    (long int)-0x1.p22,
+    -0x1.000002p22
+  },
+  { // Entry 76
+    (long int)-0x1.p22,
+    -0x1.p22
+  },
+  { // Entry 77
+    (long int)-0x1.p22,
+    -0x1.fffffep21
+  },
+  { // Entry 78
+    (long int)-0x1.000002p23,
+    -0x1.000002p23
+  },
+  { // Entry 79
+    (long int)-0x1.p23,
+    -0x1.p23
+  },
+  { // Entry 80
+    (long int)-0x1.p23,
+    -0x1.fffffep22
+  },
+  { // Entry 81
+    (long int)-0x1.000002p24,
+    -0x1.000002p24
+  },
+  { // Entry 82
+    (long int)-0x1.p24,
+    -0x1.p24
+  },
+  { // Entry 83
+    (long int)-0x1.fffffep23,
+    -0x1.fffffep23
+  },
+  { // Entry 84
+    (long int)-0x1.000002p25,
+    -0x1.000002p25
+  },
+  { // Entry 85
+    (long int)-0x1.p25,
+    -0x1.p25
+  },
+  { // Entry 86
+    (long int)-0x1.fffffep24,
+    -0x1.fffffep24
+  },
+  { // Entry 87
+    (long int)0x1.fffffep29,
+    0x1.fffffep29
+  },
+  { // Entry 88
+    (long int)0x1.p30,
+    0x1.p30
+  },
+  { // Entry 89
+    (long int)0x1.000002p30,
+    0x1.000002p30
+  },
+  { // Entry 90
+    (long int)0x1.fffffcp30,
+    0x1.fffffcp30
+  },
+  { // Entry 91
+    (long int)0x1.fffffep30,
+    0x1.fffffep30
+  },
+  { // Entry 92
+    (long int)0x1.fffffcp30,
+    0x1.fffffcp30
+  },
+  { // Entry 93
+    (long int)0x1.fffffep30,
+    0x1.fffffep30
+  },
+  { // Entry 94
+    (long int)0x1.fffffcp30,
+    0x1.fffffcp30
+  },
+  { // Entry 95
+    (long int)0x1.fffffep30,
+    0x1.fffffep30
+  },
+  { // Entry 96
+    (long int)0x1.fffffcp30,
+    0x1.fffffcp30
+  },
+  { // Entry 97
+    (long int)0x1.fffffep30,
+    0x1.fffffep30
+  },
+  { // Entry 98
+    (long int)0x1.fffffcp30,
+    0x1.fffffcp30
+  },
+  { // Entry 99
+    (long int)0x1.fffffep30,
+    0x1.fffffep30
+  },
+  { // Entry 100
+    (long int)0x1.fffffcp30,
+    0x1.fffffcp30
+  },
+  { // Entry 101
+    (long int)0x1.fffffep30,
+    0x1.fffffep30
+  },
+  { // Entry 102
+    (long int)-0x1.000002p30,
+    -0x1.000002p30
+  },
+  { // Entry 103
+    (long int)-0x1.p30,
+    -0x1.p30
+  },
+  { // Entry 104
+    (long int)-0x1.fffffep29,
+    -0x1.fffffep29
+  },
+  { // Entry 105
+    (long int)-0x1.p31,
+    -0x1.p31
+  },
+  { // Entry 106
+    (long int)-0x1.fffffep30,
+    -0x1.fffffep30
+  },
+  { // Entry 107
+    (long int)-0x1.fffffcp30,
+    -0x1.fffffcp30
+  },
+  { // Entry 108
+    (long int)-0x1.p31,
+    -0x1.p31
+  },
+  { // Entry 109
+    (long int)-0x1.fffffep30,
+    -0x1.fffffep30
+  },
+  { // Entry 110
+    (long int)-0x1.fffffcp30,
+    -0x1.fffffcp30
+  },
+  { // Entry 111
+    (long int)-0x1.p31,
+    -0x1.p31
+  },
+  { // Entry 112
+    (long int)-0x1.fffffep30,
+    -0x1.fffffep30
+  },
+  { // Entry 113
+    (long int)-0x1.fffffcp30,
+    -0x1.fffffcp30
+  },
+  { // Entry 114
+    (long int)-0x1.p31,
+    -0x1.p31
+  },
+  { // Entry 115
+    (long int)-0x1.fffffep30,
+    -0x1.fffffep30
+  },
+  { // Entry 116
+    (long int)-0x1.fffffcp30,
+    -0x1.fffffcp30
+  },
+  { // Entry 117
+    (long int)-0x1.p31,
+    -0x1.p31
+  },
+  { // Entry 118
+    (long int)-0x1.fffffep30,
+    -0x1.fffffep30
+  },
+  { // Entry 119
+    (long int)-0x1.fffffcp30,
+    -0x1.fffffcp30
+  },
+  { // Entry 120
+    (long int)-0x1.p31,
+    -0x1.p31
+  },
+  { // Entry 121
+    (long int)-0x1.fffffep30,
+    -0x1.fffffep30
+  },
+  { // Entry 122
+    (long int)-0x1.fffffcp30,
+    -0x1.fffffcp30
+  },
+  { // Entry 123
+    (long int)-0x1.p31,
+    -0x1.p31
+  },
+  { // Entry 124
+    (long int)-0x1.p31,
+    -0x1.p31
+  },
+  { // Entry 125
+    (long int)-0x1.p31,
+    -0x1.p31
+  },
+  { // Entry 126
+    (long int)-0x1.p31,
+    -0x1.p31
+  },
+  { // Entry 127
+    (long int)-0x1.p31,
+    -0x1.p31
+  },
+  { // Entry 128
+    (long int)-0x1.p31,
+    -0x1.p31
+  },
+  { // Entry 129
+    (long int)-0x1.p31,
+    -0x1.p31
+  },
+  { // Entry 130
+    (long int)-0x1.p31,
+    -0x1.p31
+  },
+  { // Entry 131
+    (long int)-0x1.p31,
+    -0x1.p31
+  },
+  { // Entry 132
+    (long int)-0x1.p31,
+    -0x1.p31
+  },
+  { // Entry 133
+    (long int)0x1.fffffcp30,
+    0x1.fffffcp30
+  },
+  { // Entry 134
+    (long int)0x1.fffffep30,
+    0x1.fffffep30
+  },
+  { // Entry 135
+    (long int)-0x1.p31,
+    -0x1.p31
+  },
+  { // Entry 136
+    (long int)-0x1.fffffep30,
+    -0x1.fffffep30
+  },
+  { // Entry 137
+    (long int)0x1.p2,
+    0x1.fffffep1
+  },
+  { // Entry 138
+    (long int)0x1.p2,
+    0x1.p2
+  },
+  { // Entry 139
+    (long int)0x1.p2,
+    0x1.000002p2
+  },
+  { // Entry 140
+    (long int)0x1.p3,
+    0x1.fffffep2
+  },
+  { // Entry 141
+    (long int)0x1.p3,
+    0x1.p3
+  },
+  { // Entry 142
+    (long int)0x1.p3,
+    0x1.000002p3
+  },
+  { // Entry 143
+    (long int)0x1.p4,
+    0x1.fffffep3
+  },
+  { // Entry 144
+    (long int)0x1.p4,
+    0x1.p4
+  },
+  { // Entry 145
+    (long int)0x1.p4,
+    0x1.000002p4
+  },
+  { // Entry 146
+    (long int)0x1.p5,
+    0x1.fffffep4
+  },
+  { // Entry 147
+    (long int)0x1.p5,
+    0x1.p5
+  },
+  { // Entry 148
+    (long int)0x1.p5,
+    0x1.000002p5
+  },
+  { // Entry 149
+    (long int)0x1.p6,
+    0x1.fffffep5
+  },
+  { // Entry 150
+    (long int)0x1.p6,
+    0x1.p6
+  },
+  { // Entry 151
+    (long int)0x1.p6,
+    0x1.000002p6
+  },
+  { // Entry 152
+    (long int)0x1.p7,
+    0x1.fffffep6
+  },
+  { // Entry 153
+    (long int)0x1.p7,
+    0x1.p7
+  },
+  { // Entry 154
+    (long int)0x1.p7,
+    0x1.000002p7
+  },
+  { // Entry 155
+    (long int)0x1.p8,
+    0x1.fffffep7
+  },
+  { // Entry 156
+    (long int)0x1.p8,
+    0x1.p8
+  },
+  { // Entry 157
+    (long int)0x1.p8,
+    0x1.000002p8
+  },
+  { // Entry 158
+    (long int)0x1.p9,
+    0x1.fffffep8
+  },
+  { // Entry 159
+    (long int)0x1.p9,
+    0x1.p9
+  },
+  { // Entry 160
+    (long int)0x1.p9,
+    0x1.000002p9
+  },
+  { // Entry 161
+    (long int)0x1.p10,
+    0x1.fffffep9
+  },
+  { // Entry 162
+    (long int)0x1.p10,
+    0x1.p10
+  },
+  { // Entry 163
+    (long int)0x1.p10,
+    0x1.000002p10
+  },
+  { // Entry 164
+    (long int)0x1.p11,
+    0x1.fffffep10
+  },
+  { // Entry 165
+    (long int)0x1.p11,
+    0x1.p11
+  },
+  { // Entry 166
+    (long int)0x1.p11,
+    0x1.000002p11
+  },
+  { // Entry 167
+    (long int)0x1.p12,
+    0x1.fffffep11
+  },
+  { // Entry 168
+    (long int)0x1.p12,
+    0x1.p12
+  },
+  { // Entry 169
+    (long int)0x1.p12,
+    0x1.000002p12
+  },
+  { // Entry 170
+    (long int)0x1.p2,
+    0x1.1ffffep2
+  },
+  { // Entry 171
+    (long int)0x1.p2,
+    0x1.20p2
+  },
+  { // Entry 172
+    (long int)0x1.40p2,
+    0x1.200002p2
+  },
+  { // Entry 173
+    (long int)0x1.p3,
+    0x1.0ffffep3
+  },
+  { // Entry 174
+    (long int)0x1.p3,
+    0x1.10p3
+  },
+  { // Entry 175
+    (long int)0x1.20p3,
+    0x1.100002p3
+  },
+  { // Entry 176
+    (long int)0x1.p4,
+    0x1.07fffep4
+  },
+  { // Entry 177
+    (long int)0x1.p4,
+    0x1.08p4
+  },
+  { // Entry 178
+    (long int)0x1.10p4,
+    0x1.080002p4
+  },
+  { // Entry 179
+    (long int)0x1.p5,
+    0x1.03fffep5
+  },
+  { // Entry 180
+    (long int)0x1.p5,
+    0x1.04p5
+  },
+  { // Entry 181
+    (long int)0x1.08p5,
+    0x1.040002p5
+  },
+  { // Entry 182
+    (long int)0x1.p6,
+    0x1.01fffep6
+  },
+  { // Entry 183
+    (long int)0x1.p6,
+    0x1.02p6
+  },
+  { // Entry 184
+    (long int)0x1.04p6,
+    0x1.020002p6
+  },
+  { // Entry 185
+    (long int)0x1.p7,
+    0x1.00fffep7
+  },
+  { // Entry 186
+    (long int)0x1.p7,
+    0x1.01p7
+  },
+  { // Entry 187
+    (long int)0x1.02p7,
+    0x1.010002p7
+  },
+  { // Entry 188
+    (long int)0x1.p8,
+    0x1.007ffep8
+  },
+  { // Entry 189
+    (long int)0x1.p8,
+    0x1.0080p8
+  },
+  { // Entry 190
+    (long int)0x1.01p8,
+    0x1.008002p8
+  },
+  { // Entry 191
+    (long int)0x1.p9,
+    0x1.003ffep9
+  },
+  { // Entry 192
+    (long int)0x1.p9,
+    0x1.0040p9
+  },
+  { // Entry 193
+    (long int)0x1.0080p9,
+    0x1.004002p9
+  },
+  { // Entry 194
+    (long int)0x1.p10,
+    0x1.001ffep10
+  },
+  { // Entry 195
+    (long int)0x1.p10,
+    0x1.0020p10
+  },
+  { // Entry 196
+    (long int)0x1.0040p10,
+    0x1.002002p10
+  },
+  { // Entry 197
+    (long int)0x1.0040p10,
+    0x1.005ffep10
+  },
+  { // Entry 198
+    (long int)0x1.0080p10,
+    0x1.0060p10
+  },
+  { // Entry 199
+    (long int)0x1.0080p10,
+    0x1.006002p10
+  },
+  { // Entry 200
+    (long int)0x1.p11,
+    0x1.000ffep11
+  },
+  { // Entry 201
+    (long int)0x1.p11,
+    0x1.0010p11
+  },
+  { // Entry 202
+    (long int)0x1.0020p11,
+    0x1.001002p11
+  },
+  { // Entry 203
+    (long int)0x1.p12,
+    0x1.0007fep12
+  },
+  { // Entry 204
+    (long int)0x1.p12,
+    0x1.0008p12
+  },
+  { // Entry 205
+    (long int)0x1.0010p12,
+    0x1.000802p12
+  },
+  { // Entry 206
+    (long int)0x1.80p1,
+    0x1.921fb6p1
+  },
+  { // Entry 207
+    (long int)-0x1.80p1,
+    -0x1.921fb6p1
+  },
+  { // Entry 208
+    (long int)0x1.p1,
+    0x1.921fb6p0
+  },
+  { // Entry 209
+    (long int)-0x1.p1,
+    -0x1.921fb6p0
+  },
+  { // Entry 210
+    (long int)0x1.p0,
+    0x1.000002p0
+  },
+  { // Entry 211
+    (long int)-0x1.p0,
+    -0x1.000002p0
+  },
+  { // Entry 212
+    (long int)0x1.p0,
+    0x1.p0
+  },
+  { // Entry 213
+    (long int)-0x1.p0,
+    -0x1.p0
+  },
+  { // Entry 214
+    (long int)0x1.p0,
+    0x1.fffffep-1
+  },
+  { // Entry 215
+    (long int)-0x1.p0,
+    -0x1.fffffep-1
+  },
+  { // Entry 216
+    (long int)0x1.p0,
+    0x1.921fb6p-1
+  },
+  { // Entry 217
+    (long int)-0x1.p0,
+    -0x1.921fb6p-1
+  },
+  { // Entry 218
+    (long int)0.0,
+    0x1.000002p-126
+  },
+  { // Entry 219
+    (long int)0.0,
+    -0x1.000002p-126
+  },
+  { // Entry 220
+    (long int)0.0,
+    0x1.p-126
+  },
+  { // Entry 221
+    (long int)0.0,
+    -0x1.p-126
+  },
+  { // Entry 222
+    (long int)0.0,
+    0x1.fffffcp-127
+  },
+  { // Entry 223
+    (long int)0.0,
+    -0x1.fffffcp-127
+  },
+  { // Entry 224
+    (long int)0.0,
+    0x1.fffff8p-127
+  },
+  { // Entry 225
+    (long int)0.0,
+    -0x1.fffff8p-127
+  },
+  { // Entry 226
+    (long int)0.0,
+    0x1.p-148
+  },
+  { // Entry 227
+    (long int)0.0,
+    -0x1.p-148
+  },
+  { // Entry 228
+    (long int)0.0,
+    0x1.p-149
+  },
+  { // Entry 229
+    (long int)0.0,
+    -0x1.p-149
+  },
+  { // Entry 230
+    (long int)0.0,
+    0.0f
+  },
+  { // Entry 231
+    (long int)0.0,
+    -0.0f
+  },
+  { // Entry 232
+    (long int)0x1.p1,
+    0x1.80p0
+  },
+  { // Entry 233
+    (long int)-0x1.p1,
+    -0x1.80p0
+  },
+  { // Entry 234
+    (long int)0x1.p1,
+    0x1.40p1
+  },
+  { // Entry 235
+    (long int)-0x1.p1,
+    -0x1.40p1
+  },
+  { // Entry 236
+    (long int)0.0,
+    0x1.fffff0p-2
+  },
+  { // Entry 237
+    (long int)0.0,
+    0x1.p-1
+  },
+  { // Entry 238
+    (long int)0x1.p0,
+    0x1.000010p-1
+  },
+  { // Entry 239
+    (long int)0.0,
+    -0x1.fffff0p-2
+  },
+  { // Entry 240
+    (long int)0.0,
+    -0x1.p-1
+  },
+  { // Entry 241
+    (long int)-0x1.p0,
+    -0x1.000010p-1
+  },
+  { // Entry 242
+    (long int)0x1.p1,
+    0x1.800010p0
+  },
+  { // Entry 243
+    (long int)0x1.p0,
+    0x1.7ffff0p0
+  },
+  { // Entry 244
+    (long int)-0x1.p1,
+    -0x1.800010p0
+  },
+  { // Entry 245
+    (long int)-0x1.p0,
+    -0x1.7ffff0p0
+  }
+};
\ No newline at end of file
diff --git a/tests/math_data_test.h b/tests/math_data_test.h
index 8aa2bf1..0aba701 100644
--- a/tests/math_data_test.h
+++ b/tests/math_data_test.h
@@ -30,6 +30,18 @@
   T1 input;
 };
 
+template <typename T1>
+struct data_long_1_t {
+  long expected;
+  T1 input;
+};
+
+template <typename T1>
+struct data_llong_1_t {
+  long long expected;
+  T1 input;
+};
+
 template <typename RT, typename T1, typename T2>
 struct data_1_2_t {
   RT expected;
@@ -157,6 +169,28 @@
   }
 }
 
+// Runs through the array 'data' applying 'f' to each of the input values
+// and asserting that the result is within ULP ulps of the expected value.
+// For testing a (double) -> long int function like lrint(3).
+template <size_t ULP, typename T, size_t N>
+void DoMathDataTest(data_long_1_t<T> (&data)[N], long f(T)) {
+  fesetenv(FE_DFL_ENV);
+  for (size_t i = 0; i < N; ++i) {
+    EXPECT_EQ(data[i].expected, f(data[i].input)) << "Failed on element " << i;
+  }
+}
+
+// Runs through the array 'data' applying 'f' to each of the input values
+// and asserting that the result is within ULP ulps of the expected value.
+// For testing a (double) -> long long int function like llrint(3).
+template <size_t ULP, typename T, size_t N>
+void DoMathDataTest(data_llong_1_t<T> (&data)[N], long long f(T)) {
+  fesetenv(FE_DFL_ENV);
+  for (size_t i = 0; i < N; ++i) {
+    EXPECT_EQ(data[i].expected, f(data[i].input)) << "Failed on element " << i;
+  }
+}
+
 // Runs through the array 'data' applying 'f' to each of the pairs of input values
 // and asserting that the result is within ULP ulps of the expected value.
 // For testing a (double, double) -> double function like pow(3).
diff --git a/tests/math_test.cpp b/tests/math_test.cpp
index e616e9b..c805cc2 100644
--- a/tests/math_test.cpp
+++ b/tests/math_test.cpp
@@ -1639,6 +1639,16 @@
   DoMathDataTest<1>(g_ldexpf_intel_data, ldexpf);
 }
 
+#include "math_data/llrint_intel_data.h"
+TEST(math, llrint_intel) {
+  DoMathDataTest<1>(g_llrint_intel_data, llrint);
+}
+
+#include "math_data/llrintf_intel_data.h"
+TEST(math, llrintf_intel) {
+  DoMathDataTest<1>(g_llrintf_intel_data, llrintf);
+}
+
 #include "math_data/log_intel_data.h"
 TEST(math, log_intel) {
   DoMathDataTest<1>(g_log_intel_data, log);
@@ -1689,6 +1699,16 @@
   DoMathDataTest<1>(g_logbf_intel_data, logbf);
 }
 
+#include "math_data/lrint_intel_data.h"
+TEST(math, lrint_intel) {
+  DoMathDataTest<1>(g_lrint_intel_data, lrint);
+}
+
+#include "math_data/lrintf_intel_data.h"
+TEST(math, lrintf_intel) {
+  DoMathDataTest<1>(g_lrintf_intel_data, lrintf);
+}
+
 #include "math_data/modf_intel_data.h"
 TEST(math, modf_intel) {
   DoMathDataTest<1>(g_modf_intel_data, modf);
diff --git a/tests/net_if_test.cpp b/tests/net_if_test.cpp
new file mode 100644
index 0000000..caaed5f
--- /dev/null
+++ b/tests/net_if_test.cpp
@@ -0,0 +1,73 @@
+/*
+ * Copyright (C) 2016 The Android Open Source Project
+ *
+ * Licensed under the Apache License, Version 2.0 (the "License");
+ * you may not use this file except in compliance with the License.
+ * You may obtain a copy of the License at
+ *
+ *      http://www.apache.org/licenses/LICENSE-2.0
+ *
+ * Unless required by applicable law or agreed to in writing, software
+ * distributed under the License is distributed on an "AS IS" BASIS,
+ * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
+ * See the License for the specific language governing permissions and
+ * limitations under the License.
+ */
+
+#include <net/if.h>
+
+#include <errno.h>
+#include <ifaddrs.h>
+
+#include <gtest/gtest.h>
+
+TEST(net_if, if_nametoindex_if_indextoname) {
+  unsigned index;
+  index = if_nametoindex("lo");
+  ASSERT_NE(index, 0U);
+
+  char buf[IF_NAMESIZE] = {};
+  char* name = if_indextoname(index, buf);
+  ASSERT_STREQ("lo", name);
+}
+
+TEST(net_if, if_nametoindex_fail) {
+  unsigned index = if_nametoindex("this-interface-does-not-exist");
+  ASSERT_EQ(0U, index);
+}
+
+TEST(net_if, if_nameindex) {
+  struct if_nameindex* list = if_nameindex();
+  ASSERT_TRUE(list != nullptr);
+
+  ASSERT_TRUE(list->if_index != 0);
+
+  std::set<std::string> if_nameindex_names;
+  char buf[IF_NAMESIZE] = {};
+  bool saw_lo = false;
+  for (struct if_nameindex* it = list; it->if_index != 0; ++it) {
+    fprintf(stderr, "\t%d\t%s\n", it->if_index, it->if_name);
+    if_nameindex_names.insert(it->if_name);
+    EXPECT_EQ(it->if_index, if_nametoindex(it->if_name));
+    EXPECT_STREQ(it->if_name, if_indextoname(it->if_index, buf));
+    if (strcmp(it->if_name, "lo") == 0) saw_lo = true;
+  }
+  ASSERT_TRUE(saw_lo);
+  if_freenameindex(list);
+
+  std::set<std::string> getifaddrs_names;
+  ifaddrs* ifa;
+  ASSERT_EQ(0, getifaddrs(&ifa));
+  for (ifaddrs* it = ifa; it != nullptr; it = it->ifa_next) {
+    getifaddrs_names.insert(it->ifa_name);
+  }
+  freeifaddrs(ifa);
+
+  ASSERT_EQ(getifaddrs_names, if_nameindex_names);
+}
+
+TEST(net_if, if_freenameindex_nullptr) {
+#if defined(__BIONIC__)
+  if_freenameindex(nullptr);
+#endif
+}
diff --git a/tests/netinet_in_test.cpp b/tests/netinet_in_test.cpp
new file mode 100644
index 0000000..a337770
--- /dev/null
+++ b/tests/netinet_in_test.cpp
@@ -0,0 +1,36 @@
+/*
+ * Copyright (C) 2016 The Android Open Source Project
+ *
+ * Licensed under the Apache License, Version 2.0 (the "License");
+ * you may not use this file except in compliance with the License.
+ * You may obtain a copy of the License at
+ *
+ *      http://www.apache.org/licenses/LICENSE-2.0
+ *
+ * Unless required by applicable law or agreed to in writing, software
+ * distributed under the License is distributed on an "AS IS" BASIS,
+ * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
+ * See the License for the specific language governing permissions and
+ * limitations under the License.
+ */
+
+#include <netinet/in.h>
+
+#include <errno.h>
+
+#include <gtest/gtest.h>
+
+TEST(netinet_in, bindresvport) {
+  // This isn't something we can usually test, so just check the symbol's there.
+  ASSERT_EQ(-1, bindresvport(-1, nullptr));
+}
+
+TEST(netinet_in, in6addr_any) {
+  in6_addr any = IN6ADDR_ANY_INIT;
+  ASSERT_EQ(0, memcmp(&any, &in6addr_any, sizeof(in6addr_any)));
+}
+
+TEST(netinet_in, in6addr_loopback) {
+  in6_addr loopback = IN6ADDR_LOOPBACK_INIT;
+  ASSERT_EQ(0, memcmp(&loopback, &in6addr_loopback, sizeof(in6addr_loopback)));
+}
diff --git a/tests/netinet_udp_test.cpp b/tests/netinet_udp_test.cpp
new file mode 100644
index 0000000..661458e
--- /dev/null
+++ b/tests/netinet_udp_test.cpp
@@ -0,0 +1,46 @@
+/*
+ * Copyright (C) 2015 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 <netinet/udp.h>
+
+#include <gtest/gtest.h>
+
+#if defined(__BIONIC__)
+  #define UDPHDR_USES_ANON_UNION
+#elif defined(__GLIBC_PREREQ)
+  #if __GLIBC_PREREQ(2, 18)
+    #define UDPHDR_USES_ANON_UNION
+  #endif
+#endif
+
+TEST(netinet_udp, compat) {
+#if defined(UDPHDR_USES_ANON_UNION)
+    static_assert(offsetof(udphdr, uh_sport) == offsetof(udphdr, source), "udphdr::source");
+    static_assert(offsetof(udphdr, uh_dport) == offsetof(udphdr, dest), "udphdr::dest");
+    static_assert(offsetof(udphdr, uh_ulen) == offsetof(udphdr, len), "udphdr::len");
+    static_assert(offsetof(udphdr, uh_sum) == offsetof(udphdr, check), "udphdr::check");
+
+    udphdr u;
+    u.uh_sport = 0x1111;
+    u.uh_dport = 0x2222;
+    u.uh_ulen = 0x3333;
+    u.uh_sum = 0x4444;
+    ASSERT_EQ(0x1111, u.source);
+    ASSERT_EQ(0x2222, u.dest);
+    ASSERT_EQ(0x3333, u.len);
+    ASSERT_EQ(0x4444, u.check);
+#endif
+}
diff --git a/tests/pthread_dlfcn_test.cpp b/tests/pthread_dlfcn_test.cpp
index 5e8b206..64423da 100644
--- a/tests/pthread_dlfcn_test.cpp
+++ b/tests/pthread_dlfcn_test.cpp
@@ -17,6 +17,8 @@
 
 #include <dlfcn.h>
 
+#include "utils.h"
+
 static int g_atfork_prepare_calls = 0;
 static void AtForkPrepare1() { g_atfork_prepare_calls = (g_atfork_prepare_calls * 10) + 1; }
 static void AtForkPrepare2() { g_atfork_prepare_calls = (g_atfork_prepare_calls * 10) + 2; }
@@ -49,7 +51,7 @@
 
   ASSERT_EQ(0, pthread_atfork(AtForkPrepare4, AtForkParent4, AtForkChild4));
 
-  int pid = fork();
+  pid_t pid = fork();
 
   ASSERT_NE(-1, pid) << strerror(errno);
 
@@ -64,8 +66,7 @@
   EXPECT_EQ(0, dlclose(handle));
   g_atfork_prepare_calls = g_atfork_parent_calls = g_atfork_child_calls = 0;
 
-  int status;
-  ASSERT_EQ(pid, waitpid(pid, &status, 0));
+  AssertChildExited(pid, 0);
 
   pid = fork();
 
@@ -79,5 +80,5 @@
   ASSERT_EQ(14, g_atfork_parent_calls);
   ASSERT_EQ(41, g_atfork_prepare_calls);
 
-  ASSERT_EQ(pid, waitpid(pid, &status, 0));
+  AssertChildExited(pid, 0);
 }
diff --git a/tests/pthread_test.cpp b/tests/pthread_test.cpp
index e210255..0313171 100755
--- a/tests/pthread_test.cpp
+++ b/tests/pthread_test.cpp
@@ -30,18 +30,14 @@
 #include <unwind.h>
 
 #include <atomic>
-#include <regex>
 #include <vector>
 
-#include <base/file.h>
-#include <base/stringprintf.h>
-
+#include "private/bionic_constants.h"
 #include "private/bionic_macros.h"
 #include "private/ScopeGuard.h"
 #include "BionicDeathTest.h"
 #include "ScopedSignalHandler.h"
-
-extern "C" pid_t gettid();
+#include "utils.h"
 
 TEST(pthread, pthread_key_create) {
   pthread_key_t key;
@@ -68,7 +64,7 @@
   std::vector<pthread_key_t> keys;
 
   auto scope_guard = make_scope_guard([&keys]{
-    for (auto key : keys) {
+    for (const auto& key : keys) {
       EXPECT_EQ(0, pthread_key_delete(key));
     }
   });
@@ -106,7 +102,7 @@
   }
 
   // Don't leak keys.
-  for (auto key : keys) {
+  for (const auto& key : keys) {
     EXPECT_EQ(0, pthread_key_delete(key));
   }
   keys.clear();
@@ -145,10 +141,7 @@
     _exit(99);
   }
 
-  int status;
-  ASSERT_EQ(pid, waitpid(pid, &status, 0));
-  ASSERT_TRUE(WIFEXITED(status));
-  ASSERT_EQ(99, WEXITSTATUS(status));
+  AssertChildExited(pid, 99);
 
   ASSERT_EQ(expected, pthread_getspecific(key));
   ASSERT_EQ(0, pthread_key_delete(key));
@@ -162,7 +155,7 @@
   pthread_key_t key;
   ASSERT_EQ(0, pthread_key_create(&key, NULL));
 
-  size_t stack_size = 128 * 1024;
+  size_t stack_size = 640 * 1024;
   void* stack = mmap(NULL, stack_size, PROT_READ|PROT_WRITE, MAP_PRIVATE|MAP_ANONYMOUS, -1, 0);
   ASSERT_NE(MAP_FAILED, stack);
   memset(stack, 0xff, stack_size);
@@ -220,13 +213,13 @@
     while (spin_flag_) {}
     return NULL;
   }
-  static volatile bool spin_flag_;
+  static std::atomic<bool> spin_flag_;
 };
 
 // It doesn't matter if spin_flag_ is used in several tests,
 // because it is always set to false after each test. Each thread
 // loops on spin_flag_ can find it becomes false at some time.
-volatile bool SpinFunctionHelper::spin_flag_ = false;
+std::atomic<bool> SpinFunctionHelper::spin_flag_;
 
 static void* JoinFn(void* arg) {
   return reinterpret_cast<void*>(pthread_join(reinterpret_cast<pthread_t>(arg), NULL));
@@ -419,6 +412,8 @@
   pthread_t t1;
   ASSERT_EQ(0, pthread_create(&t1, NULL, spinhelper.GetFunction(), NULL));
   ASSERT_EQ(0, pthread_setname_np(t1, "short 2"));
+  spinhelper.UnSpin();
+  ASSERT_EQ(0, pthread_join(t1, nullptr));
 }
 
 TEST(pthread, pthread_setname_np__no_such_thread) {
@@ -469,6 +464,8 @@
   ASSERT_EQ(0, pthread_getcpuclockid(t, &c));
   timespec ts;
   ASSERT_EQ(0, clock_gettime(c, &ts));
+  spinhelper.UnSpin();
+  ASSERT_EQ(0, pthread_join(t, nullptr));
 }
 
 TEST(pthread, pthread_getcpuclockid__no_such_thread) {
@@ -537,7 +534,7 @@
   // http://b/11693195 --- pthread_join could return before the thread had actually exited.
   // If the joiner unmapped the thread's stack, that could lead to SIGSEGV in the thread.
   for (size_t i = 0; i < 1024; ++i) {
-    size_t stack_size = 64*1024;
+    size_t stack_size = 640*1024;
     void* stack = mmap(NULL, stack_size, PROT_READ|PROT_WRITE, MAP_ANON|MAP_PRIVATE, -1, 0);
 
     pthread_attr_t a;
@@ -719,58 +716,47 @@
   ASSERT_EQ(0, pthread_rwlock_destroy(&l));
 }
 
-static void WaitUntilThreadSleep(std::atomic<pid_t>& pid) {
-  while (pid == 0) {
-    usleep(1000);
-  }
-  std::string filename = android::base::StringPrintf("/proc/%d/stat", pid.load());
-  std::regex regex {R"(\s+S\s+)"};
-
-  while (true) {
-    std::string content;
-    ASSERT_TRUE(android::base::ReadFileToString(filename, &content));
-    if (std::regex_search(content, regex)) {
-      break;
-    }
-    usleep(1000);
-  }
-}
-
 struct RwlockWakeupHelperArg {
   pthread_rwlock_t lock;
   enum Progress {
     LOCK_INITIALIZED,
     LOCK_WAITING,
     LOCK_RELEASED,
-    LOCK_ACCESSED
+    LOCK_ACCESSED,
+    LOCK_TIMEDOUT,
   };
   std::atomic<Progress> progress;
   std::atomic<pid_t> tid;
+  std::function<int (pthread_rwlock_t*)> trylock_function;
+  std::function<int (pthread_rwlock_t*)> lock_function;
+  std::function<int (pthread_rwlock_t*, const timespec*)> timed_lock_function;
 };
 
-static void pthread_rwlock_reader_wakeup_writer_helper(RwlockWakeupHelperArg* arg) {
+static void pthread_rwlock_wakeup_helper(RwlockWakeupHelperArg* arg) {
   arg->tid = gettid();
   ASSERT_EQ(RwlockWakeupHelperArg::LOCK_INITIALIZED, arg->progress);
   arg->progress = RwlockWakeupHelperArg::LOCK_WAITING;
 
-  ASSERT_EQ(EBUSY, pthread_rwlock_trywrlock(&arg->lock));
-  ASSERT_EQ(0, pthread_rwlock_wrlock(&arg->lock));
+  ASSERT_EQ(EBUSY, arg->trylock_function(&arg->lock));
+  ASSERT_EQ(0, arg->lock_function(&arg->lock));
   ASSERT_EQ(RwlockWakeupHelperArg::LOCK_RELEASED, arg->progress);
   ASSERT_EQ(0, pthread_rwlock_unlock(&arg->lock));
 
   arg->progress = RwlockWakeupHelperArg::LOCK_ACCESSED;
 }
 
-TEST(pthread, pthread_rwlock_reader_wakeup_writer) {
+static void test_pthread_rwlock_reader_wakeup_writer(std::function<int (pthread_rwlock_t*)> lock_function) {
   RwlockWakeupHelperArg wakeup_arg;
   ASSERT_EQ(0, pthread_rwlock_init(&wakeup_arg.lock, NULL));
   ASSERT_EQ(0, pthread_rwlock_rdlock(&wakeup_arg.lock));
   wakeup_arg.progress = RwlockWakeupHelperArg::LOCK_INITIALIZED;
   wakeup_arg.tid = 0;
+  wakeup_arg.trylock_function = pthread_rwlock_trywrlock;
+  wakeup_arg.lock_function = lock_function;
 
   pthread_t thread;
   ASSERT_EQ(0, pthread_create(&thread, NULL,
-    reinterpret_cast<void* (*)(void*)>(pthread_rwlock_reader_wakeup_writer_helper), &wakeup_arg));
+    reinterpret_cast<void* (*)(void*)>(pthread_rwlock_wakeup_helper), &wakeup_arg));
   WaitUntilThreadSleep(wakeup_arg.tid);
   ASSERT_EQ(RwlockWakeupHelperArg::LOCK_WAITING, wakeup_arg.progress);
 
@@ -782,29 +768,31 @@
   ASSERT_EQ(0, pthread_rwlock_destroy(&wakeup_arg.lock));
 }
 
-static void pthread_rwlock_writer_wakeup_reader_helper(RwlockWakeupHelperArg* arg) {
-  arg->tid = gettid();
-  ASSERT_EQ(RwlockWakeupHelperArg::LOCK_INITIALIZED, arg->progress);
-  arg->progress = RwlockWakeupHelperArg::LOCK_WAITING;
-
-  ASSERT_EQ(EBUSY, pthread_rwlock_tryrdlock(&arg->lock));
-  ASSERT_EQ(0, pthread_rwlock_rdlock(&arg->lock));
-  ASSERT_EQ(RwlockWakeupHelperArg::LOCK_RELEASED, arg->progress);
-  ASSERT_EQ(0, pthread_rwlock_unlock(&arg->lock));
-
-  arg->progress = RwlockWakeupHelperArg::LOCK_ACCESSED;
+TEST(pthread, pthread_rwlock_reader_wakeup_writer) {
+  test_pthread_rwlock_reader_wakeup_writer(pthread_rwlock_wrlock);
 }
 
-TEST(pthread, pthread_rwlock_writer_wakeup_reader) {
+TEST(pthread, pthread_rwlock_reader_wakeup_writer_timedwait) {
+  timespec ts;
+  ASSERT_EQ(0, clock_gettime(CLOCK_REALTIME, &ts));
+  ts.tv_sec += 1;
+  test_pthread_rwlock_reader_wakeup_writer([&](pthread_rwlock_t* lock) {
+    return pthread_rwlock_timedwrlock(lock, &ts);
+  });
+}
+
+static void test_pthread_rwlock_writer_wakeup_reader(std::function<int (pthread_rwlock_t*)> lock_function) {
   RwlockWakeupHelperArg wakeup_arg;
   ASSERT_EQ(0, pthread_rwlock_init(&wakeup_arg.lock, NULL));
   ASSERT_EQ(0, pthread_rwlock_wrlock(&wakeup_arg.lock));
   wakeup_arg.progress = RwlockWakeupHelperArg::LOCK_INITIALIZED;
   wakeup_arg.tid = 0;
+  wakeup_arg.trylock_function = pthread_rwlock_tryrdlock;
+  wakeup_arg.lock_function = lock_function;
 
   pthread_t thread;
   ASSERT_EQ(0, pthread_create(&thread, NULL,
-    reinterpret_cast<void* (*)(void*)>(pthread_rwlock_writer_wakeup_reader_helper), &wakeup_arg));
+    reinterpret_cast<void* (*)(void*)>(pthread_rwlock_wakeup_helper), &wakeup_arg));
   WaitUntilThreadSleep(wakeup_arg.tid);
   ASSERT_EQ(RwlockWakeupHelperArg::LOCK_WAITING, wakeup_arg.progress);
 
@@ -816,6 +804,85 @@
   ASSERT_EQ(0, pthread_rwlock_destroy(&wakeup_arg.lock));
 }
 
+TEST(pthread, pthread_rwlock_writer_wakeup_reader) {
+  test_pthread_rwlock_writer_wakeup_reader(pthread_rwlock_rdlock);
+}
+
+TEST(pthread, pthread_rwlock_writer_wakeup_reader_timedwait) {
+  timespec ts;
+  ASSERT_EQ(0, clock_gettime(CLOCK_REALTIME, &ts));
+  ts.tv_sec += 1;
+  test_pthread_rwlock_writer_wakeup_reader([&](pthread_rwlock_t* lock) {
+    return pthread_rwlock_timedrdlock(lock, &ts);
+  });
+}
+
+static void pthread_rwlock_wakeup_timeout_helper(RwlockWakeupHelperArg* arg) {
+  arg->tid = gettid();
+  ASSERT_EQ(RwlockWakeupHelperArg::LOCK_INITIALIZED, arg->progress);
+  arg->progress = RwlockWakeupHelperArg::LOCK_WAITING;
+
+  ASSERT_EQ(EBUSY, arg->trylock_function(&arg->lock));
+
+  timespec ts;
+  ASSERT_EQ(0, clock_gettime(CLOCK_REALTIME, &ts));
+  ASSERT_EQ(ETIMEDOUT, arg->timed_lock_function(&arg->lock, &ts));
+  ts.tv_nsec = -1;
+  ASSERT_EQ(EINVAL, arg->timed_lock_function(&arg->lock, &ts));
+  ts.tv_nsec = NS_PER_S;
+  ASSERT_EQ(EINVAL, arg->timed_lock_function(&arg->lock, &ts));
+  ts.tv_nsec = NS_PER_S - 1;
+  ts.tv_sec = -1;
+  ASSERT_EQ(ETIMEDOUT, arg->timed_lock_function(&arg->lock, &ts));
+  ASSERT_EQ(0, clock_gettime(CLOCK_REALTIME, &ts));
+  ts.tv_sec += 1;
+  ASSERT_EQ(ETIMEDOUT, arg->timed_lock_function(&arg->lock, &ts));
+  ASSERT_EQ(RwlockWakeupHelperArg::LOCK_WAITING, arg->progress);
+  arg->progress = RwlockWakeupHelperArg::LOCK_TIMEDOUT;
+}
+
+TEST(pthread, pthread_rwlock_timedrdlock_timeout) {
+  RwlockWakeupHelperArg wakeup_arg;
+  ASSERT_EQ(0, pthread_rwlock_init(&wakeup_arg.lock, nullptr));
+  ASSERT_EQ(0, pthread_rwlock_wrlock(&wakeup_arg.lock));
+  wakeup_arg.progress = RwlockWakeupHelperArg::LOCK_INITIALIZED;
+  wakeup_arg.tid = 0;
+  wakeup_arg.trylock_function = pthread_rwlock_tryrdlock;
+  wakeup_arg.timed_lock_function = pthread_rwlock_timedrdlock;
+
+  pthread_t thread;
+  ASSERT_EQ(0, pthread_create(&thread, nullptr,
+      reinterpret_cast<void* (*)(void*)>(pthread_rwlock_wakeup_timeout_helper), &wakeup_arg));
+  WaitUntilThreadSleep(wakeup_arg.tid);
+  ASSERT_EQ(RwlockWakeupHelperArg::LOCK_WAITING, wakeup_arg.progress);
+
+  ASSERT_EQ(0, pthread_join(thread, nullptr));
+  ASSERT_EQ(RwlockWakeupHelperArg::LOCK_TIMEDOUT, wakeup_arg.progress);
+  ASSERT_EQ(0, pthread_rwlock_unlock(&wakeup_arg.lock));
+  ASSERT_EQ(0, pthread_rwlock_destroy(&wakeup_arg.lock));
+}
+
+TEST(pthread, pthread_rwlock_timedwrlock_timeout) {
+  RwlockWakeupHelperArg wakeup_arg;
+  ASSERT_EQ(0, pthread_rwlock_init(&wakeup_arg.lock, nullptr));
+  ASSERT_EQ(0, pthread_rwlock_rdlock(&wakeup_arg.lock));
+  wakeup_arg.progress = RwlockWakeupHelperArg::LOCK_INITIALIZED;
+  wakeup_arg.tid = 0;
+  wakeup_arg.trylock_function = pthread_rwlock_trywrlock;
+  wakeup_arg.timed_lock_function = pthread_rwlock_timedwrlock;
+
+  pthread_t thread;
+  ASSERT_EQ(0, pthread_create(&thread, nullptr,
+      reinterpret_cast<void* (*)(void*)>(pthread_rwlock_wakeup_timeout_helper), &wakeup_arg));
+  WaitUntilThreadSleep(wakeup_arg.tid);
+  ASSERT_EQ(RwlockWakeupHelperArg::LOCK_WAITING, wakeup_arg.progress);
+
+  ASSERT_EQ(0, pthread_join(thread, nullptr));
+  ASSERT_EQ(RwlockWakeupHelperArg::LOCK_TIMEDOUT, wakeup_arg.progress);
+  ASSERT_EQ(0, pthread_rwlock_unlock(&wakeup_arg.lock));
+  ASSERT_EQ(0, pthread_rwlock_destroy(&wakeup_arg.lock));
+}
+
 class RwlockKindTestHelper {
  private:
   struct ThreadArg {
@@ -967,7 +1034,7 @@
   ASSERT_EQ(0, pthread_atfork(AtForkPrepare1, AtForkParent1, AtForkChild1));
   ASSERT_EQ(0, pthread_atfork(AtForkPrepare2, AtForkParent2, AtForkChild2));
 
-  int pid = fork();
+  pid_t pid = fork();
   ASSERT_NE(-1, pid) << strerror(errno);
 
   // Child and parent calls are made in the order they were registered.
@@ -979,8 +1046,7 @@
 
   // Prepare calls are made in the reverse order.
   ASSERT_EQ(21, g_atfork_prepare_calls);
-  int status;
-  ASSERT_EQ(pid, waitpid(pid, &status, 0));
+  AssertChildExited(pid, 0);
 }
 
 TEST(pthread, pthread_attr_getscope) {
@@ -1060,36 +1126,44 @@
   };
   std::atomic<Progress> progress;
   pthread_t thread;
+  std::function<int (pthread_cond_t* cond, pthread_mutex_t* mutex)> wait_function;
 
  protected:
-  virtual void SetUp() {
-    ASSERT_EQ(0, pthread_mutex_init(&mutex, NULL));
-    ASSERT_EQ(0, pthread_cond_init(&cond, NULL));
+  void SetUp() override {
+    ASSERT_EQ(0, pthread_mutex_init(&mutex, nullptr));
+  }
+
+  void InitCond(clockid_t clock=CLOCK_REALTIME) {
+    pthread_condattr_t attr;
+    ASSERT_EQ(0, pthread_condattr_init(&attr));
+    ASSERT_EQ(0, pthread_condattr_setclock(&attr, clock));
+    ASSERT_EQ(0, pthread_cond_init(&cond, &attr));
+    ASSERT_EQ(0, pthread_condattr_destroy(&attr));
+  }
+
+  void StartWaitingThread(std::function<int (pthread_cond_t* cond, pthread_mutex_t* mutex)> wait_function) {
     progress = INITIALIZED;
-    ASSERT_EQ(0,
-      pthread_create(&thread, NULL, reinterpret_cast<void* (*)(void*)>(WaitThreadFn), this));
-  }
-
-  virtual void TearDown() {
-    ASSERT_EQ(0, pthread_join(thread, NULL));
-    ASSERT_EQ(FINISHED, progress);
-    ASSERT_EQ(0, pthread_cond_destroy(&cond));
-    ASSERT_EQ(0, pthread_mutex_destroy(&mutex));
-  }
-
-  void SleepUntilProgress(Progress expected_progress) {
-    while (progress != expected_progress) {
+    this->wait_function = wait_function;
+    ASSERT_EQ(0, pthread_create(&thread, NULL, reinterpret_cast<void* (*)(void*)>(WaitThreadFn), this));
+    while (progress != WAITING) {
       usleep(5000);
     }
     usleep(5000);
   }
 
+  void TearDown() override {
+    ASSERT_EQ(0, pthread_join(thread, nullptr));
+    ASSERT_EQ(FINISHED, progress);
+    ASSERT_EQ(0, pthread_cond_destroy(&cond));
+    ASSERT_EQ(0, pthread_mutex_destroy(&mutex));
+  }
+
  private:
   static void WaitThreadFn(pthread_CondWakeupTest* test) {
     ASSERT_EQ(0, pthread_mutex_lock(&test->mutex));
     test->progress = WAITING;
     while (test->progress == WAITING) {
-      ASSERT_EQ(0, pthread_cond_wait(&test->cond, &test->mutex));
+      ASSERT_EQ(0, test->wait_function(&test->cond, &test->mutex));
     }
     ASSERT_EQ(SIGNALED, test->progress);
     test->progress = FINISHED;
@@ -1097,39 +1171,65 @@
   }
 };
 
-TEST_F(pthread_CondWakeupTest, signal) {
-  SleepUntilProgress(WAITING);
+TEST_F(pthread_CondWakeupTest, signal_wait) {
+  InitCond();
+  StartWaitingThread([](pthread_cond_t* cond, pthread_mutex_t* mutex) {
+    return pthread_cond_wait(cond, mutex);
+  });
   progress = SIGNALED;
-  pthread_cond_signal(&cond);
+  ASSERT_EQ(0, pthread_cond_signal(&cond));
 }
 
-TEST_F(pthread_CondWakeupTest, broadcast) {
-  SleepUntilProgress(WAITING);
+TEST_F(pthread_CondWakeupTest, broadcast_wait) {
+  InitCond();
+  StartWaitingThread([](pthread_cond_t* cond, pthread_mutex_t* mutex) {
+    return pthread_cond_wait(cond, mutex);
+  });
   progress = SIGNALED;
-  pthread_cond_broadcast(&cond);
+  ASSERT_EQ(0, pthread_cond_broadcast(&cond));
 }
 
-TEST(pthread, pthread_mutex_timedlock) {
-  pthread_mutex_t m;
-  ASSERT_EQ(0, pthread_mutex_init(&m, NULL));
-
-  // If the mutex is already locked, pthread_mutex_timedlock should time out.
-  ASSERT_EQ(0, pthread_mutex_lock(&m));
-
+TEST_F(pthread_CondWakeupTest, signal_timedwait_CLOCK_REALTIME) {
+  InitCond(CLOCK_REALTIME);
   timespec ts;
   ASSERT_EQ(0, clock_gettime(CLOCK_REALTIME, &ts));
-  ts.tv_nsec += 1;
-  ASSERT_EQ(ETIMEDOUT, pthread_mutex_timedlock(&m, &ts));
+  ts.tv_sec += 1;
+  StartWaitingThread([&](pthread_cond_t* cond, pthread_mutex_t* mutex) {
+    return pthread_cond_timedwait(cond, mutex, &ts);
+  });
+  progress = SIGNALED;
+  ASSERT_EQ(0, pthread_cond_signal(&cond));
+}
 
-  // If the mutex is unlocked, pthread_mutex_timedlock should succeed.
-  ASSERT_EQ(0, pthread_mutex_unlock(&m));
+TEST_F(pthread_CondWakeupTest, signal_timedwait_CLOCK_MONOTONIC) {
+  InitCond(CLOCK_MONOTONIC);
+  timespec ts;
+  ASSERT_EQ(0, clock_gettime(CLOCK_MONOTONIC, &ts));
+  ts.tv_sec += 1;
+  StartWaitingThread([&](pthread_cond_t* cond, pthread_mutex_t* mutex) {
+    return pthread_cond_timedwait(cond, mutex, &ts);
+  });
+  progress = SIGNALED;
+  ASSERT_EQ(0, pthread_cond_signal(&cond));
+}
 
+TEST(pthread, pthread_cond_timedwait_timeout) {
+  pthread_mutex_t mutex;
+  ASSERT_EQ(0, pthread_mutex_init(&mutex, nullptr));
+  pthread_cond_t cond;
+  ASSERT_EQ(0, pthread_cond_init(&cond, nullptr));
+  ASSERT_EQ(0, pthread_mutex_lock(&mutex));
+  timespec ts;
   ASSERT_EQ(0, clock_gettime(CLOCK_REALTIME, &ts));
-  ts.tv_nsec += 1;
-  ASSERT_EQ(0, pthread_mutex_timedlock(&m, &ts));
-
-  ASSERT_EQ(0, pthread_mutex_unlock(&m));
-  ASSERT_EQ(0, pthread_mutex_destroy(&m));
+  ASSERT_EQ(ETIMEDOUT, pthread_cond_timedwait(&cond, &mutex, &ts));
+  ts.tv_nsec = -1;
+  ASSERT_EQ(EINVAL, pthread_cond_timedwait(&cond, &mutex, &ts));
+  ts.tv_nsec = NS_PER_S;
+  ASSERT_EQ(EINVAL, pthread_cond_timedwait(&cond, &mutex, &ts));
+  ts.tv_nsec = NS_PER_S - 1;
+  ts.tv_sec = -1;
+  ASSERT_EQ(ETIMEDOUT, pthread_cond_timedwait(&cond, &mutex, &ts));
+  ASSERT_EQ(0, pthread_mutex_unlock(&mutex));
 }
 
 TEST(pthread, pthread_attr_getstack__main_thread) {
@@ -1155,31 +1255,30 @@
   // The two methods of asking for the stack size should agree.
   EXPECT_EQ(stack_size, stack_size2);
 
+#if defined(__BIONIC__)
   // What does /proc/self/maps' [stack] line say?
   void* maps_stack_hi = NULL;
-  FILE* fp = fopen("/proc/self/maps", "r");
-  ASSERT_TRUE(fp != NULL);
-  char line[BUFSIZ];
-  while (fgets(line, sizeof(line), fp) != NULL) {
-    uintptr_t lo, hi;
-    char name[10];
-    sscanf(line, "%" PRIxPTR "-%" PRIxPTR " %*4s %*x %*x:%*x %*d %10s", &lo, &hi, name);
-    if (strcmp(name, "[stack]") == 0) {
-      maps_stack_hi = reinterpret_cast<void*>(hi);
+  std::vector<map_record> maps;
+  ASSERT_TRUE(Maps::parse_maps(&maps));
+  for (const auto& map : maps) {
+    if (map.pathname == "[stack]") {
+      maps_stack_hi = reinterpret_cast<void*>(map.addr_end);
       break;
     }
   }
-  fclose(fp);
+
+  // The high address of the /proc/self/maps [stack] region should equal stack_base + stack_size.
+  // Remember that the stack grows down (and is mapped in on demand), so the low address of the
+  // region isn't very interesting.
+  EXPECT_EQ(maps_stack_hi, reinterpret_cast<uint8_t*>(stack_base) + stack_size);
 
   // The stack size should correspond to RLIMIT_STACK.
   rlimit rl;
   ASSERT_EQ(0, getrlimit(RLIMIT_STACK, &rl));
   uint64_t original_rlim_cur = rl.rlim_cur;
-#if defined(__BIONIC__)
   if (rl.rlim_cur == RLIM_INFINITY) {
     rl.rlim_cur = 8 * 1024 * 1024; // Bionic reports unlimited stacks as 8MiB.
   }
-#endif
   EXPECT_EQ(rl.rlim_cur, stack_size);
 
   auto guard = make_scope_guard([&rl, original_rlim_cur]() {
@@ -1187,11 +1286,6 @@
     ASSERT_EQ(0, setrlimit(RLIMIT_STACK, &rl));
   });
 
-  // The high address of the /proc/self/maps [stack] region should equal stack_base + stack_size.
-  // Remember that the stack grows down (and is mapped in on demand), so the low address of the
-  // region isn't very interesting.
-  EXPECT_EQ(maps_stack_hi, reinterpret_cast<uint8_t*>(stack_base) + stack_size);
-
   //
   // What if RLIMIT_STACK is smaller than the stack's current extent?
   //
@@ -1219,6 +1313,76 @@
 
   EXPECT_EQ(stack_size, stack_size2);
   ASSERT_EQ(6666U, stack_size);
+#endif
+}
+
+struct GetStackSignalHandlerArg {
+  volatile bool done;
+  void* signal_handler_sp;
+  void* main_stack_base;
+  size_t main_stack_size;
+};
+
+static GetStackSignalHandlerArg getstack_signal_handler_arg;
+
+static void getstack_signal_handler(int sig) {
+  ASSERT_EQ(SIGUSR1, sig);
+  // Use sleep() to make current thread be switched out by the kernel to provoke the error.
+  sleep(1);
+  pthread_attr_t attr;
+  ASSERT_EQ(0, pthread_getattr_np(pthread_self(), &attr));
+  void* stack_base;
+  size_t stack_size;
+  ASSERT_EQ(0, pthread_attr_getstack(&attr, &stack_base, &stack_size));
+  getstack_signal_handler_arg.signal_handler_sp = &attr;
+  getstack_signal_handler_arg.main_stack_base = stack_base;
+  getstack_signal_handler_arg.main_stack_size = stack_size;
+  getstack_signal_handler_arg.done = true;
+}
+
+// The previous code obtained the main thread's stack by reading the entry in
+// /proc/self/task/<pid>/maps that was labeled [stack]. Unfortunately, on x86/x86_64, the kernel
+// relies on sp0 in task state segment(tss) to label the stack map with [stack]. If the kernel
+// switches a process while the main thread is in an alternate stack, then the kernel will label
+// the wrong map with [stack]. This test verifies that when the above situation happens, the main
+// thread's stack is found correctly.
+TEST(pthread, pthread_attr_getstack_in_signal_handler) {
+  // This test is only meaningful for the main thread, so make sure we're running on it!
+  ASSERT_EQ(getpid(), syscall(__NR_gettid));
+
+  const size_t sig_stack_size = 16 * 1024;
+  void* sig_stack = mmap(NULL, sig_stack_size, PROT_READ | PROT_WRITE, MAP_PRIVATE | MAP_ANONYMOUS,
+                         -1, 0);
+  ASSERT_NE(MAP_FAILED, sig_stack);
+  stack_t ss;
+  ss.ss_sp = sig_stack;
+  ss.ss_size = sig_stack_size;
+  ss.ss_flags = 0;
+  stack_t oss;
+  ASSERT_EQ(0, sigaltstack(&ss, &oss));
+
+  pthread_attr_t attr;
+  ASSERT_EQ(0, pthread_getattr_np(pthread_self(), &attr));
+  void* main_stack_base;
+  size_t main_stack_size;
+  ASSERT_EQ(0, pthread_attr_getstack(&attr, &main_stack_base, &main_stack_size));
+
+  ScopedSignalHandler handler(SIGUSR1, getstack_signal_handler, SA_ONSTACK);
+  getstack_signal_handler_arg.done = false;
+  kill(getpid(), SIGUSR1);
+  ASSERT_EQ(true, getstack_signal_handler_arg.done);
+
+  // Verify if the stack used by the signal handler is the alternate stack just registered.
+  ASSERT_LE(sig_stack, getstack_signal_handler_arg.signal_handler_sp);
+  ASSERT_GE(reinterpret_cast<char*>(sig_stack) + sig_stack_size,
+            getstack_signal_handler_arg.signal_handler_sp);
+
+  // Verify if the main thread's stack got in the signal handler is correct.
+  ASSERT_EQ(main_stack_base, getstack_signal_handler_arg.main_stack_base);
+  ASSERT_LE(main_stack_size, getstack_signal_handler_arg.main_stack_size);
+
+  ASSERT_EQ(0, sigaltstack(&oss, nullptr));
+  ASSERT_EQ(0, munmap(sig_stack, sig_stack_size));
 }
 
 static void pthread_attr_getstack_18908062_helper(void*) {
@@ -1245,11 +1409,14 @@
 }
 
 #if defined(__BIONIC__)
-static pthread_mutex_t gettid_mutex;
+static pthread_mutex_t pthread_gettid_np_mutex = PTHREAD_MUTEX_INITIALIZER;
+
 static void* pthread_gettid_np_helper(void* arg) {
-  pthread_mutex_lock(&gettid_mutex);
   *reinterpret_cast<pid_t*>(arg) = gettid();
-  pthread_mutex_unlock(&gettid_mutex);
+
+  // Wait for our parent to call pthread_gettid_np on us before exiting.
+  pthread_mutex_lock(&pthread_gettid_np_mutex);
+  pthread_mutex_unlock(&pthread_gettid_np_mutex);
   return NULL;
 }
 #endif
@@ -1258,17 +1425,19 @@
 #if defined(__BIONIC__)
   ASSERT_EQ(gettid(), pthread_gettid_np(pthread_self()));
 
+  // Ensure the other thread doesn't exit until after we've called
+  // pthread_gettid_np on it.
+  pthread_mutex_lock(&pthread_gettid_np_mutex);
+
   pid_t t_gettid_result;
   pthread_t t;
-  pthread_mutex_init(&gettid_mutex, NULL);
-  pthread_mutex_lock(&gettid_mutex);
   pthread_create(&t, NULL, pthread_gettid_np_helper, &t_gettid_result);
 
   pid_t t_pthread_gettid_np_result = pthread_gettid_np(t);
-  pthread_mutex_unlock(&gettid_mutex);
 
+  // Release the other thread and wait for it to exit.
+  pthread_mutex_unlock(&pthread_gettid_np_mutex);
   pthread_join(t, NULL);
-  pthread_mutex_destroy(&gettid_mutex);
 
   ASSERT_EQ(t_gettid_result, t_pthread_gettid_np_result);
 #else
@@ -1370,6 +1539,9 @@
 
   ASSERT_EQ(0, pthread_mutex_lock(&m.lock));
   ASSERT_EQ(0, pthread_mutex_unlock(&m.lock));
+  ASSERT_EQ(0, pthread_mutex_trylock(&m.lock));
+  ASSERT_EQ(EBUSY, pthread_mutex_trylock(&m.lock));
+  ASSERT_EQ(0, pthread_mutex_unlock(&m.lock));
 }
 
 TEST(pthread, pthread_mutex_lock_ERRORCHECK) {
@@ -1392,6 +1564,8 @@
   ASSERT_EQ(0, pthread_mutex_unlock(&m.lock));
   ASSERT_EQ(0, pthread_mutex_unlock(&m.lock));
   ASSERT_EQ(0, pthread_mutex_trylock(&m.lock));
+  ASSERT_EQ(0, pthread_mutex_trylock(&m.lock));
+  ASSERT_EQ(0, pthread_mutex_unlock(&m.lock));
   ASSERT_EQ(0, pthread_mutex_unlock(&m.lock));
   ASSERT_EQ(EPERM, pthread_mutex_unlock(&m.lock));
 }
@@ -1489,6 +1663,35 @@
 #endif
 }
 
+TEST(pthread, pthread_mutex_timedlock) {
+  pthread_mutex_t m;
+  ASSERT_EQ(0, pthread_mutex_init(&m, nullptr));
+
+  // If the mutex is already locked, pthread_mutex_timedlock should time out.
+  ASSERT_EQ(0, pthread_mutex_lock(&m));
+
+  timespec ts;
+  ASSERT_EQ(0, clock_gettime(CLOCK_REALTIME, &ts));
+  ASSERT_EQ(ETIMEDOUT, pthread_mutex_timedlock(&m, &ts));
+  ts.tv_nsec = -1;
+  ASSERT_EQ(EINVAL, pthread_mutex_timedlock(&m, &ts));
+  ts.tv_nsec = NS_PER_S;
+  ASSERT_EQ(EINVAL, pthread_mutex_timedlock(&m, &ts));
+  ts.tv_nsec = NS_PER_S - 1;
+  ts.tv_sec = -1;
+  ASSERT_EQ(ETIMEDOUT, pthread_mutex_timedlock(&m, &ts));
+
+  // If the mutex is unlocked, pthread_mutex_timedlock should succeed.
+  ASSERT_EQ(0, pthread_mutex_unlock(&m));
+
+  ASSERT_EQ(0, clock_gettime(CLOCK_REALTIME, &ts));
+  ts.tv_sec += 1;
+  ASSERT_EQ(0, pthread_mutex_timedlock(&m, &ts));
+
+  ASSERT_EQ(0, pthread_mutex_unlock(&m));
+  ASSERT_EQ(0, pthread_mutex_destroy(&m));
+}
+
 class StrictAlignmentAllocator {
  public:
   void* allocate(size_t size, size_t alignment) {
@@ -1501,8 +1704,8 @@
   }
 
   ~StrictAlignmentAllocator() {
-    for (auto& p : allocated_array) {
-      delete [] p;
+    for (const auto& p : allocated_array) {
+      delete[] p;
     }
   }
 
@@ -1602,3 +1805,155 @@
   kill(getpid(), SIGUSR1);
   ASSERT_TRUE(signal_handler_on_altstack_done);
 }
+
+TEST(pthread, pthread_barrierattr_smoke) {
+  pthread_barrierattr_t attr;
+  ASSERT_EQ(0, pthread_barrierattr_init(&attr));
+  int pshared;
+  ASSERT_EQ(0, pthread_barrierattr_getpshared(&attr, &pshared));
+  ASSERT_EQ(PTHREAD_PROCESS_PRIVATE, pshared);
+  ASSERT_EQ(0, pthread_barrierattr_setpshared(&attr, PTHREAD_PROCESS_SHARED));
+  ASSERT_EQ(0, pthread_barrierattr_getpshared(&attr, &pshared));
+  ASSERT_EQ(PTHREAD_PROCESS_SHARED, pshared);
+  ASSERT_EQ(0, pthread_barrierattr_destroy(&attr));
+}
+
+struct BarrierTestHelperData {
+  size_t thread_count;
+  pthread_barrier_t barrier;
+  std::atomic<int> finished_mask;
+  std::atomic<int> serial_thread_count;
+  size_t iteration_count;
+  std::atomic<size_t> finished_iteration_count;
+
+  BarrierTestHelperData(size_t thread_count, size_t iteration_count)
+      : thread_count(thread_count), finished_mask(0), serial_thread_count(0),
+        iteration_count(iteration_count), finished_iteration_count(0) {
+  }
+};
+
+struct BarrierTestHelperArg {
+  int id;
+  BarrierTestHelperData* data;
+};
+
+static void BarrierTestHelper(BarrierTestHelperArg* arg) {
+  for (size_t i = 0; i < arg->data->iteration_count; ++i) {
+    int result = pthread_barrier_wait(&arg->data->barrier);
+    if (result == PTHREAD_BARRIER_SERIAL_THREAD) {
+      arg->data->serial_thread_count++;
+    } else {
+      ASSERT_EQ(0, result);
+    }
+    arg->data->finished_mask |= (1 << arg->id);
+    if (arg->data->finished_mask == ((1 << arg->data->thread_count) - 1)) {
+      ASSERT_EQ(1, arg->data->serial_thread_count);
+      arg->data->finished_iteration_count++;
+      arg->data->finished_mask = 0;
+      arg->data->serial_thread_count = 0;
+    }
+  }
+}
+
+TEST(pthread, pthread_barrier_smoke) {
+  const size_t BARRIER_ITERATION_COUNT = 10;
+  const size_t BARRIER_THREAD_COUNT = 10;
+  BarrierTestHelperData data(BARRIER_THREAD_COUNT, BARRIER_ITERATION_COUNT);
+  ASSERT_EQ(0, pthread_barrier_init(&data.barrier, nullptr, data.thread_count));
+  std::vector<pthread_t> threads(data.thread_count);
+  std::vector<BarrierTestHelperArg> args(threads.size());
+  for (size_t i = 0; i < threads.size(); ++i) {
+    args[i].id = i;
+    args[i].data = &data;
+    ASSERT_EQ(0, pthread_create(&threads[i], nullptr,
+                                reinterpret_cast<void* (*)(void*)>(BarrierTestHelper), &args[i]));
+  }
+  for (size_t i = 0; i < threads.size(); ++i) {
+    ASSERT_EQ(0, pthread_join(threads[i], nullptr));
+  }
+  ASSERT_EQ(data.iteration_count, data.finished_iteration_count);
+  ASSERT_EQ(0, pthread_barrier_destroy(&data.barrier));
+}
+
+struct BarrierDestroyTestArg {
+  std::atomic<int> tid;
+  pthread_barrier_t* barrier;
+};
+
+static void BarrierDestroyTestHelper(BarrierDestroyTestArg* arg) {
+  arg->tid = gettid();
+  ASSERT_EQ(0, pthread_barrier_wait(arg->barrier));
+}
+
+TEST(pthread, pthread_barrier_destroy) {
+  pthread_barrier_t barrier;
+  ASSERT_EQ(0, pthread_barrier_init(&barrier, nullptr, 2));
+  pthread_t thread;
+  BarrierDestroyTestArg arg;
+  arg.tid = 0;
+  arg.barrier = &barrier;
+  ASSERT_EQ(0, pthread_create(&thread, nullptr,
+                              reinterpret_cast<void* (*)(void*)>(BarrierDestroyTestHelper), &arg));
+  WaitUntilThreadSleep(arg.tid);
+  ASSERT_EQ(EBUSY, pthread_barrier_destroy(&barrier));
+  ASSERT_EQ(PTHREAD_BARRIER_SERIAL_THREAD, pthread_barrier_wait(&barrier));
+  // Verify if the barrier can be destroyed directly after pthread_barrier_wait().
+  ASSERT_EQ(0, pthread_barrier_destroy(&barrier));
+  ASSERT_EQ(0, pthread_join(thread, nullptr));
+#if defined(__BIONIC__)
+  ASSERT_EQ(EINVAL, pthread_barrier_destroy(&barrier));
+#endif
+}
+
+struct BarrierOrderingTestHelperArg {
+  pthread_barrier_t* barrier;
+  size_t* array;
+  size_t array_length;
+  size_t id;
+};
+
+void BarrierOrderingTestHelper(BarrierOrderingTestHelperArg* arg) {
+  const size_t ITERATION_COUNT = 10000;
+  for (size_t i = 1; i <= ITERATION_COUNT; ++i) {
+    arg->array[arg->id] = i;
+    int result = pthread_barrier_wait(arg->barrier);
+    ASSERT_TRUE(result == 0 || result == PTHREAD_BARRIER_SERIAL_THREAD);
+    for (size_t j = 0; j < arg->array_length; ++j) {
+      ASSERT_EQ(i, arg->array[j]);
+    }
+    result = pthread_barrier_wait(arg->barrier);
+    ASSERT_TRUE(result == 0 || result == PTHREAD_BARRIER_SERIAL_THREAD);
+  }
+}
+
+TEST(pthread, pthread_barrier_check_ordering) {
+  const size_t THREAD_COUNT = 4;
+  pthread_barrier_t barrier;
+  ASSERT_EQ(0, pthread_barrier_init(&barrier, nullptr, THREAD_COUNT));
+  size_t array[THREAD_COUNT];
+  std::vector<pthread_t> threads(THREAD_COUNT);
+  std::vector<BarrierOrderingTestHelperArg> args(THREAD_COUNT);
+  for (size_t i = 0; i < THREAD_COUNT; ++i) {
+    args[i].barrier = &barrier;
+    args[i].array = array;
+    args[i].array_length = THREAD_COUNT;
+    args[i].id = i;
+    ASSERT_EQ(0, pthread_create(&threads[i], nullptr,
+                                reinterpret_cast<void* (*)(void*)>(BarrierOrderingTestHelper),
+                                &args[i]));
+  }
+  for (size_t i = 0; i < THREAD_COUNT; ++i) {
+    ASSERT_EQ(0, pthread_join(threads[i], nullptr));
+  }
+}
+
+TEST(pthread, pthread_spinlock_smoke) {
+  pthread_spinlock_t lock;
+  ASSERT_EQ(0, pthread_spin_init(&lock, 0));
+  ASSERT_EQ(0, pthread_spin_trylock(&lock));
+  ASSERT_EQ(0, pthread_spin_unlock(&lock));
+  ASSERT_EQ(0, pthread_spin_lock(&lock));
+  ASSERT_EQ(EBUSY, pthread_spin_trylock(&lock));
+  ASSERT_EQ(0, pthread_spin_unlock(&lock));
+  ASSERT_EQ(0, pthread_spin_destroy(&lock));
+}
diff --git a/tests/pty_test.cpp b/tests/pty_test.cpp
index 7fe97e9..91d1f5e 100644
--- a/tests/pty_test.cpp
+++ b/tests/pty_test.cpp
@@ -19,6 +19,8 @@
 #include <pty.h>
 #include <sys/ioctl.h>
 
+#include "utils.h"
+
 TEST(pty, openpty) {
   int master, slave;
   char name[32];
@@ -58,10 +60,7 @@
 
   ASSERT_EQ(sid, getsid(0));
 
-  int status;
-  ASSERT_EQ(pid, waitpid(pid, &status, 0));
-  ASSERT_TRUE(WIFEXITED(status));
-  ASSERT_EQ(0, WEXITSTATUS(status));
+  AssertChildExited(pid, 0);
 
   close(master);
 }
diff --git a/tests/regex_test.cpp b/tests/regex_test.cpp
index d026221..0e7f8dd 100644
--- a/tests/regex_test.cpp
+++ b/tests/regex_test.cpp
@@ -36,3 +36,24 @@
 
   regfree(&re);
 }
+
+TEST(regex, match_offsets) {
+  regex_t re;
+  regmatch_t matches[1];
+  ASSERT_EQ(0, regcomp(&re, "b", 0));
+  ASSERT_EQ(0, regexec(&re, "abc", 1, matches, 0));
+  ASSERT_EQ(1, matches[0].rm_so);
+  ASSERT_EQ(2, matches[0].rm_eo);
+  regfree(&re);
+}
+
+TEST(regex, regerror_NULL_0) {
+  regex_t re;
+  int error = regcomp(&re, "*", REG_EXTENDED);
+  ASSERT_NE(0, error);
+
+  // Passing a null pointer and a size of 0 is a legitimate way to ask
+  // how large a buffer we would need for the error message.
+  int error_length = regerror(error, &re, nullptr, 0);
+  ASSERT_GT(error_length, 0);
+}
diff --git a/tests/semaphore_test.cpp b/tests/semaphore_test.cpp
index e517f81..7dc7225 100644
--- a/tests/semaphore_test.cpp
+++ b/tests/semaphore_test.cpp
@@ -24,6 +24,7 @@
 #include <unistd.h>
 
 #include "private/bionic_constants.h"
+#include "ScopedSignalHandler.h"
 
 TEST(semaphore, sem_init) {
   sem_t s;
@@ -117,10 +118,27 @@
   ts.tv_nsec = -1;
   ASSERT_EQ(-1, sem_timedwait(&s, &ts));
   ASSERT_EQ(EINVAL, errno);
+  errno = 0;
+  ts.tv_nsec = NS_PER_S;
+  ASSERT_EQ(-1, sem_timedwait(&s, &ts));
+  ASSERT_EQ(EINVAL, errno);
+
+  errno = 0;
+  ts.tv_nsec = NS_PER_S - 1;
+  ts.tv_sec = -1;
+  ASSERT_EQ(-1, sem_timedwait(&s, &ts));
+  ASSERT_EQ(ETIMEDOUT, errno);
 
   ASSERT_EQ(0, sem_destroy(&s));
 }
 
+TEST(semaphore_DeathTest, sem_timedwait_null_timeout) {
+  sem_t s;
+  ASSERT_EQ(0, sem_init(&s, 0, 0));
+
+  ASSERT_EXIT(sem_timedwait(&s, nullptr), testing::KilledBySignal(SIGSEGV), "");
+}
+
 TEST(semaphore, sem_getvalue) {
   sem_t s;
   ASSERT_EQ(0, sem_init(&s, 0, 0));
@@ -141,3 +159,71 @@
   ASSERT_EQ(0, sem_getvalue(&s, &i));
   ASSERT_EQ(1, i);
 }
+
+extern "C" void android_set_application_target_sdk_version(uint32_t target);
+
+static void sem_wait_test_signal_handler(int) {
+}
+
+static void* SemWaitEINTRThreadFn(void* arg) {
+  sem_t* sem = reinterpret_cast<sem_t*>(arg);
+  uintptr_t have_eintr = 0;
+  uintptr_t have_error = 0;
+  while (true) {
+    int result = sem_wait(sem);
+    if (result == 0) {
+      break;
+    }
+    if (result == -1) {
+      if (errno == EINTR) {
+        have_eintr = 1;
+      } else {
+        have_error = 1;
+        break;
+      }
+    }
+  }
+  return reinterpret_cast<void*>((have_eintr << 1) | have_error);
+}
+
+TEST(semaphore, sem_wait_no_EINTR_in_sdk_less_equal_than_23) {
+#if defined(__BIONIC__)
+  android_set_application_target_sdk_version(23U);
+  sem_t s;
+  ASSERT_EQ(0, sem_init(&s, 0, 0));
+  ScopedSignalHandler handler(SIGUSR1, sem_wait_test_signal_handler);
+  pthread_t thread;
+  ASSERT_EQ(0, pthread_create(&thread, nullptr, SemWaitEINTRThreadFn, &s));
+  // Give some time for the thread to run sem_wait.
+  usleep(500000);
+  ASSERT_EQ(0, pthread_kill(thread, SIGUSR1));
+  // Give some time for the thread to handle signal.
+  usleep(500000);
+  ASSERT_EQ(0, sem_post(&s));
+  void* result;
+  ASSERT_EQ(0, pthread_join(thread, &result));
+  ASSERT_EQ(0U, reinterpret_cast<uintptr_t>(result));
+#else
+  GTEST_LOG_(INFO) << "This test tests sem_wait's compatibility for old sdk versions";
+#endif
+}
+
+TEST(semaphore, sem_wait_EINTR_in_sdk_greater_than_23) {
+#if defined(__BIONIC__)
+  android_set_application_target_sdk_version(24U);
+#endif
+  sem_t s;
+  ASSERT_EQ(0, sem_init(&s, 0, 0));
+  ScopedSignalHandler handler(SIGUSR1, sem_wait_test_signal_handler);
+  pthread_t thread;
+  ASSERT_EQ(0, pthread_create(&thread, nullptr, SemWaitEINTRThreadFn, &s));
+  // Give some time for the thread to run sem_wait.
+  usleep(500000);
+  ASSERT_EQ(0, pthread_kill(thread, SIGUSR1));
+  // Give some time for the thread to handle signal.
+  usleep(500000);
+  ASSERT_EQ(0, sem_post(&s));
+  void* result;
+  ASSERT_EQ(0, pthread_join(thread, &result));
+  ASSERT_EQ(2U, reinterpret_cast<uintptr_t>(result));
+}
diff --git a/tests/setjmp_test.cpp b/tests/setjmp_test.cpp
index a3b5885..b7e856f 100644
--- a/tests/setjmp_test.cpp
+++ b/tests/setjmp_test.cpp
@@ -212,3 +212,52 @@
     CHECK_FREGS;
   }
 }
+
+#if defined(__arm__)
+#define __JB_SIGFLAG 0
+#elif defined(__aarch64__)
+#define __JB_SIGFLAG 0
+#elif defined(__i386__)
+#define __JB_SIGFLAG 7
+#elif defined(__x86_64)
+#define __JB_SIGFLAG 8
+#elif defined(__mips__) && defined(__LP64__)
+#define __JB_SIGFLAG 1
+#elif defined(__mips__)
+#define __JB_SIGFLAG 2
+#endif
+
+TEST(setjmp, setjmp_cookie) {
+  jmp_buf jb;
+  int value = setjmp(jb);
+  ASSERT_EQ(0, value);
+
+#if defined(__mips__) && !defined(__LP64__)
+  // round address to 8-byte boundry
+  uintptr_t jb_aligned = reinterpret_cast<uintptr_t>(jb) & ~7L;
+  long* sigflag = reinterpret_cast<long*>(jb_aligned) + __JB_SIGFLAG;
+#else
+  long* sigflag = reinterpret_cast<long*>(jb) + __JB_SIGFLAG;
+#endif
+
+  // Make sure there's actually a cookie.
+  EXPECT_NE(0, *sigflag & ~1);
+
+  // Wipe it out
+  *sigflag &= 1;
+  EXPECT_DEATH(longjmp(jb, 0), "");
+}
+
+TEST(setjmp, setjmp_cookie_checksum) {
+  jmp_buf jb;
+  int value = setjmp(jb);
+
+  if (value == 0) {
+    // Flip a bit.
+    reinterpret_cast<long*>(jb)[0] ^= 1;
+
+    EXPECT_DEATH(longjmp(jb, 1), "checksum mismatch");
+  } else {
+    fprintf(stderr, "setjmp_cookie_checksum: longjmp succeeded?");
+  }
+}
diff --git a/tests/signal_test.cpp b/tests/signal_test.cpp
index f8fdc3f..c5128ea 100644
--- a/tests/signal_test.cpp
+++ b/tests/signal_test.cpp
@@ -14,12 +14,14 @@
  * limitations under the License.
  */
 
+#include <errno.h>
 #include <signal.h>
+#include <sys/syscall.h>
+#include <sys/types.h>
+#include <unistd.h>
 
 #include <gtest/gtest.h>
 
-#include <errno.h>
-
 #include "ScopedSignalHandler.h"
 
 static size_t SIGNAL_MIN() {
@@ -375,3 +377,48 @@
 
   ASSERT_EQ(0, sigprocmask(SIG_SETMASK, &original_set, NULL));
 }
+
+#if defined(__BIONIC__)
+TEST(signal, rt_tgsigqueueinfo) {
+  // Test whether rt_tgsigqueueinfo allows sending arbitrary si_code values to self.
+  // If this fails, your kernel needs commit 66dd34a to be backported.
+  static constexpr char error_msg[] =
+    "\nPlease ensure that the following kernel patch has been applied:\n"
+    "* https://git.kernel.org/cgit/linux/kernel/git/torvalds/linux.git/commit/?id=66dd34ad31e5963d72a700ec3f2449291d322921\n";
+  static siginfo received;
+
+  struct sigaction handler;
+  memset(&handler, 0, sizeof(handler));
+  handler.sa_sigaction = [](int, siginfo_t* siginfo, void*) { received = *siginfo; };
+  handler.sa_flags = SA_SIGINFO;
+
+  ASSERT_EQ(0, sigaction(SIGUSR1, &handler, nullptr));
+
+  siginfo sent;
+  memset(&sent, 0, sizeof(sent));
+
+  sent.si_code = SI_TKILL;
+  ASSERT_EQ(0, syscall(SYS_rt_tgsigqueueinfo, getpid(), gettid(), SIGUSR1, &sent))
+    << "rt_tgsigqueueinfo failed: " << strerror(errno) << error_msg;
+  ASSERT_EQ(sent.si_code, received.si_code) << "rt_tgsigqueueinfo modified si_code, expected "
+                                            << sent.si_code << ", received " << received.si_code
+                                            << error_msg;
+
+  sent.si_code = SI_USER;
+  ASSERT_EQ(0, syscall(SYS_rt_tgsigqueueinfo, getpid(), gettid(), SIGUSR1, &sent))
+    << "rt_tgsigqueueinfo failed: " << strerror(errno) << error_msg;
+  ASSERT_EQ(sent.si_code, received.si_code) << "rt_tgsigqueueinfo modified si_code, expected "
+                                            << sent.si_code << ", received " << received.si_code
+                                            << error_msg;
+}
+
+#if defined(__arm__) || defined(__aarch64__) || defined(__i386__) || defined(__x86_64__)
+TEST(signal, sigset_size) {
+  // The setjmp implementations for ARM, AArch64, x86, and x86_64 assume that sigset_t can fit in a
+  // long. This is true because ARM and x86 have broken rt signal support, and AArch64 and x86_64
+  // both have a SIGRTMAX defined as 64.
+  static_assert(sizeof(sigset_t) <= sizeof(long), "sigset_t doesn't fit in a long");
+}
+
+#endif
+#endif
diff --git a/tests/stack_protector_test.cpp b/tests/stack_protector_test.cpp
index 22285d1..5f5a241 100644
--- a/tests/stack_protector_test.cpp
+++ b/tests/stack_protector_test.cpp
@@ -27,108 +27,83 @@
 #include <unistd.h>
 #include <set>
 
-extern "C" pid_t gettid();
+#include "private/bionic_tls.h"
 
-// For x86, bionic and glibc have per-thread stack guard values (all identical).
-#if defined(__i386__)
-static uint32_t GetGuardFromTls() {
-  uint32_t guard;
-  asm ("mov %%gs:0x14, %0": "=d" (guard));
-  return guard;
-}
+extern "C" pid_t gettid(); // glibc defines this but doesn't declare it anywhere.
+
+#if defined(__BIONIC__)
+extern uintptr_t __stack_chk_guard;
+#endif
 
 struct stack_protector_checker {
   std::set<pid_t> tids;
-  std::set<uint32_t> guards;
+  std::set<void*> guards;
 
   void Check() {
     pid_t tid = gettid();
-    uint32_t guard = GetGuardFromTls();
+    void* guard = __get_tls()[TLS_SLOT_STACK_GUARD];
 
-    printf("[thread %d] %%gs:0x14 = 0x%08x\n", tid, guard);
+    printf("[thread %d] TLS stack guard = %p\n", tid, guard);
 
     // Duplicate tid. gettid(2) bug? Seeing this would be very upsetting.
     ASSERT_TRUE(tids.find(tid) == tids.end());
 
-    // Uninitialized guard. Our bug. Note this is potentially flaky; we _could_ get
-    // four random zero bytes, but it should be vanishingly unlikely.
-    ASSERT_NE(guard, 0U);
+    // Uninitialized guard. Our bug. Note this is potentially flaky; we _could_
+    // get four random zero bytes, but it should be vanishingly unlikely.
+    ASSERT_NE(guard, nullptr);
+
+#if defined(__BIONIC__)
+    // bionic always has the global too.
+    ASSERT_EQ(__stack_chk_guard, reinterpret_cast<uintptr_t>(guard));
+#endif
 
     tids.insert(tid);
     guards.insert(guard);
   }
 };
 
-static void* ThreadGuardHelper(void* arg) {
-  stack_protector_checker* checker = reinterpret_cast<stack_protector_checker*>(arg);
-  checker->Check();
-  return NULL;
-}
-#endif // __i386__
-
 TEST(stack_protector, same_guard_per_thread) {
-#if defined(__i386__)
+  // Everyone has the TLS slot set, even if their stack protector
+  // implementation doesn't yet use it.
   stack_protector_checker checker;
-  size_t thread_count = 10;
-  for (size_t i = 0; i < thread_count; ++i) {
+
+  // Check the main thread.
+  ASSERT_EQ(getpid(), gettid()); // We are the main thread, right?
+  checker.Check();
+
+  size_t thread_count = 9;
+  for (size_t i = 1; i < thread_count; ++i) {
     pthread_t t;
-    ASSERT_EQ(0, pthread_create(&t, NULL, ThreadGuardHelper, &checker));
+    ASSERT_EQ(0, pthread_create(&t, NULL, [](void* arg) -> void* {
+      stack_protector_checker* checker = reinterpret_cast<stack_protector_checker*>(arg);
+      checker->Check();
+      return nullptr;
+    }, &checker));
     void* result;
     ASSERT_EQ(0, pthread_join(t, &result));
     ASSERT_EQ(NULL, result);
   }
   ASSERT_EQ(thread_count, checker.tids.size());
 
-  // bionic and glibc use the same guard for every thread.
+  // Both bionic and glibc use the same guard for every thread.
   ASSERT_EQ(1U, checker.guards.size());
-#else // __i386__
-  GTEST_LOG_(INFO) << "This test does nothing.\n";
-#endif // __i386__
 }
 
-// For ARM and MIPS, glibc has a global stack check guard value.
-#if defined(__BIONIC__) || defined(__arm__) || defined(__mips__)
-#define TEST_STACK_CHK_GUARD
-
-// Bionic has the global for x86 too, to support binaries that can run on
-// Android releases that didn't implement the TLS guard value.
-extern "C" uintptr_t __stack_chk_guard;
-
-/*
- * When this function returns, the stack canary will be inconsistent
- * with the previous value, which will generate a call to __stack_chk_fail(),
- * eventually resulting in a SIGABRT.
- *
- * This must be marked with "__attribute__ ((noinline))", to ensure the
- * compiler generates the proper stack guards around this function.
- */
-static char* dummy_buf;
-
-__attribute__ ((noinline))
-static void do_modify_stack_chk_guard() {
-  char buf[128];
-  // Store local array's address to global variable to force compiler to generate stack guards.
-  dummy_buf = buf;
-  __stack_chk_guard = 0x12345678;
-}
-
-#endif
-
 TEST(stack_protector, global_guard) {
-#if defined(TEST_STACK_CHK_GUARD)
+#if defined(__BIONIC__)
+  // Bionic always has a global, even if it's using TLS.
   ASSERT_NE(0, gettid());
   ASSERT_NE(0U, __stack_chk_guard);
-#else // TEST_STACK_CHK_GUARD
-  GTEST_LOG_(INFO) << "This test does nothing.\n";
-#endif // TEST_STACK_CHK_GUARD
+#else
+  GTEST_LOG_(INFO) << "glibc doesn't have a global __stack_chk_guard.\n";
+#endif
 }
 
 class stack_protector_DeathTest : public BionicDeathTest {};
 
 TEST_F(stack_protector_DeathTest, modify_stack_protector) {
-#if defined(TEST_STACK_CHK_GUARD)
-  ASSERT_EXIT(do_modify_stack_chk_guard(), testing::KilledBySignal(SIGABRT), "");
-#else // TEST_STACK_CHK_GUARD
-  GTEST_LOG_(INFO) << "This test does nothing.\n";
-#endif // TEST_STACK_CHK_GUARD
+  // In another file to prevent inlining, which removes stack protection.
+  extern void modify_stack_protector_test();
+  ASSERT_EXIT(modify_stack_protector_test(),
+              testing::KilledBySignal(SIGABRT), "stack corruption detected");
 }
diff --git a/tests/stack_protector_test_helper.cpp b/tests/stack_protector_test_helper.cpp
new file mode 100644
index 0000000..53a5e05
--- /dev/null
+++ b/tests/stack_protector_test_helper.cpp
@@ -0,0 +1,31 @@
+/*
+ * Copyright (C) 2012 The Android Open Source Project
+ *
+ * Licensed under the Apache License, Version 2.0 (the "License");
+ * you may not use this file except in compliance with the License.
+ * You may obtain a copy of the License at
+ *
+ *      http://www.apache.org/licenses/LICENSE-2.0
+ *
+ * Unless required by applicable law or agreed to in writing, software
+ * distributed under the License is distributed on an "AS IS" BASIS,
+ * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
+ * See the License for the specific language governing permissions and
+ * limitations under the License.
+ */
+
+// Deliberately overwrite the stack canary.
+__attribute__((noinline)) void modify_stack_protector_test() {
+  char buf[128];
+  // We can't use memset here because it's fortified, and we want to test
+  // the line of defense *after* that.
+  // Without volatile, the generic x86/x86-64 targets don't write to the stack.
+  volatile char* p = buf;
+  int size = static_cast<int>(sizeof(buf) + 1);
+#if __x86_64__
+  // The generic x86-64 target leaves an 8-byte gap between `buf` and the stack guard.
+  // We only need to corrupt one byte though.
+  size += 8;
+#endif
+  while ((p - buf) < size) *p++ = '\0';
+}
diff --git a/tests/stdio_ext_test.cpp b/tests/stdio_ext_test.cpp
index c95cbbd..7872567 100644
--- a/tests/stdio_ext_test.cpp
+++ b/tests/stdio_ext_test.cpp
@@ -30,6 +30,7 @@
 #include <locale.h>
 
 #include "TemporaryFile.h"
+#include "utils.h"
 
 TEST(stdio_ext, __fbufsize) {
   FILE* fp = fopen("/proc/version", "r");
@@ -140,3 +141,24 @@
   ASSERT_EQ(FSETLOCKING_INTERNAL, __fsetlocking(fp, FSETLOCKING_QUERY));
   fclose(fp);
 }
+
+static void LockingByCallerHelper(std::atomic<pid_t>* pid) {
+  *pid = gettid();
+  flockfile(stdout);
+  funlockfile(stdout);
+}
+
+TEST(stdio_ext, __fsetlocking_BYCALLER) {
+  // Check if users can use flockfile/funlockfile to protect stdio operations.
+  int old_state = __fsetlocking(stdout, FSETLOCKING_BYCALLER);
+  flockfile(stdout);
+  pthread_t thread;
+  std::atomic<pid_t> pid(0);
+  ASSERT_EQ(0, pthread_create(&thread, nullptr,
+                              reinterpret_cast<void* (*)(void*)>(LockingByCallerHelper), &pid));
+  WaitUntilThreadSleep(pid);
+  funlockfile(stdout);
+
+  ASSERT_EQ(0, pthread_join(thread, nullptr));
+  __fsetlocking(stdout, old_state);
+}
diff --git a/tests/stdio_nofortify_test.cpp b/tests/stdio_nofortify_test.cpp
new file mode 100644
index 0000000..9bdcb03
--- /dev/null
+++ b/tests/stdio_nofortify_test.cpp
@@ -0,0 +1,12 @@
+
+#ifdef _FORTIFY_SOURCE
+#undef _FORTIFY_SOURCE
+#endif
+
+#define NOFORTIFY
+
+#include "stdio_test.cpp"
+
+#if defined(_FORTIFY_SOURCE)
+#error "_FORTIFY_SOURCE has been redefined, fix the code to remove this redefinition."
+#endif
diff --git a/tests/stdio_test.cpp b/tests/stdio_test.cpp
index 62677cd..7e82612 100644
--- a/tests/stdio_test.cpp
+++ b/tests/stdio_test.cpp
@@ -31,14 +31,20 @@
 
 #include "TemporaryFile.h"
 
-TEST(stdio, flockfile_18208568_stderr) {
+#if defined(NOFORTIFY)
+#define STDIO_TEST stdio_nofortify
+#else
+#define STDIO_TEST stdio
+#endif
+
+TEST(STDIO_TEST, flockfile_18208568_stderr) {
   // Check that we have a _recursive_ mutex for flockfile.
   flockfile(stderr);
   feof(stderr); // We don't care about the result, but this needs to take the lock.
   funlockfile(stderr);
 }
 
-TEST(stdio, flockfile_18208568_regular) {
+TEST(STDIO_TEST, flockfile_18208568_regular) {
   // We never had a bug for streams other than stdin/stdout/stderr, but test anyway.
   FILE* fp = fopen("/dev/null", "w");
   ASSERT_TRUE(fp != NULL);
@@ -48,7 +54,7 @@
   fclose(fp);
 }
 
-TEST(stdio, tmpfile_fileno_fprintf_rewind_fgets) {
+TEST(STDIO_TEST, tmpfile_fileno_fprintf_rewind_fgets) {
   FILE* fp = tmpfile();
   ASSERT_TRUE(fp != NULL);
 
@@ -73,7 +79,13 @@
   fclose(fp);
 }
 
-TEST(stdio, dprintf) {
+TEST(STDIO_TEST, tmpfile64) {
+  FILE* fp = tmpfile64();
+  ASSERT_TRUE(fp != nullptr);
+  fclose(fp);
+}
+
+TEST(STDIO_TEST, dprintf) {
   TemporaryFile tf;
 
   int rc = dprintf(tf.fd, "hello\n");
@@ -91,7 +103,7 @@
   fclose(tfile);
 }
 
-TEST(stdio, getdelim) {
+TEST(STDIO_TEST, getdelim) {
   FILE* fp = tmpfile();
   ASSERT_TRUE(fp != NULL);
 
@@ -126,7 +138,7 @@
   fclose(fp);
 }
 
-TEST(stdio, getdelim_invalid) {
+TEST(STDIO_TEST, getdelim_invalid) {
   FILE* fp = tmpfile();
   ASSERT_TRUE(fp != NULL);
 
@@ -151,7 +163,7 @@
   fclose(fp);
 }
 
-TEST(stdio, getdelim_directory) {
+TEST(STDIO_TEST, getdelim_directory) {
   FILE* fp = fopen("/proc", "r");
   ASSERT_TRUE(fp != NULL);
   char* word_read;
@@ -160,7 +172,7 @@
   fclose(fp);
 }
 
-TEST(stdio, getline) {
+TEST(STDIO_TEST, getline) {
   FILE* fp = tmpfile();
   ASSERT_TRUE(fp != NULL);
 
@@ -202,7 +214,7 @@
   fclose(fp);
 }
 
-TEST(stdio, getline_invalid) {
+TEST(STDIO_TEST, getline_invalid) {
   FILE* fp = tmpfile();
   ASSERT_TRUE(fp != NULL);
 
@@ -227,7 +239,7 @@
   fclose(fp);
 }
 
-TEST(stdio, printf_ssize_t) {
+TEST(STDIO_TEST, printf_ssize_t) {
   // http://b/8253769
   ASSERT_EQ(sizeof(ssize_t), sizeof(long int));
   ASSERT_EQ(sizeof(ssize_t), sizeof(size_t));
@@ -240,20 +252,20 @@
 }
 
 // https://code.google.com/p/android/issues/detail?id=64886
-TEST(stdio, snprintf_a) {
+TEST(STDIO_TEST, snprintf_a) {
   char buf[BUFSIZ];
   EXPECT_EQ(23, snprintf(buf, sizeof(buf), "<%a>", 9990.235));
   EXPECT_STREQ("<0x1.3831e147ae148p+13>", buf);
 }
 
-TEST(stdio, snprintf_lc) {
+TEST(STDIO_TEST, snprintf_lc) {
   char buf[BUFSIZ];
   wint_t wc = L'a';
   EXPECT_EQ(3, snprintf(buf, sizeof(buf), "<%lc>", wc));
   EXPECT_STREQ("<a>", buf);
 }
 
-TEST(stdio, snprintf_ls) {
+TEST(STDIO_TEST, snprintf_ls) {
   char buf[BUFSIZ];
   wchar_t* ws = NULL;
   EXPECT_EQ(8, snprintf(buf, sizeof(buf), "<%ls>", ws));
@@ -265,7 +277,7 @@
   EXPECT_STREQ("<hi>", buf);
 }
 
-TEST(stdio, snprintf_n) {
+TEST(STDIO_TEST, snprintf_n) {
 #if defined(__BIONIC__)
   // http://b/14492135
   char buf[32];
@@ -274,11 +286,11 @@
   EXPECT_EQ(1234, i);
   EXPECT_STREQ("a n b", buf);
 #else
-  GTEST_LOG_(INFO) << "This test does nothing.\n";
+  GTEST_LOG_(INFO) << "This test does nothing on glibc.\n";
 #endif
 }
 
-TEST(stdio, snprintf_smoke) {
+TEST(STDIO_TEST, snprintf_smoke) {
   char buf[BUFSIZ];
 
   snprintf(buf, sizeof(buf), "a");
@@ -401,7 +413,7 @@
   EXPECT_STREQ(minus_inf, buf) << fmt_plus;
 }
 
-TEST(stdio, snprintf_inf_nan) {
+TEST(STDIO_TEST, snprintf_inf_nan) {
   CheckInfNan(snprintf, "%a", "%+a", "-inf", "inf", "+inf", "-nan", "nan", "+nan");
   CheckInfNan(snprintf, "%A", "%+A", "-INF", "INF", "+INF", "-NAN", "NAN", "+NAN");
   CheckInfNan(snprintf, "%e", "%+e", "-inf", "inf", "+inf", "-nan", "nan", "+nan");
@@ -412,7 +424,7 @@
   CheckInfNan(snprintf, "%G", "%+G", "-INF", "INF", "+INF", "-NAN", "NAN", "+NAN");
 }
 
-TEST(stdio, wsprintf_inf_nan) {
+TEST(STDIO_TEST, wsprintf_inf_nan) {
   CheckInfNan(swprintf, L"%a", L"%+a", L"-inf", L"inf", L"+inf", L"-nan", L"nan", L"+nan");
   CheckInfNan(swprintf, L"%A", L"%+A", L"-INF", L"INF", L"+INF", L"-NAN", L"NAN", L"+NAN");
   CheckInfNan(swprintf, L"%e", L"%+e", L"-inf", L"inf", L"+inf", L"-nan", L"nan", L"+nan");
@@ -423,19 +435,19 @@
   CheckInfNan(swprintf, L"%G", L"%+G", L"-INF", L"INF", L"+INF", L"-NAN", L"NAN", L"+NAN");
 }
 
-TEST(stdio, snprintf_d_INT_MAX) {
+TEST(STDIO_TEST, snprintf_d_INT_MAX) {
   char buf[BUFSIZ];
   snprintf(buf, sizeof(buf), "%d", INT_MAX);
   EXPECT_STREQ("2147483647", buf);
 }
 
-TEST(stdio, snprintf_d_INT_MIN) {
+TEST(STDIO_TEST, snprintf_d_INT_MIN) {
   char buf[BUFSIZ];
   snprintf(buf, sizeof(buf), "%d", INT_MIN);
   EXPECT_STREQ("-2147483648", buf);
 }
 
-TEST(stdio, snprintf_ld_LONG_MAX) {
+TEST(STDIO_TEST, snprintf_ld_LONG_MAX) {
   char buf[BUFSIZ];
   snprintf(buf, sizeof(buf), "%ld", LONG_MAX);
 #if __LP64__
@@ -445,7 +457,7 @@
 #endif
 }
 
-TEST(stdio, snprintf_ld_LONG_MIN) {
+TEST(STDIO_TEST, snprintf_ld_LONG_MIN) {
   char buf[BUFSIZ];
   snprintf(buf, sizeof(buf), "%ld", LONG_MIN);
 #if __LP64__
@@ -455,19 +467,19 @@
 #endif
 }
 
-TEST(stdio, snprintf_lld_LLONG_MAX) {
+TEST(STDIO_TEST, snprintf_lld_LLONG_MAX) {
   char buf[BUFSIZ];
   snprintf(buf, sizeof(buf), "%lld", LLONG_MAX);
   EXPECT_STREQ("9223372036854775807", buf);
 }
 
-TEST(stdio, snprintf_lld_LLONG_MIN) {
+TEST(STDIO_TEST, snprintf_lld_LLONG_MIN) {
   char buf[BUFSIZ];
   snprintf(buf, sizeof(buf), "%lld", LLONG_MIN);
   EXPECT_STREQ("-9223372036854775808", buf);
 }
 
-TEST(stdio, snprintf_e) {
+TEST(STDIO_TEST, snprintf_e) {
   char buf[BUFSIZ];
 
   snprintf(buf, sizeof(buf), "%e", 1.5);
@@ -477,7 +489,7 @@
   EXPECT_STREQ("1.500000e+00", buf);
 }
 
-TEST(stdio, snprintf_negative_zero_5084292) {
+TEST(STDIO_TEST, snprintf_negative_zero_5084292) {
   char buf[BUFSIZ];
 
   snprintf(buf, sizeof(buf), "%e", -0.0);
@@ -498,7 +510,7 @@
   EXPECT_STREQ("-0X0P+0", buf);
 }
 
-TEST(stdio, snprintf_utf8_15439554) {
+TEST(STDIO_TEST, snprintf_utf8_15439554) {
   locale_t cloc = newlocale(LC_ALL, "C.UTF-8", 0);
   locale_t old_locale = uselocale(cloc);
 
@@ -522,7 +534,41 @@
   freelocale(cloc);
 }
 
-TEST(stdio, fprintf_failures_7229520) {
+static void* snprintf_small_stack_fn(void*) {
+  // Make life (realistically) hard for ourselves by allocating our own buffer for the result.
+  char buf[PATH_MAX];
+  snprintf(buf, sizeof(buf), "/proc/%d", getpid());
+  return nullptr;
+}
+
+TEST(STDIO_TEST, snprintf_small_stack) {
+  // Is it safe to call snprintf on a thread with a small stack?
+  // (The snprintf implementation puts some pretty large buffers on the stack.)
+  pthread_attr_t a;
+  ASSERT_EQ(0, pthread_attr_init(&a));
+  ASSERT_EQ(0, pthread_attr_setstacksize(&a, PTHREAD_STACK_MIN));
+
+  pthread_t t;
+  ASSERT_EQ(0, pthread_create(&t, &a, snprintf_small_stack_fn, nullptr));
+  ASSERT_EQ(0, pthread_join(t, nullptr));
+}
+
+TEST(STDIO_TEST, snprintf_asterisk_overflow) {
+  char buf[128];
+  ASSERT_EQ(5, snprintf(buf, sizeof(buf), "%.*s%c", 4, "hello world", '!'));
+  ASSERT_EQ(12, snprintf(buf, sizeof(buf), "%.*s%c", INT_MAX/2, "hello world", '!'));
+  ASSERT_EQ(12, snprintf(buf, sizeof(buf), "%.*s%c", INT_MAX-1, "hello world", '!'));
+  ASSERT_EQ(12, snprintf(buf, sizeof(buf), "%.*s%c", INT_MAX, "hello world", '!'));
+  ASSERT_EQ(12, snprintf(buf, sizeof(buf), "%.*s%c", -1, "hello world", '!'));
+
+  // INT_MAX-1, INT_MAX, INT_MAX+1.
+  ASSERT_EQ(12, snprintf(buf, sizeof(buf), "%.2147483646s%c", "hello world", '!'));
+  ASSERT_EQ(12, snprintf(buf, sizeof(buf), "%.2147483647s%c", "hello world", '!'));
+  ASSERT_EQ(-1, snprintf(buf, sizeof(buf), "%.2147483648s%c", "hello world", '!'));
+  ASSERT_EQ(ENOMEM, errno);
+}
+
+TEST(STDIO_TEST, fprintf_failures_7229520) {
   // http://b/7229520
   FILE* fp;
 
@@ -545,7 +591,7 @@
   ASSERT_EQ(-1, fclose(fp));
 }
 
-TEST(stdio, popen) {
+TEST(STDIO_TEST, popen) {
   FILE* fp = popen("cat /proc/version", "r");
   ASSERT_TRUE(fp != NULL);
 
@@ -557,7 +603,7 @@
   ASSERT_EQ(0, pclose(fp));
 }
 
-TEST(stdio, getc) {
+TEST(STDIO_TEST, getc) {
   FILE* fp = fopen("/proc/version", "r");
   ASSERT_TRUE(fp != NULL);
   ASSERT_EQ('L', getc(fp));
@@ -568,14 +614,14 @@
   fclose(fp);
 }
 
-TEST(stdio, putc) {
+TEST(STDIO_TEST, putc) {
   FILE* fp = fopen("/proc/version", "r");
   ASSERT_TRUE(fp != NULL);
   ASSERT_EQ(EOF, putc('x', fp));
   fclose(fp);
 }
 
-TEST(stdio, sscanf) {
+TEST(STDIO_TEST, sscanf) {
   char s1[123];
   int i1;
   double d1;
@@ -586,7 +632,7 @@
   ASSERT_DOUBLE_EQ(1.23, d1);
 }
 
-TEST(stdio, cantwrite_EBADF) {
+TEST(STDIO_TEST, cantwrite_EBADF) {
   // If we open a file read-only...
   FILE* fp = fopen("/proc/version", "r");
 
@@ -626,7 +672,7 @@
 
 // Tests that we can only have a consistent and correct fpos_t when using
 // f*pos functions (i.e. fpos doesn't get inside a multi byte character).
-TEST(stdio, consistent_fpos_t) {
+TEST(STDIO_TEST, consistent_fpos_t) {
   ASSERT_STREQ("C.UTF-8", setlocale(LC_CTYPE, "C.UTF-8"));
   uselocale(LC_GLOBAL_LOCALE);
 
@@ -690,7 +736,7 @@
 }
 
 // Exercise the interaction between fpos and seek.
-TEST(stdio, fpos_t_and_seek) {
+TEST(STDIO_TEST, fpos_t_and_seek) {
   ASSERT_STREQ("C.UTF-8", setlocale(LC_CTYPE, "C.UTF-8"));
   uselocale(LC_GLOBAL_LOCALE);
 
@@ -750,7 +796,7 @@
   fclose(fp);
 }
 
-TEST(stdio, fmemopen) {
+TEST(STDIO_TEST, fmemopen) {
   char buf[16];
   memset(buf, 0, sizeof(buf));
   FILE* fp = fmemopen(buf, sizeof(buf), "r+");
@@ -770,7 +816,7 @@
   fclose(fp);
 }
 
-TEST(stdio, fmemopen_NULL) {
+TEST(STDIO_TEST, fmemopen_NULL) {
   FILE* fp = fmemopen(nullptr, 128, "r+");
   ASSERT_NE(EOF, fputs("xyz\n", fp));
 
@@ -784,7 +830,7 @@
   fclose(fp);
 }
 
-TEST(stdio, fmemopen_EINVAL) {
+TEST(STDIO_TEST, fmemopen_EINVAL) {
   char buf[16];
 
   // Invalid size.
@@ -798,7 +844,7 @@
   ASSERT_EQ(EINVAL, errno);
 }
 
-TEST(stdio, open_memstream) {
+TEST(STDIO_TEST, open_memstream) {
   char* p = nullptr;
   size_t size = 0;
   FILE* fp = open_memstream(&p, &size);
@@ -810,7 +856,7 @@
   free(p);
 }
 
-TEST(stdio, open_memstream_EINVAL) {
+TEST(STDIO_TEST, open_memstream_EINVAL) {
 #if defined(__BIONIC__)
   char* p;
   size_t size;
@@ -825,11 +871,11 @@
   ASSERT_EQ(nullptr, open_memstream(&p, nullptr));
   ASSERT_EQ(EINVAL, errno);
 #else
-  GTEST_LOG_(INFO) << "This test does nothing.\n";
+  GTEST_LOG_(INFO) << "This test does nothing on glibc.\n";
 #endif
 }
 
-TEST(stdio, fdopen_CLOEXEC) {
+TEST(STDIO_TEST, fdopen_CLOEXEC) {
   int fd = open("/proc/version", O_RDONLY);
   ASSERT_TRUE(fd != -1);
 
@@ -850,7 +896,7 @@
   close(fd);
 }
 
-TEST(stdio, freopen_CLOEXEC) {
+TEST(STDIO_TEST, freopen_CLOEXEC) {
   FILE* fp = fopen("/proc/version", "r");
   ASSERT_TRUE(fp != NULL);
 
@@ -869,9 +915,17 @@
   fclose(fp);
 }
 
+TEST(STDIO_TEST, fopen64_freopen64) {
+  FILE* fp = fopen64("/proc/version", "r");
+  ASSERT_TRUE(fp != nullptr);
+  fp = freopen64("/proc/version", "re", fp);
+  ASSERT_TRUE(fp != nullptr);
+  fclose(fp);
+}
+
 // https://code.google.com/p/android/issues/detail?id=81155
 // http://b/18556607
-TEST(stdio, fread_unbuffered_pathological_performance) {
+TEST(STDIO_TEST, fread_unbuffered_pathological_performance) {
   FILE* fp = fopen("/dev/zero", "r");
   ASSERT_TRUE(fp != NULL);
 
@@ -900,7 +954,7 @@
   }
 }
 
-TEST(stdio, fread_EOF) {
+TEST(STDIO_TEST, fread_EOF) {
   std::string digits("0123456789");
   FILE* fp = fmemopen(&digits[0], digits.size(), "r");
 
@@ -934,11 +988,11 @@
   fclose(fp);
 }
 
-TEST(stdio, fread_from_write_only_stream_slow_path) {
+TEST(STDIO_TEST, fread_from_write_only_stream_slow_path) {
   test_fread_from_write_only_stream(1);
 }
 
-TEST(stdio, fread_from_write_only_stream_fast_path) {
+TEST(STDIO_TEST, fread_from_write_only_stream_fast_path) {
   test_fread_from_write_only_stream(64*1024);
 }
 
@@ -956,7 +1010,7 @@
 
   // But hitting EOF doesn't prevent us from writing...
   errno = 0;
-  ASSERT_EQ(1U, fwrite("2", 1, 1, fp)) << errno;
+  ASSERT_EQ(1U, fwrite("2", 1, 1, fp)) << strerror(errno);
 
   // And if we rewind, everything's there.
   rewind(fp);
@@ -967,16 +1021,16 @@
   fclose(fp);
 }
 
-TEST(stdio, fwrite_after_fread_slow_path) {
+TEST(STDIO_TEST, fwrite_after_fread_slow_path) {
   test_fwrite_after_fread(16);
 }
 
-TEST(stdio, fwrite_after_fread_fast_path) {
+TEST(STDIO_TEST, fwrite_after_fread_fast_path) {
   test_fwrite_after_fread(64*1024);
 }
 
 // http://b/19172514
-TEST(stdio, fread_after_fseek) {
+TEST(STDIO_TEST, fread_after_fseek) {
   TemporaryFile tf;
 
   FILE* fp = fopen(tf.filename, "w+");
@@ -1005,10 +1059,241 @@
   ASSERT_EQ(memcmp(file_data+cur_location, buffer, 8192), 0);
 
   // Small backwards seek to verify fseek does not reuse the internal buffer.
-  ASSERT_EQ(0, fseek(fp, -22, SEEK_CUR));
+  ASSERT_EQ(0, fseek(fp, -22, SEEK_CUR)) << strerror(errno);
   cur_location = static_cast<size_t>(ftell(fp));
   ASSERT_EQ(22U, fread(buffer, 1, 22, fp));
   ASSERT_EQ(memcmp(file_data+cur_location, buffer, 22), 0);
 
   fclose(fp);
 }
+
+// https://code.google.com/p/android/issues/detail?id=184847
+TEST(STDIO_TEST, fread_EOF_184847) {
+  TemporaryFile tf;
+  char buf[6] = {0};
+
+  FILE* fw = fopen(tf.filename, "w");
+  ASSERT_TRUE(fw != nullptr);
+
+  FILE* fr = fopen(tf.filename, "r");
+  ASSERT_TRUE(fr != nullptr);
+
+  fwrite("a", 1, 1, fw);
+  fflush(fw);
+  ASSERT_EQ(1U, fread(buf, 1, 1, fr));
+  ASSERT_STREQ("a", buf);
+
+  // 'fr' is now at EOF.
+  ASSERT_EQ(0U, fread(buf, 1, 1, fr));
+  ASSERT_TRUE(feof(fr));
+
+  // Write some more...
+  fwrite("z", 1, 1, fw);
+  fflush(fw);
+
+  // ...and check that we can read it back.
+  // (BSD thinks that once a stream has hit EOF, it must always return EOF. SysV disagrees.)
+  ASSERT_EQ(1U, fread(buf, 1, 1, fr));
+  ASSERT_STREQ("z", buf);
+
+  // But now we're done.
+  ASSERT_EQ(0U, fread(buf, 1, 1, fr));
+
+  fclose(fr);
+  fclose(fw);
+}
+
+TEST(STDIO_TEST, fclose_invalidates_fd) {
+  // The typical error we're trying to help people catch involves accessing
+  // memory after it's been freed. But we know that stdin/stdout/stderr are
+  // special and don't get deallocated, so this test uses stdin.
+  ASSERT_EQ(0, fclose(stdin));
+
+  // Even though using a FILE* after close is undefined behavior, I've closed
+  // this bug as "WAI" too many times. We shouldn't hand out stale fds,
+  // especially because they might actually correspond to a real stream.
+  errno = 0;
+  ASSERT_EQ(-1, fileno(stdin));
+  ASSERT_EQ(EBADF, errno);
+}
+
+TEST(STDIO_TEST, fseek_ftell_unseekable) {
+#if defined(__BIONIC__) // glibc has fopencookie instead.
+  auto read_fn = [](void*, char*, int) { return -1; };
+  FILE* fp = funopen(nullptr, read_fn, nullptr, nullptr, nullptr);
+  ASSERT_TRUE(fp != nullptr);
+
+  // Check that ftell balks on an unseekable FILE*.
+  errno = 0;
+  ASSERT_EQ(-1, ftell(fp));
+  ASSERT_EQ(ESPIPE, errno);
+
+  // SEEK_CUR is rewritten as SEEK_SET internally...
+  errno = 0;
+  ASSERT_EQ(-1, fseek(fp, 0, SEEK_CUR));
+  ASSERT_EQ(ESPIPE, errno);
+
+  // ...so it's worth testing the direct seek path too.
+  errno = 0;
+  ASSERT_EQ(-1, fseek(fp, 0, SEEK_SET));
+  ASSERT_EQ(ESPIPE, errno);
+
+  fclose(fp);
+#else
+  GTEST_LOG_(INFO) << "glibc uses fopencookie instead.\n";
+#endif
+}
+
+TEST(STDIO_TEST, funopen_EINVAL) {
+#if defined(__BIONIC__)
+  errno = 0;
+  ASSERT_EQ(nullptr, funopen(nullptr, nullptr, nullptr, nullptr, nullptr));
+  ASSERT_EQ(EINVAL, errno);
+#else
+  GTEST_LOG_(INFO) << "glibc uses fopencookie instead.\n";
+#endif
+}
+
+TEST(STDIO_TEST, funopen_seek) {
+#if defined(__BIONIC__)
+  auto read_fn = [](void*, char*, int) { return -1; };
+
+  auto seek_fn = [](void*, fpos_t, int) -> fpos_t { return 0xfedcba12; };
+  auto seek64_fn = [](void*, fpos64_t, int) -> fpos64_t { return 0xfedcba12345678; };
+
+  FILE* fp = funopen(nullptr, read_fn, nullptr, seek_fn, nullptr);
+  ASSERT_TRUE(fp != nullptr);
+  fpos_t pos;
+#if defined(__LP64__)
+  EXPECT_EQ(0, fgetpos(fp, &pos)) << strerror(errno);
+  EXPECT_EQ(0xfedcba12LL, pos);
+#else
+  EXPECT_EQ(-1, fgetpos(fp, &pos)) << strerror(errno);
+  EXPECT_EQ(EOVERFLOW, errno);
+#endif
+
+  FILE* fp64 = funopen64(nullptr, read_fn, nullptr, seek64_fn, nullptr);
+  ASSERT_TRUE(fp64 != nullptr);
+  fpos64_t pos64;
+  EXPECT_EQ(0, fgetpos64(fp64, &pos64)) << strerror(errno);
+  EXPECT_EQ(0xfedcba12345678, pos64);
+#else
+  GTEST_LOG_(INFO) << "glibc uses fopencookie instead.\n";
+#endif
+}
+
+TEST(STDIO_TEST, lots_of_concurrent_files) {
+  std::vector<TemporaryFile*> tfs;
+  std::vector<FILE*> fps;
+
+  for (size_t i = 0; i < 256; ++i) {
+    TemporaryFile* tf = new TemporaryFile;
+    tfs.push_back(tf);
+    FILE* fp = fopen(tf->filename, "w+");
+    fps.push_back(fp);
+    fprintf(fp, "hello %zu!\n", i);
+    fflush(fp);
+  }
+
+  for (size_t i = 0; i < 256; ++i) {
+    rewind(fps[i]);
+
+    char buf[BUFSIZ];
+    ASSERT_TRUE(fgets(buf, sizeof(buf), fps[i]) != nullptr);
+
+    char expected[BUFSIZ];
+    snprintf(expected, sizeof(expected), "hello %zu!\n", i);
+    ASSERT_STREQ(expected, buf);
+
+    fclose(fps[i]);
+    delete tfs[i];
+  }
+}
+
+static void AssertFileOffsetAt(FILE* fp, off64_t offset) {
+  EXPECT_EQ(offset, ftell(fp));
+  EXPECT_EQ(offset, ftello(fp));
+  EXPECT_EQ(offset, ftello64(fp));
+  fpos_t pos;
+  fpos64_t pos64;
+  EXPECT_EQ(0, fgetpos(fp, &pos));
+  EXPECT_EQ(0, fgetpos64(fp, &pos64));
+#if defined(__BIONIC__)
+  EXPECT_EQ(offset, static_cast<off64_t>(pos));
+  EXPECT_EQ(offset, static_cast<off64_t>(pos64));
+#else
+  GTEST_LOG_(INFO) << "glibc's fpos_t is opaque.\n";
+#endif
+}
+
+TEST(STDIO_TEST, seek_tell_family_smoke) {
+  TemporaryFile tf;
+  FILE* fp = fdopen(tf.fd, "w+");
+
+  // Initially we should be at 0.
+  AssertFileOffsetAt(fp, 0);
+
+  // Seek to offset 8192.
+  ASSERT_EQ(0, fseek(fp, 8192, SEEK_SET));
+  AssertFileOffsetAt(fp, 8192);
+  fpos_t eight_k_pos;
+  ASSERT_EQ(0, fgetpos(fp, &eight_k_pos));
+
+  // Seek forward another 8192...
+  ASSERT_EQ(0, fseek(fp, 8192, SEEK_CUR));
+  AssertFileOffsetAt(fp, 8192 + 8192);
+  fpos64_t sixteen_k_pos64;
+  ASSERT_EQ(0, fgetpos64(fp, &sixteen_k_pos64));
+
+  // Seek back 8192...
+  ASSERT_EQ(0, fseek(fp, -8192, SEEK_CUR));
+  AssertFileOffsetAt(fp, 8192);
+
+  // Since we haven't written anything, the end is also at 0.
+  ASSERT_EQ(0, fseek(fp, 0, SEEK_END));
+  AssertFileOffsetAt(fp, 0);
+
+  // Check that our fpos64_t from 16KiB works...
+  ASSERT_EQ(0, fsetpos64(fp, &sixteen_k_pos64));
+  AssertFileOffsetAt(fp, 8192 + 8192);
+  // ...as does our fpos_t from 8192.
+  ASSERT_EQ(0, fsetpos(fp, &eight_k_pos));
+  AssertFileOffsetAt(fp, 8192);
+
+  // Do fseeko and fseeko64 work too?
+  ASSERT_EQ(0, fseeko(fp, 1234, SEEK_SET));
+  AssertFileOffsetAt(fp, 1234);
+  ASSERT_EQ(0, fseeko64(fp, 5678, SEEK_SET));
+  AssertFileOffsetAt(fp, 5678);
+
+  fclose(fp);
+}
+
+TEST(STDIO_TEST, fseek_fseeko_EINVAL) {
+  TemporaryFile tf;
+  FILE* fp = fdopen(tf.fd, "w+");
+
+  // Bad whence.
+  errno = 0;
+  ASSERT_EQ(-1, fseek(fp, 0, 123));
+  ASSERT_EQ(EINVAL, errno);
+  errno = 0;
+  ASSERT_EQ(-1, fseeko(fp, 0, 123));
+  ASSERT_EQ(EINVAL, errno);
+  errno = 0;
+  ASSERT_EQ(-1, fseeko64(fp, 0, 123));
+  ASSERT_EQ(EINVAL, errno);
+
+  // Bad offset.
+  errno = 0;
+  ASSERT_EQ(-1, fseek(fp, -1, SEEK_SET));
+  ASSERT_EQ(EINVAL, errno);
+  errno = 0;
+  ASSERT_EQ(-1, fseeko(fp, -1, SEEK_SET));
+  ASSERT_EQ(EINVAL, errno);
+  errno = 0;
+  ASSERT_EQ(-1, fseeko64(fp, -1, SEEK_SET));
+  ASSERT_EQ(EINVAL, errno);
+
+  fclose(fp);
+}
diff --git a/tests/stdlib_test.cpp b/tests/stdlib_test.cpp
index 050f5a7..6ae6cda 100644
--- a/tests/stdlib_test.cpp
+++ b/tests/stdlib_test.cpp
@@ -15,8 +15,10 @@
  */
 
 #include <gtest/gtest.h>
+
 #include "BionicDeathTest.h"
 #include "TemporaryFile.h"
+#include "utils.h"
 
 #include <errno.h>
 #include <libgen.h>
@@ -323,10 +325,7 @@
     quick_exit(99);
   }
 
-  int status;
-  ASSERT_EQ(pid, waitpid(pid, &status, 0));
-  ASSERT_TRUE(WIFEXITED(status));
-  ASSERT_EQ(99, WEXITSTATUS(status));
+  AssertChildExited(pid, 99);
 }
 
 static int quick_exit_status = 0;
@@ -355,24 +354,18 @@
     quick_exit(99);
   }
 
-  int status;
-  ASSERT_EQ(pid, waitpid(pid, &status, 0));
-  ASSERT_TRUE(WIFEXITED(status));
-  ASSERT_EQ(99, WEXITSTATUS(status));
+  AssertChildExited(pid, 99);
 }
 
 TEST(unistd, _Exit) {
-  int pid = fork();
+  pid_t pid = fork();
   ASSERT_NE(-1, pid) << strerror(errno);
 
   if (pid == 0) {
     _Exit(99);
   }
 
-  int status;
-  ASSERT_EQ(pid, waitpid(pid, &status, 0));
-  ASSERT_TRUE(WIFEXITED(status));
-  ASSERT_EQ(99, WEXITSTATUS(status));
+  AssertChildExited(pid, 99);
 }
 
 TEST(stdlib, pty_smoke) {
diff --git a/tests/string_nofortify_test.cpp b/tests/string_nofortify_test.cpp
new file mode 100644
index 0000000..1c0be35
--- /dev/null
+++ b/tests/string_nofortify_test.cpp
@@ -0,0 +1,12 @@
+
+#ifdef _FORTIFY_SOURCE
+#undef _FORTIFY_SOURCE
+#endif
+
+#define NOFORTIFY
+
+#include "string_test.cpp"
+
+#if defined(_FORTIFY_SOURCE)
+#error "_FORTIFY_SOURCE has been redefined, fix the code to remove this redefinition."
+#endif
diff --git a/tests/string_test.cpp b/tests/string_test.cpp
index 1d63c76..4b2cca2 100644
--- a/tests/string_test.cpp
+++ b/tests/string_test.cpp
@@ -22,9 +22,19 @@
 #include <gtest/gtest.h>
 #include <malloc.h>
 #include <math.h>
+#include <stdint.h>
+
+#include <algorithm>
+#include <vector>
 
 #include "buffer_tests.h"
 
+#if defined(NOFORTIFY)
+#define STRING_TEST string_nofortify
+#else
+#define STRING_TEST string
+#endif
+
 #if defined(__BIONIC__)
 #define STRLCPY_SUPPORTED
 #define STRLCAT_SUPPORTED
@@ -44,7 +54,7 @@
   return 0;
 }
 
-TEST(string, strerror) {
+TEST(STRING_TEST, strerror) {
   // Valid.
   ASSERT_STREQ("Success", strerror(0));
   ASSERT_STREQ("Operation not permitted", strerror(1));
@@ -62,7 +72,7 @@
 #endif // __BIONIC__
 
 // glibc's strerror isn't thread safe, only its strsignal.
-TEST(string, strerror_concurrent) {
+TEST(STRING_TEST, strerror_concurrent) {
 #if defined(__BIONIC__)
   const char* strerror1001 = strerror(1001);
   ASSERT_STREQ("Unknown error 1001", strerror1001);
@@ -79,7 +89,7 @@
 #endif // __BIONIC__
 }
 
-TEST(string, gnu_strerror_r) {
+TEST(STRING_TEST, gnu_strerror_r) {
   char buf[256];
 
   // Note that glibc doesn't necessarily write into the buffer.
@@ -109,7 +119,7 @@
   ASSERT_EQ(0, errno);
 }
 
-TEST(string, strsignal) {
+TEST(STRING_TEST, strsignal) {
   // A regular signal.
   ASSERT_STREQ("Hangup", strsignal(1));
 
@@ -129,7 +139,7 @@
   return reinterpret_cast<void*>(equal);
 }
 
-TEST(string, strsignal_concurrent) {
+TEST(STRING_TEST, strsignal_concurrent) {
   const char* strsignal1001 = strsignal(1001);
   ASSERT_STREQ("Unknown signal 1001", strsignal1001);
 
@@ -242,7 +252,7 @@
 template<class Character>
 size_t StringTestState<Character>::alignments_size = sizeof(alignments)/sizeof(size_t);
 
-TEST(string, strcat) {
+TEST(STRING_TEST, strcat) {
   StringTestState<char> state(SMALL);
   for (size_t i = 1; i < state.n; i++) {
     for (state.BeginIterations(); state.HasNextIteration(); state.NextIteration()) {
@@ -263,7 +273,7 @@
 }
 
 // one byte target with "\0" source
-TEST(string, strcpy2) {
+TEST(STRING_TEST, strcpy2) {
   char buf[1];
   char* orig = strdup("");
   ASSERT_EQ(buf, strcpy(buf, orig));
@@ -272,7 +282,7 @@
 }
 
 // multibyte target where we under fill target
-TEST(string, strcpy3) {
+TEST(STRING_TEST, strcpy3) {
   char buf[10];
   char* orig = strdup("12345");
   memset(buf, 'A', sizeof(buf));
@@ -286,7 +296,7 @@
 }
 
 // multibyte target where we fill target exactly
-TEST(string, strcpy4) {
+TEST(STRING_TEST, strcpy4) {
   char buf[10];
   char* orig = strdup("123456789");
   memset(buf, 'A', sizeof(buf));
@@ -296,7 +306,7 @@
 }
 
 // one byte target with "\0" source
-TEST(string, stpcpy2) {
+TEST(STRING_TEST, stpcpy2) {
   char buf[1];
   char* orig = strdup("");
   ASSERT_EQ(buf, stpcpy(buf, orig));
@@ -305,7 +315,7 @@
 }
 
 // multibyte target where we under fill target
-TEST(string, stpcpy3) {
+TEST(STRING_TEST, stpcpy3) {
   char buf[10];
   char* orig = strdup("12345");
   memset(buf, 'A', sizeof(buf));
@@ -319,7 +329,7 @@
 }
 
 // multibyte target where we fill target exactly
-TEST(string, stpcpy4) {
+TEST(STRING_TEST, stpcpy4) {
   char buf[10];
   char* orig = strdup("123456789");
   memset(buf, 'A', sizeof(buf));
@@ -328,7 +338,7 @@
   free(orig);
 }
 
-TEST(string, strcat2) {
+TEST(STRING_TEST, strcat2) {
   char buf[10];
   memset(buf, 'A', sizeof(buf));
   buf[0] = 'a';
@@ -341,7 +351,7 @@
   ASSERT_EQ('A',  buf[9]);
 }
 
-TEST(string, strcat3) {
+TEST(STRING_TEST, strcat3) {
   char buf[10];
   memset(buf, 'A', sizeof(buf));
   buf[0] = 'a';
@@ -351,7 +361,7 @@
   ASSERT_STREQ("a01234567", buf);
 }
 
-TEST(string, strncat2) {
+TEST(STRING_TEST, strncat2) {
   char buf[10];
   memset(buf, 'A', sizeof(buf));
   buf[0] = 'a';
@@ -364,7 +374,7 @@
   ASSERT_EQ('A',  buf[9]);
 }
 
-TEST(string, strncat3) {
+TEST(STRING_TEST, strncat3) {
   char buf[10];
   memset(buf, 'A', sizeof(buf));
   buf[0] = 'a';
@@ -377,7 +387,7 @@
   ASSERT_EQ('A',  buf[9]);
 }
 
-TEST(string, strncat4) {
+TEST(STRING_TEST, strncat4) {
   char buf[10];
   memset(buf, 'A', sizeof(buf));
   buf[0] = 'a';
@@ -387,7 +397,7 @@
   ASSERT_STREQ("a01234567", buf);
 }
 
-TEST(string, strncat5) {
+TEST(STRING_TEST, strncat5) {
   char buf[10];
   memset(buf, 'A', sizeof(buf));
   buf[0] = 'a';
@@ -397,14 +407,14 @@
   ASSERT_STREQ("a01234567", buf);
 }
 
-TEST(string, strchr_with_0) {
+TEST(STRING_TEST, strchr_with_0) {
   char buf[10];
   const char* s = "01234";
   memcpy(buf, s, strlen(s) + 1);
   EXPECT_TRUE(strchr(buf, '\0') == (buf + strlen(s)));
 }
 
-TEST(string, strchr_multiple) {
+TEST(STRING_TEST, strchr_multiple) {
   char str[128];
   memset(str, 'a', sizeof(str) - 1);
   str[sizeof(str)-1] = '\0';
@@ -422,7 +432,7 @@
   }
 }
 
-TEST(string, strchr) {
+TEST(STRING_TEST, strchr) {
   int seek_char = 'R';
 
   StringTestState<char> state(SMALL);
@@ -453,7 +463,14 @@
   }
 }
 
-TEST(string, strcmp) {
+TEST(STRING_TEST, strchrnul) {
+  const char* s = "01234222";
+  EXPECT_TRUE(strchrnul(s, '2') == &s[2]);
+  EXPECT_TRUE(strchrnul(s, '8') == (s + strlen(s)));
+  EXPECT_TRUE(strchrnul(s, '\0') == (s + strlen(s)));
+}
+
+TEST(STRING_TEST, strcmp) {
   StringTestState<char> state(SMALL);
   for (size_t i = 1; i < state.n; i++) {
     for (state.BeginIterations(); state.HasNextIteration(); state.NextIteration()) {
@@ -488,7 +505,7 @@
   }
 }
 
-TEST(string, stpcpy) {
+TEST(STRING_TEST, stpcpy) {
   StringTestState<char> state(SMALL);
   for (state.BeginIterations(); state.HasNextIteration(); state.NextIteration()) {
     size_t pos = random() % state.MAX_LEN;
@@ -512,7 +529,7 @@
   }
 }
 
-TEST(string, strcpy) {
+TEST(STRING_TEST, strcpy) {
   StringTestState<char> state(SMALL);
   for (state.BeginIterations(); state.HasNextIteration(); state.NextIteration()) {
     size_t pos = random() % state.MAX_LEN;
@@ -536,7 +553,7 @@
   }
 }
 
-TEST(string, strlcat) {
+TEST(STRING_TEST, strlcat) {
 #if defined(STRLCAT_SUPPORTED)
   StringTestState<char> state(SMALL);
   for (size_t i = 0; i < state.n; i++) {
@@ -565,7 +582,7 @@
 #endif
 }
 
-TEST(string, strlcpy) {
+TEST(STRING_TEST, strlcpy) {
 #if defined(STRLCPY_SUPPORTED)
   StringTestState<char> state(SMALL);
   for (state.BeginIterations(); state.HasNextIteration(); state.NextIteration()) {
@@ -597,7 +614,7 @@
 #endif
 }
 
-TEST(string, strncat) {
+TEST(STRING_TEST, strncat) {
   StringTestState<char> state(SMALL);
   for (size_t i = 1; i < state.n; i++) {
     for (state.BeginIterations(); state.HasNextIteration(); state.NextIteration()) {
@@ -621,7 +638,7 @@
   }
 }
 
-TEST(string, strncmp) {
+TEST(STRING_TEST, strncmp) {
   StringTestState<char> state(SMALL);
   for (size_t i = 1; i < state.n; i++) {
     for (state.BeginIterations(); state.HasNextIteration(); state.NextIteration()) {
@@ -656,7 +673,7 @@
   }
 }
 
-TEST(string, stpncpy) {
+TEST(STRING_TEST, stpncpy) {
   StringTestState<char> state(SMALL);
   for (state.BeginIterations(); state.HasNextIteration(); state.NextIteration()) {
     memset(state.ptr1, 'J', state.MAX_LEN);
@@ -691,7 +708,7 @@
   }
 }
 
-TEST(string, strncpy) {
+TEST(STRING_TEST, strncpy) {
   StringTestState<char> state(SMALL);
   for (state.BeginIterations(); state.HasNextIteration(); state.NextIteration()) {
     // Choose a random value to fill the string, except \0 (string terminator),
@@ -728,7 +745,7 @@
   }
 }
 
-TEST(string, strrchr) {
+TEST(STRING_TEST, strrchr) {
   int seek_char = 'M';
   StringTestState<char> state(SMALL);
   for (size_t i = 1; i < state.n; i++) {
@@ -758,7 +775,7 @@
   }
 }
 
-TEST(string, memchr) {
+TEST(STRING_TEST, memchr) {
   int seek_char = 'N';
   StringTestState<char> state(SMALL);
   for (size_t i = 0; i < state.n; i++) {
@@ -779,7 +796,7 @@
   }
 }
 
-TEST(string, memchr_zero) {
+TEST(STRING_TEST, memchr_zero) {
   uint8_t* buffer;
   ASSERT_EQ(0, posix_memalign(reinterpret_cast<void**>(&buffer), 64, 64));
   memset(buffer, 10, 64);
@@ -787,7 +804,7 @@
   ASSERT_TRUE(NULL == memchr(buffer, 10, 0));
 }
 
-TEST(string, memrchr) {
+TEST(STRING_TEST, memrchr) {
   int seek_char = 'P';
   StringTestState<char> state(SMALL);
   for (size_t i = 0; i < state.n; i++) {
@@ -808,7 +825,7 @@
   }
 }
 
-TEST(string, memcmp) {
+TEST(STRING_TEST, memcmp) {
   StringTestState<char> state(SMALL);
   for (size_t i = 0; i < state.n; i++) {
     for (state.BeginIterations(); state.HasNextIteration(); state.NextIteration()) {
@@ -828,7 +845,7 @@
   }
 }
 
-TEST(string, wmemcmp) {
+TEST(STRING_TEST, wmemcmp) {
   StringTestState<wchar_t> state(SMALL);
 
   for (size_t i = 0; i < state.n; i++) {
@@ -850,7 +867,7 @@
   }
 }
 
-TEST(string, memcpy) {
+TEST(STRING_TEST, memcpy) {
   StringTestState<char> state(LARGE);
   int rand = 4;
   for (size_t i = 0; i < state.n - 1; i++) {
@@ -870,7 +887,7 @@
   }
 }
 
-TEST(string, memset) {
+TEST(STRING_TEST, memset) {
   StringTestState<char> state(LARGE);
   char ch = 'P';
   for (size_t i = 0; i < state.n - 1; i++) {
@@ -890,7 +907,7 @@
   }
 }
 
-TEST(string, memmove) {
+TEST(STRING_TEST, memmove) {
   StringTestState<char> state(LARGE);
   for (size_t i = 0; i < state.n - 1; i++) {
     for (state.BeginIterations(); state.HasNextIteration(); state.NextIteration()) {
@@ -909,7 +926,7 @@
   }
 }
 
-TEST(string, memmove_cache_size) {
+TEST(STRING_TEST, memmove_cache_size) {
   size_t len = 600000;
   int max_alignment = 31;
   int alignments[] = {0, 5, 11, 29, 30};
@@ -947,7 +964,7 @@
 
 #define MEMMOVE_DATA_SIZE (1024*1024*3)
 
-TEST(string, memmove_check) {
+TEST(STRING_TEST, memmove_check) {
   char* buffer = reinterpret_cast<char*>(malloc(MEMMOVE_DATA_SIZE));
   ASSERT_TRUE(buffer != NULL);
 
@@ -988,7 +1005,7 @@
   }
 }
 
-TEST(string, bcopy) {
+TEST(STRING_TEST, bcopy) {
   StringTestState<char> state(LARGE);
   for (size_t i = 0; i < state.n; i++) {
     for (state.BeginIterations(); state.HasNextIteration(); state.NextIteration()) {
@@ -1005,7 +1022,7 @@
   }
 }
 
-TEST(string, bzero) {
+TEST(STRING_TEST, bzero) {
   StringTestState<char> state(LARGE);
   for (state.BeginIterations(); state.HasNextIteration(); state.NextIteration()) {
     memset(state.ptr1, 'R', state.MAX_LEN);
@@ -1031,11 +1048,11 @@
   ASSERT_TRUE(memcmp(src, dst, len) == 0);
 }
 
-TEST(string, memcpy_align) {
+TEST(STRING_TEST, memcpy_align) {
   RunSrcDstBufferAlignTest(LARGE, DoMemcpyTest);
 }
 
-TEST(string, memcpy_overread) {
+TEST(STRING_TEST, memcpy_overread) {
   RunSrcDstBufferOverreadTest(DoMemcpyTest);
 }
 
@@ -1047,11 +1064,11 @@
   ASSERT_TRUE(memcmp(src, dst, len) == 0);
 }
 
-TEST(string, memmove_align) {
+TEST(STRING_TEST, memmove_align) {
   RunSrcDstBufferAlignTest(LARGE, DoMemmoveTest);
 }
 
-TEST(string, memmove_overread) {
+TEST(STRING_TEST, memmove_overread) {
   RunSrcDstBufferOverreadTest(DoMemmoveTest);
 }
 
@@ -1066,7 +1083,7 @@
   }
 }
 
-TEST(string, memset_align) {
+TEST(STRING_TEST, memset_align) {
   RunSingleBufferAlignTest(LARGE, DoMemsetTest);
 }
 
@@ -1078,11 +1095,11 @@
   }
 }
 
-TEST(string, strlen_align) {
+TEST(STRING_TEST, strlen_align) {
   RunSingleBufferAlignTest(LARGE, DoStrlenTest);
 }
 
-TEST(string, strlen_overread) {
+TEST(STRING_TEST, strlen_overread) {
   RunSingleBufferOverreadTest(DoStrlenTest);
 }
 
@@ -1097,11 +1114,11 @@
   }
 }
 
-TEST(string, strcpy_align) {
+TEST(STRING_TEST, strcpy_align) {
   RunSrcDstBufferAlignTest(LARGE, DoStrcpyTest);
 }
 
-TEST(string, strcpy_overread) {
+TEST(STRING_TEST, strcpy_overread) {
   RunSrcDstBufferOverreadTest(DoStrcpyTest);
 }
 
@@ -1118,7 +1135,7 @@
 }
 #endif
 
-TEST(string, strlcpy_align) {
+TEST(STRING_TEST, strlcpy_align) {
 #if defined(STRLCPY_SUPPORTED)
   RunSrcDstBufferAlignTest(LARGE, DoStrlcpyTest);
 #else
@@ -1126,7 +1143,7 @@
 #endif
 }
 
-TEST(string, strlcpy_overread) {
+TEST(STRING_TEST, strlcpy_overread) {
 #if defined(STRLCPY_SUPPORTED)
   RunSrcDstBufferOverreadTest(DoStrlcpyTest);
 #else
@@ -1146,11 +1163,11 @@
   }
 }
 
-TEST(string, stpcpy_align) {
+TEST(STRING_TEST, stpcpy_align) {
   RunSrcDstBufferAlignTest(LARGE, DoStpcpyTest);
 }
 
-TEST(string, stpcpy_overread) {
+TEST(STRING_TEST, stpcpy_overread) {
   RunSrcDstBufferOverreadTest(DoStpcpyTest);
 }
 
@@ -1166,7 +1183,7 @@
   return 1;
 }
 
-#define STRCAT_DST_LEN  128
+#define STRCAT_DST_LEN  64
 
 static void DoStrcatTest(uint8_t* src, uint8_t* dst, size_t len) {
   if (len >= 1) {
@@ -1181,7 +1198,7 @@
       int value2 = 32 + (value + 2) % 96;
       memset(cmp_buf, value2, sizeof(cmp_buf));
 
-      for (size_t i = 1; i <= STRCAT_DST_LEN; i++) {
+      for (size_t i = 1; i <= STRCAT_DST_LEN;) {
         memset(dst, value2, i-1);
         memset(dst+i-1, 0, len-i);
         src[len-i] = '\0';
@@ -1189,6 +1206,13 @@
                                                          reinterpret_cast<char*>(src))));
         ASSERT_TRUE(memcmp(dst, cmp_buf, i-1) == 0);
         ASSERT_TRUE(memcmp(src, dst+i-1, len-i+1) == 0);
+        // This is an expensive loop, so don't loop through every value,
+        // get to a certain size and then start doubling.
+        if (i < 16) {
+          i++;
+        } else {
+          i <<= 1;
+        }
       }
     } else {
       dst[0] = '\0';
@@ -1199,11 +1223,11 @@
   }
 }
 
-TEST(string, strcat_align) {
+TEST(STRING_TEST, strcat_align) {
   RunSrcDstBufferAlignTest(MEDIUM, DoStrcatTest, LargeSetIncrement);
 }
 
-TEST(string, strcat_overread) {
+TEST(STRING_TEST, strcat_overread) {
   RunSrcDstBufferOverreadTest(DoStrcatTest);
 }
 
@@ -1221,7 +1245,7 @@
       int value2 = 32 + (value + 2) % 96;
       memset(cmp_buf, value2, sizeof(cmp_buf));
 
-      for (size_t i = 1; i <= STRCAT_DST_LEN; i++) {
+      for (size_t i = 1; i <= STRCAT_DST_LEN;) {
         memset(dst, value2, i-1);
         memset(dst+i-1, 0, len-i);
         src[len-i] = '\0';
@@ -1229,6 +1253,13 @@
                                  reinterpret_cast<char*>(src), len));
         ASSERT_TRUE(memcmp(dst, cmp_buf, i-1) == 0);
         ASSERT_TRUE(memcmp(src, dst+i-1, len-i+1) == 0);
+        // This is an expensive loop, so don't loop through every value,
+        // get to a certain size and then start doubling.
+        if (i < 16) {
+          i++;
+        } else {
+          i <<= 1;
+        }
       }
     } else {
       dst[0] = '\0';
@@ -1240,7 +1271,7 @@
 }
 #endif
 
-TEST(string, strlcat_align) {
+TEST(STRING_TEST, strlcat_align) {
 #if defined(STRLCAT_SUPPORTED)
   RunSrcDstBufferAlignTest(MEDIUM, DoStrlcatTest, LargeSetIncrement);
 #else
@@ -1248,7 +1279,7 @@
 #endif
 }
 
-TEST(string, strlcat_overread) {
+TEST(STRING_TEST, strlcat_overread) {
 #if defined(STRLCAT_SUPPORTED)
   RunSrcDstBufferOverreadTest(DoStrlcatTest);
 #else
@@ -1301,11 +1332,11 @@
   }
 }
 
-TEST(string, strcmp_align) {
+TEST(STRING_TEST, strcmp_align) {
   RunCmpBufferAlignTest(MEDIUM, DoStrcmpTest, DoStrcmpFailTest, LargeSetIncrement);
 }
 
-TEST(string, strcmp_overread) {
+TEST(STRING_TEST, strcmp_overread) {
   RunCmpBufferOverreadTest(DoStrcmpTest, DoStrcmpFailTest);
 }
 
@@ -1333,11 +1364,11 @@
   ASSERT_NE(0, memcmp(buf1, buf2, len));
 }
 
-TEST(string, memcmp_align) {
+TEST(STRING_TEST, memcmp_align) {
   RunCmpBufferAlignTest(MEDIUM, DoMemcmpTest, DoMemcmpFailTest, LargeSetIncrement);
 }
 
-TEST(string, memcmp_overread) {
+TEST(STRING_TEST, memcmp_overread) {
   RunCmpBufferOverreadTest(DoMemcmpTest, DoMemcmpFailTest);
 }
 
@@ -1359,11 +1390,11 @@
   }
 }
 
-TEST(string, strchr_align) {
+TEST(STRING_TEST, strchr_align) {
   RunSingleBufferAlignTest(MEDIUM, DoStrchrTest);
 }
 
-TEST(string, strchr_overread) {
+TEST(STRING_TEST, strchr_overread) {
   RunSingleBufferOverreadTest(DoStrchrTest);
 }
 
@@ -1374,7 +1405,7 @@
   ASSERT_EQ(0, errno) << in;
 }
 
-TEST(string, __gnu_basename) {
+TEST(STRING_TEST, __gnu_basename) {
   TestBasename("", "");
   TestBasename("/usr/lib", "lib");
   TestBasename("/usr/", "");
@@ -1386,7 +1417,7 @@
   TestBasename("//usr//lib//", "");
 }
 
-TEST(string, strnlen_147048) {
+TEST(STRING_TEST, strnlen_147048) {
   // https://code.google.com/p/android/issues/detail?id=147048
   char stack_src[64] = {0};
   EXPECT_EQ(0U, strnlen(stack_src, 1024*1024*1024));
@@ -1396,7 +1427,31 @@
   delete[] heap_src;
 }
 
-TEST(string, mempcpy) {
+TEST(STRING_TEST, strnlen_74741) {
+  ASSERT_EQ(4U, strnlen("test", SIZE_MAX));
+}
+
+TEST(STRING_TEST, mempcpy) {
   char dst[6];
   ASSERT_EQ(&dst[4], reinterpret_cast<char*>(mempcpy(dst, "hello", 4)));
 }
+
+// clang depends on the fact that a memcpy where src and dst is the same
+// still operates correctly. This test verifies that this assumption
+// holds true.
+// See https://llvm.org/bugs/show_bug.cgi?id=11763 for more information.
+static std::vector<uint8_t> g_memcpy_same_buffer;
+
+static void DoMemcpySameTest(uint8_t* buffer, size_t len) {
+  memcpy(buffer, g_memcpy_same_buffer.data(), len);
+  ASSERT_EQ(buffer, memcpy(buffer, buffer, len));
+  ASSERT_TRUE(memcmp(buffer, g_memcpy_same_buffer.data(), len) == 0);
+}
+
+TEST(STRING_TEST, memcpy_src_dst_same) {
+  g_memcpy_same_buffer.resize(MEDIUM);
+  for (size_t i = 0; i < MEDIUM; i++) {
+    g_memcpy_same_buffer[i] = i;
+  }
+  RunSingleBufferAlignTest(MEDIUM, DoMemcpySameTest);
+}
diff --git a/tests/strings_nofortify_test.cpp b/tests/strings_nofortify_test.cpp
new file mode 100644
index 0000000..36eee75
--- /dev/null
+++ b/tests/strings_nofortify_test.cpp
@@ -0,0 +1,12 @@
+
+#ifdef _FORTIFY_SOURCE
+#undef _FORTIFY_SOURCE
+#endif
+
+#define NOFORTIFY
+
+#include "strings_test.cpp"
+
+#if defined(_FORTIFY_SOURCE)
+#error "_FORTIFY_SOURCE has been redefined, fix the code to remove this redefinition."
+#endif
diff --git a/tests/strings_test.cpp b/tests/strings_test.cpp
index 823aa4f..1716843 100644
--- a/tests/strings_test.cpp
+++ b/tests/strings_test.cpp
@@ -20,7 +20,13 @@
 #include <locale.h>
 #include <strings.h>
 
-TEST(strings, ffs) {
+#if defined(NOFORTIFY)
+#define STRINGS_TEST strings_nofortify
+#else
+#define STRINGS_TEST strings
+#endif
+
+TEST(STRINGS_TEST, ffs) {
   ASSERT_EQ( 0, ffs(0x00000000));
   ASSERT_EQ( 1, ffs(0x00000001));
   ASSERT_EQ( 6, ffs(0x00000020));
@@ -32,13 +38,13 @@
   ASSERT_EQ(32, ffs(0x80000000));
 }
 
-TEST(strings, strcasecmp) {
+TEST(STRINGS_TEST, strcasecmp) {
   ASSERT_EQ(0, strcasecmp("hello", "HELLO"));
   ASSERT_LT(strcasecmp("hello1", "hello2"), 0);
   ASSERT_GT(strcasecmp("hello2", "hello1"), 0);
 }
 
-TEST(strings, strcasecmp_l) {
+TEST(STRINGS_TEST, strcasecmp_l) {
   locale_t l = newlocale(LC_ALL, "C", 0);
   ASSERT_EQ(0, strcasecmp_l("hello", "HELLO", l));
   ASSERT_LT(strcasecmp_l("hello1", "hello2", l), 0);
@@ -46,14 +52,14 @@
   freelocale(l);
 }
 
-TEST(strings, strncasecmp) {
+TEST(STRINGS_TEST, strncasecmp) {
   ASSERT_EQ(0, strncasecmp("hello", "HELLO", 3));
   ASSERT_EQ(0, strncasecmp("abcXX", "ABCYY", 3));
   ASSERT_LT(strncasecmp("hello1", "hello2", 6), 0);
   ASSERT_GT(strncasecmp("hello2", "hello1", 6), 0);
 }
 
-TEST(strings, strncasecmp_l) {
+TEST(STRINGS_TEST, strncasecmp_l) {
   locale_t l = newlocale(LC_ALL, "C", 0);
   ASSERT_EQ(0, strncasecmp_l("hello", "HELLO", 3, l));
   ASSERT_EQ(0, strncasecmp_l("abcXX", "ABCYY", 3, l));
diff --git a/tests/stubs_test.cpp b/tests/stubs_test.cpp
index 89d67cb..c81ca58 100644
--- a/tests/stubs_test.cpp
+++ b/tests/stubs_test.cpp
@@ -122,6 +122,14 @@
   check_get_passwd("radio", 1001, TYPE_SYSTEM);
 }
 
+TEST(getpwnam, oem_id_0) {
+  check_get_passwd("oem_0", 5000, TYPE_SYSTEM);
+}
+
+TEST(getpwnam, oem_id_999) {
+  check_get_passwd("oem_999", 5999, TYPE_SYSTEM);
+}
+
 TEST(getpwnam, app_id_nobody) {
   check_get_passwd("nobody", 9999, TYPE_SYSTEM);
 }
@@ -163,8 +171,6 @@
   check_get_passwd("u1_i0", 199000, TYPE_APP);
 }
 
-#if defined(__BIONIC__)
-
 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);
@@ -174,6 +180,8 @@
   ASSERT_TRUE(grp->gr_mem[1] == NULL);
 }
 
+#if defined(__BIONIC__)
+
 static void check_getgrgid(const char* group_name, gid_t gid) {
   errno = 0;
   group* grp = getgrgid(gid);
@@ -190,17 +198,49 @@
   check_group(grp, group_name, gid);
 }
 
+static void check_getgrgid_r(const char* group_name, gid_t gid) {
+  group grp_storage;
+  char buf[512];
+  group* grp;
+
+  errno = 0;
+  int result = getgrgid_r(gid, &grp_storage, buf, sizeof(buf), &grp);
+  ASSERT_EQ(0, result);
+  ASSERT_EQ(0, errno);
+  SCOPED_TRACE("getgrgid_r");
+  check_group(grp, group_name, gid);
+}
+
+static void check_getgrnam_r(const char* group_name, gid_t gid) {
+  group grp_storage;
+  char buf[512];
+  group* grp;
+
+  errno = 0;
+  int result = getgrnam_r(group_name, &grp_storage, buf, sizeof(buf), &grp);
+  ASSERT_EQ(0, result);
+  ASSERT_EQ(0, errno);
+  SCOPED_TRACE("getgrnam_r");
+  check_group(grp, group_name, gid);
+}
+
 static void check_get_group(const char* group_name, gid_t gid) {
   check_getgrgid(group_name, gid);
   check_getgrnam(group_name, gid);
+  check_getgrgid_r(group_name, gid);
+  check_getgrnam_r(group_name, gid);
 }
 
 #else // !defined(__BIONIC__)
 
-static void check_get_group(const char* /* group_name */, gid_t /* gid */) {
+static void print_no_getgrnam_test_info() {
   GTEST_LOG_(INFO) << "This test is about gid/group_name translation for Android, which does nothing on libc other than bionic.\n";
 }
 
+static void check_get_group(const char*, gid_t) {
+  print_no_getgrnam_test_info();
+}
+
 #endif
 
 TEST(getgrnam, system_id_root) {
@@ -215,6 +255,14 @@
   check_get_group("radio", 1001);
 }
 
+TEST(getgrnam, oem_id_0) {
+  check_get_group("oem_0", 5000);
+}
+
+TEST(getgrnam, oem_id_999) {
+  check_get_group("oem_999", 5999);
+}
+
 TEST(getgrnam, app_id_nobody) {
   check_get_group("nobody", 9999);
 }
@@ -259,3 +307,53 @@
 TEST(getgrnam, app_id_u1_i0) {
   check_get_group("u1_i0", 199000);
 }
+
+TEST(getgrnam_r, reentrancy) {
+#if defined(__BIONIC__)
+  group grp_storage[2];
+  char buf[2][512];
+  group* grp[3];
+  int result = getgrnam_r("root", &grp_storage[0], buf[0], sizeof(buf[0]), &grp[0]);
+  ASSERT_EQ(0, result);
+  check_group(grp[0], "root", 0);
+  grp[1] = getgrnam("system");
+  check_group(grp[1], "system", 1000);
+  result = getgrnam_r("radio", &grp_storage[1], buf[1], sizeof(buf[1]), &grp[2]);
+  ASSERT_EQ(0, result);
+  check_group(grp[2], "radio", 1001);
+  check_group(grp[0], "root", 0);
+  check_group(grp[1], "system", 1000);
+#else
+  print_no_getgrnam_test_info();
+#endif
+}
+
+TEST(getgrgid_r, reentrancy) {
+#if defined(__BIONIC__)
+  group grp_storage[2];
+  char buf[2][512];
+  group* grp[3];
+  int result = getgrgid_r(0, &grp_storage[0], buf[0], sizeof(buf[0]), &grp[0]);
+  ASSERT_EQ(0, result);
+  check_group(grp[0], "root", 0);
+  grp[1] = getgrgid(1000);
+  check_group(grp[1], "system", 1000);
+  result = getgrgid_r(1001, &grp_storage[1], buf[1], sizeof(buf[1]), &grp[2]);
+  ASSERT_EQ(0, result);
+  check_group(grp[2], "radio", 1001);
+  check_group(grp[0], "root", 0);
+  check_group(grp[1], "system", 1000);
+#else
+  print_no_getgrnam_test_info();
+#endif
+}
+
+TEST(getgrnam_r, large_enough_suggested_buffer_size) {
+  long size = sysconf(_SC_GETGR_R_SIZE_MAX);
+  ASSERT_GT(size, 0);
+  char buf[size];
+  group grp_storage;
+  group* grp;
+  ASSERT_EQ(0, getgrnam_r("root", &grp_storage, buf, size, &grp));
+  check_group(grp, "root", 0);
+}
diff --git a/tests/sys_mman_test.cpp b/tests/sys_mman_test.cpp
index b0e40fd..ddb6c77 100644
--- a/tests/sys_mman_test.cpp
+++ b/tests/sys_mman_test.cpp
@@ -17,6 +17,7 @@
 #include <gtest/gtest.h>
 
 #include <sys/mman.h>
+#include <sys/user.h>
 #include <sys/types.h>
 #include <unistd.h>
 
@@ -215,3 +216,19 @@
 
   ASSERT_EQ(0, munmap(map, pagesize));
 }
+
+TEST(sys_mman, mremap) {
+  ASSERT_EQ(MAP_FAILED, mremap(nullptr, 0, 0, 0));
+}
+
+const size_t huge = size_t(PTRDIFF_MAX) + 1;
+
+TEST(sys_mman, mmap_PTRDIFF_MAX) {
+  ASSERT_EQ(MAP_FAILED, mmap(nullptr, huge, PROT_NONE, MAP_PRIVATE | MAP_ANONYMOUS, -1, 0));
+}
+
+TEST(sys_mman, mremap_PTRDIFF_MAX) {
+  void* map = mmap(nullptr, PAGE_SIZE, PROT_NONE, MAP_PRIVATE | MAP_ANONYMOUS, -1, 0);
+  ASSERT_NE(MAP_FAILED, map);
+  ASSERT_EQ(MAP_FAILED, mremap(map, PAGE_SIZE, huge, MREMAP_MAYMOVE));
+}
diff --git a/tests/sys_personality_test.cpp b/tests/sys_personality_test.cpp
index 2dfaa65..6bd00ef 100644
--- a/tests/sys_personality_test.cpp
+++ b/tests/sys_personality_test.cpp
@@ -21,7 +21,9 @@
 TEST(sys_personality, current_persona) {
   int persona = personality(0xffffffff) & PER_MASK;
 #if defined(__BIONIC__)
-#if defined(__LP64__)
+// When personality syscall is executed on mips64, for a 32bit process
+// sys_32_personality() is called, which converts PER_LINUX32 -> PER_LINUX
+#if defined(__LP64__) || (__mips==32 && __mips_isa_rev>2)
   ASSERT_EQ(PER_LINUX, persona);
 #else
   ASSERT_EQ(PER_LINUX32, persona);
diff --git a/tests/sys_prctl_test.cpp b/tests/sys_prctl_test.cpp
new file mode 100644
index 0000000..5a563c1
--- /dev/null
+++ b/tests/sys_prctl_test.cpp
@@ -0,0 +1,39 @@
+/*
+ * Copyright (C) 2015 The Android Open Source Project
+ *
+ * Licensed under the Apache License, Version 2.0 (the "License");
+ * you may not use this file except in compliance with the License.
+ * You may obtain a copy of the License at
+ *
+ *      http://www.apache.org/licenses/LICENSE-2.0
+ *
+ * Unless required by applicable law or agreed to in writing, software
+ * distributed under the License is distributed on an "AS IS" BASIS,
+ * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
+ * See the License for the specific language governing permissions and
+ * limitations under the License.
+ */
+
+#include <gtest/gtest.h>
+
+#include <sys/mman.h>
+#include <sys/prctl.h>
+#include <unistd.h>
+#include "private/bionic_prctl.h"
+
+// http://b/20017123.
+TEST(sys_prctl, bug_20017123) {
+#if defined(__ANDROID__)
+  size_t page_size = static_cast<size_t>(sysconf(_SC_PAGESIZE));
+  void* p = mmap(NULL, page_size * 3, PROT_READ | PROT_WRITE, MAP_PRIVATE | MAP_ANONYMOUS, -1, 0);
+  ASSERT_NE(MAP_FAILED, p);
+  ASSERT_EQ(0, mprotect(p, page_size, PROT_NONE));
+  ASSERT_NE(-1, prctl(PR_SET_VMA, PR_SET_VMA_ANON_NAME, p, page_size * 3, "anonymous map space"));
+  volatile char* vp = reinterpret_cast<volatile char*>(p);
+  // Below memory access causes SEGV if the memory map is screwed up.
+  *(vp + page_size) = 0;
+  ASSERT_EQ(0, munmap(p, page_size * 3));
+#else
+  GTEST_LOG_(INFO) << "This test does nothing as it tests an Android specific kernel feature.";
+#endif
+}
diff --git a/tests/sys_resource_test.cpp b/tests/sys_resource_test.cpp
index 8cefc65..0b6b6ef 100644
--- a/tests/sys_resource_test.cpp
+++ b/tests/sys_resource_test.cpp
@@ -33,7 +33,8 @@
   virtual void SetUp() {
     ASSERT_EQ(0, getrlimit(RLIMIT_CORE, &l32_));
     ASSERT_EQ(0, getrlimit64(RLIMIT_CORE, &l64_));
-    ASSERT_EQ(0, prlimit64(0, RLIMIT_CORE, NULL, &pr_l64_));
+    ASSERT_EQ(0, prlimit(0, RLIMIT_CORE, nullptr, &pr_l32_));
+    ASSERT_EQ(0, prlimit64(0, RLIMIT_CORE, nullptr, &pr_l64_));
   }
 
   void CheckResourceLimits();
@@ -41,21 +42,28 @@
  protected:
   rlimit l32_;
   rlimit64 l64_;
+  rlimit pr_l32_;
   rlimit64 pr_l64_;
 };
 
 void SysResourceTest::CheckResourceLimits() {
   ASSERT_EQ(0, getrlimit(RLIMIT_CORE, &l32_));
   ASSERT_EQ(0, getrlimit64(RLIMIT_CORE, &l64_));
-  ASSERT_EQ(0, prlimit64(0, RLIMIT_CORE, NULL, &pr_l64_));
+  ASSERT_EQ(0, prlimit(0, RLIMIT_CORE, nullptr, &pr_l32_));
+  ASSERT_EQ(0, prlimit64(0, RLIMIT_CORE, nullptr, &pr_l64_));
+
+  ASSERT_EQ(l32_.rlim_cur, pr_l32_.rlim_cur);
   ASSERT_EQ(l64_.rlim_cur, pr_l64_.rlim_cur);
+
   if (l64_.rlim_cur == RLIM64_INFINITY) {
     ASSERT_EQ(RLIM_INFINITY, l32_.rlim_cur);
   } else {
     ASSERT_EQ(l64_.rlim_cur, l32_.rlim_cur);
   }
 
+  ASSERT_EQ(l32_.rlim_max, pr_l32_.rlim_max);
   ASSERT_EQ(l64_.rlim_max, pr_l64_.rlim_max);
+
   if (l64_.rlim_max == RLIM64_INFINITY) {
     ASSERT_EQ(RLIM_INFINITY, l32_.rlim_max);
   } else {
@@ -88,13 +96,16 @@
   ASSERT_EQ(456U, l64_.rlim_cur);
 }
 
-TEST_F(SysResourceTest, prlimit64) {
-  pr_l64_.rlim_cur = pr_l64_.rlim_max;
-  ASSERT_EQ(0, prlimit64(0, RLIMIT_CORE, &pr_l64_, NULL));
+TEST_F(SysResourceTest, prlimit) {
+  pr_l32_.rlim_cur = pr_l32_.rlim_max;
+  ASSERT_EQ(0, prlimit(0, RLIMIT_CORE, &pr_l32_, nullptr));
   CheckResourceLimits();
-  ASSERT_EQ(pr_l64_.rlim_max, pr_l64_.rlim_cur);
+  ASSERT_EQ(pr_l32_.rlim_max, pr_l32_.rlim_cur);
 }
 
-TEST_F(SysResourceTest, prlimit) {
-  // prlimit is prlimit64 on LP64 and unimplemented on 32-bit. So we only test prlimit64.
+TEST_F(SysResourceTest, prlimit64) {
+  pr_l64_.rlim_cur = pr_l64_.rlim_max;
+  ASSERT_EQ(0, prlimit64(0, RLIMIT_CORE, &pr_l64_, nullptr));
+  CheckResourceLimits();
+  ASSERT_EQ(pr_l64_.rlim_max, pr_l64_.rlim_cur);
 }
diff --git a/tests/sys_select_test.cpp b/tests/sys_select_test.cpp
index c1732ee..4ad77f0 100644
--- a/tests/sys_select_test.cpp
+++ b/tests/sys_select_test.cpp
@@ -23,6 +23,8 @@
 #include <sys/types.h>
 #include <sys/wait.h>
 
+#include "utils.h"
+
 TEST(sys_select, fd_set_smoke) {
   fd_set fds;
   FD_ZERO(&fds);
@@ -68,7 +70,8 @@
   char buf[sizeof(DELAY_MSG)];
   ASSERT_EQ(static_cast<ssize_t>(sizeof(DELAY_MSG)), read(fd, buf, sizeof(DELAY_MSG)));
   ASSERT_STREQ(DELAY_MSG, buf);
-  ASSERT_EQ(pid, waitpid(pid, NULL, 0));
+
+  AssertChildExited(pid, 0);
 }
 
 TEST(sys_select, select_smoke) {
@@ -89,7 +92,16 @@
   ASSERT_EQ(-1, select(-1, &r, &w, &e, NULL));
   ASSERT_EQ(EINVAL, errno);
 
-  ASSERT_EQ(2, select(max, &r, &w, &e, NULL));
+  int num_fds = select(max, &r, &w, &e, NULL);
+  // If there is data to be read on STDIN, then the number of
+  // fds ready will be 3 instead of 2. Allow this case, but verify
+  // every fd that is set.
+  ASSERT_TRUE(num_fds == 2 || num_fds == 3) << "Num fds returned " << num_fds;
+  ASSERT_TRUE(FD_ISSET(STDOUT_FILENO, &w));
+  ASSERT_TRUE(FD_ISSET(STDERR_FILENO, &w));
+  if (num_fds == 3) {
+    ASSERT_TRUE(FD_ISSET(STDIN_FILENO, &r));
+  }
 
   // Invalid timeout.
   timeval tv;
@@ -135,7 +147,16 @@
   ASSERT_EQ(-1, pselect(-1, &r, &w, &e, NULL, &ss));
   ASSERT_EQ(EINVAL, errno);
 
-  ASSERT_EQ(2, pselect(max, &r, &w, &e, NULL, &ss));
+  // If there is data to be read on STDIN, then the number of
+  // fds ready will be 3 instead of 2. Allow this case, but verify
+  // every fd that is set.
+  int num_fds = pselect(max, &r, &w, &e, NULL, &ss);
+  ASSERT_TRUE(num_fds == 2 || num_fds == 3) << "Num fds returned " << num_fds;
+  ASSERT_TRUE(FD_ISSET(STDOUT_FILENO, &w));
+  ASSERT_TRUE(FD_ISSET(STDERR_FILENO, &w));
+  if (num_fds == 3) {
+    ASSERT_TRUE(FD_ISSET(STDIN_FILENO, &r));
+  }
 
   // Invalid timeout.
   timespec tv;
diff --git a/tests/sys_sysmacros_test.cpp b/tests/sys_sysmacros_test.cpp
new file mode 100644
index 0000000..f17fac5
--- /dev/null
+++ b/tests/sys_sysmacros_test.cpp
@@ -0,0 +1,31 @@
+/*
+ * Copyright (C) 2016 The Android Open Source Project
+ *
+ * Licensed under the Apache License, Version 2.0 (the "License");
+ * you may not use this file except in compliance with the License.
+ * You may obtain a copy of the License at
+ *
+ *      http://www.apache.org/licenses/LICENSE-2.0
+ *
+ * Unless required by applicable law or agreed to in writing, software
+ * distributed under the License is distributed on an "AS IS" BASIS,
+ * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
+ * See the License for the specific language governing permissions and
+ * limitations under the License.
+ */
+
+#include <sys/sysmacros.h>
+
+#include <gtest/gtest.h>
+
+TEST(sys_sysmacros, makedev) {
+  ASSERT_EQ(0x12345aabbcc678ddULL, makedev(0x12345678, 0xaabbccdd));
+}
+
+TEST(sys_sysmacros, major) {
+  ASSERT_EQ(0x12345678UL, major(0x12345aabbcc678dd));
+}
+
+TEST(sys_sysmacros, minor) {
+  ASSERT_EQ(0xaabbccddUL, minor(0x12345aabbcc678dd));
+}
diff --git a/tests/sys_time_test.cpp b/tests/sys_time_test.cpp
index bb142bc..18fbe10 100644
--- a/tests/sys_time_test.cpp
+++ b/tests/sys_time_test.cpp
@@ -63,7 +63,7 @@
     tv2.tv_usec += 1000000;
   }
 
-  // Should be less than (a very generous, to try to avoid flakiness) 1000us.
+  // Should be less than (a very generous, to try to avoid flakiness) 2ms (2000us).
   ASSERT_EQ(0, tv2.tv_sec);
-  ASSERT_LT(tv2.tv_usec, 1000);
+  ASSERT_LT(tv2.tv_usec, 2000);
 }
diff --git a/tests/sys_timex_test.cpp b/tests/sys_timex_test.cpp
new file mode 100644
index 0000000..1340ea4
--- /dev/null
+++ b/tests/sys_timex_test.cpp
@@ -0,0 +1,47 @@
+/*
+ * Copyright (C) 2016 The Android Open Source Project
+ *
+ * Licensed under the Apache License, Version 2.0 (the "License");
+ * you may not use this file except in compliance with the License.
+ * You may obtain a copy of the License at
+ *
+ *      http://www.apache.org/licenses/LICENSE-2.0
+ *
+ * Unless required by applicable law or agreed to in writing, software
+ * distributed under the License is distributed on an "AS IS" BASIS,
+ * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
+ * See the License for the specific language governing permissions and
+ * limitations under the License.
+ */
+
+#include <sys/timex.h>
+
+#include <errno.h>
+
+#include <gtest/gtest.h>
+
+TEST(sys_timex, adjtimex_smoke) {
+  timex t;
+  memset(&t, 0, sizeof(t));
+  // adjtimex/clock_adjtime return the clock state on success, -1 on failure.
+  ASSERT_NE(-1, adjtimex(&t));
+}
+
+TEST(sys_timex, adjtimex_EFAULT) {
+  errno = 0;
+  ASSERT_EQ(-1, adjtimex(nullptr));
+  ASSERT_EQ(EFAULT, errno);
+}
+
+TEST(sys_timex, clock_adjtime_smoke) {
+  timex t;
+  memset(&t, 0, sizeof(t));
+  // adjtimex/clock_adjtime return the clock state on success, -1 on failure.
+  ASSERT_NE(-1, clock_adjtime(CLOCK_REALTIME, &t));
+}
+
+TEST(sys_timex, clock_adjtime_EFAULT) {
+  errno = 0;
+  ASSERT_EQ(-1, clock_adjtime(CLOCK_REALTIME, nullptr));
+  ASSERT_EQ(EFAULT, errno);
+}
diff --git a/tests/sys_uio_test.cpp b/tests/sys_uio_test.cpp
index c7af8a7..569d4fb 100644
--- a/tests/sys_uio_test.cpp
+++ b/tests/sys_uio_test.cpp
@@ -18,10 +18,60 @@
 
 #include <sys/uio.h>
 
-TEST(sys_uio, process_vm_readv_ESRCH) {
+#include "TemporaryFile.h"
+
+TEST(sys_uio, readv_writev) {
+  TemporaryFile tf;
+
+  char buf1[] = "hello";
+  char buf2[] = "world";
+  iovec ios[] = { { buf1, 5 }, { buf2, 5 } };
+
+  ASSERT_EQ(10, writev(tf.fd, ios, 2));
+
+  ASSERT_EQ(0, lseek(tf.fd, 0, SEEK_SET));
+
+  memset(buf1, '1', sizeof(buf1));
+  memset(buf2, '2', sizeof(buf2));
+
+  ASSERT_EQ(10, readv(tf.fd, ios, 2));
+  buf1[5] = buf2[5] = '\0';
+  ASSERT_STREQ("hello", buf1);
+  ASSERT_STREQ("world", buf2);
+}
+
+template <typename ReadFn, typename WriteFn>
+void TestPreadVPwriteV(ReadFn read_fn, WriteFn write_fn) {
+  TemporaryFile tf;
+
+  char buf[] = "world";
+  iovec ios[] = { { buf, 5 } };
+
+  ASSERT_EQ(5, write_fn(tf.fd, ios, 1, 5));
+  ASSERT_EQ(0, lseek(tf.fd, 0, SEEK_CUR));
+
+  strcpy(buf, "hello");
+  ASSERT_EQ(5, write_fn(tf.fd, ios, 1, 0));
+  ASSERT_EQ(0, lseek(tf.fd, 0, SEEK_CUR));
+
+  ASSERT_EQ(5, read_fn(tf.fd, ios, 1, 5));
+  ASSERT_STREQ("world", buf);
+  ASSERT_EQ(5, read_fn(tf.fd, ios, 1, 0));
+  ASSERT_STREQ("hello", buf);
+}
+
+TEST(sys_uio, preadv_pwritev) {
+  TestPreadVPwriteV(preadv, pwritev);
+}
+
+TEST(sys_uio, preadv64_pwritev64) {
+  TestPreadVPwriteV(preadv64, pwritev64);
+}
+
+TEST(sys_uio, process_vm_readv) {
   ASSERT_EQ(0, process_vm_readv(0, nullptr, 0, nullptr, 0, 0));
 }
 
-TEST(sys_uio, process_vm_writev_ESRCH) {
+TEST(sys_uio, process_vm_writev) {
   ASSERT_EQ(0, process_vm_writev(0, nullptr, 0, nullptr, 0, 0));
 }
diff --git a/tests/sys_xattr_test.cpp b/tests/sys_xattr_test.cpp
index 1842682..113ec26 100644
--- a/tests/sys_xattr_test.cpp
+++ b/tests/sys_xattr_test.cpp
@@ -80,6 +80,7 @@
   ASSERT_EQ(-1, res);
   ASSERT_EQ(EBADF, errno);
 #endif
+  close(fd);
 }
 
 TEST(sys_xattr, fsetxattr_with_opath_toosmall) {
@@ -97,4 +98,32 @@
   ASSERT_EQ(-1, res);
   ASSERT_EQ(EBADF, errno);
 #endif
+  close(fd);
+}
+
+TEST(sys_xattr, flistattr) {
+  TemporaryFile tf;
+  char buf[65536];  // 64kB is max possible xattr list size. See "man 7 xattr".
+  ASSERT_EQ(0, fsetxattr(tf.fd, "user.foo", "bar", 4, 0));
+  ssize_t result = flistxattr(tf.fd, buf, sizeof(buf));
+  ASSERT_TRUE(result >= 9);
+  ASSERT_TRUE(memmem(buf, sizeof(buf), "user.foo", 9) != NULL);
+}
+
+TEST(sys_xattr, flistattr_opath) {
+  TemporaryFile tf;
+  char buf[65536];  // 64kB is max possible xattr list size. See "man 7 xattr".
+  ASSERT_EQ(0, fsetxattr(tf.fd, "user.foo", "bar", 4, 0));
+  int fd = open(tf.filename, O_PATH);
+  ASSERT_NE(-1, fd);
+  ssize_t res = flistxattr(fd, buf, sizeof(buf));
+#if defined(__BIONIC__)
+  ASSERT_TRUE(res >= 9);
+  ASSERT_TRUE(static_cast<size_t>(res) <= sizeof(buf));
+  ASSERT_TRUE(memmem(buf, res, "user.foo", 9) != NULL);
+#else
+  ASSERT_EQ(-1, res);
+  ASSERT_EQ(EBADF, errno);
+#endif
+  close(fd);
 }
diff --git a/tests/system_properties_test.cpp b/tests/system_properties_test.cpp
index c7bfee6..09eac3f 100644
--- a/tests/system_properties_test.cpp
+++ b/tests/system_properties_test.cpp
@@ -41,9 +41,6 @@
             return;
         }
 
-        old_pa = __system_property_area__;
-        __system_property_area__ = NULL;
-
         pa_dirname = dirname;
         pa_filename = pa_dirname + "/__properties__";
 
@@ -57,9 +54,8 @@
             return;
         }
 
-        __system_property_area__ = old_pa;
-
         __system_property_set_filename(PROP_FILENAME);
+        __system_properties_init();
         unlink(pa_filename.c_str());
         rmdir(pa_dirname.c_str());
     }
@@ -68,7 +64,6 @@
 private:
     std::string pa_dirname;
     std::string pa_filename;
-    void *old_pa;
 };
 
 static void foreach_test_callback(const prop_info *pi, void* cookie) {
diff --git a/tests/thread_local_test.cpp b/tests/thread_local_test.cpp
new file mode 100644
index 0000000..1422ed2
--- /dev/null
+++ b/tests/thread_local_test.cpp
@@ -0,0 +1,260 @@
+/*
+ * Copyright (C) 2015 The Android Open Source Project
+ *
+ * Licensed under the Apache License, Version 2.0 (the "License");
+ * you may not use this file except in compliance with the License.
+ * You may obtain a copy of the License at
+ *
+ *      http://www.apache.org/licenses/LICENSE-2.0
+ *
+ * Unless required by applicable law or agreed to in writing, software
+ * distributed under the License is distributed on an "AS IS" BASIS,
+ * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
+ * See the License for the specific language governing permissions and
+ * limitations under the License.
+ */
+
+#include <gtest/gtest.h>
+#include <stdint.h>
+#include <string.h>
+
+#if defined(__GNUC__) && !defined(__clang__) && \
+    (defined(__arm__) || defined(__aarch64__))
+// Gcc has a bug with -O -fdata-section for the arm target: http://b/22772147.
+// Until that bug is fixed, disable optimization since
+// it is not essential for this test.
+#pragma GCC optimize("-O0")
+#endif
+
+__thread int local_var = 100;
+int shared_var = 200;
+
+static void reset_vars() {
+  local_var = 1000;
+  shared_var = 2000;
+  // local_var should be reset by threads
+}
+
+typedef void* (*MyThread)(void*);
+
+static void* inc_shared_var(void* p) {
+  int *data = reinterpret_cast<int*>(p);
+  shared_var++;
+  *data = shared_var;
+  return nullptr;
+}
+
+static void* inc_local_var(void* p) {
+  int *data = reinterpret_cast<int*>(p);
+  local_var++;
+  *data = local_var;
+  return nullptr;
+}
+
+static int run_one_thread(MyThread foo) {
+  pthread_t t;
+  int data;
+  int error = pthread_create(&t, nullptr, foo, &data);
+  if (!error)
+      error = pthread_join(t, nullptr);
+  return error ? error : data;
+}
+
+TEST(thread_local_storage, shared) {
+  reset_vars();
+  ASSERT_EQ(local_var, 1000);
+  ASSERT_EQ(shared_var, 2000);
+
+  // Update shared_var, local_var remains 1000.
+  ASSERT_EQ(run_one_thread(inc_shared_var), 2001);
+  ASSERT_EQ(local_var, 1000);
+  ASSERT_EQ(shared_var, 2001);
+
+  ASSERT_EQ(run_one_thread(inc_shared_var), 2002);
+  ASSERT_EQ(local_var, 1000);
+  ASSERT_EQ(shared_var, 2002);
+
+  ASSERT_EQ(run_one_thread(inc_shared_var), 2003);
+  ASSERT_EQ(local_var, 1000);
+  ASSERT_EQ(shared_var, 2003);
+}
+
+TEST(thread_local_storage, local) {
+  reset_vars();
+  ASSERT_EQ(local_var, 1000);
+  ASSERT_EQ(shared_var, 2000);
+
+  // When a child thread updates its own TLS variable,
+  // this thread's local_var and shared_var are not changed.
+  // TLS local_var is initialized to 100 in a thread.
+  ASSERT_EQ(run_one_thread(inc_local_var), 101);
+  ASSERT_EQ(local_var, 1000);
+  ASSERT_EQ(shared_var, 2000);
+
+  ASSERT_EQ(run_one_thread(inc_local_var), 101);
+  ASSERT_EQ(local_var, 1000);
+  ASSERT_EQ(shared_var, 2000);
+
+  ASSERT_EQ(run_one_thread(inc_local_var), 101);
+  ASSERT_EQ(local_var, 1000);
+  ASSERT_EQ(shared_var, 2000);
+}
+
+// Test TLS initialization of more complicated type, array of struct.
+struct Point {
+  int x, y;
+};
+
+typedef Point Triangle[3];
+
+__thread Triangle local_triangle = {{10,10}, {20,20}, {30,30}};
+Triangle shared_triangle = {{1,1}, {2,2}, {3,3}};
+
+static void reset_triangle() {
+  static const Triangle t1 = {{3,3}, {4,4}, {5,5}};
+  static const Triangle t2 = {{2,2}, {3,3}, {4,4}};
+  memcpy(local_triangle, t1, sizeof(local_triangle));
+  memcpy(shared_triangle, t2, sizeof(shared_triangle));
+}
+
+static void* move_shared_triangle(void* p) {
+  int *data = reinterpret_cast<int*>(p);
+  shared_triangle[1].y++;
+  *data = shared_triangle[1].y;
+  return nullptr;
+}
+
+static void* move_local_triangle(void* p) {
+  int *data = reinterpret_cast<int*>(p);
+  local_triangle[1].y++;
+  *data = local_triangle[1].y;
+  return nullptr;
+}
+
+TEST(thread_local_storage, shared_triangle) {
+  reset_triangle();
+  ASSERT_EQ(local_triangle[1].y, 4);
+  ASSERT_EQ(shared_triangle[1].y, 3);
+
+  // Update shared_triangle, local_triangle remains 1000.
+  ASSERT_EQ(run_one_thread(move_shared_triangle), 4);
+  ASSERT_EQ(local_triangle[1].y, 4);
+  ASSERT_EQ(shared_triangle[1].y, 4);
+
+  ASSERT_EQ(run_one_thread(move_shared_triangle), 5);
+  ASSERT_EQ(local_triangle[1].y, 4);
+  ASSERT_EQ(shared_triangle[1].y, 5);
+
+  ASSERT_EQ(run_one_thread(move_shared_triangle), 6);
+  ASSERT_EQ(local_triangle[1].y, 4);
+  ASSERT_EQ(shared_triangle[1].y, 6);
+}
+
+TEST(thread_local_storage, local_triangle) {
+  reset_triangle();
+  ASSERT_EQ(local_triangle[1].y, 4);
+  ASSERT_EQ(shared_triangle[1].y, 3);
+
+  // Update local_triangle, parent thread's
+  // shared_triangle and local_triangle are unchanged.
+  ASSERT_EQ(run_one_thread(move_local_triangle), 21);
+  ASSERT_EQ(local_triangle[1].y, 4);
+  ASSERT_EQ(shared_triangle[1].y, 3);
+
+  ASSERT_EQ(run_one_thread(move_local_triangle), 21);
+  ASSERT_EQ(local_triangle[1].y, 4);
+  ASSERT_EQ(shared_triangle[1].y, 3);
+
+  ASSERT_EQ(run_one_thread(move_local_triangle), 21);
+  ASSERT_EQ(local_triangle[1].y, 4);
+  ASSERT_EQ(shared_triangle[1].y, 3);
+}
+
+// Test emutls runtime data structures and __emutls_get_address function.
+typedef unsigned int gcc_word __attribute__((mode(word)));
+typedef unsigned int gcc_pointer __attribute__((mode(pointer)));
+struct gcc_emutls_object {  // for libgcc
+  gcc_word size;
+  gcc_word align;
+  union {
+    gcc_pointer offset;
+    void* ptr;
+  } loc;
+  void* templ;
+};
+
+typedef struct __emutls_control {  // for clang/llvm
+  size_t size;
+  size_t align;
+  union {
+    uintptr_t index;
+    void* address;
+  } object;
+  void* value;
+} __emutls_control;
+
+TEST(thread_local_storage, type_size) {
+  static_assert(sizeof(size_t) == sizeof(gcc_word),
+                "size_t != gcc_word");
+  static_assert(sizeof(uintptr_t) == sizeof(gcc_pointer),
+                "uintptr_t != gcc_pointer");
+  static_assert(sizeof(uintptr_t) == sizeof(void*),
+                "sizoeof(uintptr_t) != sizeof(void*)");
+  static_assert(sizeof(__emutls_control) == sizeof(struct gcc_emutls_object),
+                "sizeof(__emutls_control) != sizeof(struct gcc_emutls_object)");
+}
+
+extern "C" void* __emutls_get_address(__emutls_control*);
+
+TEST(thread_local_storage, init_value) {
+  char tls_value1[] = "123456789";
+  char tls_value2[] = "abcdefghi";
+  constexpr size_t num_saved_values = 10;
+  __emutls_control tls_var[num_saved_values];
+  size_t prev_index = 0;
+  void* saved_gap[num_saved_values];
+  void* saved_p[num_saved_values];
+  ASSERT_TRUE(strlen(tls_value2) <= strlen(tls_value1));
+  __emutls_control c =
+      {strlen(tls_value1) + 1, 1, {0}, tls_value1};
+  for (size_t n = 0; n < num_saved_values; n++) {
+    memcpy(&tls_var[n], &c, sizeof(c));
+    tls_var[n].align = (1 << n);
+  }
+  for (size_t n = 0; n < num_saved_values; n++) {
+    // Try to mess up malloc space so that the next malloc will not have the
+    // required alignment, but __emutls_get_address should still return an
+    // aligned address.
+    saved_gap[n] = malloc(1);
+    void* p = __emutls_get_address(&tls_var[n]);
+    saved_p[n] = p;
+    ASSERT_TRUE(p != nullptr);
+    ASSERT_TRUE(tls_var[n].object.index != 0);
+    // check if p is a new object.
+    if (n > 0) {
+      // In single-thread environment, object.address == p.
+      // In multi-threads environment, object.index is increased.
+      ASSERT_TRUE(prev_index + 1 == tls_var[n].object.index ||
+                  p == tls_var[n].object.address);
+      ASSERT_TRUE(p != saved_p[n - 1]);
+    }
+    prev_index = tls_var[n].object.index;
+    // check if p is aligned
+    uintptr_t align = (1 << n);
+    uintptr_t address= reinterpret_cast<uintptr_t>(p);
+    ASSERT_EQ((address & ~(align - 1)), address);
+    // check if *p is initialized
+    ASSERT_STREQ(tls_value1, static_cast<char*>(p));
+    // change value in *p
+    memcpy(p, tls_value2, strlen(tls_value2) + 1);
+  }
+  for (size_t n = 0; n < num_saved_values; n++) {
+    free(saved_gap[n]);
+  }
+  for (size_t n = 0; n < num_saved_values; n++) {
+    void* p = __emutls_get_address(&tls_var[n]);
+    ASSERT_EQ(p, saved_p[n]);
+    // check if *p has the new value
+    ASSERT_STREQ(tls_value2, static_cast<char*>(p));
+  }
+}
diff --git a/tests/time_test.cpp b/tests/time_test.cpp
index 0ea90a8..6cdabd2 100644
--- a/tests/time_test.cpp
+++ b/tests/time_test.cpp
@@ -27,6 +27,7 @@
 #include <atomic>
 
 #include "ScopedSignalHandler.h"
+#include "utils.h"
 
 #include "private/bionic_constants.h"
 
@@ -58,19 +59,13 @@
   // Is it safe to call tzload on a thread with a small stack?
   // http://b/14313703
   // https://code.google.com/p/android/issues/detail?id=61130
-  pthread_attr_t attributes;
-  ASSERT_EQ(0, pthread_attr_init(&attributes));
-#if defined(__BIONIC__)
-  ASSERT_EQ(0, pthread_attr_setstacksize(&attributes, PTHREAD_STACK_MIN));
-#else
-  // PTHREAD_STACK_MIN not currently in the host GCC sysroot.
-  ASSERT_EQ(0, pthread_attr_setstacksize(&attributes, 4 * getpagesize()));
-#endif
+  pthread_attr_t a;
+  ASSERT_EQ(0, pthread_attr_init(&a));
+  ASSERT_EQ(0, pthread_attr_setstacksize(&a, PTHREAD_STACK_MIN));
 
   pthread_t t;
-  ASSERT_EQ(0, pthread_create(&t, &attributes, gmtime_no_stack_overflow_14313703_fn, NULL));
-  void* result;
-  ASSERT_EQ(0, pthread_join(t, &result));
+  ASSERT_EQ(0, pthread_create(&t, &a, gmtime_no_stack_overflow_14313703_fn, NULL));
+  ASSERT_EQ(0, pthread_join(t, nullptr));
 }
 
 TEST(time, mktime_empty_TZ) {
@@ -143,6 +138,44 @@
   EXPECT_STREQ("Sun Mar 10 00:00:00 2100", buf);
 }
 
+TEST(time, strftime_null_tm_zone) {
+  // Netflix on Nexus Player wouldn't start (http://b/25170306).
+  struct tm t;
+  memset(&t, 0, sizeof(tm));
+
+  char buf[64];
+
+  setenv("TZ", "America/Los_Angeles", 1);
+  tzset();
+
+  t.tm_isdst = 0; // "0 if Daylight Savings Time is not in effect".
+  EXPECT_EQ(5U, strftime(buf, sizeof(buf), "<%Z>", &t));
+  EXPECT_STREQ("<PST>", buf);
+
+#if defined(__BIONIC__) // glibc 2.19 only copes with tm_isdst being 0 and 1.
+  t.tm_isdst = 2; // "positive if Daylight Savings Time is in effect"
+  EXPECT_EQ(5U, strftime(buf, sizeof(buf), "<%Z>", &t));
+  EXPECT_STREQ("<PDT>", buf);
+
+  t.tm_isdst = -123; // "and negative if the information is not available".
+  EXPECT_EQ(2U, strftime(buf, sizeof(buf), "<%Z>", &t));
+  EXPECT_STREQ("<>", buf);
+#endif
+
+  setenv("TZ", "UTC", 1);
+  tzset();
+
+  t.tm_isdst = 0;
+  EXPECT_EQ(5U, strftime(buf, sizeof(buf), "<%Z>", &t));
+  EXPECT_STREQ("<UTC>", buf);
+
+#if defined(__BIONIC__) // glibc 2.19 thinks UTC DST is "UTC".
+  t.tm_isdst = 1; // UTC has no DST.
+  EXPECT_EQ(2U, strftime(buf, sizeof(buf), "<%Z>", &t));
+  EXPECT_STREQ("<>", buf);
+#endif
+}
+
 TEST(time, strptime) {
   setenv("TZ", "UTC", 1);
 
@@ -180,7 +213,7 @@
   timer_t timer_id;
   ASSERT_EQ(0, timer_create(CLOCK_MONOTONIC, &se, &timer_id));
 
-  int pid = fork();
+  pid_t pid = fork();
   ASSERT_NE(-1, pid) << strerror(errno);
 
   if (pid == 0) {
@@ -190,10 +223,7 @@
     _exit(0);
   }
 
-  int status;
-  ASSERT_EQ(pid, waitpid(pid, &status, 0));
-  ASSERT_TRUE(WIFEXITED(status));
-  ASSERT_EQ(0, WEXITSTATUS(status));
+  AssertChildExited(pid, 0);
 
   ASSERT_EQ(0, timer_delete(timer_id));
 }
@@ -223,7 +253,7 @@
   ts.it_value.tv_nsec = 1;
   ts.it_interval.tv_sec = 0;
   ts.it_interval.tv_nsec = 0;
-  ASSERT_EQ(0, timer_settime(timer_id, TIMER_ABSTIME, &ts, NULL));
+  ASSERT_EQ(0, timer_settime(timer_id, 0, &ts, NULL));
 
   usleep(500000);
   ASSERT_EQ(1, timer_create_SIGEV_SIGNAL_signal_handler_invocation_count);
diff --git a/tests/unistd_nofortify_test.cpp b/tests/unistd_nofortify_test.cpp
new file mode 100644
index 0000000..29966e9
--- /dev/null
+++ b/tests/unistd_nofortify_test.cpp
@@ -0,0 +1,12 @@
+
+#ifdef _FORTIFY_SOURCE
+#undef _FORTIFY_SOURCE
+#endif
+
+#define NOFORTIFY
+
+#include "unistd_test.cpp"
+
+#if defined(_FORTIFY_SOURCE)
+#error "_FORTIFY_SOURCE has been redefined, fix the code to remove this redefinition."
+#endif
diff --git a/tests/unistd_test.cpp b/tests/unistd_test.cpp
index 75b3edc..ccf4dcc 100644
--- a/tests/unistd_test.cpp
+++ b/tests/unistd_test.cpp
@@ -15,9 +15,11 @@
  */
 
 #include <gtest/gtest.h>
+
 #include "BionicDeathTest.h"
 #include "ScopedSignalHandler.h"
 #include "TemporaryFile.h"
+#include "utils.h"
 
 #include <errno.h>
 #include <fcntl.h>
@@ -30,6 +32,19 @@
 #include <sys/wait.h>
 #include <unistd.h>
 
+#include <android-base/file.h>
+#include <android-base/strings.h>
+
+#include "private/get_cpu_count_from_string.h"
+
+#if defined(NOFORTIFY)
+#define UNISTD_TEST unistd_nofortify
+#define UNISTD_DEATHTEST unistd_nofortify_DeathTest
+#else
+#define UNISTD_TEST unistd
+#define UNISTD_DEATHTEST unistd_DeathTest
+#endif
+
 static void* get_brk() {
   return sbrk(0);
 }
@@ -39,7 +54,7 @@
   return reinterpret_cast<void*>((addr + mask) & ~mask);
 }
 
-TEST(unistd, brk) {
+TEST(UNISTD_TEST, brk) {
   void* initial_break = get_brk();
 
   // The kernel aligns the break to a page.
@@ -52,7 +67,7 @@
   ASSERT_EQ(get_brk(), new_break);
 }
 
-TEST(unistd, brk_ENOMEM) {
+TEST(UNISTD_TEST, brk_ENOMEM) {
   ASSERT_EQ(-1, brk(reinterpret_cast<void*>(-1)));
   ASSERT_EQ(ENOMEM, errno);
 }
@@ -65,7 +80,7 @@
 #define SBRK_MAX PTRDIFF_MAX
 #endif
 
-TEST(unistd, sbrk_ENOMEM) {
+TEST(UNISTD_TEST, sbrk_ENOMEM) {
 #if defined(__BIONIC__) && !defined(__LP64__)
   // There is no way to guarantee that all overflow conditions can be tested
   // without manipulating the underlying values of the current break.
@@ -136,7 +151,7 @@
 #endif
 }
 
-TEST(unistd, truncate) {
+TEST(UNISTD_TEST, truncate) {
   TemporaryFile tf;
   ASSERT_EQ(0, close(tf.fd));
   ASSERT_EQ(0, truncate(tf.filename, 123));
@@ -146,7 +161,7 @@
   ASSERT_EQ(123, sb.st_size);
 }
 
-TEST(unistd, truncate64) {
+TEST(UNISTD_TEST, truncate64) {
   TemporaryFile tf;
   ASSERT_EQ(0, close(tf.fd));
   ASSERT_EQ(0, truncate64(tf.filename, 123));
@@ -156,7 +171,7 @@
   ASSERT_EQ(123, sb.st_size);
 }
 
-TEST(unistd, ftruncate) {
+TEST(UNISTD_TEST, ftruncate) {
   TemporaryFile tf;
   ASSERT_EQ(0, ftruncate(tf.fd, 123));
   ASSERT_EQ(0, close(tf.fd));
@@ -166,7 +181,7 @@
   ASSERT_EQ(123, sb.st_size);
 }
 
-TEST(unistd, ftruncate64) {
+TEST(UNISTD_TEST, ftruncate64) {
   TemporaryFile tf;
   ASSERT_EQ(0, ftruncate64(tf.fd, 123));
   ASSERT_EQ(0, close(tf.fd));
@@ -176,7 +191,7 @@
   ASSERT_EQ(123, sb.st_size);
 }
 
-TEST(unistd, ftruncate_negative) {
+TEST(UNISTD_TEST, ftruncate_negative) {
   TemporaryFile tf;
   errno = 0;
   ASSERT_EQ(-1, ftruncate(tf.fd, -123));
@@ -188,7 +203,7 @@
   g_pause_test_flag = true;
 }
 
-TEST(unistd, pause) {
+TEST(UNISTD_TEST, pause) {
   ScopedSignalHandler handler(SIGALRM, PauseTestSignalHandler);
 
   alarm(1);
@@ -197,7 +212,7 @@
   ASSERT_TRUE(g_pause_test_flag);
 }
 
-TEST(unistd, read) {
+TEST(UNISTD_TEST, read) {
   int fd = open("/proc/version", O_RDONLY);
   ASSERT_TRUE(fd != -1);
 
@@ -211,7 +226,7 @@
   close(fd);
 }
 
-TEST(unistd, read_EBADF) {
+TEST(UNISTD_TEST, read_EBADF) {
   // read returns ssize_t which is 64-bits on LP64, so it's worth explicitly checking that
   // our syscall stubs correctly return a 64-bit -1.
   char buf[1];
@@ -219,7 +234,7 @@
   ASSERT_EQ(EBADF, errno);
 }
 
-TEST(unistd, syscall_long) {
+TEST(UNISTD_TEST, syscall_long) {
   // Check that syscall(3) correctly returns long results.
   // https://code.google.com/p/android/issues/detail?id=73952
   // We assume that the break is > 4GiB, but this is potentially flaky.
@@ -227,39 +242,36 @@
   ASSERT_EQ(p, static_cast<uintptr_t>(syscall(__NR_brk, 0)));
 }
 
-TEST(unistd, alarm) {
+TEST(UNISTD_TEST, alarm) {
   ASSERT_EQ(0U, alarm(0));
 }
 
-TEST(unistd, _exit) {
-  int pid = fork();
+TEST(UNISTD_TEST, _exit) {
+  pid_t pid = fork();
   ASSERT_NE(-1, pid) << strerror(errno);
 
   if (pid == 0) {
     _exit(99);
   }
 
-  int status;
-  ASSERT_EQ(pid, waitpid(pid, &status, 0));
-  ASSERT_TRUE(WIFEXITED(status));
-  ASSERT_EQ(99, WEXITSTATUS(status));
+  AssertChildExited(pid, 99);
 }
 
-TEST(unistd, getenv_unsetenv) {
+TEST(UNISTD_TEST, getenv_unsetenv) {
   ASSERT_EQ(0, setenv("test-variable", "hello", 1));
   ASSERT_STREQ("hello", getenv("test-variable"));
   ASSERT_EQ(0, unsetenv("test-variable"));
   ASSERT_TRUE(getenv("test-variable") == NULL);
 }
 
-TEST(unistd, unsetenv_EINVAL) {
+TEST(UNISTD_TEST, unsetenv_EINVAL) {
   EXPECT_EQ(-1, unsetenv(""));
   EXPECT_EQ(EINVAL, errno);
   EXPECT_EQ(-1, unsetenv("a=b"));
   EXPECT_EQ(EINVAL, errno);
 }
 
-TEST(unistd, setenv_EINVAL) {
+TEST(UNISTD_TEST, setenv_EINVAL) {
   EXPECT_EQ(-1, setenv(NULL, "value", 0));
   EXPECT_EQ(EINVAL, errno);
   EXPECT_EQ(-1, setenv(NULL, "value", 1));
@@ -274,7 +286,7 @@
   EXPECT_EQ(EINVAL, errno);
 }
 
-TEST(unistd, setenv) {
+TEST(UNISTD_TEST, setenv) {
   ASSERT_EQ(0, unsetenv("test-variable"));
 
   char a[] = "a";
@@ -300,7 +312,7 @@
   ASSERT_EQ(0, unsetenv("test-variable"));
 }
 
-TEST(unistd, putenv) {
+TEST(UNISTD_TEST, putenv) {
   ASSERT_EQ(0, unsetenv("a"));
 
   char* s1 = strdup("a=b");
@@ -321,7 +333,7 @@
   free(s2);
 }
 
-TEST(unistd, clearenv) {
+TEST(UNISTD_TEST, clearenv) {
   extern char** environ;
 
   // Guarantee that environ is not initially empty...
@@ -374,7 +386,7 @@
   close(fd);
 
   // The fd can even be a directory.
-  ASSERT_NE(-1, fd = open("/data", O_RDONLY));
+  ASSERT_NE(-1, fd = open("/data/local/tmp", O_RDONLY));
   EXPECT_EQ(0, fn(fd));
   close(fd);
 
@@ -386,11 +398,11 @@
   close(fd);
 }
 
-TEST(unistd, fdatasync) {
+TEST(UNISTD_TEST, fdatasync) {
   TestFsyncFunction(fdatasync);
 }
 
-TEST(unistd, fsync) {
+TEST(UNISTD_TEST, fsync) {
   TestFsyncFunction(fsync);
 }
 
@@ -402,11 +414,11 @@
   }
 }
 
-TEST(unistd, getpid_caching_and_fork) {
+static void TestGetPidCachingWithFork(int (*fork_fn)()) {
   pid_t parent_pid = getpid();
   ASSERT_EQ(syscall(__NR_getpid), parent_pid);
 
-  pid_t fork_result = fork();
+  pid_t fork_result = fork_fn();
   ASSERT_NE(fork_result, -1);
   if (fork_result == 0) {
     // We're the child.
@@ -416,20 +428,24 @@
   } else {
     // We're the parent.
     ASSERT_EQ(parent_pid, getpid());
-
-    int status;
-    ASSERT_EQ(fork_result, waitpid(fork_result, &status, 0));
-    ASSERT_TRUE(WIFEXITED(status));
-    ASSERT_EQ(123, WEXITSTATUS(status));
+    AssertChildExited(fork_result, 123);
   }
 }
 
+TEST(UNISTD_TEST, getpid_caching_and_fork) {
+  TestGetPidCachingWithFork(fork);
+}
+
+TEST(UNISTD_TEST, getpid_caching_and_vfork) {
+  TestGetPidCachingWithFork(vfork);
+}
+
 static int GetPidCachingCloneStartRoutine(void*) {
   AssertGetPidCorrect();
   return 123;
 }
 
-TEST(unistd, getpid_caching_and_clone) {
+TEST(UNISTD_TEST, getpid_caching_and_clone) {
   pid_t parent_pid = getpid();
   ASSERT_EQ(syscall(__NR_getpid), parent_pid);
 
@@ -443,10 +459,7 @@
 
   ASSERT_EQ(parent_pid, getpid());
 
-  int status;
-  ASSERT_EQ(clone_result, waitpid(clone_result, &status, 0));
-  ASSERT_TRUE(WIFEXITED(status));
-  ASSERT_EQ(123, WEXITSTATUS(status));
+  AssertChildExited(clone_result, 123);
 }
 
 static void* GetPidCachingPthreadStartRoutine(void*) {
@@ -454,7 +467,7 @@
   return NULL;
 }
 
-TEST(unistd, getpid_caching_and_pthread_create) {
+TEST(UNISTD_TEST, getpid_caching_and_pthread_create) {
   pid_t parent_pid = getpid();
 
   pthread_t t;
@@ -467,13 +480,13 @@
   ASSERT_EQ(NULL, result);
 }
 
-class unistd_DeathTest : public BionicDeathTest {};
+class UNISTD_DEATHTEST : public BionicDeathTest {};
 
-TEST_F(unistd_DeathTest, abort) {
+TEST_F(UNISTD_DEATHTEST, abort) {
   ASSERT_EXIT(abort(), testing::KilledBySignal(SIGABRT), "");
 }
 
-TEST(unistd, sethostname) {
+TEST(UNISTD_TEST, sethostname) {
   // The permissions check happens before the argument check, so this will
   // fail for a different reason if you're running as root than if you're
   // not, but it'll fail either way. Checking that we have the symbol is about
@@ -481,7 +494,7 @@
   ASSERT_EQ(-1, sethostname("", -1));
 }
 
-TEST(unistd, gethostname) {
+TEST(UNISTD_TEST, gethostname) {
   char hostname[HOST_NAME_MAX + 1];
   memset(hostname, 0, sizeof(hostname));
 
@@ -504,7 +517,7 @@
   ASSERT_EQ(ENAMETOOLONG, errno);
 }
 
-TEST(unistd, pathconf_fpathconf) {
+TEST(UNISTD_TEST, pathconf_fpathconf) {
   TemporaryFile tf;
   long rc = 0L;
   // As a file system's block size is always power of 2, the configure values
@@ -525,7 +538,7 @@
 }
 
 
-TEST(unistd, _POSIX_macros_smoke) {
+TEST(UNISTD_TEST, _POSIX_macros_smoke) {
   // 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);
@@ -664,7 +677,7 @@
       << ret <<", Error Message: " << strerror(errno);
 }
 
-TEST(unistd, sysconf) {
+TEST(UNISTD_TEST, sysconf) {
   VERIFY_SYSCONF_POSIX_VERSION(_SC_ADVISORY_INFO);
   VERIFY_SYSCONF_POSITIVE(_SC_ARG_MAX);
   VERIFY_SYSCONF_POSITIVE(_SC_BC_BASE_MAX);
@@ -694,6 +707,8 @@
   VERIFY_SYSCONF_POSITIVE(_SC_IOV_MAX);
   VERIFY_SYSCONF_POSITIVE(_SC_PAGESIZE);
   VERIFY_SYSCONF_POSITIVE(_SC_PAGE_SIZE);
+  VerifySysconf(_SC_PAGE_SIZE, "_SC_PAGE_SIZE",
+                [](long v){return v == sysconf(_SC_PAGESIZE) && v == getpagesize();});
   VERIFY_SYSCONF_POSITIVE(_SC_XOPEN_UNIX);
   VERIFY_SYSCONF_POSITIVE(_SC_AIO_LISTIO_MAX);
   VERIFY_SYSCONF_POSITIVE(_SC_AIO_MAX);
@@ -809,7 +824,29 @@
 #endif // defined(__BIONIC__)
 }
 
-TEST(unistd, dup2_same) {
+TEST(UNISTD_TEST, get_cpu_count_from_string) {
+  ASSERT_EQ(0, GetCpuCountFromString(" "));
+  ASSERT_EQ(1, GetCpuCountFromString("0"));
+  ASSERT_EQ(40, GetCpuCountFromString("0-39"));
+  ASSERT_EQ(4, GetCpuCountFromString("0, 1-2, 4\n"));
+}
+
+TEST(UNISTD_TEST, sysconf_SC_NPROCESSORS_ONLN) {
+  std::string line;
+  ASSERT_TRUE(android::base::ReadFileToString("/sys/devices/system/cpu/online", &line));
+  long online_cpus = 0;
+  for (const std::string& s : android::base::Split(line, ",")) {
+    std::vector<std::string> numbers = android::base::Split(s, "-");
+    if (numbers.size() == 1u) {
+      online_cpus++;
+    } else {
+      online_cpus += atoi(numbers[1].c_str()) - atoi(numbers[0].c_str()) + 1;
+    }
+  }
+  ASSERT_EQ(online_cpus, sysconf(_SC_NPROCESSORS_ONLN));
+}
+
+TEST(UNISTD_TEST, dup2_same) {
   // POSIX says of dup2:
   // If fildes2 is already a valid open file descriptor ...
   // [and] fildes is equal to fildes2 ... dup2() shall return
@@ -827,3 +864,125 @@
   ASSERT_EQ(-1, dup2(fd, fd));
   ASSERT_EQ(EBADF, errno);
 }
+
+TEST(UNISTD_TEST, lockf_smoke) {
+  constexpr off64_t file_size = 32*1024LL;
+
+  TemporaryFile tf;
+  ASSERT_EQ(0, ftruncate(tf.fd, file_size));
+
+  // Lock everything.
+  ASSERT_EQ(0, lseek64(tf.fd, 0, SEEK_SET));
+  ASSERT_EQ(0, lockf64(tf.fd, F_LOCK, file_size));
+
+  // Try-lock everything, this should succeed too.
+  ASSERT_EQ(0, lseek64(tf.fd, 0, SEEK_SET));
+  ASSERT_EQ(0, lockf64(tf.fd, F_TLOCK, file_size));
+
+  // Check status.
+  ASSERT_EQ(0, lseek64(tf.fd, 0, SEEK_SET));
+  ASSERT_EQ(0, lockf64(tf.fd, F_TEST, file_size));
+
+  // Unlock file.
+  ASSERT_EQ(0, lseek64(tf.fd, 0, SEEK_SET));
+  ASSERT_EQ(0, lockf64(tf.fd, F_ULOCK, file_size));
+}
+
+TEST(UNISTD_TEST, lockf_zero) {
+  constexpr off64_t file_size = 32*1024LL;
+
+  TemporaryFile tf;
+  ASSERT_EQ(0, ftruncate(tf.fd, file_size));
+
+  // Lock everything by specifying a size of 0 (meaning "to the end, even if it changes").
+  ASSERT_EQ(0, lseek64(tf.fd, 0, SEEK_SET));
+  ASSERT_EQ(0, lockf64(tf.fd, F_LOCK, 0));
+
+  // Check that it's locked.
+  ASSERT_EQ(0, lseek64(tf.fd, 0, SEEK_SET));
+  ASSERT_EQ(0, lockf64(tf.fd, F_TEST, file_size));
+
+  // Move the end.
+  ASSERT_EQ(0, ftruncate(tf.fd, 2*file_size));
+
+  // Check that the new section is locked too.
+  ASSERT_EQ(file_size, lseek64(tf.fd, file_size, SEEK_SET));
+  ASSERT_EQ(0, lockf64(tf.fd, F_TEST, 2*file_size));
+}
+
+TEST(UNISTD_TEST, lockf_negative) {
+  constexpr off64_t file_size = 32*1024LL;
+
+  TemporaryFile tf;
+  ASSERT_EQ(0, ftruncate(tf.fd, file_size));
+
+  // Lock everything, but specifying the range in reverse.
+  ASSERT_EQ(file_size, lseek64(tf.fd, file_size, SEEK_SET));
+  ASSERT_EQ(0, lockf64(tf.fd, F_LOCK, -file_size));
+
+  // Check that it's locked.
+  ASSERT_EQ(0, lseek64(tf.fd, 0, SEEK_SET));
+  ASSERT_EQ(0, lockf64(tf.fd, F_TEST, file_size));
+}
+
+TEST(UNISTD_TEST, lockf_with_child) {
+  constexpr off64_t file_size = 32*1024LL;
+
+  TemporaryFile tf;
+  ASSERT_EQ(0, ftruncate(tf.fd, file_size));
+
+  // Lock everything.
+  ASSERT_EQ(0, lseek64(tf.fd, 0, SEEK_SET));
+  ASSERT_EQ(0, lockf64(tf.fd, F_LOCK, file_size));
+
+  // Fork a child process
+  pid_t pid = fork();
+  ASSERT_NE(-1, pid);
+  if (pid == 0) {
+    // Check that the child cannot lock the file.
+    ASSERT_EQ(0, lseek64(tf.fd, 0, SEEK_SET));
+    ASSERT_EQ(-1, lockf64(tf.fd, F_TLOCK, file_size));
+    ASSERT_EQ(EAGAIN, errno);
+    // Check also that it reports itself as locked.
+    ASSERT_EQ(0, lseek64(tf.fd, 0, SEEK_SET));
+    ASSERT_EQ(-1, lockf64(tf.fd, F_TEST, file_size));
+    ASSERT_EQ(EACCES, errno);
+    _exit(0);
+  }
+  AssertChildExited(pid, 0);
+}
+
+TEST(UNISTD_TEST, lockf_partial_with_child) {
+  constexpr off64_t file_size = 32*1024LL;
+
+  TemporaryFile tf;
+  ASSERT_EQ(0, ftruncate(tf.fd, file_size));
+
+  // Lock the first half of the file.
+  ASSERT_EQ(0, lseek64(tf.fd, 0, SEEK_SET));
+  ASSERT_EQ(0, lockf64(tf.fd, F_LOCK, file_size/2));
+
+  // Fork a child process.
+  pid_t pid = fork();
+  ASSERT_NE(-1, pid);
+  if (pid == 0) {
+    // Check that the child can lock the other half.
+    ASSERT_EQ(file_size/2, lseek64(tf.fd, file_size/2, SEEK_SET));
+    ASSERT_EQ(0, lockf64(tf.fd, F_TLOCK, file_size/2));
+    // Check that the child cannot lock the first half.
+    ASSERT_EQ(0, lseek64(tf.fd, 0, SEEK_SET));
+    ASSERT_EQ(-1, lockf64(tf.fd, F_TEST, file_size/2));
+    ASSERT_EQ(EACCES, errno);
+    // Check also that it reports itself as locked.
+    ASSERT_EQ(0, lseek64(tf.fd, 0, SEEK_SET));
+    ASSERT_EQ(-1, lockf64(tf.fd, F_TEST, file_size/2));
+    ASSERT_EQ(EACCES, errno);
+    _exit(0);
+  }
+  AssertChildExited(pid, 0);
+
+  // The second half was locked by the child, but the lock disappeared
+  // when the process exited, so check it can be locked now.
+  ASSERT_EQ(file_size/2, lseek64(tf.fd, file_size/2, SEEK_SET));
+  ASSERT_EQ(0, lockf64(tf.fd, F_TLOCK, file_size/2));
+}
diff --git a/tests/utils.h b/tests/utils.h
index fd012a3..f8e0039 100644
--- a/tests/utils.h
+++ b/tests/utils.h
@@ -16,8 +16,19 @@
 
 #ifndef __TEST_UTILS_H
 #define __TEST_UTILS_H
+
 #include <inttypes.h>
 #include <sys/mman.h>
+#include <sys/types.h>
+#include <sys/wait.h>
+#include <unistd.h>
+
+#include <atomic>
+#include <string>
+#include <regex>
+
+#include <android-base/file.h>
+#include <android-base/stringprintf.h>
 
 #include "private/ScopeGuard.h"
 
@@ -38,9 +49,7 @@
 class Maps {
  public:
   static bool parse_maps(std::vector<map_record>* maps) {
-    char path[64];
-    snprintf(path, sizeof(path), "/proc/self/task/%d/maps", getpid());
-    FILE* fp = fopen(path, "re");
+    FILE* fp = fopen("/proc/self/maps", "re");
     if (fp == nullptr) {
       return false;
     }
@@ -53,11 +62,11 @@
     while (fgets(line, sizeof(line), fp) != nullptr) {
       map_record record;
       uint32_t dev_major, dev_minor;
-      char pathstr[BUFSIZ];
+      int path_offset;
       char prot[5]; // sizeof("rwxp")
-      if (sscanf(line, "%" SCNxPTR "-%" SCNxPTR " %4s %" SCNxPTR " %x:%x %lu %s",
+      if (sscanf(line, "%" SCNxPTR "-%" SCNxPTR " %4s %" SCNxPTR " %x:%x %lu %n",
             &record.addr_start, &record.addr_end, prot, &record.offset,
-            &dev_major, &dev_minor, &record.inode, pathstr) == 8) {
+            &dev_major, &dev_minor, &record.inode, &path_offset) == 7) {
         record.perms = 0;
         if (prot[0] == 'r') {
           record.perms |= PROT_READ;
@@ -72,7 +81,10 @@
         // TODO: parse shared/private?
 
         record.device = makedev(dev_major, dev_minor);
-        record.pathname = pathstr;
+        record.pathname = line + path_offset;
+        if (!record.pathname.empty() && record.pathname.back() == '\n') {
+          record.pathname.pop_back();
+        }
         maps->push_back(record);
       }
     }
@@ -81,4 +93,33 @@
   }
 };
 
+extern "C" pid_t gettid();
+
+static inline void WaitUntilThreadSleep(std::atomic<pid_t>& tid) {
+  while (tid == 0) {
+    usleep(1000);
+  }
+  std::string filename = android::base::StringPrintf("/proc/%d/stat", tid.load());
+  std::regex regex {R"(\s+S\s+)"};
+
+  while (true) {
+    std::string content;
+    ASSERT_TRUE(android::base::ReadFileToString(filename, &content));
+    if (std::regex_search(content, regex)) {
+      break;
+    }
+    usleep(1000);
+  }
+}
+
+static inline void AssertChildExited(int pid, int expected_exit_status) {
+  int status;
+  ASSERT_EQ(pid, waitpid(pid, &status, 0));
+  ASSERT_TRUE(WIFEXITED(status));
+  ASSERT_EQ(expected_exit_status, WEXITSTATUS(status));
+}
+
+// The absolute path to the executable
+const std::string& get_executable_path();
+
 #endif
diff --git a/tests/utmp_test.cpp b/tests/utmp_test.cpp
index b61110d..0fa55c7 100644
--- a/tests/utmp_test.cpp
+++ b/tests/utmp_test.cpp
@@ -23,3 +23,9 @@
   // This test just checks that we're exporting the symbol independently.
   ASSERT_EQ(-1, login_tty(-1));
 }
+
+TEST(utmp, setutent_getutent_endutent) {
+  setutent();
+  getutent();
+  endutent();
+}
diff --git a/tools/bionicbb/presubmit.py b/tools/bionicbb/presubmit.py
index cc6f3cc..3e6ebfa 100644
--- a/tools/bionicbb/presubmit.py
+++ b/tools/bionicbb/presubmit.py
@@ -73,8 +73,10 @@
     build = 'clean-bionic-presubmit'
     if build in jenkins:
         if not dry_run:
-            job = jenkins[build].invoke()
-            url = job.get_build().baseurl
+            _ = jenkins[build].invoke()
+            # https://issues.jenkins-ci.org/browse/JENKINS-27256
+            # url = job.get_build().baseurl
+            url = 'URL UNAVAILABLE'
         else:
             url = 'DRY_RUN_URL'
         logging.info('Cleaning: %s %s', build, url)
diff --git a/tools/relocation_packer/Android.mk b/tools/relocation_packer/Android.mk
index 4e2fd97..2bf77b9 100644
--- a/tools/relocation_packer/Android.mk
+++ b/tools/relocation_packer/Android.mk
@@ -30,7 +30,7 @@
   src/packer.cc \
   src/sleb128.cc \
 
-LOCAL_STATIC_LIBRARIES := libelf
+LOCAL_STATIC_LIBRARIES := libelf libz
 LOCAL_C_INCLUDES := external/elfutils/src/libelf
 LOCAL_MODULE := lib_relocation_packer
 
@@ -45,7 +45,7 @@
 LOCAL_CPP_EXTENSION := .cc
 
 LOCAL_SRC_FILES := src/main.cc
-LOCAL_STATIC_LIBRARIES := lib_relocation_packer libelf
+LOCAL_STATIC_LIBRARIES := lib_relocation_packer libelf libz
 
 # Statically linking libc++ to make it work from prebuilts
 LOCAL_CXX_STL := libc++_static
@@ -70,7 +70,7 @@
   src/sleb128_unittest.cc \
   src/packer_unittest.cc \
 
-LOCAL_STATIC_LIBRARIES := lib_relocation_packer libelf
+LOCAL_STATIC_LIBRARIES := lib_relocation_packer libelf libz
 LOCAL_C_INCLUDES := external/elfutils/src/libelf
 
 LOCAL_CPPFLAGS := $(common_cppflags)
@@ -96,5 +96,11 @@
 $(eval $(call copy-test-library,elf_file_unittest_relocs_arm32_packed.so))
 $(eval $(call copy-test-library,elf_file_unittest_relocs_arm64.so))
 $(eval $(call copy-test-library,elf_file_unittest_relocs_arm64_packed.so))
+$(eval $(call copy-test-library,elf_file_unittest_relocs_ia32.so))
+$(eval $(call copy-test-library,elf_file_unittest_relocs_ia32_packed.so))
+$(eval $(call copy-test-library,elf_file_unittest_relocs_x64.so))
+$(eval $(call copy-test-library,elf_file_unittest_relocs_x64_packed.so))
+$(eval $(call copy-test-library,elf_file_unittest_relocs_mips32.so))
+$(eval $(call copy-test-library,elf_file_unittest_relocs_mips32_packed.so))
 
 endif
diff --git a/tools/relocation_packer/src/elf_file.cc b/tools/relocation_packer/src/elf_file.cc
index 102d614..014883d 100644
--- a/tools/relocation_packer/src/elf_file.cc
+++ b/tools/relocation_packer/src/elf_file.cc
@@ -302,13 +302,75 @@
   }
 }
 
-// Helper for ResizeSection().  Adjust the offsets of any program headers
-// that have offsets currently beyond the hole start.
+// Helpers for ResizeSection().  On packing, reduce p_align for LOAD segments
+// to 4kb if larger.  On unpacking, restore p_align for LOAD segments if
+// packing reduced it to 4kb.  Return true if p_align was changed.
 template <typename ELF>
-static void AdjustProgramHeaderOffsets(typename ELF::Phdr* program_headers,
+static bool ClampLoadSegmentAlignment(typename ELF::Phdr* program_header) {
+  CHECK(program_header->p_type == PT_LOAD);
+
+  // If large, reduce p_align for a LOAD segment to page size on packing.
+  if (program_header->p_align > kPageSize) {
+    program_header->p_align = kPageSize;
+    return true;
+  }
+  return false;
+}
+
+template <typename ELF>
+static bool RestoreLoadSegmentAlignment(typename ELF::Phdr* program_headers,
+                                        size_t count,
+                                        typename ELF::Phdr* program_header) {
+  CHECK(program_header->p_type == PT_LOAD);
+
+  // If p_align was reduced on packing, restore it to its previous value
+  // on unpacking.  We do this by searching for a different LOAD segment
+  // and setting p_align to that of the other LOAD segment found.
+  //
+  // Relies on the following observations:
+  //   - a packable ELF executable has more than one LOAD segment;
+  //   - before packing all LOAD segments have the same p_align;
+  //   - on packing we reduce only one LOAD segment's p_align.
+  if (program_header->p_align == kPageSize) {
+    for (size_t i = 0; i < count; ++i) {
+      typename ELF::Phdr* other_header = &program_headers[i];
+      if (other_header->p_type == PT_LOAD && other_header != program_header) {
+        program_header->p_align = other_header->p_align;
+        return true;
+      }
+    }
+    LOG(WARNING) << "Cannot find a LOAD segment from which to restore p_align";
+  }
+  return false;
+}
+
+template <typename ELF>
+static bool AdjustLoadSegmentAlignment(typename ELF::Phdr* program_headers,
                                        size_t count,
-                                       typename ELF::Off hole_start,
+                                       typename ELF::Phdr* program_header,
                                        ssize_t hole_size) {
+  CHECK(program_header->p_type == PT_LOAD);
+
+  bool status = false;
+  if (hole_size < 0) {
+    status = ClampLoadSegmentAlignment<ELF>(program_header);
+  } else if (hole_size > 0) {
+    status = RestoreLoadSegmentAlignment<ELF>(program_headers,
+                                              count,
+                                              program_header);
+  }
+  return status;
+}
+
+// Helper for ResizeSection().  Adjust the offsets of any program headers
+// that have offsets currently beyond the hole start, and adjust the
+// virtual and physical addrs (and perhaps alignment) of the others.
+template <typename ELF>
+static void AdjustProgramHeaderFields(typename ELF::Phdr* program_headers,
+                                      size_t count,
+                                      typename ELF::Off hole_start,
+                                      ssize_t hole_size) {
+  int alignment_changes = 0;
   for (size_t i = 0; i < count; ++i) {
     typename ELF::Phdr* program_header = &program_headers[i];
 
@@ -327,9 +389,20 @@
     } else {
       program_header->p_vaddr -= hole_size;
       program_header->p_paddr -= hole_size;
-      if (program_header->p_align > kPageSize) {
-        program_header->p_align = kPageSize;
+
+      // If packing, clamp LOAD segment alignment to 4kb to prevent strip
+      // from adjusting it unnecessarily if run on a packed file.  If
+      // unpacking, attempt to restore a reduced alignment to its previous
+      // value.  Ensure that we do this on at most one LOAD segment.
+      if (program_header->p_type == PT_LOAD) {
+        alignment_changes += AdjustLoadSegmentAlignment<ELF>(program_headers,
+                                                             count,
+                                                             program_header,
+                                                             hole_size);
+        LOG_IF(FATAL, alignment_changes > 1)
+            << "Changed p_align on more than one LOAD segment";
       }
+
       VLOG(1) << "phdr[" << i
               << "] p_vaddr adjusted to "<< program_header->p_vaddr
               << "; p_paddr adjusted to "<< program_header->p_paddr
@@ -383,10 +456,10 @@
   target_load_header->p_memsz += hole_size;
 
   // Adjust the offsets and p_vaddrs
-  AdjustProgramHeaderOffsets<ELF>(elf_program_header,
-                                  program_header_count,
-                                  hole_start,
-                                  hole_size);
+  AdjustProgramHeaderFields<ELF>(elf_program_header,
+                                 program_header_count,
+                                 hole_start,
+                                 hole_size);
 }
 
 // Helper for ResizeSection().  Locate and return the dynamic section.
@@ -666,7 +739,7 @@
   VLOG(1) << "Packed         (no padding): " << packed_bytes_estimate << " bytes";
 
   if (packed.empty()) {
-    LOG(INFO) << "Too few relocations to pack";
+    VLOG(1) << "Too few relocations to pack";
     return true;
   }
 
@@ -679,16 +752,16 @@
   // hole_size needs to be page_aligned.
   hole_size -= hole_size % kPreserveAlignment;
 
-  LOG(INFO) << "Compaction                 : " << hole_size << " bytes";
+  VLOG(1) << "Compaction                 : " << hole_size << " bytes";
 
   // Adjusting for alignment may have removed any packing benefit.
   if (hole_size == 0) {
-    LOG(INFO) << "Too few relocations to pack after alignment";
+    VLOG(1) << "Too few relocations to pack after alignment";
     return true;
   }
 
   if (hole_size <= 0) {
-    LOG(INFO) << "Packing relocations saves no space";
+    VLOG(1) << "Packing relocations saves no space";
     return true;
   }
 
diff --git a/tools/relocation_packer/src/elf_file_unittest.cc b/tools/relocation_packer/src/elf_file_unittest.cc
index 32f7968..d5c8918 100644
--- a/tools/relocation_packer/src/elf_file_unittest.cc
+++ b/tools/relocation_packer/src/elf_file_unittest.cc
@@ -183,6 +183,18 @@
   RunPackRelocationsTestFor("arm64");
 }
 
+TEST(ElfFile, PackRelocationsMips32) {
+  RunPackRelocationsTestFor("mips32");
+}
+
+TEST(ElfFile, PackRelocationsIa32) {
+  RunPackRelocationsTestFor("ia32");
+}
+
+TEST(ElfFile, PackRelocationsX64) {
+  RunPackRelocationsTestFor("x64");
+}
+
 TEST(ElfFile, UnpackRelocationsArm32) {
   RunUnpackRelocationsTestFor("arm32");
 }
@@ -191,4 +203,16 @@
   RunUnpackRelocationsTestFor("arm64");
 }
 
+TEST(ElfFile, UnpackRelocationsMips32) {
+  RunUnpackRelocationsTestFor("mips32");
+}
+
+TEST(ElfFile, UnpackRelocationsIa32) {
+  RunUnpackRelocationsTestFor("ia32");
+}
+
+TEST(ElfFile, UnpackRelocationsX64) {
+  RunUnpackRelocationsTestFor("x64");
+}
+
 }  // namespace relocation_packer
diff --git a/tools/relocation_packer/test_data/elf_file_unittest_relocs_arm32.so b/tools/relocation_packer/test_data/elf_file_unittest_relocs_arm32.so
index 6ce6d0c..5e339ae 100755
--- a/tools/relocation_packer/test_data/elf_file_unittest_relocs_arm32.so
+++ b/tools/relocation_packer/test_data/elf_file_unittest_relocs_arm32.so
Binary files differ
diff --git a/tools/relocation_packer/test_data/elf_file_unittest_relocs_arm32_packed.so b/tools/relocation_packer/test_data/elf_file_unittest_relocs_arm32_packed.so
index 6ac2eef..253dd97 100755
--- a/tools/relocation_packer/test_data/elf_file_unittest_relocs_arm32_packed.so
+++ b/tools/relocation_packer/test_data/elf_file_unittest_relocs_arm32_packed.so
Binary files differ
diff --git a/tools/relocation_packer/test_data/elf_file_unittest_relocs_arm64.so b/tools/relocation_packer/test_data/elf_file_unittest_relocs_arm64.so
index 945b450..d3d0194 100755
--- a/tools/relocation_packer/test_data/elf_file_unittest_relocs_arm64.so
+++ b/tools/relocation_packer/test_data/elf_file_unittest_relocs_arm64.so
Binary files differ
diff --git a/tools/relocation_packer/test_data/elf_file_unittest_relocs_arm64_packed.so b/tools/relocation_packer/test_data/elf_file_unittest_relocs_arm64_packed.so
index ed85ce1..269b975 100755
--- a/tools/relocation_packer/test_data/elf_file_unittest_relocs_arm64_packed.so
+++ b/tools/relocation_packer/test_data/elf_file_unittest_relocs_arm64_packed.so
Binary files differ
diff --git a/tools/relocation_packer/test_data/elf_file_unittest_relocs_ia32.so b/tools/relocation_packer/test_data/elf_file_unittest_relocs_ia32.so
new file mode 100755
index 0000000..42db62c
--- /dev/null
+++ b/tools/relocation_packer/test_data/elf_file_unittest_relocs_ia32.so
Binary files differ
diff --git a/tools/relocation_packer/test_data/elf_file_unittest_relocs_ia32_packed.so b/tools/relocation_packer/test_data/elf_file_unittest_relocs_ia32_packed.so
new file mode 100755
index 0000000..27817cc
--- /dev/null
+++ b/tools/relocation_packer/test_data/elf_file_unittest_relocs_ia32_packed.so
Binary files differ
diff --git a/tools/relocation_packer/test_data/elf_file_unittest_relocs_mips32.so b/tools/relocation_packer/test_data/elf_file_unittest_relocs_mips32.so
new file mode 100755
index 0000000..6da324b
--- /dev/null
+++ b/tools/relocation_packer/test_data/elf_file_unittest_relocs_mips32.so
Binary files differ
diff --git a/tools/relocation_packer/test_data/elf_file_unittest_relocs_mips32_packed.so b/tools/relocation_packer/test_data/elf_file_unittest_relocs_mips32_packed.so
new file mode 100755
index 0000000..b11ca48
--- /dev/null
+++ b/tools/relocation_packer/test_data/elf_file_unittest_relocs_mips32_packed.so
Binary files differ
diff --git a/tools/relocation_packer/test_data/elf_file_unittest_relocs_x64.so b/tools/relocation_packer/test_data/elf_file_unittest_relocs_x64.so
new file mode 100755
index 0000000..6cb689e
--- /dev/null
+++ b/tools/relocation_packer/test_data/elf_file_unittest_relocs_x64.so
Binary files differ
diff --git a/tools/relocation_packer/test_data/elf_file_unittest_relocs_x64_packed.so b/tools/relocation_packer/test_data/elf_file_unittest_relocs_x64_packed.so
new file mode 100755
index 0000000..60b9ad1
--- /dev/null
+++ b/tools/relocation_packer/test_data/elf_file_unittest_relocs_x64_packed.so
Binary files differ