Merge changes I0527ef62,I0d66a93f,I528ef380,Ia9140851,If1874867, ...

* changes:
  vndk-def: Fix bad inward-customized vndk calculation.
  vndk-def: Fix inward customization.
  vndk-def: Rename vndk-core and vndk-ext libs.
  vndk-def: Rename map_path_to_lib(s) to get_lib(s).
  vndk-def: Rename ELFLinker.add() to add_lib().
  vndk-def: Add non-AOSP lib to imported_ext_symbols.
  vndk-def: Skip ndk ext check if no generic-refs.
This commit is contained in:
Treehugger Robot
2017-03-21 00:47:57 +00:00
committed by Gerrit Code Review
71 changed files with 736 additions and 110 deletions

View File

@@ -43,7 +43,7 @@ class GraphBuilder(object):
exported_symbols=exported_symbols,
imported_symbols=imported_symbols)
node = self.graph.add(partition, path, elf)
node = self.graph.add_lib(partition, path, elf)
setattr(self, name + '_' + elf.elf_class_name, node)
return node
@@ -95,23 +95,23 @@ class ELFLinkerTest(unittest.TestCase):
def _get_paths_from_nodes(self, nodes):
return sorted([node.path for node in nodes])
def test_map_path_to_lib(self):
def test_get_lib(self):
gb = self._create_normal_graph()
graph = gb.graph
node = graph.map_path_to_lib('/system/lib/libc.so')
node = graph.get_lib('/system/lib/libc.so')
self.assertEqual(gb.libc_32, node)
self.assertEqual('/system/lib/libc.so', node.path)
node = graph.map_path_to_lib('/system/lib64/libdl.so')
node = graph.get_lib('/system/lib64/libdl.so')
self.assertEqual(gb.libdl_64, node)
self.assertEqual('/system/lib64/libdl.so', node.path)
node = graph.map_path_to_lib('/vendor/lib64/libEGL.so')
node = graph.get_lib('/vendor/lib64/libEGL.so')
self.assertEqual(gb.libEGL_64, node)
self.assertEqual('/vendor/lib64/libEGL.so', node.path)
self.assertEqual(None, graph.map_path_to_lib('/no/such/path.so'))
self.assertEqual(None, graph.get_lib('/no/such/path.so'))
def test_map_paths_to_libs(self):
gb = self._create_normal_graph()
@@ -119,7 +119,7 @@ class ELFLinkerTest(unittest.TestCase):
bad = []
paths = ['/system/lib/libc.so', '/system/lib/libdl.so']
nodes = graph.map_paths_to_libs(paths, bad.append)
nodes = graph.get_libs(paths, bad.append)
self.assertEqual([], bad)
self.assertEqual(2, len(nodes))
@@ -127,7 +127,7 @@ class ELFLinkerTest(unittest.TestCase):
bad = []
paths = ['/no/such/path.so', '/system/lib64/libdl.so']
nodes = graph.map_paths_to_libs(paths, bad.append)
nodes = graph.get_libs(paths, bad.append)
self.assertEqual(['/no/such/path.so'], bad)
self.assertEqual(['/system/lib64/libdl.so'],
self._get_paths_from_nodes(nodes))
@@ -149,17 +149,17 @@ class ELFLinkerTest(unittest.TestCase):
graph = gb.graph
# Check the dependencies of libc.so.
node = gb.graph.map_path_to_lib('/system/lib/libc.so')
node = gb.graph.get_lib('/system/lib/libc.so')
self.assertEqual(['/system/lib/libdl.so', '/system/lib/libm.so'],
self._get_paths_from_nodes(node.deps))
# Check the dependencies of libRS.so.
node = gb.graph.map_path_to_lib('/system/lib64/libRS.so')
node = gb.graph.get_lib('/system/lib64/libRS.so')
self.assertEqual(['/system/lib64/libdl.so'],
self._get_paths_from_nodes(node.deps))
# Check the dependencies of libEGL.so.
node = gb.graph.map_path_to_lib('/vendor/lib64/libEGL.so')
node = gb.graph.get_lib('/vendor/lib64/libEGL.so')
self.assertEqual(['/system/lib64/libc.so', '/system/lib64/libcutils.so',
'/system/lib64/libdl.so'],
self._get_paths_from_nodes(node.deps))
@@ -175,13 +175,13 @@ class ELFLinkerTest(unittest.TestCase):
# Check the linked symbols.
for lib in ('lib', 'lib64'):
libdl = graph.map_path_to_lib('/system/' + lib + '/libdl.so')
libm = graph.map_path_to_lib('/system/' + lib + '/libm.so')
libc = graph.map_path_to_lib('/system/' + lib + '/libc.so')
libRS = graph.map_path_to_lib('/system/' + lib + '/libRS.so')
libdl = graph.get_lib('/system/' + lib + '/libdl.so')
libm = graph.get_lib('/system/' + lib + '/libm.so')
libc = graph.get_lib('/system/' + lib + '/libc.so')
libRS = graph.get_lib('/system/' + lib + '/libRS.so')
libcutils = \
graph.map_path_to_lib('/system/' + lib + '/libcutils.so')
libEGL = graph.map_path_to_lib('/vendor/' + lib + '/libEGL.so')
graph.get_lib('/system/' + lib + '/libcutils.so')
libEGL = graph.get_lib('/vendor/' + lib + '/libEGL.so')
# Check the linked symbols for libc.so.
self.assertIs(libdl, libc.linked_symbols['dlclose'])
@@ -211,7 +211,7 @@ class ELFLinkerTest(unittest.TestCase):
imported_symbols={'__does_not_exist'})
gb.resolve()
lib = gb.graph.map_path_to_lib('/system/lib64/libfoo.so')
lib = gb.graph.get_lib('/system/lib64/libfoo.so')
self.assertEqual({'__does_not_exist'}, lib.unresolved_symbols)
def test_users(self):
@@ -219,22 +219,22 @@ class ELFLinkerTest(unittest.TestCase):
graph = gb.graph
# Check the users of libc.so.
node = graph.map_path_to_lib('/system/lib/libc.so')
node = graph.get_lib('/system/lib/libc.so')
self.assertEqual(['/system/lib/libcutils.so', '/vendor/lib/libEGL.so'],
self._get_paths_from_nodes(node.users))
# Check the users of libdl.so.
node = graph.map_path_to_lib('/system/lib/libdl.so')
node = graph.get_lib('/system/lib/libdl.so')
self.assertEqual(['/system/lib/libRS.so', '/system/lib/libc.so',
'/system/lib/libcutils.so', '/vendor/lib/libEGL.so'],
self._get_paths_from_nodes(node.users))
# Check the users of libRS.so.
node = graph.map_path_to_lib('/system/lib64/libRS.so')
node = graph.get_lib('/system/lib64/libRS.so')
self.assertEqual([], self._get_paths_from_nodes(node.users))
# Check the users of libEGL.so.
node = graph.map_path_to_lib('/vendor/lib64/libEGL.so')
node = graph.get_lib('/vendor/lib64/libEGL.so')
self.assertEqual([], self._get_paths_from_nodes(node.users))
def test_compute_vndk_stable(self):

