Merge changes Ia359d9f2,Ibabbf559,I1b542e47,I4b6f48af,I82e442f0

* changes:
  Fix bootstrap linker library searching
  Remove dangling soinfo* from elf_readers_map_
  Fix DL_WARN_documented_change URL
  remove search_linked_namespaces param
  Refactor linker lookup code a bit
diff --git a/apex/Android.bp b/apex/Android.bp
index f62f930..f6820d1 100644
--- a/apex/Android.bp
+++ b/apex/Android.bp
@@ -28,7 +28,10 @@
     ],
     multilib: {
         both: {
-            binaries: ["linker"],
+            binaries: [
+                "crash_dump",
+                "linker",
+            ],
         },
     },
     key: "com.android.runtime.key",
diff --git a/libc/Android.bp b/libc/Android.bp
index 49654b3..650726a 100644
--- a/libc/Android.bp
+++ b/libc/Android.bp
@@ -1777,9 +1777,15 @@
     native_bridge_supported: true,
     apex_available: [
         "//apex_available:platform",
-        "com.android.runtime",
-        "com.android.art.debug",
-        "com.android.art.release",
+        "//apex_available:anyapex",
+    ],
+    visibility: [
+        ":__subpackages__", // visible to bionic
+        // ... and only to these places (b/152668052)
+        "//external/gwp_asan",
+        "//external/libunwind_llvm",
+        "//system/core/property_service/libpropertyinfoparser",
+        "//system/extras/toolchain-extras",
     ],
 
     no_libcrt: true,
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/include/dirent.h b/libc/include/dirent.h
index d6819f2..2328b1a 100644
--- a/libc/include/dirent.h
+++ b/libc/include/dirent.h
@@ -26,8 +26,12 @@
  * SUCH DAMAGE.
  */
 
-#ifndef _DIRENT_H_
-#define _DIRENT_H_
+#pragma once
+
+/**
+ * @file dirent.h
+ * @brief Directory entry iteration.
+ */
 
 #include <stdint.h>
 #include <sys/cdefs.h>
@@ -35,17 +39,23 @@
 
 __BEGIN_DECLS
 
-#ifndef DT_UNKNOWN
+/** d_type value when the type is not known. */
 #define DT_UNKNOWN 0
+/** d_type value for a FIFO. */
 #define DT_FIFO 1
+/** d_type value for a character device. */
 #define DT_CHR 2
+/** d_type value for a directory. */
 #define DT_DIR 4
+/** d_type value for a block device. */
 #define DT_BLK 6
+/** d_type value for a regular file. */
 #define DT_REG 8
+/** d_type value for a symbolic link. */
 #define DT_LNK 10
+/** d_type value for a socket. */
 #define DT_SOCK 12
 #define DT_WHT 14
-#endif
 
 #if defined(__LP64__)
 #define __DIRENT64_INO_T ino_t
@@ -60,7 +70,9 @@
     unsigned char d_type; \
     char d_name[256]; \
 
+/** The structure returned by readdir(). Identical to dirent64 on Android. */
 struct dirent { __DIRENT64_BODY };
+/** The structure returned by readdir64(). Identical to dirent on Android. */
 struct dirent64 { __DIRENT64_BODY };
 
 #undef __DIRENT64_BODY
@@ -74,29 +86,158 @@
 
 #define d_fileno d_ino
 
+/** The structure returned by opendir()/fopendir(). */
 typedef struct DIR DIR;
 
+/**
+ * [opendir(3)](http://man7.org/linux/man-pages/man3/opendir.3.html)
+ * opens a directory stream for the directory at `__path`.
+ *
+ * Returns null and sets `errno` on failure.
+ */
 DIR* opendir(const char* __path);
+
+/**
+ * [fopendir(3)](http://man7.org/linux/man-pages/man3/opendir.3.html)
+ * opens a directory stream for the directory at `__dir_fd`.
+ *
+ * Returns null and sets `errno` on failure.
+ */
 DIR* fdopendir(int __dir_fd);
