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
This commit is contained in:
@@ -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()
|
||||
|
||||
@@ -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())
|
||||
|
||||
Reference in New Issue
Block a user