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/sectionbuilder.h"
18 
19 #include <functional>
20 #include <vector>
21 
22 #include "linkerconfig/common.h"
23 #include "linkerconfig/log.h"
24 #include "linkerconfig/namespacebuilder.h"
25 #include "linkerconfig/section.h"
26 
27 using android::linkerconfig::contents::SectionType;
28 using android::linkerconfig::modules::ApexInfo;
29 using android::linkerconfig::modules::LibProvider;
30 using android::linkerconfig::modules::LibProviders;
31 using android::linkerconfig::modules::Namespace;
32 using android::linkerconfig::modules::Section;
33 
34 namespace android {
35 namespace linkerconfig {
36 namespace contents {
37 
38 // Builds default section for the apex
39 // For com.android.foo,
40 //   dir.com.android.foo = /apex/com.android.foo/bin
41 //   [com.android.foo]
42 //   additional.namespaces = system
43 //   namespace.default....
44 //   namespace.system...
BuildApexDefaultSection(Context & ctx,const ApexInfo & apex_info)45 Section BuildApexDefaultSection(Context& ctx, const ApexInfo& apex_info) {
46   ctx.SetCurrentSection(SectionType::Other);
47 
48   bool target_apex_visible = apex_info.visible;
49   std::set<std::string> visible_apexes;
50   if (apex_info.name == "com.android.art") {
51     // ld.config.txt for the ART module needs to have the namespaces with public
52     // and JNI libs visible since it runs dalvikvm and hence libnativeloader,
53     // which builds classloader namespaces that may link to those libs.
54     for (const auto& apex : ctx.GetApexModules()) {
55       if (apex.jni_libs.size() > 0 || apex.public_libs.size() > 0) {
56         visible_apexes.insert(apex.name);
57         if (apex.name == apex_info.name) {
58           target_apex_visible = true;
59         }
60       }
61     }
62   }
63 
64   std::vector<Namespace> namespaces;
65 
66   // If target APEX should be visible, then there will be two namespaces -
67   // default and APEX namespace - with same set of libraries. To avoid any
68   // confusion based on two same namespaces, and also to avoid loading same
69   // library twice based on the namespace, use empty default namespace which
70   // does not contain any search path and fully links to visible APEX namespace.
71   if (target_apex_visible) {
72     namespaces.emplace_back(BuildApexEmptyDefaultNamespace(ctx, apex_info));
73   } else {
74     namespaces.emplace_back(BuildApexDefaultNamespace(ctx, apex_info));
75   }
76   namespaces.emplace_back(BuildApexPlatformNamespace(ctx));
77 
78   LibProviders libs_providers;
79   libs_providers[":sphal"] = LibProvider{
80       "sphal",
81       std::bind(BuildSphalNamespace, ctx),
82       {},
83   };
84   if (ctx.IsVndkAvailable()) {
85     VndkUserPartition user_partition = VndkUserPartition::Vendor;
86     std::string user_partition_suffix = "VENDOR";
87     if (apex_info.InProduct()) {
88       user_partition = VndkUserPartition::Product;
89       user_partition_suffix = "PRODUCT";
90     }
91     libs_providers[":sanitizer"] = LibProvider{
92         ctx.GetSystemNamespaceName(),
93         std::bind(BuildApexPlatformNamespace,
94                   ctx),  // "system" should be available
95         {Var("SANITIZER_DEFAULT_" + user_partition_suffix)},
96     };
97     libs_providers[":vndk"] = LibProvider{
98         "vndk",
99         std::bind(BuildVndkNamespace, ctx, user_partition),
100         {Var("VNDK_SAMEPROCESS_LIBRARIES_" + user_partition_suffix),
101          Var("VNDK_CORE_LIBRARIES_" + user_partition_suffix)},
102     };
103     libs_providers[":vndksp"] = LibProvider{
104         "vndk",
105         std::bind(BuildVndkNamespace, ctx, user_partition),
106         {Var("VNDK_SAMEPROCESS_LIBRARIES_" + user_partition_suffix)},
107     };
108   }
109 
110   return BuildSection(
111       ctx, apex_info.name, std::move(namespaces), visible_apexes, libs_providers);
112 }
113 
114 }  // namespace contents
115 }  // namespace linkerconfig
116 }  // namespace android
117