From 8f4afc8298ebae34e8f944a0807943997908c67d Mon Sep 17 00:00:00 2001 From: Jiyong Park Date: Mon, 22 Jul 2019 14:20:40 +0900 Subject: [PATCH] Use android::base::Result in libnativeloader Remove the out parameters for error messages using Result. Bug: 130388701 Test: libnativeloader_test Change-Id: Idbaf391c183fb20d5e1d7c96f3a4ccbf9745b7e6 --- libnativeloader/library_namespaces.cpp | 87 +++++++------- libnativeloader/library_namespaces.h | 11 +- libnativeloader/native_loader.cpp | 33 +++--- libnativeloader/native_loader_namespace.cpp | 96 ++++++++++------ libnativeloader/native_loader_namespace.h | 26 ++--- libnativeloader/public_libraries.cpp | 119 +++++++++++--------- 6 files changed, 213 insertions(+), 159 deletions(-) diff --git a/libnativeloader/library_namespaces.cpp b/libnativeloader/library_namespaces.cpp index c22ce8abf..a9eea8cc9 100644 --- a/libnativeloader/library_namespaces.cpp +++ b/libnativeloader/library_namespaces.cpp @@ -33,6 +33,8 @@ #include "public_libraries.h" #include "utils.h" +using android::base::Error; + namespace android::nativeloader { namespace { @@ -128,11 +130,11 @@ void LibraryNamespaces::Initialize() { } } -NativeLoaderNamespace* LibraryNamespaces::Create(JNIEnv* env, uint32_t target_sdk_version, - jobject class_loader, bool is_shared, - jstring dex_path, jstring java_library_path, - jstring java_permitted_path, - std::string* error_msg) { +Result LibraryNamespaces::Create(JNIEnv* env, uint32_t target_sdk_version, + jobject class_loader, bool is_shared, + jstring dex_path, + jstring java_library_path, + jstring java_permitted_path) { std::string library_path; // empty string by default. if (java_library_path != nullptr) { @@ -158,14 +160,14 @@ NativeLoaderNamespace* LibraryNamespaces::Create(JNIEnv* env, uint32_t target_sd } // Initialize the anonymous namespace with the first non-empty library path. + Result ret; if (!library_path.empty() && !initialized_ && - !InitPublicNamespace(library_path.c_str(), error_msg)) { - return nullptr; + !(ret = InitPublicNamespace(library_path.c_str()))) { + return ret.error(); } - bool found = FindNamespaceByClassLoader(env, class_loader); - - LOG_ALWAYS_FATAL_IF(found, "There is already a namespace associated with this classloader"); + LOG_ALWAYS_FATAL_IF(FindNamespaceByClassLoader(env, class_loader) != nullptr, + "There is already a namespace associated with this classloader"); std::string system_exposed_libraries = default_public_libraries(); const char* namespace_name = kClassloaderNamespaceName; @@ -216,58 +218,66 @@ NativeLoaderNamespace* LibraryNamespaces::Create(JNIEnv* env, uint32_t target_sd auto app_ns = NativeLoaderNamespace::Create(namespace_name, library_path, permitted_path, parent_ns, is_shared, target_sdk_version < 24 /* is_greylist_enabled */); - if (app_ns.IsNil()) { - *error_msg = app_ns.GetError(); - return nullptr; + if (!app_ns) { + return app_ns.error(); } // ... and link to other namespaces to allow access to some public libraries - bool is_bridged = app_ns.IsBridged(); + bool is_bridged = app_ns->IsBridged(); auto platform_ns = NativeLoaderNamespace::GetPlatformNamespace(is_bridged); - if (!app_ns.Link(platform_ns, system_exposed_libraries)) { - *error_msg = app_ns.GetError(); - return nullptr; + if (!platform_ns) { + return platform_ns.error(); + } + + auto linked = app_ns->Link(*platform_ns, system_exposed_libraries); + if (!linked) { + return linked.error(); } auto runtime_ns = NativeLoaderNamespace::GetExportedNamespace(kRuntimeNamespaceName, is_bridged); // Runtime apex does not exist in host, and under certain build conditions. - if (!runtime_ns.IsNil()) { - if (!app_ns.Link(runtime_ns, runtime_public_libraries())) { - *error_msg = app_ns.GetError(); - return nullptr; + if (runtime_ns) { + linked = app_ns->Link(*runtime_ns, runtime_public_libraries()); + if (!linked) { + return linked.error(); } } // Give access to NNAPI libraries (apex-updated LLNDK library). auto nnapi_ns = NativeLoaderNamespace::GetExportedNamespace(kNeuralNetworksNamespaceName, is_bridged); - if (!app_ns.Link(nnapi_ns, neuralnetworks_public_libraries())) { - *error_msg = app_ns.GetError(); - return nullptr; + if (nnapi_ns) { + linked = app_ns->Link(*nnapi_ns, neuralnetworks_public_libraries()); + if (!linked) { + return linked.error(); + } } // Give access to VNDK-SP libraries from the 'vndk' namespace. if (unbundled_vendor_or_product_app && !vndksp_libraries().empty()) { auto vndk_ns = NativeLoaderNamespace::GetExportedNamespace(kVndkNamespaceName, is_bridged); - if (!vndk_ns.IsNil() && !app_ns.Link(vndk_ns, vndksp_libraries())) { - *error_msg = app_ns.GetError(); - return nullptr; + if (vndk_ns) { + linked = app_ns->Link(*vndk_ns, vndksp_libraries()); + if (!linked) { + return linked.error(); + } } } - // Note that when vendor_ns is not configured, vendor_ns.IsNil() will be true - // and it will result in linking to the default namespace which is expected - // behavior in this case. if (!vendor_public_libraries().empty()) { auto vendor_ns = NativeLoaderNamespace::GetExportedNamespace(kVendorNamespaceName, is_bridged); - if (!app_ns.Link(vendor_ns, vendor_public_libraries())) { - *error_msg = dlerror(); - return nullptr; + // when vendor_ns is not configured, link to the platform namespace + auto target_ns = vendor_ns ? vendor_ns : platform_ns; + if (target_ns) { + linked = app_ns->Link(*target_ns, vendor_public_libraries()); + if (!linked) { + return linked.error(); + } } } - namespaces_.push_back(std::make_pair(env->NewWeakGlobalRef(class_loader), app_ns)); + namespaces_.push_back(std::make_pair(env->NewWeakGlobalRef(class_loader), *app_ns)); return &(namespaces_.back().second); } @@ -285,7 +295,7 @@ NativeLoaderNamespace* LibraryNamespaces::FindNamespaceByClassLoader(JNIEnv* env return nullptr; } -bool LibraryNamespaces::InitPublicNamespace(const char* library_path, std::string* error_msg) { +Result LibraryNamespaces::InitPublicNamespace(const char* library_path) { // Ask native bride if this apps library path should be handled by it bool is_native_bridge = NativeBridgeIsPathSupported(library_path); @@ -296,8 +306,7 @@ bool LibraryNamespaces::InitPublicNamespace(const char* library_path, std::strin initialized_ = android_init_anonymous_namespace(default_public_libraries().c_str(), is_native_bridge ? nullptr : library_path); if (!initialized_) { - *error_msg = dlerror(); - return false; + return Error() << dlerror(); } // and now initialize native bridge namespaces if necessary. @@ -305,11 +314,11 @@ bool LibraryNamespaces::InitPublicNamespace(const char* library_path, std::strin initialized_ = NativeBridgeInitAnonymousNamespace(default_public_libraries().c_str(), is_native_bridge ? library_path : nullptr); if (!initialized_) { - *error_msg = NativeBridgeGetError(); + return Error() << NativeBridgeGetError(); } } - return initialized_; + return {}; } NativeLoaderNamespace* LibraryNamespaces::FindParentNamespaceByClassLoader(JNIEnv* env, diff --git a/libnativeloader/library_namespaces.h b/libnativeloader/library_namespaces.h index 6e9a19047..e54bc0a56 100644 --- a/libnativeloader/library_namespaces.h +++ b/libnativeloader/library_namespaces.h @@ -25,10 +25,13 @@ #include #include +#include #include namespace android::nativeloader { +using android::base::Result; + // LibraryNamespaces is a singleton object that manages NativeLoaderNamespace // objects for an app process. Its main job is to create (and configure) a new // NativeLoaderNamespace object for a Java ClassLoader, and to find an existing @@ -46,13 +49,13 @@ class LibraryNamespaces { namespaces_.clear(); initialized_ = false; } - NativeLoaderNamespace* Create(JNIEnv* env, uint32_t target_sdk_version, jobject class_loader, - bool is_shared, jstring dex_path, jstring java_library_path, - jstring java_permitted_path, std::string* error_msg); + Result Create(JNIEnv* env, uint32_t target_sdk_version, + jobject class_loader, bool is_shared, jstring dex_path, + jstring java_library_path, jstring java_permitted_path); NativeLoaderNamespace* FindNamespaceByClassLoader(JNIEnv* env, jobject class_loader); private: - bool InitPublicNamespace(const char* library_path, std::string* error_msg); + Result InitPublicNamespace(const char* library_path); NativeLoaderNamespace* FindParentNamespaceByClassLoader(JNIEnv* env, jobject class_loader); bool initialized_; diff --git a/libnativeloader/native_loader.cpp b/libnativeloader/native_loader.cpp index 0c29324e6..6d3c057b9 100644 --- a/libnativeloader/native_loader.cpp +++ b/libnativeloader/native_loader.cpp @@ -92,12 +92,10 @@ jstring CreateClassLoaderNamespace(JNIEnv* env, int32_t target_sdk_version, jobj jstring permitted_path) { #if defined(__ANDROID__) std::lock_guard guard(g_namespaces_mutex); - - std::string error_msg; - bool success = g_namespaces->Create(env, target_sdk_version, class_loader, is_shared, dex_path, - library_path, permitted_path, &error_msg) != nullptr; - if (!success) { - return env->NewStringUTF(error_msg.c_str()); + auto ns = g_namespaces->Create(env, target_sdk_version, class_loader, is_shared, dex_path, + library_path, permitted_path); + if (!ns) { + return env->NewStringUTF(ns.error().message().c_str()); } #else UNUSED(env, target_sdk_version, class_loader, is_shared, dex_path, library_path, permitted_path); @@ -139,11 +137,14 @@ void* OpenNativeLibrary(JNIEnv* env, int32_t target_sdk_version, const char* pat if ((ns = g_namespaces->FindNamespaceByClassLoader(env, class_loader)) == nullptr) { // This is the case where the classloader was not created by ApplicationLoaders // In this case we create an isolated not-shared namespace for it. - std::string create_error_msg; - if ((ns = g_namespaces->Create(env, target_sdk_version, class_loader, false /* is_shared */, - nullptr, library_path, nullptr, &create_error_msg)) == nullptr) { - *error_msg = strdup(create_error_msg.c_str()); + Result isolated_ns = + g_namespaces->Create(env, target_sdk_version, class_loader, false /* is_shared */, nullptr, + library_path, nullptr); + if (!isolated_ns) { + *error_msg = strdup(isolated_ns.error().message().c_str()); return nullptr; + } else { + ns = *isolated_ns; } } @@ -222,12 +223,14 @@ void NativeLoaderFreeErrorMessage(char* msg) { #if defined(__ANDROID__) void* OpenNativeLibraryInNamespace(NativeLoaderNamespace* ns, const char* path, bool* needs_native_bridge, char** error_msg) { - void* handle = ns->Load(path); - if (handle == nullptr) { - *error_msg = ns->GetError(); + auto handle = ns->Load(path); + if (!handle && error_msg != nullptr) { + *error_msg = strdup(handle.error().message().c_str()); } - *needs_native_bridge = ns->IsBridged(); - return handle; + if (needs_native_bridge != nullptr) { + *needs_native_bridge = ns->IsBridged(); + } + return handle ? *handle : nullptr; } // native_bridge_namespaces are not supported for callers of this function. diff --git a/libnativeloader/native_loader_namespace.cpp b/libnativeloader/native_loader_namespace.cpp index 58ac6869b..4b0211670 100644 --- a/libnativeloader/native_loader_namespace.cpp +++ b/libnativeloader/native_loader_namespace.cpp @@ -28,6 +28,9 @@ #include "nativeloader/dlext_namespaces.h" +using android::base::Error; +using android::base::Errorf; + namespace android { namespace { @@ -35,41 +38,46 @@ namespace { constexpr const char* kDefaultNamespaceName = "default"; constexpr const char* kPlatformNamespaceName = "platform"; -} // namespace - -NativeLoaderNamespace NativeLoaderNamespace::GetExportedNamespace(const std::string& name, - bool is_bridged) { - if (!is_bridged) { - return NativeLoaderNamespace(name, android_get_exported_namespace(name.c_str())); - } else { - return NativeLoaderNamespace(name, NativeBridgeGetExportedNamespace(name.c_str())); +std::string GetLinkerError(bool is_bridged) { + const char* msg = is_bridged ? NativeBridgeGetError() : dlerror(); + if (msg == nullptr) { + return "no error"; } + return std::string(msg); } -char* NativeLoaderNamespace::GetError() const { - if (!IsBridged()) { - return strdup(dlerror()); +} // namespace + +Result NativeLoaderNamespace::GetExportedNamespace(const std::string& name, + bool is_bridged) { + if (!is_bridged) { + auto raw = android_get_exported_namespace(name.c_str()); + if (raw != nullptr) { + return NativeLoaderNamespace(name, raw); + } } else { - return strdup(NativeBridgeGetError()); + auto raw = NativeBridgeGetExportedNamespace(name.c_str()); + if (raw != nullptr) { + return NativeLoaderNamespace(name, raw); + } } + return Errorf("namespace {} does not exist or exported", name); } // The platform namespace is called "default" for binaries in /system and // "platform" for those in the Runtime APEX. Try "platform" first since // "default" always exists. -NativeLoaderNamespace NativeLoaderNamespace::GetPlatformNamespace(bool is_bridged) { - NativeLoaderNamespace ns = GetExportedNamespace(kPlatformNamespaceName, is_bridged); - if (ns.IsNil()) { +Result NativeLoaderNamespace::GetPlatformNamespace(bool is_bridged) { + auto ns = GetExportedNamespace(kPlatformNamespaceName, is_bridged); + if (!ns) { ns = GetExportedNamespace(kDefaultNamespaceName, is_bridged); } return ns; } -NativeLoaderNamespace NativeLoaderNamespace::Create(const std::string& name, - const std::string& search_paths, - const std::string& permitted_paths, - const NativeLoaderNamespace* parent, - bool is_shared, bool is_greylist_enabled) { +Result NativeLoaderNamespace::Create( + const std::string& name, const std::string& search_paths, const std::string& permitted_paths, + const NativeLoaderNamespace* parent, bool is_shared, bool is_greylist_enabled) { bool is_bridged = false; if (parent != nullptr) { is_bridged = parent->IsBridged(); @@ -78,8 +86,11 @@ NativeLoaderNamespace NativeLoaderNamespace::Create(const std::string& name, } // Fall back to the platform namespace if no parent is set. - const NativeLoaderNamespace& effective_parent = - parent != nullptr ? *parent : GetPlatformNamespace(is_bridged); + auto platform_ns = GetPlatformNamespace(is_bridged); + if (!platform_ns) { + return platform_ns.error(); + } + const NativeLoaderNamespace& effective_parent = parent != nullptr ? *parent : *platform_ns; uint64_t type = ANDROID_NAMESPACE_TYPE_ISOLATED; if (is_shared) { @@ -93,37 +104,56 @@ NativeLoaderNamespace NativeLoaderNamespace::Create(const std::string& name, android_namespace_t* raw = android_create_namespace(name.c_str(), nullptr, search_paths.c_str(), type, permitted_paths.c_str(), effective_parent.ToRawAndroidNamespace()); - return NativeLoaderNamespace(name, raw); + if (raw != nullptr) { + return NativeLoaderNamespace(name, raw); + } } else { native_bridge_namespace_t* raw = NativeBridgeCreateNamespace( name.c_str(), nullptr, search_paths.c_str(), type, permitted_paths.c_str(), effective_parent.ToRawNativeBridgeNamespace()); - return NativeLoaderNamespace(name, raw); + if (raw != nullptr) { + return NativeLoaderNamespace(name, raw); + } } + return Errorf("failed to create {} namespace name:{}, search_paths:{}, permitted_paths:{}", + is_bridged ? "bridged" : "native", name, search_paths, permitted_paths); } -bool NativeLoaderNamespace::Link(const NativeLoaderNamespace& target, - const std::string& shared_libs) const { +Result NativeLoaderNamespace::Link(const NativeLoaderNamespace& target, + const std::string& shared_libs) const { LOG_ALWAYS_FATAL_IF(shared_libs.empty(), "empty share lib when linking %s to %s", this->name().c_str(), target.name().c_str()); if (!IsBridged()) { - return android_link_namespaces(this->ToRawAndroidNamespace(), target.ToRawAndroidNamespace(), - shared_libs.c_str()); + if (android_link_namespaces(this->ToRawAndroidNamespace(), target.ToRawAndroidNamespace(), + shared_libs.c_str())) { + return {}; + } } else { - return NativeBridgeLinkNamespaces(this->ToRawNativeBridgeNamespace(), - target.ToRawNativeBridgeNamespace(), shared_libs.c_str()); + if (NativeBridgeLinkNamespaces(this->ToRawNativeBridgeNamespace(), + target.ToRawNativeBridgeNamespace(), shared_libs.c_str())) { + return {}; + } } + return Error() << GetLinkerError(IsBridged()); } -void* NativeLoaderNamespace::Load(const char* lib_name) const { +Result NativeLoaderNamespace::Load(const char* lib_name) const { if (!IsBridged()) { android_dlextinfo extinfo; extinfo.flags = ANDROID_DLEXT_USE_NAMESPACE; extinfo.library_namespace = this->ToRawAndroidNamespace(); - return android_dlopen_ext(lib_name, RTLD_NOW, &extinfo); + void* handle = android_dlopen_ext(lib_name, RTLD_NOW, &extinfo); + if (handle != nullptr) { + return handle; + } } else { - return NativeBridgeLoadLibraryExt(lib_name, RTLD_NOW, this->ToRawNativeBridgeNamespace()); + void* handle = + NativeBridgeLoadLibraryExt(lib_name, RTLD_NOW, this->ToRawNativeBridgeNamespace()); + if (handle != nullptr) { + return handle; + } } + return Error() << GetLinkerError(IsBridged()); } } // namespace android diff --git a/libnativeloader/native_loader_namespace.h b/libnativeloader/native_loader_namespace.h index 71e42477a..29b759cb4 100644 --- a/libnativeloader/native_loader_namespace.h +++ b/libnativeloader/native_loader_namespace.h @@ -21,22 +21,25 @@ #include #include +#include #include #include #include namespace android { +using android::base::Result; + // NativeLoaderNamespace abstracts a linker namespace for the native // architecture (ex: arm on arm) or the translated architecture (ex: arm on // x86). Instances of this class are managed by LibraryNamespaces object. struct NativeLoaderNamespace { public: - // TODO(return with errors) - static NativeLoaderNamespace Create(const std::string& name, const std::string& search_paths, - const std::string& permitted_paths, - const NativeLoaderNamespace* parent, bool is_shared, - bool is_greylist_enabled); + static Result Create(const std::string& name, + const std::string& search_paths, + const std::string& permitted_paths, + const NativeLoaderNamespace* parent, bool is_shared, + bool is_greylist_enabled); NativeLoaderNamespace(NativeLoaderNamespace&&) = default; NativeLoaderNamespace(const NativeLoaderNamespace&) = default; @@ -47,16 +50,13 @@ struct NativeLoaderNamespace { std::string name() const { return name_; } bool IsBridged() const { return raw_.index() == 1; } - bool IsNil() const { - return IsBridged() ? std::get<1>(raw_) == nullptr : std::get<0>(raw_) == nullptr; - } - bool Link(const NativeLoaderNamespace& target, const std::string& shared_libs) const; - void* Load(const char* lib_name) const; - char* GetError() const; + Result Link(const NativeLoaderNamespace& target, const std::string& shared_libs) const; + Result Load(const char* lib_name) const; - static NativeLoaderNamespace GetExportedNamespace(const std::string& name, bool is_bridged); - static NativeLoaderNamespace GetPlatformNamespace(bool is_bridged); + static Result GetExportedNamespace(const std::string& name, + bool is_bridged); + static Result GetPlatformNamespace(bool is_bridged); private: explicit NativeLoaderNamespace(const std::string& name, android_namespace_t* ns) diff --git a/libnativeloader/public_libraries.cpp b/libnativeloader/public_libraries.cpp index 10e23fdf1..6cee668a1 100644 --- a/libnativeloader/public_libraries.cpp +++ b/libnativeloader/public_libraries.cpp @@ -26,6 +26,7 @@ #include #include #include +#include #include #include @@ -34,6 +35,9 @@ namespace android::nativeloader { using namespace std::string_literals; +using android::base::ErrnoError; +using android::base::Errorf; +using android::base::Result; namespace { @@ -91,22 +95,21 @@ void InsertVndkVersionStr(std::string* file_name) { file_name->insert(insert_pos, vndk_version_str()); } -const std::function always_true = - [](const std::string&, std::string*) { return true; }; +const std::function(const std::string&)> always_true = + [](const std::string&) -> Result { return {}; }; -bool ReadConfig(const std::string& configFile, std::vector* sonames, - const std::function& check_soname, - std::string* error_msg = nullptr) { +Result> ReadConfig( + const std::string& configFile, + const std::function(const std::string& /* soname */)>& check_soname) { // Read list of public native libraries from the config file. std::string file_content; if (!base::ReadFileToString(configFile, &file_content)) { - if (error_msg) *error_msg = strerror(errno); - return false; + return ErrnoError(); } std::vector lines = base::Split(file_content, "\n"); + std::vector sonames; for (auto& line : lines) { auto trimmed_line = base::Trim(line); if (trimmed_line[0] == '#' || trimmed_line.empty()) { @@ -116,8 +119,7 @@ bool ReadConfig(const std::string& configFile, std::vector* sonames if (space_pos != std::string::npos) { std::string type = trimmed_line.substr(space_pos + 1); if (type != "32" && type != "64") { - if (error_msg) *error_msg = "Malformed line: " + line; - return false; + return Errorf("Malformed line: {}", line); } #if defined(__LP64__) // Skip 32 bit public library. @@ -133,13 +135,13 @@ bool ReadConfig(const std::string& configFile, std::vector* sonames trimmed_line.resize(space_pos); } - if (check_soname(trimmed_line, error_msg)) { - sonames->push_back(trimmed_line); - } else { - return false; + auto ret = check_soname(trimmed_line); + if (!ret) { + return ret.error(); } + sonames.push_back(trimmed_line); } - return true; + return sonames; } void ReadExtensionLibraries(const char* dirname, std::vector* sonames) { @@ -162,24 +164,22 @@ void ReadExtensionLibraries(const char* dirname, std::vector* sonam "Error extracting company name from public native library list file path \"%s\"", config_file_path.c_str()); - std::string error_msg; - - LOG_ALWAYS_FATAL_IF( - !ReadConfig(config_file_path, sonames, - [&company_name](const std::string& soname, std::string* error_msg) { - if (android::base::StartsWith(soname, "lib") && - android::base::EndsWith(soname, "." + company_name + ".so")) { - return true; - } else { - *error_msg = "Library name \"" + soname + - "\" does not end with the company name: " + company_name + - "."; - return false; - } - }, - &error_msg), - "Error reading public native library list from \"%s\": %s", config_file_path.c_str(), - error_msg.c_str()); + auto ret = ReadConfig( + config_file_path, [&company_name](const std::string& soname) -> Result { + if (android::base::StartsWith(soname, "lib") && + android::base::EndsWith(soname, "." + company_name + ".so")) { + return {}; + } else { + return Errorf("Library name \"{}\" does not end with the company name {}.", soname, + company_name); + } + }); + if (ret) { + sonames->insert(sonames->end(), ret->begin(), ret->end()); + } else { + LOG_ALWAYS_FATAL("Error reading public native library list from \"%s\": %s", + config_file_path.c_str(), ret.error().message().c_str()); + } } } } @@ -187,16 +187,17 @@ void ReadExtensionLibraries(const char* dirname, std::vector* sonam static std::string InitDefaultPublicLibraries() { std::string config_file = root_dir() + kDefaultPublicLibrariesFile; - std::vector sonames; - std::string error_msg; - LOG_ALWAYS_FATAL_IF(!ReadConfig(config_file, &sonames, always_true, &error_msg), - "Error reading public native library list from \"%s\": %s", - config_file.c_str(), error_msg.c_str()); + auto sonames = ReadConfig(config_file, always_true); + if (!sonames) { + LOG_ALWAYS_FATAL("Error reading public native library list from \"%s\": %s", + config_file.c_str(), sonames.error().message().c_str()); + return ""; + } std::string additional_libs = additional_public_libraries(); if (!additional_libs.empty()) { auto vec = base::Split(additional_libs, ":"); - std::copy(vec.begin(), vec.end(), std::back_inserter(sonames)); + std::copy(vec.begin(), vec.end(), std::back_inserter(*sonames)); } // Remove the public libs in the runtime namespace. @@ -216,18 +217,18 @@ static std::string InitDefaultPublicLibraries() { continue; } - auto it = std::find(sonames.begin(), sonames.end(), lib_name); - if (it != sonames.end()) { - sonames.erase(it); + auto it = std::find(sonames->begin(), sonames->end(), lib_name); + if (it != sonames->end()) { + sonames->erase(it); } } // Remove the public libs in the nnapi namespace. - auto it = std::find(sonames.begin(), sonames.end(), kNeuralNetworksApexPublicLibrary); - if (it != sonames.end()) { - sonames.erase(it); + auto it = std::find(sonames->begin(), sonames->end(), kNeuralNetworksApexPublicLibrary); + if (it != sonames->end()) { + sonames->erase(it); } - return android::base::Join(sonames, ':'); + return android::base::Join(*sonames, ':'); } static std::string InitRuntimePublicLibraries() { @@ -243,9 +244,11 @@ static std::string InitRuntimePublicLibraries() { static std::string InitVendorPublicLibraries() { // This file is optional, quietly ignore if the file does not exist. - std::vector sonames; - ReadConfig(kVendorPublicLibrariesFile, &sonames, always_true, nullptr); - return android::base::Join(sonames, ':'); + auto sonames = ReadConfig(kVendorPublicLibrariesFile, always_true); + if (!sonames) { + return ""; + } + return android::base::Join(*sonames, ':'); } // read /system/etc/public.libraries-.txt and @@ -262,17 +265,23 @@ static std::string InitExtendedPublicLibraries() { static std::string InitLlndkLibraries() { std::string config_file = kLlndkLibrariesFile; InsertVndkVersionStr(&config_file); - std::vector sonames; - ReadConfig(config_file, &sonames, always_true, nullptr); - return android::base::Join(sonames, ':'); + auto sonames = ReadConfig(config_file, always_true); + if (!sonames) { + LOG_ALWAYS_FATAL("%s", sonames.error().message().c_str()); + return ""; + } + return android::base::Join(*sonames, ':'); } static std::string InitVndkspLibraries() { std::string config_file = kVndkLibrariesFile; InsertVndkVersionStr(&config_file); - std::vector sonames; - ReadConfig(config_file, &sonames, always_true, nullptr); - return android::base::Join(sonames, ':'); + auto sonames = ReadConfig(config_file, always_true); + if (!sonames) { + LOG_ALWAYS_FATAL("%s", sonames.error().message().c_str()); + return ""; + } + return android::base::Join(*sonames, ':'); } static std::string InitNeuralNetworksPublicLibraries() {