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.

Change-Id: I297be32e04ecd316ee12b8e694588e1249e2bb89
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 c6d7ddb..d815dba 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);