+
+/**
+ * [readdir(3)](http://man7.org/linux/man-pages/man3/readdir.3.html)
+ * returns the next directory entry in the given directory.
+ *
+ * Returns a pointer to a directory entry on success,
+ * or returns null and leaves `errno` unchanged at the end of the directory,
+ * or returns null and sets `errno` on failure.
+ */
 struct dirent* readdir(DIR* __dir);
+
+/**
+ * [readdir64(3)](http://man7.org/linux/man-pages/man3/readdir.3.html)
+ * returns the next directory entry in the given directory.
+ *
+ * Returns a pointer to a directory entry on success,
+ * or returns null and leaves `errno` unchanged at the end of the directory,
+ * or returns null and sets `errno` on failure.
+ */
 struct dirent64* readdir64(DIR* __dir) __INTRODUCED_IN(21);
+
 int readdir_r(DIR* __dir, struct dirent* __entry, struct dirent** __buffer) __attribute__((__deprecated__("readdir_r is deprecated; use readdir instead")));
 int readdir64_r(DIR* __dir, struct dirent64* __entry, struct dirent64** __buffer) __INTRODUCED_IN(21) __attribute__((__deprecated__("readdir64_r is deprecated; use readdir64 instead")));
+
+/**
+ * [closedir(3)](http://man7.org/linux/man-pages/man3/closedir.3.html)
+ * closes a directory stream.
+ *
+ * Returns 0 on success and returns -1 and sets `errno` on failure.
+ */
 int closedir(DIR* __dir);
+
+/**
+ * [rewinddir(3)](http://man7.org/linux/man-pages/man3/rewinddir.3.html)
+ * rewinds a directory stream to the first entry.
+ */
 void rewinddir(DIR* __dir);
+
+/**
+ * [seekdir(3)](http://man7.org/linux/man-pages/man3/seekdir.3.html)
+ * seeks a directory stream to the given entry, which must be a value returned
+ * by telldir().
+ *
+ * Available since API level 23.
+ */
 void seekdir(DIR* __dir, long __location) __INTRODUCED_IN(23);
+
+/**
+ * [telldir(3)](http://man7.org/linux/man-pages/man3/telldir.3.html)
+ * returns a value representing the current position in the directory
+ * for use with seekdir().
+ *
+ * Returns the current position on success and returns -1 and sets `errno` on failure.
+ *
+ * Available since API level 23.
+ */
 long telldir(DIR* __dir) __INTRODUCED_IN(23);
+
+/**
+ * [dirfd(3)](http://man7.org/linux/man-pages/man3/dirfd.3.html)
+ * returns the file descriptor backing the given directory stream.
+ *
+ * Returns a file descriptor on success and returns -1 and sets `errno` on failure.
+ */
 int dirfd(DIR* __dir);
+
+/**
+ * [alphasort](http://man7.org/linux/man-pages/man3/alphasort.3.html) is a
+ * comparator for use with scandir() that uses strcoll().
+ */
 int alphasort(const struct dirent** __lhs, const struct dirent** __rhs);
+
+/**
+ * [alphasort64](http://man7.org/linux/man-pages/man3/alphasort.3.html) is a
+ * comparator for use with scandir64() that uses strcmp().
+ *
+ * Available since API level 21.
+ */
 int alphasort64(const struct dirent64** __lhs, const struct dirent64** __rhs) __INTRODUCED_IN(21);
-int scandir64(const char* __path, struct dirent64*** __name_list, int (*__filter)(const struct dirent64*), int (*__comparator)(const struct dirent64**, const struct dirent64**)) __INTRODUCED_IN(21);
+
+/**
+ * [scandir(3)](http://man7.org/linux/man-pages/man3/scandir.3.html)
+ * scans all the directory `__path`, filtering entries with `__filter` and
+ * sorting them with qsort() using the given `__comparator`, and storing them
+ * into `__name_list`. Passing NULL as the filter accepts all entries.
+ *
+ * Returns the number of entries returned in the list on success,
+ * and returns -1 and sets `errno` on failure.
+ */
 int scandir(const char* __path, struct dirent*** __name_list, int (*__filter)(const struct dirent*), int (*__comparator)(const struct dirent**, const struct dirent**));
 