View File

@@ -48,7 +48,7 @@ class ELFLinkerVNDKTest(unittest.TestCase):
def is_banned(self, name):
return False
generic_refs_dir = os.path.join(TESTDATA_DIR, 'vndk_ext_ref')
generic_refs_dir = os.path.join(TESTDATA_DIR, 'vndk_gr')
generic_refs = GenericRefs.create_from_dir(generic_refs_dir)
@@ -70,8 +70,8 @@ class ELFLinkerVNDKTest(unittest.TestCase):
'/system/lib64/vndk/libRS.so',
'/system/lib64/vndk/libcutils.so'],
self._get_paths_from_nodes(vndk.vndk_core))
self.assertEqual(['/system/lib/libRS.so',
'/system/lib64/libRS.so'],
self.assertEqual(['/system/lib/vndk-ext/libRS.so',
'/system/lib64/vndk-ext/libRS.so'],
self._get_paths_from_nodes(vndk.vndk_fwk_ext))
self.assertEqual([], self._get_paths_from_nodes(vndk.vndk_vnd_ext))
@@ -80,7 +80,7 @@ class ELFLinkerVNDKTest(unittest.TestCase):
def is_banned(self, name):
return False
generic_refs_dir = os.path.join(TESTDATA_DIR, 'vndk_ext_ref')
generic_refs_dir = os.path.join(TESTDATA_DIR, 'vndk_gr')
generic_refs = GenericRefs.create_from_dir(generic_refs_dir)
@@ -103,9 +103,113 @@ class ELFLinkerVNDKTest(unittest.TestCase):
'/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(['/system/lib/libRS.so', '/system/lib64/libRS.so'],
self.assertEqual(['/vendor/lib/vndk-ext/libRS.so',
'/vendor/lib64/vndk-ext/libRS.so'],
self._get_paths_from_nodes(vndk.vndk_vnd_ext))
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))
if __name__ == '__main__':
unittest.main()

View File

@@ -0,0 +1,8 @@
EI_CLASS 32
EI_DATA Little-Endian
E_MACHINE EM_ARM
DT_NEEDED libdl.so
DT_NEEDED libc.so
DT_NEEDED libm.so
EXP_SYMBOL jpeg_CreateCompress
EXP_SYMBOL jpeg_CreateDecompress

View File

@@ -0,0 +1,8 @@
EI_CLASS 64
EI_DATA Little-Endian
E_MACHINE EM_AARCH64
DT_NEEDED libdl.so
DT_NEEDED libc.so
DT_NEEDED libm.so
EXP_SYMBOL jpeg_CreateCompress
EXP_SYMBOL jpeg_CreateDecompress

View File

@@ -0,0 +1,9 @@
EI_CLASS 32
EI_DATA Little-Endian
E_MACHINE EM_ARM
DT_NEEDED libdl.so
DT_NEEDED libRS_internal.so
EXP_SYMBOL rsContextCreate
IMP_SYMBOL dlclose
IMP_SYMBOL dlopen
IMP_SYMBOL dlsym

View File

@@ -0,0 +1,5 @@
EI_CLASS 32
EI_DATA Little-Endian
E_MACHINE EM_ARM
DT_NEEDED libdl.so
DT_NEEDED libRS_internal_vendor.so

View File

@@ -0,0 +1,4 @@
EI_CLASS 32
EI_DATA Little-Endian
E_MACHINE EM_ARM
DT_NEEDED libdl.so

