1 2 3 4 5 6 7 8 9 10 11 12 13 14 15 16 17 18 19 20 21 22 23 24 25 26 27 28 29 30 31 32 33 34 35 36 37 38 39 40 41 42 43 44 45 46 47 48 49 50 51 52 53 54 55 56 57 58 59 60 61 62 63 64 65 66 67 68 69 70 71 72 73 74 75 76 77 78 79 80 81 82 83 84 85 86 87 88 89 90 91 92 93 94
| void* do_dlopen(const char* name, int flags, const android_dlextinfo* extinfo, const void* caller_addr) { std::string trace_prefix = std::string("dlopen: ") + (name == nullptr ? "(nullptr)" : name); ScopedTrace trace(trace_prefix.c_str()); ScopedTrace loading_trace((trace_prefix + " - loading and linking").c_str()); soinfo* const caller = find_containing_library(caller_addr); android_namespace_t* ns = get_caller_namespace(caller);
LD_LOG(kLogDlopen, "dlopen(name=\"%s\", flags=0x%x, extinfo=%s, caller=\"%s\", caller_ns=%s@%p) ...",9 name, flags, android_dlextinfo_to_string(extinfo).c_str(), caller == nullptr ? "(null)" : caller->get_realpath(), ns == nullptr ? "(null)" : ns->get_name(), ns);
auto failure_guard = android::base::make_scope_guard( [&]() { LD_LOG(kLogDlopen, "... dlopen failed: %s", linker_get_error_buffer()); });
if ((flags & ~(RTLD_NOW|RTLD_LAZY|RTLD_LOCAL|RTLD_GLOBAL|RTLD_NODELETE|RTLD_NOLOAD)) != 0) { DL_ERR("invalid flags to dlopen: %x", flags); return nullptr; }
if (extinfo != nullptr) { if ((extinfo->flags & ~(ANDROID_DLEXT_VALID_FLAG_BITS)) != 0) { DL_ERR("invalid extended flags to android_dlopen_ext: 0x%" PRIx64, extinfo->flags); return nullptr; }
if ((extinfo->flags & ANDROID_DLEXT_USE_LIBRARY_FD) == 0 && (extinfo->flags & ANDROID_DLEXT_USE_LIBRARY_FD_OFFSET) != 0) { DL_ERR("invalid extended flag combination (ANDROID_DLEXT_USE_LIBRARY_FD_OFFSET without " "ANDROID_DLEXT_USE_LIBRARY_FD): 0x%" PRIx64, extinfo->flags); return nullptr; }
if ((extinfo->flags & ANDROID_DLEXT_LOAD_AT_FIXED_ADDRESS) != 0 && (extinfo->flags & (ANDROID_DLEXT_RESERVED_ADDRESS | ANDROID_DLEXT_RESERVED_ADDRESS_HINT)) != 0) { DL_ERR("invalid extended flag combination: ANDROID_DLEXT_LOAD_AT_FIXED_ADDRESS is not " "compatible with ANDROID_DLEXT_RESERVED_ADDRESS/ANDROID_DLEXT_RESERVED_ADDRESS_HINT"); return nullptr; }
if ((extinfo->flags & ANDROID_DLEXT_USE_NAMESPACE) != 0) { if (extinfo->library_namespace == nullptr) { DL_ERR("ANDROID_DLEXT_USE_NAMESPACE is set but extinfo->library_namespace is null"); return nullptr; } ns = extinfo->library_namespace; } }
std::string asan_name_holder;
const char* translated_name = name; if (g_is_asan && translated_name != nullptr && translated_name[0] == '/') { char original_path[PATH_MAX]; if (realpath(name, original_path) != nullptr) { asan_name_holder = std::string(kAsanLibDirPrefix) + original_path; if (file_exists(asan_name_holder.c_str())) { soinfo* si = nullptr; if (find_loaded_library_by_realpath(ns, original_path, true, &si)) { PRINT("linker_asan dlopen NOT translating \"%s\" -> \"%s\": library already loaded", name, asan_name_holder.c_str()); } else { PRINT("linker_asan dlopen translating \"%s\" -> \"%s\"", name, translated_name); translated_name = asan_name_holder.c_str(); } } } }
ProtectedDataGuard guard; soinfo* si = find_library(ns, translated_name, flags, extinfo, caller); loading_trace.End();
if (si != nullptr) { void* handle = si->to_handle(); LD_LOG(kLogDlopen, "... dlopen calling constructors: realpath=\"%s\", soname=\"%s\", handle=%p", si->get_realpath(), si->get_soname(), handle); si->call_constructors(); failure_guard.Disable(); LD_LOG(kLogDlopen, "... dlopen successful: realpath=\"%s\", soname=\"%s\", handle=%p", si->get_realpath(), si->get_soname(), handle); return handle; }
return nullptr; }
|