A special linker for ASan executables.
Setup a /system/bin/linker_asan as a symlink to "linker".
Read the linker name from PT_INTERP, and if it is linker_asan,
switch default library lookup paths to the ASan set, which
starts with the path to the instrumented libraries
(/data/lib), followed by /system/lib as a fallback.
This ensures that ASan binaries prefer ASan libraries, when
available. This approach is way better then RPATH/RUNPATH and even
better than LD_LIBRARY_PATH:
- RUNPATH is per-DSO, while default paths are global.
- LD_LIBRARY_PATH is overwritten by android_update_LD_LIBRARY_PATH.
- neither RUNPATH nor LD_LIBRARY_PATH appear in
android_get_LD_LIBRARY_PATH which is used to build java.lang.path.
Having ASan libraries in java.lang.path is a good thing.
Bug: 22355945
Change-Id: I1d2791fbf5740618f18f71a3ae3d873714669d3f
diff --git a/linker/linker_phdr.cpp b/linker/linker_phdr.cpp
index 30118e3..cf012f4 100644
--- a/linker/linker_phdr.cpp
+++ b/linker/linker_phdr.cpp
@@ -771,6 +771,26 @@
}
}
+/* Return the program interpreter string, or nullptr if missing.
+ *
+ * Input:
+ * phdr_table -> program header table
+ * phdr_count -> number of entries in tables
+ * load_bias -> load bias
+ * Return:
+ * pointer to the program interpreter string.
+ */
+const char* phdr_table_get_interpreter_name(const ElfW(Phdr) * phdr_table, size_t phdr_count,
+ ElfW(Addr) load_bias) {
+ for (size_t i = 0; i<phdr_count; ++i) {
+ const ElfW(Phdr)& phdr = phdr_table[i];
+ if (phdr.p_type == PT_INTERP) {
+ return reinterpret_cast<const char*>(load_bias + phdr.p_vaddr);
+ }
+ }
+ return nullptr;
+}
+
// Sets loaded_phdr_ to the address of the program header table as it appears
// in the loaded segments in memory. This is in contrast with phdr_table_,
// which is temporary and will be released before the library is relocated.