Merge "Always call into native loader when loading a native library"
diff --git a/runtime/java_vm_ext.cc b/runtime/java_vm_ext.cc
index a1ed470..8e76aeb 100644
--- a/runtime/java_vm_ext.cc
+++ b/runtime/java_vm_ext.cc
@@ -54,10 +54,10 @@
class SharedLibrary {
public:
SharedLibrary(JNIEnv* env, Thread* self, const std::string& path, void* handle,
- jobject class_loader, void* class_loader_allocator)
+ bool needs_native_bridge, jobject class_loader, void* class_loader_allocator)
: path_(path),
handle_(handle),
- needs_native_bridge_(false),
+ needs_native_bridge_(needs_native_bridge),
class_loader_(env->NewWeakGlobalRef(class_loader)),
class_loader_allocator_(class_loader_allocator),
jni_on_load_lock_("JNI_OnLoad lock"),
@@ -73,9 +73,7 @@
self->GetJniEnv()->DeleteWeakGlobalRef(class_loader_);
}
- if (!needs_native_bridge_) {
- android::CloseNativeLibrary(handle_);
- }
+ android::CloseNativeLibrary(handle_, needs_native_bridge_);
}
jweak GetClassLoader() const {
@@ -131,8 +129,8 @@
jni_on_load_cond_.Broadcast(self);
}
- void SetNeedsNativeBridge() {
- needs_native_bridge_ = true;
+ void SetNeedsNativeBridge(bool needs) {
+ needs_native_bridge_ = needs;
}
bool NeedsNativeBridge() const {
@@ -817,24 +815,18 @@
Locks::mutator_lock_->AssertNotHeld(self);
const char* path_str = path.empty() ? nullptr : path.c_str();
+ bool needs_native_bridge = false;
void* handle = android::OpenNativeLibrary(env,
runtime_->GetTargetSdkVersion(),
path_str,
class_loader,
- library_path);
-
- bool needs_native_bridge = false;
- if (handle == nullptr) {
- if (android::NativeBridgeIsSupported(path_str)) {
- handle = android::NativeBridgeLoadLibrary(path_str, RTLD_NOW);
- needs_native_bridge = true;
- }
- }
+ library_path,
+ &needs_native_bridge,
+ error_msg);
VLOG(jni) << "[Call to dlopen(\"" << path << "\", RTLD_NOW) returned " << handle << "]";
if (handle == nullptr) {
- *error_msg = dlerror();
VLOG(jni) << "dlopen(\"" << path << "\", RTLD_NOW) failed: " << *error_msg;
return false;
}
@@ -850,7 +842,14 @@
{
// Create SharedLibrary ahead of taking the libraries lock to maintain lock ordering.
std::unique_ptr<SharedLibrary> new_library(
- new SharedLibrary(env, self, path, handle, class_loader, class_loader_allocator));
+ new SharedLibrary(env,
+ self,
+ path,
+ handle,
+ needs_native_bridge,
+ class_loader,
+ class_loader_allocator));
+
MutexLock mu(self, *Locks::jni_libraries_lock_);
library = libraries_->Get(path);
if (library == nullptr) { // We won race to get libraries_lock.
@@ -867,11 +866,7 @@
VLOG(jni) << "[Added shared library \"" << path << "\" for ClassLoader " << class_loader << "]";
bool was_successful = false;
- void* sym;
- if (needs_native_bridge) {
- library->SetNeedsNativeBridge();
- }
- sym = library->FindSymbol("JNI_OnLoad", nullptr);
+ void* sym = library->FindSymbol("JNI_OnLoad", nullptr);
if (sym == nullptr) {
VLOG(jni) << "[No JNI_OnLoad found in \"" << path << "\"]";
was_successful = true;
diff --git a/test/115-native-bridge/nativebridge.cc b/test/115-native-bridge/nativebridge.cc
index aca356b..56d737f 100644
--- a/test/115-native-bridge/nativebridge.cc
+++ b/test/115-native-bridge/nativebridge.cc
@@ -370,7 +370,7 @@
// v2 parts.
-extern "C" bool nb_is_compatible(uint32_t bridge_version ATTRIBUTE_UNUSED) {
+extern "C" bool native_bridge_isCompatibleWith(uint32_t bridge_version ATTRIBUTE_UNUSED) {
return true;
}
@@ -453,7 +453,7 @@
return true;
}
-static ::android::NativeBridgeSignalHandlerFn native_bridge_get_signal_handler(int signal) {
+static ::android::NativeBridgeSignalHandlerFn native_bridge_getSignalHandler(int signal) {
// Test segv for already claimed signal, and sigill for not claimed signal
if ((signal == SIGSEGV) || (signal == SIGILL)) {
return &nb_signalhandler;
@@ -461,16 +461,63 @@
return nullptr;
}
+extern "C" int native_bridge_unloadLibrary(void* handle ATTRIBUTE_UNUSED) {
+ printf("dlclose() in native bridge.\n");
+ return 0;
+}
+
+extern "C" char* native_bridge_getError() {
+ printf("dlerror() in native bridge.\n");
+ return nullptr;
+}
+
+extern "C" bool native_bridge_isPathSupported(const char* library_path ATTRIBUTE_UNUSED) {
+ printf("Checking for path support in native bridge.\n");
+ return false;
+}
+
+extern "C" bool native_bridge_initNamespace(const char* public_ns_sonames ATTRIBUTE_UNUSED,
+ const char* anon_ns_library_path ATTRIBUTE_UNUSED) {
+ printf("Initializing namespaces in native bridge.\n");
+ return false;
+}
+
+extern "C" android::native_bridge_namespace_t*
+native_bridge_createNamespace(const char* name ATTRIBUTE_UNUSED,
+ const char* ld_library_path ATTRIBUTE_UNUSED,
+ const char* default_library_path ATTRIBUTE_UNUSED,
+ uint64_t type ATTRIBUTE_UNUSED,
+ const char* permitted_when_isolated_path ATTRIBUTE_UNUSED,
+ android::native_bridge_namespace_t* parent_ns ATTRIBUTE_UNUSED) {
+ printf("Creating namespace in native bridge.\n");
+ return nullptr;
+}
+
+extern "C" void* native_bridge_loadLibraryExt(const char* libpath ATTRIBUTE_UNUSED,
+ int flag ATTRIBUTE_UNUSED,
+ android::native_bridge_namespace_t* ns ATTRIBUTE_UNUSED) {
+ printf("Loading library with Extension in native bridge.\n");
+ return nullptr;
+}
// "NativeBridgeItf" is effectively an API (it is the name of the symbol that will be loaded
// by the native bridge library).
android::NativeBridgeCallbacks NativeBridgeItf {
- .version = 2,
+ // v1
+ .version = 3,
.initialize = &native_bridge_initialize,
.loadLibrary = &native_bridge_loadLibrary,
.getTrampoline = &native_bridge_getTrampoline,
.isSupported = &native_bridge_isSupported,
.getAppEnv = &native_bridge_getAppEnv,
- .isCompatibleWith = &nb_is_compatible,
- .getSignalHandler = &native_bridge_get_signal_handler
+ // v2
+ .isCompatibleWith = &native_bridge_isCompatibleWith,
+ .getSignalHandler = &native_bridge_getSignalHandler,
+ // v3
+ .unloadLibrary = &native_bridge_unloadLibrary,
+ .getError = &native_bridge_getError,
+ .isPathSupported = &native_bridge_isPathSupported,
+ .initNamespace = &native_bridge_initNamespace,
+ .createNamespace = &native_bridge_createNamespace,
+ .loadLibraryExt = &native_bridge_loadLibraryExt
};