View File

@@ -0,0 +1,12 @@
EI_CLASS 32
EI_DATA Little-Endian
E_MACHINE EM_ARM
DT_NEEDED libdl.so
DT_NEEDED libm.so
EXP_SYMBOL fclose
EXP_SYMBOL fopen
EXP_SYMBOL fread
IMP_SYMBOL dlclose
IMP_SYMBOL dlopen
IMP_SYMBOL cos
IMP_SYMBOL sin

View File

@@ -0,0 +1,9 @@
EI_CLASS 32
EI_DATA Little-Endian
E_MACHINE EM_ARM
DT_NEEDED libc.so
DT_NEEDED libdl.so
IMP_SYMBOL dlclose
IMP_SYMBOL dlopen
IMP_SYMBOL fclose
IMP_SYMBOL fopen

View File

@@ -0,0 +1,6 @@
EI_CLASS 32
EI_DATA Little-Endian
E_MACHINE EM_ARM
EXP_SYMBOL dlclose
EXP_SYMBOL dlopen
EXP_SYMBOL dlsym

View File

@@ -0,0 +1,8 @@
EI_CLASS 32
EI_DATA Little-Endian
E_MACHINE EM_ARM
DT_NEEDED libdl.so
DT_NEEDED libc.so
DT_NEEDED libm.so
EXP_SYMBOL jpeg_CreateCompress
EXP_SYMBOL jpeg_CreateDecompress

View File

@@ -0,0 +1,5 @@
EI_CLASS 32
EI_DATA Little-Endian
E_MACHINE EM_ARM
EXP_SYMBOL cos
EXP_SYMBOL sin

View File

@@ -0,0 +1,9 @@
EI_CLASS 64
EI_DATA Little-Endian
E_MACHINE EM_AARCH64
DT_NEEDED libdl.so
DT_NEEDED libRS_internal.so
EXP_SYMBOL rsContextCreate
IMP_SYMBOL dlclose
IMP_SYMBOL dlopen
IMP_SYMBOL dlsym

View File

@@ -0,0 +1,5 @@
EI_CLASS 64
EI_DATA Little-Endian
E_MACHINE EM_AARCH64
DT_NEEDED libdl.so
DT_NEEDED libRS_internal_vendor.so

View File

@@ -0,0 +1,4 @@
EI_CLASS 64
EI_DATA Little-Endian
E_MACHINE EM_AARCH64
DT_NEEDED libdl.so

View File

@@ -0,0 +1,12 @@
EI_CLASS 64
EI_DATA Little-Endian
E_MACHINE EM_AARCH64
DT_NEEDED libdl.so
DT_NEEDED libm.so
EXP_SYMBOL fclose
EXP_SYMBOL fopen
EXP_SYMBOL fread
IMP_SYMBOL dlclose
IMP_SYMBOL dlopen
IMP_SYMBOL cos
IMP_SYMBOL sin

View File

@@ -0,0 +1,9 @@
EI_CLASS 64
EI_DATA Little-Endian
E_MACHINE EM_AARCH64
DT_NEEDED libc.so
DT_NEEDED libdl.so
IMP_SYMBOL dlclose
IMP_SYMBOL dlopen
IMP_SYMBOL fclose
IMP_SYMBOL fopen

View File

@@ -0,0 +1,6 @@
EI_CLASS 64
EI_DATA Little-Endian
E_MACHINE EM_AARCH64
EXP_SYMBOL dlclose
EXP_SYMBOL dlopen
EXP_SYMBOL dlsym

View File

@@ -0,0 +1,8 @@
EI_CLASS 64
EI_DATA Little-Endian
E_MACHINE EM_AARCH64
DT_NEEDED libdl.so
DT_NEEDED libc.so
DT_NEEDED libm.so
EXP_SYMBOL jpeg_CreateCompress
EXP_SYMBOL jpeg_CreateDecompress

View File

@@ -0,0 +1,5 @@
EI_CLASS 64
EI_DATA Little-Endian
E_MACHINE EM_AARCH64
EXP_SYMBOL cos
EXP_SYMBOL sin

View File

@@ -0,0 +1,9 @@
EI_CLASS 32
EI_DATA Little-Endian
E_MACHINE EM_ARM
DT_NEEDED libc.so
DT_NEEDED libcutils.so
DT_NEEDED libdl.so
EXP_SYMBOL eglGetDisplay
IMP_SYMBOL fclose
IMP_SYMBOL fopen

View File

@@ -0,0 +1,5 @@
EI_CLASS 32
EI_DATA Little-Endian
E_MACHINE EM_ARM
DT_NEEDED libRS.so
IMP_SYMBOL rsContextCreate

View File

@@ -0,0 +1,9 @@
EI_CLASS 64
EI_DATA Little-Endian
E_MACHINE EM_AARCH64
DT_NEEDED libc.so
DT_NEEDED libcutils.so
DT_NEEDED libdl.so
EXP_SYMBOL eglGetDisplay
IMP_SYMBOL fclose
IMP_SYMBOL fopen

View File

@@ -0,0 +1,5 @@
EI_CLASS 64
EI_DATA Little-Endian
E_MACHINE EM_AARCH64
DT_NEEDED libRS.so
IMP_SYMBOL rsContextCreate

View File

