Merge "Revert "Revert "Allow dlopen("/system/lib/<soname>") for pre-Q"""
diff --git a/libc/bionic/icu.cpp b/libc/bionic/icu.cpp
index 41a0729..72dac9b 100644
--- a/libc/bionic/icu.cpp
+++ b/libc/bionic/icu.cpp
@@ -36,53 +36,12 @@
 
 #include <async_safe/log.h>
 
-// Allowed icu4c version numbers are in the range [44, 999].
-// Gingerbread's icu4c 4.4 is the minimum supported ICU version.
-static constexpr auto ICUDATA_VERSION_MIN_LENGTH = 2;
-static constexpr auto ICUDATA_VERSION_MAX_LENGTH = 3;
-static constexpr auto ICUDATA_VERSION_MIN = 44;
-
-static char g_icudata_version[ICUDATA_VERSION_MAX_LENGTH + 1];
-
 static void* g_libicuuc_handle = nullptr;
 
-static int __icu_dat_file_filter(const dirent* dirp) {
-  const char* name = dirp->d_name;
-
-  // Is the name the right length to match 'icudt(\d\d\d)l.dat'?
-  const size_t len = strlen(name);
-  if (len < 10 + ICUDATA_VERSION_MIN_LENGTH || len > 10 + ICUDATA_VERSION_MAX_LENGTH) return 0;
-
-  return !strncmp(name, "icudt", 5) && !strncmp(&name[len - 5], "l.dat", 5);
-}
-
 static bool __find_icu() {
-  dirent** namelist = nullptr;
-  int n = scandir("/apex/com.android.runtime/etc/icu", &namelist, &__icu_dat_file_filter,
-                  alphasort);
-  if (n < 0) {
-    async_safe_write_log(ANDROID_LOG_ERROR, "bionic-icu", "couldn't find ICU folder");
-    return false;
-  }
-  int max_version = -1;
-  while (n--) {
-    // We prefer the latest version available.
-    int version = atoi(&namelist[n]->d_name[strlen("icudt")]);
-    if (version != 0 && version > max_version) max_version = version;
-    free(namelist[n]);
-  }
-  free(namelist);
-
-  if (max_version < ICUDATA_VERSION_MIN) {
-    async_safe_write_log(ANDROID_LOG_ERROR, "bionic-icu", "couldn't find an ICU .dat file");
-    return false;
-  }
-
-  snprintf(g_icudata_version, sizeof(g_icudata_version), "_%d", max_version);
-
-  g_libicuuc_handle = dlopen("libicuuc.so", RTLD_LOCAL);
+  g_libicuuc_handle = dlopen("libandroidicu.so", RTLD_LOCAL);
   if (g_libicuuc_handle == nullptr) {
-    async_safe_format_log(ANDROID_LOG_ERROR, "bionic-icu", "couldn't open libicuuc.so: %s",
+    async_safe_format_log(ANDROID_LOG_ERROR, "bionic-icu", "couldn't open libandroidicu.so: %s",
                           dlerror());
     return false;
   }
@@ -94,9 +53,9 @@
   static bool found_icu = __find_icu();
   if (!found_icu) return nullptr;
 
-  char versioned_symbol_name[strlen(symbol_name) + sizeof(g_icudata_version)];
-  snprintf(versioned_symbol_name, sizeof(versioned_symbol_name), "%s%s",
-           symbol_name, g_icudata_version);
+  char versioned_symbol_name[strlen(symbol_name) + strlen("_android") + 1];
+  snprintf(versioned_symbol_name, sizeof(versioned_symbol_name), "%s_android",
+           symbol_name);
 
   void* symbol = dlsym(g_libicuuc_handle, versioned_symbol_name);
   if (symbol == nullptr) {
diff --git a/libc/symbol_ordering b/libc/symbol_ordering
index b672b35..8b2d153 100644
--- a/libc/symbol_ordering
+++ b/libc/symbol_ordering
@@ -46,7 +46,6 @@
 optreset
 _rs_forked
 daylight
-_ZL17g_icudata_version
 gMallocLeakZygoteChild
 _ZL18netdClientInitOnce
 je_opt_narenas
diff --git a/tests/Android.bp b/tests/Android.bp
index c1d19fa..b039f00 100644
--- a/tests/Android.bp
+++ b/tests/Android.bp
@@ -40,7 +40,7 @@
     ],
     stl: "libc++",
     sanitize: {
-        never: true,
+        address: false,
     },
     bootstrap: true,
 }
diff --git a/tests/buffer_tests.cpp b/tests/buffer_tests.cpp
index 7563448..fb0b6d8 100644
--- a/tests/buffer_tests.cpp
+++ b/tests/buffer_tests.cpp
@@ -20,6 +20,7 @@
 
 #include <gtest/gtest.h>
 #include "buffer_tests.h"
+#include "utils.h"
 
 // For the comparison buffer tests, the maximum length to test for the
 // miscompare checks.
@@ -227,16 +228,11 @@
   }
 }
 
