summaryrefslogtreecommitdiffstats
path: root/vndk
diff options
context:
space:
mode:
authorLogan Chien <loganchien@google.com>2019-01-03 17:48:34 +0800
committerLogan Chien <loganchien@google.com>2019-01-03 18:18:04 +0800
commit64c28f7422950f5684e446722bcf188483505407 (patch)
treefa0907a917cff9fbd1e41c097b277b4ae1229365 /vndk
parentd7867edc4f1cdb176ce2f142dee2bbaae83bc68f (diff)
downloadandroid_development-64c28f7422950f5684e446722bcf188483505407.tar.gz
android_development-64c28f7422950f5684e446722bcf188483505407.tar.bz2
android_development-64c28f7422950f5684e446722bcf188483505407.zip
vndk-def: Separate methods with two empty lines
This commit adds several empty lines to the file so that all method definitions in `vndk_definition_tool.py` are separated by two empty lines. Test: n/a Change-Id: I5976dec4ba73a80a29693bfa92fcaf5ecceace9d
Diffstat (limited to 'vndk')
-rw-r--r--vndk/tools/definition-tool/tests/compat.py10
-rwxr-xr-xvndk/tools/definition-tool/tests/ndk_toolchain.py13
-rwxr-xr-xvndk/tools/definition-tool/tests/run.py1
-rwxr-xr-xvndk/tools/definition-tool/tests/test_elf.py15
-rwxr-xr-xvndk/tools/definition-tool/tests/test_elf_link_data.py8
-rwxr-xr-xvndk/tools/definition-tool/tests/test_elf_resolver.py2
-rwxr-xr-xvndk/tools/definition-tool/tests/test_elfdump.py6
-rwxr-xr-xvndk/tools/definition-tool/tests/test_generic_refs.py4
-rwxr-xr-xvndk/tools/definition-tool/tests/test_module_info.py1
-rw-r--r--vndk/tools/definition-tool/tests/utils.py7
-rwxr-xr-xvndk/tools/definition-tool/vndk_definition_tool.py164
11 files changed, 231 insertions, 0 deletions
diff --git a/vndk/tools/definition-tool/tests/compat.py b/vndk/tools/definition-tool/tests/compat.py
index 9f418539d..7fcbc2e93 100644
--- a/vndk/tools/definition-tool/tests/compat.py
+++ b/vndk/tools/definition-tool/tests/compat.py
@@ -3,30 +3,37 @@
import os
import sys
+
try:
from tempfile import TemporaryDirectory
except ImportError:
import shutil
import tempfile
+
class TemporaryDirectory(object):
def __init__(self, suffix='', prefix='tmp', dir=None):
self.name = tempfile.mkdtemp(suffix, prefix, dir)
+
def __del__(self):
self.cleanup()
+
def __enter__(self):
return self.name
+
def __exit__(self, exc, value, tb):
self.cleanup()
+
def cleanup(self):
if self.name:
shutil.rmtree(self.name)
self.name = None
+
if sys.version_info >= (3, 0):
from os import makedirs
else:
@@ -35,6 +42,7 @@ else:
return
return os.makedirs(path)
+
if sys.version_info >= (3, 0):
from io import StringIO
else:
@@ -45,6 +53,8 @@ try:
from unittest.mock import patch
except ImportError:
import contextlib
+
+
@contextlib.contextmanager
def patch(target, mock):
obj, attr = target.rsplit('.')
diff --git a/vndk/tools/definition-tool/tests/ndk_toolchain.py b/vndk/tools/definition-tool/tests/ndk_toolchain.py
index 8ad9144ce..485b1b85c 100755
--- a/vndk/tools/definition-tool/tests/ndk_toolchain.py
+++ b/vndk/tools/definition-tool/tests/ndk_toolchain.py
@@ -9,6 +9,7 @@ import re
import subprocess
import sys
+
def detect_ndk_dir():
ndk_dir = os.getenv('NDK')
if not ndk_dir:
@@ -28,6 +29,7 @@ error:'''
return ndk_dir
+
def detect_api_level(ndk_dir):
try:
apis = []
@@ -42,6 +44,7 @@ def detect_api_level(ndk_dir):
except IOError:
raise ValueError('failed to find latest api')
+
def detect_host():
if sys.platform.startswith('linux'):
return 'linux-x86_64'
@@ -49,15 +52,19 @@ def detect_host():
return 'darwin-x86_64'
raise NotImplementedError('unknown host platform')
+
def get_gcc_dir(ndk_dir, arch, host):
return os.path.join(ndk_dir, 'toolchains', arch, 'prebuilt', host)
+
def get_clang_dir(ndk_dir, host):
return os.path.join(ndk_dir, 'toolchains', 'llvm', 'prebuilt', host)
+
def get_platform_dir(ndk_dir, api, subdirs):
return os.path.join(ndk_dir, 'platforms', api, *subdirs)
+
class Target(object):
def __init__(self, name, triple, cflags, ldflags, gcc_toolchain_dir,
clang_dir, ndk_include, ndk_lib):
@@ -71,6 +78,7 @@ class Target(object):
self.ndk_include = ndk_include
self.ndk_lib = ndk_lib
+
def check_paths(self):
def check_path(path):
if os.path.exists(path):
@@ -88,6 +96,7 @@ class Target(object):
success &= check_path(self.ndk_lib)
return success
+
def compile(self, obj_file, src_file, cflags):
clang = os.path.join(self.clang_dir, 'bin', 'clang')
@@ -100,6 +109,7 @@ class Target(object):
cmd.extend(self.target_cflags)
subprocess.check_call(cmd)
+
def link(self, out_file, obj_files, ldflags):
if '-shared' in ldflags:
crtbegin = os.path.join(self.ndk_lib, 'crtbegin_so.o')
@@ -124,6 +134,7 @@ class Target(object):
cmd.append('-Wl,-pie')
subprocess.check_call(cmd)
+
def create_targets(ndk_dir=None, api=None, host=None):
if ndk_dir is None:
ndk_dir = detect_ndk_dir()
@@ -180,6 +191,7 @@ def create_targets(ndk_dir=None, api=None, host=None):
return targets
+
def main():
parser = argparse.ArgumentParser(
description='Dry-run NDK toolchain detection')
@@ -198,5 +210,6 @@ def main():
print('succeed')
+
if __name__ == '__main__':
main()
diff --git a/vndk/tools/definition-tool/tests/run.py b/vndk/tools/definition-tool/tests/run.py
index 2d2352bf5..2837d5cef 100755
--- a/vndk/tools/definition-tool/tests/run.py
+++ b/vndk/tools/definition-tool/tests/run.py
@@ -4,6 +4,7 @@ import argparse
import os
import unittest
+
def main():
parser = argparse.ArgumentParser()
parser.add_argument('--verbose', '-v', action='store_true')
diff --git a/vndk/tools/definition-tool/tests/test_elf.py b/vndk/tools/definition-tool/tests/test_elf.py
index a45fb5816..160911d0e 100755
--- a/vndk/tools/definition-tool/tests/test_elf.py
+++ b/vndk/tools/definition-tool/tests/test_elf.py
@@ -12,6 +12,7 @@ import unittest
from compat import StringIO
from vndk_definition_tool import Elf_Sym, ELF
+
class ElfSymTest(unittest.TestCase):
def setUp(self):
self.sym_local = Elf_Sym(0, 0, 4, 0, 0, 1)
@@ -19,21 +20,25 @@ class ElfSymTest(unittest.TestCase):
self.sym_weak = Elf_Sym(0, 0, 4, 33, 0, 1)
self.sym_undef = Elf_Sym(0, 0, 4, 16, 0, 0)
+
def test_is_local(self):
self.assertTrue(self.sym_local.is_local)
self.assertFalse(self.sym_global.is_local)
self.assertFalse(self.sym_weak.is_local)
+
def test_is_global(self):
self.assertFalse(self.sym_local.is_global)
self.assertTrue(self.sym_global.is_global)
self.assertFalse(self.sym_weak.is_global)
+
def test_is_weak(self):
self.assertFalse(self.sym_local.is_weak)
self.assertFalse(self.sym_global.is_weak)
self.assertTrue(self.sym_weak.is_weak)
+
def test_is_undef(self):
self.assertFalse(self.sym_global.is_undef)
self.assertTrue(self.sym_undef.is_undef)
@@ -44,12 +49,14 @@ class ELFTest(unittest.TestCase):
self.assertEqual(ELF.ELFCLASS32, ELF.get_ei_class_from_name('32'))
self.assertEqual(ELF.ELFCLASS64, ELF.get_ei_class_from_name('64'))
+
def test_get_ei_data_from_name(self):
self.assertEqual(ELF.ELFDATA2LSB,
ELF.get_ei_data_from_name('Little-Endian'))
self.assertEqual(ELF.ELFDATA2MSB,
ELF.get_ei_data_from_name('Big-Endian'))
+
def test_get_e_machine_from_name(self):
self.assertEqual(0, ELF.get_e_machine_from_name('EM_NONE'))
self.assertEqual(3, ELF.get_e_machine_from_name('EM_386'))
@@ -58,6 +65,7 @@ class ELFTest(unittest.TestCase):
self.assertEqual(62, ELF.get_e_machine_from_name('EM_X86_64'))
self.assertEqual(183, ELF.get_e_machine_from_name('EM_AARCH64'))
+
def test_repr(self):
elf = ELF()
self.assertEqual(elf, eval(repr(elf)))
@@ -67,6 +75,7 @@ class ELFTest(unittest.TestCase):
dt_needed=['c', 'd'], exported_symbols={'e', 'f', 'g'})
self.assertEqual(elf, eval(repr(elf)))
+
def test_class_name(self):
self.assertEqual('None', ELF().elf_class_name)
@@ -80,6 +89,7 @@ class ELFTest(unittest.TestCase):
self.assertFalse(elf.is_32bit)
self.assertTrue(elf.is_64bit)
+
def test_endianness(self):
self.assertEqual('None', ELF().elf_data_name)
self.assertEqual('Little-Endian',
@@ -87,6 +97,7 @@ class ELFTest(unittest.TestCase):
self.assertEqual('Big-Endian',
ELF(None, ELF.ELFDATA2MSB).elf_data_name)
+
def test_machine_name(self):
self.assertEqual('EM_NONE', ELF(e_machine=0).elf_machine_name)
self.assertEqual('EM_386', ELF(e_machine=3).elf_machine_name)
@@ -95,6 +106,7 @@ class ELFTest(unittest.TestCase):
self.assertEqual('EM_X86_64', ELF(e_machine=62).elf_machine_name)
self.assertEqual('EM_AARCH64', ELF(e_machine=183).elf_machine_name)
+
def test_dt_rpath_runpath(self):
elf = ELF()
self.assertEqual([], elf.dt_rpath)
@@ -104,6 +116,7 @@ class ELFTest(unittest.TestCase):
self.assertEqual(['a'], elf.dt_rpath)
self.assertEqual(['b'], elf.dt_runpath)
+
def test_dump(self):
elf = ELF(ELF.ELFCLASS32, ELF.ELFDATA2LSB, 183, ['a'], ['b'],
['libc.so', 'libm.so'], {'hello', 'world'}, {'d', 'e'})
@@ -130,6 +143,7 @@ class ELFTest(unittest.TestCase):
'IMP_SYMBOL\te\n',
actual_output)
+
def test_parse_dump_file(self):
data = ('EI_CLASS\t64\n'
'EI_DATA\t\tLittle-Endian\n'
@@ -190,6 +204,7 @@ class ELFJniLibTest(unittest.TestCase):
elf = ELF(dt_needed=['libc.so'])
self.assertFalse(elf.is_jni_lib())
+
def test_jni_symbols(self):
elf = ELF(imported_symbols={'JNI_CreateJavaVM'})
self.assertTrue(elf.is_jni_lib())
diff --git a/vndk/tools/definition-tool/tests/test_elf_link_data.py b/vndk/tools/definition-tool/tests/test_elf_link_data.py
index e850307da..98ae69243 100755
--- a/vndk/tools/definition-tool/tests/test_elf_link_data.py
+++ b/vndk/tools/definition-tool/tests/test_elf_link_data.py
@@ -25,6 +25,7 @@ class ELFLinkDataTest(unittest.TestCase):
self.z.add_needed_dep(self.w)
self.z.add_dlopen_dep(self.w)
+
def test_add_dep_and_accessors(self):
self.assertIn(self.y, self.x.deps_needed_all)
self.assertIn(self.x, self.y.users_needed_all)
@@ -36,6 +37,7 @@ class ELFLinkDataTest(unittest.TestCase):
self.assertNotIn(self.z, self.x.deps_needed_all)
self.assertNotIn(self.x, self.z.users_needed_all)
+
def test_remove_dep(self):
self.assertIn(self.y, self.x.deps_needed_all)
self.assertIn(self.x, self.y.users_needed_all)
@@ -51,6 +53,7 @@ class ELFLinkDataTest(unittest.TestCase):
self.assertNotIn(self.y, self.x.deps_needed)
self.assertNotIn(self.x, self.y.users_needed)
+
def test_num_deps(self):
self.assertEqual(2, self.x.num_deps)
self.assertEqual(0, self.y.num_deps)
@@ -60,6 +63,7 @@ class ELFLinkDataTest(unittest.TestCase):
# NEEDED and DLOPEN are counted twice.
self.assertEqual(2, self.z.num_deps)
+
def test_num_users(self):
self.assertEqual(0, self.x.num_users)
self.assertEqual(1, self.y.num_users)
@@ -69,22 +73,26 @@ class ELFLinkDataTest(unittest.TestCase):
# NEEDED and DLOPEN are counted twice.
self.assertEqual(2, self.w.num_users)
+
def test_has_dep(self):
self.assertTrue(self.x.has_dep(self.y))
self.assertTrue(self.x.has_dep(self.z))
self.assertFalse(self.x.has_dep(self.x))
self.assertFalse(self.x.has_dep(self.w))
+
def test_has_user(self):
self.assertTrue(self.y.has_user(self.x))
self.assertTrue(self.z.has_user(self.x))
self.assertFalse(self.x.has_user(self.x))
self.assertFalse(self.w.has_user(self.x))
+
def test_is_system_lib(self):
self.assertTrue(self.x.is_system_lib())
self.assertFalse(self.v.is_system_lib())
+
def test_get_dep_linked_symbols(self):
self.x.linked_symbols['c'] = self.y
self.x.linked_symbols['b'] = self.y
diff --git a/vndk/tools/definition-tool/tests/test_elf_resolver.py b/vndk/tools/definition-tool/tests/test_elf_resolver.py
index 29973e302..30bab9f7c 100755
--- a/vndk/tools/definition-tool/tests/test_elf_resolver.py
+++ b/vndk/tools/definition-tool/tests/test_elf_resolver.py
@@ -10,6 +10,7 @@ import unittest
from vndk_definition_tool import ELFResolver
+
class ELFResolverTest(unittest.TestCase):
def setUp(self):
lib_set = {
@@ -24,6 +25,7 @@ class ELFResolverTest(unittest.TestCase):
self.resolver = ELFResolver(lib_set, ['/system/lib', '/vendor/lib'])
+
def test_get_candidates(self):
r = self.resolver
diff --git a/vndk/tools/definition-tool/tests/test_elfdump.py b/vndk/tools/definition-tool/tests/test_elfdump.py
index 2c0b2305d..c738fd8da 100755
--- a/vndk/tools/definition-tool/tests/test_elfdump.py
+++ b/vndk/tools/definition-tool/tests/test_elfdump.py
@@ -41,11 +41,13 @@ class ELFDumpTest(unittest.TestCase):
cls._build_fixtures(cls.target_name)
+
@classmethod
def tearDownClass(cls):
if not test_dir_base:
cls.tmp_dir.cleanup()
+
@classmethod
def _build_fixtures(cls, target_name):
target = cls.targets[target_name]
@@ -97,6 +99,7 @@ class ELFDumpTest(unittest.TestCase):
['-shared', '-lc', '-Wl,-rpath,/system/lib:/vendor/lib',
'-Wl,--enable-new-dtags'])
+
def _remove_size_lines(self, lines):
"""Remove file size information because they may vary."""
prefixes = (
@@ -109,6 +112,7 @@ class ELFDumpTest(unittest.TestCase):
patt = re.compile('|'.join('(?:' + re.escape(x) +')' for x in prefixes))
return [line for line in lines if not patt.match(line)]
+
def _assert_equal_to_file(self, expected_file_name, actual):
actual = actual.splitlines(True)
expected_file_path = os.path.join(self.expected_dir, expected_file_name)
@@ -117,10 +121,12 @@ class ELFDumpTest(unittest.TestCase):
self.assertEqual(self._remove_size_lines(expected),
self._remove_size_lines(actual))
+
def _test_main_out(self):
out_file = os.path.join(self.test_dir, 'main.out')
self._assert_equal_to_file('main.out.txt', run_elf_dump(out_file))
+
def _test_libtest(self, expected_file_name, lib_name):
lib_file = os.path.join(self.test_dir, lib_name)
self._assert_equal_to_file(expected_file_name, run_elf_dump(lib_file))
diff --git a/vndk/tools/definition-tool/tests/test_generic_refs.py b/vndk/tools/definition-tool/tests/test_generic_refs.py
index c887d19d6..349debca5 100755
--- a/vndk/tools/definition-tool/tests/test_generic_refs.py
+++ b/vndk/tools/definition-tool/tests/test_generic_refs.py
@@ -39,6 +39,7 @@ class GenericRefsTest(unittest.TestCase):
self.ref.add('/system/lib64/libm.so',
MockELF({'cos', 'sin', 'tan'}))
+
def test_create_from_sym_dir(self):
input_dir = os.path.join(SCRIPT_DIR, 'testdata', 'test_generic_refs')
@@ -60,6 +61,7 @@ class GenericRefsTest(unittest.TestCase):
self.assertEqual({'cos', 'sin', 'tan'},
g.refs['/system/lib64/libm.so'].exported_symbols)
+
def test_classify_lib(self):
libc_sub = MockLib('/system/lib/libc.so', {'fclose', 'fopen', 'fread'})
libc_sup = MockLib('/system/lib/libc.so',
@@ -75,6 +77,7 @@ class GenericRefsTest(unittest.TestCase):
self.ref.classify_lib(libc_eq))
self.assertEqual(GenericRefs.NEW_LIB, self.ref.classify_lib(libfoo))
+
def test_is_equivalent_lib(self):
libc_sub = MockLib('/system/lib/libc.so', {'fclose', 'fopen', 'fread'})
libc_sup = MockLib('/system/lib/libc.so',
@@ -87,6 +90,7 @@ class GenericRefsTest(unittest.TestCase):
self.assertTrue(self.ref.is_equivalent_lib(libc_eq))
+
def test_has_same_name_lib(self):
self.assertTrue(self.ref.has_same_name_lib(
MockLib('/vendor/lib/libc.so', {})))
diff --git a/vndk/tools/definition-tool/tests/test_module_info.py b/vndk/tools/definition-tool/tests/test_module_info.py
index 2da17b40d..f36edb09d 100755
--- a/vndk/tools/definition-tool/tests/test_module_info.py
+++ b/vndk/tools/definition-tool/tests/test_module_info.py
@@ -18,6 +18,7 @@ class ModuleInfoTest(unittest.TestCase):
m = ModuleInfo.load_from_path_or_default(None)
self.assertEqual([], m.get_module_path('/system/lib64/libA.so'))
+
def test_get_module_path(self):
json_path = os.path.join(SCRIPT_DIR, 'testdata', 'test_module_info',
'module-info.json')
diff --git a/vndk/tools/definition-tool/tests/utils.py b/vndk/tools/definition-tool/tests/utils.py
index 6c61a3467..c241dc577 100644
--- a/vndk/tools/definition-tool/tests/utils.py
+++ b/vndk/tools/definition-tool/tests/utils.py
@@ -16,14 +16,17 @@ class GraphBuilder(object):
PT_VENDOR: 'vendor',
}
+
_LIB_DIRS = {
ELF.ELFCLASS32: 'lib',
ELF.ELFCLASS64: 'lib64',
}
+
def __init__(self):
self.graph = ELFLinker()
+
def add_lib(self, partition, klass, name, dt_needed=[],
exported_symbols=set(), imported_symbols=set(),
extra_dir=None):
@@ -44,18 +47,21 @@ class GraphBuilder(object):
setattr(self, name + '_' + elf.elf_class_name, lib)
return lib
+
def add_lib32(self, partition, name, dt_needed=[],
exported_symbols=set(), imported_symbols=set(),
extra_dir=None):
return self.add_lib(partition, ELF.ELFCLASS32, name, dt_needed,
exported_symbols, imported_symbols, extra_dir)
+
def add_lib64(self, partition, name, dt_needed=[],
exported_symbols=set(), imported_symbols=set(),
extra_dir=None):
return self.add_lib(partition, ELF.ELFCLASS64, name, dt_needed,
exported_symbols, imported_symbols, extra_dir)
+
def add_multilib(self, partition, name, dt_needed=[],
exported_symbols=set(), imported_symbols=set(),
extra_dir=None):
@@ -67,6 +73,7 @@ class GraphBuilder(object):
exported_symbols, imported_symbols, extra_dir)
)
+
def resolve(self, vndk_lib_dirs=None, ro_vndk_version=None):
if vndk_lib_dirs is not None:
self.graph.vndk_lib_dirs = vndk_lib_dirs
diff --git a/vndk/tools/definition-tool/vndk_definition_tool.py b/vndk/tools/definition-tool/vndk_definition_tool.py
index 4e29986de..996e5b20d 100755
--- a/vndk/tools/definition-tool/vndk_definition_tool.py
+++ b/vndk/tools/definition-tool/vndk_definition_tool.py
@@ -314,22 +314,27 @@ class Elf_Sym(collections.namedtuple(
SHN_UNDEF = 0
+
@property
def st_bind(self):
return self.st_info >> 4
+
@property
def is_local(self):
return self.st_bind == Elf_Sym.STB_LOCAL
+
@property
def is_global(self):
return self.st_bind == Elf_Sym.STB_GLOBAL
+
@property
def is_weak(self):
return self.st_bind == Elf_Sym.STB_WEAK
+
@property
def is_undef(self):
return self.st_shndx == Elf_Sym.SHN_UNDEF
@@ -381,6 +386,7 @@ class ELF(object):
EM_X86_64 = 62
EM_AARCH64 = 183
+
def _create_elf_machines(d):
elf_machine_ids = {}
for key, value in d.items():
@@ -400,14 +406,17 @@ class ELF(object):
return key
raise KeyError(dst)
+
@staticmethod
def get_ei_class_from_name(name):
return ELF._dict_find_key_by_value(ELF._ELF_CLASS_NAMES, name)
+
@staticmethod
def get_ei_data_from_name(name):
return ELF._dict_find_key_by_value(ELF._ELF_DATA_NAMES, name)
+
@staticmethod
def get_e_machine_from_name(name):
return ELF._dict_find_key_by_value(ELF.ELF_MACHINES, name)
@@ -440,41 +449,51 @@ class ELF(object):
self.rw_seg_file_size = rw_seg_file_size
self.rw_seg_mem_size = rw_seg_mem_size
+
def __repr__(self):
args = (a + '=' + repr(getattr(self, a)) for a in self.__slots__)
return 'ELF(' + ', '.join(args) + ')'
+
def __eq__(self, rhs):
return all(getattr(self, a) == getattr(rhs, a) for a in self.__slots__)
+
@property
def elf_class_name(self):
return self._ELF_CLASS_NAMES.get(self.ei_class, 'None')
+
@property
def elf_data_name(self):
return self._ELF_DATA_NAMES.get(self.ei_data, 'None')
+
@property
def elf_machine_name(self):
return self.ELF_MACHINES.get(self.e_machine, str(self.e_machine))
+
@property
def is_32bit(self):
return self.ei_class == ELF.ELFCLASS32
+
@property
def is_64bit(self):
return self.ei_class == ELF.ELFCLASS64
+
@property
def sorted_exported_symbols(self):
return sorted(list(self.exported_symbols))
+
@property
def sorted_imported_symbols(self):
return sorted(list(self.imported_symbols))
+
def dump(self, file=None):
"""Print parsed ELF information to the file"""
file = file if file is not None else sys.stdout
@@ -498,6 +517,7 @@ class ELF(object):
for symbol in self.sorted_imported_symbols:
print('IMP_SYMBOL\t' + symbol, file=file)
+
# Extract zero-terminated buffer slice.
def _extract_zero_terminated_buf_slice(self, buf, offset):
"""Extract a zero-terminated buffer slice from the given offset"""
@@ -506,6 +526,7 @@ class ELF(object):
return buf[offset:]
return buf[offset:end]
+
# Extract c-style interned string from the buffer.
if sys.version_info >= (3, 0):
def _extract_zero_terminated_str(self, buf, offset):
@@ -517,6 +538,7 @@ class ELF(object):
"""Extract a c-style string from the given buffer and offset"""
return intern(self._extract_zero_terminated_buf_slice(buf, offset))
+
def _parse_from_buf_internal(self, buf):
"""Parse ELF image resides in the buffer"""
@@ -695,6 +717,7 @@ class ELF(object):
elif not ent.is_local:
exp_symbols.add(symbol_name)
+
def _parse_from_buf(self, buf):
"""Parse ELF image resides in the buffer"""
try:
@@ -702,6 +725,7 @@ class ELF(object):
except IndexError:
raise ELFError('bad offset')
+
def _parse_from_file(self, path):
"""Parse ELF image from the file path"""
with open(path, 'rb') as f:
@@ -711,6 +735,7 @@ class ELF(object):
with mmap(f.fileno(), st.st_size, access=ACCESS_READ) as image:
self._parse_from_buf(image)
+
def _parse_from_dump_lines(self, path, lines):
patt = re.compile('^([A-Za-z_]+)\t+(.*)$')
for line_no, line in enumerate(lines):
@@ -752,16 +777,19 @@ class ELF(object):
print('error: {}: {}: unknown tag name: {}'
.format(path, line_no + 1, key), file=sys.stderr)
+
def _parse_from_dump_file(self, path):
"""Load information from ELF dump file."""
with open(path, 'r') as f:
self._parse_from_dump_lines(path, f)
+
def _parse_from_dump_buf(self, buf):
"""Load information from ELF dump buffer."""
self._parse_from_dump_lines('<str:0x{:x}>'.format(id(buf)),
buf.splitlines())
+
@staticmethod
def load(path):
"""Create an ELF instance from the file path"""
@@ -769,6 +797,7 @@ class ELF(object):
elf._parse_from_file(path)
return elf
+
@staticmethod
def loads(buf):
"""Create an ELF instance from the buffer"""
@@ -776,6 +805,7 @@ class ELF(object):
elf._parse_from_buf(buf)
return elf
+
@staticmethod
def load_dump(path):
"""Create an ELF instance from a dump file path"""
@@ -783,6 +813,7 @@ class ELF(object):
elf._parse_from_dump_file(path)
return elf
+
@staticmethod
def load_dumps(buf):
"""Create an ELF instance from a dump file buffer"""
@@ -790,6 +821,7 @@ class ELF(object):
elf._parse_from_dump_buf(buf)
return elf
+
def is_jni_lib(self):
"""Test whether the ELF file looks like a JNI library."""
for name in ['libnativehelper.so', 'libandroid_runtime.so']:
@@ -1077,6 +1109,7 @@ class TaggedDict(object):
_define_tag_constants(locals())
del _define_tag_constants
+
_TAG_ALIASES = {
'hl_ndk': 'fwk_only', # Treat HL-NDK as FWK-ONLY.
'sp_ndk': 'll_ndk',
@@ -1094,6 +1127,7 @@ class TaggedDict(object):
'vndk_sp_private': 'vndk_sp_indirect_private',
}
+
@classmethod
def _normalize_tag(cls, tag):
tag = tag.lower().replace('-', '_')
@@ -1102,6 +1136,7 @@ class TaggedDict(object):
raise ValueError('unknown lib tag ' + tag)
return tag
+
_LL_NDK_VIS = {'ll_ndk', 'll_ndk_indirect'}
_VNDK_SP_VIS = {'ll_ndk', 'vndk_sp', 'vndk_sp_indirect',
'vndk_sp_indirect_private', 'fwk_only_rs'}
@@ -1134,10 +1169,12 @@ class TaggedDict(object):
del _LL_NDK_VIS, _VNDK_SP_VIS, _FWK_ONLY_VIS, _SP_HAL_VIS
+
@classmethod
def is_tag_visible(cls, from_tag, to_tag):
return to_tag in cls._TAG_VISIBILITY[from_tag]
+
def __init__(self, vndk_lib_dirs=None):
self._path_tag = dict()
for tag in self.TAGS:
@@ -1150,14 +1187,17 @@ class TaggedDict(object):
self._vndk_suffixes = [VNDKLibDir.create_vndk_dir_suffix(version)
for version in vndk_lib_dirs]
+
def add(self, tag, lib):
lib_set = getattr(self, tag)
lib_set.add(lib)
self._path_tag[lib] = tag
+
def add_regex(self, tag, pattern):
self._regex_patterns.append((re.compile(pattern), tag))
+
def get_path_tag(self, lib):
try:
return self._path_tag[lib]
@@ -1170,36 +1210,45 @@ class TaggedDict(object):
return self.get_path_tag_default(lib)
+
def get_path_tag_default(self, lib):
raise NotImplementedError()
+
def get_path_tag_bit(self, lib):
return self.TAGS[self.get_path_tag(lib)]
+
def is_path_visible(self, from_lib, to_lib):
return self.is_tag_visible(self.get_path_tag(from_lib),
self.get_path_tag(to_lib))
+
@staticmethod
def is_ll_ndk(tag_bit):
return bool(tag_bit & TaggedDict.LL_NDK)
+
@staticmethod
def is_vndk_sp(tag_bit):
return bool(tag_bit & TaggedDict.VNDK_SP)
+
@staticmethod
def is_vndk_sp_indirect(tag_bit):
return bool(tag_bit & TaggedDict.VNDK_SP_INDIRECT)
+
@staticmethod
def is_vndk_sp_indirect_private(tag_bit):
return bool(tag_bit & TaggedDict.VNDK_SP_INDIRECT_PRIVATE)
+
@staticmethod
def is_fwk_only_rs(tag_bit):
return bool(tag_bit & TaggedDict.FWK_ONLY_RS)
+
@staticmethod
def is_sp_hal(tag_bit):
return bool(tag_bit & TaggedDict.SP_HAL)
@@ -1227,17 +1276,20 @@ class TaggedPathDict(TaggedDict):
for row in reader:
self.add(self._normalize_tag(row[tag_col]), row[path_col])
+
@staticmethod
def create_from_csv(fp, vndk_lib_dirs=None):
d = TaggedPathDict(vndk_lib_dirs)
d.load_from_csv(fp)
return d
+
@staticmethod
def create_from_csv_path(path, vndk_lib_dirs=None):
with open(path, 'r') as fp:
return TaggedPathDict.create_from_csv(fp, vndk_lib_dirs)
+
def _enumerate_paths_with_lib(self, pattern):
if '${LIB}' in pattern:
yield pattern.replace('${LIB}', 'lib')
@@ -1245,6 +1297,7 @@ class TaggedPathDict(TaggedDict):
else:
yield pattern
+
def _enumerate_paths(self, pattern):
if '${VNDK_VER}' not in pattern:
for path in self._enumerate_paths_with_lib(pattern):
@@ -1255,6 +1308,7 @@ class TaggedPathDict(TaggedDict):
for path in self._enumerate_paths_with_lib(pattern_with_suffix):
yield path
+
def add(self, tag, path):
if path.startswith('[regex]'):
super(TaggedPathDict, self).add_regex(tag, path[7:])
@@ -1262,6 +1316,7 @@ class TaggedPathDict(TaggedDict):
for path in self._enumerate_paths(path):
super(TaggedPathDict, self).add(tag, path)
+
def get_path_tag_default(self, path):
return 'vnd_only' if path.startswith('/vendor') else 'fwk_only'
@@ -1272,11 +1327,13 @@ class TaggedLibDict(object):
for tag in TaggedDict.TAGS:
setattr(self, tag, set())
+
def add(self, tag, lib):
lib_set = getattr(self, tag)
lib_set.add(lib)
self._path_tag[lib] = tag
+
@staticmethod
def create_from_graph(graph, tagged_paths, generic_refs=None):
d = TaggedLibDict()
@@ -1294,12 +1351,14 @@ class TaggedLibDict(object):
d.add('vnd_only', lib)
return d
+
def get_path_tag(self, lib):
try:
return self._path_tag[lib]
except KeyError:
return self.get_path_tag_default(lib)
+
def get_path_tag_default(self, lib):
return 'vnd_only' if lib.path.startswith('/vendor') else 'fwk_only'
@@ -1672,6 +1731,7 @@ class ELFResolver(object):
self.lib_set = lib_set
self.default_search_path = default_search_path
+
def get_candidates(self, requester, name, dt_rpath=None, dt_runpath=None):
# Search app-specific search paths.
if _APP_DIR_PATTERNS.match(requester):
@@ -1687,6 +1747,7 @@ class ELFResolver(object):
for d in self.default_search_path:
yield os.path.join(d, name)
+
def resolve(self, requester, name, dt_rpath=None, dt_runpath=None):
for path in self.get_candidates(requester, name, dt_rpath, dt_runpath):
try:
@@ -1715,54 +1776,65 @@ class ELFLinkData(object):
self.unresolved_dt_needed = []
self.linked_symbols = dict()
+
@property
def is_ll_ndk(self):
return TaggedDict.is_ll_ndk(self._tag_bit)
+
@property
def is_vndk_sp(self):
return TaggedDict.is_vndk_sp(self._tag_bit)
+
@property
def is_vndk_sp_indirect(self):
return TaggedDict.is_vndk_sp_indirect(self._tag_bit)
+
@property
def is_vndk_sp_indirect_private(self):
return TaggedDict.is_vndk_sp_indirect_private(self._tag_bit)
+
@property
def is_fwk_only_rs(self):
return TaggedDict.is_fwk_only_rs(self._tag_bit)
+
@property
def is_sp_hal(self):
return TaggedDict.is_sp_hal(self._tag_bit)
+
def add_needed_dep(self, dst):
assert dst not in self.deps_needed_hidden
assert self not in dst.users_needed_hidden
self.deps_needed.add(dst)
dst.users_needed.add(self)
+
def add_dlopen_dep(self, dst):
assert dst not in self.deps_dlopen_hidden
assert self not in dst.users_dlopen_hidden
self.deps_dlopen.add(dst)
dst.users_dlopen.add(self)
+
def hide_needed_dep(self, dst):
self.deps_needed.remove(dst)
dst.users_needed.remove(self)
self.deps_needed_hidden.add(dst)
dst.users_needed_hidden.add(self)
+
def hide_dlopen_dep(self, dst):
self.deps_dlopen.remove(dst)
dst.users_dlopen.remove(self)
self.deps_dlopen_hidden.add(dst)
dst.users_dlopen_hidden.add(self)
+
@property
def num_deps(self):
"""Get the number of dependencies. If a library is linked by both
@@ -1770,23 +1842,28 @@ class ELFLinkData(object):
return (len(self.deps_needed) + len(self.deps_needed_hidden) +
len(self.deps_dlopen) + len(self.deps_dlopen_hidden))
+
@property
def deps_all(self):
return itertools.chain(self.deps_needed, self.deps_needed_hidden,
self.deps_dlopen, self.deps_dlopen_hidden)
+
@property
def deps_good(self):
return itertools.chain(self.deps_needed, self.deps_dlopen)
+
@property
def deps_needed_all(self):
return itertools.chain(self.deps_needed, self.deps_needed_hidden)
+
@property
def deps_dlopen_all(self):
return itertools.chain(self.deps_dlopen, self.deps_dlopen_hidden)
+
@property
def num_users(self):
"""Get the number of users. If a library is linked by both NEEDED and
@@ -1794,34 +1871,42 @@ class ELFLinkData(object):
return (len(self.users_needed) + len(self.users_needed_hidden) +
len(self.users_dlopen) + len(self.users_dlopen_hidden))
+
@property
def users_all(self):
return itertools.chain(self.users_needed, self.users_needed_hidden,
self.users_dlopen, self.users_dlopen_hidden)
+
@property
def users_good(self):
return itertools.chain(self.users_needed, self.users_dlopen)
+
@property
def users_needed_all(self):
return itertools.chain(self.users_needed, self.users_needed_hidden)
+
@property
def users_dlopen_all(self):
return itertools.chain(self.users_dlopen, self.users_dlopen_hidden)
+
def has_dep(self, dst):
return (dst in self.deps_needed or dst in self.deps_needed_hidden or
dst in self.deps_dlopen or dst in self.deps_dlopen_hidden)
+
def has_user(self, dst):
return (dst in self.users_needed or dst in self.users_needed_hidden or
dst in self.users_dlopen or dst in self.users_dlopen_hidden)
+
def is_system_lib(self):
return self.partition == PT_SYSTEM
+
def get_dep_linked_symbols(self, dep):
symbols = set()
for symbol, exp_lib in self.linked_symbols.items():
@@ -1829,6 +1914,7 @@ class ELFLinkData(object):
symbols.add(symbol)
return sorted(symbols)
+
def __lt__(self, rhs):
return self.path < rhs.path
@@ -1838,6 +1924,7 @@ def sorted_lib_path_list(libs):
libs.sort()
return libs
+
_VNDK_RESULT_FIELD_NAMES = (
'll_ndk', 'll_ndk_indirect',
'vndk_sp', 'vndk_sp_unused', 'vndk_sp_indirect',
@@ -1848,6 +1935,7 @@ _VNDK_RESULT_FIELD_NAMES = (
VNDKResult = defaultnamedtuple('VNDKResult', _VNDK_RESULT_FIELD_NAMES, set())
+
_SIMPLE_VNDK_RESULT_FIELD_NAMES = (
'vndk_sp', 'vndk_sp_ext', 'extra_vendor_libs')
@@ -1859,12 +1947,15 @@ class ELFLibDict(defaultnamedtuple('ELFLibDict', ('lib32', 'lib64'), {})):
def get_lib_dict(self, elf_class):
return self[elf_class - 1]
+
def add(self, path, lib):
self.get_lib_dict(lib.elf.ei_class)[path] = lib
+
def remove(self, lib):
del self.get_lib_dict(lib.elf.ei_class)[lib.path]
+
def get(self, path, default=None):
for lib_set in self:
res = lib_set.get(path, None)
@@ -1872,12 +1963,15 @@ class ELFLibDict(defaultnamedtuple('ELFLibDict', ('lib32', 'lib64'), {})):
return res
return default
+
def keys(self):
return itertools.chain(self.lib32.keys(), self.lib64.keys())
+
def values(self):
return itertools.chain(self.lib32.values(), self.lib64.values())
+
def items(self):
return itertools.chain(self.lib32.items(), self.lib64.items())
@@ -1903,18 +1997,22 @@ class ELFLinker(object):
self.ro_vndk_version = ro_vndk_version
+
def _add_lib_to_lookup_dict(self, lib):
self.lib_pt[lib.partition].add(lib.path, lib)
+
def _remove_lib_from_lookup_dict(self, lib):
self.lib_pt[lib.partition].remove(lib)
+
def add_lib(self, partition, path, elf):
lib = ELFLinkData(partition, path, elf,
self.tagged_paths.get_path_tag_bit(path))
self._add_lib_to_lookup_dict(lib)
return lib
+
def add_dlopen_dep(self, src_path, dst_path):
num_matches = 0
for elf_class in (ELF.ELFCLASS32, ELF.ELFCLASS64):
@@ -1927,6 +2025,7 @@ class ELFLinker(object):
raise ValueError('Failed to add dlopen dependency from {} to {}'
.format(src_path, dst_path))
+
def _get_libs_in_elf_class(self, elf_class, path):
result = set()
if '${LIB}' in path:
@@ -1947,6 +2046,7 @@ class ELFLinker(object):
result.add(lib)
return result
+
def get_lib(self, path):
for lib_set in self.lib_pt:
lib = lib_set.get(path)
@@ -1954,6 +2054,7 @@ class ELFLinker(object):
return lib
return None
+
def get_libs(self, paths, report_error=None):
result = set()
for path in paths:
@@ -1966,23 +2067,27 @@ class ELFLinker(object):
result.add(lib)
return result
+
def all_libs(self):
for lib_set in self.lib_pt:
for lib in lib_set.values():
yield lib
+
def _compute_lib_dict(self, elf_class):
res = dict()
for lib_pt in self.lib_pt:
res.update(lib_pt.get_lib_dict(elf_class))
return res
+
@staticmethod
def _compile_path_matcher(root, subdirs):
dirs = [os.path.normpath(os.path.join(root, i)) for i in subdirs]
patts = ['(?:' + re.escape(i) + os.sep + ')' for i in dirs]
return re.compile('|'.join(patts))
+
def add_executables_in_dir(self, partition_name, partition, root,
alter_partition, alter_subdirs, ignored_subdirs,
scan_elf_files, unzip_files):
@@ -2011,6 +2116,7 @@ class ELFLinker(object):
else:
self.add_lib(partition, short_path, elf)
+
def add_dlopen_deps(self, path):
patt = re.compile('([^:]*):\\s*(.*)')
with open(path, 'r') as dlopen_dep_file:
@@ -2024,6 +2130,7 @@ class ELFLinker(object):
print('error:{}:{}: {}.'.format(path, line_no, e),
file=sys.stderr)
+
def _find_exported_symbol(self, symbol, libs):
"""Find the shared library with the exported symbol."""
for lib in libs:
@@ -2031,6 +2138,7 @@ class ELFLinker(object):
return lib
return None
+
def _resolve_lib_imported_symbols(self, lib, imported_libs, generic_refs):
"""Resolve the imported symbols in a library."""
for symbol in lib.elf.imported_symbols:
@@ -2044,6 +2152,7 @@ class ELFLinker(object):
if not ref_lib or not symbol in ref_lib.exported_symbols:
lib.imported_ext_symbols[imported_lib].add(symbol)
+
def _resolve_lib_dt_needed(self, lib, resolver):
imported_libs = []
for dt_needed in lib.elf.dt_needed:
@@ -2061,6 +2170,7 @@ class ELFLinker(object):
imported_libs.append(dep)
return imported_libs
+
def _resolve_lib_deps(self, lib, resolver, generic_refs):
# Resolve DT_NEEDED entries.
imported_libs = self._resolve_lib_dt_needed(lib, resolver)
@@ -2076,6 +2186,7 @@ class ELFLinker(object):
# Resolve imported symbols.
self._resolve_lib_imported_symbols(lib, imported_libs, generic_refs)
+
def _resolve_lib_set_deps(self, lib_set, resolver, generic_refs):
for lib in lib_set:
self._resolve_lib_deps(lib, resolver, generic_refs)
@@ -2088,6 +2199,7 @@ class ELFLinker(object):
'/vendor/' + lib_dir,
]
+
def _get_vendor_search_paths(self, lib_dir, vndk_sp_dirs, vndk_dirs):
vendor_lib_dirs = [
'/vendor/' + lib_dir + '/hw',
@@ -2212,6 +2324,7 @@ class ELFLinker(object):
return SPLibResult(sp_hal, sp_hal_dep, vndk_sp_hal, ll_ndk,
ll_ndk_indirect, vndk_sp_both)
+
def normalize_partition_tags(self, sp_hals, generic_refs):
def is_system_lib_or_sp_hal(lib):
return lib.is_system_lib() or lib in sp_hals
@@ -2237,6 +2350,7 @@ class ELFLinker(object):
file=sys.stderr)
lib.hide_dlopen_dep(dep)
+
@staticmethod
def _parse_action_on_ineligible_lib(arg):
follow = False
@@ -2252,6 +2366,7 @@ class ELFLinker(object):
raise ValueError('unknown action \"{}\"'.format(flag))
return (follow, warn)
+
def compute_degenerated_vndk(self, generic_refs, tagged_paths=None,
action_ineligible_vndk_sp='warn',
action_ineligible_vndk='warn'):
@@ -2529,6 +2644,7 @@ class ELFLinker(object):
vndk_sp_indirect_ext=vndk_sp_indirect_ext,
extra_vendor_libs=extra_vendor_libs)
+
@staticmethod
def _compute_closure(root_set, is_excluded, get_successors):
closure = set(root_set)
@@ -2543,6 +2659,7 @@ class ELFLinker(object):
stack.append(succ)
return closure
+
@classmethod
def compute_deps_closure(cls, root_set, is_excluded,
ignore_hidden_deps=False):
@@ -2550,6 +2667,7 @@ class ELFLinker(object):
(lambda x: x.deps_all)
return cls._compute_closure(root_set, is_excluded, get_successors)
+
@classmethod
def compute_users_closure(cls, root_set, is_excluded,
ignore_hidden_users=False):
@@ -2557,6 +2675,7 @@ class ELFLinker(object):
(lambda x: x.users_all)
return cls._compute_closure(root_set, is_excluded, get_successors)
+
@staticmethod
def _create_internal(scan_elf_files, system_dirs, system_dirs_as_vendor,
system_dirs_ignored, vendor_dirs,
@@ -2591,6 +2710,7 @@ class ELFLinker(object):
return graph
+
@staticmethod
def create(system_dirs=None, system_dirs_as_vendor=None,
system_dirs_ignored=None, vendor_dirs=None,
@@ -2614,14 +2734,17 @@ class GenericRefs(object):
EXPORT_SUPER_SET = 2
MODIFIED = 3
+
def __init__(self):
self.refs = dict()
self._lib_names = set()
+
def add(self, path, elf):
self.refs[path] = elf
self._lib_names.add(os.path.basename(path))
+
def _load_from_sym_dir(self, root):
root = os.path.abspath(root)
prefix_len = len(root) + 1
@@ -2633,24 +2756,28 @@ class GenericRefs(object):
lib_path = '/' + path[prefix_len:-4]
self.add(lib_path, ELF.load_dump(path))
+
@staticmethod
def create_from_sym_dir(root):
result = GenericRefs()
result._load_from_sym_dir(root)
return result
+
def _load_from_image_dir(self, root, prefix):
root = os.path.abspath(root)
root_len = len(root) + 1
for path, elf in scan_elf_files(root):
self.add(os.path.join(prefix, path[root_len:]), elf)
+
@staticmethod
def create_from_image_dir(root, prefix):
result = GenericRefs()
result._load_from_image_dir(root, prefix)
return result
+
def classify_lib(self, lib):
ref_lib = self.refs.get(lib.path)
if not ref_lib:
@@ -2662,9 +2789,11 @@ class GenericRefs(object):
return GenericRefs.EXPORT_SUPER_SET
return GenericRefs.MODIFIED
+
def is_equivalent_lib(self, lib):
return self.classify_lib(lib) == GenericRefs.EXPORT_EQUAL
+
def has_same_name_lib(self, lib):
return os.path.basename(lib.path) in self._lib_names
@@ -2802,13 +2931,16 @@ class ModuleInfo(object):
self._mods = {installed_path: sorted(src_dirs)
for installed_path, src_dirs in mods.items()}
+
def get_module_path(self, installed_path):
return self._mods.get(installed_path, [])
+
@staticmethod
def load(f):
return ModuleInfo(json.load(f))
+
@staticmethod
def load_from_path_or_default(path):
if not path:
@@ -2838,9 +2970,11 @@ class ELFDumpCommand(Command):
super(ELFDumpCommand, self).__init__(
'elfdump', help='Dump ELF .dynamic section')
+
def add_argparser_options(self, parser):
parser.add_argument('path', help='path to an ELF file')
+
def main(self, args):
try:
ELF.load(args.path).dump()
@@ -2856,12 +2990,14 @@ class CreateGenericRefCommand(Command):
super(CreateGenericRefCommand, self).__init__(
'create-generic-ref', help='Create generic references')
+
def add_argparser_options(self, parser):
parser.add_argument('dir')
parser.add_argument('-o', '--output', required=True,
help='output directory')
+
def main(self, args):
root = os.path.abspath(args.dir)
print(root)
@@ -2926,6 +3062,7 @@ class ELFGraphCommand(Command):
'--tag-file', required=is_tag_file_required,
help='lib tag file')
+
def get_generic_refs_from_args(self, args):
if args.load_generic_refs:
return GenericRefs.create_from_sym_dir(args.load_generic_refs)
@@ -2934,6 +3071,7 @@ class ELFGraphCommand(Command):
args.aosp_system, '/system')
return None
+
def _check_arg_dir_exists(self, arg_name, dirs):
for path in dirs:
if not os.path.exists(path):
@@ -2945,10 +3083,12 @@ class ELFGraphCommand(Command):
.format(path, arg_name), file=sys.stderr)
sys.exit(1)
+
def check_dirs_from_args(self, args):
self._check_arg_dir_exists('--system', args.system)
self._check_arg_dir_exists('--vendor', args.vendor)
+
def create_from_args(self, args):
self.check_dirs_from_args(args)
@@ -2992,6 +3132,7 @@ class VNDKCommandBase(ELFGraphCommand):
help='action when a vendor lib/exe uses fwk-only libs '
'(option: follow,warn,ignore)')
+
def create_from_args(self, args):
"""Create all essential data structures for VNDK computation."""
@@ -3012,6 +3153,7 @@ class VNDKCommand(VNDKCommandBase):
super(VNDKCommand, self).__init__(
'vndk', help='Compute VNDK libraries set')
+
def add_argparser_options(self, parser):
super(VNDKCommand, self).add_argparser_options(parser)
@@ -3031,6 +3173,7 @@ class VNDKCommand(VNDKCommandBase):
'--file-size-output',
help='output file for calculated file sizes')
+
def _warn_incorrect_partition_lib_set(self, lib_set, partition, error_msg):
for lib in lib_set.values():
if not lib.num_users:
@@ -3038,6 +3181,7 @@ class VNDKCommand(VNDKCommandBase):
if all((user.partition != partition for user in lib.users_all)):
print(error_msg.format(lib.path), file=sys.stderr)
+
def _warn_incorrect_partition(self, graph):
self._warn_incorrect_partition_lib_set(
graph.lib_pt[PT_VENDOR], PT_VENDOR,
@@ -3049,6 +3193,7 @@ class VNDKCommand(VNDKCommandBase):
'warning: {}: This is a framework library with vendor-only '
'usages.')
+
@staticmethod
def _extract_simple_vndk_result(vndk_result):
field_name_tags = [
@@ -3069,6 +3214,7 @@ class VNDKCommand(VNDKCommandBase):
getattr(results, tag).update(getattr(vndk_result, field_name))
return results
+
def _print_tags(self, vndk_lib, full, file=sys.stdout):
if full:
result_tags = _VNDK_RESULT_FIELD_NAMES
@@ -3084,6 +3230,7 @@ class VNDKCommand(VNDKCommandBase):
for lib in sorted_lib_path_list(libs):
print(tag, lib, file=file)
+
def _print_make(self, vndk_lib, file=sys.stdout):
def get_module_name(path):
return os.path.splitext(os.path.basename(path))[0]
@@ -3113,6 +3260,7 @@ class VNDKCommand(VNDKCommandBase):
file.write(template)
+
def _print_file_size_output(self, graph, vndk_lib, file=sys.stderr):
def collect_tags(lib):
tags = []
@@ -3177,6 +3325,7 @@ class VNDKCommand(VNDKCommandBase):
writer.writerow(SEPARATOR)
writer.writerow(['Total', None] + calc_total_size(graph.all_libs()))
+
def main(self, args):
generic_refs, graph, tagged_paths, _ = self.create_from_args(args)
@@ -3206,6 +3355,7 @@ class DepsInsightCommand(VNDKCommandBase):
super(DepsInsightCommand, self).__init__(
'deps-insight', help='Generate HTML to show dependencies')
+
def add_argparser_options(self, parser):
super(DepsInsightCommand, self).add_argparser_options(parser)
@@ -3214,6 +3364,7 @@ class DepsInsightCommand(VNDKCommandBase):
parser.add_argument('-o', '--output', required=True,
help='output directory')
+
@staticmethod
def serialize_data(libs, vndk_lib, module_info):
strs = []
@@ -3279,6 +3430,7 @@ class DepsInsightCommand(VNDKCommandBase):
return (strs, mods)
+
def main(self, args):
generic_refs, graph, tagged_paths, _ = self.create_from_args(args)
@@ -3316,6 +3468,7 @@ class DepsCommand(ELFGraphCommand):
super(DepsCommand, self).__init__(
'deps', help='Print binary dependencies for debugging')
+
def add_argparser_options(self, parser):
super(DepsCommand, self).add_argparser_options(parser)
@@ -3337,6 +3490,7 @@ class DepsCommand(ELFGraphCommand):
parser.add_argument('--module-info')
+
def main(self, args):
_, graph, _, _ = self.create_from_args(args)
@@ -3399,6 +3553,7 @@ class DepsClosureCommand(ELFGraphCommand):
super(DepsClosureCommand, self).__init__(
'deps-closure', help='Find transitive closure of dependencies')
+
def add_argparser_options(self, parser):
super(DepsClosureCommand, self).add_argparser_options(parser)
@@ -3417,6 +3572,7 @@ class DepsClosureCommand(ELFGraphCommand):
parser.add_argument('--enumerate', action='store_true',
help='print closure for each lib instead of union')
+
def print_deps_closure(self, root_libs, graph, is_excluded_libs,
is_reverted, indent):
if is_reverted:
@@ -3464,11 +3620,13 @@ class DepsUnresolvedCommand(ELFGraphCommand):
'deps-unresolved',
help='Show unresolved dt_needed entries or symbols')
+
def add_argparser_options(self, parser):
super(DepsUnresolvedCommand, self).add_argparser_options(parser)
parser.add_argument('--module-info')
parser.add_argument('--path-filter')
+
def _dump_unresolved(self, lib, module_info, delimiter):
if not lib.unresolved_symbols and not lib.unresolved_dt_needed:
return
@@ -3482,6 +3640,7 @@ class DepsUnresolvedCommand(ELFGraphCommand):
for symbol in sorted(lib.unresolved_symbols):
print('\tUNRESOLVED_SYMBOL:', symbol)
+
def main(self, args):
_, graph, _, _ = self.create_from_args(args)
module_info = ModuleInfo.load_from_path_or_default(args.module_info)
@@ -3502,6 +3661,7 @@ class ApkDepsCommand(ELFGraphCommand):
super(ApkDepsCommand, self).__init__(
'apk-deps', help='Print APK dependencies for debugging')
+
def main(self, args):
_, graph, _, _ = self.create_from_args(args)
@@ -3520,14 +3680,17 @@ class CheckDepCommandBase(ELFGraphCommand):
super(CheckDepCommandBase, self).__init__(*args, **kwargs)
self.delimiter = ''
+
def add_argparser_options(self, parser):
super(CheckDepCommandBase, self).add_argparser_options(parser)
parser.add_argument('--module-info')
+
def _print_delimiter(self):
print(self.delimiter, end='')
self.delimiter = '\n'
+
def _dump_dep(self, lib, bad_deps, module_info):
self._print_delimiter()
print(lib.path)
@@ -3540,6 +3703,7 @@ class CheckDepCommandBase(ELFGraphCommand):
for symbol in lib.get_dep_linked_symbols(dep):
print('\t\t' + symbol)
+
def _dump_apk_dep(self, apk_path, bad_deps, module_info):
self._print_delimiter()
print(apk_path)