Merge "Move kernel README files to Markdown."
diff --git a/PREUPLOAD.cfg b/PREUPLOAD.cfg
index 98bede5..c9dcd8f 100644
--- a/PREUPLOAD.cfg
+++ b/PREUPLOAD.cfg
@@ -1,4 +1,3 @@
 [Hook Scripts]
 notice = tools/update_notice.sh
-seccomp = tools/update_seccomp.sh
 syscalls = tools/update_syscalls.sh
diff --git a/benchmarks/malloc_benchmark.cpp b/benchmarks/malloc_benchmark.cpp
index 2fa1c87..ca54f11 100644
--- a/benchmarks/malloc_benchmark.cpp
+++ b/benchmarks/malloc_benchmark.cpp
@@ -102,22 +102,27 @@
 //       bionic/libc/malloc_debug/tools/gen_malloc.pl -i <THREAD_ID> g_sql_entries kMaxSqlAllocSlots < <ALLOC_FILE> > malloc_sql.h
 #include "malloc_sql.h"
 
-static void BM_malloc_sql_trace_decay_time_0(benchmark::State& state) {
+static void BM_malloc_sql_trace_default(benchmark::State& state) {
+  // The default is expected to be a zero decay time.
   mallopt(M_DECAY_TIME, 0);
-  for (auto _ : state) {
-    BenchmarkMalloc(g_sql_entries, sizeof(g_sql_entries) / sizeof(MallocEntry),
-                    kMaxSqlAllocSlots);
-  }
-}
-BIONIC_BENCHMARK(BM_malloc_sql_trace_decay_time_0);
 
-static void BM_malloc_sql_trace_decay_time_1(benchmark::State& state) {
-  mallopt(M_DECAY_TIME, 1);
   for (auto _ : state) {
     BenchmarkMalloc(g_sql_entries, sizeof(g_sql_entries) / sizeof(MallocEntry),
                     kMaxSqlAllocSlots);
   }
 }
-BIONIC_BENCHMARK(BM_malloc_sql_trace_decay_time_1);
+BIONIC_BENCHMARK(BM_malloc_sql_trace_default);
+
+static void BM_malloc_sql_trace_decay1(benchmark::State& state) {
+  mallopt(M_DECAY_TIME, 1);
+
+  for (auto _ : state) {
+    BenchmarkMalloc(g_sql_entries, sizeof(g_sql_entries) / sizeof(MallocEntry),
+                    kMaxSqlAllocSlots);
+  }
+
+  mallopt(M_DECAY_TIME, 0);
+}
+BIONIC_BENCHMARK(BM_malloc_sql_trace_decay1);
 
 #endif
diff --git a/benchmarks/stdlib_benchmark.cpp b/benchmarks/stdlib_benchmark.cpp
index 7330dc4..6afe7aa 100644
--- a/benchmarks/stdlib_benchmark.cpp
+++ b/benchmarks/stdlib_benchmark.cpp
@@ -17,30 +17,120 @@
 #include <err.h>
 #include <langinfo.h>
 #include <locale.h>
+#include <malloc.h>
 #include <stdlib.h>
 #include <unistd.h>
 
 #include <benchmark/benchmark.h>
 #include "util.h"
 
-static void BM_stdlib_malloc_free(benchmark::State& state) {
+#if defined(__BIONIC__)
+
+#else
+#endif
+
+static __always_inline void MakeAllocationResident(void* ptr, size_t nbytes, int pagesize) {
+  uint8_t* data = reinterpret_cast<uint8_t*>(ptr);
+  for (size_t i = 0; i < nbytes; i += pagesize) {
+    data[i] = 1;
+  }
+}
+
+static void MallocFree(benchmark::State& state) {
   const size_t nbytes = state.range(0);
   int pagesize = getpagesize();
 
-  void* ptr;
   for (auto _ : state) {
-    ptr = malloc(nbytes);
-    // Make the entire allocation resident.
-    uint8_t* data = reinterpret_cast<uint8_t*>(ptr);
-    for (size_t i = 0; i < nbytes; i += pagesize) {
-      data[i] = 1;
-    }
+    void* ptr;
+    benchmark::DoNotOptimize(ptr = malloc(nbytes));
+    MakeAllocationResident(ptr, nbytes, pagesize);
     free(ptr);
   }
 
   state.SetBytesProcessed(uint64_t(state.iterations()) * uint64_t(nbytes));
 }
-BIONIC_BENCHMARK_WITH_ARG(BM_stdlib_malloc_free, "AT_COMMON_SIZES");
+
+static void BM_stdlib_malloc_free_default(benchmark::State& state) {
+#if defined(__BIONIC__)
+  // The default is expected to be a zero decay time.
+  mallopt(M_DECAY_TIME, 0);
+#endif
+
+  MallocFree(state);
+}
+BIONIC_BENCHMARK_WITH_ARG(BM_stdlib_malloc_free_default, "AT_COMMON_SIZES");
+
+#if defined(__BIONIC__)
+static void BM_stdlib_malloc_free_decay1(benchmark::State& state) {
+  mallopt(M_DECAY_TIME, 1);
+
+  MallocFree(state);
+
+  mallopt(M_DECAY_TIME, 0);
+}
+BIONIC_BENCHMARK_WITH_ARG(BM_stdlib_malloc_free_decay1, "AT_COMMON_SIZES");
+#endif
+
+static void MallocMultiple(benchmark::State& state, size_t nbytes, size_t numAllocs) {
+  int pagesize = getpagesize();
+  void* ptrs[numAllocs];
+  for (auto _ : state) {
+    for (size_t i = 0; i < numAllocs; i++) {
+      benchmark::DoNotOptimize(ptrs[i] = reinterpret_cast<uint8_t*>(malloc(nbytes)));
+      MakeAllocationResident(ptrs[i], nbytes, pagesize);
+    }
+    state.PauseTiming(); // Stop timers while freeing pointers.
+    for (size_t i = 0; i < numAllocs; i++) {
+      free(ptrs[i]);
+    }
+    state.ResumeTiming();
+  }
+
+  state.SetBytesProcessed(uint64_t(state.iterations()) * uint64_t(nbytes) * numAllocs);
+}
+
+void BM_stdlib_malloc_forty_default(benchmark::State& state) {
+
+#if defined(__BIONIC__)
+  // The default is expected to be a zero decay time.
+  mallopt(M_DECAY_TIME, 0);
+#endif
+
+  MallocMultiple(state, state.range(0), 40);
+}
+BIONIC_BENCHMARK_WITH_ARG(BM_stdlib_malloc_forty_default, "AT_COMMON_SIZES");
+
+#if defined(__BIONIC__)
+void BM_stdlib_malloc_forty_decay1(benchmark::State& state) {
+  mallopt(M_DECAY_TIME, 1);
+
+  MallocMultiple(state, state.range(0), 40);
+
+  mallopt(M_DECAY_TIME, 0);
+}
+BIONIC_BENCHMARK_WITH_ARG(BM_stdlib_malloc_forty_decay1, "AT_COMMON_SIZES");
+#endif
+
+void BM_stdlib_malloc_multiple_8192_allocs_default(benchmark::State& state) {
+#if defined(__BIONIC__)
+  // The default is expected to be a zero decay time.
+  mallopt(M_DECAY_TIME, 0);
+#endif
+
+  MallocMultiple(state, 8192, state.range(0));
+}
+BIONIC_BENCHMARK_WITH_ARG(BM_stdlib_malloc_multiple_8192_allocs_default, "AT_SMALL_SIZES");
+
+#if defined(__BIONIC__)
+void BM_stdlib_malloc_multiple_8192_allocs_decay1(benchmark::State& state) {
+  mallopt(M_DECAY_TIME, 1);
+
+  MallocMultiple(state, 8192, state.range(0));
+
+  mallopt(M_DECAY_TIME, 0);
+}
+BIONIC_BENCHMARK_WITH_ARG(BM_stdlib_malloc_multiple_8192_allocs_decay1, "AT_SMALL_SIZES");
+#endif
 
 static void BM_stdlib_mbstowcs(benchmark::State& state) {
   const size_t buf_alignment = state.range(0);
@@ -167,3 +257,4 @@
   }
 }
 BIONIC_BENCHMARK(BM_stdlib_strtoull);
+
diff --git a/libc/Android.bp b/libc/Android.bp
index 0950662..23ccbe3 100644
--- a/libc/Android.bp
+++ b/libc/Android.bp
@@ -1578,6 +1578,9 @@
         "ld-android",
         "libdl",
     ],