-// Malloc can return a tagged pointer, which is not accepted in mm system calls like mprotect.
-// Clear top 8 bits of the address on 64-bit platforms.
+// Malloc can return a tagged pointer, which is not accepted in mm system calls like mprotect
+// in the preliminary version of the syscall tagging support in the current Pixel 2 kernel.
+// Note: the final version of the kernel patchset may relax this requirement.
 static int MprotectHeap(void* addr, size_t len, int prot) {
-#if defined(__LP64__)
-  constexpr uintptr_t mask = (static_cast<uintptr_t>(1) << 56) - 1;
-  void* untagged_addr = reinterpret_cast<void*>(reinterpret_cast<uintptr_t>(addr) & mask);
-#else
-  void* untagged_addr = addr;
-#endif
-  return mprotect(untagged_addr, len, prot);
+  return mprotect(untag_address(addr), len, prot);
 }
 
 void RunSingleBufferAlignTest(
diff --git a/tests/dl_test.cpp b/tests/dl_test.cpp
index aea92b4..468ce3d 100644
--- a/tests/dl_test.cpp
+++ b/tests/dl_test.cpp
@@ -138,7 +138,7 @@
 
 TEST(dl, preinit_system_calls) {
 #if defined(__BIONIC__)
-  SKIP_WITH_HWASAN; // hwasan not initialized in preinit_array
+  SKIP_WITH_HWASAN; // hwasan not initialized in preinit_array, b/124007027
   std::string helper = GetTestlibRoot() +
       "/preinit_syscall_test_helper/preinit_syscall_test_helper";
   chmod(helper.c_str(), 0755); // TODO: "x" lost in CTS, b/34945607
@@ -150,6 +150,7 @@
 
 TEST(dl, preinit_getauxval) {
 #if defined(__BIONIC__)
+  SKIP_WITH_HWASAN; // hwasan not initialized in preinit_array, b/124007027
   std::string helper = GetTestlibRoot() +
       "/preinit_getauxval_test_helper/preinit_getauxval_test_helper";
   chmod(helper.c_str(), 0755); // TODO: "x" lost in CTS, b/34945607
diff --git a/tests/malloc_test.cpp b/tests/malloc_test.cpp
index 2506691..a3fe5af 100644
--- a/tests/malloc_test.cpp
+++ b/tests/malloc_test.cpp
@@ -515,6 +515,7 @@
 
 TEST(malloc, mallopt_decay) {
 #if defined(__BIONIC__)
+  SKIP_WITH_HWASAN; // hwasan does not implement mallopt
   errno = 0;
   ASSERT_EQ(1, mallopt(M_DECAY_TIME, 1));
   ASSERT_EQ(1, mallopt(M_DECAY_TIME, 0));
@@ -527,6 +528,7 @@
 
 TEST(malloc, mallopt_purge) {
 #if defined(__BIONIC__)
+  SKIP_WITH_HWASAN; // hwasan does not implement mallopt
   errno = 0;
   ASSERT_EQ(1, mallopt(M_PURGE, 0));
 #else
@@ -564,6 +566,7 @@
 
 TEST(malloc, mallinfo) {
 #if defined(__BIONIC__)
+  SKIP_WITH_HWASAN; // hwasan does not implement mallinfo
   static size_t sizes[] = {
     8, 32, 128, 4096, 32768, 131072, 1024000, 10240000, 20480000, 300000000
   };
diff --git a/tests/pthread_test.cpp b/tests/pthread_test.cpp
index 8da54ce..973ca53 100644
--- a/tests/pthread_test.cpp
+++ b/tests/pthread_test.cpp
@@ -1553,7 +1553,7 @@
   void* maps_stack_hi = nullptr;
   std::vector<map_record> maps;
   ASSERT_TRUE(Maps::parse_maps(&maps));
-  uintptr_t stack_address = reinterpret_cast<uintptr_t>(&maps_stack_hi);
+  uintptr_t stack_address = reinterpret_cast<uintptr_t>(untag_address(&maps_stack_hi));
   for (const auto& map : maps) {
     if (map.addr_start <= stack_address && map.addr_end > stack_address){
       maps_stack_hi = reinterpret_cast<void*>(map.addr_end);
@@ -1632,9 +1632,9 @@
 
   // Verify if the stack used by the signal handler is the alternate stack just registered.
   ASSERT_LE(getstack_signal_handler_arg.signal_stack_base, &attr);
-  ASSERT_LT(static_cast<void*>(&attr),
+  ASSERT_LT(static_cast<void*>(untag_address(&attr)),
             static_cast<char*>(getstack_signal_handler_arg.signal_stack_base) +
-            getstack_signal_handler_arg.signal_stack_size);
+                getstack_signal_handler_arg.signal_stack_size);
 
   // Verify if the main thread's stack got in the signal handler is correct.
   ASSERT_EQ(getstack_signal_handler_arg.main_stack_base, stack_base);
@@ -1693,7 +1693,7 @@
 
   // Test whether &local_variable is in [stack_base, stack_base + stack_size).
   ASSERT_LE(reinterpret_cast<char*>(stack_base), &local_variable);
-  ASSERT_LT(&local_variable, reinterpret_cast<char*>(stack_base) + stack_size);
+  ASSERT_LT(untag_address(&local_variable), reinterpret_cast<char*>(stack_base) + stack_size);
 }
 
 // Check whether something on stack is in the range of
diff --git a/tests/stack_protector_test.cpp b/tests/stack_protector_test.cpp
index 34e3c11..7a85cc3 100644
--- a/tests/stack_protector_test.cpp
+++ b/tests/stack_protector_test.cpp
@@ -104,6 +104,11 @@
 TEST_F(stack_protector_DeathTest, modify_stack_protector) {
   // In another file to prevent inlining, which removes stack protection.
   extern void modify_stack_protector_test();
+#if __has_feature(hwaddress_sanitizer)
+  ASSERT_EXIT(modify_stack_protector_test(),
+              testing::KilledBySignal(SIGABRT), "tag-mismatch");
+#else
   ASSERT_EXIT(modify_stack_protector_test(),
               testing::KilledBySignal(SIGABRT), "stack corruption detected");
+#endif
 }
diff --git a/tests/sys_ptrace_test.cpp b/tests/sys_ptrace_test.cpp
index 83fd93b..04dcd4e 100644
--- a/tests/sys_ptrace_test.cpp
+++ b/tests/sys_ptrace_test.cpp
@@ -35,6 +35,8 @@
 #include <android-base/macros.h>
 #include <android-base/unique_fd.h>
 
+#include "utils.h"
+
 using namespace std::chrono_literals;
 
 using android::base::unique_fd;
@@ -193,7 +195,7 @@
     return;
   }
 
-  set_watchpoint(child, uintptr_t(&data) + offset, size);
+  set_watchpoint(child, uintptr_t(untag_address(&data)) + offset, size);
 
   ASSERT_EQ(0, ptrace(PTRACE_CONT, child, nullptr, nullptr)) << strerror(errno);
   ASSERT_EQ(child, TEMP_FAILURE_RETRY(waitpid(child, &status, __WALL))) << strerror(errno);
diff --git a/tests/unistd_test.cpp b/tests/unistd_test.cpp
index f4a7f1f..cb94e45 100644
--- a/tests/unistd_test.cpp
+++ b/tests/unistd_test.cpp
@@ -538,7 +538,7 @@
 
 static int CloneStartRoutine(int (*start_routine)(void*)) {
   void* child_stack[1024];
-  return clone(start_routine, &child_stack[1024], SIGCHLD, nullptr);
+  return clone(start_routine, untag_address(&child_stack[1024]), SIGCHLD, nullptr);
 }
 
 static int GetPidCachingCloneStartRoutine(void*) {
diff --git a/tests/utils.h b/tests/utils.h
index 5fc1d93..cc1aa8c 100644
--- a/tests/utils.h
+++ b/tests/utils.h
@@ -66,6 +66,16 @@
 
 #define SKIP_WITH_HWASAN if (running_with_hwasan()) { return; }
 
+static inline void* untag_address(void* addr) {
+#if defined(__LP64__)
+  if (running_with_hwasan()) {
+    constexpr uintptr_t mask = (static_cast<uintptr_t>(1) << 56) - 1;
+    addr = reinterpret_cast<void*>(reinterpret_cast<uintptr_t>(addr) & mask);
+  }
+#endif
+  return addr;
+}
+
 #if defined(__linux__)
 
 #include <sys/sysmacros.h>