1 /*
2 * Copyright (C) 2019 The Android Open Source Project
3 *
4 * Licensed under the Apache License, Version 2.0 (the "License");
5 * you may not use this file except in compliance with the License.
6 * You may obtain a copy of the License at
7 *
8 * http://www.apache.org/licenses/LICENSE-2.0
9 *
10 * Unless required by applicable law or agreed to in writing, software
11 * distributed under the License is distributed on an "AS IS" BASIS,
12 * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
13 * See the License for the specific language governing permissions and
14 * limitations under the License.
15 */
16
17 #include "linkerconfig/namespace.h"
18 #include "linkerconfig/sectionbuilder.h"
19
20 #include <functional>
21 #include <vector>
22
23 #include "linkerconfig/common.h"
24 #include "linkerconfig/environment.h"
25 #include "linkerconfig/log.h"
26 #include "linkerconfig/namespacebuilder.h"
27 #include "linkerconfig/section.h"
28
29 using android::linkerconfig::contents::SectionType;
30 using android::linkerconfig::modules::ApexInfo;
31 using android::linkerconfig::modules::LibProvider;
32 using android::linkerconfig::modules::LibProviders;
33 using android::linkerconfig::modules::Namespace;
34 using android::linkerconfig::modules::Section;
35 using android::linkerconfig::modules::SharedLibs;
36
37 namespace android {
38 namespace linkerconfig {
39 namespace contents {
40
41 // Builds default section for the apex
42 // For com.android.foo,
43 // dir.com.android.foo = /apex/com.android.foo/bin
44 // [com.android.foo]
45 // additional.namespaces = system
46 // namespace.default....
47 // namespace.system...
BuildApexDefaultSection(Context & ctx,const ApexInfo & apex_info)48 Section BuildApexDefaultSection(Context& ctx, const ApexInfo& apex_info) {
49 ctx.SetCurrentSection(SectionType::Other);
50
51 bool target_apex_visible = apex_info.visible;
52 std::set<std::string> visible_apexes;
53 if (apex_info.name == "com.android.art") {
54 // ld.config.txt for the ART module needs to have the namespaces with public
55 // and JNI libs visible since it runs dalvikvm and hence libnativeloader,
56 // which builds classloader namespaces that may link to those libs.
57 for (const auto& apex : ctx.GetApexModules()) {
58 if (apex.jni_libs.size() > 0 || apex.public_libs.size() > 0) {
59 visible_apexes.insert(apex.name);
60 if (apex.name == apex_info.name) {
61 target_apex_visible = true;
62 }
63 }
64 }
65 }
66
67 std::vector<Namespace> namespaces;
68
69 // If target APEX should be visible, then there will be two namespaces -
70 // default and APEX namespace - with same set of libraries. To avoid any
71 // confusion based on two same namespaces, and also to avoid loading same
72 // library twice based on the namespace, use empty default namespace which
73 // does not contain any search path and fully links to visible APEX namespace.
74 if (target_apex_visible) {
75 namespaces.emplace_back(BuildApexEmptyDefaultNamespace(ctx, apex_info));
76 } else {
77 namespaces.emplace_back(BuildApexDefaultNamespace(ctx, apex_info));
78 }
79 namespaces.emplace_back(BuildApexPlatformNamespace(ctx));
80
81 // Vendor APEXes can use libs provided by "vendor"
82 // and Product APEXes can use libs provided by "product"
83 if (android::linkerconfig::modules::IsTreblelizedDevice()) {
84 if (apex_info.InVendor()) {
85 namespaces.emplace_back(BuildRsNamespace(ctx));
86 auto vendor = BuildVendorNamespace(ctx, "vendor");
87 if (!vendor.GetProvides().empty()) {
88 namespaces.emplace_back(std::move(vendor));
89 }
90 if (android::linkerconfig::modules::IsVendorVndkVersionDefined()) {
91 namespaces.emplace_back(
92 BuildVndkNamespace(ctx, VndkUserPartition::Vendor));
93 if (android::linkerconfig::modules::IsVndkInSystemNamespace()) {
94 namespaces.emplace_back(BuildVndkInSystemNamespace(ctx));
95 }
96 }
97 } else if (apex_info.InProduct()) {
98 auto product = BuildProductNamespace(ctx, "product");
99 if (!product.GetProvides().empty()) {
100 namespaces.emplace_back(std::move(product));
101 }
102 if (android::linkerconfig::modules::IsProductVndkVersionDefined()) {
103 namespaces.emplace_back(
104 BuildVndkNamespace(ctx, VndkUserPartition::Product));
105 if (android::linkerconfig::modules::IsVndkInSystemNamespace()) {
106 namespaces.emplace_back(BuildVndkInSystemNamespace(ctx));
107 }
108 }
109 }
110 }
111
112 LibProviders libs_providers;
113 if (apex_info.InVendor()) {
114 // In Vendor APEX, sphal namespace is not required and possible to cause
115 // same library being loaded from two namespaces (sphal and vendor). As
116 // SPHAL itself is not required from vendor (APEX) section, add vendor
117 // namespace instead.
118 libs_providers[":sphal"] = {LibProvider{
119 "vendor",
120 std::bind(BuildVendorNamespace, ctx, "vendor"),
121 SharedLibs{{}},
122 }};
123 } else {
124 libs_providers[":sphal"] = {LibProvider{
125 "sphal",
126 std::bind(BuildSphalNamespace, ctx),
127 SharedLibs{{}},
128 }};
129 }
130
131 bool in_vendor_with_vndk_enabled =
132 !apex_info.InProduct() &&
133 android::linkerconfig::modules::IsVendorVndkVersionDefined();
134 bool in_product_with_vndk_enabled =
135 apex_info.InProduct() &&
136 android::linkerconfig::modules::IsProductVndkVersionDefined();
137
138 if (in_vendor_with_vndk_enabled || in_product_with_vndk_enabled) {
139 VndkUserPartition user_partition = VndkUserPartition::Vendor;
140 std::string user_partition_suffix = "VENDOR";
141 if (apex_info.InProduct()) {
142 user_partition = VndkUserPartition::Product;
143 user_partition_suffix = "PRODUCT";
144 }
145 libs_providers[":sanitizer"] = {LibProvider{
146 ctx.GetSystemNamespaceName(),
147 std::bind(BuildApexPlatformNamespace,
148 ctx), // "system" should be available
149 SharedLibs{{Var("SANITIZER_DEFAULT_" + user_partition_suffix)}},
150 }};
151 libs_providers[":vndk"] = GetVndkProvider(ctx, user_partition);
152 libs_providers[":vndksp"] = {LibProvider{
153 "vndk",
154 std::bind(BuildVndkNamespace, ctx, user_partition),
155 SharedLibs{{Var("VNDK_SAMEPROCESS_LIBRARIES_" + user_partition_suffix)}},
156 }};
157 } else if (apex_info.InProduct() || apex_info.InVendor()) {
158 // vendor or product partitions don't need this because they link LLNDK
159 // libs. however, vendor/product apexes still need to link LLNDK sanitizer
160 // libs even though these are not listed in "required".
161 libs_providers[":sanitizer"] = {LibProvider{
162 ctx.GetSystemNamespaceName(),
163 std::bind(BuildApexPlatformNamespace,
164 ctx), // "system" should be available
165 SharedLibs{{Var("SANITIZER_LIBRARIES_LLNDK")}},
166 }};
167 }
168
169 if (apex_info.InVendor()) {
170 AddVendorSubdirNamespaceProviders(ctx, libs_providers);
171 }
172
173 return BuildSection(
174 ctx, apex_info.name, std::move(namespaces), visible_apexes, libs_providers);
175 }
176
177 } // namespace contents
178 } // namespace linkerconfig
179 } // namespace android
180