class GraphBuilder(object): _PARTITION_NAMES = { PT_SYSTEM: 'system', 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): """Create and add a shared library to ELFLinker.""" lib_dir = os.path.join('/', self._PARTITION_NAMES[partition], self._LIB_DIRS[klass]) if extra_dir: lib_dir = os.path.join(lib_dir, extra_dir) path = os.path.join(lib_dir, name + '.so') elf = ELF(klass, ELF.ELFDATA2LSB, dt_needed=dt_needed, exported_symbols=exported_symbols, imported_symbols=imported_symbols) node = self.graph.add_lib(partition, path, elf) setattr(self, name + '_' + elf.elf_class_name, node) return node def add_multilib(self, partition, name, dt_needed=[], exported_symbols=set(), imported_symbols=set(), extra_dir=None): """Add 32-bit / 64-bit shared libraries to ELFLinker.""" return (self.add_lib(partition, ELF.ELFCLASS32, name, dt_needed, exported_symbols, imported_symbols, extra_dir), self.add_lib(partition, ELF.ELFCLASS64, name, dt_needed, exported_symbols, imported_symbols, extra_dir)) def resolve(self): self.graph.resolve_deps()
def test_rewrite_apex_modules(self): graph = ELFLinker() libfoo = graph.add_lib(PT_SYSTEM, '/system/apex/foo/lib/libfoo.so', ELF(ELF.ELFCLASS32, ELF.ELFDATA2LSB)) libbar = graph.add_lib(PT_SYSTEM, '/system/apex/bar/lib/libbar.so', ELF(ELF.ELFCLASS32, ELF.ELFDATA2LSB)) graph.rewrite_apex_modules() self.assertEqual(libfoo.path, '/apex/foo/lib/libfoo.so') self.assertEqual(libbar.path, '/apex/bar/lib/libbar.so')
def test_compute_vndk_vnd_ext(self): class MockBannedLibs(object): def is_banned(self, name): return False generic_refs_dir = os.path.join(TESTDATA_DIR, 'vndk_gr') generic_refs = GenericRefs.create_from_dir(generic_refs_dir) input_dir = os.path.join(TESTDATA_DIR, 'vndk_vnd_ext') graph = ELFLinker.create_from_dump( system_dirs=[os.path.join(input_dir, 'system')], vendor_dirs=[os.path.join(input_dir, 'vendor')], generic_refs=generic_refs) vndk = graph.compute_vndk(sp_hals=set(), vndk_stable=set(), vndk_customized_for_system=set(), vndk_customized_for_vendor=set(), generic_refs=generic_refs, banned_libs=MockBannedLibs()) self.assertEqual([ '/system/lib/vndk/libRS.so', '/system/lib/vndk/libcutils.so', '/system/lib64/vndk/libRS.so', '/system/lib64/vndk/libcutils.so' ], self._get_paths_from_nodes(vndk.vndk_core)) self.assertEqual([], self._get_paths_from_nodes(vndk.vndk_fwk_ext)) self.assertEqual([ '/vendor/lib/vndk-ext/libRS.so', '/vendor/lib64/vndk-ext/libRS.so' ], self._get_paths_from_nodes(vndk.vndk_vnd_ext))
class GraphBuilder(object): _PARTITION_NAMES = { PT_SYSTEM: 'system', 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): """Create and add a shared library to ELFLinker.""" lib_dir = os.path.join('/', self._PARTITION_NAMES[partition], self._LIB_DIRS[klass]) if extra_dir: lib_dir = os.path.join(lib_dir, extra_dir) path = os.path.join(lib_dir, name + '.so') elf = ELF(klass, ELF.ELFDATA2LSB, dt_needed=dt_needed, exported_symbols=exported_symbols, imported_symbols=imported_symbols) node = self.graph.add_lib(partition, path, elf) setattr(self, name + '_' + elf.elf_class_name, node) return node def add_multilib(self, partition, name, dt_needed=[], exported_symbols=set(), imported_symbols=set(), extra_dir=None): """Add 32-bit / 64-bit shared libraries to ELFLinker.""" return ( self.add_lib(partition, ELF.ELFCLASS32, name, dt_needed, exported_symbols, imported_symbols, extra_dir), self.add_lib(partition, ELF.ELFCLASS64, name, dt_needed, exported_symbols, imported_symbols, extra_dir) ) def resolve(self): self.graph.resolve_deps()
def test_link_apex_modules(self): graph = ELFLinker() libfoo = graph.add_lib(PT_SYSTEM, '/system/apex/foo/lib/libfoo.so', ELF(ELF.ELFCLASS32, ELF.ELFDATA2LSB)) libbar = graph.add_lib( PT_SYSTEM, '/system/lib/libbar.so', ELF(ELF.ELFCLASS32, ELF.ELFDATA2LSB, dt_needed=['libfoo.so'])) graph.rewrite_apex_modules() graph.resolve_deps() self.assertIn(libfoo, libbar.deps_all)
def test_link_apex_bionic(self): graph = ELFLinker() libc = graph.add_lib( PT_SYSTEM, '/system/apex/com.android.runtime/lib/bionic/libc.so', ELF(ELF.ELFCLASS32, ELF.ELFDATA2LSB)) libbar = graph.add_lib( PT_SYSTEM, '/system/lib/libbar.so', ELF(ELF.ELFCLASS32, ELF.ELFDATA2LSB, dt_needed=['libc.so'])) graph.rewrite_apex_modules() graph.resolve_deps() self.assertIn(libc, libbar.deps_all)
class GraphBuilder(object): _PARTITION_NAMES = { PT_SYSTEM: 'system', 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, imported_symbols): """Create and add a shared library to ELFLinker.""" elf = ELF(klass, ELF.ELFDATA2LSB, dt_needed=dt_needed, exported_symbols=exported_symbols, imported_symbols=imported_symbols) setattr(self, 'elf' + elf.elf_class_name + '_' + name, elf) path = os.path.join('/', self._PARTITION_NAMES[partition], self._LIB_DIRS[klass], name + '.so') self.graph.add(partition, path, elf) def add_multilib(self, partition, name, dt_needed, exported_symbols, imported_symbols): """Add 32-bit / 64-bit shared libraries to ELFLinker.""" for klass in (ELF.ELFCLASS32, ELF.ELFCLASS64): self.add_lib(partition, klass, name, dt_needed, exported_symbols, imported_symbols) def resolve(self): self.graph.resolve_deps()
def test_compute_vndk_inward_customization(self): class MockBannedLibs(object): def is_banned(self, name): return False generic_refs_dir = os.path.join(TESTDATA_DIR, 'vndk_gr') generic_refs = GenericRefs.create_from_dir(generic_refs_dir) input_dir = os.path.join(TESTDATA_DIR, 'vndk_inward_customization') graph = ELFLinker.create_from_dump( system_dirs=[os.path.join(input_dir, 'system')], vendor_dirs=[os.path.join(input_dir, 'vendor')], generic_refs=generic_refs) # Make sure libjpeg.so was loaded from the input dir. libjpeg_32 = graph.get_lib('/system/lib/libjpeg.so') self.assertIsNotNone(libjpeg_32) libjpeg_64 = graph.get_lib('/system/lib64/libjpeg.so') self.assertIsNotNone(libjpeg_64) # Compute vndk sets and move libraries to the correct directories. vndk = graph.compute_vndk(sp_hals=set(), vndk_stable=set(), vndk_customized_for_system=set(), vndk_customized_for_vendor=set(), generic_refs=generic_refs, banned_libs=MockBannedLibs()) # Check vndk-core libraries. self.assertEqual([ '/system/lib/vndk/libRS.so', '/system/lib/vndk/libcutils.so', '/system/lib64/vndk/libRS.so', '/system/lib64/vndk/libcutils.so' ], self._get_paths_from_nodes(vndk.vndk_core)) # Check vndk-indirect libraries. self.assertEqual( ['/system/lib/vndk/libjpeg.so', '/system/lib64/vndk/libjpeg.so'], self._get_paths_from_nodes(vndk.vndk_indirect)) # Check libjpeg.so (inward-customization) has been renamed. self.assertIsNone(graph.get_lib('/system/lib/libjpeg.so')) self.assertIsNone(graph.get_lib('/system/lib64/libjpeg.so')) self.assertIs(libjpeg_32, graph.get_lib('/system/lib/vndk/libjpeg.so')) self.assertIs(libjpeg_64, graph.get_lib('/system/lib64/vndk/libjpeg.so')) # Check the absence of vndk-ext libraries. self.assertEqual([], self._get_paths_from_nodes(vndk.vndk_fwk_ext)) self.assertEqual([], self._get_paths_from_nodes(vndk.vndk_vnd_ext))
def test_compute_vndk_indirect_ext(self): class MockBannedLibs(object): def is_banned(self, name): return False # This test case reveals a corner case that will break vndk-indirect # computation. To reproduce the case, the following condition must be # satisfied: # # 1. libA depends on libB. # 2. libA is a vndk-fwk-ext. # 3. libB is an outward-customized vndk which depends on non-AOSP libC. # # Both AOSP libA and libB will be added to vndk-core. But, # unfortunately, libA will be resolved to libB in vndk-fwk-ext and this # will break the vndk-indirect computation because libC is not in # generic references. generic_refs_dir = os.path.join(TESTDATA_DIR, 'vndk_indirect_ext_gr') generic_refs = GenericRefs.create_from_dir(generic_refs_dir) input_dir = os.path.join(TESTDATA_DIR, 'vndk_indirect_ext') graph = ELFLinker.create_from_dump( system_dirs=[os.path.join(input_dir, 'system')], vendor_dirs=[os.path.join(input_dir, 'vendor')], generic_refs=generic_refs) vndk = graph.compute_vndk(sp_hals=set(), vndk_stable=set(), vndk_customized_for_system=set(), vndk_customized_for_vendor=set(), generic_refs=generic_refs, banned_libs=MockBannedLibs()) self.assertEqual([ '/system/lib/vndk/libRS.so', '/system/lib/vndk/libcutils.so', '/system/lib64/vndk/libRS.so', '/system/lib64/vndk/libcutils.so' ], self._get_paths_from_nodes(vndk.vndk_core)) self.assertEqual([ '/system/lib/vndk/libRS_internal.so', '/system/lib64/vndk/libRS_internal.so' ], self._get_paths_from_nodes(vndk.vndk_indirect)) self.assertEqual([ '/system/lib/vndk-ext/libRS_internal.so', '/system/lib64/vndk-ext/libRS_internal.so' ], self._get_paths_from_nodes(vndk.vndk_fwk_ext))
def test_link_apex_modules(self): graph = ELFLinker() libfoo = graph.add_lib(PT_SYSTEM, '/system/apex/foo/lib/libfoo.so', ELF(ELF.ELFCLASS32, ELF.ELFDATA2LSB)) libbar = graph.add_lib(PT_SYSTEM, '/system/lib/libbar.so', ELF(ELF.ELFCLASS32, ELF.ELFDATA2LSB, dt_needed=['libfoo.so'])) graph.rewrite_apex_modules() graph.resolve_deps() self.assertIn(libfoo, libbar.deps_all)
def _create_graph_gr(self, input_dir, generic_refs_dir): if not generic_refs_dir: generic_refs = None else: generic_refs_dir = os.path.join(TESTDATA_DIR, generic_refs_dir) generic_refs = GenericRefs.create_from_dir(generic_refs_dir) input_dir = os.path.join(TESTDATA_DIR, input_dir) graph = ELFLinker.create_from_dump( system_dirs=[os.path.join(input_dir, 'system')], vendor_dirs=[os.path.join(input_dir, 'vendor')], generic_refs=generic_refs) return (graph, generic_refs)
def _create_graph_gr(self, input_dir, generic_refs_dir): if not generic_refs_dir: generic_refs = None else: generic_refs_dir = os.path.join(TESTDATA_DIR, generic_refs_dir) generic_refs = GenericRefs.create_from_sym_dir(generic_refs_dir) input_dir = os.path.join(TESTDATA_DIR, input_dir) graph = ELFLinker.create_from_dump( system_dirs=[os.path.join(input_dir, 'system')], vendor_dirs=[os.path.join(input_dir, 'vendor')], generic_refs=generic_refs) return (graph, generic_refs)
def __init__(self): self.graph = ELFLinker()