[automerger skipped] Revert "Add debug logging for memtag level" am: 9908b1e3c8 -s ours

am skip reason: Merged-In Ia7b8285a6abd6f89d49859a981be1c9cfa104f81 with SHA-1 dd44378da7 is already in history

Original change: https://googleplex-android-review.googlesource.com/c/platform/bionic/+/23298943

Change-Id: Iccb0a2b697a73b8dd23f3a7acfc5a5e1793b8abb
Signed-off-by: Automerger Merge Worker <android-build-automerger-merge-worker@system.gserviceaccount.com>
diff --git a/README.md b/README.md
index 8d8e583..5107f42 100644
--- a/README.md
+++ b/README.md
@@ -48,7 +48,9 @@
 #### tests/ --- unit tests
 
 The `tests/` directory contains unit tests. Roughly arranged as one file per
-publicly-exported header file.
+publicly-exported header file. `tests/headers/` contains compile-only tests
+that just check that things are _in_ the headers, whereas the "real" tests
+check actual _behavior_.
 
 #### benchmarks/ --- benchmarks
 
diff --git a/docs/defines.md b/docs/defines.md
index 4775cd2..65a715e 100644
--- a/docs/defines.md
+++ b/docs/defines.md
@@ -54,7 +54,7 @@
 work around issues with some of them, use these macros to detect the versinon of
 the NDK you're being built with. Usually only `__NDK_MAJOR__` will be necessary.
 
-## `__arm__`, `__aarch64__`, `__i386__`, `__x86_64__`
+## `__arm__`, `__aarch64__`, `__i386__`, `__x86_64__`, `__riscv`
 
 If your code is specific to a particular processor architecture, use these
 macros to conditionally compile. Note that the ABI usually called `arm64` uses
diff --git a/docs/status.md b/docs/status.md
index c2ed944..411b140 100644
--- a/docs/status.md
+++ b/docs/status.md
@@ -55,6 +55,9 @@
 
 Current libc symbols: https://android.googlesource.com/platform/bionic/+/master/libc/libc.map.txt
 
+New libc functions in V (API level 35):
+  * `timespec_getres` (C23 addition).
+
 New libc functions in U (API level 34):
   * `close_range` and `copy_file_range` (Linux-specific GNU extensions).
   * `memset_explicit` in <string.h> (C23 addition).
diff --git a/libc/Android.bp b/libc/Android.bp
index f5f5f7c..ecabb06 100644
--- a/libc/Android.bp
+++ b/libc/Android.bp
@@ -1205,8 +1205,8 @@
         "bionic/termios.cpp",
         "bionic/thread_private.cpp",
         "bionic/threads.cpp",
+        "bionic/time.cpp",
         "bionic/time_l.cpp",
-        "bionic/timespec_get.cpp",
         "bionic/tmpfile.cpp",
         "bionic/umount.cpp",
         "bionic/unlink.cpp",
diff --git a/libc/arch-arm64/bionic/vfork.S b/libc/arch-arm64/bionic/vfork.S
index 9eb82d8..9b19232 100644
--- a/libc/arch-arm64/bionic/vfork.S
+++ b/libc/arch-arm64/bionic/vfork.S
@@ -28,6 +28,7 @@
 
 #include <platform/bionic/tls_defines.h>
 #include <private/bionic_asm.h>
+#include <private/bionic_asm_offsets.h>
 #include <asm/signal.h>
 #include <linux/sched.h>
 
@@ -42,10 +43,29 @@
     ldr     w10, [x9, #20]
     str     w0, [x9, #20]
 
-    // Clear vfork_child_stack_bottom_.
-    str     xzr, [x9, #776]
+    mov     x0, #SIGCHLD
 
-    mov     x0, #(CLONE_VM | CLONE_VFORK | SIGCHLD)
+    // If either HWASan or stack MTE is enabled, set up the clone() flags to
+    // make vfork() act like fork(). We don't call the atfork handlers, so we
+    // may deadlock if the child allocates, but we have seen badly written
+    // atfork handlers themselves cause deadlocks [1]. ndk_translation already
+    // implements vfork() as fork() without calling handlers, so we have some
+    // evidence that it isn't necessary to call them.
+    //
+    // POSIX.1 defines vfork() to have the same effect as fork() except that
+    // most behavior, including heap allocation, becomes undefined in the child,
+    // so we aren't violating POSIX by doing this.
+    //
+    // [1] https://cs.android.com/android/platform/superproject/+/master:system/extras/simpleperf/app_api/cpp/simpleperf.cpp;drc=788fa4183441f4977ddbd5a055e42a7fe7691d21;l=308
+#if !__has_feature(hwaddress_sanitizer)
+    // if (!__libc_globals->memtag_stack) x0 |= CLONE_VM | CLONE_VFORK;
+    adrp    x1, __libc_globals + OFFSETOF_libc_globals_memtag_stack
+    ldrb    w1, [x1, :lo12:__libc_globals + OFFSETOF_libc_globals_memtag_stack]
+    cbnz    w1, 1f
+    orr     x0, x0, #CLONE_VM
+    orr     x0, x0, #CLONE_VFORK
+1:
+#endif
     mov     x1, xzr
     mov     x2, xzr
     mov     x3, xzr
@@ -62,25 +82,6 @@
     cneg    x0, x0, hi
     b.hi    __set_errno_internal
 
-    // Clean up stack shadow in the parent process.
-    // https://github.com/google/sanitizers/issues/925
-    paciasp
-    .cfi_negate_ra_state
-    stp x0, x30, [sp, #-16]!
-    .cfi_adjust_cfa_offset 16
-    .cfi_rel_offset x0, 0
-    .cfi_rel_offset x30, 8
-
-    add x0, sp, #16
-    bl memtag_handle_vfork
-
-    ldp x0, x30, [sp], #16
-    .cfi_adjust_cfa_offset -16
-    .cfi_restore x0
-    .cfi_restore x30
-    autiasp
-    .cfi_negate_ra_state
-
 .L_exit:
     ret
 END(vfork)
diff --git a/libc/bionic/exec.cpp b/libc/bionic/exec.cpp
index 40612e7..863aa97 100644
--- a/libc/bionic/exec.cpp
+++ b/libc/bionic/exec.cpp
@@ -186,6 +186,5 @@
 
 __attribute__((no_sanitize("memtag"))) int execve(const char* pathname, char* const* argv,
                                                   char* const* envp) {
-  __get_thread()->vfork_child_stack_bottom = __builtin_frame_address(0);
   return __execve(pathname, argv, envp);
 }
diff --git a/libc/bionic/exit.cpp b/libc/bionic/exit.cpp
index 52fd193..04baac2 100644
--- a/libc/bionic/exit.cpp
+++ b/libc/bionic/exit.cpp
@@ -37,7 +37,6 @@
 extern "C" __noreturn void __exit_group(int status);
 
 __attribute__((no_sanitize("memtag"))) void _exit(int status) {
-  __get_thread()->vfork_child_stack_bottom = __builtin_frame_address(0);
   __exit_group(status);
 }
 
diff --git a/libc/bionic/heap_tagging.cpp b/libc/bionic/heap_tagging.cpp
index 78d21b0..be21e0c 100644
--- a/libc/bionic/heap_tagging.cpp
+++ b/libc/bionic/heap_tagging.cpp
@@ -212,29 +212,3 @@
   __hwasan_handle_longjmp(sp_dst);
 #endif  // __has_feature(hwaddress_sanitizer)
 }
-
-extern "C" __LIBC_HIDDEN__ __attribute__((no_sanitize("memtag"), no_sanitize("hwaddress"))) void
-memtag_handle_vfork(void* sp __unused) {
-#ifdef __aarch64__
-  if (__libc_globals->memtag_stack) {
-    void* child_sp = __get_thread()->vfork_child_stack_bottom;
-    __get_thread()->vfork_child_stack_bottom = nullptr;
-    if (child_sp) {
-      size_t distance = reinterpret_cast<uintptr_t>(sp) - reinterpret_cast<uintptr_t>(child_sp);
-      if (distance > kUntagLimit) {
-        async_safe_fatal(
-            "memtag_handle_vfork: stack adjustment too large! %p -> %p, distance %zx > %zx\n",
-            child_sp, sp, distance, kUntagLimit);
-      } else {
-        untag_memory(child_sp, sp);
-      }
-    } else {
-      async_safe_fatal("memtag_handle_vfork: child SP unknown\n");
-    }
-  }
-#endif  // __aarch64__
-
-#if __has_feature(hwaddress_sanitizer)
-  __hwasan_handle_vfork(sp);
-#endif  // __has_feature(hwaddress_sanitizer)
-}
diff --git a/libc/bionic/pthread_create.cpp b/libc/bionic/pthread_create.cpp
index 7bf9b40..844f9d8 100644
--- a/libc/bionic/pthread_create.cpp
+++ b/libc/bionic/pthread_create.cpp
@@ -140,7 +140,7 @@
 #if defined(__aarch64__)
   __asm__ __volatile__("mov x18, %0" ::"r"(scs));
 #elif defined(__riscv)
-  __asm__ __volatile__("mv gp, %0" ::"r"(scs));
+  __asm__ __volatile__("mv x3, %0" ::"r"(scs));
 #endif
 #endif
 }
diff --git a/libc/bionic/pthread_internal.h b/libc/bionic/pthread_internal.h
index a3a4ccd..7efbf6d 100644
--- a/libc/bionic/pthread_internal.h
+++ b/libc/bionic/pthread_internal.h
@@ -137,7 +137,7 @@
   //    clobber x18 on arm64, therefore each process must declare early during
   //    process startup whether it might load legacy code.
   //    TODO: riscv64 has no legacy code, so we can actually go this route
-  //    there, but hopefully we'll actually get the Zsslpcfi extension instead.
+  //    there, but hopefully we'll actually get the Zisslpcfi extension instead.
   // 2) Mark the guard region as such using prctl(PR_SET_VMA_ANON_NAME) and
   //    discover its address by reading /proc/self/maps. One issue with this is
   //    that reading /proc/self/maps can race with allocations, so we may need
@@ -176,13 +176,6 @@
   bionic_tls* bionic_tls;
 
   int errno_value;
-
-  // The last observed value of SP in a vfork child process.
-  // The part of the stack between this address and the value of SP when the vfork parent process
-  // regains control may have stale MTE tags and needs cleanup. This field is only meaningful while
-  // the parent is waiting for the vfork child to return control by calling either exec*() or
-  // exit().
-  void* vfork_child_stack_bottom;
 };
 
 struct ThreadMapping {
diff --git a/libc/bionic/syslog.cpp b/libc/bionic/syslog.cpp
index 6b17d26..a459c6b 100644
--- a/libc/bionic/syslog.cpp
+++ b/libc/bionic/syslog.cpp
@@ -18,18 +18,22 @@
 #include <stdlib.h>
 #include <string.h>
 #include <syslog.h>
+#include <unistd.h>
 
 #include <async_safe/log.h>
 
 static const char* syslog_log_tag = nullptr;
 static int syslog_priority_mask = 0xff;
+static int syslog_options = 0;
 
 void closelog() {
   syslog_log_tag = nullptr;
+  syslog_options = 0;
 }
 
-void openlog(const char* log_tag, int /*options*/, int /*facility*/) {
+void openlog(const char* log_tag, int options, int /*facility*/) {
   syslog_log_tag = log_tag;
+  syslog_options = options;
 }
 
 int setlogmask(int new_mask) {
@@ -73,10 +77,16 @@
     android_log_priority = ANDROID_LOG_DEBUG;
   }
 
-  // We can't let async_safe_format_log do the formatting because it doesn't support
-  // all the printf functionality.
+  // We can't let async_safe_format_log do the formatting because it doesn't
+  // support all the printf functionality.
   char log_line[1024];
-  vsnprintf(log_line, sizeof(log_line), fmt, args);
+  int n = vsnprintf(log_line, sizeof(log_line), fmt, args);
+  if (n < 0) return;
 
   async_safe_format_log(android_log_priority, log_tag, "%s", log_line);
+  if ((syslog_options & LOG_PERROR) != 0) {
+    bool have_newline =
+        (n > 0 && n < static_cast<int>(sizeof(log_line)) && log_line[n - 1] == '\n');
+    dprintf(STDERR_FILENO, "%s: %s%s", log_tag, log_line, have_newline ? "" : "\n");
+  }
 }
diff --git a/libc/bionic/timespec_get.cpp b/libc/bionic/time.cpp
similarity index 89%
rename from libc/bionic/timespec_get.cpp
rename to libc/bionic/time.cpp
index 7fc2182..800395e 100644
--- a/libc/bionic/timespec_get.cpp
+++ b/libc/bionic/time.cpp
@@ -29,5 +29,9 @@
 #include <time.h>
 
 int timespec_get(timespec* ts, int base) {
-  return (base == TIME_UTC && clock_gettime(CLOCK_REALTIME, ts) != -1) ? base : 0;
+  return (clock_gettime(base - 1, ts) != -1) ? base : 0;
+}
+
+int timespec_getres(timespec* ts, int base) {
+  return (clock_getres(base - 1, ts) != -1) ? base : 0;
 }
diff --git a/libc/include/bits/ctype_inlines.h b/libc/include/bits/ctype_inlines.h
index 744eb91..089a642 100644
--- a/libc/include/bits/ctype_inlines.h
+++ b/libc/include/bits/ctype_inlines.h
@@ -61,7 +61,7 @@
 __BEGIN_DECLS
 
 /** Internal implementation detail. Do not use. */
-extern const char* _ctype_;
+extern const char* _Nonnull _ctype_;
 
 /** Returns true if `ch` is in `[A-Za-z0-9]`. */
 __BIONIC_CTYPE_INLINE int isalnum(int __ch) {
@@ -175,33 +175,33 @@
 
 #if __ANDROID_API__ >= 21
 /** Like isalnum but with an ignored `locale_t`. */
-int isalnum_l(int __ch, locale_t __l) __INTRODUCED_IN(21);
+int isalnum_l(int __ch, locale_t _Nonnull __l) __INTRODUCED_IN(21);
 /** Like isalpha but with an ignored `locale_t`. */
-int isalpha_l(int __ch, locale_t __l) __INTRODUCED_IN(21);
+int isalpha_l(int __ch, locale_t _Nonnull __l) __INTRODUCED_IN(21);
 /** Like isblank but with an ignored `locale_t`. */
-int isblank_l(int __ch, locale_t __l) __INTRODUCED_IN(21);
+int isblank_l(int __ch, locale_t _Nonnull __l) __INTRODUCED_IN(21);
 /** Like iscntrl but with an ignored `locale_t`. */
-int iscntrl_l(int __ch, locale_t __l) __INTRODUCED_IN(21);
+int iscntrl_l(int __ch, locale_t _Nonnull __l) __INTRODUCED_IN(21);
 /** Like isdigit but with an ignored `locale_t`. */
-int isdigit_l(int __ch, locale_t __l) __INTRODUCED_IN(21);
+int isdigit_l(int __ch, locale_t _Nonnull __l) __INTRODUCED_IN(21);
 /** Like isgraph but with an ignored `locale_t`. */
-int isgraph_l(int __ch, locale_t __l) __INTRODUCED_IN(21);
+int isgraph_l(int __ch, locale_t _Nonnull __l) __INTRODUCED_IN(21);
 /** Like islower but with an ignored `locale_t`. */
-int islower_l(int __ch, locale_t __l) __INTRODUCED_IN(21);
+int islower_l(int __ch, locale_t _Nonnull __l) __INTRODUCED_IN(21);
 /** Like isprint but with an ignored `locale_t`. */
-int isprint_l(int __ch, locale_t __l) __INTRODUCED_IN(21);
+int isprint_l(int __ch, locale_t _Nonnull __l) __INTRODUCED_IN(21);
 /** Like ispunct but with an ignored `locale_t`. */
-int ispunct_l(int __ch, locale_t __l) __INTRODUCED_IN(21);
+int ispunct_l(int __ch, locale_t _Nonnull __l) __INTRODUCED_IN(21);
 /** Like isspace but with an ignored `locale_t`. */
-int isspace_l(int __ch, locale_t __l) __INTRODUCED_IN(21);
+int isspace_l(int __ch, locale_t _Nonnull __l) __INTRODUCED_IN(21);
 /** Like isupper but with an ignored `locale_t`. */
-int isupper_l(int __ch, locale_t __l) __INTRODUCED_IN(21);
+int isupper_l(int __ch, locale_t _Nonnull __l) __INTRODUCED_IN(21);
 /** Like isxdigit but with an ignored `locale_t`. */
-int isxdigit_l(int __ch, locale_t __l) __INTRODUCED_IN(21);
+int isxdigit_l(int __ch, locale_t _Nonnull __l) __INTRODUCED_IN(21);
 /** Like tolower but with an ignored `locale_t`. */
-int tolower_l(int __ch, locale_t __l) __INTRODUCED_IN(21);
+int tolower_l(int __ch, locale_t _Nonnull __l) __INTRODUCED_IN(21);
 /** Like toupper but with an ignored `locale_t`. */
-int toupper_l(int __ch, locale_t __l) __INTRODUCED_IN(21);
+int toupper_l(int __ch, locale_t _Nonnull __l) __INTRODUCED_IN(21);
 #else
 // Implemented as static inlines in libc++ before 21.
 #endif
diff --git a/libc/include/bits/get_device_api_level_inlines.h b/libc/include/bits/get_device_api_level_inlines.h
index d14eb2c..dc5871b 100644
--- a/libc/include/bits/get_device_api_level_inlines.h
+++ b/libc/include/bits/get_device_api_level_inlines.h
@@ -35,8 +35,8 @@
 __BEGIN_DECLS
 
 // Avoid circular dependencies since this is exposed from <sys/cdefs.h>.
-int __system_property_get(const char* __name, char* __value);
-int atoi(const char* __s) __attribute_pure__;
+int __system_property_get(const char* _Nonnull __name, char*  _Nonnull __value);
+int atoi(const char* _Nonnull __s) __attribute_pure__;
 
 __BIONIC_GET_DEVICE_API_LEVEL_INLINE int android_get_device_api_level() {
   char value[92] = { 0 };
diff --git a/libc/include/bits/getopt.h b/libc/include/bits/getopt.h
index 0411716..60a89ed 100644
--- a/libc/include/bits/getopt.h
+++ b/libc/include/bits/getopt.h
@@ -38,12 +38,12 @@
  * Returns the next option character on success, returns -1 if all options have been parsed, and
  * returns `'?'` on error.
  */
-int getopt(int __argc, char* const __argv[], const char* __options);
+int getopt(int __argc, char* const _Nonnull __argv[_Nullable], const char* _Nonnull __options);
 
 /**
  * Points to the text of the corresponding value for options that take an argument.
  */
-extern char* optarg;
+extern char* _Nullable optarg;
 
 /**
  * The index of the next element to be processed.
diff --git a/libc/include/bits/glibc-syscalls.h b/libc/include/bits/glibc-syscalls.h
index c144919..79f7da0 100644
--- a/libc/include/bits/glibc-syscalls.h
+++ b/libc/include/bits/glibc-syscalls.h
@@ -906,6 +906,9 @@
 #if defined(__NR_restart_syscall)
   #define SYS_restart_syscall __NR_restart_syscall
 #endif
+#if defined(__NR_riscv_flush_icache)
+  #define SYS_riscv_flush_icache __NR_riscv_flush_icache
+#endif
 #if defined(__NR_rmdir)
   #define SYS_rmdir __NR_rmdir
 #endif
diff --git a/libc/include/bits/strcasecmp.h b/libc/include/bits/strcasecmp.h
index 3994b68..23acbe5 100644
--- a/libc/include/bits/strcasecmp.h
+++ b/libc/include/bits/strcasecmp.h
@@ -46,12 +46,12 @@
  * Returns an integer less than, equal to, or greater than zero if the first string is less than,
  * equal to, or greater than the second string (ignoring case).
  */
-int strcasecmp(const char* __s1, const char* __s2) __attribute_pure__;
+int strcasecmp(const char* _Nonnull __s1, const char* _Nonnull __s2) __attribute_pure__;
 
 /**
  * Like strcasecmp() but taking a `locale_t`.
  */
-int strcasecmp_l(const char* __s1, const char* __s2, locale_t __l) __attribute_pure__ __INTRODUCED_IN(23);
+int strcasecmp_l(const char* _Nonnull __s1, const char* _Nonnull __s2, locale_t _Nonnull __l) __attribute_pure__ __INTRODUCED_IN(23);
 
 /**
  * [strncasecmp(3)](http://man7.org/linux/man-pages/man3/strncasecmp.3.html) compares the first
@@ -61,11 +61,11 @@
  * first string is less than, equal to, or greater than the first `n` bytes of the second
  * string (ignoring case).
  */
-int strncasecmp(const char* __s1, const char* __s2, size_t __n) __attribute_pure__;
+int strncasecmp(const char* _Nonnull __s1, const char* _Nonnull __s2, size_t __n) __attribute_pure__;
 
 /**
  * Like strncasecmp() but taking a `locale_t`.
  */
-int strncasecmp_l(const char* __s1, const char* __s2, size_t __n, locale_t __l) __attribute_pure__ __INTRODUCED_IN(23);
+int strncasecmp_l(const char* _Nonnull __s1, const char* _Nonnull __s2, size_t __n, locale_t _Nonnull __l) __attribute_pure__ __INTRODUCED_IN(23);
 
 __END_DECLS
diff --git a/libc/include/bits/swab.h b/libc/include/bits/swab.h
index 63281b6..9591c2e 100644
--- a/libc/include/bits/swab.h
+++ b/libc/include/bits/swab.h
@@ -38,7 +38,7 @@
 
 __BEGIN_DECLS
 
-__BIONIC_SWAB_INLINE void swab(const void* __void_src, void* __void_dst, ssize_t __byte_count) {
+__BIONIC_SWAB_INLINE void swab(const void* _Nonnull __void_src, void* _Nonnull __void_dst, ssize_t __byte_count) {
   const uint8_t* __src = __BIONIC_CAST(static_cast, const uint8_t*, __void_src);
   uint8_t* __dst = __BIONIC_CAST(static_cast, uint8_t*, __void_dst);
   while (__byte_count > 1) {
diff --git a/libc/include/bits/wait.h b/libc/include/bits/wait.h
index a6a2129..c7f1fb0 100644
--- a/libc/include/bits/wait.h
+++ b/libc/include/bits/wait.h
@@ -53,7 +53,7 @@
 #define WIFEXITED(__status) (WTERMSIG(__status) == 0)
 
 /** Returns true if the process was stopped by a signal. */
-#define WIFSTOPPED(__status) (WTERMSIG(__status) == 0x7f)
+#define WIFSTOPPED(__status) (((__status) & 0xff) == 0x7f)
 
 /** Returns true if the process was terminated by a signal. */
 #define WIFSIGNALED(__status) (WTERMSIG((__status)+1) >= 2)
diff --git a/libc/include/malloc.h b/libc/include/malloc.h
index 6a2d380..91d63b3 100644
--- a/libc/include/malloc.h
+++ b/libc/include/malloc.h
@@ -232,8 +232,9 @@
 /**
  * mallopt() option for per-thread memory initialization tuning.
  * The value argument should be one of:
- * 1: Disable automatic heap initialization and, where possible, memory tagging,
- *    on this thread.
+ * 1: Disable automatic heap initialization on this thread only.
+ *    If memory tagging is enabled, disable as much as possible of the
+ *    memory tagging initialization for this thread.
  * 0: Normal behavior.
  *
  * Available since API level 31.
diff --git a/libc/include/net/if.h b/libc/include/net/if.h
index f261f71..79b4195 100644
--- a/libc/include/net/if.h
+++ b/libc/include/net/if.h
@@ -41,13 +41,13 @@
 
 struct if_nameindex {
   unsigned if_index;
-  char* if_name;
+  char* _Nullable if_name;
 };
 
-char* if_indextoname(unsigned __index, char* __buf);
-unsigned if_nametoindex(const char* __name);
-struct if_nameindex* if_nameindex(void) __INTRODUCED_IN(24);
-void if_freenameindex(struct if_nameindex* __ptr) __INTRODUCED_IN(24);
+char* _Nullable if_indextoname(unsigned __index, char* _Nonnull __buf);
+unsigned if_nametoindex(const char* _Nonnull __name);
+struct if_nameindex* _Nullable if_nameindex(void) __INTRODUCED_IN(24);
+void if_freenameindex(struct if_nameindex* _Nullable __ptr) __INTRODUCED_IN(24);
 
 __END_DECLS
 
diff --git a/libc/include/netdb.h b/libc/include/netdb.h
index 7a1987e..7afdc1a 100644
--- a/libc/include/netdb.h
+++ b/libc/include/netdb.h
@@ -79,31 +79,31 @@
  * use in system calls).
  */
 struct hostent {
-	char	*h_name;	/* official name of host */
-	char	**h_aliases;	/* alias list */
+	char	* _Nullable h_name;	/* official name of host */
+	char	* _Nullable * _Nullable h_aliases;	/* alias list */
 	int	h_addrtype;	/* host address type */
 	int	h_length;	/* length of address */
-	char	**h_addr_list;	/* list of addresses from name server */
+	char	* _Nullable * _Nullable h_addr_list;	/* list of addresses from name server */
 #define	h_addr	h_addr_list[0]	/* address, for backward compatibility */
 };
 
 struct netent {
-	char		*n_name;	/* official name of net */
-	char		**n_aliases;	/* alias list */
+	char		* _Nullable n_name;	/* official name of net */
+	char		* _Nullable * _Nullable n_aliases;	/* alias list */
 	int		n_addrtype;	/* net address type */
 	uint32_t	n_net;		/* network # */
 };
 
 struct servent {
-	char	*s_name;	/* official service name */
-	char	**s_aliases;	/* alias list */
+	char	* _Nullable s_name;	/* official service name */
+	char	* _Nullable * _Nullable s_aliases;	/* alias list */
 	int	s_port;		/* port # */
-	char	*s_proto;	/* protocol to use */
+	char	* _Nullable s_proto;	/* protocol to use */
 };
 
 struct protoent {
-	char	*p_name;	/* official protocol name */
-	char	**p_aliases;	/* alias list */
+	char	* _Nullable p_name;	/* official protocol name */
+	char	* _Nullable * _Nullable p_aliases;	/* alias list */
 	int	p_proto;	/* protocol # */
 };
 
@@ -113,9 +113,9 @@
 	int	ai_socktype;	/* SOCK_xxx */
 	int	ai_protocol;	/* 0 or IPPROTO_xxx for IPv4 and IPv6 */
 	socklen_t ai_addrlen;	/* length of ai_addr */
-	char	*ai_canonname;	/* canonical name for hostname */
-	struct	sockaddr *ai_addr;	/* binary address */
-	struct	addrinfo *ai_next;	/* next structure in linked list */
+	char	* _Nullable ai_canonname;	/* canonical name for hostname */
+	struct	sockaddr * _Nullable ai_addr;	/* binary address */
+	struct	addrinfo * _Nullable ai_next;	/* next structure in linked list */
 };
 
 /*
@@ -196,47 +196,47 @@
 
 __BEGIN_DECLS
 
-int getaddrinfo(const char* __node, const char* __service, const struct addrinfo* __hints, struct addrinfo** __result);
-void freeaddrinfo(struct addrinfo* __ptr);
+int getaddrinfo(const char* _Nullable __node, const char* _Nullable __service, const struct addrinfo* _Nullable __hints, struct addrinfo* _Nullable * _Nonnull __result);
+void freeaddrinfo(struct addrinfo* _Nullable __ptr);
 
 /* Android ABI error: POSIX getnameinfo(3) uses socklen_t rather than size_t. */
-int getnameinfo(const struct sockaddr* __sa, socklen_t __sa_length, char* __host, size_t __host_length, char* __service, size_t __service_length, int __flags);
-const char* gai_strerror(int __error);
+int getnameinfo(const struct sockaddr* _Nonnull __sa, socklen_t __sa_length, char* _Nullable __host, size_t __host_length, char* _Nullable __service, size_t __service_length, int __flags);
+const char* _Nonnull gai_strerror(int __error);
 
 /* These functions are obsolete. Use getaddrinfo/getnameinfo instead. */
 #define h_errno (*__get_h_errno())
-int* __get_h_errno(void);
-void herror(const char* __s);
-const char* hstrerror(int __error);
-struct hostent* gethostbyaddr(const void* __addr, socklen_t __length, int __type);
-int gethostbyaddr_r(const void* __addr, socklen_t __length, int __type, struct hostent* __ret, char* __buf, size_t __buf_size, struct hostent** __result, int* __h_errno_ptr) __INTRODUCED_IN(23);
-struct hostent* gethostbyname(const char* __name);
-int gethostbyname_r(const char* __name, struct hostent* __ret, char* __buf, size_t __buf_size, struct hostent** __result, int* __h_errno_ptr);
-struct hostent* gethostbyname2(const char* __name, int __af);
-int gethostbyname2_r(const char* __name, int __af, struct hostent* __ret, char* __buf, size_t __buf_size, struct hostent** __result, int* __h_errno_ptr) __INTRODUCED_IN(23);
+int* _Nonnull __get_h_errno(void);
+void herror(const char* _Nonnull __s);
+const char* _Nonnull hstrerror(int __error);
+struct hostent* _Nullable gethostbyaddr(const void* _Nonnull __addr, socklen_t __length, int __type);
+int gethostbyaddr_r(const void* _Nonnull __addr, socklen_t __length, int __type, struct hostent* _Nonnull __ret, char* _Nonnull __buf, size_t __buf_size, struct hostent* _Nullable * _Nonnull __result, int* _Nonnull __h_errno_ptr) __INTRODUCED_IN(23);
+struct hostent* _Nullable gethostbyname(const char* _Nonnull __name);
+int gethostbyname_r(const char* _Nonnull __name, struct hostent* _Nonnull __ret, char* _Nonnull __buf, size_t __buf_size, struct hostent* _Nullable * _Nonnull __result, int* _Nonnull __h_errno_ptr);
+struct hostent* _Nullable gethostbyname2(const char* _Nonnull __name, int __af);
+int gethostbyname2_r(const char* _Nonnull __name, int __af, struct hostent* _Nonnull __ret, char* _Nonnull __buf, size_t __buf_size, struct hostent* _Nullable * _Nonnull __result, int* _Nonnull __h_errno_ptr) __INTRODUCED_IN(23);
 void endhostent(void) __INTRODUCED_IN(28);
-struct hostent* gethostent(void);
+struct hostent* _Nullable gethostent(void);
 void sethostent(int __stay_open) __INTRODUCED_IN(28);
 
 /* These functions are obsolete. None of these functions return anything but nullptr. */
 void endnetent(void) __INTRODUCED_IN(28);
-struct netent* getnetbyaddr(uint32_t __net, int __type);
-struct netent* getnetbyname(const char* __name);
-struct netent* getnetent(void) __INTRODUCED_IN(28);
+struct netent* _Nullable getnetbyaddr(uint32_t __net, int __type);
+struct netent* _Nullable getnetbyname(const char* _Nonnull __name);
+struct netent* _Nullable getnetent(void) __INTRODUCED_IN(28);
 void setnetent(int __stay_open) __INTRODUCED_IN(28);
 
 /* None of these functions return anything but nullptr. */
 void endprotoent(void) __INTRODUCED_IN(28);
-struct protoent* getprotobyname(const char* __name);
-struct protoent* getprotobynumber(int __proto);
-struct protoent* getprotoent(void) __INTRODUCED_IN(28);
+struct protoent* _Nullable getprotobyname(const char* _Nonnull __name);
+struct protoent* _Nullable getprotobynumber(int __proto);
+struct protoent* _Nullable getprotoent(void) __INTRODUCED_IN(28);
 void setprotoent(int __stay_open) __INTRODUCED_IN(28);
 
 /* These functions return entries from a built-in database. */
 void endservent(void);
-struct servent* getservbyname(const char* __name, const char* __proto);
-struct servent* getservbyport(int __port_in_network_order, const char* __proto);
-struct servent* getservent(void);
+struct servent* _Nullable getservbyname(const char* _Nonnull __name, const char* _Nullable __proto);
+struct servent* _Nullable getservbyport(int __port_in_network_order, const char* _Nullable __proto);
+struct servent* _Nullable getservent(void);
 void setservent(int __stay_open);
 
 __END_DECLS
diff --git a/libc/include/netinet/ether.h b/libc/include/netinet/ether.h
index 480063d..d570c18 100644
--- a/libc/include/netinet/ether.h
+++ b/libc/include/netinet/ether.h
@@ -44,7 +44,7 @@
  *
  * Returns a pointer to a static buffer.
  */
-char* ether_ntoa(const struct ether_addr* __addr);
+char* _Nonnull ether_ntoa(const struct ether_addr* _Nonnull __addr);
 
 /**
  * [ether_ntoa_r(3)](http://man7.org/linux/man-pages/man3/ether_ntoa_r.3.html) returns a string
@@ -52,7 +52,7 @@
  *
  * Returns a pointer to the given buffer.
  */
-char* ether_ntoa_r(const struct ether_addr* __addr, char* __buf);
+char* _Nonnull ether_ntoa_r(const struct ether_addr* _Nonnull __addr, char* _Nonnull __buf);
 
 /**
  * [ether_aton(3)](http://man7.org/linux/man-pages/man3/ether_aton.3.html) returns an `ether_addr`
@@ -60,7 +60,7 @@
  *
  * Returns a pointer to a static buffer, or NULL if the given string isn't a valid MAC address.
  */
-struct ether_addr* ether_aton(const char* __ascii);
+struct ether_addr* _Nullable ether_aton(const char* _Nonnull __ascii);
 
 /**
  * [ether_aton_r(3)](http://man7.org/linux/man-pages/man3/ether_aton_r.3.html) returns an
@@ -68,6 +68,6 @@
  *
  * Returns a pointer to the given buffer, or NULL if the given string isn't a valid MAC address.
  */
-struct ether_addr* ether_aton_r(const char* __ascii, struct ether_addr* __addr);
+struct ether_addr* _Nullable ether_aton_r(const char* _Nonnull __ascii, struct ether_addr* _Nonnull __addr);
 
 __END_DECLS
diff --git a/libc/include/netinet/in.h b/libc/include/netinet/in.h
index 46e3543..b235e6e 100644
--- a/libc/include/netinet/in.h
+++ b/libc/include/netinet/in.h
@@ -54,7 +54,7 @@
 
 typedef uint16_t in_port_t;
 
-int bindresvport(int __fd, struct sockaddr_in* __sin);
+int bindresvport(int __fd, struct sockaddr_in* _Nullable __sin);
 
 #if __ANDROID_API__ >= 24
 extern const struct in6_addr in6addr_any __INTRODUCED_IN(24);
diff --git a/libc/include/stdio.h b/libc/include/stdio.h
index e748faa..d7b65e4 100644
--- a/libc/include/stdio.h
+++ b/libc/include/stdio.h
@@ -143,9 +143,9 @@
     (defined(__cplusplus) && __cplusplus <= 201103L)
 char* _Nullable gets(char* _Nonnull __buf) __attribute__((deprecated("gets is unsafe, use fgets instead")));
 #endif
-int sprintf(char* _Nonnull __s, const char* _Nonnull __fmt, ...)
+int sprintf(char* __BIONIC_COMPLICATED_NULLNESS __s, const char* _Nonnull __fmt, ...)
     __printflike(2, 3) __warnattr_strict("sprintf is often misused; please use snprintf");
-int vsprintf(char* _Nonnull __s, const char* _Nonnull __fmt, va_list __args)
+int vsprintf(char* __BIONIC_COMPLICATED_NULLNESS __s, const char* _Nonnull __fmt, va_list __args)
     __printflike(2, 0) __warnattr_strict("vsprintf is often misused; please use vsnprintf");
 char* _Nullable tmpnam(char* _Nullable __s)
     __warnattr("tmpnam is unsafe, use mkstemp or tmpfile instead");
@@ -251,10 +251,10 @@
 FILE* _Nullable tmpfile(void);
 FILE* _Nullable tmpfile64(void) __INTRODUCED_IN(24);
 
-int snprintf(char* _Nullable __buf, size_t __size, const char* _Nonnull __fmt, ...) __printflike(3, 4);
+int snprintf(char* __BIONIC_COMPLICATED_NULLNESS __buf, size_t __size, const char* _Nonnull __fmt, ...) __printflike(3, 4);
 int vfscanf(FILE* _Nonnull __fp, const char* _Nonnull __fmt, va_list __args) __scanflike(2, 0);
 int vscanf(const char* _Nonnull __fmt , va_list __args) __scanflike(1, 0);
-int vsnprintf(char* _Nullable __buf, size_t __size, const char* _Nonnull __fmt, va_list __args) __printflike(3, 0);
+int vsnprintf(char* __BIONIC_COMPLICATED_NULLNESS __buf, size_t __size, const char* _Nonnull __fmt, va_list __args) __printflike(3, 0);
 int vsscanf(const char* _Nonnull __s, const char* _Nonnull __fmt, va_list __args) __scanflike(2, 0);
 
 #define L_ctermid 1024 /* size for ctermid() */
diff --git a/libc/include/sys/resource.h b/libc/include/sys/resource.h
index ccb267d..0b540de 100644
--- a/libc/include/sys/resource.h
+++ b/libc/include/sys/resource.h
@@ -43,19 +43,19 @@
 typedef unsigned long rlim_t;
 typedef unsigned long long rlim64_t;
 
-int getrlimit(int __resource, struct rlimit* __limit);
-int setrlimit(int __resource, const struct rlimit* __limit);
+int getrlimit(int __resource, struct rlimit* _Nonnull __limit);
+int setrlimit(int __resource, const struct rlimit* _Nonnull __limit);
 
-int getrlimit64(int __resource, struct rlimit64* __limit) __INTRODUCED_IN(21);
-int setrlimit64(int __resource, const struct rlimit64* __limit) __INTRODUCED_IN(21);
+int getrlimit64(int __resource, struct rlimit64* _Nonnull __limit) __INTRODUCED_IN(21);
+int setrlimit64(int __resource, const struct rlimit64* _Nonnull __limit) __INTRODUCED_IN(21);
 
 int getpriority(int __which, id_t __who);
 int setpriority(int __which, id_t __who, int __priority);
 
-int getrusage(int __who, struct rusage* __usage);
+int getrusage(int __who, struct rusage* _Nonnull __usage);
 
-int prlimit(pid_t __pid, int __resource, const struct rlimit* __new_limit, struct rlimit* __old_limit) __INTRODUCED_IN_32(24) __INTRODUCED_IN_64(21);
-int prlimit64(pid_t __pid, int __resource, const struct rlimit64* __new_limit, struct rlimit64* __old_limit) __INTRODUCED_IN(21);
+int prlimit(pid_t __pid, int __resource, const struct rlimit* _Nullable __new_limit, struct rlimit* _Nullable __old_limit) __INTRODUCED_IN_32(24) __INTRODUCED_IN_64(21);
+int prlimit64(pid_t __pid, int __resource, const struct rlimit64* _Nullable __new_limit, struct rlimit64* _Nullable __old_limit) __INTRODUCED_IN(21);
 
 __END_DECLS
 
diff --git a/libc/include/sys/sem.h b/libc/include/sys/sem.h
index cd62242..f4256e2 100644
--- a/libc/include/sys/sem.h
+++ b/libc/include/sys/sem.h
@@ -45,18 +45,18 @@
 
 union semun {
   int val;
-  struct semid_ds* buf;
-  unsigned short* array;
-  struct seminfo* __buf;
-  void* __pad;
+  struct semid_ds* _Nullable buf;
+  unsigned short* _Nullable array;
+  struct seminfo* _Nullable __buf;
+  void* _Nullable __pad;
 };
 
 int semctl(int __sem_id, int __sem_num, int __cmd, ...) __INTRODUCED_IN(26);
 int semget(key_t __key, int __sem_count, int __flags) __INTRODUCED_IN(26);
-int semop(int __sem_id, struct sembuf* __ops, size_t __op_count) __INTRODUCED_IN(26);
+int semop(int __sem_id, struct sembuf* _Nonnull __ops, size_t __op_count) __INTRODUCED_IN(26);
 
 #if defined(__USE_GNU)
-int semtimedop(int __sem_id, struct sembuf* __ops, size_t __op_count, const struct timespec* __timeout) __INTRODUCED_IN(26);
+int semtimedop(int __sem_id, struct sembuf* _Nonnull __ops, size_t __op_count, const struct timespec* _Nullable __timeout) __INTRODUCED_IN(26);
 #endif
 
 __END_DECLS
diff --git a/libc/include/sys/statvfs.h b/libc/include/sys/statvfs.h
index 793ee13..d81f836 100644
--- a/libc/include/sys/statvfs.h
+++ b/libc/include/sys/statvfs.h
@@ -96,7 +96,7 @@
  *
  * Available since API level 19.
  */
-int statvfs(const char* __path, struct statvfs* __buf) __INTRODUCED_IN(19);
+int statvfs(const char* _Nonnull __path, struct statvfs* _Nonnull __buf) __INTRODUCED_IN(19);
 
 /**
  * [fstatvfs(3)](http://man7.org/linux/man-pages/man3/fstatvfs.3.html)
@@ -106,12 +106,12 @@
  *
  * Available since API level 19.
  */
-int fstatvfs(int __fd, struct statvfs* __buf) __INTRODUCED_IN(19);
+int fstatvfs(int __fd, struct statvfs* _Nonnull __buf) __INTRODUCED_IN(19);
 
 /** Equivalent to statvfs() . */
-int statvfs64(const char* __path, struct statvfs64* __buf) __INTRODUCED_IN(21);
+int statvfs64(const char* _Nonnull __path, struct statvfs64* _Nonnull __buf) __INTRODUCED_IN(21);
 
 /** Equivalent to fstatvfs(). */
-int fstatvfs64(int __fd, struct statvfs64* __buf) __INTRODUCED_IN(21);
+int fstatvfs64(int __fd, struct statvfs64* _Nonnull __buf) __INTRODUCED_IN(21);
 
 __END_DECLS
diff --git a/libc/include/sys/time.h b/libc/include/sys/time.h
index 45190c3..6ba7a37 100644
--- a/libc/include/sys/time.h
+++ b/libc/include/sys/time.h
@@ -38,21 +38,34 @@
 
 __BEGIN_DECLS
 
-int gettimeofday(struct timeval* __tv, struct timezone* __tz);
-int settimeofday(const struct timeval* __tv, const struct timezone* __tz);
+int gettimeofday(struct timeval* _Nullable __tv, struct timezone* _Nullable __tz);
+int settimeofday(const struct timeval* _Nullable __tv, const struct timezone* _Nullable __tz);
 
-int getitimer(int __which, struct itimerval* __current_value);
-int setitimer(int __which, const struct itimerval* __new_value, struct itimerval* __old_value);
+int getitimer(int __which, struct itimerval* _Nonnull __current_value);
+int setitimer(int __which, const struct itimerval* _Nonnull __new_value, struct itimerval* _Nullable __old_value);
 
-int utimes(const char* __path, const struct timeval __times[2]);
+int utimes(const char* _Nonnull __path, const struct timeval __times[_Nullable 2]);
 
 #if defined(__USE_BSD)
-int futimes(int __fd, const struct timeval __times[2]) __INTRODUCED_IN(26);
-int lutimes(const char* __path, const struct timeval __times[2]) __INTRODUCED_IN(26);
+int futimes(int __fd, const struct timeval __times[_Nullable 2]) __INTRODUCED_IN(26);
+int lutimes(const char* _Nonnull __path, const struct timeval __times[_Nullable 2]) __INTRODUCED_IN(26);
 #endif
 
 #if defined(__USE_GNU)
-int futimesat(int __dir_fd, const char* __path, const struct timeval __times[2]) __INTRODUCED_IN(26);
+/**
+ * [futimesat(2)](https://man7.org/linux/man-pages/man2/futimesat.2.html) sets
+ * file timestamps.
+ *
+ * Note: Linux supports `__path` being NULL (in which case `__dir_fd` need not
+ * be a directory), allowing futimensat() to be implemented with utimensat().
+ * Most callers should just use utimensat() directly, especially on Android
+ * where utimensat() has been available for longer than futimesat().
+ *
+ * Returns 0 on success and -1 and sets `errno` on failure.
+ *
+ * Available since API level 26.
+ */
+int futimesat(int __dir_fd, const char* __BIONIC_COMPLICATED_NULLNESS __path, const struct timeval __times[_Nullable 2]) __INTRODUCED_IN(26);
 #endif
 
 #define timerclear(a)   \
diff --git a/libc/include/sys/timerfd.h b/libc/include/sys/timerfd.h
index b89941b..aafcef2 100644
--- a/libc/include/sys/timerfd.h
+++ b/libc/include/sys/timerfd.h
@@ -68,7 +68,7 @@
  *
  * Available since API level 19.
  */
-int timerfd_settime(int __fd, int __flags, const struct itimerspec* __new_value, struct itimerspec* __old_value) __INTRODUCED_IN(19);
+int timerfd_settime(int __fd, int __flags, const struct itimerspec* _Nonnull __new_value, struct itimerspec* _Nullable __old_value) __INTRODUCED_IN(19);
 
 /**
  * [timerfd_gettime(2)](http://man7.org/linux/man-pages/man2/timerfd_gettime.2.html) queries the
@@ -78,6 +78,6 @@
  *
  * Available since API level 19.
  */
-int timerfd_gettime(int __fd, struct itimerspec* __current_value) __INTRODUCED_IN(19);
+int timerfd_gettime(int __fd, struct itimerspec* _Nonnull __current_value) __INTRODUCED_IN(19);
 
 __END_DECLS
diff --git a/libc/include/sys/times.h b/libc/include/sys/times.h
index 25d03e3..8b6e91d 100644
--- a/libc/include/sys/times.h
+++ b/libc/include/sys/times.h
@@ -46,6 +46,6 @@
  * Returns a (possibly overflowed) absolute time on success,
  * and returns -1 and sets `errno` on failure.
  */
-clock_t times(struct tms* __buf);
+clock_t times(struct tms* _Nullable __buf);
 
 __END_DECLS
diff --git a/libc/include/sys/timex.h b/libc/include/sys/timex.h
index 52db5dc..4823edf 100644
--- a/libc/include/sys/timex.h
+++ b/libc/include/sys/timex.h
@@ -46,7 +46,7 @@
  *
  * Available since API level 24.
  */
-int adjtimex(struct timex* __buf) __INTRODUCED_IN(24);
+int adjtimex(struct timex* _Nonnull __buf) __INTRODUCED_IN(24);
 
 /**
  * clock_adjtime adjusts a specific kernel clock.
@@ -55,6 +55,6 @@
  *
  * Available since API level 24.
  */
-int clock_adjtime(clockid_t __clock, struct timex* __tx) __INTRODUCED_IN(24);
+int clock_adjtime(clockid_t __clock, struct timex* _Nonnull __tx) __INTRODUCED_IN(24);
 
 __END_DECLS
diff --git a/libc/include/sys/ucontext.h b/libc/include/sys/ucontext.h
index bb6443b..4f4d5ce 100644
--- a/libc/include/sys/ucontext.h
+++ b/libc/include/sys/ucontext.h
@@ -318,12 +318,20 @@
 
 #if defined(__USE_GNU)
 
-#define REG_PC 0
-#define REG_RA 1
-#define REG_SP 2
-#define REG_TP 4
-#define REG_S0 8
-#define REG_A0 10
+enum {
+  REG_PC = 0,
+#define REG_PC REG_PC
+  REG_RA = 1,
+#define REG_RA REG_RA
+  REG_SP = 2,
+#define REG_SP REG_SP
+  REG_TP = 4,
+#define REG_TP REG_TP
+  REG_S0 = 8,
+#define REG_S0 REG_S0
+  REG_A0 = 10,
+#define REG_A0 REG_A0
+};
 
 #endif // defined(__USE_GNU)
 
diff --git a/libc/include/sys/uio.h b/libc/include/sys/uio.h
index 583cfc6..c8c64ae 100644
--- a/libc/include/sys/uio.h
+++ b/libc/include/sys/uio.h
@@ -46,7 +46,7 @@
  * Returns the number of bytes read on success,
  * and returns -1 and sets `errno` on failure.
  */
-ssize_t readv(int __fd, const struct iovec* __iov, int __count);
+ssize_t readv(int __fd, const struct iovec* _Nonnull __iov, int __count);
 
 /**
  * [writev(2)](http://man7.org/linux/man-pages/man2/writev.2.html) writes
@@ -55,7 +55,7 @@
  * Returns the number of bytes written on success,
  * and returns -1 and sets `errno` on failure.
  */
-ssize_t writev(int __fd, const struct iovec* __iov, int __count);
+ssize_t writev(int __fd, const struct iovec* _Nonnull __iov, int __count);
 
 #if defined(__USE_GNU)
 
@@ -69,7 +69,7 @@
  *
  * Available since API level 24.
  */
-ssize_t preadv(int __fd, const struct iovec* __iov, int __count, off_t __offset) __RENAME_IF_FILE_OFFSET64(preadv64) __INTRODUCED_IN(24);
+ssize_t preadv(int __fd, const struct iovec* _Nonnull __iov, int __count, off_t __offset) __RENAME_IF_FILE_OFFSET64(preadv64) __INTRODUCED_IN(24);
 
 /**
  * [pwritev(2)](http://man7.org/linux/man-pages/man2/pwritev.2.html) writes
@@ -81,21 +81,21 @@
  *
  * Available since API level 24.
  */
-ssize_t pwritev(int __fd, const struct iovec* __iov, int __count, off_t __offset) __RENAME_IF_FILE_OFFSET64(pwritev64) __INTRODUCED_IN(24);
+ssize_t pwritev(int __fd, const struct iovec* _Nonnull __iov, int __count, off_t __offset) __RENAME_IF_FILE_OFFSET64(pwritev64) __INTRODUCED_IN(24);
 
 /**
  * Like preadv() but with a 64-bit offset even in a 32-bit process.
  *
  * Available since API level 24.
  */
-ssize_t preadv64(int __fd, const struct iovec* __iov, int __count, off64_t __offset) __INTRODUCED_IN(24);
+ssize_t preadv64(int __fd, const struct iovec* _Nonnull __iov, int __count, off64_t __offset) __INTRODUCED_IN(24);
 
 /**
  * Like pwritev() but with a 64-bit offset even in a 32-bit process.
  *
  * Available since API level 24.
  */
-ssize_t pwritev64(int __fd, const struct iovec* __iov, int __count, off64_t __offset) __INTRODUCED_IN(24);
+ssize_t pwritev64(int __fd, const struct iovec* _Nonnull __iov, int __count, off64_t __offset) __INTRODUCED_IN(24);
 
 /**
  * [preadv2(2)](http://man7.org/linux/man-pages/man2/preadv2.2.html) reads
@@ -107,7 +107,7 @@
  *
  * Available since API level 33.
  */
-ssize_t preadv2(int __fd, const struct iovec* __iov, int __count, off_t __offset, int __flags) __RENAME_IF_FILE_OFFSET64(preadv64v2) __INTRODUCED_IN(33);
+ssize_t preadv2(int __fd, const struct iovec* _Nonnull __iov, int __count, off_t __offset, int __flags) __RENAME_IF_FILE_OFFSET64(preadv64v2) __INTRODUCED_IN(33);
 
 /**
  * [pwritev2(2)](http://man7.org/linux/man-pages/man2/pwritev2.2.html) writes
@@ -119,21 +119,21 @@
  *
  * Available since API level 33.
  */
-ssize_t pwritev2(int __fd, const struct iovec* __iov, int __count, off_t __offset, int __flags) __RENAME_IF_FILE_OFFSET64(pwritev64v2) __INTRODUCED_IN(33);
+ssize_t pwritev2(int __fd, const struct iovec* _Nonnull __iov, int __count, off_t __offset, int __flags) __RENAME_IF_FILE_OFFSET64(pwritev64v2) __INTRODUCED_IN(33);
 
 /**
  * Like preadv2() but with a 64-bit offset even in a 32-bit process.
  *
  * Available since API level 33.
  */
-ssize_t preadv64v2(int __fd, const struct iovec* __iov, int __count, off64_t __offset, int __flags) __INTRODUCED_IN(33);
+ssize_t preadv64v2(int __fd, const struct iovec* _Nonnull __iov, int __count, off64_t __offset, int __flags) __INTRODUCED_IN(33);
 
 /**
  * Like pwritev2() but with a 64-bit offset even in a 32-bit process.
  *
  * Available since API level 33.
  */
-ssize_t pwritev64v2(int __fd, const struct iovec* __iov, int __count, off64_t __offset, int __flags) __INTRODUCED_IN(33);
+ssize_t pwritev64v2(int __fd, const struct iovec* _Nonnull __iov, int __count, off64_t __offset, int __flags) __INTRODUCED_IN(33);
 
 /**
  * [process_vm_readv(2)](http://man7.org/linux/man-pages/man2/process_vm_readv.2.html)
@@ -144,7 +144,7 @@
  *
  * Available since API level 23.
  */
-ssize_t process_vm_readv(pid_t __pid, const struct iovec* __local_iov, unsigned long __local_iov_count, const struct iovec* __remote_iov, unsigned long __remote_iov_count, unsigned long __flags) __INTRODUCED_IN(23);
+ssize_t process_vm_readv(pid_t __pid, const struct iovec* __BIONIC_COMPLICATED_NULLNESS __local_iov, unsigned long __local_iov_count, const struct iovec* __BIONIC_COMPLICATED_NULLNESS __remote_iov, unsigned long __remote_iov_count, unsigned long __flags) __INTRODUCED_IN(23);
 
 /**
  * [process_vm_writev(2)](http://man7.org/linux/man-pages/man2/process_vm_writev.2.html)
@@ -155,7 +155,7 @@
  *
  * Available since API level 23.
  */
-ssize_t process_vm_writev(pid_t __pid, const struct iovec* __local_iov, unsigned long __local_iov_count, const struct iovec* __remote_iov, unsigned long __remote_iov_count, unsigned long __flags) __INTRODUCED_IN(23);
+ssize_t process_vm_writev(pid_t __pid, const struct iovec* __BIONIC_COMPLICATED_NULLNESS __local_iov, unsigned long __local_iov_count, const struct iovec* __BIONIC_COMPLICATED_NULLNESS __remote_iov, unsigned long __remote_iov_count, unsigned long __flags) __INTRODUCED_IN(23);
 
 #endif
 
diff --git a/libc/include/syslog.h b/libc/include/syslog.h
index d89d769..90ea76e 100644
--- a/libc/include/syslog.h
+++ b/libc/include/syslog.h
@@ -112,17 +112,21 @@
  */
 #define LOG_UPTO(pri) ((1 << ((pri)+1)) - 1)
 
-/** openlog() options are currently ignored on Android. */
+/** openlog() option ignored on Android. */
 #define LOG_PID    0x01
-/** openlog() options are currently ignored on Android. */
+/** openlog() option ignored on Android. */
 #define LOG_CONS   0x02
-/** openlog() options are currently ignored on Android. */
+/** openlog() option ignored on Android. */
 #define LOG_ODELAY 0x04
-/** openlog() options are currently ignored on Android. */
+/** openlog() option ignored on Android. */
 #define LOG_NDELAY 0x08
-/** openlog() options are currently ignored on Android. */
+/** openlog() option ignored on Android. */
 #define LOG_NOWAIT 0x10
-/** openlog() options are currently ignored on Android. */
+/**
+ * openlog() option to log to stderr as well as the system log.
+ *
+ * Available since API level 34 (ignored before then).
+ */
 #define LOG_PERROR 0x20
 
 /**
diff --git a/libc/include/time.h b/libc/include/time.h
index 5339540..1c3ae4b 100644
--- a/libc/include/time.h
+++ b/libc/include/time.h
@@ -26,8 +26,7 @@
  * SUCH DAMAGE.
  */
 
-#ifndef _TIME_H_
-#define _TIME_H_
+#pragma once
 
 #include <sys/cdefs.h>
 #include <sys/time.h>
@@ -105,9 +104,52 @@
 time_t timelocal(struct tm* _Nonnull __tm);
 time_t timegm(struct tm* _Nonnull __tm);
 
-#define TIME_UTC 1
+/**
+ * The timebase for timespec_get() and timespec_getres() corresponding to CLOCK_REALTIME.
+ *
+ * Available since API level 29.
+ */
+#define TIME_UTC (CLOCK_REALTIME+1)
+
+/**
+ * The timebase for timespec_get() and timespec_getres() corresponding to CLOCK_MONOTONIC.
+ *
+ * Available since API level 35.
+ */
+#define TIME_MONOTONIC (CLOCK_MONOTONIC+1)
+
+/**
+ * The timebase for timespec_get() and timespec_getres() corresponding to CLOCK_PROCESS_CPUTIME_ID.
+ *
+ * Available since API level 35.
+ */
+#define TIME_ACTIVE (CLOCK_PROCESS_CPUTIME_ID+1)
+
+/**
+ * The timebase for timespec_get() and timespec_getres() corresponding to CLOCK_THREAD_CPUTIME_ID.
+ *
+ * Available since API level 35.
+ */
+#define TIME_THREAD_ACTIVE (CLOCK_THREAD_CPUTIME_ID+1)
+
+/**
+ * timespec_get(3) is equivalent to clock_gettime() for the clock corresponding to the given base.
+ *
+ * Returns the base on success and returns 0 on failure.
+ *
+ * Available since API level 29 for TIME_UTC; other bases arrived later.
+ * Code for Android should prefer clock_gettime().
+ */
 int timespec_get(struct timespec* _Nonnull __ts, int __base) __INTRODUCED_IN(29);
 
-__END_DECLS
+/**
+ * timespec_getres(3) is equivalent to clock_getres() for the clock corresponding to the given base.
+ *
+ * Returns the base on success and returns 0 on failure.
+ *
+ * Available since API level 35.
+ * Code for Android should prefer clock_gettime().
+ */
+int timespec_getres(struct timespec* _Nonnull __ts, int __base) __INTRODUCED_IN(35);
 
-#endif
+__END_DECLS
diff --git a/libc/kernel/tools/update_all.py b/libc/kernel/tools/update_all.py
index abc72a4..ae89a80 100755
--- a/libc/kernel/tools/update_all.py
+++ b/libc/kernel/tools/update_all.py
@@ -92,6 +92,7 @@
                      'kernel/uapi/asm-arm/asm/unistd.h',
                      'kernel/uapi/asm-arm/asm/unistd-eabi.h',
                      'kernel/uapi/asm-arm/asm/unistd-oabi.h',
+                     'kernel/uapi/asm-riscv/asm/unistd.h',
                      'kernel/uapi/asm-x86/asm/unistd_32.h',
                      'kernel/uapi/asm-x86/asm/unistd_64.h',
                      'kernel/uapi/asm-x86/asm/unistd_x32.h']:
diff --git a/libc/kernel/uapi/asm-arm64/asm/hwcap.h b/libc/kernel/uapi/asm-arm64/asm/hwcap.h
index bb592e4..3ec1354 100644
--- a/libc/kernel/uapi/asm-arm64/asm/hwcap.h
+++ b/libc/kernel/uapi/asm-arm64/asm/hwcap.h
@@ -87,4 +87,10 @@
 #define HWCAP2_CSSC (1UL << 34)
 #define HWCAP2_RPRFM (1UL << 35)
 #define HWCAP2_SVE2P1 (1UL << 36)
+#define HWCAP2_SME2 (1UL << 37)
+#define HWCAP2_SME2P1 (1UL << 38)
+#define HWCAP2_SME_I16I32 (1UL << 39)
+#define HWCAP2_SME_BI32I32 (1UL << 40)
+#define HWCAP2_SME_B16B16 (1UL << 41)
+#define HWCAP2_SME_F16F16 (1UL << 42)
 #endif
diff --git a/libc/kernel/uapi/asm-arm64/asm/kvm.h b/libc/kernel/uapi/asm-arm64/asm/kvm.h
index ce0c318..a413b36 100644
--- a/libc/kernel/uapi/asm-arm64/asm/kvm.h
+++ b/libc/kernel/uapi/asm-arm64/asm/kvm.h
@@ -74,6 +74,7 @@
 #define KVM_ARM_VCPU_SVE 4
 #define KVM_ARM_VCPU_PTRAUTH_ADDRESS 5
 #define KVM_ARM_VCPU_PTRAUTH_GENERIC 6
+#define KVM_ARM_VCPU_HAS_EL2 7
 struct kvm_vcpu_init {
   __u32 target;
   __u32 features[7];
diff --git a/libc/kernel/uapi/asm-arm64/asm/sigcontext.h b/libc/kernel/uapi/asm-arm64/asm/sigcontext.h
index 04aa593..84cd16d 100644
--- a/libc/kernel/uapi/asm-arm64/asm/sigcontext.h
+++ b/libc/kernel/uapi/asm-arm64/asm/sigcontext.h
@@ -59,12 +59,23 @@
   __u16 __reserved[2];
 };
 #define SVE_SIG_FLAG_SM 0x1
+#define TPIDR2_MAGIC 0x54504902
+struct tpidr2_context {
+  struct _aarch64_ctx head;
+  __u64 tpidr2;
+};
 #define ZA_MAGIC 0x54366345
 struct za_context {
   struct _aarch64_ctx head;
   __u16 vl;
   __u16 __reserved[3];
 };
+#define ZT_MAGIC 0x5a544e01
+struct zt_context {
+  struct _aarch64_ctx head;
+  __u16 nregs;
+  __u16 __reserved[3];
+};
 #endif
 #include <asm/sve_context.h>
 #define SVE_VQ_BYTES __SVE_VQ_BYTES
@@ -94,4 +105,9 @@
 #define ZA_SIG_REGS_SIZE(vq) ((vq * __SVE_VQ_BYTES) * (vq * __SVE_VQ_BYTES))
 #define ZA_SIG_ZAV_OFFSET(vq,n) (ZA_SIG_REGS_OFFSET + (SVE_SIG_ZREG_SIZE(vq) * n))
 #define ZA_SIG_CONTEXT_SIZE(vq) (ZA_SIG_REGS_OFFSET + ZA_SIG_REGS_SIZE(vq))
+#define ZT_SIG_REG_SIZE 512
+#define ZT_SIG_REG_BYTES (ZT_SIG_REG_SIZE / 8)
+#define ZT_SIG_REGS_OFFSET sizeof(struct zt_context)
+#define ZT_SIG_REGS_SIZE(n) (ZT_SIG_REG_BYTES * n)
+#define ZT_SIG_CONTEXT_SIZE(n) (sizeof(struct zt_context) + ZT_SIG_REGS_SIZE(n))
 #endif
diff --git a/libc/kernel/uapi/asm-riscv/asm/setup.h b/libc/kernel/uapi/asm-riscv/asm/setup.h
index 940c4db..faac9a6 100644
--- a/libc/kernel/uapi/asm-riscv/asm/setup.h
+++ b/libc/kernel/uapi/asm-riscv/asm/setup.h
@@ -16,4 +16,7 @@
  ***
  ****************************************************************************
  ****************************************************************************/
-#include <asm-generic/setup.h>
+#ifndef _UAPI_ASM_RISCV_SETUP_H
+#define _UAPI_ASM_RISCV_SETUP_H
+#define COMMAND_LINE_SIZE 1024
+#endif
diff --git a/libc/kernel/uapi/asm-x86/asm/kvm.h b/libc/kernel/uapi/asm-x86/asm/kvm.h
index 77d35fc..5c8f5a6 100644
--- a/libc/kernel/uapi/asm-x86/asm/kvm.h
+++ b/libc/kernel/uapi/asm-x86/asm/kvm.h
@@ -20,6 +20,7 @@
 #define _ASM_X86_KVM_H
 #include <linux/types.h>
 #include <linux/ioctl.h>
+#include <linux/stddef.h>
 #define KVM_PIO_PAGE_OFFSET 1
 #define KVM_COALESCED_MMIO_PAGE_OFFSET 2
 #define KVM_DIRTY_LOG_PAGE_OFFSET 64
@@ -395,8 +396,8 @@
     __u8 pad[120];
   } hdr;
   union {
-    struct kvm_vmx_nested_state_data vmx[0];
-    struct kvm_svm_nested_state_data svm[0];
+    __DECLARE_FLEX_ARRAY(struct kvm_vmx_nested_state_data, vmx);
+    __DECLARE_FLEX_ARRAY(struct kvm_svm_nested_state_data, svm);
   } data;
 };
 struct kvm_pmu_event_filter {
@@ -409,6 +410,14 @@
 };
 #define KVM_PMU_EVENT_ALLOW 0
 #define KVM_PMU_EVENT_DENY 1
+#define KVM_PMU_EVENT_FLAG_MASKED_EVENTS BIT(0)
+#define KVM_PMU_EVENT_FLAGS_VALID_MASK (KVM_PMU_EVENT_FLAG_MASKED_EVENTS)
+#define KVM_PMU_ENCODE_MASKED_ENTRY(event_select,mask,match,exclude) (((event_select) & 0xFFULL) | (((event_select) & 0XF00ULL) << 24) | (((mask) & 0xFFULL) << 56) | (((match) & 0xFFULL) << 8) | ((__u64) (! ! (exclude)) << 55))
+#define KVM_PMU_MASKED_ENTRY_EVENT_SELECT (GENMASK_ULL(7, 0) | GENMASK_ULL(35, 32))
+#define KVM_PMU_MASKED_ENTRY_UMASK_MASK (GENMASK_ULL(63, 56))
+#define KVM_PMU_MASKED_ENTRY_UMASK_MATCH (GENMASK_ULL(15, 8))
+#define KVM_PMU_MASKED_ENTRY_EXCLUDE (BIT_ULL(55))
+#define KVM_PMU_MASKED_ENTRY_UMASK_MASK_SHIFT (56)
 #define KVM_VCPU_TSC_CTRL 0
 #define KVM_VCPU_TSC_OFFSET 0
 #endif
diff --git a/libc/kernel/uapi/drm/amdgpu_drm.h b/libc/kernel/uapi/drm/amdgpu_drm.h
index fcd5ab8..8d0d0b0 100644
--- a/libc/kernel/uapi/drm/amdgpu_drm.h
+++ b/libc/kernel/uapi/drm/amdgpu_drm.h
@@ -428,6 +428,7 @@
 #define AMDGPU_IDS_FLAGS_FUSION 0x1
 #define AMDGPU_IDS_FLAGS_PREEMPTION 0x2
 #define AMDGPU_IDS_FLAGS_TMZ 0x4
+#define AMDGPU_IDS_FLAGS_CONFORMANT_TRUNC_COORD 0x8
 #define AMDGPU_INFO_ACCEL_WORKING 0x00
 #define AMDGPU_INFO_CRTC_FROM_ID 0x01
 #define AMDGPU_INFO_HW_IP_INFO 0x02
@@ -486,6 +487,8 @@
 #define AMDGPU_INFO_SENSOR_VDDGFX 0x7
 #define AMDGPU_INFO_SENSOR_STABLE_PSTATE_GFX_SCLK 0x8
 #define AMDGPU_INFO_SENSOR_STABLE_PSTATE_GFX_MCLK 0x9
+#define AMDGPU_INFO_SENSOR_PEAK_PSTATE_GFX_SCLK 0xa
+#define AMDGPU_INFO_SENSOR_PEAK_PSTATE_GFX_MCLK 0xb
 #define AMDGPU_INFO_NUM_VRAM_CPU_PAGE_FAULTS 0x1E
 #define AMDGPU_INFO_VRAM_LOST_COUNTER 0x1F
 #define AMDGPU_INFO_RAS_ENABLED_FEATURES 0x20
@@ -616,7 +619,7 @@
   __u32 enabled_rb_pipes_mask;
   __u32 num_rb_pipes;
   __u32 num_hw_gfx_contexts;
-  __u32 _pad;
+  __u32 pcie_gen;
   __u64 ids_flags;
   __u64 virtual_address_offset;
   __u64 virtual_address_max;
@@ -643,12 +646,22 @@
   __u32 gs_vgt_table_depth;
   __u32 gs_prim_buffer_depth;
   __u32 max_gs_waves_per_vgt;
-  __u32 _pad1;
+  __u32 pcie_num_lanes;
   __u32 cu_ao_bitmap[4][4];
   __u64 high_va_offset;
   __u64 high_va_max;
   __u32 pa_sc_tile_steering_override;
   __u64 tcc_disabled_mask;
+  __u64 min_engine_clock;
+  __u64 min_memory_clock;
+  __u32 tcp_cache_size;
+  __u32 num_sqc_per_wgp;
+  __u32 sqc_data_cache_size;
+  __u32 sqc_inst_cache_size;
+  __u32 gl1c_cache_size;
+  __u32 gl2c_cache_size;
+  __u64 mall_size;
+  __u32 enabled_rb_pipes_mask_hi;
 };
 struct drm_amdgpu_info_hw_ip {
   __u32 hw_ip_version_major;
diff --git a/libc/kernel/uapi/misc/habanalabs.h b/libc/kernel/uapi/drm/habanalabs_accel.h
similarity index 98%
rename from libc/kernel/uapi/misc/habanalabs.h
rename to libc/kernel/uapi/drm/habanalabs_accel.h
index b25c833..d7dccef 100644
--- a/libc/kernel/uapi/misc/habanalabs.h
+++ b/libc/kernel/uapi/drm/habanalabs_accel.h
@@ -662,6 +662,7 @@
 #define HL_INFO_ENGINE_STATUS 32
 #define HL_INFO_PAGE_FAULT_EVENT 33
 #define HL_INFO_USER_MAPPINGS 34
+#define HL_INFO_FW_GENERIC_REQ 35
 #define HL_INFO_VERSION_MAX_LEN 128
 #define HL_INFO_CARD_NAME_MAX_LEN 16
 #define HL_ENGINES_DATA_MAX_SIZE SZ_1M
@@ -872,6 +873,7 @@
     __u32 user_buffer_actual_size;
     __u32 sec_attest_nonce;
     __u32 array_size;
+    __u32 fw_sub_opcode;
   };
   __u32 pad;
 };
@@ -935,6 +937,7 @@
 #define HL_CS_FLAGS_RESERVE_SIGNALS_ONLY 0x1000
 #define HL_CS_FLAGS_UNRESERVE_SIGNALS_ONLY 0x2000
 #define HL_CS_FLAGS_ENGINE_CORE_COMMAND 0x4000
+#define HL_CS_FLAGS_FLUSH_PCI_HBW_WRITES 0x8000
 #define HL_CS_STATUS_SUCCESS 0
 #define HL_MAX_JOBS_PER_CS 512
 #define HL_ENGINE_CORE_HALT (1 << 0)
@@ -1072,8 +1075,9 @@
       __u64 device_virt_addr;
     } unmap;
     struct {
-      __u64 handle;
+      __u64 addr;
       __u64 mem_size;
+      __u64 offset;
     } export_dmabuf_fd;
   };
   __u32 op;
diff --git a/libc/kernel/uapi/drm/i810_drm.h b/libc/kernel/uapi/drm/i810_drm.h
deleted file mode 100644
index e33387d..0000000
--- a/libc/kernel/uapi/drm/i810_drm.h
+++ /dev/null
@@ -1,220 +0,0 @@
-/****************************************************************************
- ****************************************************************************
- ***
- ***   This header was automatically generated from a Linux kernel header
- ***   of the same name, to make information necessary for userspace to
- ***   call into the kernel available to libc.  It contains only constants,
- ***   structures, and macros generated from the original header, and thus,
- ***   contains no copyrightable information.
- ***
- ***   To edit the content of this header, modify the corresponding
- ***   source file (e.g. under external/kernel-headers/original/) then
- ***   run bionic/libc/kernel/tools/update_all.py
- ***
- ***   Any manual change here will be lost the next time this script will
- ***   be run. You've been warned!
- ***
- ****************************************************************************
- ****************************************************************************/
-#ifndef _I810_DRM_H_
-#define _I810_DRM_H_
-#include "drm.h"
-#ifdef __cplusplus
-extern "C" {
-#endif
-#ifndef _I810_DEFINES_
-#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
-#define I810_NR_TEX_REGIONS 64
-#define I810_LOG_MIN_TEX_REGION_SIZE 16
-#endif
-#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
-#define I810_UPLOAD_TEX1 0x20
-#define I810_UPLOAD_CLIPRECTS 0x40
-#define I810_DESTREG_DI0 0
-#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
-#define I810_DESTREG_DR2 6
-#define I810_DESTREG_DR3 7
-#define I810_DESTREG_DR4 8
-#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
-#define I810_CTXREG_VF 4
-#define I810_CTXREG_MT 5
-#define I810_CTXREG_MC0 6
-#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
-#define I810_CTXREG_SDM 12
-#define I810_CTXREG_FOG 13
-#define I810_CTXREG_B1 14
-#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
-#define I810_CTX_SETUP_SIZE 20
-#define I810_TEXREG_MI0 0
-#define I810_TEXREG_MI1 1
-#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
-#define I810_TEXREG_MCS 7
-#define I810_TEX_SETUP_SIZE 8
-#define I810_FRONT 0x1
-#define I810_BACK 0x2
-#define I810_DEPTH 0x4
-typedef enum _drm_i810_init_func {
-  I810_INIT_DMA = 0x01,
-  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;
-  unsigned int mmio_offset;
-  unsigned int buffers_offset;
-  int sarea_priv_offset;
-  unsigned int ring_start;
-  unsigned int ring_end;
-  unsigned int ring_size;
-  unsigned int front_offset;
-  unsigned int back_offset;
-  unsigned int depth_offset;
-  unsigned int overlay_offset;
-  unsigned int overlay_physical;
-  unsigned int w;
-  unsigned int h;
-  unsigned int pitch;
-  unsigned int pitch_bits;
-} drm_i810_init_t;
-typedef struct _drm_i810_pre12_init {
-  drm_i810_init_func_t func;
-  unsigned int mmio_offset;
-  unsigned int buffers_offset;
-  int sarea_priv_offset;
-  unsigned int ring_start;
-  unsigned int ring_end;
-  unsigned int ring_size;
-  unsigned int front_offset;
-  unsigned int back_offset;
-  unsigned int depth_offset;
-  unsigned int w;
-  unsigned int h;
-  unsigned int pitch;
-  unsigned int pitch_bits;
-} drm_i810_pre12_init_t;
-typedef struct _drm_i810_tex_region {
-  unsigned char next, prev;
-  unsigned char in_use;
-  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];
-  unsigned int TexState[2][I810_TEX_SETUP_SIZE];
-  unsigned int dirty;
-  unsigned int nbox;
-  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;
-  int last_quiescent;
-  int ctxOwner;
-  int vertex_prim;
-  int pf_enabled;
-  int pf_active;
-  int pf_current_page;
-} drm_i810_sarea_t;
-#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
-#define DRM_I810_GETBUF 0x05
-#define DRM_I810_SWAP 0x06
-#define DRM_I810_COPY 0x07
-#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
-#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)
-#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)
-#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)
-#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)
-#define DRM_IOCTL_I810_FLIP DRM_IO(DRM_COMMAND_BASE + DRM_I810_FLIP)
-typedef struct _drm_i810_clear {
-  int clear_color;
-  int clear_depth;
-  int flags;
-} drm_i810_clear_t;
-typedef struct _drm_i810_vertex {
-  int idx;
-  int used;
-  int discard;
-} drm_i810_vertex_t;
-typedef struct _drm_i810_copy_t {
-  int idx;
-  int used;
-  void * address;
-} 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)
-#define PR_POLYGON (0x4 << 18)
-#define PR_LINES (0x5 << 18)
-#define PR_LINESTRIP (0x6 << 18)
-#define PR_RECTS (0x7 << 18)
-#define PR_MASK (0x7 << 18)
-typedef struct drm_i810_dma {
-  void * __linux_virtual;
-  int request_idx;
-  int request_size;
-  int granted;
-} drm_i810_dma_t;
-typedef struct _drm_i810_overlay_t {
-  unsigned int offset;
-  unsigned int physical;
-} drm_i810_overlay_t;
-typedef struct _drm_i810_mc {
-  int idx;
-  int used;
-  int num_blocks;
-  int * length;
-  unsigned int last_render;
-} drm_i810_mc_t;
-#ifdef __cplusplus
-}
-#endif
-#endif
diff --git a/libc/kernel/uapi/drm/ivpu_accel.h b/libc/kernel/uapi/drm/ivpu_accel.h
new file mode 100644
index 0000000..e148a5b
--- /dev/null
+++ b/libc/kernel/uapi/drm/ivpu_accel.h
@@ -0,0 +1,102 @@
+/****************************************************************************
+ ****************************************************************************
+ ***
+ ***   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_IVPU_DRM_H__
+#define __UAPI_IVPU_DRM_H__
+#include "drm.h"
+#ifdef __cplusplus
+extern "C" {
+#endif
+#define DRM_IVPU_DRIVER_MAJOR 1
+#define DRM_IVPU_DRIVER_MINOR 0
+#define DRM_IVPU_GET_PARAM 0x00
+#define DRM_IVPU_SET_PARAM 0x01
+#define DRM_IVPU_BO_CREATE 0x02
+#define DRM_IVPU_BO_INFO 0x03
+#define DRM_IVPU_SUBMIT 0x05
+#define DRM_IVPU_BO_WAIT 0x06
+#define DRM_IOCTL_IVPU_GET_PARAM DRM_IOWR(DRM_COMMAND_BASE + DRM_IVPU_GET_PARAM, struct drm_ivpu_param)
+#define DRM_IOCTL_IVPU_SET_PARAM DRM_IOW(DRM_COMMAND_BASE + DRM_IVPU_SET_PARAM, struct drm_ivpu_param)
+#define DRM_IOCTL_IVPU_BO_CREATE DRM_IOWR(DRM_COMMAND_BASE + DRM_IVPU_BO_CREATE, struct drm_ivpu_bo_create)
+#define DRM_IOCTL_IVPU_BO_INFO DRM_IOWR(DRM_COMMAND_BASE + DRM_IVPU_BO_INFO, struct drm_ivpu_bo_info)
+#define DRM_IOCTL_IVPU_SUBMIT DRM_IOW(DRM_COMMAND_BASE + DRM_IVPU_SUBMIT, struct drm_ivpu_submit)
+#define DRM_IOCTL_IVPU_BO_WAIT DRM_IOWR(DRM_COMMAND_BASE + DRM_IVPU_BO_WAIT, struct drm_ivpu_bo_wait)
+#define DRM_IVPU_PARAM_DEVICE_ID 0
+#define DRM_IVPU_PARAM_DEVICE_REVISION 1
+#define DRM_IVPU_PARAM_PLATFORM_TYPE 2
+#define DRM_IVPU_PARAM_CORE_CLOCK_RATE 3
+#define DRM_IVPU_PARAM_NUM_CONTEXTS 4
+#define DRM_IVPU_PARAM_CONTEXT_BASE_ADDRESS 5
+#define DRM_IVPU_PARAM_CONTEXT_PRIORITY 6
+#define DRM_IVPU_PARAM_CONTEXT_ID 7
+#define DRM_IVPU_PARAM_FW_API_VERSION 8
+#define DRM_IVPU_PARAM_ENGINE_HEARTBEAT 9
+#define DRM_IVPU_PARAM_UNIQUE_INFERENCE_ID 10
+#define DRM_IVPU_PARAM_TILE_CONFIG 11
+#define DRM_IVPU_PARAM_SKU 12
+#define DRM_IVPU_PLATFORM_TYPE_SILICON 0
+#define DRM_IVPU_CONTEXT_PRIORITY_IDLE 0
+#define DRM_IVPU_CONTEXT_PRIORITY_NORMAL 1
+#define DRM_IVPU_CONTEXT_PRIORITY_FOCUS 2
+#define DRM_IVPU_CONTEXT_PRIORITY_REALTIME 3
+struct drm_ivpu_param {
+  __u32 param;
+  __u32 index;
+  __u64 value;
+};
+#define DRM_IVPU_BO_HIGH_MEM 0x00000001
+#define DRM_IVPU_BO_MAPPABLE 0x00000002
+#define DRM_IVPU_BO_CACHED 0x00000000
+#define DRM_IVPU_BO_UNCACHED 0x00010000
+#define DRM_IVPU_BO_WC 0x00020000
+#define DRM_IVPU_BO_CACHE_MASK 0x00030000
+#define DRM_IVPU_BO_FLAGS (DRM_IVPU_BO_HIGH_MEM | DRM_IVPU_BO_MAPPABLE | DRM_IVPU_BO_CACHE_MASK)
+struct drm_ivpu_bo_create {
+  __u64 size;
+  __u32 flags;
+  __u32 handle;
+  __u64 vpu_addr;
+};
+struct drm_ivpu_bo_info {
+  __u32 handle;
+  __u32 flags;
+  __u64 vpu_addr;
+  __u64 mmap_offset;
+  __u64 size;
+};
+#define DRM_IVPU_ENGINE_COMPUTE 0
+#define DRM_IVPU_ENGINE_COPY 1
+struct drm_ivpu_submit {
+  __u64 buffers_ptr;
+  __u32 buffer_count;
+  __u32 engine;
+  __u32 flags;
+  __u32 commands_offset;
+};
+#define DRM_IVPU_JOB_STATUS_SUCCESS 0
+struct drm_ivpu_bo_wait {
+  __u32 handle;
+  __u32 flags;
+  __s64 timeout_ns;
+  __u32 job_status;
+  __u32 pad;
+};
+#ifdef __cplusplus
+}
+#endif
+#endif
diff --git a/libc/kernel/uapi/drm/mga_drm.h b/libc/kernel/uapi/drm/mga_drm.h
deleted file mode 100644
index eb55fa7..0000000
--- a/libc/kernel/uapi/drm/mga_drm.h
+++ /dev/null
@@ -1,247 +0,0 @@
-/****************************************************************************
- ****************************************************************************
- ***
- ***   This header was automatically generated from a Linux kernel header
- ***   of the same name, to make information necessary for userspace to
- ***   call into the kernel available to libc.  It contains only constants,
- ***   structures, and macros generated from the original header, and thus,
- ***   contains no copyrightable information.
- ***
- ***   To edit the content of this header, modify the corresponding
- ***   source file (e.g. under external/kernel-headers/original/) then
- ***   run bionic/libc/kernel/tools/update_all.py
- ***
- ***   Any manual change here will be lost the next time this script will
- ***   be run. You've been warned!
- ***
- ****************************************************************************
- ****************************************************************************/
-#ifndef __MGA_DRM_H__
-#define __MGA_DRM_H__
-#include "drm.h"
-#ifdef __cplusplus
-extern "C" {
-#endif
-#ifndef __MGA_SAREA_DEFINES__
-#define __MGA_SAREA_DEFINES__
-#define MGA_F 0x1
-#define MGA_A 0x2
-#define MGA_S 0x4
-#define MGA_T2 0x8
-#define MGA_WARP_TGZ 0
-#define MGA_WARP_TGZF (MGA_F)
-#define MGA_WARP_TGZA (MGA_A)
-#define MGA_WARP_TGZAF (MGA_F | MGA_A)
-#define MGA_WARP_TGZS (MGA_S)
-#define MGA_WARP_TGZSF (MGA_S | MGA_F)
-#define MGA_WARP_TGZSA (MGA_S | MGA_A)
-#define MGA_WARP_TGZSAF (MGA_S | MGA_F | MGA_A)
-#define MGA_WARP_T2GZ (MGA_T2)
-#define MGA_WARP_T2GZF (MGA_T2 | MGA_F)
-#define MGA_WARP_T2GZA (MGA_T2 | MGA_A)
-#define MGA_WARP_T2GZAF (MGA_T2 | MGA_A | MGA_F)
-#define MGA_WARP_T2GZS (MGA_T2 | MGA_S)
-#define MGA_WARP_T2GZSF (MGA_T2 | MGA_S | MGA_F)
-#define MGA_WARP_T2GZSA (MGA_T2 | MGA_S | MGA_A)
-#define MGA_WARP_T2GZSAF (MGA_T2 | MGA_S | MGA_F | MGA_A)
-#define MGA_MAX_G200_PIPES 8
-#define MGA_MAX_G400_PIPES 16
-#define MGA_MAX_WARP_PIPES MGA_MAX_G400_PIPES
-#define MGA_WARP_UCODE_SIZE 32768
-#define MGA_CARD_TYPE_G200 1
-#define MGA_CARD_TYPE_G400 2
-#define MGA_CARD_TYPE_G450 3
-#define MGA_CARD_TYPE_G550 4
-#define MGA_FRONT 0x1
-#define MGA_BACK 0x2
-#define MGA_DEPTH 0x4
-#define MGA_UPLOAD_CONTEXT 0x1
-#define MGA_UPLOAD_TEX0 0x2
-#define MGA_UPLOAD_TEX1 0x4
-#define MGA_UPLOAD_PIPE 0x8
-#define MGA_UPLOAD_TEX0IMAGE 0x10
-#define MGA_UPLOAD_TEX1IMAGE 0x20
-#define MGA_UPLOAD_2D 0x40
-#define MGA_WAIT_AGE 0x80
-#define MGA_UPLOAD_CLIPRECTS 0x100
-#define MGA_BUFFER_SIZE (1 << 16)
-#define MGA_NUM_BUFFERS 128
-#define MGA_NR_SAREA_CLIPRECTS 8
-#define MGA_CARD_HEAP 0
-#define MGA_AGP_HEAP 1
-#define MGA_NR_TEX_HEAPS 2
-#define MGA_NR_TEX_REGIONS 16
-#define MGA_LOG_MIN_TEX_REGION_SIZE 16
-#define DRM_MGA_IDLE_RETRY 2048
-#endif
-typedef struct {
-  unsigned int dstorg;
-  unsigned int maccess;
-  unsigned int plnwt;
-  unsigned int dwgctl;
-  unsigned int alphactrl;
-  unsigned int fogcolor;
-  unsigned int wflag;
-  unsigned int tdualstage0;
-  unsigned int tdualstage1;
-  unsigned int fcol;
-  unsigned int stencil;
-  unsigned int stencilctl;
-} drm_mga_context_regs_t;
-typedef struct {
-  unsigned int pitch;
-} drm_mga_server_regs_t;
-typedef struct {
-  unsigned int texctl;
-  unsigned int texctl2;
-  unsigned int texfilter;
-  unsigned int texbordercol;
-  unsigned int texorg;
-  unsigned int texwidth;
-  unsigned int texheight;
-  unsigned int texorg1;
-  unsigned int texorg2;
-  unsigned int texorg3;
-  unsigned int texorg4;
-} drm_mga_texture_regs_t;
-typedef struct {
-  unsigned int head;
-  unsigned int wrap;
-} drm_mga_age_t;
-typedef struct _drm_mga_sarea {
-  drm_mga_context_regs_t context_state;
-  drm_mga_server_regs_t server_state;
-  drm_mga_texture_regs_t tex_state[2];
-  unsigned int warp_pipe;
-  unsigned int dirty;
-  unsigned int vertsize;
-  struct drm_clip_rect boxes[MGA_NR_SAREA_CLIPRECTS];
-  unsigned int nbox;
-  unsigned int req_drawable;
-  unsigned int req_draw_buffer;
-  unsigned int exported_drawable;
-  unsigned int exported_index;
-  unsigned int exported_stamp;
-  unsigned int exported_buffers;
-  unsigned int exported_nfront;
-  unsigned int exported_nback;
-  int exported_back_x, exported_front_x, exported_w;
-  int exported_back_y, exported_front_y, exported_h;
-  struct drm_clip_rect exported_boxes[MGA_NR_SAREA_CLIPRECTS];
-  unsigned int status[4];
-  unsigned int last_wrap;
-  drm_mga_age_t last_frame;
-  unsigned int last_enqueue;
-  unsigned int last_dispatch;
-  unsigned int last_quiescent;
-  struct drm_tex_region texList[MGA_NR_TEX_HEAPS][MGA_NR_TEX_REGIONS + 1];
-  unsigned int texAge[MGA_NR_TEX_HEAPS];
-  int ctxOwner;
-} drm_mga_sarea_t;
-#define DRM_MGA_INIT 0x00
-#define DRM_MGA_FLUSH 0x01
-#define DRM_MGA_RESET 0x02
-#define DRM_MGA_SWAP 0x03
-#define DRM_MGA_CLEAR 0x04
-#define DRM_MGA_VERTEX 0x05
-#define DRM_MGA_INDICES 0x06
-#define DRM_MGA_ILOAD 0x07
-#define DRM_MGA_BLIT 0x08
-#define DRM_MGA_GETPARAM 0x09
-#define DRM_MGA_SET_FENCE 0x0a
-#define DRM_MGA_WAIT_FENCE 0x0b
-#define DRM_MGA_DMA_BOOTSTRAP 0x0c
-#define DRM_IOCTL_MGA_INIT DRM_IOW(DRM_COMMAND_BASE + DRM_MGA_INIT, drm_mga_init_t)
-#define DRM_IOCTL_MGA_FLUSH DRM_IOW(DRM_COMMAND_BASE + DRM_MGA_FLUSH, struct drm_lock)
-#define DRM_IOCTL_MGA_RESET DRM_IO(DRM_COMMAND_BASE + DRM_MGA_RESET)
-#define DRM_IOCTL_MGA_SWAP DRM_IO(DRM_COMMAND_BASE + DRM_MGA_SWAP)
-#define DRM_IOCTL_MGA_CLEAR DRM_IOW(DRM_COMMAND_BASE + DRM_MGA_CLEAR, drm_mga_clear_t)
-#define DRM_IOCTL_MGA_VERTEX DRM_IOW(DRM_COMMAND_BASE + DRM_MGA_VERTEX, drm_mga_vertex_t)
-#define DRM_IOCTL_MGA_INDICES DRM_IOW(DRM_COMMAND_BASE + DRM_MGA_INDICES, drm_mga_indices_t)
-#define DRM_IOCTL_MGA_ILOAD DRM_IOW(DRM_COMMAND_BASE + DRM_MGA_ILOAD, drm_mga_iload_t)
-#define DRM_IOCTL_MGA_BLIT DRM_IOW(DRM_COMMAND_BASE + DRM_MGA_BLIT, drm_mga_blit_t)
-#define DRM_IOCTL_MGA_GETPARAM DRM_IOWR(DRM_COMMAND_BASE + DRM_MGA_GETPARAM, drm_mga_getparam_t)
-#define DRM_IOCTL_MGA_SET_FENCE DRM_IOW(DRM_COMMAND_BASE + DRM_MGA_SET_FENCE, __u32)
-#define DRM_IOCTL_MGA_WAIT_FENCE DRM_IOWR(DRM_COMMAND_BASE + DRM_MGA_WAIT_FENCE, __u32)
-#define DRM_IOCTL_MGA_DMA_BOOTSTRAP DRM_IOWR(DRM_COMMAND_BASE + DRM_MGA_DMA_BOOTSTRAP, drm_mga_dma_bootstrap_t)
-typedef struct _drm_mga_warp_index {
-  int installed;
-  unsigned long phys_addr;
-  int size;
-} drm_mga_warp_index_t;
-typedef struct drm_mga_init {
-  enum {
-    MGA_INIT_DMA = 0x01,
-    MGA_CLEANUP_DMA = 0x02
-  } func;
-  unsigned long sarea_priv_offset;
-  __struct_group(, always32bit,, int chipset;
-  int sgram;
-  unsigned int maccess;
-  unsigned int fb_cpp;
-  unsigned int front_offset, front_pitch;
-  unsigned int back_offset, back_pitch;
-  unsigned int depth_cpp;
-  unsigned int depth_offset, depth_pitch;
-  unsigned int texture_offset[MGA_NR_TEX_HEAPS];
-  unsigned int texture_size[MGA_NR_TEX_HEAPS];
- );
-  unsigned long fb_offset;
-  unsigned long mmio_offset;
-  unsigned long status_offset;
-  unsigned long warp_offset;
-  unsigned long primary_offset;
-  unsigned long buffers_offset;
-} drm_mga_init_t;
-typedef struct drm_mga_dma_bootstrap {
-  unsigned long texture_handle;
-  __u32 texture_size;
-  __u32 primary_size;
-  __u32 secondary_bin_count;
-  __u32 secondary_bin_size;
-  __u32 agp_mode;
-  __u8 agp_size;
-} drm_mga_dma_bootstrap_t;
-typedef struct drm_mga_clear {
-  unsigned int flags;
-  unsigned int clear_color;
-  unsigned int clear_depth;
-  unsigned int color_mask;
-  unsigned int depth_mask;
-} drm_mga_clear_t;
-typedef struct drm_mga_vertex {
-  int idx;
-  int used;
-  int discard;
-} drm_mga_vertex_t;
-typedef struct drm_mga_indices {
-  int idx;
-  unsigned int start;
-  unsigned int end;
-  int discard;
-} drm_mga_indices_t;
-typedef struct drm_mga_iload {
-  int idx;
-  unsigned int dstorg;
-  unsigned int length;
-} drm_mga_iload_t;
-typedef struct _drm_mga_blit {
-  unsigned int planemask;
-  unsigned int srcorg;
-  unsigned int dstorg;
-  int src_pitch, dst_pitch;
-  int delta_sx, delta_sy;
-  int delta_dx, delta_dy;
-  int height, ydir;
-  int source_pitch, dest_pitch;
-} drm_mga_blit_t;
-#define MGA_PARAM_IRQ_NR 1
-#define MGA_PARAM_CARD_TYPE 2
-typedef struct drm_mga_getparam {
-  int param;
-  void  * value;
-} drm_mga_getparam_t;
-#ifdef __cplusplus
-}
-#endif
-#endif
diff --git a/libc/kernel/uapi/drm/msm_drm.h b/libc/kernel/uapi/drm/msm_drm.h
index ad3a971..f5a4627 100644
--- a/libc/kernel/uapi/drm/msm_drm.h
+++ b/libc/kernel/uapi/drm/msm_drm.h
@@ -116,7 +116,8 @@
 #define MSM_SUBMIT_BO_READ 0x0001
 #define MSM_SUBMIT_BO_WRITE 0x0002
 #define MSM_SUBMIT_BO_DUMP 0x0004
-#define MSM_SUBMIT_BO_FLAGS (MSM_SUBMIT_BO_READ | MSM_SUBMIT_BO_WRITE | MSM_SUBMIT_BO_DUMP)
+#define MSM_SUBMIT_BO_NO_IMPLICIT 0x0008
+#define MSM_SUBMIT_BO_FLAGS (MSM_SUBMIT_BO_READ | MSM_SUBMIT_BO_WRITE | MSM_SUBMIT_BO_DUMP | MSM_SUBMIT_BO_NO_IMPLICIT)
 struct drm_msm_gem_submit_bo {
   __u32 flags;
   __u32 handle;
diff --git a/libc/kernel/uapi/drm/r128_drm.h b/libc/kernel/uapi/drm/r128_drm.h
deleted file mode 100644
index 3e013b1..0000000
--- a/libc/kernel/uapi/drm/r128_drm.h
+++ /dev/null
@@ -1,235 +0,0 @@
-/****************************************************************************
- ****************************************************************************
- ***
- ***   This header was automatically generated from a Linux kernel header
- ***   of the same name, to make information necessary for userspace to
- ***   call into the kernel available to libc.  It contains only constants,
- ***   structures, and macros generated from the original header, and thus,
- ***   contains no copyrightable information.
- ***
- ***   To edit the content of this header, modify the corresponding
- ***   source file (e.g. under external/kernel-headers/original/) then
- ***   run bionic/libc/kernel/tools/update_all.py
- ***
- ***   Any manual change here will be lost the next time this script will
- ***   be run. You've been warned!
- ***
- ****************************************************************************
- ****************************************************************************/
-#ifndef __R128_DRM_H__
-#define __R128_DRM_H__
-#include "drm.h"
-#ifdef __cplusplus
-extern "C" {
-#endif
-#ifndef __R128_SAREA_DEFINES__
-#define __R128_SAREA_DEFINES__
-#define R128_UPLOAD_CONTEXT 0x001
-#define R128_UPLOAD_SETUP 0x002
-#define R128_UPLOAD_TEX0 0x004
-#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
-#define R128_UPLOAD_WINDOW 0x100
-#define R128_UPLOAD_CLIPRECTS 0x200
-#define R128_REQUIRE_QUIESCENCE 0x400
-#define R128_UPLOAD_ALL 0x7ff
-#define R128_FRONT 0x1
-#define R128_BACK 0x2
-#define R128_DEPTH 0x4
-#define R128_POINTS 0x1
-#define R128_LINES 0x2
-#define R128_LINE_STRIP 0x3
-#define R128_TRIANGLES 0x4
-#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
-#define R128_NR_SAREA_CLIPRECTS 12
-#define R128_LOCAL_TEX_HEAP 0
-#define R128_AGP_TEX_HEAP 1
-#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
-#define R128_MAX_TEXTURE_UNITS 2
-#endif
-typedef struct {
-  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;
-  unsigned int z_pitch_c;
-  unsigned int z_sten_cntl_c;
-  unsigned int tex_cntl_c;
-  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;
-  unsigned int constant_color_c;
-  unsigned int pm4_vc_fpu_setup;
-  unsigned int setup_cntl;
-  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;
-} drm_r128_context_regs_t;
-typedef struct {
-  unsigned int tex_cntl;
-  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;
-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;
-  unsigned int vertsize;
-  unsigned int vc_format;
-  struct drm_clip_rect boxes[R128_NR_SAREA_CLIPRECTS];
-  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];
-  int ctx_owner;
-  int pfAllowPageFlip;
-  int pfCurrentPage;
-} 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
-#define DRM_R128_CCE_IDLE 0x04
-#define DRM_R128_RESET 0x06
-#define DRM_R128_SWAP 0x07
-#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
-#define DRM_R128_STIPPLE 0x0d
-#define DRM_R128_INDIRECT 0x0f
-#define DRM_R128_FULLSCREEN 0x10
-#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)
-#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)
-#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)
-#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)
-#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)
-typedef struct drm_r128_init {
-  enum {
-    R128_INIT_CCE = 0x01,
-    R128_CLEANUP_CCE = 0x02
-  } func;
-  unsigned long sarea_priv_offset;
-  int is_pci;
-  int cce_mode;
-  int cce_secure;
-  int ring_size;
-  int usec_timeout;
-  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;
-  unsigned int span_offset;
-  unsigned long fb_offset;
-  unsigned long mmio_offset;
-  unsigned long ring_offset;
-  unsigned long ring_rptr_offset;
-  unsigned long buffers_offset;
-  unsigned long agp_textures_offset;
-} drm_r128_init_t;
-typedef struct drm_r128_cce_stop {
-  int flush;
-  int idle;
-} drm_r128_cce_stop_t;
-typedef struct drm_r128_clear {
-  unsigned int flags;
-  unsigned int clear_color;
-  unsigned int clear_depth;
-  unsigned int color_mask;
-  unsigned int depth_mask;
-} drm_r128_clear_t;
-typedef struct drm_r128_vertex {
-  int prim;
-  int idx;
-  int count;
-  int discard;
-} drm_r128_vertex_t;
-typedef struct drm_r128_indices {
-  int prim;
-  int idx;
-  int start;
-  int end;
-  int discard;
-} drm_r128_indices_t;
-typedef struct drm_r128_blit {
-  int idx;
-  int pitch;
-  int offset;
-  int format;
-  unsigned short x, y;
-  unsigned short width, height;
-} drm_r128_blit_t;
-typedef struct drm_r128_depth {
-  enum {
-    R128_WRITE_SPAN = 0x01,
-    R128_WRITE_PIXELS = 0x02,
-    R128_READ_SPAN = 0x03,
-    R128_READ_PIXELS = 0x04
-  } func;
-  int n;
-  int  * x;
-  int  * y;
-  unsigned int  * buffer;
-  unsigned char  * mask;
-} drm_r128_depth_t;
-typedef struct drm_r128_stipple {
-  unsigned int  * mask;
-} drm_r128_stipple_t;
-typedef struct drm_r128_indirect {
-  int idx;
-  int start;
-  int end;
-  int discard;
-} drm_r128_indirect_t;
-typedef struct drm_r128_fullscreen {
-  enum {
-    R128_INIT_FULLSCREEN = 0x01,
-    R128_CLEANUP_FULLSCREEN = 0x02
-  } func;
-} drm_r128_fullscreen_t;
-#define R128_PARAM_IRQ_NR 1
-typedef struct drm_r128_getparam {
-  int param;
-  void  * value;
-} drm_r128_getparam_t;
-#ifdef __cplusplus
-}
-#endif
-#endif
diff --git a/libc/kernel/uapi/drm/savage_drm.h b/libc/kernel/uapi/drm/savage_drm.h
deleted file mode 100644
index efc0ae6..0000000
--- a/libc/kernel/uapi/drm/savage_drm.h
+++ /dev/null
@@ -1,157 +0,0 @@
-/****************************************************************************
- ****************************************************************************
- ***
- ***   This header was automatically generated from a Linux kernel header
- ***   of the same name, to make information necessary for userspace to
- ***   call into the kernel available to libc.  It contains only constants,
- ***   structures, and macros generated from the original header, and thus,
- ***   contains no copyrightable information.
- ***
- ***   To edit the content of this header, modify the corresponding
- ***   source file (e.g. under external/kernel-headers/original/) then
- ***   run bionic/libc/kernel/tools/update_all.py
- ***
- ***   Any manual change here will be lost the next time this script will
- ***   be run. You've been warned!
- ***
- ****************************************************************************
- ****************************************************************************/
-#ifndef __SAVAGE_DRM_H__
-#define __SAVAGE_DRM_H__
-#include "drm.h"
-#ifdef __cplusplus
-extern "C" {
-#endif
-#ifndef __SAVAGE_SAREA_DEFINES__
-#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
-#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];
-  unsigned int texAge[SAVAGE_NR_TEX_HEAPS];
-  int ctxOwner;
-} drm_savage_sarea_t, * drm_savage_sarea_ptr;
-#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)
-#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
-#define SAVAGE_DMA_AGP 3
-typedef struct drm_savage_init {
-  enum {
-    SAVAGE_INIT_BCI = 1,
-    SAVAGE_CLEANUP_BCI = 2
-  } func;
-  unsigned int sarea_priv_offset;
-  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;
-  unsigned int back_offset, back_pitch;
-  unsigned int depth_bpp;
-  unsigned int depth_offset, depth_pitch;
-  unsigned int texture_offset;
-  unsigned int texture_size;
-  unsigned long status_offset;
-  unsigned long buffers_offset;
-  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 {
-  drm_savage_cmd_header_t  * cmd_addr;
-  unsigned int size;
-  unsigned int dma_idx;
-  int discard;
-  unsigned int  * vb_addr;
-  unsigned int vb_size;
-  unsigned int vb_stride;
-  struct drm_clip_rect  * box_addr;
-  unsigned int nbox;
-} drm_savage_cmdbuf_t;
-#define SAVAGE_WAIT_2D 0x1
-#define SAVAGE_WAIT_3D 0x2
-#define SAVAGE_WAIT_IRQ 0x4
-typedef struct drm_savage_event {
-  unsigned int count;
-  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
-#define SAVAGE_CMD_DMA_IDX 3
-#define SAVAGE_CMD_VB_IDX 4
-#define SAVAGE_CMD_CLEAR 5
-#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
-#define SAVAGE_SKIP_Z 0x01
-#define SAVAGE_SKIP_W 0x02
-#define SAVAGE_SKIP_C0 0x04
-#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
-#define SAVAGE_SKIP_T1 0x80
-#define SAVAGE_SKIP_ST1 0xc0
-#define SAVAGE_SKIP_ALL_S3D 0x3f
-#define SAVAGE_SKIP_ALL_S4 0xff
-#define SAVAGE_FRONT 0x1
-#define SAVAGE_BACK 0x2
-#define SAVAGE_DEPTH 0x4
-union drm_savage_cmd_header {
-  struct {
-    unsigned char cmd;
-    unsigned char pad0;
-    unsigned short pad1;
-    unsigned short pad2;
-    unsigned short pad3;
-  } cmd;
-  struct {
-    unsigned char cmd;
-    unsigned char global;
-    unsigned short count;
-    unsigned short start;
-    unsigned short pad3;
-  } state;
-  struct {
-    unsigned char cmd;
-    unsigned char prim;
-    unsigned short skip;
-    unsigned short count;
-    unsigned short start;
-  } prim;
-  struct {
-    unsigned char cmd;
-    unsigned char prim;
-    unsigned short skip;
-    unsigned short count;
-    unsigned short pad3;
-  } idx;
-  struct {
-    unsigned char cmd;
-    unsigned char pad0;
-    unsigned short pad1;
-    unsigned int flags;
-  } clear0;
-  struct {
-    unsigned int mask;
-    unsigned int value;
-  } clear1;
-};
-#ifdef __cplusplus
-}
-#endif
-#endif
diff --git a/libc/kernel/uapi/drm/sis_drm.h b/libc/kernel/uapi/drm/sis_drm.h
deleted file mode 100644
index 1606a85..0000000
--- a/libc/kernel/uapi/drm/sis_drm.h
+++ /dev/null
@@ -1,54 +0,0 @@
-/****************************************************************************
- ****************************************************************************
- ***
- ***   This header was automatically generated from a Linux kernel header
- ***   of the same name, to make information necessary for userspace to
- ***   call into the kernel available to libc.  It contains only constants,
- ***   structures, and macros generated from the original header, and thus,
- ***   contains no copyrightable information.
- ***
- ***   To edit the content of this header, modify the corresponding
- ***   source file (e.g. under external/kernel-headers/original/) then
- ***   run bionic/libc/kernel/tools/update_all.py
- ***
- ***   Any manual change here will be lost the next time this script will
- ***   be run. You've been warned!
- ***
- ****************************************************************************
- ****************************************************************************/
-#ifndef __SIS_DRM_H__
-#define __SIS_DRM_H__
-#include "drm.h"
-#ifdef __cplusplus
-extern "C" {
-#endif
-#define NOT_USED_0_3
-#define DRM_SIS_FB_ALLOC 0x04
-#define DRM_SIS_FB_FREE 0x05
-#define NOT_USED_6_12
-#define DRM_SIS_AGP_INIT 0x13
-#define DRM_SIS_AGP_ALLOC 0x14
-#define DRM_SIS_AGP_FREE 0x15
-#define DRM_SIS_FB_INIT 0x16
-#define DRM_IOCTL_SIS_FB_ALLOC DRM_IOWR(DRM_COMMAND_BASE + DRM_SIS_FB_ALLOC, drm_sis_mem_t)
-#define DRM_IOCTL_SIS_FB_FREE DRM_IOW(DRM_COMMAND_BASE + DRM_SIS_FB_FREE, drm_sis_mem_t)
-#define DRM_IOCTL_SIS_AGP_INIT DRM_IOWR(DRM_COMMAND_BASE + DRM_SIS_AGP_INIT, drm_sis_agp_t)
-#define DRM_IOCTL_SIS_AGP_ALLOC DRM_IOWR(DRM_COMMAND_BASE + DRM_SIS_AGP_ALLOC, drm_sis_mem_t)
-#define DRM_IOCTL_SIS_AGP_FREE DRM_IOW(DRM_COMMAND_BASE + DRM_SIS_AGP_FREE, drm_sis_mem_t)
-#define DRM_IOCTL_SIS_FB_INIT DRM_IOW(DRM_COMMAND_BASE + DRM_SIS_FB_INIT, drm_sis_fb_t)
-typedef struct {
-  int context;
-  unsigned long offset;
-  unsigned long size;
-  unsigned long free;
-} drm_sis_mem_t;
-typedef struct {
-  unsigned long offset, size;
-} drm_sis_agp_t;
-typedef struct {
-  unsigned long offset, size;
-} drm_sis_fb_t;
-#ifdef __cplusplus
-}
-#endif
-#endif
diff --git a/libc/kernel/uapi/drm/via_drm.h b/libc/kernel/uapi/drm/via_drm.h
deleted file mode 100644
index 95a149b..0000000
--- a/libc/kernel/uapi/drm/via_drm.h
+++ /dev/null
@@ -1,202 +0,0 @@
-/****************************************************************************
- ****************************************************************************
- ***
- ***   This header was automatically generated from a Linux kernel header
- ***   of the same name, to make information necessary for userspace to
- ***   call into the kernel available to libc.  It contains only constants,
- ***   structures, and macros generated from the original header, and thus,
- ***   contains no copyrightable information.
- ***
- ***   To edit the content of this header, modify the corresponding
- ***   source file (e.g. under external/kernel-headers/original/) then
- ***   run bionic/libc/kernel/tools/update_all.py
- ***
- ***   Any manual change here will be lost the next time this script will
- ***   be run. You've been warned!
- ***
- ****************************************************************************
- ****************************************************************************/
-#ifndef _VIA_DRM_H_
-#define _VIA_DRM_H_
-#include "drm.h"
-#ifdef __cplusplus
-extern "C" {
-#endif
-#ifndef _VIA_DEFINES_
-#define _VIA_DEFINES_
-#define VIA_NR_SAREA_CLIPRECTS 8
-#define VIA_NR_XVMC_PORTS 10
-#define VIA_NR_XVMC_LOCKS 5
-#define VIA_MAX_CACHELINE_SIZE 64
-#define XVMCLOCKPTR(saPriv,lockNo) ((volatile struct drm_hw_lock *) (((((unsigned long) (saPriv)->XvMCLockArea) + (VIA_MAX_CACHELINE_SIZE - 1)) & ~(VIA_MAX_CACHELINE_SIZE - 1)) + VIA_MAX_CACHELINE_SIZE * (lockNo)))
-#define VIA_NR_TEX_REGIONS 64
-#define VIA_LOG_MIN_TEX_REGION_SIZE 16
-#endif
-#define VIA_UPLOAD_TEX0IMAGE 0x1
-#define VIA_UPLOAD_TEX1IMAGE 0x2
-#define VIA_UPLOAD_CTX 0x4
-#define VIA_UPLOAD_BUFFERS 0x8
-#define VIA_UPLOAD_TEX0 0x10
-#define VIA_UPLOAD_TEX1 0x20
-#define VIA_UPLOAD_CLIPRECTS 0x40
-#define VIA_UPLOAD_ALL 0xff
-#define DRM_VIA_ALLOCMEM 0x00
-#define DRM_VIA_FREEMEM 0x01
-#define DRM_VIA_AGP_INIT 0x02
-#define DRM_VIA_FB_INIT 0x03
-#define DRM_VIA_MAP_INIT 0x04
-#define DRM_VIA_DEC_FUTEX 0x05
-#define NOT_USED
-#define DRM_VIA_DMA_INIT 0x07
-#define DRM_VIA_CMDBUFFER 0x08
-#define DRM_VIA_FLUSH 0x09
-#define DRM_VIA_PCICMD 0x0a
-#define DRM_VIA_CMDBUF_SIZE 0x0b
-#define NOT_USED
-#define DRM_VIA_WAIT_IRQ 0x0d
-#define DRM_VIA_DMA_BLIT 0x0e
-#define DRM_VIA_BLIT_SYNC 0x0f
-#define DRM_IOCTL_VIA_ALLOCMEM DRM_IOWR(DRM_COMMAND_BASE + DRM_VIA_ALLOCMEM, drm_via_mem_t)
-#define DRM_IOCTL_VIA_FREEMEM DRM_IOW(DRM_COMMAND_BASE + DRM_VIA_FREEMEM, drm_via_mem_t)
-#define DRM_IOCTL_VIA_AGP_INIT DRM_IOWR(DRM_COMMAND_BASE + DRM_VIA_AGP_INIT, drm_via_agp_t)
-#define DRM_IOCTL_VIA_FB_INIT DRM_IOWR(DRM_COMMAND_BASE + DRM_VIA_FB_INIT, drm_via_fb_t)
-#define DRM_IOCTL_VIA_MAP_INIT DRM_IOWR(DRM_COMMAND_BASE + DRM_VIA_MAP_INIT, drm_via_init_t)
-#define DRM_IOCTL_VIA_DEC_FUTEX DRM_IOW(DRM_COMMAND_BASE + DRM_VIA_DEC_FUTEX, drm_via_futex_t)
-#define DRM_IOCTL_VIA_DMA_INIT DRM_IOWR(DRM_COMMAND_BASE + DRM_VIA_DMA_INIT, drm_via_dma_init_t)
-#define DRM_IOCTL_VIA_CMDBUFFER DRM_IOW(DRM_COMMAND_BASE + DRM_VIA_CMDBUFFER, drm_via_cmdbuffer_t)
-#define DRM_IOCTL_VIA_FLUSH DRM_IO(DRM_COMMAND_BASE + DRM_VIA_FLUSH)
-#define DRM_IOCTL_VIA_PCICMD DRM_IOW(DRM_COMMAND_BASE + DRM_VIA_PCICMD, drm_via_cmdbuffer_t)
-#define DRM_IOCTL_VIA_CMDBUF_SIZE DRM_IOWR(DRM_COMMAND_BASE + DRM_VIA_CMDBUF_SIZE, drm_via_cmdbuf_size_t)
-#define DRM_IOCTL_VIA_WAIT_IRQ DRM_IOWR(DRM_COMMAND_BASE + DRM_VIA_WAIT_IRQ, drm_via_irqwait_t)
-#define DRM_IOCTL_VIA_DMA_BLIT DRM_IOW(DRM_COMMAND_BASE + DRM_VIA_DMA_BLIT, drm_via_dmablit_t)
-#define DRM_IOCTL_VIA_BLIT_SYNC DRM_IOW(DRM_COMMAND_BASE + DRM_VIA_BLIT_SYNC, drm_via_blitsync_t)
-#define VIA_TEX_SETUP_SIZE 8
-#define VIA_FRONT 0x1
-#define VIA_BACK 0x2
-#define VIA_DEPTH 0x4
-#define VIA_STENCIL 0x8
-#define VIA_MEM_VIDEO 0
-#define VIA_MEM_AGP 1
-#define VIA_MEM_SYSTEM 2
-#define VIA_MEM_MIXED 3
-#define VIA_MEM_UNKNOWN 4
-typedef struct {
-  __u32 offset;
-  __u32 size;
-} drm_via_agp_t;
-typedef struct {
-  __u32 offset;
-  __u32 size;
-} drm_via_fb_t;
-typedef struct {
-  __u32 context;
-  __u32 type;
-  __u32 size;
-  unsigned long index;
-  unsigned long offset;
-} drm_via_mem_t;
-typedef struct _drm_via_init {
-  enum {
-    VIA_INIT_MAP = 0x01,
-    VIA_CLEANUP_MAP = 0x02
-  } func;
-  unsigned long sarea_priv_offset;
-  unsigned long fb_offset;
-  unsigned long mmio_offset;
-  unsigned long agpAddr;
-} drm_via_init_t;
-typedef struct _drm_via_futex {
-  enum {
-    VIA_FUTEX_WAIT = 0x00,
-    VIA_FUTEX_WAKE = 0X01
-  } func;
-  __u32 ms;
-  __u32 lock;
-  __u32 val;
-} drm_via_futex_t;
-typedef struct _drm_via_dma_init {
-  enum {
-    VIA_INIT_DMA = 0x01,
-    VIA_CLEANUP_DMA = 0x02,
-    VIA_DMA_INITIALIZED = 0x03
-  } func;
-  unsigned long offset;
-  unsigned long size;
-  unsigned long reg_pause_addr;
-} drm_via_dma_init_t;
-typedef struct _drm_via_cmdbuffer {
-  char  * buf;
-  unsigned long size;
-} drm_via_cmdbuffer_t;
-typedef struct _drm_via_tex_region {
-  unsigned char next, prev;
-  unsigned char inUse;
-  int age;
-} drm_via_tex_region_t;
-typedef struct _drm_via_sarea {
-  unsigned int dirty;
-  unsigned int nbox;
-  struct drm_clip_rect boxes[VIA_NR_SAREA_CLIPRECTS];
-  drm_via_tex_region_t texList[VIA_NR_TEX_REGIONS + 1];
-  int texAge;
-  int ctxOwner;
-  int vertexPrim;
-  char XvMCLockArea[VIA_MAX_CACHELINE_SIZE * (VIA_NR_XVMC_LOCKS + 1)];
-  unsigned int XvMCDisplaying[VIA_NR_XVMC_PORTS];
-  unsigned int XvMCSubPicOn[VIA_NR_XVMC_PORTS];
-  unsigned int XvMCCtxNoGrabbed;
-  unsigned int pfCurrentOffset;
-} drm_via_sarea_t;
-typedef struct _drm_via_cmdbuf_size {
-  enum {
-    VIA_CMDBUF_SPACE = 0x01,
-    VIA_CMDBUF_LAG = 0x02
-  } func;
-  int wait;
-  __u32 size;
-} drm_via_cmdbuf_size_t;
-typedef enum {
-  VIA_IRQ_ABSOLUTE = 0x0,
-  VIA_IRQ_RELATIVE = 0x1,
-  VIA_IRQ_SIGNAL = 0x10000000,
-  VIA_IRQ_FORCE_SEQUENCE = 0x20000000
-} via_irq_seq_type_t;
-#define VIA_IRQ_FLAGS_MASK 0xF0000000
-enum drm_via_irqs {
-  drm_via_irq_hqv0 = 0,
-  drm_via_irq_hqv1,
-  drm_via_irq_dma0_dd,
-  drm_via_irq_dma0_td,
-  drm_via_irq_dma1_dd,
-  drm_via_irq_dma1_td,
-  drm_via_irq_num
-};
-struct drm_via_wait_irq_request {
-  unsigned irq;
-  via_irq_seq_type_t type;
-  __u32 sequence;
-  __u32 signal;
-};
-typedef union drm_via_irqwait {
-  struct drm_via_wait_irq_request request;
-  struct drm_wait_vblank_reply reply;
-} drm_via_irqwait_t;
-typedef struct drm_via_blitsync {
-  __u32 sync_handle;
-  unsigned engine;
-} drm_via_blitsync_t;
-typedef struct drm_via_dmablit {
-  __u32 num_lines;
-  __u32 line_length;
-  __u32 fb_addr;
-  __u32 fb_stride;
-  unsigned char * mem_addr;
-  __u32 mem_stride;
-  __u32 flags;
-  int to_fb;
-  drm_via_blitsync_t sync;
-} drm_via_dmablit_t;
-#ifdef __cplusplus
-}
-#endif
-#endif
diff --git a/libc/kernel/uapi/linux/android/binder.h b/libc/kernel/uapi/linux/android/binder.h
index 52f4c6b..0d1f83d 100644
--- a/libc/kernel/uapi/linux/android/binder.h
+++ b/libc/kernel/uapi/linux/android/binder.h
@@ -221,6 +221,7 @@
   BR_FAILED_REPLY = _IO('r', 17),
   BR_FROZEN_REPLY = _IO('r', 18),
   BR_ONEWAY_SPAM_SUSPECT = _IO('r', 19),
+  BR_TRANSACTION_PENDING_FROZEN = _IO('r', 20),
 };
 enum binder_driver_command_protocol {
   BC_TRANSACTION = _IOW('c', 0, struct binder_transaction_data),
diff --git a/libc/kernel/uapi/linux/auxvec.h b/libc/kernel/uapi/linux/auxvec.h
index c80c170..3ca56fc 100644
--- a/libc/kernel/uapi/linux/auxvec.h
+++ b/libc/kernel/uapi/linux/auxvec.h
@@ -41,6 +41,8 @@
 #define AT_BASE_PLATFORM 24
 #define AT_RANDOM 25
 #define AT_HWCAP2 26
+#define AT_RSEQ_FEATURE_SIZE 27
+#define AT_RSEQ_ALIGN 28
 #define AT_EXECFN 31
 #ifndef AT_MINSIGSTKSZ
 #define AT_MINSIGSTKSZ 51
diff --git a/libc/kernel/uapi/linux/batadv_packet.h b/libc/kernel/uapi/linux/batadv_packet.h
index ede53cf..9daed82 100644
--- a/libc/kernel/uapi/linux/batadv_packet.h
+++ b/libc/kernel/uapi/linux/batadv_packet.h
@@ -28,6 +28,7 @@
   BATADV_CODED = 0x02,
   BATADV_ELP = 0x03,
   BATADV_OGM2 = 0x04,
+  BATADV_MCAST = 0x05,
 #define BATADV_UNICAST_MIN 0x40
   BATADV_UNICAST = 0x40,
   BATADV_UNICAST_FRAG = 0x41,
diff --git a/libc/kernel/uapi/linux/bpf.h b/libc/kernel/uapi/linux/bpf.h
index 163dd1e..4131ce4 100644
--- a/libc/kernel/uapi/linux/bpf.h
+++ b/libc/kernel/uapi/linux/bpf.h
@@ -275,6 +275,7 @@
 #define BPF_F_TEST_STATE_FREQ (1U << 3)
 #define BPF_F_SLEEPABLE (1U << 4)
 #define BPF_F_XDP_HAS_FRAGS (1U << 5)
+#define BPF_F_XDP_DEV_BOUND_ONLY (1U << 6)
 #define BPF_F_KPROBE_MULTI_RETURN (1U << 0)
 #define BPF_PSEUDO_MAP_FD 1
 #define BPF_PSEUDO_MAP_IDX 5
@@ -557,6 +558,7 @@
   BPF_F_ZERO_CSUM_TX = (1ULL << 1),
   BPF_F_DONT_FRAGMENT = (1ULL << 2),
   BPF_F_SEQ_NUMBER = (1ULL << 3),
+  BPF_F_NO_TUNNEL_KEY = (1ULL << 4),
 };
 enum {
   BPF_F_TUNINFO_FLAGS = (1ULL << 4),
@@ -583,6 +585,8 @@
   BPF_F_ADJ_ROOM_ENCAP_L4_UDP = (1ULL << 4),
   BPF_F_ADJ_ROOM_NO_CSUM_RESET = (1ULL << 5),
   BPF_F_ADJ_ROOM_ENCAP_L2_ETH = (1ULL << 6),
+  BPF_F_ADJ_ROOM_DECAP_L3_IPV4 = (1ULL << 7),
+  BPF_F_ADJ_ROOM_DECAP_L3_IPV6 = (1ULL << 8),
 };
 enum {
   BPF_ADJ_ROOM_ENCAP_L2_MASK = 0xff,
@@ -1095,6 +1099,7 @@
 enum {
   BPF_FIB_LOOKUP_DIRECT = (1U << 0),
   BPF_FIB_LOOKUP_OUTPUT = (1U << 1),
+  BPF_FIB_LOOKUP_SKIP_NEIGH = (1U << 2),
 };
 enum {
   BPF_FIB_LKUP_RET_SUCCESS,
@@ -1218,6 +1223,15 @@
   __u64 : 64;
   __u64 : 64;
 } __attribute__((aligned(8)));
+struct bpf_rb_root {
+  __u64 : 64;
+  __u64 : 64;
+} __attribute__((aligned(8)));
+struct bpf_rb_node {
+  __u64 : 64;
+  __u64 : 64;
+  __u64 : 64;
+} __attribute__((aligned(8)));
 struct bpf_sysctl {
   __u32 write;
   __u32 file_pos;
diff --git a/libc/kernel/uapi/linux/btrfs.h b/libc/kernel/uapi/linux/btrfs.h
index 0fdac66..5220647 100644
--- a/libc/kernel/uapi/linux/btrfs.h
+++ b/libc/kernel/uapi/linux/btrfs.h
@@ -157,7 +157,8 @@
   __u8 uuid[BTRFS_UUID_SIZE];
   __u64 bytes_used;
   __u64 total_bytes;
-  __u64 unused[379];
+  __u8 fsid[BTRFS_UUID_SIZE];
+  __u64 unused[377];
   __u8 path[BTRFS_DEVICE_PATH_NAME_MAX];
 };
 #define BTRFS_FS_INFO_FLAG_CSUM_INFO (1 << 0)
diff --git a/libc/kernel/uapi/linux/cxl_mem.h b/libc/kernel/uapi/linux/cxl_mem.h
index c94af87..5a0a34e 100644
--- a/libc/kernel/uapi/linux/cxl_mem.h
+++ b/libc/kernel/uapi/linux/cxl_mem.h
@@ -37,7 +37,9 @@
 struct cxl_command_info {
   __u32 id;
   __u32 flags;
-#define CXL_MEM_COMMAND_FLAG_MASK GENMASK(0, 0)
+#define CXL_MEM_COMMAND_FLAG_MASK GENMASK(1, 0)
+#define CXL_MEM_COMMAND_FLAG_ENABLED BIT(0)
+#define CXL_MEM_COMMAND_FLAG_EXCLUSIVE BIT(1)
   __u32 size_in;
   __u32 size_out;
 };
diff --git a/libc/kernel/uapi/linux/dcbnl.h b/libc/kernel/uapi/linux/dcbnl.h
index bc88387..b2fec7b 100644
--- a/libc/kernel/uapi/linux/dcbnl.h
+++ b/libc/kernel/uapi/linux/dcbnl.h
@@ -181,6 +181,7 @@
   DCB_ATTR_IEEE_QCN_STATS,
   DCB_ATTR_DCB_BUFFER,
   DCB_ATTR_DCB_APP_TRUST_TABLE,
+  DCB_ATTR_DCB_REWR_TABLE,
   __DCB_ATTR_IEEE_MAX
 };
 #define DCB_ATTR_IEEE_MAX (__DCB_ATTR_IEEE_MAX - 1)
diff --git a/libc/kernel/uapi/linux/elf.h b/libc/kernel/uapi/linux/elf.h
index 28c8426..e4901d1 100644
--- a/libc/kernel/uapi/linux/elf.h
+++ b/libc/kernel/uapi/linux/elf.h
@@ -366,6 +366,7 @@
 #define NT_ARM_PAC_ENABLED_KEYS 0x40a
 #define NT_ARM_SSVE 0x40b
 #define NT_ARM_ZA 0x40c
+#define NT_ARM_ZT 0x40d
 #define NT_ARC_V2 0x600
 #define NT_VMCOREDD 0x700
 #define NT_MIPS_DSP 0x800
@@ -376,6 +377,8 @@
 #define NT_LOONGARCH_LSX 0xa02
 #define NT_LOONGARCH_LASX 0xa03
 #define NT_LOONGARCH_LBT 0xa04
+#define NT_LOONGARCH_HW_BREAK 0xa05
+#define NT_LOONGARCH_HW_WATCH 0xa06
 #define NT_GNU_PROPERTY_TYPE_0 5
 typedef struct elf32_note {
   Elf32_Word n_namesz;
diff --git a/libc/kernel/uapi/linux/ethtool.h b/libc/kernel/uapi/linux/ethtool.h
index a58be6f..eec750d 100644
--- a/libc/kernel/uapi/linux/ethtool.h
+++ b/libc/kernel/uapi/linux/ethtool.h
@@ -269,6 +269,11 @@
   ETH_SS_STATS_RMON,
   ETH_SS_COUNT
 };
+enum ethtool_mac_stats_src {
+  ETHTOOL_MAC_STATS_SRC_AGGREGATE,
+  ETHTOOL_MAC_STATS_SRC_EMAC,
+  ETHTOOL_MAC_STATS_SRC_PMAC,
+};
 enum ethtool_module_power_mode_policy {
   ETHTOOL_MODULE_POWER_MODE_POLICY_HIGH = 1,
   ETHTOOL_MODULE_POWER_MODE_POLICY_AUTO,
@@ -291,6 +296,14 @@
   ETHTOOL_PODL_PSE_PW_D_STATUS_IDLE,
   ETHTOOL_PODL_PSE_PW_D_STATUS_ERROR,
 };
+enum ethtool_mm_verify_status {
+  ETHTOOL_MM_VERIFY_STATUS_UNKNOWN,
+  ETHTOOL_MM_VERIFY_STATUS_INITIAL,
+  ETHTOOL_MM_VERIFY_STATUS_VERIFYING,
+  ETHTOOL_MM_VERIFY_STATUS_SUCCEEDED,
+  ETHTOOL_MM_VERIFY_STATUS_FAILED,
+  ETHTOOL_MM_VERIFY_STATUS_DISABLED,
+};
 struct ethtool_gstrings {
   __u32 cmd;
   __u32 string_set;
@@ -419,7 +432,7 @@
     __u32 rule_cnt;
     __u32 rss_context;
   };
-  __u32 rule_locs[0];
+  __u32 rule_locs[];
 };
 struct ethtool_rxfh_indir {
   __u32 cmd;
@@ -725,6 +738,9 @@
   ETHTOOL_LINK_MODE_800000baseDR8_2_Full_BIT = 96,
   ETHTOOL_LINK_MODE_800000baseSR8_Full_BIT = 97,
   ETHTOOL_LINK_MODE_800000baseVR8_Full_BIT = 98,
+  ETHTOOL_LINK_MODE_10baseT1S_Full_BIT = 99,
+  ETHTOOL_LINK_MODE_10baseT1S_Half_BIT = 100,
+  ETHTOOL_LINK_MODE_10baseT1S_P2MP_Half_BIT = 101,
   __ETHTOOL_LINK_MODE_MASK_NBITS
 };
 #define __ETHTOOL_LINK_MODE_LEGACY_MASK(base_name) (1UL << (ETHTOOL_LINK_MODE_ ##base_name ##_BIT))
diff --git a/libc/kernel/uapi/linux/ethtool_netlink.h b/libc/kernel/uapi/linux/ethtool_netlink.h
index cc9c53c..f1ef896 100644
--- a/libc/kernel/uapi/linux/ethtool_netlink.h
+++ b/libc/kernel/uapi/linux/ethtool_netlink.h
@@ -59,6 +59,11 @@
   ETHTOOL_MSG_PSE_GET,
   ETHTOOL_MSG_PSE_SET,
   ETHTOOL_MSG_RSS_GET,
+  ETHTOOL_MSG_PLCA_GET_CFG,
+  ETHTOOL_MSG_PLCA_SET_CFG,
+  ETHTOOL_MSG_PLCA_GET_STATUS,
+  ETHTOOL_MSG_MM_GET,
+  ETHTOOL_MSG_MM_SET,
   __ETHTOOL_MSG_USER_CNT,
   ETHTOOL_MSG_USER_MAX = __ETHTOOL_MSG_USER_CNT - 1
 };
@@ -102,6 +107,11 @@
   ETHTOOL_MSG_MODULE_NTF,
   ETHTOOL_MSG_PSE_GET_REPLY,
   ETHTOOL_MSG_RSS_GET_REPLY,
+  ETHTOOL_MSG_PLCA_GET_CFG_REPLY,
+  ETHTOOL_MSG_PLCA_GET_STATUS_REPLY,
+  ETHTOOL_MSG_PLCA_NTF,
+  ETHTOOL_MSG_MM_GET_REPLY,
+  ETHTOOL_MSG_MM_NTF,
   __ETHTOOL_MSG_KERNEL_CNT,
   ETHTOOL_MSG_KERNEL_MAX = __ETHTOOL_MSG_KERNEL_CNT - 1
 };
@@ -266,6 +276,7 @@
   ETHTOOL_A_RINGS_TCP_DATA_SPLIT,
   ETHTOOL_A_RINGS_CQE_SIZE,
   ETHTOOL_A_RINGS_TX_PUSH,
+  ETHTOOL_A_RINGS_RX_PUSH,
   __ETHTOOL_A_RINGS_CNT,
   ETHTOOL_A_RINGS_MAX = (__ETHTOOL_A_RINGS_CNT - 1)
 };
@@ -310,6 +321,9 @@
   ETHTOOL_A_COALESCE_RATE_SAMPLE_INTERVAL,
   ETHTOOL_A_COALESCE_USE_CQE_MODE_TX,
   ETHTOOL_A_COALESCE_USE_CQE_MODE_RX,
+  ETHTOOL_A_COALESCE_TX_AGGR_MAX_BYTES,
+  ETHTOOL_A_COALESCE_TX_AGGR_MAX_FRAMES,
+  ETHTOOL_A_COALESCE_TX_AGGR_TIME_USECS,
   __ETHTOOL_A_COALESCE_CNT,
   ETHTOOL_A_COALESCE_MAX = (__ETHTOOL_A_COALESCE_CNT - 1)
 };
@@ -320,6 +334,7 @@
   ETHTOOL_A_PAUSE_RX,
   ETHTOOL_A_PAUSE_TX,
   ETHTOOL_A_PAUSE_STATS,
+  ETHTOOL_A_PAUSE_STATS_SRC,
   __ETHTOOL_A_PAUSE_CNT,
   ETHTOOL_A_PAUSE_MAX = (__ETHTOOL_A_PAUSE_CNT - 1)
 };
@@ -538,6 +553,7 @@
   ETHTOOL_A_STATS_HEADER,
   ETHTOOL_A_STATS_GROUPS,
   ETHTOOL_A_STATS_GRP,
+  ETHTOOL_A_STATS_SRC,
   __ETHTOOL_A_STATS_CNT,
   ETHTOOL_A_STATS_MAX = (__ETHTOOL_A_STATS_CNT - 1)
 };
@@ -635,6 +651,48 @@
   __ETHTOOL_A_RSS_CNT,
   ETHTOOL_A_RSS_MAX = (__ETHTOOL_A_RSS_CNT - 1),
 };
+enum {
+  ETHTOOL_A_PLCA_UNSPEC,
+  ETHTOOL_A_PLCA_HEADER,
+  ETHTOOL_A_PLCA_VERSION,
+  ETHTOOL_A_PLCA_ENABLED,
+  ETHTOOL_A_PLCA_STATUS,
+  ETHTOOL_A_PLCA_NODE_CNT,
+  ETHTOOL_A_PLCA_NODE_ID,
+  ETHTOOL_A_PLCA_TO_TMR,
+  ETHTOOL_A_PLCA_BURST_CNT,
+  ETHTOOL_A_PLCA_BURST_TMR,
+  __ETHTOOL_A_PLCA_CNT,
+  ETHTOOL_A_PLCA_MAX = (__ETHTOOL_A_PLCA_CNT - 1)
+};
+enum {
+  ETHTOOL_A_MM_STAT_UNSPEC,
+  ETHTOOL_A_MM_STAT_PAD,
+  ETHTOOL_A_MM_STAT_REASSEMBLY_ERRORS,
+  ETHTOOL_A_MM_STAT_SMD_ERRORS,
+  ETHTOOL_A_MM_STAT_REASSEMBLY_OK,
+  ETHTOOL_A_MM_STAT_RX_FRAG_COUNT,
+  ETHTOOL_A_MM_STAT_TX_FRAG_COUNT,
+  ETHTOOL_A_MM_STAT_HOLD_COUNT,
+  __ETHTOOL_A_MM_STAT_CNT,
+  ETHTOOL_A_MM_STAT_MAX = (__ETHTOOL_A_MM_STAT_CNT - 1)
+};
+enum {
+  ETHTOOL_A_MM_UNSPEC,
+  ETHTOOL_A_MM_HEADER,
+  ETHTOOL_A_MM_PMAC_ENABLED,
+  ETHTOOL_A_MM_TX_ENABLED,
+  ETHTOOL_A_MM_TX_ACTIVE,
+  ETHTOOL_A_MM_TX_MIN_FRAG_SIZE,
+  ETHTOOL_A_MM_RX_MIN_FRAG_SIZE,
+  ETHTOOL_A_MM_VERIFY_ENABLED,
+  ETHTOOL_A_MM_VERIFY_STATUS,
+  ETHTOOL_A_MM_VERIFY_TIME,
+  ETHTOOL_A_MM_MAX_VERIFY_TIME,
+  ETHTOOL_A_MM_STATS,
+  __ETHTOOL_A_MM_CNT,
+  ETHTOOL_A_MM_MAX = (__ETHTOOL_A_MM_CNT - 1)
+};
 #define ETHTOOL_GENL_NAME "ethtool"
 #define ETHTOOL_GENL_VERSION 1
 #define ETHTOOL_MCGRP_MONITOR_NAME "monitor"
diff --git a/libc/kernel/uapi/linux/fanotify.h b/libc/kernel/uapi/linux/fanotify.h
index 9815a64..f9551a8 100644
--- a/libc/kernel/uapi/linux/fanotify.h
+++ b/libc/kernel/uapi/linux/fanotify.h
@@ -113,13 +113,27 @@
   __s32 error;
   __u32 error_count;
 };
+#define FAN_RESPONSE_INFO_NONE 0
+#define FAN_RESPONSE_INFO_AUDIT_RULE 1
 struct fanotify_response {
   __s32 fd;
   __u32 response;
 };
+struct fanotify_response_info_header {
+  __u8 type;
+  __u8 pad;
+  __u16 len;
+};
+struct fanotify_response_info_audit_rule {
+  struct fanotify_response_info_header hdr;
+  __u32 rule_number;
+  __u32 subj_trust;
+  __u32 obj_trust;
+};
 #define FAN_ALLOW 0x01
 #define FAN_DENY 0x02
 #define FAN_AUDIT 0x10
+#define FAN_INFO 0x20
 #define FAN_NOFD - 1
 #define FAN_NOPIDFD FAN_NOFD
 #define FAN_EPIDFD - 2
diff --git a/libc/kernel/uapi/linux/fcntl.h b/libc/kernel/uapi/linux/fcntl.h
index a46726b..05393d5 100644
--- a/libc/kernel/uapi/linux/fcntl.h
+++ b/libc/kernel/uapi/linux/fcntl.h
@@ -34,6 +34,7 @@
 #define F_SEAL_GROW 0x0004
 #define F_SEAL_WRITE 0x0008
 #define F_SEAL_FUTURE_WRITE 0x0010
+#define F_SEAL_EXEC 0x0020
 #define F_GET_RW_HINT (F_LINUX_SPECIFIC_BASE + 11)
 #define F_SET_RW_HINT (F_LINUX_SPECIFIC_BASE + 12)
 #define F_GET_FILE_RW_HINT (F_LINUX_SPECIFIC_BASE + 13)
diff --git a/libc/kernel/uapi/linux/fou.h b/libc/kernel/uapi/linux/fou.h
index a16b8c6..7b06cff 100644
--- a/libc/kernel/uapi/linux/fou.h
+++ b/libc/kernel/uapi/linux/fou.h
@@ -19,7 +19,12 @@
 #ifndef _UAPI_LINUX_FOU_H
 #define _UAPI_LINUX_FOU_H
 #define FOU_GENL_NAME "fou"
-#define FOU_GENL_VERSION 0x1
+#define FOU_GENL_VERSION 1
+enum {
+  FOU_ENCAP_UNSPEC,
+  FOU_ENCAP_DIRECT,
+  FOU_ENCAP_GUE,
+};
 enum {
   FOU_ATTR_UNSPEC,
   FOU_ATTR_PORT,
@@ -33,7 +38,7 @@
   FOU_ATTR_PEER_V6,
   FOU_ATTR_PEER_PORT,
   FOU_ATTR_IFINDEX,
-  __FOU_ATTR_MAX,
+  __FOU_ATTR_MAX
 };
 #define FOU_ATTR_MAX (__FOU_ATTR_MAX - 1)
 enum {
@@ -41,12 +46,7 @@
   FOU_CMD_ADD,
   FOU_CMD_DEL,
   FOU_CMD_GET,
-  __FOU_CMD_MAX,
-};
-enum {
-  FOU_ENCAP_UNSPEC,
-  FOU_ENCAP_DIRECT,
-  FOU_ENCAP_GUE,
+  __FOU_CMD_MAX
 };
 #define FOU_CMD_MAX (__FOU_CMD_MAX - 1)
 #endif
diff --git a/libc/kernel/uapi/linux/fuse.h b/libc/kernel/uapi/linux/fuse.h
index f1eec4d..c3668e7 100644
--- a/libc/kernel/uapi/linux/fuse.h
+++ b/libc/kernel/uapi/linux/fuse.h
@@ -111,6 +111,7 @@
 #define FUSE_INIT_RESERVED (1 << 31)
 #define FUSE_SECURITY_CTX (1ULL << 32)
 #define FUSE_HAS_INODE_DAX (1ULL << 33)
+#define FUSE_CREATE_SUPP_GROUP (1ULL << 34)
 #if FUSE_KERNEL_VERSION > 7 || FUSE_KERNEL_VERSION == 7 && FUSE_KERNEL_MINOR_VERSION >= 36
 #define FUSE_PASSTHROUGH (1ULL << 63)
 #else
@@ -140,6 +141,10 @@
 #define FUSE_OPEN_KILL_SUIDGID (1 << 0)
 #define FUSE_SETXATTR_ACL_KILL_SGID (1 << 0)
 #define FUSE_EXPIRE_ONLY (1 << 0)
+enum fuse_ext_type {
+  FUSE_MAX_NR_SECCTX = 31,
+  FUSE_EXT_GROUPS = 32,
+};
 enum fuse_opcode {
   FUSE_LOOKUP = 1,
   FUSE_FORGET = 2,
@@ -465,7 +470,8 @@
   uint32_t uid;
   uint32_t gid;
   uint32_t pid;
-  uint32_t padding;
+  uint16_t total_extlen;
+  uint16_t padding;
 };
 struct fuse_out_header {
   uint32_t len;
@@ -575,4 +581,12 @@
   uint32_t size;
   uint32_t nr_secctx;
 };
+struct fuse_ext_header {
+  uint32_t size;
+  uint32_t type;
+};
+struct fuse_supp_groups {
+  uint32_t nr_groups;
+  uint32_t groups[];
+};
 #endif
diff --git a/libc/kernel/uapi/linux/gsmmux.h b/libc/kernel/uapi/linux/gsmmux.h
index 4e6920a..6ddf1b9 100644
--- a/libc/kernel/uapi/linux/gsmmux.h
+++ b/libc/kernel/uapi/linux/gsmmux.h
@@ -47,4 +47,10 @@
 #define GSMIOC_ENABLE_NET _IOW('G', 2, struct gsm_netconfig)
 #define GSMIOC_DISABLE_NET _IO('G', 3)
 #define GSMIOC_GETFIRST _IOR('G', 4, __u32)
+struct gsm_config_ext {
+  __u32 keep_alive;
+  __u32 reserved[7];
+};
+#define GSMIOC_GETCONF_EXT _IOR('G', 5, struct gsm_config_ext)
+#define GSMIOC_SETCONF_EXT _IOW('G', 6, struct gsm_config_ext)
 #endif
diff --git a/libc/kernel/uapi/linux/if_bridge.h b/libc/kernel/uapi/linux/if_bridge.h
index 702363e..48f6345 100644
--- a/libc/kernel/uapi/linux/if_bridge.h
+++ b/libc/kernel/uapi/linux/if_bridge.h
@@ -435,6 +435,8 @@
   BRIDGE_VLANDB_ENTRY_TUNNEL_INFO,
   BRIDGE_VLANDB_ENTRY_STATS,
   BRIDGE_VLANDB_ENTRY_MCAST_ROUTER,
+  BRIDGE_VLANDB_ENTRY_MCAST_N_GROUPS,
+  BRIDGE_VLANDB_ENTRY_MCAST_MAX_GROUPS,
   __BRIDGE_VLANDB_ENTRY_MAX,
 };
 #define BRIDGE_VLANDB_ENTRY_MAX (__BRIDGE_VLANDB_ENTRY_MAX - 1)
diff --git a/libc/kernel/uapi/linux/if_link.h b/libc/kernel/uapi/linux/if_link.h
index 19c6346..fbb933b 100644
--- a/libc/kernel/uapi/linux/if_link.h
+++ b/libc/kernel/uapi/linux/if_link.h
@@ -167,6 +167,8 @@
   IFLA_TSO_MAX_SEGS,
   IFLA_ALLMULTI,
   IFLA_DEVLINK_PORT,
+  IFLA_GSO_IPV4_MAX_SIZE,
+  IFLA_GRO_IPV4_MAX_SIZE,
   __IFLA_MAX
 };
 #define IFLA_MAX (__IFLA_MAX - 1)
@@ -307,6 +309,8 @@
   IFLA_BRPORT_MCAST_EHT_HOSTS_CNT,
   IFLA_BRPORT_LOCKED,
   IFLA_BRPORT_MAB,
+  IFLA_BRPORT_MCAST_N_GROUPS,
+  IFLA_BRPORT_MCAST_MAX_GROUPS,
   __IFLA_BRPORT_MAX
 };
 #define IFLA_BRPORT_MAX (__IFLA_BRPORT_MAX - 1)
diff --git a/libc/kernel/uapi/linux/if_packet.h b/libc/kernel/uapi/linux/if_packet.h
index 340b2ee..719f596 100644
--- a/libc/kernel/uapi/linux/if_packet.h
+++ b/libc/kernel/uapi/linux/if_packet.h
@@ -113,6 +113,7 @@
 #define TP_STATUS_BLK_TMO (1 << 5)
 #define TP_STATUS_VLAN_TPID_VALID (1 << 6)
 #define TP_STATUS_CSUM_VALID (1 << 7)
+#define TP_STATUS_GSO_TCP (1 << 8)
 #define TP_STATUS_AVAILABLE 0
 #define TP_STATUS_SEND_REQUEST (1 << 0)
 #define TP_STATUS_SENDING (1 << 1)
diff --git a/libc/kernel/uapi/linux/in.h b/libc/kernel/uapi/linux/in.h
index 53d3074..3947d5a 100644
--- a/libc/kernel/uapi/linux/in.h
+++ b/libc/kernel/uapi/linux/in.h
@@ -141,6 +141,7 @@
 #define MCAST_MSFILTER 48
 #define IP_MULTICAST_ALL 49
 #define IP_UNICAST_IF 50
+#define IP_LOCAL_PORT_RANGE 51
 #define MCAST_EXCLUDE 0
 #define MCAST_INCLUDE 1
 #define IP_DEFAULT_MULTICAST_TTL 1
diff --git a/libc/kernel/uapi/linux/io_uring.h b/libc/kernel/uapi/linux/io_uring.h
index 5561448..a2d4f5f 100644
--- a/libc/kernel/uapi/linux/io_uring.h
+++ b/libc/kernel/uapi/linux/io_uring.h
@@ -200,6 +200,7 @@
   IORING_MSG_SEND_FD,
 };
 #define IORING_MSG_RING_CQE_SKIP (1U << 0)
+#define IORING_MSG_RING_FLAGS_PASS (1U << 1)
 struct io_uring_cqe {
   __u64 user_data;
   __s32 res;
@@ -272,6 +273,7 @@
 #define IORING_FEAT_RSRC_TAGS (1U << 10)
 #define IORING_FEAT_CQE_SKIP (1U << 11)
 #define IORING_FEAT_LINKED_FILE (1U << 12)
+#define IORING_FEAT_REG_REG_RING (1U << 13)
 enum {
   IORING_REGISTER_BUFFERS = 0,
   IORING_UNREGISTER_BUFFERS = 1,
@@ -299,7 +301,8 @@
   IORING_UNREGISTER_PBUF_RING = 23,
   IORING_REGISTER_SYNC_CANCEL = 24,
   IORING_REGISTER_FILE_ALLOC_RANGE = 25,
-  IORING_REGISTER_LAST
+  IORING_REGISTER_LAST,
+  IORING_REGISTER_USE_REGISTERED_RING = 1U << 31
 };
 enum {
   IO_WQ_BOUND,
@@ -381,7 +384,7 @@
       __u16 resv3;
       __u16 tail;
     };
-    struct io_uring_buf bufs[0];
+    __DECLARE_FLEX_ARRAY(struct io_uring_buf, bufs);
   };
 };
 struct io_uring_buf_reg {
diff --git a/libc/kernel/uapi/linux/ioam6.h b/libc/kernel/uapi/linux/ioam6.h
index e32c8e9..8d2a25b 100644
--- a/libc/kernel/uapi/linux/ioam6.h
+++ b/libc/kernel/uapi/linux/ioam6.h
@@ -58,6 +58,6 @@
 #error "Please fix <asm/byteorder.h>"
 #endif
 #define IOAM6_TRACE_DATA_SIZE_MAX 244
-  __u8 data[0];
+  __u8 data[];
 } __attribute__((packed));
 #endif
diff --git a/libc/kernel/uapi/linux/kd.h b/libc/kernel/uapi/linux/kd.h
index 903681b..a14cab6 100644
--- a/libc/kernel/uapi/linux/kd.h
+++ b/libc/kernel/uapi/linux/kd.h
@@ -158,5 +158,7 @@
 #define KD_FONT_OP_GET 1
 #define KD_FONT_OP_SET_DEFAULT 2
 #define KD_FONT_OP_COPY 3
+#define KD_FONT_OP_SET_TALL 4
+#define KD_FONT_OP_GET_TALL 5
 #define KD_FONT_FLAG_DONT_RECALC 1
 #endif
diff --git a/libc/kernel/uapi/linux/kvm.h b/libc/kernel/uapi/linux/kvm.h
index 9d33399..342c5c9 100644
--- a/libc/kernel/uapi/linux/kvm.h
+++ b/libc/kernel/uapi/linux/kvm.h
@@ -436,6 +436,8 @@
     struct {
       __u8 ar;
       __u8 key;
+      __u8 pad1[6];
+      __u64 old_addr;
     };
     __u32 sida_offset;
     __u8 reserved[32];
@@ -447,9 +449,12 @@
 #define KVM_S390_MEMOP_SIDA_WRITE 3
 #define KVM_S390_MEMOP_ABSOLUTE_READ 4
 #define KVM_S390_MEMOP_ABSOLUTE_WRITE 5
+#define KVM_S390_MEMOP_ABSOLUTE_CMPXCHG 6
 #define KVM_S390_MEMOP_F_CHECK_ONLY (1ULL << 0)
 #define KVM_S390_MEMOP_F_INJECT_EXCEPTION (1ULL << 1)
 #define KVM_S390_MEMOP_F_SKEY_PROTECTION (1ULL << 2)
+#define KVM_S390_MEMOP_EXTENSION_CAP_BASE (1 << 0)
+#define KVM_S390_MEMOP_EXTENSION_CAP_CMPXCHG (1 << 1)
 struct kvm_interrupt {
   __u32 irq;
 };
@@ -926,6 +931,7 @@
 #define KVM_CAP_DIRTY_LOG_RING_ACQ_REL 223
 #define KVM_CAP_S390_PROTECTED_ASYNC_DISABLE 224
 #define KVM_CAP_DIRTY_LOG_RING_WITH_BITMAP 225
+#define KVM_CAP_PMU_EVENT_MASKED_EVENTS 226
 #ifdef KVM_CAP_IRQ_ROUTING
 struct kvm_irq_routing_irqchip {
   __u32 irqchip;
diff --git a/libc/kernel/uapi/linux/mdio.h b/libc/kernel/uapi/linux/mdio.h
index 7a2c9af..725eb1a 100644
--- a/libc/kernel/uapi/linux/mdio.h
+++ b/libc/kernel/uapi/linux/mdio.h
@@ -78,6 +78,8 @@
 #define MDIO_AN_T1_LP_L 517
 #define MDIO_AN_T1_LP_M 518
 #define MDIO_AN_T1_LP_H 519
+#define MDIO_AN_10BT1_AN_CTRL 526
+#define MDIO_AN_10BT1_AN_STAT 527
 #define MDIO_PMA_PMD_BT1_CTRL 2100
 #define MDIO_PMA_LASI_RXCTRL 0x9000
 #define MDIO_PMA_LASI_TXCTRL 0x9001
@@ -270,6 +272,8 @@
 #define MDIO_AN_T1_LP_M_B10L 0x4000
 #define MDIO_AN_T1_LP_H_10L_TX_HI_REQ 0x1000
 #define MDIO_AN_T1_LP_H_10L_TX_HI 0x2000
+#define MDIO_AN_10BT1_AN_CTRL_ADV_EEE_T1L 0x4000
+#define MDIO_AN_10BT1_AN_STAT_LPA_EEE_T1L 0x4000
 #define MDIO_PMA_PMD_BT1_CTRL_CFG_MST 0x4000
 #define MDIO_AN_EEE_ADV_100TX 0x0002
 #define MDIO_AN_EEE_ADV_1000T 0x0004
diff --git a/libc/kernel/uapi/linux/media-bus-format.h b/libc/kernel/uapi/linux/media-bus-format.h
index 87614cf..79d4cd5 100644
--- a/libc/kernel/uapi/linux/media-bus-format.h
+++ b/libc/kernel/uapi/linux/media-bus-format.h
@@ -30,8 +30,11 @@
 #define MEDIA_BUS_FMT_RGB565_2X8_BE 0x1007
 #define MEDIA_BUS_FMT_RGB565_2X8_LE 0x1008
 #define MEDIA_BUS_FMT_RGB666_1X18 0x1009
+#define MEDIA_BUS_FMT_BGR666_1X18 0x1023
 #define MEDIA_BUS_FMT_RBG888_1X24 0x100e
 #define MEDIA_BUS_FMT_RGB666_1X24_CPADHI 0x1015
+#define MEDIA_BUS_FMT_BGR666_1X24_CPADHI 0x1024
+#define MEDIA_BUS_FMT_RGB565_1X24_CPADHI 0x1022
 #define MEDIA_BUS_FMT_RGB666_1X7X3_SPWG 0x1010
 #define MEDIA_BUS_FMT_BGR888_1X24 0x1013
 #define MEDIA_BUS_FMT_BGR888_3X8 0x101b
diff --git a/libc/kernel/uapi/linux/membarrier.h b/libc/kernel/uapi/linux/membarrier.h
index 43c103b..94dd797 100644
--- a/libc/kernel/uapi/linux/membarrier.h
+++ b/libc/kernel/uapi/linux/membarrier.h
@@ -29,6 +29,7 @@
   MEMBARRIER_CMD_REGISTER_PRIVATE_EXPEDITED_SYNC_CORE = (1 << 6),
   MEMBARRIER_CMD_PRIVATE_EXPEDITED_RSEQ = (1 << 7),
   MEMBARRIER_CMD_REGISTER_PRIVATE_EXPEDITED_RSEQ = (1 << 8),
+  MEMBARRIER_CMD_GET_REGISTRATIONS = (1 << 9),
   MEMBARRIER_CMD_SHARED = MEMBARRIER_CMD_GLOBAL,
 };
 enum membarrier_cmd_flag {
diff --git a/libc/kernel/uapi/linux/memfd.h b/libc/kernel/uapi/linux/memfd.h
index 914c076..28228df 100644
--- a/libc/kernel/uapi/linux/memfd.h
+++ b/libc/kernel/uapi/linux/memfd.h
@@ -22,6 +22,8 @@
 #define MFD_CLOEXEC 0x0001U
 #define MFD_ALLOW_SEALING 0x0002U
 #define MFD_HUGETLB 0x0004U
+#define MFD_NOEXEC_SEAL 0x0008U
+#define MFD_EXEC 0x0010U
 #define MFD_HUGE_SHIFT HUGETLB_FLAG_ENCODE_SHIFT
 #define MFD_HUGE_MASK HUGETLB_FLAG_ENCODE_MASK
 #define MFD_HUGE_64KB HUGETLB_FLAG_ENCODE_64KB
diff --git a/libc/kernel/uapi/linux/meye.h b/libc/kernel/uapi/linux/meye.h
deleted file mode 100644
index a1112c4..0000000
--- a/libc/kernel/uapi/linux/meye.h
+++ /dev/null
@@ -1,38 +0,0 @@
-/****************************************************************************
- ****************************************************************************
- ***
- ***   This header was automatically generated from a Linux kernel header
- ***   of the same name, to make information necessary for userspace to
- ***   call into the kernel available to libc.  It contains only constants,
- ***   structures, and macros generated from the original header, and thus,
- ***   contains no copyrightable information.
- ***
- ***   To edit the content of this header, modify the corresponding
- ***   source file (e.g. under external/kernel-headers/original/) then
- ***   run bionic/libc/kernel/tools/update_all.py
- ***
- ***   Any manual change here will be lost the next time this script will
- ***   be run. You've been warned!
- ***
- ****************************************************************************
- ****************************************************************************/
-#ifndef _MEYE_H_
-#define _MEYE_H_
-struct meye_params {
-  unsigned char subsample;
-  unsigned char quality;
-  unsigned char sharpness;
-  unsigned char agc;
-  unsigned char picture;
-  unsigned char framerate;
-};
-#define MEYEIOC_G_PARAMS _IOR('v', BASE_VIDIOC_PRIVATE + 0, struct meye_params)
-#define MEYEIOC_S_PARAMS _IOW('v', BASE_VIDIOC_PRIVATE + 1, struct meye_params)
-#define MEYEIOC_QBUF_CAPT _IOW('v', BASE_VIDIOC_PRIVATE + 2, int)
-#define MEYEIOC_SYNC _IOWR('v', BASE_VIDIOC_PRIVATE + 3, int)
-#define MEYEIOC_STILLCAPT _IO('v', BASE_VIDIOC_PRIVATE + 4)
-#define MEYEIOC_STILLJCAPT _IOR('v', BASE_VIDIOC_PRIVATE + 5, int)
-#define V4L2_CID_MEYE_AGC (V4L2_CID_USER_MEYE_BASE + 0)
-#define V4L2_CID_MEYE_PICTURE (V4L2_CID_USER_MEYE_BASE + 1)
-#define V4L2_CID_MEYE_FRAMERATE (V4L2_CID_USER_MEYE_BASE + 2)
-#endif
diff --git a/libc/kernel/uapi/linux/netdev.h b/libc/kernel/uapi/linux/netdev.h
new file mode 100644
index 0000000..53a237b
--- /dev/null
+++ b/libc/kernel/uapi/linux/netdev.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_NETDEV_H
+#define _UAPI_LINUX_NETDEV_H
+#define NETDEV_FAMILY_NAME "netdev"
+#define NETDEV_FAMILY_VERSION 1
+enum netdev_xdp_act {
+  NETDEV_XDP_ACT_BASIC = 1,
+  NETDEV_XDP_ACT_REDIRECT = 2,
+  NETDEV_XDP_ACT_NDO_XMIT = 4,
+  NETDEV_XDP_ACT_XSK_ZEROCOPY = 8,
+  NETDEV_XDP_ACT_HW_OFFLOAD = 16,
+  NETDEV_XDP_ACT_RX_SG = 32,
+  NETDEV_XDP_ACT_NDO_XMIT_SG = 64,
+  NETDEV_XDP_ACT_MASK = 127,
+};
+enum {
+  NETDEV_A_DEV_IFINDEX = 1,
+  NETDEV_A_DEV_PAD,
+  NETDEV_A_DEV_XDP_FEATURES,
+  __NETDEV_A_DEV_MAX,
+  NETDEV_A_DEV_MAX = (__NETDEV_A_DEV_MAX - 1)
+};
+enum {
+  NETDEV_CMD_DEV_GET = 1,
+  NETDEV_CMD_DEV_ADD_NTF,
+  NETDEV_CMD_DEV_DEL_NTF,
+  NETDEV_CMD_DEV_CHANGE_NTF,
+  __NETDEV_CMD_MAX,
+  NETDEV_CMD_MAX = (__NETDEV_CMD_MAX - 1)
+};
+#define NETDEV_MCGRP_MGMT "mgmt"
+#endif
diff --git a/libc/kernel/uapi/linux/netfilter/nf_tables.h b/libc/kernel/uapi/linux/netfilter/nf_tables.h
index f07d7c7..33bfb7f 100644
--- a/libc/kernel/uapi/linux/netfilter/nf_tables.h
+++ b/libc/kernel/uapi/linux/netfilter/nf_tables.h
@@ -87,6 +87,13 @@
   NFT_MSG_GETFLOWTABLE,
   NFT_MSG_DELFLOWTABLE,
   NFT_MSG_GETRULE_RESET,
+  NFT_MSG_DESTROYTABLE,
+  NFT_MSG_DESTROYCHAIN,
+  NFT_MSG_DESTROYRULE,
+  NFT_MSG_DESTROYSET,
+  NFT_MSG_DESTROYSETELEM,
+  NFT_MSG_DESTROYOBJ,
+  NFT_MSG_DESTROYFLOWTABLE,
   NFT_MSG_MAX,
 };
 enum nft_list_attributes {
diff --git a/libc/kernel/uapi/linux/nl80211.h b/libc/kernel/uapi/linux/nl80211.h
index 83fe597..d73922a 100644
--- a/libc/kernel/uapi/linux/nl80211.h
+++ b/libc/kernel/uapi/linux/nl80211.h
@@ -528,6 +528,7 @@
   NL80211_ATTR_TX_HW_TIMESTAMP,
   NL80211_ATTR_RX_HW_TIMESTAMP,
   NL80211_ATTR_TD_BITMAP,
+  NL80211_ATTR_PUNCT_BITMAP,
   __NL80211_ATTR_AFTER_LAST,
   NUM_NL80211_ATTR = __NL80211_ATTR_AFTER_LAST,
   NL80211_ATTR_MAX = __NL80211_ATTR_AFTER_LAST - 1
@@ -1396,6 +1397,7 @@
 #define NL80211_KEK_LEN 16
 #define NL80211_KCK_EXT_LEN 24
 #define NL80211_KEK_EXT_LEN 32
+#define NL80211_KCK_EXT_LEN_32 32
 #define NL80211_REPLAY_CTR_LEN 8
 enum nl80211_rekey_data {
   __NL80211_REKEY_DATA_INVALID,
@@ -1533,6 +1535,8 @@
   NL80211_EXT_FEATURE_FILS_CRYPTO_OFFLOAD,
   NL80211_EXT_FEATURE_RADAR_BACKGROUND,
   NL80211_EXT_FEATURE_POWERED_ADDR_CHANGE,
+  NL80211_EXT_FEATURE_PUNCT,
+  NL80211_EXT_FEATURE_SECURE_NAN,
   NUM_NL80211_EXT_FEATURES,
   MAX_NL80211_EXT_FEATURES = NUM_NL80211_EXT_FEATURES - 1
 };
diff --git a/libc/kernel/uapi/linux/pci_regs.h b/libc/kernel/uapi/linux/pci_regs.h
index f932c18..44b0613 100644
--- a/libc/kernel/uapi/linux/pci_regs.h
+++ b/libc/kernel/uapi/linux/pci_regs.h
@@ -594,6 +594,7 @@
 #define PCI_EXP_LNKCTL2_TX_MARGIN 0x0380
 #define PCI_EXP_LNKCTL2_HASD 0x0020
 #define PCI_EXP_LNKSTA2 0x32
+#define PCI_EXP_LNKSTA2_FLIT 0x0400
 #define PCI_CAP_EXP_ENDPOINT_SIZEOF_V2 0x32
 #define PCI_EXP_SLTCAP2 0x34
 #define PCI_EXP_SLTCAP2_IBPD 0x00000001
diff --git a/libc/kernel/uapi/linux/perf_event.h b/libc/kernel/uapi/linux/perf_event.h
index 8f081ed..9223bd7 100644
--- a/libc/kernel/uapi/linux/perf_event.h
+++ b/libc/kernel/uapi/linux/perf_event.h
@@ -237,6 +237,7 @@
 #define PERF_ATTR_SIZE_VER5 112
 #define PERF_ATTR_SIZE_VER6 120
 #define PERF_ATTR_SIZE_VER7 128
+#define PERF_ATTR_SIZE_VER8 136
 struct perf_event_attr {
   __u32 type;
   __u32 size;
@@ -276,6 +277,7 @@
   __u32 aux_sample_size;
   __u32 __reserved_3;
   __u64 sig_data;
+  __u64 config3;
 };
 struct perf_event_query_bpf {
   __u32 ids_len;
diff --git a/libc/kernel/uapi/linux/prctl.h b/libc/kernel/uapi/linux/prctl.h
index 1dac726..6ad1c04 100644
--- a/libc/kernel/uapi/linux/prctl.h
+++ b/libc/kernel/uapi/linux/prctl.h
@@ -184,6 +184,9 @@
 #define PR_SME_GET_VL 64
 #define PR_SME_VL_LEN_MASK 0xffff
 #define PR_SME_VL_INHERIT (1 << 17)
+#define PR_SET_MDWE 65
+#define PR_MDWE_REFUSE_EXEC_GAIN 1
+#define PR_GET_MDWE 66
 #define PR_SET_VMA 0x53564d41
 #define PR_SET_VMA_ANON_NAME 0
 #endif
diff --git a/libc/kernel/uapi/linux/rpl.h b/libc/kernel/uapi/linux/rpl.h
index 3648bfc..4226297 100644
--- a/libc/kernel/uapi/linux/rpl.h
+++ b/libc/kernel/uapi/linux/rpl.h
@@ -34,8 +34,8 @@
 #error "Please fix <asm/byteorder.h>"
 #endif
   union {
-    struct in6_addr addr[0];
-    __u8 data[0];
+    __DECLARE_FLEX_ARRAY(struct in6_addr, addr);
+    __DECLARE_FLEX_ARRAY(__u8, data);
   } segments;
 } __attribute__((packed));
 #define rpl_segaddr segments.addr
diff --git a/libc/kernel/uapi/linux/rseq.h b/libc/kernel/uapi/linux/rseq.h
index 29a9457..f837720 100644
--- a/libc/kernel/uapi/linux/rseq.h
+++ b/libc/kernel/uapi/linux/rseq.h
@@ -49,5 +49,8 @@
   __u32 cpu_id;
   __u64 rseq_cs;
   __u32 flags;
+  __u32 node_id;
+  __u32 mm_cid;
+  char end[];
 } __attribute__((aligned(4 * sizeof(__u64))));
 #endif
diff --git a/libc/kernel/uapi/linux/rtnetlink.h b/libc/kernel/uapi/linux/rtnetlink.h
index 7201827..335a19a 100644
--- a/libc/kernel/uapi/linux/rtnetlink.h
+++ b/libc/kernel/uapi/linux/rtnetlink.h
@@ -463,6 +463,7 @@
   TCA_INGRESS_BLOCK,
   TCA_EGRESS_BLOCK,
   TCA_DUMP_FLAGS,
+  TCA_EXT_WARN_MSG,
   __TCA_MAX
 };
 #define TCA_MAX (__TCA_MAX - 1)
@@ -589,6 +590,7 @@
   TCA_ROOT_FLAGS,
   TCA_ROOT_COUNT,
   TCA_ROOT_TIME_DELTA,
+  TCA_ROOT_EXT_WARN_MSG,
   __TCA_ROOT_MAX,
 #define TCA_ROOT_MAX (__TCA_ROOT_MAX - 1)
 };
diff --git a/libc/kernel/uapi/linux/sed-opal.h b/libc/kernel/uapi/linux/sed-opal.h
index 4c66231..4685bb3 100644
--- a/libc/kernel/uapi/linux/sed-opal.h
+++ b/libc/kernel/uapi/linux/sed-opal.h
@@ -122,6 +122,7 @@
 #define OPAL_FL_LOCKED 0x00000008
 #define OPAL_FL_MBR_ENABLED 0x00000010
 #define OPAL_FL_MBR_DONE 0x00000020
+#define OPAL_FL_SUM_SUPPORTED 0x00000040
 struct opal_status {
   __u32 flags;
   __u32 reserved;
diff --git a/libc/kernel/uapi/linux/serial_core.h b/libc/kernel/uapi/linux/serial_core.h
index 1e04429..ecd395c 100644
--- a/libc/kernel/uapi/linux/serial_core.h
+++ b/libc/kernel/uapi/linux/serial_core.h
@@ -99,6 +99,7 @@
 #define PORT_VT8500 97
 #define PORT_XUARTPS 98
 #define PORT_AR933X 99
+#define PORT_MCHP16550A 100
 #define PORT_ARC 101
 #define PORT_RP2 102
 #define PORT_LPUART 103
diff --git a/libc/kernel/uapi/linux/serial_reg.h b/libc/kernel/uapi/linux/serial_reg.h
index e41e649..36d778d 100644
--- a/libc/kernel/uapi/linux/serial_reg.h
+++ b/libc/kernel/uapi/linux/serial_reg.h
@@ -37,6 +37,11 @@
 #define UART_IIR_RX_TIMEOUT 0x0c
 #define UART_IIR_XOFF 0x10
 #define UART_IIR_CTS_RTS_DSR 0x20
+#define UART_IIR_64BYTE_FIFO 0x20
+#define UART_IIR_FIFO_ENABLED 0xc0
+#define UART_IIR_FIFO_ENABLED_8250 0x00
+#define UART_IIR_FIFO_ENABLED_16550 0x80
+#define UART_IIR_FIFO_ENABLED_16550A 0xc0
 #define UART_FCR 2
 #define UART_FCR_ENABLE_FIFO 0x01
 #define UART_FCR_CLEAR_RCVR 0x02
diff --git a/libc/kernel/uapi/linux/snmp.h b/libc/kernel/uapi/linux/snmp.h
index e3d6ee3..ea3f058 100644
--- a/libc/kernel/uapi/linux/snmp.h
+++ b/libc/kernel/uapi/linux/snmp.h
@@ -87,6 +87,8 @@
   ICMP_MIB_OUTADDRMASKS,
   ICMP_MIB_OUTADDRMASKREPS,
   ICMP_MIB_CSUMERRORS,
+  ICMP_MIB_RATELIMITGLOBAL,
+  ICMP_MIB_RATELIMITHOST,
   __ICMP_MIB_MAX
 };
 #define __ICMPMSG_MIB_MAX 512
@@ -97,6 +99,7 @@
   ICMP6_MIB_OUTMSGS,
   ICMP6_MIB_OUTERRORS,
   ICMP6_MIB_CSUMERRORS,
+  ICMP6_MIB_RATELIMITHOST,
   __ICMP6_MIB_MAX
 };
 #define __ICMP6MSG_MIB_MAX 512
diff --git a/libc/kernel/uapi/linux/ublk_cmd.h b/libc/kernel/uapi/linux/ublk_cmd.h
index 8c9cbeb..6e0a9f8 100644
--- a/libc/kernel/uapi/linux/ublk_cmd.h
+++ b/libc/kernel/uapi/linux/ublk_cmd.h
@@ -29,6 +29,7 @@
 #define UBLK_CMD_GET_PARAMS 0x09
 #define UBLK_CMD_START_USER_RECOVERY 0x10
 #define UBLK_CMD_END_USER_RECOVERY 0x11
+#define UBLK_CMD_GET_DEV_INFO2 0x12
 #define UBLK_IO_FETCH_REQ 0x20
 #define UBLK_IO_COMMIT_AND_FETCH_REQ 0x21
 #define UBLK_IO_NEED_GET_DATA 0x22
@@ -43,6 +44,7 @@
 #define UBLK_F_NEED_GET_DATA (1UL << 2)
 #define UBLK_F_USER_RECOVERY (1UL << 3)
 #define UBLK_F_USER_RECOVERY_REISSUE (1UL << 4)
+#define UBLK_F_UNPRIVILEGED_DEV (1UL << 5)
 #define UBLK_S_DEV_DEAD 0
 #define UBLK_S_DEV_LIVE 1
 #define UBLK_S_DEV_QUIESCED 2
@@ -51,7 +53,10 @@
   __u16 queue_id;
   __u16 len;
   __u64 addr;
-  __u64 data[2];
+  __u64 data[1];
+  __u16 dev_path_len;
+  __u16 pad;
+  __u32 reserved;
 };
 struct ublksrv_ctrl_dev_info {
   __u16 nr_hw_queues;
@@ -64,7 +69,8 @@
   __u32 pad1;
   __u64 flags;
   __u64 ublksrv_flags;
-  __u64 reserved0;
+  __u32 owner_uid;
+  __u32 owner_gid;
   __u64 reserved1;
   __u64 reserved2;
 };
@@ -116,12 +122,20 @@
   __u16 max_discard_segments;
   __u16 reserved0;
 };
+struct ublk_param_devt {
+  __u32 char_major;
+  __u32 char_minor;
+  __u32 disk_major;
+  __u32 disk_minor;
+};
 struct ublk_params {
   __u32 len;
 #define UBLK_PARAM_TYPE_BASIC (1 << 0)
 #define UBLK_PARAM_TYPE_DISCARD (1 << 1)
+#define UBLK_PARAM_TYPE_DEVT (1 << 2)
   __u32 types;
   struct ublk_param_basic basic;
   struct ublk_param_discard discard;
+  struct ublk_param_devt devt;
 };
 #endif
diff --git a/libc/kernel/uapi/linux/usb/ch9.h b/libc/kernel/uapi/linux/usb/ch9.h
index 49eb5fa..9ddc640 100644
--- a/libc/kernel/uapi/linux/usb/ch9.h
+++ b/libc/kernel/uapi/linux/usb/ch9.h
@@ -417,6 +417,16 @@
   __u8 ContainerID[16];
 } __attribute__((packed));
 #define USB_DT_USB_SS_CONTN_ID_SIZE 20
+#define USB_PLAT_DEV_CAP_TYPE 5
+struct usb_plat_dev_cap_descriptor {
+  __u8 bLength;
+  __u8 bDescriptorType;
+  __u8 bDevCapabilityType;
+  __u8 bReserved;
+  __u8 UUID[16];
+  __u8 CapabilityData[];
+} __attribute__((packed));
+#define USB_DT_USB_PLAT_DEV_CAP_SIZE(capability_data_size) (20 + capability_data_size)
 #define USB_SSP_CAP_TYPE 0xa
 struct usb_ssp_cap_descriptor {
   __u8 bLength;
diff --git a/libc/kernel/uapi/linux/usb/video.h b/libc/kernel/uapi/linux/usb/video.h
index c3d360a..0ceabe7 100644
--- a/libc/kernel/uapi/linux/usb/video.h
+++ b/libc/kernel/uapi/linux/usb/video.h
@@ -139,6 +139,32 @@
 #define UVC_CONTROL_CAP_DISABLED (1 << 2)
 #define UVC_CONTROL_CAP_AUTOUPDATE (1 << 3)
 #define UVC_CONTROL_CAP_ASYNCHRONOUS (1 << 4)
+enum uvc_color_primaries_values {
+  UVC_COLOR_PRIMARIES_UNSPECIFIED,
+  UVC_COLOR_PRIMARIES_BT_709_SRGB,
+  UVC_COLOR_PRIMARIES_BT_470_2_M,
+  UVC_COLOR_PRIMARIES_BT_470_2_B_G,
+  UVC_COLOR_PRIMARIES_SMPTE_170M,
+  UVC_COLOR_PRIMARIES_SMPTE_240M,
+};
+enum uvc_transfer_characteristics_values {
+  UVC_TRANSFER_CHARACTERISTICS_UNSPECIFIED,
+  UVC_TRANSFER_CHARACTERISTICS_BT_709,
+  UVC_TRANSFER_CHARACTERISTICS_BT_470_2_M,
+  UVC_TRANSFER_CHARACTERISTICS_BT_470_2_B_G,
+  UVC_TRANSFER_CHARACTERISTICS_SMPTE_170M,
+  UVC_TRANSFER_CHARACTERISTICS_SMPTE_240M,
+  UVC_TRANSFER_CHARACTERISTICS_LINEAR,
+  UVC_TRANSFER_CHARACTERISTICS_SRGB,
+};
+enum uvc_matrix_coefficients {
+  UVC_MATRIX_COEFFICIENTS_UNSPECIFIED,
+  UVC_MATRIX_COEFFICIENTS_BT_709,
+  UVC_MATRIX_COEFFICIENTS_FCC,
+  UVC_MATRIX_COEFFICIENTS_BT_470_2_B_G,
+  UVC_MATRIX_COEFFICIENTS_SMPTE_170M,
+  UVC_MATRIX_COEFFICIENTS_SMPTE_240M,
+};
 struct uvc_descriptor_header {
   __u8 bLength;
   __u8 bDescriptorType;
diff --git a/libc/kernel/uapi/linux/uuid.h b/libc/kernel/uapi/linux/uuid.h
index d0f82c1..1505137 100644
--- a/libc/kernel/uapi/linux/uuid.h
+++ b/libc/kernel/uapi/linux/uuid.h
@@ -21,11 +21,9 @@
 #include <linux/types.h>
 typedef struct {
   __u8 b[16];
-} guid_t;
-#define GUID_INIT(a,b,c,d0,d1,d2,d3,d4,d5,d6,d7) \
-((guid_t) \
+} uuid_le;
+#define UUID_LE(a,b,c,d0,d1,d2,d3,d4,d5,d6,d7) \
+((uuid_le) \
 { { (a) & 0xff, ((a) >> 8) & 0xff, ((a) >> 16) & 0xff, ((a) >> 24) & 0xff, (b) & 0xff, ((b) >> 8) & 0xff, (c) & 0xff, ((c) >> 8) & 0xff, (d0), (d1), (d2), (d3), (d4), (d5), (d6), (d7) } })
-typedef guid_t uuid_le;
-#define UUID_LE(a,b,c,d0,d1,d2,d3,d4,d5,d6,d7) GUID_INIT(a, b, c, d0, d1, d2, d3, d4, d5, d6, d7)
 #define NULL_UUID_LE UUID_LE(0x00000000, 0x0000, 0x0000, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00)
 #endif
diff --git a/libc/kernel/uapi/linux/uvcvideo.h b/libc/kernel/uapi/linux/uvcvideo.h
index f15ed78..b63858f 100644
--- a/libc/kernel/uapi/linux/uvcvideo.h
+++ b/libc/kernel/uapi/linux/uvcvideo.h
@@ -36,9 +36,10 @@
 #define UVC_CTRL_FLAG_AUTO_UPDATE (1 << 7)
 #define UVC_CTRL_FLAG_ASYNCHRONOUS (1 << 8)
 #define UVC_CTRL_FLAG_GET_RANGE (UVC_CTRL_FLAG_GET_CUR | UVC_CTRL_FLAG_GET_MIN | UVC_CTRL_FLAG_GET_MAX | UVC_CTRL_FLAG_GET_RES | UVC_CTRL_FLAG_GET_DEF)
+#define UVC_MENU_NAME_LEN 32
 struct uvc_menu_info {
   __u32 value;
-  __u8 name[32];
+  __u8 name[UVC_MENU_NAME_LEN];
 };
 struct uvc_xu_control_mapping {
   __u32 id;
diff --git a/libc/kernel/uapi/linux/v4l2-subdev.h b/libc/kernel/uapi/linux/v4l2-subdev.h
index 2954dc3..8b2c1bd 100644
--- a/libc/kernel/uapi/linux/v4l2-subdev.h
+++ b/libc/kernel/uapi/linux/v4l2-subdev.h
@@ -18,6 +18,7 @@
  ****************************************************************************/
 #ifndef __LINUX_V4L2_SUBDEV_H
 #define __LINUX_V4L2_SUBDEV_H
+#include <linux/const.h>
 #include <linux/ioctl.h>
 #include <linux/types.h>
 #include <linux/v4l2-common.h>
@@ -30,13 +31,15 @@
   __u32 which;
   __u32 pad;
   struct v4l2_mbus_framefmt format;
-  __u32 reserved[8];
+  __u32 stream;
+  __u32 reserved[7];
 };
 struct v4l2_subdev_crop {
   __u32 which;
   __u32 pad;
   struct v4l2_rect rect;
-  __u32 reserved[8];
+  __u32 stream;
+  __u32 reserved[7];
 };
 #define V4L2_SUBDEV_MBUS_CODE_CSC_COLORSPACE 0x00000001
 #define V4L2_SUBDEV_MBUS_CODE_CSC_XFER_FUNC 0x00000002
@@ -49,7 +52,8 @@
   __u32 code;
   __u32 which;
   __u32 flags;
-  __u32 reserved[7];
+  __u32 stream;
+  __u32 reserved[6];
 };
 struct v4l2_subdev_frame_size_enum {
   __u32 index;
@@ -60,12 +64,14 @@
   __u32 min_height;
   __u32 max_height;
   __u32 which;
-  __u32 reserved[8];
+  __u32 stream;
+  __u32 reserved[7];
 };
 struct v4l2_subdev_frame_interval {
   __u32 pad;
   struct v4l2_fract interval;
-  __u32 reserved[9];
+  __u32 stream;
+  __u32 reserved[8];
 };
 struct v4l2_subdev_frame_interval_enum {
   __u32 index;
@@ -75,7 +81,8 @@
   __u32 height;
   struct v4l2_fract interval;
   __u32 which;
-  __u32 reserved[8];
+  __u32 stream;
+  __u32 reserved[7];
 };
 struct v4l2_subdev_selection {
   __u32 which;
@@ -83,7 +90,8 @@
   __u32 target;
   __u32 flags;
   struct v4l2_rect r;
-  __u32 reserved[8];
+  __u32 stream;
+  __u32 reserved[7];
 };
 struct v4l2_subdev_capability {
   __u32 version;
@@ -91,6 +99,22 @@
   __u32 reserved[14];
 };
 #define V4L2_SUBDEV_CAP_RO_SUBDEV 0x00000001
+#define V4L2_SUBDEV_CAP_STREAMS 0x00000002
+#define V4L2_SUBDEV_ROUTE_FL_ACTIVE (1U << 0)
+struct v4l2_subdev_route {
+  __u32 sink_pad;
+  __u32 sink_stream;
+  __u32 source_pad;
+  __u32 source_stream;
+  __u32 flags;
+  __u32 reserved[5];
+};
+struct v4l2_subdev_routing {
+  __u32 which;
+  __u32 num_routes;
+  __u64 routes;
+  __u32 reserved[6];
+};
 #define v4l2_subdev_edid v4l2_edid
 #define VIDIOC_SUBDEV_QUERYCAP _IOR('V', 0, struct v4l2_subdev_capability)
 #define VIDIOC_SUBDEV_G_FMT _IOWR('V', 4, struct v4l2_subdev_format)
@@ -104,6 +128,8 @@
 #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)
+#define VIDIOC_SUBDEV_G_ROUTING _IOWR('V', 38, struct v4l2_subdev_routing)
+#define VIDIOC_SUBDEV_S_ROUTING _IOWR('V', 39, struct v4l2_subdev_routing)
 #define VIDIOC_SUBDEV_G_STD _IOR('V', 23, v4l2_std_id)
 #define VIDIOC_SUBDEV_S_STD _IOW('V', 24, v4l2_std_id)
 #define VIDIOC_SUBDEV_ENUMSTD _IOWR('V', 25, struct v4l2_standard)
diff --git a/libc/kernel/uapi/linux/version.h b/libc/kernel/uapi/linux/version.h
index 0d50613..9d48e3d 100644
--- a/libc/kernel/uapi/linux/version.h
+++ b/libc/kernel/uapi/linux/version.h
@@ -16,8 +16,8 @@
  ***
  ****************************************************************************
  ****************************************************************************/
-#define LINUX_VERSION_CODE 393728
+#define LINUX_VERSION_CODE 393984
 #define KERNEL_VERSION(a,b,c) (((a) << 16) + ((b) << 8) + ((c) > 255 ? 255 : (c)))
 #define LINUX_VERSION_MAJOR 6
-#define LINUX_VERSION_PATCHLEVEL 2
+#define LINUX_VERSION_PATCHLEVEL 3
 #define LINUX_VERSION_SUBLEVEL 0
diff --git a/libc/kernel/uapi/linux/vhost.h b/libc/kernel/uapi/linux/vhost.h
index e5b1327..5138f0c 100644
--- a/libc/kernel/uapi/linux/vhost.h
+++ b/libc/kernel/uapi/linux/vhost.h
@@ -69,4 +69,5 @@
 #define VHOST_VDPA_GET_VRING_GROUP _IOWR(VHOST_VIRTIO, 0x7B, struct vhost_vring_state)
 #define VHOST_VDPA_SET_GROUP_ASID _IOW(VHOST_VIRTIO, 0x7C, struct vhost_vring_state)
 #define VHOST_VDPA_SUSPEND _IO(VHOST_VIRTIO, 0x7D)
+#define VHOST_VDPA_RESUME _IO(VHOST_VIRTIO, 0x7E)
 #endif
diff --git a/libc/kernel/uapi/linux/vhost_types.h b/libc/kernel/uapi/linux/vhost_types.h
index 32efa85..1669c28 100644
--- a/libc/kernel/uapi/linux/vhost_types.h
+++ b/libc/kernel/uapi/linux/vhost_types.h
@@ -106,4 +106,5 @@
 #define VHOST_BACKEND_F_IOTLB_BATCH 0x2
 #define VHOST_BACKEND_F_IOTLB_ASID 0x3
 #define VHOST_BACKEND_F_SUSPEND 0x4
+#define VHOST_BACKEND_F_RESUME 0x5
 #endif
diff --git a/libc/kernel/uapi/linux/videodev2.h b/libc/kernel/uapi/linux/videodev2.h
index 4fb0a25..95c2d94 100644
--- a/libc/kernel/uapi/linux/videodev2.h
+++ b/libc/kernel/uapi/linux/videodev2.h
@@ -244,6 +244,9 @@
 #define V4L2_PIX_FMT_RGBX32 v4l2_fourcc('X', 'B', '2', '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_RGBX1010102 v4l2_fourcc('R', 'X', '3', '0')
+#define V4L2_PIX_FMT_RGBA1010102 v4l2_fourcc('R', 'A', '3', '0')
+#define V4L2_PIX_FMT_ARGB2101010 v4l2_fourcc('A', 'R', '3', '0')
 #define V4L2_PIX_FMT_GREY v4l2_fourcc('G', 'R', 'E', 'Y')
 #define V4L2_PIX_FMT_Y4 v4l2_fourcc('Y', '0', '4', ' ')
 #define V4L2_PIX_FMT_Y6 v4l2_fourcc('Y', '0', '6', ' ')
@@ -275,6 +278,9 @@
 #define V4L2_PIX_FMT_YUVA32 v4l2_fourcc('Y', 'U', 'V', 'A')
 #define V4L2_PIX_FMT_YUVX32 v4l2_fourcc('Y', 'U', 'V', 'X')
 #define V4L2_PIX_FMT_M420 v4l2_fourcc('M', '4', '2', '0')
+#define V4L2_PIX_FMT_Y210 v4l2_fourcc('Y', '2', '1', '0')
+#define V4L2_PIX_FMT_Y212 v4l2_fourcc('Y', '2', '1', '2')
+#define V4L2_PIX_FMT_Y216 v4l2_fourcc('Y', '2', '1', '6')
 #define V4L2_PIX_FMT_NV12 v4l2_fourcc('N', 'V', '1', '2')
 #define V4L2_PIX_FMT_NV21 v4l2_fourcc('N', 'V', '2', '1')
 #define V4L2_PIX_FMT_NV16 v4l2_fourcc('N', 'V', '1', '6')
diff --git a/libc/kernel/uapi/linux/virtio_blk.h b/libc/kernel/uapi/linux/virtio_blk.h
index 0dd08c5..1b7c7e9 100644
--- a/libc/kernel/uapi/linux/virtio_blk.h
+++ b/libc/kernel/uapi/linux/virtio_blk.h
@@ -32,6 +32,7 @@
 #define VIRTIO_BLK_F_DISCARD 13
 #define VIRTIO_BLK_F_WRITE_ZEROES 14
 #define VIRTIO_BLK_F_SECURE_ERASE 16
+#define VIRTIO_BLK_F_ZONED 17
 #ifndef VIRTIO_BLK_NO_LEGACY
 #define VIRTIO_BLK_F_BARRIER 0
 #define VIRTIO_BLK_F_SCSI 7
@@ -67,6 +68,15 @@
   __virtio32 max_secure_erase_sectors;
   __virtio32 max_secure_erase_seg;
   __virtio32 secure_erase_sector_alignment;
+  struct virtio_blk_zoned_characteristics {
+    __virtio32 zone_sectors;
+    __virtio32 max_open_zones;
+    __virtio32 max_active_zones;
+    __virtio32 max_append_sectors;
+    __virtio32 write_granularity;
+    __u8 model;
+    __u8 unused2[3];
+  } zoned;
 } __attribute__((packed));
 #define VIRTIO_BLK_T_IN 0
 #define VIRTIO_BLK_T_OUT 1
@@ -78,6 +88,13 @@
 #define VIRTIO_BLK_T_DISCARD 11
 #define VIRTIO_BLK_T_WRITE_ZEROES 13
 #define VIRTIO_BLK_T_SECURE_ERASE 14
+#define VIRTIO_BLK_T_ZONE_APPEND 15
+#define VIRTIO_BLK_T_ZONE_REPORT 16
+#define VIRTIO_BLK_T_ZONE_OPEN 18
+#define VIRTIO_BLK_T_ZONE_CLOSE 20
+#define VIRTIO_BLK_T_ZONE_FINISH 22
+#define VIRTIO_BLK_T_ZONE_RESET 24
+#define VIRTIO_BLK_T_ZONE_RESET_ALL 26
 #ifndef VIRTIO_BLK_NO_LEGACY
 #define VIRTIO_BLK_T_BARRIER 0x80000000
 #endif
@@ -86,6 +103,33 @@
   __virtio32 ioprio;
   __virtio64 sector;
 };
+#define VIRTIO_BLK_Z_NONE 0
+#define VIRTIO_BLK_Z_HM 1
+#define VIRTIO_BLK_Z_HA 2
+struct virtio_blk_zone_descriptor {
+  __virtio64 z_cap;
+  __virtio64 z_start;
+  __virtio64 z_wp;
+  __u8 z_type;
+  __u8 z_state;
+  __u8 reserved[38];
+};
+struct virtio_blk_zone_report {
+  __virtio64 nr_zones;
+  __u8 reserved[56];
+  struct virtio_blk_zone_descriptor zones[];
+};
+#define VIRTIO_BLK_ZT_CONV 1
+#define VIRTIO_BLK_ZT_SWR 2
+#define VIRTIO_BLK_ZT_SWP 3
+#define VIRTIO_BLK_ZS_NOT_WP 0
+#define VIRTIO_BLK_ZS_EMPTY 1
+#define VIRTIO_BLK_ZS_IOPEN 2
+#define VIRTIO_BLK_ZS_EOPEN 3
+#define VIRTIO_BLK_ZS_CLOSED 4
+#define VIRTIO_BLK_ZS_RDONLY 13
+#define VIRTIO_BLK_ZS_FULL 14
+#define VIRTIO_BLK_ZS_OFFLINE 15
 #define VIRTIO_BLK_WRITE_ZEROES_FLAG_UNMAP 0x00000001
 struct virtio_blk_discard_write_zeroes {
   __le64 sector;
@@ -103,4 +147,8 @@
 #define VIRTIO_BLK_S_OK 0
 #define VIRTIO_BLK_S_IOERR 1
 #define VIRTIO_BLK_S_UNSUPP 2
+#define VIRTIO_BLK_S_ZONE_INVALID_CMD 3
+#define VIRTIO_BLK_S_ZONE_UNALIGNED_WP 4
+#define VIRTIO_BLK_S_ZONE_OPEN_RESOURCE 5
+#define VIRTIO_BLK_S_ZONE_ACTIVE_RESOURCE 6
 #endif
diff --git a/libc/kernel/uapi/rdma/hns-abi.h b/libc/kernel/uapi/rdma/hns-abi.h
index 0407571..f778ef2 100644
--- a/libc/kernel/uapi/rdma/hns-abi.h
+++ b/libc/kernel/uapi/rdma/hns-abi.h
@@ -62,9 +62,13 @@
 };
 enum {
   HNS_ROCE_EXSGE_FLAGS = 1 << 0,
+  HNS_ROCE_RQ_INLINE_FLAGS = 1 << 1,
+  HNS_ROCE_CQE_INLINE_FLAGS = 1 << 2,
 };
 enum {
   HNS_ROCE_RSP_EXSGE_FLAGS = 1 << 0,
+  HNS_ROCE_RSP_RQ_INLINE_FLAGS = 1 << 1,
+  HNS_ROCE_RSP_CQE_INLINE_FLAGS = 1 << 2,
 };
 struct hns_roce_ib_alloc_ucontext_resp {
   __u32 qp_tab_size;
diff --git a/libc/kernel/uapi/scsi/scsi_bsg_fc.h b/libc/kernel/uapi/scsi/scsi_bsg_fc.h
index 2647249..3836282 100644
--- a/libc/kernel/uapi/scsi/scsi_bsg_fc.h
+++ b/libc/kernel/uapi/scsi/scsi_bsg_fc.h
@@ -69,7 +69,7 @@
   __u32 vendor_cmd[];
 };
 struct fc_bsg_host_vendor_reply {
-  __u32 vendor_rsp[0];
+  __DECLARE_FLEX_ARRAY(__u32, vendor_rsp);
 };
 struct fc_bsg_rport_els {
   __u8 els_code;
diff --git a/libc/kernel/uapi/scsi/scsi_bsg_mpi3mr.h b/libc/kernel/uapi/scsi/scsi_bsg_mpi3mr.h
index fcba8cd..48e88d3 100644
--- a/libc/kernel/uapi/scsi/scsi_bsg_mpi3mr.h
+++ b/libc/kernel/uapi/scsi/scsi_bsg_mpi3mr.h
@@ -220,9 +220,6 @@
     struct mpi3mr_bsg_mptcmd mptcmd;
   } cmd;
 };
-#ifndef MPI3_NVME_ENCAP_CMD_MAX
-#define MPI3_NVME_ENCAP_CMD_MAX (1)
-#endif
 struct mpi3_nvme_encapsulated_request {
   __le16 host_tag;
   __u8 ioc_use_only02;
@@ -236,7 +233,7 @@
   __le16 flags;
   __le32 data_length;
   __le32 reserved14[3];
-  __le32 command[MPI3_NVME_ENCAP_CMD_MAX];
+  __le32 command[];
 };
 struct mpi3_nvme_encapsulated_error_reply {
   __le16 host_tag;
diff --git a/libc/kernel/uapi/scsi/scsi_bsg_ufs.h b/libc/kernel/uapi/scsi/scsi_bsg_ufs.h
index ae5c757..036243e 100644
--- a/libc/kernel/uapi/scsi/scsi_bsg_ufs.h
+++ b/libc/kernel/uapi/scsi/scsi_bsg_ufs.h
@@ -20,8 +20,22 @@
 #define SCSI_BSG_UFS_H
 #include <linux/types.h>
 #define UFS_CDB_SIZE 16
-#define UPIU_TRANSACTION_UIC_CMD 0x1F
 #define UIC_CMD_SIZE (sizeof(__u32) * 4)
+enum ufs_bsg_msg_code {
+  UPIU_TRANSACTION_UIC_CMD = 0x1F,
+  UPIU_TRANSACTION_ARPMB_CMD,
+};
+enum ufs_rpmb_op_type {
+  UFS_RPMB_WRITE_KEY = 0x01,
+  UFS_RPMB_READ_CNT = 0x02,
+  UFS_RPMB_WRITE = 0x03,
+  UFS_RPMB_READ = 0x04,
+  UFS_RPMB_READ_RESP = 0x05,
+  UFS_RPMB_SEC_CONF_WRITE = 0x06,
+  UFS_RPMB_SEC_CONF_READ = 0x07,
+  UFS_RPMB_PURGE_ENABLE = 0x08,
+  UFS_RPMB_PURGE_STATUS_READ = 0x09,
+};
 struct utp_upiu_header {
   __be32 dword_0;
   __be32 dword_1;
@@ -49,13 +63,36 @@
     struct utp_upiu_query uc;
   };
 };
+struct ufs_arpmb_meta {
+  __be16 req_resp_type;
+  __u8 nonce[16];
+  __be32 write_counter;
+  __be16 addr_lun;
+  __be16 block_count;
+  __be16 result;
+} __attribute__((__packed__));
+struct ufs_ehs {
+  __u8 length;
+  __u8 ehs_type;
+  __be16 ehssub_type;
+  struct ufs_arpmb_meta meta;
+  __u8 mac_key[32];
+} __attribute__((__packed__));
 struct ufs_bsg_request {
   __u32 msgcode;
   struct utp_upiu_req upiu_req;
 };
 struct ufs_bsg_reply {
-  __u32 result;
+  int result;
   __u32 reply_payload_rcv_len;
   struct utp_upiu_req upiu_rsp;
 };
+struct ufs_rpmb_request {
+  struct ufs_bsg_request bsg_request;
+  struct ufs_ehs ehs_req;
+};
+struct ufs_rpmb_reply {
+  struct ufs_bsg_reply bsg_reply;
+  struct ufs_ehs ehs_rsp;
+};
 #endif
diff --git a/libc/kernel/uapi/sound/firewire.h b/libc/kernel/uapi/sound/firewire.h
index d26d722..cc13cb9 100644
--- a/libc/kernel/uapi/sound/firewire.h
+++ b/libc/kernel/uapi/sound/firewire.h
@@ -27,6 +27,7 @@
 #define SNDRV_FIREWIRE_EVENT_MOTU_NOTIFICATION 0x64776479
 #define SNDRV_FIREWIRE_EVENT_TASCAM_CONTROL 0x7473636d
 #define SNDRV_FIREWIRE_EVENT_MOTU_REGISTER_DSP_CHANGE 0x4d545244
+#define SNDRV_FIREWIRE_EVENT_FF400_MESSAGE 0x4f6c6761
 struct snd_firewire_event_common {
   unsigned int type;
 };
@@ -74,6 +75,14 @@
   __u32 count;
   __u32 changes[];
 };
+struct snd_firewire_event_ff400_message {
+  unsigned int type;
+  unsigned int message_count;
+  struct {
+    __u32 message;
+    __u32 tstamp;
+  } messages[];
+};
 union snd_firewire_event {
   struct snd_firewire_event_common common;
   struct snd_firewire_event_lock_status lock_status;
@@ -83,6 +92,7 @@
   struct snd_firewire_event_tascam_control tascam_control;
   struct snd_firewire_event_motu_notification motu_notification;
   struct snd_firewire_event_motu_register_dsp_change motu_register_dsp_change;
+  struct snd_firewire_event_ff400_message ff400_message;
 };
 #define SNDRV_FIREWIRE_IOCTL_GET_INFO _IOR('H', 0xf8, struct snd_firewire_get_info)
 #define SNDRV_FIREWIRE_IOCTL_LOCK _IO('H', 0xf9)
diff --git a/libc/kernel/uapi/sound/intel/avs/tokens.h b/libc/kernel/uapi/sound/intel/avs/tokens.h
index b6b3002..d524278 100644
--- a/libc/kernel/uapi/sound/intel/avs/tokens.h
+++ b/libc/kernel/uapi/sound/intel/avs/tokens.h
@@ -100,6 +100,7 @@
   AVS_TKN_MOD_CORE_ID_U8 = 1704,
   AVS_TKN_MOD_PROC_DOMAIN_U8 = 1705,
   AVS_TKN_MOD_MODCFG_EXT_ID_U32 = 1706,
+  AVS_TKN_MOD_KCONTROL_ID_U32 = 1707,
   AVS_TKN_PATH_TMPL_ID_U32 = 1801,
   AVS_TKN_PATH_ID_U32 = 1901,
   AVS_TKN_PATH_FE_FMT_ID_U32 = 1902,
@@ -107,5 +108,6 @@
   AVS_TKN_PIN_FMT_INDEX_U32 = 2201,
   AVS_TKN_PIN_FMT_IOBS_U32 = 2202,
   AVS_TKN_PIN_FMT_AFMT_ID_U32 = 2203,
+  AVS_TKN_KCONTROL_ID_U32 = 2301,
 };
 #endif
diff --git a/libc/libc.map.txt b/libc/libc.map.txt
index c75b13a..0102b30 100644
--- a/libc/libc.map.txt
+++ b/libc/libc.map.txt
@@ -1584,6 +1584,11 @@
     posix_spawn_file_actions_addfchdir_np;
 } LIBC_T;
 
+LIBC_V { # introduced=VanillaIceCream
+  global:
+    timespec_getres;
+} LIBC_U;
+
 LIBC_PRIVATE {
   global:
     __accept4; # arm x86
diff --git a/libc/bionic/timespec_get.cpp b/libc/private/bionic_asm_offsets.h
similarity index 86%
copy from libc/bionic/timespec_get.cpp
copy to libc/private/bionic_asm_offsets.h
index 7fc2182..c2f2b56 100644
--- a/libc/bionic/timespec_get.cpp
+++ b/libc/private/bionic_asm_offsets.h
@@ -1,5 +1,5 @@
 /*
- * Copyright (C) 2018 The Android Open Source Project
+ * Copyright (C) 2023 The Android Open Source Project
  * All rights reserved.
  *
  * Redistribution and use in source and binary forms, with or without
@@ -26,8 +26,8 @@
  * SUCH DAMAGE.
  */
 
-#include <time.h>
+#pragma once
 
-int timespec_get(timespec* ts, int base) {
-  return (base == TIME_UTC && clock_gettime(CLOCK_REALTIME, ts) != -1) ? base : 0;
-}
+#ifdef __aarch64__
+#define OFFSETOF_libc_globals_memtag_stack 80
+#endif
diff --git a/libc/private/bionic_globals.h b/libc/private/bionic_globals.h
index c375cc4..510d556 100644
--- a/libc/private/bionic_globals.h
+++ b/libc/private/bionic_globals.h
@@ -38,6 +38,7 @@
 
 #include "private/WriteProtected.h"
 #include "private/bionic_allocator.h"
+#include "private/bionic_asm_offsets.h"
 #include "private/bionic_elf_tls.h"
 #include "private/bionic_fdsan.h"
 #include "private/bionic_malloc_dispatch.h"
@@ -65,6 +66,10 @@
   MallocDispatch malloc_dispatch_table;
 };
 
+#ifdef __aarch64__
+static_assert(OFFSETOF_libc_globals_memtag_stack == offsetof(libc_globals, memtag_stack));
+#endif
+
 __LIBC_HIDDEN__ extern WriteProtected<libc_globals> __libc_globals;
 
 struct abort_msg_t;
diff --git a/libc/stdio/local.h b/libc/stdio/local.h
index 2fc12a0..a5eb636 100644
--- a/libc/stdio/local.h
+++ b/libc/stdio/local.h
@@ -290,17 +290,21 @@
 
 #define WCIO_GET(fp) (_EXT(fp) ? &(_EXT(fp)->_wcio) : (struct wchar_io_data*)0)
 
-#define _SET_ORIENTATION(fp, mode)                                 \
-  do {                                                             \
-    struct wchar_io_data* _wcio = WCIO_GET(fp);                    \
-    if (_wcio && _wcio->wcio_mode == 0) _wcio->wcio_mode = (mode); \
+#define ORIENT_BYTES (-1)
+#define ORIENT_UNKNOWN 0
+#define ORIENT_CHARS 1
+
+#define _SET_ORIENTATION(fp, mode)                                              \
+  do {                                                                          \
+    struct wchar_io_data* _wcio = WCIO_GET(fp);                                 \
+    if (_wcio && _wcio->wcio_mode == ORIENT_UNKNOWN) _wcio->wcio_mode = (mode); \
   } while (0)
 
 #define WCIO_FREE(fp)                           \
   do {                                          \
     struct wchar_io_data* _wcio = WCIO_GET(fp); \
     if (_wcio) {                                \
-      _wcio->wcio_mode = 0;                     \
+      _wcio->wcio_mode = ORIENT_UNKNOWN;        \
       _wcio->wcio_ungetwc_inbuf = 0;            \
     }                                           \
   } while (0)
diff --git a/libc/stdio/printf_common.h b/libc/stdio/printf_common.h
index b0055f0..365728b 100644
--- a/libc/stdio/printf_common.h
+++ b/libc/stdio/printf_common.h
@@ -528,17 +528,29 @@
       case 'b':
         ADDUARG();
         break;
-      case 'w':
+      case 'w': {
         n = 0;
+        bool fast = false;
         ch = *fmt++;
+        if (ch == 'f') {
+          fast = true;
+          ch = *fmt++;
+        }
         while (is_digit(ch)) {
           APPEND_DIGIT(n, ch);
           ch = *fmt++;
         }
         if (n == 64) {
           flags |= LLONGINT;
+        } else {
+          if (n != 8 && fast) {
+#if defined(__LP64__)
+            flags |= LLONGINT;
+#endif
+          }
         }
         goto reswitch;
+      }
       default: /* "%?" prints ?, unless ? is NUL */
         if (ch == '\0') goto done;
         break;
@@ -824,4 +836,15 @@
     return convbuf;
   }
 
+  // Trasnlate a fixed size integer argument for the %w/%wf format to a
+  // flag representation. Supported sizes are 8, 16, 32, and 64 so far.
+  // See details in bionic/libc/include/stdint.h
+  static int w_to_flag(int size, bool fast) {
+    static constexpr int fast_size = sizeof(void*) == 8 ? LLONGINT : 0;
+    if (size == 8) return CHARINT;
+    if (size == 16) return fast ? fast_size : SHORTINT;
+    if (size == 32) return fast ? fast_size : 0;
+    if (size == 64) return LLONGINT;
+    __fortify_fatal("%%w%s%d is unsupported", fast ? "f" : "", size);
+  }
 };
diff --git a/libc/stdio/stdio.cpp b/libc/stdio/stdio.cpp
index 645aefa..f18cd81 100644
--- a/libc/stdio/stdio.cpp
+++ b/libc/stdio/stdio.cpp
@@ -773,7 +773,7 @@
 char* fgets_unlocked(char* buf, int n, FILE* fp) {
   if (n <= 0) __fortify_fatal("fgets: buffer size %d <= 0", n);
 
-  _SET_ORIENTATION(fp, -1);
+  _SET_ORIENTATION(fp, ORIENT_BYTES);
 
   char* s = buf;
   n--; // Leave space for NUL.
@@ -903,7 +903,7 @@
     errno = EBADF;
     return EOF;
   }
-  _SET_ORIENTATION(fp, -1);
+  _SET_ORIENTATION(fp, ORIENT_BYTES);
   if (--fp->_w >= 0 || (fp->_w >= fp->_lbfsize && c != '\n')) {
     return (*fp->_p++ = c);
   }
@@ -1098,7 +1098,7 @@
   size_t total = desired_total;
   if (total == 0) return 0;
 
-  _SET_ORIENTATION(fp, -1);
+  _SET_ORIENTATION(fp, ORIENT_BYTES);
 
   // TODO: how can this ever happen?!
   if (fp->_r < 0) fp->_r = 0;
@@ -1165,7 +1165,7 @@
   __siov iov = { .iov_base = const_cast<void*>(buf), .iov_len = n };
   __suio uio = { .uio_iov = &iov, .uio_iovcnt = 1, .uio_resid = n };
 
-  _SET_ORIENTATION(fp, -1);
+  _SET_ORIENTATION(fp, ORIENT_BYTES);
 
   // The usual case is success (__sfvwrite returns 0); skip the divide if this happens,
   // since divides are generally slow.
diff --git a/libc/stdio/vfprintf.cpp b/libc/stdio/vfprintf.cpp
index b7c68dd..12cceeb 100644
--- a/libc/stdio/vfprintf.cpp
+++ b/libc/stdio/vfprintf.cpp
@@ -39,7 +39,27 @@
 #define CHAR_TYPE_inf "inf"
 #define CHAR_TYPE_NAN "NAN"
 #define CHAR_TYPE_nan "nan"
-#define CHAR_TYPE_ORIENTATION -1
+#define CHAR_TYPE_ORIENTATION ORIENT_BYTES
+
+#define PRINT(ptr, len)                          \
+  do {                                           \
+    iovp->iov_base = (ptr);                      \
+    iovp->iov_len = (len);                       \
+    uio.uio_resid += (len);                      \
+    iovp++;                                      \
+    if (++uio.uio_iovcnt >= NIOV) {              \
+      if (helpers::sprint(fp, &uio)) goto error; \
+      iovp = iov;                                \
+    }                                            \
+  } while (0)
+
+#define FLUSH()                                                 \
+  do {                                                          \
+    if (uio.uio_resid && helpers::sprint(fp, &uio)) goto error; \
+    uio.uio_iovcnt = 0;                                         \
+    iovp = iov;                                                 \
+  } while (0)
+
 #include "printf_common.h"
 
 int FUNCTION_NAME(FILE* fp, const CHAR_TYPE* fmt0, va_list ap) {
@@ -115,24 +135,6 @@
   static const char xdigs_lower[] = "0123456789abcdef";
   static const char xdigs_upper[] = "0123456789ABCDEF";
 
-#define PRINT(ptr, len)                   \
-  do {                                    \
-    iovp->iov_base = (ptr);               \
-    iovp->iov_len = (len);                \
-    uio.uio_resid += (len);               \
-    iovp++;                               \
-    if (++uio.uio_iovcnt >= NIOV) {       \
-      if (helpers::sprint(fp, &uio)) goto error; \
-      iovp = iov;                         \
-    }                                     \
-  } while (0)
-#define FLUSH()                                          \
-  do {                                                   \
-    if (uio.uio_resid && helpers::sprint(fp, &uio)) goto error; \
-    uio.uio_iovcnt = 0;                                  \
-    iovp = iov;                                          \
-  } while (0)
-
   _SET_ORIENTATION(fp, CHAR_TYPE_ORIENTATION);
 
   // Writing "" to a read only file returns EOF, not 0.
@@ -359,14 +361,14 @@
         if (dtoaresult) __freedtoa(dtoaresult);
         if (flags & LONGDBL) {
           fparg.ldbl = GETARG(long double);
-          dtoaresult = cp = __hldtoa(fparg.ldbl, xdigs, prec, &expt, &signflag, &dtoaend);
+          dtoaresult = __hldtoa(fparg.ldbl, xdigs, prec, &expt, &signflag, &dtoaend);
           if (dtoaresult == nullptr) {
             errno = ENOMEM;
             goto error;
           }
         } else {
           fparg.dbl = GETARG(double);
-          dtoaresult = cp = __hdtoa(fparg.dbl, xdigs, prec, &expt, &signflag, &dtoaend);
+          dtoaresult = __hdtoa(fparg.dbl, xdigs, prec, &expt, &signflag, &dtoaend);
           if (dtoaresult == nullptr) {
             errno = ENOMEM;
             goto error;
@@ -396,14 +398,14 @@
         if (dtoaresult) __freedtoa(dtoaresult);
         if (flags & LONGDBL) {
           fparg.ldbl = GETARG(long double);
-          dtoaresult = cp = __ldtoa(&fparg.ldbl, expchar ? 2 : 3, prec, &expt, &signflag, &dtoaend);
+          dtoaresult = __ldtoa(&fparg.ldbl, expchar ? 2 : 3, prec, &expt, &signflag, &dtoaend);
           if (dtoaresult == nullptr) {
             errno = ENOMEM;
             goto error;
           }
         } else {
           fparg.dbl = GETARG(double);
-          dtoaresult = cp = __dtoa(fparg.dbl, expchar ? 2 : 3, prec, &expt, &signflag, &dtoaend);
+          dtoaresult = __dtoa(fparg.dbl, expchar ? 2 : 3, prec, &expt, &signflag, &dtoaend);
           if (dtoaresult == nullptr) {
             errno = ENOMEM;
             goto error;
@@ -411,6 +413,13 @@
           if (expt == 9999) expt = INT_MAX;
         }
       fp_common:
+#if CHAR_TYPE_ORIENTATION == ORIENT_BYTES
+        cp = dtoaresult;
+#else
+        free(convbuf);
+        cp = convbuf = helpers::mbsconv(dtoaresult, -1);
+        if (cp == nullptr) goto error;
+#endif
         if (signflag) sign = '-';
         if (expt == INT_MAX) { /* inf or nan */
           if (*cp == 'N') {
@@ -423,7 +432,7 @@
           break;
         }
         flags |= FPT;
-        ndig = dtoaend - cp;
+        ndig = dtoaend - dtoaresult;
         if (ch == 'g' || ch == 'G') {
           if (expt > -4 && expt <= prec) {
             /* Make %[gG] smell like %[fF] */
@@ -521,34 +530,21 @@
         _umax = UARG();
         base = DEC;
         goto nosign;
-      case 'w':
+      case 'w': {
         n = 0;
+        bool fast = false;
         ch = *fmt++;
+        if (ch == 'f') {
+          fast = true;
+          ch = *fmt++;
+        }
         while (is_digit(ch)) {
           APPEND_DIGIT(n, ch);
           ch = *fmt++;
         }
-        switch (n) {
-          case 8: {
-            flags |= CHARINT;
-            goto reswitch;
-          }
-          case 16: {
-            flags |= SHORTINT;
-            goto reswitch;
-          }
-          case 32: {
-            goto reswitch;
-          }
-          case 64: {
-            flags |= LLONGINT;
-            goto reswitch;
-          }
-          default: {
-            __fortify_fatal("%%w%d is unsupported", n);
-            break;
-          }
-        }
+        flags |= helpers::w_to_flag(n, fast);
+        goto reswitch;
+      }
       case 'X':
         xdigs = xdigs_upper;
         goto hex;
@@ -673,6 +669,7 @@
     } else { /* glue together f_p fragments */
       if (decimal_point == nullptr) decimal_point = nl_langinfo(RADIXCHAR);
       if (!expchar) { /* %[fF] or sufficiently short %[gG] */
+        CHAR_TYPE* end = cp + ndig;
         if (expt <= 0) {
           PRINT(zeroes, 1);
           if (prec || flags & ALT) PRINT(decimal_point, 1);
@@ -680,11 +677,11 @@
           /* already handled initial 0's */
           prec += expt;
         } else {
-          PRINTANDPAD(cp, dtoaend, lead, zeroes);
+          PRINTANDPAD(cp, end, lead, zeroes);
           cp += lead;
           if (prec || flags & ALT) PRINT(decimal_point, 1);
         }
-        PRINTANDPAD(cp, dtoaend, prec, zeroes);
+        PRINTANDPAD(cp, end, prec, zeroes);
       } else { /* %[eE] or sufficiently long %[gG] */
         if (prec > 1 || flags & ALT) {
           buf[0] = *cp++;
diff --git a/libc/stdio/vfscanf.cpp b/libc/stdio/vfscanf.cpp
index d05a3a6..dfd001d 100644
--- a/libc/stdio/vfscanf.cpp
+++ b/libc/stdio/vfscanf.cpp
@@ -102,7 +102,7 @@
   void* allocation = nullptr; // Allocated but unassigned result for %mc/%ms/%m[.
   size_t capacity = 0; // Number of char/wchar_t units allocated in `allocation`.
 
-  _SET_ORIENTATION(fp, -1);
+  _SET_ORIENTATION(fp, ORIENT_BYTES);
 
   nassigned = 0;
   nread = 0;
diff --git a/libc/stdio/vfwprintf.cpp b/libc/stdio/vfwprintf.cpp
index 52ae64b..d6f6a6b 100644
--- a/libc/stdio/vfwprintf.cpp
+++ b/libc/stdio/vfwprintf.cpp
@@ -39,7 +39,17 @@
 #define CHAR_TYPE_inf L"inf"
 #define CHAR_TYPE_NAN L"NAN"
 #define CHAR_TYPE_nan L"nan"
-#define CHAR_TYPE_ORIENTATION 1
+#define CHAR_TYPE_ORIENTATION ORIENT_CHARS
+
+#define PRINT(ptr, len)                                          \
+  do {                                                           \
+    for (int n3 = 0; n3 < (len); n3++) {                         \
+      if ((helpers::xfputwc((ptr)[n3], fp)) == WEOF) goto error; \
+    }                                                            \
+  } while (0)
+
+#define FLUSH()
+
 #include "printf_common.h"
 
 int FUNCTION_NAME(FILE* fp, const CHAR_TYPE* fmt0, va_list ap) {
@@ -115,13 +125,6 @@
   static const char xdigs_lower[] = "0123456789abcdef";
   static const char xdigs_upper[] = "0123456789ABCDEF";
 
-#define PRINT(ptr, len)                                   \
-  do {                                                    \
-    for (int n3 = 0; n3 < (len); n3++) {                      \
-      if ((helpers::xfputwc((ptr)[n3], fp)) == WEOF) goto error; \
-    }                                                     \
-  } while (0)
-
   _SET_ORIENTATION(fp, CHAR_TYPE_ORIENTATION);
 
   // Writing "" to a read only file returns EOF, not 0.
@@ -352,10 +355,6 @@
         }
         if (prec < 0) prec = dtoaend - dtoaresult;
         if (expt == INT_MAX) ox[1] = '\0';
-        free(convbuf);
-        cp = convbuf = helpers::mbsconv(dtoaresult, -1);
-        if (cp == nullptr) goto error;
-        ndig = dtoaend - dtoaresult;
         goto fp_common;
       case 'e':
       case 'E':
@@ -392,11 +391,14 @@
           }
           if (expt == 9999) expt = INT_MAX;
         }
+      fp_common:
+#if CHAR_TYPE_ORIENTATION == ORIENT_BYTES
+        cp = dtoaresult;
+#else
         free(convbuf);
         cp = convbuf = helpers::mbsconv(dtoaresult, -1);
         if (cp == nullptr) goto error;
-        ndig = dtoaend - dtoaresult;
-      fp_common:
+#endif
         if (signflag) sign = '-';
         if (expt == INT_MAX) { /* inf or nan */
           if (*cp == 'N') {
@@ -409,6 +411,7 @@
           break;
         }
         flags |= FPT;
+        ndig = dtoaend - dtoaresult;
         if (ch == 'g' || ch == 'G') {
           if (expt > -4 && expt <= prec) {
             /* Make %[gG] smell like %[fF] */
@@ -510,34 +513,21 @@
         _umax = UARG();
         base = DEC;
         goto nosign;
-      case 'w':
+      case 'w': {
         n = 0;
+        bool fast = false;
         ch = *fmt++;
+        if (ch == 'f') {
+          fast = true;
+          ch = *fmt++;
+        }
         while (is_digit(ch)) {
           APPEND_DIGIT(n, ch);
           ch = *fmt++;
         }
-        switch (n) {
-          case 8: {
-            flags |= CHARINT;
-            goto reswitch;
-          }
-          case 16: {
-            flags |= SHORTINT;
-            goto reswitch;
-          }
-          case 32: {
-            goto reswitch;
-          }
-          case 64: {
-            flags |= LLONGINT;
-            goto reswitch;
-          }
-          default: {
-            __fortify_fatal("%%w%d is unsupported", n);
-            break;
-          }
-        }
+        flags |= helpers::w_to_flag(n, fast);
+        goto reswitch;
+      }
       case 'X':
         xdigs = xdigs_upper;
         goto hex;
@@ -662,6 +652,7 @@
     } else { /* glue together f_p fragments */
       if (decimal_point == nullptr) decimal_point = nl_langinfo(RADIXCHAR);
       if (!expchar) { /* %[fF] or sufficiently short %[gG] */
+        CHAR_TYPE* end = cp + ndig;
         if (expt <= 0) {
           PRINT(zeroes, 1);
           if (prec || flags & ALT) PRINT(decimal_point, 1);
@@ -669,11 +660,11 @@
           /* already handled initial 0's */
           prec += expt;
         } else {
-          PRINTANDPAD(cp, convbuf + ndig, lead, zeroes);
+          PRINTANDPAD(cp, end, lead, zeroes);
           cp += lead;
           if (prec || flags & ALT) PRINT(decimal_point, 1);
         }
-        PRINTANDPAD(cp, convbuf + ndig, prec, zeroes);
+        PRINTANDPAD(cp, end, prec, zeroes);
       } else { /* %[eE] or sufficiently long %[gG] */
         if (prec > 1 || flags & ALT) {
           buf[0] = *cp++;
@@ -694,8 +685,11 @@
     if (width < realsz) width = realsz;
     if (width > INT_MAX - ret) goto overflow;
     ret += width;
+
+    FLUSH(); /* copy out the I/O vectors */
   }
 done:
+  FLUSH();
 error:
   va_end(orgap);
   if (__sferror(fp)) ret = -1;
diff --git a/libc/stdio/vfwscanf.cpp b/libc/stdio/vfwscanf.cpp
index 06f706a..5f21acd 100644
--- a/libc/stdio/vfwscanf.cpp
+++ b/libc/stdio/vfwscanf.cpp
@@ -150,7 +150,7 @@
   char mbbuf[MB_LEN_MAX]; /* temporary mb. character buffer */
   mbstate_t mbs;
 
-  _SET_ORIENTATION(fp, 1);
+  _SET_ORIENTATION(fp, ORIENT_CHARS);
 
   nassigned = 0;
   nconversions = 0;
diff --git a/libc/tools/gensyscalls.py b/libc/tools/gensyscalls.py
index 558b004..4f33777 100755
--- a/libc/tools/gensyscalls.py
+++ b/libc/tools/gensyscalls.py
@@ -88,7 +88,7 @@
     ecall
 
     li      a7, -MAX_ERRNO
-    bgtu    a0, a7, 1f
+    bgeu    a0, a7, 1f
 
     ret
 1:
diff --git a/libc/tzcode/asctime.c b/libc/tzcode/asctime.c
index ce5d4be..4cdfd13 100644
--- a/libc/tzcode/asctime.c
+++ b/libc/tzcode/asctime.c
@@ -17,12 +17,6 @@
 #include <stdio.h>
 
 /*
-** Some systems only handle "%.2d"; others only handle "%02d";
-** "%02.2d" makes (most) everybody happy.
-** At least some versions of gcc warn about the %02.2d;
-** we conditionalize below to avoid the warning.
-*/
-/*
 ** All years associated with 32-bit time_t values are exactly four digits long;
 ** some years associated with 64-bit time_t values are not.
 ** Vintage programs are coded for years that are always four digits long
@@ -34,24 +28,16 @@
 ** The ISO C and POSIX standards prohibit padding the year,
 ** but many implementations pad anyway; most likely the standards are buggy.
 */
-#ifdef __GNUC__
-#define ASCTIME_FMT	"%s %s%3d %2.2d:%2.2d:%2.2d %-4s\n"
-#else /* !defined __GNUC__ */
-#define ASCTIME_FMT	"%s %s%3d %02.2d:%02.2d:%02.2d %-4s\n"
-#endif /* !defined __GNUC__ */
+static char const ASCTIME_FMT[] = "%s %s%3d %.2d:%.2d:%.2d %-4s\n";
 /*
 ** For years that are more than four digits we put extra spaces before the year
 ** so that code trying to overwrite the newline won't end up overwriting
 ** a digit within a year and truncating the year (operating on the assumption
 ** that no output is better than wrong output).
 */
-#ifdef __GNUC__
-#define ASCTIME_FMT_B	"%s %s%3d %2.2d:%2.2d:%2.2d     %s\n"
-#else /* !defined __GNUC__ */
-#define ASCTIME_FMT_B	"%s %s%3d %02.2d:%02.2d:%02.2d     %s\n"
-#endif /* !defined __GNUC__ */
+static char const ASCTIME_FMT_B[] = "%s %s%3d %.2d:%.2d:%.2d     %s\n";
 
-#define STD_ASCTIME_BUF_SIZE	26
+enum { STD_ASCTIME_BUF_SIZE = 26 };
 /*
 ** Big enough for something such as
 ** ??? ???-2147483648 -2147483648:-2147483648:-2147483648     -2147483648\n
@@ -59,15 +45,23 @@
 ** seven explicit spaces, two explicit colons, a newline,
 ** 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
+** as an example; the size expression below is a bound for the system at
 ** hand.
 */
-#define MAX_ASCTIME_BUF_SIZE	(2*3+5*INT_STRLEN_MAXIMUM(int)+7+2+1+1)
+static char buf_asctime[2*3 + 5*INT_STRLEN_MAXIMUM(int) + 7 + 2 + 1 + 1];
 
-static char	buf_asctime[MAX_ASCTIME_BUF_SIZE];
+/* A similar buffer for ctime.
+   C89 requires that they be the same buffer.
+   This requirement was removed in C99, so support it only if requested,
+   as support is more likely to lead to bugs in badly written programs.  */
+#if SUPPORT_C89
+# define buf_ctime buf_asctime
+#else
+static char buf_ctime[sizeof buf_asctime];
+#endif
 
 char *
-asctime_r(register const struct tm *timeptr, char *buf)
+asctime_r(struct tm const *restrict timeptr, char *restrict buf)
 {
 	static const char	wday_name[][4] = {
 		"Sun", "Mon", "Tue", "Wed", "Thu", "Fri", "Sat"
@@ -79,7 +73,7 @@
 	register const char *	wn;
 	register const char *	mn;
 	char			year[INT_STRLEN_MAXIMUM(int) + 2];
-	char			result[MAX_ASCTIME_BUF_SIZE];
+	char result[sizeof buf_asctime];
 
 	if (timeptr == NULL) {
 		errno = EINVAL;
@@ -107,7 +101,8 @@
 		timeptr->tm_mday, timeptr->tm_hour,
 		timeptr->tm_min, timeptr->tm_sec,
 		year);
-	if (strlen(result) < STD_ASCTIME_BUF_SIZE || buf == buf_asctime)
+	if (strlen(result) < STD_ASCTIME_BUF_SIZE
+	    || buf == buf_ctime || buf == buf_asctime)
 		return strcpy(buf, result);
 	else {
 		errno = EOVERFLOW;
@@ -120,3 +115,17 @@
 {
 	return asctime_r(timeptr, buf_asctime);
 }
+
+char *
+ctime_r(const time_t *timep, char *buf)
+{
+  struct tm mytm;
+  struct tm *tmp = localtime_r(timep, &mytm);
+  return tmp ? asctime_r(tmp, buf) : NULL;
+}
+
+char *
+ctime(const time_t *timep)
+{
+  return ctime_r(timep, buf_ctime);
+}
diff --git a/libc/tzcode/localtime.c b/libc/tzcode/localtime.c
index 8ff5cee..5e1181f 100644
--- a/libc/tzcode/localtime.c
+++ b/libc/tzcode/localtime.c
@@ -28,29 +28,22 @@
 static void unlock(void) { }
 #endif
 
-#ifndef TZ_ABBR_MAX_LEN
-#define TZ_ABBR_MAX_LEN 16
-#endif /* !defined TZ_ABBR_MAX_LEN */
-
 #ifndef TZ_ABBR_CHAR_SET
-#define TZ_ABBR_CHAR_SET \
+# define TZ_ABBR_CHAR_SET \
     "abcdefghijklmnopqrstuvwxyzABCDEFGHIJKLMNOPQRSTUVWXYZ0123456789 :+-._"
 #endif /* !defined TZ_ABBR_CHAR_SET */
 
 #ifndef TZ_ABBR_ERR_CHAR
-#define TZ_ABBR_ERR_CHAR    '_'
+# define TZ_ABBR_ERR_CHAR    '_'
 #endif /* !defined TZ_ABBR_ERR_CHAR */
 
 /*
-** SunOS 4.1.1 headers lack O_BINARY.
++** Support non-POSIX platforms that distinguish between text and binary files.
 */
 
-#ifdef O_BINARY
-#define OPEN_MODE   (O_RDONLY | O_BINARY)
-#endif /* defined O_BINARY */
 #ifndef O_BINARY
-#define OPEN_MODE   O_RDONLY
-#endif /* !defined O_BINARY */
+# define O_BINARY 0
+#endif
 
 #ifndef WILDABBR
 /*
@@ -72,12 +65,13 @@
 ** manual page of what this "time zone abbreviation" means (doing this so
 ** that tzname[0] has the "normal" length of three characters).
 */
-#define WILDABBR    "   "
+# define WILDABBR    "   "
 #endif /* !defined WILDABBR */
 
 static const char       wildabbr[] = WILDABBR;
 
-static const char gmt[] = "GMT";
+static char const etc_utc[] = "Etc/UTC";
+static char const *utc = etc_utc + sizeof "Etc/" - 1;
 
 /*
 ** The DST rules to use if TZ has no rules and we can't load TZDEFRULES.
@@ -86,7 +80,7 @@
 ** for historical reasons, US rules are a common default.
 */
 #ifndef TZDEFRULESTRING
-#define TZDEFRULESTRING ",M3.2.0,M11.1.0"
+# define TZDEFRULESTRING ",M3.2.0,M11.1.0"
 #endif
 
 struct ttinfo {              /* time type information */
@@ -102,9 +96,6 @@
     int_fast32_t ls_corr;    /* correction to apply */
 };
 
-#define SMALLEST(a, b)	(((a) < (b)) ? (a) : (b))
-#define BIGGEST(a, b)   (((a) > (b)) ? (a) : (b))
-
 /* This abbreviation means local time is unspecified.  */
 static char const UNSPEC[] = "-00";
 
@@ -112,14 +103,13 @@
    This needs to be at least 1 for null termination in case the input
    data isn't properly terminated, and it also needs to be big enough
    for ttunspecified to work without crashing.  */
-enum { CHARS_EXTRA = BIGGEST(sizeof UNSPEC, 2) - 1 };
+enum { CHARS_EXTRA = max(sizeof UNSPEC, 2) - 1 };
 
-#ifdef TZNAME_MAX
-#define MY_TZNAME_MAX   TZNAME_MAX
-#endif /* defined TZNAME_MAX */
-#ifndef TZNAME_MAX
-#define MY_TZNAME_MAX   255
-#endif /* !defined TZNAME_MAX */
+/* Limit to time zone abbreviation length in POSIX-style TZ strings.
+   This is distinct from TZ_MAX_CHARS, which limits TZif file contents.  */
+#ifndef TZNAME_MAXIMUM
+# define TZNAME_MAXIMUM 255
+#endif
 
 struct state {
     int           leapcnt;
@@ -131,9 +121,8 @@
     time_t        ats[TZ_MAX_TIMES];
     unsigned char types[TZ_MAX_TIMES];
     struct ttinfo ttis[TZ_MAX_TYPES];
-    char          chars[BIGGEST(BIGGEST(TZ_MAX_CHARS + CHARS_EXTRA,
-                            sizeof gmt),
-                  (2 * (MY_TZNAME_MAX + 1)))];
+    char chars[max(max(TZ_MAX_CHARS + CHARS_EXTRA, sizeof "UTC"),
+		         2 * (TZNAME_MAXIMUM + 1))];
     struct lsinfo lsis[TZ_MAX_LEAPS];
     /* The time type to use for early times or if no transitions.
        It is always zero for recent tzdb releases.
@@ -174,12 +163,12 @@
 #ifndef ALL_STATE
 static struct state lclmem;
 static struct state gmtmem;
-#define lclptr      (&lclmem)
-#define gmtptr      (&gmtmem)
+static struct state *const lclptr = &lclmem;
+static struct state *const gmtptr = &gmtmem;
 #endif /* State Farm */
 
 #ifndef TZ_STRLEN_MAX
-#define TZ_STRLEN_MAX 255
+# define TZ_STRLEN_MAX 255
 #endif /* !defined TZ_STRLEN_MAX */
 
 static char lcl_TZname[TZ_STRLEN_MAX + 1];
@@ -191,9 +180,14 @@
 **  ctime, gmtime, localtime] return values in one of two static
 **  objects: a broken-down time structure and an array of char.
 ** Thanks to Paul Eggert for noting this.
+**
+** This requirement was removed in C99, so support it only if requested,
+** as support is more likely to lead to bugs in badly written programs.
 */
 
+#if SUPPORT_C89
 static struct tm	tm;
+#endif
 
 #if 2 <= HAVE_TZNAME + TZ_TIME_T
 char *			tzname[2] = {
@@ -321,7 +315,7 @@
 	int stddst_mask = 0;
 
 #if HAVE_TZNAME
-	tzname[0] = tzname[1] = (char *) (sp ? wildabbr : gmt);
+	tzname[0] = tzname[1] = (char *) (sp ? wildabbr : utc);
 	stddst_mask = 3;
 #endif
 #if USG_COMPAT
@@ -346,27 +340,28 @@
 #endif
 }
 
-static void
+/* Replace bogus characters in time zone abbreviations.
+   Return 0 on success, an errno value if a time zone abbreviation is
+   too long.  */
+static int
 scrub_abbrs(struct state *sp)
 {
 	int i;
-	/*
-	** First, replace bogus characters.
-	*/
+
+	/* Reject overlong abbreviations.  */
+	for (i = 0; i < sp->charcnt - (TZNAME_MAXIMUM + 1); ) {
+	  int len = strlen(&sp->chars[i]);
+	  if (TZNAME_MAXIMUM < len)
+	    return EOVERFLOW;
+	  i += len + 1;
+	}
+
+	/* 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];
-		char *cp = &sp->chars[ttisp->tt_desigidx];
 
-		if (strlen(cp) > TZ_ABBR_MAX_LEN &&
-			strcmp(cp, GRANDPARENTED) != 0)
-				*(cp + TZ_ABBR_MAX_LEN) = '\0';
-	}
+	return 0;
 }
 
 /* Input buffer for data read from a compiled tz file.  */
@@ -399,8 +394,7 @@
   // Android-removed: There is no directory with file-per-time zone on Android.
   #ifndef __BIONIC__
   /* The file name to be opened.  */
-  char fullname[BIGGEST(sizeof(struct file_analysis),
-      sizeof tzdirslash + 1024)];
+  char fullname[max(sizeof(struct file_analysis), sizeof tzdirslash + 1024)];
   #endif
 };
 
@@ -446,8 +440,7 @@
 #endif
 	if (!doaccess) {
 		char const *dot;
-		size_t namelen = strlen(name);
-		if (sizeof lsp->fullname - sizeof tzdirslash <= namelen)
+		if (sizeof lsp->fullname - sizeof tzdirslash <= strlen(name))
 		  return ENAMETOOLONG;
 
 		/* Create a string "TZDIR/NAME".  Using sprintf here
@@ -470,7 +463,7 @@
 	}
 	if (doaccess && access(name, R_OK) != 0)
 	  return errno;
-	fid = open(name, OPEN_MODE);
+  fid = open(name, O_RDONLY | O_BINARY);
 #endif
 	if (fid < 0)
 	  return errno;
@@ -828,12 +821,14 @@
 		b < 0 || b >= sp->typecnt)
 			result = false;
 	else {
+		/* Compare the relevant members of *AP and *BP.
+		   Ignore tt_ttisstd and tt_ttisut, as they are
+		   irrelevant now and counting them could cause
+		   sp->goahead to mistakenly remain false.  */
 		register const struct ttinfo *	ap = &sp->ttis[a];
 		register const struct ttinfo *	bp = &sp->ttis[b];
 		result = (ap->tt_utoff == bp->tt_utoff
 			  && ap->tt_isdst == bp->tt_isdst
-			  && ap->tt_ttisstd == bp->tt_ttisstd
-			  && ap->tt_ttisut == bp->tt_ttisut
 			  && (strcmp(&sp->chars[ap->tt_desigidx],
 				     &sp->chars[bp->tt_desigidx])
 			      == 0));
@@ -863,7 +858,7 @@
 ** Return a pointer to that character.
 */
 
-static ATTRIBUTE_PURE const char *
+ATTRIBUTE_REPRODUCIBLE static const char *
 getzname(register const char *strp)
 {
 	register char	c;
@@ -884,7 +879,7 @@
 ** We don't do any checking here; checking is done later in common-case code.
 */
 
-static ATTRIBUTE_PURE const char *
+ATTRIBUTE_REPRODUCIBLE static const char *
 getqzname(register const char *strp, const int delim)
 {
 	register int	c;
@@ -1122,7 +1117,7 @@
             value += mon_lengths[leapyear][i] * SECSPERDAY;
         break;
 
-        default: UNREACHABLE();
+        default: unreachable();
     }
 
     /*
@@ -1144,13 +1139,11 @@
 {
 	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;
+	ptrdiff_t stdlen, dstlen, charcnt;
 	time_t atlo = TIME_T_MIN, leaplo = TIME_T_MIN;
 
 	stdname = name;
@@ -1166,14 +1159,12 @@
 	  name = getzname(name);
 	  stdlen = name - stdname;
 	}
-	if (!stdlen)
+	if (! (0 < stdlen && stdlen <= TZNAME_MAXIMUM))
 	  return false;
 	name = getoffset(name, &stdoffset);
 	if (name == NULL)
 	  return false;
 	charcnt = stdlen + 1;
-	if (sizeof sp->chars < charcnt)
-	  return false;
 	if (basep) {
 	  if (0 < basep->timecnt)
 	    atlo = basep->ats[basep->timecnt - 1];
@@ -1200,11 +1191,9 @@
 			name = getzname(name);
 			dstlen = name - dstname; /* length of DST abbr. */
 		}
-		if (!dstlen)
+		if (! (0 < dstlen && dstlen <= TZNAME_MAXIMUM))
 		  return false;
 		charcnt += dstlen + 1;
-		if (sizeof sp->chars < charcnt)
-		  return false;
 		if (*name != '\0' && *name != ',' && *name != ';') {
 			name = getoffset(name, &dstoffset);
 			if (name == NULL)
@@ -1420,8 +1409,8 @@
 static void
 gmtload(struct state *const sp)
 {
-	if (tzload(gmt, sp, true) != 0)
-	  tzparse("GMT0", sp, NULL);
+	if (tzload(etc_utc, sp, true) != 0)
+	  tzparse("UTC0", sp, NULL);
 }
 
 /* Initialize *SP to a value appropriate for the TZ setting NAME.
@@ -1439,7 +1428,7 @@
     sp->charcnt = 0;
     sp->goback = sp->goahead = false;
     init_ttinfo(&sp->ttis[0], 0, false, 0);
-    strcpy(sp->chars, gmt);
+    strcpy(sp->chars, utc);
     sp->defaulttype = 0;
     return 0;
   } else {
@@ -1447,7 +1436,7 @@
     if (err != 0 && name && name[0] != ':' && tzparse(name, sp, NULL))
       err = 0;
     if (err == 0)
-      scrub_abbrs(sp);
+      err = scrub_abbrs(sp);
     return err;
   }
 }
@@ -1557,7 +1546,7 @@
 ** set the applicable parts of tzname, timezone and altzone;
 ** however, it's OK to omit this step if the timezone 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,
+** SETNAME's type is int_fast32_t for compatibility with gmtsub,
 ** but it is actually a boolean and its value should be 0 or 1.
 */
 
@@ -1601,6 +1590,14 @@
 					return NULL;	/* "cannot happen" */
 			result = localsub(sp, &newt, setname, tmp);
 			if (result) {
+#if defined ckd_add && defined ckd_sub
+				if (t < sp->ats[0]
+				    ? ckd_sub(&result->tm_year,
+					      result->tm_year, years)
+				    : ckd_add(&result->tm_year,
+					      result->tm_year, years))
+				  return NULL;
+#else
 				register int_fast64_t newy;
 
 				newy = result->tm_year;
@@ -1610,6 +1607,7 @@
 				if (! (INT_MIN <= newy && newy <= INT_MAX))
 					return NULL;
 				result->tm_year = newy;
+#endif
 			}
 			return result;
 	}
@@ -1650,7 +1648,8 @@
 #if NETBSD_INSPIRED
 
 struct tm *
-localtime_rz(struct state *sp, time_t const *timep, struct tm *tmp)
+localtime_rz(struct state *restrict sp, time_t const *restrict timep,
+	     struct tm *restrict tmp)
 {
   return localsub(sp, timep, 0, tmp);
 }
@@ -1681,11 +1680,14 @@
 struct tm *
 localtime(const time_t *timep)
 {
+#if !SUPPORT_C89
+  static struct tm tm;
+#endif
   return localtime_tzset(timep, &tm);
 }
 
 struct tm *
-localtime_r(const time_t *timep, struct tm *tmp)
+localtime_r(const time_t *restrict timep, struct tm *restrict tmp)
 {
   return localtime_tzset(timep, tmp);
 }
@@ -1695,8 +1697,8 @@
 */
 
 static struct tm *
-gmtsub(struct state const *sp, time_t const *timep, int_fast32_t offset,
-       struct tm *tmp)
+gmtsub(ATTRIBUTE_MAYBE_UNUSED struct state const *sp, time_t const *timep,
+       int_fast32_t offset, struct tm *tmp)
 {
 	register struct tm *	result;
 
@@ -1708,7 +1710,7 @@
 	** but this is no time for a treasure hunt.
 	*/
 	tmp->TM_ZONE = ((char *)
-			(offset ? wildabbr : gmtptr ? gmtptr->chars : gmt));
+			(offset ? wildabbr : gmtptr ? gmtptr->chars : utc));
 #endif /* defined TM_ZONE */
 	return result;
 }
@@ -1718,7 +1720,7 @@
 */
 
 struct tm *
-gmtime_r(const time_t *timep, struct tm *tmp)
+gmtime_r(time_t const *restrict timep, struct tm *restrict tmp)
 {
   gmtcheck();
   return gmtsub(gmtptr, timep, 0, tmp);
@@ -1727,19 +1729,26 @@
 struct tm *
 gmtime(const time_t *timep)
 {
+#if !SUPPORT_C89
+  static struct tm tm;
+#endif
   return gmtime_r(timep, &tm);
 }
 
-#ifdef STD_INSPIRED
+#if STD_INSPIRED
 
 struct tm *
 offtime(const time_t *timep, long offset)
 {
   gmtcheck();
+
+#if !SUPPORT_C89
+  static struct tm tm;
+#endif
   return gmtsub(gmtptr, timep, offset, &tm);
 }
 
-#endif /* defined STD_INSPIRED */
+#endif
 
 /*
 ** Return the number of leap years through the end of the given year
@@ -1825,6 +1834,12 @@
 		y = newy;
 	}
 
+#ifdef ckd_add
+	if (ckd_add(&tmp->tm_year, y, -TM_YEAR_BASE)) {
+	  errno = EOVERFLOW;
+	  return NULL;
+	}
+#else
 	if (!TYPE_SIGNED(time_t) && y < TM_YEAR_BASE) {
 	  int signed_y = y;
 	  tmp->tm_year = signed_y - TM_YEAR_BASE;
@@ -1835,6 +1850,7 @@
 	  errno = EOVERFLOW;
 	  return NULL;
 	}
+#endif
 	tmp->tm_yday = idays;
 	/*
 	** The "extra" mods below avoid overflow problems.
@@ -1868,27 +1884,6 @@
 	return tmp;
 }
 
-char *
-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))
-*/
-  struct tm *tmp = localtime(timep);
-  return tmp ? asctime(tmp) : NULL;
-}
-
-char *
-ctime_r(const time_t *timep, char *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
@@ -1899,7 +1894,7 @@
 */
 
 #ifndef WRONG
-#define WRONG	(-1)
+# define WRONG (-1)
 #endif /* !defined WRONG */
 
 /*
@@ -1909,6 +1904,9 @@
 static bool
 increment_overflow(int *ip, int j)
 {
+#ifdef ckd_add
+	return ckd_add(ip, *ip, j);
+#else
 	register int const	i = *ip;
 
 	/*
@@ -1921,22 +1919,30 @@
 		return true;
 	*ip += j;
 	return false;
+#endif
 }
 
 static bool
 increment_overflow32(int_fast32_t *const lp, int const m)
 {
+#ifdef ckd_add
+	return ckd_add(lp, *lp, m);
+#else
 	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;
+#endif
 }
 
 static bool
 increment_overflow_time(time_t *tp, int_fast32_t j)
 {
+#ifdef ckd_add
+	return ckd_add(tp, *tp, j);
+#else
 	/*
 	** This is like
 	** 'if (! (TIME_T_MIN <= *tp + j && *tp + j <= TIME_T_MAX)) ...',
@@ -1948,6 +1954,7 @@
 		return true;
 	*tp += j;
 	return false;
+#endif
 }
 
 static bool
@@ -1990,6 +1997,23 @@
 	return result;
 }
 
+/* Copy to *DEST from *SRC.  Copy only the members needed for mktime,
+   as other members might not be initialized.  */
+static void
+mktmcpy(struct tm *dest, struct tm const *src)
+{
+  dest->tm_sec = src->tm_sec;
+  dest->tm_min = src->tm_min;
+  dest->tm_hour = src->tm_hour;
+  dest->tm_mday = src->tm_mday;
+  dest->tm_mon = src->tm_mon;
+  dest->tm_year = src->tm_year;
+  dest->tm_isdst = src->tm_isdst;
+#if defined TM_GMTOFF && ! UNINIT_TRAP
+  dest->TM_GMTOFF = src->TM_GMTOFF;
+#endif
+}
+
 static time_t
 time2sub(struct tm *const tmp,
 	 struct tm *(*funcp)(struct state const *, time_t const *,
@@ -2011,7 +2035,8 @@
 	struct tm			yourtm, mytm;
 
 	*okayp = false;
-	yourtm = *tmp;
+	mktmcpy(&yourtm, tmp);
+
 	if (do_norm_secs) {
 		if (normalize_overflow(&yourtm.tm_min, &yourtm.tm_sec,
 			SECSPERMIN))
@@ -2053,14 +2078,19 @@
 				return WRONG;
 		}
 	}
+#ifdef ckd_add
+	if (ckd_add(&yourtm.tm_year, y, -TM_YEAR_BASE))
+	  return WRONG;
+#else
 	if (increment_overflow32(&y, -TM_YEAR_BASE))
 		return WRONG;
 	if (! (INT_MIN <= y && y <= INT_MAX))
 		return WRONG;
 	yourtm.tm_year = y;
+#endif
 	if (yourtm.tm_sec >= 0 && yourtm.tm_sec < SECSPERMIN)
 		saved_seconds = 0;
-	else if (y + TM_YEAR_BASE < EPOCH_YEAR) {
+	else if (yourtm.tm_year < EPOCH_YEAR - TM_YEAR_BASE) {
 		/*
 		** We can't set tm_sec to 0, because that might push the
 		** time below the minimum representable time.
@@ -2120,10 +2150,10 @@
 		    && (yourtm.TM_GMTOFF < 0
 			? (-SECSPERDAY <= yourtm.TM_GMTOFF
 			   && (mytm.TM_GMTOFF <=
-			       (SMALLEST(INT_FAST32_MAX, LONG_MAX)
+			       (min(INT_FAST32_MAX, LONG_MAX)
 				+ yourtm.TM_GMTOFF)))
 			: (yourtm.TM_GMTOFF <= SECSPERDAY
-			   && ((BIGGEST(INT_FAST32_MIN, LONG_MIN)
+			   && ((max(INT_FAST32_MIN, LONG_MIN)
 				+ yourtm.TM_GMTOFF)
 			       <= mytm.TM_GMTOFF)))) {
 		  /* MYTM matches YOURTM except with the wrong UT offset.
@@ -2294,7 +2324,7 @@
 #if NETBSD_INSPIRED
 
 time_t
-mktime_z(struct state *sp, struct tm *tmp)
+mktime_z(struct state *restrict sp, struct tm *restrict tmp)
 {
   return mktime_tzname(sp, tmp, false);
 }
@@ -2324,8 +2354,7 @@
   return t;
 }
 
-#ifdef STD_INSPIRED
-
+#if STD_INSPIRED
 time_t
 timelocal(struct tm *tmp)
 {
@@ -2333,13 +2362,9 @@
 		tmp->tm_isdst = -1;	/* in case it wasn't initialized */
 	return mktime(tmp);
 }
-
-time_t
-timegm(struct tm *tmp)
-{
-  return timeoff(tmp, 0);
-}
-
+#else
+static
+#endif
 time_t
 timeoff(struct tm *tmp, long offset)
 {
@@ -2349,7 +2374,18 @@
   return time1(tmp, gmtsub, gmtptr, offset);
 }
 
-#endif /* defined STD_INSPIRED */
+time_t
+timegm(struct tm *tmp)
+{
+  time_t t;
+  struct tm tmcpy;
+  mktmcpy(&tmcpy, tmp);
+  tmcpy.tm_wday = -1;
+  t = timeoff(&tmcpy, 0);
+  if (0 <= tmcpy.tm_wday)
+    *tmp = tmcpy;
+  return t;
+}
 
 static int_fast32_t
 leapcorr(struct state const *sp, time_t t)
@@ -2370,7 +2406,7 @@
 ** XXX--is the below the right way to conditionalize??
 */
 
-#ifdef STD_INSPIRED
+#if STD_INSPIRED
 
 /* NETBSD_INSPIRED_EXTERN functions are exported to callers if
    NETBSD_INSPIRED is defined, and are private otherwise.  */
@@ -2455,7 +2491,7 @@
   return t;
 }
 
-#endif /* defined STD_INSPIRED */
+#endif /* STD_INSPIRED */
 
 #if TZ_TIME_T
 
diff --git a/libc/tzcode/private.h b/libc/tzcode/private.h
index 4c03324..838ab2b 100644
--- a/libc/tzcode/private.h
+++ b/libc/tzcode/private.h
@@ -17,6 +17,36 @@
 ** Thank you!
 */
 
+/* PORT_TO_C89 means the code should work even if the underlying
+   compiler and library support only C89.  SUPPORT_C89 means the
+   tzcode library should support C89 callers in addition to the usual
+   support for C99-and-later callers.  These macros are obsolescent,
+   and the plan is to remove them along with any code needed only when
+   they are nonzero.  */
+#ifndef PORT_TO_C89
+# define PORT_TO_C89 0
+#endif
+#ifndef SUPPORT_C89
+# define SUPPORT_C89 0
+#endif
+
+#ifndef __STDC_VERSION__
+# define __STDC_VERSION__ 0
+#endif
+
+/* Define true, false and bool if they don't work out of the box.  */
+#if PORT_TO_C89 && __STDC_VERSION__ < 199901
+# define true 1
+# define false 0
+# define bool int
+#elif __STDC_VERSION__ < 202311
+# include <stdbool.h>
+#endif
+
+#if __STDC_VERSION__ < 202311
+# define static_assert(cond) extern int static_assert_check[(cond) ? 1 : -1]
+#endif
+
 /*
 ** zdump has been made independent of the rest of the time
 ** conversion package to increase confidence in the verification it provides.
@@ -36,79 +66,86 @@
 */
 
 #ifndef HAVE_DECL_ASCTIME_R
-#define HAVE_DECL_ASCTIME_R 1
+# define HAVE_DECL_ASCTIME_R 1
 #endif
 
-#if !defined HAVE_GENERIC && defined __has_extension
+#if !defined HAVE__GENERIC && defined __has_extension
 # if __has_extension(c_generic_selections)
-#  define HAVE_GENERIC 1
+#  define HAVE__GENERIC 1
 # else
-#  define HAVE_GENERIC 0
+#  define HAVE__GENERIC 0
 # endif
 #endif
 /* _Generic is buggy in pre-4.9 GCC.  */
-#if !defined HAVE_GENERIC && defined __GNUC__
-# define HAVE_GENERIC (4 < __GNUC__ + (9 <= __GNUC_MINOR__))
+#if !defined HAVE__GENERIC && defined __GNUC__ && !defined __STRICT_ANSI__
+# define HAVE__GENERIC (4 < __GNUC__ + (9 <= __GNUC_MINOR__))
 #endif
-#ifndef HAVE_GENERIC
-# define HAVE_GENERIC (201112 <= __STDC_VERSION__)
+#ifndef HAVE__GENERIC
+# define HAVE__GENERIC (201112 <= __STDC_VERSION__)
 #endif
 
+#if !defined HAVE_GETTEXT && defined __has_include
+# if __has_include(<libintl.h>)
+#  define HAVE_GETTEXT true
+# endif
+#endif
 #ifndef HAVE_GETTEXT
-#define HAVE_GETTEXT		0
-#endif /* !defined HAVE_GETTEXT */
+# define HAVE_GETTEXT false
+#endif
 
 #ifndef HAVE_INCOMPATIBLE_CTIME_R
-#define HAVE_INCOMPATIBLE_CTIME_R	0
+# define HAVE_INCOMPATIBLE_CTIME_R 0
 #endif
 
 #ifndef HAVE_LINK
-#define HAVE_LINK		1
+# define HAVE_LINK 1
 #endif /* !defined HAVE_LINK */
 
 #ifndef HAVE_MALLOC_ERRNO
-#define HAVE_MALLOC_ERRNO 1
+# define HAVE_MALLOC_ERRNO 1
 #endif
 
 #ifndef HAVE_POSIX_DECLS
-#define HAVE_POSIX_DECLS 1
+# define HAVE_POSIX_DECLS 1
 #endif
 
-#ifndef HAVE_STDBOOL_H
-#define HAVE_STDBOOL_H (199901 <= __STDC_VERSION__)
+#ifndef HAVE_SETENV
+# define HAVE_SETENV 1
 #endif
 
 #ifndef HAVE_STRDUP
-#define HAVE_STRDUP 1
-#endif
-
-#ifndef HAVE_STRTOLL
-#define HAVE_STRTOLL 1
+# define HAVE_STRDUP 1
 #endif
 
 #ifndef HAVE_SYMLINK
-#define HAVE_SYMLINK		1
+# define HAVE_SYMLINK 1
 #endif /* !defined HAVE_SYMLINK */
 
+#if !defined HAVE_SYS_STAT_H && defined __has_include
+# if !__has_include(<sys/stat.h>)
+#  define HAVE_SYS_STAT_H false
+# endif
+#endif
 #ifndef HAVE_SYS_STAT_H
-#define HAVE_SYS_STAT_H		1
-#endif /* !defined HAVE_SYS_STAT_H */
+# define HAVE_SYS_STAT_H true
+#endif
 
+#if !defined HAVE_UNISTD_H && defined __has_include
+# if !__has_include(<unistd.h>)
+#  define HAVE_UNISTD_H false
+# endif
+#endif
 #ifndef HAVE_UNISTD_H
-#define HAVE_UNISTD_H		1
-#endif /* !defined HAVE_UNISTD_H */
-
-#ifndef HAVE_UTMPX_H
-#define HAVE_UTMPX_H		1
-#endif /* !defined HAVE_UTMPX_H */
+# define HAVE_UNISTD_H true
+#endif
 
 #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
+# define asctime_r _incompatible_asctime_r
+# define ctime_r _incompatible_ctime_r
 #endif /* HAVE_INCOMPATIBLE_CTIME_R */
 
 /* Enable tm_gmtoff, tm_zone, and environ on GNUish systems.  */
@@ -118,15 +155,17 @@
 /* Enable strtoimax on pre-C99 Solaris 11.  */
 #define __EXTENSIONS__ 1
 
-/* To avoid having 'stat' fail unnecessarily with errno == EOVERFLOW,
-   enable large files on GNUish systems ...  */
+/* On GNUish systems where time_t might be 32 or 64 bits, use 64.
+   On these platforms _FILE_OFFSET_BITS must also be 64; otherwise
+   setting _TIME_BITS to 64 does not work.  The code does not
+   otherwise rely on _FILE_OFFSET_BITS being 64, since it does not
+   use off_t or functions like 'stat' that depend on off_t.  */
 #ifndef _FILE_OFFSET_BITS
 # define _FILE_OFFSET_BITS 64
 #endif
-/* ... and on AIX ...  */
-#define _LARGE_FILES 1
-/* ... and enable large inode numbers on Mac OS X 10.5 and later.  */
-#define _DARWIN_USE_64_BIT_INODE 1
+#if !defined _TIME_BITS && _FILE_OFFSET_BITS == 64
+# define _TIME_BITS 64
+#endif
 
 /*
 ** Nested includes
@@ -157,8 +196,11 @@
 #undef tzalloc
 #undef tzfree
 
-#include <sys/types.h>	/* for time_t */
+#include <stddef.h>
 #include <string.h>
+#if !PORT_TO_C89
+# include <inttypes.h>
+#endif
 #include <limits.h>	/* for CHAR_BIT et al. */
 #include <stdlib.h>
 
@@ -168,6 +210,9 @@
 # define EINVAL ERANGE
 #endif
 
+#ifndef ELOOP
+# define ELOOP EINVAL
+#endif
 #ifndef ENAMETOOLONG
 # define ENAMETOOLONG EINVAL
 #endif
@@ -182,11 +227,11 @@
 #endif
 
 #if HAVE_GETTEXT
-#include <libintl.h>
+# include <libintl.h>
 #endif /* HAVE_GETTEXT */
 
 #if HAVE_UNISTD_H
-#include <unistd.h>	/* for R_OK, and other POSIX goodness */
+# include <unistd.h> /* for R_OK, and other POSIX goodness */
 #endif /* HAVE_UNISTD_H */
 
 #ifndef HAVE_STRFTIME_L
@@ -222,24 +267,29 @@
 #endif
 
 #ifndef R_OK
-#define R_OK	4
+# define R_OK 4
 #endif /* !defined R_OK */
 
+#if PORT_TO_C89
+
 /*
 ** Define HAVE_STDINT_H's default value here, rather than at the
 ** start, since __GLIBC__ and INTMAX_MAX's values depend on
-** previously-included files.  glibc 2.1 and Solaris 10 and later have
+** previously included files.  glibc 2.1 and Solaris 10 and later have
 ** stdint.h, even with pre-C99 compilers.
 */
+#if !defined HAVE_STDINT_H && defined __has_include
+# define HAVE_STDINT_H true /* C23 __has_include implies C99 stdint.h.  */
+#endif
 #ifndef HAVE_STDINT_H
-#define HAVE_STDINT_H \
+# define HAVE_STDINT_H \
    (199901 <= __STDC_VERSION__ \
-    || 2 < __GLIBC__ + (1 <= __GLIBC_MINOR__)	\
+    || 2 < __GLIBC__ + (1 <= __GLIBC_MINOR__) \
     || __CYGWIN__ || INTMAX_MAX)
 #endif /* !defined HAVE_STDINT_H */
 
 #if HAVE_STDINT_H
-#include <stdint.h>
+# include <stdint.h>
 #endif /* !HAVE_STDINT_H */
 
 #ifndef HAVE_INTTYPES_H
@@ -250,36 +300,36 @@
 #endif
 
 /* Pre-C99 GCC compilers define __LONG_LONG_MAX__ instead of LLONG_MAX.  */
-#ifdef __LONG_LONG_MAX__
+#if defined __LONG_LONG_MAX__ && !defined __STRICT_ANSI__
 # ifndef LLONG_MAX
 #  define LLONG_MAX __LONG_LONG_MAX__
 # endif
 # ifndef LLONG_MIN
 #  define LLONG_MIN (-1 - LLONG_MAX)
 # endif
+# ifndef ULLONG_MAX
+#  define ULLONG_MAX (LLONG_MAX * 2ull + 1)
+# 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
-#  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
-typedef long		int_fast64_t;
+# if 1 <= LONG_MAX >> 31 >> 31
+typedef long int_fast64_t;
 #  define INT_FAST64_MIN LONG_MIN
 #  define INT_FAST64_MAX LONG_MAX
+# else
+/* If this fails, compile with -DHAVE_STDINT_H or with a better compiler.  */
+typedef long long int_fast64_t;
+#  define INT_FAST64_MIN LLONG_MIN
+#  define INT_FAST64_MAX LLONG_MAX
 # endif
 #endif
 
 #ifndef PRIdFAST64
-# if INT_FAST64_MAX == LLONG_MAX
-#  define PRIdFAST64 "lld"
-# else
+# if INT_FAST64_MAX == LONG_MAX
 #  define PRIdFAST64 "ld"
+# else
+#  define PRIdFAST64 "lld"
 # endif
 #endif
 
@@ -302,6 +352,9 @@
 #ifndef INTMAX_MAX
 # ifdef LLONG_MAX
 typedef long long intmax_t;
+#  ifndef HAVE_STRTOLL
+#   define HAVE_STRTOLL true
+#  endif
 #  if HAVE_STRTOLL
 #   define strtoimax strtoll
 #  endif
@@ -325,70 +378,183 @@
 # endif
 #endif
 
+#ifndef PTRDIFF_MAX
+# define PTRDIFF_MAX MAXVAL(ptrdiff_t, TYPE_BIT(ptrdiff_t))
+#endif
+
 #ifndef UINT_FAST32_MAX
 typedef unsigned long uint_fast32_t;
 #endif
 
 #ifndef UINT_FAST64_MAX
-# if defined ULLONG_MAX || defined __LONG_LONG_MAX__
-typedef unsigned long long uint_fast64_t;
+# if 3 <= ULONG_MAX >> 31 >> 31
+typedef unsigned long uint_fast64_t;
+#  define UINT_FAST64_MAX ULONG_MAX
 # 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;
+/* If this fails, compile with -DHAVE_STDINT_H or with a better compiler.  */
+typedef unsigned long long uint_fast64_t;
+#  define UINT_FAST64_MAX ULLONG_MAX
 # endif
 #endif
 
 #ifndef UINTMAX_MAX
-# if defined ULLONG_MAX || defined __LONG_LONG_MAX__
+# ifdef ULLONG_MAX
 typedef unsigned long long uintmax_t;
+#  define UINTMAX_MAX ULLONG_MAX
 # else
 typedef unsigned long uintmax_t;
+#  define UINTMAX_MAX ULONG_MAX
 # endif
 #endif
 
 #ifndef PRIuMAX
-# if defined ULLONG_MAX || defined __LONG_LONG_MAX__
+# ifdef ULLONG_MAX
 #  define PRIuMAX "llu"
 # else
 #  define PRIuMAX "lu"
 # endif
 #endif
 
-#ifndef INT32_MAX
-#define INT32_MAX 0x7fffffff
-#endif /* !defined INT32_MAX */
-#ifndef INT32_MIN
-#define INT32_MIN (-1 - INT32_MAX)
-#endif /* !defined INT32_MIN */
-
 #ifndef SIZE_MAX
-#define SIZE_MAX ((size_t) -1)
+# define SIZE_MAX ((size_t) -1)
+#endif
+
+#endif /* PORT_TO_C89 */
+
+/* The maximum size of any created object, as a signed integer.
+   Although the C standard does not outright prohibit larger objects,
+   behavior is undefined if the result of pointer subtraction does not
+   fit into ptrdiff_t, and the code assumes in several places that
+   pointer subtraction works.  As a practical matter it's OK to not
+   support objects larger than this.  */
+#define INDEX_MAX ((ptrdiff_t) min(PTRDIFF_MAX, SIZE_MAX))
+
+/* Support ckd_add, ckd_sub, ckd_mul on C23 or recent-enough GCC-like
+   hosts, unless compiled with -DHAVE_STDCKDINT_H=0 or with pre-C23 EDG.  */
+#if !defined HAVE_STDCKDINT_H && defined __has_include
+# if __has_include(<stdckdint.h>)
+#  define HAVE_STDCKDINT_H true
+# endif
+#endif
+#ifdef HAVE_STDCKDINT_H
+# if HAVE_STDCKDINT_H
+#  include <stdckdint.h>
+# endif
+#elif defined __EDG__
+/* Do nothing, to work around EDG bug <https://bugs.gnu.org/53256>.  */
+#elif defined __has_builtin
+# if __has_builtin(__builtin_add_overflow)
+#  define ckd_add(r, a, b) __builtin_add_overflow(a, b, r)
+# endif
+# if __has_builtin(__builtin_sub_overflow)
+#  define ckd_sub(r, a, b) __builtin_sub_overflow(a, b, r)
+# endif
+# if __has_builtin(__builtin_mul_overflow)
+#  define ckd_mul(r, a, b) __builtin_mul_overflow(a, b, r)
+# endif
+#elif 7 <= __GNUC__
+# define ckd_add(r, a, b) __builtin_add_overflow(a, b, r)
+# define ckd_sub(r, a, b) __builtin_sub_overflow(a, b, r)
+# define ckd_mul(r, a, b) __builtin_mul_overflow(a, b, r)
 #endif
 
 #if 3 <= __GNUC__
-# define ATTRIBUTE_CONST __attribute__((const))
-# define ATTRIBUTE_MALLOC __attribute__((__malloc__))
-# define ATTRIBUTE_PURE __attribute__((__pure__))
-# define ATTRIBUTE_FORMAT(spec) __attribute__((__format__ spec))
+# define ATTRIBUTE_MALLOC __attribute__((malloc))
+# define ATTRIBUTE_FORMAT(spec) __attribute__((format spec))
 #else
-# define ATTRIBUTE_CONST /* empty */
 # define ATTRIBUTE_MALLOC /* empty */
-# define ATTRIBUTE_PURE /* empty */
 # define ATTRIBUTE_FORMAT(spec) /* empty */
 #endif
 
-#if !defined _Noreturn && __STDC_VERSION__ < 201112
-# if 2 < __GNUC__ + (8 <= __GNUC_MINOR__)
-#  define _Noreturn __attribute__((__noreturn__))
+#if (defined __has_c_attribute \
+     && (202311 <= __STDC_VERSION__ || !defined __STRICT_ANSI__))
+# define HAVE___HAS_C_ATTRIBUTE true
+#else
+# define HAVE___HAS_C_ATTRIBUTE false
+#endif
+
+#if HAVE___HAS_C_ATTRIBUTE
+# if __has_c_attribute(deprecated)
+#  define ATTRIBUTE_DEPRECATED [[deprecated]]
+# endif
+#endif
+#ifndef ATTRIBUTE_DEPRECATED
+# if 3 < __GNUC__ + (2 <= __GNUC_MINOR__)
+#  define ATTRIBUTE_DEPRECATED __attribute__((deprecated))
 # else
-#  define _Noreturn
+#  define ATTRIBUTE_DEPRECATED /* empty */
 # endif
 #endif
 
-#if __STDC_VERSION__ < 199901 && !defined restrict
+#if HAVE___HAS_C_ATTRIBUTE
+# if __has_c_attribute(fallthrough)
+#  define ATTRIBUTE_FALLTHROUGH [[fallthrough]]
+# endif
+#endif
+#ifndef ATTRIBUTE_FALLTHROUGH
+# if 7 <= __GNUC__
+#  define ATTRIBUTE_FALLTHROUGH __attribute__((fallthrough))
+# else
+#  define ATTRIBUTE_FALLTHROUGH ((void) 0)
+# endif
+#endif
+
+#if HAVE___HAS_C_ATTRIBUTE
+# if __has_c_attribute(maybe_unused)
+#  define ATTRIBUTE_MAYBE_UNUSED [[maybe_unused]]
+# endif
+#endif
+#ifndef ATTRIBUTE_MAYBE_UNUSED
+# if 2 < __GNUC__ + (7 <= __GNUC_MINOR__)
+#  define ATTRIBUTE_MAYBE_UNUSED __attribute__((unused))
+# else
+#  define ATTRIBUTE_MAYBE_UNUSED /* empty */
+# endif
+#endif
+
+#if HAVE___HAS_C_ATTRIBUTE
+# if __has_c_attribute(noreturn)
+#  define ATTRIBUTE_NORETURN [[noreturn]]
+# endif
+#endif
+#ifndef ATTRIBUTE_NORETURN
+# if 201112 <= __STDC_VERSION__
+#  define ATTRIBUTE_NORETURN _Noreturn
+# elif 2 < __GNUC__ + (8 <= __GNUC_MINOR__)
+#  define ATTRIBUTE_NORETURN __attribute__((noreturn))
+# else
+#  define ATTRIBUTE_NORETURN /* empty */
+# endif
+#endif
+
+#if HAVE___HAS_C_ATTRIBUTE
+# if __has_c_attribute(reproducible)
+#  define ATTRIBUTE_REPRODUCIBLE [[reproducible]]
+# endif
+#endif
+#ifndef ATTRIBUTE_REPRODUCIBLE
+# if 3 <= __GNUC__
+#  define ATTRIBUTE_REPRODUCIBLE __attribute__((pure))
+# else
+#  define ATTRIBUTE_REPRODUCIBLE /* empty */
+# endif
+#endif
+
+#if HAVE___HAS_C_ATTRIBUTE
+# if __has_c_attribute(unsequenced)
+#  define ATTRIBUTE_UNSEQUENCED [[unsequenced]]
+# endif
+#endif
+#ifndef ATTRIBUTE_UNSEQUENCED
+# if 3 <= __GNUC__
+#  define ATTRIBUTE_UNSEQUENCED __attribute__((const))
+# else
+#  define ATTRIBUTE_UNSEQUENCED /* empty */
+# endif
+#endif
+
+#if (__STDC_VERSION__ < 199901 && !defined restrict \
+     && (PORT_TO_C89 || defined _MSC_VER))
 # define restrict /* empty */
 #endif
 
@@ -505,11 +671,16 @@
 #  define altzone tz_altzone
 # endif
 
-char *asctime(struct tm const *);
+# if __STDC_VERSION__ < 202311
+#  define DEPRECATED_IN_C23 /* empty */
+# else
+#  define DEPRECATED_IN_C23 ATTRIBUTE_DEPRECATED
+# endif
+DEPRECATED_IN_C23 char *asctime(struct tm const *);
 char *asctime_r(struct tm const *restrict, char *restrict);
-char *ctime(time_t const *);
+DEPRECATED_IN_C23 char *ctime(time_t const *);
 char *ctime_r(time_t const *, char *);
-double difftime(time_t, time_t) ATTRIBUTE_CONST;
+ATTRIBUTE_UNSEQUENCED double difftime(time_t, time_t);
 size_t strftime(char *restrict, size_t, char const *restrict,
 		struct tm const *restrict);
 # if HAVE_STRFTIME_L
@@ -522,9 +693,24 @@
 struct tm *localtime_r(time_t const *restrict, struct tm *restrict);
 time_t mktime(struct tm *);
 time_t time(time_t *);
+time_t timegm(struct tm *);
 void tzset(void);
 #endif
 
+#ifndef HAVE_DECL_TIMEGM
+# if (202311 <= __STDC_VERSION__ \
+      || defined __GLIBC__ || defined __tm_zone /* musl */ \
+      || defined __FreeBSD__ || defined __NetBSD__ || defined __OpenBSD__ \
+      || (defined __APPLE__ && defined __MACH__))
+#  define HAVE_DECL_TIMEGM true
+# else
+#  define HAVE_DECL_TIMEGM false
+# endif
+#endif
+#if !HAVE_DECL_TIMEGM && !defined timegm
+time_t timegm(struct tm *);
+#endif
+
 #if !HAVE_DECL_ASCTIME_R && !defined asctime_r
 extern char *asctime_r(struct tm const *restrict, char *restrict);
 #endif
@@ -557,13 +743,13 @@
 ** declarations if time_tz is defined.
 */
 
-#ifdef STD_INSPIRED
+#ifndef STD_INSPIRED
+# define STD_INSPIRED 0
+#endif
+#if STD_INSPIRED
 # if TZ_TIME_T || !defined offtime
 struct tm *offtime(time_t const *, long);
 # endif
-# if TZ_TIME_T || !defined timegm
-time_t timegm(struct tm *);
-# endif
 # if TZ_TIME_T || !defined timelocal
 time_t timelocal(struct tm *);
 # endif
@@ -581,6 +767,7 @@
 /* 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 __tm_zone /* musl */ \
      || defined __FreeBSD__ || defined __NetBSD__ || defined __OpenBSD__ \
      || (defined __APPLE__ && defined __MACH__))
 # if !defined TM_GMTOFF && !defined NO_TM_GMTOFF
@@ -606,12 +793,12 @@
 time_t mktime_z(timezone_t restrict, struct tm *restrict);
 timezone_t tzalloc(char const *);
 void tzfree(timezone_t);
-# ifdef STD_INSPIRED
+# if STD_INSPIRED
 #  if TZ_TIME_T || !defined posix2time_z
-time_t posix2time_z(timezone_t, time_t) ATTRIBUTE_PURE;
+ATTRIBUTE_REPRODUCIBLE time_t posix2time_z(timezone_t, time_t);
 #  endif
 #  if TZ_TIME_T || !defined time2posix_z
-time_t time2posix_z(timezone_t, time_t) ATTRIBUTE_PURE;
+ATTRIBUTE_REPRODUCIBLE time_t time2posix_z(timezone_t, time_t);
 #  endif
 # endif
 #endif
@@ -620,18 +807,15 @@
 ** Finally, some convenience items.
 */
 
-#if HAVE_STDBOOL_H
-# include <stdbool.h>
-#else
-# define true 1
-# define false 0
-# define bool int
-#endif
-
-#define TYPE_BIT(type)	(sizeof(type) * CHAR_BIT)
+#define TYPE_BIT(type) (CHAR_BIT * (ptrdiff_t) sizeof(type))
 #define TYPE_SIGNED(type) (((type) -1) < 0)
 #define TWOS_COMPLEMENT(t) ((t) ~ (t) 0 < 0)
 
+/* Minimum and maximum of two values.  Use lower case to avoid
+   naming clashes with standard include files.  */
+#define max(a, b) ((a) > (b) ? (a) : (b))
+#define min(a, b) ((a) < (b) ? (a) : (b))
+
 /* 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.  */
@@ -651,7 +835,7 @@
    This implementation assumes no padding if time_t is signed and
    either the compiler lacks support for _Generic or time_t is not one
    of the standard signed integer types.  */
-#if HAVE_GENERIC
+#if HAVE__GENERIC
 # define TIME_T_MIN \
     _Generic((time_t) 0, \
 	     signed char: SCHAR_MIN, short: SHRT_MIN, \
@@ -664,10 +848,23 @@
 		int: INT_MAX, long: LONG_MAX, long long: LLONG_MAX, \
 		default: TIME_T_MAX_NO_PADDING)			    \
      : (time_t) -1)
+enum { SIGNED_PADDING_CHECK_NEEDED
+         = _Generic((time_t) 0,
+		    signed char: false, short: false,
+		    int: false, long: false, long long: false,
+		    default: true) };
 #else
 # define TIME_T_MIN TIME_T_MIN_NO_PADDING
 # define TIME_T_MAX TIME_T_MAX_NO_PADDING
+enum { SIGNED_PADDING_CHECK_NEEDED = true };
 #endif
+/* Try to check the padding assumptions.  Although TIME_T_MAX and the
+   following check can both have undefined behavior on oddball
+   platforms due to shifts exceeding widths of signed integers, these
+   platforms' compilers are likely to diagnose these issues in integer
+   constant expressions, so it shouldn't hurt to check statically.  */
+static_assert(! TYPE_SIGNED(time_t) || ! SIGNED_PADDING_CHECK_NEEDED
+	      || TIME_T_MAX >> (TYPE_BIT(time_t) - 2) == 1);
 
 /*
 ** 302 / 1000 is log10(2.0) rounded up.
@@ -689,21 +886,30 @@
 # define INITIALIZE(x)
 #endif
 
+/* Whether memory access must strictly follow the C standard.
+   If 0, it's OK to read uninitialized storage so long as the value is
+   not relied upon.  Defining it to 0 lets mktime access parts of
+   struct tm that might be uninitialized, as a heuristic when the
+   standard doesn't say what to return and when tm_gmtoff can help
+   mktime likely infer a better value.  */
 #ifndef UNINIT_TRAP
 # define UNINIT_TRAP 0
 #endif
 
 #ifdef DEBUG
-# define UNREACHABLE() abort()
-#elif 4 < __GNUC__ + (5 <= __GNUC_MINOR__)
-# define UNREACHABLE() __builtin_unreachable()
-#elif defined __has_builtin
-# if __has_builtin(__builtin_unreachable)
-#  define UNREACHABLE() __builtin_unreachable()
+# undef unreachable
+# define unreachable() abort()
+#elif !defined unreachable
+# ifdef __has_builtin
+#  if __has_builtin(__builtin_unreachable)
+#   define unreachable() __builtin_unreachable()
+#  endif
+# elif 4 < __GNUC__ + (5 <= __GNUC_MINOR__)
+#  define unreachable() __builtin_unreachable()
 # endif
-#endif
-#ifndef UNREACHABLE
-# define UNREACHABLE() ((void) 0)
+# ifndef unreachable
+#  define unreachable() ((void) 0)
+# endif
 #endif
 
 /*
@@ -725,53 +931,61 @@
 #if HAVE_INCOMPATIBLE_CTIME_R
 #undef asctime_r
 #undef ctime_r
-char *asctime_r(struct tm const *, char *);
+char *asctime_r(struct tm const *restrict, char *restrict);
 char *ctime_r(time_t const *, char *);
 #endif /* HAVE_INCOMPATIBLE_CTIME_R */
 
 /* Handy macros that are independent of tzfile implementation.  */
 
-#define SECSPERMIN	60
-#define MINSPERHOUR	60
-#define HOURSPERDAY	24
-#define DAYSPERWEEK	7
-#define DAYSPERNYEAR	365
-#define DAYSPERLYEAR	366
-#define SECSPERHOUR	(SECSPERMIN * MINSPERHOUR)
-#define SECSPERDAY	((int_fast32_t) SECSPERHOUR * HOURSPERDAY)
-#define MONSPERYEAR	12
+enum {
+  SECSPERMIN = 60,
+  MINSPERHOUR = 60,
+  SECSPERHOUR = SECSPERMIN * MINSPERHOUR,
+  HOURSPERDAY = 24,
+  DAYSPERWEEK = 7,
+  DAYSPERNYEAR = 365,
+  DAYSPERLYEAR = DAYSPERNYEAR + 1,
+  MONSPERYEAR = 12,
+  YEARSPERREPEAT = 400	/* years before a Gregorian repeat */
+};
 
-#define YEARSPERREPEAT		400	/* years before a Gregorian repeat */
+#define SECSPERDAY	((int_fast32_t) SECSPERHOUR * HOURSPERDAY)
+
 #define DAYSPERREPEAT		((int_fast32_t) 400 * 365 + 100 - 4 + 1)
 #define SECSPERREPEAT		((int_fast64_t) DAYSPERREPEAT * SECSPERDAY)
 #define AVGSECSPERYEAR		(SECSPERREPEAT / YEARSPERREPEAT)
 
-#define TM_SUNDAY	0
-#define TM_MONDAY	1
-#define TM_TUESDAY	2
-#define TM_WEDNESDAY	3
-#define TM_THURSDAY	4
-#define TM_FRIDAY	5
-#define TM_SATURDAY	6
+enum {
+  TM_SUNDAY,
+  TM_MONDAY,
+  TM_TUESDAY,
+  TM_WEDNESDAY,
+  TM_THURSDAY,
+  TM_FRIDAY,
+  TM_SATURDAY
+};
 
-#define TM_JANUARY	0
-#define TM_FEBRUARY	1
-#define TM_MARCH	2
-#define TM_APRIL	3
-#define TM_MAY		4
-#define TM_JUNE		5
-#define TM_JULY		6
-#define TM_AUGUST	7
-#define TM_SEPTEMBER	8
-#define TM_OCTOBER	9
-#define TM_NOVEMBER	10
-#define TM_DECEMBER	11
+enum {
+  TM_JANUARY,
+  TM_FEBRUARY,
+  TM_MARCH,
+  TM_APRIL,
+  TM_MAY,
+  TM_JUNE,
+  TM_JULY,
+  TM_AUGUST,
+  TM_SEPTEMBER,
+  TM_OCTOBER,
+  TM_NOVEMBER,
+  TM_DECEMBER
+};
 
-#define TM_YEAR_BASE	1900
-#define TM_WDAY_BASE	TM_MONDAY
-
-#define EPOCH_YEAR	1970
-#define EPOCH_WDAY	TM_THURSDAY
+enum {
+  TM_YEAR_BASE = 1900,
+  TM_WDAY_BASE = TM_MONDAY,
+  EPOCH_YEAR = 1970,
+  EPOCH_WDAY = TM_THURSDAY
+};
 
 #define isleap(y) (((y) % 4) == 0 && (((y) % 100) != 0 || ((y) % 400) == 0))
 
diff --git a/libc/tzcode/strftime.c b/libc/tzcode/strftime.c
index d04c5ba..4cde556 100644
--- a/libc/tzcode/strftime.c
+++ b/libc/tzcode/strftime.c
@@ -71,8 +71,6 @@
     const char *    date_fmt;
 };
 
-#define Locale  (&C_time_locale)
-
 static const struct lc_time_T   C_time_locale = {
     {
         "Jan", "Feb", "Mar", "Apr", "May", "Jun",
@@ -128,13 +126,14 @@
 static char *   _yconv(int, int, bool, bool, char *, const char *, int);
 
 #ifndef YEAR_2000_NAME
-#define YEAR_2000_NAME  "CHECK_STRFTIME_FORMATS_FOR_TWO_DIGIT_YEARS"
+# define YEAR_2000_NAME  "CHECK_STRFTIME_FORMATS_FOR_TWO_DIGIT_YEARS"
 #endif /* !defined YEAR_2000_NAME */
 
 #if HAVE_STRFTIME_L
 size_t
-strftime_l(char *s, size_t maxsize, char const *format, struct tm const *t,
-	   locale_t locale)
+strftime_l(char *restrict s, size_t maxsize, char const *restrict format,
+	   struct tm const *restrict t,
+	   ATTRIBUTE_MAYBE_UNUSED locale_t locale)
 {
   /* Just call strftime, as only the C locale is supported.  */
   return strftime(s, maxsize, format, t);
@@ -144,7 +143,8 @@
 #define FORCE_LOWER_CASE 0x100 /* Android extension. */
 
 size_t
-strftime(char *s, size_t maxsize, const char *format, const struct tm *t)
+strftime(char *restrict s, size_t maxsize, char const *restrict format,
+	 struct tm const *restrict t)
 {
     char *  p;
     int saved_errno = errno;
@@ -217,6 +217,8 @@
 _fmt(const char *format, const struct tm *t, char *pt,
         const char *ptlim, enum warn *warnp)
 {
+	struct lc_time_T const *Locale = &C_time_locale;
+
     for ( ; *format; ++format) {
         if (*format == '%') {
             int modifier = 0;
@@ -378,12 +380,21 @@
                     char buf[INT_STRLEN_MAXIMUM(time64_t) + 1] __attribute__((__uninitialized__));
                     time64_t    mkt;
 
-                    tm = *t;
+          					tm.tm_sec = t->tm_sec;
+					          tm.tm_min = t->tm_min;
+          					tm.tm_hour = t->tm_hour;
+					          tm.tm_mday = t->tm_mday;
+          					tm.tm_mon = t->tm_mon;
+					          tm.tm_year = t->tm_year;
+          					tm.tm_isdst = t->tm_isdst;
+#if defined TM_GMTOFF && ! UNINIT_TRAP
+					          tm.TM_GMTOFF = t->TM_GMTOFF;
+#endif
                     mkt = mktime64(&tm);
-					/* There is no portable, definitive
-					   test for whether whether mktime
-					   succeeded, so treat (time_t) -1 as
-					   the success that it might be.  */
+					/* If mktime fails, %s expands to the
+              value of (time_t) -1 as a failure
+              marker; this is better in practice
+              than strftime failing.  */
                     if (TYPE_SIGNED(time64_t)) {
                       intmax_t n = mkt;
                       sprintf(buf, "%"PRIdMAX, n);
@@ -607,19 +618,19 @@
 # endif
                 negative = diff < 0;
                 if (diff == 0) {
-#ifdef TM_ZONE
+# ifdef TM_ZONE
                   // Android-changed: do not use TM_ZONE as it is as it may be null.
                   {
                     const char* zone = _safe_tm_zone(t);
                     negative = zone[0] == '-';
                   }
-#else
+# else
                     negative = t->tm_isdst < 0;
-# if HAVE_TZNAME
+#  if HAVE_TZNAME
                     if (tzname[t->tm_isdst != 0][0] == '-')
                         negative = true;
+#  endif
 # endif
-#endif
                 }
                 if (negative) {
                     sign = "-";
@@ -748,7 +759,7 @@
     register int    lead;
     register int    trail;
 
-#define DIVISOR 100
+    int DIVISOR = 100;
     trail = a % DIVISOR + b % DIVISOR;
     lead = a / DIVISOR + b / DIVISOR + trail / DIVISOR;
     trail %= DIVISOR;
diff --git a/libc/tzcode/tzfile.h b/libc/tzcode/tzfile.h
index c5f9967..7ac8b51 100644
--- a/libc/tzcode/tzfile.h
+++ b/libc/tzcode/tzfile.h
@@ -22,15 +22,15 @@
 */
 
 #ifndef TZDIR
-#define TZDIR	"/usr/share/zoneinfo" /* Time zone object file directory */
+# define TZDIR "/usr/share/zoneinfo" /* Time zone object file directory */
 #endif /* !defined TZDIR */
 
 #ifndef TZDEFAULT
-#define TZDEFAULT	"/etc/localtime"
+# define TZDEFAULT "/etc/localtime"
 #endif /* !defined TZDEFAULT */
 
 #ifndef TZDEFRULES
-#define TZDEFRULES	"posixrules"
+# define TZDEFRULES "posixrules"
 #endif /* !defined TZDEFRULES */
 
 
@@ -103,21 +103,25 @@
 */
 
 #ifndef TZ_MAX_TIMES
-#define TZ_MAX_TIMES	2000
+/* This must be at least 242 for Europe/London with 'zic -b fat'.  */
+# define TZ_MAX_TIMES 2000
 #endif /* !defined TZ_MAX_TIMES */
 
 #ifndef TZ_MAX_TYPES
-/* This must be at least 17 for Europe/Samara and Europe/Vilnius.  */
-#define TZ_MAX_TYPES	256 /* Limited by what (unsigned char)'s can hold */
+/* This must be at least 18 for Europe/Vilnius with 'zic -b fat'.  */
+# define TZ_MAX_TYPES 256 /* Limited by what (unsigned char)'s can hold */
 #endif /* !defined TZ_MAX_TYPES */
 
 #ifndef TZ_MAX_CHARS
-#define TZ_MAX_CHARS	50	/* Maximum number of abbreviation characters */
+/* This must be at least 40 for America/Anchorage.  */
+# define TZ_MAX_CHARS 50	/* Maximum number of abbreviation characters */
 				/* (limited by what unsigned chars can hold) */
 #endif /* !defined TZ_MAX_CHARS */
 
 #ifndef TZ_MAX_LEAPS
-#define TZ_MAX_LEAPS	50	/* Maximum number of leap second corrections */
+/* This must be at least 27 for leap seconds from 1972 through mid-2023.
+   There's a plan to discontinue leap seconds by 2035.  */
+# define TZ_MAX_LEAPS 50	/* Maximum number of leap second corrections */
 #endif /* !defined TZ_MAX_LEAPS */
 
 #define SECSPERMIN	60
diff --git a/linker/arch/riscv64/begin.S b/linker/arch/riscv64/begin.S
index f7509c6..21665cb 100644
--- a/linker/arch/riscv64/begin.S
+++ b/linker/arch/riscv64/begin.S
@@ -33,7 +33,7 @@
   .cfi_undefined ra
 
   mv a0, sp
-  jal __linker_init
+  call __linker_init
 
   // __linker_init returns the address of the entry point in the main image.
   jr a0
diff --git a/tests/Android.bp b/tests/Android.bp
index 1be1ec3..281e29d 100644
--- a/tests/Android.bp
+++ b/tests/Android.bp
@@ -503,6 +503,7 @@
         "sys_vfs_test.cpp",
         "sys_wait_test.cpp",
         "sys_xattr_test.cpp",
+        "syslog_test.cpp",
         "system_properties_test.cpp",
         "system_properties_test2.cpp",
         "termios_test.cpp",
diff --git a/tests/fortify_test.cpp b/tests/fortify_test.cpp
index 4abee67..cc3080d 100644
--- a/tests/fortify_test.cpp
+++ b/tests/fortify_test.cpp
@@ -670,6 +670,10 @@
   ASSERT_FORTIFY(readlinkat(AT_FDCWD, "/dev/null", buf, ct));
 }
 
+TEST(TEST_NAME, snprintf_nullptr_valid) {
+  ASSERT_EQ(10, snprintf(nullptr, 0, "0123456789"));
+}
+
 extern "C" char* __strncat_chk(char*, const char*, size_t, size_t);
 extern "C" char* __strcat_chk(char*, const char*, size_t);
 
diff --git a/tests/headers/posix/README.md b/tests/headers/posix/README.md
new file mode 100644
index 0000000..e7c171a
--- /dev/null
+++ b/tests/headers/posix/README.md
@@ -0,0 +1,8 @@
+# POSIX header tests
+
+These compile-time tests check that each POSIX header contains _at
+least_ what POSIX says. Every POSIX header file gets a corresponding
+`.c` file in this directory. Every constant, macro, type, struct field,
+and function in the header gets a corresponding assertion in the file.
+
+See `header_checks.h` for the implementation of the assertions.
diff --git a/tests/hwasan_test.cpp b/tests/hwasan_test.cpp
index 5c21495..e32534e 100644
--- a/tests/hwasan_test.cpp
+++ b/tests/hwasan_test.cpp
@@ -1,17 +1,29 @@
 /*
  * Copyright (C) 2023 The Android Open Source Project
+ * All rights reserved.
  *
- * 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
+ * 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.
  *
- *      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 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>
diff --git a/tests/libs/dlopen_testlib_simple_hwasan.cpp b/tests/libs/dlopen_testlib_simple_hwasan.cpp
index b92e05f..ddf8a31 100644
--- a/tests/libs/dlopen_testlib_simple_hwasan.cpp
+++ b/tests/libs/dlopen_testlib_simple_hwasan.cpp
@@ -1,17 +1,29 @@
 /*
  * Copyright (C) 2023 The Android Open Source Project
+ * All rights reserved.
  *
- * 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
+ * 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.
  *
- *      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 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>
diff --git a/tests/stdio_test.cpp b/tests/stdio_test.cpp
index 0e267c5..b85edfb 100644
--- a/tests/stdio_test.cpp
+++ b/tests/stdio_test.cpp
@@ -99,6 +99,27 @@
   ASSERT_EQ(nullptr, fgets(line, sizeof(line), fp)) << "junk at end of file: " << line;
 }
 
+#define EXPECT_SNPRINTF_N(expected, n, fmt, ...)                        \
+  {                                                                     \
+    char buf[BUFSIZ];                                                   \
+    int w = snprintf(buf, sizeof(buf), fmt __VA_OPT__(, ) __VA_ARGS__); \
+    EXPECT_EQ(n, w);                                                    \
+    EXPECT_STREQ(expected, buf);                                        \
+  }
+
+#define EXPECT_SNPRINTF(expected, fmt, ...) \
+  EXPECT_SNPRINTF_N(expected, static_cast<int>(strlen(expected)), fmt __VA_OPT__(, ) __VA_ARGS__)
+
+#define EXPECT_SWPRINTF_N(expected, n, fmt, ...)                        \
+  {                                                                     \
+    wchar_t buf[BUFSIZ];                                                \
+    int w = swprintf(buf, sizeof(buf), fmt __VA_OPT__(, ) __VA_ARGS__); \
+    EXPECT_EQ(n, w);                                                    \
+    EXPECT_EQ(std::wstring(expected), std::wstring(buf, w));            \
+  }
+#define EXPECT_SWPRINTF(expected, fmt, ...) \
+  EXPECT_SWPRINTF_N(expected, static_cast<int>(wcslen(expected)), fmt __VA_OPT__(, ) __VA_ARGS__)
+
 TEST(STDIO_TEST, flockfile_18208568_stderr) {
   // Check that we have a _recursive_ mutex for flockfile.
   flockfile(stderr);
@@ -309,21 +330,23 @@
   // error: format '%zd' expects argument of type 'signed size_t',
   //     but argument 4 has type 'ssize_t {aka long int}' [-Werror=format]
   ssize_t v = 1;
-  char buf[32];
-  snprintf(buf, sizeof(buf), "%zd", v);
+  EXPECT_SNPRINTF("1", "%zd", v);
+  EXPECT_SWPRINTF(L"1", L"%zd", v);
 }
 
 // https://code.google.com/p/android/issues/detail?id=64886
 TEST(STDIO_TEST, snprintf_a) {
-  char buf[BUFSIZ];
-  EXPECT_EQ(23, snprintf(buf, sizeof(buf), "<%a>", 9990.235));
-  EXPECT_STREQ("<0x1.3831e147ae148p+13>", buf);
+  EXPECT_SNPRINTF("<0x1.3831e147ae148p+13>", "<%a>", 9990.235);
+}
+
+// https://code.google.com/p/android/issues/detail?id=64886
+TEST(STDIO_TEST, swprintf_a) {
+  EXPECT_SWPRINTF(L"<0x1.3831e147ae148p+13>", L"<%a>", 9990.235);
 }
 
 // http://b/152588929
 TEST(STDIO_TEST, snprintf_La) {
 #if defined(__LP64__)
-  char buf[BUFSIZ];
   union {
     uint64_t a[2];
     long double v;
@@ -331,59 +354,98 @@
 
   u.a[0] = UINT64_C(0x9b9b9b9b9b9b9b9b);
   u.a[1] = UINT64_C(0xdfdfdfdfdfdfdfdf);
-  EXPECT_EQ(41, snprintf(buf, sizeof(buf), "<%La>", u.v));
-  EXPECT_STREQ("<-0x1.dfdfdfdfdfdf9b9b9b9b9b9b9b9bp+8160>", buf);
+  EXPECT_SNPRINTF("<-0x1.dfdfdfdfdfdf9b9b9b9b9b9b9b9bp+8160>", "<%La>", u.v);
 
   u.a[0] = UINT64_C(0xffffffffffffffff);
   u.a[1] = UINT64_C(0x7ffeffffffffffff);
-  EXPECT_EQ(41, snprintf(buf, sizeof(buf), "<%La>", u.v));
-  EXPECT_STREQ("<0x1.ffffffffffffffffffffffffffffp+16383>", buf);
+  EXPECT_SNPRINTF("<0x1.ffffffffffffffffffffffffffffp+16383>", "<%La>", u.v);
 
   u.a[0] = UINT64_C(0x0000000000000000);
   u.a[1] = UINT64_C(0x0000000000000000);
-  EXPECT_EQ(8, snprintf(buf, sizeof(buf), "<%La>", u.v));
-  EXPECT_STREQ("<0x0p+0>", buf);
+  EXPECT_SNPRINTF("<0x0p+0>", "<%La>", u.v);
+#else
+  GTEST_SKIP() << "no ld128";
+#endif
+}
+
+// http://b/152588929
+TEST(STDIO_TEST, swprintf_La) {
+#if defined(__LP64__)
+  union {
+    uint64_t a[2];
+    long double v;
+  } u;
+
+  u.a[0] = UINT64_C(0x9b9b9b9b9b9b9b9b);
+  u.a[1] = UINT64_C(0xdfdfdfdfdfdfdfdf);
+  EXPECT_SWPRINTF(L"<-0x1.dfdfdfdfdfdf9b9b9b9b9b9b9b9bp+8160>", L"<%La>", u.v);
+
+  u.a[0] = UINT64_C(0xffffffffffffffff);
+  u.a[1] = UINT64_C(0x7ffeffffffffffff);
+  EXPECT_SWPRINTF(L"<0x1.ffffffffffffffffffffffffffffp+16383>", L"<%La>", u.v);
+
+  u.a[0] = UINT64_C(0x0000000000000000);
+  u.a[1] = UINT64_C(0x0000000000000000);
+  EXPECT_SWPRINTF(L"<0x0p+0>", L"<%La>", u.v);
 #else
   GTEST_SKIP() << "no ld128";
 #endif
 }
 
 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);
+  EXPECT_SNPRINTF("<a>", "<%lc>", wc);
 }
 
-TEST(STDIO_TEST, snprintf_C) { // Synonym for %lc.
-  char buf[BUFSIZ];
+TEST(STDIO_TEST, swprintf_lc) {
+  wint_t wc = L'a';
+  EXPECT_SWPRINTF(L"<a>", L"<%lc>", wc);
+}
+
+TEST(STDIO_TEST, snprintf_C) {  // Synonym for %lc.
   wchar_t wc = L'a';
-  EXPECT_EQ(3, snprintf(buf, sizeof(buf), "<%C>", wc));
-  EXPECT_STREQ("<a>", buf);
+  EXPECT_SNPRINTF("<a>", "<%C>", wc);
+}
+
+TEST(STDIO_TEST, swprintf_C) {  // Synonym for %lc.
+  wchar_t wc = L'a';
+  EXPECT_SWPRINTF(L"<a>", L"<%C>", wc);
+}
+
+TEST(STDIO_TEST, snprintf_ls_null) {
+  EXPECT_SNPRINTF("<(null)>", "<%ls>", static_cast<wchar_t*>(nullptr));
+}
+
+TEST(STDIO_TEST, swprintf_ls_null) {
+  EXPECT_SWPRINTF(L"<(null)>", L"<%ls>", static_cast<wchar_t*>(nullptr));
 }
 
 TEST(STDIO_TEST, snprintf_ls) {
-  char buf[BUFSIZ];
-  wchar_t* ws = nullptr;
-  EXPECT_EQ(8, snprintf(buf, sizeof(buf), "<%ls>", ws));
-  EXPECT_STREQ("<(null)>", buf);
+  static const wchar_t chars[] = L"Hello\u0666 World";
+  EXPECT_SNPRINTF("<Hello\xd9\xa6 World>", "<%ls>", chars);
+}
 
-  wchar_t chars[] = { L'h', L'i', 0 };
-  ws = chars;
-  EXPECT_EQ(4, snprintf(buf, sizeof(buf), "<%ls>", ws));
-  EXPECT_STREQ("<hi>", buf);
+TEST(STDIO_TEST, swprintf_ls) {
+  static const wchar_t chars[] = L"Hello\u0666 World";
+  EXPECT_SWPRINTF(L"<Hello\u0666 World>", L"<%ls>", chars);
+}
+
+TEST(STDIO_TEST, snprintf_S_nullptr) {  // Synonym for %ls.
+  EXPECT_SNPRINTF("<(null)>", "<%S>", static_cast<wchar_t*>(nullptr));
+}
+
+TEST(STDIO_TEST, swprintf_S_nullptr) {  // Synonym for %ls.
+  EXPECT_SWPRINTF(L"<(null)>", L"<%S>", static_cast<wchar_t*>(nullptr));
 }
 
 TEST(STDIO_TEST, snprintf_S) { // Synonym for %ls.
-  char buf[BUFSIZ];
-  wchar_t* ws = nullptr;
-  EXPECT_EQ(8, snprintf(buf, sizeof(buf), "<%S>", ws));
-  EXPECT_STREQ("<(null)>", buf);
+  static const wchar_t chars[] = L"Hello\u0666 World";
+  EXPECT_SNPRINTF("<Hello\xd9\xa6 World>", "<%S>", chars);
+}
 
-  wchar_t chars[] = { L'h', L'i', 0 };
-  ws = chars;
-  EXPECT_EQ(4, snprintf(buf, sizeof(buf), "<%S>", ws));
-  EXPECT_STREQ("<hi>", buf);
+TEST(STDIO_TEST, swprintf_S) {  // Synonym for %ls.
+  static const wchar_t chars[] = L"Hello\u0666 World";
+  EXPECT_SWPRINTF(L"<Hello\u0666 World>", L"<%S>", chars);
 }
 
 TEST_F(STDIO_DEATHTEST, snprintf_n) {
@@ -400,106 +462,111 @@
 #endif
 }
 
+TEST_F(STDIO_DEATHTEST, swprintf_n) {
+#if defined(__BIONIC__)
+#pragma clang diagnostic push
+#pragma clang diagnostic ignored "-Wformat"
+  // http://b/14492135 and http://b/31832608.
+  wchar_t buf[32];
+  int i = 1234;
+  EXPECT_DEATH(swprintf(buf, sizeof(buf), L"a %n b", &i), "%n not allowed on Android");
+#pragma clang diagnostic pop
+#else
+  GTEST_SKIP() << "glibc does allow %n";
+#endif
+}
+
 TEST(STDIO_TEST, snprintf_measure) {
-  char buf[16];
+  char buf[1] = {'x'};
   ASSERT_EQ(11, snprintf(buf, 0, "Hello %s", "world"));
+  ASSERT_EQ('x', buf[0]);
+}
+
+// Unlike snprintf(), you *can't* use swprintf() to measure.
+TEST(STDIO_TEST, swprintf_measure) {
+  wchar_t buf[1] = {L'x'};
+  ASSERT_EQ(-1, swprintf(buf, 0, L"Hello %S", L"world"));
+  ASSERT_EQ(L'x', buf[0]);
 }
 
 TEST(STDIO_TEST, snprintf_smoke) {
-  char buf[BUFSIZ];
+  EXPECT_SNPRINTF("a", "a");
+  EXPECT_SNPRINTF("%", "%%");
+  EXPECT_SNPRINTF("01234", "01234");
+  EXPECT_SNPRINTF("a01234b", "a%sb", "01234");
 
-  snprintf(buf, sizeof(buf), "a");
-  EXPECT_STREQ("a", buf);
+  EXPECT_SNPRINTF("a(null)b", "a%sb", static_cast<char*>(nullptr));
+  EXPECT_SNPRINTF("aabbcc", "aa%scc", "bb");
+  EXPECT_SNPRINTF("abc", "a%cc", 'b');
+  EXPECT_SNPRINTF("a1234b", "a%db", 1234);
+  EXPECT_SNPRINTF("a-8123b", "a%db", -8123);
+  EXPECT_SNPRINTF("a16b", "a%hdb", static_cast<short>(0x7fff0010));
+  EXPECT_SNPRINTF("a16b", "a%hhdb", static_cast<char>(0x7fffff10));
+  EXPECT_SNPRINTF("a68719476736b", "a%lldb", 0x1000000000LL);
+  EXPECT_SNPRINTF("a70000b", "a%ldb", 70000L);
+  EXPECT_SNPRINTF("a0xb0001234b", "a%pb", reinterpret_cast<void*>(0xb0001234));
+  EXPECT_SNPRINTF("a12abz", "a%xz", 0x12ab);
+  EXPECT_SNPRINTF("a12ABz", "a%Xz", 0x12ab);
+  EXPECT_SNPRINTF("a00123456z", "a%08xz", 0x123456);
+  EXPECT_SNPRINTF("a 1234z", "a%5dz", 1234);
+  EXPECT_SNPRINTF("a01234z", "a%05dz", 1234);
+  EXPECT_SNPRINTF("a    1234z", "a%8dz", 1234);
+  EXPECT_SNPRINTF("a1234    z", "a%-8dz", 1234);
+  EXPECT_SNPRINTF("Aabcdef     Z", "A%-11sZ", "abcdef");
+  EXPECT_SNPRINTF("Ahello:1234Z", "A%s:%dZ", "hello", 1234);
+  EXPECT_SNPRINTF("a005:5:05z", "a%03d:%d:%02dz", 5, 5, 5);
 
-  snprintf(buf, sizeof(buf), "%%");
-  EXPECT_STREQ("%", buf);
-
-  snprintf(buf, sizeof(buf), "01234");
-  EXPECT_STREQ("01234", buf);
-
-  snprintf(buf, sizeof(buf), "a%sb", "01234");
-  EXPECT_STREQ("a01234b", buf);
-
-  char* s = nullptr;
-  snprintf(buf, sizeof(buf), "a%sb", s);
-  EXPECT_STREQ("a(null)b", buf);
-
-  snprintf(buf, sizeof(buf), "aa%scc", "bb");
-  EXPECT_STREQ("aabbcc", buf);
-
-  snprintf(buf, sizeof(buf), "a%cc", 'b');
-  EXPECT_STREQ("abc", buf);
-
-  snprintf(buf, sizeof(buf), "a%db", 1234);
-  EXPECT_STREQ("a1234b", buf);
-
-  snprintf(buf, sizeof(buf), "a%db", -8123);
-  EXPECT_STREQ("a-8123b", buf);
-
-  snprintf(buf, sizeof(buf), "a%hdb", static_cast<short>(0x7fff0010));
-  EXPECT_STREQ("a16b", buf);
-
-  snprintf(buf, sizeof(buf), "a%hhdb", static_cast<char>(0x7fffff10));
-  EXPECT_STREQ("a16b", buf);
-
-  snprintf(buf, sizeof(buf), "a%lldb", 0x1000000000LL);
-  EXPECT_STREQ("a68719476736b", buf);
-
-  snprintf(buf, sizeof(buf), "a%ldb", 70000L);
-  EXPECT_STREQ("a70000b", buf);
-
-  snprintf(buf, sizeof(buf), "a%pb", reinterpret_cast<void*>(0xb0001234));
-  EXPECT_STREQ("a0xb0001234b", buf);
-
-  snprintf(buf, sizeof(buf), "a%xz", 0x12ab);
-  EXPECT_STREQ("a12abz", buf);
-
-  snprintf(buf, sizeof(buf), "a%Xz", 0x12ab);
-  EXPECT_STREQ("a12ABz", buf);
-
-  snprintf(buf, sizeof(buf), "a%08xz", 0x123456);
-  EXPECT_STREQ("a00123456z", buf);
-
-  snprintf(buf, sizeof(buf), "a%5dz", 1234);
-  EXPECT_STREQ("a 1234z", buf);
-
-  snprintf(buf, sizeof(buf), "a%05dz", 1234);
-  EXPECT_STREQ("a01234z", buf);
-
-  snprintf(buf, sizeof(buf), "a%8dz", 1234);
-  EXPECT_STREQ("a    1234z", buf);
-
-  snprintf(buf, sizeof(buf), "a%-8dz", 1234);
-  EXPECT_STREQ("a1234    z", buf);
-
-  snprintf(buf, sizeof(buf), "A%-11sZ", "abcdef");
-  EXPECT_STREQ("Aabcdef     Z", buf);
-
-  snprintf(buf, sizeof(buf), "A%s:%dZ", "hello", 1234);
-  EXPECT_STREQ("Ahello:1234Z", buf);
-
-  snprintf(buf, sizeof(buf), "a%03d:%d:%02dz", 5, 5, 5);
-  EXPECT_STREQ("a005:5:05z", buf);
-
-  void* p = nullptr;
-  snprintf(buf, sizeof(buf), "a%d,%pz", 5, p);
 #if defined(__BIONIC__)
-  EXPECT_STREQ("a5,0x0z", buf);
+  EXPECT_SNPRINTF("a5,0x0z", "a%d,%pz", 5, static_cast<void*>(nullptr));
 #else // __BIONIC__
-  EXPECT_STREQ("a5,(nil)z", buf);
+  EXPECT_SNPRINTF("a5,(nil)z", "a%d,%pz", 5, static_cast<void*>(nullptr));
 #endif // __BIONIC__
 
-  snprintf(buf, sizeof(buf), "a%lld,%d,%d,%dz", 0x1000000000LL, 6, 7, 8);
-  EXPECT_STREQ("a68719476736,6,7,8z", buf);
+  EXPECT_SNPRINTF("a68719476736,6,7,8z", "a%lld,%d,%d,%dz", 0x1000000000LL, 6, 7, 8);
 
-  snprintf(buf, sizeof(buf), "a_%f_b", 1.23f);
-  EXPECT_STREQ("a_1.230000_b", buf);
+  EXPECT_SNPRINTF("a_1.230000_b", "a_%f_b", 1.23f);
+  EXPECT_SNPRINTF("a_3.14_b", "a_%g_b", 3.14);
+  EXPECT_SNPRINTF("print_me_twice print_me_twice", "%1$s %1$s", "print_me_twice");
+}
 
-  snprintf(buf, sizeof(buf), "a_%g_b", 3.14);
-  EXPECT_STREQ("a_3.14_b", buf);
+TEST(STDIO_TEST, swprintf_smoke) {
+  EXPECT_SWPRINTF(L"a", L"a");
+  EXPECT_SWPRINTF(L"%", L"%%");
+  EXPECT_SWPRINTF(L"01234", L"01234");
+  EXPECT_SWPRINTF(L"a01234b", L"a%sb", "01234");
 
-  snprintf(buf, sizeof(buf), "%1$s %1$s", "print_me_twice");
-  EXPECT_STREQ("print_me_twice print_me_twice", buf);
+  EXPECT_SWPRINTF(L"a(null)b", L"a%sb", static_cast<char*>(nullptr));
+  EXPECT_SWPRINTF(L"aabbcc", L"aa%scc", "bb");
+  EXPECT_SWPRINTF(L"abc", L"a%cc", 'b');
+  EXPECT_SWPRINTF(L"a1234b", L"a%db", 1234);
+  EXPECT_SWPRINTF(L"a-8123b", L"a%db", -8123);
+  EXPECT_SWPRINTF(L"a16b", L"a%hdb", static_cast<short>(0x7fff0010));
+  EXPECT_SWPRINTF(L"a16b", L"a%hhdb", static_cast<char>(0x7fffff10));
+  EXPECT_SWPRINTF(L"a68719476736b", L"a%lldb", 0x1000000000LL);
+  EXPECT_SWPRINTF(L"a70000b", L"a%ldb", 70000L);
+  EXPECT_SWPRINTF(L"a0xb0001234b", L"a%pb", reinterpret_cast<void*>(0xb0001234));
+  EXPECT_SWPRINTF(L"a12abz", L"a%xz", 0x12ab);
+  EXPECT_SWPRINTF(L"a12ABz", L"a%Xz", 0x12ab);
+  EXPECT_SWPRINTF(L"a00123456z", L"a%08xz", 0x123456);
+  EXPECT_SWPRINTF(L"a 1234z", L"a%5dz", 1234);
+  EXPECT_SWPRINTF(L"a01234z", L"a%05dz", 1234);
+  EXPECT_SWPRINTF(L"a    1234z", L"a%8dz", 1234);
+  EXPECT_SWPRINTF(L"a1234    z", L"a%-8dz", 1234);
+  EXPECT_SWPRINTF(L"Aabcdef     Z", L"A%-11sZ", "abcdef");
+  EXPECT_SWPRINTF(L"Ahello:1234Z", L"A%s:%dZ", "hello", 1234);
+  EXPECT_SWPRINTF(L"a005:5:05z", L"a%03d:%d:%02dz", 5, 5, 5);
+
+#if defined(__BIONIC__)
+  EXPECT_SWPRINTF(L"a5,0x0z", L"a%d,%pz", 5, static_cast<void*>(nullptr));
+#else   // __BIONIC__
+  EXPECT_SWPRINTF(L"a5,(nil)z", L"a%d,%pz", 5, static_cast<void*>(nullptr));
+#endif  // __BIONIC__
+
+  EXPECT_SWPRINTF(L"a68719476736,6,7,8z", L"a%lld,%d,%d,%dz", 0x1000000000LL, 6, 7, 8);
+
+  EXPECT_SWPRINTF(L"a_1.230000_b", L"a_%f_b", 1.23f);
+  EXPECT_SWPRINTF(L"a_3.14_b", L"a_%g_b", 3.14);
+  EXPECT_SWPRINTF(L"print_me_twice print_me_twice", L"%1$s %1$s", "print_me_twice");
 }
 
 template <typename T>
@@ -634,227 +701,164 @@
               L"[-NAN]", L"[NAN]", L"[+NAN]");
 }
 
-TEST(STDIO_TEST, swprintf) {
-  constexpr size_t nchars = 32;
-  wchar_t buf[nchars];
-
-  ASSERT_EQ(2, swprintf(buf, nchars, L"ab")) << strerror(errno);
-  ASSERT_EQ(std::wstring(L"ab"), buf);
-  ASSERT_EQ(5, swprintf(buf, nchars, L"%s", "abcde"));
-  ASSERT_EQ(std::wstring(L"abcde"), buf);
-
-  // Unlike swprintf(), swprintf() returns -1 in case of truncation
-  // and doesn't necessarily zero-terminate the output!
-  ASSERT_EQ(-1, swprintf(buf, 4, L"%s", "abcde"));
-
-  const char kString[] = "Hello, World";
-  ASSERT_EQ(12, swprintf(buf, nchars, L"%s", kString));
-  ASSERT_EQ(std::wstring(L"Hello, World"), buf);
-  ASSERT_EQ(12, swprintf(buf, 13, L"%s", kString));
-  ASSERT_EQ(std::wstring(L"Hello, World"), buf);
-}
-
-TEST(STDIO_TEST, swprintf_a) {
-  constexpr size_t nchars = 32;
-  wchar_t buf[nchars];
-
-  ASSERT_EQ(20, swprintf(buf, nchars, L"%a", 3.1415926535));
-  ASSERT_EQ(std::wstring(L"0x1.921fb54411744p+1"), buf);
-}
-
-TEST(STDIO_TEST, swprintf_lc) {
-  constexpr size_t nchars = 32;
-  wchar_t buf[nchars];
-
-  wint_t wc = L'a';
-  EXPECT_EQ(3, swprintf(buf, nchars, L"<%lc>", wc));
-  EXPECT_EQ(std::wstring(L"<a>"), buf);
-}
-
-TEST(STDIO_TEST, swprintf_C) { // Synonym for %lc.
-  constexpr size_t nchars = 32;
-  wchar_t buf[nchars];
-
-  wint_t wc = L'a';
-  EXPECT_EQ(3, swprintf(buf, nchars, L"<%C>", wc));
-  EXPECT_EQ(std::wstring(L"<a>"), buf);
+TEST(STDIO_TEST, snprintf_jd_INTMAX_MAX) {
+  EXPECT_SNPRINTF("9223372036854775807", "%jd", INTMAX_MAX);
 }
 
 TEST(STDIO_TEST, swprintf_jd_INTMAX_MAX) {
-  constexpr size_t nchars = 32;
-  wchar_t buf[nchars];
-
-  swprintf(buf, nchars, L"%jd", INTMAX_MAX);
-  EXPECT_EQ(std::wstring(L"9223372036854775807"), buf);
-}
-
-TEST(STDIO_TEST, swprintf_jd_INTMAX_MIN) {
-  constexpr size_t nchars = 32;
-  wchar_t buf[nchars];
-
-  swprintf(buf, nchars, L"%jd", INTMAX_MIN);
-  EXPECT_EQ(std::wstring(L"-9223372036854775808"), buf);
-}
-
-TEST(STDIO_TEST, swprintf_ju_UINTMAX_MAX) {
-  constexpr size_t nchars = 32;
-  wchar_t buf[nchars];
-
-  swprintf(buf, nchars, L"%ju", UINTMAX_MAX);
-  EXPECT_EQ(std::wstring(L"18446744073709551615"), buf);
-}
-
-TEST(STDIO_TEST, swprintf_1$ju_UINTMAX_MAX) {
-  constexpr size_t nchars = 32;
-  wchar_t buf[nchars];
-
-  swprintf(buf, nchars, L"%1$ju", UINTMAX_MAX);
-  EXPECT_EQ(std::wstring(L"18446744073709551615"), buf);
-}
-
-TEST(STDIO_TEST, swprintf_ls) {
-  constexpr size_t nchars = 32;
-  wchar_t buf[nchars];
-
-  static const wchar_t kWideString[] = L"Hello\uff41 World";
-  ASSERT_EQ(12, swprintf(buf, nchars, L"%ls", kWideString));
-  ASSERT_EQ(std::wstring(kWideString), buf);
-  ASSERT_EQ(12, swprintf(buf, 13, L"%ls", kWideString));
-  ASSERT_EQ(std::wstring(kWideString), buf);
-}
-
-TEST(STDIO_TEST, swprintf_S) { // Synonym for %ls.
-  constexpr size_t nchars = 32;
-  wchar_t buf[nchars];
-
-  static const wchar_t kWideString[] = L"Hello\uff41 World";
-  ASSERT_EQ(12, swprintf(buf, nchars, L"%S", kWideString));
-  ASSERT_EQ(std::wstring(kWideString), buf);
-  ASSERT_EQ(12, swprintf(buf, 13, L"%S", kWideString));
-  ASSERT_EQ(std::wstring(kWideString), buf);
-}
-
-TEST(STDIO_TEST, snprintf_d_INT_MAX) {
-  char buf[BUFSIZ];
-  snprintf(buf, sizeof(buf), "%d", INT_MAX);
-  EXPECT_STREQ("2147483647", buf);
-}
-
-TEST(STDIO_TEST, snprintf_d_INT_MIN) {
-  char buf[BUFSIZ];
-  snprintf(buf, sizeof(buf), "%d", INT_MIN);
-  EXPECT_STREQ("-2147483648", buf);
-}
-
-TEST(STDIO_TEST, snprintf_jd_INTMAX_MAX) {
-  char buf[BUFSIZ];
-  snprintf(buf, sizeof(buf), "%jd", INTMAX_MAX);
-  EXPECT_STREQ("9223372036854775807", buf);
+  EXPECT_SWPRINTF(L"9223372036854775807", L"%jd", INTMAX_MAX);
 }
 
 TEST(STDIO_TEST, snprintf_jd_INTMAX_MIN) {
-  char buf[BUFSIZ];
-  snprintf(buf, sizeof(buf), "%jd", INTMAX_MIN);
-  EXPECT_STREQ("-9223372036854775808", buf);
+  EXPECT_SNPRINTF("-9223372036854775808", "%jd", INTMAX_MIN);
+}
+
+TEST(STDIO_TEST, swprintf_jd_INTMAX_MIN) {
+  EXPECT_SWPRINTF(L"-9223372036854775808", L"%jd", INTMAX_MIN);
 }
 
 TEST(STDIO_TEST, snprintf_ju_UINTMAX_MAX) {
-  char buf[BUFSIZ];
-  snprintf(buf, sizeof(buf), "%ju", UINTMAX_MAX);
-  EXPECT_STREQ("18446744073709551615", buf);
+  EXPECT_SNPRINTF("18446744073709551615", "%ju", UINTMAX_MAX);
+}
+
+TEST(STDIO_TEST, swprintf_ju_UINTMAX_MAX) {
+  EXPECT_SWPRINTF(L"18446744073709551615", L"%ju", UINTMAX_MAX);
 }
 
 TEST(STDIO_TEST, snprintf_1$ju_UINTMAX_MAX) {
-  char buf[BUFSIZ];
-  snprintf(buf, sizeof(buf), "%1$ju", UINTMAX_MAX);
-  EXPECT_STREQ("18446744073709551615", buf);
+  EXPECT_SNPRINTF("18446744073709551615", "%1$ju", UINTMAX_MAX);
+}
+
+TEST(STDIO_TEST, swprintf_1$ju_UINTMAX_MAX) {
+  EXPECT_SWPRINTF(L"18446744073709551615", L"%1$ju", UINTMAX_MAX);
+}
+
+TEST(STDIO_TEST, snprintf_d_INT_MAX) {
+  EXPECT_SNPRINTF("2147483647", "%d", INT_MAX);
+}
+
+TEST(STDIO_TEST, swprintf_d_INT_MAX) {
+  EXPECT_SWPRINTF(L"2147483647", L"%d", INT_MAX);
+}
+
+TEST(STDIO_TEST, snprintf_d_INT_MIN) {
+  EXPECT_SNPRINTF("-2147483648", "%d", INT_MIN);
+}
+
+TEST(STDIO_TEST, swprintf_d_INT_MIN) {
+  EXPECT_SWPRINTF(L"-2147483648", L"%d", INT_MIN);
 }
 
 TEST(STDIO_TEST, snprintf_ld_LONG_MAX) {
-  char buf[BUFSIZ];
-  snprintf(buf, sizeof(buf), "%ld", LONG_MAX);
 #if defined(__LP64__)
-  EXPECT_STREQ("9223372036854775807", buf);
+  EXPECT_SNPRINTF("9223372036854775807", "%ld", LONG_MAX);
 #else
-  EXPECT_STREQ("2147483647", buf);
+  EXPECT_SNPRINTF("2147483647", "%ld", LONG_MAX);
+#endif
+}
+
+TEST(STDIO_TEST, swprintf_ld_LONG_MAX) {
+#if defined(__LP64__)
+  EXPECT_SWPRINTF(L"9223372036854775807", L"%ld", LONG_MAX);
+#else
+  EXPECT_SWPRINTF(L"2147483647", L"%ld", LONG_MAX);
 #endif
 }
 
 TEST(STDIO_TEST, snprintf_ld_LONG_MIN) {
-  char buf[BUFSIZ];
-  snprintf(buf, sizeof(buf), "%ld", LONG_MIN);
 #if defined(__LP64__)
-  EXPECT_STREQ("-9223372036854775808", buf);
+  EXPECT_SNPRINTF("-9223372036854775808", "%ld", LONG_MIN);
 #else
-  EXPECT_STREQ("-2147483648", buf);
+  EXPECT_SNPRINTF("-2147483648", "%ld", LONG_MIN);
+#endif
+}
+
+TEST(STDIO_TEST, swprintf_ld_LONG_MIN) {
+#if defined(__LP64__)
+  EXPECT_SWPRINTF(L"-9223372036854775808", L"%ld", LONG_MIN);
+#else
+  EXPECT_SWPRINTF(L"-2147483648", L"%ld", LONG_MIN);
 #endif
 }
 
 TEST(STDIO_TEST, snprintf_lld_LLONG_MAX) {
-  char buf[BUFSIZ];
-  snprintf(buf, sizeof(buf), "%lld", LLONG_MAX);
-  EXPECT_STREQ("9223372036854775807", buf);
+  EXPECT_SNPRINTF("9223372036854775807", "%lld", LLONG_MAX);
+}
+
+TEST(STDIO_TEST, swprintf_lld_LLONG_MAX) {
+  EXPECT_SWPRINTF(L"9223372036854775807", L"%lld", LLONG_MAX);
 }
 
 TEST(STDIO_TEST, snprintf_lld_LLONG_MIN) {
-  char buf[BUFSIZ];
-  snprintf(buf, sizeof(buf), "%lld", LLONG_MIN);
-  EXPECT_STREQ("-9223372036854775808", buf);
+  EXPECT_SNPRINTF("-9223372036854775808", "%lld", LLONG_MIN);
+}
+
+TEST(STDIO_TEST, swprintf_lld_LLONG_MIN) {
+  EXPECT_SWPRINTF(L"-9223372036854775808", L"%lld", LLONG_MIN);
 }
 
 TEST(STDIO_TEST, snprintf_o_UINT_MAX) {
-  char buf[BUFSIZ];
-  snprintf(buf, sizeof(buf), "%o", UINT_MAX);
-  EXPECT_STREQ("37777777777", buf);
+  EXPECT_SNPRINTF("37777777777", "%o", UINT_MAX);
+}
+
+TEST(STDIO_TEST, swprintf_o_UINT_MAX) {
+  EXPECT_SWPRINTF(L"37777777777", L"%o", UINT_MAX);
 }
 
 TEST(STDIO_TEST, snprintf_u_UINT_MAX) {
-  char buf[BUFSIZ];
-  snprintf(buf, sizeof(buf), "%u", UINT_MAX);
-  EXPECT_STREQ("4294967295", buf);
+  EXPECT_SNPRINTF("4294967295", "%u", UINT_MAX);
+}
+
+TEST(STDIO_TEST, swprintf_u_UINT_MAX) {
+  EXPECT_SWPRINTF(L"4294967295", L"%u", UINT_MAX);
 }
 
 TEST(STDIO_TEST, snprintf_x_UINT_MAX) {
-  char buf[BUFSIZ];
-  snprintf(buf, sizeof(buf), "%x", UINT_MAX);
-  EXPECT_STREQ("ffffffff", buf);
+  EXPECT_SNPRINTF("ffffffff", "%x", UINT_MAX);
+}
+
+TEST(STDIO_TEST, swprintf_x_UINT_MAX) {
+  EXPECT_SWPRINTF(L"ffffffff", L"%x", UINT_MAX);
 }
 
 TEST(STDIO_TEST, snprintf_X_UINT_MAX) {
-  char buf[BUFSIZ];
-  snprintf(buf, sizeof(buf), "%X", UINT_MAX);
-  EXPECT_STREQ("FFFFFFFF", buf);
+  EXPECT_SNPRINTF("FFFFFFFF", "%X", UINT_MAX);
+}
+
+TEST(STDIO_TEST, swprintf_X_UINT_MAX) {
+  EXPECT_SWPRINTF(L"FFFFFFFF", L"%X", UINT_MAX);
 }
 
 TEST(STDIO_TEST, snprintf_e) {
-  char buf[BUFSIZ];
+  EXPECT_SNPRINTF("1.500000e+00", "%e", 1.5);
+  EXPECT_SNPRINTF("1.500000e+00", "%Le", 1.5L);
+}
 
-  snprintf(buf, sizeof(buf), "%e", 1.5);
-  EXPECT_STREQ("1.500000e+00", buf);
-
-  snprintf(buf, sizeof(buf), "%Le", 1.5L);
-  EXPECT_STREQ("1.500000e+00", buf);
+TEST(STDIO_TEST, swprintf_e) {
+  EXPECT_SWPRINTF(L"1.500000e+00", L"%e", 1.5);
+  EXPECT_SWPRINTF(L"1.500000e+00", L"%Le", 1.5L);
 }
 
 TEST(STDIO_TEST, snprintf_negative_zero_5084292) {
-  char buf[BUFSIZ];
+  EXPECT_SNPRINTF("-0.000000e+00", "%e", -0.0);
+  EXPECT_SNPRINTF("-0.000000E+00", "%E", -0.0);
+  EXPECT_SNPRINTF("-0.000000", "%f", -0.0);
+  EXPECT_SNPRINTF("-0.000000", "%F", -0.0);
+  EXPECT_SNPRINTF("-0", "%g", -0.0);
+  EXPECT_SNPRINTF("-0", "%G", -0.0);
+  EXPECT_SNPRINTF("-0x0p+0", "%a", -0.0);
+  EXPECT_SNPRINTF("-0X0P+0", "%A", -0.0);
+}
 
-  snprintf(buf, sizeof(buf), "%e", -0.0);
-  EXPECT_STREQ("-0.000000e+00", buf);
-  snprintf(buf, sizeof(buf), "%E", -0.0);
-  EXPECT_STREQ("-0.000000E+00", buf);
-  snprintf(buf, sizeof(buf), "%f", -0.0);
-  EXPECT_STREQ("-0.000000", buf);
-  snprintf(buf, sizeof(buf), "%F", -0.0);
-  EXPECT_STREQ("-0.000000", buf);
-  snprintf(buf, sizeof(buf), "%g", -0.0);
-  EXPECT_STREQ("-0", buf);
-  snprintf(buf, sizeof(buf), "%G", -0.0);
-  EXPECT_STREQ("-0", buf);
-  snprintf(buf, sizeof(buf), "%a", -0.0);
-  EXPECT_STREQ("-0x0p+0", buf);
-  snprintf(buf, sizeof(buf), "%A", -0.0);
-  EXPECT_STREQ("-0X0P+0", buf);
+TEST(STDIO_TEST, swprintf_negative_zero_5084292) {
+  EXPECT_SWPRINTF(L"-0.000000e+00", L"%e", -0.0);
+  EXPECT_SWPRINTF(L"-0.000000E+00", L"%E", -0.0);
+  EXPECT_SWPRINTF(L"-0.000000", L"%f", -0.0);
+  EXPECT_SWPRINTF(L"-0.000000", L"%F", -0.0);
+  EXPECT_SWPRINTF(L"-0", L"%g", -0.0);
+  EXPECT_SWPRINTF(L"-0", L"%G", -0.0);
+  EXPECT_SWPRINTF(L"-0x0p+0", L"%a", -0.0);
+  EXPECT_SWPRINTF(L"-0X0P+0", L"%A", -0.0);
 }
 
 TEST(STDIO_TEST, snprintf_utf8_15439554) {
@@ -915,18 +919,36 @@
   ASSERT_EQ(ENOMEM, errno);
 }
 
+TEST(STDIO_TEST, swprintf_asterisk_overflow) {
+  wchar_t buf[128];
+  ASSERT_EQ(5, swprintf(buf, sizeof(buf), L"%.*s%c", 4, "hello world", '!'));
+  ASSERT_EQ(12, swprintf(buf, sizeof(buf), L"%.*s%c", INT_MAX / 2, "hello world", '!'));
+  ASSERT_EQ(12, swprintf(buf, sizeof(buf), L"%.*s%c", INT_MAX - 1, "hello world", '!'));
+  ASSERT_EQ(12, swprintf(buf, sizeof(buf), L"%.*s%c", INT_MAX, "hello world", '!'));
+  ASSERT_EQ(12, swprintf(buf, sizeof(buf), L"%.*s%c", -1, "hello world", '!'));
+
+  // INT_MAX-1, INT_MAX, INT_MAX+1.
+  ASSERT_EQ(12, swprintf(buf, sizeof(buf), L"%.2147483646s%c", "hello world", '!'));
+  ASSERT_EQ(12, swprintf(buf, sizeof(buf), L"%.2147483647s%c", "hello world", '!'));
+  ASSERT_EQ(-1, swprintf(buf, sizeof(buf), L"%.2147483648s%c", "hello world", '!'));
+  ASSERT_EQ(ENOMEM, errno);
+}
+
 // Inspired by https://github.com/landley/toybox/issues/163.
 TEST(STDIO_TEST, printf_NULL) {
-  char buf[128];
   char* null = nullptr;
-  EXPECT_EQ(4, snprintf(buf, sizeof(buf), "<%*.*s>", 2, 2, null));
-  EXPECT_STREQ("<(n>", buf);
-  EXPECT_EQ(8, snprintf(buf, sizeof(buf), "<%*.*s>", 2, 8, null));
-  EXPECT_STREQ("<(null)>", buf);
-  EXPECT_EQ(10, snprintf(buf, sizeof(buf), "<%*.*s>", 8, 2, null));
-  EXPECT_STREQ("<      (n>", buf);
-  EXPECT_EQ(10, snprintf(buf, sizeof(buf), "<%*.*s>", 8, 8, null));
-  EXPECT_STREQ("<  (null)>", buf);
+  EXPECT_SNPRINTF("<(n>", "<%*.*s>", 2, 2, null);
+  EXPECT_SNPRINTF("<(null)>", "<%*.*s>", 2, 8, null);
+  EXPECT_SNPRINTF("<      (n>", "<%*.*s>", 8, 2, null);
+  EXPECT_SNPRINTF("<  (null)>", "<%*.*s>", 8, 8, null);
+}
+
+TEST(STDIO_TEST, wprintf_NULL) {
+  char* null = nullptr;
+  EXPECT_SWPRINTF(L"<(n>", L"<%*.*s>", 2, 2, null);
+  EXPECT_SWPRINTF(L"<(null)>", L"<%*.*s>", 2, 8, null);
+  EXPECT_SWPRINTF(L"<      (n>", L"<%*.*s>", 8, 2, null);
+  EXPECT_SWPRINTF(L"<  (null)>", L"<%*.*s>", 8, 8, null);
 }
 
 TEST(STDIO_TEST, fprintf) {
@@ -2469,7 +2491,7 @@
 }
 
 TEST_F(STDIO_DEATHTEST, snprintf_30445072_unknown_buffer_size) {
-  std::string buf = "world";
+  std::string buf = "hello";  // So the compiler doesn't know the buffer size.
   ASSERT_EXIT(snprintf(&buf[0], atol("-1"), "hello"),
               testing::KilledBySignal(SIGABRT),
               "FORTIFY: vsnprintf: size .* > SSIZE_MAX");
@@ -2482,48 +2504,36 @@
 }
 
 TEST(STDIO_TEST, printf_m) {
-  char buf[BUFSIZ];
   errno = 0;
-  snprintf(buf, sizeof(buf), "<%m>");
-  ASSERT_STREQ("<Success>", buf);
+  EXPECT_SNPRINTF("<Success>", "<%m>");
   errno = -1;
-  snprintf(buf, sizeof(buf), "<%m>");
-  ASSERT_STREQ("<Unknown error -1>", buf);
+  EXPECT_SNPRINTF("<Unknown error -1>", "<%m>");
   errno = EINVAL;
-  snprintf(buf, sizeof(buf), "<%m>");
-  ASSERT_STREQ("<Invalid argument>", buf);
-}
-
-TEST(STDIO_TEST, printf_m_does_not_clobber_strerror) {
-  char buf[BUFSIZ];
-  const char* m = strerror(-1);
-  ASSERT_STREQ("Unknown error -1", m);
-  errno = -2;
-  snprintf(buf, sizeof(buf), "<%m>");
-  ASSERT_STREQ("<Unknown error -2>", buf);
-  ASSERT_STREQ("Unknown error -1", m);
+  EXPECT_SNPRINTF("<Invalid argument>", "<%m>");
 }
 
 TEST(STDIO_TEST, wprintf_m) {
-  wchar_t buf[BUFSIZ];
   errno = 0;
-  swprintf(buf, sizeof(buf), L"<%m>");
-  ASSERT_EQ(std::wstring(L"<Success>"), buf);
+  EXPECT_SWPRINTF(L"<Success>", L"<%m>");
   errno = -1;
-  swprintf(buf, sizeof(buf), L"<%m>");
-  ASSERT_EQ(std::wstring(L"<Unknown error -1>"), buf);
+  EXPECT_SWPRINTF(L"<Unknown error -1>", L"<%m>");
   errno = EINVAL;
-  swprintf(buf, sizeof(buf), L"<%m>");
-  ASSERT_EQ(std::wstring(L"<Invalid argument>"), buf);
+  EXPECT_SWPRINTF(L"<Invalid argument>", L"<%m>");
 }
 
-TEST(STDIO_TEST, wprintf_m_does_not_clobber_strerror) {
-  wchar_t buf[BUFSIZ];
+TEST(STDIO_TEST, printf_m_does_not_clobber_strerror) {
   const char* m = strerror(-1);
   ASSERT_STREQ("Unknown error -1", m);
   errno = -2;
-  swprintf(buf, sizeof(buf), L"<%m>");
-  ASSERT_EQ(std::wstring(L"<Unknown error -2>"), buf);
+  EXPECT_SNPRINTF("<Unknown error -2>", "<%m>");
+  ASSERT_STREQ("Unknown error -1", m);
+}
+
+TEST(STDIO_TEST, wprintf_m_does_not_clobber_strerror) {
+  const char* m = strerror(-1);
+  ASSERT_STREQ("Unknown error -1", m);
+  errno = -2;
+  EXPECT_SWPRINTF(L"<Unknown error -2>", L"<%m>");
   ASSERT_STREQ("Unknown error -1", m);
 }
 
@@ -3000,156 +3010,86 @@
 #endif
 }
 
-TEST(STDIO_TEST, snprintf_b) {
+TEST(STDIO_TEST, snprintf_b_B) {
 #if defined(__BIONIC__)
-  char buf[BUFSIZ];
-
   uint8_t b = 5;
-  EXPECT_EQ(5, snprintf(buf, sizeof(buf), "<%" PRIb8 ">", b));
-  EXPECT_STREQ("<101>", buf);
-  EXPECT_EQ(10, snprintf(buf, sizeof(buf), "<%08" PRIb8 ">", b));
-  EXPECT_STREQ("<00000101>", buf);
+  EXPECT_SNPRINTF("<101>", "<%" PRIb8 ">", b);
+  EXPECT_SNPRINTF("<101>", "<%" PRIB8 ">", b);
+  EXPECT_SNPRINTF("<00000101>", "<%08" PRIb8 ">", b);
+  EXPECT_SNPRINTF("<00000101>", "<%08" PRIB8 ">", b);
 
   uint16_t s = 0xaaaa;
-  EXPECT_EQ(18, snprintf(buf, sizeof(buf), "<%" PRIb16 ">", s));
-  EXPECT_STREQ("<1010101010101010>", buf);
-  EXPECT_EQ(20, snprintf(buf, sizeof(buf), "<%#" PRIb16 ">", s));
-  EXPECT_STREQ("<0b1010101010101010>", buf);
+  EXPECT_SNPRINTF("<1010101010101010>", "<%" PRIb16 ">", s);
+  EXPECT_SNPRINTF("<1010101010101010>", "<%" PRIB16 ">", s);
+  EXPECT_SNPRINTF("<0b1010101010101010>", "<%#" PRIb16 ">", s);
+  EXPECT_SNPRINTF("<0B1010101010101010>", "<%#" PRIB16 ">", s);
 
-  EXPECT_EQ(34, snprintf(buf, sizeof(buf), "<%" PRIb32 ">", 0xaaaaaaaa));
-  EXPECT_STREQ("<10101010101010101010101010101010>", buf);
-  EXPECT_EQ(36, snprintf(buf, sizeof(buf), "<%#" PRIb32 ">", 0xaaaaaaaa));
-  EXPECT_STREQ("<0b10101010101010101010101010101010>", buf);
+  EXPECT_SNPRINTF("<10101010101010101010101010101010>", "<%" PRIb32 ">", 0xaaaaaaaa);
+  EXPECT_SNPRINTF("<10101010101010101010101010101010>", "<%" PRIB32 ">", 0xaaaaaaaa);
+  EXPECT_SNPRINTF("<0b10101010101010101010101010101010>", "<%#" PRIb32 ">", 0xaaaaaaaa);
+  EXPECT_SNPRINTF("<0B10101010101010101010101010101010>", "<%#" PRIB32 ">", 0xaaaaaaaa);
 
   // clang doesn't like "%lb" (https://github.com/llvm/llvm-project/issues/62247)
 #pragma clang diagnostic push
 #pragma clang diagnostic ignored "-Wformat"
-  EXPECT_EQ(66, snprintf(buf, sizeof(buf), "<%" PRIb64 ">", 0xaaaaaaaa'aaaaaaaa));
-  EXPECT_STREQ("<1010101010101010101010101010101010101010101010101010101010101010>", buf);
-  EXPECT_EQ(68, snprintf(buf, sizeof(buf), "<%#" PRIb64 ">", 0xaaaaaaaa'aaaaaaaa));
-  EXPECT_STREQ("<0b1010101010101010101010101010101010101010101010101010101010101010>", buf);
+  EXPECT_SNPRINTF("<1010101010101010101010101010101010101010101010101010101010101010>",
+                  "<%" PRIb64 ">", 0xaaaaaaaa'aaaaaaaa);
+  EXPECT_SNPRINTF("<1010101010101010101010101010101010101010101010101010101010101010>",
+                  "<%" PRIB64 ">", 0xaaaaaaaa'aaaaaaaa);
+  EXPECT_SNPRINTF("<0b1010101010101010101010101010101010101010101010101010101010101010>",
+                  "<%#" PRIb64 ">", 0xaaaaaaaa'aaaaaaaa);
+  EXPECT_SNPRINTF("<0B1010101010101010101010101010101010101010101010101010101010101010>",
+                  "<%#" PRIB64 ">", 0xaaaaaaaa'aaaaaaaa);
 #pragma clang diagnostic pop
 
-  EXPECT_EQ(3, snprintf(buf, sizeof(buf), "<%#b>", 0));
-  EXPECT_STREQ("<0>", buf);
+  EXPECT_SNPRINTF("<0>", "<%#b>", 0);
+  EXPECT_SNPRINTF("<0>", "<%#B>", 0);
 #else
   GTEST_SKIP() << "no %b in glibc";
 #endif
 }
 
-TEST(STDIO_TEST, snprintf_B) {
+TEST(STDIO_TEST, swprintf_b_B) {
 #if defined(__BIONIC__)
-  char buf[BUFSIZ];
-
   uint8_t b = 5;
-  EXPECT_EQ(5, snprintf(buf, sizeof(buf), "<%" PRIB8 ">", b));
-  EXPECT_STREQ("<101>", buf);
-  EXPECT_EQ(10, snprintf(buf, sizeof(buf), "<%08" PRIB8 ">", b));
-  EXPECT_STREQ("<00000101>", buf);
+  EXPECT_SWPRINTF(L"<101>", L"<%" PRIb8 ">", b);
+  EXPECT_SWPRINTF(L"<101>", L"<%" PRIB8 ">", b);
+  EXPECT_SWPRINTF(L"<0b101>", L"<%#" PRIb8 ">", b);
+  EXPECT_SWPRINTF(L"<0B101>", L"<%#" PRIB8 ">", b);
+  EXPECT_SWPRINTF(L"<00000101>", L"<%08" PRIb8 ">", b);
+  EXPECT_SWPRINTF(L"<00000101>", L"<%08" PRIB8 ">", b);
 
   uint16_t s = 0xaaaa;
-  EXPECT_EQ(18, snprintf(buf, sizeof(buf), "<%" PRIB16 ">", s));
-  EXPECT_STREQ("<1010101010101010>", buf);
-  EXPECT_EQ(20, snprintf(buf, sizeof(buf), "<%#" PRIB16 ">", s));
-  EXPECT_STREQ("<0B1010101010101010>", buf);
+  EXPECT_SWPRINTF(L"<1010101010101010>", L"<%" PRIb16 ">", s);
+  EXPECT_SWPRINTF(L"<1010101010101010>", L"<%" PRIB16 ">", s);
+  EXPECT_SWPRINTF(L"<0b1010101010101010>", L"<%#" PRIb16 ">", s);
+  EXPECT_SWPRINTF(L"<0B1010101010101010>", L"<%#" PRIB16 ">", s);
 
-  EXPECT_EQ(34, snprintf(buf, sizeof(buf), "<%" PRIB32 ">", 0xaaaaaaaa));
-  EXPECT_STREQ("<10101010101010101010101010101010>", buf);
-  EXPECT_EQ(36, snprintf(buf, sizeof(buf), "<%#" PRIB32 ">", 0xaaaaaaaa));
-  EXPECT_STREQ("<0B10101010101010101010101010101010>", buf);
+  EXPECT_SWPRINTF(L"<10101010101010101010101010101010>", L"<%" PRIb32 ">", 0xaaaaaaaa);
+  EXPECT_SWPRINTF(L"<10101010101010101010101010101010>", L"<%" PRIB32 ">", 0xaaaaaaaa);
+  EXPECT_SWPRINTF(L"<0b10101010101010101010101010101010>", L"<%#" PRIb32 ">", 0xaaaaaaaa);
+  EXPECT_SWPRINTF(L"<0B10101010101010101010101010101010>", L"<%#" PRIB32 ">", 0xaaaaaaaa);
 
-  // clang doesn't like "%lB" (https://github.com/llvm/llvm-project/issues/62247)
+  // clang doesn't like "%lb" (https://github.com/llvm/llvm-project/issues/62247)
 #pragma clang diagnostic push
 #pragma clang diagnostic ignored "-Wformat"
-  EXPECT_EQ(66, snprintf(buf, sizeof(buf), "<%" PRIB64 ">", 0xaaaaaaaa'aaaaaaaa));
-  EXPECT_STREQ("<1010101010101010101010101010101010101010101010101010101010101010>", buf);
-  EXPECT_EQ(68, snprintf(buf, sizeof(buf), "<%#" PRIB64 ">", 0xaaaaaaaa'aaaaaaaa));
-  EXPECT_STREQ("<0B1010101010101010101010101010101010101010101010101010101010101010>", buf);
+  EXPECT_SWPRINTF(L"<1010101010101010101010101010101010101010101010101010101010101010>",
+                  L"<%" PRIb64 ">", 0xaaaaaaaa'aaaaaaaa);
+  EXPECT_SWPRINTF(L"<1010101010101010101010101010101010101010101010101010101010101010>",
+                  L"<%" PRIB64 ">", 0xaaaaaaaa'aaaaaaaa);
+  EXPECT_SWPRINTF(L"<0b1010101010101010101010101010101010101010101010101010101010101010>",
+                  L"<%#" PRIb64 ">", 0xaaaaaaaa'aaaaaaaa);
+  EXPECT_SWPRINTF(L"<0B1010101010101010101010101010101010101010101010101010101010101010>",
+                  L"<%#" PRIB64 ">", 0xaaaaaaaa'aaaaaaaa);
 #pragma clang diagnostic pop
 
-  EXPECT_EQ(3, snprintf(buf, sizeof(buf), "<%#b>", 0));
-  EXPECT_STREQ("<0>", buf);
-#else
-  GTEST_SKIP() << "no %B in glibc";
-#endif
-}
-
-TEST(STDIO_TEST, swprintf_b) {
-#if defined(__BIONIC__)
-  wchar_t buf[BUFSIZ];
-
-  uint8_t b = 5;
-  EXPECT_EQ(5, swprintf(buf, sizeof(buf), L"<%" PRIb8 ">", b));
-  EXPECT_EQ(std::wstring(L"<101>"), buf);
-  EXPECT_EQ(10, swprintf(buf, sizeof(buf), L"<%08" PRIb8 ">", b));
-  EXPECT_EQ(std::wstring(L"<00000101>"), buf);
-
-  uint16_t s = 0xaaaa;
-  EXPECT_EQ(18, swprintf(buf, sizeof(buf), L"<%" PRIb16 ">", s));
-  EXPECT_EQ(std::wstring(L"<1010101010101010>"), buf);
-  EXPECT_EQ(20, swprintf(buf, sizeof(buf), L"<%#" PRIb16 ">", s));
-  EXPECT_EQ(std::wstring(L"<0b1010101010101010>"), buf);
-
-  EXPECT_EQ(34, swprintf(buf, sizeof(buf), L"<%" PRIb32 ">", 0xaaaaaaaa));
-  EXPECT_EQ(std::wstring(L"<10101010101010101010101010101010>"), buf);
-  EXPECT_EQ(36, swprintf(buf, sizeof(buf), L"<%#" PRIb32 ">", 0xaaaaaaaa));
-  EXPECT_EQ(std::wstring(L"<0b10101010101010101010101010101010>"), buf);
-
-#pragma clang diagnostic push
-#pragma clang diagnostic ignored "-Wformat"  // clang doesn't like "%lb"
-  EXPECT_EQ(66, swprintf(buf, sizeof(buf), L"<%" PRIb64 ">", 0xaaaaaaaa'aaaaaaaa));
-  EXPECT_EQ(std::wstring(L"<1010101010101010101010101010101010101010101010101010101010101010>"),
-            buf);
-  EXPECT_EQ(68, swprintf(buf, sizeof(buf), L"<%#" PRIb64 ">", 0xaaaaaaaa'aaaaaaaa));
-  EXPECT_EQ(std::wstring(L"<0b1010101010101010101010101010101010101010101010101010101010101010>"),
-            buf);
-#pragma clang diagnostic pop
-
-  EXPECT_EQ(3, swprintf(buf, sizeof(buf), L"<%#b>", 0));
-  EXPECT_EQ(std::wstring(L"<0>"), buf);
+  EXPECT_SWPRINTF(L"<0>", L"<%#b>", 0);
+  EXPECT_SWPRINTF(L"<0>", L"<%#B>", 0);
 #else
   GTEST_SKIP() << "no %b in glibc";
 #endif
 }
 
-TEST(STDIO_TEST, swprintf_B) {
-#if defined(__BIONIC__)
-  wchar_t buf[BUFSIZ];
-
-  uint8_t b = 5;
-  EXPECT_EQ(5, swprintf(buf, sizeof(buf), L"<%" PRIB8 ">", b));
-  EXPECT_EQ(std::wstring(L"<101>"), buf);
-  EXPECT_EQ(10, swprintf(buf, sizeof(buf), L"<%08" PRIB8 ">", b));
-  EXPECT_EQ(std::wstring(L"<00000101>"), buf);
-
-  uint16_t s = 0xaaaa;
-  EXPECT_EQ(18, swprintf(buf, sizeof(buf), L"<%" PRIB16 ">", s));
-  EXPECT_EQ(std::wstring(L"<1010101010101010>"), buf);
-  EXPECT_EQ(20, swprintf(buf, sizeof(buf), L"<%#" PRIB16 ">", s));
-  EXPECT_EQ(std::wstring(L"<0B1010101010101010>"), buf);
-
-  EXPECT_EQ(34, swprintf(buf, sizeof(buf), L"<%" PRIB32 ">", 0xaaaaaaaa));
-  EXPECT_EQ(std::wstring(L"<10101010101010101010101010101010>"), buf);
-  EXPECT_EQ(36, swprintf(buf, sizeof(buf), L"<%#" PRIB32 ">", 0xaaaaaaaa));
-  EXPECT_EQ(std::wstring(L"<0B10101010101010101010101010101010>"), buf);
-
-#pragma clang diagnostic push
-#pragma clang diagnostic ignored "-Wformat"  // clang doesn't like "%lb"
-  EXPECT_EQ(66, swprintf(buf, sizeof(buf), L"<%" PRIB64 ">", 0xaaaaaaaa'aaaaaaaa));
-  EXPECT_EQ(std::wstring(L"<1010101010101010101010101010101010101010101010101010101010101010>"),
-            buf);
-  EXPECT_EQ(68, swprintf(buf, sizeof(buf), L"<%#" PRIB64 ">", 0xaaaaaaaa'aaaaaaaa));
-  EXPECT_EQ(std::wstring(L"<0B1010101010101010101010101010101010101010101010101010101010101010>"),
-            buf);
-#pragma clang diagnostic pop
-
-  EXPECT_EQ(3, swprintf(buf, sizeof(buf), L"<%#B>", 0));
-  EXPECT_EQ(std::wstring(L"<0>"), buf);
-#else
-  GTEST_SKIP() << "no %B in glibc";
-#endif
-}
-
 TEST(STDIO_TEST, scanf_i_decimal) {
   int i;
   EXPECT_EQ(1, sscanf("<123789>", "<%i>", &i));
@@ -3281,30 +3221,47 @@
 #pragma clang diagnostic push
 #pragma clang diagnostic ignored "-Wformat-invalid-specifier"
 #pragma clang diagnostic ignored "-Wconstant-conversion"
-  char buf[BUFSIZ];
   int8_t a = 0b101;
-  snprintf(buf, sizeof(buf), "<%w8b>", a);
-  EXPECT_STREQ("<101>", buf);
+  EXPECT_SNPRINTF("<101>", "<%w8b>", a);
   int8_t b1 = 0xFF;
-  snprintf(buf, sizeof(buf), "<%w8d>", b1);
-  EXPECT_STREQ("<-1>", buf);
+  EXPECT_SNPRINTF("<-1>", "<%w8d>", b1);
   int8_t b2 = 0x1FF;
-  snprintf(buf, sizeof(buf), "<%w8d>", b2);
-  EXPECT_STREQ("<-1>", buf);
+  EXPECT_SNPRINTF("<-1>", "<%w8d>", b2);
   int16_t c = 0xFFFF;
-  snprintf(buf, sizeof(buf), "<%w16i>", c);
-  EXPECT_STREQ("<-1>", buf);
+  EXPECT_SNPRINTF("<-1>", "<%w16i>", c);
   int32_t d = 021;
-  snprintf(buf, sizeof(buf), "<%w32o>", d);
-  EXPECT_STREQ("<21>", buf);
+  EXPECT_SNPRINTF("<21>", "<%w32o>", d);
   uint32_t e = -1;
-  snprintf(buf, sizeof(buf), "<%w32u>", e);
-  EXPECT_STREQ("<4294967295>", buf);
+  EXPECT_SNPRINTF("<4294967295>", "<%w32u>", e);
   int64_t f = 0x3b;
-  snprintf(buf, sizeof(buf), "<%w64x>", f);
-  EXPECT_STREQ("<3b>", buf);
-  snprintf(buf, sizeof(buf), "<%w64X>", f);
-  EXPECT_STREQ("<3B>", buf);
+  EXPECT_SNPRINTF("<3b>", "<%w64x>", f);
+  EXPECT_SNPRINTF("<3B>", "<%w64X>", f);
+#pragma clang diagnostic pop
+#else
+  GTEST_SKIP() << "no %w in glibc";
+#endif
+}
+
+TEST(STDIO_TEST, swprintf_w_base) {
+#if defined(__BIONIC__)
+#pragma clang diagnostic push
+#pragma clang diagnostic ignored "-Wformat-invalid-specifier"
+#pragma clang diagnostic ignored "-Wconstant-conversion"
+  int8_t a = 0b101;
+  EXPECT_SWPRINTF(L"<101>", L"<%w8b>", a);
+  int8_t b1 = 0xFF;
+  EXPECT_SWPRINTF(L"<-1>", L"<%w8d>", b1);
+  int8_t b2 = 0x1FF;
+  EXPECT_SWPRINTF(L"<-1>", L"<%w8d>", b2);
+  int16_t c = 0xFFFF;
+  EXPECT_SWPRINTF(L"<-1>", L"<%w16i>", c);
+  int32_t d = 021;
+  EXPECT_SWPRINTF(L"<21>", L"<%w32o>", d);
+  uint32_t e = -1;
+  EXPECT_SWPRINTF(L"<4294967295>", L"<%w32u>", e);
+  int64_t f = 0x3b;
+  EXPECT_SWPRINTF(L"<3b>", L"<%w64x>", f);
+  EXPECT_SWPRINTF(L"<3B>", L"<%w64X>", f);
 #pragma clang diagnostic pop
 #else
   GTEST_SKIP() << "no %w in glibc";
@@ -3316,18 +3273,37 @@
 #pragma clang diagnostic push
 #pragma clang diagnostic ignored "-Wformat-invalid-specifier"
 #pragma clang diagnostic ignored "-Wformat-extra-args"
-  char buf[BUFSIZ];
   int32_t a = 0xaaaaaaaa;
   int64_t b = 0x11111111'22222222;
   int64_t c = 0x33333333'44444444;
   int64_t d = 0xaaaaaaaa'aaaaaaaa;
-  snprintf(buf, sizeof(buf), "<%2$w32b --- %1$w64x>", c, a);
-  EXPECT_STREQ("<10101010101010101010101010101010 --- 3333333344444444>", buf);
-  snprintf(buf, sizeof(buf), "<%3$w64b --- %1$w64x --- %2$w64x>", b, c, d);
-  EXPECT_STREQ(
+  EXPECT_SNPRINTF("<10101010101010101010101010101010 --- 3333333344444444>",
+                  "<%2$w32b --- %1$w64x>", c, a);
+  EXPECT_SNPRINTF(
       "<1010101010101010101010101010101010101010101010101010101010101010 --- 1111111122222222 --- "
       "3333333344444444>",
-      buf);
+      "<%3$w64b --- %1$w64x --- %2$w64x>", b, c, d);
+#pragma clang diagnostic pop
+#else
+  GTEST_SKIP() << "no %w in glibc";
+#endif
+}
+
+TEST(STDIO_TEST, swprintf_w_arguments_reordering) {
+#if defined(__BIONIC__)
+#pragma clang diagnostic push
+#pragma clang diagnostic ignored "-Wformat-invalid-specifier"
+#pragma clang diagnostic ignored "-Wformat-extra-args"
+  int32_t a = 0xaaaaaaaa;
+  int64_t b = 0x11111111'22222222;
+  int64_t c = 0x33333333'44444444;
+  int64_t d = 0xaaaaaaaa'aaaaaaaa;
+  EXPECT_SWPRINTF(L"<10101010101010101010101010101010 --- 3333333344444444>",
+                  L"<%2$w32b --- %1$w64x>", c, a);
+  EXPECT_SWPRINTF(
+      L"<1010101010101010101010101010101010101010101010101010101010101010 --- 1111111122222222 --- "
+      L"3333333344444444>",
+      L"<%3$w64b --- %1$w64x --- %2$w64x>", b, c, d);
 #pragma clang diagnostic pop
 #else
   GTEST_SKIP() << "no %w in glibc";
@@ -3347,63 +3323,6 @@
 #endif
 }
 
-TEST(STDIO_TEST, swprintf_w_base) {
-#if defined(__BIONIC__)
-#pragma clang diagnostic push
-#pragma clang diagnostic ignored "-Wformat-invalid-specifier"
-#pragma clang diagnostic ignored "-Wconstant-conversion"
-  wchar_t buf[BUFSIZ];
-  int8_t a = 0b101;
-  swprintf(buf, sizeof(buf), L"<%w8b>", a);
-  EXPECT_EQ(std::wstring(L"<101>"), buf);
-  int8_t b1 = 0xFF;
-  swprintf(buf, sizeof(buf), L"<%w8d>", b1);
-  EXPECT_EQ(std::wstring(L"<-1>"), buf);
-  int8_t b2 = 0x1FF;
-  swprintf(buf, sizeof(buf), L"<%w8d>", b2);
-  EXPECT_EQ(std::wstring(L"<-1>"), buf);
-  int16_t c = 0xFFFF;
-  swprintf(buf, sizeof(buf), L"<%w16i>", c);
-  EXPECT_EQ(std::wstring(L"<-1>"), buf);
-  int32_t d = 021;
-  swprintf(buf, sizeof(buf), L"<%w32o>", d);
-  EXPECT_EQ(std::wstring(L"<21>"), buf);
-  uint32_t e = -1;
-  swprintf(buf, sizeof(buf), L"<%w32u>", e);
-  EXPECT_EQ(std::wstring(L"<4294967295>"), buf);
-  int64_t f = 0x3b;
-  swprintf(buf, sizeof(buf), L"<%w64x>", f);
-  EXPECT_EQ(std::wstring(L"<3b>"), buf);
-  swprintf(buf, sizeof(buf), L"<%w64X>", f);
-  EXPECT_EQ(std::wstring(L"<3B>"), buf);
-#pragma clang diagnostic pop
-#else
-  GTEST_SKIP() << "no %w in glibc";
-#endif
-}
-
-TEST(STDIO_TEST, swprintf_w_arguments_reordering) {
-#if defined(__BIONIC__)
-#pragma clang diagnostic push
-#pragma clang diagnostic ignored "-Wformat-invalid-specifier"
-#pragma clang diagnostic ignored "-Wformat-extra-args"
-  wchar_t buf[BUFSIZ];
-  int32_t a = 0xaaaaaaaa;
-  int64_t b = 0x11111111'22222222;
-  int64_t c = 0x33333333'44444444;
-  int64_t d = 0xaaaaaaaa'aaaaaaaa;
-  swprintf(buf, sizeof(buf), L"<%2$w32b --- %1$w64x>", c, a);
-  EXPECT_EQ(std::wstring(L"<10101010101010101010101010101010 --- 3333333344444444>"), buf);
-  swprintf(buf, sizeof(buf), L"<%3$w64b --- %1$w64x --- %2$w64x>", b, c, d);
-  EXPECT_EQ(std::wstring(L"<1010101010101010101010101010101010101010101010101010101010101010 --- "
-                         L"1111111122222222 --- 3333333344444444>"),
-            buf);
-#pragma clang diagnostic pop
-#else
-  GTEST_SKIP() << "no %w in glibc";
-#endif
-}
-
 TEST(STDIO_TEST, swprintf_invalid_w_width) {
 #if defined(__BIONIC__)
 #pragma clang diagnostic push
@@ -3415,4 +3334,155 @@
 #else
   GTEST_SKIP() << "no %w in glibc";
 #endif
-}
\ No newline at end of file
+}
+
+TEST(STDIO_TEST, snprintf_wf_base) {
+#if defined(__BIONIC__)
+#pragma clang diagnostic push
+#pragma clang diagnostic ignored "-Wconstant-conversion"
+#pragma clang diagnostic ignored "-Wformat"
+#pragma clang diagnostic ignored "-Wformat-invalid-specifier"
+  int_fast8_t a = 0b101;
+  EXPECT_SNPRINTF("<101>", "<%wf8b>", a);
+  int_fast8_t b = 0x12341234'12341234;
+  EXPECT_SNPRINTF("<34>", "<%wf8x>", b);
+  uint_fast16_t c = 0x11111111'22222222;
+#if defined(__LP64__)
+  EXPECT_SNPRINTF("<1111111122222222>", "<%wf16x>", c);
+#else
+  EXPECT_SNPRINTF("<22222222>", "<%wf16x>", c);
+#endif
+  int_fast32_t d = 0x33333333'44444444;
+#if defined(__LP64__)
+  EXPECT_SNPRINTF("<3333333344444444>", "<%wf32x>", d);
+#else
+  EXPECT_SNPRINTF("<44444444>", "<%wf32x>", d);
+#endif
+  int_fast64_t e = 0xaaaaaaaa'aaaaaaaa;
+  EXPECT_SNPRINTF("<aaaaaaaaaaaaaaaa>", "<%wf64x>", e);
+  EXPECT_SNPRINTF("<AAAAAAAAAAAAAAAA>", "<%wf64X>", e);
+#pragma clang diagnostic pop
+#else
+  GTEST_SKIP() << "no %wf in glibc";
+#endif
+}
+TEST(STDIO_TEST, swprintf_wf_base) {
+#if defined(__BIONIC__)
+#pragma clang diagnostic push
+#pragma clang diagnostic ignored "-Wconstant-conversion"
+#pragma clang diagnostic ignored "-Wformat"
+#pragma clang diagnostic ignored "-Wformat-invalid-specifier"
+  int_fast8_t a = 0b101;
+  EXPECT_SWPRINTF(L"<101>", L"<%wf8b>", a);
+  int_fast8_t b = 0x12341234'12341234;
+  EXPECT_SWPRINTF(L"<34>", L"<%wf8x>", b);
+  uint_fast16_t c = 0x11111111'22222222;
+#if defined(__LP64__)
+  EXPECT_SWPRINTF(L"<1111111122222222>", L"<%wf16x>", c);
+#else
+  EXPECT_SWPRINTF(L"<22222222>", L"<%wf16x>", c);
+#endif
+  int_fast32_t d = 0x33333333'44444444;
+#if defined(__LP64__)
+  EXPECT_SWPRINTF(L"<3333333344444444>", L"<%wf32x>", d);
+#else
+  EXPECT_SWPRINTF(L"<44444444>", L"<%wf32x>", d);
+#endif
+  int_fast64_t e = 0xaaaaaaaa'aaaaaaaa;
+  EXPECT_SWPRINTF(L"<aaaaaaaaaaaaaaaa>", L"<%wf64x>", e);
+  EXPECT_SWPRINTF(L"<AAAAAAAAAAAAAAAA>", L"<%wf64X>", e);
+#pragma clang diagnostic pop
+#else
+  GTEST_SKIP() << "no %wf in glibc";
+#endif
+}
+
+TEST(STDIO_TEST, snprintf_wf_arguments_reordering) {
+#if defined(__BIONIC__)
+#pragma clang diagnostic push
+#pragma clang diagnostic ignored "-Wconstant-conversion"
+#pragma clang diagnostic ignored "-Wformat"
+#pragma clang diagnostic ignored "-Wformat-extra-args"
+#pragma clang diagnostic ignored "-Wformat-invalid-specifier"
+  int_fast16_t a = 0x11111111'22222222;
+  int_fast32_t b = 0x33333333'44444444;
+  int_fast32_t c = 0xaaaaaaaa'aaaaaaaa;
+#if defined(__LP64__)
+  EXPECT_SNPRINTF(
+      "<3333333344444444 --- 1010101010101010101010101010101010101010101010101010101010101010>",
+      "<%2$wf32x --- %1$wf32b>", c, b);
+
+  EXPECT_SNPRINTF(
+      "<1010101010101010101010101010101010101010101010101010101010101010 --- 1111111122222222 --- "
+      "3333333344444444>",
+      "<%3$wf32b --- %1$wf16x --- %2$wf32x>", a, b, c);
+#else
+  EXPECT_SNPRINTF("<44444444 --- 10101010101010101010101010101010>", "<%2$wf32x --- %1$wf32b>", c,
+                  b);
+  EXPECT_SNPRINTF("<10101010101010101010101010101010 --- 22222222 --- 44444444>",
+                  "<%3$wf32b --- %1$wf16x --- %2$wf32x>", a, b, c);
+#endif
+#pragma clang diagnostic pop
+#else
+  GTEST_SKIP() << "no %w in glibc";
+#endif
+}
+
+TEST(STDIO_TEST, swprintf_wf_arguments_reordering) {
+#if defined(__BIONIC__)
+#pragma clang diagnostic push
+#pragma clang diagnostic ignored "-Wconstant-conversion"
+#pragma clang diagnostic ignored "-Wformat"
+#pragma clang diagnostic ignored "-Wformat-extra-args"
+#pragma clang diagnostic ignored "-Wformat-invalid-specifier"
+  int_fast16_t a = 0x11111111'22222222;
+  int_fast32_t b = 0x33333333'44444444;
+  int_fast32_t c = 0xaaaaaaaa'aaaaaaaa;
+#if defined(__LP64__)
+  EXPECT_SWPRINTF(
+      L"<3333333344444444 --- 1010101010101010101010101010101010101010101010101010101010101010>",
+      L"<%2$wf32x --- %1$wf32b>", c, b);
+
+  EXPECT_SWPRINTF(
+      L"<1010101010101010101010101010101010101010101010101010101010101010 --- 1111111122222222 --- "
+      L"3333333344444444>",
+      L"<%3$wf32b --- %1$wf16x --- %2$wf32x>", a, b, c);
+#else
+  EXPECT_SWPRINTF(L"<44444444 --- 10101010101010101010101010101010>", L"<%2$wf32x --- %1$wf32b>", c,
+                  b);
+  EXPECT_SWPRINTF(L"<10101010101010101010101010101010 --- 22222222 --- 44444444>",
+                  L"<%3$wf32b --- %1$wf16x --- %2$wf32x>", a, b, c);
+#endif
+#pragma clang diagnostic pop
+#else
+  GTEST_SKIP() << "no %w in glibc";
+#endif
+}
+
+TEST(STDIO_TEST, snprintf_invalid_wf_width) {
+#if defined(__BIONIC__)
+#pragma clang diagnostic push
+#pragma clang diagnostic ignored "-Wformat"
+#pragma clang diagnostic ignored "-Wformat-invalid-specifier"
+  char buf[BUFSIZ];
+  int_fast32_t a = 100;
+  EXPECT_DEATH(snprintf(buf, sizeof(buf), "%wf20d", &a), "%wf20 is unsupported");
+#pragma clang diagnostic pop
+#else
+  GTEST_SKIP() << "no %w in glibc";
+#endif
+}
+
+TEST(STDIO_TEST, swprintf_invalid_wf_width) {
+#if defined(__BIONIC__)
+#pragma clang diagnostic push
+#pragma clang diagnostic ignored "-Wformat"
+#pragma clang diagnostic ignored "-Wformat-invalid-specifier"
+  wchar_t buf[BUFSIZ];
+  int_fast32_t a = 100;
+  EXPECT_DEATH(swprintf(buf, sizeof(buf), L"%wf20d", &a), "%wf20 is unsupported");
+#pragma clang diagnostic pop
+#else
+  GTEST_SKIP() << "no %w in glibc";
+#endif
+}
diff --git a/tests/struct_layout_test.cpp b/tests/struct_layout_test.cpp
index 10c100a..0123ed9 100644
--- a/tests/struct_layout_test.cpp
+++ b/tests/struct_layout_test.cpp
@@ -30,7 +30,7 @@
 #define CHECK_OFFSET(name, field, offset) \
     check_offset(#name, #field, offsetof(name, field), offset);
 #ifdef __LP64__
-  CHECK_SIZE(pthread_internal_t, 784);
+  CHECK_SIZE(pthread_internal_t, 776);
   CHECK_OFFSET(pthread_internal_t, next, 0);
   CHECK_OFFSET(pthread_internal_t, prev, 8);
   CHECK_OFFSET(pthread_internal_t, tid, 16);
@@ -55,7 +55,6 @@
   CHECK_OFFSET(pthread_internal_t, dlerror_buffer, 248);
   CHECK_OFFSET(pthread_internal_t, bionic_tls, 760);
   CHECK_OFFSET(pthread_internal_t, errno_value, 768);
-  CHECK_OFFSET(pthread_internal_t, vfork_child_stack_bottom, 776);
   CHECK_SIZE(bionic_tls, 12200);
   CHECK_OFFSET(bionic_tls, key_data, 0);
   CHECK_OFFSET(bionic_tls, locale, 2080);
@@ -73,7 +72,7 @@
   CHECK_OFFSET(bionic_tls, bionic_systrace_disabled, 12193);
   CHECK_OFFSET(bionic_tls, padding, 12194);
 #else
-  CHECK_SIZE(pthread_internal_t, 672);
+  CHECK_SIZE(pthread_internal_t, 668);
   CHECK_OFFSET(pthread_internal_t, next, 0);
   CHECK_OFFSET(pthread_internal_t, prev, 4);
   CHECK_OFFSET(pthread_internal_t, tid, 8);
@@ -98,7 +97,6 @@
   CHECK_OFFSET(pthread_internal_t, dlerror_buffer, 148);
   CHECK_OFFSET(pthread_internal_t, bionic_tls, 660);
   CHECK_OFFSET(pthread_internal_t, errno_value, 664);
-  CHECK_OFFSET(pthread_internal_t, vfork_child_stack_bottom, 668);
   CHECK_SIZE(bionic_tls, 11080);
   CHECK_OFFSET(bionic_tls, key_data, 0);
   CHECK_OFFSET(bionic_tls, locale, 1040);
diff --git a/tests/sys_sem_test.cpp b/tests/sys_sem_test.cpp
index b98926b..4bac92f 100644
--- a/tests/sys_sem_test.cpp
+++ b/tests/sys_sem_test.cpp
@@ -87,15 +87,21 @@
 }
 
 TEST(sys_sem, semop_failure) {
+#pragma clang diagnostic push
+#pragma clang diagnostic ignored "-Wnonnull"
   errno = 0;
   ASSERT_EQ(-1, semop(-1, nullptr, 0));
   ASSERT_TRUE(errno == EINVAL || errno == ENOSYS);
+#pragma clang diagnostic pop
 }
 
 TEST(sys_sem, semtimedop_failure) {
+#pragma clang diagnostic push
+#pragma clang diagnostic ignored "-Wnonnull"
   errno = 0;
   ASSERT_EQ(-1, semtimedop(-1, nullptr, 0, nullptr));
   ASSERT_TRUE(errno == EINVAL || errno == ENOSYS);
+#pragma clang diagnostic pop
 }
 
 TEST(sys_sem, union_semun) {
diff --git a/tests/sys_timex_test.cpp b/tests/sys_timex_test.cpp
index 1340ea4..44b73c9 100644
--- a/tests/sys_timex_test.cpp
+++ b/tests/sys_timex_test.cpp
@@ -27,21 +27,9 @@
   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_wait_test.cpp b/tests/sys_wait_test.cpp
index c006972..200fabe 100644
--- a/tests/sys_wait_test.cpp
+++ b/tests/sys_wait_test.cpp
@@ -42,3 +42,22 @@
   ASSERT_EQ(66, si.si_status);
   ASSERT_EQ(CLD_EXITED, si.si_code);
 }
+
+// https://github.com/android/ndk/issues/1878
+TEST(sys_wait, macros) {
+#if defined(__GLIBC__)
+  // glibc before 2016 requires an lvalue.
+#else
+  ASSERT_FALSE(WIFEXITED(0x7f));
+  ASSERT_TRUE(WIFSTOPPED(0x7f));
+  ASSERT_FALSE(WIFCONTINUED(0x7f));
+
+  ASSERT_TRUE(WIFEXITED(0x80));
+  ASSERT_FALSE(WIFSTOPPED(0x80));
+  ASSERT_FALSE(WIFCONTINUED(0x80));
+
+  ASSERT_FALSE(WIFEXITED(0xffff));
+  ASSERT_FALSE(WIFSTOPPED(0xffff));
+  ASSERT_TRUE(WIFCONTINUED(0xffff));
+#endif
+}
diff --git a/tests/syslog_test.cpp b/tests/syslog_test.cpp
new file mode 100644
index 0000000..3ec3337
--- /dev/null
+++ b/tests/syslog_test.cpp
@@ -0,0 +1,74 @@
+/*
+ * Copyright (C) 2023 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 <syslog.h>
+
+#include <errno.h>
+#include <gtest/gtest.h>
+
+#include "utils.h"
+
+TEST(syslog, syslog_percent_m) {
+  ExecTestHelper eth;
+  eth.Run(
+      [&]() {
+        openlog("foo", LOG_PERROR, LOG_AUTH);
+        errno = EINVAL;
+        syslog(LOG_ERR, "a b c: %m");
+        closelog();
+        exit(0);
+      },
+      0, "foo: a b c: Invalid argument\n");
+}
+
+TEST(syslog, syslog_empty) {
+  ExecTestHelper eth;
+  eth.Run(
+      [&]() {
+        openlog("foo", LOG_PERROR, LOG_AUTH);
+        errno = EINVAL;
+        syslog(LOG_ERR, "");
+        closelog();
+        exit(0);
+      },
+      0, "foo: \n");
+}
+
+TEST(syslog, syslog_truncation) {
+  ExecTestHelper eth;
+  eth.Run(
+      [&]() {
+        openlog("bar", LOG_PERROR, LOG_AUTH);
+        char too_long[2048] = {};
+        memset(too_long, 'x', sizeof(too_long) - 1);
+        syslog(LOG_ERR, "%s", too_long);
+        closelog();
+        exit(0);
+      },
+      0, "bar: x{1023}\n");
+}
diff --git a/tests/time_test.cpp b/tests/time_test.cpp
index f0ad937..d16600c 100644
--- a/tests/time_test.cpp
+++ b/tests/time_test.cpp
@@ -181,10 +181,25 @@
   ASSERT_NE(static_cast<time_t>(-1), mktime(&t));
   ASSERT_EQ(0, errno);
 
-  // This will overflow for LP32 or LP64.
+  // This will overflow for LP32.
   t.tm_year = INT_MAX;
 
   errno = 0;
+#if !defined(__LP64__)
+  ASSERT_EQ(static_cast<time_t>(-1), mktime(&t));
+  ASSERT_EQ(EOVERFLOW, errno);
+#else
+  ASSERT_EQ(static_cast<time_t>(67768036166016000U), mktime(&t));
+  ASSERT_EQ(0, errno);
+#endif
+
+  // This will overflow for LP32 or LP64.
+  // tm_year is int, this t struct points to INT_MAX + 1 no matter what TZ is.
+  t.tm_year = INT_MAX;
+  t.tm_mon = 11;
+  t.tm_mday = 45;
+
+  errno = 0;
   ASSERT_EQ(static_cast<time_t>(-1), mktime(&t));
   ASSERT_EQ(EOVERFLOW, errno);
 }
@@ -1254,8 +1269,39 @@
 TEST(time, timespec_get) {
 #if __BIONIC__
   timespec ts = {};
-  ASSERT_EQ(0, timespec_get(&ts, 123));
   ASSERT_EQ(TIME_UTC, timespec_get(&ts, TIME_UTC));
+  ASSERT_EQ(TIME_MONOTONIC, timespec_get(&ts, TIME_MONOTONIC));
+  ASSERT_EQ(TIME_ACTIVE, timespec_get(&ts, TIME_ACTIVE));
+  ASSERT_EQ(TIME_THREAD_ACTIVE, timespec_get(&ts, TIME_THREAD_ACTIVE));
+#else
+  GTEST_SKIP() << "glibc doesn't have timespec_get until 2.21";
+#endif
+}
+
+TEST(time, timespec_get_invalid) {
+#if __BIONIC__
+  timespec ts = {};
+  ASSERT_EQ(0, timespec_get(&ts, 123));
+#else
+  GTEST_SKIP() << "glibc doesn't have timespec_get until 2.21";
+#endif
+}
+
+TEST(time, timespec_getres) {
+#if __BIONIC__
+  timespec ts = {};
+  ASSERT_EQ(TIME_UTC, timespec_getres(&ts, TIME_UTC));
+  ASSERT_EQ(1, ts.tv_nsec);
+  ASSERT_EQ(0, ts.tv_sec);
+#else
+  GTEST_SKIP() << "glibc doesn't have timespec_get until 2.21";
+#endif
+}
+
+TEST(time, timespec_getres_invalid) {
+#if __BIONIC__
+  timespec ts = {};
+  ASSERT_EQ(0, timespec_getres(&ts, 123));
 #else
   GTEST_SKIP() << "glibc doesn't have timespec_get until 2.21";
 #endif