From 7d422b30e47382c48d611caf0a30b262a6bac98d Mon Sep 17 00:00:00 2001 From: Kiyoung Kim Date: Tue, 5 Mar 2019 17:06:13 +0900 Subject: [PATCH] Define modules for linker config Define modules for linker config and implement config string generator for each modules. Bug: 123722631 Test: m -j && atest linkerconfig_modules_unittest Change-Id: Id9a234830c381267c23ec7af657f354d51a58889 --- .clang-format | 11 ++++ Android.bp | 58 +++++++++++++++++ OWNERS | 5 ++ PREUPLOAD.cfg | 5 ++ TEST_MAPPING | 7 +++ include/linkerconfig/link.h | 63 +++++++++++++++++++ include/linkerconfig/namespace.h | 90 ++++++++++++++++++++++++++ include/linkerconfig/section.h | 57 +++++++++++++++++ modules/link.cc | 42 +++++++++++++ modules/namespace.cc | 119 +++++++++++++++++++++++++++++++++++ modules/section.cc | 84 +++++++++++++++++++++++++ modules/tests/link_test.cc | 42 +++++++++++++ modules/tests/modules_testbase.h | 39 ++++++++++++ modules/tests/namespace_test.cc | 77 +++++++++++++++++++++++ modules/tests/section_test.cc | 133 +++++++++++++++++++++++++++++++++++++++ 15 files changed, 832 insertions(+) create mode 100644 .clang-format create mode 100644 Android.bp create mode 100644 OWNERS create mode 100644 PREUPLOAD.cfg create mode 100644 TEST_MAPPING create mode 100644 include/linkerconfig/link.h create mode 100644 include/linkerconfig/namespace.h create mode 100644 include/linkerconfig/section.h create mode 100644 modules/link.cc create mode 100644 modules/namespace.cc create mode 100644 modules/section.cc create mode 100644 modules/tests/link_test.cc create mode 100644 modules/tests/modules_testbase.h create mode 100644 modules/tests/namespace_test.cc create mode 100644 modules/tests/section_test.cc diff --git a/.clang-format b/.clang-format new file mode 100644 index 0000000..175c5dd --- /dev/null +++ b/.clang-format @@ -0,0 +1,11 @@ +BasedOnStyle: Google +AllowShortBlocksOnASingleLine: false +AllowShortFunctionsOnASingleLine: false + +CommentPragmas: NOLINT:.* +DerivePointerAlignment: false +IndentWidth: 2 +PointerAlignment: Left +TabWidth: 2 +UseTab: Never +PenaltyExcessCharacter: 32 \ No newline at end of file diff --git a/Android.bp b/Android.bp new file mode 100644 index 0000000..02f3857 --- /dev/null +++ b/Android.bp @@ -0,0 +1,58 @@ +/* + * Copyright (C) 2019 The Android Open Source Project + * + * Licensed under the Apache License, Version 2.0 (the "License"); + * you may not use this file except in compliance with the License. + * You may obtain a copy of the License at + * + * http://www.apache.org/licenses/LICENSE-2.0 + * + * Unless required by applicable law or agreed to in writing, software + * distributed under the License is distributed on an "AS IS" BASIS, + * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. + * See the License for the specific language governing permissions and + * limitations under the License. + */ + +cc_defaults { + name: "linkerconfig_defaults", + cflags: [ + "-Wall", + "-Werror", + "-Wextra", + ], + static_libs: [ + "libbase", + "liblog", + ], + header_libs: ["linkerconfig_headers"], +} + +cc_library_headers { + name: "linkerconfig_headers", + export_include_dirs: ["include"], +} + +cc_library_static { + name: "linkerconfig_modules", + defaults: [ "linkerconfig_defaults" ], + srcs: [ + "modules/*.cc", + ], +} + +cc_test { + name: "linkerconfig_modules_unittest", + defaults: [ "linkerconfig_defaults" ], + srcs: [ + "modules/tests/*_test.cc", + ], + static_libs: [ + "linkerconfig_modules", + ], + cflags: [ + "-g", + "-Wunused", + ], + test_suites: ["general-tests"], +} \ No newline at end of file diff --git a/OWNERS b/OWNERS new file mode 100644 index 0000000..41f7379 --- /dev/null +++ b/OWNERS @@ -0,0 +1,5 @@ +kiyoungkim@google.com +danalbert@google.com +enh@google.com +jiyong@google.com +rprichard@google.com \ No newline at end of file diff --git a/PREUPLOAD.cfg b/PREUPLOAD.cfg new file mode 100644 index 0000000..f3f966e --- /dev/null +++ b/PREUPLOAD.cfg @@ -0,0 +1,5 @@ +[Builtin Hooks] +clang_format = true + +[Builtin Hooks Options] +clang_format = --commit ${PREUPLOAD_COMMIT} --style file --extensions c,h,cc,cpp \ No newline at end of file diff --git a/TEST_MAPPING b/TEST_MAPPING new file mode 100644 index 0000000..18361d9 --- /dev/null +++ b/TEST_MAPPING @@ -0,0 +1,7 @@ +{ + "presubmit": [ + { + "name": "linkerconfig_modules_unittest" + } + ] +} \ No newline at end of file diff --git a/include/linkerconfig/link.h b/include/linkerconfig/link.h new file mode 100644 index 0000000..fada5b3 --- /dev/null +++ b/include/linkerconfig/link.h @@ -0,0 +1,63 @@ +/* + * Copyright (C) 2019 The Android Open Source Project + * + * Licensed under the Apache License, Version 2.0 (the "License"); + * you may not use this file except in compliance with the License. + * You may obtain a copy of the License at + * + * http://www.apache.org/licenses/LICENSE-2.0 + * + * Unless required by applicable law or agreed to in writing, software + * distributed under the License is distributed on an "AS IS" BASIS, + * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. + * See the License for the specific language governing permissions and + * limitations under the License. + */ +#pragma once + +#include +#include +#include + +#include + +#define LOG_TAG "linkerconfig" + +namespace android { +namespace linkerconfig { +namespace modules { +class Link { + public: + Link(const std::string& origin_namespace, const std::string& target_namespace, + bool allow_all_shared_libs = false) + : origin_namespace_(origin_namespace), + target_namespace_(target_namespace), + allow_all_shared_libs_(allow_all_shared_libs) { + } + template + void AddSharedLib(T&& lib_name, Args&&... lib_names); + std::string GenerateConfig(); + + private: + const std::string origin_namespace_; + const std::string target_namespace_; + const bool allow_all_shared_libs_; + std::vector shared_libs_; +}; + +template +void Link::AddSharedLib(T&& lib_name, Args&&... lib_names) { + if (allow_all_shared_libs_) { + LOG(WARNING) << "Tried to add shared libraries to link from " + << origin_namespace_ << " to " << target_namespace_ + << "while this link is allow_all_shared_libs"; + return; + } + shared_libs_.push_back(std::forward(lib_name)); + if constexpr (sizeof...(Args) > 0) { + AddSharedLib(std::forward(lib_names)...); + } +} +} // namespace modules +} // namespace linkerconfig +} // namespace android \ No newline at end of file diff --git a/include/linkerconfig/namespace.h b/include/linkerconfig/namespace.h new file mode 100644 index 0000000..0ad4b9a --- /dev/null +++ b/include/linkerconfig/namespace.h @@ -0,0 +1,90 @@ +/* + * Copyright (C) 2019 The Android Open Source Project + * + * Licensed under the Apache License, Version 2.0 (the "License"); + * you may not use this file except in compliance with the License. + * You may obtain a copy of the License at + * + * http://www.apache.org/licenses/LICENSE-2.0 + * + * Unless required by applicable law or agreed to in writing, software + * distributed under the License is distributed on an "AS IS" BASIS, + * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. + * See the License for the specific language governing permissions and + * limitations under the License. + */ +#pragma once + +#include +#include +#include + +#include "link.h" + +namespace android { +namespace linkerconfig { +namespace modules { + +class Namespace { + public: + Namespace(const std::string& name, bool is_isolated = false, + bool is_visible = false) + : is_isolated_(is_isolated), is_visible_(is_visible), name_(name) { + } + + // Add path to search path + // This function will add path to namespace.<>.search.paths + // If also_in_asan is true, this will add path also to + // namespace.<>.asan.search.paths + // If with_data_asan is true when also_in_asan is true, + // this will also add asan path starts with /data/asan + // + // AddSearchPath("/system/${LIB}", false, false) : + // namespace.xxx.search.paths += /system/${LIB} + // AddSearchPath("/system/${LIB}", true, false) : + // namespace.xxx.search.paths += /system/${LIB} + // namespace.xxx.asan.search.paths += /system/${LIB} + // AddSearchPath("/system/${LIB}", true, true) : + // namespace.xxx.search.paths += /system/${LIB} + // namespace.xxx.asan.search.paths += /system/${LIB} + // namespace.xxx.asan.search.paths += /data/asan/system/${LIB} + void AddSearchPath(const std::string& path, bool also_in_asan = true, + bool with_data_asan = true); + + // Add path to permitted path + // This function will add path to namespace.<>.permitted.paths + // If also_in_asan is true, this will add path also to + // namespace.<>.asan.permitted.paths + // If with_data_asan is true when also_in_asan is true, + // this will also add asan path starts with /data/asan + // + // AddSearchPath("/system/${LIB}", false, false) : + // namespace.xxx.permitted.paths += /system/${LIB} + // AddSearchPath("/system/${LIB}", true, false) : + // namespace.xxx.permitted.paths += /system/${LIB} + // namespace.xxx.asan.permitted.paths += /system/${LIB} + // AddSearchPath("/system/${LIB}", true, true) : + // namespace.xxx.permitted.paths += /system/${LIB} + // namespace.xxx.asan.permitted.paths += /system/${LIB} + // namespace.xxx.asan.permitted.paths += /data/asan/system/${LIB} + void AddPermittedPath(const std::string& path, bool also_in_asan = true, + bool with_data_asan = true); + std::shared_ptr CreateLink(const std::string& target_namespace, + bool allow_all_shared_libs = false); + std::string GenerateConfig(); + + private: + const bool is_isolated_; + const bool is_visible_; + const std::string name_; + std::vector search_paths_; + std::vector permitted_paths_; + std::vector asan_search_paths_; + std::vector asan_permitted_paths_; + std::map> links_; + std::string GetPathString(const std::string& path_type, + const std::vector& path_list); +}; +} // namespace modules +} // namespace linkerconfig +} // namespace android \ No newline at end of file diff --git a/include/linkerconfig/section.h b/include/linkerconfig/section.h new file mode 100644 index 0000000..d5e37c6 --- /dev/null +++ b/include/linkerconfig/section.h @@ -0,0 +1,57 @@ +/* + * Copyright (C) 2019 The Android Open Source Project + * + * Licensed under the Apache License, Version 2.0 (the "License"); + * you may not use this file except in compliance with the License. + * You may obtain a copy of the License at + * + * http://www.apache.org/licenses/LICENSE-2.0 + * + * Unless required by applicable law or agreed to in writing, software + * distributed under the License is distributed on an "AS IS" BASIS, + * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. + * See the License for the specific language governing permissions and + * limitations under the License. + */ +#pragma once + +#include +#include +#include +#include +#include + +#include "namespace.h" + +namespace android { +namespace linkerconfig { +namespace modules { +class Section { + public: + Section(const std::string& name) : name_(name) { + } + template + void AddBinaryPath(T&& binary_path, Args&&... binary_paths); + std::shared_ptr CreateNamespace(const std::string& namespace_name, + bool is_isolated = false, + bool is_visible = false); + std::string GenerateConfig(); + std::string GenerateBinaryPaths(); + std::string GetName(); + + private: + const std::string name_; + std::vector binary_paths_; + std::map> namespaces_; +}; + +template +void Section::AddBinaryPath(T&& binary_path, Args&&... binary_paths) { + binary_paths_.push_back(std::forward(binary_path)); + if constexpr (sizeof...(Args) > 0) { + AddBinaryPath(std::forward(binary_paths)...); + } +} +} // namespace modules +} // namespace linkerconfig +} // namespace android \ No newline at end of file diff --git a/modules/link.cc b/modules/link.cc new file mode 100644 index 0000000..133cd57 --- /dev/null +++ b/modules/link.cc @@ -0,0 +1,42 @@ +/* + * Copyright (C) 2019 The Android Open Source Project + * + * Licensed under the Apache License, Version 2.0 (the "License"); + * you may not use this file except in compliance with the License. + * You may obtain a copy of the License at + * + * http://www.apache.org/licenses/LICENSE-2.0 + * + * Unless required by applicable law or agreed to in writing, software + * distributed under the License is distributed on an "AS IS" BASIS, + * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. + * See the License for the specific language governing permissions and + * limitations under the License. + */ + +#include "linkerconfig/link.h" + +namespace android { +namespace linkerconfig { +namespace modules { +std::string Link::GenerateConfig() { + std::string prefix = + "namespace." + origin_namespace_ + ".link." + target_namespace_; + std::string config = ""; + if (allow_all_shared_libs_) { + config = prefix + ".allow_all_shared_libs = true\n"; + } else { + bool is_first = true; + + for (auto& lib_name : shared_libs_) { + config += prefix + ".shared_libs " + (is_first ? "= " : "+= ") + + lib_name + "\n"; + is_first = false; + } + } + + return config; +} +} // namespace modules +} // namespace linkerconfig +} // namespace android \ No newline at end of file diff --git a/modules/namespace.cc b/modules/namespace.cc new file mode 100644 index 0000000..c2c3ea2 --- /dev/null +++ b/modules/namespace.cc @@ -0,0 +1,119 @@ +/* + * Copyright (C) 2019 The Android Open Source Project + * + * Licensed under the Apache License, Version 2.0 (the "License"); + * you may not use this file except in compliance with the License. + * You may obtain a copy of the License at + * + * http://www.apache.org/licenses/LICENSE-2.0 + * + * Unless required by applicable law or agreed to in writing, software + * distributed under the License is distributed on an "AS IS" BASIS, + * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. + * See the License for the specific language governing permissions and + * limitations under the License. + */ + +#include "linkerconfig/namespace.h" + +#include + +#define LOG_TAG "linkerconfig" + +namespace android { +namespace linkerconfig { +namespace modules { + +constexpr const char* kDataAsanPath = "/data/asan"; + +std::string Namespace::GetPathString(const std::string& path_type, + const std::vector& path_list) { + std::string prefix = "namespace." + name_ + "." + path_type + ".paths "; + std::string path_string = ""; + bool is_first = true; + for (auto& path : path_list) { + path_string += prefix + (is_first ? "= " : "+= ") + path + "\n"; + is_first = false; + } + + return path_string; +} + +std::shared_ptr Namespace::CreateLink(const std::string& target_namespace, + bool allow_all_shared_libs) { + auto new_link = + std::make_shared(name_, target_namespace, allow_all_shared_libs); + + if (links_.find(target_namespace) != links_.end()) { + LOG(INFO) << "Link to " << target_namespace + << " already exists. Overwriting link."; + } + + links_[target_namespace] = new_link; + return new_link; +} + +std::string Namespace::GenerateConfig() { + std::string config = ""; + std::string prefix = "namespace." + name_ + "."; + + config += prefix + "isolated = " + (is_isolated_ ? "true" : "false") + "\n"; + + if (is_visible_) { + config += prefix + "visible = true\n"; + } + + config += GetPathString("search", search_paths_); + config += GetPathString("permitted", permitted_paths_); + config += GetPathString("asan.search", asan_search_paths_); + config += GetPathString("asan.permitted", asan_permitted_paths_); + + if (!links_.empty()) { + config += prefix + "links = "; + + bool is_first = true; + for (auto& link : links_) { + if (!is_first) { + config += ","; + } + config += link.first; + is_first = false; + } + + config += "\n"; + + for (auto& link : links_) { + config += link.second->GenerateConfig(); + } + } + + return config; +} + +void Namespace::AddSearchPath(const std::string& path, bool in_asan, + bool with_data_asan) { + search_paths_.push_back(path); + + if (in_asan) { + asan_search_paths_.push_back(path); + if (with_data_asan) { + asan_search_paths_.push_back(kDataAsanPath + path); + } + } +} + +void Namespace::AddPermittedPath(const std::string& path, bool in_asan, + bool with_data_asan) { + permitted_paths_.push_back(path); + + if (in_asan) { + asan_permitted_paths_.push_back(path); + if (with_data_asan) { + asan_permitted_paths_.push_back(kDataAsanPath + path); + } + } +} + +} // namespace modules +} // namespace linkerconfig +} // namespace android \ No newline at end of file diff --git a/modules/section.cc b/modules/section.cc new file mode 100644 index 0000000..5501ce3 --- /dev/null +++ b/modules/section.cc @@ -0,0 +1,84 @@ +/* + * Copyright (C) 2019 The Android Open Source Project + * + * Licensed under the Apache License, Version 2.0 (the "License"); + * you may not use this file except in compliance with the License. + * You may obtain a copy of the License at + * + * http://www.apache.org/licenses/LICENSE-2.0 + * + * Unless required by applicable law or agreed to in writing, software + * distributed under the License is distributed on an "AS IS" BASIS, + * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. + * See the License for the specific language governing permissions and + * limitations under the License. + */ + +#include "linkerconfig/section.h" + +#include + +#define LOG_TAG "linkerconfig" + +namespace android { +namespace linkerconfig { +namespace modules { +std::shared_ptr Section::CreateNamespace( + const std::string& namespace_name, bool is_isolated, bool is_visible) { + auto new_namespace = + std::make_shared(namespace_name, is_isolated, is_visible); + + if (namespaces_.find(namespace_name) != namespaces_.end()) { + LOG(INFO) << "Namespace " << namespace_name + << " already exists. Overwriting namespace."; + } + + namespaces_[namespace_name] = new_namespace; + return new_namespace; +} + +std::string Section::GenerateConfig() { + std::string config = "[" + name_ + "]\n"; + + std::string additional_namespaces = ""; + + bool is_first = true; + for (auto& ns : namespaces_) { + if (ns.first != "default") { + if (!is_first) { + additional_namespaces += ","; + } + + additional_namespaces += ns.first; + is_first = false; + } + } + + if (!is_first) { + config += "additional.namespaces = " + additional_namespaces + "\n"; + } + + for (auto& ns : namespaces_) { + config += ns.second->GenerateConfig(); + } + + return config; +} + +std::string Section::GenerateBinaryPaths() { + std::string binary_path = ""; + std::string prefix = "dir." + name_ + " = "; + + for (auto& path : binary_paths_) { + binary_path += prefix + path + "\n"; + } + + return binary_path; +} + +std::string Section::GetName() { + return name_; +} +} // namespace modules +} // namespace linkerconfig +} // namespace android \ No newline at end of file diff --git a/modules/tests/link_test.cc b/modules/tests/link_test.cc new file mode 100644 index 0000000..d84e3b4 --- /dev/null +++ b/modules/tests/link_test.cc @@ -0,0 +1,42 @@ +/* + * Copyright (C) 2019 The Android Open Source Project + * + * Licensed under the Apache License, Version 2.0 (the "License"); + * you may not use this file except in compliance with the License. + * You may obtain a copy of the License at + * + * http://www.apache.org/licenses/LICENSE-2.0 + * + * Unless required by applicable law or agreed to in writing, software + * distributed under the License is distributed on an "AS IS" BASIS, + * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. + * See the License for the specific language governing permissions and + * limitations under the License. + */ + +#include + +#include "linkerconfig/link.h" + +constexpr const char* kSharedLibsExpectedResult = + R"(namespace.originalNamespace.link.targetNamespace.shared_libs = lib1.so +namespace.originalNamespace.link.targetNamespace.shared_libs += lib2.so +namespace.originalNamespace.link.targetNamespace.shared_libs += lib3.so +)"; + +TEST(linkerconfig_link, link_with_all_shared_libs) { + auto link = std::make_shared( + "originalNamespace", "targetNamespace", true); + auto config_text = link->GenerateConfig(); + ASSERT_EQ(config_text, + "namespace.originalNamespace.link.targetNamespace.allow_all_shared_" + "libs = true\n"); +} + +TEST(linkerconfig_link, link_with_shared_libs) { + auto link = std::make_shared( + "originalNamespace", "targetNamespace"); + link->AddSharedLib("lib1.so", "lib2.so", "lib3.so"); + auto config_text = link->GenerateConfig(); + ASSERT_EQ(config_text, kSharedLibsExpectedResult); +} \ No newline at end of file diff --git a/modules/tests/modules_testbase.h b/modules/tests/modules_testbase.h new file mode 100644 index 0000000..7974416 --- /dev/null +++ b/modules/tests/modules_testbase.h @@ -0,0 +1,39 @@ +/* + * Copyright (C) 2019 The Android Open Source Project + * + * Licensed under the Apache License, Version 2.0 (the "License"); + * you may not use this file except in compliance with the License. + * You may obtain a copy of the License at + * + * http://www.apache.org/licenses/LICENSE-2.0 + * + * Unless required by applicable law or agreed to in writing, software + * distributed under the License is distributed on an "AS IS" BASIS, + * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. + * See the License for the specific language governing permissions and + * limitations under the License. + */ +#pragma once + +#include + +#include "linkerconfig/namespace.h" + +inline void DecorateNamespaceWithPaths( + std::shared_ptr ns) { + ns->AddSearchPath("/search_path1"); + ns->AddSearchPath("/search_path2", true, false); + ns->AddSearchPath("/search_path3", false, false); + ns->AddPermittedPath("/permitted_path1"); + ns->AddPermittedPath("/permitted_path2", true, false); + ns->AddPermittedPath("/permitted_path3", false, false); +} + +inline void DecorateNamespaceWithLinks( + std::shared_ptr ns, + std::string target_1, std::string target_2) { + auto link = ns->CreateLink(target_1, false); + link->AddSharedLib("lib1.so", "lib2.so", "lib3.so"); + + ns->CreateLink(target_2, true); +} \ No newline at end of file diff --git a/modules/tests/namespace_test.cc b/modules/tests/namespace_test.cc new file mode 100644 index 0000000..e6a70eb --- /dev/null +++ b/modules/tests/namespace_test.cc @@ -0,0 +1,77 @@ +/* + * Copyright (C) 2019 The Android Open Source Project + * + * Licensed under the Apache License, Version 2.0 (the "License"); + * you may not use this file except in compliance with the License. + * You may obtain a copy of the License at + * + * http://www.apache.org/licenses/LICENSE-2.0 + * + * Unless required by applicable law or agreed to in writing, software + * distributed under the License is distributed on an "AS IS" BASIS, + * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. + * See the License for the specific language governing permissions and + * limitations under the License. + */ + +#include + +#include "modules_testbase.h" + +constexpr const char* kExpectedSimpleNamespaceConfig = + R"(namespace.test_namespace.isolated = false +namespace.test_namespace.search.paths = /search_path1 +namespace.test_namespace.search.paths += /search_path2 +namespace.test_namespace.search.paths += /search_path3 +namespace.test_namespace.permitted.paths = /permitted_path1 +namespace.test_namespace.permitted.paths += /permitted_path2 +namespace.test_namespace.permitted.paths += /permitted_path3 +namespace.test_namespace.asan.search.paths = /search_path1 +namespace.test_namespace.asan.search.paths += /data/asan/search_path1 +namespace.test_namespace.asan.search.paths += /search_path2 +namespace.test_namespace.asan.permitted.paths = /permitted_path1 +namespace.test_namespace.asan.permitted.paths += /data/asan/permitted_path1 +namespace.test_namespace.asan.permitted.paths += /permitted_path2 +)"; + +constexpr const char* kExpectedNamespaceWithLinkConfig = + R"(namespace.test_namespace.isolated = true +namespace.test_namespace.visible = true +namespace.test_namespace.search.paths = /search_path1 +namespace.test_namespace.search.paths += /search_path2 +namespace.test_namespace.search.paths += /search_path3 +namespace.test_namespace.permitted.paths = /permitted_path1 +namespace.test_namespace.permitted.paths += /permitted_path2 +namespace.test_namespace.permitted.paths += /permitted_path3 +namespace.test_namespace.asan.search.paths = /search_path1 +namespace.test_namespace.asan.search.paths += /data/asan/search_path1 +namespace.test_namespace.asan.search.paths += /search_path2 +namespace.test_namespace.asan.permitted.paths = /permitted_path1 +namespace.test_namespace.asan.permitted.paths += /data/asan/permitted_path1 +namespace.test_namespace.asan.permitted.paths += /permitted_path2 +namespace.test_namespace.links = target_namespace1,target_namespace2 +namespace.test_namespace.link.target_namespace1.shared_libs = lib1.so +namespace.test_namespace.link.target_namespace1.shared_libs += lib2.so +namespace.test_namespace.link.target_namespace1.shared_libs += lib3.so +namespace.test_namespace.link.target_namespace2.allow_all_shared_libs = true +)"; + +TEST(linkerconfig_namespace, simple_namespace) { + auto ns = std::make_shared( + "test_namespace"); + DecorateNamespaceWithPaths(ns); + auto config = ns->GenerateConfig(); + + ASSERT_EQ(config, kExpectedSimpleNamespaceConfig); +} + +TEST(linkerconfig_namespace, namespace_with_links) { + auto ns = std::make_shared( + "test_namespace", /*is_isolated*/ true, + /*is_visible*/ true); + DecorateNamespaceWithPaths(ns); + DecorateNamespaceWithLinks(ns, "target_namespace1", "target_namespace2"); + auto config = ns->GenerateConfig(); + + ASSERT_EQ(config, kExpectedNamespaceWithLinkConfig); +} \ No newline at end of file diff --git a/modules/tests/section_test.cc b/modules/tests/section_test.cc new file mode 100644 index 0000000..697e595 --- /dev/null +++ b/modules/tests/section_test.cc @@ -0,0 +1,133 @@ +/* + * Copyright (C) 2019 The Android Open Source Project + * + * Licensed under the Apache License, Version 2.0 (the "License"); + * you may not use this file except in compliance with the License. + * You may obtain a copy of the License at + * + * http://www.apache.org/licenses/LICENSE-2.0 + * + * Unless required by applicable law or agreed to in writing, software + * distributed under the License is distributed on an "AS IS" BASIS, + * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. + * See the License for the specific language governing permissions and + * limitations under the License. + */ + +#include + +#include "linkerconfig/section.h" +#include "modules_testbase.h" + +constexpr const char* kSectionWithNamespacesExpectedResult = + R"([test_section] +additional.namespaces = namespace1,namespace2 +namespace.default.isolated = true +namespace.default.visible = true +namespace.default.search.paths = /search_path1 +namespace.default.search.paths += /search_path2 +namespace.default.search.paths += /search_path3 +namespace.default.permitted.paths = /permitted_path1 +namespace.default.permitted.paths += /permitted_path2 +namespace.default.permitted.paths += /permitted_path3 +namespace.default.asan.search.paths = /search_path1 +namespace.default.asan.search.paths += /data/asan/search_path1 +namespace.default.asan.search.paths += /search_path2 +namespace.default.asan.permitted.paths = /permitted_path1 +namespace.default.asan.permitted.paths += /data/asan/permitted_path1 +namespace.default.asan.permitted.paths += /permitted_path2 +namespace.default.links = namespace1,namespace2 +namespace.default.link.namespace1.shared_libs = lib1.so +namespace.default.link.namespace1.shared_libs += lib2.so +namespace.default.link.namespace1.shared_libs += lib3.so +namespace.default.link.namespace2.allow_all_shared_libs = true +namespace.namespace1.isolated = false +namespace.namespace1.search.paths = /search_path1 +namespace.namespace1.search.paths += /search_path2 +namespace.namespace1.search.paths += /search_path3 +namespace.namespace1.permitted.paths = /permitted_path1 +namespace.namespace1.permitted.paths += /permitted_path2 +namespace.namespace1.permitted.paths += /permitted_path3 +namespace.namespace1.asan.search.paths = /search_path1 +namespace.namespace1.asan.search.paths += /data/asan/search_path1 +namespace.namespace1.asan.search.paths += /search_path2 +namespace.namespace1.asan.permitted.paths = /permitted_path1 +namespace.namespace1.asan.permitted.paths += /data/asan/permitted_path1 +namespace.namespace1.asan.permitted.paths += /permitted_path2 +namespace.namespace1.links = default,namespace2 +namespace.namespace1.link.default.shared_libs = lib1.so +namespace.namespace1.link.default.shared_libs += lib2.so +namespace.namespace1.link.default.shared_libs += lib3.so +namespace.namespace1.link.namespace2.allow_all_shared_libs = true +namespace.namespace2.isolated = false +namespace.namespace2.search.paths = /search_path1 +namespace.namespace2.search.paths += /search_path2 +namespace.namespace2.search.paths += /search_path3 +namespace.namespace2.permitted.paths = /permitted_path1 +namespace.namespace2.permitted.paths += /permitted_path2 +namespace.namespace2.permitted.paths += /permitted_path3 +namespace.namespace2.asan.search.paths = /search_path1 +namespace.namespace2.asan.search.paths += /data/asan/search_path1 +namespace.namespace2.asan.search.paths += /search_path2 +namespace.namespace2.asan.permitted.paths = /permitted_path1 +namespace.namespace2.asan.permitted.paths += /data/asan/permitted_path1 +namespace.namespace2.asan.permitted.paths += /permitted_path2 +)"; + +constexpr const char* kSectionWithOneNamespaceExpectedResult = + R"([test_section] +namespace.default.isolated = false +namespace.default.search.paths = /search_path1 +namespace.default.search.paths += /search_path2 +namespace.default.search.paths += /search_path3 +namespace.default.permitted.paths = /permitted_path1 +namespace.default.permitted.paths += /permitted_path2 +namespace.default.permitted.paths += /permitted_path3 +namespace.default.asan.search.paths = /search_path1 +namespace.default.asan.search.paths += /data/asan/search_path1 +namespace.default.asan.search.paths += /search_path2 +namespace.default.asan.permitted.paths = /permitted_path1 +namespace.default.asan.permitted.paths += /data/asan/permitted_path1 +namespace.default.asan.permitted.paths += /permitted_path2 +)"; + +constexpr const char* kSectionBinaryPathExpectedResult = + R"(dir.test_section = binary_path1 +dir.test_section = binary_path2 +dir.test_section = binary_path3 +)"; +TEST(linkerconfig_section, section_with_namespaces) { + android::linkerconfig::modules::Section section("test_section"); + + auto default_namespace = section.CreateNamespace( + "default", /*is_isolated*/ true, /*is_visible*/ true); + DecorateNamespaceWithPaths(default_namespace); + DecorateNamespaceWithLinks(default_namespace, "namespace1", "namespace2"); + + auto namespace1 = section.CreateNamespace("namespace1"); + DecorateNamespaceWithPaths(namespace1); + DecorateNamespaceWithLinks(namespace1, "default", "namespace2"); + + auto namespace2 = section.CreateNamespace("namespace2"); + DecorateNamespaceWithPaths(namespace2); + + auto config = section.GenerateConfig(); + ASSERT_EQ(config, kSectionWithNamespacesExpectedResult); +} + +TEST(linkerconfig_section, section_with_one_namespace) { + android::linkerconfig::modules::Section section("test_section"); + auto ns = section.CreateNamespace("default"); + DecorateNamespaceWithPaths(ns); + + auto config = section.GenerateConfig(); + ASSERT_EQ(config, kSectionWithOneNamespaceExpectedResult); +} + +TEST(linkerconfig_section, binary_paths) { + android::linkerconfig::modules::Section section("test_section"); + section.AddBinaryPath("binary_path1", "binary_path2", "binary_path3"); + + auto binary_paths = section.GenerateBinaryPaths(); + ASSERT_EQ(binary_paths, kSectionBinaryPathExpectedResult); +} \ No newline at end of file -- 2.11.0