Merge "Move crash_dump into the runtime APEX."
diff --git a/TEST_MAPPING b/TEST_MAPPING
index 9f60ae7..ae61304 100644
--- a/TEST_MAPPING
+++ b/TEST_MAPPING
@@ -7,6 +7,9 @@
       "name": "fdtrack_test"
     },
     {
+      "name": "gwp_asan_unittest"
+    },
+    {
       "name": "malloc_debug_system_tests"
     },
     {
diff --git a/libc/Android.bp b/libc/Android.bp
index 4d35592..49654b3 100644
--- a/libc/Android.bp
+++ b/libc/Android.bp
@@ -1747,6 +1747,7 @@
         "//art:__subpackages__",
         "//bionic:__subpackages__",
         "//frameworks:__subpackages__",
+        "//external/gwp_asan:__subpackages__",
         "//external/perfetto:__subpackages__",
         "//external/scudo:__subpackages__",
         "//system/core/debuggerd:__subpackages__",
@@ -1774,6 +1775,12 @@
     ramdisk_available: true,
     recovery_available: true,
     native_bridge_supported: true,
+    apex_available: [
+        "//apex_available:platform",
+        "com.android.runtime",
+        "com.android.art.debug",
+        "com.android.art.release",
+    ],
 
     no_libcrt: true,
     stl: "none",
@@ -1905,6 +1912,10 @@
     ramdisk_available: true,
     recovery_available: true,
     native_bridge_supported: true,
+    apex_available: [
+        "//apex_available:platform",
+        "//apex_available:anyapex",
+    ],
 
     cflags: [
         "-Wno-gcc-compat",
diff --git a/libc/bionic/android_profiling_dynamic.cpp b/libc/bionic/android_profiling_dynamic.cpp
index 54f896c..9d92a6d 100644
--- a/libc/bionic/android_profiling_dynamic.cpp
+++ b/libc/bionic/android_profiling_dynamic.cpp
@@ -63,6 +63,14 @@
   action.sa_flags = SA_SIGINFO | SA_RESTART;
   action.sa_sigaction = HandleProfilingSignal;
   sigaction(BIONIC_SIGNAL_PROFILER, &action, nullptr);
+
+  // The perfetto_hprof ART plugin installs a signal handler to handle this signal. That plugin
+  // does not get loaded for a) non-apps, b) non-profilable apps on user. The default signal
+  // disposition is to crash. We do not want the target to crash if we accidentally target a
+  // non-app or non-profilable process.
+  //
+  // This does *not* get run for processes that statically link libc, and those will still crash.
+  signal(BIONIC_SIGNAL_ART_PROFILER, SIG_IGN);
 }
 
 static void HandleSigsysSeccompOverride(int, siginfo_t*, void*);
diff --git a/libc/bionic/ffs.cpp b/libc/bionic/ffs.cpp
index b2270e5..aa7e504 100644
--- a/libc/bionic/ffs.cpp
+++ b/libc/bionic/ffs.cpp
@@ -26,8 +26,5 @@
  * SUCH DAMAGE.
  */
 
+#define __BIONIC_STRINGS_INLINE /* Out of line. */
 #include <strings.h>
-
-int ffs(int x) {
-  return __builtin_ffs(x);
-}
diff --git a/libc/include/android/legacy_strings_inlines.h b/libc/include/android/legacy_strings_inlines.h
deleted file mode 100644
index 2cc2da2..0000000
--- a/libc/include/android/legacy_strings_inlines.h
+++ /dev/null
@@ -1,44 +0,0 @@
-/*
- * Copyright (C) 2017 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.
- */
-
-#pragma once
-
-#include <sys/cdefs.h>
-
-#if defined(__i386__) && __ANDROID_API__ < 18
-
-#include <strings.h>
-
-__BEGIN_DECLS
-
-/* Everyone except x86 had ffs since the beginning. */
-static __inline int ffs(int __n) { return __builtin_ffs(__n); }
-
-__END_DECLS
-
-#endif
diff --git a/libc/include/strings.h b/libc/include/strings.h
index 08c2326..ba69c8d 100644
--- a/libc/include/strings.h
+++ b/libc/include/strings.h
@@ -49,6 +49,10 @@
 
 #include <bits/strcasecmp.h>
 
+#if !defined(__BIONIC_STRINGS_INLINE)
+#define __BIONIC_STRINGS_INLINE static __inline
+#endif
+
 __BEGIN_DECLS
 
 /** Deprecated. Use memmove() instead. */
@@ -63,19 +67,41 @@
   __builtin_memset(b, 0, len);
 }
 
