Move dlsym and dladdr implementation to linker.cpp
Bug: http://b/25716705
Bug: http://b/22865643
Change-Id: If22fc1eda219f676b5fcc06490f7901d21d1749c
diff --git a/linker/dlfcn.cpp b/linker/dlfcn.cpp
index fde9f5c..788a7a0 100644
--- a/linker/dlfcn.cpp
+++ b/linker/dlfcn.cpp
@@ -16,12 +16,10 @@
#include "linker.h"
-#include <dlfcn.h>
#include <pthread.h>
#include <stdio.h>
#include <stdlib.h>
#include <string.h>
-#include <android/dlext.h>
#include <android/api-level.h>
#include <bionic/pthread_internal.h>
@@ -70,8 +68,7 @@
static void* dlopen_ext(const char* filename, int flags,
const android_dlextinfo* extinfo, void* caller_addr) {
ScopedPthreadMutexLocker locker(&g_dl_mutex);
- soinfo* caller = find_containing_library(caller_addr);
- soinfo* result = do_dlopen(filename, flags, extinfo, caller);
+ soinfo* result = do_dlopen(filename, flags, extinfo, caller_addr);
if (result == nullptr) {
__bionic_format_dlerror("dlopen failed", linker_get_error_buffer());
return nullptr;
@@ -92,71 +89,20 @@
extern android_namespace_t* g_anonymous_namespace;
void* dlsym(void* handle, const char* symbol) {
- ScopedPthreadMutexLocker locker(&g_dl_mutex);
-
- // TODO(dimitry): move (most of) the code below to linker.cpp
-#if !defined(__LP64__)
- if (handle == nullptr) {
- __bionic_format_dlerror("dlsym library handle is null", nullptr);
- return nullptr;
- }
-#endif
-
- if (symbol == nullptr) {
- __bionic_format_dlerror("dlsym symbol name is null", nullptr);
- return nullptr;
- }
-
- soinfo* found = nullptr;
- const ElfW(Sym)* sym = nullptr;
void* caller_addr = __builtin_return_address(0);
- soinfo* caller = find_containing_library(caller_addr);
- android_namespace_t* ns = caller != nullptr ? caller->get_namespace() : g_anonymous_namespace;
-
- if (handle == RTLD_DEFAULT || handle == RTLD_NEXT) {
- sym = dlsym_linear_lookup(ns, symbol, &found, caller, handle);
- } else {
- sym = dlsym_handle_lookup(reinterpret_cast<soinfo*>(handle), &found, symbol);
- }
-
- if (sym != nullptr) {
- unsigned bind = ELF_ST_BIND(sym->st_info);
-
- if ((bind == STB_GLOBAL || bind == STB_WEAK) && sym->st_shndx != 0) {
- return reinterpret_cast<void*>(found->resolve_symbol_address(sym));
- }
-
- __bionic_format_dlerror("symbol found but not global", symbol);
- return nullptr;
- } else {
- __bionic_format_dlerror("undefined symbol", symbol);
+ ScopedPthreadMutexLocker locker(&g_dl_mutex);
+ void* result;
+ if (!do_dlsym(handle, symbol, nullptr, caller_addr, &result)) {
+ __bionic_format_dlerror(linker_get_error_buffer(), nullptr);
return nullptr;
}
+
+ return result;
}
int dladdr(const void* addr, Dl_info* info) {
ScopedPthreadMutexLocker locker(&g_dl_mutex);
-
- // Determine if this address can be found in any library currently mapped.
- soinfo* si = find_containing_library(addr);
- if (si == nullptr) {
- return 0;
- }
-
- memset(info, 0, sizeof(Dl_info));
-
- info->dli_fname = si->get_realpath();
- // Address at which the shared object is loaded.
- info->dli_fbase = reinterpret_cast<void*>(si->base);
-
- // Determine if any symbol in the library contains the specified address.
- ElfW(Sym)* sym = si->find_symbol_by_address(addr);
- if (sym != nullptr) {
- info->dli_sname = si->get_string(sym->st_name);
- info->dli_saddr = reinterpret_cast<void*>(si->resolve_symbol_address(sym));
- }
-
- return 1;
+ return do_dladdr(addr, info);
}
int dlclose(void* handle) {