*/
#include "linkerconfig/baseconfig.h"
-
#include "linkerconfig/sectionbuilder.h"
+using android::linkerconfig::modules::DirToSection;
using android::linkerconfig::modules::Section;
+namespace {
+const std::vector<DirToSection> kDirToSection = {
+ {"/system/bin/", "system"},
+ {"/system/xbin/", "system"},
+ {"/@{SYSTEM_EXT:system_ext}/bin/", "system"},
+ {"/@{PRODUCT:product}/bin/", "system"},
+
+ {"/odm/bin/", "vendor"},
+ {"/vendor/bin/", "vendor"},
+ {"/data/nativetest/odm", "vendor"},
+ {"/data/nativetest64/odm", "vendor"},
+ {"/data/benchmarktest/odm", "vendor"},
+ {"/data/benchmarktest64/odm", "vendor"},
+ {"/data/nativetest/vendor", "vendor"},
+ {"/data/nativetest64/vendor", "vendor"},
+ {"/data/benchmarktest/vendor", "vendor"},
+ {"/data/benchmarktest64/vendor", "vendor"},
+
+ {"/data/nativetest/unrestricted", "unrestricted"},
+ {"/data/nativetest64/unrestricted", "unrestricted"},
+
+ // TODO(b/123864775): Ensure tests are run from /data/nativetest{,64} or (if
+ // necessary) the unrestricted subdirs above. Then clean this up.
+ {"/data/local/tmp", "unrestricted"},
+
+ {"/postinstall", "postinstall"},
+ // Fallback entry to provide APEX namespace lookups for binaries anywhere
+ // else. This must be last.
+ {"/data", "system"},
+};
+} // namespace
+
namespace android {
namespace linkerconfig {
namespace contents {
sections.emplace_back(BuildUnrestrictedSection(current_context));
sections.emplace_back(BuildPostInstallSection(current_context));
- return android::linkerconfig::modules::Configuration(std::move(sections));
+ return android::linkerconfig::modules::Configuration(std::move(sections),
+ kDirToSection);
}
} // namespace contents
} // namespace linkerconfig
*/
#include "linkerconfig/legacy.h"
-
#include "linkerconfig/sectionbuilder.h"
+using android::linkerconfig::modules::DirToSection;
using android::linkerconfig::modules::Section;
+namespace {
+const std::vector<DirToSection> kDirToSection = {
+ // All binaries gets the same configuration 'legacy'
+ {"/system", "legacy"},
+ {"/product", "legacy"},
+ {"/vendor", "legacy"},
+ {"/odm", "legacy"},
+ {"/sbin", "legacy"},
+ // Except for /postinstall, where only /system and /product are searched
+ {"/postinstall", "postinstall"},
+ // Fallback entry to provide APEX namespace lookups for binaries anywhere
+ // else. This must be last.
+ {"/data", "legacy"},
+};
+} // namespace
+
namespace android {
namespace linkerconfig {
namespace contents {
sections.emplace_back(BuildLegacySection(current_context));
sections.emplace_back(BuildPostInstallSection(current_context));
- return android::linkerconfig::modules::Configuration(std::move(sections));
+ return android::linkerconfig::modules::Configuration(std::move(sections),
+ kDirToSection);
}
} // namespace contents
} // namespace linkerconfig
using android::linkerconfig::modules::Namespace;
using android::linkerconfig::modules::Section;
-namespace {
-const std::vector<std::string> kLegacyBinaryPath = {
- "/system",
- "/product",
- "/vendor",
- "/odm",
- "/sbin",
-};
-} // namespace
-
namespace android {
namespace linkerconfig {
namespace contents {
namespaces.emplace_back(BuildResolvNamespace(ctx));
namespaces.emplace_back(BuildNeuralNetworksNamespace(ctx));
- return Section("legacy", kLegacyBinaryPath, std::move(namespaces));
+ return Section("legacy", std::move(namespaces));
}
} // namespace contents
} // namespace linkerconfig
using android::linkerconfig::modules::Namespace;
using android::linkerconfig::modules::Section;
-namespace {
-const std::vector<std::string> kBinaryPath = {"/postinstall"};
-} // namespace
-
namespace android {
namespace linkerconfig {
namespace contents {
namespaces.emplace_back(BuildPostInstallNamespace(ctx));
- return Section("postinstall", kBinaryPath, std::move(namespaces));
+ return Section("postinstall", std::move(namespaces));
}
} // namespace contents
} // namespace linkerconfig
using android::linkerconfig::modules::Namespace;
using android::linkerconfig::modules::Section;
-namespace {
-const std::vector<std::string> kBinaryPath = {
- "/system/bin/",
- "/system/xbin/",
- "/@{SYSTEM_EXT:system_ext}/bin/",
- "/@{PRODUCT:product}/bin/",
- "/data",
-};
-} // namespace
-
namespace android {
namespace linkerconfig {
namespace contents {
namespaces.emplace_back(BuildVndkNamespace(ctx));
namespaces.emplace_back(BuildNeuralNetworksNamespace(ctx));
- return Section("system", kBinaryPath, std::move(namespaces));
+ return Section("system", std::move(namespaces));
}
} // namespace contents
} // namespace linkerconfig
using android::linkerconfig::modules::Namespace;
using android::linkerconfig::modules::Section;
-namespace {
-const std::vector<std::string> kBinaryPath = {
- "/data/nativetest/unrestricted",
- "/data/nativetest64/unrestricted",
- "/data/local/tmp",
-};
-} // namespace
-
namespace android {
namespace linkerconfig {
namespace contents {
namespaces.emplace_back(BuildResolvNamespace(ctx));
namespaces.emplace_back(BuildNeuralNetworksNamespace(ctx));
- return Section("unrestricted", kBinaryPath, std::move(namespaces));
+ return Section("unrestricted", std::move(namespaces));
}
} // namespace contents
} // namespace linkerconfig
using android::linkerconfig::modules::Namespace;
using android::linkerconfig::modules::Section;
-namespace {
-const std::vector<std::string> kBinaryPath = {
- "/odm/bin/",
- "/vendor/bin/",
- "/data/nativetest/odm",
- "/data/nativetest64/odm",
- "/data/benchmarktest/odm",
- "/data/benchmarktest64/odm",
- "/data/nativetest/vendor",
- "/data/nativetest64/vendor",
- "/data/benchmarktest/vendor",
- "/data/benchmarktest64/vendor",
-};
-} // namespace
-
namespace android {
namespace linkerconfig {
namespace contents {
namespaces.emplace_back(BuildVndkInSystemNamespace(ctx));
}
- return Section("vendor", kBinaryPath, std::move(namespaces));
+ return Section("vendor", std::move(namespaces));
}
} // namespace contents
} // namespace linkerconfig
#include "linkerconfig/configuration.h"
+#include <unordered_map>
+
#include "linkerconfig/log.h"
#include "linkerconfig/variables.h"
namespace linkerconfig {
namespace modules {
void Configuration::WriteConfig(ConfigWriter& writer) {
- std::map<std::string, std::string> resolved_binary_paths;
+ std::unordered_map<std::string, std::string> resolved_dirs;
- for (auto& section : sections_) {
- auto binary_paths = section.GetBinaryPaths();
- auto section_name = section.GetName();
- for (auto& path : binary_paths) {
- auto resolved_path = Variables::ResolveVariables(path);
- auto it = resolved_binary_paths.find(resolved_path);
- if (it != resolved_binary_paths.end()) {
- LOG(WARNING) << "Binary path " << path << " already found from "
- << it->second << ". Path from " << section_name
- << " will be ignored.";
- } else {
- resolved_binary_paths[resolved_path] = section_name;
- }
- }
- }
+ for (auto& dir_to_section : dir_to_section_list_) {
+ auto resolved_dir = Variables::ResolveVariables(dir_to_section.first);
+
+ auto it = resolved_dirs.find(resolved_dir);
- // Navigate in reverse order to keep sub directories on top of parent directory
- for (auto it = resolved_binary_paths.rbegin();
- it != resolved_binary_paths.rend();
- it++) {
- writer.WriteLine("dir.%s = %s", it->second.c_str(), it->first.c_str());
+ if (it != resolved_dirs.end()) {
+ LOG(WARNING) << "Binary path " << resolved_dir << " already found from "
+ << it->second << ". Path from " << dir_to_section.second
+ << " will be ignored.";
+ } else {
+ resolved_dirs[resolved_dir] = dir_to_section.second;
+ writer.WriteLine(
+ "dir.%s = %s", dir_to_section.second.c_str(), resolved_dir.c_str());
+ }
}
for (auto& section : sections_) {
#pragma once
#include <string>
+#include <utility>
#include <vector>
#include "linkerconfig/configwriter.h"
namespace android {
namespace linkerconfig {
namespace modules {
+using DirToSection = std::pair<std::string, std::string>;
+
class Configuration {
public:
- explicit Configuration(std::vector<Section> sections)
- : sections_(std::move(sections)) {
+ explicit Configuration(std::vector<Section> sections,
+ std::vector<DirToSection> dir_to_sections)
+ : sections_(std::move(sections)),
+ dir_to_section_list_(std::move(dir_to_sections)) {
}
Configuration(const Configuration&) = delete;
Configuration(Configuration&&) = default;
private:
std::vector<Section> sections_;
+ std::vector<DirToSection> dir_to_section_list_;
};
} // namespace modules
} // namespace linkerconfig
class Section {
public:
- Section(std::string name, std::vector<std::string> binary_paths,
- std::vector<Namespace> namespaces)
- : name_(std::move(name)),
- binary_paths_(std::move(binary_paths)),
- namespaces_(std::move(namespaces)) {
+ Section(std::string name, std::vector<Namespace> namespaces)
+ : name_(std::move(name)), namespaces_(std::move(namespaces)) {
}
Section(const Section&) = delete;
private:
const std::string name_;
- std::vector<std::string> binary_paths_;
std::vector<Namespace> namespaces_;
};
} // namespace modules
}
}
-std::vector<std::string> Section::GetBinaryPaths() {
- return binary_paths_;
-}
-
Namespace* Section::GetNamespace(const std::string& namespace_name) {
for (auto& ns : namespaces_) {
if (ns.GetName() == namespace_name) {
using namespace android::linkerconfig::modules;
constexpr const char* kExpectedConfiguration =
- R"(dir.vendor = /vendor/bin
+ R"(dir.system = /system/bin
dir.system = /system/xbin
-dir.vendor = /system/bin/vendor
-dir.system = /system/bin
-dir.vendor = /product/bin/vendor
dir.system = /product/bin
dir.vendor = /odm/bin
+dir.vendor = /vendor/bin
+dir.vendor = /system/bin/vendor
+dir.vendor = /product/bin/vendor
[system]
additional.namespaces = namespace1,namespace2
namespace.default.isolated = false
Variables::AddValue("PRODUCT", "product");
std::vector<Section> sections;
- std::vector<Namespace> system_namespaces;
- std::vector<std::string> system_binary_path = {
- "/system/bin",
- "/system/xbin",
- "/@{PRODUCT}/bin",
+ std::vector<DirToSection> dir_to_sections = {
+ {"/system/bin", "system"},
+ {"/system/xbin", "system"},
+ {"/@{PRODUCT}/bin", "system"},
+ {"/odm/bin", "vendor"},
+ {"/vendor/bin", "vendor"},
+ {"/system/bin/vendor", "vendor"},
+ {"/product/bin/vendor", "vendor"},
+ {"/product/bin", "vendor"},
};
+ std::vector<Namespace> system_namespaces;
+
system_namespaces.emplace_back(CreateNamespaceWithLinks(
"default", false, false, "namespace1", "namespace2"));
system_namespaces.emplace_back(
system_namespaces.emplace_back(
CreateNamespaceWithPaths("namespace2", false, false));
- Section system_section(
- "system", system_binary_path, std::move(system_namespaces));
+ Section system_section("system", std::move(system_namespaces));
sections.emplace_back(std::move(system_section));
std::vector<Namespace> vendor_namespaces;
- std::vector<std::string> vendor_binary_path = {"/odm/bin",
- "/vendor/bin",
- "/system/bin/vendor",
- "/product/bin/vendor",
- "/product/bin"};
vendor_namespaces.emplace_back(
CreateNamespaceWithPaths("default", false, false));
- Section vendor_section(
- "vendor", vendor_binary_path, std::move(vendor_namespaces));
+ Section vendor_section("vendor", std::move(vendor_namespaces));
sections.emplace_back(std::move(vendor_section));
- Configuration conf(std::move(sections));
+ Configuration conf(std::move(sections), dir_to_sections);
android::linkerconfig::modules::ConfigWriter writer;
conf.WriteConfig(writer);
- ASSERT_EQ(writer.ToString(), kExpectedConfiguration);
+ ASSERT_EQ(kExpectedConfiguration, writer.ToString());
}
\ No newline at end of file
"default", "namespace2"));
namespaces.emplace_back(CreateNamespaceWithPaths("namespace2", false, false));
- std::vector<std::string> empty_list;
-
- Section section("test_section", empty_list, std::move(namespaces));
+ Section section("test_section", std::move(namespaces));
section.WriteConfig(writer);
auto config = writer.ToString();
- ASSERT_EQ(config, kSectionWithNamespacesExpectedResult);
+ ASSERT_EQ(kSectionWithNamespacesExpectedResult, config);
}
TEST(linkerconfig_section, section_with_one_namespace) {
std::vector<Namespace> namespaces;
namespaces.emplace_back(CreateNamespaceWithPaths("default", false, false));
- std::vector<std::string> empty_list;
-
- Section section("test_section", empty_list, std::move(namespaces));
+ Section section("test_section", std::move(namespaces));
section.WriteConfig(writer);
auto config = writer.ToString();
- ASSERT_EQ(config, kSectionWithOneNamespaceExpectedResult);
-}
-
-TEST(linkerconfig_section, binary_paths) {
- std::vector<std::string> binary_paths = {"/root/a", "/root/a/b", "/root/b"};
- std::vector<Namespace> empty_namespace;
- Section section("test_section", binary_paths, std::move(empty_namespace));
-
- auto section_binary_paths = section.GetBinaryPaths();
-
- ASSERT_EQ(section_binary_paths, binary_paths);
+ ASSERT_EQ(kSectionWithOneNamespaceExpectedResult, config);
}
\ No newline at end of file