Merge "Add malloc debug documentation."
diff --git a/libc/Android.bp b/libc/Android.bp
index 3ec5e96..8024912 100644
--- a/libc/Android.bp
+++ b/libc/Android.bp
@@ -307,8 +307,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",
@@ -508,6 +506,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",
@@ -1279,6 +1278,7 @@
         "bionic/fpclassify.cpp",
         "bionic/fsetxattr.cpp",
         "bionic/ftruncate.cpp",
+        "bionic/ftw.cpp",
         "bionic/futimens.cpp",
         "bionic/getcwd.cpp",
         "bionic/getdomainname.cpp",
@@ -1350,12 +1350,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",
@@ -1369,6 +1374,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",
@@ -1914,7 +1920,7 @@
         "crt_defaults",
         "crt_so_defaults",
     ],
-    deps: [
+    objs: [
         "crtbegin_so1",
         "crtbrand",
     ],
@@ -1972,7 +1978,7 @@
 cc_object {
     name: "crtbegin_static",
 
-    deps: [
+    objs: [
         "crtbegin_static1",
         "crtbrand",
     ],
@@ -2018,7 +2024,7 @@
 cc_object {
     name: "crtbegin_dynamic",
 
-    deps: [
+    objs: [
         "crtbegin_dynamic1",
         "crtbrand",
     ],
diff --git a/libc/Android.mk b/libc/Android.mk
index fa392d1..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 \
@@ -288,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 \
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/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/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/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 651fea4..541dbb2 100644
--- a/libc/libc.arm.brillo.map
+++ b/libc/libc.arm.brillo.map
@@ -1434,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 1c7a0ba..1784b95 100644
--- a/libc/libc.arm.map
+++ b/libc/libc.arm.map
@@ -1445,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.map.txt b/libc/libc.map.txt
index ed20efc..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;
@@ -1471,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 d96de34..953fc29 100644
--- a/libc/libc.mips.brillo.map
+++ b/libc/libc.mips.brillo.map
@@ -1294,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 5fe3a51..90db79d 100644
--- a/libc/libc.mips.map
+++ b/libc/libc.mips.map
@@ -1305,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.x86.brillo.map b/libc/libc.x86.brillo.map
index f167183..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;
@@ -1294,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 d37d28a..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;
@@ -1305,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/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/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/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/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/linker/linker.cpp b/linker/linker.cpp
index 855b32b..77f5359 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/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/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));