diff options
Diffstat (limited to 'libnativeloader/library_namespaces.cpp')
| -rw-r--r-- | libnativeloader/library_namespaces.cpp | 54 |
1 files changed, 30 insertions, 24 deletions
diff --git a/libnativeloader/library_namespaces.cpp b/libnativeloader/library_namespaces.cpp index bcc19aaa41..1e29f4e457 100644 --- a/libnativeloader/library_namespaces.cpp +++ b/libnativeloader/library_namespaces.cpp @@ -30,6 +30,7 @@ #include <android-base/macros.h> #include <android-base/result.h> #include <android-base/strings.h> +#include <android-base/stringprintf.h> #include <nativehelper/scoped_utf_chars.h> #include "nativeloader/dlext_namespaces.h" @@ -55,24 +56,26 @@ constexpr const char* kVndkNamespaceName = "vndk"; // vndk_product namespace for unbundled product apps constexpr const char* kVndkProductNamespaceName = "vndk_product"; -// classloader-namespace is a linker namespace that is created for the loaded -// app. To be specific, it is created for the app classloader. When -// System.load() is called from a Java class that is loaded from the -// classloader, the classloader-namespace namespace associated with that -// classloader is selected for dlopen. The namespace is configured so that its -// search path is set to the app-local JNI directory and it is linked to the -// system namespace with the names of libs listed in the public.libraries.txt. -// This way an app can only load its own JNI libraries along with the public libs. -constexpr const char* kClassloaderNamespaceName = "classloader-namespace"; -// Same thing for vendor APKs. -constexpr const char* kVendorClassloaderNamespaceName = "vendor-classloader-namespace"; -// If the namespace is shared then add this suffix to form -// "classloader-namespace-shared" or "vendor-classloader-namespace-shared", -// respectively. A shared namespace (cf. ANDROID_NAMESPACE_TYPE_SHARED) has +// clns-XX is a linker namespace that is created for normal apps installed in +// the data partition. To be specific, it is created for the app classloader. +// When System.load() is called from a Java class that is loaded from the +// classloader, the clns namespace associated with that classloader is selected +// for dlopen. The namespace is configured so that its search path is set to the +// app-local JNI directory and it is linked to the system namespace with the +// names of libs listed in the public.libraries.txt and other public libraries. +// This way an app can only load its own JNI libraries along with the public +// libs. +constexpr const char* kClassloaderNamespaceName = "clns"; +// Same thing for unbundled APKs in the vendor partition. +constexpr const char* kVendorClassloaderNamespaceName = "vendor-clns"; +// Same thing for unbundled APKs in the product partition. +constexpr const char* kProductClassloaderNamespaceName = "product-clns"; +// If the namespace is shared then add this suffix to help identify it in debug +// messages. A shared namespace (cf. ANDROID_NAMESPACE_TYPE_SHARED) has // inherited all the libraries of the parent classloader namespace, or the -// system namespace for the main app classloader. It is used to give full -// access to the platform libraries for apps bundled in the system image, -// including their later updates installed in /data. +// system namespace for the main app classloader. It is used to give full access +// to the platform libraries for apps bundled in the system image, including +// their later updates installed in /data. constexpr const char* kSharedNamespaceSuffix = "-shared"; // (http://b/27588281) This is a workaround for apps using custom classloaders and calling @@ -89,7 +92,7 @@ constexpr const char* kProductLibPath = "/product/" LIB ":/system/product/" LIB; const std::regex kVendorDexPathRegex("(^|:)(/system)?/vendor/"); const std::regex kProductDexPathRegex("(^|:)(/system)?/product/"); -// Define origin of APK if it is from vendor partition or product partition +// Define origin partition of APK using ApkOrigin = enum { APK_ORIGIN_DEFAULT = 0, APK_ORIGIN_VENDOR = 1, // Includes both /vendor and /system/vendor @@ -252,7 +255,7 @@ Result<NativeLoaderNamespace*> LibraryNamespaces::Create(JNIEnv* env, uint32_t t // Different name is useful for debugging namespace_name = kVendorClassloaderNamespaceName; - } else if (apk_origin == APK_ORIGIN_PRODUCT && is_product_vndk_version_defined()) { + } else if (apk_origin == APK_ORIGIN_PRODUCT && is_product_treblelized()) { unbundled_app_origin = APK_ORIGIN_PRODUCT; apk_origin_msg = "unbundled product apk"; @@ -265,7 +268,7 @@ Result<NativeLoaderNamespace*> LibraryNamespaces::Create(JNIEnv* env, uint32_t t system_exposed_libraries = system_exposed_libraries + ':' + llndk_libraries_product(); // Different name is useful for debugging - namespace_name = kVendorClassloaderNamespaceName; + namespace_name = kProductClassloaderNamespaceName; } } @@ -275,6 +278,11 @@ Result<NativeLoaderNamespace*> LibraryNamespaces::Create(JNIEnv* env, uint32_t t namespace_name = namespace_name + kSharedNamespaceSuffix; } + // Append a unique number to the namespace name, to tell them apart when + // debugging linker issues, e.g. with debug.ld.all set to "dlopen,dlerror". + static int clns_count = 0; + namespace_name = android::base::StringPrintf("%s-%d", namespace_name.c_str(), ++clns_count); + ALOGD( "Configuring %s for %s %s. target_sdk_version=%u, uses_libraries=%s, library_path=%s, " "permitted_path=%s", @@ -291,8 +299,7 @@ Result<NativeLoaderNamespace*> LibraryNamespaces::Create(JNIEnv* env, uint32_t t // they are to other apps, including those in system, system_ext, and // product partitions. The reason is that when GSI is used, the system // partition may get replaced, and then vendor apps may fail. It's fine for - // product (and system_ext) apps, because those partitions aren't mounted in - // GSI tests. + // product apps, because that partition isn't mounted in GSI tests. auto libs = filter_public_libraries(target_sdk_version, uses_libraries, extended_public_libraries()); if (!libs.empty()) { @@ -399,8 +406,7 @@ Result<NativeLoaderNamespace*> LibraryNamespaces::Create(JNIEnv* env, uint32_t t product_public_libraries()); if (!product_libs.empty()) { auto target_ns = system_ns; - if (is_product_vndk_version_defined()) { - // If ro.product.vndk.version is defined, product namespace provides the product libraries. + if (is_product_treblelized()) { target_ns = NativeLoaderNamespace::GetExportedNamespace(kProductNamespaceName, is_bridged); } if (target_ns.ok()) { |