blob: b2183bbaa347f366158e078e1219074d00191ffe [file] [log] [blame]
Hsin-Yi Chen5b7084f2017-08-21 11:37:34 +08001#
2# Copyright (C) 2017 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
Logan Chien9f799bf2018-07-05 19:09:17 +080017import collections
Dan Shif5c3e3c2020-03-11 15:40:11 +000018import json
Hsin-Yi Chen5b7084f2017-08-21 11:37:34 +080019import logging
20import os
Hsin-Yi Chenf4f34ab2020-02-04 15:29:51 +080021import re
Dan Shif5c3e3c2020-03-11 15:40:11 +000022import zipfile
Hsin-Yi Chenf4f34ab2020-02-04 15:29:51 +080023
24try:
25 from importlib import resources
26except ImportError:
27 resources = None
Hsin-Yi Chen5b7084f2017-08-21 11:37:34 +080028
Logan Chien9f799bf2018-07-05 19:09:17 +080029# The tags in VNDK list:
Hsin-Yi Chen5b7084f2017-08-21 11:37:34 +080030# Low-level NDK libraries that can be used by framework and vendor modules.
Logan Chien9f799bf2018-07-05 19:09:17 +080031LL_NDK = "LLNDK"
Hsin-Yi Chen5b7084f2017-08-21 11:37:34 +080032
Hsin-Yi Chene4d3f2a2018-01-03 17:42:46 +080033# Same-process HAL implementation in vendor partition.
34SP_HAL = "SP-HAL"
35
Hsin-Yi Chen5b7084f2017-08-21 11:37:34 +080036# Framework libraries that can be used by vendor modules except same-process HAL
37# and its dependencies in vendor partition.
Logan Chien9f799bf2018-07-05 19:09:17 +080038VNDK = "VNDK-core"
Hsin-Yi Chen5b7084f2017-08-21 11:37:34 +080039
Hsin-Yi Chenc81d0cc2018-02-26 10:29:26 +080040# VNDK dependencies that vendor modules cannot directly access.
Logan Chien9f799bf2018-07-05 19:09:17 +080041VNDK_PRIVATE = "VNDK-core-private"
Hsin-Yi Chenc81d0cc2018-02-26 10:29:26 +080042
Hsin-Yi Chen5b7084f2017-08-21 11:37:34 +080043# Same-process HAL dependencies in framework.
44VNDK_SP = "VNDK-SP"
45
Hsin-Yi Chen5b7084f2017-08-21 11:37:34 +080046# VNDK-SP dependencies that vendor modules cannot directly access.
Logan Chien9f799bf2018-07-05 19:09:17 +080047VNDK_SP_PRIVATE = "VNDK-SP-private"
Hsin-Yi Chen5b7084f2017-08-21 11:37:34 +080048
Dan Shif5c3e3c2020-03-11 15:40:11 +000049# The tuples of (ABI name, bitness, arch name). 64-bit comes before 32-bit in
50# order to sequentially search for longest prefix.
51_ABI_LIST = (
Hsin-Yi Chenb7e1a052022-03-10 14:53:29 +080052 ("arm64", 64, "arm64"),
53 ("arm64", 32, "arm_arm64"),
54 ("arm", 32, "arm"),
Salini Venateccc18232021-04-11 16:18:19 +053055 ("x86_64", 64, "x86_64"),
56 ("x86_64", 32, "x86_x86_64"),
Dan Shif5c3e3c2020-03-11 15:40:11 +000057 ("x86", 32, "x86"),
58)
Hsin-Yi Chen5b7084f2017-08-21 11:37:34 +080059
60# The data directory.
61_GOLDEN_DIR = os.path.join("vts", "testcases", "vndk", "golden")
62
Hsin-Yi Chenf4f34ab2020-02-04 15:29:51 +080063# The data package.
Hsin-Yi Chenf3d411a2021-06-15 14:02:30 +080064_RESOURCE_PACKAGE = "vts.testcases.vndk"
Hsin-Yi Chenf4f34ab2020-02-04 15:29:51 +080065
Dan Shif5c3e3c2020-03-11 15:40:11 +000066# The name of the zip file containing ABI dumps.
67_ABI_DUMP_ZIP_NAME = "abi_dump.zip"
68
Logan Chien9f799bf2018-07-05 19:09:17 +080069# Regular expression prefix for library name patterns.
70_REGEX_PREFIX = "[regex]"
Hsin-Yi Chen5b7084f2017-08-21 11:37:34 +080071
Hsin-Yi Chen50f63f02017-12-14 15:34:41 +080072
Dan Shif5c3e3c2020-03-11 15:40:11 +000073class AbiDumpResource:
74 """The class for loading ABI dumps from the zip in resources."""
75
76 def __init__(self):
77 self._resource = None
78 self.zip_file = None
79
80 def __enter__(self):
81 self._resource = resources.open_binary(_RESOURCE_PACKAGE,
82 _ABI_DUMP_ZIP_NAME)
83 self.zip_file = zipfile.ZipFile(self._resource, "r")
84 return self
85
86 def __exit__(self, exc_type, exc_val, traceback):
87 if self._resource:
88 self._resource.close()
89 if self.zip_file:
90 self.zip_file.close()
91
92
93def GetAbiDumpPathsFromResources(version, binder_bitness, abi_name, abi_bitness):
94 """Returns the VNDK dump paths in resources.
95
96 Args:
97 version: A string, the VNDK version.
98 binder_bitness: A string or an integer, 32 or 64.
99 abi_name: A string, the ABI of the library dump.
100 abi_bitness: A string or an integer, 32 or 64.
101
102 Returns:
103 A dict of {library name: dump resource path}. For example,
104 {"libbase.so": "R/64/arm64_armv8-a/source-based/libbase.so.lsdump"}.
105 If there is no dump for the version and ABI, this function returns an
106 empty dict.
107 """
108 if not resources:
109 logging.error("Could not import resources module.")
110 return dict()
111
112 abi_bitness = int(abi_bitness)
113 try:
114 arch_name = next(x[2] for x in _ABI_LIST if
115 abi_name.startswith(x[0]) and x[1] == abi_bitness)
116 except StopIteration:
117 logging.warning("Unknown %d-bit ABI %s.", abi_bitness, abi_name)
118 return dict()
119
120 # The separator in zipped path is always "/".
121 dump_dir = "/".join((version, str(binder_bitness), arch_name,
122 "source-based")) + "/"
123
124 dump_paths = dict()
125
126 with AbiDumpResource() as dump_resource:
127 for path in dump_resource.zip_file.namelist():
128 if path.startswith(dump_dir) and path.endswith(".lsdump"):
129 lib_name = path[len(dump_dir):-len(".lsdump")]
130 dump_paths[lib_name] = path
131
132 return dump_paths
133
134
Hsin-Yi Chenf4f34ab2020-02-04 15:29:51 +0800135def _LoadVndkLibraryListsFile(vndk_lists, tags, vndk_lib_list_file):
Logan Chien9f799bf2018-07-05 19:09:17 +0800136 """Load VNDK libraries from the file to the specified tuple.
137
138 Args:
139 vndk_lists: The output tuple of lists containing library names.
140 tags: Strings, the tags of the libraries to find.
Hsin-Yi Chenf4f34ab2020-02-04 15:29:51 +0800141 vndk_lib_list_file: The file object containing the VNDK library list.
Logan Chien9f799bf2018-07-05 19:09:17 +0800142 """
143
144 lib_sets = collections.defaultdict(set)
145
146 # Load VNDK tags from the list.
Hsin-Yi Chenf4f34ab2020-02-04 15:29:51 +0800147 for line in vndk_lib_list_file:
148 # Ignore comments.
149 if line.startswith('#'):
150 continue
Logan Chien9f799bf2018-07-05 19:09:17 +0800151
Hsin-Yi Chenf4f34ab2020-02-04 15:29:51 +0800152 # Split columns.
153 cells = line.split(': ', 1)
154 if len(cells) < 2:
155 continue
156 tag = cells[0]
157 lib_name = cells[1].strip()
Logan Chien9f799bf2018-07-05 19:09:17 +0800158
Hsin-Yi Chenf4f34ab2020-02-04 15:29:51 +0800159 lib_sets[tag].add(lib_name)
Logan Chien9f799bf2018-07-05 19:09:17 +0800160
161 # Compute VNDK-core-private and VNDK-SP-private.
162 private = lib_sets.get('VNDK-private', set())
163
Logan Chien9f799bf2018-07-05 19:09:17 +0800164 lib_sets[VNDK_PRIVATE].update(lib_sets[VNDK] & private)
165 lib_sets[VNDK_SP_PRIVATE].update(lib_sets[VNDK_SP] & private)
166
167 lib_sets[LL_NDK].difference_update(private)
168 lib_sets[VNDK].difference_update(private)
169 lib_sets[VNDK_SP].difference_update(private)
170
171 # Update the output entries.
172 for index, tag in enumerate(tags):
173 for lib_name in lib_sets.get(tag, tuple()):
174 if lib_name.startswith(_REGEX_PREFIX):
175 lib_name = lib_name[len(_REGEX_PREFIX):]
176 vndk_lists[index].append(lib_name)
177
178
Hsin-Yi Chenf4f34ab2020-02-04 15:29:51 +0800179def LoadVndkLibraryListsFromResources(version, *tags):
180 """Find the VNDK libraries with specific tags in resources.
181
182 Args:
183 version: A string, the VNDK version.
184 *tags: Strings, the tags of the libraries to find.
185
186 Returns:
187 A tuple of lists containing library names. Each list corresponds to
188 one tag in the argument. For SP-HAL, the returned names are regular
189 expressions.
190 None if the VNDK list for the version is not found.
191 """
192 if not resources:
193 logging.error("Could not import resources module.")
194 return None
195
196 version_str = (version if version and re.match("\\d+", version) else
197 "current")
198 vndk_lib_list_name = version_str + ".txt"
199 vndk_lib_extra_list_name = "vndk-lib-extra-list-" + version_str + ".txt"
200
201 if not resources.is_resource(_RESOURCE_PACKAGE, vndk_lib_list_name):
202 logging.warning("Cannot load %s.", vndk_lib_list_name)
203 return None
204
205 if not resources.is_resource(_RESOURCE_PACKAGE, vndk_lib_extra_list_name):
206 logging.warning("Cannot load %s.", vndk_lib_extra_list_name)
207 return None
208
209 vndk_lists = tuple([] for x in tags)
210
211 with resources.open_text(_RESOURCE_PACKAGE, vndk_lib_list_name) as f:
212 _LoadVndkLibraryListsFile(vndk_lists, tags, f)
213 with resources.open_text(_RESOURCE_PACKAGE, vndk_lib_extra_list_name) as f:
214 _LoadVndkLibraryListsFile(vndk_lists, tags, f)
Hsin-Yi Chen5b7084f2017-08-21 11:37:34 +0800215 return vndk_lists