OSDN Git Service

libvulkan: Load layer libraries into the app namespace
authorJesse Hall <jessehall@google.com>
Thu, 12 May 2016 05:56:29 +0000 (22:56 -0700)
committerJesse Hall <jessehall@google.com>
Thu, 12 May 2016 16:56:17 +0000 (09:56 -0700)
Bug: 28213888
Change-Id: I79901693c30f0e69730643b424e504a8d3628624

vulkan/include/vulkan/vulkan_loader_data.h
vulkan/libvulkan/layers_extensions.cpp
vulkan/libvulkan/vulkan_loader_data.cpp

index 968a7aa..8ea4666 100644 (file)
 
 #include <string>
 
+struct android_namespace_t;
+
 namespace vulkan {
     struct LoaderData {
         std::string layer_path;
+        android_namespace_t* app_namespace;
+
         __attribute__((visibility("default"))) static LoaderData& GetInstance();
     };
 }
index 563e5c4..4505f41 100644 (file)
@@ -26,6 +26,7 @@
 #include <vector>
 
 #include <android-base/strings.h>
+#include <android/dlext.h>
 #include <cutils/properties.h>
 #include <log/log.h>
 #include <ziparchive/zip_archive.h>
@@ -104,6 +105,22 @@ bool LayerLibrary::Open() {
     std::lock_guard<std::mutex> lock(mutex_);
     if (refcount_++ == 0) {
         ALOGV("opening layer library '%s'", path_.c_str());
+        // Libraries in the system layer library dir can't be loaded into
+        // the application namespace. That causes compatibility problems, since
+        // any symbol dependencies will be resolved by system libraries. They
+        // can't safely use libc++_shared, for example. Which is one reason
+        // (among several) we only allow them in non-user builds.
+        auto app_namespace = LoaderData::GetInstance().app_namespace;
+        if (app_namespace &&
+            !android::base::StartsWith(path_, kSystemLayerLibraryDir)) {
+            android_dlextinfo dlextinfo = {};
+            dlextinfo.flags = ANDROID_DLEXT_USE_NAMESPACE;
+            dlextinfo.library_namespace = app_namespace;
+            dlhandle_ = android_dlopen_ext(path_.c_str(), RTLD_NOW | RTLD_LOCAL,
+                                           &dlextinfo);
+        } else {
+            dlhandle_ = dlopen(path_.c_str(), RTLD_NOW | RTLD_LOCAL);
+        }
         dlhandle_ = dlopen(path_.c_str(), RTLD_NOW | RTLD_LOCAL);
         if (!dlhandle_) {
             ALOGE("failed to load layer library '%s': %s", path_.c_str(),
index a6a0295..0eda0af 100644 (file)
@@ -19,6 +19,6 @@
 using namespace vulkan;
 
 LoaderData& LoaderData::GetInstance() {
-    static LoaderData loader_data;
+    static LoaderData loader_data = {};
     return loader_data;
 }