1#!/usr/bin/env python3 2 3from __future__ import print_function 4 5import os 6import sys 7sys.path.append(os.path.dirname(os.path.dirname(os.path.abspath(__file__)))) 8 9import unittest 10 11from compat import StringIO 12from vndk_definition_tool import (BannedLibDict, ELF, ELFLinker, GenericRefs, 13 PT_SYSTEM, PT_VENDOR) 14 15 16class GraphBuilder(object): 17 _PARTITION_NAMES = { 18 PT_SYSTEM: 'system', 19 PT_VENDOR: 'vendor', 20 } 21 22 _LIB_DIRS = { 23 ELF.ELFCLASS32: 'lib', 24 ELF.ELFCLASS64: 'lib64', 25 } 26 27 def __init__(self): 28 self.graph = ELFLinker() 29 30 def add_lib(self, partition, klass, name, dt_needed=[], 31 exported_symbols=set(), imported_symbols=set(), 32 extra_dir=None): 33 """Create and add a shared library to ELFLinker.""" 34 35 lib_dir = os.path.join('/', self._PARTITION_NAMES[partition], 36 self._LIB_DIRS[klass]) 37 if extra_dir: 38 lib_dir = os.path.join(lib_dir, extra_dir) 39 40 path = os.path.join(lib_dir, name + '.so') 41 42 elf = ELF(klass, ELF.ELFDATA2LSB, dt_needed=dt_needed, 43 exported_symbols=exported_symbols, 44 imported_symbols=imported_symbols) 45 46 node = self.graph.add_lib(partition, path, elf) 47 setattr(self, name + '_' + elf.elf_class_name, node) 48 return node 49 50 def add_multilib(self, partition, name, dt_needed=[], 51 exported_symbols=set(), imported_symbols=set(), 52 extra_dir=None): 53 """Add 32-bit / 64-bit shared libraries to ELFLinker.""" 54 return ( 55 self.add_lib(partition, ELF.ELFCLASS32, name, dt_needed, 56 exported_symbols, imported_symbols, extra_dir), 57 self.add_lib(partition, ELF.ELFCLASS64, name, dt_needed, 58 exported_symbols, imported_symbols, extra_dir) 59 ) 60 61 def resolve(self): 62 self.graph.resolve_deps() 63 64 65class ELFLinkerTest(unittest.TestCase): 66 def _create_normal_graph(self): 67 gb = GraphBuilder() 68 69 gb.add_multilib(PT_SYSTEM, 'libdl', 70 exported_symbols={'dlclose', 'dlopen', 'dlsym'}) 71 72 gb.add_multilib(PT_SYSTEM, 'libm', exported_symbols={'cos', 'sin'}) 73 74 gb.add_multilib(PT_SYSTEM, 'libc', dt_needed=['libdl.so', 'libm.so'], 75 exported_symbols={'fclose', 'fopen', 'fread'}, 76 imported_symbols={'dlclose', 'dlopen', 'cos', 'sin'}) 77 78 gb.add_multilib(PT_SYSTEM, 'libRS', dt_needed=['libdl.so'], 79 exported_symbols={'rsContextCreate'}, 80 imported_symbols={'dlclose', 'dlopen', 'dlsym'}) 81 82 gb.add_multilib(PT_SYSTEM, 'libcutils', 83 dt_needed=['libc.so', 'libdl.so'], 84 imported_symbols={'dlclose', 'dlopen', 'fclose', 85 'fopen'}) 86 87 gb.add_multilib(PT_VENDOR, 'libEGL', 88 dt_needed=['libc.so', 'libcutils.so', 'libdl.so'], 89 exported_symbols={'eglGetDisplay'}, 90 imported_symbols={'fclose', 'fopen'}) 91 92 gb.resolve() 93 return gb 94 95 def _get_paths_from_nodes(self, nodes): 96 return sorted([node.path for node in nodes]) 97 98 def test_get_lib(self): 99 gb = self._create_normal_graph() 100 graph = gb.graph 101 102 node = graph.get_lib('/system/lib/libc.so') 103 self.assertEqual(gb.libc_32, node) 104 self.assertEqual('/system/lib/libc.so', node.path) 105 106 node = graph.get_lib('/system/lib64/libdl.so') 107 self.assertEqual(gb.libdl_64, node) 108 self.assertEqual('/system/lib64/libdl.so', node.path) 109 110 node = graph.get_lib('/vendor/lib64/libEGL.so') 111 self.assertEqual(gb.libEGL_64, node) 112 self.assertEqual('/vendor/lib64/libEGL.so', node.path) 113 114 self.assertEqual(None, graph.get_lib('/no/such/path.so')) 115 116 def test_map_paths_to_libs(self): 117 gb = self._create_normal_graph() 118 graph = gb.graph 119 120 bad = [] 121 paths = ['/system/lib/libc.so', '/system/lib/libdl.so'] 122 nodes = graph.get_libs(paths, bad.append) 123 124 self.assertEqual([], bad) 125 self.assertEqual(2, len(nodes)) 126 self.assertEqual(paths, self._get_paths_from_nodes(nodes)) 127 128 bad = [] 129 paths = ['/no/such/path.so', '/system/lib64/libdl.so'] 130 nodes = graph.get_libs(paths, bad.append) 131 self.assertEqual(['/no/such/path.so'], bad) 132 self.assertEqual(['/system/lib64/libdl.so'], 133 self._get_paths_from_nodes(nodes)) 134 135 def test_elf_class_and_partitions(self): 136 gb = self._create_normal_graph() 137 graph = gb.graph 138 self.assertEqual(5, len(graph.lib_pt[PT_SYSTEM].lib32)) 139 self.assertEqual(5, len(graph.lib_pt[PT_SYSTEM].lib64)) 140 self.assertEqual(1, len(graph.lib_pt[PT_VENDOR].lib32)) 141 self.assertEqual(1, len(graph.lib_pt[PT_VENDOR].lib64)) 142 143 def test_deps(self): 144 gb = self._create_normal_graph() 145 graph = gb.graph 146 147 # Check the dependencies of libc.so. 148 node = gb.graph.get_lib('/system/lib/libc.so') 149 self.assertEqual(['/system/lib/libdl.so', '/system/lib/libm.so'], 150 self._get_paths_from_nodes(node.deps)) 151 152 # Check the dependencies of libRS.so. 153 node = gb.graph.get_lib('/system/lib64/libRS.so') 154 self.assertEqual(['/system/lib64/libdl.so'], 155 self._get_paths_from_nodes(node.deps)) 156 157 # Check the dependencies of libEGL.so. 158 node = gb.graph.get_lib('/vendor/lib64/libEGL.so') 159 self.assertEqual(['/system/lib64/libc.so', '/system/lib64/libcutils.so', 160 '/system/lib64/libdl.so'], 161 self._get_paths_from_nodes(node.deps)) 162 163 def test_linked_symbols(self): 164 gb = self._create_normal_graph() 165 graph = gb.graph 166 167 # Check the unresolved symbols. 168 for lib_set in graph.lib_pt: 169 for lib in lib_set.values(): 170 self.assertEqual(set(), lib.unresolved_symbols) 171 172 # Check the linked symbols. 173 for lib in ('lib', 'lib64'): 174 libdl = graph.get_lib('/system/' + lib + '/libdl.so') 175 libm = graph.get_lib('/system/' + lib + '/libm.so') 176 libc = graph.get_lib('/system/' + lib + '/libc.so') 177 libRS = graph.get_lib('/system/' + lib + '/libRS.so') 178 libcutils = \ 179 graph.get_lib('/system/' + lib + '/libcutils.so') 180 libEGL = graph.get_lib('/vendor/' + lib + '/libEGL.so') 181 182 # Check the linked symbols for libc.so. 183 self.assertIs(libdl, libc.linked_symbols['dlclose']) 184 self.assertIs(libdl, libc.linked_symbols['dlopen']) 185 self.assertIs(libm, libc.linked_symbols['cos']) 186 self.assertIs(libm, libc.linked_symbols['sin']) 187 188 # Check the linked symbols for libRS.so. 189 self.assertIs(libdl, libRS.linked_symbols['dlclose']) 190 self.assertIs(libdl, libRS.linked_symbols['dlopen']) 191 self.assertIs(libdl, libRS.linked_symbols['dlsym']) 192 193 # Check the linked symbols for libcutils.so. 194 self.assertIs(libdl, libcutils.linked_symbols['dlclose']) 195 self.assertIs(libdl, libcutils.linked_symbols['dlopen']) 196 self.assertIs(libc, libcutils.linked_symbols['fclose']) 197 self.assertIs(libc, libcutils.linked_symbols['fopen']) 198 199 # Check the linked symbols for libEGL.so. 200 self.assertIs(libc, libEGL.linked_symbols['fclose']) 201 self.assertIs(libc, libEGL.linked_symbols['fopen']) 202 203 def test_unresolved_symbols(self): 204 gb = GraphBuilder() 205 gb.add_lib(PT_SYSTEM, ELF.ELFCLASS64, 'libfoo', dt_needed=[], 206 exported_symbols={'foo', 'bar'}, 207 imported_symbols={'__does_not_exist'}) 208 gb.resolve() 209 210 lib = gb.graph.get_lib('/system/lib64/libfoo.so') 211 self.assertEqual({'__does_not_exist'}, lib.unresolved_symbols) 212 213 def test_users(self): 214 gb = self._create_normal_graph() 215 graph = gb.graph 216 217 # Check the users of libc.so. 218 node = graph.get_lib('/system/lib/libc.so') 219 self.assertEqual(['/system/lib/libcutils.so', '/vendor/lib/libEGL.so'], 220 self._get_paths_from_nodes(node.users)) 221 222 # Check the users of libdl.so. 223 node = graph.get_lib('/system/lib/libdl.so') 224 self.assertEqual(['/system/lib/libRS.so', '/system/lib/libc.so', 225 '/system/lib/libcutils.so', '/vendor/lib/libEGL.so'], 226 self._get_paths_from_nodes(node.users)) 227 228 # Check the users of libRS.so. 229 node = graph.get_lib('/system/lib64/libRS.so') 230 self.assertEqual([], self._get_paths_from_nodes(node.users)) 231 232 # Check the users of libEGL.so. 233 node = graph.get_lib('/vendor/lib64/libEGL.so') 234 self.assertEqual([], self._get_paths_from_nodes(node.users)) 235 236 def test_compute_predefined_fwk_only_rs(self): 237 lib_names = ( 238 'libft2', 239 'libmediandk', 240 ) 241 242 # Add VNDK-SP libraries. 243 gb = GraphBuilder() 244 for name in lib_names: 245 gb.add_multilib(PT_SYSTEM, name) 246 gb.resolve() 247 248 # Compute FWK-ONLY-RS and check the result. 249 fwk_only_rs = gb.graph.compute_predefined_fwk_only_rs() 250 fwk_only_rs = set(lib.path for lib in fwk_only_rs) 251 252 for lib_dir_name in ('lib', 'lib64'): 253 lib_dir = '/system/' + lib_dir_name 254 for name in lib_names: 255 self.assertIn(os.path.join(lib_dir, name + '.so'), fwk_only_rs) 256 257 def test_compute_predefined_vndk_sp(self): 258 lib_names = ( 259 'android.hardware.graphics.allocator@2.0', 260 'android.hardware.graphics.common@1.0', 261 'android.hardware.graphics.mapper@2.0', 262 'android.hardware.renderscript@1.0', 263 'libRSCpuRef', 264 'libRSDriver', 265 'libRS_internal', 266 'libbase', 267 'libbcinfo', 268 'libc++', 269 'libcompiler_rt', 270 'libcutils', 271 'libhardware', 272 'libhidlbase', 273 'libhidltransport', 274 'libhwbinder', 275 'libutils', 276 ) 277 278 # Add VNDK-SP libraries. 279 gb = GraphBuilder() 280 for name in lib_names: 281 gb.add_multilib(PT_SYSTEM, name, extra_dir='vndk-sp') 282 283 # Add some unrelated libraries. 284 gb.add_multilib(PT_SYSTEM, 'libfoo') 285 gb.add_multilib(PT_SYSTEM, 'libbar', extra_dir='vndk-sp') 286 287 gb.resolve() 288 289 # Compute VNDK-SP and check the result. 290 vndk_sp = set(lib.path for lib in gb.graph.compute_predefined_vndk_sp()) 291 292 for lib_dir_name in ('lib', 'lib64'): 293 lib_dir = '/system/' + lib_dir_name + '/vndk-sp' 294 for name in lib_names: 295 self.assertIn(os.path.join(lib_dir, name + '.so'), vndk_sp) 296 297 self.assertNotIn('/system/lib/libfoo.so', vndk_sp) 298 self.assertNotIn('/system/lib64/libfoo.so', vndk_sp) 299 300 self.assertNotIn('/system/lib/vndk-sp/libbar.so', vndk_sp) 301 self.assertNotIn('/system/lib64/vndk-sp/libbar.so', vndk_sp) 302 303 def test_compute_predefined_vndk_sp_indirect(self): 304 lib_names = ( 305 'libbacktrace', 306 'libblas', 307 'liblzma', 308 'libpng', 309 'libunwind', 310 ) 311 312 # Add VNDK-SP-Indirect libraries. 313 gb = GraphBuilder() 314 for name in lib_names: 315 gb.add_multilib(PT_SYSTEM, name, extra_dir='vndk-sp') 316 317 # Add some unrelated libraries. 318 gb.add_multilib(PT_SYSTEM, 'libfoo') 319 gb.add_multilib(PT_SYSTEM, 'libbar', extra_dir='vndk-sp') 320 321 gb.resolve() 322 323 # Compute VNDK-SP-Indirect and check the result. 324 vndk_sp_indirect = gb.graph.compute_predefined_vndk_sp_indirect() 325 vndk_sp_indirect = set(lib.path for lib in vndk_sp_indirect) 326 327 for lib_dir_name in ('lib', 'lib64'): 328 lib_dir = '/system/' + lib_dir_name + '/vndk-sp' 329 for name in lib_names: 330 self.assertIn(os.path.join(lib_dir, name + '.so'), 331 vndk_sp_indirect) 332 333 self.assertNotIn('/system/lib/libfoo.so', vndk_sp_indirect) 334 self.assertNotIn('/system/lib64/libfoo.so', vndk_sp_indirect) 335 336 self.assertNotIn('/system/lib/vndk-sp/libbar.so', vndk_sp_indirect) 337 self.assertNotIn('/system/lib64/vndk-sp/libbar.so', vndk_sp_indirect) 338 339 def test_compute_predefined_sp_hal(self): 340 gb = GraphBuilder() 341 342 # HIDL SP-HAL implementation. 343 gb.add_multilib(PT_SYSTEM, 'gralloc.default', extra_dir='hw') 344 gb.add_multilib(PT_SYSTEM, 'gralloc.chipset', extra_dir='hw') 345 gb.add_multilib(PT_SYSTEM, 'android.hardware.graphics.mapper@2.0-impl', 346 extra_dir='hw') 347 348 # NDK loader libraries should not be considered as SP-HALs. 349 gb.add_multilib(PT_SYSTEM, 'libvulkan') 350 gb.add_multilib(PT_SYSTEM, 'libEGL') 351 gb.add_multilib(PT_SYSTEM, 'libGLESv1_CM') 352 gb.add_multilib(PT_SYSTEM, 'libGLESv2') 353 gb.add_multilib(PT_SYSTEM, 'libGLESv3') 354 355 # OpenGL implementation. 356 gb.add_multilib(PT_VENDOR, 'libEGL_chipset', extra_dir='egl') 357 gb.add_multilib(PT_VENDOR, 'libGLES_chipset', extra_dir='egl') 358 gb.add_multilib(PT_VENDOR, 'libGLESv1_CM_chipset', extra_dir='egl') 359 gb.add_multilib(PT_VENDOR, 'libGLESv2_chipset', extra_dir='egl') 360 gb.add_multilib(PT_VENDOR, 'libGLESv3_chipset', extra_dir='egl') 361 362 # Renderscript implementation. 363 gb.add_multilib(PT_VENDOR, 'libRSDriver_chipset') 364 gb.add_multilib(PT_VENDOR, 'libPVRRS') 365 366 # Vulkan implementation. 367 gb.add_multilib(PT_VENDOR, 'vulkan.chipset', extra_dir='hw') 368 369 # Some un-related libraries. 370 gb.add_multilib(PT_SYSTEM, 'libfoo') 371 gb.add_multilib(PT_VENDOR, 'libfoo') 372 373 gb.resolve() 374 375 # Compute SP-HAL. 376 sp_hals = set(lib.path for lib in gb.graph.compute_predefined_sp_hal()) 377 378 for lib in ('lib', 'lib64'): 379 # Check HIDL SP-HAL implementation. 380 self.assertIn('/system/' + lib + '/hw/gralloc.default.so', sp_hals) 381 self.assertIn('/system/' + lib + '/hw/gralloc.chipset.so', sp_hals) 382 self.assertIn('/system/' + lib + '/hw/' 383 'android.hardware.graphics.mapper@2.0-impl.so', 384 sp_hals) 385 386 387 # Check that NDK loaders are not SP-HALs. 388 self.assertNotIn('/system/' + lib + '/libvulkan.so', sp_hals) 389 self.assertNotIn('/system/' + lib + '/libEGL.so', sp_hals) 390 self.assertNotIn('/system/' + lib + '/libGLESv1_CM.so', sp_hals) 391 self.assertNotIn('/system/' + lib + '/libGLESv2.so', sp_hals) 392 self.assertNotIn('/system/' + lib + '/libGLESv3.so', sp_hals) 393 394 # Check that OpenGL implementations are SP-HALs. 395 self.assertIn('/vendor/' + lib + '/egl/libEGL_chipset.so', sp_hals) 396 self.assertIn('/vendor/' + lib + '/egl/libGLES_chipset.so', 397 sp_hals) 398 self.assertIn('/vendor/' + lib + '/egl/libGLESv1_CM_chipset.so', 399 sp_hals) 400 self.assertIn('/vendor/' + lib + '/egl/libGLESv2_chipset.so', 401 sp_hals) 402 self.assertIn('/vendor/' + lib + '/egl/libGLESv3_chipset.so', 403 sp_hals) 404 405 # Check that Renderscript implementations are SP-HALs. 406 self.assertIn('/vendor/' + lib + '/libRSDriver_chipset.so', sp_hals) 407 self.assertIn('/vendor/' + lib + '/libPVRRS.so', sp_hals) 408 409 # Check that vulkan implementation are SP-HALs. 410 self.assertIn('/vendor/' + lib + '/libPVRRS.so', sp_hals) 411 412 # Check that un-related libraries are not SP-HALs. 413 self.assertNotIn('/system/' + lib + '/libfoo.so', sp_hals) 414 self.assertNotIn('/vendor/' + lib + '/libfoo.so', sp_hals) 415 416 def test_compute_sp_lib(self): 417 # Create graph. 418 gb = GraphBuilder() 419 420 # LL-NDK (should be excluded from result) 421 gb.add_multilib(PT_SYSTEM, 'libc') 422 423 # SP-Both VNDK-SP 424 gb.add_multilib(PT_SYSTEM, 'libsp_both_vs') 425 426 # SP-NDK VNDK-SP 427 gb.add_multilib(PT_SYSTEM, 'libcutils_dep', dt_needed=['libc.so']) 428 gb.add_multilib(PT_SYSTEM, 'libcutils', 429 dt_needed=['libc.so', 'libcutils_dep.so', 430 'libsp_both_vs.so']) 431 432 # SP-NDK dependencies 433 gb.add_multilib(PT_SYSTEM, 'libutils', 434 dt_needed=['libc.so', 'libcutils.so']) 435 436 # SP-NDK 437 gb.add_multilib(PT_SYSTEM, 'libEGL', 438 dt_needed=['libc.so', 'libutils.so']) 439 440 # SP-HAL dependencies 441 gb.add_multilib(PT_VENDOR, 'libllvm_vendor_dep') 442 gb.add_multilib(PT_VENDOR, 'libllvm_vendor', 443 dt_needed=['libc.so', 'libllvm_vendor_dep.so']) 444 445 # SP-HAL VNDK-SP 446 gb.add_multilib(PT_SYSTEM, 'libhidlbase') 447 gb.add_multilib(PT_SYSTEM, 'libhidlmemory', 448 dt_needed=['libhidlbase.so', 'libsp_both_vs.so']) 449 450 # SP-HAL 451 gb.add_multilib(PT_VENDOR, 'libEGL_chipset', extra_dir='egl', 452 dt_needed=['libc.so', 'libllvm_vendor.so', 453 'libhidlmemory.so']) 454 455 gb.resolve() 456 457 # Create generic reference. 458 class MockGenericRefs(object): 459 def classify_lib(self, lib): 460 if 'libllvm_vendor' in lib.path: 461 return GenericRefs.NEW_LIB 462 return GenericRefs.EXPORT_EQUAL 463 464 sp_lib = gb.graph.compute_sp_lib(MockGenericRefs()) 465 466 self.assertEqual(2 * 1, len(sp_lib.sp_hal)) 467 self.assertEqual(2 * 2, len(sp_lib.sp_hal_dep)) 468 self.assertEqual(2 * 2, len(sp_lib.vndk_sp_hal)) 469 self.assertEqual(2 * 1, len(sp_lib.sp_ndk)) 470 self.assertEqual(2 * 3, len(sp_lib.sp_ndk_indirect)) 471 self.assertEqual(2 * 1, len(sp_lib.vndk_sp_both)) 472 473 sp_hal = self._get_paths_from_nodes(sp_lib.sp_hal) 474 sp_hal_dep = self._get_paths_from_nodes(sp_lib.sp_hal_dep) 475 vndk_sp_hal = self._get_paths_from_nodes(sp_lib.vndk_sp_hal) 476 477 sp_ndk = self._get_paths_from_nodes(sp_lib.sp_ndk) 478 sp_ndk_indirect = self._get_paths_from_nodes(sp_lib.sp_ndk_indirect) 479 480 vndk_sp_both = self._get_paths_from_nodes(sp_lib.vndk_sp_both) 481 482 for lib_dir in ('lib', 'lib64'): 483 # SP-Both 484 self.assertIn('/system/{}/libsp_both_vs.so'.format(lib_dir), 485 vndk_sp_both) 486 487 # SP-NDK dependencies 488 self.assertIn('/system/{}/libcutils.so'.format(lib_dir), 489 sp_ndk_indirect) 490 self.assertIn('/system/{}/libcutils_dep.so'.format(lib_dir), 491 sp_ndk_indirect) 492 self.assertIn('/system/{}/libutils.so'.format(lib_dir), 493 sp_ndk_indirect) 494 495 # SP-NDK 496 self.assertIn('/system/{}/libEGL.so'.format(lib_dir), sp_ndk) 497 498 # SP-HAL dependencies 499 self.assertIn('/vendor/{}/libllvm_vendor.so'.format(lib_dir), 500 sp_hal_dep) 501 self.assertIn('/vendor/{}/libllvm_vendor_dep.so'.format(lib_dir), 502 sp_hal_dep) 503 504 # SP-HAL VNDK-SP 505 self.assertIn('/system/{}/libhidlbase.so'.format(lib_dir), 506 vndk_sp_hal) 507 self.assertIn('/system/{}/libhidlmemory.so'.format(lib_dir), 508 vndk_sp_hal) 509 510 # SP-HAL 511 self.assertIn('/vendor/{}/egl/libEGL_chipset.so'.format(lib_dir), 512 sp_hal) 513 514 # LL-NDK must be excluded. 515 libc_path = '/system/{}/libc.so'.format(lib_dir) 516 self.assertNotIn(libc_path, sp_hal) 517 self.assertNotIn(libc_path, sp_hal_dep) 518 self.assertNotIn(libc_path, vndk_sp_hal) 519 self.assertNotIn(libc_path, sp_ndk) 520 self.assertNotIn(libc_path, sp_ndk_indirect) 521 522 523 def test_compute_vndk_cap(self): 524 gb = GraphBuilder() 525 526 # Add LL-NDK libraries. 527 gb.add_multilib(PT_SYSTEM, 'libc') 528 gb.add_multilib(PT_SYSTEM, 'libdl') 529 gb.add_multilib(PT_SYSTEM, 'liblog') 530 gb.add_multilib(PT_SYSTEM, 'libm') 531 gb.add_multilib(PT_SYSTEM, 'libstdc++') 532 533 # Add SP-NDK libraries. 534 gb.add_multilib(PT_SYSTEM, 'libEGL') 535 gb.add_multilib(PT_SYSTEM, 'libGLES_v2') 536 537 # Add banned libraries. 538 gb.add_multilib(PT_SYSTEM, 'libbinder') 539 gb.add_multilib(PT_SYSTEM, 'libselinux') 540 541 # Add good examples. 542 gb.add_multilib(PT_SYSTEM, 'libgood_a', dt_needed=['libc.so']) 543 gb.add_multilib(PT_SYSTEM, 'libgood_b', dt_needed=['libEGL.so']) 544 gb.add_multilib(PT_SYSTEM, 'libgood_c', dt_needed=['libGLES_v2.so']) 545 546 # Add bad examples. 547 gb.add_multilib(PT_SYSTEM, 'libbad_a', dt_needed=['libbinder.so']) 548 gb.add_multilib(PT_SYSTEM, 'libbad_b', dt_needed=['libselinux.so']) 549 gb.add_multilib(PT_SYSTEM, 'libbad_c', dt_needed=['libbad_a.so']) 550 gb.add_multilib(PT_SYSTEM, 'libbad_d', dt_needed=['libbad_c.so']) 551 gb.add_multilib(PT_VENDOR, 'libbad_e', dt_needed=['libc.so']) 552 553 gb.resolve() 554 555 # Compute VNDK cap. 556 banned_libs = BannedLibDict.create_default() 557 vndk_cap = gb.graph.compute_vndk_cap(banned_libs) 558 vndk_cap = set(lib.path for lib in vndk_cap) 559 560 # Check the existence of good examples. 561 self.assertIn('/system/lib/libgood_a.so', vndk_cap) 562 self.assertIn('/system/lib/libgood_b.so', vndk_cap) 563 self.assertIn('/system/lib/libgood_c.so', vndk_cap) 564 565 self.assertIn('/system/lib64/libgood_a.so', vndk_cap) 566 self.assertIn('/system/lib64/libgood_b.so', vndk_cap) 567 self.assertIn('/system/lib64/libgood_c.so', vndk_cap) 568 569 # Check the absence of bad examples. 570 self.assertNotIn('/system/lib/libbad_a.so', vndk_cap) 571 self.assertNotIn('/system/lib/libbad_b.so', vndk_cap) 572 self.assertNotIn('/system/lib/libbad_c.so', vndk_cap) 573 self.assertNotIn('/system/lib/libbad_d.so', vndk_cap) 574 self.assertNotIn('/vendor/lib/libbad_e.so', vndk_cap) 575 576 self.assertNotIn('/system/lib64/libbad_a.so', vndk_cap) 577 self.assertNotIn('/system/lib64/libbad_b.so', vndk_cap) 578 self.assertNotIn('/system/lib64/libbad_c.so', vndk_cap) 579 self.assertNotIn('/system/lib64/libbad_d.so', vndk_cap) 580 self.assertNotIn('/vendor/lib64/libbad_e.so', vndk_cap) 581 582 # Check the absence of banned libraries. 583 self.assertNotIn('/system/lib/libbinder.so', vndk_cap) 584 self.assertNotIn('/system/lib/libselinux.so', vndk_cap) 585 586 self.assertNotIn('/system/lib64/libbinder.so', vndk_cap) 587 self.assertNotIn('/system/lib64/libselinux.so', vndk_cap) 588 589 # Check the absence of NDK libraries. Although LL-NDK and SP-NDK 590 # libraries are not banned, they are not VNDK libraries either. 591 self.assertNotIn('/system/lib/libEGL.so', vndk_cap) 592 self.assertNotIn('/system/lib/libOpenGLES_v2.so', vndk_cap) 593 self.assertNotIn('/system/lib/libc.so', vndk_cap) 594 self.assertNotIn('/system/lib/libdl.so', vndk_cap) 595 self.assertNotIn('/system/lib/liblog.so', vndk_cap) 596 self.assertNotIn('/system/lib/libm.so', vndk_cap) 597 self.assertNotIn('/system/lib/libstdc++.so', vndk_cap) 598 599 self.assertNotIn('/system/lib64/libEGL.so', vndk_cap) 600 self.assertNotIn('/system/lib64/libOpenGLES_v2.so', vndk_cap) 601 self.assertNotIn('/system/lib64/libc.so', vndk_cap) 602 self.assertNotIn('/system/lib64/libdl.so', vndk_cap) 603 self.assertNotIn('/system/lib64/liblog.so', vndk_cap) 604 self.assertNotIn('/system/lib64/libm.so', vndk_cap) 605 self.assertNotIn('/system/lib64/libstdc++.so', vndk_cap) 606 607if __name__ == '__main__': 608 unittest.main() 609