+    static_libs: [
+        "libdl_android",
+    ],
     whole_static_libs: [
         "libjemalloc5",
     ],
diff --git a/libc/bionic/malloc_common_dynamic.cpp b/libc/bionic/malloc_common_dynamic.cpp
index 3ccaed6..e7147a0 100644
--- a/libc/bionic/malloc_common_dynamic.cpp
+++ b/libc/bionic/malloc_common_dynamic.cpp
@@ -54,6 +54,8 @@
 #include <stdlib.h>
 #include <unistd.h>
 
+#include <android/dlext.h>
+
 #include <private/bionic_config.h>
 #include <private/bionic_defs.h>
 #include <private/bionic_malloc_dispatch.h>
@@ -277,8 +279,41 @@
   return true;
 }
 
+// Note about USE_SCUDO. This file is compiled into libc.so and libc_scudo.so.
+// When compiled into libc_scudo.so, the libc_malloc_* libraries don't need
+// to be loaded from the runtime namespace since libc_scudo.so is not from
+// the runtime APEX, but is copied to any APEX that needs it.
+#ifndef USE_SCUDO
+extern "C" struct android_namespace_t* android_get_exported_namespace(const char* name);
+#endif
+
 void* LoadSharedLibrary(const char* shared_lib, const char* prefix, MallocDispatch* dispatch_table) {
-  void* impl_handle = dlopen(shared_lib, RTLD_NOW | RTLD_LOCAL);
+  void* impl_handle = nullptr;
+#ifndef USE_SCUDO
+  // Try to load the libc_malloc_* libs from the "runtime" namespace and then
+  // fall back to dlopen() to load them from the default namespace.
+  //
+  // The libraries are packaged in the runtime APEX together with libc.so.
+  // However, since the libc.so is searched via the symlink in the system
+  // partition (/system/lib/libc.so -> /apex/com.android.runtime/bionic.libc.so)
+  // libc.so is loaded into the default namespace. If we just dlopen() here, the
+  // linker will load the libs found in /system/lib which might be incompatible
+  // with libc.so in the runtime APEX. Use android_dlopen_ext to explicitly load
+  // the ones in the runtime APEX.
+  struct android_namespace_t* runtime_ns = android_get_exported_namespace("runtime");
+  if (runtime_ns != nullptr) {
+    const android_dlextinfo dlextinfo = {
+      .flags = ANDROID_DLEXT_USE_NAMESPACE,
+      .library_namespace = runtime_ns,
+    };
+    impl_handle = android_dlopen_ext(shared_lib, RTLD_NOW | RTLD_LOCAL, &dlextinfo);
+  }
+#endif
+
+  if (impl_handle == nullptr) {
+    impl_handle = dlopen(shared_lib, RTLD_NOW | RTLD_LOCAL);
+  }
+
   if (impl_handle == nullptr) {
     error_log("%s: Unable to open shared library %s: %s", getprogname(), shared_lib, dlerror());
     return nullptr;
diff --git a/libc/include/bits/glibc-syscalls.h b/libc/include/bits/glibc-syscalls.h
index 52eff56..e831bdc 100644
--- a/libc/include/bits/glibc-syscalls.h
+++ b/libc/include/bits/glibc-syscalls.h
@@ -1,6 +1,5 @@
-/* Generated by gensyscalls.py. Do not edit. */
-#ifndef _BIONIC_BITS_GLIBC_SYSCALLS_H_
-#define _BIONIC_BITS_GLIBC_SYSCALLS_H_
+/* Generated file. Do not edit. */
+#pragma once
 #if defined(__NR__llseek)
   #define SYS__llseek __NR__llseek
 #endif
@@ -61,12 +60,6 @@
 #if defined(__NR_brk)
   #define SYS_brk __NR_brk
 #endif
-#if defined(__NR_cachectl)
-  #define SYS_cachectl __NR_cachectl
-#endif
-#if defined(__NR_cacheflush)
-  #define SYS_cacheflush __NR_cacheflush
-#endif
 #if defined(__NR_capget)
   #define SYS_capget __NR_capget
 #endif
@@ -1123,9 +1116,6 @@
 #if defined(__NR_syslog)
   #define SYS_syslog __NR_syslog
 #endif
-#if defined(__NR_sysmips)
-  #define SYS_sysmips __NR_sysmips
-#endif
 #if defined(__NR_tee)
   #define SYS_tee __NR_tee
 #endif
@@ -1150,9 +1140,6 @@
 #if defined(__NR_timer_settime)
   #define SYS_timer_settime __NR_timer_settime
 #endif
-#if defined(__NR_timerfd)
-  #define SYS_timerfd __NR_timerfd
-#endif
 #if defined(__NR_timerfd_create)
   #define SYS_timerfd_create __NR_timerfd_create
 #endif
@@ -1255,4 +1242,3 @@
 #if defined(__NR_writev)
   #define SYS_writev __NR_writev
 #endif
-#endif /* _BIONIC_BITS_GLIBC_SYSCALLS_H_ */
diff --git a/libc/kernel/tools/update_all.py b/libc/kernel/tools/update_all.py
index 0f30ecd..9d5b02d 100755
--- a/libc/kernel/tools/update_all.py
+++ b/libc/kernel/tools/update_all.py
@@ -4,7 +4,7 @@
 from defaults import *
 from utils import *
 
-def usage():
+def Usage():
     print """\
   usage: %(progname)s [kernel-original-path] [kernel-modified-path]
 
@@ -24,7 +24,7 @@
 """ % { "progname" : os.path.basename(sys.argv[0]) }
     sys.exit(0)
 
-def processFiles(updater, original_dir, modified_dir, src_rel_dir, update_rel_dir):
+def ProcessFiles(updater, original_dir, modified_dir, src_rel_dir, update_rel_dir):
     # Delete the old headers before updating to the new headers.
     update_dir = os.path.join(get_kernel_dir(), update_rel_dir)
     shutil.rmtree(update_dir)
@@ -64,15 +64,64 @@
             update_path = os.path.join(update_rel_dir, rel_path)
             print "cleaning %s -> %s (%s)" % (src_str, update_path, state)
 
+
+# This lets us support regular system calls like __NR_write and also weird
+# ones like __ARM_NR_cacheflush, where the NR doesn't come at the start.
+def make__NR_name(name):
+    if name.startswith('__ARM_NR_'):
+        return name
+    else:
+        return '__NR_%s' % (name)
+
+
+# Scan Linux kernel asm/unistd.h files containing __NR_* constants
+# and write out equivalent SYS_* constants for glibc source compatibility.
+def GenerateGlibcSyscallsHeader(updater):
+    libc_root = '%s/bionic/libc/' % os.environ['ANDROID_BUILD_TOP']
+
+    # Collect the set of all syscalls for all architectures.
+    syscalls = set()
+    pattern = re.compile(r'^\s*#\s*define\s*__NR_([a-z_]\S+)')
+    for unistd_h in ['kernel/uapi/asm-generic/unistd.h',
+                     'kernel/uapi/asm-arm/asm/unistd.h',
+                     'kernel/uapi/asm-arm/asm/unistd-common.h',
+                     'kernel/uapi/asm-arm/asm/unistd-eabi.h',
+                     'kernel/uapi/asm-arm/asm/unistd-oabi.h',
+                     'kernel/uapi/asm-x86/asm/unistd_32.h',
+                     'kernel/uapi/asm-x86/asm/unistd_64.h',
+                     'kernel/uapi/asm-x86/asm/unistd_x32.h']:
+        for line in open(os.path.join(libc_root, unistd_h)):
+            m = re.search(pattern, line)
+            if m:
+                nr_name = m.group(1)
+                if 'reserved' not in nr_name and 'unused' not in nr_name:
+                    syscalls.add(nr_name)
+
+    # Create a single file listing them all.
+    # Note that the input files include #if trickery, so even for a single
+    # architecture we don't know exactly which ones are available.
+    # https://b.corp.google.com/issues/37110151
+    content = '/* Generated file. Do not edit. */\n'
+    content += '#pragma once\n'
+
+    for syscall in sorted(syscalls):
+        nr_name = make__NR_name(syscall)
+        content += '#if defined(%s)\n' % nr_name
+        content += '  #define SYS_%s %s\n' % (syscall, nr_name)
+        content += '#endif\n'
+
+    updater.editFile('%s/include/bits/glibc-syscalls.h' % libc_root, content)
+
+
 try:
     optlist, args = getopt.getopt(sys.argv[1:], '')
 except:
     # Unrecognized option
     sys.stderr.write("error: unrecognized option\n")
-    usage()
+    Usage()
 
 if len(optlist) > 0 or len(args) > 2:
-    usage()
+    Usage()
 
 if len(args) > 0:
     original_dir = args[0]
@@ -91,10 +140,16 @@
     panic("The kernel modified directory %s is not a directory\n" % modified_dir)
 
 updater = BatchFileUpdater()
+
 # Process the original uapi headers first.
-processFiles(updater, original_dir, modified_dir, "uapi", "uapi"),
+ProcessFiles(updater, original_dir, modified_dir, "uapi", "uapi"),
 
 # Now process the special files.
-processFiles(updater, original_dir, modified_dir, "scsi", os.path.join("android", "scsi", "scsi"))
+ProcessFiles(updater, original_dir, modified_dir, "scsi", os.path.join("android", "scsi", "scsi"))
 
 updater.updateGitFiles()
+
+# Now re-generate the <bits/glibc-syscalls.h> from the new uapi headers.
+updater = BatchFileUpdater()
+GenerateGlibcSyscallsHeader(updater)
+updater.updateGitFiles()
diff --git a/libc/tools/gensyscalls.py b/libc/tools/gensyscalls.py
index 9a3b95e..31a8bd0 100755
--- a/libc/tools/gensyscalls.py
+++ b/libc/tools/gensyscalls.py
@@ -527,7 +527,6 @@
     def __init__(self):
         self.old_stubs = []
         self.new_stubs = []
-        self.other_files = []
         self.syscalls = []
 
 
@@ -565,56 +564,6 @@
                 syscall["asm-x86_64"] = add_footer(64, x86_64_genstub(syscall), syscall)
 
 
-    # Scan Linux kernel asm/unistd.h files containing __NR_* constants
-    # and write out equivalent SYS_* constants for glibc source compatibility.
-    def gen_glibc_syscalls_h(self):
-        glibc_syscalls_h_path = "include/bits/glibc-syscalls.h"
-        logging.info("generating " + glibc_syscalls_h_path)
-        glibc_fp = create_file(glibc_syscalls_h_path)
-        glibc_fp.write("/* %s */\n" % warning)
-        glibc_fp.write("#ifndef _BIONIC_BITS_GLIBC_SYSCALLS_H_\n")
-        glibc_fp.write("#define _BIONIC_BITS_GLIBC_SYSCALLS_H_\n")
-
-        # Collect the set of all syscalls for all architectures.
-        syscalls = set()
-        pattern = re.compile(r'^\s*#\s*define\s*__NR_([a-z_]\S+)')
-        for unistd_h in ["kernel/uapi/asm-generic/unistd.h",
-                         "kernel/uapi/asm-arm/asm/unistd.h",
-                         "kernel/uapi/asm-arm/asm/unistd-common.h",
-                         "kernel/uapi/asm-arm/asm/unistd-eabi.h",
-                         "kernel/uapi/asm-arm/asm/unistd-oabi.h",
-                         "kernel/uapi/asm-mips/asm/unistd.h",
-                         "kernel/uapi/asm-mips/asm/unistd_n32.h",
-                         "kernel/uapi/asm-mips/asm/unistd_n64.h",
-                         "kernel/uapi/asm-mips/asm/unistd_nr_n32.h",
-                         "kernel/uapi/asm-mips/asm/unistd_nr_n64.h",
-                         "kernel/uapi/asm-mips/asm/unistd_nr_o32.h",
-                         "kernel/uapi/asm-mips/asm/unistd_o32.h",
-                         "kernel/uapi/asm-x86/asm/unistd_32.h",
-                         "kernel/uapi/asm-x86/asm/unistd_64.h",
-                         "kernel/uapi/asm-x86/asm/unistd_x32.h"]:
-          for line in open(os.path.join(bionic_libc_root, unistd_h)):
-            m = re.search(pattern, line)
-            if m:
-              nr_name = m.group(1)
-              if 'reserved' not in nr_name and 'unused' not in nr_name:
-                syscalls.add(nr_name)
-
-        # Write out a single file listing them all. Note that the input
-        # files include #if trickery, so even for a single architecture
-        # we don't know exactly which ones are available.
-        # https://code.google.com/p/android/issues/detail?id=215853
-        for syscall in sorted(syscalls):
-          nr_name = make__NR_name(syscall)
-          glibc_fp.write("#if defined(%s)\n" % nr_name)
-          glibc_fp.write("  #define SYS_%s %s\n" % (syscall, nr_name))
-          glibc_fp.write("#endif\n")
-
-        glibc_fp.write("#endif /* _BIONIC_BITS_GLIBC_SYSCALLS_H_ */\n")
-        glibc_fp.close()
-        self.other_files.append(glibc_syscalls_h_path)
-
-
     # Write each syscall stub.
     def gen_syscall_stubs(self):
         for syscall in self.syscalls:
@@ -645,16 +594,15 @@
             logging.info("creating %s..." % bionic_temp)
             make_dir(bionic_temp)
 
-        logging.info("re-generating stubs and support files...")
+        logging.info("re-generating stubs...")
 
-        self.gen_glibc_syscalls_h()
         self.gen_syscall_stubs()
 
         logging.info("comparing files...")
         adds    = []
         edits   = []
 
-        for stub in self.new_stubs + self.other_files:
+        for stub in self.new_stubs:
             tmp_file = os.path.join(bionic_temp, stub)
             libc_file = os.path.join(bionic_libc_root, stub)
             if not os.path.exists(libc_file):
diff --git a/libdl/Android.bp b/libdl/Android.bp
index a41aa2d..b1ee5ab 100644
--- a/libdl/Android.bp
+++ b/libdl/Android.bp
@@ -114,6 +114,7 @@
     name: "libdl_android",
 
     defaults: ["linux_bionic_supported"],
+    recovery_available: true,
 
     // NOTE: --exclude-libs=libgcc.a makes sure that any symbols libdl.so pulls from
     // libgcc.a are made static to libdl.so.  This in turn ensures that libraries that
diff --git a/tools/update_seccomp.sh b/tools/update_seccomp.sh
deleted file mode 100755
index b9e53aa..0000000
--- a/tools/update_seccomp.sh
+++ /dev/null
@@ -1,7 +0,0 @@
-#!/bin/bash
-DIR="$( cd "$( dirname "${BASH_SOURCE[0]}" )" && pwd )"
-cd $DIR/..
-./libc/tools/genseccomp.py
-
-git diff --exit-code HEAD libc/seccomp/
-exit $?