Merge "Add a couple of demangler tests."
diff --git a/android-changes-for-ndk-developers.md b/android-changes-for-ndk-developers.md
index da07c79..13c8911 100644
--- a/android-changes-for-ndk-developers.md
+++ b/android-changes-for-ndk-developers.md
@@ -6,6 +6,11 @@
 See also [bionic status](docs/status.md) for general libc/libm/libdl
 behavior changes.
 
+See also the
+[unwinder documentation](https://android.googlesource.com/platform/system/unwinding/+/refs/heads/master/libunwindstack/AndroidVersions.md)
+for details about changes in stack unwinding (crash dumps) between
+different releases.
+
 Required tools: the NDK has an _arch_-linux-android-readelf binary
 (e.g. arm-linux-androideabi-readelf or i686-linux-android-readelf)
 for each architecture (under toolchains/), but you can use readelf for
diff --git a/benchmarks/get_heap_size_benchmark.cpp b/benchmarks/get_heap_size_benchmark.cpp
index c3680dc..47d5b18 100644
--- a/benchmarks/get_heap_size_benchmark.cpp
+++ b/benchmarks/get_heap_size_benchmark.cpp
@@ -30,8 +30,6 @@
 #include <benchmark/benchmark.h>
 #include "util.h"
 
-static volatile size_t sink;
-
 static constexpr int NTHREADS = 5;
 
 static std::atomic<int> thread_count;
@@ -57,7 +55,7 @@
     sched_yield();
   }
   for (auto _ : state) {
-    sink = mallinfo().uordblks;
+    benchmark::DoNotOptimize(mallinfo().uordblks);
   }
   for (int i = 0; i < 5; i++) {
     int res = pthread_join(t[i], NULL);
diff --git a/benchmarks/stdio_benchmark.cpp b/benchmarks/stdio_benchmark.cpp
index 037bbd9..03f3f29 100644
--- a/benchmarks/stdio_benchmark.cpp
+++ b/benchmarks/stdio_benchmark.cpp
@@ -155,9 +155,8 @@
   while (state.KeepRunning()) {
     FILE* fp = fopen("/dev/zero", "re");
     if (no_locking) __fsetlocking(fp, FSETLOCKING_BYCALLER);
-    volatile int c __attribute__((unused));
     for (size_t i = 0; i < nbytes; ++i) {
-      c = fgetc(fp);
+      benchmark::DoNotOptimize(fgetc(fp));
     }
     fclose(fp);
   }
diff --git a/benchmarks/stdlib_benchmark.cpp b/benchmarks/stdlib_benchmark.cpp
index 45b953f..b6ea58d 100644
--- a/benchmarks/stdlib_benchmark.cpp
+++ b/benchmarks/stdlib_benchmark.cpp
@@ -189,9 +189,8 @@
         buf[l++] = i, buf[l++] = j, buf[l++] = 0x80, buf[l++] = k;
   buf[l++] = 0;
 
-  volatile size_t c __attribute__((unused)) = 0;
   for (auto _ : state) {
-    c = mbstowcs(widebuf_aligned, buf_aligned, 500000);
+    benchmark::DoNotOptimize(mbstowcs(widebuf_aligned, buf_aligned, 500000));
   }
 
   state.SetBytesProcessed(uint64_t(state.iterations()) * uint64_t(500000));
diff --git a/benchmarks/string_benchmark.cpp b/benchmarks/string_benchmark.cpp
index d176675..9be54c7 100644
--- a/benchmarks/string_benchmark.cpp
+++ b/benchmarks/string_benchmark.cpp
@@ -31,9 +31,8 @@
   char* src_aligned = GetAlignedPtrFilled(&src, src_alignment, nbytes, 'x');
   char* dst_aligned = GetAlignedPtrFilled(&dst, dst_alignment, nbytes, 'x');
 
-  volatile int c __attribute__((unused)) = 0;
   while (state.KeepRunning()) {
-    c += memcmp(dst_aligned, src_aligned, nbytes);
+    benchmark::DoNotOptimize(memcmp(dst_aligned, src_aligned, nbytes));
   }
 
   state.SetBytesProcessed(uint64_t(state.iterations()) * uint64_t(nbytes));
@@ -129,9 +128,8 @@
   char* buf_aligned = GetAlignedPtrFilled(&buf, alignment, nbytes + 1, 'x');
   buf_aligned[nbytes - 1] = '\0';
 
-  volatile int c __attribute__((unused)) = 0;
   while (state.KeepRunning()) {
-    c += strlen(buf_aligned);
+    benchmark::DoNotOptimize(strlen(buf_aligned));
   }
 
   state.SetBytesProcessed(uint64_t(state.iterations()) * uint64_t(nbytes));
@@ -239,9 +237,8 @@
   s1_aligned[nbytes - 1] = '\0';
   s2_aligned[nbytes - 1] = '\0';
 
-  volatile int c __attribute__((unused));
   while (state.KeepRunning()) {
-    c = strcmp(s1_aligned, s2_aligned);
+    benchmark::DoNotOptimize(strcmp(s1_aligned, s2_aligned));
   }
 
   state.SetBytesProcessed(uint64_t(state.iterations()) * uint64_t(nbytes));
@@ -258,9 +255,8 @@
   char* s1_aligned = GetAlignedPtrFilled(&s1, s1_alignment, nbytes, 'x');
   char* s2_aligned = GetAlignedPtrFilled(&s2, s2_alignment, nbytes, 'x');
 
-  volatile int c __attribute__((unused));
   for (auto _ : state) {
-    c = strncmp(s1_aligned, s2_aligned, nbytes);
+    benchmark::DoNotOptimize(strncmp(s1_aligned, s2_aligned, nbytes));
   }
 
   state.SetBytesProcessed(uint64_t(state.iterations()) * uint64_t(nbytes));
diff --git a/libc/Android.bp b/libc/Android.bp
index 06eb6dd..c6bd6fa 100644
--- a/libc/Android.bp
+++ b/libc/Android.bp
@@ -84,6 +84,7 @@
         fuzzer: false,
     },
     ramdisk_available: true,
