Bionic loader is no longer hijacking libdl.so

Do not hijack libdl.so methods but make libdl proxy calls to
loader instead. This will be replaces by calls to libc.so
once loader functionality is migrated.

Also add a lock to dl_unwind_find_exidx function call.

Test: bionic-unit-tests --gtest_filter=dl*:Dl*
Bug: http://b/27106625
Change-Id: I9e666e771e4bbca52151cfa7fc4c8677e1480818
diff --git a/libdl/libdl.c b/libdl/libdl.c
index 4cc4dea..8329468 100644
--- a/libdl/libdl.c
+++ b/libdl/libdl.c
@@ -20,54 +20,148 @@
 #include <stdbool.h>
 #include <android/dlext.h>
 
-// These are stubs for functions that are actually defined
-// in the dynamic linker and hijacked at runtime.
+// These functions are exported by the loader
+// TODO(dimitry): replace these with reference to libc.so
 
-void* dlopen(const char* filename __unused, int flag __unused) { return 0; }
+__attribute__((__weak__, visibility("default")))
+void* __loader_dlopen(const char* filename, int flags, const void* caller_addr);
 
-char* dlerror(void) { return 0; }
+__attribute__((__weak__, visibility("default")))
+void* __loader_dlerror();
 
-void* dlsym(void* handle __unused, const char* symbol __unused) { return 0; }
+__attribute__((__weak__, visibility("default")))
+void* __loader_dlsym(void* handle, const char* symbol, const void* caller_addr);
 
-void* dlvsym(void* handle __unused, const char* symbol __unused, const char* version __unused) {
-  return 0;
-}
+__attribute__((__weak__, visibility("default")))
+void* __loader_dlvsym(void* handle,
+                      const char* symbol,
+                      const char* version,
+                      const void* caller_addr);
 
-int dladdr(const void* addr __unused, Dl_info* info __unused) { return 0; }
+__attribute__((__weak__, visibility("default")))
+int __loader_dladdr(const void* addr, Dl_info* info);
 
-int dlclose(void* handle __unused) { return 0; }
+__attribute__((__weak__, visibility("default")))
+int __loader_dlclose(void* handle);
 
 #if defined(__arm__)
-_Unwind_Ptr dl_unwind_find_exidx(_Unwind_Ptr pc __unused, int* pcount __unused) { return 0; }
+__attribute__((__weak__, visibility("default")))
+_Unwind_Ptr __loader_dl_unwind_find_exidx(_Unwind_Ptr pc, int* pcount);
 #endif
 
