Merge "Re-enable libsnapshot ImageManagerTest"
diff --git a/fs_mgr/fs_mgr.cpp b/fs_mgr/fs_mgr.cpp
index 1486e87..0c2569d 100644
--- a/fs_mgr/fs_mgr.cpp
+++ b/fs_mgr/fs_mgr.cpp
@@ -358,7 +358,7 @@
                        const struct ext4_super_block* sb, int* fs_stat) {
     bool has_quota = (sb->s_feature_ro_compat & cpu_to_le32(EXT4_FEATURE_RO_COMPAT_QUOTA)) != 0;
     bool want_quota = entry.fs_mgr_flags.quota;
-    bool want_projid = android::base::GetBoolProperty("ro.emulated_storage.projid", false);
+    bool want_projid = android::base::GetBoolProperty("external_storage.projid.enabled", false);
 
     if (has_quota == want_quota) {
         return;
@@ -521,7 +521,8 @@
 static void tune_casefold(const std::string& blk_device, const struct ext4_super_block* sb,
                           int* fs_stat) {
     bool has_casefold = (sb->s_feature_incompat & cpu_to_le32(EXT4_FEATURE_INCOMPAT_CASEFOLD)) != 0;
-    bool wants_casefold = android::base::GetBoolProperty("ro.emulated_storage.casefold", false);
+    bool wants_casefold =
+            android::base::GetBoolProperty("external_storage.casefold.enabled", false);
 
     if (!wants_casefold || has_casefold) return;
 
diff --git a/fs_mgr/fs_mgr_format.cpp b/fs_mgr/fs_mgr_format.cpp
index 778c0c1..301c907 100644
--- a/fs_mgr/fs_mgr_format.cpp
+++ b/fs_mgr/fs_mgr_format.cpp
@@ -166,8 +166,8 @@
     bool needs_projid = false;
 
     if (entry.mount_point == "/data") {
-        needs_casefold = android::base::GetBoolProperty("ro.emulated_storage.casefold", false);
-        needs_projid = android::base::GetBoolProperty("ro.emulated_storage.projid", false);
+        needs_casefold = android::base::GetBoolProperty("external_storage.casefold.enabled", false);
+        needs_projid = android::base::GetBoolProperty("external_storage.projid.enabled", false);
     }
 
     if (entry.fs_type == "f2fs") {
diff --git a/liblog/include/log/log_read.h b/liblog/include/log/log_read.h
index f3be0b8..e2bc297 100644
--- a/liblog/include/log/log_read.h
+++ b/liblog/include/log/log_read.h
@@ -16,22 +16,8 @@
 
 #pragma once
 
-#include <sys/types.h>
-
-/* deal with possible sys/cdefs.h conflict with fcntl.h */
-#ifdef __unused
-#define __unused_defined __unused
-#undef __unused
-#endif
-
-#include <fcntl.h> /* Pick up O_* macros */
-
-/* restore definitions from above */
-#ifdef __unused_defined
-#define __unused __attribute__((__unused__))
-#endif
-
 #include <stdint.h>
+#include <sys/types.h>
 
 #include <log/log_id.h>
 #include <log/log_time.h>
@@ -40,6 +26,8 @@
 extern "C" {
 #endif
 
+#define ANDROID_LOG_WRAP_DEFAULT_TIMEOUT 7200 /* 2 hour default */
+
 /*
  * Native log reading interface section. See logcat for sample code.
  *
@@ -114,13 +102,10 @@
                                       char* buf, size_t len);
 int android_logger_set_prune_list(struct logger_list* logger_list, const char* buf, size_t len);
 
-#ifndef O_NONBLOCK
+/* The below values are used for the `mode` argument of the below functions. */
+/* Note that 0x00000003 were previously used and should be considered reserved. */
 #define ANDROID_LOG_NONBLOCK 0x00000800
-#else
-#define ANDROID_LOG_NONBLOCK O_NONBLOCK
-#endif
 #define ANDROID_LOG_WRAP 0x40000000 /* Block until buffer about to wrap */
-#define ANDROID_LOG_WRAP_DEFAULT_TIMEOUT 7200 /* 2 hour default */
 #define ANDROID_LOG_PSTORE 0x80000000
 
 struct logger_list* android_logger_list_alloc(int mode, unsigned int tail,
diff --git a/liblog/include_vndk/log/log.h b/liblog/include_vndk/log/log.h
index a79beec..ab4adc4 100644
--- a/liblog/include_vndk/log/log.h
+++ b/liblog/include_vndk/log/log.h
@@ -3,6 +3,9 @@
 #ifndef _LIBS_LOG_LOG_H
 #define _LIBS_LOG_LOG_H
 
+/* Historically vendors have depended on this header being included. */
+#include <fcntl.h>
+
 #include <android/log.h>
 #include <log/log_id.h>
 #include <log/log_main.h>
diff --git a/libunwindstack/Android.bp b/libunwindstack/Android.bp
index 9afc9a3..ab59a4b 100644
--- a/libunwindstack/Android.bp
+++ b/libunwindstack/Android.bp
@@ -373,12 +373,26 @@
 
     srcs: [
         "benchmarks/unwind_benchmarks.cpp",
+        "benchmarks/SymbolBenchmark.cpp",
+    ],
+
+    data: [
+        "benchmarks/files/*",
     ],
 
     shared_libs: [
         "libbase",
         "libunwindstack",
     ],
+
+    target: {
+        android: {
+            static_libs: [
+                "libmeminfo",
+                "libprocinfo",
+            ],
+        },
+    },
 }
 
 // Generates the elf data for use in the tests for .gnu_debugdata frames.
diff --git a/libunwindstack/benchmarks/SymbolBenchmark.cpp b/libunwindstack/benchmarks/SymbolBenchmark.cpp
new file mode 100644
index 0000000..a850ff0
--- /dev/null
+++ b/libunwindstack/benchmarks/SymbolBenchmark.cpp
@@ -0,0 +1,158 @@
+/*
+ * Copyright (C) 2020 The Android Open Source Project
+ *
+ * Licensed under the Apache License, Version 2.0 (the "License");
+ * you may not use this file except in compliance with the License.
+ * You may obtain a copy of the License at
+ *
+ *      http://www.apache.org/licenses/LICENSE-2.0
+ *
+ * Unless required by applicable law or agreed to in writing, software
+ * distributed under the License is distributed on an "AS IS" BASIS,
+ * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
+ * See the License for the specific language governing permissions and
+ * limitations under the License.
+ */
+
+#include <err.h>
+#include <inttypes.h>
+#include <malloc.h>
+#include <stdint.h>
+
+#include <string>
+#include <vector>
+
+#include <android-base/file.h>
+#include <android-base/strings.h>
+#include <benchmark/benchmark.h>
+
+#include <unwindstack/Elf.h>
+#include <unwindstack/Memory.h>
+
+#if defined(__BIONIC__)
+
+#include <meminfo/procmeminfo.h>
+#include <procinfo/process_map.h>
+
+static void Gather(uint64_t* rss_bytes) {
+  android::meminfo::ProcMemInfo proc_mem(getpid());
+  const std::vector<android::meminfo::Vma>& maps = proc_mem.MapsWithoutUsageStats();
+  for (auto& vma : maps) {
+    if (vma.name == "[anon:libc_malloc]" || android::base::StartsWith(vma.name, "[anon:scudo:") ||
+        android::base::StartsWith(vma.name, "[anon:GWP-ASan")) {
+      android::meminfo::Vma update_vma(vma);
+      if (!proc_mem.FillInVmaStats(update_vma)) {
+        err(1, "FillInVmaStats failed\n");
+      }
+      *rss_bytes += update_vma.usage.rss;
+    }
+  }
+}
+#endif
+
+static void BenchmarkSymbolLookup(benchmark::State& state, std::vector<uint64_t> offsets,
+                                  std::string elf_file, bool expect_found) {
+#if defined(__BIONIC__)
+  uint64_t rss_bytes = 0;
+#endif
+  uint64_t alloc_bytes = 0;
+  for (auto _ : state) {
+    state.PauseTiming();
+    unwindstack::Elf elf(unwindstack::Memory::CreateFileMemory(elf_file, 0).release());
+    if (!elf.Init() || !elf.valid()) {
+      errx(1, "Internal Error: Cannot open elf.");
+    }
+
+#if defined(__BIONIC__)
+    mallopt(M_PURGE, 0);
+    uint64_t rss_bytes_before = 0;
+    Gather(&rss_bytes_before);
+#endif
+    uint64_t alloc_bytes_before = mallinfo().uordblks;
+    state.ResumeTiming();
+
+    for (auto pc : offsets) {
+      std::string name;
+      uint64_t offset;
+      bool found = elf.GetFunctionName(pc, &name, &offset);
+      if (expect_found && !found) {
+        errx(1, "expected pc 0x%" PRIx64 " present, but not found.", pc);
+      } else if (!expect_found && found) {
+        errx(1, "expected pc 0x%" PRIx64 " not present, but found.", pc);
+      }
+    }
+
+    state.PauseTiming();
+#if defined(__BIONIC__)
+    mallopt(M_PURGE, 0);
+#endif
+    alloc_bytes += mallinfo().uordblks - alloc_bytes_before;
+#if defined(__BIONIC__)
+    Gather(&rss_bytes);
+    rss_bytes -= rss_bytes_before;
+#endif
+    state.ResumeTiming();
+  }
+
+#if defined(__BIONIC__)
+  state.counters["RSS_BYTES"] = rss_bytes / static_cast<double>(state.iterations());
+#endif
+  state.counters["ALLOCATED_BYTES"] = alloc_bytes / static_cast<double>(state.iterations());
+}
+
+static void BenchmarkSymbolLookup(benchmark::State& state, uint64_t pc, std::string elf_file,
+                                  bool expect_found) {
+  BenchmarkSymbolLookup(state, std::vector<uint64_t>{pc}, elf_file, expect_found);
+}
+
+std::string GetElfFile() {
+  return android::base::GetExecutableDirectory() + "/benchmarks/files/libart_arm.so";
+}
+
+std::string GetSortedElfFile() {
+  return android::base::GetExecutableDirectory() + "/benchmarks/files/boot_arm.oat";
+}
+
+void BM_symbol_not_present(benchmark::State& state) {
+  BenchmarkSymbolLookup(state, 0, GetElfFile(), false);
+}
+BENCHMARK(BM_symbol_not_present);
+
+void BM_symbol_find_single(benchmark::State& state) {
+  BenchmarkSymbolLookup(state, 0x22b2bc, GetElfFile(), true);
+}
+BENCHMARK(BM_symbol_find_single);
+
+void BM_symbol_find_single_many_times(benchmark::State& state) {
+  BenchmarkSymbolLookup(state, std::vector<uint64_t>(15, 0x22b2bc), GetElfFile(), true);
+}
+BENCHMARK(BM_symbol_find_single_many_times);
+
+void BM_symbol_find_multiple(benchmark::State& state) {
+  BenchmarkSymbolLookup(state,
+                        std::vector<uint64_t>{0x22b2bc, 0xd5d30, 0x1312e8, 0x13582e, 0x1389c8},
+                        GetElfFile(), true);
+}
+BENCHMARK(BM_symbol_find_multiple);
+
+void BM_symbol_not_present_from_sorted(benchmark::State& state) {
+  BenchmarkSymbolLookup(state, 0, GetSortedElfFile(), false);
+}
+BENCHMARK(BM_symbol_not_present_from_sorted);
+
+void BM_symbol_find_single_from_sorted(benchmark::State& state) {
+  BenchmarkSymbolLookup(state, 0x138638, GetSortedElfFile(), true);
+}
+BENCHMARK(BM_symbol_find_single_from_sorted);
+
+void BM_symbol_find_single_many_times_from_sorted(benchmark::State& state) {
+  BenchmarkSymbolLookup(state, std::vector<uint64_t>(15, 0x138638), GetSortedElfFile(), true);
+}
+BENCHMARK(BM_symbol_find_single_many_times_from_sorted);
+
+void BM_symbol_find_multiple_from_sorted(benchmark::State& state) {
+  BenchmarkSymbolLookup(state,
+                        std::vector<uint64_t>{0x138638, 0x84350, 0x14df18, 0x1f3a38, 0x1f3ca8},
+                        GetSortedElfFile(), true);
+}
+BENCHMARK(BM_symbol_find_multiple_from_sorted);
diff --git a/libunwindstack/benchmarks/files/boot_arm.oat b/libunwindstack/benchmarks/files/boot_arm.oat
new file mode 100644
index 0000000..51188eb
--- /dev/null
+++ b/libunwindstack/benchmarks/files/boot_arm.oat
Binary files differ
diff --git a/libunwindstack/benchmarks/files/libart_arm.so b/libunwindstack/benchmarks/files/libart_arm.so
new file mode 100644
index 0000000..2201faf
--- /dev/null
+++ b/libunwindstack/benchmarks/files/libart_arm.so
Binary files differ
diff --git a/libziparchive/include/ziparchive/zip_archive.h b/libziparchive/include/ziparchive/zip_archive.h
index 3d51de9..005d697 100644
--- a/libziparchive/include/ziparchive/zip_archive.h
+++ b/libziparchive/include/ziparchive/zip_archive.h
@@ -48,9 +48,10 @@
   // Modification time. The zipfile format specifies
   // that the first two little endian bytes contain the time
   // and the last two little endian bytes contain the date.
-  // See `GetModificationTime`.
+  // See `GetModificationTime`. Use signed integer to avoid the
+  // sub-overflow.
   // TODO: should be overridden by extra time field, if present.
-  uint32_t mod_time;
+  int32_t mod_time;
 
   // Returns `mod_time` as a broken-down struct tm.
   struct tm GetModificationTime() const;
diff --git a/libziparchive/zip_archive.cc b/libziparchive/zip_archive.cc
index 7bf2120..014f881 100644
--- a/libziparchive/zip_archive.cc
+++ b/libziparchive/zip_archive.cc
@@ -1570,6 +1570,7 @@
   return true;
 }
 
+// This function returns the embedded timestamp as is; and doesn't perform validations.
 tm ZipEntryCommon::GetModificationTime() const {
   tm t = {};