1#!/usr/bin/env python3 2 3import os 4import sys 5import tempfile 6 7import_path = os.path.abspath(os.path.join(os.path.dirname(__file__), '..')) 8import_path = os.path.abspath(os.path.join(import_path, 'utils')) 9sys.path.insert(1, import_path) 10 11from utils import run_header_abi_dumper 12from utils import run_header_abi_dumper_on_file 13from utils import run_header_abi_linker 14from utils import SOURCE_ABI_DUMP_EXT 15 16 17SCRIPT_DIR = os.path.abspath(os.path.dirname(__file__)) 18ARCH_TARGET_CFLAGS = { 19 'arm': ('-target', 'arm-linux-androideabi'), 20 'arm64': ('-target', 'aarch64-linux-android'), 21 'x86': ('-target', 'i386-linux-androideabi'), 22 'x86_64': ('-target', 'x86_64-linux-android'), 23 'mips': ('-target', 'mips-linux-androideabi'), 24 'mips64': ('-target', 'mips64-linux-android'), 25} 26TARGET_ARCHES = ['arm', 'arm64', 'x86', 'x86_64', 'mips', 'mips64'] 27 28 29def relative_to_abs_path(relative_path): 30 return os.path.join(SCRIPT_DIR, relative_path) 31 32 33def relative_to_abs_path_list(relative_path_list): 34 abs_paths = [] 35 for relative_path in relative_path_list: 36 abs_paths.append(relative_to_abs_path(relative_path)) 37 return abs_paths 38 39 40class Module(object): 41 def __init__(self, name, arch, cflags, export_include_dirs): 42 self.name = name 43 self.arch = arch 44 self.cflags = tuple(cflags) 45 self.arch_cflags = ARCH_TARGET_CFLAGS.get(self.arch, tuple()) 46 self.export_include_dirs = relative_to_abs_path_list( 47 export_include_dirs) 48 49 def get_dump_name(self): 50 """Returns the module name followed by file extension.""" 51 raise NotImplementedError() 52 53 def make_dump(self): 54 """Returns the dump content as a string.""" 55 raise NotImplementedError() 56 57 def mutate_for_arch(self, target_arch): 58 """Returns a clone of this instance with arch=target_arch.""" 59 raise NotImplementedError() 60 61 def mutate_for_all_arches(self): 62 if self.arch: 63 return [self] 64 modules = [] 65 for target_arch in TARGET_ARCHES: 66 modules.append(self.mutate_for_arch(target_arch)) 67 return modules 68 69 @staticmethod 70 def get_test_modules(): 71 modules = [] 72 for module in TEST_MODULES.values(): 73 modules += module.mutate_for_all_arches() 74 return modules 75 76 @staticmethod 77 def get_test_modules_by_name(name): 78 return TEST_MODULES.get(name).mutate_for_all_arches() 79 80 81class SdumpModule(Module): 82 def __init__(self, name, src, export_include_dirs=tuple(), cflags=tuple(), 83 arch='', dumper_flags=tuple()): 84 super(SdumpModule, self).__init__(name, arch, cflags, 85 export_include_dirs) 86 self.src = relative_to_abs_path(src) 87 self.dumper_flags = dumper_flags 88 89 def get_dump_name(self): 90 return self.name + '.sdump' 91 92 def make_dump(self): 93 return run_header_abi_dumper( 94 self.src, cflags=self.cflags, 95 export_include_dirs=self.export_include_dirs, 96 flags=self.dumper_flags) 97 98 def mutate_for_arch(self, target_arch): 99 return SdumpModule(self.name, self.src, self.export_include_dirs, 100 self.cflags, target_arch, self.dumper_flags) 101 102 103class LsdumpModule(Module): 104 def __init__(self, name, srcs, version_script, export_include_dirs, 105 cflags=tuple(), arch='', api='current', dumper_flags=tuple(), 106 linker_flags=tuple()): 107 super(LsdumpModule, self).__init__(name, arch, cflags, 108 export_include_dirs) 109 self.srcs = relative_to_abs_path_list(srcs) 110 self.version_script = relative_to_abs_path(version_script) 111 self.api = api 112 self.dumper_flags = dumper_flags 113 self.linker_flags = linker_flags 114 115 def get_dump_name(self): 116 return self.name + SOURCE_ABI_DUMP_EXT 117 118 def make_dump(self): 119 """For each source file, produce a .sdump file, and link them to form 120 an lsump file.""" 121 dumps_to_link = [] 122 with tempfile.TemporaryDirectory() as tmp: 123 output_lsdump = os.path.join(tmp, self.get_dump_name()) 124 for src in self.srcs: 125 output_path = os.path.join(tmp, 126 os.path.basename(src) + '.sdump') 127 dumps_to_link.append(output_path) 128 run_header_abi_dumper_on_file( 129 src, output_path, self.export_include_dirs, 130 self.cflags + self.arch_cflags, 131 self.dumper_flags) 132 return run_header_abi_linker(output_lsdump, dumps_to_link, 133 self.version_script, self.api, 134 self.arch, self.linker_flags) 135 136 def mutate_for_arch(self, target_arch): 137 return LsdumpModule(self.name, self.srcs, self.version_script, 138 self.export_include_dirs, self.cflags, target_arch, 139 self.api, self.dumper_flags, self.linker_flags) 140 141 142TEST_MODULES = [ 143 SdumpModule( 144 name='undeclared_types.h', 145 src='integration/cpp/header/undeclared_types.h', 146 arch='', 147 dumper_flags=['-suppress-errors', '-output-format', 'Json']), 148 SdumpModule( 149 name='known_issues.h', 150 src='integration/cpp/header/known_issues.h', 151 arch='', 152 dumper_flags=['-suppress-errors', '-output-format', 'Json']), 153 LsdumpModule( 154 name='libc_and_cpp', 155 srcs=[ 156 'integration/c_and_cpp/source1.cpp', 157 'integration/c_and_cpp/source2.c', 158 ], 159 version_script='integration/c_and_cpp/map.txt', 160 export_include_dirs=['integration/c_and_cpp/include'], 161 ), 162 LsdumpModule( 163 name='libc_and_cpp_with_opaque_ptr_a', 164 srcs=[ 165 'integration/c_and_cpp/source1.cpp', 166 'integration/c_and_cpp/source2.c', 167 ], 168 version_script='integration/c_and_cpp/map.txt', 169 export_include_dirs=['integration/c_and_cpp/include'], 170 cflags=['-DOPAQUE_STRUCT_A=1'], 171 ), 172 LsdumpModule( 173 name='libc_and_cpp_with_opaque_ptr_b', 174 srcs=[ 175 'integration/c_and_cpp/source1.cpp', 176 'integration/c_and_cpp/source2.c', 177 ], 178 version_script='integration/c_and_cpp/map.txt', 179 export_include_dirs=['integration/c_and_cpp/include'], 180 cflags=['-DOPAQUE_STRUCT_B=1'], 181 ), 182 LsdumpModule( 183 name='libc_and_cpp_with_unused_struct', 184 srcs=[ 185 'integration/c_and_cpp/source1.cpp', 186 'integration/c_and_cpp/source2.c', 187 ], 188 version_script='integration/c_and_cpp/map.txt', 189 export_include_dirs=['integration/c_and_cpp/include'], 190 cflags=['-DINCLUDE_UNUSED_STRUCTS=1'], 191 ), 192 LsdumpModule( 193 name='libc_and_cpp_with_unused_cstruct', 194 srcs=[ 195 'integration/c_and_cpp/source1.cpp', 196 'integration/c_and_cpp/source2.c', 197 ], 198 version_script='integration/c_and_cpp/map.txt', 199 export_include_dirs=['integration/c_and_cpp/include'], 200 cflags=['-DINCLUDE_UNUSED_STRUCTS=1', '-DMAKE_UNUSED_STRUCT_C=1'], 201 ), 202 LsdumpModule( 203 name='libgolden_cpp', 204 srcs=[ 205 'integration/cpp/gold/golden_1.cpp', 206 'integration/cpp/gold/high_volume_speaker.cpp', 207 'integration/cpp/gold/low_volume_speaker.cpp', 208 ], 209 version_script='integration/cpp/gold/map.txt', 210 export_include_dirs=['integration/cpp/gold/include'], 211 ), 212 LsdumpModule( 213 name='libgolden_cpp_odr', 214 srcs=[ 215 'integration/cpp/gold/golden_1.cpp', 216 'integration/cpp/gold/high_volume_speaker.cpp', 217 'integration/cpp/gold/low_volume_speaker.cpp', 218 ], 219 version_script='integration/cpp/gold/map.txt', 220 export_include_dirs=['integration/cpp/gold/include'], 221 cflags=['-DTEST_ODR'], 222 ), 223 LsdumpModule( 224 name='libgolden_cpp_add_function', 225 srcs=[ 226 'integration/cpp/gold/golden_1.cpp', 227 'integration/cpp/gold/high_volume_speaker.cpp', 228 'integration/cpp/gold/low_volume_speaker.cpp', 229 ], 230 version_script='integration/cpp/gold/map_add_function.txt', 231 export_include_dirs=['integration/cpp/gold/include'], 232 cflags=['-DGOLDEN_ADD_FUNCTION=1'], 233 ), 234 LsdumpModule( 235 name='libgolden_cpp_add_function_and_unexported_elf', 236 srcs=[ 237 'integration/cpp/gold/golden_1.cpp', 238 'integration/cpp/gold/high_volume_speaker.cpp', 239 'integration/cpp/gold/low_volume_speaker.cpp', 240 ], 241 version_script='integration/cpp/gold/map_add_function_elf_symbol.txt', 242 export_include_dirs=['integration/cpp/gold/include'], 243 cflags=['-DGOLDEN_ADD_FUNCTION=1', '-DADD_UNEXPORTED_ELF_SYMBOL'], 244 arch='', 245 api='current', 246 ), 247 LsdumpModule( 248 name='libgolden_cpp_add_function_sybmol_only', 249 srcs=[ 250 'integration/cpp/gold/golden_1.cpp', 251 'integration/cpp/gold/high_volume_speaker.cpp', 252 'integration/cpp/gold/low_volume_speaker.cpp', 253 ], 254 version_script='integration/cpp/gold/map_add_function.txt', 255 export_include_dirs=['integration/cpp/gold/include'], 256 ), 257 LsdumpModule( 258 name='libgolden_cpp_change_function_access', 259 srcs=[ 260 'integration/cpp/gold/golden_1.cpp', 261 'integration/cpp/gold/high_volume_speaker.cpp', 262 'integration/cpp/gold/low_volume_speaker.cpp', 263 ], 264 version_script='integration/cpp/gold/map.txt', 265 export_include_dirs=['integration/cpp/gold/include'], 266 cflags=['-DGOLDEN_CHANGE_FUNCTION_ACCESS=1'], 267 ), 268 LsdumpModule( 269 name='libgolden_cpp_add_global_variable', 270 srcs=[ 271 'integration/cpp/gold/golden_1.cpp', 272 'integration/cpp/gold/high_volume_speaker.cpp', 273 'integration/cpp/gold/low_volume_speaker.cpp', 274 ], 275 version_script='integration/cpp/gold/map_added_globvar.txt', 276 export_include_dirs=['integration/cpp/gold/include'], 277 cflags=['-DGOLDEN_ADD_GLOBVAR=1'], 278 ), 279 LsdumpModule( 280 name='libgolden_cpp_add_global_variable_private', 281 srcs=[ 282 'integration/cpp/gold/golden_1.cpp', 283 'integration/cpp/gold/high_volume_speaker.cpp', 284 'integration/cpp/gold/low_volume_speaker.cpp', 285 ], 286 version_script='integration/cpp/gold/map_added_globvar.txt', 287 export_include_dirs=['integration/cpp/gold/include'], 288 cflags=['-DGOLDEN_ADD_GLOBVAR=1', '-DGOLDEN_ADD_GLOBVAR_PRIVATE'], 289 ), 290 LsdumpModule( 291 name='libgolden_cpp_return_type_diff', 292 srcs=[ 293 'integration/cpp/gold/golden_1.cpp', 294 'integration/cpp/gold/high_volume_speaker.cpp', 295 'integration/cpp/gold/low_volume_speaker.cpp', 296 ], 297 version_script='integration/cpp/gold/map.txt', 298 export_include_dirs=['integration/cpp/gold/include'], 299 cflags=['-DGOLDEN_RETURN_TYPE_DIFF=1'], 300 ), 301 LsdumpModule( 302 name='libgolden_cpp_parameter_type_diff', 303 srcs=[ 304 'integration/cpp/gold/golden_1.cpp', 305 'integration/cpp/gold/high_volume_speaker.cpp', 306 'integration/cpp/gold/low_volume_speaker.cpp', 307 ], 308 version_script='integration/cpp/gold/map_parameter_type_diff.txt', 309 export_include_dirs=['integration/cpp/gold/include'], 310 cflags=['-DGOLDEN_PARAMETER_TYPE_DIFF=1'], 311 ), 312 LsdumpModule( 313 name='libgolden_cpp_vtable_diff', 314 srcs=[ 315 'integration/cpp/gold/golden_1.cpp', 316 'integration/cpp/gold/high_volume_speaker.cpp', 317 'integration/cpp/gold/low_volume_speaker.cpp', 318 ], 319 version_script='integration/cpp/gold/map.txt', 320 export_include_dirs=['integration/cpp/gold/include'], 321 cflags=['-DGOLDEN_VTABLE_DIFF=1'], 322 ), 323 LsdumpModule( 324 name='libgolden_cpp_member_diff', 325 srcs=[ 326 'integration/cpp/gold/golden_1.cpp', 327 'integration/cpp/gold/high_volume_speaker.cpp', 328 'integration/cpp/gold/low_volume_speaker.cpp', 329 ], 330 version_script='integration/cpp/gold/map.txt', 331 export_include_dirs=['integration/cpp/gold/include'], 332 cflags=['-DGOLDEN_MEMBER_DIFF=1'], 333 ), 334 LsdumpModule( 335 name='libgolden_cpp_member_fake_diff', 336 srcs=[ 337 'integration/cpp/gold/golden_1.cpp', 338 'integration/cpp/gold/high_volume_speaker.cpp', 339 'integration/cpp/gold/low_volume_speaker.cpp', 340 ], 341 version_script='integration/cpp/gold/map.txt', 342 export_include_dirs=['integration/cpp/gold/include'], 343 cflags=['-DGOLDEN_MEMBER_FAKE_DIFF=1'], 344 ), 345 LsdumpModule( 346 name='libgolden_cpp_member_cv_diff', 347 srcs=[ 348 'integration/cpp/gold/golden_1.cpp', 349 'integration/cpp/gold/high_volume_speaker.cpp', 350 'integration/cpp/gold/low_volume_speaker.cpp', 351 ], 352 version_script='integration/cpp/gold/map.txt', 353 export_include_dirs=['integration/cpp/gold/include'], 354 cflags=['-DGOLDEN_MEMBER_CV_DIFF=1'], 355 ), 356 LsdumpModule( 357 name='libgolden_cpp_change_member_access', 358 srcs=[ 359 'integration/cpp/gold/golden_1.cpp', 360 'integration/cpp/gold/high_volume_speaker.cpp', 361 'integration/cpp/gold/low_volume_speaker.cpp', 362 ], 363 version_script='integration/cpp/gold/map.txt', 364 export_include_dirs=['integration/cpp/gold/include'], 365 cflags=['-DGOLDEN_CHANGE_MEMBER_ACCESS=1'], 366 ), 367 LsdumpModule( 368 name='libgolden_cpp_member_integral_type_diff', 369 srcs=[ 370 'integration/cpp/gold/golden_1.cpp', 371 'integration/cpp/gold/high_volume_speaker.cpp', 372 'integration/cpp/gold/low_volume_speaker.cpp', 373 ], 374 version_script='integration/cpp/gold/map.txt', 375 export_include_dirs=['integration/cpp/gold/include'], 376 cflags=['-DGOLDEN_MEMBER_INTEGRAL_TYPE_DIFF=1'], 377 ), 378 LsdumpModule( 379 name='libgolden_cpp_enum_diff', 380 srcs=[ 381 'integration/cpp/gold/golden_1.cpp', 382 'integration/cpp/gold/high_volume_speaker.cpp', 383 'integration/cpp/gold/low_volume_speaker.cpp', 384 ], 385 version_script='integration/cpp/gold/map.txt', 386 export_include_dirs=['integration/cpp/gold/include'], 387 cflags=['-DGOLDEN_ENUM_DIFF=1'], 388 ), 389 LsdumpModule( 390 name='libgolden_cpp_enum_extended', 391 srcs=[ 392 'integration/cpp/gold/golden_1.cpp', 393 'integration/cpp/gold/high_volume_speaker.cpp', 394 'integration/cpp/gold/low_volume_speaker.cpp', 395 ], 396 version_script='integration/cpp/gold/map.txt', 397 export_include_dirs=['integration/cpp/gold/include'], 398 cflags=['-DGOLDEN_ENUM_EXTENSION=1'], 399 ), 400 LsdumpModule( 401 name='libgolden_cpp_unreferenced_elf_symbol_removed', 402 srcs=[ 403 'integration/cpp/gold/golden_1.cpp', 404 'integration/cpp/gold/high_volume_speaker.cpp', 405 'integration/cpp/gold/low_volume_speaker.cpp', 406 ], 407 version_script='integration/cpp/gold/map_elf_symbol_removed.txt', 408 export_include_dirs=['integration/cpp/gold/include'], 409 ), 410 LsdumpModule( 411 name='libreproducability', 412 srcs=['integration/c_and_cpp/reproducability.c'], 413 version_script='integration/c_and_cpp/repro_map.txt', 414 export_include_dirs=['integration/c_and_cpp/include'], 415 ), 416 LsdumpModule( 417 name='libgolden_cpp_member_name_changed', 418 srcs=[ 419 'integration/cpp/gold/golden_1.cpp', 420 'integration/cpp/gold/high_volume_speaker.cpp', 421 'integration/cpp/gold/low_volume_speaker.cpp', 422 ], 423 version_script='integration/cpp/gold/map.txt', 424 export_include_dirs=['integration/cpp/gold/include'], 425 cflags=['-DGOLDEN_CHANGE_MEMBER_NAME_SAME_OFFSET=1'], 426 ), 427 LsdumpModule( 428 name='libgolden_cpp_function_pointer', 429 srcs=[ 430 'integration/cpp/gold/golden_1.cpp', 431 'integration/cpp/gold/high_volume_speaker.cpp', 432 'integration/cpp/gold/low_volume_speaker.cpp', 433 ], 434 version_script='integration/cpp/gold/map.txt', 435 export_include_dirs=['integration/cpp/gold/include'], 436 cflags=['-DGOLDEN_FUNCTION_POINTER=1'], 437 ), 438 LsdumpModule( 439 name='libgolden_cpp_function_pointer_parameter_added', 440 srcs=[ 441 'integration/cpp/gold/golden_1.cpp', 442 'integration/cpp/gold/high_volume_speaker.cpp', 443 'integration/cpp/gold/low_volume_speaker.cpp', 444 ], 445 version_script='integration/cpp/gold/map.txt', 446 export_include_dirs=['integration/cpp/gold/include'], 447 cflags=['-DGOLDEN_FUNCTION_POINTER_ADD_PARAM=1', 448 '-DGOLDEN_FUNCTION_POINTER=1'], 449 ), 450 LsdumpModule( 451 name='libgolden_cpp_internal_public_struct', 452 srcs=[ 453 'integration/cpp/gold/golden_1.cpp', 454 'integration/cpp/gold/high_volume_speaker.cpp', 455 'integration/cpp/gold/low_volume_speaker.cpp', 456 ], 457 version_script='integration/cpp/gold/map.txt', 458 export_include_dirs=['integration/cpp/gold/include'], 459 cflags=['-DGOLDEN_WITH_INTERNAL_STRUCT', 460 '-DGOLDEN_WITH_PUBLIC_INTERNAL_STRUCT'], 461 ), 462 LsdumpModule( 463 name='libgolden_cpp_internal_private_struct', 464 srcs=[ 465 'integration/cpp/gold/golden_1.cpp', 466 'integration/cpp/gold/high_volume_speaker.cpp', 467 'integration/cpp/gold/low_volume_speaker.cpp', 468 ], 469 version_script='integration/cpp/gold/map.txt', 470 export_include_dirs=['integration/cpp/gold/include'], 471 cflags=['-DGOLDEN_WITH_INTERNAL_STRUCT'], 472 ), 473 LsdumpModule( 474 name='libgolden_cpp_inheritance_type_changed', 475 srcs=[ 476 'integration/cpp/gold/golden_1.cpp', 477 'integration/cpp/gold/high_volume_speaker.cpp', 478 'integration/cpp/gold/low_volume_speaker.cpp', 479 ], 480 version_script='integration/cpp/gold/map.txt', 481 export_include_dirs=['integration/cpp/gold/include'], 482 cflags=['-DGOLDEN_CHANGE_INHERITANCE_TYPE'], 483 ), 484 LsdumpModule( 485 name='libpure_virtual_function', 486 srcs=['integration/cpp/pure_virtual/pure_virtual_function.cpp'], 487 export_include_dirs=['integration/cpp/pure_virtual/include'], 488 version_script='', 489 ), 490 LsdumpModule( 491 name='libgolden_cpp_json', 492 srcs=[ 493 'integration/cpp/gold/golden_1.cpp', 494 'integration/cpp/gold/high_volume_speaker.cpp', 495 'integration/cpp/gold/low_volume_speaker.cpp', 496 ], 497 version_script='integration/cpp/gold/map.txt', 498 export_include_dirs=['integration/cpp/gold/include'], 499 dumper_flags=['-output-format', 'Json'], 500 linker_flags=['-input-format', 'Json', '-output-format', 'Json'] 501 ), 502 LsdumpModule( 503 name='libversion_script_example', 504 arch='arm64', 505 srcs=[ 506 'integration/version_script_example/example.cpp', 507 ], 508 version_script='integration/version_script_example/example.map.txt', 509 export_include_dirs=['integration/version_script_example'], 510 dumper_flags=['-output-format', 'Json'], 511 linker_flags=[ 512 '-input-format', 'Json', 513 '-output-format', 'Json', 514 '-so', relative_to_abs_path( 515 'integration/version_script_example/prebuilts/' + 516 'libversion_script_example.so' 517 ), 518 ] 519 ), 520 LsdumpModule( 521 name='libversion_script_example_no_private', 522 arch='arm64', 523 srcs=[ 524 'integration/version_script_example/example.cpp', 525 ], 526 version_script='integration/version_script_example/example.map.txt', 527 export_include_dirs=['integration/version_script_example'], 528 dumper_flags=['-output-format', 'Json'], 529 linker_flags=[ 530 '-input-format', 'Json', 531 '-output-format', 'Json', 532 '-so', relative_to_abs_path( 533 'integration/version_script_example/prebuilts/' + 534 'libversion_script_example.so' 535 ), 536 '--exclude-symbol-version', 'LIBVERSION_SCRIPT_EXAMPLE_PRIVATE', 537 ] 538 ), 539 LsdumpModule( 540 name='libversion_script_example_no_mytag', 541 arch='arm64', 542 srcs=[ 543 'integration/version_script_example/example.cpp', 544 ], 545 version_script='integration/version_script_example/example.map.txt', 546 export_include_dirs=['integration/version_script_example'], 547 dumper_flags=['-output-format', 'Json'], 548 linker_flags=[ 549 '-input-format', 'Json', 550 '-output-format', 'Json', 551 '-so', relative_to_abs_path( 552 'integration/version_script_example/prebuilts/' + 553 'libversion_script_example.so' 554 ), 555 '--exclude-symbol-tag', 'mytag', 556 ] 557 ), 558 559 # Test data for test_allow_adding_removing_weak_symbols 560 LsdumpModule( 561 name='libweak_symbols_old', 562 arch='arm64', 563 srcs=[ 564 'integration/weak_symbols/example.c', 565 ], 566 version_script='integration/weak_symbols/libexample_old.map.txt', 567 export_include_dirs=[], 568 dumper_flags=['-output-format', 'Json'], 569 linker_flags=[ 570 '-input-format', 'Json', 571 '-output-format', 'Json', 572 ] 573 ), 574 LsdumpModule( 575 name='libweak_symbols_new', 576 arch='arm64', 577 srcs=[ 578 'integration/weak_symbols/example.c', 579 ], 580 version_script='integration/weak_symbols/libexample_new.map.txt', 581 export_include_dirs=[], 582 dumper_flags=['-output-format', 'Json'], 583 linker_flags=[ 584 '-input-format', 'Json', 585 '-output-format', 'Json', 586 ], 587 cflags=['-DNEW=1'] 588 ), 589] 590 591TEST_MODULES = {m.name: m for m in TEST_MODULES} 592