From d836ab005a3fd70e477a01d4200483131a285c9a Mon Sep 17 00:00:00 2001 From: Dimitry Ivanov <dimitry@google.com> Date: Wed, 2 Nov 2016 18:03:10 -0700 Subject: [PATCH] Allow different namespace types for different classloaders An app should be able to make cross-arch calls to different apps via other app's Context.getClassLoader() Bug: 32542970 Test: Boot fugu. Check that there are no linker-namespace related errors in the log. Change-Id: I1593f4688bcde0121a5e24a707441a4935fa7dc4 --- include/nativebridge/native_bridge.h | 4 ++-- libnativebridge/native_bridge.cc | 6 +++--- libnativebridge/tests/DummyNativeBridge3.cpp | 2 +- libnativeloader/native_loader.cpp | 18 +++++++++++------- 4 files changed, 17 insertions(+), 13 deletions(-) diff --git a/include/nativebridge/native_bridge.h b/include/nativebridge/native_bridge.h index 26556f048..45266dedf 100644 --- a/include/nativebridge/native_bridge.h +++ b/include/nativebridge/native_bridge.h @@ -104,7 +104,7 @@ int NativeBridgeUnloadLibrary(void* handle); // Get last error message of native bridge when fail to load library or search symbol. // This is reflection of dlerror() for native bridge. -char* NativeBridgeGetError(); +const char* NativeBridgeGetError(); struct native_bridge_namespace_t; @@ -244,7 +244,7 @@ struct NativeBridgeCallbacks { // Returns: // A string describing the most recent error that occurred when load library // or lookup symbol via native bridge. - char* (*getError)(); + const char* (*getError)(); // Check whether library paths are supported by native bridge. // diff --git a/libnativebridge/native_bridge.cc b/libnativebridge/native_bridge.cc index 43e6c0a5b..eafc53d8d 100644 --- a/libnativebridge/native_bridge.cc +++ b/libnativebridge/native_bridge.cc @@ -551,15 +551,15 @@ int NativeBridgeUnloadLibrary(void* handle) { return -1; } -char* NativeBridgeGetError() { +const char* NativeBridgeGetError() { if (NativeBridgeInitialized()) { if (isCompatibleWith(NAMESPACE_VERSION)) { return callbacks->getError(); } else { - ALOGE("not compatible with version %d, cannot get message", NAMESPACE_VERSION); + return "native bridge implementation is not compatible with version 3, cannot get message"; } } - return nullptr; + return "native bridge is not initialized"; } bool NativeBridgeIsPathSupported(const char* path) { diff --git a/libnativebridge/tests/DummyNativeBridge3.cpp b/libnativebridge/tests/DummyNativeBridge3.cpp index c538fa071..13fce8599 100644 --- a/libnativebridge/tests/DummyNativeBridge3.cpp +++ b/libnativebridge/tests/DummyNativeBridge3.cpp @@ -68,7 +68,7 @@ extern "C" int native_bridge3_unloadLibrary(void* /* handle */) { return 0; } -extern "C" char* native_bridge3_getError() { +extern "C" const char* native_bridge3_getError() { return nullptr; } diff --git a/libnativeloader/native_loader.cpp b/libnativeloader/native_loader.cpp index e09cce3e3..15fe0540e 100644 --- a/libnativeloader/native_loader.cpp +++ b/libnativeloader/native_loader.cpp @@ -308,13 +308,17 @@ class LibraryNamespaces { // code is one example) unknown to linker in which case linker uses anonymous // namespace. The second argument specifies the search path for the anonymous // namespace which is the library_path of the classloader. - if (!is_native_bridge) { - initialized_ = android_init_namespaces(public_libraries_.c_str(), library_path); - if (!initialized_) { - *error_msg = dlerror(); - } - } else { - initialized_ = NativeBridgeInitNamespace(public_libraries_.c_str(), library_path); + initialized_ = android_init_namespaces(public_libraries_.c_str(), + is_native_bridge ? nullptr : library_path); + if (!initialized_) { + *error_msg = dlerror(); + return false; + } + + // and now initialize native bridge namespaces if necessary. + if (NativeBridgeInitialized()) { + initialized_ = NativeBridgeInitNamespace(public_libraries_.c_str(), + is_native_bridge ? library_path : nullptr); if (!initialized_) { *error_msg = NativeBridgeGetError(); }