From 24db75c1ce7ff8376a475214b059b9a37ac07936 Mon Sep 17 00:00:00 2001 From: Dimitry Ivanov Date: Thu, 12 May 2016 15:34:41 -0700 Subject: Set parent namespace for linker-namespaces This change allows applications to share RTLD_GLOBAL native libraries between namespaces associated with different classloaders. The rule is - if a library is GLOBAL within namespace associated with parent classloader, it is shared with namespace associated with this classloader Note that the sharing happens on create_namespace event, which is tied to createClassloader in case of application classloaders created by the framework, for custom application classloaders it is tied to first loadLibrary() event. Bug: http://b/28560538 Bug: https://code.google.com/p/android/issues/detail?id=208458 Change-Id: I7ee701166f8ec5eff033b7acc0f80c7aa4ec5bda --- libnativeloader/native_loader.cpp | 28 +++++++++++++++++++++++++++- 1 file changed, 27 insertions(+), 1 deletion(-) (limited to 'libnativeloader/native_loader.cpp') diff --git a/libnativeloader/native_loader.cpp b/libnativeloader/native_loader.cpp index 79518cac5..713a59df2 100644 --- a/libnativeloader/native_loader.cpp +++ b/libnativeloader/native_loader.cpp @@ -95,11 +95,14 @@ class LibraryNamespaces { namespace_type |= ANDROID_NAMESPACE_TYPE_SHARED; } + android_namespace_t* parent_ns = FindParentNamespaceByClassLoader(env, class_loader); + ns = android_create_namespace("classloader-namespace", nullptr, library_path.c_str(), namespace_type, - permitted_path.c_str()); + permitted_path.c_str(), + parent_ns); if (ns != nullptr) { namespaces_.push_back(std::make_pair(env->NewWeakGlobalRef(class_loader), ns)); @@ -200,6 +203,29 @@ class LibraryNamespaces { return initialized_; } + jobject GetParentClassLoader(JNIEnv* env, jobject class_loader) { + jclass class_loader_class = env->FindClass("java/lang/ClassLoader"); + jmethodID get_parent = env->GetMethodID(class_loader_class, + "getParent", + "()Ljava/lang/ClassLoader;"); + + return env->CallObjectMethod(class_loader, get_parent); + } + + android_namespace_t* FindParentNamespaceByClassLoader(JNIEnv* env, jobject class_loader) { + jobject parent_class_loader = GetParentClassLoader(env, class_loader); + + while (parent_class_loader != nullptr) { + android_namespace_t* ns = FindNamespaceByClassLoader(env, parent_class_loader); + if (ns != nullptr) { + return ns; + } + + parent_class_loader = GetParentClassLoader(env, parent_class_loader); + } + return nullptr; + } + bool initialized_; std::vector> namespaces_; std::string public_libraries_; -- cgit v1.2.3