Merge "Fix fcntrl#tee test to use the same expected/actual buffer size."
diff --git a/PREUPLOAD.cfg b/PREUPLOAD.cfg
index 7b533a4..f7c8fd7 100644
--- a/PREUPLOAD.cfg
+++ b/PREUPLOAD.cfg
@@ -1,2 +1,5 @@
 [Hook Scripts]
 notice = tools/update_notice.sh
+seccomp = tools/update_seccomp.sh
+syscalls = tools/update_syscalls.sh
+version_scripts = tools/update_version_scripts.sh
diff --git a/benchmarks/Android.bp b/benchmarks/Android.bp
index e8745a2..00c9560 100644
--- a/benchmarks/Android.bp
+++ b/benchmarks/Android.bp
@@ -73,7 +73,6 @@
 cc_benchmark_host {
     name: "bionic-benchmarks-glibc",
     defaults: ["bionic-benchmarks-defaults"],
-    host_ldlibs: ["-lrt"],
     target: {
         darwin: {
             // Only supported on linux systems.
diff --git a/libc/Android.bp b/libc/Android.bp
index d126f2f..cd01efd 100644
--- a/libc/Android.bp
+++ b/libc/Android.bp
@@ -299,13 +299,14 @@
 cc_library_static {
     defaults: ["libc_defaults"],
     srcs: [
+        "upstream-freebsd/lib/libc/gen/glob.c",
         "upstream-freebsd/lib/libc/stdlib/realpath.c",
     ],
 
     cflags: [
         "-Wno-sign-compare",
         "-include freebsd-compat.h",
-        "-Wframe-larger-than=15000",
+        "-Wframe-larger-than=66000",
     ],
 
     local_include_dirs: [
@@ -1825,7 +1826,6 @@
             "bionic/dl_iterate_phdr_static.cpp",
             "bionic/icu_static.cpp",
             "bionic/malloc_common.cpp",
-            "bionic/libc_init_static.cpp",
         ],
         cflags: ["-DLIBC_STATIC"],
         whole_static_libs: ["libc_init_static"],
diff --git a/libc/NOTICE b/libc/NOTICE
index feea29d..32980b7 100644
--- a/libc/NOTICE
+++ b/libc/NOTICE
@@ -1914,6 +1914,75 @@
    The Regents of the University of California.  All rights reserved.
 
 This code is derived from software contributed to Berkeley by
+Guido van Rossum.
+
+Copyright (c) 2011 The FreeBSD Foundation
+All rights reserved.
+Portions of this software were developed by David Chisnall
+under sponsorship from the FreeBSD Foundation.
+
+Redistribution and use in source and binary forms, with or without
+modification, are permitted provided that the following conditions
+are met:
+1. Redistributions of source code must retain the above copyright
+   notice, this list of conditions and the following disclaimer.
+2. Redistributions in binary form must reproduce the above copyright
+   notice, this list of conditions and the following disclaimer in the
+   documentation and/or other materials provided with the distribution.
+3. Neither the name of the University nor the names of its contributors
+   may be used to endorse or promote products derived from this software
+   without specific prior written permission.
+
+THIS SOFTWARE IS PROVIDED BY THE REGENTS AND CONTRIBUTORS ``AS IS'' AND
+ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE
+IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE
+ARE DISCLAIMED.  IN NO EVENT SHALL THE REGENTS OR CONTRIBUTORS BE LIABLE
+FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL
+DAMAGES (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS
+OR SERVICES; LOSS OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION)
+HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT
+LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY
+OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF
+SUCH DAMAGE.
+
+-------------------------------------------------------------------
+
+Copyright (c) 1989, 1993
+   The Regents of the University of California.  All rights reserved.
+
+This code is derived from software contributed to Berkeley by
+Guido van Rossum.
+
+Redistribution and use in source and binary forms, with or without
+modification, are permitted provided that the following conditions
+are met:
+1. Redistributions of source code must retain the above copyright
+   notice, this list of conditions and the following disclaimer.
+2. Redistributions in binary form must reproduce the above copyright
+   notice, this list of conditions and the following disclaimer in the
+   documentation and/or other materials provided with the distribution.
+3. Neither the name of the University nor the names of its contributors
+   may be used to endorse or promote products derived from this software
+   without specific prior written permission.
+
+THIS SOFTWARE IS PROVIDED BY THE REGENTS AND CONTRIBUTORS ``AS IS'' AND
+ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE
+IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE
+ARE DISCLAIMED.  IN NO EVENT SHALL THE REGENTS OR CONTRIBUTORS BE LIABLE
+FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL
+DAMAGES (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS
+OR SERVICES; LOSS OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION)
+HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT
+LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY
+OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF
+SUCH DAMAGE.
+
+-------------------------------------------------------------------
+
+Copyright (c) 1989, 1993
+   The Regents of the University of California.  All rights reserved.
+
+This code is derived from software contributed to Berkeley by
 Roger L. Snyder.
 
 Redistribution and use in source and binary forms, with or without
diff --git a/libc/SECCOMP_WHITELIST.TXT b/libc/SECCOMP_WHITELIST.TXT
index 2c4767b..36a579b 100644
--- a/libc/SECCOMP_WHITELIST.TXT
+++ b/libc/SECCOMP_WHITELIST.TXT
@@ -35,7 +35,6 @@
 int	rt_sigreturn:rt_sigreturn(unsigned long __unused)	all
 int	rt_tgsigqueueinfo:int rt_tgsigqueueinfo(pid_t tgid, pid_t tid, int sig, siginfo_t *uinfo)	all
 int	restart_syscall:int restart_syscall()	all
-int	getrandom:int getrandom(void *buf, size_t buflen, unsigned int flags) all
 int	fstatat64|fstatat:newfstatat(int, const char*, struct stat*, int)	mips64
 int	fstat64|fstat:fstat(int, struct stat*)	mips64
 int	_flush_cache:cacheflush(char* addr, const int nbytes, const int op)	mips64
diff --git a/libc/SYSCALLS.TXT b/libc/SYSCALLS.TXT
index a1d1af0..f8be0b0 100644
--- a/libc/SYSCALLS.TXT
+++ b/libc/SYSCALLS.TXT
@@ -353,3 +353,6 @@
 # vdso stuff.
 int __clock_gettime:clock_gettime(clockid_t, timespec*) all
 int __gettimeofday:gettimeofday(timeval*, timezone*) all
+
+# <sys/random.h>
+ssize_t getrandom(void*, size_t, unsigned) all
diff --git a/libc/arch-arm/syscalls/getrandom.S b/libc/arch-arm/syscalls/getrandom.S
new file mode 100644
index 0000000..3f28af6
--- /dev/null
+++ b/libc/arch-arm/syscalls/getrandom.S
@@ -0,0 +1,16 @@
+/* Generated by gensyscalls.py. Do not edit. */
+
+#include <private/bionic_asm.h>
+
+ENTRY(getrandom)
+    mov     ip, r7
+    .cfi_register r7, ip
+    ldr     r7, =__NR_getrandom
+    swi     #0
+    mov     r7, ip
+    .cfi_restore r7
+    cmn     r0, #(MAX_ERRNO + 1)
+    bxls    lr
+    neg     r0, r0
+    b       __set_errno_internal
+END(getrandom)
diff --git a/libc/arch-arm64/syscalls/getrandom.S b/libc/arch-arm64/syscalls/getrandom.S
new file mode 100644
index 0000000..c8fe41f
--- /dev/null
+++ b/libc/arch-arm64/syscalls/getrandom.S
@@ -0,0 +1,14 @@
+/* Generated by gensyscalls.py. Do not edit. */
+
+#include <private/bionic_asm.h>
+
+ENTRY(getrandom)
+    mov     x8, __NR_getrandom
+    svc     #0
+
+    cmn     x0, #(MAX_ERRNO + 1)
+    cneg    x0, x0, hi
+    b.hi    __set_errno_internal
+
+    ret
+END(getrandom)
diff --git a/libc/arch-mips/syscalls/getrandom.S b/libc/arch-mips/syscalls/getrandom.S
new file mode 100644
index 0000000..7a2f3b9
--- /dev/null
+++ b/libc/arch-mips/syscalls/getrandom.S
@@ -0,0 +1,19 @@
+/* Generated by gensyscalls.py. Do not edit. */
+
+#include <private/bionic_asm.h>
+
+ENTRY(getrandom)
+    .set noreorder
+    .cpload t9
+    li v0, __NR_getrandom
+    syscall
+    bnez a3, 1f
+    move a0, v0
+    j ra
+    nop
+1:
+    la t9,__set_errno_internal
+    j t9
+    nop
+    .set reorder
+END(getrandom)
diff --git a/libc/arch-mips64/syscalls/getrandom.S b/libc/arch-mips64/syscalls/getrandom.S
new file mode 100644
index 0000000..3c5b467
--- /dev/null
+++ b/libc/arch-mips64/syscalls/getrandom.S
@@ -0,0 +1,25 @@
+/* Generated by gensyscalls.py. Do not edit. */
+
+#include <private/bionic_asm.h>
+
+ENTRY(getrandom)
+    .set push
+    .set noreorder
+    li v0, __NR_getrandom
+    syscall
+    bnez a3, 1f
+    move a0, v0
+    j ra
+    nop
+1:
+    move t0, ra
+    bal     2f
+    nop
+2:
+    .cpsetup ra, t1, 2b
+    LA t9,__set_errno_internal
+    .cpreturn
+    j t9
+    move ra, t0
+    .set pop
+END(getrandom)
diff --git a/libc/arch-x86/syscalls/getrandom.S b/libc/arch-x86/syscalls/getrandom.S
new file mode 100644
index 0000000..2e8ebc9
--- /dev/null
+++ b/libc/arch-x86/syscalls/getrandom.S
@@ -0,0 +1,39 @@
+/* Generated by gensyscalls.py. Do not edit. */
+
+#include <private/bionic_asm.h>
+
+ENTRY(getrandom)
+    pushl   %ebx
+    .cfi_def_cfa_offset 8
+    .cfi_rel_offset ebx, 0
+    pushl   %ecx
+    .cfi_adjust_cfa_offset 4
+    .cfi_rel_offset ecx, 0
+    pushl   %edx
+    .cfi_adjust_cfa_offset 4
+    .cfi_rel_offset edx, 0
+
+    call    __kernel_syscall
+    pushl   %eax
+    .cfi_adjust_cfa_offset 4
+    .cfi_rel_offset eax, 0
+
+    mov     20(%esp), %ebx
+    mov     24(%esp), %ecx
+    mov     28(%esp), %edx
+    movl    $__NR_getrandom, %eax
+    call    *(%esp)
+    addl    $4, %esp
+
+    cmpl    $-MAX_ERRNO, %eax
+    jb      1f
+    negl    %eax
+    pushl   %eax
+    call    __set_errno_internal
+    addl    $4, %esp
+1:
+    popl    %edx
+    popl    %ecx
+    popl    %ebx
+    ret
+END(getrandom)
diff --git a/libc/arch-x86_64/syscalls/getrandom.S b/libc/arch-x86_64/syscalls/getrandom.S
new file mode 100644
index 0000000..c5e44a9
--- /dev/null
+++ b/libc/arch-x86_64/syscalls/getrandom.S
@@ -0,0 +1,15 @@
+/* Generated by gensyscalls.py. Do not edit. */
+
+#include <private/bionic_asm.h>
+
+ENTRY(getrandom)
+    movl    $__NR_getrandom, %eax
+    syscall
+    cmpq    $-MAX_ERRNO, %rax
+    jb      1f
+    negl    %eax
+    movl    %eax, %edi
+    call    __set_errno_internal
+1:
+    ret
+END(getrandom)
diff --git a/libc/bionic/clone.cpp b/libc/bionic/clone.cpp
index d7ce37f..66ec503 100644
--- a/libc/bionic/clone.cpp
+++ b/libc/bionic/clone.cpp
@@ -34,11 +34,15 @@
 
 #include "pthread_internal.h"
 
+#include "private/bionic_macros.h"
+
 extern "C" pid_t __bionic_clone(uint32_t flags, void* child_stack, int* parent_tid, void* tls, int* child_tid, int (*fn)(void*), void* arg);
 extern "C" __noreturn void __exit(int status);
 
 // Called from the __bionic_clone assembler to call the thread function then exit.
 extern "C" __LIBC_HIDDEN__ void __start_thread(int (*fn)(void*), void* arg) {
+  BIONIC_STOP_UNWIND;
+
   pthread_internal_t* self = __get_thread();
   if (self && self->tid == -1) {
     self->tid = syscall(__NR_gettid);
diff --git a/libc/bionic/grp_pwd.cpp b/libc/bionic/grp_pwd.cpp
index 2823662..50fcbce 100644
--- a/libc/bionic/grp_pwd.cpp
+++ b/libc/bionic/grp_pwd.cpp
@@ -580,7 +580,7 @@
   ErrnoRestorer errno_restorer;
   *result = NULL;
   char* p = reinterpret_cast<char*>(
-      BIONIC_ALIGN(reinterpret_cast<uintptr_t>(buf), sizeof(uintptr_t)));
+      __BIONIC_ALIGN(reinterpret_cast<uintptr_t>(buf), sizeof(uintptr_t)));
   if (p + sizeof(group_state_t) > buf + buflen) {
     return ERANGE;
   }
diff --git a/libc/bionic/jemalloc_wrapper.cpp b/libc/bionic/jemalloc_wrapper.cpp
index 266b966..19081a4 100644
--- a/libc/bionic/jemalloc_wrapper.cpp
+++ b/libc/bionic/jemalloc_wrapper.cpp
@@ -23,7 +23,7 @@
 
 void* je_pvalloc(size_t bytes) {
   size_t pagesize = getpagesize();
-  size_t size = BIONIC_ALIGN(bytes, pagesize);
+  size_t size = __BIONIC_ALIGN(bytes, pagesize);
   if (size < bytes) {
     return NULL;
   }
diff --git a/libc/bionic/libc_init_dynamic.cpp b/libc/bionic/libc_init_dynamic.cpp
index 7c73950..349d488 100644
--- a/libc/bionic/libc_init_dynamic.cpp
+++ b/libc/bionic/libc_init_dynamic.cpp
@@ -52,6 +52,7 @@
 #include "libc_init_common.h"
 
 #include "private/bionic_globals.h"
+#include "private/bionic_macros.h"
 #include "private/bionic_ssp.h"
 #include "private/bionic_tls.h"
 #include "private/KernelArgumentBlock.h"
@@ -108,6 +109,7 @@
                             void (*onexit)(void) __unused,
                             int (*slingshot)(int, char**, char**),
                             structors_array_t const * const structors) {
+  BIONIC_STOP_UNWIND;
 
   KernelArgumentBlock args(raw_args);
 
diff --git a/libc/bionic/libc_init_static.cpp b/libc/bionic/libc_init_static.cpp
index 5e06d39..93a63b5 100644
--- a/libc/bionic/libc_init_static.cpp
+++ b/libc/bionic/libc_init_static.cpp
@@ -40,6 +40,7 @@
 #include "pthread_internal.h"
 
 #include "private/bionic_globals.h"
+#include "private/bionic_macros.h"
 #include "private/bionic_page.h"
 #include "private/bionic_tls.h"
 #include "private/KernelArgumentBlock.h"
@@ -82,6 +83,8 @@
                             void (*onexit)(void) __unused,
                             int (*slingshot)(int, char**, char**),
                             structors_array_t const * const structors) {
+  BIONIC_STOP_UNWIND;
+
   KernelArgumentBlock args(raw_args);
   __libc_init_main_thread(args);
 
diff --git a/libc/bionic/mmap.cpp b/libc/bionic/mmap.cpp
index 57a8cdf..3503319 100644
--- a/libc/bionic/mmap.cpp
+++ b/libc/bionic/mmap.cpp
@@ -48,7 +48,7 @@
   }
 
   // prevent allocations large enough for `end - start` to overflow
-  size_t rounded = BIONIC_ALIGN(size, PAGE_SIZE);
+  size_t rounded = __BIONIC_ALIGN(size, PAGE_SIZE);
   if (rounded < size || rounded > PTRDIFF_MAX) {
     errno = ENOMEM;
     return MAP_FAILED;
diff --git a/libc/bionic/mremap.cpp b/libc/bionic/mremap.cpp
index 6653d43..896ccef 100644
--- a/libc/bionic/mremap.cpp
+++ b/libc/bionic/mremap.cpp
@@ -38,7 +38,7 @@
 
 void* mremap(void* old_address, size_t old_size, size_t new_size, int flags, ...) {
   // prevent allocations large enough for `end - start` to overflow
-  size_t rounded = BIONIC_ALIGN(new_size, PAGE_SIZE);
+  size_t rounded = __BIONIC_ALIGN(new_size, PAGE_SIZE);
   if (rounded < new_size || rounded > PTRDIFF_MAX) {
     errno = ENOMEM;
     return MAP_FAILED;
diff --git a/libc/bionic/pthread_create.cpp b/libc/bionic/pthread_create.cpp
index 65ab92c..be0fd1b 100644
--- a/libc/bionic/pthread_create.cpp
+++ b/libc/bionic/pthread_create.cpp
@@ -172,8 +172,8 @@
     // Make sure the stack size and guard size are multiples of PAGE_SIZE.
     if (__builtin_add_overflow(attr->stack_size, attr->guard_size, &mmap_size)) return EAGAIN;
     if (__builtin_add_overflow(mmap_size, sizeof(pthread_internal_t), &mmap_size)) return EAGAIN;
-    mmap_size = BIONIC_ALIGN(mmap_size, PAGE_SIZE);
-    attr->guard_size = BIONIC_ALIGN(attr->guard_size, PAGE_SIZE);
+    mmap_size = __BIONIC_ALIGN(mmap_size, PAGE_SIZE);
+    attr->guard_size = __BIONIC_ALIGN(attr->guard_size, PAGE_SIZE);
     attr->stack_base = __create_thread_mapped_space(mmap_size, attr->guard_size);
     if (attr->stack_base == NULL) {
       return EAGAIN;
diff --git a/libc/bionic/sysconf.cpp b/libc/bionic/sysconf.cpp
index 7325dbd..d45cb38 100644
--- a/libc/bionic/sysconf.cpp
+++ b/libc/bionic/sysconf.cpp
@@ -148,7 +148,7 @@
     case _SC_THREAD_PRIO_INHERIT: return _POSIX_THREAD_PRIO_INHERIT;
     case _SC_THREAD_PRIO_PROTECT: return _POSIX_THREAD_PRIO_PROTECT;
     case _SC_THREAD_SAFE_FUNCTIONS:  return _POSIX_THREAD_SAFE_FUNCTIONS;
-    case _SC_MONOTONIC_CLOCK:   return _POSIX_VERSION;
+    case _SC_MONOTONIC_CLOCK:   return _POSIX_MONOTONIC_CLOCK;
 
     case _SC_2_PBS:             return -1;     // Obsolescent in POSIX.1-2008.
     case _SC_2_PBS_ACCOUNTING:  return -1;     // Obsolescent in POSIX.1-2008.
@@ -159,7 +159,7 @@
     case _SC_ADVISORY_INFO:     return _POSIX_ADVISORY_INFO;
     case _SC_BARRIERS:          return _POSIX_BARRIERS;
     case _SC_CLOCK_SELECTION:   return _POSIX_CLOCK_SELECTION;
-    case _SC_CPUTIME:           return _POSIX_VERSION;
+    case _SC_CPUTIME:           return _POSIX_CPUTIME;
 
     case _SC_HOST_NAME_MAX:     return _POSIX_HOST_NAME_MAX;    // Minimum requirement.
     case _SC_IPV6:              return _POSIX_IPV6;
@@ -172,7 +172,7 @@
     case _SC_SPORADIC_SERVER:   return _POSIX_SPORADIC_SERVER;
     case _SC_SS_REPL_MAX:       return -1;
     case _SC_SYMLOOP_MAX:       return _POSIX_SYMLOOP_MAX;      // Minimum requirement.
-    case _SC_THREAD_CPUTIME:    return _POSIX_VERSION;
+    case _SC_THREAD_CPUTIME:    return _POSIX_THREAD_CPUTIME;
 
     case _SC_THREAD_PROCESS_SHARED: return _POSIX_THREAD_PROCESS_SHARED;
     case _SC_THREAD_ROBUST_PRIO_INHERIT:  return _POSIX_THREAD_ROBUST_PRIO_INHERIT;
diff --git a/libc/bionic/system_properties.cpp b/libc/bionic/system_properties.cpp
index c57cd9c..b781ea3 100644
--- a/libc/bionic/system_properties.cpp
+++ b/libc/bionic/system_properties.cpp
@@ -304,7 +304,7 @@
 }
 
 void* prop_area::allocate_obj(const size_t size, uint_least32_t* const off) {
-  const size_t aligned = BIONIC_ALIGN(size, sizeof(uint_least32_t));
+  const size_t aligned = __BIONIC_ALIGN(size, sizeof(uint_least32_t));
   if (bytes_used_ + aligned > pa_data_size) {
     return nullptr;
   }
diff --git a/libc/include/android/api-level.h b/libc/include/android/api-level.h
index 7e3aa99..18825e7 100644
--- a/libc/include/android/api-level.h
+++ b/libc/include/android/api-level.h
@@ -57,5 +57,6 @@
 #define __ANDROID_API_N__ 24
 #define __ANDROID_API_N_MR1__ 25
 #define __ANDROID_API_O__ 26
+#define __ANDROID_API_O_MR1__ 27
 
 #endif /* ANDROID_API_LEVEL_H */
diff --git a/libc/include/android/legacy_sys_mman_inlines.h b/libc/include/android/legacy_sys_mman_inlines.h
new file mode 100644
index 0000000..7eb537e
--- /dev/null
+++ b/libc/include/android/legacy_sys_mman_inlines.h
@@ -0,0 +1,70 @@
+/*
+ * Copyright (C) 2017 The Android Open Source Project
+ * All rights reserved.
+ *
+ * Redistribution and use in source and binary forms, with or without
+ * modification, are permitted provided that the following conditions
+ * are met:
+ *  * Redistributions of source code must retain the above copyright
+ *    notice, this list of conditions and the following disclaimer.
+ *  * Redistributions in binary form must reproduce the above copyright
+ *    notice, this list of conditions and the following disclaimer in
+ *    the documentation and/or other materials provided with the
+ *    distribution.
+ *
+ * THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS
+ * "AS IS" AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT
+ * LIMITED TO, THE IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS
+ * FOR A PARTICULAR PURPOSE ARE DISCLAIMED. IN NO EVENT SHALL THE
+ * COPYRIGHT OWNER OR CONTRIBUTORS BE LIABLE FOR ANY DIRECT, INDIRECT,
+ * INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING,
+ * BUT NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; LOSS
+ * OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED
+ * AND ON ANY THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY,
+ * OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT
+ * OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF
+ * SUCH DAMAGE.
+ */
+
+#pragma once
+
+#include <sys/cdefs.h>
+#include <sys/mman.h>
+#include <sys/syscall.h>
+#include <unistd.h>
+
+#if __ANDROID_API__ < __ANDROID_API_L__
+
+__BEGIN_DECLS
+
+/*
+ * While this was never an inline, this function alone has caused most of the
+ * bug reports related to _FILE_OFFSET_BITS=64. Providing an inline for it
+ * should allow a lot more code to build with _FILE_OFFSET_BITS=64 when
+ * targeting pre-L.
+ */
+static __inline void* mmap64(void* __addr, size_t __size, int __prot, int __flags, int __fd,
+                             off64_t __offset) __RENAME(mmap64);
+static __inline void* mmap64(void* __addr, size_t __size, int __prot, int __flags, int __fd,
+                             off64_t __offset) {
+  const int __mmap2_shift = 12; // 2**12 == 4096
+  if (__offset < 0 || (__offset & ((1UL << __mmap2_shift) - 1)) != 0) {
+    errno = EINVAL;
+    return MAP_FAILED;
+  }
+
+  // prevent allocations large enough for `end - start` to overflow
+  size_t __rounded = __BIONIC_ALIGN(__size, PAGE_SIZE);
+  if (__rounded < __size || __rounded > PTRDIFF_MAX) {
+    errno = ENOMEM;
+    return MAP_FAILED;
+  }
+
+  extern void* __mmap2(void* __addr, size_t __size, int __prot, int __flags, int __fd,
+                       size_t __offset);
+  return __mmap2(__addr, __size, __prot, __flags, __fd, __offset >> __mmap2_shift);
+}
+
+__END_DECLS
+
+#endif  /* __ANDROID_API__ < __ANDROID_API_L__ */
diff --git a/libc/include/bits/posix_limits.h b/libc/include/bits/posix_limits.h
index cfc46f5..4038c3a 100644
--- a/libc/include/bits/posix_limits.h
+++ b/libc/include/bits/posix_limits.h
@@ -31,93 +31,67 @@
 
 #include <sys/cdefs.h>
 
-#define __BIONIC_POSIX_FEATURE_SINCE(level) (((__ANDROID_API__) >= level) ? 200809L : -1)
+#define _POSIX_VERSION 200809L
+#define _POSIX2_VERSION _POSIX_VERSION
+#define _XOPEN_VERSION 700
 
-/* Any constant values here other than -1 or 200809L are explicitly specified by POSIX.1-2008. */
+#define __BIONIC_POSIX_FEATURE_MISSING (-1)
+#define __BIONIC_POSIX_FEATURE_SINCE(level) \
+    (((__ANDROID_API__) >= level) ? _POSIX_VERSION : __BIONIC_POSIX_FEATURE_MISSING)
+
+/* Availability macros. */
+/* See http://man7.org/linux/man-pages/man7/posixoptions.7.html for documentation. */
 /* Keep this list sorted by name. */
 #define _POSIX_ADVISORY_INFO __BIONIC_POSIX_FEATURE_SINCE(23) /* posix_memadvise arrived late. */
-#define _POSIX_AIO_LISTIO_MAX       2
-#define _POSIX_AIO_MAX              1
-#define _POSIX_ARG_MAX              4096
-#define _POSIX_ASYNCHRONOUS_IO      -1  /* not implemented */
+#define _POSIX_ASYNCHRONOUS_IO __BIONIC_POSIX_FEATURE_MISSING
 #define _POSIX_BARRIERS __BIONIC_POSIX_FEATURE_SINCE(24)
-#define _POSIX_CHILD_MAX            25
-#define _POSIX_CHOWN_RESTRICTED     1  /* yes, chown requires appropriate privileges */
-#define _POSIX_CLOCK_SELECTION      200809L
-#define _POSIX_CPUTIME              0  /* Use sysconf to detect support at runtime. */
-#define _POSIX_DELAYTIMER_MAX       32
-#define _POSIX_FSYNC 200809L
-#define _POSIX_HOST_NAME_MAX        255
-#define _POSIX_IPV6                 200809L
-#define _POSIX_JOB_CONTROL          1  /* job control is a Linux feature */
-#define _POSIX_LINK_MAX             8
-#define _POSIX_LOGIN_NAME_MAX       9  /* includes trailing NUL */
-#define _POSIX_MAPPED_FILES         200809L  /* mmap-ed files supported */
-#define _POSIX_MAX_CANON            255
-#define _POSIX_MAX_INPUT            255
-#define _POSIX_MEMLOCK __BIONIC_POSIX_FEATURE_SINCE(17) /* mlockall. */
-#define _POSIX_MEMLOCK_RANGE        200809L /* mlock. */
-#define _POSIX_MEMORY_PROTECTION    200809L
-#define _POSIX_MESSAGE_PASSING      -1  /* not implemented */
-#define _POSIX_MONOTONIC_CLOCK      0  /* the monotonic clock may be available; ask sysconf */
-#define _POSIX_MQ_OPEN_MAX          8
-#define _POSIX_MQ_PRIO_MAX          32
-#define _POSIX_NAME_MAX             14
-#define _POSIX_NGROUPS_MAX          8
-#define _POSIX_NO_TRUNC             1  /* very long pathnames generate an error */
-#define _POSIX_OPEN_MAX             20
-#define _POSIX_PATH_MAX             256
-#define _POSIX_PIPE_BUF             512
-#define _POSIX_PRIORITY_SCHEDULING  200809L  /* priority scheduling is a Linux feature */
-#define _POSIX_PRIORITIZED_IO       -1  /* not implemented */
-#define _POSIX_RAW_SOCKETS          200809L
-#define _POSIX_READER_WRITER_LOCKS  200809L
-#define _POSIX_REALTIME_SIGNALS     200809L
-#define _POSIX_REGEXP               1
-#define _POSIX_RE_DUP_MAX           255
-#define _POSIX_SAVED_IDS            1  /* saved user ids is a Linux feature */
-#define _POSIX_SEMAPHORES           200809L
-#define _POSIX_SEM_NSEMS_MAX        256
-#define _POSIX_SEM_VALUE_MAX        32767
-#define _POSIX_SHARED_MEMORY_OBJECTS  -1  /* shm_open()/shm_unlink() not implemented */
-#define _POSIX_SHELL                1   /* system() supported */
-#define _POSIX_SIGQUEUE_MAX         32
-#define _POSIX_SPAWN                -1  /* not implemented */
-#define _POSIX_SPIN_LOCKS __BIONIC_POSIX_FEATURE_SINCE(24)
-#define _POSIX_SPORADIC_SERVER      -1  /* not implemented */
-#define _POSIX_SSIZE_MAX            32767
-#define _POSIX_STREAM_MAX           8
-#define _POSIX_SYMLINK_MAX          255
-#define _POSIX_SYMLOOP_MAX          8
-#define _POSIX_SYNCHRONIZED_IO      200809L  /* synchronized i/o supported */
-#define _POSIX_THREADS              200809L  /* we support threads */
-#define _POSIX_THREAD_ATTR_STACKADDR  200809L
-#define _POSIX_THREAD_ATTR_STACKSIZE  200809L
-#define _POSIX_THREAD_CPUTIME       0  /* Use sysconf to detect support at runtime. */
-#define _POSIX_THREAD_DESTRUCTOR_ITERATIONS 4
-#define _POSIX_THREAD_KEYS_MAX      128
-#define _POSIX_THREAD_PRIORITY_SCHEDULING 200809L
-#define _POSIX_THREAD_PRIO_INHERIT -1  /* not implemented */
-#define _POSIX_THREAD_PRIO_PROTECT -1  /* not implemented */
-#define _POSIX_THREAD_PROCESS_SHARED  200809L  /* PTHREAD_PROCESS_SHARED supported. */
-#define _POSIX_THREAD_ROBUST_PRIO_INHERIT -1  /* not implemented */
-#define _POSIX_THREAD_ROBUST_PRIO_PROTECT -1  /* not implemented */
-#define _POSIX_THREAD_SAFE_FUNCTIONS 200809L
-#define _POSIX_THREAD_SPORADIC_SERVER -1  /* not implemented */
-#define _POSIX_THREAD_THREADS_MAX   64
+#define _POSIX_CHOWN_RESTRICTED 1 /* chown/fchown require appropriate privileges. */
+#define _POSIX_CLOCK_SELECTION __BIONIC_POSIX_FEATURE_SINCE(21) /* clock_nanosleep/pthread_condattr_getclock/pthread_condattr_setclock. */
+#define _POSIX_CPUTIME _POSIX_VERSION /* CLOCK_PROCESS_CPUTIME_ID. */
+#define _POSIX_FSYNC _POSIX_VERSION /* fsync. */
+#define _POSIX_IPV6 _POSIX_VERSION
+#define _POSIX_JOB_CONTROL __BIONIC_POSIX_FEATURE_SINCE(21) /* setpgid/tcdrain/tcflush/tcgetpgrp/tcsendbreak/tcsetattr/tcsetpgrp. */
+#define _POSIX_MAPPED_FILES _POSIX_VERSION /* mmap/msync/munmap. */
+#define _POSIX_MEMLOCK __BIONIC_POSIX_FEATURE_SINCE(17) /* mlockall/munlockall. */
+#define _POSIX_MEMLOCK_RANGE _POSIX_VERSION /* mlock/munlock. */
+#define _POSIX_MEMORY_PROTECTION _POSIX_VERSION /* mprotect. */
+#define _POSIX_MESSAGE_PASSING __BIONIC_POSIX_FEATURE_MISSING
+#define _POSIX_MONOTONIC_CLOCK _POSIX_VERSION /* CLOCK_MONOTONIC. */
+#define _POSIX_NO_TRUNC 1 /* Over-long pathnames return errors. */
+#define _POSIX_PRIORITIZED_IO __BIONIC_POSIX_FEATURE_MISSING
+#define _POSIX_PRIORITY_SCHEDULING _POSIX_VERSION /* sched_*. */
+#define _POSIX_RAW_SOCKETS _POSIX_VERSION
+#define _POSIX_READER_WRITER_LOCKS _POSIX_VERSION /* pthread_rwlock*. */
+#define _POSIX_REALTIME_SIGNALS __BIONIC_POSIX_FEATURE_SINCE(23) /* sigqueue/sigtimedwait/sigwaitinfo. */
+#define _POSIX_REGEXP 1
+#define _POSIX_SAVED_IDS 1
+#define _POSIX_SEMAPHORES _POSIX_VERSION /* sem_*. */
+#define _POSIX_SHARED_MEMORY_OBJECTS __BIONIC_POSIX_FEATURE_MISSING /* mmap/munmap are implemented, but shm_open/shm_unlink are not. */
+#define _POSIX_SHELL 1 /* system. */
+#define _POSIX_SPAWN __BIONIC_POSIX_FEATURE_MISSING /* <spawn.h> */
+#define _POSIX_SPIN_LOCKS __BIONIC_POSIX_FEATURE_SINCE(24) /* pthread_spin_*. */
+#define _POSIX_SPORADIC_SERVER _POSIX_VERSION /* sched_setparam/sched_setscheduler. */
+#define _POSIX_SYNCHRONIZED_IO _POSIX_VERSION
+#define _POSIX_THREAD_ATTR_STACKADDR _POSIX_VERSION /* Strictly, we're missing the deprecated pthread_attr_getstackaddr/pthread_attr_setstackaddr, but we do have pthread_attr_getstack/pthread_attr_setstack. */
+#define _POSIX_THREAD_ATTR_STACKSIZE _POSIX_VERSION /* pthread_attr_getstack/pthread_attr_getstacksize/pthread_attr_setstack/pthread_attr_setstacksize. */
+#define _POSIX_THREAD_CPUTIME _POSIX_VERSION /* CLOCK_THREAD_CPUTIME_ID. */
+#define _POSIX_THREAD_PRIO_INHERIT __BIONIC_POSIX_FEATURE_MISSING
+#define _POSIX_THREAD_PRIO_PROTECT __BIONIC_POSIX_FEATURE_MISSING
+#define _POSIX_THREAD_PRIORITY_SCHEDULING _POSIX_VERSION /* Strictly, pthread_attr_getinheritsched/pthread_attr_setinheritsched are missing. */
+#define _POSIX_THREAD_PROCESS_SHARED _POSIX_VERSION
+#define _POSIX_THREAD_ROBUST_PRIO_INHERIT __BIONIC_POSIX_FEATURE_MISSING
+#define _POSIX_THREAD_ROBUST_PRIO_PROTECT __BIONIC_POSIX_FEATURE_MISSING
+#define _POSIX_THREAD_SAFE_FUNCTIONS _POSIX_VERSION
+#define _POSIX_THREAD_SPORADIC_SERVER _POSIX_VERSION /* sched_setparam/sched_setscheduler. */
+#define _POSIX_THREADS _POSIX_VERSION /* Strictly, pthread_cancel/pthread_testcancel are missing. */
 #define _POSIX_TIMEOUTS __BIONIC_POSIX_FEATURE_SINCE(21) /* pthread_mutex_timedlock arrived late. */
-#define _POSIX_TIMERS               200809L  /* Posix timers are supported */
-#define _POSIX_TIMER_MAX            32
-#define _POSIX_TRACE                -1  /* not implemented */
-#define _POSIX_TRACE_EVENT_FILTER   -1  /* not implemented */
-#define _POSIX_TRACE_INHERIT        -1  /* not implemented */
-#define _POSIX_TRACE_LOG            -1  /* not implemented */
-#define _POSIX_TRACE_NAME_MAX       8
-#define _POSIX_TRACE_SYS_MAX        8
-#define _POSIX_TRACE_USER_EVENT_MAX 32
-#define _POSIX_TTY_NAME_MAX         9  /* includes trailing NUL */
-#define _POSIX_TYPED_MEMORY_OBJECTS -1  /* not implemented */
-#define _POSIX_TZNAME_MAX           6
+#define _POSIX_TIMERS _POSIX_VERSION /* clock_getres/clock_gettime/clock_settime/nanosleep/timer_create/timer_delete/timer_gettime/timer_getoverrun/timer_settime. */
+#define _POSIX_TRACE __BIONIC_POSIX_FEATURE_MISSING
+#define _POSIX_TRACE_EVENT_FILTER __BIONIC_POSIX_FEATURE_MISSING
+#define _POSIX_TRACE_INHERIT __BIONIC_POSIX_FEATURE_MISSING
+#define _POSIX_TRACE_LOG __BIONIC_POSIX_FEATURE_MISSING
+#define _POSIX_TYPED_MEMORY_OBJECTS __BIONIC_POSIX_FEATURE_MISSING
+
 #define _POSIX_VDISABLE             '\0'
 
 #if defined(__LP64__)
@@ -132,6 +106,42 @@
 #define _POSIX_V7_LPBIG_OFFBIG      -1
 #endif
 
+/* Minimum values for other maxima. These numbers are simply lower bounds mandated by POSIX. */
+/* Any constant values here other than -1 or 200809L are explicitly specified by POSIX.1-2008. */
+#define _POSIX_AIO_LISTIO_MAX       2
+#define _POSIX_AIO_MAX              1
+#define _POSIX_ARG_MAX              4096
+#define _POSIX_CHILD_MAX            25
+#define _POSIX_DELAYTIMER_MAX       32
+#define _POSIX_HOST_NAME_MAX        255
+#define _POSIX_LINK_MAX             8
+#define _POSIX_LOGIN_NAME_MAX       9  /* includes trailing NUL */
+#define _POSIX_MAX_CANON            255
+#define _POSIX_MAX_INPUT            255
+#define _POSIX_MQ_OPEN_MAX          8
+#define _POSIX_MQ_PRIO_MAX          32
+#define _POSIX_NAME_MAX             14
+#define _POSIX_NGROUPS_MAX          8
+#define _POSIX_OPEN_MAX             20
+#define _POSIX_PATH_MAX             256
+#define _POSIX_PIPE_BUF             512
+#define _POSIX_RE_DUP_MAX           255
+#define _POSIX_SEM_NSEMS_MAX        256
+#define _POSIX_SEM_VALUE_MAX        32767
+#define _POSIX_SIGQUEUE_MAX         32
+#define _POSIX_SSIZE_MAX            32767
+#define _POSIX_STREAM_MAX           8
+#define _POSIX_SYMLINK_MAX          255
+#define _POSIX_SYMLOOP_MAX          8
+#define _POSIX_THREAD_DESTRUCTOR_ITERATIONS 4
+#define _POSIX_THREAD_KEYS_MAX      128
+#define _POSIX_THREAD_THREADS_MAX   64
+#define _POSIX_TIMER_MAX            32
+#define _POSIX_TRACE_NAME_MAX       8
+#define _POSIX_TRACE_SYS_MAX        8
+#define _POSIX_TRACE_USER_EVENT_MAX 32
+#define _POSIX_TTY_NAME_MAX         9  /* includes trailing NUL */
+#define _POSIX_TZNAME_MAX           6
 #define _POSIX2_BC_BASE_MAX         99
 #define _POSIX2_BC_DIM_MAX          2048
 #define _POSIX2_BC_SCALE_MAX        99
diff --git a/libc/include/glob.h b/libc/include/glob.h
new file mode 100644
index 0000000..6ae8573
--- /dev/null
+++ b/libc/include/glob.h
@@ -0,0 +1,98 @@
+/*
+ * Copyright (c) 1989, 1993
+ *	The Regents of the University of California.  All rights reserved.
+ *
+ * This code is derived from software contributed to Berkeley by
+ * Guido van Rossum.
+ *
+ * Redistribution and use in source and binary forms, with or without
+ * modification, are permitted provided that the following conditions
+ * are met:
+ * 1. Redistributions of source code must retain the above copyright
+ *    notice, this list of conditions and the following disclaimer.
+ * 2. Redistributions in binary form must reproduce the above copyright
+ *    notice, this list of conditions and the following disclaimer in the
+ *    documentation and/or other materials provided with the distribution.
+ * 3. Neither the name of the University nor the names of its contributors
+ *    may be used to endorse or promote products derived from this software
+ *    without specific prior written permission.
+ *
+ * THIS SOFTWARE IS PROVIDED BY THE REGENTS AND CONTRIBUTORS ``AS IS'' AND
+ * ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE
+ * IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE
+ * ARE DISCLAIMED.  IN NO EVENT SHALL THE REGENTS OR CONTRIBUTORS BE LIABLE
+ * FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL
+ * DAMAGES (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS
+ * OR SERVICES; LOSS OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION)
+ * HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT
+ * LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY
+ * OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF
+ * SUCH DAMAGE.
+ *
+ *	@(#)glob.h	8.1 (Berkeley) 6/2/93
+ * $FreeBSD$
+ */
+
+#ifndef _GLOB_H_
+#define _GLOB_H_
+
+#include <sys/cdefs.h>
+#include <sys/types.h>
+
+struct dirent;
+struct stat;
+
+typedef struct {
+  size_t gl_pathc;	/* Count of total paths so far. */
+  size_t gl_matchc;	/* Count of paths matching pattern. */
+  size_t gl_offs;		/* Reserved at beginning of gl_pathv. */
+  int gl_flags;		/* Copy of flags parameter to glob. */
+  char** gl_pathv;	/* List of paths matching pattern. */
+
+  /* Copy of `__error_callback` parameter to glob. */
+  int (*gl_errfunc)(const char* __failure_path, int __failure_errno);
+
+  /*
+   * Alternate filesystem access methods for glob; replacement
+   * versions of closedir(3), readdir(3), opendir(3), stat(2)
+   * and lstat(2).
+   */
+  void (*gl_closedir)(void*);
+  struct dirent* (*gl_readdir)(void*);
+  void* (*gl_opendir)(const char*);
+  int (*gl_lstat)(const char*, struct stat*);
+  int (*gl_stat)(const char*, struct stat*);
+} glob_t;
+
+/* Believed to have been introduced in 1003.2-1992 */
+#define GLOB_APPEND	0x0001	/* Append to output from previous call. */
+#define GLOB_DOOFFS	0x0002	/* Prepend `gl_offs` null pointers (leaving space for exec, say). */
+#define GLOB_ERR	0x0004	/* Return on error. */
+#define GLOB_MARK	0x0008	/* Append "/" to the names of returned directories. */
+#define GLOB_NOCHECK	0x0010	/* Return pattern itself if nothing matches. */
+#define GLOB_NOSORT	0x0020	/* Don't sort. */
+#define GLOB_NOESCAPE	0x2000	/* Disable backslash escaping. */
+
+/* Error values returned by glob(3) */
+#define GLOB_NOSPACE	(-1)	/* Malloc call failed. */
+#define GLOB_ABORTED	(-2)	/* Unignored error. */
+#define GLOB_NOMATCH	(-3)	/* No match and GLOB_NOCHECK was not set. */
+
+#if __USE_BSD
+#define GLOB_ALTDIRFUNC	0x0040	/* Use alternately specified directory funcs. */
+#define GLOB_BRACE	0x0080	/* Expand braces like csh. */
+#define GLOB_MAGCHAR	0x0100	/* Set in `gl_flags` if the pattern had globbing characters. */
+#define GLOB_NOMAGIC	0x0200	/* GLOB_NOCHECK without magic chars (csh). */
+#define GLOB_QUOTE	0x0400	/* Quote special chars with \. */
+#define GLOB_TILDE	0x0800	/* Expand tilde names from the passwd file. */
+#define GLOB_LIMIT	0x1000	/* limit number of returned paths */
+#endif
+
+__BEGIN_DECLS
+
+int glob(const char* __pattern, int __flags, int (*__error_callback)(const char* __failure_path, int __failure_errno), glob_t* __result_ptr) __INTRODUCED_IN_FUTURE;
+void globfree(glob_t* __result_ptr) __INTRODUCED_IN_FUTURE;
+
+__END_DECLS
+
+#endif
diff --git a/libc/include/limits.h b/libc/include/limits.h
index 51f4fad..4384f6f 100644
--- a/libc/include/limits.h
+++ b/libc/include/limits.h
@@ -140,10 +140,6 @@
 #define LOGIN_NAME_MAX 256
 #define TTY_NAME_MAX 32
 
-#define _POSIX_VERSION 200809L
-#define _POSIX2_VERSION _POSIX_VERSION
-#define _XOPEN_VERSION 700       /* by Posix definition */
-
 /* >= _POSIX_THREAD_DESTRUCTOR_ITERATIONS */
 #define PTHREAD_DESTRUCTOR_ITERATIONS 4
 /* >= _POSIX_THREAD_KEYS_MAX */
diff --git a/libc/include/sys/cdefs.h b/libc/include/sys/cdefs.h
index 063b51d..3656733 100644
--- a/libc/include/sys/cdefs.h
+++ b/libc/include/sys/cdefs.h
@@ -79,6 +79,8 @@
 #define __BIONIC_CAST(_k,_t,_v) ((_t) (_v))
 #endif
 
+#define __BIONIC_ALIGN(__value, __alignment) (((__value) + (__alignment)-1) & ~((__alignment)-1))
+
 /*
  * The __CONCAT macro is used to concatenate parts of symbol names, e.g.
  * with "#define OLD(foo) __CONCAT(old,foo)", OLD(foo) produces oldfoo.
diff --git a/libc/include/sys/mman.h b/libc/include/sys/mman.h
index 1e752c4..028b024 100644
--- a/libc/include/sys/mman.h
+++ b/libc/include/sys/mman.h
@@ -45,12 +45,30 @@
 #define MREMAP_FIXED    2
 
 #if defined(__USE_FILE_OFFSET64)
-void* mmap(void* __addr, size_t __size, int __prot, int __flags, int __fd, off_t __offset) __RENAME(mmap64) __INTRODUCED_IN(21);
+/*
+ * mmap64 wasn't really around until L, but we added an inline for it since it
+ * allows a lot more code to compile with _FILE_OFFSET_BITS=64.
+ *
+ * GCC removes the static inline unless it is explicitly used. We can get around
+ * this with __attribute__((used)), but that needlessly adds a definition of
+ * mmap64 to every translation unit that includes this header. Instead, just
+ * preserve the old behavior for GCC and emit a useful diagnostic.
+ */
+void* mmap(void* __addr, size_t __size, int __prot, int __flags, int __fd, off_t __offset)
+#if !defined(__clang__) && __ANDROID_API__ < __ANDROID_API_L__
+    __attribute__((error("mmap is not available with _FILE_OFFSET_BITS=64 when using GCC until "
+                         "android-21. Either raise your minSdkVersion, disable "
+                         "_FILE_OFFSET_BITS=64, or switch to Clang.")));
+#else
+    __RENAME(mmap64);
+#endif  /* defined(__clang__) */
 #else
 void* mmap(void* __addr, size_t __size, int __prot, int __flags, int __fd, off_t __offset);
-#endif
+#endif  /* defined(__USE_FILE_OFFSET64) */
 
+#if __ANDROID_API__ >= __ANDROID_API_L__
 void* mmap64(void* __addr, size_t __size, int __prot, int __flags, int __fd, off64_t __offset) __INTRODUCED_IN(21);
+#endif
 
 int munmap(void* __addr, size_t __size);
 int msync(void* __addr, size_t __size, int __flags);
@@ -86,4 +104,6 @@
 
 __END_DECLS
 
+#include <android/legacy_sys_mman_inlines.h>
+
 #endif
diff --git a/libc/include/sys/random.h b/libc/include/sys/random.h
new file mode 100644
index 0000000..3475652
--- /dev/null
+++ b/libc/include/sys/random.h
@@ -0,0 +1,47 @@
+/*
+ * Copyright (C) 2017 The Android Open Source Project
+ * All rights reserved.
+ *
+ * Redistribution and use in source and binary forms, with or without
+ * modification, are permitted provided that the following conditions
+ * are met:
+ *  * Redistributions of source code must retain the above copyright
+ *    notice, this list of conditions and the following disclaimer.
+ *  * Redistributions in binary form must reproduce the above copyright
+ *    notice, this list of conditions and the following disclaimer in
+ *    the documentation and/or other materials provided with the
+ *    distribution.
+ *
+ * THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS
+ * "AS IS" AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT
+ * LIMITED TO, THE IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS
+ * FOR A PARTICULAR PURPOSE ARE DISCLAIMED. IN NO EVENT SHALL THE
+ * COPYRIGHT OWNER OR CONTRIBUTORS BE LIABLE FOR ANY DIRECT, INDIRECT,
+ * INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING,
+ * BUT NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; LOSS
+ * OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED
+ * AND ON ANY THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY,
+ * OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT
+ * OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF
+ * SUCH DAMAGE.
+ */
+
+#ifndef _SYS_RANDOM_H_
+#define _SYS_RANDOM_H_
+
+#include <sys/cdefs.h>
+#include <sys/types.h>
+
+#include <linux/random.h>
+
+__BEGIN_DECLS
+
+/* See also arc4random_buf in <stdlib.h>, which is available in all API levels. */
+
+int getentropy(void* __buffer, size_t __buffer_size) __wur __INTRODUCED_IN_FUTURE;
+
+ssize_t getrandom(void* __buffer, size_t __buffer_size, unsigned int __flags) __wur __INTRODUCED_IN_FUTURE;
+
+__END_DECLS
+
+#endif
diff --git a/libc/libc.arm.map b/libc/libc.arm.map
index 5018951..13c267a 100644
--- a/libc/libc.arm.map
+++ b/libc/libc.arm.map
@@ -1318,21 +1318,25 @@
     wctrans_l; # introduced=26
 } LIBC_N;
 
-LIBC_P {
+LIBC_P { # introduced=P
   global:
-    __freading; # future
-    __fwriting; # future
-    getlogin_r; # future
-    hcreate; # future
-    hcreate_r; # future
-    hdestroy; # future
-    hdestroy_r; # future
-    hsearch; # future
-    hsearch_r; # future
-    iconv; # future
-    iconv_close; # future
-    iconv_open; # future
-    syncfs; # future
+    __freading;
+    __fwriting;
+    getentropy;
+    getrandom;
+    getlogin_r;
+    glob;
+    globfree;
+    hcreate;
+    hcreate_r;
+    hdestroy;
+    hdestroy_r;
+    hsearch;
+    hsearch_r;
+    iconv;
+    iconv_close;
+    iconv_open;
+    syncfs;
 } LIBC_O;
 
 LIBC_PRIVATE {
diff --git a/libc/libc.arm64.map b/libc/libc.arm64.map
index 4ea5896..9d8c1b7 100644
--- a/libc/libc.arm64.map
+++ b/libc/libc.arm64.map
@@ -1238,21 +1238,25 @@
     wctrans_l; # introduced=26
 } LIBC_N;
 
-LIBC_P {
+LIBC_P { # introduced=P
   global:
-    __freading; # future
-    __fwriting; # future
-    getlogin_r; # future
-    hcreate; # future
-    hcreate_r; # future
-    hdestroy; # future
-    hdestroy_r; # future
-    hsearch; # future
-    hsearch_r; # future
-    iconv; # future
-    iconv_close; # future
-    iconv_open; # future
-    syncfs; # future
+    __freading;
+    __fwriting;
+    getentropy;
+    getrandom;
+    getlogin_r;
+    glob;
+    globfree;
+    hcreate;
+    hcreate_r;
+    hdestroy;
+    hdestroy_r;
+    hsearch;
+    hsearch_r;
+    iconv;
+    iconv_close;
+    iconv_open;
+    syncfs;
 } LIBC_O;
 
 LIBC_PRIVATE {
diff --git a/libc/libc.map.txt b/libc/libc.map.txt
index a0ac50a..da462d3 100644
--- a/libc/libc.map.txt
+++ b/libc/libc.map.txt
@@ -1343,21 +1343,25 @@
     wctrans_l; # introduced=26
 } LIBC_N;
 
-LIBC_P {
+LIBC_P { # introduced=P
   global:
-    __freading; # future
-    __fwriting; # future
-    getlogin_r; # future
-    hcreate; # future
-    hcreate_r; # future
-    hdestroy; # future
-    hdestroy_r; # future
-    hsearch; # future
-    hsearch_r; # future
-    iconv; # future
-    iconv_close; # future
-    iconv_open; # future
-    syncfs; # future
+    __freading;
+    __fwriting;
+    getentropy;
+    getrandom;
+    getlogin_r;
+    glob;
+    globfree;
+    hcreate;
+    hcreate_r;
+    hdestroy;
+    hdestroy_r;
+    hsearch;
+    hsearch_r;
+    iconv;
+    iconv_close;
+    iconv_open;
+    syncfs;
 } LIBC_O;
 
 LIBC_PRIVATE {
diff --git a/libc/libc.mips.map b/libc/libc.mips.map
index 8970549..3e41f95 100644
--- a/libc/libc.mips.map
+++ b/libc/libc.mips.map
@@ -1302,21 +1302,25 @@
     wctrans_l; # introduced=26
 } LIBC_N;
 
-LIBC_P {
+LIBC_P { # introduced=P
   global:
-    __freading; # future
-    __fwriting; # future
-    getlogin_r; # future
-    hcreate; # future
-    hcreate_r; # future
-    hdestroy; # future
-    hdestroy_r; # future
-    hsearch; # future
-    hsearch_r; # future
-    iconv; # future
-    iconv_close; # future
-    iconv_open; # future
-    syncfs; # future
+    __freading;
+    __fwriting;
+    getentropy;
+    getrandom;
+    getlogin_r;
+    glob;
+    globfree;
+    hcreate;
+    hcreate_r;
+    hdestroy;
+    hdestroy_r;
+    hsearch;
+    hsearch_r;
+    iconv;
+    iconv_close;
+    iconv_open;
+    syncfs;
 } LIBC_O;
 
 LIBC_PRIVATE {
diff --git a/libc/libc.mips64.map b/libc/libc.mips64.map
index 4ea5896..9d8c1b7 100644
--- a/libc/libc.mips64.map
+++ b/libc/libc.mips64.map
@@ -1238,21 +1238,25 @@
     wctrans_l; # introduced=26
 } LIBC_N;
 
-LIBC_P {
+LIBC_P { # introduced=P
   global:
-    __freading; # future
-    __fwriting; # future
-    getlogin_r; # future
-    hcreate; # future
-    hcreate_r; # future
-    hdestroy; # future
-    hdestroy_r; # future
-    hsearch; # future
-    hsearch_r; # future
-    iconv; # future
-    iconv_close; # future
-    iconv_open; # future
-    syncfs; # future
+    __freading;
+    __fwriting;
+    getentropy;
+    getrandom;
+    getlogin_r;
+    glob;
+    globfree;
+    hcreate;
+    hcreate_r;
+    hdestroy;
+    hdestroy_r;
+    hsearch;
+    hsearch_r;
+    iconv;
+    iconv_close;
+    iconv_open;
+    syncfs;
 } LIBC_O;
 
 LIBC_PRIVATE {
diff --git a/libc/libc.x86.map b/libc/libc.x86.map
index 5439852..c3d678c 100644
--- a/libc/libc.x86.map
+++ b/libc/libc.x86.map
@@ -1300,21 +1300,25 @@
     wctrans_l; # introduced=26
 } LIBC_N;
 
-LIBC_P {
+LIBC_P { # introduced=P
   global:
-    __freading; # future
-    __fwriting; # future
-    getlogin_r; # future
-    hcreate; # future
-    hcreate_r; # future
-    hdestroy; # future
-    hdestroy_r; # future
-    hsearch; # future
-    hsearch_r; # future
-    iconv; # future
-    iconv_close; # future
-    iconv_open; # future
-    syncfs; # future
+    __freading;
+    __fwriting;
+    getentropy;
+    getrandom;
+    getlogin_r;
+    glob;
+    globfree;
+    hcreate;
+    hcreate_r;
+    hdestroy;
+    hdestroy_r;
+    hsearch;
+    hsearch_r;
+    iconv;
+    iconv_close;
+    iconv_open;
+    syncfs;
 } LIBC_O;
 
 LIBC_PRIVATE {
diff --git a/libc/libc.x86_64.map b/libc/libc.x86_64.map
index 4ea5896..9d8c1b7 100644
--- a/libc/libc.x86_64.map
+++ b/libc/libc.x86_64.map
@@ -1238,21 +1238,25 @@
     wctrans_l; # introduced=26
 } LIBC_N;
 
-LIBC_P {
+LIBC_P { # introduced=P
   global:
-    __freading; # future
-    __fwriting; # future
-    getlogin_r; # future
-    hcreate; # future
-    hcreate_r; # future
-    hdestroy; # future
-    hdestroy_r; # future
-    hsearch; # future
-    hsearch_r; # future
-    iconv; # future
-    iconv_close; # future
-    iconv_open; # future
-    syncfs; # future
+    __freading;
+    __fwriting;
+    getentropy;
+    getrandom;
+    getlogin_r;
+    glob;
+    globfree;
+    hcreate;
+    hcreate_r;
+    hdestroy;
+    hdestroy_r;
+    hsearch;
+    hsearch_r;
+    iconv;
+    iconv_close;
+    iconv_open;
+    syncfs;
 } LIBC_O;
 
 LIBC_PRIVATE {
diff --git a/libc/malloc_debug/BacktraceData.cpp b/libc/malloc_debug/BacktraceData.cpp
index 65ae6fa..d597280 100644
--- a/libc/malloc_debug/BacktraceData.cpp
+++ b/libc/malloc_debug/BacktraceData.cpp
@@ -53,7 +53,7 @@
     : OptionData(debug_data) {
   size_t hdr_len = sizeof(BacktraceHeader) + sizeof(uintptr_t) * config.backtrace_frames();
   alloc_offset_ = *offset;
-  *offset += BIONIC_ALIGN(hdr_len, MINIMUM_ALIGNMENT_BYTES);
+  *offset += __BIONIC_ALIGN(hdr_len, MINIMUM_ALIGNMENT_BYTES);
 }
 
 bool BacktraceData::Initialize(const Config& config) {
diff --git a/libc/malloc_debug/Config.cpp b/libc/malloc_debug/Config.cpp
index e3798ab..3cecf9b 100644
--- a/libc/malloc_debug/Config.cpp
+++ b/libc/malloc_debug/Config.cpp
@@ -191,7 +191,7 @@
 
   // It's necessary to align the front guard to MINIMUM_ALIGNMENT_BYTES to
   // make sure that the header is aligned properly.
-  front_guard_bytes_ = BIONIC_ALIGN(rear_guard_bytes_, MINIMUM_ALIGNMENT_BYTES);
+  front_guard_bytes_ = __BIONIC_ALIGN(rear_guard_bytes_, MINIMUM_ALIGNMENT_BYTES);
   return true;
 }
 
@@ -201,7 +201,7 @@
   }
   // It's necessary to align the front guard to MINIMUM_ALIGNMENT_BYTES to
   // make sure that the header is aligned properly.
-  front_guard_bytes_ = BIONIC_ALIGN(front_guard_bytes_, MINIMUM_ALIGNMENT_BYTES);
+  front_guard_bytes_ = __BIONIC_ALIGN(front_guard_bytes_, MINIMUM_ALIGNMENT_BYTES);
   return true;
 }
 
diff --git a/libc/malloc_debug/DebugData.cpp b/libc/malloc_debug/DebugData.cpp
index e9974d7..d6ca998 100644
--- a/libc/malloc_debug/DebugData.cpp
+++ b/libc/malloc_debug/DebugData.cpp
@@ -47,7 +47,7 @@
     need_header_ = true;
 
     // Initialize all of the static header offsets.
-    pointer_offset_ = BIONIC_ALIGN(sizeof(Header), MINIMUM_ALIGNMENT_BYTES);
+    pointer_offset_ = __BIONIC_ALIGN(sizeof(Header), MINIMUM_ALIGNMENT_BYTES);
 
     if (config_.options() & BACKTRACE) {
       backtrace.reset(new BacktraceData(this, config_, &pointer_offset_));
diff --git a/libc/malloc_debug/malloc_debug.cpp b/libc/malloc_debug/malloc_debug.cpp
index d890a1c..a2ada2f 100644
--- a/libc/malloc_debug/malloc_debug.cpp
+++ b/libc/malloc_debug/malloc_debug.cpp
@@ -767,7 +767,7 @@
   }
 
   size_t pagesize = getpagesize();
-  size_t size = BIONIC_ALIGN(bytes, pagesize);
+  size_t size = __BIONIC_ALIGN(bytes, pagesize);
   if (size < bytes) {
     // Overflow
     errno = ENOMEM;
diff --git a/libc/malloc_debug/tests/malloc_debug_unit_tests.cpp b/libc/malloc_debug/tests/malloc_debug_unit_tests.cpp
index 37d8057..d7ba379 100644
--- a/libc/malloc_debug/tests/malloc_debug_unit_tests.cpp
+++ b/libc/malloc_debug/tests/malloc_debug_unit_tests.cpp
@@ -74,9 +74,10 @@
 constexpr uint32_t BACKTRACE_HEADER = 0x1;
 
 static size_t get_tag_offset(uint32_t flags = 0, size_t backtrace_frames = 0) {
-  size_t offset = BIONIC_ALIGN(sizeof(Header), MINIMUM_ALIGNMENT_BYTES);
+  size_t offset = __BIONIC_ALIGN(sizeof(Header), MINIMUM_ALIGNMENT_BYTES);
   if (flags & BACKTRACE_HEADER) {
-    offset += BIONIC_ALIGN(sizeof(BacktraceHeader) + sizeof(uintptr_t) * backtrace_frames, MINIMUM_ALIGNMENT_BYTES);
+    offset += __BIONIC_ALIGN(sizeof(BacktraceHeader) + sizeof(uintptr_t) * backtrace_frames,
+                             MINIMUM_ALIGNMENT_BYTES);
   }
   return offset;
 }
diff --git a/libc/private/bionic_macros.h b/libc/private/bionic_macros.h
index 303218e..c0df917 100644
--- a/libc/private/bionic_macros.h
+++ b/libc/private/bionic_macros.h
@@ -40,9 +40,6 @@
   TypeName() = delete;                           \
   DISALLOW_COPY_AND_ASSIGN(TypeName)
 
-#define BIONIC_ALIGN(value, alignment) \
-  (((value) + (alignment) - 1) & ~((alignment) - 1))
-
 #define BIONIC_ROUND_UP_POWER_OF_2(value) \
   ((sizeof(value) == 8) \
     ? (1UL << (64 - __builtin_clzl(static_cast<unsigned long>(value)))) \
@@ -66,4 +63,17 @@
   return reinterpret_cast<T*>(align_up(reinterpret_cast<uintptr_t>(p), align));
 }
 
+#if defined(__arm__)
+// Do not emit anything for arm, clang does not allow emiting an arm unwind
+// directive.
+// #define BIONIC_STOP_UNWIND asm volatile(".cantunwind")
+#define BIONIC_STOP_UNWIND
+#elif defined(__aarch64__)
+#define BIONIC_STOP_UNWIND asm volatile(".cfi_undefined x30")
+#elif defined(__i386__)
+#define BIONIC_STOP_UNWIND asm volatile(".cfi_undefined \%eip")
+#elif defined(__x86_64__)
+#define BIONIC_STOP_UNWIND asm volatile(".cfi_undefined \%rip")
+#endif
+
 #endif // _BIONIC_MACROS_H_
diff --git a/libc/private/bionic_tls.h b/libc/private/bionic_tls.h
index 852b9ae..de086f2 100644
--- a/libc/private/bionic_tls.h
+++ b/libc/private/bionic_tls.h
@@ -102,7 +102,7 @@
   passwd_state_t passwd;
 };
 
-#define BIONIC_TLS_SIZE (BIONIC_ALIGN(sizeof(bionic_tls), PAGE_SIZE))
+#define BIONIC_TLS_SIZE (__BIONIC_ALIGN(sizeof(bionic_tls), PAGE_SIZE))
 
 /*
  * Bionic uses some pthread keys internally. All pthread keys used internally
diff --git a/libc/seccomp/Android.bp b/libc/seccomp/Android.bp
index a75aa65..b3707bc 100644
--- a/libc/seccomp/Android.bp
+++ b/libc/seccomp/Android.bp
@@ -16,6 +16,7 @@
         "mips64_global_policy.cpp",
     ],
     export_include_dirs: ["include"],
+    cflags: ["-Wall", "-Werror"],
     shared: {
         shared_libs: ["libbase"],
     },
diff --git a/libc/seccomp/arm64_global_policy.cpp b/libc/seccomp/arm64_global_policy.cpp
index 1a138b7..e2c594e 100644
--- a/libc/seccomp/arm64_global_policy.cpp
+++ b/libc/seccomp/arm64_global_policy.cpp
@@ -5,12 +5,12 @@
 
 #include "seccomp_bpfs.h"
 const sock_filter arm64_global_filter[] = {
-BPF_JUMP(BPF_JMP|BPF_JGE|BPF_K, 5, 0, 32),
+BPF_JUMP(BPF_JMP|BPF_JGE|BPF_K, 0, 0, 32),
 BPF_JUMP(BPF_JMP|BPF_JGE|BPF_K, 219, 15, 0),
 BPF_JUMP(BPF_JMP|BPF_JGE|BPF_K, 101, 7, 0),
 BPF_JUMP(BPF_JMP|BPF_JGE|BPF_K, 43, 3, 0),
 BPF_JUMP(BPF_JMP|BPF_JGE|BPF_K, 19, 1, 0),
-BPF_JUMP(BPF_JMP|BPF_JGE|BPF_K, 18, 27, 26), //setxattr|lsetxattr|fsetxattr|getxattr|lgetxattr|fgetxattr|listxattr|llistxattr|flistxattr|removexattr|lremovexattr|fremovexattr|getcwd
+BPF_JUMP(BPF_JMP|BPF_JGE|BPF_K, 18, 27, 26), //io_setup|io_destroy|io_submit|io_cancel|io_getevents|setxattr|lsetxattr|fsetxattr|getxattr|lgetxattr|fgetxattr|listxattr|llistxattr|flistxattr|removexattr|lremovexattr|fremovexattr|getcwd
 BPF_JUMP(BPF_JMP|BPF_JGE|BPF_K, 42, 26, 25), //eventfd2|epoll_create1|epoll_ctl|epoll_pwait|dup|dup3|fcntl|inotify_init1|inotify_add_watch|inotify_rm_watch|ioctl|ioprio_set|ioprio_get|flock|mknodat|mkdirat|unlinkat|symlinkat|linkat|renameat|umount2|mount|pivot_root
 BPF_JUMP(BPF_JMP|BPF_JGE|BPF_K, 59, 1, 0),
 BPF_JUMP(BPF_JMP|BPF_JGE|BPF_K, 58, 24, 23), //statfs|fstatfs|truncate|ftruncate|fallocate|faccessat|chdir|fchdir|chroot|fchmod|fchmodat|fchownat|fchown|openat|close
diff --git a/libc/seccomp/arm_global_policy.cpp b/libc/seccomp/arm_global_policy.cpp
index 2f9a122..d7b5d7e 100644
--- a/libc/seccomp/arm_global_policy.cpp
+++ b/libc/seccomp/arm_global_policy.cpp
@@ -5,7 +5,7 @@
 
 #include "seccomp_bpfs.h"
 const sock_filter arm_global_filter[] = {
-BPF_JUMP(BPF_JMP|BPF_JGE|BPF_K, 0, 0, 132),
+BPF_JUMP(BPF_JMP|BPF_JGE|BPF_K, 0, 0, 130),
 BPF_JUMP(BPF_JMP|BPF_JGE|BPF_K, 168, 65, 0),
 BPF_JUMP(BPF_JMP|BPF_JGE|BPF_K, 77, 33, 0),
 BPF_JUMP(BPF_JMP|BPF_JGE|BPF_K, 45, 17, 0),
@@ -13,88 +13,86 @@
 BPF_JUMP(BPF_JMP|BPF_JGE|BPF_K, 19, 5, 0),
 BPF_JUMP(BPF_JMP|BPF_JGE|BPF_K, 10, 3, 0),
 BPF_JUMP(BPF_JMP|BPF_JGE|BPF_K, 8, 1, 0),
-BPF_JUMP(BPF_JMP|BPF_JGE|BPF_K, 7, 124, 123), //restart_syscall|exit|fork|read|write|open|close
-BPF_JUMP(BPF_JMP|BPF_JGE|BPF_K, 9, 123, 122), //creat
-BPF_JUMP(BPF_JMP|BPF_JGE|BPF_K, 13, 122, 121), //unlink|execve|chdir
+BPF_JUMP(BPF_JMP|BPF_JGE|BPF_K, 7, 122, 121), //restart_syscall|exit|fork|read|write|open|close
+BPF_JUMP(BPF_JMP|BPF_JGE|BPF_K, 9, 121, 120), //creat
+BPF_JUMP(BPF_JMP|BPF_JGE|BPF_K, 13, 120, 119), //unlink|execve|chdir
 BPF_JUMP(BPF_JMP|BPF_JGE|BPF_K, 24, 1, 0),
-BPF_JUMP(BPF_JMP|BPF_JGE|BPF_K, 22, 120, 119), //lseek|getpid|mount
-BPF_JUMP(BPF_JMP|BPF_JGE|BPF_K, 25, 119, 118), //getuid
+BPF_JUMP(BPF_JMP|BPF_JGE|BPF_K, 22, 118, 117), //lseek|getpid|mount
+BPF_JUMP(BPF_JMP|BPF_JGE|BPF_K, 25, 117, 116), //getuid
 BPF_JUMP(BPF_JMP|BPF_JGE|BPF_K, 36, 3, 0),
 BPF_JUMP(BPF_JMP|BPF_JGE|BPF_K, 33, 1, 0),
-BPF_JUMP(BPF_JMP|BPF_JGE|BPF_K, 27, 116, 115), //ptrace
-BPF_JUMP(BPF_JMP|BPF_JGE|BPF_K, 34, 115, 114), //access
+BPF_JUMP(BPF_JMP|BPF_JGE|BPF_K, 27, 114, 113), //ptrace
+BPF_JUMP(BPF_JMP|BPF_JGE|BPF_K, 34, 113, 112), //access
 BPF_JUMP(BPF_JMP|BPF_JGE|BPF_K, 41, 1, 0),
-BPF_JUMP(BPF_JMP|BPF_JGE|BPF_K, 40, 113, 112), //sync|kill|rename|mkdir
-BPF_JUMP(BPF_JMP|BPF_JGE|BPF_K, 44, 112, 111), //dup|pipe|times
+BPF_JUMP(BPF_JMP|BPF_JGE|BPF_K, 40, 111, 110), //sync|kill|rename|mkdir
+BPF_JUMP(BPF_JMP|BPF_JGE|BPF_K, 44, 110, 109), //dup|pipe|times
 BPF_JUMP(BPF_JMP|BPF_JGE|BPF_K, 60, 7, 0),
 BPF_JUMP(BPF_JMP|BPF_JGE|BPF_K, 54, 3, 0),
 BPF_JUMP(BPF_JMP|BPF_JGE|BPF_K, 51, 1, 0),
-BPF_JUMP(BPF_JMP|BPF_JGE|BPF_K, 46, 108, 107), //brk
-BPF_JUMP(BPF_JMP|BPF_JGE|BPF_K, 53, 107, 106), //acct|umount2
+BPF_JUMP(BPF_JMP|BPF_JGE|BPF_K, 46, 106, 105), //brk
+BPF_JUMP(BPF_JMP|BPF_JGE|BPF_K, 53, 105, 104), //acct|umount2
 BPF_JUMP(BPF_JMP|BPF_JGE|BPF_K, 57, 1, 0),
-BPF_JUMP(BPF_JMP|BPF_JGE|BPF_K, 56, 105, 104), //ioctl|fcntl
-BPF_JUMP(BPF_JMP|BPF_JGE|BPF_K, 58, 104, 103), //setpgid
+BPF_JUMP(BPF_JMP|BPF_JGE|BPF_K, 56, 103, 102), //ioctl|fcntl
+BPF_JUMP(BPF_JMP|BPF_JGE|BPF_K, 58, 102, 101), //setpgid
 BPF_JUMP(BPF_JMP|BPF_JGE|BPF_K, 66, 3, 0),
 BPF_JUMP(BPF_JMP|BPF_JGE|BPF_K, 63, 1, 0),
-BPF_JUMP(BPF_JMP|BPF_JGE|BPF_K, 62, 101, 100), //umask|chroot
-BPF_JUMP(BPF_JMP|BPF_JGE|BPF_K, 65, 100, 99), //dup2|getppid
+BPF_JUMP(BPF_JMP|BPF_JGE|BPF_K, 62, 99, 98), //umask|chroot
+BPF_JUMP(BPF_JMP|BPF_JGE|BPF_K, 65, 98, 97), //dup2|getppid
 BPF_JUMP(BPF_JMP|BPF_JGE|BPF_K, 74, 1, 0),
-BPF_JUMP(BPF_JMP|BPF_JGE|BPF_K, 68, 98, 97), //setsid|sigaction
-BPF_JUMP(BPF_JMP|BPF_JGE|BPF_K, 76, 97, 96), //sethostname|setrlimit
+BPF_JUMP(BPF_JMP|BPF_JGE|BPF_K, 68, 96, 95), //setsid|sigaction
+BPF_JUMP(BPF_JMP|BPF_JGE|BPF_K, 76, 95, 94), //sethostname|setrlimit
 BPF_JUMP(BPF_JMP|BPF_JGE|BPF_K, 116, 15, 0),
 BPF_JUMP(BPF_JMP|BPF_JGE|BPF_K, 94, 7, 0),
 BPF_JUMP(BPF_JMP|BPF_JGE|BPF_K, 87, 3, 0),
 BPF_JUMP(BPF_JMP|BPF_JGE|BPF_K, 85, 1, 0),
-BPF_JUMP(BPF_JMP|BPF_JGE|BPF_K, 80, 92, 91), //getrusage|gettimeofday|settimeofday
-BPF_JUMP(BPF_JMP|BPF_JGE|BPF_K, 86, 91, 90), //readlink
+BPF_JUMP(BPF_JMP|BPF_JGE|BPF_K, 80, 90, 89), //getrusage|gettimeofday|settimeofday
+BPF_JUMP(BPF_JMP|BPF_JGE|BPF_K, 86, 89, 88), //readlink
 BPF_JUMP(BPF_JMP|BPF_JGE|BPF_K, 91, 1, 0),
-BPF_JUMP(BPF_JMP|BPF_JGE|BPF_K, 89, 89, 88), //swapon|reboot
-BPF_JUMP(BPF_JMP|BPF_JGE|BPF_K, 93, 88, 87), //munmap|truncate
+BPF_JUMP(BPF_JMP|BPF_JGE|BPF_K, 89, 87, 86), //swapon|reboot
+BPF_JUMP(BPF_JMP|BPF_JGE|BPF_K, 93, 86, 85), //munmap|truncate
 BPF_JUMP(BPF_JMP|BPF_JGE|BPF_K, 103, 3, 0),
 BPF_JUMP(BPF_JMP|BPF_JGE|BPF_K, 96, 1, 0),
-BPF_JUMP(BPF_JMP|BPF_JGE|BPF_K, 95, 85, 84), //fchmod
-BPF_JUMP(BPF_JMP|BPF_JGE|BPF_K, 98, 84, 83), //getpriority|setpriority
+BPF_JUMP(BPF_JMP|BPF_JGE|BPF_K, 95, 83, 82), //fchmod
+BPF_JUMP(BPF_JMP|BPF_JGE|BPF_K, 98, 82, 81), //getpriority|setpriority
 BPF_JUMP(BPF_JMP|BPF_JGE|BPF_K, 114, 1, 0),
-BPF_JUMP(BPF_JMP|BPF_JGE|BPF_K, 106, 82, 81), //syslog|setitimer|getitimer
-BPF_JUMP(BPF_JMP|BPF_JGE|BPF_K, 115, 81, 80), //wait4
+BPF_JUMP(BPF_JMP|BPF_JGE|BPF_K, 106, 80, 79), //syslog|setitimer|getitimer
+BPF_JUMP(BPF_JMP|BPF_JGE|BPF_K, 115, 79, 78), //wait4
 BPF_JUMP(BPF_JMP|BPF_JGE|BPF_K, 131, 7, 0),
 BPF_JUMP(BPF_JMP|BPF_JGE|BPF_K, 124, 3, 0),
 BPF_JUMP(BPF_JMP|BPF_JGE|BPF_K, 118, 1, 0),
-BPF_JUMP(BPF_JMP|BPF_JGE|BPF_K, 117, 77, 76), //sysinfo
-BPF_JUMP(BPF_JMP|BPF_JGE|BPF_K, 123, 76, 75), //fsync|sigreturn|clone|setdomainname|uname
+BPF_JUMP(BPF_JMP|BPF_JGE|BPF_K, 117, 75, 74), //sysinfo
+BPF_JUMP(BPF_JMP|BPF_JGE|BPF_K, 123, 74, 73), //fsync|sigreturn|clone|setdomainname|uname
 BPF_JUMP(BPF_JMP|BPF_JGE|BPF_K, 128, 1, 0),
-BPF_JUMP(BPF_JMP|BPF_JGE|BPF_K, 126, 74, 73), //adjtimex|mprotect
-BPF_JUMP(BPF_JMP|BPF_JGE|BPF_K, 130, 73, 72), //init_module|delete_module
+BPF_JUMP(BPF_JMP|BPF_JGE|BPF_K, 126, 72, 71), //adjtimex|mprotect
+BPF_JUMP(BPF_JMP|BPF_JGE|BPF_K, 130, 71, 70), //init_module|delete_module
 BPF_JUMP(BPF_JMP|BPF_JGE|BPF_K, 138, 3, 0),
 BPF_JUMP(BPF_JMP|BPF_JGE|BPF_K, 136, 1, 0),
-BPF_JUMP(BPF_JMP|BPF_JGE|BPF_K, 134, 70, 69), //quotactl|getpgid|fchdir
-BPF_JUMP(BPF_JMP|BPF_JGE|BPF_K, 137, 69, 68), //personality
+BPF_JUMP(BPF_JMP|BPF_JGE|BPF_K, 134, 68, 67), //quotactl|getpgid|fchdir
+BPF_JUMP(BPF_JMP|BPF_JGE|BPF_K, 137, 67, 66), //personality
 BPF_JUMP(BPF_JMP|BPF_JGE|BPF_K, 150, 1, 0),
-BPF_JUMP(BPF_JMP|BPF_JGE|BPF_K, 149, 67, 66), //setfsuid|setfsgid|_llseek|getdents|_newselect|flock|msync|readv|writev|getsid|fdatasync
-BPF_JUMP(BPF_JMP|BPF_JGE|BPF_K, 164, 66, 65), //mlock|munlock|mlockall|munlockall|sched_setparam|sched_getparam|sched_setscheduler|sched_getscheduler|sched_yield|sched_get_priority_max|sched_get_priority_min|sched_rr_get_interval|nanosleep|mremap
-BPF_JUMP(BPF_JMP|BPF_JGE|BPF_K, 309, 33, 0),
-BPF_JUMP(BPF_JMP|BPF_JGE|BPF_K, 248, 17, 0),
-BPF_JUMP(BPF_JMP|BPF_JGE|BPF_K, 213, 9, 0),
-BPF_JUMP(BPF_JMP|BPF_JGE|BPF_K, 190, 5, 0),
+BPF_JUMP(BPF_JMP|BPF_JGE|BPF_K, 149, 65, 64), //setfsuid|setfsgid|_llseek|getdents|_newselect|flock|msync|readv|writev|getsid|fdatasync
+BPF_JUMP(BPF_JMP|BPF_JGE|BPF_K, 164, 64, 63), //mlock|munlock|mlockall|munlockall|sched_setparam|sched_getparam|sched_setscheduler|sched_getscheduler|sched_yield|sched_get_priority_max|sched_get_priority_min|sched_rr_get_interval|nanosleep|mremap
+BPF_JUMP(BPF_JMP|BPF_JGE|BPF_K, 309, 31, 0),
+BPF_JUMP(BPF_JMP|BPF_JGE|BPF_K, 224, 15, 0),
+BPF_JUMP(BPF_JMP|BPF_JGE|BPF_K, 199, 7, 0),
 BPF_JUMP(BPF_JMP|BPF_JGE|BPF_K, 183, 3, 0),
 BPF_JUMP(BPF_JMP|BPF_JGE|BPF_K, 172, 1, 0),
-BPF_JUMP(BPF_JMP|BPF_JGE|BPF_K, 169, 59, 58), //poll
-BPF_JUMP(BPF_JMP|BPF_JGE|BPF_K, 182, 58, 57), //prctl|rt_sigreturn|rt_sigaction|rt_sigprocmask|rt_sigpending|rt_sigtimedwait|rt_sigqueueinfo|rt_sigsuspend|pread64|pwrite64
-BPF_JUMP(BPF_JMP|BPF_JGE|BPF_K, 188, 57, 56), //getcwd|capget|capset|sigaltstack|sendfile
-BPF_JUMP(BPF_JMP|BPF_JGE|BPF_K, 199, 1, 0),
-BPF_JUMP(BPF_JMP|BPF_JGE|BPF_K, 198, 55, 54), //vfork|ugetrlimit|mmap2|truncate64|ftruncate64|stat64|lstat64|fstat64
-BPF_JUMP(BPF_JMP|BPF_JGE|BPF_K, 212, 54, 53), //getuid32|getgid32|geteuid32|getegid32|setreuid32|setregid32|getgroups32|setgroups32|fchown32|setresuid32|getresuid32|setresgid32|getresgid32
-BPF_JUMP(BPF_JMP|BPF_JGE|BPF_K, 219, 3, 0),
-BPF_JUMP(BPF_JMP|BPF_JGE|BPF_K, 217, 1, 0),
-BPF_JUMP(BPF_JMP|BPF_JGE|BPF_K, 215, 51, 50), //setuid32|setgid32
-BPF_JUMP(BPF_JMP|BPF_JGE|BPF_K, 218, 50, 49), //getdents64
-BPF_JUMP(BPF_JMP|BPF_JGE|BPF_K, 224, 1, 0),
-BPF_JUMP(BPF_JMP|BPF_JGE|BPF_K, 222, 48, 47), //mincore|madvise|fcntl64
-BPF_JUMP(BPF_JMP|BPF_JGE|BPF_K, 243, 47, 46), //gettid|readahead|setxattr|lsetxattr|fsetxattr|getxattr|lgetxattr|fgetxattr|listxattr|llistxattr|flistxattr|removexattr|lremovexattr|fremovexattr|tkill|sendfile64|futex|sched_setaffinity|sched_getaffinity
+BPF_JUMP(BPF_JMP|BPF_JGE|BPF_K, 169, 58, 57), //poll
+BPF_JUMP(BPF_JMP|BPF_JGE|BPF_K, 182, 57, 56), //prctl|rt_sigreturn|rt_sigaction|rt_sigprocmask|rt_sigpending|rt_sigtimedwait|rt_sigqueueinfo|rt_sigsuspend|pread64|pwrite64
+BPF_JUMP(BPF_JMP|BPF_JGE|BPF_K, 190, 1, 0),
+BPF_JUMP(BPF_JMP|BPF_JGE|BPF_K, 188, 55, 54), //getcwd|capget|capset|sigaltstack|sendfile
+BPF_JUMP(BPF_JMP|BPF_JGE|BPF_K, 198, 54, 53), //vfork|ugetrlimit|mmap2|truncate64|ftruncate64|stat64|lstat64|fstat64
+BPF_JUMP(BPF_JMP|BPF_JGE|BPF_K, 217, 3, 0),
+BPF_JUMP(BPF_JMP|BPF_JGE|BPF_K, 213, 1, 0),
+BPF_JUMP(BPF_JMP|BPF_JGE|BPF_K, 212, 51, 50), //getuid32|getgid32|geteuid32|getegid32|setreuid32|setregid32|getgroups32|setgroups32|fchown32|setresuid32|getresuid32|setresgid32|getresgid32
+BPF_JUMP(BPF_JMP|BPF_JGE|BPF_K, 215, 50, 49), //setuid32|setgid32
+BPF_JUMP(BPF_JMP|BPF_JGE|BPF_K, 219, 1, 0),
+BPF_JUMP(BPF_JMP|BPF_JGE|BPF_K, 218, 48, 47), //getdents64
+BPF_JUMP(BPF_JMP|BPF_JGE|BPF_K, 222, 47, 46), //mincore|madvise|fcntl64
 BPF_JUMP(BPF_JMP|BPF_JGE|BPF_K, 280, 7, 0),
 BPF_JUMP(BPF_JMP|BPF_JGE|BPF_K, 256, 3, 0),
 BPF_JUMP(BPF_JMP|BPF_JGE|BPF_K, 250, 1, 0),
-BPF_JUMP(BPF_JMP|BPF_JGE|BPF_K, 249, 43, 42), //exit_group
+BPF_JUMP(BPF_JMP|BPF_JGE|BPF_K, 249, 43, 42), //gettid|readahead|setxattr|lsetxattr|fsetxattr|getxattr|lgetxattr|fgetxattr|listxattr|llistxattr|flistxattr|removexattr|lremovexattr|fremovexattr|tkill|sendfile64|futex|sched_setaffinity|sched_getaffinity|io_setup|io_destroy|io_getevents|io_submit|io_cancel|exit_group
 BPF_JUMP(BPF_JMP|BPF_JGE|BPF_K, 254, 42, 41), //epoll_create|epoll_ctl|epoll_wait|remap_file_pages
 BPF_JUMP(BPF_JMP|BPF_JGE|BPF_K, 270, 1, 0),
 BPF_JUMP(BPF_JMP|BPF_JGE|BPF_K, 269, 40, 39), //set_tid_address|timer_create|timer_settime|timer_gettime|timer_getoverrun|timer_delete|clock_settime|clock_gettime|clock_getres|clock_nanosleep|statfs64|fstatfs64|tgkill
diff --git a/libc/seccomp/mips64_global_policy.cpp b/libc/seccomp/mips64_global_policy.cpp
index 004eda2..04c13b3 100644
--- a/libc/seccomp/mips64_global_policy.cpp
+++ b/libc/seccomp/mips64_global_policy.cpp
@@ -59,9 +59,9 @@
 BPF_JUMP(BPF_JMP|BPF_JGE|BPF_K, 5173, 35, 34), //quotactl
 BPF_JUMP(BPF_JMP|BPF_JGE|BPF_K, 5193, 34, 33), //gettid|readahead|setxattr|lsetxattr|fsetxattr|getxattr|lgetxattr|fgetxattr|listxattr|llistxattr|flistxattr|removexattr|lremovexattr|fremovexattr|tkill
 BPF_JUMP(BPF_JMP|BPF_JGE|BPF_K, 5208, 3, 0),
-BPF_JUMP(BPF_JMP|BPF_JGE|BPF_K, 5205, 1, 0),
+BPF_JUMP(BPF_JMP|BPF_JGE|BPF_K, 5200, 1, 0),
 BPF_JUMP(BPF_JMP|BPF_JGE|BPF_K, 5198, 31, 30), //futex|sched_setaffinity|sched_getaffinity|cacheflush
-BPF_JUMP(BPF_JMP|BPF_JGE|BPF_K, 5206, 30, 29), //exit_group
+BPF_JUMP(BPF_JMP|BPF_JGE|BPF_K, 5206, 30, 29), //io_setup|io_destroy|io_getevents|io_submit|io_cancel|exit_group
 BPF_JUMP(BPF_JMP|BPF_JGE|BPF_K, 5209, 29, 28), //epoll_ctl
 BPF_JUMP(BPF_JMP|BPF_JGE|BPF_K, 5239, 5, 0),
 BPF_JUMP(BPF_JMP|BPF_JGE|BPF_K, 5237, 3, 0),
diff --git a/libc/seccomp/mips_global_policy.cpp b/libc/seccomp/mips_global_policy.cpp
index b4fa23d..103e544 100644
--- a/libc/seccomp/mips_global_policy.cpp
+++ b/libc/seccomp/mips_global_policy.cpp
@@ -5,93 +5,91 @@
 
 #include "seccomp_bpfs.h"
 const sock_filter mips_global_filter[] = {
-BPF_JUMP(BPF_JMP|BPF_JGE|BPF_K, 4001, 0, 114),
-BPF_JUMP(BPF_JMP|BPF_JGE|BPF_K, 4136, 57, 0),
-BPF_JUMP(BPF_JMP|BPF_JGE|BPF_K, 4066, 29, 0),
-BPF_JUMP(BPF_JMP|BPF_JGE|BPF_K, 4041, 15, 0),
+BPF_JUMP(BPF_JMP|BPF_JGE|BPF_K, 4001, 0, 112),
+BPF_JUMP(BPF_JMP|BPF_JGE|BPF_K, 4131, 55, 0),
+BPF_JUMP(BPF_JMP|BPF_JGE|BPF_K, 4063, 27, 0),
+BPF_JUMP(BPF_JMP|BPF_JGE|BPF_K, 4036, 13, 0),
 BPF_JUMP(BPF_JMP|BPF_JGE|BPF_K, 4023, 7, 0),
 BPF_JUMP(BPF_JMP|BPF_JGE|BPF_K, 4010, 3, 0),
 BPF_JUMP(BPF_JMP|BPF_JGE|BPF_K, 4008, 1, 0),
-BPF_JUMP(BPF_JMP|BPF_JGE|BPF_K, 4007, 107, 106), //exit|fork|read|write|open|close
-BPF_JUMP(BPF_JMP|BPF_JGE|BPF_K, 4009, 106, 105), //creat
+BPF_JUMP(BPF_JMP|BPF_JGE|BPF_K, 4007, 105, 104), //exit|fork|read|write|open|close
+BPF_JUMP(BPF_JMP|BPF_JGE|BPF_K, 4009, 104, 103), //creat
 BPF_JUMP(BPF_JMP|BPF_JGE|BPF_K, 4019, 1, 0),
-BPF_JUMP(BPF_JMP|BPF_JGE|BPF_K, 4013, 104, 103), //unlink|execve|chdir
-BPF_JUMP(BPF_JMP|BPF_JGE|BPF_K, 4022, 103, 102), //lseek|getpid|mount
+BPF_JUMP(BPF_JMP|BPF_JGE|BPF_K, 4013, 102, 101), //unlink|execve|chdir
+BPF_JUMP(BPF_JMP|BPF_JGE|BPF_K, 4022, 101, 100), //lseek|getpid|mount
 BPF_JUMP(BPF_JMP|BPF_JGE|BPF_K, 4033, 3, 0),
 BPF_JUMP(BPF_JMP|BPF_JGE|BPF_K, 4026, 1, 0),
-BPF_JUMP(BPF_JMP|BPF_JGE|BPF_K, 4025, 100, 99), //setuid|getuid
-BPF_JUMP(BPF_JMP|BPF_JGE|BPF_K, 4027, 99, 98), //ptrace
-BPF_JUMP(BPF_JMP|BPF_JGE|BPF_K, 4036, 1, 0),
-BPF_JUMP(BPF_JMP|BPF_JGE|BPF_K, 4034, 97, 96), //access
-BPF_JUMP(BPF_JMP|BPF_JGE|BPF_K, 4040, 96, 95), //sync|kill|rename|mkdir
-BPF_JUMP(BPF_JMP|BPF_JGE|BPF_K, 4057, 7, 0),
-BPF_JUMP(BPF_JMP|BPF_JGE|BPF_K, 4049, 3, 0),
-BPF_JUMP(BPF_JMP|BPF_JGE|BPF_K, 4045, 1, 0),
-BPF_JUMP(BPF_JMP|BPF_JGE|BPF_K, 4044, 92, 91), //dup|pipe|times
-BPF_JUMP(BPF_JMP|BPF_JGE|BPF_K, 4048, 91, 90), //brk|setgid|getgid
-BPF_JUMP(BPF_JMP|BPF_JGE|BPF_K, 4054, 1, 0),
-BPF_JUMP(BPF_JMP|BPF_JGE|BPF_K, 4053, 89, 88), //geteuid|getegid|acct|umount2
-BPF_JUMP(BPF_JMP|BPF_JGE|BPF_K, 4056, 88, 87), //ioctl|fcntl
-BPF_JUMP(BPF_JMP|BPF_JGE|BPF_K, 4063, 3, 0),
-BPF_JUMP(BPF_JMP|BPF_JGE|BPF_K, 4060, 1, 0),
-BPF_JUMP(BPF_JMP|BPF_JGE|BPF_K, 4058, 85, 84), //setpgid
-BPF_JUMP(BPF_JMP|BPF_JGE|BPF_K, 4062, 84, 83), //umask|chroot
-BPF_JUMP(BPF_JMP|BPF_JGE|BPF_K, 4065, 83, 82), //dup2|getppid
-BPF_JUMP(BPF_JMP|BPF_JGE|BPF_K, 4103, 13, 0),
-BPF_JUMP(BPF_JMP|BPF_JGE|BPF_K, 4087, 7, 0),
-BPF_JUMP(BPF_JMP|BPF_JGE|BPF_K, 4074, 3, 0),
-BPF_JUMP(BPF_JMP|BPF_JGE|BPF_K, 4070, 1, 0),
-BPF_JUMP(BPF_JMP|BPF_JGE|BPF_K, 4068, 78, 77), //setsid|sigaction
-BPF_JUMP(BPF_JMP|BPF_JGE|BPF_K, 4072, 77, 76), //setreuid|setregid
-BPF_JUMP(BPF_JMP|BPF_JGE|BPF_K, 4085, 1, 0),
-BPF_JUMP(BPF_JMP|BPF_JGE|BPF_K, 4082, 75, 74), //sethostname|setrlimit|getrlimit|getrusage|gettimeofday|settimeofday|getgroups|setgroups
-BPF_JUMP(BPF_JMP|BPF_JGE|BPF_K, 4086, 74, 73), //readlink
-BPF_JUMP(BPF_JMP|BPF_JGE|BPF_K, 4094, 3, 0),
-BPF_JUMP(BPF_JMP|BPF_JGE|BPF_K, 4090, 1, 0),
-BPF_JUMP(BPF_JMP|BPF_JGE|BPF_K, 4089, 71, 70), //swapon|reboot
-BPF_JUMP(BPF_JMP|BPF_JGE|BPF_K, 4093, 70, 69), //mmap|munmap|truncate
-BPF_JUMP(BPF_JMP|BPF_JGE|BPF_K, 4098, 69, 68), //fchmod|fchown|getpriority|setpriority
-BPF_JUMP(BPF_JMP|BPF_JGE|BPF_K, 4124, 7, 0),
-BPF_JUMP(BPF_JMP|BPF_JGE|BPF_K, 4116, 3, 0),
-BPF_JUMP(BPF_JMP|BPF_JGE|BPF_K, 4114, 1, 0),
-BPF_JUMP(BPF_JMP|BPF_JGE|BPF_K, 4106, 65, 64), //syslog|setitimer|getitimer
-BPF_JUMP(BPF_JMP|BPF_JGE|BPF_K, 4115, 64, 63), //wait4
-BPF_JUMP(BPF_JMP|BPF_JGE|BPF_K, 4118, 1, 0),
-BPF_JUMP(BPF_JMP|BPF_JGE|BPF_K, 4117, 62, 61), //sysinfo
-BPF_JUMP(BPF_JMP|BPF_JGE|BPF_K, 4123, 61, 60), //fsync|sigreturn|clone|setdomainname|uname
-BPF_JUMP(BPF_JMP|BPF_JGE|BPF_K, 4131, 3, 0),
-BPF_JUMP(BPF_JMP|BPF_JGE|BPF_K, 4128, 1, 0),
-BPF_JUMP(BPF_JMP|BPF_JGE|BPF_K, 4126, 58, 57), //adjtimex|mprotect
-BPF_JUMP(BPF_JMP|BPF_JGE|BPF_K, 4130, 57, 56), //init_module|delete_module
-BPF_JUMP(BPF_JMP|BPF_JGE|BPF_K, 4134, 56, 55), //quotactl|getpgid|fchdir
+BPF_JUMP(BPF_JMP|BPF_JGE|BPF_K, 4025, 98, 97), //setuid|getuid
+BPF_JUMP(BPF_JMP|BPF_JGE|BPF_K, 4027, 97, 96), //ptrace
+BPF_JUMP(BPF_JMP|BPF_JGE|BPF_K, 4034, 96, 95), //access
+BPF_JUMP(BPF_JMP|BPF_JGE|BPF_K, 4054, 7, 0),
+BPF_JUMP(BPF_JMP|BPF_JGE|BPF_K, 4045, 3, 0),
+BPF_JUMP(BPF_JMP|BPF_JGE|BPF_K, 4041, 1, 0),
+BPF_JUMP(BPF_JMP|BPF_JGE|BPF_K, 4040, 92, 91), //sync|kill|rename|mkdir
+BPF_JUMP(BPF_JMP|BPF_JGE|BPF_K, 4044, 91, 90), //dup|pipe|times
+BPF_JUMP(BPF_JMP|BPF_JGE|BPF_K, 4049, 1, 0),
+BPF_JUMP(BPF_JMP|BPF_JGE|BPF_K, 4048, 89, 88), //brk|setgid|getgid
+BPF_JUMP(BPF_JMP|BPF_JGE|BPF_K, 4053, 88, 87), //geteuid|getegid|acct|umount2
+BPF_JUMP(BPF_JMP|BPF_JGE|BPF_K, 4060, 3, 0),
+BPF_JUMP(BPF_JMP|BPF_JGE|BPF_K, 4057, 1, 0),
+BPF_JUMP(BPF_JMP|BPF_JGE|BPF_K, 4056, 85, 84), //ioctl|fcntl
+BPF_JUMP(BPF_JMP|BPF_JGE|BPF_K, 4058, 84, 83), //setpgid
+BPF_JUMP(BPF_JMP|BPF_JGE|BPF_K, 4062, 83, 82), //umask|chroot
+BPF_JUMP(BPF_JMP|BPF_JGE|BPF_K, 4094, 13, 0),
+BPF_JUMP(BPF_JMP|BPF_JGE|BPF_K, 4085, 7, 0),
+BPF_JUMP(BPF_JMP|BPF_JGE|BPF_K, 4070, 3, 0),
+BPF_JUMP(BPF_JMP|BPF_JGE|BPF_K, 4066, 1, 0),
+BPF_JUMP(BPF_JMP|BPF_JGE|BPF_K, 4065, 78, 77), //dup2|getppid
+BPF_JUMP(BPF_JMP|BPF_JGE|BPF_K, 4068, 77, 76), //setsid|sigaction
+BPF_JUMP(BPF_JMP|BPF_JGE|BPF_K, 4074, 1, 0),
+BPF_JUMP(BPF_JMP|BPF_JGE|BPF_K, 4072, 75, 74), //setreuid|setregid
+BPF_JUMP(BPF_JMP|BPF_JGE|BPF_K, 4082, 74, 73), //sethostname|setrlimit|getrlimit|getrusage|gettimeofday|settimeofday|getgroups|setgroups
+BPF_JUMP(BPF_JMP|BPF_JGE|BPF_K, 4090, 3, 0),
+BPF_JUMP(BPF_JMP|BPF_JGE|BPF_K, 4087, 1, 0),
+BPF_JUMP(BPF_JMP|BPF_JGE|BPF_K, 4086, 71, 70), //readlink
+BPF_JUMP(BPF_JMP|BPF_JGE|BPF_K, 4089, 70, 69), //swapon|reboot
+BPF_JUMP(BPF_JMP|BPF_JGE|BPF_K, 4093, 69, 68), //mmap|munmap|truncate
+BPF_JUMP(BPF_JMP|BPF_JGE|BPF_K, 4118, 7, 0),
+BPF_JUMP(BPF_JMP|BPF_JGE|BPF_K, 4114, 3, 0),
+BPF_JUMP(BPF_JMP|BPF_JGE|BPF_K, 4103, 1, 0),
+BPF_JUMP(BPF_JMP|BPF_JGE|BPF_K, 4098, 65, 64), //fchmod|fchown|getpriority|setpriority
+BPF_JUMP(BPF_JMP|BPF_JGE|BPF_K, 4106, 64, 63), //syslog|setitimer|getitimer
+BPF_JUMP(BPF_JMP|BPF_JGE|BPF_K, 4116, 1, 0),
+BPF_JUMP(BPF_JMP|BPF_JGE|BPF_K, 4115, 62, 61), //wait4
+BPF_JUMP(BPF_JMP|BPF_JGE|BPF_K, 4117, 61, 60), //sysinfo
+BPF_JUMP(BPF_JMP|BPF_JGE|BPF_K, 4128, 3, 0),
+BPF_JUMP(BPF_JMP|BPF_JGE|BPF_K, 4124, 1, 0),
+BPF_JUMP(BPF_JMP|BPF_JGE|BPF_K, 4123, 58, 57), //fsync|sigreturn|clone|setdomainname|uname
+BPF_JUMP(BPF_JMP|BPF_JGE|BPF_K, 4126, 57, 56), //adjtimex|mprotect
+BPF_JUMP(BPF_JMP|BPF_JGE|BPF_K, 4130, 56, 55), //init_module|delete_module
 BPF_JUMP(BPF_JMP|BPF_JGE|BPF_K, 4248, 27, 0),
-BPF_JUMP(BPF_JMP|BPF_JGE|BPF_K, 4188, 13, 0),
-BPF_JUMP(BPF_JMP|BPF_JGE|BPF_K, 4169, 7, 0),
-BPF_JUMP(BPF_JMP|BPF_JGE|BPF_K, 4151, 3, 0),
-BPF_JUMP(BPF_JMP|BPF_JGE|BPF_K, 4138, 1, 0),
-BPF_JUMP(BPF_JMP|BPF_JGE|BPF_K, 4137, 50, 49), //personality
-BPF_JUMP(BPF_JMP|BPF_JGE|BPF_K, 4148, 49, 48), //setfsuid|setfsgid|_llseek|getdents|_newselect|flock|msync|readv|writev|cacheflush
-BPF_JUMP(BPF_JMP|BPF_JGE|BPF_K, 4154, 1, 0),
-BPF_JUMP(BPF_JMP|BPF_JGE|BPF_K, 4153, 47, 46), //getsid|fdatasync
-BPF_JUMP(BPF_JMP|BPF_JGE|BPF_K, 4168, 46, 45), //mlock|munlock|mlockall|munlockall|sched_setparam|sched_getparam|sched_setscheduler|sched_getscheduler|sched_yield|sched_get_priority_max|sched_get_priority_min|sched_rr_get_interval|nanosleep|mremap
-BPF_JUMP(BPF_JMP|BPF_JGE|BPF_K, 4179, 3, 0),
-BPF_JUMP(BPF_JMP|BPF_JGE|BPF_K, 4176, 1, 0),
-BPF_JUMP(BPF_JMP|BPF_JGE|BPF_K, 4175, 43, 42), //bind|connect|getpeername|getsockname|getsockopt|listen
-BPF_JUMP(BPF_JMP|BPF_JGE|BPF_K, 4178, 42, 41), //recvfrom|recvmsg
-BPF_JUMP(BPF_JMP|BPF_JGE|BPF_K, 4187, 41, 40), //sendmsg|sendto|setsockopt|shutdown|socket|socketpair|setresuid|getresuid
-BPF_JUMP(BPF_JMP|BPF_JGE|BPF_K, 4217, 7, 0),
-BPF_JUMP(BPF_JMP|BPF_JGE|BPF_K, 4203, 3, 0),
-BPF_JUMP(BPF_JMP|BPF_JGE|BPF_K, 4190, 1, 0),
-BPF_JUMP(BPF_JMP|BPF_JGE|BPF_K, 4189, 37, 36), //poll
-BPF_JUMP(BPF_JMP|BPF_JGE|BPF_K, 4202, 36, 35), //setresgid|getresgid|prctl|rt_sigreturn|rt_sigaction|rt_sigprocmask|rt_sigpending|rt_sigtimedwait|rt_sigqueueinfo|rt_sigsuspend|pread64|pwrite64
-BPF_JUMP(BPF_JMP|BPF_JGE|BPF_K, 4210, 1, 0),
-BPF_JUMP(BPF_JMP|BPF_JGE|BPF_K, 4208, 34, 33), //getcwd|capget|capset|sigaltstack|sendfile
-BPF_JUMP(BPF_JMP|BPF_JGE|BPF_K, 4216, 33, 32), //mmap2|truncate64|ftruncate64|stat64|lstat64|fstat64
-BPF_JUMP(BPF_JMP|BPF_JGE|BPF_K, 4246, 3, 0),
-BPF_JUMP(BPF_JMP|BPF_JGE|BPF_K, 4222, 1, 0),
-BPF_JUMP(BPF_JMP|BPF_JGE|BPF_K, 4221, 30, 29), //mincore|madvise|getdents64|fcntl64
-BPF_JUMP(BPF_JMP|BPF_JGE|BPF_K, 4241, 29, 28), //gettid|readahead|setxattr|lsetxattr|fsetxattr|getxattr|lgetxattr|fgetxattr|listxattr|llistxattr|flistxattr|removexattr|lremovexattr|fremovexattr|tkill|sendfile64|futex|sched_setaffinity|sched_getaffinity
-BPF_JUMP(BPF_JMP|BPF_JGE|BPF_K, 4247, 28, 27), //exit_group
+BPF_JUMP(BPF_JMP|BPF_JGE|BPF_K, 4179, 13, 0),
+BPF_JUMP(BPF_JMP|BPF_JGE|BPF_K, 4154, 7, 0),
+BPF_JUMP(BPF_JMP|BPF_JGE|BPF_K, 4138, 3, 0),
+BPF_JUMP(BPF_JMP|BPF_JGE|BPF_K, 4136, 1, 0),
+BPF_JUMP(BPF_JMP|BPF_JGE|BPF_K, 4134, 50, 49), //quotactl|getpgid|fchdir
+BPF_JUMP(BPF_JMP|BPF_JGE|BPF_K, 4137, 49, 48), //personality
+BPF_JUMP(BPF_JMP|BPF_JGE|BPF_K, 4151, 1, 0),
+BPF_JUMP(BPF_JMP|BPF_JGE|BPF_K, 4148, 47, 46), //setfsuid|setfsgid|_llseek|getdents|_newselect|flock|msync|readv|writev|cacheflush
+BPF_JUMP(BPF_JMP|BPF_JGE|BPF_K, 4153, 46, 45), //getsid|fdatasync
+BPF_JUMP(BPF_JMP|BPF_JGE|BPF_K, 4176, 3, 0),
+BPF_JUMP(BPF_JMP|BPF_JGE|BPF_K, 4169, 1, 0),
+BPF_JUMP(BPF_JMP|BPF_JGE|BPF_K, 4168, 43, 42), //mlock|munlock|mlockall|munlockall|sched_setparam|sched_getparam|sched_setscheduler|sched_getscheduler|sched_yield|sched_get_priority_max|sched_get_priority_min|sched_rr_get_interval|nanosleep|mremap
+BPF_JUMP(BPF_JMP|BPF_JGE|BPF_K, 4175, 42, 41), //bind|connect|getpeername|getsockname|getsockopt|listen
+BPF_JUMP(BPF_JMP|BPF_JGE|BPF_K, 4178, 41, 40), //recvfrom|recvmsg
+BPF_JUMP(BPF_JMP|BPF_JGE|BPF_K, 4210, 7, 0),
+BPF_JUMP(BPF_JMP|BPF_JGE|BPF_K, 4190, 3, 0),
+BPF_JUMP(BPF_JMP|BPF_JGE|BPF_K, 4188, 1, 0),
+BPF_JUMP(BPF_JMP|BPF_JGE|BPF_K, 4187, 37, 36), //sendmsg|sendto|setsockopt|shutdown|socket|socketpair|setresuid|getresuid
+BPF_JUMP(BPF_JMP|BPF_JGE|BPF_K, 4189, 36, 35), //poll
+BPF_JUMP(BPF_JMP|BPF_JGE|BPF_K, 4203, 1, 0),
+BPF_JUMP(BPF_JMP|BPF_JGE|BPF_K, 4202, 34, 33), //setresgid|getresgid|prctl|rt_sigreturn|rt_sigaction|rt_sigprocmask|rt_sigpending|rt_sigtimedwait|rt_sigqueueinfo|rt_sigsuspend|pread64|pwrite64
+BPF_JUMP(BPF_JMP|BPF_JGE|BPF_K, 4208, 33, 32), //getcwd|capget|capset|sigaltstack|sendfile
+BPF_JUMP(BPF_JMP|BPF_JGE|BPF_K, 4222, 3, 0),
+BPF_JUMP(BPF_JMP|BPF_JGE|BPF_K, 4217, 1, 0),
+BPF_JUMP(BPF_JMP|BPF_JGE|BPF_K, 4216, 30, 29), //mmap2|truncate64|ftruncate64|stat64|lstat64|fstat64
+BPF_JUMP(BPF_JMP|BPF_JGE|BPF_K, 4221, 29, 28), //mincore|madvise|getdents64|fcntl64
+BPF_JUMP(BPF_JMP|BPF_JGE|BPF_K, 4247, 28, 27), //gettid|readahead|setxattr|lsetxattr|fsetxattr|getxattr|lgetxattr|fgetxattr|listxattr|llistxattr|flistxattr|removexattr|lremovexattr|fremovexattr|tkill|sendfile64|futex|sched_setaffinity|sched_getaffinity|io_setup|io_destroy|io_getevents|io_submit|io_cancel|exit_group
 BPF_JUMP(BPF_JMP|BPF_JGE|BPF_K, 4316, 13, 0),
 BPF_JUMP(BPF_JMP|BPF_JGE|BPF_K, 4288, 7, 0),
 BPF_JUMP(BPF_JMP|BPF_JGE|BPF_K, 4280, 3, 0),
diff --git a/libc/seccomp/x86_64_global_policy.cpp b/libc/seccomp/x86_64_global_policy.cpp
index 71be1c1..801d6c2 100644
--- a/libc/seccomp/x86_64_global_policy.cpp
+++ b/libc/seccomp/x86_64_global_policy.cpp
@@ -5,81 +5,83 @@
 
 #include "seccomp_bpfs.h"
 const sock_filter x86_64_global_filter[] = {
-BPF_JUMP(BPF_JMP|BPF_JGE|BPF_K, 0, 0, 86),
+BPF_JUMP(BPF_JMP|BPF_JGE|BPF_K, 0, 0, 88),
 BPF_JUMP(BPF_JMP|BPF_JGE|BPF_K, 175, 43, 0),
 BPF_JUMP(BPF_JMP|BPF_JGE|BPF_K, 79, 21, 0),
 BPF_JUMP(BPF_JMP|BPF_JGE|BPF_K, 35, 11, 0),
 BPF_JUMP(BPF_JMP|BPF_JGE|BPF_K, 8, 5, 0),
 BPF_JUMP(BPF_JMP|BPF_JGE|BPF_K, 5, 3, 0),
 BPF_JUMP(BPF_JMP|BPF_JGE|BPF_K, 3, 1, 0),
-BPF_JUMP(BPF_JMP|BPF_JGE|BPF_K, 2, 79, 78), //read|write
-BPF_JUMP(BPF_JMP|BPF_JGE|BPF_K, 4, 78, 77), //close
-BPF_JUMP(BPF_JMP|BPF_JGE|BPF_K, 6, 77, 76), //fstat
+BPF_JUMP(BPF_JMP|BPF_JGE|BPF_K, 2, 81, 80), //read|write
+BPF_JUMP(BPF_JMP|BPF_JGE|BPF_K, 4, 80, 79), //close
+BPF_JUMP(BPF_JMP|BPF_JGE|BPF_K, 6, 79, 78), //fstat
 BPF_JUMP(BPF_JMP|BPF_JGE|BPF_K, 32, 3, 0),
 BPF_JUMP(BPF_JMP|BPF_JGE|BPF_K, 24, 1, 0),
-BPF_JUMP(BPF_JMP|BPF_JGE|BPF_K, 21, 74, 73), //lseek|mmap|mprotect|munmap|brk|rt_sigaction|rt_sigprocmask|rt_sigreturn|ioctl|pread64|pwrite64|readv|writev
-BPF_JUMP(BPF_JMP|BPF_JGE|BPF_K, 29, 73, 72), //sched_yield|mremap|msync|mincore|madvise
-BPF_JUMP(BPF_JMP|BPF_JGE|BPF_K, 33, 72, 71), //dup
+BPF_JUMP(BPF_JMP|BPF_JGE|BPF_K, 21, 76, 75), //lseek|mmap|mprotect|munmap|brk|rt_sigaction|rt_sigprocmask|rt_sigreturn|ioctl|pread64|pwrite64|readv|writev
+BPF_JUMP(BPF_JMP|BPF_JGE|BPF_K, 29, 75, 74), //sched_yield|mremap|msync|mincore|madvise
+BPF_JUMP(BPF_JMP|BPF_JGE|BPF_K, 33, 74, 73), //dup
 BPF_JUMP(BPF_JMP|BPF_JGE|BPF_K, 58, 5, 0),
 BPF_JUMP(BPF_JMP|BPF_JGE|BPF_K, 44, 3, 0),
 BPF_JUMP(BPF_JMP|BPF_JGE|BPF_K, 38, 1, 0),
-BPF_JUMP(BPF_JMP|BPF_JGE|BPF_K, 37, 68, 67), //nanosleep|getitimer
-BPF_JUMP(BPF_JMP|BPF_JGE|BPF_K, 43, 67, 66), //setitimer|getpid|sendfile|socket|connect
-BPF_JUMP(BPF_JMP|BPF_JGE|BPF_K, 57, 66, 65), //sendto|recvfrom|sendmsg|recvmsg|shutdown|bind|listen|getsockname|getpeername|socketpair|setsockopt|getsockopt|clone
+BPF_JUMP(BPF_JMP|BPF_JGE|BPF_K, 37, 70, 69), //nanosleep|getitimer
+BPF_JUMP(BPF_JMP|BPF_JGE|BPF_K, 43, 69, 68), //setitimer|getpid|sendfile|socket|connect
+BPF_JUMP(BPF_JMP|BPF_JGE|BPF_K, 57, 68, 67), //sendto|recvfrom|sendmsg|recvmsg|shutdown|bind|listen|getsockname|getpeername|socketpair|setsockopt|getsockopt|clone
 BPF_JUMP(BPF_JMP|BPF_JGE|BPF_K, 72, 1, 0),
-BPF_JUMP(BPF_JMP|BPF_JGE|BPF_K, 64, 64, 63), //vfork|execve|exit|wait4|kill|uname
-BPF_JUMP(BPF_JMP|BPF_JGE|BPF_K, 78, 63, 62), //fcntl|flock|fsync|fdatasync|truncate|ftruncate
+BPF_JUMP(BPF_JMP|BPF_JGE|BPF_K, 64, 66, 65), //vfork|execve|exit|wait4|kill|uname
+BPF_JUMP(BPF_JMP|BPF_JGE|BPF_K, 78, 65, 64), //fcntl|flock|fsync|fdatasync|truncate|ftruncate
 BPF_JUMP(BPF_JMP|BPF_JGE|BPF_K, 137, 11, 0),
 BPF_JUMP(BPF_JMP|BPF_JGE|BPF_K, 95, 5, 0),
 BPF_JUMP(BPF_JMP|BPF_JGE|BPF_K, 93, 3, 0),
 BPF_JUMP(BPF_JMP|BPF_JGE|BPF_K, 91, 1, 0),
-BPF_JUMP(BPF_JMP|BPF_JGE|BPF_K, 82, 58, 57), //getcwd|chdir|fchdir
-BPF_JUMP(BPF_JMP|BPF_JGE|BPF_K, 92, 57, 56), //fchmod
-BPF_JUMP(BPF_JMP|BPF_JGE|BPF_K, 94, 56, 55), //fchown
+BPF_JUMP(BPF_JMP|BPF_JGE|BPF_K, 82, 60, 59), //getcwd|chdir|fchdir
+BPF_JUMP(BPF_JMP|BPF_JGE|BPF_K, 92, 59, 58), //fchmod
+BPF_JUMP(BPF_JMP|BPF_JGE|BPF_K, 94, 58, 57), //fchown
 BPF_JUMP(BPF_JMP|BPF_JGE|BPF_K, 135, 3, 0),
 BPF_JUMP(BPF_JMP|BPF_JGE|BPF_K, 112, 1, 0),
-BPF_JUMP(BPF_JMP|BPF_JGE|BPF_K, 111, 53, 52), //umask|gettimeofday|getrlimit|getrusage|sysinfo|times|ptrace|getuid|syslog|getgid|setuid|setgid|geteuid|getegid|setpgid|getppid
-BPF_JUMP(BPF_JMP|BPF_JGE|BPF_K, 132, 52, 51), //setsid|setreuid|setregid|getgroups|setgroups|setresuid|getresuid|setresgid|getresgid|getpgid|setfsuid|setfsgid|getsid|capget|capset|rt_sigpending|rt_sigtimedwait|rt_sigqueueinfo|rt_sigsuspend|sigaltstack
-BPF_JUMP(BPF_JMP|BPF_JGE|BPF_K, 136, 51, 50), //personality
+BPF_JUMP(BPF_JMP|BPF_JGE|BPF_K, 111, 55, 54), //umask|gettimeofday|getrlimit|getrusage|sysinfo|times|ptrace|getuid|syslog|getgid|setuid|setgid|geteuid|getegid|setpgid|getppid
+BPF_JUMP(BPF_JMP|BPF_JGE|BPF_K, 132, 54, 53), //setsid|setreuid|setregid|getgroups|setgroups|setresuid|getresuid|setresgid|getresgid|getpgid|setfsuid|setfsgid|getsid|capget|capset|rt_sigpending|rt_sigtimedwait|rt_sigqueueinfo|rt_sigsuspend|sigaltstack
+BPF_JUMP(BPF_JMP|BPF_JGE|BPF_K, 136, 53, 52), //personality
 BPF_JUMP(BPF_JMP|BPF_JGE|BPF_K, 157, 5, 0),
 BPF_JUMP(BPF_JMP|BPF_JGE|BPF_K, 155, 3, 0),
 BPF_JUMP(BPF_JMP|BPF_JGE|BPF_K, 140, 1, 0),
-BPF_JUMP(BPF_JMP|BPF_JGE|BPF_K, 139, 47, 46), //statfs|fstatfs
-BPF_JUMP(BPF_JMP|BPF_JGE|BPF_K, 153, 46, 45), //getpriority|setpriority|sched_setparam|sched_getparam|sched_setscheduler|sched_getscheduler|sched_get_priority_max|sched_get_priority_min|sched_rr_get_interval|mlock|munlock|mlockall|munlockall
-BPF_JUMP(BPF_JMP|BPF_JGE|BPF_K, 156, 45, 44), //pivot_root
+BPF_JUMP(BPF_JMP|BPF_JGE|BPF_K, 139, 49, 48), //statfs|fstatfs
+BPF_JUMP(BPF_JMP|BPF_JGE|BPF_K, 153, 48, 47), //getpriority|setpriority|sched_setparam|sched_getparam|sched_setscheduler|sched_getscheduler|sched_get_priority_max|sched_get_priority_min|sched_rr_get_interval|mlock|munlock|mlockall|munlockall
+BPF_JUMP(BPF_JMP|BPF_JGE|BPF_K, 156, 47, 46), //pivot_root
 BPF_JUMP(BPF_JMP|BPF_JGE|BPF_K, 169, 1, 0),
-BPF_JUMP(BPF_JMP|BPF_JGE|BPF_K, 168, 43, 42), //prctl|arch_prctl|adjtimex|setrlimit|chroot|sync|acct|settimeofday|mount|umount2|swapon
-BPF_JUMP(BPF_JMP|BPF_JGE|BPF_K, 172, 42, 41), //reboot|sethostname|setdomainname
-BPF_JUMP(BPF_JMP|BPF_JGE|BPF_K, 262, 21, 0),
-BPF_JUMP(BPF_JMP|BPF_JGE|BPF_K, 233, 11, 0),
+BPF_JUMP(BPF_JMP|BPF_JGE|BPF_K, 168, 45, 44), //prctl|arch_prctl|adjtimex|setrlimit|chroot|sync|acct|settimeofday|mount|umount2|swapon
+BPF_JUMP(BPF_JMP|BPF_JGE|BPF_K, 172, 44, 43), //reboot|sethostname|setdomainname
+BPF_JUMP(BPF_JMP|BPF_JGE|BPF_K, 257, 21, 0),
+BPF_JUMP(BPF_JMP|BPF_JGE|BPF_K, 221, 11, 0),
 BPF_JUMP(BPF_JMP|BPF_JGE|BPF_K, 202, 5, 0),
 BPF_JUMP(BPF_JMP|BPF_JGE|BPF_K, 186, 3, 0),
 BPF_JUMP(BPF_JMP|BPF_JGE|BPF_K, 179, 1, 0),
-BPF_JUMP(BPF_JMP|BPF_JGE|BPF_K, 177, 36, 35), //init_module|delete_module
-BPF_JUMP(BPF_JMP|BPF_JGE|BPF_K, 180, 35, 34), //quotactl
-BPF_JUMP(BPF_JMP|BPF_JGE|BPF_K, 201, 34, 33), //gettid|readahead|setxattr|lsetxattr|fsetxattr|getxattr|lgetxattr|fgetxattr|listxattr|llistxattr|flistxattr|removexattr|lremovexattr|fremovexattr|tkill
-BPF_JUMP(BPF_JMP|BPF_JGE|BPF_K, 221, 3, 0),
-BPF_JUMP(BPF_JMP|BPF_JGE|BPF_K, 217, 1, 0),
-BPF_JUMP(BPF_JMP|BPF_JGE|BPF_K, 205, 31, 30), //futex|sched_setaffinity|sched_getaffinity
-BPF_JUMP(BPF_JMP|BPF_JGE|BPF_K, 220, 30, 29), //getdents64|set_tid_address|restart_syscall
-BPF_JUMP(BPF_JMP|BPF_JGE|BPF_K, 232, 29, 28), //fadvise64|timer_create|timer_settime|timer_gettime|timer_getoverrun|timer_delete|clock_settime|clock_gettime|clock_getres|clock_nanosleep|exit_group
-BPF_JUMP(BPF_JMP|BPF_JGE|BPF_K, 254, 5, 0),
-BPF_JUMP(BPF_JMP|BPF_JGE|BPF_K, 250, 3, 0),
-BPF_JUMP(BPF_JMP|BPF_JGE|BPF_K, 247, 1, 0),
-BPF_JUMP(BPF_JMP|BPF_JGE|BPF_K, 235, 25, 24), //epoll_ctl|tgkill
-BPF_JUMP(BPF_JMP|BPF_JGE|BPF_K, 249, 24, 23), //waitid|add_key
+BPF_JUMP(BPF_JMP|BPF_JGE|BPF_K, 177, 38, 37), //init_module|delete_module
+BPF_JUMP(BPF_JMP|BPF_JGE|BPF_K, 180, 37, 36), //quotactl
+BPF_JUMP(BPF_JMP|BPF_JGE|BPF_K, 201, 36, 35), //gettid|readahead|setxattr|lsetxattr|fsetxattr|getxattr|lgetxattr|fgetxattr|listxattr|llistxattr|flistxattr|removexattr|lremovexattr|fremovexattr|tkill
+BPF_JUMP(BPF_JMP|BPF_JGE|BPF_K, 217, 3, 0),
+BPF_JUMP(BPF_JMP|BPF_JGE|BPF_K, 206, 1, 0),
+BPF_JUMP(BPF_JMP|BPF_JGE|BPF_K, 205, 33, 32), //futex|sched_setaffinity|sched_getaffinity
+BPF_JUMP(BPF_JMP|BPF_JGE|BPF_K, 211, 32, 31), //io_setup|io_destroy|io_getevents|io_submit|io_cancel
+BPF_JUMP(BPF_JMP|BPF_JGE|BPF_K, 220, 31, 30), //getdents64|set_tid_address|restart_syscall
+BPF_JUMP(BPF_JMP|BPF_JGE|BPF_K, 250, 5, 0),
+BPF_JUMP(BPF_JMP|BPF_JGE|BPF_K, 247, 3, 0),
+BPF_JUMP(BPF_JMP|BPF_JGE|BPF_K, 233, 1, 0),
+BPF_JUMP(BPF_JMP|BPF_JGE|BPF_K, 232, 27, 26), //fadvise64|timer_create|timer_settime|timer_gettime|timer_getoverrun|timer_delete|clock_settime|clock_gettime|clock_getres|clock_nanosleep|exit_group
+BPF_JUMP(BPF_JMP|BPF_JGE|BPF_K, 235, 26, 25), //epoll_ctl|tgkill
+BPF_JUMP(BPF_JMP|BPF_JGE|BPF_K, 249, 25, 24), //waitid|add_key
+BPF_JUMP(BPF_JMP|BPF_JGE|BPF_K, 254, 1, 0),
 BPF_JUMP(BPF_JMP|BPF_JGE|BPF_K, 253, 23, 22), //keyctl|ioprio_set|ioprio_get
-BPF_JUMP(BPF_JMP|BPF_JGE|BPF_K, 257, 1, 0),
-BPF_JUMP(BPF_JMP|BPF_JGE|BPF_K, 256, 21, 20), //inotify_add_watch|inotify_rm_watch
-BPF_JUMP(BPF_JMP|BPF_JGE|BPF_K, 261, 20, 19), //openat|mkdirat|mknodat|fchownat
-BPF_JUMP(BPF_JMP|BPF_JGE|BPF_K, 302, 9, 0),
-BPF_JUMP(BPF_JMP|BPF_JGE|BPF_K, 283, 5, 0),
-BPF_JUMP(BPF_JMP|BPF_JGE|BPF_K, 280, 3, 0),
-BPF_JUMP(BPF_JMP|BPF_JGE|BPF_K, 275, 1, 0),
-BPF_JUMP(BPF_JMP|BPF_JGE|BPF_K, 273, 15, 14), //newfstatat|unlinkat|renameat|linkat|symlinkat|readlinkat|fchmodat|faccessat|pselect6|ppoll|unshare
-BPF_JUMP(BPF_JMP|BPF_JGE|BPF_K, 279, 14, 13), //splice|tee|sync_file_range|vmsplice
-BPF_JUMP(BPF_JMP|BPF_JGE|BPF_K, 282, 13, 12), //utimensat|epoll_pwait
-BPF_JUMP(BPF_JMP|BPF_JGE|BPF_K, 285, 1, 0),
+BPF_JUMP(BPF_JMP|BPF_JGE|BPF_K, 256, 22, 21), //inotify_add_watch|inotify_rm_watch
+BPF_JUMP(BPF_JMP|BPF_JGE|BPF_K, 302, 11, 0),
+BPF_JUMP(BPF_JMP|BPF_JGE|BPF_K, 280, 5, 0),
+BPF_JUMP(BPF_JMP|BPF_JGE|BPF_K, 275, 3, 0),
+BPF_JUMP(BPF_JMP|BPF_JGE|BPF_K, 262, 1, 0),
+BPF_JUMP(BPF_JMP|BPF_JGE|BPF_K, 261, 17, 16), //openat|mkdirat|mknodat|fchownat
+BPF_JUMP(BPF_JMP|BPF_JGE|BPF_K, 273, 16, 15), //newfstatat|unlinkat|renameat|linkat|symlinkat|readlinkat|fchmodat|faccessat|pselect6|ppoll|unshare
+BPF_JUMP(BPF_JMP|BPF_JGE|BPF_K, 279, 15, 14), //splice|tee|sync_file_range|vmsplice
+BPF_JUMP(BPF_JMP|BPF_JGE|BPF_K, 285, 3, 0),
+BPF_JUMP(BPF_JMP|BPF_JGE|BPF_K, 283, 1, 0),
+BPF_JUMP(BPF_JMP|BPF_JGE|BPF_K, 282, 12, 11), //utimensat|epoll_pwait
 BPF_JUMP(BPF_JMP|BPF_JGE|BPF_K, 284, 11, 10), //timerfd_create
 BPF_JUMP(BPF_JMP|BPF_JGE|BPF_K, 300, 10, 9), //fallocate|timerfd_settime|timerfd_gettime|accept4|signalfd4|eventfd2|epoll_create1|dup3|pipe2|inotify_init1|preadv|pwritev|rt_tgsigqueueinfo|perf_event_open|recvmmsg
 BPF_JUMP(BPF_JMP|BPF_JGE|BPF_K, 322, 5, 0),
diff --git a/libc/seccomp/x86_global_policy.cpp b/libc/seccomp/x86_global_policy.cpp
index 36f4884..9305729 100644
--- a/libc/seccomp/x86_global_policy.cpp
+++ b/libc/seccomp/x86_global_policy.cpp
@@ -5,109 +5,111 @@
 
 #include "seccomp_bpfs.h"
 const sock_filter x86_global_filter[] = {
-BPF_JUMP(BPF_JMP|BPF_JGE|BPF_K, 0, 0, 118),
+BPF_JUMP(BPF_JMP|BPF_JGE|BPF_K, 0, 0, 120),
 BPF_JUMP(BPF_JMP|BPF_JGE|BPF_K, 136, 59, 0),
 BPF_JUMP(BPF_JMP|BPF_JGE|BPF_K, 66, 29, 0),
 BPF_JUMP(BPF_JMP|BPF_JGE|BPF_K, 41, 15, 0),
 BPF_JUMP(BPF_JMP|BPF_JGE|BPF_K, 24, 7, 0),
 BPF_JUMP(BPF_JMP|BPF_JGE|BPF_K, 10, 3, 0),
 BPF_JUMP(BPF_JMP|BPF_JGE|BPF_K, 8, 1, 0),
-BPF_JUMP(BPF_JMP|BPF_JGE|BPF_K, 7, 111, 110), //restart_syscall|exit|fork|read|write|open|close
-BPF_JUMP(BPF_JMP|BPF_JGE|BPF_K, 9, 110, 109), //creat
+BPF_JUMP(BPF_JMP|BPF_JGE|BPF_K, 7, 113, 112), //restart_syscall|exit|fork|read|write|open|close
+BPF_JUMP(BPF_JMP|BPF_JGE|BPF_K, 9, 112, 111), //creat
 BPF_JUMP(BPF_JMP|BPF_JGE|BPF_K, 19, 1, 0),
-BPF_JUMP(BPF_JMP|BPF_JGE|BPF_K, 13, 108, 107), //unlink|execve|chdir
-BPF_JUMP(BPF_JMP|BPF_JGE|BPF_K, 22, 107, 106), //lseek|getpid|mount
+BPF_JUMP(BPF_JMP|BPF_JGE|BPF_K, 13, 110, 109), //unlink|execve|chdir
+BPF_JUMP(BPF_JMP|BPF_JGE|BPF_K, 22, 109, 108), //lseek|getpid|mount
 BPF_JUMP(BPF_JMP|BPF_JGE|BPF_K, 33, 3, 0),
 BPF_JUMP(BPF_JMP|BPF_JGE|BPF_K, 26, 1, 0),
-BPF_JUMP(BPF_JMP|BPF_JGE|BPF_K, 25, 104, 103), //getuid
-BPF_JUMP(BPF_JMP|BPF_JGE|BPF_K, 27, 103, 102), //ptrace
+BPF_JUMP(BPF_JMP|BPF_JGE|BPF_K, 25, 106, 105), //getuid
+BPF_JUMP(BPF_JMP|BPF_JGE|BPF_K, 27, 105, 104), //ptrace
 BPF_JUMP(BPF_JMP|BPF_JGE|BPF_K, 36, 1, 0),
-BPF_JUMP(BPF_JMP|BPF_JGE|BPF_K, 34, 101, 100), //access
-BPF_JUMP(BPF_JMP|BPF_JGE|BPF_K, 40, 100, 99), //sync|kill|rename|mkdir
+BPF_JUMP(BPF_JMP|BPF_JGE|BPF_K, 34, 103, 102), //access
+BPF_JUMP(BPF_JMP|BPF_JGE|BPF_K, 40, 102, 101), //sync|kill|rename|mkdir
 BPF_JUMP(BPF_JMP|BPF_JGE|BPF_K, 57, 7, 0),
 BPF_JUMP(BPF_JMP|BPF_JGE|BPF_K, 51, 3, 0),
 BPF_JUMP(BPF_JMP|BPF_JGE|BPF_K, 45, 1, 0),
-BPF_JUMP(BPF_JMP|BPF_JGE|BPF_K, 44, 96, 95), //dup|pipe|times
-BPF_JUMP(BPF_JMP|BPF_JGE|BPF_K, 46, 95, 94), //brk
+BPF_JUMP(BPF_JMP|BPF_JGE|BPF_K, 44, 98, 97), //dup|pipe|times
+BPF_JUMP(BPF_JMP|BPF_JGE|BPF_K, 46, 97, 96), //brk
 BPF_JUMP(BPF_JMP|BPF_JGE|BPF_K, 54, 1, 0),
-BPF_JUMP(BPF_JMP|BPF_JGE|BPF_K, 53, 93, 92), //acct|umount2
-BPF_JUMP(BPF_JMP|BPF_JGE|BPF_K, 56, 92, 91), //ioctl|fcntl
+BPF_JUMP(BPF_JMP|BPF_JGE|BPF_K, 53, 95, 94), //acct|umount2
+BPF_JUMP(BPF_JMP|BPF_JGE|BPF_K, 56, 94, 93), //ioctl|fcntl
 BPF_JUMP(BPF_JMP|BPF_JGE|BPF_K, 63, 3, 0),
 BPF_JUMP(BPF_JMP|BPF_JGE|BPF_K, 60, 1, 0),
-BPF_JUMP(BPF_JMP|BPF_JGE|BPF_K, 58, 89, 88), //setpgid
-BPF_JUMP(BPF_JMP|BPF_JGE|BPF_K, 62, 88, 87), //umask|chroot
-BPF_JUMP(BPF_JMP|BPF_JGE|BPF_K, 65, 87, 86), //dup2|getppid
+BPF_JUMP(BPF_JMP|BPF_JGE|BPF_K, 58, 91, 90), //setpgid
+BPF_JUMP(BPF_JMP|BPF_JGE|BPF_K, 62, 90, 89), //umask|chroot
+BPF_JUMP(BPF_JMP|BPF_JGE|BPF_K, 65, 89, 88), //dup2|getppid
 BPF_JUMP(BPF_JMP|BPF_JGE|BPF_K, 102, 15, 0),
 BPF_JUMP(BPF_JMP|BPF_JGE|BPF_K, 87, 7, 0),
 BPF_JUMP(BPF_JMP|BPF_JGE|BPF_K, 77, 3, 0),
 BPF_JUMP(BPF_JMP|BPF_JGE|BPF_K, 74, 1, 0),
-BPF_JUMP(BPF_JMP|BPF_JGE|BPF_K, 68, 82, 81), //setsid|sigaction
-BPF_JUMP(BPF_JMP|BPF_JGE|BPF_K, 76, 81, 80), //sethostname|setrlimit
+BPF_JUMP(BPF_JMP|BPF_JGE|BPF_K, 68, 84, 83), //setsid|sigaction
+BPF_JUMP(BPF_JMP|BPF_JGE|BPF_K, 76, 83, 82), //sethostname|setrlimit
 BPF_JUMP(BPF_JMP|BPF_JGE|BPF_K, 85, 1, 0),
-BPF_JUMP(BPF_JMP|BPF_JGE|BPF_K, 80, 79, 78), //getrusage|gettimeofday|settimeofday
-BPF_JUMP(BPF_JMP|BPF_JGE|BPF_K, 86, 78, 77), //readlink
+BPF_JUMP(BPF_JMP|BPF_JGE|BPF_K, 80, 81, 80), //getrusage|gettimeofday|settimeofday
+BPF_JUMP(BPF_JMP|BPF_JGE|BPF_K, 86, 80, 79), //readlink
 BPF_JUMP(BPF_JMP|BPF_JGE|BPF_K, 94, 3, 0),
 BPF_JUMP(BPF_JMP|BPF_JGE|BPF_K, 90, 1, 0),
-BPF_JUMP(BPF_JMP|BPF_JGE|BPF_K, 89, 75, 74), //swapon|reboot
-BPF_JUMP(BPF_JMP|BPF_JGE|BPF_K, 93, 74, 73), //mmap|munmap|truncate
+BPF_JUMP(BPF_JMP|BPF_JGE|BPF_K, 89, 77, 76), //swapon|reboot
+BPF_JUMP(BPF_JMP|BPF_JGE|BPF_K, 93, 76, 75), //mmap|munmap|truncate
 BPF_JUMP(BPF_JMP|BPF_JGE|BPF_K, 96, 1, 0),
-BPF_JUMP(BPF_JMP|BPF_JGE|BPF_K, 95, 72, 71), //fchmod
-BPF_JUMP(BPF_JMP|BPF_JGE|BPF_K, 98, 71, 70), //getpriority|setpriority
+BPF_JUMP(BPF_JMP|BPF_JGE|BPF_K, 95, 74, 73), //fchmod
+BPF_JUMP(BPF_JMP|BPF_JGE|BPF_K, 98, 73, 72), //getpriority|setpriority
 BPF_JUMP(BPF_JMP|BPF_JGE|BPF_K, 124, 7, 0),
 BPF_JUMP(BPF_JMP|BPF_JGE|BPF_K, 116, 3, 0),
 BPF_JUMP(BPF_JMP|BPF_JGE|BPF_K, 114, 1, 0),
-BPF_JUMP(BPF_JMP|BPF_JGE|BPF_K, 106, 67, 66), //socketcall|syslog|setitimer|getitimer
-BPF_JUMP(BPF_JMP|BPF_JGE|BPF_K, 115, 66, 65), //wait4
+BPF_JUMP(BPF_JMP|BPF_JGE|BPF_K, 106, 69, 68), //socketcall|syslog|setitimer|getitimer
+BPF_JUMP(BPF_JMP|BPF_JGE|BPF_K, 115, 68, 67), //wait4
 BPF_JUMP(BPF_JMP|BPF_JGE|BPF_K, 118, 1, 0),
-BPF_JUMP(BPF_JMP|BPF_JGE|BPF_K, 117, 64, 63), //sysinfo
-BPF_JUMP(BPF_JMP|BPF_JGE|BPF_K, 123, 63, 62), //fsync|sigreturn|clone|setdomainname|uname
+BPF_JUMP(BPF_JMP|BPF_JGE|BPF_K, 117, 66, 65), //sysinfo
+BPF_JUMP(BPF_JMP|BPF_JGE|BPF_K, 123, 65, 64), //fsync|sigreturn|clone|setdomainname|uname
 BPF_JUMP(BPF_JMP|BPF_JGE|BPF_K, 131, 3, 0),
 BPF_JUMP(BPF_JMP|BPF_JGE|BPF_K, 128, 1, 0),
-BPF_JUMP(BPF_JMP|BPF_JGE|BPF_K, 126, 60, 59), //adjtimex|mprotect
-BPF_JUMP(BPF_JMP|BPF_JGE|BPF_K, 130, 59, 58), //init_module|delete_module
-BPF_JUMP(BPF_JMP|BPF_JGE|BPF_K, 134, 58, 57), //quotactl|getpgid|fchdir
-BPF_JUMP(BPF_JMP|BPF_JGE|BPF_K, 286, 29, 0),
+BPF_JUMP(BPF_JMP|BPF_JGE|BPF_K, 126, 62, 61), //adjtimex|mprotect
+BPF_JUMP(BPF_JMP|BPF_JGE|BPF_K, 130, 61, 60), //init_module|delete_module
+BPF_JUMP(BPF_JMP|BPF_JGE|BPF_K, 134, 60, 59), //quotactl|getpgid|fchdir
+BPF_JUMP(BPF_JMP|BPF_JGE|BPF_K, 284, 29, 0),
 BPF_JUMP(BPF_JMP|BPF_JGE|BPF_K, 213, 15, 0),
 BPF_JUMP(BPF_JMP|BPF_JGE|BPF_K, 172, 7, 0),
 BPF_JUMP(BPF_JMP|BPF_JGE|BPF_K, 150, 3, 0),
 BPF_JUMP(BPF_JMP|BPF_JGE|BPF_K, 138, 1, 0),
-BPF_JUMP(BPF_JMP|BPF_JGE|BPF_K, 137, 52, 51), //personality
-BPF_JUMP(BPF_JMP|BPF_JGE|BPF_K, 149, 51, 50), //setfsuid|setfsgid|_llseek|getdents|_newselect|flock|msync|readv|writev|getsid|fdatasync
+BPF_JUMP(BPF_JMP|BPF_JGE|BPF_K, 137, 54, 53), //personality
+BPF_JUMP(BPF_JMP|BPF_JGE|BPF_K, 149, 53, 52), //setfsuid|setfsgid|_llseek|getdents|_newselect|flock|msync|readv|writev|getsid|fdatasync
 BPF_JUMP(BPF_JMP|BPF_JGE|BPF_K, 168, 1, 0),
-BPF_JUMP(BPF_JMP|BPF_JGE|BPF_K, 164, 49, 48), //mlock|munlock|mlockall|munlockall|sched_setparam|sched_getparam|sched_setscheduler|sched_getscheduler|sched_yield|sched_get_priority_max|sched_get_priority_min|sched_rr_get_interval|nanosleep|mremap
-BPF_JUMP(BPF_JMP|BPF_JGE|BPF_K, 169, 48, 47), //poll
+BPF_JUMP(BPF_JMP|BPF_JGE|BPF_K, 164, 51, 50), //mlock|munlock|mlockall|munlockall|sched_setparam|sched_getparam|sched_setscheduler|sched_getscheduler|sched_yield|sched_get_priority_max|sched_get_priority_min|sched_rr_get_interval|nanosleep|mremap
+BPF_JUMP(BPF_JMP|BPF_JGE|BPF_K, 169, 50, 49), //poll
 BPF_JUMP(BPF_JMP|BPF_JGE|BPF_K, 190, 3, 0),
 BPF_JUMP(BPF_JMP|BPF_JGE|BPF_K, 183, 1, 0),
-BPF_JUMP(BPF_JMP|BPF_JGE|BPF_K, 182, 45, 44), //prctl|rt_sigreturn|rt_sigaction|rt_sigprocmask|rt_sigpending|rt_sigtimedwait|rt_sigqueueinfo|rt_sigsuspend|pread64|pwrite64
-BPF_JUMP(BPF_JMP|BPF_JGE|BPF_K, 188, 44, 43), //getcwd|capget|capset|sigaltstack|sendfile
+BPF_JUMP(BPF_JMP|BPF_JGE|BPF_K, 182, 47, 46), //prctl|rt_sigreturn|rt_sigaction|rt_sigprocmask|rt_sigpending|rt_sigtimedwait|rt_sigqueueinfo|rt_sigsuspend|pread64|pwrite64
+BPF_JUMP(BPF_JMP|BPF_JGE|BPF_K, 188, 46, 45), //getcwd|capget|capset|sigaltstack|sendfile
 BPF_JUMP(BPF_JMP|BPF_JGE|BPF_K, 199, 1, 0),
-BPF_JUMP(BPF_JMP|BPF_JGE|BPF_K, 198, 42, 41), //vfork|ugetrlimit|mmap2|truncate64|ftruncate64|stat64|lstat64|fstat64
-BPF_JUMP(BPF_JMP|BPF_JGE|BPF_K, 212, 41, 40), //getuid32|getgid32|geteuid32|getegid32|setreuid32|setregid32|getgroups32|setgroups32|fchown32|setresuid32|getresuid32|setresgid32|getresgid32
-BPF_JUMP(BPF_JMP|BPF_JGE|BPF_K, 254, 7, 0),
+BPF_JUMP(BPF_JMP|BPF_JGE|BPF_K, 198, 44, 43), //vfork|ugetrlimit|mmap2|truncate64|ftruncate64|stat64|lstat64|fstat64
+BPF_JUMP(BPF_JMP|BPF_JGE|BPF_K, 212, 43, 42), //getuid32|getgid32|geteuid32|getegid32|setreuid32|setregid32|getgroups32|setgroups32|fchown32|setresuid32|getresuid32|setresgid32|getresgid32
+BPF_JUMP(BPF_JMP|BPF_JGE|BPF_K, 252, 7, 0),
 BPF_JUMP(BPF_JMP|BPF_JGE|BPF_K, 224, 3, 0),
 BPF_JUMP(BPF_JMP|BPF_JGE|BPF_K, 218, 1, 0),
-BPF_JUMP(BPF_JMP|BPF_JGE|BPF_K, 215, 37, 36), //setuid32|setgid32
-BPF_JUMP(BPF_JMP|BPF_JGE|BPF_K, 222, 36, 35), //mincore|madvise|getdents64|fcntl64
-BPF_JUMP(BPF_JMP|BPF_JGE|BPF_K, 252, 1, 0),
-BPF_JUMP(BPF_JMP|BPF_JGE|BPF_K, 244, 34, 33), //gettid|readahead|setxattr|lsetxattr|fsetxattr|getxattr|lgetxattr|fgetxattr|listxattr|llistxattr|flistxattr|removexattr|lremovexattr|fremovexattr|tkill|sendfile64|futex|sched_setaffinity|sched_getaffinity|set_thread_area
-BPF_JUMP(BPF_JMP|BPF_JGE|BPF_K, 253, 33, 32), //exit_group
-BPF_JUMP(BPF_JMP|BPF_JGE|BPF_K, 284, 3, 0),
-BPF_JUMP(BPF_JMP|BPF_JGE|BPF_K, 272, 1, 0),
-BPF_JUMP(BPF_JMP|BPF_JGE|BPF_K, 271, 30, 29), //epoll_create|epoll_ctl|epoll_wait|remap_file_pages|set_tid_address|timer_create|timer_settime|timer_gettime|timer_getoverrun|timer_delete|clock_settime|clock_gettime|clock_getres|clock_nanosleep|statfs64|fstatfs64|tgkill
-BPF_JUMP(BPF_JMP|BPF_JGE|BPF_K, 273, 29, 28), //fadvise64_64
-BPF_JUMP(BPF_JMP|BPF_JGE|BPF_K, 285, 28, 27), //waitid
-BPF_JUMP(BPF_JMP|BPF_JGE|BPF_K, 322, 13, 0),
-BPF_JUMP(BPF_JMP|BPF_JGE|BPF_K, 300, 7, 0),
-BPF_JUMP(BPF_JMP|BPF_JGE|BPF_K, 291, 3, 0),
-BPF_JUMP(BPF_JMP|BPF_JGE|BPF_K, 288, 1, 0),
-BPF_JUMP(BPF_JMP|BPF_JGE|BPF_K, 287, 23, 22), //add_key
+BPF_JUMP(BPF_JMP|BPF_JGE|BPF_K, 215, 39, 38), //setuid32|setgid32
+BPF_JUMP(BPF_JMP|BPF_JGE|BPF_K, 222, 38, 37), //mincore|madvise|getdents64|fcntl64
+BPF_JUMP(BPF_JMP|BPF_JGE|BPF_K, 245, 1, 0),
+BPF_JUMP(BPF_JMP|BPF_JGE|BPF_K, 244, 36, 35), //gettid|readahead|setxattr|lsetxattr|fsetxattr|getxattr|lgetxattr|fgetxattr|listxattr|llistxattr|flistxattr|removexattr|lremovexattr|fremovexattr|tkill|sendfile64|futex|sched_setaffinity|sched_getaffinity|set_thread_area
+BPF_JUMP(BPF_JMP|BPF_JGE|BPF_K, 250, 35, 34), //io_setup|io_destroy|io_getevents|io_submit|io_cancel
+BPF_JUMP(BPF_JMP|BPF_JGE|BPF_K, 272, 3, 0),
+BPF_JUMP(BPF_JMP|BPF_JGE|BPF_K, 254, 1, 0),
+BPF_JUMP(BPF_JMP|BPF_JGE|BPF_K, 253, 32, 31), //exit_group
+BPF_JUMP(BPF_JMP|BPF_JGE|BPF_K, 271, 31, 30), //epoll_create|epoll_ctl|epoll_wait|remap_file_pages|set_tid_address|timer_create|timer_settime|timer_gettime|timer_getoverrun|timer_delete|clock_settime|clock_gettime|clock_getres|clock_nanosleep|statfs64|fstatfs64|tgkill
+BPF_JUMP(BPF_JMP|BPF_JGE|BPF_K, 273, 30, 29), //fadvise64_64
+BPF_JUMP(BPF_JMP|BPF_JGE|BPF_K, 322, 15, 0),
+BPF_JUMP(BPF_JMP|BPF_JGE|BPF_K, 295, 7, 0),
+BPF_JUMP(BPF_JMP|BPF_JGE|BPF_K, 288, 3, 0),
+BPF_JUMP(BPF_JMP|BPF_JGE|BPF_K, 286, 1, 0),
+BPF_JUMP(BPF_JMP|BPF_JGE|BPF_K, 285, 25, 24), //waitid
+BPF_JUMP(BPF_JMP|BPF_JGE|BPF_K, 287, 24, 23), //add_key
+BPF_JUMP(BPF_JMP|BPF_JGE|BPF_K, 291, 1, 0),
 BPF_JUMP(BPF_JMP|BPF_JGE|BPF_K, 289, 22, 21), //keyctl
-BPF_JUMP(BPF_JMP|BPF_JGE|BPF_K, 295, 1, 0),
-BPF_JUMP(BPF_JMP|BPF_JGE|BPF_K, 294, 20, 19), //inotify_init|inotify_add_watch|inotify_rm_watch
-BPF_JUMP(BPF_JMP|BPF_JGE|BPF_K, 299, 19, 18), //openat|mkdirat|mknodat|fchownat
-BPF_JUMP(BPF_JMP|BPF_JGE|BPF_K, 318, 3, 0),
-BPF_JUMP(BPF_JMP|BPF_JGE|BPF_K, 313, 1, 0),
-BPF_JUMP(BPF_JMP|BPF_JGE|BPF_K, 311, 16, 15), //fstatat64|unlinkat|renameat|linkat|symlinkat|readlinkat|fchmodat|faccessat|pselect6|ppoll|unshare
+BPF_JUMP(BPF_JMP|BPF_JGE|BPF_K, 294, 21, 20), //inotify_init|inotify_add_watch|inotify_rm_watch
+BPF_JUMP(BPF_JMP|BPF_JGE|BPF_K, 313, 3, 0),
+BPF_JUMP(BPF_JMP|BPF_JGE|BPF_K, 300, 1, 0),
+BPF_JUMP(BPF_JMP|BPF_JGE|BPF_K, 299, 18, 17), //openat|mkdirat|mknodat|fchownat
+BPF_JUMP(BPF_JMP|BPF_JGE|BPF_K, 311, 17, 16), //fstatat64|unlinkat|renameat|linkat|symlinkat|readlinkat|fchmodat|faccessat|pselect6|ppoll|unshare
+BPF_JUMP(BPF_JMP|BPF_JGE|BPF_K, 318, 1, 0),
 BPF_JUMP(BPF_JMP|BPF_JGE|BPF_K, 317, 15, 14), //splice|sync_file_range|tee|vmsplice
 BPF_JUMP(BPF_JMP|BPF_JGE|BPF_K, 321, 14, 13), //getcpu|epoll_pwait|utimensat
 BPF_JUMP(BPF_JMP|BPF_JGE|BPF_K, 350, 7, 0),
diff --git a/libc/upstream-freebsd/android/include/collate.h b/libc/upstream-freebsd/android/include/collate.h
new file mode 100644
index 0000000..e69de29
--- /dev/null
+++ b/libc/upstream-freebsd/android/include/collate.h
diff --git a/libc/upstream-freebsd/android/include/freebsd-compat.h b/libc/upstream-freebsd/android/include/freebsd-compat.h
index 7acdf7c..8f0a307 100644
--- a/libc/upstream-freebsd/android/include/freebsd-compat.h
+++ b/libc/upstream-freebsd/android/include/freebsd-compat.h
@@ -18,6 +18,10 @@
 #define _BIONIC_FREEBSD_COMPAT_H_included
 
 #define _BSD_SOURCE
+
+#include <sys/cdefs.h>
+#include <stddef.h> // For size_t.
+
 #define REPLACE_GETOPT
 
 /*
@@ -40,4 +44,12 @@
 /* Redirect internal C library calls to the public function. */
 #define _nanosleep nanosleep
 
+/* FreeBSD has this as API, but we just use it internally. */
+void* reallocarray(void*, size_t, size_t);
+
+/* FreeBSD has this, but we can't really implement it correctly on Linux. */
+#define issetugid() 0
+
+#define ARG_MAX sysconf(_SC_ARG_MAX)
+
 #endif
diff --git a/libc/upstream-freebsd/lib/libc/gen/glob.c b/libc/upstream-freebsd/lib/libc/gen/glob.c
new file mode 100644
index 0000000..026f68e
--- /dev/null
+++ b/libc/upstream-freebsd/lib/libc/gen/glob.c
@@ -0,0 +1,1125 @@
+/*
+ * Copyright (c) 1989, 1993
+ *	The Regents of the University of California.  All rights reserved.
+ *
+ * This code is derived from software contributed to Berkeley by
+ * Guido van Rossum.
+ *
+ * Copyright (c) 2011 The FreeBSD Foundation
+ * All rights reserved.
+ * Portions of this software were developed by David Chisnall
+ * under sponsorship from the FreeBSD Foundation.
+ *
+ * Redistribution and use in source and binary forms, with or without
+ * modification, are permitted provided that the following conditions
+ * are met:
+ * 1. Redistributions of source code must retain the above copyright
+ *    notice, this list of conditions and the following disclaimer.
+ * 2. Redistributions in binary form must reproduce the above copyright
+ *    notice, this list of conditions and the following disclaimer in the
+ *    documentation and/or other materials provided with the distribution.
+ * 3. Neither the name of the University nor the names of its contributors
+ *    may be used to endorse or promote products derived from this software
+ *    without specific prior written permission.
+ *
+ * THIS SOFTWARE IS PROVIDED BY THE REGENTS AND CONTRIBUTORS ``AS IS'' AND
+ * ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE
+ * IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE
+ * ARE DISCLAIMED.  IN NO EVENT SHALL THE REGENTS OR CONTRIBUTORS BE LIABLE
+ * FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL
+ * DAMAGES (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS
+ * OR SERVICES; LOSS OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION)
+ * HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT
+ * LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY
+ * OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF
+ * SUCH DAMAGE.
+ */
+
+#if defined(LIBC_SCCS) && !defined(lint)
+static char sccsid[] = "@(#)glob.c	8.3 (Berkeley) 10/13/93";
+#endif /* LIBC_SCCS and not lint */
+#include <sys/cdefs.h>
+__FBSDID("$FreeBSD: head/lib/libc/gen/glob.c 317913 2017-05-07 19:52:56Z jilles $");
+
+/*
+ * glob(3) -- a superset of the one defined in POSIX 1003.2.
+ *
+ * The [!...] convention to negate a range is supported (SysV, Posix, ksh).
+ *
+ * Optional extra services, controlled by flags not defined by POSIX:
+ *
+ * GLOB_QUOTE:
+ *	Escaping convention: \ inhibits any special meaning the following
+ *	character might have (except \ at end of string is retained).
+ * GLOB_MAGCHAR:
+ *	Set in gl_flags if pattern contained a globbing character.
+ * GLOB_NOMAGIC:
+ *	Same as GLOB_NOCHECK, but it will only append pattern if it did
+ *	not contain any magic characters.  [Used in csh style globbing]
+ * GLOB_ALTDIRFUNC:
+ *	Use alternately specified directory access functions.
+ * GLOB_TILDE:
+ *	expand ~user/foo to the /home/dir/of/user/foo
+ * GLOB_BRACE:
+ *	expand {1,2}{a,b} to 1a 1b 2a 2b
+ * gl_matchc:
+ *	Number of matches in the current invocation of glob.
+ */
+
+/*
+ * Some notes on multibyte character support:
+ * 1. Patterns with illegal byte sequences match nothing - even if
+ *    GLOB_NOCHECK is specified.
+ * 2. Illegal byte sequences in filenames are handled by treating them as
+ *    single-byte characters with a values of such bytes of the sequence
+ *    cast to wchar_t.
+ * 3. State-dependent encodings are not currently supported.
+ */
+
+#include <sys/param.h>
+#include <sys/stat.h>
+
+#include <ctype.h>
+#include <dirent.h>
+#include <errno.h>
+#include <glob.h>
+#include <limits.h>
+#include <pwd.h>
+#include <stdint.h>
+#include <stdio.h>
+#include <stdlib.h>
+#include <string.h>
+#include <unistd.h>
+#include <wchar.h>
+
+#include "collate.h"
+
+/*
+ * glob(3) expansion limits. Stop the expansion if any of these limits
+ * is reached. This caps the runtime in the face of DoS attacks. See
+ * also CVE-2010-2632
+ */
+#define	GLOB_LIMIT_BRACE	128	/* number of brace calls */
+#define	GLOB_LIMIT_PATH		65536	/* number of path elements */
+#define	GLOB_LIMIT_READDIR	16384	/* number of readdirs */
+#define	GLOB_LIMIT_STAT		1024	/* number of stat system calls */
+#define	GLOB_LIMIT_STRING	ARG_MAX	/* maximum total size for paths */
+
+struct glob_limit {
+	size_t	l_brace_cnt;
+	size_t	l_path_lim;
+	size_t	l_readdir_cnt;	
+	size_t	l_stat_cnt;	
+	size_t	l_string_cnt;
+};
+
+#define	DOT		L'.'
+#define	EOS		L'\0'
+#define	LBRACKET	L'['
+#define	NOT		L'!'
+#define	QUESTION	L'?'
+#define	QUOTE		L'\\'
+#define	RANGE		L'-'
+#define	RBRACKET	L']'
+#define	SEP		L'/'
+#define	STAR		L'*'
+#define	TILDE		L'~'
+#define	LBRACE		L'{'
+#define	RBRACE		L'}'
+#define	COMMA		L','
+
+#define	M_QUOTE		0x8000000000ULL
+#define	M_PROTECT	0x4000000000ULL
+#define	M_MASK		0xffffffffffULL
+#define	M_CHAR		0x00ffffffffULL
+
+typedef uint_fast64_t Char;
+
+#define	CHAR(c)		((Char)((c)&M_CHAR))
+#define	META(c)		((Char)((c)|M_QUOTE))
+#define	UNPROT(c)	((c) & ~M_PROTECT)
+#define	M_ALL		META(L'*')
+#define	M_END		META(L']')
+#define	M_NOT		META(L'!')
+#define	M_ONE		META(L'?')
+#define	M_RNG		META(L'-')
+#define	M_SET		META(L'[')
+#define	ismeta(c)	(((c)&M_QUOTE) != 0)
+#ifdef DEBUG
+#define	isprot(c)	(((c)&M_PROTECT) != 0)
+#endif
+
+static int	 compare(const void *, const void *);
+static int	 g_Ctoc(const Char *, char *, size_t);
+static int	 g_lstat(Char *, struct stat *, glob_t *);
+static DIR	*g_opendir(Char *, glob_t *);
+static const Char *g_strchr(const Char *, wchar_t);
+#ifdef notdef
+static Char	*g_strcat(Char *, const Char *);
+#endif
+static int	 g_stat(Char *, struct stat *, glob_t *);
+static int	 glob0(const Char *, glob_t *, struct glob_limit *,
+    const char *);
+static int	 glob1(Char *, glob_t *, struct glob_limit *);
+static int	 glob2(Char *, Char *, Char *, Char *, glob_t *,
+    struct glob_limit *);
+static int	 glob3(Char *, Char *, Char *, Char *, Char *, glob_t *,
+    struct glob_limit *);
+static int	 globextend(const Char *, glob_t *, struct glob_limit *,
+    const char *);
+static const Char *
+		 globtilde(const Char *, Char *, size_t, glob_t *);
+static int	 globexp0(const Char *, glob_t *, struct glob_limit *,
+    const char *);
+static int	 globexp1(const Char *, glob_t *, struct glob_limit *);
+static int	 globexp2(const Char *, const Char *, glob_t *,
+    struct glob_limit *);
+static int	 globfinal(glob_t *, struct glob_limit *, size_t,
+    const char *);
+static int	 match(Char *, Char *, Char *);
+static int	 err_nomatch(glob_t *, struct glob_limit *, const char *);
+static int	 err_aborted(glob_t *, int, char *);
+#ifdef DEBUG
+static void	 qprintf(const char *, Char *);
+#endif
+
+int
+glob(const char * __restrict pattern, int flags,
+	 int (*errfunc)(const char *, int), glob_t * __restrict pglob)
+{
+	struct glob_limit limit = { 0, 0, 0, 0, 0 };
+	const char *patnext;
+	Char *bufnext, *bufend, patbuf[MAXPATHLEN], prot;
+	mbstate_t mbs;
+	wchar_t wc;
+	size_t clen;
+	int too_long;
+
+	patnext = pattern;
+	if (!(flags & GLOB_APPEND)) {
+		pglob->gl_pathc = 0;
+		pglob->gl_pathv = NULL;
+		if (!(flags & GLOB_DOOFFS))
+			pglob->gl_offs = 0;
+	}
+	if (flags & GLOB_LIMIT) {
+		limit.l_path_lim = pglob->gl_matchc;
+		if (limit.l_path_lim == 0)
+			limit.l_path_lim = GLOB_LIMIT_PATH;
+	}
+	pglob->gl_flags = flags & ~GLOB_MAGCHAR;
+	pglob->gl_errfunc = errfunc;
+	pglob->gl_matchc = 0;
+
+	bufnext = patbuf;
+	bufend = bufnext + MAXPATHLEN - 1;
+	too_long = 1;
+	if (flags & GLOB_NOESCAPE) {
+		memset(&mbs, 0, sizeof(mbs));
+		while (bufnext <= bufend) {
+			clen = mbrtowc(&wc, patnext, MB_LEN_MAX, &mbs);
+			if (clen == (size_t)-1 || clen == (size_t)-2)
+				return (err_nomatch(pglob, &limit, pattern));
+			else if (clen == 0) {
+				too_long = 0;
+				break;
+			}
+			*bufnext++ = wc;
+			patnext += clen;
+		}
+	} else {
+		/* Protect the quoted characters. */
+		memset(&mbs, 0, sizeof(mbs));
+		while (bufnext <= bufend) {
+			if (*patnext == '\\') {
+				if (*++patnext == '\0') {
+					*bufnext++ = QUOTE;
+					continue;
+				}
+				prot = M_PROTECT;
+			} else
+				prot = 0;
+			clen = mbrtowc(&wc, patnext, MB_LEN_MAX, &mbs);
+			if (clen == (size_t)-1 || clen == (size_t)-2)
+				return (err_nomatch(pglob, &limit, pattern));
+			else if (clen == 0) {
+				too_long = 0;
+				break;
+			}
+			*bufnext++ = wc | prot;
+			patnext += clen;
+		}
+	}
+	if (too_long)
+		return (err_nomatch(pglob, &limit, pattern));
+	*bufnext = EOS;
+
+	if (flags & GLOB_BRACE)
+	    return (globexp0(patbuf, pglob, &limit, pattern));
+	else
+	    return (glob0(patbuf, pglob, &limit, pattern));
+}
+
+static int
+globexp0(const Char *pattern, glob_t *pglob, struct glob_limit *limit,
+    const char *origpat) {
+	int rv;
+	size_t oldpathc;
+
+	/* Protect a single {}, for find(1), like csh */
+	if (pattern[0] == LBRACE && pattern[1] == RBRACE && pattern[2] == EOS) {
+		if ((pglob->gl_flags & GLOB_LIMIT) &&
+		    limit->l_brace_cnt++ >= GLOB_LIMIT_BRACE) {
+			errno = E2BIG;
+			return (GLOB_NOSPACE);
+		}
+		return (glob0(pattern, pglob, limit, origpat));
+	}
+
+	oldpathc = pglob->gl_pathc;
+
+	if ((rv = globexp1(pattern, pglob, limit)) != 0)
+		return rv;
+
+	return (globfinal(pglob, limit, oldpathc, origpat));
+}
+
+/*
+ * Expand recursively a glob {} pattern. When there is no more expansion
+ * invoke the standard globbing routine to glob the rest of the magic
+ * characters
+ */
+static int
+globexp1(const Char *pattern, glob_t *pglob, struct glob_limit *limit)
+{
+	const Char* ptr;
+
+	if ((ptr = g_strchr(pattern, LBRACE)) != NULL) {
+		if ((pglob->gl_flags & GLOB_LIMIT) &&
+		    limit->l_brace_cnt++ >= GLOB_LIMIT_BRACE) {
+			errno = E2BIG;
+			return (GLOB_NOSPACE);
+		}
+		return (globexp2(ptr, pattern, pglob, limit));
+	}
+
+	return (glob0(pattern, pglob, limit, NULL));
+}
+
+
+/*
+ * Recursive brace globbing helper. Tries to expand a single brace.
+ * If it succeeds then it invokes globexp1 with the new pattern.
+ * If it fails then it tries to glob the rest of the pattern and returns.
+ */
+static int
+globexp2(const Char *ptr, const Char *pattern, glob_t *pglob,
+    struct glob_limit *limit)
+{
+	int     i, rv;
+	Char   *lm, *ls;
+	const Char *pe, *pm, *pm1, *pl;
+	Char    patbuf[MAXPATHLEN];
+
+	/* copy part up to the brace */
+	for (lm = patbuf, pm = pattern; pm != ptr; *lm++ = *pm++)
+		continue;
+	*lm = EOS;
+	ls = lm;
+
+	/* Find the balanced brace */
+	for (i = 0, pe = ++ptr; *pe != EOS; pe++)
+		if (*pe == LBRACKET) {
+			/* Ignore everything between [] */
+			for (pm = pe++; *pe != RBRACKET && *pe != EOS; pe++)
+				continue;
+			if (*pe == EOS) {
+				/*
+				 * We could not find a matching RBRACKET.
+				 * Ignore and just look for RBRACE
+				 */
+				pe = pm;
+			}
+		}
+		else if (*pe == LBRACE)
+			i++;
+		else if (*pe == RBRACE) {
+			if (i == 0)
+				break;
+			i--;
+		}
+
+	/* Non matching braces; just glob the pattern */
+	if (i != 0 || *pe == EOS)
+		return (glob0(pattern, pglob, limit, NULL));
+
+	for (i = 0, pl = pm = ptr; pm <= pe; pm++)
+		switch (*pm) {
+		case LBRACKET:
+			/* Ignore everything between [] */
+			for (pm1 = pm++; *pm != RBRACKET && *pm != EOS; pm++)
+				continue;
+			if (*pm == EOS) {
+				/*
+				 * We could not find a matching RBRACKET.
+				 * Ignore and just look for RBRACE
+				 */
+				pm = pm1;
+			}
+			break;
+
+		case LBRACE:
+			i++;
+			break;
+
+		case RBRACE:
+			if (i) {
+			    i--;
+			    break;
+			}
+			/* FALLTHROUGH */
+		case COMMA:
+			if (i && *pm == COMMA)
+				break;
+			else {
+				/* Append the current string */
+				for (lm = ls; (pl < pm); *lm++ = *pl++)
+					continue;
+				/*
+				 * Append the rest of the pattern after the
+				 * closing brace
+				 */
+				for (pl = pe + 1; (*lm++ = *pl++) != EOS;)
+					continue;
+
+				/* Expand the current pattern */
+#ifdef DEBUG
+				qprintf("globexp2:", patbuf);
+#endif
+				rv = globexp1(patbuf, pglob, limit);
+				if (rv)
+					return (rv);
+
+				/* move after the comma, to the next string */
+				pl = pm + 1;
+			}
+			break;
+
+		default:
+			break;
+		}
+	return (0);
+}
+
+
+
+/*
+ * expand tilde from the passwd file.
+ */
+static const Char *
+globtilde(const Char *pattern, Char *patbuf, size_t patbuf_len, glob_t *pglob)
+{
+	struct passwd *pwd;
+	char *h, *sc;
+	const Char *p;
+	Char *b, *eb;
+	wchar_t wc;
+	wchar_t wbuf[MAXPATHLEN];
+	wchar_t *wbufend, *dc;
+	size_t clen;
+	mbstate_t mbs;
+	int too_long;
+
+	if (*pattern != TILDE || !(pglob->gl_flags & GLOB_TILDE))
+		return (pattern);
+
+	/* 
+	 * Copy up to the end of the string or / 
+	 */
+	eb = &patbuf[patbuf_len - 1];
+	for (p = pattern + 1, b = patbuf;
+	    b < eb && *p != EOS && UNPROT(*p) != SEP; *b++ = *p++)
+		continue;
+
+	if (*p != EOS && UNPROT(*p) != SEP)
+		return (NULL);
+
+	*b = EOS;
+	h = NULL;
+
+	if (patbuf[0] == EOS) {
+		/*
+		 * handle a plain ~ or ~/ by expanding $HOME first (iff
+		 * we're not running setuid or setgid) and then trying
+		 * the password file
+		 */
+		if (issetugid() != 0 ||
+		    (h = getenv("HOME")) == NULL) {
+			if (((h = getlogin()) != NULL &&
+			     (pwd = getpwnam(h)) != NULL) ||
+			    (pwd = getpwuid(getuid())) != NULL)
+				h = pwd->pw_dir;
+			else
+				return (pattern);
+		}
+	}
+	else {
+		/*
+		 * Expand a ~user
+		 */
+		if (g_Ctoc(patbuf, (char *)wbuf, sizeof(wbuf)))
+			return (NULL);
+		if ((pwd = getpwnam((char *)wbuf)) == NULL)
+			return (pattern);
+		else
+			h = pwd->pw_dir;
+	}
+
+	/* Copy the home directory */
+	dc = wbuf;
+	sc = h;
+	wbufend = wbuf + MAXPATHLEN - 1;
+	too_long = 1;
+	memset(&mbs, 0, sizeof(mbs));
+	while (dc <= wbufend) {
+		clen = mbrtowc(&wc, sc, MB_LEN_MAX, &mbs);
+		if (clen == (size_t)-1 || clen == (size_t)-2) {
+			/* XXX See initial comment #2. */
+			wc = (unsigned char)*sc;
+			clen = 1;
+			memset(&mbs, 0, sizeof(mbs));
+		}
+		if ((*dc++ = wc) == EOS) {
+			too_long = 0;
+			break;
+		}
+		sc += clen;
+	}
+	if (too_long)
+		return (NULL);
+
+	dc = wbuf;
+	for (b = patbuf; b < eb && *dc != EOS; *b++ = *dc++ | M_PROTECT)
+		continue;
+	if (*dc != EOS)
+		return (NULL);
+
+	/* Append the rest of the pattern */
+	if (*p != EOS) {
+		too_long = 1;
+		while (b <= eb) {
+			if ((*b++ = *p++) == EOS) {
+				too_long = 0;
+				break;
+			}
+		}
+		if (too_long)
+			return (NULL);
+	} else
+		*b = EOS;
+
+	return (patbuf);
+}
+
+
+/*
+ * The main glob() routine: compiles the pattern (optionally processing
+ * quotes), calls glob1() to do the real pattern matching, and finally
+ * sorts the list (unless unsorted operation is requested).  Returns 0
+ * if things went well, nonzero if errors occurred.
+ */
+static int
+glob0(const Char *pattern, glob_t *pglob, struct glob_limit *limit,
+    const char *origpat) {
+	const Char *qpatnext;
+	int err;
+	size_t oldpathc;
+	Char *bufnext, c, patbuf[MAXPATHLEN];
+
+	qpatnext = globtilde(pattern, patbuf, MAXPATHLEN, pglob);
+	if (qpatnext == NULL) {
+		errno = E2BIG;
+		return (GLOB_NOSPACE);
+	}
+	oldpathc = pglob->gl_pathc;
+	bufnext = patbuf;
+
+	/* We don't need to check for buffer overflow any more. */
+	while ((c = *qpatnext++) != EOS) {
+		switch (c) {
+		case LBRACKET:
+			c = *qpatnext;
+			if (c == NOT)
+				++qpatnext;
+			if (*qpatnext == EOS ||
+			    g_strchr(qpatnext+1, RBRACKET) == NULL) {
+				*bufnext++ = LBRACKET;
+				if (c == NOT)
+					--qpatnext;
+				break;
+			}
+			*bufnext++ = M_SET;
+			if (c == NOT)
+				*bufnext++ = M_NOT;
+			c = *qpatnext++;
+			do {
+				*bufnext++ = CHAR(c);
+				if (*qpatnext == RANGE &&
+				    (c = qpatnext[1]) != RBRACKET) {
+					*bufnext++ = M_RNG;
+					*bufnext++ = CHAR(c);
+					qpatnext += 2;
+				}
+			} while ((c = *qpatnext++) != RBRACKET);
+			pglob->gl_flags |= GLOB_MAGCHAR;
+			*bufnext++ = M_END;
+			break;
+		case QUESTION:
+			pglob->gl_flags |= GLOB_MAGCHAR;
+			*bufnext++ = M_ONE;
+			break;
+		case STAR:
+			pglob->gl_flags |= GLOB_MAGCHAR;
+			/* collapse adjacent stars to one,
+			 * to ensure "**" at the end continues to match the
+			 * empty string
+			 */
+			if (bufnext == patbuf || bufnext[-1] != M_ALL)
+			    *bufnext++ = M_ALL;
+			break;
+		default:
+			*bufnext++ = CHAR(c);
+			break;
+		}
+	}
+	*bufnext = EOS;
+#ifdef DEBUG
+	qprintf("glob0:", patbuf);
+#endif
+
+	if ((err = glob1(patbuf, pglob, limit)) != 0)
+		return(err);
+
+	if (origpat != NULL)
+		return (globfinal(pglob, limit, oldpathc, origpat));
+
+	return (0);
+}
+
+static int
+globfinal(glob_t *pglob, struct glob_limit *limit, size_t oldpathc,
+    const char *origpat) {
+	if (pglob->gl_pathc == oldpathc)
+		return (err_nomatch(pglob, limit, origpat));
+
+	if (!(pglob->gl_flags & GLOB_NOSORT))
+		qsort(pglob->gl_pathv + pglob->gl_offs + oldpathc,
+		    pglob->gl_pathc - oldpathc, sizeof(char *), compare);
+
+	return (0);
+}
+
+static int
+compare(const void *p, const void *q)
+{
+	return (strcoll(*(char **)p, *(char **)q));
+}
+
+static int
+glob1(Char *pattern, glob_t *pglob, struct glob_limit *limit)
+{
+	Char pathbuf[MAXPATHLEN];
+
+	/* A null pathname is invalid -- POSIX 1003.1 sect. 2.4. */
+	if (*pattern == EOS)
+		return (0);
+	return (glob2(pathbuf, pathbuf, pathbuf + MAXPATHLEN - 1,
+	    pattern, pglob, limit));
+}
+
+/*
+ * The functions glob2 and glob3 are mutually recursive; there is one level
+ * of recursion for each segment in the pattern that contains one or more
+ * meta characters.
+ */
+static int
+glob2(Char *pathbuf, Char *pathend, Char *pathend_last, Char *pattern,
+      glob_t *pglob, struct glob_limit *limit)
+{
+	struct stat sb;
+	Char *p, *q;
+	int anymeta;
+
+	/*
+	 * Loop over pattern segments until end of pattern or until
+	 * segment with meta character found.
+	 */
+	for (anymeta = 0;;) {
+		if (*pattern == EOS) {		/* End of pattern? */
+			*pathend = EOS;
+			if (g_lstat(pathbuf, &sb, pglob))
+				return (0);
+
+			if ((pglob->gl_flags & GLOB_LIMIT) &&
+			    limit->l_stat_cnt++ >= GLOB_LIMIT_STAT) {
+				errno = E2BIG;
+				return (GLOB_NOSPACE);
+			}
+			if ((pglob->gl_flags & GLOB_MARK) &&
+			    UNPROT(pathend[-1]) != SEP &&
+			    (S_ISDIR(sb.st_mode) ||
+			    (S_ISLNK(sb.st_mode) &&
+			    g_stat(pathbuf, &sb, pglob) == 0 &&
+			    S_ISDIR(sb.st_mode)))) {
+				if (pathend + 1 > pathend_last) {
+					errno = E2BIG;
+					return (GLOB_NOSPACE);
+				}
+				*pathend++ = SEP;
+				*pathend = EOS;
+			}
+			++pglob->gl_matchc;
+			return (globextend(pathbuf, pglob, limit, NULL));
+		}
+
+		/* Find end of next segment, copy tentatively to pathend. */
+		q = pathend;
+		p = pattern;
+		while (*p != EOS && UNPROT(*p) != SEP) {
+			if (ismeta(*p))
+				anymeta = 1;
+			if (q + 1 > pathend_last) {
+				errno = E2BIG;
+				return (GLOB_NOSPACE);
+			}
+			*q++ = *p++;
+		}
+
+		if (!anymeta) {		/* No expansion, do next segment. */
+			pathend = q;
+			pattern = p;
+			while (UNPROT(*pattern) == SEP) {
+				if (pathend + 1 > pathend_last) {
+					errno = E2BIG;
+					return (GLOB_NOSPACE);
+				}
+				*pathend++ = *pattern++;
+			}
+		} else			/* Need expansion, recurse. */
+			return (glob3(pathbuf, pathend, pathend_last, pattern,
+			    p, pglob, limit));
+	}
+	/* NOTREACHED */
+}
+
+static int
+glob3(Char *pathbuf, Char *pathend, Char *pathend_last,
+      Char *pattern, Char *restpattern,
+      glob_t *pglob, struct glob_limit *limit)
+{
+	struct dirent *dp;
+	DIR *dirp;
+	int err, too_long, saverrno, saverrno2;
+	char buf[MAXPATHLEN + MB_LEN_MAX - 1];
+
+	struct dirent *(*readdirfunc)(DIR *);
+
+	if (pathend > pathend_last) {
+		errno = E2BIG;
+		return (GLOB_NOSPACE);
+	}
+	*pathend = EOS;
+	if (pglob->gl_errfunc != NULL &&
+	    g_Ctoc(pathbuf, buf, sizeof(buf))) {
+		errno = E2BIG;
+		return (GLOB_NOSPACE);
+	}
+
+	saverrno = errno;
+	errno = 0;
+	if ((dirp = g_opendir(pathbuf, pglob)) == NULL) {
+		if (errno == ENOENT || errno == ENOTDIR)
+			return (0);
+		err = err_aborted(pglob, errno, buf);
+		if (errno == 0)
+			errno = saverrno;
+		return (err);
+	}
+
+	err = 0;
+
+	/* pglob->gl_readdir takes a void *, fix this manually */
+	if (pglob->gl_flags & GLOB_ALTDIRFUNC)
+		readdirfunc = (struct dirent *(*)(DIR *))pglob->gl_readdir;
+	else
+		readdirfunc = readdir;
+
+	errno = 0;
+	/* Search directory for matching names. */
+	while ((dp = (*readdirfunc)(dirp)) != NULL) {
+		char *sc;
+		Char *dc;
+		wchar_t wc;
+		size_t clen;
+		mbstate_t mbs;
+
+		if ((pglob->gl_flags & GLOB_LIMIT) &&
+		    limit->l_readdir_cnt++ >= GLOB_LIMIT_READDIR) {
+			errno = E2BIG;
+			err = GLOB_NOSPACE;
+			break;
+		}
+
+		/* Initial DOT must be matched literally. */
+		if (dp->d_name[0] == '.' && UNPROT(*pattern) != DOT) {
+			errno = 0;
+			continue;
+		}
+		memset(&mbs, 0, sizeof(mbs));
+		dc = pathend;
+		sc = dp->d_name;
+		too_long = 1;
+		while (dc <= pathend_last) {
+			clen = mbrtowc(&wc, sc, MB_LEN_MAX, &mbs);
+			if (clen == (size_t)-1 || clen == (size_t)-2) {
+				/* XXX See initial comment #2. */
+				wc = (unsigned char)*sc;
+				clen = 1;
+				memset(&mbs, 0, sizeof(mbs));
+			}
+			if ((*dc++ = wc) == EOS) {
+				too_long = 0;
+				break;
+			}
+			sc += clen;
+		}
+		if (too_long && (err = err_aborted(pglob, ENAMETOOLONG,
+		    buf))) {
+			errno = ENAMETOOLONG;
+			break;
+		}
+		if (too_long || !match(pathend, pattern, restpattern)) {
+			*pathend = EOS;
+			errno = 0;
+			continue;
+		}
+		if (errno == 0)
+			errno = saverrno;
+		err = glob2(pathbuf, --dc, pathend_last, restpattern,
+		    pglob, limit);
+		if (err)
+			break;
+		errno = 0;
+	}
+
+	saverrno2 = errno;
+	if (pglob->gl_flags & GLOB_ALTDIRFUNC)
+		(*pglob->gl_closedir)(dirp);
+	else
+		closedir(dirp);
+	errno = saverrno2;
+
+	if (err)
+		return (err);
+
+	if (dp == NULL && errno != 0 &&
+	    (err = err_aborted(pglob, errno, buf)))
+		return (err);
+
+	if (errno == 0)
+		errno = saverrno;
+	return (0);
+}
+
+
+/*
+ * Extend the gl_pathv member of a glob_t structure to accommodate a new item,
+ * add the new item, and update gl_pathc.
+ *
+ * This assumes the BSD realloc, which only copies the block when its size
+ * crosses a power-of-two boundary; for v7 realloc, this would cause quadratic
+ * behavior.
+ *
+ * Return 0 if new item added, error code if memory couldn't be allocated.
+ *
+ * Invariant of the glob_t structure:
+ *	Either gl_pathc is zero and gl_pathv is NULL; or gl_pathc > 0 and
+ *	gl_pathv points to (gl_offs + gl_pathc + 1) items.
+ */
+static int
+globextend(const Char *path, glob_t *pglob, struct glob_limit *limit,
+    const char *origpat)
+{
+	char **pathv;
+	size_t i, newn, len;
+	char *copy;
+	const Char *p;
+
+	if ((pglob->gl_flags & GLOB_LIMIT) &&
+	    pglob->gl_matchc > limit->l_path_lim) {
+		errno = E2BIG;
+		return (GLOB_NOSPACE);
+	}
+
+	newn = 2 + pglob->gl_pathc + pglob->gl_offs;
+	/* reallocarray(NULL, newn, size) is equivalent to malloc(newn*size). */
+	pathv = reallocarray(pglob->gl_pathv, newn, sizeof(*pathv));
+	if (pathv == NULL)
+		return (GLOB_NOSPACE);
+
+	if (pglob->gl_pathv == NULL && pglob->gl_offs > 0) {
+		/* first time around -- clear initial gl_offs items */
+		pathv += pglob->gl_offs;
+		for (i = pglob->gl_offs + 1; --i > 0; )
+			*--pathv = NULL;
+	}
+	pglob->gl_pathv = pathv;
+
+	if (origpat != NULL)
+		copy = strdup(origpat);
+	else {
+		for (p = path; *p++ != EOS;)
+			continue;
+		len = MB_CUR_MAX * (size_t)(p - path); /* XXX overallocation */
+		if ((copy = malloc(len)) != NULL) {
+			if (g_Ctoc(path, copy, len)) {
+				free(copy);
+				errno = E2BIG;
+				return (GLOB_NOSPACE);
+			}
+		}
+	}
+	if (copy != NULL) {
+		limit->l_string_cnt += strlen(copy) + 1;
+		if ((pglob->gl_flags & GLOB_LIMIT) &&
+		    limit->l_string_cnt >= GLOB_LIMIT_STRING) {
+			free(copy);
+			errno = E2BIG;
+			return (GLOB_NOSPACE);
+		}
+		pathv[pglob->gl_offs + pglob->gl_pathc++] = copy;
+	}
+	pathv[pglob->gl_offs + pglob->gl_pathc] = NULL;
+	return (copy == NULL ? GLOB_NOSPACE : 0);
+}
+
+/*
+ * pattern matching function for filenames.
+ */
+static int
+match(Char *name, Char *pat, Char *patend)
+{
+	int ok, negate_range;
+	Char c, k, *nextp, *nextn;
+#if !defined(__BIONIC__)
+	struct xlocale_collate *table =
+		(struct xlocale_collate*)__get_locale()->components[XLC_COLLATE];
+#endif
+
+	nextn = NULL;
+	nextp = NULL;
+
+	while (1) {
+		while (pat < patend) {
+			c = *pat++;
+			switch (c & M_MASK) {
+			case M_ALL:
+				if (pat == patend)
+					return (1);
+				if (*name == EOS)
+					return (0);
+				nextn = name + 1;
+				nextp = pat - 1;
+				break;
+			case M_ONE:
+				if (*name++ == EOS)
+					goto fail;
+				break;
+			case M_SET:
+				ok = 0;
+				if ((k = *name++) == EOS)
+					goto fail;
+				negate_range = ((*pat & M_MASK) == M_NOT);
+				if (negate_range != 0)
+					++pat;
+				while (((c = *pat++) & M_MASK) != M_END)
+					if ((*pat & M_MASK) == M_RNG) {
+#if defined(__BIONIC__)
+						if (c <= k && k <= pat[1])
+#else
+						if (table->__collate_load_error ?
+						    CHAR(c) <= CHAR(k) &&
+						    CHAR(k) <= CHAR(pat[1]) :
+						    __wcollate_range_cmp(CHAR(c),
+						    CHAR(k)) <= 0 &&
+						    __wcollate_range_cmp(CHAR(k),
+						    CHAR(pat[1])) <= 0)
+#endif
+							ok = 1;
+						pat += 2;
+					} else if (c == k)
+						ok = 1;
+				if (ok == negate_range)
+					goto fail;
+				break;
+			default:
+				if (*name++ != c)
+					goto fail;
+				break;
+			}
+		}
+		if (*name == EOS)
+			return (1);
+
+	fail:
+		if (nextn == NULL)
+			break;
+		pat = nextp;
+		name = nextn;
+	}
+	return (0);
+}
+
+/* Free allocated data belonging to a glob_t structure. */
+void
+globfree(glob_t *pglob)
+{
+	size_t i;
+	char **pp;
+
+	if (pglob->gl_pathv != NULL) {
+		pp = pglob->gl_pathv + pglob->gl_offs;
+		for (i = pglob->gl_pathc; i--; ++pp)
+			if (*pp)
+				free(*pp);
+		free(pglob->gl_pathv);
+		pglob->gl_pathv = NULL;
+	}
+}
+
+static DIR *
+g_opendir(Char *str, glob_t *pglob)
+{
+	char buf[MAXPATHLEN + MB_LEN_MAX - 1];
+
+	if (*str == EOS)
+		strcpy(buf, ".");
+	else {
+		if (g_Ctoc(str, buf, sizeof(buf))) {
+			errno = ENAMETOOLONG;
+			return (NULL);
+		}
+	}
+
+	if (pglob->gl_flags & GLOB_ALTDIRFUNC)
+		return ((*pglob->gl_opendir)(buf));
+
+	return (opendir(buf));
+}
+
+static int
+g_lstat(Char *fn, struct stat *sb, glob_t *pglob)
+{
+	char buf[MAXPATHLEN + MB_LEN_MAX - 1];
+
+	if (g_Ctoc(fn, buf, sizeof(buf))) {
+		errno = ENAMETOOLONG;
+		return (-1);
+	}
+	if (pglob->gl_flags & GLOB_ALTDIRFUNC)
+		return((*pglob->gl_lstat)(buf, sb));
+	return (lstat(buf, sb));
+}
+
+static int
+g_stat(Char *fn, struct stat *sb, glob_t *pglob)
+{
+	char buf[MAXPATHLEN + MB_LEN_MAX - 1];
+
+	if (g_Ctoc(fn, buf, sizeof(buf))) {
+		errno = ENAMETOOLONG;
+		return (-1);
+	}
+	if (pglob->gl_flags & GLOB_ALTDIRFUNC)
+		return ((*pglob->gl_stat)(buf, sb));
+	return (stat(buf, sb));
+}
+
+static const Char *
+g_strchr(const Char *str, wchar_t ch)
+{
+
+	do {
+		if (*str == ch)
+			return (str);
+	} while (*str++);
+	return (NULL);
+}
+
+static int
+g_Ctoc(const Char *str, char *buf, size_t len)
+{
+	mbstate_t mbs;
+	size_t clen;
+
+	memset(&mbs, 0, sizeof(mbs));
+	while (len >= MB_CUR_MAX) {
+		clen = wcrtomb(buf, CHAR(*str), &mbs);
+		if (clen == (size_t)-1) {
+			/* XXX See initial comment #2. */
+			*buf = (char)CHAR(*str);
+			clen = 1;
+			memset(&mbs, 0, sizeof(mbs));
+		}
+		if (CHAR(*str) == EOS)
+			return (0);
+		str++;
+		buf += clen;
+		len -= clen;
+	}
+	return (1);
+}
+
+static int
+err_nomatch(glob_t *pglob, struct glob_limit *limit, const char *origpat) {
+	/*
+	 * If there was no match we are going to append the origpat
+	 * if GLOB_NOCHECK was specified or if GLOB_NOMAGIC was specified
+	 * and the origpat did not contain any magic characters
+	 * GLOB_NOMAGIC is there just for compatibility with csh.
+	 */
+	if ((pglob->gl_flags & GLOB_NOCHECK) ||
+	    ((pglob->gl_flags & GLOB_NOMAGIC) &&
+	    !(pglob->gl_flags & GLOB_MAGCHAR)))
+		return (globextend(NULL, pglob, limit, origpat));
+	return (GLOB_NOMATCH);
+}
+
+static int
+err_aborted(glob_t *pglob, int err, char *buf) {
+	if ((pglob->gl_errfunc != NULL && pglob->gl_errfunc(buf, err)) ||
+	    (pglob->gl_flags & GLOB_ERR))
+		return (GLOB_ABORTED);
+	return (0);
+}
+
+#ifdef DEBUG
+static void
+qprintf(const char *str, Char *s)
+{
+	Char *p;
+
+	(void)printf("%s\n", str);
+	if (s != NULL) {
+		for (p = s; *p != EOS; p++)
+			(void)printf("%c", (char)CHAR(*p));
+		(void)printf("\n");
+		for (p = s; *p != EOS; p++)
+			(void)printf("%c", (isprot(*p) ? '\\' : ' '));
+		(void)printf("\n");
+		for (p = s; *p != EOS; p++)
+			(void)printf("%c", (ismeta(*p) ? '_' : ' '));
+		(void)printf("\n");
+	}
+}
+#endif
diff --git a/libc/upstream-openbsd/android/include/openbsd-compat.h b/libc/upstream-openbsd/android/include/openbsd-compat.h
index d831435..f178149 100644
--- a/libc/upstream-openbsd/android/include/openbsd-compat.h
+++ b/libc/upstream-openbsd/android/include/openbsd-compat.h
@@ -18,10 +18,15 @@
 #define _BIONIC_OPENBSD_COMPAT_H_included
 
 #define _BSD_SOURCE
-
 #include <sys/cdefs.h>
+
 #include <stddef.h> // For size_t.
 
+// TODO: libandroid_support uses this file, so we need to wait for
+// <sys/random.h> to be in the NDK headers before we can lose this declaration.
+//#include <sys/random.h> // For getentropy.
+int getentropy(void*, size_t);
+
 #define __BEGIN_HIDDEN_DECLS _Pragma("GCC visibility push(hidden)")
 #define __END_HIDDEN_DECLS _Pragma("GCC visibility pop")
 
@@ -75,9 +80,6 @@
 __LIBC_HIDDEN__ extern const char* __bionic_get_shell_path();
 #define _PATH_BSHELL __bionic_get_shell_path()
 
-/* We have OpenBSD's getentropy_linux.c, but we don't mention getentropy in any header. */
-__LIBC_HIDDEN__ extern int getentropy(void*, size_t);
-
 /* OpenBSD has this as API, but we just use it internally. */
 __LIBC_HIDDEN__ void* reallocarray(void*, size_t, size_t);
 
diff --git a/libdl/Android.bp b/libdl/Android.bp
index 9f67ee8..b0bbe99 100644
--- a/libdl/Android.bp
+++ b/libdl/Android.bp
@@ -1,6 +1,28 @@
 //
 // libdl
 //
+cc_library_static {
+    name: "libdl_static",
+
+    srcs: ["libdl.c", "libdl_cfi.cpp"],
+
+    cflags: [
+        "-Wall",
+        "-Wextra",
+        "-Wunused",
+        "-Werror",
+    ],
+
+    // For private/CFIShadow.h.
+    include_dirs: ["bionic/libc"],
+
+    stl: "none",
+
+    sanitize: {
+        never: true,
+    },
+}
+
 cc_library {
     name: "libdl",
 
@@ -45,7 +67,7 @@
         },
     },
     shared: {
-        srcs: ["libdl.c", "libdl_cfi.cpp"],
+        whole_static_libs: ["libdl_static"],
     },
     static: {
         srcs: [ "libdl_static.c" ],
@@ -66,9 +88,6 @@
     allow_undefined_symbols: true,
     system_shared_libs: [],
 
-    // For private/CFIShadow.h.
-    include_dirs: ["bionic/libc"],
-
     // This is placeholder library the actual implementation is (currently)
     // provided by the linker.
     shared_libs: [ "ld-android" ],
diff --git a/libdl/libdl.arm.map b/libdl/libdl.arm.map
index 9fc9d23..1fcfc58 100644
--- a/libdl/libdl.arm.map
+++ b/libdl/libdl.arm.map
@@ -34,11 +34,11 @@
     dlvsym; # introduced=24
 } LIBC;
 
-LIBC_OMR1 { # future
+LIBC_OMR1 { # introduced=27
   global:
-    __cfi_shadow_size; # future
-    __cfi_slowpath; # future
-    __cfi_slowpath_diag; # future
+    __cfi_shadow_size;
+    __cfi_slowpath;
+    __cfi_slowpath_diag;
 } LIBC_N;
 
 LIBC_PLATFORM {
diff --git a/libdl/libdl.arm64.map b/libdl/libdl.arm64.map
index bde6cab..8d4019c 100644
--- a/libdl/libdl.arm64.map
+++ b/libdl/libdl.arm64.map
@@ -33,11 +33,11 @@
     dlvsym; # introduced=24
 } LIBC;
 
-LIBC_OMR1 { # future
+LIBC_OMR1 { # introduced=27
   global:
-    __cfi_shadow_size; # future
-    __cfi_slowpath; # future
-    __cfi_slowpath_diag; # future
+    __cfi_shadow_size;
+    __cfi_slowpath;
+    __cfi_slowpath_diag;
 } LIBC_N;
 
 LIBC_PLATFORM {
diff --git a/libdl/libdl.c b/libdl/libdl.c
index 1a65b67..b747c22 100644
--- a/libdl/libdl.c
+++ b/libdl/libdl.c
@@ -98,34 +98,41 @@
 struct android_namespace_t* __loader_android_get_exported_namespace(const char* name);
 
 // Proxy calls to bionic loader
+__attribute__((__weak__))
 void* dlopen(const char* filename, int flag) {
   const void* caller_addr = __builtin_return_address(0);
   return __loader_dlopen(filename, flag, caller_addr);
 }
 
+__attribute__((__weak__))
 char* dlerror() {
   return __loader_dlerror();
 }
 
+__attribute__((__weak__))
 void* dlsym(void* handle, const char* symbol) {
   const void* caller_addr = __builtin_return_address(0);
   return __loader_dlsym(handle, symbol, caller_addr);
 }
 
+__attribute__((__weak__))
 void* dlvsym(void* handle, const char* symbol, const char* version) {
   const void* caller_addr = __builtin_return_address(0);
   return __loader_dlvsym(handle, symbol, version, caller_addr);
 }
 
+__attribute__((__weak__))
 int dladdr(const void* addr, Dl_info* info) {
   return __loader_dladdr(addr, info);
 }
 
+__attribute__((__weak__))
 int dlclose(void* handle) {
   return __loader_dlclose(handle);
 }
 
 #if defined(__arm__)
+__attribute__((__weak__))
 _Unwind_Ptr dl_unwind_find_exidx(_Unwind_Ptr pc, int* pcount) {
   return __loader_dl_unwind_find_exidx(pc, pcount);
 }
@@ -140,31 +147,39 @@
   return __loader_dl_iterate_phdr(cb, data);
 }
 
+__attribute__((__weak__))
 void android_get_LD_LIBRARY_PATH(char* buffer, size_t buffer_size) {
   __loader_android_get_LD_LIBRARY_PATH(buffer, buffer_size);
 }
 
+__attribute__((__weak__))
 void android_update_LD_LIBRARY_PATH(const char* ld_library_path) {
   __loader_android_update_LD_LIBRARY_PATH(ld_library_path);
 }
 
+__attribute__((__weak__))
 void* android_dlopen_ext(const char* filename, int flag, const android_dlextinfo* extinfo) {
   const void* caller_addr = __builtin_return_address(0);
   return __loader_android_dlopen_ext(filename, flag, extinfo, caller_addr);
 }
 
+__attribute__((__weak__))
 void android_set_application_target_sdk_version(uint32_t target) {
   __loader_android_set_application_target_sdk_version(target);
 }
+
+__attribute__((__weak__))
 uint32_t android_get_application_target_sdk_version() {
   return __loader_android_get_application_target_sdk_version();
 }
 
+__attribute__((__weak__))
 bool android_init_anonymous_namespace(const char* shared_libs_sonames,
                                       const char* library_search_path) {
   return __loader_android_init_anonymous_namespace(shared_libs_sonames, library_search_path);
 }
 
+__attribute__((__weak__))
 struct android_namespace_t* android_create_namespace(const char* name,
                                                      const char* ld_library_path,
                                                      const char* default_library_path,
@@ -181,16 +196,19 @@
                                            caller_addr);
 }
 
+__attribute__((__weak__))
 bool android_link_namespaces(struct android_namespace_t* namespace_from,
                              struct android_namespace_t* namespace_to,
                              const char* shared_libs_sonames) {
   return __loader_android_link_namespaces(namespace_from, namespace_to, shared_libs_sonames);
 }
 
+__attribute__((__weak__))
 void android_dlwarning(void* obj, void (*f)(void*, const char*)) {
   __loader_android_dlwarning(obj, f);
 }
 
+__attribute__((__weak__))
 struct android_namespace_t* android_get_exported_namespace(const char* name) {
   return __loader_android_get_exported_namespace(name);
 }
diff --git a/libdl/libdl.map.txt b/libdl/libdl.map.txt
index d1f4ab8..002e9f8 100644
--- a/libdl/libdl.map.txt
+++ b/libdl/libdl.map.txt
@@ -33,11 +33,11 @@
     dlvsym; # introduced=24
 } LIBC;
 
-LIBC_OMR1 { # future
+LIBC_OMR1 { # introduced=27
   global:
-    __cfi_shadow_size; # future
-    __cfi_slowpath; # future
-    __cfi_slowpath_diag; # future
+    __cfi_shadow_size;
+    __cfi_slowpath;
+    __cfi_slowpath_diag;
 } LIBC_N;
 
 LIBC_PLATFORM {
diff --git a/libdl/libdl.mips.map b/libdl/libdl.mips.map
index bde6cab..8d4019c 100644
--- a/libdl/libdl.mips.map
+++ b/libdl/libdl.mips.map
@@ -33,11 +33,11 @@
     dlvsym; # introduced=24
 } LIBC;
 
-LIBC_OMR1 { # future
+LIBC_OMR1 { # introduced=27
   global:
-    __cfi_shadow_size; # future
-    __cfi_slowpath; # future
-    __cfi_slowpath_diag; # future
+    __cfi_shadow_size;
+    __cfi_slowpath;
+    __cfi_slowpath_diag;
 } LIBC_N;
 
 LIBC_PLATFORM {
diff --git a/libdl/libdl.mips64.map b/libdl/libdl.mips64.map
index bde6cab..8d4019c 100644
--- a/libdl/libdl.mips64.map
+++ b/libdl/libdl.mips64.map
@@ -33,11 +33,11 @@
     dlvsym; # introduced=24
 } LIBC;
 
-LIBC_OMR1 { # future
+LIBC_OMR1 { # introduced=27
   global:
-    __cfi_shadow_size; # future
-    __cfi_slowpath; # future
-    __cfi_slowpath_diag; # future
+    __cfi_shadow_size;
+    __cfi_slowpath;
+    __cfi_slowpath_diag;
 } LIBC_N;
 
 LIBC_PLATFORM {
diff --git a/libdl/libdl.x86.map b/libdl/libdl.x86.map
index bde6cab..8d4019c 100644
--- a/libdl/libdl.x86.map
+++ b/libdl/libdl.x86.map
@@ -33,11 +33,11 @@
     dlvsym; # introduced=24
 } LIBC;
 
-LIBC_OMR1 { # future
+LIBC_OMR1 { # introduced=27
   global:
-    __cfi_shadow_size; # future
-    __cfi_slowpath; # future
-    __cfi_slowpath_diag; # future
+    __cfi_shadow_size;
+    __cfi_slowpath;
+    __cfi_slowpath_diag;
 } LIBC_N;
 
 LIBC_PLATFORM {
diff --git a/libdl/libdl.x86_64.map b/libdl/libdl.x86_64.map
index bde6cab..8d4019c 100644
--- a/libdl/libdl.x86_64.map
+++ b/libdl/libdl.x86_64.map
@@ -33,11 +33,11 @@
     dlvsym; # introduced=24
 } LIBC;
 
-LIBC_OMR1 { # future
+LIBC_OMR1 { # introduced=27
   global:
-    __cfi_shadow_size; # future
-    __cfi_slowpath; # future
-    __cfi_slowpath_diag; # future
+    __cfi_shadow_size;
+    __cfi_slowpath;
+    __cfi_slowpath_diag;
 } LIBC_N;
 
 LIBC_PLATFORM {
diff --git a/libm/libm.arm.map b/libm/libm.arm.map
index 7e3175d..bee08d4 100644
--- a/libm/libm.arm.map
+++ b/libm/libm.arm.map
@@ -272,7 +272,7 @@
     *;
 };
 
-LIBC_O {
+LIBC_O { # introduced=O
   global:
     cacoshl;
     cacosl;
diff --git a/libm/libm.arm64.map b/libm/libm.arm64.map
index 3e259dd..550c39b 100644
--- a/libm/libm.arm64.map
+++ b/libm/libm.arm64.map
@@ -272,7 +272,7 @@
     *;
 };
 
-LIBC_O {
+LIBC_O { # introduced=O
   global:
     cacoshl;
     cacosl;
diff --git a/libm/libm.mips.map b/libm/libm.mips.map
index b368d41..0b6dc02 100644
--- a/libm/libm.mips.map
+++ b/libm/libm.mips.map
@@ -272,7 +272,7 @@
     *;
 };
 
-LIBC_O {
+LIBC_O { # introduced=O
   global:
     cacoshl;
     cacosl;
diff --git a/libm/libm.mips64.map b/libm/libm.mips64.map
index 3e259dd..550c39b 100644
--- a/libm/libm.mips64.map
+++ b/libm/libm.mips64.map
@@ -272,7 +272,7 @@
     *;
 };
 
-LIBC_O {
+LIBC_O { # introduced=O
   global:
     cacoshl;
     cacosl;
diff --git a/libm/libm.x86.map b/libm/libm.x86.map
index 3e259dd..550c39b 100644
--- a/libm/libm.x86.map
+++ b/libm/libm.x86.map
@@ -272,7 +272,7 @@
     *;
 };
 
-LIBC_O {
+LIBC_O { # introduced=O
   global:
     cacoshl;
     cacosl;
diff --git a/libm/libm.x86_64.map b/libm/libm.x86_64.map
index 3e259dd..550c39b 100644
--- a/libm/libm.x86_64.map
+++ b/libm/libm.x86_64.map
@@ -272,7 +272,7 @@
     *;
 };
 
-LIBC_O {
+LIBC_O { # introduced=O
   global:
     cacoshl;
     cacosl;
diff --git a/linker/Android.bp b/linker/Android.bp
index 9125fd6..f802f45 100644
--- a/linker/Android.bp
+++ b/linker/Android.bp
@@ -6,6 +6,7 @@
         "linker_allocator.cpp",
         "linker_memory.cpp",
     ],
+    cflags: ["-Wall", "-Werror"],
 
     // We need to access Bionic private headers in the linker.
     include_dirs: ["bionic/libc"],
@@ -26,7 +27,7 @@
     device_supported: false,
     target: {
         linux_bionic: { enabled: true },
-        linux: { enabled: false },
+        linux_glibc: { enabled: false },
         darwin: { enabled: false },
     },
 
diff --git a/linker/linker_config.cpp b/linker/linker_config.cpp
index f6d5072..e036c05 100644
--- a/linker/linker_config.cpp
+++ b/linker/linker_config.cpp
@@ -375,15 +375,6 @@
                                       bool is_asan,
                                       const Config** config,
                                       std::string* error_msg) {
-  // TODO(b/38114603) Currently, multiple namespaces does not support ASAN mode
-  // where some symbols should be intercepted via LD_PRELOAD; LD_PRELOADed libs
-  // are not being preloaded into the linked namespaces other than the default
-  // namespace. Until we fix the problem, we temporarily disable ld.config.txt
-  // in ASAN mode.
-  if (is_asan) {
-    return false;
-  }
-
   g_config.clear();
 
   std::unordered_map<std::string, PropertyValue> property_map;
diff --git a/linker/linker_main.cpp b/linker/linker_main.cpp
index 3862d8c..4799739 100644
--- a/linker/linker_main.cpp
+++ b/linker/linker_main.cpp
@@ -154,6 +154,10 @@
 
   si->prelink_image();
   si->link_image(g_empty_list, soinfo_list_t::make_list(si), nullptr);
+  // prevents accidental unloads...
+  si->set_dt_flags_1(si->get_dt_flags_1() | DF_1_NODELETE);
+  si->set_linked();
+  si->call_constructors();
 }
 
 /* gdb expects the linker to be in the debug shared object list.
@@ -204,7 +208,17 @@
 #endif
 
 static void __linker_cannot_link(const char* argv0) {
-  async_safe_fatal("CANNOT LINK EXECUTABLE \"%s\": %s", argv0, linker_get_error_buffer());
+  async_safe_format_fd(STDERR_FILENO,
+                       "CANNOT LINK EXECUTABLE \"%s\": %s\n",
+                       argv0,
+                       linker_get_error_buffer());
+
+  async_safe_format_log(ANDROID_LOG_FATAL,
+                        "linker",
+                        "CANNOT LINK EXECUTABLE \"%s\": %s",
+                        argv0,
+                        linker_get_error_buffer());
+  _exit(EXIT_FAILURE);
 }
 
 /*
@@ -352,6 +366,8 @@
     }
   }
 
+  add_vdso(args);
+
   // Load ld_preloads and dependencies.
   std::vector<const char*> needed_library_name_list;
   size_t ld_preloads_count = 0;
@@ -393,8 +409,6 @@
     si->increment_ref_count();
   }
 
-  add_vdso(args);
-
   if (!get_cfi_shadow()->InitialLinkDone(solist)) __linker_cannot_link(g_argv[0]);
 
   si->call_pre_init_constructors();
diff --git a/linker/tests/linker_config_test.cpp b/linker/tests/linker_config_test.cpp
index 87609d0..c6fade9 100644
--- a/linker/tests/linker_config_test.cpp
+++ b/linker/tests/linker_config_test.cpp
@@ -168,7 +168,6 @@
   run_linker_config_smoke_test(false);
 }
 
-// TODO(b/38114603) revive this test when ld.config.txt is enabled for ASAN mode
-//TEST(linker_config, asan_smoke) {
-//  run_linker_config_smoke_test(true);
-//}
+TEST(linker_config, asan_smoke) {
+  run_linker_config_smoke_test(true);
+}
diff --git a/tests/Android.bp b/tests/Android.bp
index 3731156..fb8b886 100644
--- a/tests/Android.bp
+++ b/tests/Android.bp
@@ -71,6 +71,7 @@
         "ftw_test.cpp",
         "getauxval_test.cpp",
         "getcwd_test.cpp",
+        "glob_test.cpp",
         "grp_pwd_test.cpp",
         "iconv_test.cpp",
         "ifaddrs_test.cpp",
@@ -131,6 +132,7 @@
         "sys_procfs_test.cpp",
         "sys_ptrace_test.cpp",
         "sys_quota_test.cpp",
+        "sys_random_test.cpp",
         "sys_resource_test.cpp",
         "sys_select_test.cpp",
         "sys_sem_test.cpp",
@@ -167,7 +169,7 @@
     ],
 
     target: {
-        android: {
+        bionic: {
             whole_static_libs: ["libasync_safe"],
         },
     },
@@ -177,7 +179,6 @@
         "liblog",
         "libbase",
     ],
-    host_ldlibs: ["-lrt"],
     shared: {
         enabled: false,
     },
@@ -327,12 +328,6 @@
             ],
         }
     },
-
-    product_variables: {
-        debuggable: {
-            cppflags: ["-DUSE_LD_CONFIG_FILE"],
-        },
-    },
 }
 
 // -----------------------------------------------------------------------------
@@ -610,8 +605,6 @@
 
     host_ldlibs: [
         "-lresolv",
-        "-lrt",
-        "-ldl",
         "-lutil",
     ],
 
@@ -626,9 +619,9 @@
         never: false,
     },
 
-    product_variables: {
-        debuggable: {
-            cppflags: ["-DUSE_LD_CONFIG_FILE"],
+    target: {
+        linux_bionic: {
+            enabled: false,
         },
     },
 }
diff --git a/tests/dl_test.cpp b/tests/dl_test.cpp
index aaf2c37..2133a2c 100644
--- a/tests/dl_test.cpp
+++ b/tests/dl_test.cpp
@@ -162,7 +162,7 @@
   chmod(helper.c_str(), 0755);
   ExecTestHelper eth;
   eth.SetArgs({ helper.c_str(), nullptr });
-  eth.Run([&]() { execve(helper.c_str(), eth.GetArgs(), eth.GetEnv()); }, -6, error_message.c_str());
+  eth.Run([&]() { execve(helper.c_str(), eth.GetArgs(), eth.GetEnv()); }, EXIT_FAILURE, error_message.c_str());
 #endif
 }
 
@@ -180,12 +180,24 @@
 }
 #endif
 
-#ifdef USE_LD_CONFIG_FILE
+#if defined(__BIONIC__)
+static bool is_user_build() {
+  std::string build_type = android::base::GetProperty("ro.build.type", "user");
+  if (build_type == "userdebug" || build_type == "eng") {
+    return false;
+  }
+  return true;
+}
+#endif
 
 // _lib1.so and _lib2.so are now searchable by having another namespace 'ns2'
 // whose search paths include the 'ns2/' subdir.
 TEST(dl, exec_with_ld_config_file) {
 #if defined(__BIONIC__)
+  if (is_user_build()) {
+    // LD_CONFIG_FILE is not supported on user build
+    return;
+  }
   std::string helper = get_testlib_root() +
       "/ld_config_test_helper/ld_config_test_helper";
   std::string config_file = get_testlib_root() + "/ld.config.txt";
@@ -204,6 +216,10 @@
 // additional namespaces other than the default namespace.
 TEST(dl, exec_with_ld_config_file_with_ld_preload) {
 #if defined(__BIONIC__)
+  if (is_user_build()) {
+    // LD_CONFIG_FILE is not supported on user build
+    return;
+  }
   std::string helper = get_testlib_root() +
       "/ld_config_test_helper/ld_config_test_helper";
   std::string config_file = get_testlib_root() + "/ld.config.txt";
@@ -218,8 +234,6 @@
 #endif
 }
 
-#endif // USE_LD_CONFIG_FILE
-
 // ensures that LD_CONFIG_FILE env var does not work for production builds.
 // The test input is the same as exec_with_ld_config_file, but it must fail in
 // this case.
@@ -230,8 +244,7 @@
     // This test is only for CTS.
     return;
   }
-  std::string build_type = android::base::GetProperty("ro.build.type", "user");
-  if (build_type == "userdebug" || build_type == "eng") {
+  if (!is_user_build()) {
     // Skip the test for non production devices
     return;
   }
diff --git a/tests/dlfcn_test.cpp b/tests/dlfcn_test.cpp
index 1e2b6c9..66ea0f9 100644
--- a/tests/dlfcn_test.cpp
+++ b/tests/dlfcn_test.cpp
@@ -245,6 +245,12 @@
   dlclose(handle);
 }
 
+TEST(dlfcn, dlopen_vdso) {
+  void* handle = dlopen("linux-vdso.so.1", RTLD_NOW);
+  ASSERT_TRUE(handle != nullptr) << dlerror();
+  dlclose(handle);
+}
+
 // mips doesn't support ifuncs
 #if !defined(__mips__)
 TEST(dlfcn, ifunc_variable) {
diff --git a/tests/glob_test.cpp b/tests/glob_test.cpp
new file mode 100644
index 0000000..623a2a3
--- /dev/null
+++ b/tests/glob_test.cpp
@@ -0,0 +1,249 @@
+/*
+ * Copyright (C) 2017 The Android Open Source Project
+ *
+ * Licensed under the Apache License, Version 2.0 (the "License");
+ * you may not use this file except in compliance with the License.
+ * You may obtain a copy of the License at
+ *
+ *      http://www.apache.org/licenses/LICENSE-2.0
+ *
+ * Unless required by applicable law or agreed to in writing, software
+ * distributed under the License is distributed on an "AS IS" BASIS,
+ * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
+ * See the License for the specific language governing permissions and
+ * limitations under the License.
+ */
+
+#include <glob.h>
+
+#include <dirent.h>
+#include <gtest/gtest.h>
+
+#include <string>
+#include <vector>
+
+#include "TemporaryFile.h"
+
+#if defined(__BIONIC__)
+#define ASSERT_MATCH_COUNT(n_,g_) ASSERT_EQ(n_, g_.gl_matchc)
+#else
+#define ASSERT_MATCH_COUNT(n_,g_)
+#endif
+
+//
+// Helper for use with GLOB_ALTDIRFUNC to iterate over the elements of `fake_dir`.
+//
+
+static std::vector<std::string> fake_dir;
+static size_t fake_dir_offset;
+static void fake_closedir(void*) {
+}
+static dirent* fake_readdir(void*) {
+  static dirent d;
+  if (fake_dir_offset >= fake_dir.size()) return nullptr;
+  strcpy(d.d_name, fake_dir[fake_dir_offset++].c_str());
+  return &d;
+}
+static void* fake_opendir(const char* path) {
+  fake_dir_offset = 0;
+  if (strcmp(path, "/opendir-fail/") == 0) {
+    errno = EINVAL;
+    return nullptr;
+  }
+  return &fake_dir;
+}
+static int fake_lstat(const char*, struct stat*) {
+  return 0;
+}
+static int fake_stat(const char*, struct stat*) {
+  return 0;
+}
+static void InstallFake(glob_t* g) {
+  g->gl_closedir = fake_closedir;
+  g->gl_readdir = fake_readdir;
+  g->gl_opendir = fake_opendir;
+  g->gl_lstat = fake_lstat;
+  g->gl_stat = fake_stat;
+}
+
+TEST(glob, glob_result_GLOB_NOMATCH) {
+  glob_t g = {};
+  ASSERT_EQ(GLOB_NOMATCH, glob("/will/match/nothing", 0, nullptr, &g));
+  ASSERT_EQ(0U, g.gl_pathc);
+  ASSERT_MATCH_COUNT(0U, g);
+}
+
+TEST(glob, glob_GLOB_APPEND) {
+  glob_t g = {};
+  ASSERT_EQ(0, glob("/proc/version", 0, nullptr, &g));
+  ASSERT_EQ(1U, g.gl_pathc);
+  ASSERT_MATCH_COUNT(1U, g);
+  ASSERT_STREQ("/proc/version", g.gl_pathv[0]);
+  ASSERT_EQ(nullptr, g.gl_pathv[1]);
+  ASSERT_EQ(0, glob("/proc/version", GLOB_APPEND, nullptr, &g));
+  ASSERT_EQ(2U, g.gl_pathc);
+  ASSERT_MATCH_COUNT(1U, g);
+  ASSERT_STREQ("/proc/version", g.gl_pathv[0]);
+  ASSERT_STREQ("/proc/version", g.gl_pathv[1]);
+  ASSERT_EQ(nullptr, g.gl_pathv[2]);
+  globfree(&g);
+}
+
+TEST(glob, glob_GLOB_DOOFFS) {
+  glob_t g = {};
+  g.gl_offs = 2;
+  ASSERT_EQ(0, glob("/proc/version", GLOB_DOOFFS, nullptr, &g));
+  ASSERT_EQ(1U, g.gl_pathc);
+  ASSERT_MATCH_COUNT(1U, g);
+  ASSERT_EQ(nullptr, g.gl_pathv[0]);
+  ASSERT_EQ(nullptr, g.gl_pathv[1]);
+  ASSERT_STREQ("/proc/version", g.gl_pathv[2]);
+  ASSERT_EQ(nullptr, g.gl_pathv[3]);
+  globfree(&g);
+}
+
+static std::string g_failure_path;
+static int g_failure_errno;
+static int test_error_callback_result;
+static int test_error_callback(const char* failure_path, int failure_errno) {
+  g_failure_path = failure_path;
+  g_failure_errno = failure_errno;
+  return test_error_callback_result;
+}
+
+TEST(glob, glob_gl_errfunc) {
+  glob_t g = {};
+  InstallFake(&g);
+
+  test_error_callback_result = 0;
+  g_failure_errno = 0;
+  ASSERT_EQ(GLOB_NOMATCH, glob("/opendir-fail/x*", GLOB_ALTDIRFUNC, test_error_callback, &g));
+  ASSERT_EQ("/opendir-fail/", g_failure_path);
+  ASSERT_EQ(EINVAL, g_failure_errno);
+
+  test_error_callback_result = 1;
+  g_failure_errno = 0;
+  ASSERT_EQ(GLOB_ABORTED, glob("/opendir-fail/x*", GLOB_ALTDIRFUNC, test_error_callback, &g));
+  ASSERT_EQ("/opendir-fail/", g_failure_path);
+  ASSERT_EQ(EINVAL, g_failure_errno);
+}
+
+TEST(glob, glob_GLOB_ERR) {
+  glob_t g = {};
+  InstallFake(&g);
+
+  ASSERT_EQ(GLOB_NOMATCH, glob("/opendir-fail/x*", GLOB_ALTDIRFUNC, nullptr, &g));
+
+  ASSERT_EQ(GLOB_ABORTED, glob("/opendir-fail/x*", GLOB_ALTDIRFUNC | GLOB_ERR, nullptr, &g));
+}
+
+TEST(glob, glob_GLOB_MARK) {
+  TemporaryDir td;
+  // The pattern we're about to pass doesn't have a trailing '/'...
+  ASSERT_NE('/', std::string(td.dirname).back());
+
+  glob_t g = {};
+  // Using GLOB_MARK gets you a trailing '/' on a directory...
+  ASSERT_EQ(0, glob(td.dirname, GLOB_MARK, nullptr, &g));
+  ASSERT_EQ(1U, g.gl_pathc);
+  ASSERT_MATCH_COUNT(1U, g);
+  ASSERT_EQ(std::string(td.dirname) + "/", g.gl_pathv[0]);
+  ASSERT_EQ(nullptr, g.gl_pathv[1]);
+
+  TemporaryFile tf;
+  // But not on a file...
+  ASSERT_EQ(0, glob(tf.filename, GLOB_MARK, nullptr, &g));
+  ASSERT_EQ(1U, g.gl_pathc);
+  ASSERT_MATCH_COUNT(1U, g);
+  ASSERT_STREQ(tf.filename, g.gl_pathv[0]);
+  ASSERT_EQ(nullptr, g.gl_pathv[1]);
+
+  globfree(&g);
+}
+
+TEST(glob, glob_GLOB_NOCHECK) {
+  glob_t g = {};
+  ASSERT_EQ(0, glob("/will/match/nothing", GLOB_NOCHECK, nullptr, &g));
+  ASSERT_EQ(1U, g.gl_pathc);
+  ASSERT_MATCH_COUNT(0U, g);
+  ASSERT_STREQ("/will/match/nothing", g.gl_pathv[0]);
+  ASSERT_EQ(nullptr, g.gl_pathv[1]);
+  globfree(&g);
+}
+
+TEST(glob, glob_GLOB_NOSORT) {
+  fake_dir = { "c", "a", "d", "b" };
+
+  glob_t g = {};
+  InstallFake(&g);
+
+  ASSERT_EQ(0, glob("*", GLOB_ALTDIRFUNC, nullptr, &g));
+  ASSERT_EQ(4U, g.gl_pathc);
+  ASSERT_MATCH_COUNT(4U, g);
+  ASSERT_STREQ("a", g.gl_pathv[0]);
+  ASSERT_STREQ("b", g.gl_pathv[1]);
+  ASSERT_STREQ("c", g.gl_pathv[2]);
+  ASSERT_STREQ("d", g.gl_pathv[3]);
+  ASSERT_EQ(nullptr, g.gl_pathv[4]);
+
+  ASSERT_EQ(0, glob("*", GLOB_ALTDIRFUNC | GLOB_NOSORT, nullptr, &g));
+  ASSERT_EQ(4U, g.gl_pathc);
+  ASSERT_MATCH_COUNT(4U, g);
+  ASSERT_STREQ("c", g.gl_pathv[0]);
+  ASSERT_STREQ("a", g.gl_pathv[1]);
+  ASSERT_STREQ("d", g.gl_pathv[2]);
+  ASSERT_STREQ("b", g.gl_pathv[3]);
+  ASSERT_EQ(nullptr, g.gl_pathv[4]);
+}
+
+TEST(glob, glob_GLOB_MAGCHAR) {
+  glob_t g = {};
+  ASSERT_EQ(GLOB_NOMATCH, glob("/does-not-exist", 0, nullptr, &g));
+  ASSERT_TRUE((g.gl_flags & GLOB_MAGCHAR) == 0);
+  ASSERT_EQ(GLOB_NOMATCH, glob("/does-not-exist*", 0, nullptr, &g));
+  ASSERT_TRUE((g.gl_flags & GLOB_MAGCHAR) != 0);
+
+  // We can lie, but glob(3) will turn that into truth...
+  ASSERT_EQ(GLOB_NOMATCH, glob("/does-not-exist", GLOB_MAGCHAR, nullptr, &g));
+  ASSERT_TRUE((g.gl_flags & GLOB_MAGCHAR) == 0);
+}
+
+static void CheckGlob(const char* pattern, const std::vector<std::string>& expected_matches) {
+  glob_t g = {};
+  InstallFake(&g);
+
+  int expected_result = expected_matches.empty() ? GLOB_NOMATCH : 0;
+  ASSERT_EQ(expected_result, glob(pattern, GLOB_ALTDIRFUNC, nullptr, &g)) << pattern;
+  ASSERT_EQ(expected_matches.size(), g.gl_pathc);
+  ASSERT_MATCH_COUNT(expected_matches.size(), g);
+  for (size_t i = 0; i < expected_matches.size(); ++i) {
+    ASSERT_EQ(expected_matches[i], g.gl_pathv[i]);
+  }
+  if (!expected_matches.empty()) {
+    ASSERT_EQ(nullptr, g.gl_pathv[expected_matches.size()]);
+  }
+  globfree(&g);
+}
+
+TEST(glob, glob_globbing) {
+  fake_dir = { "f1", "f2", "f30", "f40" };
+
+  CheckGlob("f?", { "f1", "f2" });
+  CheckGlob("f??", { "f30", "f40" });
+  CheckGlob("f*", { "f1", "f2", "f30", "f40" });
+}
+
+TEST(glob, glob_globbing_rsc) {
+  // https://research.swtch.com/glob
+  fake_dir = { "axbxcxdxe" };
+  CheckGlob("a*b*c*d*e*", { "axbxcxdxe" });
+  fake_dir = { "axbxcxdxexxx" };
+  CheckGlob("a*b*c*d*e*", { "axbxcxdxexxx" });
+  fake_dir = { "abxbbxdbxebxczzx" };
+  CheckGlob("a*b?c*x", { "abxbbxdbxebxczzx" });
+  fake_dir = { "abxbbxdbxebxczzy" };
+  CheckGlob("a*b?c*x", {});
+
+  fake_dir = { std::string(100, 'a') };
+  CheckGlob("a*a*a*a*b", {});
+}
diff --git a/tests/leak_test.cpp b/tests/leak_test.cpp
index a356640..de08869 100644
--- a/tests/leak_test.cpp
+++ b/tests/leak_test.cpp
@@ -35,20 +35,6 @@
 
 using namespace std::chrono_literals;
 
-static size_t GetMappingSize() {
-  std::vector<map_record> maps;
-  if (!Maps::parse_maps(&maps)) {
-    err(1, "failed to parse maps");
-  }
-
-  size_t result = 0;
-  for (const map_record& map : maps) {
-    result += map.addr_end - map.addr_start;
-  }
-
-  return result;
-}
-
 static void WaitUntilAllExited(pid_t* pids, size_t pid_count) {
   // Wait until all children have exited.
   bool alive = true;
@@ -70,6 +56,9 @@
 class LeakChecker {
  public:
   LeakChecker() {
+    // Avoid resizing and using memory later.
+    // 64Ki is the default limit on VMAs per process.
+    maps_.reserve(64*1024);
     Reset();
   }
 
@@ -87,6 +76,7 @@
 
  private:
   size_t previous_size_;
+  std::vector<map_record> maps_;
 
   void Check() {
     auto current_size = GetMappingSize();
@@ -94,6 +84,19 @@
       FAIL() << "increase in process map size: " << previous_size_ << " -> " << current_size;
     }
   }
+
+  size_t GetMappingSize() {
+    if (!Maps::parse_maps(&maps_)) {
+      err(1, "failed to parse maps");
+    }
+
+    size_t result = 0;
+    for (const map_record& map : maps_) {
+      result += map.addr_end - map.addr_start;
+    }
+
+    return result;
+  }
 };
 
 std::ostream& operator<<(std::ostream& os, const LeakChecker& lc) {
@@ -116,27 +119,24 @@
   LeakChecker lc;
 
   for (size_t pass = 0; pass < 2; ++pass) {
+    constexpr int kThreadCount = 100;
+    struct thread_data { pthread_barrier_t* barrier; pid_t* tid; } threads[kThreadCount] = {};
+
     pthread_barrier_t barrier;
-    constexpr int thread_count = 100;
-    ASSERT_EQ(pthread_barrier_init(&barrier, nullptr, thread_count + 1), 0);
+    ASSERT_EQ(pthread_barrier_init(&barrier, nullptr, kThreadCount + 1), 0);
 
     // Start child threads.
-    struct thread_data { pthread_barrier_t* barrier; pid_t* tid; };
-    pid_t tids[thread_count];
-    for (int i = 0; i < thread_count; ++i) {
-      thread_data* td = new thread_data{&barrier, &tids[i]};
+    pid_t tids[kThreadCount];
+    for (int i = 0; i < kThreadCount; ++i) {
+      threads[i] = {&barrier, &tids[i]};
       const auto thread_function = +[](void* ptr) -> void* {
         thread_data* data = static_cast<thread_data*>(ptr);
         *data->tid = gettid();
         pthread_barrier_wait(data->barrier);
-        // Doing this delete allocates new VMAs for jemalloc bookkeeping,
-        // but the two-pass nature of this test means we can check that
-        // it's a pool rather than an unbounded leak.
-        delete data;
         return nullptr;
       };
       pthread_t thread;
-      ASSERT_EQ(0, pthread_create(&thread, nullptr, thread_function, td));
+      ASSERT_EQ(0, pthread_create(&thread, nullptr, thread_function, &threads[i]));
       ASSERT_EQ(0, pthread_detach(thread));
     }
 
diff --git a/tests/libs/Android.bp b/tests/libs/Android.bp
index c1600cc..858f2b1 100644
--- a/tests/libs/Android.bp
+++ b/tests/libs/Android.bp
@@ -17,6 +17,10 @@
 cc_defaults {
     name: "bionic_testlib_defaults",
     host_supported: true,
+    cflags: [
+        "-Wall",
+        "-Werror",
+    ],
     ldflags: [
         "-Wl,--rpath,${ORIGIN}",
         "-Wl,--enable-new-dtags",
@@ -282,15 +286,6 @@
             enabled: false,
         },
     },
-
-    target: {
-        android: {
-            shared_libs: ["libdl"],
-        },
-        host: {
-            host_ldlibs: ["-ldl"],
-        },
-    },
 }
 
 cc_test_library {
@@ -307,15 +302,6 @@
             enabled: false,
         },
     },
-
-    target: {
-        android: {
-            shared_libs: ["libdl"],
-        },
-        host: {
-            host_ldlibs: ["-ldl"],
-        },
-    },
 }
 
 cc_test_library {
@@ -331,15 +317,6 @@
             enabled: false,
         },
     },
-
-    target: {
-        android: {
-            shared_libs: ["libdl"],
-        },
-        host: {
-            host_ldlibs: ["-ldl"],
-        },
-    },
 }
 
 // -----------------------------------------------------------------------------
@@ -416,15 +393,6 @@
     defaults: ["bionic_testlib_defaults"],
     srcs: ["dlsym_from_this_symbol.cpp"],
     shared_libs: ["libtest_dlsym_from_this_child"],
-
-    target: {
-        android: {
-            shared_libs: ["libdl"],
-        },
-        host: {
-            host_ldlibs: ["-ldl"],
-        },
-    },
 }
 
 // -----------------------------------------------------------------------------
@@ -433,14 +401,6 @@
     defaults: ["bionic_testlib_defaults"],
     srcs: ["dlsym_from_this_functions.cpp"],
     shared_libs: ["libtest_dlsym_from_this_grandchild"],
-    target: {
-        android: {
-            shared_libs: ["libdl"],
-        },
-        host: {
-            host_ldlibs: ["-ldl"],
-        },
-    },
 }
 
 // -----------------------------------------------------------------------------
@@ -475,15 +435,6 @@
     name: "libtest_check_rtld_next_from_library",
     defaults: ["bionic_testlib_defaults"],
     srcs: ["check_rtld_next_from_library.cpp"],
-
-    target: {
-        android: {
-            shared_libs: ["libdl"],
-        },
-        host: {
-            host_ldlibs: ["-ldl"],
-        },
-    },
 }
 
 // -----------------------------------------------------------------------------
@@ -493,14 +444,6 @@
     name: "libtest_dlopen_from_ctor",
     defaults: ["bionic_testlib_defaults"],
     srcs: ["dlopen_testlib_dlopen_from_ctor.cpp"],
-    target: {
-        android: {
-            shared_libs: ["libdl"],
-        },
-        host: {
-            host_ldlibs: ["-ldl"],
-        },
-    },
 }
 
 // -----------------------------------------------------------------------------
diff --git a/tests/pthread_test.cpp b/tests/pthread_test.cpp
index 46140bb..f342577 100755
--- a/tests/pthread_test.cpp
+++ b/tests/pthread_test.cpp
@@ -2117,8 +2117,9 @@
 
   const auto kPageSize = sysconf(_SC_PAGE_SIZE);
 
-  // Use up all the VMAs. By default this is 64Ki.
+  // Use up all the VMAs. By default this is 64Ki (though some will already be in use).
   std::vector<void*> pages;
+  pages.reserve(64 * 1024);
   int prot = PROT_NONE;
   while (true) {
     void* page = mmap(nullptr, kPageSize, prot, MAP_ANON|MAP_PRIVATE, -1, 0);
diff --git a/tests/sys_random_test.cpp b/tests/sys_random_test.cpp
new file mode 100644
index 0000000..78cbf4a
--- /dev/null
+++ b/tests/sys_random_test.cpp
@@ -0,0 +1,105 @@
+/*
+ * Copyright (C) 2017 The Android Open Source Project
+ *
+ * Licensed under the Apache License, Version 2.0 (the "License");
+ * you may not use this file except in compliance with the License.
+ * You may obtain a copy of the License at
+ *
+ *      http://www.apache.org/licenses/LICENSE-2.0
+ *
+ * Unless required by applicable law or agreed to in writing, software
+ * distributed under the License is distributed on an "AS IS" BASIS,
+ * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
+ * See the License for the specific language governing permissions and
+ * limitations under the License.
+ */
+
+// <sys/random.h> was only added as of glibc version 2.25.
+// Don't try to compile this code on older glibc versions.
+
+#include <sys/cdefs.h>
+#if defined(__BIONIC__)
+  #define HAVE_SYS_RANDOM 1
+#elif defined(__GLIBC_PREREQ)
+  #if __GLIBC_PREREQ(2, 25)
+    #define HAVE_SYS_RANDOM 1
+  #endif
+#endif
+
+
+#if defined(HAVE_SYS_RANDOM)
+#include <sys/random.h>
+#endif
+
+#include <errno.h>
+#include <gtest/gtest.h>
+
+TEST(sys_random, getentropy) {
+#if defined(HAVE_SYS_RANDOM)
+  char buf1[64];
+  char buf2[64];
+
+  ASSERT_EQ(0, getentropy(buf1, sizeof(buf1)));
+  ASSERT_EQ(0, getentropy(buf2, sizeof(buf2)));
+  ASSERT_TRUE(memcmp(buf1, buf2, sizeof(buf1)) != 0);
+#else
+  GTEST_LOG_(INFO) << "This test requires a C library with <sys/random.h>.\n";
+#endif
+}
+
+TEST(sys_random, getentropy_EFAULT) {
+#if defined(HAVE_SYS_RANDOM)
+  errno = 0;
+  ASSERT_EQ(-1, getentropy(nullptr, 1));
+  ASSERT_EQ(EFAULT, errno);
+#else
+  GTEST_LOG_(INFO) << "This test requires a C library with <sys/random.h>.\n";
+#endif
+}
+
+TEST(sys_random, getentropy_EIO) {
+#if defined(HAVE_SYS_RANDOM)
+  char buf[BUFSIZ];
+  static_assert(BUFSIZ > 256, "BUFSIZ <= 256!");
+
+  errno = 0;
+  ASSERT_EQ(-1, getentropy(buf, sizeof(buf)));
+  ASSERT_EQ(EIO, errno);
+#else
+  GTEST_LOG_(INFO) << "This test requires a C library with <sys/random.h>.\n";
+#endif
+}
+
+TEST(sys_random, getrandom) {
+#if defined(HAVE_SYS_RANDOM)
+  char buf1[64];
+  char buf2[64];
+
+  ASSERT_EQ(64, getrandom(buf1, sizeof(buf1), 0));
+  ASSERT_EQ(64, getrandom(buf2, sizeof(buf2), 0));
+  ASSERT_TRUE(memcmp(buf1, buf2, sizeof(buf1)) != 0);
+#else
+  GTEST_LOG_(INFO) << "This test requires a C library with <sys/random.h>.\n";
+#endif
+}
+
+TEST(sys_random, getrandom_EFAULT) {
+#if defined(HAVE_SYS_RANDOM)
+  errno = 0;
+  ASSERT_EQ(-1, getrandom(nullptr, 256, 0));
+  ASSERT_EQ(EFAULT, errno);
+#else
+  GTEST_LOG_(INFO) << "This test requires a C library with <sys/random.h>.\n";
+#endif
+}
+
+TEST(sys_random, getrandom_EINVAL) {
+#if defined(HAVE_SYS_RANDOM)
+  errno = 0;
+  char buf[64];
+  ASSERT_EQ(-1, getrandom(buf, sizeof(buf), ~0));
+  ASSERT_EQ(EINVAL, errno);
+#else
+  GTEST_LOG_(INFO) << "This test requires a C library with <sys/random.h>.\n";
+#endif
+}
diff --git a/tests/time_test.cpp b/tests/time_test.cpp
index 4e3fa83..d553ff5 100644
--- a/tests/time_test.cpp
+++ b/tests/time_test.cpp
@@ -574,6 +574,31 @@
   ASSERT_LT(ts2.tv_nsec, 1000000);
 }
 
+TEST(time, clock_gettime_CLOCK_REALTIME) {
+  timespec ts;
+  ASSERT_EQ(0, clock_gettime(CLOCK_REALTIME, &ts));
+}
+
+TEST(time, clock_gettime_CLOCK_MONOTONIC) {
+  timespec ts;
+  ASSERT_EQ(0, clock_gettime(CLOCK_MONOTONIC, &ts));
+}
+
+TEST(time, clock_gettime_CLOCK_PROCESS_CPUTIME_ID) {
+  timespec ts;
+  ASSERT_EQ(0, clock_gettime(CLOCK_PROCESS_CPUTIME_ID, &ts));
+}
+
+TEST(time, clock_gettime_CLOCK_THREAD_CPUTIME_ID) {
+  timespec ts;
+  ASSERT_EQ(0, clock_gettime(CLOCK_THREAD_CPUTIME_ID, &ts));
+}
+
+TEST(time, clock_gettime_CLOCK_BOOTTIME) {
+  timespec ts;
+  ASSERT_EQ(0, clock_gettime(CLOCK_BOOTTIME, &ts));
+}
+
 TEST(time, clock) {
   // clock(3) is hard to test, but a 1s sleep should cost less than 1ms.
   clock_t t0 = clock();
diff --git a/tests/unistd_test.cpp b/tests/unistd_test.cpp
index 8af2263..9203215 100644
--- a/tests/unistd_test.cpp
+++ b/tests/unistd_test.cpp
@@ -701,7 +701,7 @@
   EXPECT_GT(_POSIX_CHILD_MAX, 0);
   EXPECT_NE(_POSIX_CHOWN_RESTRICTED, -1);
   EXPECT_EQ(_POSIX_VERSION, _POSIX_CLOCK_SELECTION);
-  EXPECT_EQ(0, _POSIX_CPUTIME);             // Use sysconf to detect support at runtime.
+  EXPECT_EQ(_POSIX_VERSION, _POSIX_CPUTIME);
   EXPECT_GT(_POSIX_DELAYTIMER_MAX, 0);
   EXPECT_EQ(_POSIX_VERSION, _POSIX_FSYNC);
   EXPECT_GT(_POSIX_HOST_NAME_MAX, 0);
@@ -715,7 +715,7 @@
   EXPECT_EQ(_POSIX_VERSION, _POSIX_MEMLOCK);
   EXPECT_EQ(_POSIX_VERSION, _POSIX_MEMLOCK_RANGE);
   EXPECT_EQ(_POSIX_VERSION, _POSIX_MEMORY_PROTECTION);
-  EXPECT_EQ(0, _POSIX_MONOTONIC_CLOCK);
+  EXPECT_EQ(_POSIX_VERSION, _POSIX_MONOTONIC_CLOCK);
   EXPECT_GT(_POSIX_MQ_OPEN_MAX, 0);
   EXPECT_GT(_POSIX_MQ_PRIO_MAX, 0);
   EXPECT_GT(_POSIX_NAME_MAX, 0);
@@ -736,7 +736,7 @@
   EXPECT_GT(_POSIX_SEM_VALUE_MAX, 0);
   EXPECT_GT(_POSIX_SHELL, 0);
   EXPECT_GT(_POSIX_SIGQUEUE_MAX, 0);
-  EXPECT_EQ(-1, _POSIX_SPORADIC_SERVER);
+  EXPECT_EQ(_POSIX_VERSION, _POSIX_SPORADIC_SERVER);
   EXPECT_GT(_POSIX_SSIZE_MAX, 0);
   EXPECT_GT(_POSIX_STREAM_MAX, 0);
   EXPECT_GT(_POSIX_SYMLINK_MAX, 0);
@@ -745,7 +745,7 @@
   EXPECT_EQ(_POSIX_VERSION, _POSIX_THREADS);
   EXPECT_EQ(_POSIX_VERSION, _POSIX_THREAD_ATTR_STACKADDR);
   EXPECT_EQ(_POSIX_VERSION, _POSIX_THREAD_ATTR_STACKSIZE);
-  EXPECT_EQ(0, _POSIX_THREAD_CPUTIME);       // Use sysconf to detect support at runtime.
+  EXPECT_EQ(_POSIX_VERSION, _POSIX_THREAD_CPUTIME);
   EXPECT_GT(_POSIX_THREAD_DESTRUCTOR_ITERATIONS, 0);
   EXPECT_EQ(_POSIX_THREAD_KEYS_MAX, 128);
   EXPECT_EQ(_POSIX_VERSION, _POSIX_THREAD_PRIORITY_SCHEDULING);
@@ -754,7 +754,7 @@
   EXPECT_EQ(_POSIX_VERSION, _POSIX_THREAD_PROCESS_SHARED);
   EXPECT_EQ(-1, _POSIX_THREAD_ROBUST_PRIO_PROTECT);
   EXPECT_EQ(_POSIX_VERSION, _POSIX_THREAD_SAFE_FUNCTIONS);
-  EXPECT_EQ(-1, _POSIX_THREAD_SPORADIC_SERVER);
+  EXPECT_EQ(_POSIX_VERSION, _POSIX_THREAD_SPORADIC_SERVER);
   EXPECT_GT(_POSIX_THREAD_THREADS_MAX, 0);
   EXPECT_EQ(_POSIX_VERSION, _POSIX_TIMEOUTS);
   EXPECT_EQ(_POSIX_VERSION, _POSIX_TIMERS);
@@ -784,12 +784,6 @@
   EXPECT_GT(_XOPEN_IOV_MAX, 0);
   EXPECT_GT(_XOPEN_UNIX, 0);
 
-  // In O, the headers still have -1 (even though all the functionality has
-  // been there for a long time). This was fixed in O-DR, but there isn't a
-  // separate CTS for O-DR, so we'll accept both.
-  EXPECT_TRUE(_POSIX_THREAD_PROCESS_SHARED == -1 ||
-              _POSIX_THREAD_PROCESS_SHARED == _POSIX_VERSION);
-
 #if defined(__BIONIC__)
   // These tests only pass on bionic, as bionic and glibc has different support on these macros.
   // Macros like _POSIX_ASYNCHRONOUS_IO are not supported on bionic yet.
@@ -921,11 +915,11 @@
   VERIFY_SYSCONF_POSIX_VERSION(_SC_READER_WRITER_LOCKS);
   VERIFY_SYSCONF_POSITIVE(_SC_REGEXP);
   VERIFY_SYSCONF_POSITIVE(_SC_SHELL);
-  VERIFY_SYSCONF_UNSUPPORTED(_SC_SPORADIC_SERVER);
+  VERIFY_SYSCONF_POSIX_VERSION(_SC_SPORADIC_SERVER);
   VERIFY_SYSCONF_POSITIVE(_SC_SYMLOOP_MAX);
   VERIFY_SYSCONF_POSIX_VERSION(_SC_THREAD_CPUTIME);
   VERIFY_SYSCONF_POSIX_VERSION(_SC_THREAD_PROCESS_SHARED);
-  VERIFY_SYSCONF_UNSUPPORTED(_SC_THREAD_SPORADIC_SERVER);
+  VERIFY_SYSCONF_POSIX_VERSION(_SC_THREAD_SPORADIC_SERVER);
   VERIFY_SYSCONF_POSIX_VERSION(_SC_TIMEOUTS);
   VERIFY_SYSCONF_UNSUPPORTED(_SC_TRACE);
   VERIFY_SYSCONF_UNSUPPORTED(_SC_TRACE_EVENT_FILTER);
diff --git a/tests/utils.h b/tests/utils.h
index 8638850..daf382e 100644
--- a/tests/utils.h
+++ b/tests/utils.h
@@ -71,15 +71,13 @@
 class Maps {
  public:
   static bool parse_maps(std::vector<map_record>* maps) {
-    FILE* fp = fopen("/proc/self/maps", "re");
-    if (fp == nullptr) {
-      return false;
-    }
+    maps->clear();
 
-    auto fp_guard = android::base::make_scope_guard([&]() { fclose(fp); });
+    std::unique_ptr<FILE, decltype(&fclose)> fp(fopen("/proc/self/maps", "re"), fclose);
+    if (!fp) return false;
 
     char line[BUFSIZ];
-    while (fgets(line, sizeof(line), fp) != nullptr) {
+    while (fgets(line, sizeof(line), fp.get()) != nullptr) {
       map_record record;
       uint32_t dev_major, dev_minor;
       int path_offset;
diff --git a/tools/relocation_packer/Android.bp b/tools/relocation_packer/Android.bp
index 2907b31..cd6053a 100644
--- a/tools/relocation_packer/Android.bp
+++ b/tools/relocation_packer/Android.bp
@@ -16,11 +16,13 @@
 
 cc_defaults {
     name: "relocation_packer_flags",
-    cppflags: [
+    cflags: [
         "-Wall",
+        "-Werror",
+    ],
+    cppflags: [
         "-Wextra",
         "-Wunused",
-        "-Werror",
         "-Wold-style-cast",
     ],
 
diff --git a/tools/relocation_packer/src/main.cc b/tools/relocation_packer/src/main.cc
index d0a0dd4..1589043 100644
--- a/tools/relocation_packer/src/main.cc
+++ b/tools/relocation_packer/src/main.cc
@@ -106,7 +106,7 @@
   // We need to detect elf class in order to create
   // correct implementation
   uint8_t e_ident[EI_NIDENT];
-  if (TEMP_FAILURE_RETRY(read(fd.get(), e_ident, EI_NIDENT) != EI_NIDENT)) {
+  if (TEMP_FAILURE_RETRY(read(fd.get(), e_ident, EI_NIDENT)) != EI_NIDENT) {
     LOG(ERROR) << file << ": failed to read elf header:" << strerror(errno);
     return 1;
   }
diff --git a/tools/update_seccomp.sh b/tools/update_seccomp.sh
new file mode 100755
index 0000000..d108e35
--- /dev/null
+++ b/tools/update_seccomp.sh
@@ -0,0 +1,7 @@
+#!/bin/sh
+DIR="$( cd "$( dirname "${BASH_SOURCE[0]}" )" && pwd )"
+cd $DIR/..
+./libc/tools/genseccomp.py
+
+git diff --exit-code HEAD libc/seccomp/
+exit $?
diff --git a/tools/update_syscalls.sh b/tools/update_syscalls.sh
new file mode 100755
index 0000000..3ad95ed
--- /dev/null
+++ b/tools/update_syscalls.sh
@@ -0,0 +1,7 @@
+#!/bin/sh
+DIR="$( cd "$( dirname "${BASH_SOURCE[0]}" )" && pwd )"
+cd $DIR/..
+./libc/tools/gensyscalls.py
+
+git diff --exit-code HEAD libc/arch-*/syscalls/
+exit $?
diff --git a/tools/update_version_scripts.sh b/tools/update_version_scripts.sh
new file mode 100755
index 0000000..ccba475
--- /dev/null
+++ b/tools/update_version_scripts.sh
@@ -0,0 +1,7 @@
+#!/bin/sh
+DIR="$( cd "$( dirname "${BASH_SOURCE[0]}" )" && pwd )"
+cd $DIR/..
+./libc/tools/genversion-scripts.py
+
+git diff --exit-code HEAD libc/*.map libdl/*.map libm/*.map linker/*.map
+exit $?