+    vendor_ramdisk_available: true,
     recovery_available: true,
     native_bridge_supported: true,
 
@@ -1350,6 +1351,7 @@
         "libc_native_allocator_defaults",
     ],
     ramdisk_available: false,
+    vendor_ramdisk_available: false,
     srcs: libc_common_src_files + [
         "bionic/gwp_asan_wrappers.cpp",
         "bionic/heap_tagging.cpp",
@@ -1604,6 +1606,7 @@
     ],
     name: "libc",
     static_ndk_lib: true,
+    llndk_stubs: "libc.llndk",
     product_variables: {
         platform_sdk_version: {
             asflags: ["-DPLATFORM_SDK_VERSION=%d"],
@@ -1798,6 +1801,7 @@
     ],
     vendor_available: true,
     ramdisk_available: true,
+    vendor_ramdisk_available: true,
     recovery_available: true,
     native_bridge_supported: true,
     export_include_dirs: [
@@ -1825,6 +1829,7 @@
     host_supported: true,
     vendor_available: true,
     ramdisk_available: true,
+    vendor_ramdisk_available: true,
     recovery_available: true,
     native_bridge_supported: true,
     apex_available: [
@@ -1875,6 +1880,7 @@
     native_bridge_supported: true,
     vendor_available: true,
     ramdisk_available: true,
+    vendor_ramdisk_available: true,
     recovery_available: true,
     sdk_version: "1",
 
@@ -2003,6 +2009,7 @@
     defaults: ["linux_bionic_supported"],
     vendor_available: true,
     ramdisk_available: true,
+    vendor_ramdisk_available: true,
     recovery_available: true,
     native_bridge_supported: true,
     apex_available: [
@@ -2216,7 +2223,7 @@
 }
 
 llndk_library {
-    name: "libc",
+    name: "libc.llndk",
     symbol_file: "libc.map.txt",
     export_headers_as_system: true,
     export_preprocessed_headers: ["include"],
diff --git a/libc/async_safe/Android.bp b/libc/async_safe/Android.bp
index 98da2cc..90cff0d 100644
--- a/libc/async_safe/Android.bp
+++ b/libc/async_safe/Android.bp
@@ -22,8 +22,8 @@
     apex_available: [
         "//apex_available:platform",
         "com.android.runtime",
+        "com.android.art",
         "com.android.art.debug",
-        "com.android.art.release",
         "com.android.media",
         "com.android.media.swcodec",
     ],
@@ -32,6 +32,7 @@
 cc_library_headers {
     name: "libasync_safe_headers",
     ramdisk_available: true,
+    vendor_ramdisk_available: true,
     recovery_available: true,
     native_bridge_supported: true,
     defaults: ["linux_bionic_supported"],
diff --git a/libc/bionic/__bionic_get_shell_path.cpp b/libc/bionic/__bionic_get_shell_path.cpp
index 7aeed18..c087b35 100644
--- a/libc/bionic/__bionic_get_shell_path.cpp
+++ b/libc/bionic/__bionic_get_shell_path.cpp
@@ -36,6 +36,10 @@
 #define VENDOR_PREFIX "/vendor/"
 
 static const char* init_sh_path() {
+#if !defined(__ANDROID__)
+  // For the host Bionic, use the standard /bin/sh
+  return "/bin/sh";
+#else
   /* If the device is not treble enabled, return the path to the system shell.
    * Vendor code, on non-treble enabled devices could use system() / popen()
    * with relative paths for executables on /system. Since /system will not be
@@ -51,6 +55,7 @@
   }
 #endif
   return "/system/bin/sh";
+#endif  // if !defined(__ANDROID__)
 }
 
 const char* __bionic_get_shell_path() {
diff --git a/libc/bionic/empty_android_ids.h b/libc/bionic/empty_android_ids.h
new file mode 100644
index 0000000..2145dd8
--- /dev/null
+++ b/libc/bionic/empty_android_ids.h
@@ -0,0 +1,39 @@
+/*
+ * 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.
+ */
+#if defined(__ANDROID__)
+#error "This file is for host only"
+#endif
+
+struct android_id_info {
+  const char name[17];
+  unsigned aid;
+};
+
+static const struct android_id_info android_ids[] = {};
+
+#define android_id_count 0
diff --git a/libc/bionic/grp_pwd.cpp b/libc/bionic/grp_pwd.cpp
index dd8df95..600693c 100644
--- a/libc/bionic/grp_pwd.cpp
+++ b/libc/bionic/grp_pwd.cpp
@@ -46,24 +46,30 @@
 #include "private/android_filesystem_config.h"
 #include "platform/bionic/macros.h"
 
+#if defined(__ANDROID__)
 // Generated android_ids array
 #include "generated_android_ids.h"
+#else
+// Empty array for host; everything is from the database files
+#include "empty_android_ids.h"
+#endif
+
 #include "grp_pwd_file.h"
 
 static PasswdFile passwd_files[] = {
-  { "/system/etc/passwd", "system_" },
-  { "/vendor/etc/passwd", "vendor_" },
-  { "/odm/etc/passwd", "odm_" },
-  { "/product/etc/passwd", "product_" },
-  { "/system_ext/etc/passwd", "system_ext_" },
+    {"/etc/passwd", "system_"},  // symlinks to /system/etc/passwd in Android
+    {"/vendor/etc/passwd", "vendor_"},
+    {"/odm/etc/passwd", "odm_"},
+    {"/product/etc/passwd", "product_"},
+    {"/system_ext/etc/passwd", "system_ext_"},
 };
 
 static GroupFile group_files[] = {
-  { "/system/etc/group", "system_" },
-  { "/vendor/etc/group", "vendor_" },
-  { "/odm/etc/group", "odm_" },
-  { "/product/etc/group", "product_" },
-  { "/system_ext/etc/group", "system_ext_" },
+    {"/etc/group", "system_"},  // symlinks to /system/etc/group in Android
+    {"/vendor/etc/group", "vendor_"},
+    {"/odm/etc/group", "odm_"},
+    {"/product/etc/group", "product_"},
+    {"/system_ext/etc/group", "system_ext_"},
 };
 
 // POSIX seems to envisage an implementation where the <pwd.h> functions are
@@ -194,6 +200,7 @@
   return false;
 }
 
+#if defined(__ANDROID__)
 static bool is_valid_app_id(id_t id, bool is_group) {
   id_t appid = id % AID_USER_OFFSET;
 
@@ -226,6 +233,12 @@
 
   return false;
 }
+#else
+static bool is_valid_app_id(id_t, bool) {
+  // Host doesn't have the concept of app_id
+  return false;
+}
+#endif  // if defined(__ANDROID__)
 
 // This provides an iterater for app_ids within the first user's app id's.
 static id_t get_next_app_id(id_t current_id, bool is_group) {
@@ -386,6 +399,7 @@
   }
 }
 
+#if defined(__ANDROID__)
 static bool device_launched_before_api_29() {
   // Check if ro.product.first_api_level is set to a value > 0 and < 29, if so, this device was
   // launched before API 29 (Q). Any other value is considered to be either in development or
@@ -420,6 +434,12 @@
   return (id >= AID_OEM_RESERVED_START && id <= AID_OEM_RESERVED_END) ||
          (id >= AID_OEM_RESERVED_2_START && id <= AID_OEM_RESERVED_2_END);
 }
+#else
+static bool is_oem_id(id_t) {
+  // no OEM ids in host
+  return false;
+}
+#endif  // if defined(__ANDROID__)
 
 // Translate an OEM name to the corresponding user/group id.
 static id_t oem_id_from_name(const char* name) {
@@ -522,7 +542,7 @@
     return android_iinfo_to_passwd(state, android_id_info);
   }
 
-  // Handle OEM range.
+  // Find an entry from the database file
   passwd* pw = oem_id_to_passwd(uid, state);
   if (pw != nullptr) {
     return pw;
@@ -540,6 +560,7 @@
     return android_iinfo_to_passwd(state, android_id_info);
   }
 
+  // Find an entry from the database file
   for (auto& passwd_file : passwd_files) {
     if (passwd_file.FindByName(login, state)) {
       return &state->passwd_;
@@ -681,7 +702,7 @@
     return android_iinfo_to_group(state, android_id_info);
   }
 
-  // Handle OEM range.
+  // Find an entry from the database file
   group* grp = oem_id_to_group(gid, state);
   if (grp != nullptr) {
     return grp;
@@ -699,6 +720,7 @@
     return android_iinfo_to_group(state, android_id_info);
   }
 
+  // Find an entry from the database file
   for (auto& group_file : group_files) {
     if (group_file.FindByName(name, state)) {
       return &state->group_;
diff --git a/libc/bionic/grp_pwd_file.cpp b/libc/bionic/grp_pwd_file.cpp
index 81cf893..1f45e80 100644
--- a/libc/bionic/grp_pwd_file.cpp
+++ b/libc/bionic/grp_pwd_file.cpp
@@ -268,6 +268,7 @@
 
   while (line_beginning < end) {
     line_beginning = ParseLine(line_beginning, end, line->fields, line->kNumFields);
+#if defined(__ANDROID__)
     // To comply with Treble, users/groups from each partition need to be prefixed with
     // the partition name.
     if (required_prefix_ != nullptr) {
@@ -280,6 +281,7 @@
         continue;
       }
     }
+#endif
     if (predicate(line)) return true;
   }
 
diff --git a/libc/bionic/grp_pwd_file.h b/libc/bionic/grp_pwd_file.h
index 69c771b..5fd3d2f 100644
--- a/libc/bionic/grp_pwd_file.h
+++ b/libc/bionic/grp_pwd_file.h
@@ -65,7 +65,10 @@
   const char* filename_ = nullptr;
   const char* start_ = nullptr;
   const char* end_ = nullptr;
+#pragma clang diagnostic push
+#pragma clang diagnostic ignored "-Wunused-private-field"
   const char* required_prefix_;
+#pragma clang diagnostic pop
 };
 
 class PasswdFile {
diff --git a/libdl/Android.bp b/libdl/Android.bp
index 1a5439f..9a31d36 100644
--- a/libdl/Android.bp
+++ b/libdl/Android.bp
@@ -5,6 +5,7 @@
     name: "libdl_static",
     defaults: ["linux_bionic_supported"],
     ramdisk_available: true,
+    vendor_ramdisk_available: true,
     recovery_available: true,
     native_bridge_supported: true,
 
@@ -36,9 +37,11 @@
 cc_library {
     name: "libdl",
     ramdisk_available: true,
+    vendor_ramdisk_available: true,
     recovery_available: true,
     native_bridge_supported: true,
     static_ndk_lib: true,
+    llndk_stubs: "libdl.llndk",
 
     defaults: ["linux_bionic_supported"],
 
@@ -135,6 +138,7 @@
 
     defaults: ["linux_bionic_supported"],
     ramdisk_available: true,
+    vendor_ramdisk_available: true,
     recovery_available: true,
     native_bridge_supported: true,
 
@@ -218,7 +222,7 @@
 }
 
 llndk_library {
-    name: "libdl",
+    name: "libdl.llndk",
     native_bridge_supported: true,
     symbol_file: "libdl.map.txt",
 }
diff --git a/libm/Android.bp b/libm/Android.bp
index 7f96975..6c8ad22 100644
--- a/libm/Android.bp
+++ b/libm/Android.bp
@@ -5,8 +5,10 @@
     name: "libm",
     defaults: ["linux_bionic_supported"],
     ramdisk_available: true,
+    vendor_ramdisk_available: true,
     recovery_available: true,
     static_ndk_lib: true,
+    llndk_stubs: "libm.llndk",
 
     whole_static_libs: ["libarm-optimized-routines-math"],
 
@@ -520,7 +522,7 @@
 }
 
 llndk_library {
-    name: "libm",
+    name: "libm.llndk",
     native_bridge_supported: true,
     symbol_file: "libm.map.txt",
 }
diff --git a/linker/Android.bp b/linker/Android.bp
index 15585a7..8a2809a 100644
--- a/linker/Android.bp
+++ b/linker/Android.bp
@@ -124,6 +124,7 @@
     name: "linker_all_targets",
     defaults: ["linux_bionic_supported"],
     recovery_available: true,
+    vendor_ramdisk_available: true,
     native_bridge_supported: true,
 }
 
@@ -336,6 +337,7 @@
     compile_multilib: "both",
 
     recovery_available: true,
+    vendor_ramdisk_available: true,
     apex_available: [
         "//apex_available:platform",
         "com.android.runtime",
@@ -413,6 +415,7 @@
     name: "ld-android",
     defaults: ["linux_bionic_supported", "linker_version_script_overlay"],
     ramdisk_available: true,
+    vendor_ramdisk_available: true,
     recovery_available: true,
     native_bridge_supported: true,
 
diff --git a/tests/fenv_test.cpp b/tests/fenv_test.cpp
index e983a1c..89c7fd5 100644
--- a/tests/fenv_test.cpp
+++ b/tests/fenv_test.cpp
@@ -22,19 +22,20 @@
 #include <stdint.h>
 
 static void TestRounding(float expectation1, float expectation2) {
-  // volatile to prevent compiler optimizations.
+  // Volatile to prevent compile-time evaluation.
   volatile float f = 1.968750f;
   volatile float m = 0x1.0p23f;
-  volatile float x = f + m;
+  float x;
+  DoNotOptimize(x = f + m);
   ASSERT_FLOAT_EQ(expectation1, x);
-  x = x - m;
+  DoNotOptimize(x = x - m);
   ASSERT_EQ(expectation2, x);
 }
 
 static void DivideByZero() {
-  // volatile to prevent compiler optimizations.
+  // Volatile to prevent compile-time evaluation.
   volatile float zero = 0.0f;
-  volatile float result __attribute__((unused)) = 123.0f / zero;
+  DoNotOptimize(123.0f / zero);
 }
 
 TEST(fenv, fesetround_fegetround_FE_TONEAREST) {
diff --git a/tests/malloc_test.cpp b/tests/malloc_test.cpp
index 4ea6d2b..ddd3416 100644
--- a/tests/malloc_test.cpp
+++ b/tests/malloc_test.cpp
@@ -925,12 +925,8 @@
     std::thread* t = new std::thread([&stop] {
       while (!stop) {
         for (size_t size = kMinAllocationSize; size <= kMaxAllocationSize; size <<= 1) {
-          void* ptr = malloc(size);
-          if (ptr == nullptr) {
-            return;
-          }
-          // Make sure this value is not optimized away.
-          asm volatile("" : : "r,m"(ptr) : "memory");
+          void* ptr;
+          DoNotOptimize(ptr = malloc(size));
           free(ptr);
         }
       }
@@ -943,10 +939,9 @@
     pid_t pid;
     if ((pid = fork()) == 0) {
       for (size_t size = kMinAllocationSize; size <= kMaxAllocationSize; size <<= 1) {
-        void* ptr = malloc(size);
+        void* ptr;
+        DoNotOptimize(ptr = malloc(size));
         ASSERT_TRUE(ptr != nullptr);
-        // Make sure this value is not optimized away.
-        asm volatile("" : : "r,m"(ptr) : "memory");
         // Make sure we can touch all of the allocation.
         memset(ptr, 0x1, size);
         ASSERT_LE(size, malloc_usable_size(ptr));
diff --git a/tests/unistd_test.cpp b/tests/unistd_test.cpp
index 43d50f8..41ca8b4 100644
--- a/tests/unistd_test.cpp
+++ b/tests/unistd_test.cpp
@@ -676,14 +676,10 @@
   ASSERT_NE(static_cast<uint64_t>(parent_tid), reinterpret_cast<uint64_t>(result));
 }
 
-static void optimization_barrier(void* arg) {
-  asm volatile("" : : "r"(arg) : "memory");
-}
-
 __attribute__((noinline)) static void HwasanVforkTestChild() {
   // Allocate a tagged region on stack and leave it there.
   char x[10000];
-  optimization_barrier(x);
+  DoNotOptimize(x);
   _exit(0);
 }
 
@@ -700,7 +696,7 @@
   // Allocate a region on stack, but don't tag it (see the function attribute).
   // This depends on unallocated stack space at current function entry being untagged.
   char x[10000];
-  optimization_barrier(x);
+  DoNotOptimize(x);
   // Verify that contents of x[] are untagged.
   HwasanReadMemory(x, sizeof(x));
 }
diff --git a/tests/utils.h b/tests/utils.h
index acd8bc6..94ff050 100644
--- a/tests/utils.h
+++ b/tests/utils.h
@@ -290,3 +290,13 @@
 
   size_t start_count_ = CountOpenFds();
 };
+
+// From <benchmark/benchmark.h>.
+template <class Tp>
+static inline void DoNotOptimize(Tp const& value) {
+  asm volatile("" : : "r,m"(value) : "memory");
+}
+template <class Tp>
+static inline void DoNotOptimize(Tp& value) {
+  asm volatile("" : "+r,m"(value) : : "memory");
+}