Loading libnativeloader/include/nativeloader/native_loader.h +1 −0 Original line number Diff line number Diff line Loading @@ -34,6 +34,7 @@ jstring CreateClassLoaderNamespace(JNIEnv* env, int32_t target_sdk_version, jobject class_loader, bool is_shared, bool is_for_vendor, jstring library_path, jstring permitted_path); Loading libnativeloader/native_loader.cpp +72 −6 Original line number Diff line number Diff line Loading @@ -82,6 +82,11 @@ static constexpr const char* kPublicNativeLibrariesSystemConfigPathFromRoot = "/etc/public.libraries.txt"; static constexpr const char* kPublicNativeLibrariesVendorConfig = "/vendor/etc/public.libraries.txt"; static constexpr const char* kLlndkNativeLibrariesSystemConfigPathFromRoot = "/etc/llndk.libraries.txt"; static constexpr const char* kVndkspNativeLibrariesSystemConfigPathFromRoot = "/etc/vndksp.libraries.txt"; // The device may be configured to have the vendor libraries loaded to a separate namespace. // For historical reasons this namespace was named sphal but effectively it is intended Loading @@ -89,6 +94,11 @@ static constexpr const char* kPublicNativeLibrariesVendorConfig = // vendor and system namespaces. static constexpr const char* kVendorNamespaceName = "sphal"; static constexpr const char* kVndkNamespaceName = "vndk"; static constexpr const char* kClassloaderNamespaceName = "classloader-namespace"; static constexpr const char* kVendorClassloaderNamespaceName = "vendor-classloader-namespace"; // (http://b/27588281) This is a workaround for apps using custom classloaders and calling // System.load() with an absolute path which is outside of the classloader library search path. // This list includes all directories app is allowed to access this way. Loading @@ -108,6 +118,7 @@ class LibraryNamespaces { uint32_t target_sdk_version, jobject class_loader, bool is_shared, bool is_for_vendor, jstring java_library_path, jstring java_permitted_path, NativeLoaderNamespace* ns, Loading Loading @@ -163,9 +174,39 @@ class LibraryNamespaces { is_native_bridge = NativeBridgeIsPathSupported(library_path.c_str()); } std::string system_exposed_libraries = system_public_libraries_; const char* namespace_name = kClassloaderNamespaceName; android_namespace_t* vndk_ns = nullptr; if (is_for_vendor && !is_shared) { LOG_FATAL_IF(is_native_bridge, "Unbundled vendor apk must not use translated architecture"); // For vendor apks, give access to the vendor lib even though // they are treated as unbundled; the libs and apks are still bundled // together in the vendor partition. #if defined(__LP64__) std::string vendor_lib_path = "/vendor/lib64"; #else std::string vendor_lib_path = "/vendor/lib"; #endif library_path = library_path + ":" + vendor_lib_path.c_str(); permitted_path = permitted_path + ":" + vendor_lib_path.c_str(); // Also give access to LLNDK libraries since they are available to vendors system_exposed_libraries = system_exposed_libraries + ":" + system_llndk_libraries_.c_str(); // Give access to VNDK-SP libraries from the 'vndk' namespace. vndk_ns = android_get_exported_namespace(kVndkNamespaceName); LOG_ALWAYS_FATAL_IF(vndk_ns == nullptr, "Cannot find \"%s\" namespace for vendor apks", kVndkNamespaceName); // Different name is useful for debugging namespace_name = kVendorClassloaderNamespaceName; ALOGD("classloader namespace configured for unbundled vendor apk. library_path=%s", library_path.c_str()); } NativeLoaderNamespace native_loader_ns; if (!is_native_bridge) { android_namespace_t* ns = android_create_namespace("classloader-namespace", android_namespace_t* ns = android_create_namespace(namespace_name, nullptr, library_path.c_str(), namespace_type, Loading @@ -181,10 +222,18 @@ class LibraryNamespaces { // which is expected behavior in this case. android_namespace_t* vendor_ns = android_get_exported_namespace(kVendorNamespaceName); if (!android_link_namespaces(ns, nullptr, system_public_libraries_.c_str())) { if (!android_link_namespaces(ns, nullptr, system_exposed_libraries.c_str())) { *error_msg = dlerror(); return false; } if (vndk_ns != nullptr && !system_vndksp_libraries_.empty()) { // vendor apks are allowed to use VNDK-SP libraries. if (!android_link_namespaces(ns, vndk_ns, system_vndksp_libraries_.c_str())) { *error_msg = dlerror(); return false; } } if (!vendor_public_libraries_.empty()) { if (!android_link_namespaces(ns, vendor_ns, vendor_public_libraries_.c_str())) { Loading @@ -195,7 +244,7 @@ class LibraryNamespaces { native_loader_ns = NativeLoaderNamespace(ns); } else { native_bridge_namespace_t* ns = NativeBridgeCreateNamespace("classloader-namespace", native_bridge_namespace_t* ns = NativeBridgeCreateNamespace(namespace_name, nullptr, library_path.c_str(), namespace_type, Loading @@ -209,7 +258,7 @@ class LibraryNamespaces { native_bridge_namespace_t* vendor_ns = NativeBridgeGetVendorNamespace(); if (!NativeBridgeLinkNamespaces(ns, nullptr, system_public_libraries_.c_str())) { if (!NativeBridgeLinkNamespaces(ns, nullptr, system_exposed_libraries.c_str())) { *error_msg = NativeBridgeGetError(); return false; } Loading Loading @@ -259,6 +308,10 @@ class LibraryNamespaces { std::string root_dir = android_root_env != nullptr ? android_root_env : "/system"; std::string public_native_libraries_system_config = root_dir + kPublicNativeLibrariesSystemConfigPathFromRoot; std::string llndk_native_libraries_system_config = root_dir + kLlndkNativeLibrariesSystemConfigPathFromRoot; std::string vndksp_native_libraries_system_config = root_dir + kVndkspNativeLibrariesSystemConfigPathFromRoot; std::string error_msg; LOG_ALWAYS_FATAL_IF(!ReadConfig(public_native_libraries_system_config, &sonames, &error_msg), Loading Loading @@ -293,6 +346,14 @@ class LibraryNamespaces { system_public_libraries_ = base::Join(sonames, ':'); sonames.clear(); ReadConfig(kLlndkNativeLibrariesSystemConfigPathFromRoot, &sonames); system_llndk_libraries_ = base::Join(sonames, ':'); sonames.clear(); ReadConfig(kVndkspNativeLibrariesSystemConfigPathFromRoot, &sonames); system_vndksp_libraries_ = base::Join(sonames, ':'); sonames.clear(); // This file is optional, quietly ignore if the file does not exist. ReadConfig(kPublicNativeLibrariesVendorConfig, &sonames); Loading Loading @@ -404,6 +465,8 @@ class LibraryNamespaces { std::vector<std::pair<jweak, NativeLoaderNamespace>> namespaces_; std::string system_public_libraries_; std::string vendor_public_libraries_; std::string system_llndk_libraries_; std::string system_vndksp_libraries_; DISALLOW_COPY_AND_ASSIGN(LibraryNamespaces); }; Loading @@ -430,6 +493,7 @@ jstring CreateClassLoaderNamespace(JNIEnv* env, int32_t target_sdk_version, jobject class_loader, bool is_shared, bool is_for_vendor, jstring library_path, jstring permitted_path) { #if defined(__ANDROID__) Loading @@ -441,6 +505,7 @@ jstring CreateClassLoaderNamespace(JNIEnv* env, target_sdk_version, class_loader, is_shared, is_for_vendor, library_path, permitted_path, &ns, Loading @@ -449,7 +514,7 @@ jstring CreateClassLoaderNamespace(JNIEnv* env, return env->NewStringUTF(error_msg.c_str()); } #else UNUSED(env, target_sdk_version, class_loader, is_shared, UNUSED(env, target_sdk_version, class_loader, is_shared, is_for_vendor, library_path, permitted_path); #endif return nullptr; Loading Loading @@ -478,7 +543,8 @@ void* OpenNativeLibrary(JNIEnv* env, if (!g_namespaces->Create(env, target_sdk_version, class_loader, false, false /* is_shared */, false /* is_for_vendor */, library_path, nullptr, &ns, Loading rootdir/Android.mk +42 −0 Original line number Diff line number Diff line Loading @@ -258,3 +258,45 @@ LOCAL_MODULE_PATH := $(TARGET_OUT_ETC) LOCAL_MODULE_STEM := $(LOCAL_MODULE) include $(BUILD_PREBUILT) endif ####################################### # llndk.libraries.txt include $(CLEAR_VARS) LOCAL_MODULE := llndk.libraries.txt LOCAL_MODULE_CLASS := ETC LOCAL_MODULE_PATH := $(TARGET_OUT_ETC) LOCAL_MODULE_STEM := $(LOCAL_MODULE) include $(BUILD_SYSTEM)/base_rules.mk llndk_md5 = $(word 1, $(shell echo $(LLNDK_LIBRARIES) | $(MD5SUM))) llndk_dep = $(intermediates)/$(llndk_md5).dep $(llndk_dep): $(hide) mkdir -p $(dir $@) && rm -rf $(dir $@)*.dep && touch $@ $(LOCAL_BUILT_MODULE): PRIVATE_LLNDK_LIBRARIES := $(LLNDK_LIBRARIES) $(LOCAL_BUILT_MODULE): $(llndk_dep) @echo "Generate: $@" @mkdir -p $(dir $@) $(hide) echo -n > $@ $(hide) $(foreach lib,$(PRIVATE_LLNDK_LIBRARIES), \ echo $(lib).so >> $@;) ####################################### # vndksp.libraries.txt include $(CLEAR_VARS) LOCAL_MODULE := vndksp.libraries.txt LOCAL_MODULE_CLASS := ETC LOCAL_MODULE_PATH := $(TARGET_OUT_ETC) LOCAL_MODULE_STEM := $(LOCAL_MODULE) include $(BUILD_SYSTEM)/base_rules.mk vndksp_md5 = $(word 1, $(shell echo $(LLNDK_LIBRARIES) | $(MD5SUM))) vndksp_dep = $(intermediates)/$(vndksp_md5).dep $(vndksp_dep): $(hide) mkdir -p $(dir $@) && rm -rf $(dir $@)*.dep && touch $@ $(LOCAL_BUILT_MODULE): PRIVATE_VNDK_SAMEPROCESS_LIBRARIES := $(VNDK_SAMEPROCESS_LIBRARIES) $(LOCAL_BUILT_MODULE): $(vndksp_dep) @echo "Generate: $@" @mkdir -p $(dir $@) $(hide) echo -n > $@ $(hide) $(foreach lib,$(PRIVATE_VNDK_SAMEPROCESS_LIBRARIES), \ echo $(lib).so >> $@;) rootdir/etc/ld.config.txt.in +3 −6 Original line number Diff line number Diff line Loading @@ -27,16 +27,12 @@ additional.namespaces = sphal,vndk,rs # can't be loaded in this namespace. ############################################################################### namespace.default.isolated = true # TODO(b/63553457): remove /vendor/lib from the search path. For now, this is # required since the classloader namespace for vendor apks should have access # vendor libraries in the directory. These search paths are copied to the search # paths of the classloader namespace. namespace.default.search.paths = /system/${LIB}:/vendor/${LIB} namespace.default.search.paths = /system/${LIB} # /vendor/app, /vendor/framework were added since libart should be able to dlopen # the odex files from the directory. namespace.default.permitted.paths = /system/${LIB}/drm:/system/${LIB}/hw:/system/framework:/system/app:/system/priv-app:/vendor/app:/vendor/framework:/oem/app:/data:/mnt/expand namespace.default.asan.search.paths = /data/asan/system/${LIB}:/system/${LIB}:/data/asan/vendor/${LIB}:/vendor/${LIB} namespace.default.asan.search.paths = /data/asan/system/${LIB}:/system/${LIB} namespace.default.asan.permitted.paths = /data:/system/${LIB}/drm:/system/${LIB}/hw:/system/framework:/system/app:/system/priv-app:/vendor/app:/vendor/framework:/oem/app:/mnt/expand ############################################################################### Loading Loading @@ -99,6 +95,7 @@ namespace.rs.link.vndk.shared_libs = %VNDK_SAMEPROCESS_LIBRARIES% # This namespace is exclusively for vndk-sp libs. ############################################################################### namespace.vndk.isolated = true namespace.vndk.visible = true namespace.vndk.search.paths = /vendor/${LIB}/vndk-sp:/system/${LIB}/vndk-sp namespace.vndk.permitted.paths = /vendor/${LIB}/hw:/vendor/${LIB}/egl Loading Loading
libnativeloader/include/nativeloader/native_loader.h +1 −0 Original line number Diff line number Diff line Loading @@ -34,6 +34,7 @@ jstring CreateClassLoaderNamespace(JNIEnv* env, int32_t target_sdk_version, jobject class_loader, bool is_shared, bool is_for_vendor, jstring library_path, jstring permitted_path); Loading
libnativeloader/native_loader.cpp +72 −6 Original line number Diff line number Diff line Loading @@ -82,6 +82,11 @@ static constexpr const char* kPublicNativeLibrariesSystemConfigPathFromRoot = "/etc/public.libraries.txt"; static constexpr const char* kPublicNativeLibrariesVendorConfig = "/vendor/etc/public.libraries.txt"; static constexpr const char* kLlndkNativeLibrariesSystemConfigPathFromRoot = "/etc/llndk.libraries.txt"; static constexpr const char* kVndkspNativeLibrariesSystemConfigPathFromRoot = "/etc/vndksp.libraries.txt"; // The device may be configured to have the vendor libraries loaded to a separate namespace. // For historical reasons this namespace was named sphal but effectively it is intended Loading @@ -89,6 +94,11 @@ static constexpr const char* kPublicNativeLibrariesVendorConfig = // vendor and system namespaces. static constexpr const char* kVendorNamespaceName = "sphal"; static constexpr const char* kVndkNamespaceName = "vndk"; static constexpr const char* kClassloaderNamespaceName = "classloader-namespace"; static constexpr const char* kVendorClassloaderNamespaceName = "vendor-classloader-namespace"; // (http://b/27588281) This is a workaround for apps using custom classloaders and calling // System.load() with an absolute path which is outside of the classloader library search path. // This list includes all directories app is allowed to access this way. Loading @@ -108,6 +118,7 @@ class LibraryNamespaces { uint32_t target_sdk_version, jobject class_loader, bool is_shared, bool is_for_vendor, jstring java_library_path, jstring java_permitted_path, NativeLoaderNamespace* ns, Loading Loading @@ -163,9 +174,39 @@ class LibraryNamespaces { is_native_bridge = NativeBridgeIsPathSupported(library_path.c_str()); } std::string system_exposed_libraries = system_public_libraries_; const char* namespace_name = kClassloaderNamespaceName; android_namespace_t* vndk_ns = nullptr; if (is_for_vendor && !is_shared) { LOG_FATAL_IF(is_native_bridge, "Unbundled vendor apk must not use translated architecture"); // For vendor apks, give access to the vendor lib even though // they are treated as unbundled; the libs and apks are still bundled // together in the vendor partition. #if defined(__LP64__) std::string vendor_lib_path = "/vendor/lib64"; #else std::string vendor_lib_path = "/vendor/lib"; #endif library_path = library_path + ":" + vendor_lib_path.c_str(); permitted_path = permitted_path + ":" + vendor_lib_path.c_str(); // Also give access to LLNDK libraries since they are available to vendors system_exposed_libraries = system_exposed_libraries + ":" + system_llndk_libraries_.c_str(); // Give access to VNDK-SP libraries from the 'vndk' namespace. vndk_ns = android_get_exported_namespace(kVndkNamespaceName); LOG_ALWAYS_FATAL_IF(vndk_ns == nullptr, "Cannot find \"%s\" namespace for vendor apks", kVndkNamespaceName); // Different name is useful for debugging namespace_name = kVendorClassloaderNamespaceName; ALOGD("classloader namespace configured for unbundled vendor apk. library_path=%s", library_path.c_str()); } NativeLoaderNamespace native_loader_ns; if (!is_native_bridge) { android_namespace_t* ns = android_create_namespace("classloader-namespace", android_namespace_t* ns = android_create_namespace(namespace_name, nullptr, library_path.c_str(), namespace_type, Loading @@ -181,10 +222,18 @@ class LibraryNamespaces { // which is expected behavior in this case. android_namespace_t* vendor_ns = android_get_exported_namespace(kVendorNamespaceName); if (!android_link_namespaces(ns, nullptr, system_public_libraries_.c_str())) { if (!android_link_namespaces(ns, nullptr, system_exposed_libraries.c_str())) { *error_msg = dlerror(); return false; } if (vndk_ns != nullptr && !system_vndksp_libraries_.empty()) { // vendor apks are allowed to use VNDK-SP libraries. if (!android_link_namespaces(ns, vndk_ns, system_vndksp_libraries_.c_str())) { *error_msg = dlerror(); return false; } } if (!vendor_public_libraries_.empty()) { if (!android_link_namespaces(ns, vendor_ns, vendor_public_libraries_.c_str())) { Loading @@ -195,7 +244,7 @@ class LibraryNamespaces { native_loader_ns = NativeLoaderNamespace(ns); } else { native_bridge_namespace_t* ns = NativeBridgeCreateNamespace("classloader-namespace", native_bridge_namespace_t* ns = NativeBridgeCreateNamespace(namespace_name, nullptr, library_path.c_str(), namespace_type, Loading @@ -209,7 +258,7 @@ class LibraryNamespaces { native_bridge_namespace_t* vendor_ns = NativeBridgeGetVendorNamespace(); if (!NativeBridgeLinkNamespaces(ns, nullptr, system_public_libraries_.c_str())) { if (!NativeBridgeLinkNamespaces(ns, nullptr, system_exposed_libraries.c_str())) { *error_msg = NativeBridgeGetError(); return false; } Loading Loading @@ -259,6 +308,10 @@ class LibraryNamespaces { std::string root_dir = android_root_env != nullptr ? android_root_env : "/system"; std::string public_native_libraries_system_config = root_dir + kPublicNativeLibrariesSystemConfigPathFromRoot; std::string llndk_native_libraries_system_config = root_dir + kLlndkNativeLibrariesSystemConfigPathFromRoot; std::string vndksp_native_libraries_system_config = root_dir + kVndkspNativeLibrariesSystemConfigPathFromRoot; std::string error_msg; LOG_ALWAYS_FATAL_IF(!ReadConfig(public_native_libraries_system_config, &sonames, &error_msg), Loading Loading @@ -293,6 +346,14 @@ class LibraryNamespaces { system_public_libraries_ = base::Join(sonames, ':'); sonames.clear(); ReadConfig(kLlndkNativeLibrariesSystemConfigPathFromRoot, &sonames); system_llndk_libraries_ = base::Join(sonames, ':'); sonames.clear(); ReadConfig(kVndkspNativeLibrariesSystemConfigPathFromRoot, &sonames); system_vndksp_libraries_ = base::Join(sonames, ':'); sonames.clear(); // This file is optional, quietly ignore if the file does not exist. ReadConfig(kPublicNativeLibrariesVendorConfig, &sonames); Loading Loading @@ -404,6 +465,8 @@ class LibraryNamespaces { std::vector<std::pair<jweak, NativeLoaderNamespace>> namespaces_; std::string system_public_libraries_; std::string vendor_public_libraries_; std::string system_llndk_libraries_; std::string system_vndksp_libraries_; DISALLOW_COPY_AND_ASSIGN(LibraryNamespaces); }; Loading @@ -430,6 +493,7 @@ jstring CreateClassLoaderNamespace(JNIEnv* env, int32_t target_sdk_version, jobject class_loader, bool is_shared, bool is_for_vendor, jstring library_path, jstring permitted_path) { #if defined(__ANDROID__) Loading @@ -441,6 +505,7 @@ jstring CreateClassLoaderNamespace(JNIEnv* env, target_sdk_version, class_loader, is_shared, is_for_vendor, library_path, permitted_path, &ns, Loading @@ -449,7 +514,7 @@ jstring CreateClassLoaderNamespace(JNIEnv* env, return env->NewStringUTF(error_msg.c_str()); } #else UNUSED(env, target_sdk_version, class_loader, is_shared, UNUSED(env, target_sdk_version, class_loader, is_shared, is_for_vendor, library_path, permitted_path); #endif return nullptr; Loading Loading @@ -478,7 +543,8 @@ void* OpenNativeLibrary(JNIEnv* env, if (!g_namespaces->Create(env, target_sdk_version, class_loader, false, false /* is_shared */, false /* is_for_vendor */, library_path, nullptr, &ns, Loading
rootdir/Android.mk +42 −0 Original line number Diff line number Diff line Loading @@ -258,3 +258,45 @@ LOCAL_MODULE_PATH := $(TARGET_OUT_ETC) LOCAL_MODULE_STEM := $(LOCAL_MODULE) include $(BUILD_PREBUILT) endif ####################################### # llndk.libraries.txt include $(CLEAR_VARS) LOCAL_MODULE := llndk.libraries.txt LOCAL_MODULE_CLASS := ETC LOCAL_MODULE_PATH := $(TARGET_OUT_ETC) LOCAL_MODULE_STEM := $(LOCAL_MODULE) include $(BUILD_SYSTEM)/base_rules.mk llndk_md5 = $(word 1, $(shell echo $(LLNDK_LIBRARIES) | $(MD5SUM))) llndk_dep = $(intermediates)/$(llndk_md5).dep $(llndk_dep): $(hide) mkdir -p $(dir $@) && rm -rf $(dir $@)*.dep && touch $@ $(LOCAL_BUILT_MODULE): PRIVATE_LLNDK_LIBRARIES := $(LLNDK_LIBRARIES) $(LOCAL_BUILT_MODULE): $(llndk_dep) @echo "Generate: $@" @mkdir -p $(dir $@) $(hide) echo -n > $@ $(hide) $(foreach lib,$(PRIVATE_LLNDK_LIBRARIES), \ echo $(lib).so >> $@;) ####################################### # vndksp.libraries.txt include $(CLEAR_VARS) LOCAL_MODULE := vndksp.libraries.txt LOCAL_MODULE_CLASS := ETC LOCAL_MODULE_PATH := $(TARGET_OUT_ETC) LOCAL_MODULE_STEM := $(LOCAL_MODULE) include $(BUILD_SYSTEM)/base_rules.mk vndksp_md5 = $(word 1, $(shell echo $(LLNDK_LIBRARIES) | $(MD5SUM))) vndksp_dep = $(intermediates)/$(vndksp_md5).dep $(vndksp_dep): $(hide) mkdir -p $(dir $@) && rm -rf $(dir $@)*.dep && touch $@ $(LOCAL_BUILT_MODULE): PRIVATE_VNDK_SAMEPROCESS_LIBRARIES := $(VNDK_SAMEPROCESS_LIBRARIES) $(LOCAL_BUILT_MODULE): $(vndksp_dep) @echo "Generate: $@" @mkdir -p $(dir $@) $(hide) echo -n > $@ $(hide) $(foreach lib,$(PRIVATE_VNDK_SAMEPROCESS_LIBRARIES), \ echo $(lib).so >> $@;)
rootdir/etc/ld.config.txt.in +3 −6 Original line number Diff line number Diff line Loading @@ -27,16 +27,12 @@ additional.namespaces = sphal,vndk,rs # can't be loaded in this namespace. ############################################################################### namespace.default.isolated = true # TODO(b/63553457): remove /vendor/lib from the search path. For now, this is # required since the classloader namespace for vendor apks should have access # vendor libraries in the directory. These search paths are copied to the search # paths of the classloader namespace. namespace.default.search.paths = /system/${LIB}:/vendor/${LIB} namespace.default.search.paths = /system/${LIB} # /vendor/app, /vendor/framework were added since libart should be able to dlopen # the odex files from the directory. namespace.default.permitted.paths = /system/${LIB}/drm:/system/${LIB}/hw:/system/framework:/system/app:/system/priv-app:/vendor/app:/vendor/framework:/oem/app:/data:/mnt/expand namespace.default.asan.search.paths = /data/asan/system/${LIB}:/system/${LIB}:/data/asan/vendor/${LIB}:/vendor/${LIB} namespace.default.asan.search.paths = /data/asan/system/${LIB}:/system/${LIB} namespace.default.asan.permitted.paths = /data:/system/${LIB}/drm:/system/${LIB}/hw:/system/framework:/system/app:/system/priv-app:/vendor/app:/vendor/framework:/oem/app:/mnt/expand ############################################################################### Loading Loading @@ -99,6 +95,7 @@ namespace.rs.link.vndk.shared_libs = %VNDK_SAMEPROCESS_LIBRARIES% # This namespace is exclusively for vndk-sp libs. ############################################################################### namespace.vndk.isolated = true namespace.vndk.visible = true namespace.vndk.search.paths = /vendor/${LIB}/vndk-sp:/system/${LIB}/vndk-sp namespace.vndk.permitted.paths = /vendor/${LIB}/hw:/vendor/${LIB}/egl Loading