Merge "Allow vendors to extend the list of public libs"

This commit is contained in:
Dimitry Ivanov 2016-04-11 20:03:16 +00:00 committed by Gerrit Code Review
commit dc727ef1f0

View file

@ -36,7 +36,8 @@
namespace android { namespace android {
#if defined(__ANDROID__) #if defined(__ANDROID__)
static constexpr const char* kPublicNativeLibrariesConfig = "/system/etc/public.libraries.txt"; static constexpr const char* kPublicNativeLibrariesSystemConfig = "/system/etc/public.libraries.txt";
static constexpr const char* kPublicNativeLibrariesVendorConfig = "/vendor/etc/public.libraries.txt";
class LibraryNamespaces { class LibraryNamespaces {
public: public:
@ -93,35 +94,51 @@ class LibraryNamespaces {
} }
void Initialize() { void Initialize() {
std::vector<std::string> sonames;
LOG_ALWAYS_FATAL_IF(!ReadConfig(kPublicNativeLibrariesSystemConfig, &sonames),
"Error reading public native library list from \"%s\": %s",
kPublicNativeLibrariesSystemConfig, strerror(errno));
// This file is optional, quietly ignore if the file does not exist.
ReadConfig(kPublicNativeLibrariesVendorConfig, &sonames);
// android_init_namespaces() expects all the public libraries
// to be loaded so that they can be found by soname alone.
//
// TODO(dimitry): this is a bit misleading since we do not know
// if the vendor public library is going to be opened from /vendor/lib
// we might as well end up loading them from /system/lib
// For now we rely on CTS test to catch things like this but
// it should probably be addressed in the future.
for (const auto& soname : sonames) {
dlopen(soname.c_str(), RTLD_NOW | RTLD_NODELETE);
}
public_libraries_ = base::Join(sonames, ':');
}
private:
bool ReadConfig(const std::string& configFile, std::vector<std::string>* sonames) {
// Read list of public native libraries from the config file. // Read list of public native libraries from the config file.
std::string file_content; std::string file_content;
LOG_ALWAYS_FATAL_IF(!base::ReadFileToString(kPublicNativeLibrariesConfig, &file_content), if(!base::ReadFileToString(configFile, &file_content)) {
"Error reading public native library list from \"%s\": %s", return false;
kPublicNativeLibrariesConfig, strerror(errno)); }
std::vector<std::string> lines = base::Split(file_content, "\n"); std::vector<std::string> lines = base::Split(file_content, "\n");
std::vector<std::string> sonames;
for (const auto& line : lines) { for (const auto& line : lines) {
auto trimmed_line = base::Trim(line); auto trimmed_line = base::Trim(line);
if (trimmed_line[0] == '#' || trimmed_line.empty()) { if (trimmed_line[0] == '#' || trimmed_line.empty()) {
continue; continue;
} }
sonames.push_back(trimmed_line); sonames->push_back(trimmed_line);
} }
public_libraries_ = base::Join(sonames, ':'); return true;
// android_init_namespaces() expects all the public libraries
// to be loaded so that they can be found by soname alone.
for (const auto& soname : sonames) {
dlopen(soname.c_str(), RTLD_NOW | RTLD_NODELETE);
}
} }
private:
bool InitPublicNamespace(const char* library_path) { bool InitPublicNamespace(const char* library_path) {
// (http://b/25844435) - Some apps call dlopen from generated code (mono jited // (http://b/25844435) - Some apps call dlopen from generated code (mono jited
// code is one example) unknown to linker in which case linker uses anonymous // code is one example) unknown to linker in which case linker uses anonymous