int dlclose(void* handle) { ScopedPthreadMutexLocker locker(&g_dl_mutex); int result = do_dlclose(handle); if (result != 0) { __bionic_format_dlerror("dlclose failed", linker_get_error_buffer()); } return result; }
void* dlsym(void* handle, const char* symbol) { ScopedPthreadMutexLocker locker(&g_dl_mutex); #if !defined(__LP64__) if (handle == NULL) { __bionic_format_dlerror("dlsym library handle is null", NULL); return NULL; } #endif if (symbol == NULL) { __bionic_format_dlerror("dlsym symbol name is null", NULL); return NULL; } soinfo* found = NULL; ElfW(Sym)* sym = NULL; if (handle == RTLD_DEFAULT) { sym = dlsym_linear_lookup(symbol, &found, NULL); } else if (handle == RTLD_NEXT) { void* caller_addr = __builtin_return_address(0); soinfo* si = find_containing_library(caller_addr); sym = NULL; if (si && si->next) { sym = dlsym_linear_lookup(symbol, &found, si->next); } } else { found = reinterpret_cast<soinfo*>(handle); sym = dlsym_handle_lookup(found, symbol); } if (sym != NULL) { unsigned bind = ELF_ST_BIND(sym->st_info); if ((bind == STB_GLOBAL || bind == STB_WEAK) && sym->st_shndx != 0) { return reinterpret_cast<void*>(sym->st_value + found->load_bias); } __bionic_format_dlerror("symbol found but not global", symbol); return NULL; } else { __bionic_format_dlerror("undefined symbol", symbol); return NULL; } }
static void* dlopen_ext(const char* filename, int flags, const android_dlextinfo* extinfo) { ScopedPthreadMutexLocker locker(&g_dl_mutex); soinfo* result = do_dlopen(filename, flags, extinfo); if (result == nullptr) { __bionic_format_dlerror("dlopen failed", linker_get_error_buffer()); return nullptr; } return result; }
void* dlopen(const char* filename, int flags) { ScopedPthreadMutexLocker locker(&gDlMutex); soinfo* result = do_dlopen(filename, flags); if (result == NULL) { __bionic_format_dlerror("dlopen failed", linker_get_error_buffer()); return NULL; } return result; }
void* dlsym(void* handle, const char* symbol) { ScopedPthreadMutexLocker locker(&gDlMutex); if (handle == NULL) { __bionic_format_dlerror("dlsym library handle is null", NULL); return NULL; } if (symbol == NULL) { __bionic_format_dlerror("dlsym symbol name is null", NULL); return NULL; } soinfo* found = NULL; Elf32_Sym* sym = NULL; if (handle == RTLD_DEFAULT) { sym = lookup(symbol, &found, NULL); } else if (handle == RTLD_NEXT) { void* ret_addr = __builtin_return_address(0); soinfo* si = find_containing_library(ret_addr); sym = NULL; if (si && si->next) { sym = lookup(symbol, &found, si->next); } } else { found = (soinfo*) handle; sym = soinfo_lookup(found, symbol); } if (sym != NULL) { unsigned bind = ELF32_ST_BIND(sym->st_info); if (bind == STB_GLOBAL && sym->st_shndx != 0) { unsigned ret = sym->st_value + found->load_bias; return (void*) ret; } __bionic_format_dlerror("symbol found but not global", symbol); return NULL; } else { __bionic_format_dlerror("undefined symbol", symbol); return NULL; } }
bool android_init_namespaces(const char* public_ns_sonames, const char* anon_ns_library_path) { ScopedPthreadMutexLocker locker(&g_dl_mutex); bool success = init_namespaces(public_ns_sonames, anon_ns_library_path); if (!success) { __bionic_format_dlerror("android_init_namespaces failed", linker_get_error_buffer()); } return success; }
static void* dlopen_ext(const char* filename, int flags, const android_dlextinfo* extinfo, const void* caller_addr) { ScopedPthreadMutexLocker locker(&g_dl_mutex); soinfo* caller_soinfo = find_containing_library(caller_addr); soinfo* result = do_dlopen(filename, flags, caller_soinfo, extinfo); if (result == NULL) { __bionic_format_dlerror("dlopen failed", linker_get_error_buffer()); return NULL; } return result; }
void* dlopen(const char* filename, int flag) { ScopedPthreadMutexLocker locker(&gDlMutex); soinfo* result = find_library(filename); if (result == NULL) { __bionic_format_dlerror("dlopen failed", linker_get_error()); return NULL; } soinfo_call_constructors(result); result->refcount++; return result; }
void* dlsym_impl(void* handle, const char* symbol, const char* version, void* caller_addr) { ScopedPthreadMutexLocker locker(&g_dl_mutex); g_linker_logger.ResetState(); void* result; if (!do_dlsym(handle, symbol, version, caller_addr, &result)) { __bionic_format_dlerror(linker_get_error_buffer(), nullptr); return nullptr; } return result; }
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, android_namespace_t* parent_namespace) { void* caller_addr = __builtin_return_address(0); ScopedPthreadMutexLocker locker(&g_dl_mutex); android_namespace_t* result = create_namespace(caller_addr, name, ld_library_path, default_library_path, type, permitted_when_isolated_path, parent_namespace); if (result == nullptr) { __bionic_format_dlerror("android_create_namespace failed", linker_get_error_buffer()); } return result; }