-#if !defined(__i386__) || __ANDROID_API__ >= 18
 /**
- * [ffs(3)](http://man7.org/linux/man-pages/man3/ffs.3.html) finds the first set bit in `__i`.
+ * [ffs(3)](http://man7.org/linux/man-pages/man3/ffs.3.html) finds the
+ * first set bit in `__n`.
  *
- * Returns 0 if no bit is set, or the index of the lowest set bit (counting from 1) otherwise.
+ * Returns 0 if no bit is set, or the index of the lowest set bit (counting
+ * from 1) otherwise.
  */
-int ffs(int __i) __INTRODUCED_IN_X86(18);
-#endif
+__BIONIC_STRINGS_INLINE int ffs(int __n) {
+  return __builtin_ffs(__n);
+}
+
+/**
+ * [ffsl(3)](http://man7.org/linux/man-pages/man3/ffsl.3.html) finds the
+ * first set bit in `__n`.
+ *
+ * Returns 0 if no bit is set, or the index of the lowest set bit (counting
+ * from 1) otherwise.
+ */
+__BIONIC_STRINGS_INLINE int ffsl(long __n) {
+  return __builtin_ffsl(__n);
+}
+
+/**
+ * [ffsll(3)](http://man7.org/linux/man-pages/man3/ffsll.3.html) finds the
+ * first set bit in `__n`.
+ *
+ * Returns 0 if no bit is set, or the index of the lowest set bit (counting
+ * from 1) otherwise.
+ */
+__BIONIC_STRINGS_INLINE int ffsll(long long __n) {
+  return __builtin_ffsll(__n);
+}
 
 #if defined(__BIONIC_INCLUDE_FORTIFY_HEADERS)
 #include <bits/fortify/strings.h>
 #endif
 
 __END_DECLS
-
-#include <android/legacy_strings_inlines.h>
diff --git a/libc/libc.map.txt b/libc/libc.map.txt
index 4bfb8a2..2284775 100644
--- a/libc/libc.map.txt
+++ b/libc/libc.map.txt
@@ -1550,6 +1550,12 @@
     _Unwind_VRS_Set; # apex llndk arm
 } LIBC_Q;
 
