1*795d594fSAndroid Build Coastguard Worker /*
2*795d594fSAndroid Build Coastguard Worker * Copyright (C) 2015 The Android Open Source Project
3*795d594fSAndroid Build Coastguard Worker *
4*795d594fSAndroid Build Coastguard Worker * Licensed under the Apache License, Version 2.0 (the "License");
5*795d594fSAndroid Build Coastguard Worker * you may not use this file except in compliance with the License.
6*795d594fSAndroid Build Coastguard Worker * You may obtain a copy of the License at
7*795d594fSAndroid Build Coastguard Worker *
8*795d594fSAndroid Build Coastguard Worker * http://www.apache.org/licenses/LICENSE-2.0
9*795d594fSAndroid Build Coastguard Worker *
10*795d594fSAndroid Build Coastguard Worker * Unless required by applicable law or agreed to in writing, software
11*795d594fSAndroid Build Coastguard Worker * distributed under the License is distributed on an "AS IS" BASIS,
12*795d594fSAndroid Build Coastguard Worker * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
13*795d594fSAndroid Build Coastguard Worker * See the License for the specific language governing permissions and
14*795d594fSAndroid Build Coastguard Worker * limitations under the License.
15*795d594fSAndroid Build Coastguard Worker */
16*795d594fSAndroid Build Coastguard Worker
17*795d594fSAndroid Build Coastguard Worker #define LOG_TAG "nativeloader"
18*795d594fSAndroid Build Coastguard Worker
19*795d594fSAndroid Build Coastguard Worker #include "nativeloader/native_loader.h"
20*795d594fSAndroid Build Coastguard Worker
21*795d594fSAndroid Build Coastguard Worker #include <dlfcn.h>
22*795d594fSAndroid Build Coastguard Worker #include <sys/types.h>
23*795d594fSAndroid Build Coastguard Worker
24*795d594fSAndroid Build Coastguard Worker #include <algorithm>
25*795d594fSAndroid Build Coastguard Worker #include <memory>
26*795d594fSAndroid Build Coastguard Worker #include <mutex>
27*795d594fSAndroid Build Coastguard Worker #include <optional>
28*795d594fSAndroid Build Coastguard Worker #include <regex>
29*795d594fSAndroid Build Coastguard Worker #include <string>
30*795d594fSAndroid Build Coastguard Worker #include <vector>
31*795d594fSAndroid Build Coastguard Worker
32*795d594fSAndroid Build Coastguard Worker #include "android-base/file.h"
33*795d594fSAndroid Build Coastguard Worker #include "android-base/macros.h"
34*795d594fSAndroid Build Coastguard Worker #include <android-base/properties.h>
35*795d594fSAndroid Build Coastguard Worker #include "android-base/strings.h"
36*795d594fSAndroid Build Coastguard Worker #include "android-base/thread_annotations.h"
37*795d594fSAndroid Build Coastguard Worker #include "base/macros.h"
38*795d594fSAndroid Build Coastguard Worker #include "nativebridge/native_bridge.h"
39*795d594fSAndroid Build Coastguard Worker #include "nativehelper/scoped_utf_chars.h"
40*795d594fSAndroid Build Coastguard Worker #include "public_libraries.h"
41*795d594fSAndroid Build Coastguard Worker
42*795d594fSAndroid Build Coastguard Worker #ifdef ART_TARGET_ANDROID
43*795d594fSAndroid Build Coastguard Worker #include "android-modules-utils/sdk_level.h"
44*795d594fSAndroid Build Coastguard Worker #include "android/api-level.h"
45*795d594fSAndroid Build Coastguard Worker #include "library_namespaces.h"
46*795d594fSAndroid Build Coastguard Worker #include "log/log.h"
47*795d594fSAndroid Build Coastguard Worker #include "nativeloader/dlext_namespaces.h"
48*795d594fSAndroid Build Coastguard Worker #endif
49*795d594fSAndroid Build Coastguard Worker
50*795d594fSAndroid Build Coastguard Worker namespace android {
51*795d594fSAndroid Build Coastguard Worker
52*795d594fSAndroid Build Coastguard Worker namespace {
53*795d594fSAndroid Build Coastguard Worker
54*795d594fSAndroid Build Coastguard Worker #if defined(ART_TARGET_ANDROID)
55*795d594fSAndroid Build Coastguard Worker
56*795d594fSAndroid Build Coastguard Worker using ::android::base::Result;
57*795d594fSAndroid Build Coastguard Worker using ::android::nativeloader::LibraryNamespaces;
58*795d594fSAndroid Build Coastguard Worker
59*795d594fSAndroid Build Coastguard Worker // NATIVELOADER_DEFAULT_NAMESPACE_LIBS is an environment variable that can be
60*795d594fSAndroid Build Coastguard Worker // used to list extra libraries (separated by ":") that libnativeloader will
61*795d594fSAndroid Build Coastguard Worker // load from the default namespace. The libraries must be listed without paths,
62*795d594fSAndroid Build Coastguard Worker // and then LD_LIBRARY_PATH is typically set to the directories to load them
63*795d594fSAndroid Build Coastguard Worker // from. The libraries will be available in all classloader namespaces, and also
64*795d594fSAndroid Build Coastguard Worker // in the fallback namespace used when no classloader is given.
65*795d594fSAndroid Build Coastguard Worker //
66*795d594fSAndroid Build Coastguard Worker // kNativeloaderExtraLibs is the name of that fallback namespace.
67*795d594fSAndroid Build Coastguard Worker //
68*795d594fSAndroid Build Coastguard Worker // NATIVELOADER_DEFAULT_NAMESPACE_LIBS is intended to be used for testing only,
69*795d594fSAndroid Build Coastguard Worker // and in particular in the ART run tests that are executed through dalvikvm in
70*795d594fSAndroid Build Coastguard Worker // the APEX. In that case the default namespace links to the ART namespace
71*795d594fSAndroid Build Coastguard Worker // (com_android_art) for all libraries, which means this can be used to load
72*795d594fSAndroid Build Coastguard Worker // test libraries that depend on ART internal libraries.
73*795d594fSAndroid Build Coastguard Worker constexpr const char* kNativeloaderExtraLibs = "nativeloader-extra-libs";
74*795d594fSAndroid Build Coastguard Worker
75*795d594fSAndroid Build Coastguard Worker std::mutex g_namespaces_mutex;
76*795d594fSAndroid Build Coastguard Worker LibraryNamespaces* g_namespaces GUARDED_BY(g_namespaces_mutex) = new LibraryNamespaces;
77*795d594fSAndroid Build Coastguard Worker NativeLoaderNamespace* g_nativeloader_extra_libs_namespace GUARDED_BY(g_namespaces_mutex) = nullptr;
78*795d594fSAndroid Build Coastguard Worker
FindApexNamespace(const char * caller_location)79*795d594fSAndroid Build Coastguard Worker std::optional<NativeLoaderNamespace> FindApexNamespace(const char* caller_location) {
80*795d594fSAndroid Build Coastguard Worker std::optional<std::string> name = nativeloader::FindApexNamespaceName(caller_location);
81*795d594fSAndroid Build Coastguard Worker if (name.has_value()) {
82*795d594fSAndroid Build Coastguard Worker // Native Bridge is never used for APEXes.
83*795d594fSAndroid Build Coastguard Worker Result<NativeLoaderNamespace> ns =
84*795d594fSAndroid Build Coastguard Worker NativeLoaderNamespace::GetExportedNamespace(name.value(), /*is_bridged=*/false);
85*795d594fSAndroid Build Coastguard Worker LOG_ALWAYS_FATAL_IF(!ns.ok(),
86*795d594fSAndroid Build Coastguard Worker "Error finding ns %s for APEX location %s: %s",
87*795d594fSAndroid Build Coastguard Worker name.value().c_str(),
88*795d594fSAndroid Build Coastguard Worker caller_location,
89*795d594fSAndroid Build Coastguard Worker ns.error().message().c_str());
90*795d594fSAndroid Build Coastguard Worker return ns.value();
91*795d594fSAndroid Build Coastguard Worker }
92*795d594fSAndroid Build Coastguard Worker return std::nullopt;
93*795d594fSAndroid Build Coastguard Worker }
94*795d594fSAndroid Build Coastguard Worker
GetNamespaceForApiDomain(nativeloader::ApiDomain api_domain,bool is_bridged)95*795d594fSAndroid Build Coastguard Worker Result<NativeLoaderNamespace> GetNamespaceForApiDomain(nativeloader::ApiDomain api_domain,
96*795d594fSAndroid Build Coastguard Worker bool is_bridged) {
97*795d594fSAndroid Build Coastguard Worker switch (api_domain) {
98*795d594fSAndroid Build Coastguard Worker case nativeloader::API_DOMAIN_VENDOR:
99*795d594fSAndroid Build Coastguard Worker return NativeLoaderNamespace::GetExportedNamespace(nativeloader::kVendorNamespaceName,
100*795d594fSAndroid Build Coastguard Worker is_bridged);
101*795d594fSAndroid Build Coastguard Worker case nativeloader::API_DOMAIN_PRODUCT:
102*795d594fSAndroid Build Coastguard Worker return NativeLoaderNamespace::GetExportedNamespace(nativeloader::kProductNamespaceName,
103*795d594fSAndroid Build Coastguard Worker is_bridged);
104*795d594fSAndroid Build Coastguard Worker case nativeloader::API_DOMAIN_SYSTEM:
105*795d594fSAndroid Build Coastguard Worker return NativeLoaderNamespace::GetSystemNamespace(is_bridged);
106*795d594fSAndroid Build Coastguard Worker default:
107*795d594fSAndroid Build Coastguard Worker LOG_FATAL("Invalid API domain %d", api_domain);
108*795d594fSAndroid Build Coastguard Worker UNREACHABLE();
109*795d594fSAndroid Build Coastguard Worker }
110*795d594fSAndroid Build Coastguard Worker }
111*795d594fSAndroid Build Coastguard Worker
CreateNativeloaderDefaultNamespaceLibsLink(NativeLoaderNamespace & ns)112*795d594fSAndroid Build Coastguard Worker Result<void> CreateNativeloaderDefaultNamespaceLibsLink(NativeLoaderNamespace& ns)
113*795d594fSAndroid Build Coastguard Worker REQUIRES(g_namespaces_mutex) {
114*795d594fSAndroid Build Coastguard Worker const char* links = getenv("NATIVELOADER_DEFAULT_NAMESPACE_LIBS");
115*795d594fSAndroid Build Coastguard Worker if (links == nullptr || *links == 0) {
116*795d594fSAndroid Build Coastguard Worker return {};
117*795d594fSAndroid Build Coastguard Worker }
118*795d594fSAndroid Build Coastguard Worker // Pass nullptr to Link() to create a link to the default namespace without
119*795d594fSAndroid Build Coastguard Worker // requiring it to be visible.
120*795d594fSAndroid Build Coastguard Worker return ns.Link(nullptr, links);
121*795d594fSAndroid Build Coastguard Worker }
122*795d594fSAndroid Build Coastguard Worker
GetNativeloaderExtraLibsNamespace()123*795d594fSAndroid Build Coastguard Worker Result<NativeLoaderNamespace*> GetNativeloaderExtraLibsNamespace() REQUIRES(g_namespaces_mutex) {
124*795d594fSAndroid Build Coastguard Worker if (g_nativeloader_extra_libs_namespace != nullptr) {
125*795d594fSAndroid Build Coastguard Worker return g_nativeloader_extra_libs_namespace;
126*795d594fSAndroid Build Coastguard Worker }
127*795d594fSAndroid Build Coastguard Worker
128*795d594fSAndroid Build Coastguard Worker Result<NativeLoaderNamespace> ns =
129*795d594fSAndroid Build Coastguard Worker NativeLoaderNamespace::Create(kNativeloaderExtraLibs,
130*795d594fSAndroid Build Coastguard Worker /*search_paths=*/"",
131*795d594fSAndroid Build Coastguard Worker /*permitted_paths=*/"",
132*795d594fSAndroid Build Coastguard Worker /*parent=*/nullptr,
133*795d594fSAndroid Build Coastguard Worker /*is_shared=*/false,
134*795d594fSAndroid Build Coastguard Worker /*is_exempt_list_enabled=*/false,
135*795d594fSAndroid Build Coastguard Worker /*also_used_as_anonymous=*/false);
136*795d594fSAndroid Build Coastguard Worker if (!ns.ok()) {
137*795d594fSAndroid Build Coastguard Worker return ns.error();
138*795d594fSAndroid Build Coastguard Worker }
139*795d594fSAndroid Build Coastguard Worker g_nativeloader_extra_libs_namespace = new NativeLoaderNamespace(std::move(ns.value()));
140*795d594fSAndroid Build Coastguard Worker Result<void> linked =
141*795d594fSAndroid Build Coastguard Worker CreateNativeloaderDefaultNamespaceLibsLink(*g_nativeloader_extra_libs_namespace);
142*795d594fSAndroid Build Coastguard Worker if (!linked.ok()) {
143*795d594fSAndroid Build Coastguard Worker return linked.error();
144*795d594fSAndroid Build Coastguard Worker }
145*795d594fSAndroid Build Coastguard Worker return g_nativeloader_extra_libs_namespace;
146*795d594fSAndroid Build Coastguard Worker }
147*795d594fSAndroid Build Coastguard Worker
148*795d594fSAndroid Build Coastguard Worker // If the given path matches a library in NATIVELOADER_DEFAULT_NAMESPACE_LIBS
149*795d594fSAndroid Build Coastguard Worker // then load it in the nativeloader-extra-libs namespace, otherwise return
150*795d594fSAndroid Build Coastguard Worker // nullptr without error.
TryLoadNativeloaderExtraLib(const char * path)151*795d594fSAndroid Build Coastguard Worker Result<void*> TryLoadNativeloaderExtraLib(const char* path) {
152*795d594fSAndroid Build Coastguard Worker const char* links = getenv("NATIVELOADER_DEFAULT_NAMESPACE_LIBS");
153*795d594fSAndroid Build Coastguard Worker if (links == nullptr || *links == 0) {
154*795d594fSAndroid Build Coastguard Worker return nullptr;
155*795d594fSAndroid Build Coastguard Worker }
156*795d594fSAndroid Build Coastguard Worker std::vector<std::string> lib_list = base::Split(links, ":");
157*795d594fSAndroid Build Coastguard Worker if (std::find(lib_list.begin(), lib_list.end(), path) == lib_list.end()) {
158*795d594fSAndroid Build Coastguard Worker return nullptr;
159*795d594fSAndroid Build Coastguard Worker }
160*795d594fSAndroid Build Coastguard Worker
161*795d594fSAndroid Build Coastguard Worker std::lock_guard<std::mutex> guard(g_namespaces_mutex);
162*795d594fSAndroid Build Coastguard Worker Result<NativeLoaderNamespace*> ns = GetNativeloaderExtraLibsNamespace();
163*795d594fSAndroid Build Coastguard Worker if (!ns.ok()) {
164*795d594fSAndroid Build Coastguard Worker return ns.error();
165*795d594fSAndroid Build Coastguard Worker }
166*795d594fSAndroid Build Coastguard Worker
167*795d594fSAndroid Build Coastguard Worker Result<void*> res = ns.value()->Load(path);
168*795d594fSAndroid Build Coastguard Worker ALOGD("Load %s using ns %s from NATIVELOADER_DEFAULT_NAMESPACE_LIBS match: %s",
169*795d594fSAndroid Build Coastguard Worker path,
170*795d594fSAndroid Build Coastguard Worker ns.value()->name().c_str(),
171*795d594fSAndroid Build Coastguard Worker res.ok() ? "ok" : res.error().message().c_str());
172*795d594fSAndroid Build Coastguard Worker return res;
173*795d594fSAndroid Build Coastguard Worker }
174*795d594fSAndroid Build Coastguard Worker
CreateClassLoaderNamespaceLocked(JNIEnv * env,int32_t target_sdk_version,jobject class_loader,nativeloader::ApiDomain api_domain,bool is_shared,const std::string & dex_path,jstring library_path_j,jstring permitted_path_j,jstring uses_library_list_j)175*795d594fSAndroid Build Coastguard Worker Result<NativeLoaderNamespace*> CreateClassLoaderNamespaceLocked(JNIEnv* env,
176*795d594fSAndroid Build Coastguard Worker int32_t target_sdk_version,
177*795d594fSAndroid Build Coastguard Worker jobject class_loader,
178*795d594fSAndroid Build Coastguard Worker nativeloader::ApiDomain api_domain,
179*795d594fSAndroid Build Coastguard Worker bool is_shared,
180*795d594fSAndroid Build Coastguard Worker const std::string& dex_path,
181*795d594fSAndroid Build Coastguard Worker jstring library_path_j,
182*795d594fSAndroid Build Coastguard Worker jstring permitted_path_j,
183*795d594fSAndroid Build Coastguard Worker jstring uses_library_list_j)
184*795d594fSAndroid Build Coastguard Worker REQUIRES(g_namespaces_mutex) {
185*795d594fSAndroid Build Coastguard Worker Result<NativeLoaderNamespace*> ns = g_namespaces->Create(env,
186*795d594fSAndroid Build Coastguard Worker target_sdk_version,
187*795d594fSAndroid Build Coastguard Worker class_loader,
188*795d594fSAndroid Build Coastguard Worker api_domain,
189*795d594fSAndroid Build Coastguard Worker is_shared,
190*795d594fSAndroid Build Coastguard Worker dex_path,
191*795d594fSAndroid Build Coastguard Worker library_path_j,
192*795d594fSAndroid Build Coastguard Worker permitted_path_j,
193*795d594fSAndroid Build Coastguard Worker uses_library_list_j);
194*795d594fSAndroid Build Coastguard Worker if (!ns.ok()) {
195*795d594fSAndroid Build Coastguard Worker return ns;
196*795d594fSAndroid Build Coastguard Worker }
197*795d594fSAndroid Build Coastguard Worker Result<void> linked = CreateNativeloaderDefaultNamespaceLibsLink(*ns.value());
198*795d594fSAndroid Build Coastguard Worker if (!linked.ok()) {
199*795d594fSAndroid Build Coastguard Worker return linked.error();
200*795d594fSAndroid Build Coastguard Worker }
201*795d594fSAndroid Build Coastguard Worker return ns;
202*795d594fSAndroid Build Coastguard Worker }
203*795d594fSAndroid Build Coastguard Worker
204*795d594fSAndroid Build Coastguard Worker #endif // ART_TARGET_ANDROID
205*795d594fSAndroid Build Coastguard Worker
206*795d594fSAndroid Build Coastguard Worker } // namespace
207*795d594fSAndroid Build Coastguard Worker
InitializeNativeLoader()208*795d594fSAndroid Build Coastguard Worker void InitializeNativeLoader() {
209*795d594fSAndroid Build Coastguard Worker #if defined(ART_TARGET_ANDROID)
210*795d594fSAndroid Build Coastguard Worker std::lock_guard<std::mutex> guard(g_namespaces_mutex);
211*795d594fSAndroid Build Coastguard Worker g_namespaces->Initialize();
212*795d594fSAndroid Build Coastguard Worker #endif
213*795d594fSAndroid Build Coastguard Worker }
214*795d594fSAndroid Build Coastguard Worker
ResetNativeLoader()215*795d594fSAndroid Build Coastguard Worker void ResetNativeLoader() {
216*795d594fSAndroid Build Coastguard Worker #if defined(ART_TARGET_ANDROID)
217*795d594fSAndroid Build Coastguard Worker std::lock_guard<std::mutex> guard(g_namespaces_mutex);
218*795d594fSAndroid Build Coastguard Worker g_namespaces->Reset();
219*795d594fSAndroid Build Coastguard Worker delete g_nativeloader_extra_libs_namespace;
220*795d594fSAndroid Build Coastguard Worker g_nativeloader_extra_libs_namespace = nullptr;
221*795d594fSAndroid Build Coastguard Worker #endif
222*795d594fSAndroid Build Coastguard Worker }
223*795d594fSAndroid Build Coastguard Worker
224*795d594fSAndroid Build Coastguard Worker // dex_path_j may be a ':'-separated list of paths, e.g. when creating a shared
225*795d594fSAndroid Build Coastguard Worker // library loader - cf. mCodePaths in android.content.pm.SharedLibraryInfo.
CreateClassLoaderNamespace(JNIEnv * env,int32_t target_sdk_version,jobject class_loader,bool is_shared,jstring dex_path_j,jstring library_path_j,jstring permitted_path_j,jstring uses_library_list_j)226*795d594fSAndroid Build Coastguard Worker jstring CreateClassLoaderNamespace(JNIEnv* env,
227*795d594fSAndroid Build Coastguard Worker int32_t target_sdk_version,
228*795d594fSAndroid Build Coastguard Worker jobject class_loader,
229*795d594fSAndroid Build Coastguard Worker bool is_shared,
230*795d594fSAndroid Build Coastguard Worker jstring dex_path_j,
231*795d594fSAndroid Build Coastguard Worker jstring library_path_j,
232*795d594fSAndroid Build Coastguard Worker jstring permitted_path_j,
233*795d594fSAndroid Build Coastguard Worker jstring uses_library_list_j) {
234*795d594fSAndroid Build Coastguard Worker #if defined(ART_TARGET_ANDROID)
235*795d594fSAndroid Build Coastguard Worker std::string dex_path;
236*795d594fSAndroid Build Coastguard Worker if (dex_path_j != nullptr) {
237*795d594fSAndroid Build Coastguard Worker ScopedUtfChars dex_path_chars(env, dex_path_j);
238*795d594fSAndroid Build Coastguard Worker dex_path = dex_path_chars.c_str();
239*795d594fSAndroid Build Coastguard Worker }
240*795d594fSAndroid Build Coastguard Worker
241*795d594fSAndroid Build Coastguard Worker Result<nativeloader::ApiDomain> api_domain = nativeloader::GetApiDomainFromPathList(dex_path);
242*795d594fSAndroid Build Coastguard Worker if (!api_domain.ok()) {
243*795d594fSAndroid Build Coastguard Worker return env->NewStringUTF(api_domain.error().message().c_str());
244*795d594fSAndroid Build Coastguard Worker }
245*795d594fSAndroid Build Coastguard Worker
246*795d594fSAndroid Build Coastguard Worker std::lock_guard<std::mutex> guard(g_namespaces_mutex);
247*795d594fSAndroid Build Coastguard Worker Result<NativeLoaderNamespace*> ns = CreateClassLoaderNamespaceLocked(env,
248*795d594fSAndroid Build Coastguard Worker target_sdk_version,
249*795d594fSAndroid Build Coastguard Worker class_loader,
250*795d594fSAndroid Build Coastguard Worker api_domain.value(),
251*795d594fSAndroid Build Coastguard Worker is_shared,
252*795d594fSAndroid Build Coastguard Worker dex_path,
253*795d594fSAndroid Build Coastguard Worker library_path_j,
254*795d594fSAndroid Build Coastguard Worker permitted_path_j,
255*795d594fSAndroid Build Coastguard Worker uses_library_list_j);
256*795d594fSAndroid Build Coastguard Worker if (!ns.ok()) {
257*795d594fSAndroid Build Coastguard Worker return env->NewStringUTF(ns.error().message().c_str());
258*795d594fSAndroid Build Coastguard Worker }
259*795d594fSAndroid Build Coastguard Worker
260*795d594fSAndroid Build Coastguard Worker #else
261*795d594fSAndroid Build Coastguard Worker UNUSED(env,
262*795d594fSAndroid Build Coastguard Worker target_sdk_version,
263*795d594fSAndroid Build Coastguard Worker class_loader,
264*795d594fSAndroid Build Coastguard Worker is_shared,
265*795d594fSAndroid Build Coastguard Worker dex_path_j,
266*795d594fSAndroid Build Coastguard Worker library_path_j,
267*795d594fSAndroid Build Coastguard Worker permitted_path_j,
268*795d594fSAndroid Build Coastguard Worker uses_library_list_j);
269*795d594fSAndroid Build Coastguard Worker #endif
270*795d594fSAndroid Build Coastguard Worker
271*795d594fSAndroid Build Coastguard Worker return nullptr;
272*795d594fSAndroid Build Coastguard Worker }
273*795d594fSAndroid Build Coastguard Worker
274*795d594fSAndroid Build Coastguard Worker #if defined(ART_TARGET_ANDROID)
ShouldBypassLoadingForB349878424()275*795d594fSAndroid Build Coastguard Worker static bool ShouldBypassLoadingForB349878424() {
276*795d594fSAndroid Build Coastguard Worker struct stat st;
277*795d594fSAndroid Build Coastguard Worker if (stat("/system/lib64/libsobridge.so", &st) != 0 &&
278*795d594fSAndroid Build Coastguard Worker stat("/system/lib64/libwalkstack.so", &st) != 0) {
279*795d594fSAndroid Build Coastguard Worker return false;
280*795d594fSAndroid Build Coastguard Worker }
281*795d594fSAndroid Build Coastguard Worker std::string property = android::base::GetProperty("ro.product.build.fingerprint", "");
282*795d594fSAndroid Build Coastguard Worker return android_get_device_api_level() == 33 &&
283*795d594fSAndroid Build Coastguard Worker (property.starts_with("Xiaomi") ||
284*795d594fSAndroid Build Coastguard Worker property.starts_with("Redmi") ||
285*795d594fSAndroid Build Coastguard Worker property.starts_with("POCO"));
286*795d594fSAndroid Build Coastguard Worker }
287*795d594fSAndroid Build Coastguard Worker #endif
288*795d594fSAndroid Build Coastguard Worker
OpenNativeLibrary(JNIEnv * env,int32_t target_sdk_version,const char * path,jobject class_loader,const char * caller_location,jstring library_path_j,bool * needs_native_bridge,char ** error_msg)289*795d594fSAndroid Build Coastguard Worker void* OpenNativeLibrary(JNIEnv* env,
290*795d594fSAndroid Build Coastguard Worker int32_t target_sdk_version,
291*795d594fSAndroid Build Coastguard Worker const char* path,
292*795d594fSAndroid Build Coastguard Worker jobject class_loader,
293*795d594fSAndroid Build Coastguard Worker const char* caller_location,
294*795d594fSAndroid Build Coastguard Worker jstring library_path_j,
295*795d594fSAndroid Build Coastguard Worker bool* needs_native_bridge,
296*795d594fSAndroid Build Coastguard Worker char** error_msg) {
297*795d594fSAndroid Build Coastguard Worker #if defined(ART_TARGET_ANDROID)
298*795d594fSAndroid Build Coastguard Worker if (class_loader == nullptr) {
299*795d594fSAndroid Build Coastguard Worker // class_loader is null only for the boot class loader (see
300*795d594fSAndroid Build Coastguard Worker // IsBootClassLoader call in JavaVMExt::LoadNativeLibrary), i.e. the caller
301*795d594fSAndroid Build Coastguard Worker // is in the boot classpath.
302*795d594fSAndroid Build Coastguard Worker *needs_native_bridge = false;
303*795d594fSAndroid Build Coastguard Worker if (caller_location != nullptr) {
304*795d594fSAndroid Build Coastguard Worker std::optional<NativeLoaderNamespace> ns = FindApexNamespace(caller_location);
305*795d594fSAndroid Build Coastguard Worker if (ns.has_value()) {
306*795d594fSAndroid Build Coastguard Worker const android_dlextinfo dlextinfo = {
307*795d594fSAndroid Build Coastguard Worker .flags = ANDROID_DLEXT_USE_NAMESPACE,
308*795d594fSAndroid Build Coastguard Worker .library_namespace = ns.value().ToRawAndroidNamespace(),
309*795d594fSAndroid Build Coastguard Worker };
310*795d594fSAndroid Build Coastguard Worker void* handle = android_dlopen_ext(path, RTLD_NOW, &dlextinfo);
311*795d594fSAndroid Build Coastguard Worker char* dlerror_msg = handle == nullptr ? strdup(dlerror()) : nullptr;
312*795d594fSAndroid Build Coastguard Worker ALOGD("Load %s using APEX ns %s for caller %s: %s",
313*795d594fSAndroid Build Coastguard Worker path,
314*795d594fSAndroid Build Coastguard Worker ns.value().name().c_str(),
315*795d594fSAndroid Build Coastguard Worker caller_location,
316*795d594fSAndroid Build Coastguard Worker dlerror_msg == nullptr ? "ok" : dlerror_msg);
317*795d594fSAndroid Build Coastguard Worker if (dlerror_msg != nullptr) {
318*795d594fSAndroid Build Coastguard Worker *error_msg = dlerror_msg;
319*795d594fSAndroid Build Coastguard Worker }
320*795d594fSAndroid Build Coastguard Worker return handle;
321*795d594fSAndroid Build Coastguard Worker }
322*795d594fSAndroid Build Coastguard Worker }
323*795d594fSAndroid Build Coastguard Worker
324*795d594fSAndroid Build Coastguard Worker // Check if the library is in NATIVELOADER_DEFAULT_NAMESPACE_LIBS and should
325*795d594fSAndroid Build Coastguard Worker // be loaded from the kNativeloaderExtraLibs namespace.
326*795d594fSAndroid Build Coastguard Worker {
327*795d594fSAndroid Build Coastguard Worker Result<void*> handle = TryLoadNativeloaderExtraLib(path);
328*795d594fSAndroid Build Coastguard Worker if (!handle.ok()) {
329*795d594fSAndroid Build Coastguard Worker *error_msg = strdup(handle.error().message().c_str());
330*795d594fSAndroid Build Coastguard Worker return nullptr;
331*795d594fSAndroid Build Coastguard Worker }
332*795d594fSAndroid Build Coastguard Worker if (handle.value() != nullptr) {
333*795d594fSAndroid Build Coastguard Worker return handle.value();
334*795d594fSAndroid Build Coastguard Worker }
335*795d594fSAndroid Build Coastguard Worker }
336*795d594fSAndroid Build Coastguard Worker
337*795d594fSAndroid Build Coastguard Worker // Handle issue b/349878424.
338*795d594fSAndroid Build Coastguard Worker static bool bypass_loading_for_b349878424 = ShouldBypassLoadingForB349878424();
339*795d594fSAndroid Build Coastguard Worker
340*795d594fSAndroid Build Coastguard Worker if (bypass_loading_for_b349878424 &&
341*795d594fSAndroid Build Coastguard Worker (strcmp("libsobridge.so", path) == 0 || strcmp("libwalkstack.so", path) == 0)) {
342*795d594fSAndroid Build Coastguard Worker // Load a different library to pretend the loading was successful. This
343*795d594fSAndroid Build Coastguard Worker // allows the device to boot.
344*795d594fSAndroid Build Coastguard Worker ALOGD("Loading libbase.so instead of %s due to b/349878424", path);
345*795d594fSAndroid Build Coastguard Worker path = "libbase.so";
346*795d594fSAndroid Build Coastguard Worker }
347*795d594fSAndroid Build Coastguard Worker
348*795d594fSAndroid Build Coastguard Worker // Fall back to the system namespace. This happens for preloaded JNI
349*795d594fSAndroid Build Coastguard Worker // libraries in the zygote.
350*795d594fSAndroid Build Coastguard Worker void* handle = OpenSystemLibrary(path, RTLD_NOW);
351*795d594fSAndroid Build Coastguard Worker char* dlerror_msg = handle == nullptr ? strdup(dlerror()) : nullptr;
352*795d594fSAndroid Build Coastguard Worker ALOGD("Load %s using system ns (caller=%s): %s",
353*795d594fSAndroid Build Coastguard Worker path,
354*795d594fSAndroid Build Coastguard Worker caller_location == nullptr ? "<unknown>" : caller_location,
355*795d594fSAndroid Build Coastguard Worker dlerror_msg == nullptr ? "ok" : dlerror_msg);
356*795d594fSAndroid Build Coastguard Worker if (dlerror_msg != nullptr) {
357*795d594fSAndroid Build Coastguard Worker *error_msg = dlerror_msg;
358*795d594fSAndroid Build Coastguard Worker }
359*795d594fSAndroid Build Coastguard Worker return handle;
360*795d594fSAndroid Build Coastguard Worker }
361*795d594fSAndroid Build Coastguard Worker
362*795d594fSAndroid Build Coastguard Worker // If the caller is in any of the system image partitions and the library is
363*795d594fSAndroid Build Coastguard Worker // in the same partition then load it without regards to public library
364*795d594fSAndroid Build Coastguard Worker // restrictions. This is only done if the library is specified by an absolute
365*795d594fSAndroid Build Coastguard Worker // path, so we don't affect the lookup process for libraries specified by name
366*795d594fSAndroid Build Coastguard Worker // only.
367*795d594fSAndroid Build Coastguard Worker if (caller_location != nullptr &&
368*795d594fSAndroid Build Coastguard Worker // Apps in the partition may have their own native libraries which should
369*795d594fSAndroid Build Coastguard Worker // be loaded with the app's classloader namespace, so only do this for
370*795d594fSAndroid Build Coastguard Worker // libraries in the partition-wide lib(64) directories.
371*795d594fSAndroid Build Coastguard Worker nativeloader::IsPartitionNativeLibPath(path) &&
372*795d594fSAndroid Build Coastguard Worker // Don't do this if the system image is older than V, to avoid any compat
373*795d594fSAndroid Build Coastguard Worker // issues with apps and shared libs in them.
374*795d594fSAndroid Build Coastguard Worker android::modules::sdklevel::IsAtLeastV()) {
375*795d594fSAndroid Build Coastguard Worker nativeloader::ApiDomain caller_api_domain = nativeloader::GetApiDomainFromPath(caller_location);
376*795d594fSAndroid Build Coastguard Worker if (caller_api_domain != nativeloader::API_DOMAIN_DEFAULT) {
377*795d594fSAndroid Build Coastguard Worker nativeloader::ApiDomain library_api_domain = nativeloader::GetApiDomainFromPath(path);
378*795d594fSAndroid Build Coastguard Worker
379*795d594fSAndroid Build Coastguard Worker if (library_api_domain == caller_api_domain) {
380*795d594fSAndroid Build Coastguard Worker bool is_bridged = false;
381*795d594fSAndroid Build Coastguard Worker if (library_path_j != nullptr) {
382*795d594fSAndroid Build Coastguard Worker ScopedUtfChars library_path_utf_chars(env, library_path_j);
383*795d594fSAndroid Build Coastguard Worker if (library_path_utf_chars[0] != '\0') {
384*795d594fSAndroid Build Coastguard Worker is_bridged = NativeBridgeIsPathSupported(library_path_utf_chars.c_str());
385*795d594fSAndroid Build Coastguard Worker }
386*795d594fSAndroid Build Coastguard Worker }
387*795d594fSAndroid Build Coastguard Worker
388*795d594fSAndroid Build Coastguard Worker Result<NativeLoaderNamespace> ns = GetNamespaceForApiDomain(caller_api_domain, is_bridged);
389*795d594fSAndroid Build Coastguard Worker if (!ns.ok()) {
390*795d594fSAndroid Build Coastguard Worker ALOGD("Failed to find ns for caller %s in API domain %d to load %s (is_bridged=%b): %s",
391*795d594fSAndroid Build Coastguard Worker caller_location,
392*795d594fSAndroid Build Coastguard Worker caller_api_domain,
393*795d594fSAndroid Build Coastguard Worker path,
394*795d594fSAndroid Build Coastguard Worker is_bridged,
395*795d594fSAndroid Build Coastguard Worker ns.error().message().c_str());
396*795d594fSAndroid Build Coastguard Worker *error_msg = strdup(ns.error().message().c_str());
397*795d594fSAndroid Build Coastguard Worker return nullptr;
398*795d594fSAndroid Build Coastguard Worker }
399*795d594fSAndroid Build Coastguard Worker
400*795d594fSAndroid Build Coastguard Worker *needs_native_bridge = ns.value().IsBridged();
401*795d594fSAndroid Build Coastguard Worker Result<void*> handle = ns.value().Load(path);
402*795d594fSAndroid Build Coastguard Worker ALOGD("Load %s using ns %s for caller %s in same partition (is_bridged=%b): %s",
403*795d594fSAndroid Build Coastguard Worker path,
404*795d594fSAndroid Build Coastguard Worker ns.value().name().c_str(),
405*795d594fSAndroid Build Coastguard Worker caller_location,
406*795d594fSAndroid Build Coastguard Worker is_bridged,
407*795d594fSAndroid Build Coastguard Worker handle.ok() ? "ok" : handle.error().message().c_str());
408*795d594fSAndroid Build Coastguard Worker if (!handle.ok()) {
409*795d594fSAndroid Build Coastguard Worker *error_msg = strdup(handle.error().message().c_str());
410*795d594fSAndroid Build Coastguard Worker return nullptr;
411*795d594fSAndroid Build Coastguard Worker }
412*795d594fSAndroid Build Coastguard Worker return handle.value();
413*795d594fSAndroid Build Coastguard Worker }
414*795d594fSAndroid Build Coastguard Worker }
415*795d594fSAndroid Build Coastguard Worker }
416*795d594fSAndroid Build Coastguard Worker
417*795d594fSAndroid Build Coastguard Worker NativeLoaderNamespace* ns;
418*795d594fSAndroid Build Coastguard Worker const char* ns_descr;
419*795d594fSAndroid Build Coastguard Worker {
420*795d594fSAndroid Build Coastguard Worker std::lock_guard<std::mutex> guard(g_namespaces_mutex);
421*795d594fSAndroid Build Coastguard Worker
422*795d594fSAndroid Build Coastguard Worker ns = g_namespaces->FindNamespaceByClassLoader(env, class_loader);
423*795d594fSAndroid Build Coastguard Worker ns_descr = "class loader";
424*795d594fSAndroid Build Coastguard Worker
425*795d594fSAndroid Build Coastguard Worker if (ns == nullptr) {
426*795d594fSAndroid Build Coastguard Worker // This is the case where the classloader was not created by ApplicationLoaders
427*795d594fSAndroid Build Coastguard Worker // In this case we create an isolated not-shared namespace for it.
428*795d594fSAndroid Build Coastguard Worker const std::string empty_dex_path;
429*795d594fSAndroid Build Coastguard Worker Result<NativeLoaderNamespace*> res =
430*795d594fSAndroid Build Coastguard Worker CreateClassLoaderNamespaceLocked(env,
431*795d594fSAndroid Build Coastguard Worker target_sdk_version,
432*795d594fSAndroid Build Coastguard Worker class_loader,
433*795d594fSAndroid Build Coastguard Worker nativeloader::API_DOMAIN_DEFAULT,
434*795d594fSAndroid Build Coastguard Worker /*is_shared=*/false,
435*795d594fSAndroid Build Coastguard Worker empty_dex_path,
436*795d594fSAndroid Build Coastguard Worker library_path_j,
437*795d594fSAndroid Build Coastguard Worker /*permitted_path_j=*/nullptr,
438*795d594fSAndroid Build Coastguard Worker /*uses_library_list_j=*/nullptr);
439*795d594fSAndroid Build Coastguard Worker if (!res.ok()) {
440*795d594fSAndroid Build Coastguard Worker ALOGD("Failed to create isolated ns for %s (caller=%s)",
441*795d594fSAndroid Build Coastguard Worker path,
442*795d594fSAndroid Build Coastguard Worker caller_location == nullptr ? "<unknown>" : caller_location);
443*795d594fSAndroid Build Coastguard Worker *error_msg = strdup(res.error().message().c_str());
444*795d594fSAndroid Build Coastguard Worker return nullptr;
445*795d594fSAndroid Build Coastguard Worker }
446*795d594fSAndroid Build Coastguard Worker ns = res.value();
447*795d594fSAndroid Build Coastguard Worker ns_descr = "isolated";
448*795d594fSAndroid Build Coastguard Worker }
449*795d594fSAndroid Build Coastguard Worker }
450*795d594fSAndroid Build Coastguard Worker
451*795d594fSAndroid Build Coastguard Worker *needs_native_bridge = ns->IsBridged();
452*795d594fSAndroid Build Coastguard Worker Result<void*> handle = ns->Load(path);
453*795d594fSAndroid Build Coastguard Worker ALOGD("Load %s using %s ns %s (caller=%s): %s",
454*795d594fSAndroid Build Coastguard Worker path,
455*795d594fSAndroid Build Coastguard Worker ns_descr,
456*795d594fSAndroid Build Coastguard Worker ns->name().c_str(),
457*795d594fSAndroid Build Coastguard Worker caller_location == nullptr ? "<unknown>" : caller_location,
458*795d594fSAndroid Build Coastguard Worker handle.ok() ? "ok" : handle.error().message().c_str());
459*795d594fSAndroid Build Coastguard Worker if (!handle.ok()) {
460*795d594fSAndroid Build Coastguard Worker *error_msg = strdup(handle.error().message().c_str());
461*795d594fSAndroid Build Coastguard Worker return nullptr;
462*795d594fSAndroid Build Coastguard Worker }
463*795d594fSAndroid Build Coastguard Worker return handle.value();
464*795d594fSAndroid Build Coastguard Worker
465*795d594fSAndroid Build Coastguard Worker #else // !ART_TARGET_ANDROID
466*795d594fSAndroid Build Coastguard Worker UNUSED(env, target_sdk_version, class_loader, caller_location);
467*795d594fSAndroid Build Coastguard Worker
468*795d594fSAndroid Build Coastguard Worker // Do some best effort to emulate library-path support. It will not
469*795d594fSAndroid Build Coastguard Worker // work for dependencies.
470*795d594fSAndroid Build Coastguard Worker //
471*795d594fSAndroid Build Coastguard Worker // Note: null has a special meaning and must be preserved.
472*795d594fSAndroid Build Coastguard Worker std::string library_path; // Empty string by default.
473*795d594fSAndroid Build Coastguard Worker if (library_path_j != nullptr && path != nullptr && path[0] != '/') {
474*795d594fSAndroid Build Coastguard Worker ScopedUtfChars library_path_utf_chars(env, library_path_j);
475*795d594fSAndroid Build Coastguard Worker library_path = library_path_utf_chars.c_str();
476*795d594fSAndroid Build Coastguard Worker }
477*795d594fSAndroid Build Coastguard Worker
478*795d594fSAndroid Build Coastguard Worker std::vector<std::string> library_paths = base::Split(library_path, ":");
479*795d594fSAndroid Build Coastguard Worker
480*795d594fSAndroid Build Coastguard Worker for (const std::string& lib_path : library_paths) {
481*795d594fSAndroid Build Coastguard Worker *needs_native_bridge = false;
482*795d594fSAndroid Build Coastguard Worker const char* path_arg;
483*795d594fSAndroid Build Coastguard Worker std::string complete_path;
484*795d594fSAndroid Build Coastguard Worker if (path == nullptr) {
485*795d594fSAndroid Build Coastguard Worker // Preserve null.
486*795d594fSAndroid Build Coastguard Worker path_arg = nullptr;
487*795d594fSAndroid Build Coastguard Worker } else {
488*795d594fSAndroid Build Coastguard Worker complete_path = lib_path;
489*795d594fSAndroid Build Coastguard Worker if (!complete_path.empty()) {
490*795d594fSAndroid Build Coastguard Worker complete_path.append("/");
491*795d594fSAndroid Build Coastguard Worker }
492*795d594fSAndroid Build Coastguard Worker complete_path.append(path);
493*795d594fSAndroid Build Coastguard Worker path_arg = complete_path.c_str();
494*795d594fSAndroid Build Coastguard Worker }
495*795d594fSAndroid Build Coastguard Worker void* handle = dlopen(path_arg, RTLD_NOW);
496*795d594fSAndroid Build Coastguard Worker if (handle != nullptr) {
497*795d594fSAndroid Build Coastguard Worker return handle;
498*795d594fSAndroid Build Coastguard Worker }
499*795d594fSAndroid Build Coastguard Worker if (NativeBridgeIsSupported(path_arg)) {
500*795d594fSAndroid Build Coastguard Worker *needs_native_bridge = true;
501*795d594fSAndroid Build Coastguard Worker handle = NativeBridgeLoadLibrary(path_arg, RTLD_NOW);
502*795d594fSAndroid Build Coastguard Worker if (handle != nullptr) {
503*795d594fSAndroid Build Coastguard Worker return handle;
504*795d594fSAndroid Build Coastguard Worker }
505*795d594fSAndroid Build Coastguard Worker *error_msg = strdup(NativeBridgeGetError());
506*795d594fSAndroid Build Coastguard Worker } else {
507*795d594fSAndroid Build Coastguard Worker *error_msg = strdup(dlerror());
508*795d594fSAndroid Build Coastguard Worker }
509*795d594fSAndroid Build Coastguard Worker }
510*795d594fSAndroid Build Coastguard Worker return nullptr;
511*795d594fSAndroid Build Coastguard Worker #endif // !ART_TARGET_ANDROID
512*795d594fSAndroid Build Coastguard Worker }
513*795d594fSAndroid Build Coastguard Worker
CloseNativeLibrary(void * handle,const bool needs_native_bridge,char ** error_msg)514*795d594fSAndroid Build Coastguard Worker bool CloseNativeLibrary(void* handle, const bool needs_native_bridge, char** error_msg) {
515*795d594fSAndroid Build Coastguard Worker bool success;
516*795d594fSAndroid Build Coastguard Worker if (needs_native_bridge) {
517*795d594fSAndroid Build Coastguard Worker success = (NativeBridgeUnloadLibrary(handle) == 0);
518*795d594fSAndroid Build Coastguard Worker if (!success) {
519*795d594fSAndroid Build Coastguard Worker *error_msg = strdup(NativeBridgeGetError());
520*795d594fSAndroid Build Coastguard Worker }
521*795d594fSAndroid Build Coastguard Worker } else {
522*795d594fSAndroid Build Coastguard Worker success = (dlclose(handle) == 0);
523*795d594fSAndroid Build Coastguard Worker if (!success) {
524*795d594fSAndroid Build Coastguard Worker *error_msg = strdup(dlerror());
525*795d594fSAndroid Build Coastguard Worker }
526*795d594fSAndroid Build Coastguard Worker }
527*795d594fSAndroid Build Coastguard Worker
528*795d594fSAndroid Build Coastguard Worker return success;
529*795d594fSAndroid Build Coastguard Worker }
530*795d594fSAndroid Build Coastguard Worker
NativeLoaderFreeErrorMessage(char * msg)531*795d594fSAndroid Build Coastguard Worker void NativeLoaderFreeErrorMessage(char* msg) {
532*795d594fSAndroid Build Coastguard Worker // The error messages get allocated through strdup, so we must call free on them.
533*795d594fSAndroid Build Coastguard Worker free(msg);
534*795d594fSAndroid Build Coastguard Worker }
535*795d594fSAndroid Build Coastguard Worker
536*795d594fSAndroid Build Coastguard Worker #if defined(ART_TARGET_ANDROID)
OpenNativeLibraryInNamespace(NativeLoaderNamespace * ns,const char * path,bool * needs_native_bridge,char ** error_msg)537*795d594fSAndroid Build Coastguard Worker void* OpenNativeLibraryInNamespace(NativeLoaderNamespace* ns, const char* path,
538*795d594fSAndroid Build Coastguard Worker bool* needs_native_bridge, char** error_msg) {
539*795d594fSAndroid Build Coastguard Worker Result<void*> handle = ns->Load(path);
540*795d594fSAndroid Build Coastguard Worker if (!handle.ok() && error_msg != nullptr) {
541*795d594fSAndroid Build Coastguard Worker *error_msg = strdup(handle.error().message().c_str());
542*795d594fSAndroid Build Coastguard Worker }
543*795d594fSAndroid Build Coastguard Worker if (needs_native_bridge != nullptr) {
544*795d594fSAndroid Build Coastguard Worker *needs_native_bridge = ns->IsBridged();
545*795d594fSAndroid Build Coastguard Worker }
546*795d594fSAndroid Build Coastguard Worker return handle.ok() ? *handle : nullptr;
547*795d594fSAndroid Build Coastguard Worker }
548*795d594fSAndroid Build Coastguard Worker
IsNamespaceNativeBridged(const struct NativeLoaderNamespace * ns)549*795d594fSAndroid Build Coastguard Worker bool IsNamespaceNativeBridged(const struct NativeLoaderNamespace* ns) { return ns->IsBridged(); }
550*795d594fSAndroid Build Coastguard Worker
551*795d594fSAndroid Build Coastguard Worker // native_bridge_namespaces are not supported for callers of this function.
552*795d594fSAndroid Build Coastguard Worker // This function will return nullptr in the case when application is running
553*795d594fSAndroid Build Coastguard Worker // on native bridge.
FindNamespaceByClassLoader(JNIEnv * env,jobject class_loader)554*795d594fSAndroid Build Coastguard Worker android_namespace_t* FindNamespaceByClassLoader(JNIEnv* env, jobject class_loader) {
555*795d594fSAndroid Build Coastguard Worker std::lock_guard<std::mutex> guard(g_namespaces_mutex);
556*795d594fSAndroid Build Coastguard Worker NativeLoaderNamespace* ns = g_namespaces->FindNamespaceByClassLoader(env, class_loader);
557*795d594fSAndroid Build Coastguard Worker if (ns != nullptr && !ns->IsBridged()) {
558*795d594fSAndroid Build Coastguard Worker return ns->ToRawAndroidNamespace();
559*795d594fSAndroid Build Coastguard Worker }
560*795d594fSAndroid Build Coastguard Worker return nullptr;
561*795d594fSAndroid Build Coastguard Worker }
562*795d594fSAndroid Build Coastguard Worker
FindNativeLoaderNamespaceByClassLoader(JNIEnv * env,jobject class_loader)563*795d594fSAndroid Build Coastguard Worker NativeLoaderNamespace* FindNativeLoaderNamespaceByClassLoader(JNIEnv* env, jobject class_loader) {
564*795d594fSAndroid Build Coastguard Worker std::lock_guard<std::mutex> guard(g_namespaces_mutex);
565*795d594fSAndroid Build Coastguard Worker return g_namespaces->FindNamespaceByClassLoader(env, class_loader);
566*795d594fSAndroid Build Coastguard Worker }
567*795d594fSAndroid Build Coastguard Worker
LinkNativeLoaderNamespaceToExportedNamespaceLibrary(struct NativeLoaderNamespace * ns,const char * exported_ns_name,const char * library_name,char ** error_msg)568*795d594fSAndroid Build Coastguard Worker void LinkNativeLoaderNamespaceToExportedNamespaceLibrary(struct NativeLoaderNamespace* ns,
569*795d594fSAndroid Build Coastguard Worker const char* exported_ns_name,
570*795d594fSAndroid Build Coastguard Worker const char* library_name,
571*795d594fSAndroid Build Coastguard Worker char** error_msg) {
572*795d594fSAndroid Build Coastguard Worker Result<NativeLoaderNamespace> exported_ns =
573*795d594fSAndroid Build Coastguard Worker NativeLoaderNamespace::GetExportedNamespace(exported_ns_name, ns->IsBridged());
574*795d594fSAndroid Build Coastguard Worker if (!exported_ns.ok()) {
575*795d594fSAndroid Build Coastguard Worker *error_msg = strdup(exported_ns.error().message().c_str());
576*795d594fSAndroid Build Coastguard Worker return;
577*795d594fSAndroid Build Coastguard Worker }
578*795d594fSAndroid Build Coastguard Worker
579*795d594fSAndroid Build Coastguard Worker Result<void> linked = ns->Link(&exported_ns.value(), std::string(library_name));
580*795d594fSAndroid Build Coastguard Worker if (!linked.ok()) {
581*795d594fSAndroid Build Coastguard Worker *error_msg = strdup(linked.error().message().c_str());
582*795d594fSAndroid Build Coastguard Worker }
583*795d594fSAndroid Build Coastguard Worker }
584*795d594fSAndroid Build Coastguard Worker
585*795d594fSAndroid Build Coastguard Worker #endif // ART_TARGET_ANDROID
586*795d594fSAndroid Build Coastguard Worker
587*795d594fSAndroid Build Coastguard Worker } // namespace android
588