Add bootstrap directory to bootstrap linker's search path.

A proposed set of changes:
https://android-review.googlesource.com/q/topic:"no-dup-hwasans"

will cause the HWASAN runtime to be moved from /system/lib64 to
/system/lib64/bootstrap. This causes a problem in the case where libc is built
with HWASAN but init is not built with HWASAN. In this case, libc.so will have
a DT_NEEDED dependency on the HWASAN runtime but init will not. Currently,
init and other bootstrap executables arrange to load bootstrap libraries by
setting rpath, but rpath only has an effect on libraries directly depended
on by the main executable, not libraries indirectly depended on by it. This
means that the loading of the HWASAN runtime will fail.

Instead of relying on rpath to find the bootstrap libraries, modify the
bootstrap linker so that it searches the bootstrap library directory after
searching the rpath.

Bug: http://b/134503977
Test: Builds

Change-Id: I297be32e04ecd316ee12b8e694588e1249e2bb89
Merged-In: I297be32e04ecd316ee12b8e694588e1249e2bb89
(cherry picked from commit ea11be0cc85cb5355ca7ed4ee8736ea52b72e38d)
diff --git a/linker/linker.cpp b/linker/linker.cpp
index b59df73..324f3ef 100644
--- a/linker/linker.cpp
+++ b/linker/linker.cpp
@@ -1162,6 +1162,13 @@
     }
   }
 
+#if !defined(__ANDROID_APEX__)
+  if (fd == -1) {
+    std::vector<std::string> bootstrap_paths = { std::string(kSystemLibDir) + "/bootstrap" };
+    fd = open_library_on_paths(zip_archive_cache, name, file_offset, bootstrap_paths, realpath);
+  }
+#endif
+
   if (fd == -1) {
     fd = open_library_on_paths(zip_archive_cache, name, file_offset, ns->get_default_library_paths(), realpath);
   }
diff --git a/tests/dlfcn_test.cpp b/tests/dlfcn_test.cpp
index f3be988..7ff553d 100644
--- a/tests/dlfcn_test.cpp
+++ b/tests/dlfcn_test.cpp
@@ -999,6 +999,7 @@
 #error "Unknown architecture"
 #endif
 #define PATH_TO_LIBC PATH_TO_SYSTEM_LIB "libc.so"
+#define PATH_TO_BOOTSTRAP_LIBC PATH_TO_SYSTEM_LIB "bootstrap/libc.so"
 #define ALTERNATE_PATH_TO_LIBC ALTERNATE_PATH_TO_SYSTEM_LIB "libc.so"
 
 TEST(dlfcn, dladdr_libc) {
@@ -1018,6 +1019,9 @@
               sizeof(ALTERNATE_PATH_TO_SYSTEM_LIB) - 1) == 0) {
     // Platform with emulated architecture.  Symlink on ARC++.
     ASSERT_TRUE(realpath(ALTERNATE_PATH_TO_LIBC, libc_realpath) == libc_realpath);
+  } else if (strncmp(PATH_TO_BOOTSTRAP_LIBC, info.dli_fname,
+                     sizeof(PATH_TO_BOOTSTRAP_LIBC) - 1) == 0) {
+    ASSERT_TRUE(realpath(PATH_TO_BOOTSTRAP_LIBC, libc_realpath) == libc_realpath);
   } else {
     // /system/lib is symlink when this test is executed on host.
     ASSERT_TRUE(realpath(PATH_TO_LIBC, libc_realpath) == libc_realpath);