@@ -0,0 +1,9 @@
EI_CLASS 32
EI_DATA Little-Endian
E_MACHINE EM_ARM
DT_NEEDED libdl.so
DT_NEEDED libRS_internal.so
EXP_SYMBOL rsContextCreate
IMP_SYMBOL dlclose
IMP_SYMBOL dlopen
IMP_SYMBOL dlsym

View File

@@ -0,0 +1,4 @@
EI_CLASS 32
EI_DATA Little-Endian
E_MACHINE EM_ARM
DT_NEEDED libdl.so

View File

@@ -0,0 +1,12 @@
EI_CLASS 32
EI_DATA Little-Endian
E_MACHINE EM_ARM
DT_NEEDED libdl.so
DT_NEEDED libm.so
EXP_SYMBOL fclose
EXP_SYMBOL fopen
EXP_SYMBOL fread
IMP_SYMBOL dlclose
IMP_SYMBOL dlopen
IMP_SYMBOL cos
IMP_SYMBOL sin

View File

@@ -0,0 +1,9 @@
EI_CLASS 32
EI_DATA Little-Endian
E_MACHINE EM_ARM
DT_NEEDED libc.so
DT_NEEDED libdl.so
IMP_SYMBOL dlclose
IMP_SYMBOL dlopen
IMP_SYMBOL fclose
IMP_SYMBOL fopen

View File

@@ -0,0 +1,6 @@
EI_CLASS 32
EI_DATA Little-Endian
E_MACHINE EM_ARM
EXP_SYMBOL dlclose
EXP_SYMBOL dlopen
EXP_SYMBOL dlsym

View File

@@ -0,0 +1,8 @@
EI_CLASS 32
EI_DATA Little-Endian
E_MACHINE EM_ARM
DT_NEEDED libdl.so
DT_NEEDED libc.so
DT_NEEDED libm.so
EXP_SYMBOL jpeg_CreateCompress
EXP_SYMBOL jpeg_CreateDecompress

View File

@@ -0,0 +1,5 @@
EI_CLASS 32
EI_DATA Little-Endian
E_MACHINE EM_ARM
EXP_SYMBOL cos
EXP_SYMBOL sin

View File

@@ -0,0 +1,9 @@
EI_CLASS 64
EI_DATA Little-Endian
E_MACHINE EM_AARCH64
DT_NEEDED libdl.so
DT_NEEDED libRS_internal.so
EXP_SYMBOL rsContextCreate
IMP_SYMBOL dlclose
IMP_SYMBOL dlopen
IMP_SYMBOL dlsym

View File

@@ -0,0 +1,4 @@
EI_CLASS 64
EI_DATA Little-Endian
E_MACHINE EM_AARCH64
DT_NEEDED libdl.so

View File

@@ -0,0 +1,12 @@
EI_CLASS 64
EI_DATA Little-Endian
E_MACHINE EM_AARCH64
DT_NEEDED libdl.so
DT_NEEDED libm.so
EXP_SYMBOL fclose
EXP_SYMBOL fopen
EXP_SYMBOL fread
IMP_SYMBOL dlclose
IMP_SYMBOL dlopen
IMP_SYMBOL cos
IMP_SYMBOL sin

View File

@@ -0,0 +1,9 @@
EI_CLASS 64
EI_DATA Little-Endian
E_MACHINE EM_AARCH64
DT_NEEDED libc.so
DT_NEEDED libdl.so
IMP_SYMBOL dlclose
IMP_SYMBOL dlopen
IMP_SYMBOL fclose
IMP_SYMBOL fopen

View File

@@ -0,0 +1,6 @@
EI_CLASS 64
EI_DATA Little-Endian
E_MACHINE EM_AARCH64
EXP_SYMBOL dlclose
EXP_SYMBOL dlopen
EXP_SYMBOL dlsym

View File

@@ -0,0 +1,8 @@
EI_CLASS 64
EI_DATA Little-Endian
E_MACHINE EM_AARCH64
DT_NEEDED libdl.so
DT_NEEDED libc.so
DT_NEEDED libm.so
EXP_SYMBOL jpeg_CreateCompress
EXP_SYMBOL jpeg_CreateDecompress

View File

@@ -0,0 +1,5 @@
EI_CLASS 64
EI_DATA Little-Endian
E_MACHINE EM_AARCH64
EXP_SYMBOL cos
EXP_SYMBOL sin

View File

@@ -0,0 +1,9 @@
EI_CLASS 32
EI_DATA Little-Endian
E_MACHINE EM_ARM
DT_NEEDED libc.so
DT_NEEDED libcutils.so
DT_NEEDED libdl.so
EXP_SYMBOL eglGetDisplay
IMP_SYMBOL fclose
IMP_SYMBOL fopen

View File

@@ -0,0 +1,9 @@
EI_CLASS 64
EI_DATA Little-Endian
E_MACHINE EM_AARCH64
DT_NEEDED libc.so
DT_NEEDED libcutils.so
DT_NEEDED libdl.so
EXP_SYMBOL eglGetDisplay
IMP_SYMBOL fclose
IMP_SYMBOL fopen

View File

