int android_dladdr(const void *addr, Dl_info *info) { int ret = 0; pthread_mutex_lock(&dl_lock); /* Determine if this address can be found in any library currently mapped */ soinfo *si = find_containing_library(addr); if(si) { memset(info, 0, sizeof(Dl_info)); info->dli_fname = si->name; info->dli_fbase = (void*)si->base; /* Determine if any symbol in the library contains the specified address */ Elf32_Sym *sym = find_containing_symbol(addr, si); if(sym != NULL) { info->dli_sname = si->strtab + sym->st_name; info->dli_saddr = (void*)(si->base + sym->st_value); } ret = 1; } pthread_mutex_unlock(&dl_lock); return ret; }
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 *__wrap_dlsym(void *handle, const char *symbol) { if (extractLibs) return dlsym(handle, symbol); soinfo *found; Elf32_Sym *sym; unsigned bind; pthread_mutex_lock(&dl_lock); if(unlikely(handle == 0)) { set_dlerror(DL_ERR_INVALID_LIBRARY_HANDLE); goto err; } if(unlikely(symbol == 0)) { set_dlerror(DL_ERR_BAD_SYMBOL_NAME); goto err; } 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 = lookup_in_library(found, symbol); } if(likely(sym != 0)) { bind = ELF32_ST_BIND(sym->st_info); if(likely((bind == STB_GLOBAL) && (sym->st_shndx != 0))) { unsigned ret = sym->st_value + found->base; pthread_mutex_unlock(&dl_lock); return (void*)ret; } set_dlerror(DL_ERR_SYMBOL_NOT_GLOBAL); } else set_dlerror(DL_ERR_SYMBOL_NOT_FOUND); err: pthread_mutex_unlock(&dl_lock); return 0; }
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; } }
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; } }
int dladdr(const void* addr, Dl_info* info) { ScopedPthreadMutexLocker locker(&gDlMutex); // Determine if this address can be found in any library currently mapped. soinfo* si = find_containing_library(addr); if (si == NULL) { return 0; } memset(info, 0, sizeof(Dl_info)); info->dli_fname = si->name; // Address at which the shared object is loaded. info->dli_fbase = (void*) si->base; // Determine if any symbol in the library contains the specified address. Elf32_Sym *sym = soinfo_find_symbol(si, addr); if (sym != NULL) { info->dli_sname = si->strtab + sym->st_name; info->dli_saddr = (void*)(si->load_bias + sym->st_value); } return 1; }
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->name; // 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 = dladdr_find_symbol(si, 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; }
void *android_dlsym(void *handle, const char *symbol) { soinfo *found; Elf32_Sym *sym; unsigned bind; pthread_mutex_lock(&dl_lock); if(unlikely(handle == 0)) { set_dlerror(DL_ERR_INVALID_LIBRARY_HANDLE); goto err; } if(unlikely(symbol == 0)) { set_dlerror(DL_ERR_BAD_SYMBOL_NAME); goto err; } void *sym_addr; if(0 != (sym_addr = get_hooked_symbol_dlfcn(handle, symbol))) { LINKER_DEBUG_PRINTF("symbol %s hooked to %x\n",symbol,sym_addr); pthread_mutex_unlock(&dl_lock); return sym_addr; } if (is_builtin_lib_handle(handle)) { /* must be hooked.. */ set_dlerror(DL_ERR_SYMBOL_NOT_FOUND); goto err; } 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 = lookup_in_library(found, symbol); } if(likely(sym != 0)) { bind = ELF32_ST_BIND(sym->st_info); if(likely((bind == STB_GLOBAL) && (sym->st_shndx != 0))) { unsigned ret = sym->st_value + found->base; pthread_mutex_unlock(&dl_lock); return create_wrapper((char*)symbol, (void*)ret, WRAPPER_DYNHOOK); } set_dlerror(DL_ERR_SYMBOL_NOT_GLOBAL); } else set_dlerror(DL_ERR_SYMBOL_NOT_FOUND); err: LINKER_DEBUG_PRINTF("symbol %s has not been hooked\n",symbol); pthread_mutex_unlock(&dl_lock); return 0; }