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/variableloader.h"
18 
19 #include <android-base/result.h>
20 #include <android-base/strings.h>
21 
22 #include <climits>
23 #include <cstdlib>
24 #include <cstring>
25 
26 #include "linkerconfig/environment.h"
27 #include "linkerconfig/librarylistloader.h"
28 #include "linkerconfig/log.h"
29 #include "linkerconfig/stringutil.h"
30 #include "linkerconfig/variables.h"
31 
32 using android::base::Result;
33 using android::linkerconfig::modules::GetProductVndkVersion;
34 using android::linkerconfig::modules::GetVendorVndkVersion;
35 using android::linkerconfig::modules::TrimPrefix;
36 using android::linkerconfig::modules::Variables;
37 
38 namespace {
39 using namespace android::linkerconfig::generator;
40 
41 // Stub libraries are list of libraries which has stub interface and installed
42 // in system image so other partition and APEX modules can link to it.
43 // TODO(b/147210213) : Generate this list on build and read from the file
44 std::vector<std::string> stub_libraries = {
45     "libEGL.so",
46     "libGLESv1_CM.so",
47     "libGLESv2.so",
48     "libGLESv3.so",
49     "libRS.so",
50     "libaaudio.so",
51     "libadbd_auth.so",
52     "libadbd_fs.so",
53     "libandroid.so",
54     "libandroid_net.so",
55     "libbinder_ndk.so",
56     "libc.so",
57     "libcgrouprc.so",
58     "libclang_rt.asan-arm-android.so",
59     "libclang_rt.asan-i686-android.so",
60     "libclang_rt.asan-x86_64-android.so",
61     "libdl.so",
62     "libdl_android.so",
63     "libft2.so",
64     "libincident.so",
65     "liblog.so",
66     "libm.so",
67     "libmediametrics.so",
68     "libmediandk.so",
69     "libnativewindow.so",
70     "libneuralnetworks_packageinfo.so",
71     "libsync.so",
72     "libvndksupport.so",
73     "libvulkan.so",
74     "libselinux.so",
75 };
76 
77 void LoadVndkVersionVariable() {
78   Variables::AddValue("VENDOR_VNDK_VERSION", GetVendorVndkVersion());
79   Variables::AddValue("PRODUCT_VNDK_VERSION", GetProductVndkVersion());
80 }
81 
82 Result<std::string> GetRealPath(std::string target_path) {
83   char resolved_path[PATH_MAX];
84   if (realpath(target_path.c_str(), resolved_path) != nullptr) {
85     return resolved_path;
86   }
87 
88   return ErrnoErrorf("Failed to get realpath from {}", target_path);
89 }
90 
91 void LoadVariableFromPartitionPath(const std::string& root,
92                                    std::string variable_name,
93                                    std::string partition) {
94   auto real_path = GetRealPath(root + partition);
95 
96   if (real_path.ok()) {
97     Variables::AddValue(variable_name, TrimPrefix(*real_path, root));
98   } else {
99     LOG(WARNING) << real_path.error();
100     Variables::AddValue(variable_name, partition);
101   }
102 }
103 
104 void LoadPartitionPathVariables(const std::string& root) {
105   // TODO(b/141714913): generalize path handling
106   LoadVariableFromPartitionPath(root, "PRODUCT", "/product");
107   LoadVariableFromPartitionPath(root, "SYSTEM_EXT", "/system_ext");
108 }
109 
110 void LoadVndkLibraryListVariables(const std::string& root,
111                                   const std::string& vndk_version,
112                                   const std::string& partition) {
113   if (vndk_version == "") {
114     return;
115   }
116   const std::string vndk_path = root + "/apex/com.android.vndk.v" + vndk_version;
117   // Skip loading if VNDK APEX is not available
118   if (::access(vndk_path.c_str(), F_OK) != 0) {
119     return;
120   }
121   const std::string llndk_libraries_path =
122       vndk_path + "/etc/llndk.libraries." + vndk_version + ".txt";
123   const std::string vndksp_libraries_path =
124       vndk_path + "/etc/vndksp.libraries." + vndk_version + ".txt";
125   const std::string vndkcore_libraries_path =
126       vndk_path + "/etc/vndkcore.libraries." + vndk_version + ".txt";
127   const std::string vndkprivate_libraries_path =
128       vndk_path + "/etc/vndkprivate.libraries." + vndk_version + ".txt";
129   const std::string sanitizer_library_path =
130       root + "/system/etc/sanitizer.libraries.txt";
131 
132   Variables::AddValue("LLNDK_LIBRARIES_" + partition,
133                       GetPublicLibrariesString(llndk_libraries_path,
134                                                vndkprivate_libraries_path));
135 
136   Variables::AddValue("PRIVATE_LLNDK_LIBRARIES_" + partition,
137                       GetPrivateLibrariesString(llndk_libraries_path,
138                                                 vndkprivate_libraries_path));
139 
140   Variables::AddValue("VNDK_SAMEPROCESS_LIBRARIES_" + partition,
141                       GetPublicLibrariesString(vndksp_libraries_path,
142                                                vndkprivate_libraries_path));
143 
144   Variables::AddValue("VNDK_CORE_LIBRARIES_" + partition,
145                       GetPublicLibrariesString(vndkcore_libraries_path,
146                                                vndkprivate_libraries_path));
147 
148   Variables::AddValue("SANITIZER_DEFAULT_" + partition,
149                       GetPublicLibrariesString(sanitizer_library_path,
150                                                vndkcore_libraries_path));
151 
152   if (partition == "VENDOR") {
153     auto vndkcorevariant_library_path =
154         root + "/system/etc/vndkcorevariant.libraries.txt";
155     Variables::AddValue("VNDK_USING_CORE_VARIANT_LIBRARIES",
156                         GetPublicLibrariesString(vndkcorevariant_library_path,
157                                                  vndkprivate_libraries_path));
158   }
159 }
160 
161 void LoadLibraryListVariables(const std::string& root) {
162   LoadVndkLibraryListVariables(root, GetVendorVndkVersion(), "VENDOR");
163   LoadVndkLibraryListVariables(root, GetProductVndkVersion(), "PRODUCT");
164 
165   auto sanitizer_library_path = root + "/system/etc/sanitizer.libraries.txt";
166   Variables::AddValue("SANITIZER_RUNTIME_LIBRARIES",
167                       GetLibrariesString(sanitizer_library_path));
168 
169   Variables::AddValue("STUB_LIBRARIES",
170                       android::base::Join(stub_libraries, ':'));
171 }
172 }  // namespace
173 
174 namespace android {
175 namespace linkerconfig {
176 namespace generator {
177 
178 void LoadVariables(const std::string& root) {
179   LoadVndkVersionVariable();
180   LoadPartitionPathVariables(root);
181   LoadLibraryListVariables(root);
182 }
183 
184 }  // namespace generator
185 }  // namespace linkerconfig
186 }  // namespace android
187