@@ -0,0 +1,11 @@
EI_CLASS 32
EI_DATA Little-Endian
E_MACHINE EM_ARM
DT_NEEDED libdl.so
DT_NEEDED libjpeg.so
EXP_SYMBOL rsContextCreate
IMP_SYMBOL dlclose
IMP_SYMBOL dlopen
IMP_SYMBOL dlsym
IMP_SYMBOL jpeg_CreateCompress
IMP_SYMBOL jpeg_CreateDecompress

View File

@@ -0,0 +1,5 @@
EI_CLASS 32
EI_DATA Little-Endian
E_MACHINE EM_ARM
DT_NEEDED libRS.so
IMP_SYMBOL rsContextCreate

View File

@@ -0,0 +1,12 @@
EI_CLASS 32
EI_DATA Little-Endian
E_MACHINE EM_ARM
DT_NEEDED libdl.so
DT_NEEDED libm.so
EXP_SYMBOL fclose
EXP_SYMBOL fopen
EXP_SYMBOL fread
IMP_SYMBOL dlclose
IMP_SYMBOL dlopen
IMP_SYMBOL cos
IMP_SYMBOL sin

View File

@@ -0,0 +1,9 @@
EI_CLASS 32
EI_DATA Little-Endian
E_MACHINE EM_ARM
DT_NEEDED libc.so
DT_NEEDED libdl.so
IMP_SYMBOL dlclose
IMP_SYMBOL dlopen
IMP_SYMBOL fclose
IMP_SYMBOL fopen

View File

@@ -0,0 +1,6 @@
EI_CLASS 32
EI_DATA Little-Endian
E_MACHINE EM_ARM
EXP_SYMBOL dlclose
EXP_SYMBOL dlopen
EXP_SYMBOL dlsym

View File

@@ -0,0 +1,8 @@
EI_CLASS 32
EI_DATA Little-Endian
E_MACHINE EM_ARM
DT_NEEDED libdl.so
DT_NEEDED libc.so
DT_NEEDED libm.so
EXP_SYMBOL jpeg_CreateCompress
EXP_SYMBOL jpeg_CreateDecompress

View File

@@ -0,0 +1,5 @@
EI_CLASS 32
EI_DATA Little-Endian
E_MACHINE EM_ARM
EXP_SYMBOL cos
EXP_SYMBOL sin

View File

@@ -0,0 +1,11 @@
EI_CLASS 64
EI_DATA Little-Endian
E_MACHINE EM_AARCH64
DT_NEEDED libdl.so
DT_NEEDED libjpeg.so
EXP_SYMBOL rsContextCreate
IMP_SYMBOL dlclose
IMP_SYMBOL dlopen
IMP_SYMBOL dlsym
IMP_SYMBOL jpeg_CreateCompress
IMP_SYMBOL jpeg_CreateDecompress

View File

@@ -0,0 +1,5 @@
EI_CLASS 64
EI_DATA Little-Endian
E_MACHINE EM_AARCH64
DT_NEEDED libRS.so
IMP_SYMBOL rsContextCreate

View File

@@ -0,0 +1,12 @@
EI_CLASS 64
EI_DATA Little-Endian
E_MACHINE EM_AARCH64
DT_NEEDED libdl.so
DT_NEEDED libm.so
EXP_SYMBOL fclose
EXP_SYMBOL fopen
EXP_SYMBOL fread
IMP_SYMBOL dlclose
IMP_SYMBOL dlopen
IMP_SYMBOL cos
IMP_SYMBOL sin

View File

@@ -0,0 +1,9 @@
EI_CLASS 64
EI_DATA Little-Endian
E_MACHINE EM_AARCH64
DT_NEEDED libc.so
DT_NEEDED libdl.so
IMP_SYMBOL dlclose
IMP_SYMBOL dlopen
IMP_SYMBOL fclose
IMP_SYMBOL fopen

View File

@@ -0,0 +1,6 @@
EI_CLASS 64
EI_DATA Little-Endian
E_MACHINE EM_AARCH64
EXP_SYMBOL dlclose
EXP_SYMBOL dlopen
EXP_SYMBOL dlsym

View File

@@ -0,0 +1,8 @@
EI_CLASS 64
EI_DATA Little-Endian
E_MACHINE EM_AARCH64
DT_NEEDED libdl.so
DT_NEEDED libc.so
DT_NEEDED libm.so
EXP_SYMBOL jpeg_CreateCompress
EXP_SYMBOL jpeg_CreateDecompress

View File

@@ -0,0 +1,5 @@
EI_CLASS 64
EI_DATA Little-Endian
E_MACHINE EM_AARCH64
EXP_SYMBOL cos
EXP_SYMBOL sin

View File

@@ -0,0 +1,9 @@
EI_CLASS 32
EI_DATA Little-Endian
E_MACHINE EM_ARM
DT_NEEDED libc.so
DT_NEEDED libcutils.so
DT_NEEDED libdl.so
EXP_SYMBOL eglGetDisplay
IMP_SYMBOL fclose
IMP_SYMBOL fopen

View File

@@ -0,0 +1,5 @@
EI_CLASS 32
EI_DATA Little-Endian
E_MACHINE EM_ARM
DT_NEEDED libRS.so
IMP_SYMBOL rsContextCreate

View File

@@ -0,0 +1,9 @@
EI_CLASS 64
EI_DATA Little-Endian
E_MACHINE EM_AARCH64
DT_NEEDED libc.so
DT_NEEDED libcutils.so
DT_NEEDED libdl.so
EXP_SYMBOL eglGetDisplay
IMP_SYMBOL fclose
IMP_SYMBOL fopen