-int dl_iterate_phdr(int (*cb)(struct dl_phdr_info* info, size_t size, void* data) __unused,
-                    void* data __unused) {
-  return 0;
+__attribute__((__weak__, visibility("default")))
+int __loader_dl_iterate_phdr(int (*cb)(struct dl_phdr_info* info, size_t size, void* data),
+                             void* data);
+
+__attribute__((__weak__, visibility("default")))
+void __loader_android_get_LD_LIBRARY_PATH(char* buffer, size_t buffer_size);
+
+__attribute__((__weak__, visibility("default")))
+void __loader_android_update_LD_LIBRARY_PATH(const char* ld_library_path);
+
+__attribute__((__weak__, visibility("default")))
+void* __loader_android_dlopen_ext(const char* filename,
+                                  int flag,
+                                  const android_dlextinfo* extinfo,
+                                  const void* caller_addr);
+
+__attribute__((__weak__, visibility("default")))
+void __loader_android_set_application_target_sdk_version(uint32_t target);
+
+__attribute__((__weak__, visibility("default")))
+uint32_t __loader_android_get_application_target_sdk_version();
+
+__attribute__((__weak__, visibility("default")))
+bool __loader_android_init_namespaces(const char* public_ns_sonames,
+                                      const char* anon_ns_library_path);
+
+__attribute__((__weak__, visibility("default")))
+struct android_namespace_t* __loader_android_create_namespace(
+                                const char* name,
+                                const char* ld_library_path,
+                                const char* default_library_path,
+                                uint64_t type,
+                                const char* permitted_when_isolated_path,
+                                struct android_namespace_t* parent,
+                                const void* caller_addr);
+
+// Proxy calls to bionic loader
+void* dlopen(const char* filename, int flag) {
+  const void* caller_addr = __builtin_return_address(0);
+  return __loader_dlopen(filename, flag, caller_addr);
 }
 
-void android_get_LD_LIBRARY_PATH(char* buffer __unused, size_t buffer_size __unused) { }
-void android_update_LD_LIBRARY_PATH(const char* ld_library_path __unused) { }
-
-void* android_dlopen_ext(const char* filename __unused, int flag __unused,
-                         const android_dlextinfo* extinfo __unused) {
-  return 0;
+char* dlerror() {
+  return __loader_dlerror();
 }
 
-void android_set_application_target_sdk_version(uint32_t target __unused) { }
-uint32_t android_get_application_target_sdk_version() { return 0; }
-
-bool android_init_namespaces(const char* public_ns_sonames __unused,
-                             const char* anon_ns_library_path __unused) {
-  return false;
+void* dlsym(void* handle, const char* symbol) {
+  const void* caller_addr = __builtin_return_address(0);
+  return __loader_dlsym(handle, symbol, caller_addr);
 }
 
-struct android_namespace_t* android_create_namespace(const char* name __unused,
-                                                     const char* ld_library_path __unused,
-                                                     const char* default_library_path __unused,
-                                                     uint64_t type __unused,
-                                                     const char* permitted_when_isolated_path __unused) {
-  return 0;
+void* dlvsym(void* handle, const char* symbol, const char* version) {
+  const void* caller_addr = __builtin_return_address(0);
+  return __loader_dlvsym(handle, symbol, version, caller_addr);
+}
+
+int dladdr(const void* addr, Dl_info* info) {
+  return __loader_dladdr(addr, info);
+}
+
+int dlclose(void* handle) {
+  return __loader_dlclose(handle);
+}
+
+#if defined(__arm__)
+_Unwind_Ptr dl_unwind_find_exidx(_Unwind_Ptr pc, int* pcount) {
+  return __loader_dl_unwind_find_exidx(pc, pcount);
+}
+#endif
+
+int dl_iterate_phdr(int (*cb)(struct dl_phdr_info* info, size_t size, void* data), void* data) {
+  return __loader_dl_iterate_phdr(cb, data);
+}
+
+void android_get_LD_LIBRARY_PATH(char* buffer, size_t buffer_size) {
+  __loader_android_get_LD_LIBRARY_PATH(buffer, buffer_size);
+}
+
+void android_update_LD_LIBRARY_PATH(const char* ld_library_path) {
+  __loader_android_update_LD_LIBRARY_PATH(ld_library_path);
+}
+
+void* android_dlopen_ext(const char* filename, int flag, const android_dlextinfo* extinfo) {
+  const void* caller_addr = __builtin_return_address(0);
+  return __loader_android_dlopen_ext(filename, flag, extinfo, caller_addr);
+}
+
+void android_set_application_target_sdk_version(uint32_t target) {
+  __loader_android_set_application_target_sdk_version(target);
+}
+uint32_t android_get_application_target_sdk_version() {
+  return __loader_android_get_application_target_sdk_version();
+}
+
+bool android_init_namespaces(const char* public_ns_sonames,
+                             const char* anon_ns_library_path) {
+  return __loader_android_init_namespaces(public_ns_sonames, anon_ns_library_path);
+}
+
+struct android_namespace_t* android_create_namespace(const char* name,
+                                                     const char* ld_library_path,
+                                                     const char* default_library_path,
+                                                     uint64_t type,
+                                                     const char* permitted_when_isolated_path,
+                                                     struct android_namespace_t* parent) {
+  const void* caller_addr = __builtin_return_address(0);
+  return __loader_android_create_namespace(name,
+                                           ld_library_path,
+                                           default_library_path,
+                                           type,
+                                           permitted_when_isolated_path,
+                                           parent,
+                                           caller_addr);
 }
 
 void android_dlwarning(void* obj, void (*f)(void*, const char*)) { f(obj, 0); }