summaryrefslogtreecommitdiffstats
path: root/libnativeloader
diff options
context:
space:
mode:
authorDimitry Ivanov <dimitry@google.com>2016-02-23 14:23:51 -0800
committerDimitry Ivanov <dimitry@google.com>2016-02-25 11:33:32 -0800
commitd047c925af62e1fe28fcd1c1940df4afe18d458a (patch)
tree8fb2ac4e56eed5f78641efba6f00506156a74687 /libnativeloader
parentb046e74beff221d96189c4142f42f18730565921 (diff)
downloadsystem_core-d047c925af62e1fe28fcd1c1940df4afe18d458a.tar.gz
system_core-d047c925af62e1fe28fcd1c1940df4afe18d458a.tar.bz2
system_core-d047c925af62e1fe28fcd1c1940df4afe18d458a.zip
Added function to explicitly initialize a namespace
This change replaces lazy get-or-create logic for linker namespaces with the explicit one. ApplicationLoaders.getClassLoader(..) is now resposible for the namespace initialization for PathClassLoaders. Bug: http://b/27189432 Bug: http://b/22548808 Change-Id: Ife987c3ca1db33a47c20f363a5ed61512be8b5a7
Diffstat (limited to 'libnativeloader')
-rw-r--r--libnativeloader/include/nativeloader/native_loader.h16
-rw-r--r--libnativeloader/native_loader.cpp75
2 files changed, 69 insertions, 22 deletions
diff --git a/libnativeloader/include/nativeloader/native_loader.h b/libnativeloader/include/nativeloader/native_loader.h
index 5644aa637..b16c0e66e 100644
--- a/libnativeloader/include/nativeloader/native_loader.h
+++ b/libnativeloader/include/nativeloader/native_loader.h
@@ -29,9 +29,19 @@ __attribute__((visibility("default")))
void PreloadPublicNativeLibraries();
__attribute__((visibility("default")))
-void* OpenNativeLibrary(JNIEnv* env, int32_t target_sdk_version, const char* path,
- jobject class_loader, bool is_shared, jstring library_path,
- jstring permitted_path);
+jstring CreateClassLoaderNamespace(JNIEnv* env,
+ int32_t target_sdk_version,
+ jobject class_loader,
+ bool is_shared,
+ jstring library_path,
+ jstring permitted_path);
+
+__attribute__((visibility("default")))
+void* OpenNativeLibrary(JNIEnv* env,
+ int32_t target_sdk_version,
+ const char* path,
+ jobject class_loader,
+ jstring library_path);
#if defined(__ANDROID__)
// Look up linker namespace by class_loader. Returns nullptr if
diff --git a/libnativeloader/native_loader.cpp b/libnativeloader/native_loader.cpp
index b763631be..837924b03 100644
--- a/libnativeloader/native_loader.cpp
+++ b/libnativeloader/native_loader.cpp
@@ -21,6 +21,7 @@
#ifdef __ANDROID__
#include <android/dlext.h>
#include "cutils/properties.h"
+#include "log/log.h"
#endif
#include <algorithm>
@@ -61,11 +62,12 @@ class LibraryNamespaces {
public:
LibraryNamespaces() : initialized_(false) { }
- android_namespace_t* GetOrCreate(JNIEnv* env, jobject class_loader,
- bool is_shared,
- jstring java_library_path,
- jstring java_permitted_path,
- int32_t target_sdk_version) {
+ android_namespace_t* Create(JNIEnv* env,
+ jobject class_loader,
+ bool is_shared,
+ jstring java_library_path,
+ jstring java_permitted_path,
+ int32_t target_sdk_version) {
ScopedUtfChars library_path(env, java_library_path);
std::string permitted_path;
@@ -82,9 +84,7 @@ class LibraryNamespaces {
android_namespace_t* ns = FindNamespaceByClassLoader(env, class_loader);
- if (ns != nullptr) {
- return ns;
- }
+ LOG_FATAL_IF(ns != nullptr, "There is already a namespace associated with this classloader");
uint64_t namespace_type = ANDROID_NAMESPACE_TYPE_ISOLATED;
if (is_shared) {
@@ -99,7 +99,9 @@ class LibraryNamespaces {
permitted_path.c_str() :
nullptr);
- namespaces_.push_back(std::make_pair(env->NewWeakGlobalRef(class_loader), ns));
+ if (ns != nullptr) {
+ namespaces_.push_back(std::make_pair(env->NewWeakGlobalRef(class_loader), ns));
+ }
return ns;
}
@@ -147,6 +149,10 @@ class LibraryNamespaces {
};
static LibraryNamespaces* g_namespaces = new LibraryNamespaces;
+
+static bool namespaces_enabled(uint32_t target_sdk_version) {
+ return target_sdk_version > 0;
+}
#endif
void PreloadPublicNativeLibraries() {
@@ -156,20 +162,52 @@ void PreloadPublicNativeLibraries() {
}
-void* OpenNativeLibrary(JNIEnv* env, int32_t target_sdk_version, const char* path,
- jobject class_loader, bool is_shared, jstring java_library_path,
- jstring java_permitted_path) {
+jstring CreateClassLoaderNamespace(JNIEnv* env,
+ int32_t target_sdk_version,
+ jobject class_loader,
+ bool is_shared,
+ jstring library_path,
+ jstring permitted_path) {
#if defined(__ANDROID__)
- if (target_sdk_version == 0 || class_loader == nullptr) {
+ if (!namespaces_enabled(target_sdk_version)) {
+ return nullptr;
+ }
+
+ android_namespace_t* ns = g_namespaces->Create(env,
+ class_loader,
+ is_shared,
+ library_path,
+ permitted_path,
+ target_sdk_version);
+ if (ns == nullptr) {
+ return env->NewStringUTF(dlerror());
+ }
+#else
+ UNUSED(env, target_sdk_version, class_loader, is_shared,
+ library_path, permitted_path);
+#endif
+ return nullptr;
+}
+
+void* OpenNativeLibrary(JNIEnv* env,
+ int32_t target_sdk_version,
+ const char* path,
+ jobject class_loader,
+ jstring library_path) {
+#if defined(__ANDROID__)
+ if (!namespaces_enabled(target_sdk_version) || class_loader == nullptr) {
return dlopen(path, RTLD_NOW);
}
- android_namespace_t* ns =
- g_namespaces->GetOrCreate(env, class_loader, is_shared,
- java_library_path, java_permitted_path, target_sdk_version);
+ android_namespace_t* ns = g_namespaces->FindNamespaceByClassLoader(env, class_loader);
if (ns == nullptr) {
- return nullptr;
+ // This is the case where the classloader was not created by ApplicationLoaders
+ // In this case we create an isolated not-shared namespace for it.
+ ns = g_namespaces->Create(env, class_loader, false, library_path, nullptr, target_sdk_version);
+ if (ns == nullptr) {
+ return nullptr;
+ }
}
android_dlextinfo extinfo;
@@ -178,8 +216,7 @@ void* OpenNativeLibrary(JNIEnv* env, int32_t target_sdk_version, const char* pat
return android_dlopen_ext(path, RTLD_NOW, &extinfo);
#else
- UNUSED(env, target_sdk_version, class_loader, is_shared,
- java_library_path, java_permitted_path);
+ UNUSED(env, target_sdk_version, class_loader, library_path);
return dlopen(path, RTLD_NOW);
#endif
}