Skip to content
Snippets Groups Projects
Commit ade364b4 authored by Dimitry Ivanov's avatar Dimitry Ivanov
Browse files

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
(cherry picked from commit 24db75c1)
parent 6e394f0f
No related branches found
No related tags found
No related merge requests found
......@@ -83,7 +83,8 @@ extern struct android_namespace_t* android_create_namespace(const char* name,
const char* ld_library_path,
const char* default_library_path,
uint64_t type,
const char* permitted_when_isolated_path);
const char* permitted_when_isolated_path,
android_namespace_t* parent);
__END_DECLS
......
......@@ -97,11 +97,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));
......@@ -198,6 +201,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_;
......
0% Loading or .
You are about to add 0 people to the discussion. Proceed with caution.
Please register or to comment