View File

@@ -0,0 +1,5 @@
EI_CLASS 64
EI_DATA Little-Endian
E_MACHINE EM_AARCH64
DT_NEEDED libRS.so
IMP_SYMBOL rsContextCreate

View File

@@ -661,6 +661,12 @@ class ELFLinkData(object):
def deps(self):
return itertools.chain.from_iterable(self._deps)
@property
def deps_with_type(self):
dt_deps = zip(self._deps[self.NEEDED], itertools.repeat(self.NEEDED))
dl_deps = zip(self._deps[self.DLOPEN], itertools.repeat(self.DLOPEN))
return itertools.chain(dt_deps, dl_deps)
@property
def dt_deps(self):
return self._deps[self.NEEDED]
@@ -679,6 +685,12 @@ class ELFLinkData(object):
def users(self):
return itertools.chain.from_iterable(self._users)
@property
def users_with_type(self):
dt_users = zip(self._users[self.NEEDED], itertools.repeat(self.NEEDED))
dl_users = zip(self._users[self.DLOPEN], itertools.repeat(self.DLOPEN))
return itertools.chain(dt_users, dl_users)
@property
def dt_users(self):
return self._users[self.NEEDED]
@@ -727,14 +739,30 @@ class ELFLinker(object):
self.lib32_resolver = ELFResolver(self.lib32, self.LIB32_SEARCH_PATH)
self.lib64_resolver = ELFResolver(self.lib64, self.LIB64_SEARCH_PATH)
def add(self, partition, path, elf):
node = ELFLinkData(partition, path, elf)
if elf.is_32bit:
self.lib32[path] = node
def _add_lib_to_lookup_dict(self, lib):
if lib.elf.is_32bit:
self.lib32[lib.path] = lib
else:
self.lib64[path] = node
self.lib_pt[partition][path] = node
return node
self.lib64[lib.path] = lib
self.lib_pt[lib.partition][lib.path] = lib
def _remove_lib_from_lookup_dict(self, lib):
if lib.elf.is_32bit:
del self.lib32[lib.path]
else:
del self.lib64[lib.path]
del self.lib_pt[lib.partition][lib.path]
def add_lib(self, partition, path, elf):
lib = ELFLinkData(partition, path, elf)
self._add_lib_to_lookup_dict(lib)
return lib
def rename_lib(self, lib, new_partition, new_path):
self._remove_lib_from_lookup_dict(lib)
lib.path = new_path
lib.partition = new_partition
self._add_lib_to_lookup_dict(lib)
def add_dep(self, src_path, dst_path, ty):
for lib_set in (self.lib32, self.lib64):
@@ -746,17 +774,17 @@ class ELFLinker(object):
print('error: cannot add dependency from {} to {}.'
.format(src_path, dst_path), file=sys.stderr)
def map_path_to_lib(self, path):
def get_lib(self, path):
for lib_set in (self.lib32, self.lib64):
lib = lib_set.get(path)
if lib:
return lib
return None
def map_paths_to_libs(self, paths, report_error):
def get_libs(self, paths, report_error):
result = set()
for path in paths:
lib = self.map_path_to_lib(path)
lib = self.get_lib(path)
if not lib:
report_error(path)
continue
@@ -780,9 +808,9 @@ class ELFLinker(object):
for path, elf in scan_elf_files(root):
short_path = os.path.join('/', partition_name, path[prefix_len:])
if alter_subdirs and alter_patt.match(path):
self.add(alter_partition, short_path, elf)
self.add_lib(alter_partition, short_path, elf)
else:
self.add(partition, short_path, elf)
self.add_lib(partition, short_path, elf)
def load_extra_deps(self, path):
patt = re.compile('([^:]*):\\s*(.*)')
@@ -829,7 +857,18 @@ class ELFLinker(object):
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)
if generic_refs:
for imported_lib in imported_libs:
if imported_lib.path not in generic_refs.refs:
# Add imported_lib to imported_ext_symbols to make sure
# non-AOSP libraries are in the imported_ext_symbols key
# set.
lib.imported_ext_symbols[imported_lib].update()
# Resolve imported symbols.
self._resolve_lib_imported_symbols(lib, imported_libs, generic_refs)
def _resolve_lib_set_deps(self, lib_set, resolver, generic_refs):
@@ -1039,6 +1078,40 @@ class ELFLinker(object):
def compute_vndk(self, sp_hals, vndk_stable, vndk_customized_for_system,
vndk_customized_for_vendor, generic_refs, banned_libs):
# ELF resolvers.
VNDK_CORE_SEARCH_PATH32 = (
'/system/lib/vndk',
'/system/lib',
)
VNDK_CORE_SEARCH_PATH64 = (
'/system/lib64/vndk',
'/system/lib64',
)
VENDOR_SEARCH_PATH32 = (
'/system/lib/vndk',
'/vendor/lib',
# FIXME: Remove following line after we fixed vndk-stable
# resolution.
'/system/lib',
)
VENDOR_SEARCH_PATH64 = (
'/system/lib64/vndk',
'/vendor/lib64',
# FIXME: Remove following line after we fixed vndk-stable
# resolution.
'/system/lib64',
)
vndk_core_resolver32 = ELFResolver(self.lib32, VNDK_CORE_SEARCH_PATH32)
vndk_core_resolver64 = ELFResolver(self.lib64, VNDK_CORE_SEARCH_PATH64)
vendor_resolver32 = ELFResolver(self.lib32, VENDOR_SEARCH_PATH32)
vendor_resolver64 = ELFResolver(self.lib64, VENDOR_SEARCH_PATH64)
# Collect existing VNDK libraries.
vndk_core, vndk_fwk_ext, vndk_vnd_ext = self.find_existing_vndk()
@@ -1069,21 +1142,39 @@ class ELFLinker(object):
lib_dir_name = 'lib' if lib.elf.is_32bit else 'lib64'
return os.path.join('/system', lib_dir_name, 'vndk', lib_name)
def add_to_vndk_core(lib):
def get_vndk_fwk_ext_lib_name(lib):
lib_name = os.path.basename(lib.path)
lib_dir_name = 'lib' if lib.elf.is_32bit else 'lib64'
return os.path.join('/system', lib_dir_name, 'vndk-ext', lib_name)
def get_vndk_vnd_ext_lib_name(lib):
lib_name = os.path.basename(lib.path)
lib_dir_name = 'lib' if lib.elf.is_32bit else 'lib64'
return os.path.join('/vendor', lib_dir_name, 'vndk-ext', lib_name)
def is_valid_vndk_core_dep(path):
d = os.path.dirname(path)
return (d == '/system/lib' or d == '/system/lib64' or
d == '/system/lib/vndk' or d == '/system/lib64/vndk')
def add_generic_lib_to_vndk_core(lib):
"""Add a library to vndk-core."""
elf = generic_refs.refs[lib.path]
# Create new vndk-core lib from generic reference.
vndk_lib_path = get_vndk_core_lib_name(lib)
vndk_lib = self.add(PT_SYSTEM, vndk_lib_path, elf)
vndk_lib = self.add_lib(PT_SYSTEM, vndk_lib_path, elf)
# Resovle the library dependencies.
resolver = self.lib32_resolver if lib.elf.is_32bit else \
self.lib64_resolver
resolver = vndk_core_resolver32 if lib.elf.is_32bit else \
vndk_core_resolver64
self._resolve_lib_deps(vndk_lib, resolver, generic_refs)
assert all(is_valid_vndk_core_dep(dep.path) for dep in lib.deps)
# Add vndk-core to the set.
vndk_core.add(vndk_lib)
return vndk_lib
# Compute vndk-core, vndk-fwk-ext and vndk-vnd-ext.
if not generic_refs:
@@ -1112,32 +1203,55 @@ class ELFLinker(object):
prev_vndk_candidates = vndk_candidates
vndk_candidates = set()
def add_to_vndk_fwk_ext(lib):
def replace_linked_lib(user, old_lib, new_lib, dep_type):
user.remove_dep(old_lib, dep_type)
user.add_dep(new_lib, dep_type)
for symbol, imported_lib in user.linked_symbols.items():
if imported_lib == old_lib:
user.linked_symbols[symbol] = new_lib
def replace_generic_lib_usages(lib, generic_lib):
for user, dep_type in list(lib.users_with_type):
if lib not in user.imported_ext_symbols:
replace_linked_lib(user, lib, generic_lib, dep_type)
def add_to_vndk_core(lib):
self.rename_lib(lib, PT_SYSTEM, get_vndk_core_lib_name(lib))
vndk_core.add(lib)
def add_to_vndk_fwk_ext(lib, generic_lib):
self.rename_lib(lib, PT_SYSTEM,
get_vndk_fwk_ext_lib_name(lib))
vndk_fwk_ext.add(lib)
replace_generic_lib_usages(lib, generic_lib)
def add_to_vndk_vnd_ext(lib):
def add_to_vndk_vnd_ext(lib, generic_lib):
"""Add a library to vndk-vnd-ext."""
path = lib.path
# Clone lib object for vndk-vnd-ext.
cloned_lib = self.add(PT_VENDOR, path, lib.elf)
replace_generic_lib_usages(lib, generic_lib)
# Update the usages.
for user in list(lib.dt_users):
if user.is_system_lib():
user.remove_dep(lib, ELFLinkData.NEEDED)
for user in list(lib.dl_users):
if user.is_system_lib():
user.remove_dep(lib, ELFLinkData.DLOPEN)
# Create a new vndk-vnd-ext library.
vndk_vnd_ext_lib = self.add_lib(
PT_VENDOR, get_vndk_vnd_ext_lib_name(lib), lib.elf)
# Resolve the dependencies.
# Vendor libraries should link to vndk_vnd_ext_lib instead.
for user, dep_type in list(lib.users_with_type):
if not user.is_system_lib():
replace_linked_lib(user, lib, vndk_vnd_ext_lib,
dep_type)
# Resolve the dependencies. In order to find more
# dependencies from vendor partition to system partition,
# continue to resolve dependencies with the global
# ELFResolver.
resolver = self.lib32_resolver if lib.elf.is_32bit else \
self.lib64_resolver
self._resolve_lib_deps(cloned_lib, resolver, generic_refs)
self._resolve_lib_deps(vndk_vnd_ext_lib, resolver,
generic_refs)
add_deps_to_vndk_candidate(cloned_lib)
add_deps_to_vndk_candidate(vndk_vnd_ext_lib)
vndk_vnd_ext.add(cloned_lib)
vndk_vnd_ext.add(vndk_vnd_ext_lib)
def add_to_vndk_candidate(lib):
if is_not_vndk(lib):
@@ -1174,15 +1288,11 @@ class ELFLinker(object):
add_to_vndk_core(lib)
else:
# Outward-customized VNDK libraries.
# Add a vndk-core counterpart for this lib.
add_to_vndk_core(lib)
# Add this lib to vndk-ext sets.
generic_lib = add_generic_lib_to_vndk_core(lib)
if lib in vndk_customized_for_system:
add_to_vndk_fwk_ext(lib)
add_to_vndk_fwk_ext(lib, generic_lib)
if lib in vndk_customized_for_vendor:
add_to_vndk_vnd_ext(lib)
add_to_vndk_vnd_ext(lib, generic_lib)
# Compute VNDK extension candidates.
for lib in self._users_po_sorted(vndk_extended_candidates):
@@ -1198,60 +1308,47 @@ class ELFLinker(object):
if has_system_users and has_vendor_users:
break
# Add a vndk-core counterpart for this lib.
add_to_vndk_core(lib)
# Add this lib to vndk-ext sets.
generic_lib = add_generic_lib_to_vndk_core(lib)
if has_system_users:
add_to_vndk_fwk_ext(lib)
add_to_vndk_fwk_ext(lib, generic_lib)
if has_vendor_users:
add_to_vndk_vnd_ext(lib)
add_to_vndk_vnd_ext(lib, generic_lib)
# Compute the closure of the VNDK libs.
vndk_core_paths = set(lib.path for lib in vndk_core)
stack = list(vndk_core)
visited_libs = set(vndk_core)
processed_paths = set(lib.path for lib in vndk_core)
stack = []
def add_vndk_core_deps_to_stack(lib):
for dep in lib.deps:
if is_not_vndk(dep):
continue
if dep not in visited_libs:
stack.append(dep)
visited_libs.add(dep)
for lib in vndk_core:
add_vndk_core_deps_to_stack(lib)
while stack:
lib = stack.pop()
if is_not_vndk(lib):
continue
stack.extend(lib.deps)
vndk_lib_path = get_vndk_core_lib_name(lib)
if vndk_lib_path in vndk_core_paths:
if vndk_lib_path in processed_paths:
continue
vndk_core_paths.add(vndk_lib_path)
processed_paths.add(vndk_lib_path)
if lib.imported_ext_symbols or \
(generic_refs and not generic_refs.is_equivalent_lib(lib)):
vndk_fwk_ext.add(lib)
if generic_refs:
add_to_vndk_core(lib)
generic_lib = add_generic_lib_to_vndk_core(lib)
add_vndk_core_deps_to_stack(generic_lib)
add_to_vndk_fwk_ext(lib, generic_lib)
else:
vndk_core.add(lib)
add_to_vndk_core(lib)
add_vndk_core_deps_to_stack(lib)
# Truncate all vendor libs and resolve it again.
VENDOR_SEARCH_PATH32 = (
'/system/lib/vndk',
'/vendor/lib',
# FIXME: Remove following line after we fixed vndk-stable
# resolution.
'/system/lib',
)
VENDOR_SEARCH_PATH64 = (
'/system/lib64/vndk',
'/vendor/lib64',
# FIXME: Remove following line after we fixed vndk-stable
# resolution.
'/system/lib64',
)
vendor_resolver32 = ELFResolver(self.lib32, VENDOR_SEARCH_PATH32)
vendor_resolver64 = ELFResolver(self.lib64, VENDOR_SEARCH_PATH64)
for lib in self.lib_pt[PT_VENDOR].values():
lib._deps = (set(), set())
lib._users = (set(), set())
@@ -1598,7 +1695,8 @@ class VNDKCommand(ELFGraphCommand):
generic_refs=generic_refs)
# Check the API extensions to NDK libraries.
self._check_ndk_extensions(graph, generic_refs)
if generic_refs:
self._check_ndk_extensions(graph, generic_refs)
# Create banned libraries.
if not args.ban_vendor_lib_dep:
@@ -1638,12 +1736,12 @@ class VNDKCommand(ELFGraphCommand):
if args.outward_customization_for_system:
vndk_customized_for_system.update(
graph.map_paths_to_libs(
graph.get_libs(
args.outward_customization_for_system, lambda x: None))
if args.outward_customization_for_vendor:
vndk_customized_for_vendor.update(
graph.map_paths_to_libs(
graph.get_libs(
args.outward_customization_for_vendor, lambda x: None))
# Compute vndk heuristics.
@@ -1791,8 +1889,8 @@ class DepsClosureCommand(ELFGraphCommand):
# Find root/excluded libraries by their paths.
def report_error(path):
print('error: no such lib: {}'.format(path), file=sys.stderr)
root_libs = graph.map_paths_to_libs(args.lib, report_error)
excluded_libs = graph.map_paths_to_libs(args.exclude_lib, report_error)
root_libs = graph.get_libs(args.lib, report_error)
excluded_libs = graph.get_libs(args.exclude_lib, report_error)
# Compute and print the closure.
if args.exclude_ndk: