Merge "Fix sed command on Mac builds"
diff --git a/fastboot/fuzzy_fastboot/fixtures.cpp b/fastboot/fuzzy_fastboot/fixtures.cpp
index eb043ce..c23da01 100644
--- a/fastboot/fuzzy_fastboot/fixtures.cpp
+++ b/fastboot/fuzzy_fastboot/fixtures.cpp
@@ -130,10 +130,14 @@
         ASSERT_EQ(device_path, cb_scratch);  // The path can not change
     }
     fb = std::unique_ptr<FastBootDriver>(new FastBootDriver(transport.get(), {}, true));
+    // No error checking since non-A/B devices may not support the command
+    fb->GetVar("current-slot", &initial_slot);
 }
 
 void FastBootTest::TearDown() {
     EXPECT_TRUE(UsbStillAvailible()) << USB_PORT_GONE;
+    // No error checking since non-A/B devices may not support the command
+    fb->SetActive(initial_slot);
 
     TearDownSerial();
 
@@ -232,6 +236,7 @@
 
 std::string FastBootTest::device_path = "";
 std::string FastBootTest::cb_scratch = "";
+std::string FastBootTest::initial_slot = "";
 int FastBootTest::serial_port = 0;
 
 template <bool UNLOCKED>
diff --git a/fastboot/fuzzy_fastboot/fixtures.h b/fastboot/fuzzy_fastboot/fixtures.h
index 9c955ea..7c8d54d 100644
--- a/fastboot/fuzzy_fastboot/fixtures.h
+++ b/fastboot/fuzzy_fastboot/fixtures.h
@@ -70,6 +70,7 @@
     // This is an annoying hack
     static std::string cb_scratch;
     static std::string device_path;
+    static std::string initial_slot;
 };
 
 template <bool UNLOCKED>
diff --git a/fs_mgr/libdm/Android.mk b/fs_mgr/libdm/Android.mk
new file mode 100644
index 0000000..6aedc25
--- /dev/null
+++ b/fs_mgr/libdm/Android.mk
@@ -0,0 +1,22 @@
+#
+# Copyright (C) 2018 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.
+#
+
+LOCAL_PATH := $(call my-dir)
+
+include $(CLEAR_VARS)
+
+LOCAL_MODULE := VtsKernelLibdmTest
+-include test/vts/tools/build/Android.host_config.mk
diff --git a/fs_mgr/libdm/AndroidTest.xml b/fs_mgr/libdm/AndroidTest.xml
new file mode 100644
index 0000000..b4e0c23
--- /dev/null
+++ b/fs_mgr/libdm/AndroidTest.xml
@@ -0,0 +1,31 @@
+<?xml version="1.0" encoding="utf-8"?>
+<!-- Copyright (C) 2019 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.
+-->
+<configuration description="Config for VTS VtsKernelLibdmTest">
+    <option name="config-descriptor:metadata" key="plan" value="vts-kernel" />
+    <target_preparer class="com.android.compatibility.common.tradefed.targetprep.VtsFilePusher">
+        <option name="abort-on-push-failure" value="false"/>
+        <option name="push-group" value="HostDrivenTest.push"/>
+    </target_preparer>
+    <test class="com.android.tradefed.testtype.VtsMultiDeviceTest">
+      <option name="test-module-name" value="VtsKernelLibdmTest"/>
+        <option name="binary-test-source" value="_32bit::DATA/nativetest/libdm_test/libdm_test" />
+        <option name="binary-test-source" value="_64bit::DATA/nativetest64/libdm_test/libdm_test" />
+        <option name="binary-test-type" value="gtest"/>
+        <option name="test-timeout" value="1m"/>
+        <option name="precondition-first-api-level" value="29" />
+    </test>
+</configuration>
+
diff --git a/fs_mgr/liblp/Android.mk b/fs_mgr/liblp/Android.mk
new file mode 100644
index 0000000..7f7f891
--- /dev/null
+++ b/fs_mgr/liblp/Android.mk
@@ -0,0 +1,22 @@
+#
+# Copyright (C) 2018 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.
+#
+
+LOCAL_PATH := $(call my-dir)
+
+include $(CLEAR_VARS)
+
+LOCAL_MODULE := VtsKernelLiblpTest
+-include test/vts/tools/build/Android.host_config.mk
diff --git a/fs_mgr/liblp/AndroidTest.xml b/fs_mgr/liblp/AndroidTest.xml
new file mode 100644
index 0000000..007a302
--- /dev/null
+++ b/fs_mgr/liblp/AndroidTest.xml
@@ -0,0 +1,31 @@
+<?xml version="1.0" encoding="utf-8"?>
+<!-- Copyright (C) 2019 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.
+-->
+<configuration description="Config for VTS VtsKernelLiblpTest">
+    <option name="config-descriptor:metadata" key="plan" value="vts-kernel" />
+    <target_preparer class="com.android.compatibility.common.tradefed.targetprep.VtsFilePusher">
+        <option name="abort-on-push-failure" value="false"/>
+        <option name="push-group" value="HostDrivenTest.push"/>
+    </target_preparer>
+    <test class="com.android.tradefed.testtype.VtsMultiDeviceTest">
+      <option name="test-module-name" value="VtsKernelLiblpTest"/>
+        <option name="binary-test-source" value="_32bit::DATA/nativetest/liblp_test/liblp_test" />
+        <option name="binary-test-source" value="_64bit::DATA/nativetest64/liblp_test/liblp_test" />
+        <option name="binary-test-type" value="gtest"/>
+        <option name="test-timeout" value="1m"/>
+        <option name="precondition-first-api-level" value="29" />
+    </test>
+</configuration>
+
diff --git a/fs_mgr/tests/adb-remount-test.sh b/fs_mgr/tests/adb-remount-test.sh
index b95e54e..c09dc3d 100755
--- a/fs_mgr/tests/adb-remount-test.sh
+++ b/fs_mgr/tests/adb-remount-test.sh
@@ -447,59 +447,71 @@
   exit 1
 }
 
-[ "USAGE: EXPECT_EQ <lval> <rval> [message]
+[ "USAGE: EXPECT_EQ <lval> <rval> [--warning [message]]
 
 Returns true if (regex) lval matches rval" ]
 EXPECT_EQ() {
   local lval="${1}"
   local rval="${2}"
   shift 2
+  local error=1
+  local prefix="${RED}[    ERROR ]${NORMAL}"
+  if [ X"${1}" = X"--warning" ]; then
+      prefix="${RED}[  WARNING ]${NORMAL}"
+      error=0
+      shift 1
+  fi
   if ! ( echo X"${rval}" | grep '^X'"${lval}"'$' >/dev/null 2>/dev/null ); then
     if [ `echo ${lval}${rval}${*} | wc -c` -gt 50 -o "${rval}" != "${rval%
 *}" ]; then
-      echo "ERROR: expected \"${lval}\"" >&2
-      echo "       got \"${rval}\"" |
+      echo "${prefix} expected \"${lval}\"" >&2
+      echo "${prefix} got \"${rval}\"" |
         sed ': again
              N
              s/\(\n\)\([^ ]\)/\1             \2/
              t again' >&2
       if [ -n "${*}" ] ; then
-        echo "       ${*}" >&2
+        echo "${prefix} ${*}" >&2
       fi
     else
-      echo "ERROR: expected \"${lval}\" got \"${rval}\" ${*}" >&2
+      echo "${prefix} expected \"${lval}\" got \"${rval}\" ${*}" >&2
     fi
-    return 1
+    return ${error}
   fi
   if [ -n "${*}" ] ; then
-    if [ X"${lval}" != X"${rval}" ]; then
+    prefix="${GREEN}[     INFO ]${NORMAL}"
+    if [ X"${lval}" != X"${rval}" ]; then  # we were supplied a regex?
       if [ `echo ${lval}${rval}${*} | wc -c` -gt 60 -o "${rval}" != "${rval% *}" ]; then
-        echo "INFO: ok \"${lval}\"" >&2
+        echo "${prefix} ok \"${lval}\"" >&2
         echo "       = \"${rval}\"" |
           sed ': again
                N
                s/\(\n\)\([^ ]\)/\1          \2/
                t again' >&2
         if [ -n "${*}" ] ; then
-          echo "      ${*}" >&2
+          echo "${prefix} ${*}" >&2
         fi
       else
-        echo "INFO: ok \"${lval}\" = \"${rval}\" ${*}" >&2
+        echo "${prefix} ok \"${lval}\" = \"${rval}\" ${*}" >&2
       fi
     else
-      echo "INFO: ok \"${lval}\" ${*}" >&2
+      echo "${prefix} ok \"${lval}\" ${*}" >&2
     fi
   fi
   return 0
 }
 
-[ "USAGE: check_eq <lval> <rval> [message]
+[ "USAGE: check_eq <lval> <rval> [--warning [message]]
 
 Exits if (regex) lval mismatches rval" ]
 check_eq() {
   local lval="${1}"
   local rval="${2}"
   shift 2
+  if [ X"${1}" = X"--warning" ]; then
+      EXPECT_EQ "${lval}" "${rval}" ${*}
+      return
+  fi
   EXPECT_EQ "${lval}" "${rval}" ||
     die "${@}"
 }
@@ -1085,14 +1097,9 @@
     check_eq "cat: /vendor/hello: No such file or directory" "${B}" \
              vendor content after flash vendor
   else
-    (
-      echo "${ORANGE}[  WARNING ]${NORMAL} user fastboot missing required to invalidate, ignoring a failure" >&2
-      restore() {
-        true
-      }
-      check_eq "cat: /vendor/hello: No such file or directory" "${B}" \
-               vendor content after flash vendor
-    )
+    echo "${ORANGE}[  WARNING ]${NORMAL} user fastboot missing required to invalidate, ignoring a failure" >&2
+    check_eq "cat: /vendor/hello: No such file or directory" "${B}" \
+             --warning vendor content after flash vendor
   fi
 fi
 
diff --git a/libmemunreachable/HeapWalker.cpp b/libmemunreachable/HeapWalker.cpp
index e11f079..7cae048 100644
--- a/libmemunreachable/HeapWalker.cpp
+++ b/libmemunreachable/HeapWalker.cpp
@@ -207,6 +207,6 @@
   }
 }
 
-ScopedSignalHandler::SignalFn ScopedSignalHandler::handler_;
+Allocator<ScopedSignalHandler::SignalFnMap>::unique_ptr ScopedSignalHandler::handler_map_;
 
 }  // namespace android
diff --git a/libmemunreachable/HeapWalker.h b/libmemunreachable/HeapWalker.h
index 9e3db08..f00bcca 100644
--- a/libmemunreachable/HeapWalker.h
+++ b/libmemunreachable/HeapWalker.h
@@ -52,7 +52,8 @@
         allocation_bytes_(0),
         roots_(allocator),
         root_vals_(allocator),
-        segv_handler_(),
+        sigsegv_handler_(allocator),
+        sigbus_handler_(allocator),
         walking_ptr_(0),
         walking_range_{0, 0},
         segv_logged_(false),
@@ -62,10 +63,14 @@
     valid_mappings_range_.end = 0;
     valid_mappings_range_.begin = ~valid_allocations_range_.end;
 
-    segv_handler_.install(
+    sigsegv_handler_.install(
         SIGSEGV, [=](ScopedSignalHandler& handler, int signal, siginfo_t* siginfo, void* uctx) {
           this->HandleSegFault(handler, signal, siginfo, uctx);
         });
+    sigbus_handler_.install(
+        SIGBUS, [=](ScopedSignalHandler& handler, int signal, siginfo_t* siginfo, void* uctx) {
+          this->HandleSegFault(handler, signal, siginfo, uctx);
+        });
   }
 
   ~HeapWalker() {}
@@ -106,7 +111,8 @@
   allocator::vector<Range> roots_;
   allocator::vector<uintptr_t> root_vals_;
 
-  ScopedSignalHandler segv_handler_;
+  ScopedSignalHandler sigsegv_handler_;
+  ScopedSignalHandler sigbus_handler_;
   volatile uintptr_t walking_ptr_;
   Range walking_range_;
   bool segv_logged_;
diff --git a/libmemunreachable/ScopedSignalHandler.h b/libmemunreachable/ScopedSignalHandler.h
index 9e08a8e..ef4473f 100644
--- a/libmemunreachable/ScopedSignalHandler.h
+++ b/libmemunreachable/ScopedSignalHandler.h
@@ -24,6 +24,7 @@
 
 #include "android-base/macros.h"
 
+#include "Allocator.h"
 #include "log.h"
 
 namespace android {
@@ -32,17 +33,29 @@
  public:
   using Fn = std::function<void(ScopedSignalHandler&, int, siginfo_t*, void*)>;
 
-  explicit ScopedSignalHandler() : signal_(-1) {}
+  explicit ScopedSignalHandler(Allocator<ScopedSignalHandler> allocator) : signal_(-1) {
+    if (handler_map_ == nullptr) {
+      Allocator<SignalFnMap> map_allocator = allocator;
+      handler_map_ = map_allocator.make_unique(allocator);
+    }
+  }
   ~ScopedSignalHandler() { reset(); }
 
   template <class F>
   void install(int signal, F&& f) {
     if (signal_ != -1) MEM_LOG_ALWAYS_FATAL("ScopedSignalHandler already installed");
 
-    handler_ = SignalFn([=](int signal, siginfo_t* si, void* uctx) { f(*this, signal, si, uctx); });
+    if (handler_map_->find(signal) != handler_map_->end()) {
+      MEM_LOG_ALWAYS_FATAL("ScopedSignalHandler already installed for %d", signal);
+    }
+
+    (*handler_map_)[signal] =
+        SignalFn([=](int signal, siginfo_t* si, void* uctx) { f(*this, signal, si, uctx); });
 
     struct sigaction act {};
-    act.sa_sigaction = [](int signal, siginfo_t* si, void* uctx) { handler_(signal, si, uctx); };
+    act.sa_sigaction = [](int signal, siginfo_t* si, void* uctx) {
+      ((*handler_map_)[signal])(signal, si, uctx);
+    };
     act.sa_flags = SA_SIGINFO;
 
     int ret = sigaction(signal, &act, &old_act_);
@@ -59,19 +72,22 @@
       if (ret < 0) {
         MEM_ALOGE("failed to uninstall segfault handler");
       }
-      handler_ = SignalFn{};
+
+      handler_map_->erase(signal_);
+      if (handler_map_->empty()) {
+        handler_map_.reset();
+      }
       signal_ = -1;
     }
   }
 
  private:
   using SignalFn = std::function<void(int, siginfo_t*, void*)>;
+  using SignalFnMap = allocator::unordered_map<int, SignalFn>;
   DISALLOW_COPY_AND_ASSIGN(ScopedSignalHandler);
   int signal_;
   struct sigaction old_act_;
-  // TODO(ccross): to support multiple ScopedSignalHandlers handler_ would need
-  // to be a static map of signals to handlers, but allocated with Allocator.
-  static SignalFn handler_;
+  static Allocator<SignalFnMap>::unique_ptr handler_map_;
 };
 
 }  // namespace android
diff --git a/libnativeloader/native_loader.cpp b/libnativeloader/native_loader.cpp
index 1c2581f..5cc0857 100644
--- a/libnativeloader/native_loader.cpp
+++ b/libnativeloader/native_loader.cpp
@@ -288,8 +288,9 @@
 
       // Give access to VNDK-SP libraries from the 'vndk' namespace.
       vndk_ns = android_get_exported_namespace(kVndkNamespaceName);
-      LOG_ALWAYS_FATAL_IF(vndk_ns == nullptr, "Cannot find \"%s\" namespace for %s apks",
-                          kVndkNamespaceName, origin_partition);
+      if (vndk_ns == nullptr) {
+        ALOGW("Cannot find \"%s\" namespace for %s apks", kVndkNamespaceName, origin_partition);
+      }
 
       // Different name is useful for debugging
       namespace_name = kVendorClassloaderNamespaceName;
diff --git a/libprocessgroup/cgroup_map.cpp b/libprocessgroup/cgroup_map.cpp
index 9951621..b3b497f 100644
--- a/libprocessgroup/cgroup_map.cpp
+++ b/libprocessgroup/cgroup_map.cpp
@@ -336,8 +336,10 @@
 }
 
 CgroupMap& CgroupMap::GetInstance() {
-    static CgroupMap instance;
-    return instance;
+    // Deliberately leak this object to avoid a race between destruction on
+    // process exit and concurrent access from another thread.
+    static auto* instance = new CgroupMap;
+    return *instance;
 }
 
 bool CgroupMap::LoadRcFile() {
diff --git a/libprocessgroup/task_profiles.cpp b/libprocessgroup/task_profiles.cpp
index f1fbcde..9362c03 100644
--- a/libprocessgroup/task_profiles.cpp
+++ b/libprocessgroup/task_profiles.cpp
@@ -284,8 +284,10 @@
 }
 
 TaskProfiles& TaskProfiles::GetInstance() {
-    static TaskProfiles instance;
-    return instance;
+    // Deliberately leak this object to avoid a race between destruction on
+    // process exit and concurrent access from another thread.
+    static auto* instance = new TaskProfiles;
+    return *instance;
 }
 
 TaskProfiles::TaskProfiles() {
diff --git a/libziparchive/entry_name_utils-inl.h b/libziparchive/entry_name_utils-inl.h
index 5fc2fb4..1714586 100644
--- a/libziparchive/entry_name_utils-inl.h
+++ b/libziparchive/entry_name_utils-inl.h
@@ -35,7 +35,7 @@
       return false;
     } else {
       // 2-5 byte sequences.
-      for (uint8_t first = byte << 1; first & 0x80; first <<= 1) {
+      for (uint8_t first = (byte & 0x7f) << 1; first & 0x80; first = (first & 0x7f) << 1) {
         ++i;
 
         // Missing continuation byte..
diff --git a/libziparchive/zip_archive.cc b/libziparchive/zip_archive.cc
index 6b9f6e1..0710d0a 100644
--- a/libziparchive/zip_archive.cc
+++ b/libziparchive/zip_archive.cc
@@ -278,11 +278,6 @@
   if (static_cast<off64_t>(eocd->cd_start_offset) + eocd->cd_size > eocd_offset) {
     ALOGW("Zip: bad offsets (dir %" PRIu32 ", size %" PRIu32 ", eocd %" PRId64 ")",
           eocd->cd_start_offset, eocd->cd_size, static_cast<int64_t>(eocd_offset));
-#if defined(__ANDROID__)
-    if (eocd->cd_start_offset + eocd->cd_size <= eocd_offset) {
-      android_errorWriteLog(0x534e4554, "31251826");
-    }
-#endif
     return kInvalidOffset;
   }
   if (eocd->num_records == 0) {