Merge "Rename DT_MIPS_RLD_MAP2 flag to DT_MIPS_RLD_MAP_REL"
diff --git a/libc/Android.bp b/libc/Android.bp
index 7c82695..c5a513c 100644
--- a/libc/Android.bp
+++ b/libc/Android.bp
@@ -82,7 +82,9 @@
 
     stl: "none",
     system_shared_libs: [],
-    sanitize: ["never"],
+    sanitize: {
+        never: true,
+    },
     native_coverage: false,
 }
 
@@ -307,8 +309,6 @@
     defaults: ["libc_defaults"],
     srcs: [
         "upstream-netbsd/common/lib/libc/stdlib/random.c",
-        "upstream-netbsd/lib/libc/gen/ftw.c",
-        "upstream-netbsd/lib/libc/gen/nftw.c",
         "upstream-netbsd/lib/libc/gen/nice.c",
         "upstream-netbsd/lib/libc/gen/popen.c",
         "upstream-netbsd/lib/libc/gen/psignal.c",
@@ -414,6 +414,7 @@
         "upstream-openbsd/lib/libc/locale/wcsxfrm.c",
         "upstream-openbsd/lib/libc/locale/wctob.c",
         "upstream-openbsd/lib/libc/locale/wctomb.c",
+        "upstream-openbsd/lib/libc/net/base64.c",
         "upstream-openbsd/lib/libc/net/htonl.c",
         "upstream-openbsd/lib/libc/net/htons.c",
         "upstream-openbsd/lib/libc/net/inet_lnaof.c",
@@ -507,6 +508,7 @@
         "upstream-openbsd/lib/libc/stdlib/atol.c",
         "upstream-openbsd/lib/libc/stdlib/atoll.c",
         "upstream-openbsd/lib/libc/stdlib/getenv.c",
+        "upstream-openbsd/lib/libc/stdlib/getsubopt.c",
         "upstream-openbsd/lib/libc/stdlib/insque.c",
         "upstream-openbsd/lib/libc/stdlib/imaxabs.c",
         "upstream-openbsd/lib/libc/stdlib/imaxdiv.c",
@@ -1278,6 +1280,7 @@
         "bionic/fpclassify.cpp",
         "bionic/fsetxattr.cpp",
         "bionic/ftruncate.cpp",
+        "bionic/ftw.cpp",
         "bionic/futimens.cpp",
         "bionic/getcwd.cpp",
         "bionic/getdomainname.cpp",
@@ -1316,6 +1319,7 @@
         "bionic/NetdClientDispatch.cpp",
         "bionic/net_if.cpp",
         "bionic/netinet_in.cpp",
+        "bionic/nl_types.cpp",
         "bionic/open.cpp",
         "bionic/pathconf.cpp",
         "bionic/pause.cpp",
@@ -1348,12 +1352,17 @@
         "bionic/sigdelset.cpp",
         "bionic/sigemptyset.cpp",
         "bionic/sigfillset.cpp",
+        "bionic/sighold.cpp",
+        "bionic/sigignore.cpp",
         "bionic/sigismember.cpp",
         "bionic/signal.cpp",
         "bionic/signalfd.cpp",
+        "bionic/sigpause.cpp",
         "bionic/sigpending.cpp",
         "bionic/sigprocmask.cpp",
         "bionic/sigqueue.cpp",
+        "bionic/sigrelse.cpp",
+        "bionic/sigset.cpp",
         "bionic/sigsuspend.cpp",
         "bionic/sigtimedwait.cpp",
         "bionic/sigwait.cpp",
@@ -1367,6 +1376,7 @@
         "bionic/strsignal.cpp",
         "bionic/strtold.cpp",
         "bionic/symlink.cpp",
+        "bionic/sync_file_range.cpp",
         "bionic/sysinfo.cpp",
         "bionic/syslog.cpp",
         "bionic/sys_siglist.c",
@@ -1472,6 +1482,7 @@
 // ========================================================
 
 cc_library_static {
+    defaults: ["libc_defaults"],
     arch: {
         arm: {
             srcs: ["arch-arm/syscalls/**/*.S"],
@@ -1912,7 +1923,7 @@
         "crt_defaults",
         "crt_so_defaults",
     ],
-    deps: [
+    objs: [
         "crtbegin_so1",
         "crtbrand",
     ],
@@ -1970,7 +1981,7 @@
 cc_object {
     name: "crtbegin_static",
 
-    deps: [
+    objs: [
         "crtbegin_static1",
         "crtbrand",
     ],
@@ -2016,7 +2027,7 @@
 cc_object {
     name: "crtbegin_dynamic",
 
-    deps: [
+    objs: [
         "crtbegin_dynamic1",
         "crtbrand",
     ],
diff --git a/libc/Android.mk b/libc/Android.mk
index 631de5e..02682af 100644
--- a/libc/Android.mk
+++ b/libc/Android.mk
@@ -107,6 +107,7 @@
     bionic/fpclassify.cpp \
     bionic/fsetxattr.cpp \
     bionic/ftruncate.cpp \
+    bionic/ftw.cpp \
     bionic/futimens.cpp \
     bionic/getcwd.cpp \
     bionic/getdomainname.cpp \
@@ -145,6 +146,7 @@
     bionic/NetdClientDispatch.cpp \
     bionic/net_if.cpp \
     bionic/netinet_in.cpp \
+    bionic/nl_types.cpp \
     bionic/open.cpp \
     bionic/pathconf.cpp \
     bionic/pause.cpp \
@@ -287,8 +289,6 @@
 
 libc_upstream_netbsd_src_files := \
     upstream-netbsd/common/lib/libc/stdlib/random.c \
-    upstream-netbsd/lib/libc/gen/ftw.c \
-    upstream-netbsd/lib/libc/gen/nftw.c \
     upstream-netbsd/lib/libc/gen/nice.c \
     upstream-netbsd/lib/libc/gen/popen.c \
     upstream-netbsd/lib/libc/gen/psignal.c \
@@ -406,6 +406,7 @@
     upstream-openbsd/lib/libc/locale/wcsxfrm.c \
     upstream-openbsd/lib/libc/locale/wctob.c \
     upstream-openbsd/lib/libc/locale/wctomb.c \
+    upstream-openbsd/lib/libc/net/base64.c \
     upstream-openbsd/lib/libc/net/htonl.c \
     upstream-openbsd/lib/libc/net/htons.c \
     upstream-openbsd/lib/libc/net/inet_lnaof.c \
diff --git a/libc/SYSCALLS.TXT b/libc/SYSCALLS.TXT
index 87f600b..e530293 100644
--- a/libc/SYSCALLS.TXT
+++ b/libc/SYSCALLS.TXT
@@ -322,6 +322,8 @@
 ssize_t process_vm_readv(pid_t, const struct iovec*, unsigned long, const struct iovec*, unsigned long, unsigned long)  all
 ssize_t process_vm_writev(pid_t, const struct iovec*, unsigned long, const struct iovec*, unsigned long, unsigned long)  all
 
+int quotactl(int, const char*, int, char*)  all
+
 int __set_tid_address:set_tid_address(int*)  all
 
 int setfsgid(gid_t)  all
diff --git a/libc/arch-arm/syscalls/quotactl.S b/libc/arch-arm/syscalls/quotactl.S
new file mode 100644
index 0000000..831d229
--- /dev/null
+++ b/libc/arch-arm/syscalls/quotactl.S
@@ -0,0 +1,14 @@
+/* Generated by gensyscalls.py. Do not edit. */
+
+#include <private/bionic_asm.h>
+
+ENTRY(quotactl)
+    mov     ip, r7
+    ldr     r7, =__NR_quotactl
+    swi     #0
+    mov     r7, ip
+    cmn     r0, #(MAX_ERRNO + 1)
+    bxls    lr
+    neg     r0, r0
+    b       __set_errno_internal
+END(quotactl)
diff --git a/libc/arch-arm64/syscalls/quotactl.S b/libc/arch-arm64/syscalls/quotactl.S
new file mode 100644
index 0000000..b67d47e
--- /dev/null
+++ b/libc/arch-arm64/syscalls/quotactl.S
@@ -0,0 +1,14 @@
+/* Generated by gensyscalls.py. Do not edit. */
+
+#include <private/bionic_asm.h>
+
+ENTRY(quotactl)
+    mov     x8, __NR_quotactl
+    svc     #0
+
+    cmn     x0, #(MAX_ERRNO + 1)
+    cneg    x0, x0, hi
+    b.hi    __set_errno_internal
+
+    ret
+END(quotactl)
diff --git a/libc/arch-mips/syscalls/quotactl.S b/libc/arch-mips/syscalls/quotactl.S
new file mode 100644
index 0000000..fef336a
--- /dev/null
+++ b/libc/arch-mips/syscalls/quotactl.S
@@ -0,0 +1,19 @@
+/* Generated by gensyscalls.py. Do not edit. */
+
+#include <private/bionic_asm.h>
+
+ENTRY(quotactl)
+    .set noreorder
+    .cpload t9
+    li v0, __NR_quotactl
+    syscall
+    bnez a3, 1f
+    move a0, v0
+    j ra
+    nop
+1:
+    la t9,__set_errno_internal
+    j t9
+    nop
+    .set reorder
+END(quotactl)
diff --git a/libc/arch-mips64/syscalls/quotactl.S b/libc/arch-mips64/syscalls/quotactl.S
new file mode 100644
index 0000000..861947c
--- /dev/null
+++ b/libc/arch-mips64/syscalls/quotactl.S
@@ -0,0 +1,25 @@
+/* Generated by gensyscalls.py. Do not edit. */
+
+#include <private/bionic_asm.h>
+
+ENTRY(quotactl)
+    .set push
+    .set noreorder
+    li v0, __NR_quotactl
+    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(quotactl)
diff --git a/libc/arch-x86/syscalls/quotactl.S b/libc/arch-x86/syscalls/quotactl.S
new file mode 100644
index 0000000..326cf87
--- /dev/null
+++ b/libc/arch-x86/syscalls/quotactl.S
@@ -0,0 +1,44 @@
+/* Generated by gensyscalls.py. Do not edit. */
+
+#include <private/bionic_asm.h>
+
+ENTRY(quotactl)
+    pushl   %ebx
+    .cfi_def_cfa_offset 8
+    .cfi_rel_offset ebx, 0
+    pushl   %ecx
+    .cfi_adjust_cfa_offset 4
+    .cfi_rel_offset ecx, 0
+    pushl   %edx
+    .cfi_adjust_cfa_offset 4
+    .cfi_rel_offset edx, 0
+    pushl   %esi
+    .cfi_adjust_cfa_offset 4
+    .cfi_rel_offset esi, 0
+
+    call    __kernel_syscall
+    pushl   %eax
+    .cfi_adjust_cfa_offset 4
+    .cfi_rel_offset eax, 0
+
+    mov     24(%esp), %ebx
+    mov     28(%esp), %ecx
+    mov     32(%esp), %edx
+    mov     36(%esp), %esi
+    movl    $__NR_quotactl, %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    %esi
+    popl    %edx
+    popl    %ecx
+    popl    %ebx
+    ret
+END(quotactl)
diff --git a/libc/arch-x86_64/syscalls/quotactl.S b/libc/arch-x86_64/syscalls/quotactl.S
new file mode 100644
index 0000000..427358a
--- /dev/null
+++ b/libc/arch-x86_64/syscalls/quotactl.S
@@ -0,0 +1,16 @@
+/* Generated by gensyscalls.py. Do not edit. */
+
+#include <private/bionic_asm.h>
+
+ENTRY(quotactl)
+    movq    %rcx, %r10
+    movl    $__NR_quotactl, %eax
+    syscall
+    cmpq    $-MAX_ERRNO, %rax
+    jb      1f
+    negl    %eax
+    movl    %eax, %edi
+    call    __set_errno_internal
+1:
+    ret
+END(quotactl)
diff --git a/libc/bionic/clock.cpp b/libc/bionic/clock.cpp
index 053e9e7..fda0708 100644
--- a/libc/bionic/clock.cpp
+++ b/libc/bionic/clock.cpp
@@ -26,9 +26,9 @@
  * SUCH DAMAGE.
  */
 
-#include <time.h>
-#include <sys/sysconf.h>
 #include <sys/times.h>
+#include <time.h>
+#include <unistd.h>
 
 #include "private/bionic_constants.h"
 
diff --git a/libc/bionic/ftw.cpp b/libc/bionic/ftw.cpp
new file mode 100644
index 0000000..2123619
--- /dev/null
+++ b/libc/bionic/ftw.cpp
@@ -0,0 +1,124 @@
+/*
+ * Copyright (c) 2003, 2004 Todd C. Miller <Todd.Miller@courtesan.com>
+ *
+ * Permission to use, copy, modify, and distribute this software for any
+ * purpose with or without fee is hereby granted, provided that the above
+ * copyright notice and this permission notice appear in all copies.
+ *
+ * THE SOFTWARE IS PROVIDED "AS IS" AND THE AUTHOR DISCLAIMS ALL WARRANTIES
+ * WITH REGARD TO THIS SOFTWARE INCLUDING ALL IMPLIED WARRANTIES OF
+ * MERCHANTABILITY AND FITNESS. IN NO EVENT SHALL THE AUTHOR BE LIABLE FOR
+ * ANY SPECIAL, DIRECT, INDIRECT, OR CONSEQUENTIAL DAMAGES OR ANY DAMAGES
+ * WHATSOEVER RESULTING FROM LOSS OF USE, DATA OR PROFITS, WHETHER IN AN
+ * ACTION OF CONTRACT, NEGLIGENCE OR OTHER TORTIOUS ACTION, ARISING OUT OF
+ * OR IN CONNECTION WITH THE USE OR PERFORMANCE OF THIS SOFTWARE.
+ *
+ * Sponsored in part by the Defense Advanced Research Projects
+ * Agency (DARPA) and Air Force Research Laboratory, Air Force
+ * Materiel Command, USAF, under agreement number F39502-99-1-0512.
+ */
+
+#include <errno.h>
+#include <fts.h>
+#include <ftw.h>
+#include <sys/stat.h>
+#include <sys/types.h>
+#include <unistd.h>
+
+static int do_nftw(const char *path,
+                   int (*ftw_fn)(const char*, const struct stat*, int),
+                   int (*nftw_fn)(const char*, const struct stat*, int, FTW*),
+                   int nfds,
+                   int nftw_flags) {
+  // TODO: nfds is currently unused.
+  if (nfds < 1) {
+    errno = EINVAL;
+    return -1;
+  }
+
+  // Translate to fts_open options.
+  int fts_options = FTS_LOGICAL | FTS_COMFOLLOW | FTS_NOCHDIR;
+  if (nftw_fn) {
+    fts_options = FTS_COMFOLLOW | ((nftw_flags & FTW_PHYS) ? FTS_PHYSICAL : FTS_LOGICAL);
+    if (!(nftw_flags & FTW_CHDIR)) fts_options |= FTS_NOCHDIR;
+    if (nftw_flags & FTW_MOUNT) fts_options |= FTS_XDEV;
+  }
+  bool postorder = (nftw_flags & FTW_DEPTH) != 0;
+
+  // Call fts_open.
+  char* const paths[2] = { const_cast<char*>(path), nullptr };
+  FTS* fts = fts_open(paths, fts_options, nullptr);
+  if (fts == nullptr) {
+    return -1;
+  }
+
+  // Translate fts_read results into ftw/nftw callbacks.
+  int error = 0;
+  FTSENT* cur;
+  while (error == 0 && (cur = fts_read(fts)) != nullptr) {
+    int fn_flag;
+    switch (cur->fts_info) {
+      case FTS_D:
+        // In the postorder case, we'll translate FTS_DP to FTW_DP later.
+        // In the can't-access case, we'll translate FTS_DNR to FTW_DNR later.
+        if (postorder || access(cur->fts_path, R_OK) == -1) continue;
+        fn_flag = FTW_D;
+        break;
+      case FTS_DNR:
+        fn_flag = FTW_DNR;
+        break;
+      case FTS_DP:
+        if (!postorder) continue;
+        fn_flag = FTW_DP;
+        break;
+      case FTS_F:
+      case FTS_DEFAULT:
+        fn_flag = FTW_F;
+        break;
+      case FTS_NS:
+      case FTS_NSOK:
+        fn_flag = FTW_NS;
+        break;
+      case FTS_SL:
+        fn_flag = FTW_SL;
+        break;
+      case FTS_SLNONE:
+        fn_flag = (nftw_fn != nullptr) ? FTW_SLN : FTW_NS;
+        break;
+      case FTS_DC:
+        errno = ELOOP;
+        error = -1;
+        continue;
+      default:
+        error = -1;
+        continue;
+    }
+
+    // Call the appropriate function.
+    if (nftw_fn != nullptr) {
+      FTW ftw;
+      ftw.base = cur->fts_pathlen - cur->fts_namelen;
+      ftw.level = cur->fts_level;
+      error = nftw_fn(cur->fts_path, cur->fts_statp, fn_flag, &ftw);
+    } else {
+      error = ftw_fn(cur->fts_path, cur->fts_statp, fn_flag);
+    }
+  }
+
+  int saved_errno = errno;
+  if (fts_close(fts) != 0 && error == 0) {
+    error = -1;
+  } else {
+    errno = saved_errno;
+  }
+  return error;
+}
+
+int ftw(const char* path, int (*ftw_fn)(const char*, const struct stat*, int), int nfds) {
+  return do_nftw(path, ftw_fn, nullptr, nfds, 0);
+}
+
+int nftw(const char* path, int (*nftw_fn)(const char*, const struct stat*, int, FTW*),
+         int nfds, int nftw_flags) {
+  return do_nftw(path, nullptr, nftw_fn, nfds, nftw_flags);
+}
diff --git a/libc/bionic/grp_pwd.cpp b/libc/bionic/grp_pwd.cpp
index 1cabab4..d75b94d 100644
--- a/libc/bionic/grp_pwd.cpp
+++ b/libc/bionic/grp_pwd.cpp
@@ -312,27 +312,34 @@
   }
 }
 
+// oem_XXXX -> uid
+//  Supported ranges:
+//   AID_OEM_RESERVED_START to AID_OEM_RESERVED_END (2900-2999)
+//   AID_OEM_RESERVED_2_START to AID_OEM_RESERVED_2_END (5000-5999)
+// Check OEM id is within range.
+static bool is_oem_id(id_t id) {
+  return (((id >= AID_OEM_RESERVED_START) && (id <= AID_OEM_RESERVED_END)) ||
+      ((id >= AID_OEM_RESERVED_2_START) && (id <= AID_OEM_RESERVED_2_END)));
+}
+
 // Translate an OEM name to the corresponding user/group id.
-// oem_XXX -> AID_OEM_RESERVED_2_START + XXX, iff XXX is within range.
 static id_t oem_id_from_name(const char* name) {
   unsigned int id;
   if (sscanf(name, "oem_%u", &id) != 1) {
     return 0;
   }
-  // Check OEM id is within range.
-  if (id > (AID_OEM_RESERVED_2_END - AID_OEM_RESERVED_2_START)) {
+  if (!is_oem_id(id)) {
     return 0;
   }
-  return AID_OEM_RESERVED_2_START + static_cast<id_t>(id);
+  return static_cast<id_t>(id);
 }
 
 static passwd* oem_id_to_passwd(uid_t uid, passwd_state_t* state) {
-  if (uid < AID_OEM_RESERVED_2_START || uid > AID_OEM_RESERVED_2_END) {
+  if (!is_oem_id(uid)) {
     return NULL;
   }
 
-  snprintf(state->name_buffer_, sizeof(state->name_buffer_), "oem_%u",
-           uid - AID_OEM_RESERVED_2_START);
+  snprintf(state->name_buffer_, sizeof(state->name_buffer_), "oem_%u", uid);
   snprintf(state->dir_buffer_, sizeof(state->dir_buffer_), "/");
   snprintf(state->sh_buffer_, sizeof(state->sh_buffer_), "/system/bin/sh");
 
@@ -346,12 +353,12 @@
 }
 
 static group* oem_id_to_group(gid_t gid, group_state_t* state) {
-  if (gid < AID_OEM_RESERVED_2_START || gid > AID_OEM_RESERVED_2_END) {
+  if (!is_oem_id(gid)) {
     return NULL;
   }
 
   snprintf(state->group_name_buffer_, sizeof(state->group_name_buffer_),
-           "oem_%u", gid - AID_OEM_RESERVED_2_START);
+           "oem_%u", gid);
 
   group* gr = &state->group_;
   gr->gr_name   = state->group_name_buffer_;
diff --git a/libc/bionic/nl_types.cpp b/libc/bionic/nl_types.cpp
new file mode 100644
index 0000000..2cde591
--- /dev/null
+++ b/libc/bionic/nl_types.cpp
@@ -0,0 +1,45 @@
+/*
+ * Copyright (C) 2016 The Android Open Source Project
+ * All rights reserved.
+ *
+ * Redistribution and use in source and binary forms, with or without
+ * modification, are permitted provided that the following conditions
+ * are met:
+ *  * Redistributions of source code must retain the above copyright
+ *    notice, this list of conditions and the following disclaimer.
+ *  * Redistributions in binary form must reproduce the above copyright
+ *    notice, this list of conditions and the following disclaimer in
+ *    the documentation and/or other materials provided with the
+ *    distribution.
+ *
+ * THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS
+ * "AS IS" AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT
+ * LIMITED TO, THE IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS
+ * FOR A PARTICULAR PURPOSE ARE DISCLAIMED. IN NO EVENT SHALL THE
+ * COPYRIGHT OWNER OR CONTRIBUTORS BE LIABLE FOR ANY DIRECT, INDIRECT,
+ * INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING,
+ * BUT NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; LOSS
+ * OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED
+ * AND ON ANY THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY,
+ * OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT
+ * OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF
+ * SUCH DAMAGE.
+ */
+
+#include <nl_types.h>
+
+#include <errno.h>
+
+nl_catd catopen(const char*, int) {
+  return reinterpret_cast<nl_catd>(-1);
+}
+
+char* catgets(nl_catd, int, int, const char* message) {
+  return const_cast<char*>(message);
+}
+
+int catclose(nl_catd) {
+  // Since we didn't hand out a valid nl_catd, you can't be returning one to us.
+  errno = EBADF;
+  return -1;
+}
diff --git a/libc/bionic/strerror_r.cpp b/libc/bionic/strerror_r.cpp
index d419fb1..a0a0809 100644
--- a/libc/bionic/strerror_r.cpp
+++ b/libc/bionic/strerror_r.cpp
@@ -31,7 +31,7 @@
 
 static const Pair _sys_error_strings[] = {
 #define  __BIONIC_ERRDEF(x,y,z)  { x, z },
-#include <sys/_errdefs.h>
+#include "private/bionic_errdefs.h"
   { 0, NULL }
 };
 
@@ -41,7 +41,7 @@
 
 static const Pair _sys_signal_strings[] = {
 #define  __BIONIC_SIGDEF(signal_number, signal_description)  { signal_number, signal_description },
-#include <sys/_sigdefs.h>
+#include "private/bionic_sigdefs.h"
   { 0, NULL }
 };
 
diff --git a/libc/bionic/sys_siglist.c b/libc/bionic/sys_siglist.c
index 3cfddbf..8e33d64 100644
--- a/libc/bionic/sys_siglist.c
+++ b/libc/bionic/sys_siglist.c
@@ -30,5 +30,5 @@
 
 const char* const sys_siglist[NSIG] = {
 #define __BIONIC_SIGDEF(signal_number, signal_description) [ signal_number ] = signal_description,
-#include <sys/_sigdefs.h>
+#include "private/bionic_sigdefs.h"
 };
diff --git a/libc/bionic/sys_signame.c b/libc/bionic/sys_signame.c
index e1286f2..5158b83 100644
--- a/libc/bionic/sys_signame.c
+++ b/libc/bionic/sys_signame.c
@@ -30,5 +30,5 @@
 
 const char* const sys_signame[NSIG] = {
 #define __BIONIC_SIGDEF(signal_number, unused) [ signal_number ] = #signal_number + 3,
-#include <sys/_sigdefs.h>
+#include "private/bionic_sigdefs.h"
 };
diff --git a/libc/bionic/sysconf.cpp b/libc/bionic/sysconf.cpp
index cff6288..7be0ab7 100644
--- a/libc/bionic/sysconf.cpp
+++ b/libc/bionic/sysconf.cpp
@@ -34,7 +34,6 @@
 #include <stdio.h>  // For FOPEN_MAX.
 #include <sys/auxv.h>
 #include <sys/resource.h>
-#include <sys/sysconf.h>
 #include <sys/sysinfo.h>
 #include <time.h>
 #include <unistd.h>
diff --git a/libc/include/android/api-level.h b/libc/include/android/api-level.h
index 2d2f096..b230cef 100644
--- a/libc/include/android/api-level.h
+++ b/libc/include/android/api-level.h
@@ -33,6 +33,8 @@
  * Magic version number for a current development build, which has
  * not yet turned into an official release.
  */
+#ifndef __ANDROID_API__
 #define __ANDROID_API__ 10000
+#endif
 
 #endif /* ANDROID_API_LEVEL_H */
diff --git a/libc/include/android/dlext.h b/libc/include/android/dlext.h
index d5ec386..6e32b68 100644
--- a/libc/include/android/dlext.h
+++ b/libc/include/android/dlext.h
@@ -17,6 +17,7 @@
 #ifndef __ANDROID_DLEXT_H__
 #define __ANDROID_DLEXT_H__
 
+#include <stdbool.h>
 #include <stddef.h>
 #include <stdint.h>
 #include <sys/cdefs.h>
diff --git a/libc/include/android/legacy_errno_inlines.h b/libc/include/android/legacy_errno_inlines.h
index 71096fc..93cba1f 100644
--- a/libc/include/android/legacy_errno_inlines.h
+++ b/libc/include/android/legacy_errno_inlines.h
@@ -29,8 +29,11 @@
 #ifndef _ANDROID_LEGACY_ERRNO_INLINES_H
 #define _ANDROID_LEGACY_ERRNO_INLINES_H
 
+#include <errno.h>
 #include <sys/cdefs.h>
 
+#if __ANDROID_API__ < 21
+
 __BEGIN_DECLS
 
 static __inline int __attribute__((deprecated)) __set_errno(int n) {
@@ -40,4 +43,5 @@
 
 __END_DECLS
 
+#endif
 #endif /* _ANDROID_LEGACY_ERRNO_INLINES_H */
diff --git a/libc/include/android/legacy_signal_inlines.h b/libc/include/android/legacy_signal_inlines.h
index 1b6e687..bf895da 100644
--- a/libc/include/android/legacy_signal_inlines.h
+++ b/libc/include/android/legacy_signal_inlines.h
@@ -29,14 +29,18 @@
 #ifndef _ANDROID_LEGACY_SIGNAL_INLINES_H_
 #define _ANDROID_LEGACY_SIGNAL_INLINES_H_
 
+#include <errno.h>
+#include <signal.h>
 #include <string.h>
 #include <sys/cdefs.h>
 
+#if __ANDROID_API__ < 21
+
 __BEGIN_DECLS
 
 extern sighandler_t bsd_signal(int signum, sighandler_t handler);
 
-static __inline int sigismember(sigset_t *set, int signum) {
+static __inline int sigismember(const sigset_t *set, int signum) {
   /* Signal numbers start at 1, but bit positions start at 0. */
   int bit = signum - 1;
   const unsigned long *local_set = (const unsigned long *)set;
@@ -95,4 +99,5 @@
 
 __END_DECLS
 
+#endif
 #endif /* _ANDROID_LEGACY_SIGNAL_INLINES_H_ */
diff --git a/libc/include/android/legacy_stdlib_inlines.h b/libc/include/android/legacy_stdlib_inlines.h
index 58a2a9e..93554e5 100644
--- a/libc/include/android/legacy_stdlib_inlines.h
+++ b/libc/include/android/legacy_stdlib_inlines.h
@@ -29,8 +29,11 @@
 #ifndef _ANDROID_LEGACY_STDLIB_INLINES_H_
 #define _ANDROID_LEGACY_STDLIB_INLINES_H_
 
+#include <stdlib.h>
 #include <sys/cdefs.h>
 
+#if __ANDROID_API__ < 21
+
 __BEGIN_DECLS
 
 static __inline float strtof(const char *nptr, char **endptr) {
@@ -61,4 +64,5 @@
 
 __END_DECLS
 
+#endif
 #endif /* _ANDROID_LEGACY_STDLIB_INLINES_H_ */
diff --git a/libc/include/android/legacy_sys_atomics_inlines.h b/libc/include/android/legacy_sys_atomics_inlines.h
index 85cbade..3314e35 100644
--- a/libc/include/android/legacy_sys_atomics_inlines.h
+++ b/libc/include/android/legacy_sys_atomics_inlines.h
@@ -31,6 +31,8 @@
 
 #include <sys/cdefs.h>
 
+#if __ANDROID_API__ < 21
+
 __BEGIN_DECLS
 
 /* Note: atomic operations that were exported by the C library didn't
@@ -69,4 +71,5 @@
 
 __END_DECLS
 
+#endif
 #endif /* _ANDROID_LEGACY_SYS_ATOMICS_INLINES_H_ */
diff --git a/libc/include/android/legacy_sys_stat_inlines.h b/libc/include/android/legacy_sys_stat_inlines.h
index f6d3c0f..c08edfa 100644
--- a/libc/include/android/legacy_sys_stat_inlines.h
+++ b/libc/include/android/legacy_sys_stat_inlines.h
@@ -30,6 +30,9 @@
 #define _ANDROID_LEGACY_SYS_STAT_INLINES_H_
 
 #include <sys/cdefs.h>
+#include <sys/stat.h>
+
+#if __ANDROID_API__ < 21
 
 __BEGIN_DECLS
 
@@ -39,4 +42,5 @@
 
 __END_DECLS
 
+#endif
 #endif /* _ANDROID_LEGACY_SYS_STAT_INLINES_H_ */
diff --git a/libc/include/android/legacy_termios_inlines.h b/libc/include/android/legacy_termios_inlines.h
index fb61f27..41ea955 100644
--- a/libc/include/android/legacy_termios_inlines.h
+++ b/libc/include/android/legacy_termios_inlines.h
@@ -34,6 +34,8 @@
 #include <sys/ioctl.h>
 #include <sys/types.h>
 
+#if __ANDROID_API__ < 21
+
 __BEGIN_DECLS
 
 static __inline int tcgetattr(int fd, struct termios *s) {
@@ -90,4 +92,5 @@
 
 __END_DECLS
 
+#endif
 #endif /* _ANDROID_LEGACY_TERMIOS_INLINES_H_ */
diff --git a/libc/include/bits/fcntl.h b/libc/include/bits/fcntl.h
new file mode 100644
index 0000000..90f933c
--- /dev/null
+++ b/libc/include/bits/fcntl.h
@@ -0,0 +1,40 @@
+/*
+ * Copyright (C) 2016 The Android Open Source Project
+ * All rights reserved.
+ *
+ * Redistribution and use in source and binary forms, with or without
+ * modification, are permitted provided that the following conditions
+ * are met:
+ *  * Redistributions of source code must retain the above copyright
+ *    notice, this list of conditions and the following disclaimer.
+ *  * Redistributions in binary form must reproduce the above copyright
+ *    notice, this list of conditions and the following disclaimer in
+ *    the documentation and/or other materials provided with the
+ *    distribution.
+ *
+ * THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS
+ * "AS IS" AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT
+ * LIMITED TO, THE IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS
+ * FOR A PARTICULAR PURPOSE ARE DISCLAIMED. IN NO EVENT SHALL THE
+ * COPYRIGHT OWNER OR CONTRIBUTORS BE LIABLE FOR ANY DIRECT, INDIRECT,
+ * INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING,
+ * BUT NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; LOSS
+ * OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED
+ * AND ON ANY THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY,
+ * OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT
+ * OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF
+ * SUCH DAMAGE.
+ */
+
+#ifndef _BITS_FCNTL_H_
+#define _BITS_FCNTL_H_
+
+#include <sys/cdefs.h>
+
+__BEGIN_DECLS
+
+extern int fcntl(int, int, ...);
+
+__END_DECLS
+
+#endif
diff --git a/libc/include/bits/getopt.h b/libc/include/bits/getopt.h
new file mode 100644
index 0000000..7153d48
--- /dev/null
+++ b/libc/include/bits/getopt.h
@@ -0,0 +1,43 @@
+/*
+ * Copyright (C) 2016 The Android Open Source Project
+ * All rights reserved.
+ *
+ * Redistribution and use in source and binary forms, with or without
+ * modification, are permitted provided that the following conditions
+ * are met:
+ *  * Redistributions of source code must retain the above copyright
+ *    notice, this list of conditions and the following disclaimer.
+ *  * Redistributions in binary form must reproduce the above copyright
+ *    notice, this list of conditions and the following disclaimer in
+ *    the documentation and/or other materials provided with the
+ *    distribution.
+ *
+ * THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS
+ * "AS IS" AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT
+ * LIMITED TO, THE IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS
+ * FOR A PARTICULAR PURPOSE ARE DISCLAIMED. IN NO EVENT SHALL THE
+ * COPYRIGHT OWNER OR CONTRIBUTORS BE LIABLE FOR ANY DIRECT, INDIRECT,
+ * INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING,
+ * BUT NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; LOSS
+ * OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED
+ * AND ON ANY THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY,
+ * OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT
+ * OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF
+ * SUCH DAMAGE.
+ */
+
+#ifndef _BITS_GETOPT_H_
+#define _BITS_GETOPT_H_
+
+#include <sys/cdefs.h>
+
+__BEGIN_DECLS
+
+int	 getopt(int, char * const [], const char *);
+
+extern char *optarg;			/* getopt(3) external variables */
+extern int optind, opterr, optopt;
+
+__END_DECLS
+
+#endif
diff --git a/libc/include/bits/ioctl.h b/libc/include/bits/ioctl.h
new file mode 100644
index 0000000..788a4f7
--- /dev/null
+++ b/libc/include/bits/ioctl.h
@@ -0,0 +1,40 @@
+/*
+ * Copyright (C) 2016 The Android Open Source Project
+ * All rights reserved.
+ *
+ * Redistribution and use in source and binary forms, with or without
+ * modification, are permitted provided that the following conditions
+ * are met:
+ *  * Redistributions of source code must retain the above copyright
+ *    notice, this list of conditions and the following disclaimer.
+ *  * Redistributions in binary form must reproduce the above copyright
+ *    notice, this list of conditions and the following disclaimer in
+ *    the documentation and/or other materials provided with the
+ *    distribution.
+ *
+ * THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS
+ * "AS IS" AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT
+ * LIMITED TO, THE IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS
+ * FOR A PARTICULAR PURPOSE ARE DISCLAIMED. IN NO EVENT SHALL THE
+ * COPYRIGHT OWNER OR CONTRIBUTORS BE LIABLE FOR ANY DIRECT, INDIRECT,
+ * INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING,
+ * BUT NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; LOSS
+ * OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED
+ * AND ON ANY THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY,
+ * OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT
+ * OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF
+ * SUCH DAMAGE.
+ */
+
+#ifndef _BITS_IOCTL_H_
+#define _BITS_IOCTL_H_
+
+#include <sys/cdefs.h>
+
+__BEGIN_DECLS
+
+extern int ioctl(int, int, ...);
+
+__END_DECLS
+
+#endif
diff --git a/libc/include/bits/lockf.h b/libc/include/bits/lockf.h
index d814807..a0ba19d 100644
--- a/libc/include/bits/lockf.h
+++ b/libc/include/bits/lockf.h
@@ -30,6 +30,7 @@
 #define _BITS_LOCKF_H_
 
 #include <sys/cdefs.h>
+#include <sys/types.h>
 
 #define F_ULOCK 0
 #define F_LOCK 1
diff --git a/libc/include/bits/strcasecmp.h b/libc/include/bits/strcasecmp.h
new file mode 100644
index 0000000..124f5cd
--- /dev/null
+++ b/libc/include/bits/strcasecmp.h
@@ -0,0 +1,45 @@
+/*
+ * Copyright (C) 2016 The Android Open Source Project
+ * All rights reserved.
+ *
+ * Redistribution and use in source and binary forms, with or without
+ * modification, are permitted provided that the following conditions
+ * are met:
+ *  * Redistributions of source code must retain the above copyright
+ *    notice, this list of conditions and the following disclaimer.
+ *  * Redistributions in binary form must reproduce the above copyright
+ *    notice, this list of conditions and the following disclaimer in
+ *    the documentation and/or other materials provided with the
+ *    distribution.
+ *
+ * THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS
+ * "AS IS" AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT
+ * LIMITED TO, THE IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS
+ * FOR A PARTICULAR PURPOSE ARE DISCLAIMED. IN NO EVENT SHALL THE
+ * COPYRIGHT OWNER OR CONTRIBUTORS BE LIABLE FOR ANY DIRECT, INDIRECT,
+ * INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING,
+ * BUT NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; LOSS
+ * OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED
+ * AND ON ANY THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY,
+ * OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT
+ * OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF
+ * SUCH DAMAGE.
+ */
+
+#ifndef _BITS_STRCASECMP_H_
+#define _BITS_STRCASECMP_H_
+
+#include <sys/cdefs.h>
+#include <sys/types.h>
+#include <xlocale.h>
+
+__BEGIN_DECLS
+
+int strcasecmp(const char*, const char*) __purefunc;
+int strcasecmp_l(const char*, const char*, locale_t) __purefunc;
+int strncasecmp(const char*, const char*, size_t) __purefunc;
+int strncasecmp_l(const char*, const char*, size_t, locale_t) __purefunc;
+
+__END_DECLS
+
+#endif
diff --git a/libc/include/bits/sysconf.h b/libc/include/bits/sysconf.h
new file mode 100644
index 0000000..2cbbb11
--- /dev/null
+++ b/libc/include/bits/sysconf.h
@@ -0,0 +1,196 @@
+/*
+ * Copyright (C) 2008 The Android Open Source Project
+ * All rights reserved.
+ *
+ * Redistribution and use in source and binary forms, with or without
+ * modification, are permitted provided that the following conditions
+ * are met:
+ *  * Redistributions of source code must retain the above copyright
+ *    notice, this list of conditions and the following disclaimer.
+ *  * Redistributions in binary form must reproduce the above copyright
+ *    notice, this list of conditions and the following disclaimer in
+ *    the documentation and/or other materials provided with the
+ *    distribution.
+ *
+ * THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS
+ * "AS IS" AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT
+ * LIMITED TO, THE IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS
+ * FOR A PARTICULAR PURPOSE ARE DISCLAIMED. IN NO EVENT SHALL THE
+ * COPYRIGHT OWNER OR CONTRIBUTORS BE LIABLE FOR ANY DIRECT, INDIRECT,
+ * INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING,
+ * BUT NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; LOSS
+ * OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED
+ * AND ON ANY THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY,
+ * OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT
+ * OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF
+ * SUCH DAMAGE.
+ */
+
+#ifndef _BITS_SYSCONF_H_
+#define _BITS_SYSCONF_H_
+
+#include <sys/cdefs.h>
+
+/* as listed by Posix sysconf() description */
+/* most of these will return -1 and ENOSYS  */
+
+#define _SC_ARG_MAX             0x0000
+#define _SC_BC_BASE_MAX         0x0001
+#define _SC_BC_DIM_MAX          0x0002
+#define _SC_BC_SCALE_MAX        0x0003
+#define _SC_BC_STRING_MAX       0x0004
+#define _SC_CHILD_MAX           0x0005
+#define _SC_CLK_TCK             0x0006
+#define _SC_COLL_WEIGHTS_MAX    0x0007
+#define _SC_EXPR_NEST_MAX       0x0008
+#define _SC_LINE_MAX            0x0009
+#define _SC_NGROUPS_MAX         0x000a
+#define _SC_OPEN_MAX            0x000b
+#define _SC_PASS_MAX            0x000c
+#define _SC_2_C_BIND            0x000d
+#define _SC_2_C_DEV             0x000e
+#define _SC_2_C_VERSION         0x000f  /* Obsolescent in POSIX.1-2008, TODO: remove it. */
+#define _SC_2_CHAR_TERM         0x0010
+#define _SC_2_FORT_DEV          0x0011
+#define _SC_2_FORT_RUN          0x0012
+#define _SC_2_LOCALEDEF         0x0013
+#define _SC_2_SW_DEV            0x0014
+#define _SC_2_UPE               0x0015
+#define _SC_2_VERSION           0x0016
+#define _SC_JOB_CONTROL         0x0017
+#define _SC_SAVED_IDS           0x0018
+#define _SC_VERSION             0x0019
+#define _SC_RE_DUP_MAX          0x001a
+#define _SC_STREAM_MAX          0x001b
+#define _SC_TZNAME_MAX          0x001c
+#define _SC_XOPEN_CRYPT         0x001d
+#define _SC_XOPEN_ENH_I18N      0x001e
+#define _SC_XOPEN_SHM           0x001f
+#define _SC_XOPEN_VERSION       0x0020
+#define _SC_XOPEN_XCU_VERSION   0x0021  /* Obsolescent in POSIX.1-2008, TODO: remove it. */
+#define _SC_XOPEN_REALTIME      0x0022
+#define _SC_XOPEN_REALTIME_THREADS  0x0023
+#define _SC_XOPEN_LEGACY        0x0024
+#define _SC_ATEXIT_MAX          0x0025
+#define _SC_IOV_MAX             0x0026
+#define _SC_PAGESIZE            0x0027
+#define _SC_PAGE_SIZE           0x0028
+#define _SC_XOPEN_UNIX          0x0029
+#define _SC_XBS5_ILP32_OFF32    0x002a  /* Obsolescent in POSIX.1-2008, TODO: remove it. */
+#define _SC_XBS5_ILP32_OFFBIG   0x002b  /* Obsolescent in POSIX.1-2008, TODO: remove it. */
+#define _SC_XBS5_LP64_OFF64     0x002c  /* Obsolescent in POSIX.1-2008, TODO: remove it. */
+#define _SC_XBS5_LPBIG_OFFBIG   0x002d  /* Obsolescent in POSIX.1-2008, TODO: remove it. */
+#define _SC_AIO_LISTIO_MAX      0x002e
+#define _SC_AIO_MAX             0x002f
+#define _SC_AIO_PRIO_DELTA_MAX  0x0030
+#define _SC_DELAYTIMER_MAX      0x0031
+#define _SC_MQ_OPEN_MAX         0x0032
+#define _SC_MQ_PRIO_MAX         0x0033
+#define _SC_RTSIG_MAX           0x0034
+#define _SC_SEM_NSEMS_MAX       0x0035
+#define _SC_SEM_VALUE_MAX       0x0036
+#define _SC_SIGQUEUE_MAX        0x0037
+#define _SC_TIMER_MAX           0x0038
+#define _SC_ASYNCHRONOUS_IO     0x0039
+#define _SC_FSYNC               0x003a
+#define _SC_MAPPED_FILES        0x003b
+#define _SC_MEMLOCK             0x003c
+#define _SC_MEMLOCK_RANGE       0x003d
+#define _SC_MEMORY_PROTECTION   0x003e
+#define _SC_MESSAGE_PASSING     0x003f
+#define _SC_PRIORITIZED_IO      0x0040
+#define _SC_PRIORITY_SCHEDULING 0x0041
+#define _SC_REALTIME_SIGNALS    0x0042
+#define _SC_SEMAPHORES          0x0043
+#define _SC_SHARED_MEMORY_OBJECTS  0x0044
+#define _SC_SYNCHRONIZED_IO     0x0045
+#define _SC_TIMERS              0x0046
+#define _SC_GETGR_R_SIZE_MAX    0x0047
+#define _SC_GETPW_R_SIZE_MAX    0x0048
+#define _SC_LOGIN_NAME_MAX      0x0049
+#define _SC_THREAD_DESTRUCTOR_ITERATIONS  0x004a
+#define _SC_THREAD_KEYS_MAX     0x004b
+#define _SC_THREAD_STACK_MIN    0x004c
+#define _SC_THREAD_THREADS_MAX  0x004d
+#define _SC_TTY_NAME_MAX        0x004e
+
+#define _SC_THREADS                     0x004f
+#define _SC_THREAD_ATTR_STACKADDR       0x0050
+#define _SC_THREAD_ATTR_STACKSIZE       0x0051
+#define _SC_THREAD_PRIORITY_SCHEDULING  0x0052
+#define _SC_THREAD_PRIO_INHERIT         0x0053
+#define _SC_THREAD_PRIO_PROTECT         0x0054
+#define _SC_THREAD_SAFE_FUNCTIONS       0x0055
+
+#define _SC_NPROCESSORS_CONF            0x0060
+#define _SC_NPROCESSORS_ONLN            0x0061
+#define _SC_PHYS_PAGES                  0x0062
+#define _SC_AVPHYS_PAGES                0x0063
+#define _SC_MONOTONIC_CLOCK             0x0064
+
+#define _SC_2_PBS               0x0065
+#define _SC_2_PBS_ACCOUNTING    0x0066
+#define _SC_2_PBS_CHECKPOINT    0x0067
+#define _SC_2_PBS_LOCATE        0x0068
+#define _SC_2_PBS_MESSAGE       0x0069
+#define _SC_2_PBS_TRACK         0x006a
+#define _SC_ADVISORY_INFO       0x006b
+#define _SC_BARRIERS            0x006c
+#define _SC_CLOCK_SELECTION     0x006d
+#define _SC_CPUTIME             0x006e
+#define _SC_HOST_NAME_MAX       0x006f
+#define _SC_IPV6                0x0070
+#define _SC_RAW_SOCKETS         0x0071
+#define _SC_READER_WRITER_LOCKS 0x0072
+#define _SC_REGEXP              0x0073
+#define _SC_SHELL               0x0074
+#define _SC_SPAWN               0x0075
+#define _SC_SPIN_LOCKS          0x0076
+#define _SC_SPORADIC_SERVER     0x0077
+#define _SC_SS_REPL_MAX         0x0078
+#define _SC_SYMLOOP_MAX         0x0079
+#define _SC_THREAD_CPUTIME      0x007a
+#define _SC_THREAD_PROCESS_SHARED       0x007b
+#define _SC_THREAD_ROBUST_PRIO_INHERIT  0x007c
+#define _SC_THREAD_ROBUST_PRIO_PROTECT  0x007d
+#define _SC_THREAD_SPORADIC_SERVER      0x007e
+#define _SC_TIMEOUTS            0x007f
+#define _SC_TRACE               0x0080
+#define _SC_TRACE_EVENT_FILTER  0x0081
+#define _SC_TRACE_EVENT_NAME_MAX  0x0082
+#define _SC_TRACE_INHERIT       0x0083
+#define _SC_TRACE_LOG           0x0084
+#define _SC_TRACE_NAME_MAX      0x0085
+#define _SC_TRACE_SYS_MAX       0x0086
+#define _SC_TRACE_USER_EVENT_MAX  0x0087
+#define _SC_TYPED_MEMORY_OBJECTS  0x0088
+#define _SC_V7_ILP32_OFF32      0x0089
+#define _SC_V7_ILP32_OFFBIG     0x008a
+#define _SC_V7_LP64_OFF64       0x008b
+#define _SC_V7_LPBIG_OFFBIG     0x008c
+#define _SC_XOPEN_STREAMS       0x008d
+#define _SC_XOPEN_UUCP          0x008e
+
+#define _SC_LEVEL1_ICACHE_SIZE      0x008f
+#define _SC_LEVEL1_ICACHE_ASSOC     0x0090
+#define _SC_LEVEL1_ICACHE_LINESIZE  0x0091
+#define _SC_LEVEL1_DCACHE_SIZE      0x0092
+#define _SC_LEVEL1_DCACHE_ASSOC     0x0093
+#define _SC_LEVEL1_DCACHE_LINESIZE  0x0094
+#define _SC_LEVEL2_CACHE_SIZE       0x0095
+#define _SC_LEVEL2_CACHE_ASSOC      0x0096
+#define _SC_LEVEL2_CACHE_LINESIZE   0x0097
+#define _SC_LEVEL3_CACHE_SIZE       0x0098
+#define _SC_LEVEL3_CACHE_ASSOC      0x0099
+#define _SC_LEVEL3_CACHE_LINESIZE   0x009a
+#define _SC_LEVEL4_CACHE_SIZE       0x009b
+#define _SC_LEVEL4_CACHE_ASSOC      0x009c
+#define _SC_LEVEL4_CACHE_LINESIZE   0x009d
+
+__BEGIN_DECLS
+
+long sysconf(int __name);
+
+__END_DECLS
+
+#endif /* _SYS_SYSCONF_H_ */
diff --git a/libc/include/errno.h b/libc/include/errno.h
index 82f4b42..2ff1369 100644
--- a/libc/include/errno.h
+++ b/libc/include/errno.h
@@ -46,10 +46,8 @@
 /* a macro expanding to the errno l-value */
 #define  errno   (*__errno())
 
-#if __ANDROID_API__ < 21
-#include <android/legacy_errno_inlines.h>
-#endif
-
 __END_DECLS
 
+#include <android/legacy_errno_inlines.h>
+
 #endif /* _ERRNO_H */
diff --git a/libc/include/fcntl.h b/libc/include/fcntl.h
index 9d15e92..013d72c 100644
--- a/libc/include/fcntl.h
+++ b/libc/include/fcntl.h
@@ -36,6 +36,8 @@
 #include <linux/stat.h>
 #include <linux/uio.h>
 
+#include <bits/fcntl.h>
+
 #if defined(__USE_GNU) || defined(__USE_BSD)
 #include <bits/lockf.h>
 #endif
@@ -63,14 +65,12 @@
 
 extern int creat(const char*, mode_t);
 extern int creat64(const char*, mode_t);
-extern int fcntl(int, int, ...);
 extern int openat(int, const char*, int, ...);
 extern int openat64(int, const char*, int, ...);
 extern int open(const char*, int, ...);
 extern int open64(const char*, int, ...);
 extern ssize_t splice(int, off64_t*, int, off64_t*, size_t, unsigned int);
 extern ssize_t tee(int, int, size_t, unsigned int);
-extern int unlinkat(int, const char*, int);
 extern ssize_t vmsplice(int, const struct iovec*, size_t, unsigned int);
 
 #if defined(__USE_FILE_OFFSET64)
diff --git a/libc/include/getopt.h b/libc/include/getopt.h
index 4451941..46d2eb7 100644
--- a/libc/include/getopt.h
+++ b/libc/include/getopt.h
@@ -35,9 +35,10 @@
 
 #include <sys/cdefs.h>
 
+#include <bits/getopt.h>
+
 /*
  * GNU-like getopt_long()/getopt_long_only() with 4.4BSD optreset extension.
- * getopt() is declared here too for GNU programs.
  */
 #define no_argument        0
 #define required_argument  1
@@ -62,13 +63,7 @@
 	const struct option *, int *);
 int	getopt_long_only(int, char * const *, const char *,
 	const struct option *, int *);
-#ifndef _GETOPT_DECLARED
-#define	_GETOPT_DECLARED
-int	 getopt(int, char * const [], const char *);
 
-extern char *optarg;			/* getopt(3) external variables */
-extern int optind, opterr, optopt;
-#endif
 #ifndef _OPTRESET_DECLARED
 #define	_OPTRESET_DECLARED
 extern int optreset;			/* getopt(3) external variable */
diff --git a/libc/include/math.h b/libc/include/math.h
index 8e193cb..203968a 100644
--- a/libc/include/math.h
+++ b/libc/include/math.h
@@ -20,12 +20,6 @@
 #include <sys/cdefs.h>
 #include <limits.h>
 
-#if !defined(__BIONIC_NO_MATH_INLINES)
-#define __BIONIC_MATH_INLINE(__def) extern __inline__ __always_inline __attribute__((gnu_inline)) __attribute__((__artificial__)) __def
-#else
-#define __BIONIC_MATH_INLINE(__def)
-#endif
-
 __BEGIN_DECLS
 #pragma GCC visibility push(default)
 
@@ -183,7 +177,6 @@
 
 double	ceil(double);
 double	fabs(double) __pure2;
-__BIONIC_MATH_INLINE(double fabs(double x) { return __builtin_fabs(x); })
 double	floor(double);
 double	fmod(double, double);
 
@@ -302,7 +295,6 @@
 
 float	ceilf(float);
 float	fabsf(float) __pure2;
-__BIONIC_MATH_INLINE(float fabsf(float x) { return __builtin_fabsf(x); })
 float	floorf(float);
 float	fmodf(float, float);
 float	roundf(float);
@@ -390,7 +382,6 @@
 long double	expl(long double);
 long double	expm1l(long double);
 long double	fabsl(long double) __pure2;
-__BIONIC_MATH_INLINE(long double fabsl(long double x) { return __builtin_fabsl(x); })
 long double	fdiml(long double, long double);
 long double	floorl(long double);
 long double	fmal(long double, long double, long double);
diff --git a/libc/include/net/if_ieee1394.h b/libc/include/net/if_ieee1394.h
index 5a61581..2f8a7c3 100644
--- a/libc/include/net/if_ieee1394.h
+++ b/libc/include/net/if_ieee1394.h
@@ -39,6 +39,8 @@
 #ifndef _NET_IF_IEEE1394_H_
 #define _NET_IF_IEEE1394_H_
 
+#include <sys/types.h>
+
 /* hardware address information for arp / nd */
 struct ieee1394_hwaddr {
 	u_int8_t	iha_uid[8];		/* node unique ID */
diff --git a/libc/include/netinet/in_systm.h b/libc/include/netinet/in_systm.h
index ff53fb7..7e474ba 100644
--- a/libc/include/netinet/in_systm.h
+++ b/libc/include/netinet/in_systm.h
@@ -34,6 +34,8 @@
 #ifndef _NETINET_IN_SYSTM_H_
 #define _NETINET_IN_SYSTM_H_
 
+#include <sys/types.h>
+
 /*
  * Miscellaneous internetwork
  * definitions for kernel.
diff --git a/libc/include/netinet/ip6.h b/libc/include/netinet/ip6.h
index aa816c2..aa89186 100644
--- a/libc/include/netinet/ip6.h
+++ b/libc/include/netinet/ip6.h
@@ -64,6 +64,10 @@
 #ifndef _NETINET_IP6_H_
 #define _NETINET_IP6_H_
 
+#include <sys/types.h>
+
+#include <linux/in6.h>
+
 /*
  * Definition for internet protocol version 6.
  * RFC 2460
diff --git a/libc/include/netinet/tcp.h b/libc/include/netinet/tcp.h
index 5601645..e95cc09 100644
--- a/libc/include/netinet/tcp.h
+++ b/libc/include/netinet/tcp.h
@@ -29,6 +29,8 @@
 #ifndef _NETINET_TCP_H
 #define _NETINET_TCP_H
 
+#include <sys/cdefs.h>
+
 #include <linux/tcp.h>
 
 __BEGIN_DECLS
diff --git a/libc/include/nl_types.h b/libc/include/nl_types.h
new file mode 100644
index 0000000..84227bd
--- /dev/null
+++ b/libc/include/nl_types.h
@@ -0,0 +1,48 @@
+/*
+ * Copyright (C) 2016 The Android Open Source Project
+ * All rights reserved.
+ *
+ * Redistribution and use in source and binary forms, with or without
+ * modification, are permitted provided that the following conditions
+ * are met:
+ *  * Redistributions of source code must retain the above copyright
+ *    notice, this list of conditions and the following disclaimer.
+ *  * Redistributions in binary form must reproduce the above copyright
+ *    notice, this list of conditions and the following disclaimer in
+ *    the documentation and/or other materials provided with the
+ *    distribution.
+ *
+ * THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS
+ * "AS IS" AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT
+ * LIMITED TO, THE IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS
+ * FOR A PARTICULAR PURPOSE ARE DISCLAIMED. IN NO EVENT SHALL THE
+ * COPYRIGHT OWNER OR CONTRIBUTORS BE LIABLE FOR ANY DIRECT, INDIRECT,
+ * INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING,
+ * BUT NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; LOSS
+ * OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED
+ * AND ON ANY THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY,
+ * OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT
+ * OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF
+ * SUCH DAMAGE.
+ */
+
+#ifndef _NL_TYPES_H_
+#define _NL_TYPES_H_
+
+#include <sys/cdefs.h>
+
+__BEGIN_DECLS
+
+#define NL_CAT_LOCALE 1
+#define NL_SETD 1
+
+typedef void* nl_catd;
+typedef int nl_item;
+
+nl_catd catopen(const char*, int);
+char* catgets(nl_catd, int, int, const char*);
+int catclose(nl_catd);
+
+__END_DECLS
+
+#endif
diff --git a/libc/include/signal.h b/libc/include/signal.h
index 763bae9..5679402 100644
--- a/libc/include/signal.h
+++ b/libc/include/signal.h
@@ -110,15 +110,15 @@
 
 extern int sigaction(int, const struct sigaction*, struct sigaction*);
 
-extern sighandler_t signal(int, sighandler_t) __INTRODUCED_IN(21);
+__BIONIC_LEGACY_INLINE sighandler_t signal(int, sighandler_t);
 
 extern int siginterrupt(int, int);
 
-extern int sigaddset(sigset_t*, int) __INTRODUCED_IN(21);
-extern int sigdelset(sigset_t*, int) __INTRODUCED_IN(21);
-extern int sigemptyset(sigset_t*) __INTRODUCED_IN(21);
-extern int sigfillset(sigset_t*) __INTRODUCED_IN(21);
-extern int sigismember(const sigset_t*, int) __INTRODUCED_IN(21);
+__BIONIC_LEGACY_INLINE int sigaddset(sigset_t*, int);
+__BIONIC_LEGACY_INLINE int sigdelset(sigset_t*, int);
+__BIONIC_LEGACY_INLINE int sigemptyset(sigset_t*);
+__BIONIC_LEGACY_INLINE int sigfillset(sigset_t*);
+__BIONIC_LEGACY_INLINE int sigismember(const sigset_t*, int);
 
 extern int sigpending(sigset_t*) __nonnull((1));
 extern int sigprocmask(int, const sigset_t*, sigset_t*);
@@ -147,10 +147,8 @@
 extern int sigtimedwait(const sigset_t*, siginfo_t*, const struct timespec*);
 extern int sigwaitinfo(const sigset_t*, siginfo_t*);
 
-#if __ANDROID_API__ < 21
-#include <android/legacy_signal_inlines.h>
-#endif
-
 __END_DECLS
 
+#include <android/legacy_signal_inlines.h>
+
 #endif /* _SIGNAL_H_ */
diff --git a/libc/include/stdlib.h b/libc/include/stdlib.h
index 88930b1..d0fb0e8 100644
--- a/libc/include/stdlib.h
+++ b/libc/include/stdlib.h
@@ -76,10 +76,10 @@
 
 extern int posix_memalign(void **memptr, size_t alignment, size_t size);
 
-extern double atof(const char*) __INTRODUCED_IN(21);
+__BIONIC_LEGACY_INLINE double atof(const char*);
 
 extern double strtod(const char*, char**) __LIBC_ABI_PUBLIC__;
-extern float strtof(const char*, char**) __LIBC_ABI_PUBLIC__ __INTRODUCED_IN(21);
+__BIONIC_LEGACY_INLINE float strtof(const char*, char**) __LIBC_ABI_PUBLIC__;
 extern long double strtold(const char*, char**) __LIBC_ABI_PUBLIC__;
 
 extern long double strtold_l(const char *, char **, locale_t) __LIBC_ABI_PUBLIC__;
@@ -90,9 +90,9 @@
 extern long atol(const char*) __purefunc;
 extern long long atoll(const char*) __purefunc;
 
-extern int abs(int) __pure2 __INTRODUCED_IN(21);
-extern long labs(long) __pure2 __INTRODUCED_IN(21);
-extern long long llabs(long long) __pure2 __INTRODUCED_IN(21);
+__BIONIC_LEGACY_INLINE int abs(int) __pure2;
+__BIONIC_LEGACY_INLINE long labs(long) __pure2;
+__BIONIC_LEGACY_INLINE long long llabs(long long) __pure2;
 
 extern char * realpath(const char *path, char *resolved);
 extern int system(const char *string);
@@ -109,9 +109,9 @@
 
 #define RAND_MAX 0x7fffffff
 
-int rand(void) __INTRODUCED_IN(21);
+__BIONIC_LEGACY_INLINE int rand(void);
 int rand_r(unsigned int*);
-void srand(unsigned int) __INTRODUCED_IN(21);
+__BIONIC_LEGACY_INLINE void srand(unsigned int);
 
 double drand48(void);
 double erand48(unsigned short[3]);
@@ -124,12 +124,12 @@
 void srand48(long);
 
 char* initstate(unsigned int, char*, size_t);
-long random(void) __INTRODUCED_IN(21);
+__BIONIC_LEGACY_INLINE long random(void);
 char* setstate(char*);
-void srandom(unsigned int) __INTRODUCED_IN(21);
+__BIONIC_LEGACY_INLINE void srandom(unsigned int);
 
 int getpt(void);
-int grantpt(int) __INTRODUCED_IN(21);
+__BIONIC_LEGACY_INLINE int grantpt(int);
 int posix_openpt(int);
 char* ptsname(int);
 int ptsname_r(int, char*, size_t);
@@ -174,10 +174,6 @@
 extern size_t __ctype_get_mb_cur_max(void);
 #define MB_CUR_MAX __ctype_get_mb_cur_max()
 
-#if __ANDROID_API__ < 21
-#include <android/legacy_stdlib_inlines.h>
-#endif
-
 #if defined(__BIONIC_FORTIFY)
 
 extern char* __realpath_real(const char*, char*) __RENAME(realpath);
@@ -201,4 +197,6 @@
 
 __END_DECLS
 
+#include <android/legacy_stdlib_inlines.h>
+
 #endif /* _STDLIB_H */
diff --git a/libc/include/string.h b/libc/include/string.h
index 32d4a18..dada52b 100644
--- a/libc/include/string.h
+++ b/libc/include/string.h
@@ -33,6 +33,8 @@
 #include <stddef.h>
 #include <xlocale.h>
 
+#include <bits/strcasecmp.h>
+
 __BEGIN_DECLS
 
 #if defined(__USE_BSD)
@@ -72,11 +74,6 @@
 extern char*  strcpy(char* __restrict, const char* __restrict);
 extern char*  strcat(char* __restrict, const char* __restrict);
 
-int strcasecmp(const char*, const char*) __purefunc;
-int strcasecmp_l(const char*, const char*, locale_t) __purefunc;
-int strncasecmp(const char*, const char*, size_t) __purefunc;
-int strncasecmp_l(const char*, const char*, size_t, locale_t) __purefunc;
-
 extern char*  strdup(const char *);
 
 extern char*  strstr(const char *, const char *) __purefunc;
diff --git a/libc/include/strings.h b/libc/include/strings.h
index 1253006..1200e77 100644
--- a/libc/include/strings.h
+++ b/libc/include/strings.h
@@ -43,6 +43,8 @@
 #include <sys/cdefs.h>
 #include <xlocale.h>
 
+#include <bits/strcasecmp.h>
+
 __BEGIN_DECLS
 #if defined(__BIONIC_FORTIFY)
 #define bcopy(b1, b2, len) (void)(__builtin___memmove_chk((b2), (b1), (len), __bos0(b2)))
@@ -54,11 +56,6 @@
 
 int ffs(int);
 
-int strcasecmp(const char*, const char*) __purefunc;
-int strcasecmp_l(const char*, const char*, locale_t) __purefunc;
-int strncasecmp(const char*, const char*, size_t) __purefunc;
-int strncasecmp_l(const char*, const char*, size_t, locale_t) __purefunc;
-
 __END_DECLS
 
 #endif /* !defined(_STRINGS_H_) */
diff --git a/libc/include/sys/atomics.h b/libc/include/sys/atomics.h
index 38ab366..b9b2ba3 100644
--- a/libc/include/sys/atomics.h
+++ b/libc/include/sys/atomics.h
@@ -38,8 +38,6 @@
  * sys/atomics.h header was removed, so we'll just add these somewhere we can be
  * sure they will be included.
  */
-#if __ANDROID_API__ < 21
 #include <android/legacy_sys_atomics_inlines.h>
-#endif
 
 #endif /* _SYS_ATOMICS_H_ */
diff --git a/libc/include/sys/cdefs.h b/libc/include/sys/cdefs.h
index f51942b..2bd058e 100644
--- a/libc/include/sys/cdefs.h
+++ b/libc/include/sys/cdefs.h
@@ -443,6 +443,12 @@
 /* Used to rename functions so that the compiler emits a call to 'x' rather than the function this was applied to. */
 #define __RENAME(x) __asm__(#x)
 
+#if __ANDROID_API__ < 21
+#define __BIONIC_LEGACY_INLINE static __inline
+#else
+#define __BIONIC_LEGACY_INLINE extern
+#endif
+
 #ifdef __clang__
 #define __AVAILABILITY(...) __attribute__((availability(android,__VA_ARGS__)))
 #define __INTRODUCED_IN(api_level) __AVAILABILITY(introduced=api_level)
diff --git a/libc/include/sys/ioctl.h b/libc/include/sys/ioctl.h
index a1014dc..ed261f2 100644
--- a/libc/include/sys/ioctl.h
+++ b/libc/include/sys/ioctl.h
@@ -40,10 +40,6 @@
 #include <sys/ioctl_compat.h>
 #include <linux/tty.h>
 
-__BEGIN_DECLS
-
-extern int ioctl(int, int, ...);
-
-__END_DECLS
+#include <bits/ioctl.h>
 
 #endif /* _SYS_IOCTL_H_ */
diff --git a/libc/include/sys/mman.h b/libc/include/sys/mman.h
index a19ceb5..170300a 100644
--- a/libc/include/sys/mman.h
+++ b/libc/include/sys/mman.h
@@ -65,13 +65,10 @@
 extern int munlockall(void);
 extern int mlock(const void*, size_t);
 extern int munlock(const void*, size_t);
-extern int madvise(void*, size_t, int);
-
-extern int mlock(const void*, size_t);
-extern int munlock(const void*, size_t);
 
 extern int mincore(void*, size_t, unsigned char*);
 
+extern int madvise(void*, size_t, int);
 extern int posix_madvise(void*, size_t, int);
 
 __END_DECLS
diff --git a/libc/include/sys/quota.h b/libc/include/sys/quota.h
new file mode 100644
index 0000000..f4f6447
--- /dev/null
+++ b/libc/include/sys/quota.h
@@ -0,0 +1,47 @@
+/*
+ * Copyright (C) 2016 The Android Open Source Project
+ * All rights reserved.
+ *
+ * Redistribution and use in source and binary forms, with or without
+ * modification, are permitted provided that the following conditions
+ * are met:
+ *  * Redistributions of source code must retain the above copyright
+ *    notice, this list of conditions and the following disclaimer.
+ *  * Redistributions in binary form must reproduce the above copyright
+ *    notice, this list of conditions and the following disclaimer in
+ *    the documentation and/or other materials provided with the
+ *    distribution.
+ *
+ * THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS
+ * "AS IS" AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT
+ * LIMITED TO, THE IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS
+ * FOR A PARTICULAR PURPOSE ARE DISCLAIMED. IN NO EVENT SHALL THE
+ * COPYRIGHT OWNER OR CONTRIBUTORS BE LIABLE FOR ANY DIRECT, INDIRECT,
+ * INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING,
+ * BUT NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; LOSS
+ * OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED
+ * AND ON ANY THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY,
+ * OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT
+ * OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF
+ * SUCH DAMAGE.
+ */
+
+#ifndef _SYS_QUOTA_H_
+#define _SYS_QUOTA_H_
+
+#include <sys/cdefs.h>
+
+// The uapi header uses different names from userspace, oddly.
+#define if_dqblk dqblk
+#define if_dqinfo dqinfo
+#include <linux/quota.h>
+#undef if_dqblk
+#undef if_dqinfo
+
+__BEGIN_DECLS
+
+int quotactl(int, const char*, int, char*);
+
+__END_DECLS
+
+#endif
diff --git a/libc/include/sys/stat.h b/libc/include/sys/stat.h
index 86668f6..ae85f62 100644
--- a/libc/include/sys/stat.h
+++ b/libc/include/sys/stat.h
@@ -177,7 +177,7 @@
 }
 #endif /* defined(__BIONIC_FORTIFY) */
 
-extern int mkfifo(const char*, mode_t) __INTRODUCED_IN(21);
+__BIONIC_LEGACY_INLINE int mkfifo(const char*, mode_t);
 extern int mkfifoat(int, const char*, mode_t);
 
 extern int fchmodat(int, const char*, mode_t, int);
@@ -189,10 +189,8 @@
 extern int utimensat(int fd, const char *path, const struct timespec times[2], int flags);
 extern int futimens(int fd, const struct timespec times[2]);
 
-#if __ANDROID_API__ < 21
-#include <android/legacy_sys_stat_inlines.h>
-#endif
-
 __END_DECLS
 
+#include <android/legacy_sys_stat_inlines.h>
+
 #endif /* _SYS_STAT_H_ */
diff --git a/libc/include/sys/sysconf.h b/libc/include/sys/sysconf.h
index ca32132..c9895f2 100644
--- a/libc/include/sys/sysconf.h
+++ b/libc/include/sys/sysconf.h
@@ -25,171 +25,9 @@
  * OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF
  * SUCH DAMAGE.
  */
-#ifndef _SYS_SYSCONF_H_
-#define _SYS_SYSCONF_H_
 
-#include <sys/cdefs.h>
+// This file used to contain the declarations of sysconf and its associated constants.
+// No standard mentions a <sys/sysconf.h>, but there are enough users in vendor (and potential ones
+// in the NDK) to warrant not breaking source compatibility.
 
-__BEGIN_DECLS
-
-/* as listed by Posix sysconf() description */
-/* most of these will return -1 and ENOSYS  */
-
-#define _SC_ARG_MAX             0x0000
-#define _SC_BC_BASE_MAX         0x0001
-#define _SC_BC_DIM_MAX          0x0002
-#define _SC_BC_SCALE_MAX        0x0003
-#define _SC_BC_STRING_MAX       0x0004
-#define _SC_CHILD_MAX           0x0005
-#define _SC_CLK_TCK             0x0006
-#define _SC_COLL_WEIGHTS_MAX    0x0007
-#define _SC_EXPR_NEST_MAX       0x0008
-#define _SC_LINE_MAX            0x0009
-#define _SC_NGROUPS_MAX         0x000a
-#define _SC_OPEN_MAX            0x000b
-#define _SC_PASS_MAX            0x000c
-#define _SC_2_C_BIND            0x000d
-#define _SC_2_C_DEV             0x000e
-#define _SC_2_C_VERSION         0x000f  /* Obsolescent in POSIX.1-2008, TODO: remove it. */
-#define _SC_2_CHAR_TERM         0x0010
-#define _SC_2_FORT_DEV          0x0011
-#define _SC_2_FORT_RUN          0x0012
-#define _SC_2_LOCALEDEF         0x0013
-#define _SC_2_SW_DEV            0x0014
-#define _SC_2_UPE               0x0015
-#define _SC_2_VERSION           0x0016
-#define _SC_JOB_CONTROL         0x0017
-#define _SC_SAVED_IDS           0x0018
-#define _SC_VERSION             0x0019
-#define _SC_RE_DUP_MAX          0x001a
-#define _SC_STREAM_MAX          0x001b
-#define _SC_TZNAME_MAX          0x001c
-#define _SC_XOPEN_CRYPT         0x001d
-#define _SC_XOPEN_ENH_I18N      0x001e
-#define _SC_XOPEN_SHM           0x001f
-#define _SC_XOPEN_VERSION       0x0020
-#define _SC_XOPEN_XCU_VERSION   0x0021  /* Obsolescent in POSIX.1-2008, TODO: remove it. */
-#define _SC_XOPEN_REALTIME      0x0022
-#define _SC_XOPEN_REALTIME_THREADS  0x0023
-#define _SC_XOPEN_LEGACY        0x0024
-#define _SC_ATEXIT_MAX          0x0025
-#define _SC_IOV_MAX             0x0026
-#define _SC_PAGESIZE            0x0027
-#define _SC_PAGE_SIZE           0x0028
-#define _SC_XOPEN_UNIX          0x0029
-#define _SC_XBS5_ILP32_OFF32    0x002a  /* Obsolescent in POSIX.1-2008, TODO: remove it. */
-#define _SC_XBS5_ILP32_OFFBIG   0x002b  /* Obsolescent in POSIX.1-2008, TODO: remove it. */
-#define _SC_XBS5_LP64_OFF64     0x002c  /* Obsolescent in POSIX.1-2008, TODO: remove it. */
-#define _SC_XBS5_LPBIG_OFFBIG   0x002d  /* Obsolescent in POSIX.1-2008, TODO: remove it. */
-#define _SC_AIO_LISTIO_MAX      0x002e
-#define _SC_AIO_MAX             0x002f
-#define _SC_AIO_PRIO_DELTA_MAX  0x0030
-#define _SC_DELAYTIMER_MAX      0x0031
-#define _SC_MQ_OPEN_MAX         0x0032
-#define _SC_MQ_PRIO_MAX         0x0033
-#define _SC_RTSIG_MAX           0x0034
-#define _SC_SEM_NSEMS_MAX       0x0035
-#define _SC_SEM_VALUE_MAX       0x0036
-#define _SC_SIGQUEUE_MAX        0x0037
-#define _SC_TIMER_MAX           0x0038
-#define _SC_ASYNCHRONOUS_IO     0x0039
-#define _SC_FSYNC               0x003a
-#define _SC_MAPPED_FILES        0x003b
-#define _SC_MEMLOCK             0x003c
-#define _SC_MEMLOCK_RANGE       0x003d
-#define _SC_MEMORY_PROTECTION   0x003e
-#define _SC_MESSAGE_PASSING     0x003f
-#define _SC_PRIORITIZED_IO      0x0040
-#define _SC_PRIORITY_SCHEDULING 0x0041
-#define _SC_REALTIME_SIGNALS    0x0042
-#define _SC_SEMAPHORES          0x0043
-#define _SC_SHARED_MEMORY_OBJECTS  0x0044
-#define _SC_SYNCHRONIZED_IO     0x0045
-#define _SC_TIMERS              0x0046
-#define _SC_GETGR_R_SIZE_MAX    0x0047
-#define _SC_GETPW_R_SIZE_MAX    0x0048
-#define _SC_LOGIN_NAME_MAX      0x0049
-#define _SC_THREAD_DESTRUCTOR_ITERATIONS  0x004a
-#define _SC_THREAD_KEYS_MAX     0x004b
-#define _SC_THREAD_STACK_MIN    0x004c
-#define _SC_THREAD_THREADS_MAX  0x004d
-#define _SC_TTY_NAME_MAX        0x004e
-
-#define _SC_THREADS                     0x004f
-#define _SC_THREAD_ATTR_STACKADDR       0x0050
-#define _SC_THREAD_ATTR_STACKSIZE       0x0051
-#define _SC_THREAD_PRIORITY_SCHEDULING  0x0052
-#define _SC_THREAD_PRIO_INHERIT         0x0053
-#define _SC_THREAD_PRIO_PROTECT         0x0054
-#define _SC_THREAD_SAFE_FUNCTIONS       0x0055
-
-#define _SC_NPROCESSORS_CONF            0x0060
-#define _SC_NPROCESSORS_ONLN            0x0061
-#define _SC_PHYS_PAGES                  0x0062
-#define _SC_AVPHYS_PAGES                0x0063
-#define _SC_MONOTONIC_CLOCK             0x0064
-
-#define _SC_2_PBS               0x0065
-#define _SC_2_PBS_ACCOUNTING    0x0066
-#define _SC_2_PBS_CHECKPOINT    0x0067
-#define _SC_2_PBS_LOCATE        0x0068
-#define _SC_2_PBS_MESSAGE       0x0069
-#define _SC_2_PBS_TRACK         0x006a
-#define _SC_ADVISORY_INFO       0x006b
-#define _SC_BARRIERS            0x006c
-#define _SC_CLOCK_SELECTION     0x006d
-#define _SC_CPUTIME             0x006e
-#define _SC_HOST_NAME_MAX       0x006f
-#define _SC_IPV6                0x0070
-#define _SC_RAW_SOCKETS         0x0071
-#define _SC_READER_WRITER_LOCKS 0x0072
-#define _SC_REGEXP              0x0073
-#define _SC_SHELL               0x0074
-#define _SC_SPAWN               0x0075
-#define _SC_SPIN_LOCKS          0x0076
-#define _SC_SPORADIC_SERVER     0x0077
-#define _SC_SS_REPL_MAX         0x0078
-#define _SC_SYMLOOP_MAX         0x0079
-#define _SC_THREAD_CPUTIME      0x007a
-#define _SC_THREAD_PROCESS_SHARED       0x007b
-#define _SC_THREAD_ROBUST_PRIO_INHERIT  0x007c
-#define _SC_THREAD_ROBUST_PRIO_PROTECT  0x007d
-#define _SC_THREAD_SPORADIC_SERVER      0x007e
-#define _SC_TIMEOUTS            0x007f
-#define _SC_TRACE               0x0080
-#define _SC_TRACE_EVENT_FILTER  0x0081
-#define _SC_TRACE_EVENT_NAME_MAX  0x0082
-#define _SC_TRACE_INHERIT       0x0083
-#define _SC_TRACE_LOG           0x0084
-#define _SC_TRACE_NAME_MAX      0x0085
-#define _SC_TRACE_SYS_MAX       0x0086
-#define _SC_TRACE_USER_EVENT_MAX  0x0087
-#define _SC_TYPED_MEMORY_OBJECTS  0x0088
-#define _SC_V7_ILP32_OFF32      0x0089
-#define _SC_V7_ILP32_OFFBIG     0x008a
-#define _SC_V7_LP64_OFF64       0x008b
-#define _SC_V7_LPBIG_OFFBIG     0x008c
-#define _SC_XOPEN_STREAMS       0x008d
-#define _SC_XOPEN_UUCP          0x008e
-
-#define _SC_LEVEL1_ICACHE_SIZE      0x008f
-#define _SC_LEVEL1_ICACHE_ASSOC     0x0090
-#define _SC_LEVEL1_ICACHE_LINESIZE  0x0091
-#define _SC_LEVEL1_DCACHE_SIZE      0x0092
-#define _SC_LEVEL1_DCACHE_ASSOC     0x0093
-#define _SC_LEVEL1_DCACHE_LINESIZE  0x0094
-#define _SC_LEVEL2_CACHE_SIZE       0x0095
-#define _SC_LEVEL2_CACHE_ASSOC      0x0096
-#define _SC_LEVEL2_CACHE_LINESIZE   0x0097
-#define _SC_LEVEL3_CACHE_SIZE       0x0098
-#define _SC_LEVEL3_CACHE_ASSOC      0x0099
-#define _SC_LEVEL3_CACHE_LINESIZE   0x009a
-#define _SC_LEVEL4_CACHE_SIZE       0x009b
-#define _SC_LEVEL4_CACHE_ASSOC      0x009c
-#define _SC_LEVEL4_CACHE_LINESIZE   0x009d
-
-long sysconf(int);
-
-__END_DECLS
-
-#endif /* _SYS_SYSCONF_H_ */
+#include <bits/sysconf.h>
diff --git a/libc/include/termios.h b/libc/include/termios.h
index 683fde2..e604747 100644
--- a/libc/include/termios.h
+++ b/libc/include/termios.h
@@ -35,24 +35,22 @@
 
 __BEGIN_DECLS
 
-#if __ANDROID_API__ >= 21
-speed_t cfgetispeed(const struct termios*);
-speed_t cfgetospeed(const struct termios*);
-void cfmakeraw(struct termios*);
-int cfsetispeed(struct termios*, speed_t);
-int cfsetospeed(struct termios*, speed_t);
-int cfsetspeed(struct termios*, speed_t);
-int tcdrain(int);
-int tcflow(int, int);
-int tcflush(int, int);
-int tcgetattr(int, struct termios*);
-pid_t tcgetsid(int);
-int tcsendbreak(int, int);
-int tcsetattr(int, int, const struct termios*);
-#else
-#include <android/legacy_termios_inlines.h>
-#endif
+__BIONIC_LEGACY_INLINE speed_t cfgetispeed(const struct termios*);
+__BIONIC_LEGACY_INLINE speed_t cfgetospeed(const struct termios*);
+__BIONIC_LEGACY_INLINE void cfmakeraw(struct termios*);
+__BIONIC_LEGACY_INLINE int cfsetispeed(struct termios*, speed_t);
+__BIONIC_LEGACY_INLINE int cfsetospeed(struct termios*, speed_t);
+__BIONIC_LEGACY_INLINE int cfsetspeed(struct termios*, speed_t);
+__BIONIC_LEGACY_INLINE int tcdrain(int);
+__BIONIC_LEGACY_INLINE int tcflow(int, int);
+__BIONIC_LEGACY_INLINE int tcflush(int, int);
+__BIONIC_LEGACY_INLINE int tcgetattr(int, struct termios*);
+__BIONIC_LEGACY_INLINE pid_t tcgetsid(int);
+__BIONIC_LEGACY_INLINE int tcsendbreak(int, int);
+__BIONIC_LEGACY_INLINE int tcsetattr(int, int, const struct termios*);
 
 __END_DECLS
 
+#include <android/legacy_termios_inlines.h>
+
 #endif /* _TERMIOS_H_ */
diff --git a/libc/include/unistd.h b/libc/include/unistd.h
index 2d62c1f..ea6c8a1 100644
--- a/libc/include/unistd.h
+++ b/libc/include/unistd.h
@@ -33,10 +33,13 @@
 #include <sys/cdefs.h>
 #include <sys/types.h>
 #include <sys/select.h>
-#include <sys/sysconf.h>
 
+#include <bits/fcntl.h>
+#include <bits/getopt.h>
+#include <bits/ioctl.h>
 #include <bits/lockf.h>
 #include <bits/posix_limits.h>
+#include <bits/sysconf.h>
 
 __BEGIN_DECLS
 
@@ -161,8 +164,6 @@
 extern int dup(int __oldfd);
 extern int dup2(int __oldfd, int __newfd);
 extern int dup3(int __oldfd, int __newfd, int __flags) __INTRODUCED_IN(21);
-extern int fcntl(int __fd, int __cmd, ...);
-extern int ioctl(int __fd, int __request, ...);
 extern int fsync(int __fd);
 extern int fdatasync(int __fd) __INTRODUCED_IN(9);
 
@@ -207,18 +208,12 @@
 extern int brk(void* __addr);
 extern void* sbrk(ptrdiff_t __increment);
 
-extern int getopt(int __argc, char* const* __argv, const char* __argstring);
-extern char* optarg;
-extern int optind, opterr, optopt;
-
 extern int isatty(int __fd);
 extern char* ttyname(int __fd);
 extern int ttyname_r(int __fd, char* __buf, size_t __buflen) __INTRODUCED_IN(8);
 
 extern int acct(const char* __filepath);
 
-long sysconf(int __name);
-
 #if __ANDROID_API__ >= 21
 int getpagesize(void);
 #else
diff --git a/libc/include/wchar.h b/libc/include/wchar.h
index 0a94cee..fe068be 100644
--- a/libc/include/wchar.h
+++ b/libc/include/wchar.h
@@ -97,7 +97,6 @@
 extern size_t            mbrtowc(wchar_t *, const char *, size_t, mbstate_t *);
 extern size_t mbsrtowcs(wchar_t*, const char**, size_t, mbstate_t*);
 extern size_t mbsnrtowcs(wchar_t*, const char**, size_t, size_t, mbstate_t*);
-extern size_t            mbstowcs(wchar_t *, const char *, size_t);
 extern wint_t            putwc(wchar_t, FILE *);
 extern wint_t            putwchar(wchar_t);
 extern int               swprintf(wchar_t *, size_t, const wchar_t *, ...);
diff --git a/libc/libc.arm.brillo.map b/libc/libc.arm.brillo.map
index 2d286af..541dbb2 100644
--- a/libc/libc.arm.brillo.map
+++ b/libc/libc.arm.brillo.map
@@ -1273,10 +1273,14 @@
 
 LIBC_O {
   global:
+    catclose;
+    catgets;
+    catopen;
     getdomainname;
     getsubopt;
     hasmntopt;
     pthread_getname_np;
+    quotactl;
     setdomainname;
     sighold;
     sigignore;
@@ -1430,7 +1434,7 @@
     __swrite; # arm x86 mips
     __swsetup; # arm x86 mips
     __truncdfsf2; # arm
-    __udivdi3; # arm mips
+    __udivdi3; # arm x86 mips
     __udivsi3; # arm
     __unorddf2; # arm
     __unordsf2; # arm
diff --git a/libc/libc.arm.map b/libc/libc.arm.map
index 40f645c..1784b95 100644
--- a/libc/libc.arm.map
+++ b/libc/libc.arm.map
@@ -1273,10 +1273,14 @@
 
 LIBC_O {
   global:
+    catclose;
+    catgets;
+    catopen;
     getdomainname;
     getsubopt;
     hasmntopt;
     pthread_getname_np;
+    quotactl;
     setdomainname;
     sighold;
     sigignore;
@@ -1441,7 +1445,7 @@
     __swrite; # arm x86 mips
     __swsetup; # arm x86 mips
     __truncdfsf2; # arm
-    __udivdi3; # arm mips
+    __udivdi3; # arm x86 mips
     __udivsi3; # arm
     __unorddf2; # arm
     __unordsf2; # arm
diff --git a/libc/libc.arm64.map b/libc/libc.arm64.map
index 61bff70..7daa557 100644
--- a/libc/libc.arm64.map
+++ b/libc/libc.arm64.map
@@ -1195,10 +1195,14 @@
 
 LIBC_O {
   global:
+    catclose;
+    catgets;
+    catopen;
     getdomainname;
     getsubopt;
     hasmntopt;
     pthread_getname_np;
+    quotactl;
     setdomainname;
     sighold;
     sigignore;
diff --git a/libc/libc.map.txt b/libc/libc.map.txt
index d293264..f51c5d3 100644
--- a/libc/libc.map.txt
+++ b/libc/libc.map.txt
@@ -207,7 +207,6 @@
     __timer_getoverrun; # arm x86 mips
     __timer_gettime; # arm x86 mips
     __timer_settime; # arm x86 mips
-    __udivdi3; # x86
     __umask_chk;
     __vsnprintf_chk;
     __vsprintf_chk;
@@ -1299,10 +1298,14 @@
 
 LIBC_O {
   global:
+    catclose;
+    catgets;
+    catopen;
     getdomainname;
     getsubopt;
     hasmntopt;
     pthread_getname_np;
+    quotactl;
     setdomainname;
     sighold;
     sigignore;
@@ -1467,7 +1470,7 @@
     __swrite; # arm x86 mips
     __swsetup; # arm x86 mips
     __truncdfsf2; # arm
-    __udivdi3; # arm mips
+    __udivdi3; # arm x86 mips
     __udivsi3; # arm
     __umoddi3; # x86 mips
     __unorddf2; # arm
diff --git a/libc/libc.mips.brillo.map b/libc/libc.mips.brillo.map
index 5c10069..953fc29 100644
--- a/libc/libc.mips.brillo.map
+++ b/libc/libc.mips.brillo.map
@@ -1257,10 +1257,14 @@
 
 LIBC_O {
   global:
+    catclose;
+    catgets;
+    catopen;
     getdomainname;
     getsubopt;
     hasmntopt;
     pthread_getname_np;
+    quotactl;
     setdomainname;
     sighold;
     sigignore;
@@ -1290,7 +1294,7 @@
     __swbuf; # arm x86 mips
     __swrite; # arm x86 mips
     __swsetup; # arm x86 mips
-    __udivdi3; # arm mips
+    __udivdi3; # arm x86 mips
     __umoddi3; # x86 mips
     _fwalk; # arm x86 mips
     android_getaddrinfofornet;
diff --git a/libc/libc.mips.map b/libc/libc.mips.map
index baee8fb..90db79d 100644
--- a/libc/libc.mips.map
+++ b/libc/libc.mips.map
@@ -1257,10 +1257,14 @@
 
 LIBC_O {
   global:
+    catclose;
+    catgets;
+    catopen;
     getdomainname;
     getsubopt;
     hasmntopt;
     pthread_getname_np;
+    quotactl;
     setdomainname;
     sighold;
     sigignore;
@@ -1301,7 +1305,7 @@
     __swbuf; # arm x86 mips
     __swrite; # arm x86 mips
     __swsetup; # arm x86 mips
-    __udivdi3; # arm mips
+    __udivdi3; # arm x86 mips
     __umoddi3; # x86 mips
     __wait4; # arm x86 mips nobrillo
     _fwalk; # arm x86 mips
diff --git a/libc/libc.mips64.map b/libc/libc.mips64.map
index 61bff70..7daa557 100644
--- a/libc/libc.mips64.map
+++ b/libc/libc.mips64.map
@@ -1195,10 +1195,14 @@
 
 LIBC_O {
   global:
+    catclose;
+    catgets;
+    catopen;
     getdomainname;
     getsubopt;
     hasmntopt;
     pthread_getname_np;
+    quotactl;
     setdomainname;
     sighold;
     sigignore;
diff --git a/libc/libc.x86.brillo.map b/libc/libc.x86.brillo.map
index 587cf74..9f6cc52 100644
--- a/libc/libc.x86.brillo.map
+++ b/libc/libc.x86.brillo.map
@@ -203,7 +203,6 @@
     __timer_getoverrun; # arm x86 mips
     __timer_gettime; # arm x86 mips
     __timer_settime; # arm x86 mips
-    __udivdi3; # x86
     __umask_chk;
     __vsnprintf_chk;
     __vsprintf_chk;
@@ -1256,10 +1255,14 @@
 
 LIBC_O {
   global:
+    catclose;
+    catgets;
+    catopen;
     getdomainname;
     getsubopt;
     hasmntopt;
     pthread_getname_np;
+    quotactl;
     setdomainname;
     sighold;
     sigignore;
@@ -1290,6 +1293,7 @@
     __swbuf; # arm x86 mips
     __swrite; # arm x86 mips
     __swsetup; # arm x86 mips
+    __udivdi3; # arm x86 mips
     __umoddi3; # x86 mips
     _fwalk; # arm x86 mips
     android_getaddrinfofornet;
diff --git a/libc/libc.x86.map b/libc/libc.x86.map
index 9a38ee9..4443731 100644
--- a/libc/libc.x86.map
+++ b/libc/libc.x86.map
@@ -203,7 +203,6 @@
     __timer_getoverrun; # arm x86 mips
     __timer_gettime; # arm x86 mips
     __timer_settime; # arm x86 mips
-    __udivdi3; # x86
     __umask_chk;
     __vsnprintf_chk;
     __vsprintf_chk;
@@ -1256,10 +1255,14 @@
 
 LIBC_O {
   global:
+    catclose;
+    catgets;
+    catopen;
     getdomainname;
     getsubopt;
     hasmntopt;
     pthread_getname_np;
+    quotactl;
     setdomainname;
     sighold;
     sigignore;
@@ -1301,6 +1304,7 @@
     __swbuf; # arm x86 mips
     __swrite; # arm x86 mips
     __swsetup; # arm x86 mips
+    __udivdi3; # arm x86 mips
     __umoddi3; # x86 mips
     __wait4; # arm x86 mips nobrillo
     _fwalk; # arm x86 mips
diff --git a/libc/libc.x86_64.map b/libc/libc.x86_64.map
index 61bff70..7daa557 100644
--- a/libc/libc.x86_64.map
+++ b/libc/libc.x86_64.map
@@ -1195,10 +1195,14 @@
 
 LIBC_O {
   global:
+    catclose;
+    catgets;
+    catopen;
     getdomainname;
     getsubopt;
     hasmntopt;
     pthread_getname_np;
+    quotactl;
     setdomainname;
     sighold;
     sigignore;
diff --git a/libc/malloc_debug/BacktraceData.cpp b/libc/malloc_debug/BacktraceData.cpp
index 400e282..3d46bf0 100644
--- a/libc/malloc_debug/BacktraceData.cpp
+++ b/libc/malloc_debug/BacktraceData.cpp
@@ -41,27 +41,24 @@
 #include "debug_log.h"
 #include "malloc_debug.h"
 
-BacktraceData::BacktraceData(const Config& config, size_t* offset) {
+static void EnableToggle(int, siginfo_t*, void*) {
+  if (g_debug->backtrace->enabled()) {
+    g_debug->backtrace->set_enabled(false);
+  } else {
+    g_debug->backtrace->set_enabled(true);
+  }
+}
+
+BacktraceData::BacktraceData(DebugData* debug_data, const Config& config, size_t* offset)
+    : 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);
 }
 
-static BacktraceData* g_backtrace_data = nullptr;
-
-static void EnableToggle(int, siginfo_t*, void*) {
-  if (g_backtrace_data->enabled()) {
-    g_backtrace_data->set_enabled(false);
-  } else {
-    g_backtrace_data->set_enabled(true);
-  }
-}
-
 bool BacktraceData::Initialize(const Config& config) {
   enabled_ = config.backtrace_enabled;
   if (config.backtrace_enable_on_signal) {
-    g_backtrace_data = this;
-
     struct sigaction enable_act;
     memset(&enable_act, 0, sizeof(enable_act));
 
diff --git a/libc/malloc_debug/BacktraceData.h b/libc/malloc_debug/BacktraceData.h
index 842e372..dbc3989 100644
--- a/libc/malloc_debug/BacktraceData.h
+++ b/libc/malloc_debug/BacktraceData.h
@@ -33,12 +33,14 @@
 
 #include <private/bionic_macros.h>
 
+#include "OptionData.h"
+
 // Forward declarations.
 struct Config;
 
-class BacktraceData {
+class BacktraceData : public OptionData {
  public:
-  BacktraceData(const Config& config, size_t* offset);
+  BacktraceData(DebugData* debug_data, const Config& config, size_t* offset);
   virtual ~BacktraceData() = default;
 
   bool Initialize(const Config& config);
diff --git a/libc/malloc_debug/Config.cpp b/libc/malloc_debug/Config.cpp
index ded618c..cc60086 100644
--- a/libc/malloc_debug/Config.cpp
+++ b/libc/malloc_debug/Config.cpp
@@ -273,7 +273,7 @@
   fill_free_value = DEFAULT_FILL_FREE_VALUE;
   front_guard_value = DEFAULT_FRONT_GUARD_VALUE;
   rear_guard_value = DEFAULT_REAR_GUARD_VALUE;
-  backtrace_signal = SIGRTMIN + 10;
+  backtrace_signal = SIGRTMAX - 19;
   free_track_backtrace_num_frames = 16;
 
   // Parse the options are of the format:
diff --git a/libc/malloc_debug/Config.h b/libc/malloc_debug/Config.h
index cb1de5a..3ee93b2 100644
--- a/libc/malloc_debug/Config.h
+++ b/libc/malloc_debug/Config.h
@@ -49,8 +49,8 @@
 constexpr size_t MINIMUM_ALIGNMENT_BYTES = 8;
 #endif
 
-// If only one or more of these options is set, then no special header is needed.
-constexpr uint64_t NO_HEADER_OPTIONS = FILL_ON_ALLOC | FILL_ON_FREE | EXPAND_ALLOC;
+// If one or more of these options is set, then a special header is needed.
+constexpr uint64_t HEADER_OPTIONS = FRONT_GUARD | REAR_GUARD | BACKTRACE | FREE_TRACK | LEAK_TRACK;
 
 struct Config {
   bool SetFromProperties();
diff --git a/libc/malloc_debug/DebugData.cpp b/libc/malloc_debug/DebugData.cpp
index 0447566..58cbbcb 100644
--- a/libc/malloc_debug/DebugData.cpp
+++ b/libc/malloc_debug/DebugData.cpp
@@ -43,37 +43,37 @@
   }
 
   // Check to see if the options that require a header are enabled.
-  if ((config_.options & ~(NO_HEADER_OPTIONS)) != 0) {
+  if (config_.options & HEADER_OPTIONS) {
     need_header_ = true;
 
     // Initialize all of the static header offsets.
     pointer_offset_ = BIONIC_ALIGN(sizeof(Header), MINIMUM_ALIGNMENT_BYTES);
 
     if (config_.options & BACKTRACE) {
-      backtrace.reset(new BacktraceData(config_, &pointer_offset_));
+      backtrace.reset(new BacktraceData(this, config_, &pointer_offset_));
       if (!backtrace->Initialize(config_)) {
         return false;
       }
     }
 
     if (config_.options & FRONT_GUARD) {
-      front_guard.reset(new FrontGuardData(config_, &pointer_offset_));
+      front_guard.reset(new FrontGuardData(this, config_, &pointer_offset_));
     }
 
     extra_bytes_ = pointer_offset_;
 
     // Initialize all of the non-header data.
     if (config_.options & REAR_GUARD) {
-      rear_guard.reset(new RearGuardData(config_));
+      rear_guard.reset(new RearGuardData(this, config_));
       extra_bytes_ += config_.rear_guard_bytes;
     }
 
     if (config_.options & FREE_TRACK) {
-      free_track.reset(new FreeTrackData(config_));
+      free_track.reset(new FreeTrackData(this, config_));
     }
 
     if (config_.options & TRACK_ALLOCS) {
-      track.reset(new TrackData());
+      track.reset(new TrackData(this));
     }
   }
 
diff --git a/libc/malloc_debug/DebugData.h b/libc/malloc_debug/DebugData.h
index 4600b33..7e55512 100644
--- a/libc/malloc_debug/DebugData.h
+++ b/libc/malloc_debug/DebugData.h
@@ -103,4 +103,6 @@
   DISALLOW_COPY_AND_ASSIGN(DebugData);
 };
 
+extern DebugData* g_debug;
+
 #endif // MALLOC_DEBUG_DEBUGDATA_H
diff --git a/libc/malloc_debug/FreeTrackData.cpp b/libc/malloc_debug/FreeTrackData.cpp
index ed41981..8e6502e 100644
--- a/libc/malloc_debug/FreeTrackData.cpp
+++ b/libc/malloc_debug/FreeTrackData.cpp
@@ -36,22 +36,19 @@
 #include "FreeTrackData.h"
 #include "malloc_debug.h"
 
-FreeTrackData::FreeTrackData(const Config& config)
-    : backtrace_num_frames_(config.free_track_backtrace_num_frames) {
+FreeTrackData::FreeTrackData(DebugData* debug, const Config& config)
+    : OptionData(debug), backtrace_num_frames_(config.free_track_backtrace_num_frames) {
   cmp_mem_.resize(4096);
   memset(cmp_mem_.data(), config.fill_free_value, cmp_mem_.size());
 }
 
-void FreeTrackData::LogFreeError(DebugData& debug, const Header* header,
-                                 const uint8_t* pointer) {
-  ScopedDisableDebugCalls disable;
-
+void FreeTrackData::LogFreeError(const Header* header, const uint8_t* pointer) {
   error_log(LOG_DIVIDER);
   error_log("+++ ALLOCATION %p USED AFTER FREE", pointer);
-  uint8_t fill_free_value = debug.config().fill_free_value;
+  uint8_t fill_free_value = debug_->config().fill_free_value;
   for (size_t i = 0; i < header->usable_size; i++) {
     if (pointer[i] != fill_free_value) {
-      error_log("  pointer[%zu] = 0x%02x (expected 0x%02x)", i, pointer[i], fill_free_value);
+      error_log("  allocation[%zu] = 0x%02x (expected 0x%02x)", i, pointer[i], fill_free_value);
     }
   }
   auto back_iter = backtraces_.find(header);
@@ -63,10 +60,8 @@
   error_log(LOG_DIVIDER);
 }
 
-void FreeTrackData::VerifyAndFree(DebugData& debug, const Header* header,
-                                  const void* pointer) {
-  ScopedDisableDebugCalls disable;
-
+void FreeTrackData::VerifyAndFree(const Header* header) {
+  const void* pointer = debug_->GetPointer(header);
   if (header->tag != DEBUG_FREE_TAG) {
     error_log(LOG_DIVIDER);
     error_log("+++ ALLOCATION %p HAS CORRUPTED HEADER TAG 0x%x AFTER FREE", pointer, header->tag);
@@ -74,11 +69,12 @@
   } else {
     const uint8_t* memory = reinterpret_cast<const uint8_t*>(pointer);
     size_t bytes = header->usable_size;
-    bytes = (bytes < debug.config().fill_on_free_bytes) ? bytes : debug.config().fill_on_free_bytes;
+    bytes = (bytes < debug_->config().fill_on_free_bytes) ? bytes
+        : debug_->config().fill_on_free_bytes;
     while (bytes > 0) {
       size_t bytes_to_cmp = (bytes < cmp_mem_.size()) ? bytes : cmp_mem_.size();
       if (memcmp(memory, cmp_mem_.data(), bytes_to_cmp) != 0) {
-        LogFreeError(debug, header, reinterpret_cast<const uint8_t*>(pointer));
+        LogFreeError(header, reinterpret_cast<const uint8_t*>(pointer));
         break;
       }
       bytes -= bytes_to_cmp;
@@ -94,14 +90,11 @@
   g_dispatch->free(header->orig_pointer);
 }
 
-void FreeTrackData::Add(DebugData& debug, const Header* header) {
-  // Make sure the stl calls below don't call the debug_XXX functions.
-  ScopedDisableDebugCalls disable;
-
+void FreeTrackData::Add(const Header* header) {
   pthread_mutex_lock(&mutex_);
-  if (list_.size() == debug.config().free_track_allocations) {
+  if (list_.size() == debug_->config().free_track_allocations) {
     const Header* old_header = list_.back();
-    VerifyAndFree(debug, old_header, debug.GetPointer(old_header));
+    VerifyAndFree(old_header);
     list_.pop_back();
   }
 
@@ -118,19 +111,14 @@
   pthread_mutex_unlock(&mutex_);
 }
 
-void FreeTrackData::VerifyAll(DebugData& debug) {
-  // Make sure the stl calls below don't call the debug_XXX functions.
-  ScopedDisableDebugCalls disable;
-
+void FreeTrackData::VerifyAll() {
   for (const auto& header : list_) {
-    VerifyAndFree(debug, header, debug.GetPointer(header));
+    VerifyAndFree(header);
   }
   list_.clear();
 }
 
 void FreeTrackData::LogBacktrace(const Header* header) {
-  ScopedDisableDebugCalls disable;
-
   auto back_iter = backtraces_.find(header);
   if (back_iter == backtraces_.end()) {
     return;
diff --git a/libc/malloc_debug/FreeTrackData.h b/libc/malloc_debug/FreeTrackData.h
index 804b5a6..21f845f 100644
--- a/libc/malloc_debug/FreeTrackData.h
+++ b/libc/malloc_debug/FreeTrackData.h
@@ -38,26 +38,28 @@
 
 #include <private/bionic_macros.h>
 
-// Forward declarations.
-struct Header;
-class DebugData;
-struct Config;
-struct BacktraceHeader;
+#include "OptionData.h"
 
-class FreeTrackData {
+// Forward declarations.
+struct BacktraceHeader;
+struct Config;
+class DebugData;
+struct Header;
+
+class FreeTrackData : public OptionData {
  public:
-  FreeTrackData(const Config& config);
+  FreeTrackData(DebugData* debug_data, const Config& config);
   virtual ~FreeTrackData() = default;
 
-  void Add(DebugData& debug, const Header* header);
+  void Add(const Header* header);
 
-  void VerifyAll(DebugData& debug);
+  void VerifyAll();
 
   void LogBacktrace(const Header* header);
 
  private:
-  void LogFreeError(DebugData& debug, const Header* header, const uint8_t* pointer);
-  void VerifyAndFree(DebugData& debug, const Header* header, const void* pointer);
+  void LogFreeError(const Header* header, const uint8_t* pointer);
+  void VerifyAndFree(const Header* header);
 
   pthread_mutex_t mutex_ = PTHREAD_MUTEX_INITIALIZER;
   std::deque<const Header*> list_;
diff --git a/libc/malloc_debug/GuardData.cpp b/libc/malloc_debug/GuardData.cpp
index c70e8f1..e207b86 100644
--- a/libc/malloc_debug/GuardData.cpp
+++ b/libc/malloc_debug/GuardData.cpp
@@ -39,15 +39,14 @@
 #include "malloc_debug.h"
 #include "GuardData.h"
 
-GuardData::GuardData(int init_value, size_t num_bytes) {
+GuardData::GuardData(DebugData* debug_data, int init_value, size_t num_bytes)
+    : OptionData(debug_data) {
   // Create a buffer for fast comparisons of the front guard.
   cmp_mem_.resize(num_bytes);
   memset(cmp_mem_.data(), init_value, cmp_mem_.size());
 }
 
 void GuardData::LogFailure(const Header* header, const void* pointer, const void* data) {
-  ScopedDisableDebugCalls disable;
-
   error_log(LOG_DIVIDER);
   error_log("+++ ALLOCATION %p SIZE %zu HAS A CORRUPTED %s GUARD", pointer,
             header->real_size(), GetTypeName());
@@ -58,7 +57,7 @@
   const uint8_t* real = reinterpret_cast<const uint8_t*>(data);
   for (size_t i = 0; i < cmp_mem_.size(); i++, pointer_idx++) {
     if (real[i] != expected[i]) {
-      error_log("  pointer[%d] = 0x%02x (expected 0x%02x)", pointer_idx, real[i], expected[i]);
+      error_log("  allocation[%d] = 0x%02x (expected 0x%02x)", pointer_idx, real[i], expected[i]);
     }
   }
 
@@ -70,8 +69,8 @@
   error_log(LOG_DIVIDER);
 }
 
-FrontGuardData::FrontGuardData(const Config& config, size_t* offset)
-   : GuardData(config.front_guard_value, config.front_guard_bytes) {
+FrontGuardData::FrontGuardData(DebugData* debug_data, const Config& config, size_t* offset)
+   : GuardData(debug_data, config.front_guard_value, config.front_guard_bytes) {
   // Create a buffer for fast comparisons of the front guard.
   cmp_mem_.resize(config.front_guard_bytes);
   memset(cmp_mem_.data(), config.front_guard_value, cmp_mem_.size());
@@ -80,22 +79,22 @@
   *offset += config.front_guard_bytes;
 }
 
-bool FrontGuardData::Valid(DebugData& debug, const Header* header) {
-  return GuardData::Valid(debug.GetFrontGuard(header));
+bool FrontGuardData::Valid(const Header* header) {
+  return GuardData::Valid(debug_->GetFrontGuard(header));
 }
 
-void FrontGuardData::LogFailure(DebugData& debug, const Header* header) {
-  GuardData::LogFailure(header, debug.GetPointer(header), debug.GetFrontGuard(header));
+void FrontGuardData::LogFailure(const Header* header) {
+  GuardData::LogFailure(header, debug_->GetPointer(header), debug_->GetFrontGuard(header));
 }
 
-RearGuardData::RearGuardData(const Config& config)
-    : GuardData(config.rear_guard_value, config.rear_guard_bytes) {
+RearGuardData::RearGuardData(DebugData* debug_data, const Config& config)
+    : GuardData(debug_data, config.rear_guard_value, config.rear_guard_bytes) {
 }
 
-bool RearGuardData::Valid(DebugData& debug, const Header* header) {
-  return GuardData::Valid(debug.GetRearGuard(header));
+bool RearGuardData::Valid(const Header* header) {
+  return GuardData::Valid(debug_->GetRearGuard(header));
 }
 
-void RearGuardData::LogFailure(DebugData& debug, const Header* header) {
-  GuardData::LogFailure(header, debug.GetPointer(header), debug.GetRearGuard(header));
+void RearGuardData::LogFailure(const Header* header) {
+  GuardData::LogFailure(header, debug_->GetPointer(header), debug_->GetRearGuard(header));
 }
diff --git a/libc/malloc_debug/GuardData.h b/libc/malloc_debug/GuardData.h
index 4de2702..bfb3949 100644
--- a/libc/malloc_debug/GuardData.h
+++ b/libc/malloc_debug/GuardData.h
@@ -36,14 +36,16 @@
 
 #include <private/bionic_macros.h>
 
+#include "OptionData.h"
+
 // Forward declarations.
 class DebugData;
 struct Header;
 struct Config;
 
-class GuardData {
+class GuardData : public OptionData {
  public:
-  GuardData(int init_value, size_t num_bytes);
+  GuardData(DebugData* debug_data, int init_value, size_t num_bytes);
   virtual ~GuardData() = default;
 
   bool Valid(void* data) { return memcmp(data, cmp_mem_.data(), cmp_mem_.size()) == 0; }
@@ -60,12 +62,12 @@
 
 class FrontGuardData : public GuardData {
  public:
-  FrontGuardData(const Config& config, size_t* offset);
+  FrontGuardData(DebugData* debug_data, const Config& config, size_t* offset);
   virtual ~FrontGuardData() = default;
 
-  bool Valid(DebugData& debug, const Header* header);
+  bool Valid(const Header* header);
 
-  void LogFailure(DebugData& debug, const Header* header);
+  void LogFailure(const Header* header);
 
   size_t offset() { return offset_; }
 
@@ -79,12 +81,12 @@
 
 class RearGuardData : public GuardData {
  public:
-  RearGuardData(const Config& config);
+  RearGuardData(DebugData* debug_data, const Config& config);
   virtual ~RearGuardData() = default;
 
-  bool Valid(DebugData& debug, const Header* header);
+  bool Valid(const Header* header);
 
-  void LogFailure(DebugData& debug, const Header* header);
+  void LogFailure(const Header* header);
 
  private:
   const char* GetTypeName() override { return "REAR"; }
diff --git a/libc/malloc_debug/OptionData.h b/libc/malloc_debug/OptionData.h
new file mode 100644
index 0000000..80190f5
--- /dev/null
+++ b/libc/malloc_debug/OptionData.h
@@ -0,0 +1,46 @@
+/*
+ * Copyright (C) 2016 The Android Open Source Project
+ * All rights reserved.
+ *
+ * Redistribution and use in source and binary forms, with or without
+ * modification, are permitted provided that the following conditions
+ * are met:
+ *  * Redistributions of source code must retain the above copyright
+ *    notice, this list of conditions and the following disclaimer.
+ *  * Redistributions in binary form must reproduce the above copyright
+ *    notice, this list of conditions and the following disclaimer in
+ *    the documentation and/or other materials provided with the
+ *    distribution.
+ *
+ * THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS
+ * "AS IS" AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT
+ * LIMITED TO, THE IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS
+ * FOR A PARTICULAR PURPOSE ARE DISCLAIMED. IN NO EVENT SHALL THE
+ * COPYRIGHT OWNER OR CONTRIBUTORS BE LIABLE FOR ANY DIRECT, INDIRECT,
+ * INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING,
+ * BUT NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; LOSS
+ * OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED
+ * AND ON ANY THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY,
+ * OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT
+ * OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF
+ * SUCH DAMAGE.
+ */
+
+#ifndef DEBUG_MALLOC_OPTIONDATA_H
+#define DEBUG_MALLOC_OPTIONDATA_H
+
+// Forward Declarations
+class DebugData;
+
+class OptionData {
+ public:
+  OptionData(DebugData* debug) : debug_(debug) {}
+  ~OptionData() = default;
+
+ protected:
+  DebugData* debug_;
+
+  DISALLOW_COPY_AND_ASSIGN(OptionData);
+};
+
+#endif // MALLOC_DEBUG_OPTIONDATA_H
diff --git a/libc/malloc_debug/README.md b/libc/malloc_debug/README.md
new file mode 100644
index 0000000..3fc2305
--- /dev/null
+++ b/libc/malloc_debug/README.md
@@ -0,0 +1,330 @@
+Malloc Debug
+============
+
+Malloc debug is a method of debugging native memory problems. It can help
+detect memory corruption, memory leaks, and use after free issues.
+
+Currently, malloc debug requires root to enable. When it is enabled, it works
+by adding a shim layer that replaces the normal allocation calls. The replaced
+calls are:
+
+<pre>
+malloc
+free
+calloc
+realloc
+posix_memalign
+memalign
+malloc_usable_size
+</pre>
+
+On 32 bit systems, these two deprecated functions are also replaced:
+
+<pre>
+pvalloc
+valloc
+</pre>
+
+Any errors detected by the library are reported in the log.
+
+Controlling Malloc Debug Behavior
+---------------------------------
+Malloc debug is controlled by individual options. Each option can be enabled
+individually, or in a group of other options. Every single option can be
+combined with every other option.
+
+Option Descriptions
+-------------------
+### front\_guard[=SIZE\_BYTES]
+Enables a small buffer placed before the allocated data. This is an attempt
+to find memory corruption occuring to a region before the original allocation.
+On first allocation, this front guard is written with a specific pattern (0xaa).
+When the allocation is freed, the guard is checked to verify it has not been
+modified. If any part of the front guard is modified, an error will be reported
+in the log indicating what bytes changed.
+
+If the backtrace option is also enabled, then any error message will include
+the backtrace of the allocation site.
+
+If SIZE\_BYTES is present, it indicates the number of bytes in the guard.
+The default is 32 bytes, the max bytes is 16384. SIZE\_BYTES will be
+padded so that it is a multiple of 8 bytes on 32 bit systems and 16 bytes
+on 64 bit systems to make sure that the allocation returned is aligned
+properly.
+
+This option adds a special header to all allocations that contains the guard
+and information about the original allocation.
+
+Example error:
+
+<pre>
+04-10 12:00:45.621  7412  7412 E malloc_debug: +++ ALLOCATION 0x12345678 SIZE 100 HAS A CORRUPTED FRONT GUARD
+04-10 12:00:45.622  7412  7412 E malloc_debug:   allocation[-32] = 0x00 (expected 0xaa)
+04-10 12:00:45.622  7412  7412 E malloc_debug:   allocation[-15] = 0x02 (expected 0xaa)
+</pre>
+
+### rear\_guard[=SIZE\_BYTES]
+Enables a small buffer placed after the allocated data. This is an attempt
+to find memory corruption occuring to a region after the original allocation.
+On first allocation, this rear guard is written with a specific pattern (0xbb).
+When the allocation is freed, the guard is checked to verify it has not been
+modified. If any part of the rear guard is modified, an error will be reported
+in the log indicating what bytes changed.
+
+If SIZE\_BYTES is present, it indicates the number of bytes in the guard.
+The default is 32 bytes, the max bytes is 16384.
+
+This option adds a special header to all allocations that contains
+information about the original allocation.
+
+Example error:
+
+<pre>
+04-10 12:00:45.621  7412  7412 E malloc_debug: +++ ALLOCATION 0x12345678 SIZE 100 HAS A CORRUPTED REAR GUARD
+04-10 12:00:45.622  7412  7412 E malloc_debug:   allocation[130] = 0xbf (expected 0xbb)
+04-10 12:00:45.622  7412  7412 E malloc_debug:   allocation[131] = 0x00 (expected 0xbb)
+</pre>
+
+### guard[=SIZE\_BYTES]
+Enables both a front guard and a rear guard on all allocations.
+
+If SIZE\_BYTES is present, it indicates the number of bytes in both guards.
+The default is 32 bytes, the max bytes is 16384.
+
+### backtrace[=MAX\_FRAMES]
+Enable capturing the backtrace of each allocation site.
+This option will slow down allocations by an order of magnitude. If the
+system runs too slowly with this option enabled, decreasing the maximum number
+of frames captured will speed the allocations up.
+
+Note that any backtrace frames that occur within the malloc backtrace library
+itself are not recorded.
+
+If MAX\_FRAMES is present, it indicates the maximum number of frames to
+capture in a backtrace. The default is 16 frames, the maximumum value
+this can be set to is 256.
+
+This option adds a special header to all allocations that contains the
+backtrace and information about the original allocation.
+
+### backtrace\_enable\_on\_signal[=MAX\_FRAMES]
+Enable capturing the backtrace of each allocation site. If the
+backtrace capture is toggled when the process receives the signal
+SIGRTMAX - 19 (which is 45 on most Android devices). When this
+option is used alone, backtrace capture starts out disabled until the signal
+is received. If both this option and the backtrace option are set, then
+backtrace capture is enabled until the signal is received.
+
+If MAX\_FRAMES is present, it indicates the maximum number of frames to
+capture in a backtrace. The default is 16 frames, the maximumum value
+this can be set to is 256.
+
+This option adds a special header to all allocations that contains the
+backtrace and information about the original allocation.
+
+### fill\_on\_alloc[=MAX\_FILLED\_BYTES]
+Any allocation routine, other than calloc, will result in the allocation being
+filled with the value 0xeb. When doing a realloc to a larger size, the bytes
+above the original usable size will be set to 0xeb.
+
+If MAX\_FILLED\_BYTES is present, it will only fill up to the specified number
+of bytes in the allocation. The default is to fill the entire allocation.
+
+### fill\_on\_free[=MAX\_FILLED\_BYTES]
+When an allocation is freed, fill it with 0xef.
+
+If MAX\_FILLED\_BYTES is present, it will only fill up to the specified number
+of bytes in the allocation. The default is to fill the entire allocation.
+
+### fill[=MAX\_FILLED\_BYTES]
+This enables both the fill\_on\_alloc option and the fill\_on\_free option.
+
+If MAX\_FILLED\_BYTES is present, it will only fill up to the specified number
+of bytes in the allocation. The default is to fill the entire allocation.
+
+### expand\_alloc[=EXPAND\_BYTES]
+Add an extra amount to allocate for every allocation.
+
+If XX is present, it is the number of bytes to expand the allocation by.
+The default is 16 bytes, the max bytes is 16384.
+
+### free\_track[=ALLOCATION\_COUNT]
+When a pointer is freed, do not free the memory right away, but add it to
+a list of freed allocations. In addition to being added to the list, the
+entire allocation is filled with the value 0xef, and the backtrace at
+the time of the free is recorded. The backtrace recording is completely
+separate from the backtrace option, and happens automatically if this
+option is enabled. By default, a maximum of 16 frames will be recorded,
+but this value can be changed using the free\_track\_backtrace\_num\_frames
+option. It can also be completely disabled by setting the option to zero.
+See the full description of this option below.
+
+When the list is full, an allocation is removed from the list and is
+checked to make sure that none of the contents have been modified since
+being placed on the list. When the program terminates, all of the allocations
+left on the list are verified.
+
+If ALLOCATION\_COUNT is present, it indicates the total number of allocations
+in the list. The default is to record 100 freed allocations, the max
+allocations to record is 16384.
+
+This option adds a special header to all allocations that contains
+information about the original allocation.
+
+Example error:
+
+<pre>
+04-15 12:00:31.304  7412  7412 E malloc_debug: +++ ALLOCATION 0x12345678 USED AFTER FREE
+04-15 12:00:31.305  7412  7412 E malloc_debug:   allocation[20] = 0xaf (expected 0xef)
+04-15 12:00:31.305  7412  7412 E malloc_debug:   allocation[99] = 0x12 (expected 0xef)
+04-15 12:00:31.305  7412  7412 E malloc_debug: Backtrace at time of free:
+04-15 12:00:31.305  7412  7412 E malloc_debug:           #00  pc 00029310  /system/lib/libc.so
+04-15 12:00:31.305  7412  7412 E malloc_debug:           #01  pc 00021438  /system/lib/libc.so (newlocale+160)
+04-15 12:00:31.305  7412  7412 E malloc_debug:           #02  pc 000a9e38  /system/lib/libc++.so
+04-15 12:00:31.305  7412  7412 E malloc_debug:           #03  pc 000a28a8  /system/lib/libc++.so
+</pre>
+
+In addition, there is another type of error message that can occur if
+an allocation has a special header applied, and the header is corrupted
+before the verification occurs. This is the error message that will be found
+in the log:
+
+<pre>
++++ ALLOCATION 0x12345678 HAS CORRUPTED HEADER TAG 0x1cc7dc00 AFTER FREE
+</pre>
+
+### free\_track\_backtrace\_num\_frames[=MAX\_FRAMES]
+This option only has meaning if free\_track is set. It indicates how many
+backtrace frames to capture when an allocation is freed.
+
+If MAX\_FRAMES is present, it indicates the number of frames to capture.
+If the value is set to zero, then no backtrace will be captured when the
+allocation is freed. The default is to record 16 frames, the max number of
+frames to to record is 256.
+
+### leak\_track
+Track all live allocations. When the program terminates, all of the live
+allocations will be dumped to the log. If the backtrace option was enabled,
+then the log will include the backtrace of the leaked allocations. This
+option is not useful when enabled globally because a lot of programs do not
+free everything before the program terminates.
+
+This option adds a special header to all allocations that contains
+information about the original allocation.
+
+Example leak error found in the log:
+
+<pre>
+04-15 12:35:33.304  7412  7412 E malloc_debug: +++ APP leaked block of size 100 at 0x2be3b0b0 (leak 1 of 2)
+04-15 12:35:33.304  7412  7412 E malloc_debug: Backtrace at time of allocation:
+04-15 12:35:33.305  7412  7412 E malloc_debug:           #00  pc 00029310  /system/lib/libc.so
+04-15 12:35:33.305  7412  7412 E malloc_debug:           #01  pc 00021438  /system/lib/libc.so (newlocale+160)
+04-15 12:35:33.305  7412  7412 E malloc_debug:           #02  pc 000a9e38  /system/lib/libc++.so
+04-15 12:35:33.305  7412  7412 E malloc_debug:           #03  pc 000a28a8  /system/lib/libc++.so
+04-15 12:35:33.305  7412  7412 E malloc_debug: +++ APP leaked block of size 24 at 0x7be32380 (leak 2 of 2)
+04-15 12:35:33.305  7412  7412 E malloc_debug: Backtrace at time of allocation:
+04-15 12:35:33.305  7412  7412 E malloc_debug:           #00  pc 00029310  /system/lib/libc.so
+04-15 12:35:33.305  7412  7412 E malloc_debug:           #01  pc 00021438  /system/lib/libc.so (newlocale+160)
+04-15 12:35:33.305  7412  7412 E malloc_debug:           #02  pc 000a9e38  /system/lib/libc++.so
+04-15 12:35:33.305  7412  7412 E malloc_debug:           #03  pc 000a28a8  /system/lib/libc++.so
+</pre>
+
+Additional Errors
+-----------------
+There are a few other error messages that might appear in the log.
+
+### Use After Free
+<pre>
+04-15 12:00:31.304  7412  7412 E malloc_debug: +++ ALLOCATION 0x12345678 USED AFTER FREE (free)
+04-15 12:00:31.305  7412  7412 E malloc_debug: Backtrace of original free:
+04-15 12:00:31.305  7412  7412 E malloc_debug:           #00  pc 00029310  /system/lib/libc.so
+04-15 12:00:31.305  7412  7412 E malloc_debug:           #01  pc 00021438  /system/lib/libc.so (newlocale+160)
+04-15 12:00:31.305  7412  7412 E malloc_debug:           #02  pc 000a9e38  /system/lib/libc++.so
+04-15 12:00:31.305  7412  7412 E malloc_debug:           #03  pc 000a28a8  /system/lib/libc++.so
+04-15 12:00:31.305  7412  7412 E malloc_debug: Backtrace at time of failure:
+04-15 12:00:31.305  7412  7412 E malloc_debug:           #00  pc 00029310  /system/lib/libc.so
+04-15 12:00:31.305  7412  7412 E malloc_debug:           #01  pc 00021438  /system/lib/libc.so (newlocale+160)
+04-15 12:00:31.305  7412  7412 E malloc_debug:           #02  pc 000a9e38  /system/lib/libc++.so
+04-15 12:00:31.305  7412  7412 E malloc_debug:           #03  pc 000a28a8  /system/lib/libc++.so
+</pre>
+
+This indicates that code is attempting to free an already freed pointer. The
+name in parenthesis indicates that the application called the function
+<i>free</i> with the bad pointer.
+
+For example, this message:
+
+<pre>
+04-15 12:00:31.304  7412  7412 E malloc_debug: +++ ALLOCATION 0x12345678 USED AFTER FREE (realloc)
+</pre>
+
+Would indicate that the application called the <i>realloc</i> function
+with an already freed pointer.
+
+### Invalid Tag
+<pre>
+04-15 12:00:31.304  7412  7412 E malloc_debug: +++ ALLOCATION 0x12345678 HAS INVALID TAG 1ee7d000 (malloc_usable_size)
+04-15 12:00:31.305  7412  7412 E malloc_debug: Backtrace at time of failure:
+04-15 12:00:31.305  7412  7412 E malloc_debug:           #00  pc 00029310  /system/lib/libc.so
+04-15 12:00:31.305  7412  7412 E malloc_debug:           #01  pc 00021438  /system/lib/libc.so (newlocale+160)
+04-15 12:00:31.305  7412  7412 E malloc_debug:           #02  pc 000a9e38  /system/lib/libc++.so
+04-15 12:00:31.305  7412  7412 E malloc_debug:           #03  pc 000a28a8  /system/lib/libc++.so
+</pre>
+
+This indicates that a function (malloc\_usable\_size) was called with
+a pointer that is either not allocated memory, or that the memory of
+the pointer has been corrupted.
+
+As with the other error message, the function in parenthesis is the
+function that was called with the bad pointer.
+
+Examples
+========
+Enable backtrace tracking of all allocation for all processes:
+
+<pre>
+  adb shell stop
+  adb shell setprop libc.debug.malloc.options backtrace
+  adb shell start
+</pre>
+
+Enable backtrace tracking for a specific process (ls):
+
+<pre>
+  adb shell setprop libc.debug.malloc.options backtrace
+  adb shell setprop libc.debug.malloc.program ls
+  adb shell ls
+</pre>
+
+Enable backtrace tracking for the zygote and zygote based processes:
+
+<pre>
+  adb shell stop
+  adb shell setprop libc.debug.malloc.program app_process
+  adb shell setprop libc.debug.malloc.options backtrace
+  adb shell start
+</pre>
+
+Enable multiple options (backtrace and guards):
+
+<pre>
+  adb shell stop
+  adb shell setprop libc.debug.malloc.options "\"backtrace guards\""
+  adb shell start
+</pre>
+
+Enable malloc debug when multiple processes have the same name. This method
+can be used to enable malloc debug for only a very specific process if
+multiple processes have the same name.
+
+Note: The double quotes in the adb shell command are necessary. Otherwise,
+the setprop command will fail since the backtrace guards options will look
+like two arguments instead of one.
+
+<pre>
+  adb shell
+  # setprop libc.debug.malloc.env_enabled
+  # setprop libc.debug.malloc.options backtrace
+  # export LIBC_DEBUG_MALLOC_ENABLE 1
+  # ls
+</pre>
diff --git a/libc/malloc_debug/README_api.md b/libc/malloc_debug/README_api.md
new file mode 100644
index 0000000..cd04c32
--- /dev/null
+++ b/libc/malloc_debug/README_api.md
@@ -0,0 +1,64 @@
+Native Memory Tracking using libc Callbacks
+-------------------------------------------
+Malloc debug can be used to get information on all of the live allocations
+in a process. The libc library in Android exports two calls that can be
+used to gather this data from a process. This tracking can be enabled using
+either the backtrace option or the backtrace\_enabled\_on\_signal option.
+
+The function to gather the data:
+
+<pre>
+<b>
+extern "C" void get_malloc_leak_info(uint8_t** info, size_t* overall_size, size_t* info_size, size_t* total_memory, size_t* backtrace_size);
+</b>
+</pre>
+
+<i>info</i> is set to a buffer allocated by the call that contains all of
+the allocation information.
+<i>overall\_size</i> is set to the total size of the buffer returned. If this
+<i>info\_size</i>
+value is zero, then there are no allocation being tracked.
+<i>total\_memory</i> is set to the sum of all allocation sizes that are live at
+the point of the function call. This does not include the memory allocated
+by the malloc debug library itself.
+<i>backtrace\_size</i> is set to the maximum number of backtrace entries
+that are present for each allocation.
+
+In order to free the buffer allocated by the function, call:
+
+<pre>
+<b>
+extern "C" void free_malloc_leak_info(uint8_t* info);
+</b>
+</pre>
+
+### Format of info Buffer
+<pre>
+size_t size_of_original_allocation
+size_t num_backtrace_frames
+uintptr_t pc1
+uintptr_t pc2
+uintptr_t pc3
+.
+.
+.
+</pre>
+
+The number of <i>uintptr\_t</i> values is determined by the value
+<i>backtrace\_size</i> as returned by the original call to
+<i>get\_malloc\_leak\_info</i>. This value is not variable, it is the same
+for all the returned data. The value
+<i>num\_backtrace\_frames</i> contains the real number of frames found. The
+extra frames are set to zero. Each <i>uintptr\_t</i> is a pc of the callstack.
+The calls from within the malloc debug library are automatically removed.
+
+For 32 bit systems, <i>size\_t</i> and <i>uintptr\_t</i> are both 4 byte values.
+
+For 64 bit systems, <i>size\_t</i> and <i>uintptr\_t</i> are both 8 byte values.
+
+The total number of these structures returned in <i>info</i> is
+<i>overall\_size</i> divided by <i>info\_size</i>.
+
+Note, the size value in each allocation data structure will have bit 31 set
+if this allocation was created by the Zygote process. This helps to distinguish
+between native allocations created by the application.
diff --git a/libc/malloc_debug/TrackData.cpp b/libc/malloc_debug/TrackData.cpp
index c9828d0..18f428b 100644
--- a/libc/malloc_debug/TrackData.cpp
+++ b/libc/malloc_debug/TrackData.cpp
@@ -44,9 +44,10 @@
 #include "malloc_debug.h"
 #include "TrackData.h"
 
-void TrackData::GetList(std::vector<const Header*>* list) {
-  ScopedDisableDebugCalls disable;
+TrackData::TrackData(DebugData* debug_data) : OptionData(debug_data) {
+}
 
+void TrackData::GetList(std::vector<const Header*>* list) {
   for (const auto& header : headers_) {
     list->push_back(header);
   }
@@ -59,8 +60,6 @@
 }
 
 void TrackData::Add(const Header* header, bool backtrace_found) {
-  ScopedDisableDebugCalls disable;
-
   pthread_mutex_lock(&mutex_);
   if (backtrace_found) {
     total_backtrace_allocs_++;
@@ -70,8 +69,6 @@
 }
 
 void TrackData::Remove(const Header* header, bool backtrace_found) {
-  ScopedDisableDebugCalls disable;
-
   pthread_mutex_lock(&mutex_);
   headers_.erase(header);
   if (backtrace_found) {
@@ -81,26 +78,22 @@
 }
 
 bool TrackData::Contains(const Header* header) {
-  ScopedDisableDebugCalls disable;
-
   pthread_mutex_lock(&mutex_);
   bool found = headers_.count(header);
   pthread_mutex_unlock(&mutex_);
   return found;
 }
 
-void TrackData::DisplayLeaks(DebugData& debug) {
-  ScopedDisableDebugCalls disable;
-
+void TrackData::DisplayLeaks() {
   std::vector<const Header*> list;
   GetList(&list);
 
   size_t track_count = 0;
   for (const auto& header : list) {
     error_log("+++ %s leaked block of size %zu at %p (leak %zu of %zu)", getprogname(),
-              header->real_size(), debug.GetPointer(header), ++track_count, list.size());
-    if (debug.config().options & BACKTRACE) {
-      BacktraceHeader* back_header = debug.GetAllocBacktrace(header);
+              header->real_size(), debug_->GetPointer(header), ++track_count, list.size());
+    if (debug_->config().options & BACKTRACE) {
+      BacktraceHeader* back_header = debug_->GetAllocBacktrace(header);
       if (back_header->num_frames > 0) {
         error_log("Backtrace at time of allocation:");
         backtrace_log(&back_header->frames[0], back_header->num_frames);
@@ -110,15 +103,15 @@
   }
 }
 
-void TrackData::GetInfo(DebugData& debug, uint8_t** info, size_t* overall_size,
-                        size_t* info_size, size_t* total_memory, size_t* backtrace_size) {
+void TrackData::GetInfo(uint8_t** info, size_t* overall_size, size_t* info_size,
+                        size_t* total_memory, size_t* backtrace_size) {
   ScopedPthreadMutexLocker scoped(&mutex_);
 
   if (headers_.size() == 0 || total_backtrace_allocs_ == 0) {
     return;
   }
 
-  *backtrace_size = debug.config().backtrace_frames;
+  *backtrace_size = debug_->config().backtrace_frames;
   *info_size = sizeof(size_t) * 2 + sizeof(uintptr_t) * *backtrace_size;
   *info = reinterpret_cast<uint8_t*>(g_dispatch->calloc(*info_size, total_backtrace_allocs_));
   if (*info == nullptr) {
@@ -131,7 +124,7 @@
 
   uint8_t* data = *info;
   for (const auto& header : list) {
-    BacktraceHeader* back_header = debug.GetAllocBacktrace(header);
+    BacktraceHeader* back_header = debug_->GetAllocBacktrace(header);
     if (back_header->num_frames > 0) {
       memcpy(data, &header->size, sizeof(size_t));
       memcpy(&data[sizeof(size_t)], &back_header->num_frames, sizeof(size_t));
diff --git a/libc/malloc_debug/TrackData.h b/libc/malloc_debug/TrackData.h
index 1234316..fcd8f2a 100644
--- a/libc/malloc_debug/TrackData.h
+++ b/libc/malloc_debug/TrackData.h
@@ -37,14 +37,16 @@
 
 #include <private/bionic_macros.h>
 
+#include "OptionData.h"
+
 // Forward declarations.
 struct Header;
 struct Config;
 class DebugData;
 
-class TrackData {
+class TrackData : public OptionData {
  public:
-  TrackData() = default;
+  TrackData(DebugData* debug_data);
   virtual ~TrackData() = default;
 
   void GetList(std::vector<const Header*>* list);
@@ -55,10 +57,10 @@
 
   bool Contains(const Header *header);
 
-  void GetInfo(DebugData& debug, uint8_t** info, size_t* overall_size,
-               size_t* info_size, size_t* total_memory, size_t* backtrace_size);
+  void GetInfo(uint8_t** info, size_t* overall_size, size_t* info_size,
+               size_t* total_memory, size_t* backtrace_size);
 
-  void DisplayLeaks(DebugData& debug);
+  void DisplayLeaks();
 
   void PrepareFork() { pthread_mutex_lock(&mutex_); }
   void PostForkParent() { pthread_mutex_unlock(&mutex_); }
diff --git a/libc/malloc_debug/debug_disable.cpp b/libc/malloc_debug/debug_disable.cpp
index af0264b..b80ba8c 100644
--- a/libc/malloc_debug/debug_disable.cpp
+++ b/libc/malloc_debug/debug_disable.cpp
@@ -32,7 +32,6 @@
 #include "debug_disable.h"
 #include "debug_log.h"
 
-extern DebugData* g_debug;
 pthread_key_t g_disable_key;
 
 bool DebugCallsDisabled() {
diff --git a/libc/malloc_debug/malloc_debug.cpp b/libc/malloc_debug/malloc_debug.cpp
index 1ee7689..5da5b88 100644
--- a/libc/malloc_debug/malloc_debug.cpp
+++ b/libc/malloc_debug/malloc_debug.cpp
@@ -114,8 +114,6 @@
 }
 
 static void LogTagError(const Header* header, const void* pointer, const char* name) {
-  ScopedDisableDebugCalls disable;
-
   error_log(LOG_DIVIDER);
   if (header->tag == DEBUG_FREE_TAG) {
     error_log("+++ ALLOCATION %p USED AFTER FREE (%s)", pointer, name);
@@ -165,7 +163,6 @@
   if (g_debug->config().options & BACKTRACE) {
     BacktraceHeader* back_header = g_debug->GetAllocBacktrace(header);
     if (g_debug->backtrace->enabled()) {
-      ScopedDisableDebugCalls disable;
       back_header->num_frames = backtrace_get(
           &back_header->frames[0], g_debug->config().backtrace_frames);
       backtrace_found = back_header->num_frames > 0;
@@ -217,11 +214,11 @@
   }
 
   if (g_debug->config().options & FREE_TRACK) {
-    g_debug->free_track->VerifyAll(*g_debug);
+    g_debug->free_track->VerifyAll();
   }
 
   if (g_debug->config().options & LEAK_TRACK) {
-    g_debug->track->DisplayLeaks(*g_debug);
+    g_debug->track->DisplayLeaks();
   }
 
   DebugDisableSet(true);
@@ -257,32 +254,37 @@
     return;
   }
 
-  g_debug->track->GetInfo(*g_debug, info, overall_size, info_size, total_memory, backtrace_size);
+  g_debug->track->GetInfo(info, overall_size, info_size, total_memory, backtrace_size);
 }
 
 void debug_free_malloc_leak_info(uint8_t* info) {
   g_dispatch->free(info);
 }
 
-size_t debug_malloc_usable_size(void* pointer) {
-  if (DebugCallsDisabled() || !g_debug->need_header() || pointer == nullptr) {
+static size_t internal_malloc_usable_size(void* pointer) {
+  if (g_debug->need_header()) {
+    Header* header = g_debug->GetHeader(pointer);
+    if (header->tag != DEBUG_TAG) {
+      LogTagError(header, pointer, "malloc_usable_size");
+      return 0;
+    }
+
+    return header->usable_size;
+  } else {
     return g_dispatch->malloc_usable_size(pointer);
   }
-
-  Header* header = g_debug->GetHeader(pointer);
-  if (header->tag != DEBUG_TAG) {
-    LogTagError(header, pointer, "malloc_usable_size");
-    return 0;
-  }
-
-  return header->usable_size;
 }
 
-void* debug_malloc(size_t size) {
-  if (DebugCallsDisabled()) {
-    return g_dispatch->malloc(size);
+size_t debug_malloc_usable_size(void* pointer) {
+  if (DebugCallsDisabled() || pointer == nullptr) {
+    return g_dispatch->malloc_usable_size(pointer);
   }
+  ScopedDisableDebugCalls disable;
 
+  return internal_malloc_usable_size(pointer);
+}
+
+static void *internal_malloc(size_t size) {
   if (size == 0) {
     size = 1;
   }
@@ -312,7 +314,7 @@
   }
 
   if (pointer != nullptr && g_debug->config().options & FILL_ON_ALLOC) {
-    size_t bytes = debug_malloc_usable_size(pointer);
+    size_t bytes = internal_malloc_usable_size(pointer);
     size_t fill_bytes = g_debug->config().fill_on_alloc_bytes;
     bytes = (bytes < fill_bytes) ? bytes : fill_bytes;
     memset(pointer, g_debug->config().fill_alloc_value, bytes);
@@ -320,11 +322,16 @@
   return pointer;
 }
 
-void debug_free(void* pointer) {
-  if (DebugCallsDisabled() || pointer == nullptr) {
-    return g_dispatch->free(pointer);
+void* debug_malloc(size_t size) {
+  if (DebugCallsDisabled()) {
+    return g_dispatch->malloc(size);
   }
+  ScopedDisableDebugCalls disable;
 
+  return internal_malloc(size);
+}
+
+static void internal_free(void* pointer) {
   void* free_pointer = pointer;
   size_t bytes;
   Header* header;
@@ -337,13 +344,13 @@
     free_pointer = header->orig_pointer;
 
     if (g_debug->config().options & FRONT_GUARD) {
-      if (!g_debug->front_guard->Valid(*g_debug, header)) {
-        g_debug->front_guard->LogFailure(*g_debug, header);
+      if (!g_debug->front_guard->Valid(header)) {
+        g_debug->front_guard->LogFailure(header);
       }
     }
     if (g_debug->config().options & REAR_GUARD) {
-      if (!g_debug->rear_guard->Valid(*g_debug, header)) {
-        g_debug->rear_guard->LogFailure(*g_debug, header);
+      if (!g_debug->rear_guard->Valid(header)) {
+        g_debug->rear_guard->LogFailure(header);
       }
     }
 
@@ -374,16 +381,26 @@
     // frees at the same time and we wind up trying to really free this
     // pointer from another thread, while still trying to free it in
     // this function.
-    g_debug->free_track->Add(*g_debug, header);
+    g_debug->free_track->Add(header);
   } else {
     g_dispatch->free(free_pointer);
   }
 }
 
+void debug_free(void* pointer) {
+  if (DebugCallsDisabled() || pointer == nullptr) {
+    return g_dispatch->free(pointer);
+  }
+  ScopedDisableDebugCalls disable;
+
+  internal_free(pointer);
+}
+
 void* debug_memalign(size_t alignment, size_t bytes) {
   if (DebugCallsDisabled()) {
     return g_dispatch->memalign(alignment, bytes);
   }
+  ScopedDisableDebugCalls disable;
 
   if (bytes == 0) {
     bytes = 1;
@@ -438,11 +455,12 @@
   }
 
   if (pointer != nullptr && g_debug->config().options & FILL_ON_ALLOC) {
-    size_t bytes = debug_malloc_usable_size(pointer);
+    size_t bytes = internal_malloc_usable_size(pointer);
     size_t fill_bytes = g_debug->config().fill_on_alloc_bytes;
     bytes = (bytes < fill_bytes) ? bytes : fill_bytes;
     memset(pointer, g_debug->config().fill_alloc_value, bytes);
   }
+
   return pointer;
 }
 
@@ -450,13 +468,14 @@
   if (DebugCallsDisabled()) {
     return g_dispatch->realloc(pointer, bytes);
   }
+  ScopedDisableDebugCalls disable;
 
   if (pointer == nullptr) {
-    return debug_malloc(bytes);
+    return internal_malloc(bytes);
   }
 
   if (bytes == 0) {
-    debug_free(pointer);
+    internal_free(pointer);
     return nullptr;
   }
 
@@ -486,6 +505,7 @@
 
     // Same size, do nothing.
     if (real_size == header->real_size()) {
+      // Do not bother recording, this is essentially a nop.
       return pointer;
     }
 
@@ -502,11 +522,12 @@
         memset(g_debug->GetRearGuard(header), g_debug->config().rear_guard_value,
                g_debug->config().rear_guard_bytes);
       }
+      // Do not bother recording, this is essentially a nop.
       return pointer;
     }
 
     // Allocate the new size.
-    new_pointer = debug_malloc(bytes);
+    new_pointer = internal_malloc(bytes);
     if (new_pointer == nullptr) {
       errno = ENOMEM;
       return nullptr;
@@ -514,7 +535,7 @@
 
     prev_size = header->usable_size;
     memcpy(new_pointer, pointer, prev_size);
-    debug_free(pointer);
+    internal_free(pointer);
   } else {
     prev_size = g_dispatch->malloc_usable_size(pointer);
     new_pointer = g_dispatch->realloc(pointer, real_size);
@@ -524,7 +545,7 @@
   }
 
   if (g_debug->config().options & FILL_ON_ALLOC) {
-    size_t bytes = debug_malloc_usable_size(new_pointer);
+    size_t bytes = internal_malloc_usable_size(new_pointer);
     if (bytes > g_debug->config().fill_on_alloc_bytes) {
       bytes = g_debug->config().fill_on_alloc_bytes;
     }
@@ -541,6 +562,7 @@
   if (DebugCallsDisabled()) {
     return g_dispatch->calloc(nmemb, bytes);
   }
+  ScopedDisableDebugCalls disable;
 
   size_t size;
   if (__builtin_mul_overflow(nmemb, bytes, &size)) {
@@ -645,6 +667,7 @@
   if (DebugCallsDisabled() || pointer == nullptr) {
     return 0;
   }
+  ScopedDisableDebugCalls disable;
 
   if (g_debug->need_header()) {
     Header* header;
diff --git a/libc/include/sys/_errdefs.h b/libc/private/bionic_errdefs.h
similarity index 100%
rename from libc/include/sys/_errdefs.h
rename to libc/private/bionic_errdefs.h
diff --git a/libc/include/sys/_sigdefs.h b/libc/private/bionic_sigdefs.h
similarity index 100%
rename from libc/include/sys/_sigdefs.h
rename to libc/private/bionic_sigdefs.h
diff --git a/libc/tools/check-symbols-glibc.py b/libc/tools/check-symbols-glibc.py
index c5dbdcf..43531c0 100755
--- a/libc/tools/check-symbols-glibc.py
+++ b/libc/tools/check-symbols-glibc.py
@@ -178,6 +178,23 @@
   '_ctype_',
   '__libc_init',
 ])
+# POSIX has some stuff that's too stupid for words (a64l) or not actually
+# implemented in glibc unless you count always failing with ENOSYS as
+# being implemented (fattach).
+in_posix_and_glibc_but_actually_dead = set([
+  'a64l',
+  'fattach',
+  'fdetach',
+  'getmsg',
+  'getpmsg',
+  'isastream',
+  'l64a',
+  'putmsg',
+  'putpmsg',
+])
+
+posix = posix - in_posix_and_glibc_but_actually_dead
+glibc = glibc - in_posix_and_glibc_but_actually_dead
 
 if not only_unwanted:
   #print 'glibc:'
diff --git a/libc/upstream-netbsd/lib/libc/gen/ftw.c b/libc/upstream-netbsd/lib/libc/gen/ftw.c
deleted file mode 100644
index a7f6bbd..0000000
--- a/libc/upstream-netbsd/lib/libc/gen/ftw.c
+++ /dev/null
@@ -1,98 +0,0 @@
-/* $NetBSD: ftw.c,v 1.1 2005/12/30 23:07:32 agc Exp $ */
-
-/*	From OpenBSD: ftw.c,v 1.2 2003/07/21 21:15:32 millert Exp 	*/
-
-/*
- * Copyright (c) 2003 Todd C. Miller <Todd.Miller@courtesan.com>
- *
- * Permission to use, copy, modify, and distribute this software for any
- * purpose with or without fee is hereby granted, provided that the above
- * copyright notice and this permission notice appear in all copies.
- *
- * THE SOFTWARE IS PROVIDED "AS IS" AND THE AUTHOR DISCLAIMS ALL WARRANTIES
- * WITH REGARD TO THIS SOFTWARE INCLUDING ALL IMPLIED WARRANTIES OF
- * MERCHANTABILITY AND FITNESS. IN NO EVENT SHALL THE AUTHOR BE LIABLE FOR
- * ANY SPECIAL, DIRECT, INDIRECT, OR CONSEQUENTIAL DAMAGES OR ANY DAMAGES
- * WHATSOEVER RESULTING FROM LOSS OF USE, DATA OR PROFITS, WHETHER IN AN
- * ACTION OF CONTRACT, NEGLIGENCE OR OTHER TORTIOUS ACTION, ARISING OUT OF
- * OR IN CONNECTION WITH THE USE OR PERFORMANCE OF THIS SOFTWARE.
- *
- * Sponsored in part by the Defense Advanced Research Projects
- * Agency (DARPA) and Air Force Research Laboratory, Air Force
- * Materiel Command, USAF, under agreement number F39502-99-1-0512.
- */
-#include <sys/cdefs.h>
-
-#ifndef lint
-__RCSID("$NetBSD: ftw.c,v 1.1 2005/12/30 23:07:32 agc Exp $");
-#endif
-
-#include <sys/types.h>
-#include <sys/stat.h>
-#include <errno.h>
-#include <fts.h>
-#include <ftw.h>
-#include <limits.h>
-
-int
-ftw(const char *path, int (*fn)(const char *, const struct stat *, int),
-    int nfds)
-{
-	/* LINTED */
-	char * const paths[2] = { __UNCONST(path), NULL };
-	FTSENT *cur;
-	FTS *ftsp;
-	int fnflag, error, sverrno;
-
-	/* XXX - nfds is currently unused */
-	if (nfds < 1 || nfds > OPEN_MAX) {
-		errno = EINVAL;
-		return (-1);
-	}
-
-	ftsp = fts_open(paths, FTS_COMFOLLOW | FTS_NOCHDIR, NULL);
-	if (ftsp == NULL)
-		return (-1);
-	error = 0;
-	while ((cur = fts_read(ftsp)) != NULL) {
-		switch (cur->fts_info) {
-		case FTS_D:
-			fnflag = FTW_D;
-			break;
-		case FTS_DNR:
-			fnflag = FTW_DNR;
-			break;
-		case FTS_DP:
-			/* we only visit in preorder */
-			continue;
-		case FTS_F:
-		case FTS_DEFAULT:
-			fnflag = FTW_F;
-			break;
-		case FTS_NS:
-		case FTS_NSOK:
-		case FTS_SLNONE:
-			fnflag = FTW_NS;
-			break;
-		case FTS_SL:
-			fnflag = FTW_SL;
-			break;
-		case FTS_DC:
-			errno = ELOOP;
-			/* FALLTHROUGH */
-		default:
-			error = -1;
-			goto done;
-		}
-		error = fn(cur->fts_path, cur->fts_statp, fnflag);
-		if (error != 0)
-			break;
-	}
-done:
-	sverrno = errno;
-	if (fts_close(ftsp) != 0 && error == 0)
-		error = -1;
-	else
-		errno = sverrno;
-	return (error);
-}
diff --git a/libc/upstream-netbsd/lib/libc/gen/nftw.c b/libc/upstream-netbsd/lib/libc/gen/nftw.c
deleted file mode 100644
index 0e51342..0000000
--- a/libc/upstream-netbsd/lib/libc/gen/nftw.c
+++ /dev/null
@@ -1,114 +0,0 @@
-/* $NetBSD */
-
-/*	From OpenBSD: nftw.c,v 1.2 2003/07/21 21:15:32 millert Exp 	*/
-
-/*
- * Copyright (c) 2003 Todd C. Miller <Todd.Miller@courtesan.com>
- *
- * Permission to use, copy, modify, and distribute this software for any
- * purpose with or without fee is hereby granted, provided that the above
- * copyright notice and this permission notice appear in all copies.
- *
- * THE SOFTWARE IS PROVIDED "AS IS" AND THE AUTHOR DISCLAIMS ALL WARRANTIES
- * WITH REGARD TO THIS SOFTWARE INCLUDING ALL IMPLIED WARRANTIES OF
- * MERCHANTABILITY AND FITNESS. IN NO EVENT SHALL THE AUTHOR BE LIABLE FOR
- * ANY SPECIAL, DIRECT, INDIRECT, OR CONSEQUENTIAL DAMAGES OR ANY DAMAGES
- * WHATSOEVER RESULTING FROM LOSS OF USE, DATA OR PROFITS, WHETHER IN AN
- * ACTION OF CONTRACT, NEGLIGENCE OR OTHER TORTIOUS ACTION, ARISING OUT OF
- * OR IN CONNECTION WITH THE USE OR PERFORMANCE OF THIS SOFTWARE.
- *
- * Sponsored in part by the Defense Advanced Research Projects
- * Agency (DARPA) and Air Force Research Laboratory, Air Force
- * Materiel Command, USAF, under agreement number F39502-99-1-0512.
- */
-
-#include <sys/cdefs.h>
-
-#ifndef lint
-__RCSID("$NetBSD: nftw.c,v 1.1 2005/12/30 23:07:32 agc Exp $");
-#endif
-
-#include <sys/types.h>
-#include <sys/stat.h>
-#include <errno.h>
-#include <fts.h>
-#include <ftw.h>
-#include <limits.h>
-
-int
-nftw(const char *path, int (*fn)(const char *, const struct stat *, int,
-     struct FTW *), int nfds, int ftwflags)
-{
-	/* LINTED */
-	char * const paths[2] = { __UNCONST(path), NULL };
-	struct FTW f;
-	FTSENT *cur;
-	FTS *ftsp;
-	int ftsflags, fnflag, error, postorder, sverrno;
-
-	/* XXX - nfds is currently unused */
-	if (nfds < 1 || nfds > OPEN_MAX) {
-		errno = EINVAL;
-		return (-1);
-	}
-
-	ftsflags = FTS_COMFOLLOW;
-	if (!(ftwflags & FTW_CHDIR))
-		ftsflags |= FTS_NOCHDIR;
-	if (ftwflags & FTW_MOUNT)
-		ftsflags |= FTS_XDEV;
-	if (ftwflags & FTW_PHYS)
-		ftsflags |= FTS_PHYSICAL;
-	postorder = (ftwflags & FTW_DEPTH) != 0;
-	ftsp = fts_open(paths, ftsflags, NULL);
-	if (ftsp == NULL)
-		return (-1);
-	error = 0;
-	while ((cur = fts_read(ftsp)) != NULL) {
-		switch (cur->fts_info) {
-		case FTS_D:
-			if (postorder)
-				continue;
-			fnflag = FTW_D;
-			break;
-		case FTS_DNR:
-			fnflag = FTW_DNR;
-			break;
-		case FTS_DP:
-			if (!postorder)
-				continue;
-			fnflag = FTW_DP;
-			break;
-		case FTS_F:
-		case FTS_DEFAULT:
-			fnflag = FTW_F;
-			break;
-		case FTS_NS:
-		case FTS_NSOK:
-			fnflag = FTW_NS;
-			break;
-		case FTS_SL:
-			fnflag = FTW_SL;
-			break;
-		case FTS_SLNONE:
-			fnflag = FTW_SLN;
-			break;
-		case FTS_DC:
-			errno = ELOOP;
-			/* FALLTHROUGH */
-		default:
-			error = -1;
-			goto done;
-		}
-		f.base = cur->fts_pathlen - cur->fts_namelen;
-		f.level = cur->fts_level;
-		error = fn(cur->fts_path, cur->fts_statp, fnflag, &f);
-		if (error != 0)
-			break;
-	}
-done:
-	sverrno = errno;
-	(void) fts_close(ftsp);
-	errno = sverrno;
-	return (error);
-}
diff --git a/libc/dns/net/base64.c b/libc/upstream-openbsd/lib/libc/net/base64.c
similarity index 82%
rename from libc/dns/net/base64.c
rename to libc/upstream-openbsd/lib/libc/net/base64.c
index 1886986..e90696d 100644
--- a/libc/dns/net/base64.c
+++ b/libc/upstream-openbsd/lib/libc/net/base64.c
@@ -1,4 +1,4 @@
-/*	$NetBSD: base64.c,v 1.8 2002/11/11 01:15:17 thorpej Exp $	*/
+/*	$OpenBSD: base64.c,v 1.8 2015/01/16 16:48:51 deraadt Exp $	*/
 
 /*
  * Copyright (c) 1996 by Internet Software Consortium.
@@ -42,25 +42,14 @@
  * IF IBM IS APPRISED OF THE POSSIBILITY OF SUCH DAMAGES.
  */
 
-#include <sys/cdefs.h>
-#if defined(LIBC_SCCS) && !defined(lint)
-__RCSID("$NetBSD: base64.c,v 1.8 2002/11/11 01:15:17 thorpej Exp $");
-#endif /* LIBC_SCCS and not lint */
-
 #include <sys/types.h>
-#include <sys/param.h>
 #include <sys/socket.h>
 #include <netinet/in.h>
 #include <arpa/inet.h>
 #include <arpa/nameser.h>
 
-#include <assert.h>
 #include <ctype.h>
-#ifdef ANDROID_CHANGES
-#include "resolv_private.h"
-#else
 #include <resolv.h>
-#endif
 #include <stdio.h>
 
 #include <stdlib.h>
@@ -118,9 +107,9 @@
    end of the data is performed using the '=' character.
 
    Since all base64 input is an integral number of octets, only the
-         -------------------------------------------------
+         -------------------------------------------------                       
    following cases can arise:
-
+   
        (1) the final quantum of encoding input is an integral
            multiple of 24 bits; here, the final unit of encoded
 	   output will be an integral multiple of 4 characters
@@ -141,12 +130,9 @@
 	size_t targsize;
 {
 	size_t datalength = 0;
-	u_char input[3] = { 0, 0, 0 };  /* make compiler happy */
+	u_char input[3];
 	u_char output[4];
-	size_t i;
-
-	assert(src != NULL);
-	assert(target != NULL);
+	int i;
 
 	while (2 < srclength) {
 		input[0] = *src++;
@@ -154,16 +140,10 @@
 		input[2] = *src++;
 		srclength -= 3;
 
-		output[0] = (u_int32_t)input[0] >> 2;
-		output[1] = ((u_int32_t)(input[0] & 0x03) << 4) +
-		    ((u_int32_t)input[1] >> 4);
-		output[2] = ((u_int32_t)(input[1] & 0x0f) << 2) +
-		    ((u_int32_t)input[2] >> 6);
+		output[0] = input[0] >> 2;
+		output[1] = ((input[0] & 0x03) << 4) + (input[1] >> 4);
+		output[2] = ((input[1] & 0x0f) << 2) + (input[2] >> 6);
 		output[3] = input[2] & 0x3f;
-		assert(output[0] < 64);
-		assert(output[1] < 64);
-		assert(output[2] < 64);
-		assert(output[3] < 64);
 
 		if (datalength + 4 > targsize)
 			return (-1);
@@ -172,22 +152,17 @@
 		target[datalength++] = Base64[output[2]];
 		target[datalength++] = Base64[output[3]];
 	}
-
+    
 	/* Now we worry about padding. */
 	if (0 != srclength) {
 		/* Get what's left. */
 		input[0] = input[1] = input[2] = '\0';
 		for (i = 0; i < srclength; i++)
 			input[i] = *src++;
-
-		output[0] = (u_int32_t)input[0] >> 2;
-		output[1] = ((u_int32_t)(input[0] & 0x03) << 4) +
-		    ((u_int32_t)input[1] >> 4);
-		output[2] = ((u_int32_t)(input[1] & 0x0f) << 2) +
-		    ((u_int32_t)input[2] >> 6);
-		assert(output[0] < 64);
-		assert(output[1] < 64);
-		assert(output[2] < 64);
+	
+		output[0] = input[0] >> 2;
+		output[1] = ((input[0] & 0x03) << 4) + (input[1] >> 4);
+		output[2] = ((input[1] & 0x0f) << 2) + (input[2] >> 6);
 
 		if (datalength + 4 > targsize)
 			return (-1);
@@ -217,17 +192,14 @@
 	u_char *target;
 	size_t targsize;
 {
-	size_t tarindex;
-	int state, ch;
+	int tarindex, state, ch;
+	u_char nextbyte;
 	char *pos;
 
-	assert(src != NULL);
-	assert(target != NULL);
-
 	state = 0;
 	tarindex = 0;
 
-	while ((ch = (u_char) *src++) != '\0') {
+	while ((ch = (unsigned char)*src++) != '\0') {
 		if (isspace(ch))	/* Skip whitespace anywhere. */
 			continue;
 
@@ -249,24 +221,28 @@
 			break;
 		case 1:
 			if (target) {
-				if (tarindex + 1 >= targsize)
+				if (tarindex >= targsize)
 					return (-1);
-				target[tarindex] |=
-				    (u_int32_t)(pos - Base64) >> 4;
-				target[tarindex+1]  = ((pos - Base64) & 0x0f)
-							<< 4 ;
+				target[tarindex]   |=  (pos - Base64) >> 4;
+				nextbyte = ((pos - Base64) & 0x0f) << 4;
+				if (tarindex + 1 < targsize)
+					target[tarindex+1] = nextbyte;
+				else if (nextbyte)
+					return (-1);
 			}
 			tarindex++;
 			state = 2;
 			break;
 		case 2:
 			if (target) {
-				if (tarindex + 1 >= targsize)
+				if (tarindex >= targsize)
 					return (-1);
-				target[tarindex] |=
-					(u_int32_t)(pos - Base64) >> 2;
-				target[tarindex+1] = ((pos - Base64) & 0x03)
-							<< 6;
+				target[tarindex]   |=  (pos - Base64) >> 2;
+				nextbyte = ((pos - Base64) & 0x03) << 6;
+				if (tarindex + 1 < targsize)
+					target[tarindex+1] = nextbyte;
+				else if (nextbyte)
+					return (-1);
 			}
 			tarindex++;
 			state = 3;
@@ -280,8 +256,6 @@
 			tarindex++;
 			state = 0;
 			break;
-		default:
-			abort();
 		}
 	}
 
@@ -290,8 +264,8 @@
 	 * on a byte boundary, and/or with erroneous trailing characters.
 	 */
 
-	if (ch == Pad64) {		/* We got a pad char. */
-		ch = *src++;		/* Skip it, get next. */
+	if (ch == Pad64) {			/* We got a pad char. */
+		ch = (unsigned char)*src++;	/* Skip it, get next. */
 		switch (state) {
 		case 0:		/* Invalid = in first position */
 		case 1:		/* Invalid = in second position */
@@ -299,13 +273,13 @@
 
 		case 2:		/* Valid, means one byte of info */
 			/* Skip any number of spaces. */
-			for (; ch != '\0'; ch = (u_char) *src++)
+			for (; ch != '\0'; ch = (unsigned char)*src++)
 				if (!isspace(ch))
 					break;
 			/* Make sure there is another trailing = sign. */
 			if (ch != Pad64)
 				return (-1);
-			ch = *src++;		/* Skip the = */
+			ch = (unsigned char)*src++;		/* Skip the = */
 			/* Fall through to "single trailing =" case. */
 			/* FALLTHROUGH */
 
@@ -314,7 +288,7 @@
 			 * We know this char is an =.  Is there anything but
 			 * whitespace after it?
 			 */
-			for (; ch != '\0'; ch = (u_char) *src++)
+			for (; ch != '\0'; ch = (unsigned char)*src++)
 				if (!isspace(ch))
 					return (-1);
 
@@ -324,7 +298,8 @@
 			 * zeros.  If we don't check them, they become a
 			 * subliminal channel.
 			 */
-			if (target && target[tarindex] != 0)
+			if (target && tarindex < targsize &&
+			    target[tarindex] != 0)
 				return (-1);
 		}
 	} else {
diff --git a/libdl/Android.bp b/libdl/Android.bp
index 2aa9b68..84561d9 100644
--- a/libdl/Android.bp
+++ b/libdl/Android.bp
@@ -56,5 +56,7 @@
     allow_undefined_symbols: true,
     system_shared_libs: [],
 
-    sanitize: ["never"],
+    sanitize: {
+        never: true,
+    },
 }
diff --git a/libdl/libdl.arm.map b/libdl/libdl.arm.map
index 67c8d08..20efa9a 100644
--- a/libdl/libdl.arm.map
+++ b/libdl/libdl.arm.map
@@ -16,8 +16,6 @@
 
 LIBC_N {
   global:
-    android_init_namespaces;
-    android_create_namespace;
     dlvsym;
 } LIBC;
 
@@ -27,4 +25,6 @@
     android_set_application_target_sdk_version;
     android_get_LD_LIBRARY_PATH;
     android_update_LD_LIBRARY_PATH;
+    android_init_namespaces;
+    android_create_namespace;
 } LIBC_N;
diff --git a/libdl/libdl.arm64.map b/libdl/libdl.arm64.map
index 4d035f5..daf5a86 100644
--- a/libdl/libdl.arm64.map
+++ b/libdl/libdl.arm64.map
@@ -15,8 +15,6 @@
 
 LIBC_N {
   global:
-    android_init_namespaces;
-    android_create_namespace;
     dlvsym;
 } LIBC;
 
@@ -26,4 +24,6 @@
     android_set_application_target_sdk_version;
     android_get_LD_LIBRARY_PATH;
     android_update_LD_LIBRARY_PATH;
+    android_init_namespaces;
+    android_create_namespace;
 } LIBC_N;
diff --git a/libdl/libdl.map.txt b/libdl/libdl.map.txt
index 67ff64e..79bced3 100644
--- a/libdl/libdl.map.txt
+++ b/libdl/libdl.map.txt
@@ -30,8 +30,6 @@
 
 LIBC_N {
   global:
-    android_init_namespaces;
-    android_create_namespace;
     dlvsym;
 } LIBC;
 
@@ -41,4 +39,6 @@
     android_set_application_target_sdk_version;
     android_get_LD_LIBRARY_PATH;
     android_update_LD_LIBRARY_PATH;
+    android_init_namespaces;
+    android_create_namespace;
 } LIBC_N;
diff --git a/libdl/libdl.mips.map b/libdl/libdl.mips.map
index 4d035f5..daf5a86 100644
--- a/libdl/libdl.mips.map
+++ b/libdl/libdl.mips.map
@@ -15,8 +15,6 @@
 
 LIBC_N {
   global:
-    android_init_namespaces;
-    android_create_namespace;
     dlvsym;
 } LIBC;
 
@@ -26,4 +24,6 @@
     android_set_application_target_sdk_version;
     android_get_LD_LIBRARY_PATH;
     android_update_LD_LIBRARY_PATH;
+    android_init_namespaces;
+    android_create_namespace;
 } LIBC_N;
diff --git a/libdl/libdl.mips64.map b/libdl/libdl.mips64.map
index 4d035f5..daf5a86 100644
--- a/libdl/libdl.mips64.map
+++ b/libdl/libdl.mips64.map
@@ -15,8 +15,6 @@
 
 LIBC_N {
   global:
-    android_init_namespaces;
-    android_create_namespace;
     dlvsym;
 } LIBC;
 
@@ -26,4 +24,6 @@
     android_set_application_target_sdk_version;
     android_get_LD_LIBRARY_PATH;
     android_update_LD_LIBRARY_PATH;
+    android_init_namespaces;
+    android_create_namespace;
 } LIBC_N;
diff --git a/libdl/libdl.x86.map b/libdl/libdl.x86.map
index 4d035f5..daf5a86 100644
--- a/libdl/libdl.x86.map
+++ b/libdl/libdl.x86.map
@@ -15,8 +15,6 @@
 
 LIBC_N {
   global:
-    android_init_namespaces;
-    android_create_namespace;
     dlvsym;
 } LIBC;
 
@@ -26,4 +24,6 @@
     android_set_application_target_sdk_version;
     android_get_LD_LIBRARY_PATH;
     android_update_LD_LIBRARY_PATH;
+    android_init_namespaces;
+    android_create_namespace;
 } LIBC_N;
diff --git a/libdl/libdl.x86_64.map b/libdl/libdl.x86_64.map
index 4d035f5..daf5a86 100644
--- a/libdl/libdl.x86_64.map
+++ b/libdl/libdl.x86_64.map
@@ -15,8 +15,6 @@
 
 LIBC_N {
   global:
-    android_init_namespaces;
-    android_create_namespace;
     dlvsym;
 } LIBC;
 
@@ -26,4 +24,6 @@
     android_set_application_target_sdk_version;
     android_get_LD_LIBRARY_PATH;
     android_update_LD_LIBRARY_PATH;
+    android_init_namespaces;
+    android_create_namespace;
 } LIBC_N;
diff --git a/libm/Android.bp b/libm/Android.bp
index 52249c9..27ea1c1 100644
--- a/libm/Android.bp
+++ b/libm/Android.bp
@@ -314,7 +314,9 @@
     system_shared_libs: ["libc"],
 
     native_coverage: bionic_coverage,
-    sanitize: ["never"],
+    sanitize: {
+        never: true,
+    },
 
     multilib: {
         lib32: {
diff --git a/linker/linker.cpp b/linker/linker.cpp
index 93fab8f..0fdf90d 100644
--- a/linker/linker.cpp
+++ b/linker/linker.cpp
@@ -110,6 +110,7 @@
   void add_soinfos(const soinfo::soinfo_list_t& soinfos) {
     for (auto si : soinfos) {
       add_soinfo(si);
+      si->add_secondary_namespace(this);
     }
   }
 
@@ -146,6 +147,7 @@
 static LinkerTypeAllocator<LinkedListEntry<soinfo>> g_soinfo_links_allocator;
 
 static LinkerTypeAllocator<android_namespace_t> g_namespace_allocator;
+static LinkerTypeAllocator<LinkedListEntry<android_namespace_t>> g_namespace_list_allocator;
 
 static soinfo* solist;
 static soinfo* sonext;
@@ -286,6 +288,14 @@
   g_soinfo_links_allocator.free(entry);
 }
 
+LinkedListEntry<android_namespace_t>* NamespaceListAllocator::alloc() {
+  return g_namespace_list_allocator.alloc();
+}
+
+void NamespaceListAllocator::free(LinkedListEntry<android_namespace_t>* entry) {
+  g_namespace_list_allocator.free(entry);
+}
+
 static soinfo* soinfo_alloc(android_namespace_t* ns, const char* name,
                             struct stat* file_stat, off64_t file_offset,
                             uint32_t rtld_flags) {
@@ -349,9 +359,6 @@
     sonext = prev;
   }
 
-  // remove from the namespace
-  si->get_namespace()->remove_soinfo(si);
-
   si->~soinfo();
   g_soinfo_allocator.free(si);
 }
@@ -843,7 +850,7 @@
   }
 
   this->rtld_flags_ = rtld_flags;
-  this->namespace_ = ns;
+  this->primary_namespace_ = ns;
 }
 
 soinfo::~soinfo() {
@@ -1003,6 +1010,7 @@
     g_soinfo_allocator.protect_all(protection);
     g_soinfo_links_allocator.protect_all(protection);
     g_namespace_allocator.protect_all(protection);
+    g_namespace_list_allocator.protect_all(protection);
   }
 
   static size_t ref_count_;
@@ -2122,7 +2130,7 @@
           TRACE("deprecated (old format of soinfo): %s needs to unload %s",
               si->get_realpath(), library_name);
 
-          soinfo* needed = find_library(si->get_namespace(),
+          soinfo* needed = find_library(si->get_primary_namespace(),
                                         library_name, RTLD_NOLOAD, nullptr, nullptr);
 
           if (needed != nullptr) {
@@ -2172,6 +2180,10 @@
   return std::string(sym_name) + ", version " + sym_ver;
 }
 
+static android_namespace_t* get_caller_namespace(soinfo* caller) {
+  return caller != nullptr ? caller->get_primary_namespace() : g_anonymous_namespace;
+}
+
 void do_android_get_LD_LIBRARY_PATH(char* buffer, size_t buffer_size) {
   // Use basic string manipulation calls to avoid snprintf.
   // snprintf indirectly calls pthread_getspecific to get the size of a buffer.
@@ -2208,7 +2220,7 @@
     return nullptr;
   }
 
-  android_namespace_t* ns = caller != nullptr ? caller->get_namespace() : g_anonymous_namespace;
+  android_namespace_t* ns = get_caller_namespace(caller);
 
   if (extinfo != nullptr) {
     if ((extinfo->flags & ~(ANDROID_DLEXT_VALID_FLAG_BITS)) != 0) {
@@ -2302,7 +2314,7 @@
   soinfo* found = nullptr;
   const ElfW(Sym)* sym = nullptr;
   soinfo* caller = find_containing_library(caller_addr);
-  android_namespace_t* ns = caller != nullptr ? caller->get_namespace() : g_anonymous_namespace;
+  android_namespace_t* ns = get_caller_namespace(caller);
 
   version_info vi_instance;
   version_info* vi = nullptr;
@@ -2415,7 +2427,7 @@
   soinfo* caller_soinfo = find_containing_library(caller_addr);
 
   android_namespace_t* caller_ns = caller_soinfo != nullptr ?
-                                   caller_soinfo->get_namespace() :
+                                   caller_soinfo->get_primary_namespace() :
                                    g_anonymous_namespace;
 
   ProtectedDataGuard guard;
@@ -3023,10 +3035,6 @@
 
   // DT_FINI should be called after DT_FINI_ARRAY if both are present.
   call_function("DT_FINI", fini_func_);
-
-  // This is needed on second call to dlopen
-  // after library has been unloaded with RTLD_NODELETE
-  constructors_called = false;
 }
 
 void soinfo::add_child(soinfo* child) {
@@ -3054,9 +3062,20 @@
     });
   });
 
-  // 2. Once everything untied - clear local lists.
+  // 2. Remove from the primary namespace
+  primary_namespace_->remove_soinfo(this);
+  primary_namespace_ = nullptr;
+
+  // 3. Remove from secondary namespaces
+  secondary_namespaces_.for_each([&](android_namespace_t* ns) {
+    ns->remove_soinfo(this);
+  });
+
+
+  // 4. Once everything untied - clear local lists.
   parents_.clear();
   children_.clear();
+  secondary_namespaces_.clear();
 }
 
 dev_t soinfo::get_st_dev() const {
@@ -3190,14 +3209,19 @@
   return g_empty_runpath;
 }
 
-android_namespace_t* soinfo::get_namespace() {
+android_namespace_t* soinfo::get_primary_namespace() {
   if (has_min_version(3)) {
-    return namespace_;
+    return primary_namespace_;
   }
 
   return &g_default_namespace;
 }
 
+void soinfo::add_secondary_namespace(android_namespace_t* secondary_ns) {
+  CHECK(has_min_version(3));
+  secondary_namespaces_.push_back(secondary_ns);
+}
+
 ElfW(Addr) soinfo::resolve_symbol_address(const ElfW(Sym)* s) const {
   if (ELF_ST_TYPE(s->st_info) == STT_GNU_IFUNC) {
     return call_ifunc_resolver(s->st_value + load_bias);
@@ -3220,7 +3244,7 @@
 }
 
 bool soinfo::can_unload() const {
-  return (get_rtld_flags() & (RTLD_NODELETE | RTLD_GLOBAL)) == 0;
+  return !is_linked() || ((get_rtld_flags() & (RTLD_NODELETE | RTLD_GLOBAL)) == 0);
 }
 
 bool soinfo::is_linked() const {
diff --git a/linker/linker.h b/linker/linker.h
index 81f93ac..4e2e0b9 100644
--- a/linker/linker.h
+++ b/linker/linker.h
@@ -114,6 +114,16 @@
   DISALLOW_IMPLICIT_CONSTRUCTORS(SoinfoListAllocator);
 };
 
+class NamespaceListAllocator {
+ public:
+  static LinkedListEntry<android_namespace_t>* alloc();
+  static void free(LinkedListEntry<android_namespace_t>* entry);
+
+ private:
+  // unconstructable
+  DISALLOW_IMPLICIT_CONSTRUCTORS(NamespaceListAllocator);
+};
+
 class SymbolName {
  public:
   explicit SymbolName(const char* name)
@@ -166,6 +176,7 @@
 struct soinfo {
  public:
   typedef LinkedList<soinfo, SoinfoListAllocator> soinfo_list_t;
+  typedef LinkedList<android_namespace_t, NamespaceListAllocator> android_namespace_list_t;
 #if defined(__work_around_b_24465209__)
  private:
   char old_name_[SOINFO_NAME_LEN];
@@ -342,7 +353,8 @@
 
   void set_dt_runpath(const char *);
   const std::vector<std::string>& get_dt_runpath() const;
-  android_namespace_t* get_namespace();
+  android_namespace_t* get_primary_namespace();
+  void add_secondary_namespace(android_namespace_t* secondary_ns);
 
   void set_mapped_by_caller(bool reserved_map);
   bool is_mapped_by_caller() const;
@@ -414,7 +426,8 @@
 
   // version >= 3
   std::vector<std::string> dt_runpath_;
-  android_namespace_t* namespace_;
+  android_namespace_t* primary_namespace_;
+  android_namespace_list_t secondary_namespaces_;
   uintptr_t handle_;
 
   friend soinfo* get_libdl_info();
diff --git a/tests/Android.mk b/tests/Android.mk
index c190428..7292d9d 100644
--- a/tests/Android.mk
+++ b/tests/Android.mk
@@ -74,9 +74,11 @@
     net_if_test.cpp \
     netinet_in_test.cpp \
     netinet_udp_test.cpp \
+    nl_types_test.cpp \
     pthread_test.cpp \
     pty_test.cpp \
     regex_test.cpp \
+    resolv_test.cpp \
     sched_test.cpp \
     search_test.cpp \
     semaphore_test.cpp \
@@ -102,6 +104,7 @@
     sys_personality_test.cpp \
     sys_prctl_test.cpp \
     sys_procfs_test.cpp \
+    sys_quota_test.cpp \
     sys_resource_test.cpp \
     sys_select_test.cpp \
     sys_sendfile_test.cpp \
@@ -413,7 +416,7 @@
     libcutils \
 
 bionic-unit-tests-glibc_ldlibs := \
-    -lrt -ldl -lutil \
+    -lresolv -lrt -ldl -lutil \
 
 bionic-unit-tests-glibc_c_includes := \
     bionic/libc \
diff --git a/tests/dlext_test.cpp b/tests/dlext_test.cpp
index bbdc024..87e5dbc 100644
--- a/tests/dlext_test.cpp
+++ b/tests/dlext_test.cpp
@@ -959,6 +959,70 @@
   dlclose(handle2);
 }
 
+TEST(dlext, ns_shared_dlclose) {
+  std::string path = "libc.so:libc++.so:libdl.so:libm.so";
+
+  const std::string lib_path = std::string(getenv("ANDROID_DATA")) + NATIVE_TESTS_PATH;
+
+  android_set_application_target_sdk_version(42U); // something > 23
+
+  ASSERT_TRUE(android_init_namespaces(path.c_str(), nullptr)) << dlerror();
+
+  // preload this library to the default namespace to check if it
+  // is shared later on.
+  void* handle_dlopened =
+          dlopen((lib_path + "/private_namespace_libs/libnstest_dlopened.so").c_str(), RTLD_NOW);
+  ASSERT_TRUE(handle_dlopened != nullptr) << dlerror();
+
+  android_namespace_t* ns_isolated_shared =
+          android_create_namespace("private_isolated_shared", nullptr,
+                                   (lib_path + "/private_namespace_libs").c_str(),
+                                   ANDROID_NAMESPACE_TYPE_ISOLATED | ANDROID_NAMESPACE_TYPE_SHARED,
+                                   nullptr);
+  ASSERT_TRUE(ns_isolated_shared != nullptr) << dlerror();
+
+  // Check if "libnstest_dlopened.so" is loaded (and the same)
+  android_dlextinfo extinfo;
+  extinfo.flags = ANDROID_DLEXT_USE_NAMESPACE;
+  extinfo.library_namespace = ns_isolated_shared;
+
+  void* handle = android_dlopen_ext("libnstest_dlopened.so", RTLD_NOW | RTLD_NOLOAD, &extinfo);
+  ASSERT_TRUE(handle != nullptr) << dlerror();
+  ASSERT_TRUE(handle == handle_dlopened);
+  dlclose(handle);
+  dlclose(handle_dlopened);
+
+  // And now check that the library cannot be found by soname (and is no longer loaded)
+  handle = android_dlopen_ext("libnstest_dlopened.so", RTLD_NOW | RTLD_NOLOAD, &extinfo);
+  ASSERT_TRUE(handle == nullptr)
+      << "Error: libnstest_dlopened.so is still accessible in shared namespace";
+
+  handle = android_dlopen_ext((lib_path + "/private_namespace_libs/libnstest_dlopened.so").c_str(),
+                              RTLD_NOW | RTLD_NOLOAD, &extinfo);
+  ASSERT_TRUE(handle == nullptr)
+      << "Error: libnstest_dlopened.so is still accessible in shared namespace";
+
+  handle = dlopen("libnstest_dlopened.so", RTLD_NOW | RTLD_NOLOAD);
+  ASSERT_TRUE(handle == nullptr)
+      << "Error: libnstest_dlopened.so is still accessible in default namespace";
+
+  handle = dlopen((lib_path + "/private_namespace_libs/libnstest_dlopened.so").c_str(),
+                  RTLD_NOW | RTLD_NOLOAD);
+  ASSERT_TRUE(handle == nullptr)
+      << "Error: libnstest_dlopened.so is still accessible in default namespace";
+
+  // Now lets see if the soinfo area gets reused in the wrong way:
+  // load a library to default namespace.
+  const std::string lib_public_path = lib_path + "/public_namespace_libs/" + g_public_lib;
+  void* handle_public = dlopen(lib_public_path.c_str(), RTLD_NOW);
+  ASSERT_TRUE(handle_public != nullptr) << dlerror();
+
+  // try to find it in shared namespace
+  handle = android_dlopen_ext(g_public_lib, RTLD_NOW | RTLD_NOLOAD, &extinfo);
+  ASSERT_TRUE(handle == nullptr)
+      << "Error: " << g_public_lib << " is accessible in shared namespace";
+}
+
 TEST(dlext, ns_anonymous) {
   static const char* root_lib = "libnstest_root.so";
   std::string path = std::string("libc.so:libc++.so:libdl.so:libm.so:") + g_public_lib;
diff --git a/tests/dlfcn_test.cpp b/tests/dlfcn_test.cpp
index 19f9978..748d0ca 100644
--- a/tests/dlfcn_test.cpp
+++ b/tests/dlfcn_test.cpp
@@ -256,6 +256,21 @@
   ASSERT_STREQ("true", is_ctor_called());
   dlclose(handle);
 }
+
+TEST(dlfcn, ifunc_ctor_call_rtld_lazy) {
+  typedef const char* (*fn_ptr)();
+
+  void* handle = dlopen("libtest_ifunc.so", RTLD_LAZY);
+  ASSERT_TRUE(handle != nullptr) << dlerror();
+  fn_ptr is_ctor_called =  reinterpret_cast<fn_ptr>(dlsym(handle, "is_ctor_called_irelative"));
+  ASSERT_TRUE(is_ctor_called != nullptr) << dlerror();
+  ASSERT_STREQ("false", is_ctor_called());
+
+  is_ctor_called =  reinterpret_cast<fn_ptr>(dlsym(handle, "is_ctor_called_jump_slot"));
+  ASSERT_TRUE(is_ctor_called != nullptr) << dlerror();
+  ASSERT_STREQ("true", is_ctor_called());
+  dlclose(handle);
+}
 #endif
 
 TEST(dlfcn, dlopen_check_relocation_dt_needed_order) {
diff --git a/tests/ftw_test.cpp b/tests/ftw_test.cpp
index b7e5bd5..ea494ba 100644
--- a/tests/ftw_test.cpp
+++ b/tests/ftw_test.cpp
@@ -16,6 +16,7 @@
 
 #include <ftw.h>
 
+#include <pwd.h>
 #include <stdio.h>
 #include <stdlib.h>
 #include <sys/stat.h>
@@ -24,6 +25,7 @@
 
 #include "TemporaryFile.h"
 
+#include <android-base/stringprintf.h>
 #include <gtest/gtest.h>
 
 static void MakeTree(const char* root) {
@@ -39,7 +41,7 @@
   snprintf(path, sizeof(path), "%s/dangler", root);
   ASSERT_EQ(0, symlink("/does-not-exist", path));
   snprintf(path, sizeof(path), "%s/symlink", root);
-  ASSERT_EQ(0, symlink("sub2", path));
+  ASSERT_EQ(0, symlink("dir/sub", path));
 
   int fd;
   snprintf(path, sizeof(path), "%s/regular", root);
@@ -51,8 +53,21 @@
   ASSERT_TRUE(fpath != NULL);
   ASSERT_TRUE(sb != NULL);
 
+  // Was it a case where the struct stat we're given is meaningless?
+  if (tflag == FTW_NS || tflag == FTW_SLN) {
+    // If so, double-check that we really can't stat.
+    struct stat sb;
+    EXPECT_EQ(-1, stat(fpath, &sb));
+    return;
+  }
+
+  // Otherwise check that the struct stat matches the type flag.
   if (S_ISDIR(sb->st_mode)) {
-    EXPECT_TRUE(tflag == FTW_D || tflag == FTW_DNR || tflag == FTW_DP) << fpath;
+    if (access(fpath, R_OK) == 0) {
+      EXPECT_TRUE(tflag == FTW_D || tflag == FTW_DP) << fpath << ' ' << tflag;
+    } else {
+      EXPECT_EQ(FTW_DNR, tflag) << fpath;
+    }
   } else if (S_ISLNK(sb->st_mode)) {
     EXPECT_EQ(FTW_SL, tflag) << fpath;
   } else {
@@ -60,7 +75,7 @@
   }
 }
 
-void sanity_check_nftw(const char* fpath, const struct stat* sb, int tflag, struct FTW* ftwbuf) {
+void sanity_check_nftw(const char* fpath, const struct stat* sb, int tflag, FTW* ftwbuf) {
   sanity_check_ftw(fpath, sb, tflag);
   ASSERT_EQ('/', fpath[ftwbuf->base - 1]) << fpath;
 }
@@ -75,12 +90,12 @@
   return 0;
 }
 
-int check_nftw(const char* fpath, const struct stat* sb, int tflag, struct FTW* ftwbuf) {
+int check_nftw(const char* fpath, const struct stat* sb, int tflag, FTW* ftwbuf) {
   sanity_check_nftw(fpath, sb, tflag, ftwbuf);
   return 0;
 }
 
-int check_nftw64(const char* fpath, const struct stat64* sb, int tflag, struct FTW* ftwbuf) {
+int check_nftw64(const char* fpath, const struct stat64* sb, int tflag, FTW* ftwbuf) {
   sanity_check_nftw(fpath, reinterpret_cast<const struct stat*>(sb), tflag, ftwbuf);
   return 0;
 }
@@ -108,3 +123,33 @@
   MakeTree(root.dirname);
   ASSERT_EQ(0, nftw64(root.dirname, check_nftw64, 128, 0));
 }
+
+template <typename StatT>
+static int bug_28197840_ftw(const char* path, const StatT*, int flag) {
+  EXPECT_EQ(strstr(path, "unreadable") != nullptr ? FTW_DNR : FTW_D, flag) << path;
+  return 0;
+}
+
+template <typename StatT>
+static int bug_28197840_nftw(const char* path, const StatT* sb, int flag, FTW*) {
+  return bug_28197840_ftw(path, sb, flag);
+}
+
+TEST(ftw, bug_28197840) {
+  // Drop root for this test, because root can still read directories even if
+  // permissions would imply otherwise.
+  if (getuid() == 0) {
+    passwd* pwd = getpwnam("shell");
+    ASSERT_EQ(0, setuid(pwd->pw_uid));
+  }
+
+  TemporaryDir root;
+
+  std::string path = android::base::StringPrintf("%s/unreadable-directory", root.dirname);
+  ASSERT_EQ(0, mkdir(path.c_str(), 0000)) << path;
+
+  ASSERT_EQ(0, ftw(root.dirname, bug_28197840_ftw<struct stat>, 128));
+  ASSERT_EQ(0, ftw64(root.dirname, bug_28197840_ftw<struct stat64>, 128));
+  ASSERT_EQ(0, nftw(root.dirname, bug_28197840_nftw<struct stat>, 128, FTW_PHYS));
+  ASSERT_EQ(0, nftw64(root.dirname, bug_28197840_nftw<struct stat64>, 128, FTW_PHYS));
+}
diff --git a/tests/grp_pwd_test.cpp b/tests/grp_pwd_test.cpp
index c81ca58..29cd907 100644
--- a/tests/grp_pwd_test.cpp
+++ b/tests/grp_pwd_test.cpp
@@ -122,12 +122,20 @@
   check_get_passwd("radio", 1001, TYPE_SYSTEM);
 }
 
-TEST(getpwnam, oem_id_0) {
-  check_get_passwd("oem_0", 5000, TYPE_SYSTEM);
+TEST(getpwnam, oem_id_5000) {
+  check_get_passwd("oem_5000", 5000, TYPE_SYSTEM);
 }
 
-TEST(getpwnam, oem_id_999) {
-  check_get_passwd("oem_999", 5999, TYPE_SYSTEM);
+TEST(getpwnam, oem_id_5999) {
+  check_get_passwd("oem_5999", 5999, TYPE_SYSTEM);
+}
+
+TEST(getpwnam, oem_id_2900) {
+  check_get_passwd("oem_2900", 2900, TYPE_SYSTEM);
+}
+
+TEST(getpwnam, oem_id_2999) {
+  check_get_passwd("oem_2999", 2999, TYPE_SYSTEM);
 }
 
 TEST(getpwnam, app_id_nobody) {
@@ -255,12 +263,20 @@
   check_get_group("radio", 1001);
 }
 
-TEST(getgrnam, oem_id_0) {
-  check_get_group("oem_0", 5000);
+TEST(getgrnam, oem_id_5000) {
+  check_get_group("oem_5000", 5000);
 }
 
-TEST(getgrnam, oem_id_999) {
-  check_get_group("oem_999", 5999);
+TEST(getgrnam, oem_id_5999) {
+  check_get_group("oem_5999", 5999);
+}
+
+TEST(getgrnam, oem_id_2900) {
+  check_get_group("oem_2900", 2900);
+}
+
+TEST(getgrnam, oem_id_2999) {
+  check_get_group("oem_2999", 2999);
 }
 
 TEST(getgrnam, app_id_nobody) {
diff --git a/tests/nl_types_test.cpp b/tests/nl_types_test.cpp
new file mode 100644
index 0000000..2e3995b
--- /dev/null
+++ b/tests/nl_types_test.cpp
@@ -0,0 +1,31 @@
+/*
+ * Copyright (C) 2016 The Android Open Source Project
+ *
+ * Licensed under the Apache License, Version 2.0 (the "License");
+ * you may not use this file except in compliance with the License.
+ * You may obtain a copy of the License at
+ *
+ *      http://www.apache.org/licenses/LICENSE-2.0
+ *
+ * Unless required by applicable law or agreed to in writing, software
+ * distributed under the License is distributed on an "AS IS" BASIS,
+ * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
+ * See the License for the specific language governing permissions and
+ * limitations under the License.
+ */
+
+#include <nl_types.h>
+
+#include <errno.h>
+#include <gtest/gtest.h>
+
+TEST(nl_types, smoke) {
+  nl_catd cat = catopen("/does/not/exist", NL_CAT_LOCALE);
+  ASSERT_EQ(reinterpret_cast<nl_catd>(-1), cat);
+
+  ASSERT_STREQ("hello, world!", catgets(cat, NL_SETD, 0, "hello, world!"));
+
+  errno = 0;
+  ASSERT_EQ(-1, catclose(cat));
+  ASSERT_EQ(EBADF, errno);
+}
diff --git a/tests/pthread_test.cpp b/tests/pthread_test.cpp
index 019016d..589cab4 100755
--- a/tests/pthread_test.cpp
+++ b/tests/pthread_test.cpp
@@ -24,6 +24,7 @@
 #include <signal.h>
 #include <stdio.h>
 #include <sys/mman.h>
+#include <sys/prctl.h>
 #include <sys/syscall.h>
 #include <time.h>
 #include <unistd.h>
@@ -422,7 +423,21 @@
   SpinFunctionHelper spin_helper;
 
   pthread_t t;
-  ASSERT_EQ(0, pthread_create(&t, NULL, spin_helper.GetFunction(), NULL));
+  ASSERT_EQ(0, pthread_create(&t, nullptr, spin_helper.GetFunction(), nullptr));
+  test_pthread_setname_np__pthread_getname_np(t);
+  spin_helper.UnSpin();
+  ASSERT_EQ(0, pthread_join(t, nullptr));
+}
+
+// http://b/28051133: a kernel misfeature means that you can't change the
+// name of another thread if you've set PR_SET_DUMPABLE to 0.
+TEST(pthread, pthread_setname_np__pthread_getname_np__other_PR_SET_DUMPABLE) {
+  ASSERT_EQ(0, prctl(PR_SET_DUMPABLE, 0)) << strerror(errno);
+
+  SpinFunctionHelper spin_helper;
+
+  pthread_t t;
+  ASSERT_EQ(0, pthread_create(&t, nullptr, spin_helper.GetFunction(), nullptr));
   test_pthread_setname_np__pthread_getname_np(t);
   spin_helper.UnSpin();
   ASSERT_EQ(0, pthread_join(t, nullptr));
diff --git a/tests/resolv_test.cpp b/tests/resolv_test.cpp
new file mode 100644
index 0000000..08f9d90
--- /dev/null
+++ b/tests/resolv_test.cpp
@@ -0,0 +1,44 @@
+/*
+ * Copyright (C) 2016 The Android Open Source Project
+ * All rights reserved.
+ *
+ * Redistribution and use in source and binary forms, with or without
+ * modification, are permitted provided that the following conditions
+ * are met:
+ *  * Redistributions of source code must retain the above copyright
+ *    notice, this list of conditions and the following disclaimer.
+ *  * Redistributions in binary form must reproduce the above copyright
+ *    notice, this list of conditions and the following disclaimer in
+ *    the documentation and/or other materials provided with the
+ *    distribution.
+ *
+ * THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS
+ * "AS IS" AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT
+ * LIMITED TO, THE IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS
+ * FOR A PARTICULAR PURPOSE ARE DISCLAIMED. IN NO EVENT SHALL THE
+ * COPYRIGHT OWNER OR CONTRIBUTORS BE LIABLE FOR ANY DIRECT, INDIRECT,
+ * INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING,
+ * BUT NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; LOSS
+ * OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED
+ * AND ON ANY THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY,
+ * OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT
+ * OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF
+ * SUCH DAMAGE.
+ */
+
+#include <resolv.h>
+
+#include <gtest/gtest.h>
+
+TEST(resolv, b64_pton_28035006) {
+  // Test data from https://groups.google.com/forum/#!topic/mailing.openbsd.tech/w3ACIlklJkI.
+  const char* data =
+      "p1v3+nehH3N3n+/OokzXpsyGF2VVpxIxkjSn3Mv/Sq74OE1iFuVU+K4bQImuVj"
+      "S55RB2fpCpbB8Nye7tzrt6h9YPP3yyJfqORDETGmIB4lveZXA4KDxx50F9rYrO"
+      "dFbTLyWfNBb/8Q2TnD72eY/3Y5P9qwtJwyDL25Tleic8G3g=";
+
+  // This buffer is exactly the right size, but old versions of the BSD code
+  // incorrectly required an extra byte. http://b/28035006.
+  uint8_t buf[128];
+  ASSERT_EQ(128, b64_pton(data, buf, sizeof(buf)));
+}
diff --git a/tests/sys_quota_test.cpp b/tests/sys_quota_test.cpp
new file mode 100644
index 0000000..e23207b
--- /dev/null
+++ b/tests/sys_quota_test.cpp
@@ -0,0 +1,33 @@
+/*
+ * Copyright (C) 2016 The Android Open Source Project
+ *
+ * Licensed under the Apache License, Version 2.0 (the "License");
+ * you may not use this file except in compliance with the License.
+ * You may obtain a copy of the License at
+ *
+ *      http://www.apache.org/licenses/LICENSE-2.0
+ *
+ * Unless required by applicable law or agreed to in writing, software
+ * distributed under the License is distributed on an "AS IS" BASIS,
+ * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
+ * See the License for the specific language governing permissions and
+ * limitations under the License.
+ */
+
+#include <sys/quota.h>
+
+#include <gtest/gtest.h>
+
+TEST(sys_quota, quotactl_dqblk) {
+  // We don't even have kernels with CONFIG_QUOTA enabled right now.
+  // This just tests that we can compile reasonable code.
+  dqblk current;
+  quotactl(QCMD(Q_GETQUOTA, USRQUOTA), "/", getuid(), reinterpret_cast<char*>(&current));
+}
+
+TEST(sys_quota, quotactl_dqinfo) {
+  // We don't even have kernels with CONFIG_QUOTA enabled right now.
+  // This just tests that we can compile reasonable code.
+  dqinfo current;
+  quotactl(QCMD(Q_GETINFO, USRQUOTA), "/", 0, reinterpret_cast<char*>(&current));
+}