void
*
do_dlopen(const char
*
name,
int
flags,
2064
const android_dlextinfo
*
extinfo,
2065
const void
*
caller_addr) {
2066
std::string trace_prefix
=
std::string(
"dlopen: "
)
+
(name
=
=
nullptr ?
"(nullptr)"
: name);
2067
ScopedTrace trace(trace_prefix.c_str());
2068
ScopedTrace loading_trace((trace_prefix
+
" - loading and linking"
).c_str());
2069
soinfo
*
const caller
=
find_containing_library(caller_addr);
2070
android_namespace_t
*
ns
=
get_caller_namespace(caller);
2071
2072
LD_LOG(kLogDlopen,
2073
"dlopen(name=\"%s\", flags=0x%x, extinfo=%s, caller=\"%s\", caller_ns=%s@%p, targetSdkVersion=%i) ..."
,
2074
name,
2075
flags,
2076
android_dlextinfo_to_string(extinfo).c_str(),
2077
caller
=
=
nullptr ?
"(null)"
: caller
-
>get_realpath(),
2078
ns
=
=
nullptr ?
"(null)"
: ns
-
>get_name(),
2079
ns,
2080
get_application_target_sdk_version());
2081
2082
auto purge_guard
=
android::base::make_scope_guard([&]() { purge_unused_memory(); });
2083
2084
auto failure_guard
=
android::base::make_scope_guard(
2085
[&]() { LD_LOG(kLogDlopen,
"... dlopen failed: %s"
, linker_get_error_buffer()); });
2086
2087
if
((flags & ~(RTLD_NOW|RTLD_LAZY|RTLD_LOCAL|RTLD_GLOBAL|RTLD_NODELETE|RTLD_NOLOAD)) !
=
0
) {
2088
DL_OPEN_ERR(
"invalid flags to dlopen: %x"
, flags);
2089
return
nullptr;
2090
}
2091
2092
if
(extinfo !
=
nullptr) {
2093
if
((extinfo
-
>flags & ~(ANDROID_DLEXT_VALID_FLAG_BITS)) !
=
0
) {
2094
DL_OPEN_ERR(
"invalid extended flags to android_dlopen_ext: 0x%"
PRIx64, extinfo
-
>flags);
2095
return
nullptr;
2096
}
2097
2098
if
((extinfo
-
>flags & ANDROID_DLEXT_USE_LIBRARY_FD)
=
=
0
&&
2099
(extinfo
-
>flags & ANDROID_DLEXT_USE_LIBRARY_FD_OFFSET) !
=
0
) {
2100
DL_OPEN_ERR(
"invalid extended flag combination (ANDROID_DLEXT_USE_LIBRARY_FD_OFFSET without "
2101
"ANDROID_DLEXT_USE_LIBRARY_FD): 0x%"
PRIx64, extinfo
-
>flags);
2102
return
nullptr;
2103
}
2104
2105
if
((extinfo
-
>flags & ANDROID_DLEXT_USE_NAMESPACE) !
=
0
) {
2106
if
(extinfo
-
>library_namespace
=
=
nullptr) {
2107
DL_OPEN_ERR(
"ANDROID_DLEXT_USE_NAMESPACE is set but extinfo->library_namespace is null"
);
2108
return
nullptr;
2109
}
2110
ns
=
extinfo
-
>library_namespace;
2111
}
2112
}
2113
2114
/
/
Workaround
for
dlopen(
/
system
/
lib
/
<soname>) when .so
is
in
/
apex. http:
/
/
b
/
121248172
2115
/
/
The workaround works only when targetSdkVersion < Q.
2116
std::string name_to_apex;
2117
if
(translateSystemPathToApexPath(name, &name_to_apex)) {
2118
const char
*
new_name
=
name_to_apex.c_str();
2119
LD_LOG(kLogDlopen,
"dlopen considering translation from %s to APEX path %s"
,
2120
name,
2121
new_name);
2122
/
/
Some APEXs could be optionally disabled. Only translate the path
2123
/
/
when the old
file
is
absent
and
the new
file
exists.
2124
/
/
TODO(b
/
124218500
): Re
-
enable it once app compat issue
is
resolved
2125
/
*
2126
if
(file_exists(name)) {
2127
LD_LOG(kLogDlopen,
"dlopen %s exists, not translating"
, name);
2128
}
else
2129
*
/
2130
if
(!file_exists(new_name)) {
2131
LD_LOG(kLogDlopen,
"dlopen %s does not exist, not translating"
,
2132
new_name);
2133
}
else
{
2134
LD_LOG(kLogDlopen,
"dlopen translation accepted: using %s"
, new_name);
2135
name
=
new_name;
2136
}
2137
}
2138
/
/
End Workaround
for
dlopen(
/
system
/
lib
/
<soname>) when .so
is
in
/
apex.
2139
2140
std::string asan_name_holder;
2141
2142
const char
*
translated_name
=
name;
2143
if
(g_is_asan && translated_name !
=
nullptr && translated_name[
0
]
=
=
'/'
) {
2144
char original_path[PATH_MAX];
2145
if
(realpath(name, original_path) !
=
nullptr) {
2146
asan_name_holder
=
std::string(kAsanLibDirPrefix)
+
original_path;
2147
if
(file_exists(asan_name_holder.c_str())) {
2148
soinfo
*
si
=
nullptr;
2149
if
(find_loaded_library_by_realpath(ns, original_path, true, &si)) {
2150
PRINT
(
"linker_asan dlopen NOT translating \"%s\" -> \"%s\": library already loaded"
, name,
2151
asan_name_holder.c_str());
2152
}
else
{
2153
PRINT
(
"linker_asan dlopen translating \"%s\" -> \"%s\""
, name, translated_name);
2154
translated_name
=
asan_name_holder.c_str();
2155
}
2156
}
2157
}
2158
}
2159
2160
ProtectedDataGuard guard;
2161
soinfo
*
si
=
find_library(ns, translated_name, flags, extinfo, caller);
2162
loading_trace.End();
2163
2164
if
(si !
=
nullptr) {
2165
void
*
handle
=
si
-
>to_handle();
2166
LD_LOG(kLogDlopen,
2167
"... dlopen calling constructors: realpath=\"%s\", soname=\"%s\", handle=%p"
,
2168
si
-
>get_realpath(), si
-
>get_soname(), handle);
2169
si
-
>call_constructors();
2170
failure_guard.Disable();
2171
LD_LOG(kLogDlopen,
2172
"... dlopen successful: realpath=\"%s\", soname=\"%s\", handle=%p"
,
2173
si
-
>get_realpath(), si
-
>get_soname(), handle);
2174
return
handle;
2175
}
2176
2177
return
nullptr;
2178
}