From 807d9d62d8360ce954ab01e77a3fd0f0ee80b4e6 Mon Sep 17 00:00:00 2001 From: Ryan Prichard Date: Mon, 15 Jul 2019 13:35:31 -0700 Subject: [PATCH 1/2] Switch libvndksupport's linker.c to C++ Bug: none Test: device boots Change-Id: I64237006a7f903647c8d8f7ca681b1da23ac53a9 --- libvndksupport/Android.bp | 2 +- libvndksupport/{linker.c => linker.cpp} | 9 ++++++--- 2 files changed, 7 insertions(+), 4 deletions(-) rename libvndksupport/{linker.c => linker.cpp} (87%) diff --git a/libvndksupport/Android.bp b/libvndksupport/Android.bp index e5b536cae..f4544a14c 100644 --- a/libvndksupport/Android.bp +++ b/libvndksupport/Android.bp @@ -3,7 +3,7 @@ subdirs = ["tests"] cc_library { name: "libvndksupport", native_bridge_supported: true, - srcs: ["linker.c"], + srcs: ["linker.cpp"], cflags: [ "-Wall", "-Werror", diff --git a/libvndksupport/linker.c b/libvndksupport/linker.cpp similarity index 87% rename from libvndksupport/linker.c rename to libvndksupport/linker.cpp index 84c21324f..057e5b197 100644 --- a/libvndksupport/linker.c +++ b/libvndksupport/linker.cpp @@ -23,8 +23,10 @@ #include #include -__attribute__((weak)) extern struct android_namespace_t* android_get_exported_namespace(const char*); -__attribute__((weak)) extern void* android_dlopen_ext(const char*, int, const android_dlextinfo*); +__attribute__((weak)) extern "C" struct android_namespace_t* android_get_exported_namespace( + const char*); +__attribute__((weak)) extern "C" void* android_dlopen_ext(const char*, int, + const android_dlextinfo*); static const char* namespace_name = NULL; @@ -67,7 +69,8 @@ void* android_load_sphal_library(const char* name, int flag) { struct android_namespace_t* vendor_namespace = get_vendor_namespace(); if (vendor_namespace != NULL) { const android_dlextinfo dlextinfo = { - .flags = ANDROID_DLEXT_USE_NAMESPACE, .library_namespace = vendor_namespace, + .flags = ANDROID_DLEXT_USE_NAMESPACE, + .library_namespace = vendor_namespace, }; void* handle = NULL; if (android_dlopen_ext != NULL) { From 8c733615aa1bcf52e6bede6dbfe3d3a8a606f39c Mon Sep 17 00:00:00 2001 From: Ryan Prichard Date: Mon, 15 Jul 2019 13:40:05 -0700 Subject: [PATCH 2/2] Make android_load_sphal_library thread-safe Also: remove an obsolete comment from linker_test.cpp. The test program is at /data/nativetest[64]/libvndksupport-tests/libvndksupport-tests, which may will be in the system or legacy configuration, and either the "sphal" or "default" namespace will be visible. Bug: none Test: run libvndksupport-tests, device boots Change-Id: I5e33e5bf1402a0368e046b03827c216789b02c96 --- libvndksupport/linker.cpp | 61 +++++++++++++++------------- libvndksupport/tests/linker_test.cpp | 5 --- 2 files changed, 33 insertions(+), 33 deletions(-) diff --git a/libvndksupport/linker.cpp b/libvndksupport/linker.cpp index 057e5b197..cf0f6186d 100644 --- a/libvndksupport/linker.cpp +++ b/libvndksupport/linker.cpp @@ -13,40 +13,44 @@ * See the License for the specific language governing permissions and * limitations under the License. */ + +#define LOG_TAG "vndksupport" + #include "linker.h" #include #include - -#define LOG_TAG "vndksupport" #include #include #include -__attribute__((weak)) extern "C" struct android_namespace_t* android_get_exported_namespace( - const char*); +#include + +__attribute__((weak)) extern "C" android_namespace_t* android_get_exported_namespace(const char*); __attribute__((weak)) extern "C" void* android_dlopen_ext(const char*, int, const android_dlextinfo*); -static const char* namespace_name = NULL; +namespace { -static struct android_namespace_t* get_vendor_namespace() { - const char* namespace_names[] = {"sphal", "default", NULL}; - static struct android_namespace_t* vendor_namespace = NULL; - if (vendor_namespace == NULL) { - int name_idx = 0; - while (namespace_names[name_idx] != NULL) { - if (android_get_exported_namespace != NULL) { - vendor_namespace = android_get_exported_namespace(namespace_names[name_idx]); +struct VendorNamespace { + android_namespace_t* ptr = nullptr; + const char* name = nullptr; +}; + +} // anonymous namespace + +static VendorNamespace get_vendor_namespace() { + static VendorNamespace result = ([] { + for (const char* name : {"sphal", "default"}) { + if (android_get_exported_namespace != nullptr) { + if (android_namespace_t* ns = android_get_exported_namespace(name)) { + return VendorNamespace{ns, name}; + } } - if (vendor_namespace != NULL) { - namespace_name = namespace_names[name_idx]; - break; - } - name_idx++; } - } - return vendor_namespace; + return VendorNamespace{}; + })(); + return result; } int android_is_in_vendor_process() { @@ -55,29 +59,30 @@ int android_is_in_vendor_process() { if (getpid() == 1) { return 0; } - if (android_get_exported_namespace == NULL) { + if (android_get_exported_namespace == nullptr) { ALOGD("android_get_exported_namespace() not available. Assuming system process."); return 0; } // In vendor process, 'vndk' namespace is not visible, whereas in system // process, it is. - return android_get_exported_namespace("vndk") == NULL; + return android_get_exported_namespace("vndk") == nullptr; } void* android_load_sphal_library(const char* name, int flag) { - struct android_namespace_t* vendor_namespace = get_vendor_namespace(); - if (vendor_namespace != NULL) { + VendorNamespace vendor_namespace = get_vendor_namespace(); + if (vendor_namespace.ptr != nullptr) { const android_dlextinfo dlextinfo = { .flags = ANDROID_DLEXT_USE_NAMESPACE, - .library_namespace = vendor_namespace, + .library_namespace = vendor_namespace.ptr, }; - void* handle = NULL; - if (android_dlopen_ext != NULL) { + void* handle = nullptr; + if (android_dlopen_ext != nullptr) { handle = android_dlopen_ext(name, flag, &dlextinfo); } if (!handle) { - ALOGE("Could not load %s from %s namespace: %s.", name, namespace_name, dlerror()); + ALOGE("Could not load %s from %s namespace: %s.", name, vendor_namespace.name, + dlerror()); } return handle; } else { diff --git a/libvndksupport/tests/linker_test.cpp b/libvndksupport/tests/linker_test.cpp index 7ce27d411..d0c8ef753 100644 --- a/libvndksupport/tests/linker_test.cpp +++ b/libvndksupport/tests/linker_test.cpp @@ -21,11 +21,6 @@ #include #include -// Since the test executable will be in /data and ld.config.txt does not -// configure sphal namespace for executables in /data, the call to -// android_load_sphal_library will always fallback to the plain dlopen from the -// default namespace. - // Let's use libEGL_.so as a SP-HAL in test static std::string find_sphal_lib() { const char* path =