+LIBC_S { # introduced=31
+  global:
+    ffsl;
+    ffsll;
+} LIBC_R;
+
 LIBC_PRIVATE {
   global:
     __accept4; # arm x86
diff --git a/libc/malloc_debug/tests/malloc_debug_system_tests.cpp b/libc/malloc_debug/tests/malloc_debug_system_tests.cpp
index 9e612f0..dd569fd 100644
--- a/libc/malloc_debug/tests/malloc_debug_system_tests.cpp
+++ b/libc/malloc_debug/tests/malloc_debug_system_tests.cpp
@@ -150,7 +150,7 @@
   log_str->clear();
 
   logger_list* list;
-  list = android_logger_list_open(log, ANDROID_LOG_RDONLY | ANDROID_LOG_NONBLOCK, 1000, pid);
+  list = android_logger_list_open(log, ANDROID_LOG_NONBLOCK, 1000, pid);
   ASSERT_TRUE(list != nullptr);
 
   while (true) {
diff --git a/libc/platform/bionic/macros.h b/libc/platform/bionic/macros.h
index 28a69e6..076cff1 100644
--- a/libc/platform/bionic/macros.h
+++ b/libc/platform/bionic/macros.h
@@ -83,11 +83,15 @@
 #define __BIONIC_FALLTHROUGH
 #endif
 
-template <typename T>
-static inline T* untag_address(T* p) {
+static inline uintptr_t untag_address(uintptr_t p) {
 #if defined(__aarch64__)
-  return reinterpret_cast<T*>(reinterpret_cast<uintptr_t>(p) & ((1ULL << 56) - 1));
+  return p & ((1ULL << 56) - 1);
 #else
   return p;
 #endif
 }
+
+template <typename T>
+static inline T* untag_address(T* p) {
+  return reinterpret_cast<T*>(untag_address(reinterpret_cast<uintptr_t>(p)));
+}
diff --git a/libc/platform/bionic/reserved_signals.h b/libc/platform/bionic/reserved_signals.h
index 3c5bc02..c90fc06 100644
--- a/libc/platform/bionic/reserved_signals.h
+++ b/libc/platform/bionic/reserved_signals.h
@@ -47,8 +47,10 @@
 // If you change this, also change __ndk_legacy___libc_current_sigrtmin
 // in <android/legacy_signal_inlines.h> to match.
 
+#define BIONIC_SIGNAL_POSIX_TIMERS (__SIGRTMIN + 0)
 #define BIONIC_SIGNAL_DEBUGGER (__SIGRTMIN + 3)
 #define BIONIC_SIGNAL_PROFILER (__SIGRTMIN + 4)
+#define BIONIC_SIGNAL_ART_PROFILER (__SIGRTMIN + 6)
 #define BIONIC_SIGNAL_FDTRACK (__SIGRTMIN + 7)
 
 #define __SIGRT_RESERVED 8
diff --git a/libdl/Android.bp b/libdl/Android.bp
index f431e84..8e3a3fc 100644
--- a/libdl/Android.bp
+++ b/libdl/Android.bp
@@ -29,11 +29,6 @@
     sanitize: {
         never: true,
     },
-
-    apex_available: [
-        "//apex_available:platform",
-        "com.android.runtime",
-    ],
 }
 
 cc_library {
diff --git a/linker/Android.bp b/linker/Android.bp
index 3190870..4be080b 100644
--- a/linker/Android.bp
+++ b/linker/Android.bp
@@ -98,7 +98,6 @@
     static_libs: [
         "libziparchive",
         "libbase",
-        "libdl", // libbase uses dlsym
         "libz",
 
         "libasync_safe",
diff --git a/tests/Android.bp b/tests/Android.bp
index d78a204..f1182a7 100644
--- a/tests/Android.bp
+++ b/tests/Android.bp
@@ -779,17 +779,6 @@
 }
 
 cc_test {
-    name: "bionic-unit-tests-scudo",
-    defaults: [
-        "bionic_unit_tests_defaults",
-    ],
-
-    shared_libs: [
-        "libc_scudo",
-    ],
-}
-
-cc_test {
     name: "bionic-stress-tests",
     defaults: [
         "bionic_tests_defaults",
diff --git a/tests/headers/posix/strings_h.c b/tests/headers/posix/strings_h.c
index 0a2fa84..2051c8b 100644
--- a/tests/headers/posix/strings_h.c
+++ b/tests/headers/posix/strings_h.c
@@ -32,6 +32,10 @@
 
 static void strings_h() {
   FUNCTION(ffs, int (*f)(int));
+#if !defined(__GLIBC__)
+  FUNCTION(ffsl, int (*f)(long));
+  FUNCTION(ffsll, int (*f)(long long));
+#endif
   FUNCTION(strcasecmp, int (*f)(const char*, const char*));
   FUNCTION(strcasecmp_l, int (*f)(const char*, const char*, locale_t));
   FUNCTION(strncasecmp, int (*f)(const char*, const char*, size_t));
diff --git a/tests/signal_test.cpp b/tests/signal_test.cpp
index 3c66034..f465458 100644
--- a/tests/signal_test.cpp
+++ b/tests/signal_test.cpp
@@ -154,44 +154,6 @@
   raise(SIGALRM);
 }
 
-TEST(signal, sigwait_SIGALRM) {
-  ScopedSignalHandler ssh(SIGALRM, [](int sig) { ASSERT_EQ(SIGALRM, sig); });
-
-  sigset_t wait_set;
-  sigemptyset(&wait_set);
-  sigaddset(&wait_set, SIGALRM);
-
-  alarm(1);
-
-  int received_signal;
-  errno = 0;
-  ASSERT_EQ(0, sigwait(&wait_set, &received_signal));
-  ASSERT_EQ(0, errno);
-  ASSERT_EQ(SIGALRM, received_signal);
-}
-
-TEST(signal, sigwait64_SIGRTMIN) {
-  ScopedSignalHandler ssh(SIGRTMIN, [](int sig) { ASSERT_EQ(SIGRTMIN, sig); });
-
-  sigset64_t wait_set;
-  sigemptyset64(&wait_set);
-  sigaddset64(&wait_set, SIGRTMIN);
-
-  pid_t tid = gettid();
-  std::thread thread([&tid]() {
-    sleep(1);
-    tgkill(getpid(), tid, SIGRTMIN);
-  });
-
-  int received_signal;
-  errno = 0;
-  ASSERT_EQ(0, sigwait64(&wait_set, &received_signal));
-  ASSERT_EQ(0, errno);
-  ASSERT_EQ(SIGRTMIN, received_signal);
-
-  thread.join();
-}
-
 static int g_sigsuspend_signal_handler_call_count = 0;
 
 TEST(signal, sigsuspend_sigpending) {
@@ -620,8 +582,7 @@
 
 TEST(signal, sigqueue) {
   ScopedSignalHandler ssh(SIGALRM, SigqueueSignalHandler, SA_SIGINFO);
-  sigval_t sigval;
-  sigval.sival_int = 1;
+  sigval_t sigval = {.sival_int = 1};
   errno = 0;
   ASSERT_EQ(0, sigqueue(getpid(), SIGALRM, sigval));
   ASSERT_EQ(0, errno);
@@ -630,8 +591,7 @@
 
 TEST(signal, pthread_sigqueue_self) {
   ScopedSignalHandler ssh(SIGALRM, SigqueueSignalHandler, SA_SIGINFO);
-  sigval_t sigval;
-  sigval.sival_int = 1;
+  sigval_t sigval = {.sival_int = 1};
   errno = 0;
   ASSERT_EQ(0, pthread_sigqueue(pthread_self(), SIGALRM, sigval));
   ASSERT_EQ(0, errno);
@@ -640,8 +600,7 @@
 
 TEST(signal, pthread_sigqueue_other) {
   ScopedSignalHandler ssh(SIGALRM, SigqueueSignalHandler, SA_SIGINFO);
-  sigval_t sigval;
-  sigval.sival_int = 1;
+  sigval_t sigval = {.sival_int = 1};
 
   sigset_t mask;
   sigfillset(&mask);
@@ -664,6 +623,44 @@
   ASSERT_EQ(1, g_sigqueue_signal_handler_call_count);
 }
 
+TEST(signal, sigwait_SIGALRM) {
+  SignalMaskRestorer smr;
+
+  // Block SIGALRM.
+  sigset_t just_SIGALRM;
+  sigemptyset(&just_SIGALRM);
+  sigaddset(&just_SIGALRM, SIGALRM);
+  ASSERT_EQ(0, sigprocmask(SIG_BLOCK, &just_SIGALRM, nullptr));
+
+  // Raise SIGALRM.
+  sigval_t sigval = {.sival_int = 1};
+  ASSERT_EQ(0, sigqueue(getpid(), SIGALRM, sigval));
+
+  // Get pending SIGALRM.
+  int sig;
+  ASSERT_EQ(0, sigwait(&just_SIGALRM, &sig));
+  ASSERT_EQ(SIGALRM, sig);
+}
+
+TEST(signal, sigwait64_SIGRTMIN) {
+  SignalMaskRestorer smr;
+
+  // Block SIGRTMIN.
+  sigset64_t just_SIGRTMIN;
+  sigemptyset64(&just_SIGRTMIN);
+  sigaddset64(&just_SIGRTMIN, SIGRTMIN);
+  ASSERT_EQ(0, sigprocmask64(SIG_BLOCK, &just_SIGRTMIN, nullptr));
+
+  // Raise SIGRTMIN.
+  sigval_t sigval = {.sival_int = 1};
+  ASSERT_EQ(0, sigqueue(getpid(), SIGRTMIN, sigval));
+
+  // Get pending SIGRTMIN.
+  int sig;
+  ASSERT_EQ(0, sigwait64(&just_SIGRTMIN, &sig));
+  ASSERT_EQ(SIGRTMIN, sig);
+}
+
 TEST(signal, sigwaitinfo) {
   SignalMaskRestorer smr;
 
@@ -674,8 +671,7 @@
   ASSERT_EQ(0, sigprocmask(SIG_BLOCK, &just_SIGALRM, nullptr));
 
   // Raise SIGALRM.
-  sigval_t sigval;
-  sigval.sival_int = 1;
+  sigval_t sigval = {.sival_int = 1};
   ASSERT_EQ(0, sigqueue(getpid(), SIGALRM, sigval));
 
   // Get pending SIGALRM.
@@ -697,8 +693,7 @@
   ASSERT_EQ(0, sigprocmask64(SIG_BLOCK, &just_SIGRTMIN, nullptr));
 
   // Raise SIGRTMIN.
-  sigval_t sigval;
-  sigval.sival_int = 1;
+  sigval_t sigval = {.sival_int = 1};
   ASSERT_EQ(0, sigqueue(getpid(), SIGRTMIN, sigval));
 
   // Get pending SIGRTMIN.
diff --git a/tests/spawn_test.cpp b/tests/spawn_test.cpp
index 04b66d3..d7ed970 100644
--- a/tests/spawn_test.cpp
+++ b/tests/spawn_test.cpp
@@ -31,6 +31,8 @@
 # if !defined(POSIX_SPAWN_SETSID)
 #  define POSIX_SPAWN_SETSID 0
 # endif
+#else
+#include <platform/bionic/reserved_signals.h>
 #endif
 
 TEST(spawn, posix_spawnattr_init_posix_spawnattr_destroy) {
@@ -292,7 +294,7 @@
   pid_t sid;
 };
 
-static void GetChildStat(posix_spawnattr_t* sa, ProcStat* ps) {
+static __attribute__((unused)) void GetChildStat(posix_spawnattr_t* sa, ProcStat* ps) {
   std::string content;
   CatFileToString(sa, "/proc/self/stat", &content);
 
@@ -307,7 +309,7 @@
   uint64_t sigign;
 };
 
-static void GetChildStatus(posix_spawnattr_t* sa, ProcStatus* ps) {
+static void __attribute__((unused)) GetChildStatus(posix_spawnattr_t* sa, ProcStatus* ps) {
   std::string content;
   CatFileToString(sa, "/proc/self/status", &content);
 
@@ -377,6 +379,9 @@
 }
 
 TEST(spawn, posix_spawn_POSIX_SPAWN_SETSIGMASK) {
+#if defined(__GLIBC__)
+  GTEST_SKIP() << "glibc doesn't ignore the same signals.";
+#else
   // Block SIGBUS in the parent...
   sigset_t just_SIGBUS;
   sigemptyset(&just_SIGBUS);
@@ -400,15 +405,21 @@
   // TIMER_SIGNAL should also be blocked.
   uint64_t expected_blocked = 0;
   SignalSetAdd(&expected_blocked, SIGALRM);
-  SignalSetAdd(&expected_blocked, __SIGRTMIN + 0);
+  SignalSetAdd(&expected_blocked, BIONIC_SIGNAL_POSIX_TIMERS);
   EXPECT_EQ(expected_blocked, ps.sigblk);
 
-  EXPECT_EQ(static_cast<uint64_t>(0), ps.sigign);
+  uint64_t expected_ignored = 0;
+  SignalSetAdd(&expected_ignored, BIONIC_SIGNAL_ART_PROFILER);
+  EXPECT_EQ(expected_ignored, ps.sigign);
 
   ASSERT_EQ(0, posix_spawnattr_destroy(&sa));
+#endif
 }
 
 TEST(spawn, posix_spawn_POSIX_SPAWN_SETSIGDEF) {
+#if defined(__GLIBC__)
+  GTEST_SKIP() << "glibc doesn't ignore the same signals.";
+#else
   // Ignore SIGALRM and SIGCONT in the parent...
   ASSERT_NE(SIG_ERR, signal(SIGALRM, SIG_IGN));
   ASSERT_NE(SIG_ERR, signal(SIGCONT, SIG_IGN));
@@ -430,14 +441,16 @@
 
   // TIMER_SIGNAL should be blocked.
   uint64_t expected_blocked = 0;
-  SignalSetAdd(&expected_blocked, __SIGRTMIN + 0);
+  SignalSetAdd(&expected_blocked, BIONIC_SIGNAL_POSIX_TIMERS);
   EXPECT_EQ(expected_blocked, ps.sigblk);
 
   uint64_t expected_ignored = 0;
   SignalSetAdd(&expected_ignored, SIGCONT);
+  SignalSetAdd(&expected_ignored, BIONIC_SIGNAL_ART_PROFILER);
   EXPECT_EQ(expected_ignored, ps.sigign);
 
   ASSERT_EQ(0, posix_spawnattr_destroy(&sa));
+#endif
 }
 
 TEST(spawn, signal_stress) {
diff --git a/tests/stdatomic_test.cpp b/tests/stdatomic_test.cpp
index 8a6b267..11d41b4 100644
--- a/tests/stdatomic_test.cpp
+++ b/tests/stdatomic_test.cpp
@@ -181,7 +181,7 @@
 
 // And a rudimentary test of acquire-release memory ordering:
 
-constexpr static uint_least32_t BIG = 10000000ul; // Assumed even below.
+constexpr static uint_least32_t BIG = 30'000'000ul; // Assumed even below.
 
 struct three_atomics {
   atomic_uint_least32_t x;
diff --git a/tests/strings_test.cpp b/tests/strings_test.cpp
index ac327d4..0226d1a 100644
--- a/tests/strings_test.cpp
+++ b/tests/strings_test.cpp
@@ -38,6 +38,48 @@
   ASSERT_EQ(32, ffs(0x80000000));
 }
 
+TEST(STRINGS_TEST, ffsl) {
+  ASSERT_EQ( 0, ffsl(0x00000000L));
+  ASSERT_EQ( 1, ffsl(0x00000001L));
+  ASSERT_EQ( 6, ffsl(0x00000020L));
+  ASSERT_EQ(11, ffsl(0x00000400L));
+  ASSERT_EQ(16, ffsl(0x00008000L));
+  ASSERT_EQ(17, ffsl(0x00010000L));
+  ASSERT_EQ(22, ffsl(0x00200000L));
+  ASSERT_EQ(27, ffsl(0x04000000L));
+  ASSERT_EQ(32, ffsl(0x80000000L));
+#if defined(__LP64__)
+  ASSERT_EQ(33, ffsl(0x0000000100000000L));
+  ASSERT_EQ(38, ffsl(0x0000002000000000L));
+  ASSERT_EQ(43, ffsl(0x0000040000000000L));
+  ASSERT_EQ(48, ffsl(0x0000800000000000L));
+  ASSERT_EQ(49, ffsl(0x0001000000000000L));
+  ASSERT_EQ(54, ffsl(0x0020000000000000L));
+  ASSERT_EQ(59, ffsl(0x0400000000000000L));
+  ASSERT_EQ(64, ffsl(0x8000000000000000L));
+#endif
+}
+
+TEST(STRINGS_TEST, ffsll) {
+  ASSERT_EQ( 0, ffsll(0x0000000000000000LL));
+  ASSERT_EQ( 1, ffsll(0x0000000000000001LL));
+  ASSERT_EQ( 6, ffsll(0x0000000000000020LL));
+  ASSERT_EQ(11, ffsll(0x0000000000000400LL));
+  ASSERT_EQ(16, ffsll(0x0000000000008000LL));
+  ASSERT_EQ(17, ffsll(0x0000000000010000LL));
+  ASSERT_EQ(22, ffsll(0x0000000000200000LL));
+  ASSERT_EQ(27, ffsll(0x0000000004000000LL));
+  ASSERT_EQ(32, ffsll(0x0000000080000000LL));
+  ASSERT_EQ(33, ffsll(0x0000000100000000LL));
+  ASSERT_EQ(38, ffsll(0x0000002000000000LL));
+  ASSERT_EQ(43, ffsll(0x0000040000000000LL));
+  ASSERT_EQ(48, ffsll(0x0000800000000000LL));
+  ASSERT_EQ(49, ffsll(0x0001000000000000LL));
+  ASSERT_EQ(54, ffsll(0x0020000000000000LL));
+  ASSERT_EQ(59, ffsll(0x0400000000000000LL));
+  ASSERT_EQ(64, ffsll(0x8000000000000000LL));
+}
+
 TEST(STRINGS_TEST, strcasecmp) {
   ASSERT_EQ(0, strcasecmp("hello", "HELLO"));
   ASSERT_LT(strcasecmp("hello1", "hello2"), 0);
diff --git a/tests/utils.h b/tests/utils.h
index 5014ef7..5085a7a 100644
--- a/tests/utils.h
+++ b/tests/utils.h
@@ -25,6 +25,8 @@
 #include <sys/wait.h>
 #include <unistd.h>
 
+#include <bionic/macros.h>
+
 #include <atomic>
 #include <string>
 #include <regex>
@@ -66,14 +68,6 @@
 
 #define SKIP_WITH_HWASAN if (running_with_hwasan()) GTEST_SKIP()
 
-static inline void* untag_address(void* addr) {
-#if defined(__LP64__)
-  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>