+/**
+ * [scandir64(3)](http://man7.org/linux/man-pages/man3/scandir.3.html)
+ * scans all the directory `__path`, filtering entries with `__filter` and
+ * sorting them with qsort() using the given `__comparator`, and storing them
+ * into `__name_list`. Passing NULL as the filter accepts all entries.
+ *
+ * Returns the number of entries returned in the list on success,
+ * and returns -1 and sets `errno` on failure.
+ *
+ * Available since API level 21.
+ */
+int scandir64(const char* __path, struct dirent64*** __name_list, int (*__filter)(const struct dirent64*), int (*__comparator)(const struct dirent64**, const struct dirent64**)) __INTRODUCED_IN(21);
+
 #if defined(__USE_GNU)
+
+/**
+ * [scandirat64(3)](http://man7.org/linux/man-pages/man3/scandirat.3.html)
+ * scans all the directory referenced by the pair of `__dir_fd` and `__path`,
+ * filtering entries with `__filter` and sorting them with qsort() using the
+ * given `__comparator`, and storing them into `__name_list`. Passing NULL as
+ * the filter accepts all entries.
+ *
+ * Returns the number of entries returned in the list on success,
+ * and returns -1 and sets `errno` on failure.
+ *
+ * Available since API level 24.
+ */
 int scandirat64(int __dir_fd, const char* __path, struct dirent64*** __name_list, int (*__filter)(const struct dirent64*), int (*__comparator)(const struct dirent64**, const struct dirent64**)) __INTRODUCED_IN(24);
+
+/**
+ * [scandirat(3)](http://man7.org/linux/man-pages/man3/scandirat.3.html)
+ * scans all the directory referenced by the pair of `__dir_fd` and `__path`,
+ * filtering entries with `__filter` and sorting them with qsort() using the
+ * given `__comparator`, and storing them into `__name_list`. Passing NULL as
+ * the filter accepts all entries.
+ *
+ * Returns the number of entries returned in the list on success,
+ * and returns -1 and sets `errno` on failure.
+ *
+ * Available since API level 24.
+ */
 int scandirat(int __dir_fd, const char* __path, struct dirent*** __name_list, int (*__filter)(const struct dirent*), int (*__comparator)(const struct dirent**, const struct dirent**)) __INTRODUCED_IN(24);
+
 #endif
 
 __END_DECLS
-
-#endif
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/linker/linker_debuggerd_android.cpp b/linker/linker_debuggerd_android.cpp
index 42ea2b7..6a81673 100644
--- a/linker/linker_debuggerd_android.cpp
+++ b/linker/linker_debuggerd_android.cpp
@@ -33,18 +33,25 @@
 
 #include "linker_gdb_support.h"
 
+#if defined(__ANDROID_APEX__)
+static debugger_process_info get_process_info() {
+  return {
+      .abort_msg = __libc_shared_globals()->abort_msg,
+      .fdsan_table = &__libc_shared_globals()->fd_table,
+      .gwp_asan_state = __libc_shared_globals()->gwp_asan_state,
+      .gwp_asan_metadata = __libc_shared_globals()->gwp_asan_metadata,
+  };
+}
+#endif
+
 void linker_debuggerd_init() {
+  // There may be a version mismatch between the bootstrap linker and the crash_dump in the APEX,
+  // so don't pass in any process info from the bootstrap linker.
   debuggerd_callbacks_t callbacks = {
-    .get_abort_message = []() {
-      return __libc_shared_globals()->abort_msg;
-    },
-    .post_dump = &notify_gdb_of_libraries,
-    .get_gwp_asan_state = []() {
-      return __libc_shared_globals()->gwp_asan_state;
-    },
-    .get_gwp_asan_metadata = []() {
-      return __libc_shared_globals()->gwp_asan_metadata;
-    },
+#if defined(__ANDROID_APEX__)
+      .get_process_info = get_process_info,
+#endif
+      .post_dump = notify_gdb_of_libraries,
   };
   debuggerd_init(&callbacks);
 }
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/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) {