Lock on dl_interate_phdr

There is possibility of someone dlclosing a library
while dl_iterate_phdr in progress which can lead to
dl_iterate_phdr calling callback with invalid address
if it was unmapped by dlclose.

Bug: http://b/22047255
Change-Id: I3fc0d9fd2c51fb36fd34cb035f37271fa893a7be
diff --git a/linker/dlfcn.cpp b/linker/dlfcn.cpp
index a70abf5..ef454ab 100644
--- a/linker/dlfcn.cpp
+++ b/linker/dlfcn.cpp
@@ -158,6 +158,11 @@
   return 0;
 }
 
+int dl_iterate_phdr(int (*cb)(dl_phdr_info* info, size_t size, void* data), void* data) {
+  ScopedPthreadMutexLocker locker(&g_dl_mutex);
+  return do_dl_iterate_phdr(cb, data);
+}
+
 void android_set_application_target_sdk_version(uint32_t target) {
   // lock to avoid modification in the middle of dlopen.
   ScopedPthreadMutexLocker locker(&g_dl_mutex);
diff --git a/linker/linker.cpp b/linker/linker.cpp
index e1b8ca9..f7b58c4 100644
--- a/linker/linker.cpp
+++ b/linker/linker.cpp
@@ -353,7 +353,7 @@
 
 // Here, we only have to provide a callback to iterate across all the
 // loaded libraries. gcc_eh does the rest.
-int dl_iterate_phdr(int (*cb)(dl_phdr_info* info, size_t size, void* data), void* data) {
+int do_dl_iterate_phdr(int (*cb)(dl_phdr_info* info, size_t size, void* data), void* data) {
   int rv = 0;
   for (soinfo* si = solist; si != nullptr; si = si->next) {
     dl_phdr_info dl_info;
diff --git a/linker/linker.h b/linker/linker.h
index 6042cb8..023b672 100644
--- a/linker/linker.h
+++ b/linker/linker.h
@@ -421,6 +421,8 @@
 soinfo* do_dlopen(const char* name, int flags, const android_dlextinfo* extinfo);
 void do_dlclose(soinfo* si);
 
+int do_dl_iterate_phdr(int (*cb)(dl_phdr_info* info, size_t size, void* data), void* data);
+
 const ElfW(Sym)* dlsym_linear_lookup(const char* name, soinfo** found, soinfo* caller, void* handle);
 soinfo* find_containing_library(const void* addr);