diff options
-rw-r--r-- | libnativeloader/include/nativeloader/native_loader.h | 2 | ||||
-rw-r--r-- | libnativeloader/native_loader.cpp | 67 | ||||
-rw-r--r-- | rootdir/etc/public.libraries.android.txt | 19 | ||||
-rw-r--r-- | rootdir/etc/public.libraries.wear.txt | 18 |
4 files changed, 74 insertions, 32 deletions
diff --git a/libnativeloader/include/nativeloader/native_loader.h b/libnativeloader/include/nativeloader/native_loader.h index b16c0e66e..1bd3b8f07 100644 --- a/libnativeloader/include/nativeloader/native_loader.h +++ b/libnativeloader/include/nativeloader/native_loader.h @@ -26,7 +26,7 @@ namespace android { __attribute__((visibility("default"))) -void PreloadPublicNativeLibraries(); +void InitializeNativeLoader(); __attribute__((visibility("default"))) jstring CreateClassLoaderNamespace(JNIEnv* env, diff --git a/libnativeloader/native_loader.cpp b/libnativeloader/native_loader.cpp index 3e4b15a01..e6b37ed3b 100644 --- a/libnativeloader/native_loader.cpp +++ b/libnativeloader/native_loader.cpp @@ -29,34 +29,14 @@ #include <string> #include <mutex> +#include "android-base/file.h" #include "android-base/macros.h" #include "android-base/strings.h" namespace android { -#ifdef __ANDROID__ -// TODO(dimitry): move this to system properties. -static const char* kPublicNativeLibraries = "libandroid.so:" - "libc.so:" - "libcamera2ndk.so:" - "libdl.so:" - "libEGL.so:" - "libGLESv1_CM.so:" - "libGLESv2.so:" - "libGLESv3.so:" - "libicui18n.so:" - "libicuuc.so:" - "libjnigraphics.so:" - "liblog.so:" - "libmediandk.so:" - "libm.so:" - "libOpenMAXAL.so:" - "libOpenSLES.so:" - "libRS.so:" - "libstdc++.so:" - "libvulkan.so:" - "libwebviewchromium_plat_support.so:" - "libz.so"; +#if defined(__ANDROID__) +static constexpr const char* kPublicNativeLibrariesConfig = "/system/etc/public.libraries.txt"; class LibraryNamespaces { public: @@ -82,7 +62,8 @@ class LibraryNamespaces { android_namespace_t* ns = FindNamespaceByClassLoader(env, class_loader); - LOG_FATAL_IF(ns != nullptr, "There is already a namespace associated with this classloader"); + LOG_ALWAYS_FATAL_IF(ns != nullptr, + "There is already a namespace associated with this classloader"); uint64_t namespace_type = ANDROID_NAMESPACE_TYPE_ISOLATED; if (is_shared) { @@ -112,10 +93,30 @@ class LibraryNamespaces { return it != namespaces_.end() ? it->second : nullptr; } - void PreloadPublicLibraries() { + void Initialize() { + // Read list of public native libraries from the config file. + std::string file_content; + LOG_ALWAYS_FATAL_IF(!base::ReadFileToString(kPublicNativeLibrariesConfig, &file_content), + "Error reading public native library list from \"%s\": %s", + kPublicNativeLibrariesConfig, strerror(errno)); + + std::vector<std::string> lines = base::Split(file_content, "\n"); + + std::vector<std::string> sonames; + + for (const auto& line : lines) { + auto trimmed_line = base::Trim(line); + if (trimmed_line[0] == '#' || trimmed_line.empty()) { + continue; + } + + sonames.push_back(trimmed_line); + } + + public_libraries_ = base::Join(sonames, ':'); + // android_init_namespaces() expects all the public libraries // to be loaded so that they can be found by soname alone. - std::vector<std::string> sonames = android::base::Split(kPublicNativeLibraries, ":"); for (const auto& soname : sonames) { dlopen(soname.c_str(), RTLD_NOW | RTLD_NODELETE); } @@ -123,9 +124,7 @@ class LibraryNamespaces { private: bool InitPublicNamespace(const char* library_path, int32_t target_sdk_version) { - // Some apps call dlopen from generated code unknown to linker in which - // case linker uses anonymous namespace. See b/25844435 for details. - std::string publicNativeLibraries = kPublicNativeLibraries; + std::string publicNativeLibraries = public_libraries_; // TODO (dimitry): This is a workaround for http://b/26436837 // will be removed before the release. @@ -139,6 +138,10 @@ class LibraryNamespaces { } // END OF WORKAROUND + // (http://b/25844435) - Some apps call dlopen from generated code (mono jited + // 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. initialized_ = android_init_namespaces(publicNativeLibraries.c_str(), library_path); return initialized_; @@ -146,6 +149,8 @@ class LibraryNamespaces { bool initialized_; std::vector<std::pair<jweak, android_namespace_t*>> namespaces_; + std::string public_libraries_; + DISALLOW_COPY_AND_ASSIGN(LibraryNamespaces); }; @@ -158,10 +163,10 @@ static bool namespaces_enabled(uint32_t target_sdk_version) { } #endif -void PreloadPublicNativeLibraries() { +void InitializeNativeLoader() { #if defined(__ANDROID__) std::lock_guard<std::mutex> guard(g_namespaces_mutex); - g_namespaces->PreloadPublicLibraries(); + g_namespaces->Initialize(); #endif } diff --git a/rootdir/etc/public.libraries.android.txt b/rootdir/etc/public.libraries.android.txt new file mode 100644 index 000000000..8db2ba892 --- /dev/null +++ b/rootdir/etc/public.libraries.android.txt @@ -0,0 +1,19 @@ +libandroid.so +libc.so +libdl.so +libEGL.so +libGLESv1_CM.so +libGLESv2.so +libGLESv3.so +libicui18n.so +libicuuc.so +libjnigraphics.so +liblog.so +libmediandk.so +libm.so +libOpenMAXAL.so +libOpenSLES.so +libRS.so +libstdc++.so +libwebviewchromium_plat_support.so +libz.so diff --git a/rootdir/etc/public.libraries.wear.txt b/rootdir/etc/public.libraries.wear.txt new file mode 100644 index 000000000..673e11594 --- /dev/null +++ b/rootdir/etc/public.libraries.wear.txt @@ -0,0 +1,18 @@ +libandroid.so +libc.so +libdl.so +libEGL.so +libGLESv1_CM.so +libGLESv2.so +libGLESv3.so +libicui18n.so +libicuuc.so +libjnigraphics.so +liblog.so +libmediandk.so +libm.so +libOpenMAXAL.so +libOpenSLES.so +libRS.so +libstdc++.so +libz.so |