From 9788c86218207c2f1779bbc3a65b11733e7748b7 Mon Sep 17 00:00:00 2001 From: Logan Chien Date: Thu, 9 Mar 2017 17:20:06 +0800 Subject: [PATCH 1/2] vndk-def: Remove stale debug assertion. Test: ./tests/run.py Change-Id: I62bf6bb2b20be155901c088fbca18d35a9cdd6ad --- vndk/tools/definition-tool/vndk_definition_tool.py | 2 -- 1 file changed, 2 deletions(-) diff --git a/vndk/tools/definition-tool/vndk_definition_tool.py b/vndk/tools/definition-tool/vndk_definition_tool.py index 8b2b153e8..4e3b813ec 100755 --- a/vndk/tools/definition-tool/vndk_definition_tool.py +++ b/vndk/tools/definition-tool/vndk_definition_tool.py @@ -1043,8 +1043,6 @@ class ELFLinker(object): # Collect existing VNDK libraries. vndk_core, vndk_fwk_ext, vndk_vnd_ext = self.find_existing_vndk() - assert not vndk_core, "debug: no existing vndk core" - # Collect VNDK candidates. def is_not_vndk(lib): return (lib.is_ndk or banned_libs.is_banned(lib.path) or From d42d07d76232921573ded8db0c2cae89c025325c Mon Sep 17 00:00:00 2001 From: Logan Chien Date: Thu, 9 Mar 2017 17:21:29 +0800 Subject: [PATCH 2/2] vndk-def: Add vndk-cap subcommand. This commit adds vndk-cap subcommand. vndk-cap subcommand will compute the upper bound of the eligible libraries for VNDK definition. Test: ./tests/test_elf_linker.py Change-Id: Ie6600c35735de36055b2770836f2e87397221ddd --- .../definition-tool/tests/test_elf_linker.py | 89 ++++++++++++++++++- .../definition-tool/vndk_definition_tool.py | 59 ++++++++++++ 2 files changed, 147 insertions(+), 1 deletion(-) diff --git a/vndk/tools/definition-tool/tests/test_elf_linker.py b/vndk/tools/definition-tool/tests/test_elf_linker.py index dbdd95eef..de30de568 100755 --- a/vndk/tools/definition-tool/tests/test_elf_linker.py +++ b/vndk/tools/definition-tool/tests/test_elf_linker.py @@ -9,7 +9,8 @@ sys.path.append(os.path.dirname(os.path.dirname(os.path.abspath(__file__)))) import unittest from compat import StringIO -from vndk_definition_tool import ELF, ELFLinker, PT_SYSTEM, PT_VENDOR +from vndk_definition_tool import (BannedLibDict, ELF, ELFLinker, PT_SYSTEM, + PT_VENDOR) class GraphBuilder(object): @@ -451,6 +452,92 @@ class ELFLinkerTest(unittest.TestCase): self.assertSetEqual(expected_vndk_fwk_ext, vndk_fwk_ext) self.assertSetEqual(expected_vndk_vnd_ext, vndk_vnd_ext) + def test_compute_vndk_cap(self): + gb = GraphBuilder() + + # Add LL-NDK libraries. + gb.add_multilib(PT_SYSTEM, 'libc') + gb.add_multilib(PT_SYSTEM, 'libdl') + gb.add_multilib(PT_SYSTEM, 'liblog') + gb.add_multilib(PT_SYSTEM, 'libm') + gb.add_multilib(PT_SYSTEM, 'libstdc++') + gb.add_multilib(PT_SYSTEM, 'libz') + + # Add SP-NDK libraries. + gb.add_multilib(PT_SYSTEM, 'libEGL') + gb.add_multilib(PT_SYSTEM, 'libGLES_v2') + + # Add banned libraries. + gb.add_multilib(PT_SYSTEM, 'libbinder') + gb.add_multilib(PT_SYSTEM, 'libselinux') + + # Add good examples. + gb.add_multilib(PT_SYSTEM, 'libgood_a', dt_needed=['libc.so']) + gb.add_multilib(PT_SYSTEM, 'libgood_b', dt_needed=['libEGL.so']) + gb.add_multilib(PT_SYSTEM, 'libgood_c', dt_needed=['libGLES_v2.so']) + + # Add bad examples. + gb.add_multilib(PT_SYSTEM, 'libbad_a', dt_needed=['libbinder.so']) + gb.add_multilib(PT_SYSTEM, 'libbad_b', dt_needed=['libselinux.so']) + gb.add_multilib(PT_SYSTEM, 'libbad_c', dt_needed=['libbad_a.so']) + gb.add_multilib(PT_SYSTEM, 'libbad_d', dt_needed=['libbad_c.so']) + gb.add_multilib(PT_VENDOR, 'libbad_e', dt_needed=['libc.so']) + + gb.resolve() + + # Compute VNDK cap. + banned_libs = BannedLibDict.create_default() + vndk_cap = gb.graph.compute_vndk_cap(banned_libs) + vndk_cap = set(lib.path for lib in vndk_cap) + + # Check the existence of good examples. + self.assertIn('/system/lib/libgood_a.so', vndk_cap) + self.assertIn('/system/lib/libgood_b.so', vndk_cap) + self.assertIn('/system/lib/libgood_c.so', vndk_cap) + + self.assertIn('/system/lib64/libgood_a.so', vndk_cap) + self.assertIn('/system/lib64/libgood_b.so', vndk_cap) + self.assertIn('/system/lib64/libgood_c.so', vndk_cap) + + # Check the absence of bad examples. + self.assertNotIn('/system/lib/libbad_a.so', vndk_cap) + self.assertNotIn('/system/lib/libbad_b.so', vndk_cap) + self.assertNotIn('/system/lib/libbad_c.so', vndk_cap) + self.assertNotIn('/system/lib/libbad_d.so', vndk_cap) + self.assertNotIn('/vendor/lib/libbad_e.so', vndk_cap) + + self.assertNotIn('/system/lib64/libbad_a.so', vndk_cap) + self.assertNotIn('/system/lib64/libbad_b.so', vndk_cap) + self.assertNotIn('/system/lib64/libbad_c.so', vndk_cap) + self.assertNotIn('/system/lib64/libbad_d.so', vndk_cap) + self.assertNotIn('/vendor/lib64/libbad_e.so', vndk_cap) + + # Check the absence of banned libraries. + self.assertNotIn('/system/lib/libbinder.so', vndk_cap) + self.assertNotIn('/system/lib/libselinux.so', vndk_cap) + + self.assertNotIn('/system/lib64/libbinder.so', vndk_cap) + self.assertNotIn('/system/lib64/libselinux.so', vndk_cap) + + # Check the absence of NDK libraries. Although LL-NDK and SP-NDK + # libraries are not banned, they are not VNDK libraries either. + self.assertNotIn('/system/lib/libEGL.so', vndk_cap) + self.assertNotIn('/system/lib/libOpenGLES_v2.so', vndk_cap) + self.assertNotIn('/system/lib/libc.so', vndk_cap) + self.assertNotIn('/system/lib/libdl.so', vndk_cap) + self.assertNotIn('/system/lib/liblog.so', vndk_cap) + self.assertNotIn('/system/lib/libm.so', vndk_cap) + self.assertNotIn('/system/lib/libstdc++.so', vndk_cap) + self.assertNotIn('/system/lib/libz.so', vndk_cap) + + self.assertNotIn('/system/lib64/libEGL.so', vndk_cap) + self.assertNotIn('/system/lib64/libOpenGLES_v2.so', vndk_cap) + self.assertNotIn('/system/lib64/libc.so', vndk_cap) + self.assertNotIn('/system/lib64/libdl.so', vndk_cap) + self.assertNotIn('/system/lib64/liblog.so', vndk_cap) + self.assertNotIn('/system/lib64/libm.so', vndk_cap) + self.assertNotIn('/system/lib64/libstdc++.so', vndk_cap) + self.assertNotIn('/system/lib64/libz.so', vndk_cap) if __name__ == '__main__': unittest.main() diff --git a/vndk/tools/definition-tool/vndk_definition_tool.py b/vndk/tools/definition-tool/vndk_definition_tool.py index 4e3b813ec..12902b038 100755 --- a/vndk/tools/definition-tool/vndk_definition_tool.py +++ b/vndk/tools/definition-tool/vndk_definition_tool.py @@ -1282,6 +1282,43 @@ class ELFLinker(object): extra_system_libs, extra_vendor_libs, extra_vndk_core, vndk_core, vndk_indirect, vndk_fwk_ext, vndk_vnd_ext) + def compute_vndk_cap(self, banned_libs): + # ELF files on vendor partitions are banned unconditionally. ELF files + # on the system partition are banned if their file extensions are not + # '.so' or their file names are listed in banned_libs. LL-NDK and + # SP-NDK libraries are treated as a special case which will not be + # considered as banned libraries at the moment. + def is_banned(lib): + if lib.is_ndk: + return NDK_LIBS.is_hlndk(lib.path) + return (banned_libs.is_banned(lib.path) or + not lib.is_system_lib() or + not lib.path.endswith('.so')) + + # Find all libraries that are banned. + banned_set = set() + for lib_set in self.lib_pt: + for lib in lib_set.values(): + if is_banned(lib): + banned_set.add(lib) + + # Find the transitive closure of the banned libraries. + stack = list(banned_set) + while stack: + lib = stack.pop() + for user in lib.users: + if not user.is_ndk and user not in banned_set: + banned_set.add(user) + stack.append(user) + + # Find the non-NDK non-banned libraries. + vndk_cap = set() + for lib in self.lib_pt[PT_SYSTEM].values(): + if not lib.is_ndk and lib not in banned_set: + vndk_cap.add(lib) + + return vndk_cap + @staticmethod def compute_closure(root_set, is_excluded): closure = set(root_set) @@ -1648,6 +1685,27 @@ class VNDKCommand(ELFGraphCommand): return 0 +class VNDKCapCommand(ELFGraphCommand): + def __init__(self): + super(VNDKCapCommand, self).__init__( + 'vndk-cap', help='Compute VNDK set upper bound') + + def add_argparser_options(self, parser): + super(VNDKCapCommand, self).add_argparser_options(parser) + + def main(self, args): + graph = ELFLinker.create(args.system, args.system_dir_as_vendor, + args.vendor, args.vendor_dir_as_system, + args.load_extra_deps) + + banned_libs = BannedLibDict.create_default() + + vndk_cap = graph.compute_vndk_cap(banned_libs) + + for lib in sorted_lib_path_list(vndk_cap): + print(lib) + + class DepsCommand(ELFGraphCommand): def __init__(self): super(DepsCommand, self).__init__( @@ -1788,6 +1846,7 @@ def main(): register_subcmd(ELFDumpCommand()) register_subcmd(CreateGenericRefCommand()) register_subcmd(VNDKCommand()) + register_subcmd(VNDKCapCommand()) register_subcmd(DepsCommand()) register_subcmd(DepsClosureCommand()) register_subcmd(SpHalCommand())