summaryrefslogtreecommitdiff
path: root/libnativeloader/native_loader.cpp
diff options
context:
space:
mode:
authorDimitry Ivanov <dimitry@google.com>2016-05-12 15:34:41 -0700
committerDimitry Ivanov <dimitry@google.com>2016-05-16 18:13:49 -0700
commit24db75c1ce7ff8376a475214b059b9a37ac07936 (patch)
tree66b0e79b7cc091a08e353a77013e660b92d89454 /libnativeloader/native_loader.cpp
parenta214a769f9a98b0962e62bd716575a05cf6f9f59 (diff)
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
Diffstat (limited to 'libnativeloader/native_loader.cpp')
-rw-r--r--libnativeloader/native_loader.cpp28
1 files changed, 27 insertions, 1 deletions
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<std::pair<jweak, android_namespace_t*>> namespaces_;
std::string public_libraries_;